From 1e9d66e961bae1e3884be7c844c7faba252c4bed Mon Sep 17 00:00:00 2001 From: Henson Choi Date: Thu, 4 Jun 2026 20:28:51 +0900 Subject: [PATCH 44/68] Tidy up row pattern recognition pattern compilation Mark the unreachable tails of the three node-type switches (rprPatternEqual, optimizeRPRPattern, fillRPRPattern) with pg_unreachable() instead of a "keep compiler quiet" return. RPRPatternNodeType has only four members and each switch handles all of them, so the trailing return can never be reached. In buildRPRPattern(), the absorption-eligibility test guarded against a ROWS frame redundantly: RPR is ROWS-only because transformRPR() rejects RANGE and GROUPS up front, so the FRAMEOPTION_ROWS term was always true. Drop the hasLimitedFrame variable, assert the ROWS-only invariant instead, and test FRAMEOPTION_END_UNBOUNDED_FOLLOWING directly. No behavior change. Patch by Jian He, with minor adjustments. --- src/backend/optimizer/plan/rpr.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/backend/optimizer/plan/rpr.c b/src/backend/optimizer/plan/rpr.c index 617a3869948..3205559c03a 100644 --- a/src/backend/optimizer/plan/rpr.c +++ b/src/backend/optimizer/plan/rpr.c @@ -132,7 +132,8 @@ rprPatternEqual(RPRPatternNode *a, RPRPatternNode *b) return rprPatternChildrenEqual(a->children, b->children); } - return false; /* keep compiler quiet */ + pg_unreachable(); + return false; } /* @@ -993,7 +994,8 @@ optimizeRPRPattern(RPRPatternNode *pattern) return optimizeGroupPattern(pattern); } - return pattern; /* keep compiler quiet */ + pg_unreachable(); + return pattern; } /* @@ -1450,7 +1452,8 @@ fillRPRPattern(RPRPatternNode *node, RPRPattern *pat, int *idx, RPRDepth depth) return fillRPRPatternAlt(node, pat, idx, depth); } - return false; /* unreachable */ + pg_unreachable(); + return false; } /* @@ -1955,10 +1958,11 @@ buildRPRPattern(RPRPatternNode *pattern, List *defineVariableList, int numElements; RPRDepth maxDepth; int idx; - bool hasLimitedFrame; /* Caller must check for NULL pattern before calling */ Assert(pattern != NULL); + /* RPR is ROWS-only: transformRPR() rejects RANGE/GROUPS up front */ + Assert(frameOptions & FRAMEOPTION_ROWS); /* Optimize the pattern tree */ optimized = optimizeRPRPattern(copyObject(pattern)); @@ -1997,10 +2001,8 @@ buildRPRPattern(RPRPatternNode *pattern, List *defineVariableList, * absorption semantics - older contexts don't necessarily produce longer * matches when frame limits apply differently to each context. */ - hasLimitedFrame = (frameOptions & FRAMEOPTION_ROWS) && - !(frameOptions & FRAMEOPTION_END_UNBOUNDED_FOLLOWING); - - if (rpSkipTo == ST_PAST_LAST_ROW && !hasLimitedFrame && + if (rpSkipTo == ST_PAST_LAST_ROW && + (frameOptions & FRAMEOPTION_END_UNBOUNDED_FOLLOWING) && !hasMatchStartDependent) { /* Runtime conditions met - check structural absorbability */ -- 2.50.1 (Apple Git-155)