From 2bc7f29dcfceefc83fd787eb138c96247f565360 Mon Sep 17 00:00:00 2001 From: Henson Choi Date: Tue, 3 Mar 2026 15:50:48 +0900 Subject: [PATCH 2/8] Fix RPR reluctant quantifier flag lost during VIEW serialization diff --git a/src/backend/optimizer/plan/rpr.c b/src/backend/optimizer/plan/rpr.c index 8792d8174fa..009c0f5019d 100644 --- a/src/backend/optimizer/plan/rpr.c +++ b/src/backend/optimizer/plan/rpr.c @@ -198,7 +198,7 @@ flattenSeqChildren(List *children) /* GROUP{1,1} should have been unwrapped by optimizeGroupPattern */ Assert(!(opt->nodeType == RPR_PATTERN_GROUP && - opt->min == 1 && opt->max == 1 && opt->reluctant < 0)); + opt->min == 1 && opt->max == 1 && opt->reluctant == false)); if (opt->nodeType == RPR_PATTERN_SEQ) { @@ -234,7 +234,7 @@ mergeConsecutiveVars(List *children) { RPRPatternNode *child = (RPRPatternNode *) lfirst(lc); - if (child->nodeType == RPR_PATTERN_VAR && child->reluctant < 0) + if (child->nodeType == RPR_PATTERN_VAR && child->reluctant == false) { /* ---------------------- * Can merge consecutive VAR nodes if: @@ -253,7 +253,7 @@ mergeConsecutiveVars(List *children) * Merge: accumulate min/max into prev. prev is guaranteed to * be a non-reluctant VAR by the outer condition. */ - Assert(prev->nodeType == RPR_PATTERN_VAR && prev->reluctant < 0); + Assert(prev->nodeType == RPR_PATTERN_VAR && prev->reluctant == false); prev->min += child->min; @@ -308,7 +308,7 @@ mergeConsecutiveGroups(List *children) { RPRPatternNode *child = (RPRPatternNode *) lfirst(lc); - if (child->nodeType == RPR_PATTERN_GROUP && child->reluctant < 0) + if (child->nodeType == RPR_PATTERN_GROUP && child->reluctant == false) { /* ---------------------- * Can merge consecutive GROUP nodes if: @@ -327,7 +327,7 @@ mergeConsecutiveGroups(List *children) * Merge: accumulate min/max into prev. prev is guaranteed to * be a non-reluctant GROUP by the outer condition. */ - Assert(prev->nodeType == RPR_PATTERN_GROUP && prev->reluctant < 0); + Assert(prev->nodeType == RPR_PATTERN_GROUP && prev->reluctant == false); prev->min += child->min; @@ -385,7 +385,7 @@ mergeConsecutiveAlts(List *children) { RPRPatternNode *child = (RPRPatternNode *) lfirst(lc); - if (child->nodeType == RPR_PATTERN_ALT && child->reluctant < 0) + if (child->nodeType == RPR_PATTERN_ALT && child->reluctant == false) { if (prev != NULL && rprPatternChildrenEqual(prev->children, child->children)) @@ -406,7 +406,8 @@ mergeConsecutiveAlts(List *children) group->nodeType = RPR_PATTERN_GROUP; group->min = count; group->max = count; - group->reluctant = -1; + group->reluctant = false; + group->reluctant_location = -1; group->location = -1; group->children = list_make1(prev); mergedChildren = lappend(mergedChildren, group); @@ -430,7 +431,8 @@ mergeConsecutiveAlts(List *children) group->nodeType = RPR_PATTERN_GROUP; group->min = count; group->max = count; - group->reluctant = -1; + group->reluctant = false; + group->reluctant_location = -1; group->location = -1; group->children = list_make1(prev); mergedChildren = lappend(mergedChildren, group); @@ -454,7 +456,8 @@ mergeConsecutiveAlts(List *children) group->nodeType = RPR_PATTERN_GROUP; group->min = count; group->max = count; - group->reluctant = -1; + group->reluctant = false; + group->reluctant_location = -1; group->location = -1; group->children = list_make1(prev); mergedChildren = lappend(mergedChildren, group); @@ -498,7 +501,7 @@ mergeGroupPrefixSuffix(List *children) * children. GROUP's content may be wrapped in a SEQ - unwrap for * comparison. */ - if (child->nodeType == RPR_PATTERN_GROUP && child->reluctant < 0) + if (child->nodeType == RPR_PATTERN_GROUP && child->reluctant == false) { List *groupContent = child->children; int groupChildCount; @@ -773,14 +776,14 @@ tryMultiplyQuantifiers(RPRPatternNode *pattern) /* Parser always creates GROUP with exactly one child */ Assert(list_length(pattern->children) == 1); - if (pattern->reluctant >= 0) + if (pattern->reluctant) return pattern; child = (RPRPatternNode *) linitial(pattern->children); if ((child->nodeType != RPR_PATTERN_VAR && child->nodeType != RPR_PATTERN_GROUP) || - child->reluctant >= 0) + child->reluctant) return pattern; /* Case 1: Both unbounded - (A*)* -> A*, (A+)+ -> A+ */ @@ -862,11 +865,12 @@ tryUnwrapGroup(RPRPatternNode *pattern) * the child and unwrap. E.g., (A)?? -> A??, (A)+? -> A+? */ if (child->nodeType == RPR_PATTERN_VAR && - child->min == 1 && child->max == 1 && child->reluctant < 0) + child->min == 1 && child->max == 1 && child->reluctant == false) { child->min = pattern->min; child->max = pattern->max; child->reluctant = pattern->reluctant; + child->reluctant_location = pattern->reluctant_location; return child; } @@ -1150,7 +1154,7 @@ fillRPRPatternVar(RPRPatternNode *node, RPRPattern *pat, int *idx, RPRDepth dept elem->max = (node->max == INT_MAX) ? RPR_QUANTITY_INF : node->max; elem->next = RPR_ELEMIDX_INVALID; elem->jump = RPR_ELEMIDX_INVALID; - if (node->reluctant >= 0) + if (node->reluctant) elem->flags |= RPR_ELEM_RELUCTANT; (*idx)++; @@ -1189,7 +1193,7 @@ fillRPRPatternGroup(RPRPatternNode *node, RPRPattern *pat, int *idx, RPRDepth de elem->max = (node->max == INT_MAX) ? RPR_QUANTITY_INF : node->max; elem->next = RPR_ELEMIDX_INVALID; /* set by finalize */ elem->jump = RPR_ELEMIDX_INVALID; /* set after END */ - if (node->reluctant >= 0) + if (node->reluctant) elem->flags |= RPR_ELEM_RELUCTANT; (*idx)++; groupStartIdx = *idx; /* children start after BEGIN */ @@ -1214,7 +1218,7 @@ fillRPRPatternGroup(RPRPatternNode *node, RPRPattern *pat, int *idx, RPRDepth de endElem->max = (node->max == INT_MAX) ? RPR_QUANTITY_INF : node->max; endElem->next = RPR_ELEMIDX_INVALID; endElem->jump = groupStartIdx; /* loop to first child */ - if (node->reluctant >= 0) + if (node->reluctant) endElem->flags |= RPR_ELEM_RELUCTANT; /* diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index b55a11cc837..f1a71cd036b 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -16967,7 +16967,8 @@ row_pattern_alt: n->children = list_make2($1, $3); n->min = 1; n->max = 1; - n->reluctant = -1; + n->reluctant = false; + n->reluctant_location = -1; n->location = @1; $$ = (Node *) n; } @@ -16994,7 +16995,8 @@ row_pattern_seq: n->children = list_make2($1, $2); n->min = 1; n->max = 1; - n->reluctant = -1; + n->reluctant = false; + n->reluctant_location = -1; n->location = @1; $$ = (Node *) n; } @@ -17010,6 +17012,7 @@ row_pattern_term: n->min = q->min; n->max = q->max; n->reluctant = q->reluctant; + n->reluctant_location = q->reluctant_location; $$ = (Node *) n; } ; @@ -17022,7 +17025,8 @@ row_pattern_primary: n->varName = $1; n->min = 1; n->max = 1; - n->reluctant = -1; + n->reluctant = false; + n->reluctant_location = -1; n->children = NIL; n->location = @1; $$ = (Node *) n; @@ -17035,7 +17039,8 @@ row_pattern_primary: n->children = list_make1(inner); n->min = 1; n->max = 1; - n->reluctant = -1; + n->reluctant = false; + n->reluctant_location = -1; n->location = @1; $$ = (Node *) n; } @@ -20400,14 +20405,15 @@ makeRecursiveViewSelect(char *relname, List *aliases, Node *query) * Create an RPRPatternNode with specified quantifier bounds. */ static RPRPatternNode * -makeRPRQuantifier(int min, int max, ParseLoc reluctant, int location, +makeRPRQuantifier(int min, int max, ParseLoc reluctant_location, int location, core_yyscan_t yyscanner) { RPRPatternNode *n = makeNode(RPRPatternNode); n->min = min; n->max = max; - n->reluctant = reluctant; + n->reluctant = (reluctant_location >= 0); + n->reluctant_location = reluctant_location; n->location = location; return n; } diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index f5bb81e8c05..928bed2e9fb 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -6778,7 +6778,7 @@ append_pattern_quantifier(StringInfo buf, RPRPatternNode *node) else appendStringInfo(buf, "{%d,%d}", node->min, node->max); - if (node->reluctant >= 0) + if (node->reluctant) { if (!has_quantifier) appendStringInfo(buf, "{1}"); /* make reluctant ? unambiguous */ diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index 8af527b57d3..22e856c671d 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -608,8 +608,8 @@ typedef struct RPRPatternNode RPRPatternNodeType nodeType; /* VAR, SEQ, ALT, GROUP */ int min; /* minimum repetitions (0 for *, ?) */ int max; /* maximum repetitions (INT_MAX for *, +) */ - ParseLoc reluctant; /* location of '?' for reluctant, -1 for - * greedy */ + bool reluctant; /* true for reluctant (non-greedy) */ + ParseLoc reluctant_location; /* location of '?' token, or -1 */ ParseLoc location; /* token location, or -1 */ char *varName; /* VAR: variable name */ List *children; /* SEQ, ALT, GROUP: child nodes */ -- 2.50.1 (Apple Git-155)