0001-parser-Add-and_patch.txt
text/plain
Filename: 0001-parser-Add-and_patch.txt
Type: text/plain
Part: 0
Message:
Re: Row pattern recognition
From 987a3fce6fb7823b42631658079e8ec2d0b432e4 Mon Sep 17 00:00:00 2001
From: Henson Choi <assam258@gmail.com>
Date: Sat, 3 Jan 2026 19:51:38 +0900
Subject: [PATCH] parser: Add "|" and "{}"
---
src/backend/parser/gram.y | 27 ++++++++++++++++++++++++++-
src/backend/parser/scan.l | 4 ++--
2 files changed, 28 insertions(+), 3 deletions(-)
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 99c27dc178c..bd7c2820265 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -900,7 +900,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
%nonassoc IDENT PARTITION RANGE ROWS GROUPS PRECEDING FOLLOWING CUBE ROLLUP
SET KEYS OBJECT_P SCALAR VALUE_P WITH WITHOUT PATH
AFTER INITIAL SEEK PATTERN_P
-%left Op OPERATOR /* multi-character ops and user-defined operators */
+%left Op OPERATOR '|' /* multi-character ops and user-defined operators */
%left '+' '-'
%left '*' '/' '%'
%left '^'
@@ -16871,6 +16871,7 @@ opt_row_pattern_initial_or_seek:
row_pattern:
row_pattern_term { $$ = list_make1($1); }
| row_pattern row_pattern_term { $$ = lappend($1, $2); }
+ | row_pattern '|' row_pattern_term { $$ = lappend($1, $3); /* TODO: mark as alternation */ }
;
row_pattern_term:
@@ -16892,6 +16893,27 @@ row_pattern_term:
$$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "?", (Node *)makeString($1), NULL, @1);
}
+ /* {m} - exactly m times */
+ | ColId '{' Iconst '}'
+ {
+ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "{m}", (Node *)makeString($1), (Node *)makeInteger($3), @1);
+ }
+ /* {m,} - at least m times */
+ | ColId '{' Iconst ',' '}'
+ {
+ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "{m,}", (Node *)makeString($1), (Node *)makeInteger($3), @1);
+ }
+ /* {m,n} - between m and n times */
+ | ColId '{' Iconst ',' Iconst '}'
+ {
+ List *bounds = list_make2(makeInteger($3), makeInteger($5));
+ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "{m,n}", (Node *)makeString($1), (Node *)bounds, @1);
+ }
+ /* {,n} - at most n times (0 to n) */
+ | ColId '{' ',' Iconst '}'
+ {
+ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "{,n}", (Node *)makeString($1), (Node *)makeInteger($4), @1);
+ }
;
row_pattern_definition_list:
@@ -16953,12 +16975,15 @@ MathOp: '+' { $$ = "+"; }
| LESS_EQUALS { $$ = "<="; }
| GREATER_EQUALS { $$ = ">="; }
| NOT_EQUALS { $$ = "<>"; }
+ | '|' { $$ = "|"; }
;
qual_Op: Op
{ $$ = list_make1(makeString($1)); }
| OPERATOR '(' any_operator ')'
{ $$ = $3; }
+ | '|'
+ { $$ = list_make1(makeString("|")); }
;
qual_all_Op:
diff --git a/src/backend/parser/scan.l b/src/backend/parser/scan.l
index a67815339b7..c7b984df34c 100644
--- a/src/backend/parser/scan.l
+++ b/src/backend/parser/scan.l
@@ -363,7 +363,7 @@ not_equals "!="
* If you change either set, adjust the character lists appearing in the
* rule for "operator"!
*/
-self [,()\[\].;\:\+\-\*\/\%\^\<\>\=]
+self [,()\[\].;\:\+\-\*\/\%\^\<\>\=\|\{\}]
op_chars [\~\!\@\#\^\&\|\`\?\+\-\*\/\%\<\>\=]
operator {op_chars}+
@@ -955,7 +955,7 @@ other .
* that the "self" rule would have.
*/
if (nchars == 1 &&
- strchr(",()[].;:+-*/%^<>=", yytext[0]))
+ strchr(",()[].;:+-*/%^<>=|{}", yytext[0]))
return yytext[0];
/*
* Likewise, if what we have left is two chars, and
--
2.50.1 (Apple Git-155)