From f7ce59b5068b40730f29e7e774ace3c2101fda36 Mon Sep 17 00:00:00 2001 From: jian he Date: Sun, 16 Aug 2026 13:28:36 +0900 Subject: [PATCH] Simplify the RPR pattern grammar actions with castNode row_pattern_alt and row_pattern_seq each tested IsA($1, RPRPatternNode) before reading the node's type, and wrapped the value in a fresh ALT or SEQ node when the test failed. The test cannot fail. row_pattern_primary reduces to makeNode(RPRPatternNode) on both of its producing alternatives and raises an error on the third, and splitRPRTrailingAlt() returns either its argument or a node it made itself, so every value that reaches these actions is an RPRPatternNode. The fallback arms were unreachable. Take the cast with castNode() instead, which asserts the tag rather than branching on it, and name the result once at the top of each action. A wrong tag now stops an assert-enabled build, where it used to be wrapped up and carried on with. The neighbouring row_pattern_term already casts without a test. No grammar rule, %type declaration or precedence changes, and %expect stays at 0. Nothing reachable behaves differently, so no expected output moves, and that is what covers this: the arms that survive are the two appends and the two makeNode arms, and the Pattern: lines in the RPR tests exercise all four -- an alternation or a sequence of three or more members at one level takes an append, two members takes a makeNode. The arms being removed cannot be covered, since nothing produces a value for these actions but makeNode(RPRPatternNode). --- src/backend/parser/gram.y | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 1031d7ef167..cb2bc1b4639 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -17720,23 +17720,22 @@ row_pattern_alt: } | row_pattern_alt '|' row_pattern_seq { - RPRPatternNode *n; - RPRPatternNode *rhs = splitRPRTrailingAlt((RPRPatternNode *) $3, + RPRPatternNode *lhs = castNode(RPRPatternNode, $1); + RPRPatternNode *rhs = splitRPRTrailingAlt(castNode(RPRPatternNode, $3), yyscanner); /* If left side is already ALT, append to it */ - if (IsA($1, RPRPatternNode) && - ((RPRPatternNode *) $1)->nodeType == RPR_PATTERN_ALT) + if (lhs->nodeType == RPR_PATTERN_ALT) { - n = (RPRPatternNode *) $1; - n->children = lappend(n->children, rhs); - $$ = (Node *) n; + lhs->children = lappend(lhs->children, rhs); + $$ = (Node *) lhs; } else { - n = makeNode(RPRPatternNode); + RPRPatternNode *n = makeNode(RPRPatternNode); + n->nodeType = RPR_PATTERN_ALT; - n->children = list_make2($1, rhs); + n->children = list_make2(lhs, rhs); n->min = 1; n->max = 1; n->reluctant = false; @@ -17750,25 +17749,24 @@ row_pattern_seq: row_pattern_term { $$ = $1; } | row_pattern_seq row_pattern_term { - RPRPatternNode *n; + RPRPatternNode *seq = castNode(RPRPatternNode, $1); /* * If left side is already SEQ, append to it. A glued * quantifier's trailing_alt stays on the child term; * row_pattern_alt splits on it once the seq is complete. */ - if (IsA($1, RPRPatternNode) && - ((RPRPatternNode *) $1)->nodeType == RPR_PATTERN_SEQ) + if (seq->nodeType == RPR_PATTERN_SEQ) { - n = (RPRPatternNode *) $1; - n->children = lappend(n->children, $2); - $$ = (Node *) n; + seq->children = lappend(seq->children, $2); + $$ = (Node *) seq; } else { - n = makeNode(RPRPatternNode); + RPRPatternNode *n = makeNode(RPRPatternNode); + n->nodeType = RPR_PATTERN_SEQ; - n->children = list_make2($1, $2); + n->children = list_make2(seq, $2); n->min = 1; n->max = 1; n->reluctant = false;