From 34c409c8f227ded8bd00a9b7379171109c812372 Mon Sep 17 00:00:00 2001 From: jian he Date: Sun, 16 Aug 2026 13:49:57 +0900 Subject: [PATCH] Drop a redundant assertion and a redundant copy from the RPR planner Two unrelated bits of housekeeping in rpr.c, neither of which changes what the planner produces. rprPatternEqual() asserted both of its arguments non-NULL, one line before dereferencing them. Nothing can violate it: a children list built by the grammar cannot carry a NULL pattern node, since every production there returns makeNode and the one arm that does not raises an error, and the optimizer's passes only ever rebuild those lists from what they were given. The function is static and its two callers are in this file. Drop the assertion, and state the requirement in the header comment where a caller reads it, rather than in a comment left standing over nothing. buildRPRPattern() copied each DEFINE variable name into a stack array that outlives nothing. Both readers of that array -- the strcmp in scanRPRPattern() and the pstrdup in makeRPRPattern() -- run inside buildRPRPattern's own extent, the names belong to the WindowClause, and makeRPRPattern() copies them anyway, so the result still owns what it returns. Borrow the pointer instead, which is also what the pattern scan already does with the names it collects. The quantifier range assertions in fillRPRPatternVar() and fillRPRPatternGroup() stay, although finalizeRPRPattern() checks the same range over every element and so covers them. They are not redundant in the way that matters: those three fire with the pattern node still in scope, while the one in finalizeRPRPattern() runs after the array is built and can name only an index. Assertions cost nothing in a production build, and a duplicated check that fails nearer its cause is worth keeping. --- src/backend/optimizer/plan/rpr.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/backend/optimizer/plan/rpr.c b/src/backend/optimizer/plan/rpr.c index 122aaa67a24..21f87b1e4b4 100644 --- a/src/backend/optimizer/plan/rpr.c +++ b/src/backend/optimizer/plan/rpr.c @@ -99,14 +99,12 @@ static void computeAbsorbability(RPRPattern *pattern); * rprPatternEqual * Compare two RPRPatternNode trees for equality. * - * Returns true if the trees are structurally identical. + * Returns true if the trees are structurally identical. Neither argument + * may be NULL: a children list never holds one. */ static bool rprPatternEqual(RPRPatternNode *a, RPRPatternNode *b) { - /* Pattern nodes in children lists must never be NULL */ - Assert(a != NULL && b != NULL); - /* Must have same node type and quantifiers */ if (a->nodeType != b->nodeType) return false; @@ -2078,7 +2076,7 @@ buildRPRPattern(RPRPatternNode *pattern, List *defineClause, /* Parser always assigns a name to each DEFINE entry */ Assert(te->resname != NULL); - varNamesStack[numVars++] = pstrdup(te->resname); + varNamesStack[numVars++] = te->resname; } /* Scan pattern: collect variables, count elements, validate limits */