Skip to content

Commit c956dec

Browse files
tatsuo-ishiiCommitfest Bot
authored andcommitted
Row pattern recognition patch for raw parser.
1 parent 4856618 commit c956dec

File tree

4 files changed

+159
-16
lines changed

4 files changed

+159
-16
lines changed

src/backend/parser/gram.y

Lines changed: 106 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -672,6 +672,13 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
672672
json_object_constructor_null_clause_opt
673673
json_array_constructor_null_clause_opt
674674

675+
%type <target> row_pattern_definition
676+
%type <node> opt_row_pattern_common_syntax
677+
row_pattern_term
678+
%type <list> row_pattern_definition_list
679+
row_pattern
680+
%type <ival> opt_row_pattern_skip_to
681+
%type <boolean> opt_row_pattern_initial_or_seek
675682

676683
/*
677684
* Non-keyword token types. These are hard-wired into the "flex" lexer.
@@ -715,7 +722,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
715722
CURRENT_TIME CURRENT_TIMESTAMP CURRENT_USER CURSOR CYCLE
716723

717724
DATA_P DATABASE DAY_P DEALLOCATE DEC DECIMAL_P DECLARE DEFAULT DEFAULTS
718-
DEFERRABLE DEFERRED DEFINER DELETE_P DELIMITER DELIMITERS DEPENDS DEPTH DESC
725+
DEFERRABLE DEFERRED DEFINE DEFINER DELETE_P DELIMITER DELIMITERS DEPENDS DEPTH DESC
719726
DETACH DICTIONARY DISABLE_P DISCARD DISTINCT DO DOCUMENT_P DOMAIN_P
720727
DOUBLE_P DROP
721728

@@ -731,7 +738,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
731738
HANDLER HAVING HEADER_P HOLD HOUR_P
732739

733740
IDENTITY_P IF_P ILIKE IMMEDIATE IMMUTABLE IMPLICIT_P IMPORT_P IN_P INCLUDE
734-
INCLUDING INCREMENT INDENT INDEX INDEXES INHERIT INHERITS INITIALLY INLINE_P
741+
INCLUDING INCREMENT INDENT INDEX INDEXES INHERIT INHERITS INITIAL INITIALLY INLINE_P
735742
INNER_P INOUT INPUT_P INSENSITIVE INSERT INSTEAD INT_P INTEGER
736743
INTERSECT INTERVAL INTO INVOKER IS ISNULL ISOLATION
737744

@@ -756,8 +763,8 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
756763
ORDER ORDINALITY OTHERS OUT_P OUTER_P
757764
OVER OVERLAPS OVERLAY OVERRIDING OWNED OWNER
758765

759-
PARALLEL PARAMETER PARSER PARTIAL PARTITION PASSING PASSWORD PATH
760-
PERIOD PLACING PLAN PLANS POLICY
766+
PARALLEL PARAMETER PARSER PARTIAL PARTITION PASSING PASSWORD PAST
767+
PATH PATTERN_P PERIOD PLACING PLAN PLANS POLICY
761768
POSITION PRECEDING PRECISION PRESERVE PREPARE PREPARED PRIMARY
762769
PRIOR PRIVILEGES PROCEDURAL PROCEDURE PROCEDURES PROGRAM PUBLICATION
763770

@@ -768,7 +775,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
768775
RESET RESTART RESTRICT RETURN RETURNING RETURNS REVOKE RIGHT ROLE ROLLBACK ROLLUP
769776
ROUTINE ROUTINES ROW ROWS RULE
770777

771-
SAVEPOINT SCALAR SCHEMA SCHEMAS SCROLL SEARCH SECOND_P SECURITY SELECT
778+
SAVEPOINT SCALAR SCHEMA SCHEMAS SCROLL SEARCH SECOND_P SECURITY SEEK SELECT
772779
SEQUENCE SEQUENCES
773780
SERIALIZABLE SERVER SESSION SESSION_USER SET SETS SETOF SHARE SHOW
774781
SIMILAR SIMPLE SKIP SMALLINT SNAPSHOT SOME SOURCE SQL_P STABLE STANDALONE_P
@@ -851,8 +858,8 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
851858
* reference point for a precedence level that we can assign to other
852859
* keywords that lack a natural precedence level.
853860
*
854-
* We need to do this for PARTITION, RANGE, ROWS, and GROUPS to support
855-
* opt_existing_window_name (see comment there).
861+
* We need to do this for PARTITION, RANGE, ROWS, GROUPS, AFTER, INITIAL,
862+
* SEEK, PATTERN_P to support opt_existing_window_name (see comment there).
856863
*
857864
* The frame_bound productions UNBOUNDED PRECEDING and UNBOUNDED FOLLOWING
858865
* are even messier: since UNBOUNDED is an unreserved keyword (per spec!),
@@ -882,6 +889,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
882889
%nonassoc UNBOUNDED NESTED /* ideally would have same precedence as IDENT */
883890
%nonassoc IDENT PARTITION RANGE ROWS GROUPS PRECEDING FOLLOWING CUBE ROLLUP
884891
SET KEYS OBJECT_P SCALAR VALUE_P WITH WITHOUT PATH
892+
AFTER INITIAL SEEK PATTERN_P
885893
%left Op OPERATOR /* multi-character ops and user-defined operators */
886894
%left '+' '-'
887895
%left '*' '/' '%'
@@ -16476,7 +16484,8 @@ over_clause: OVER window_specification
1647616484
;
1647716485

1647816486
window_specification: '(' opt_existing_window_name opt_partition_clause
16479-
opt_sort_clause opt_frame_clause ')'
16487+
opt_sort_clause opt_frame_clause
16488+
opt_row_pattern_common_syntax ')'
1648016489
{
1648116490
WindowDef *n = makeNode(WindowDef);
1648216491

@@ -16488,20 +16497,21 @@ window_specification: '(' opt_existing_window_name opt_partition_clause
1648816497
n->frameOptions = $5->frameOptions;
1648916498
n->startOffset = $5->startOffset;
1649016499
n->endOffset = $5->endOffset;
16500+
n->rpCommonSyntax = (RPCommonSyntax *)$6;
1649116501
n->location = @1;
1649216502
$$ = n;
1649316503
}
1649416504
;
1649516505

1649616506
/*
16497-
* If we see PARTITION, RANGE, ROWS or GROUPS as the first token after the '('
16498-
* of a window_specification, we want the assumption to be that there is
16499-
* no existing_window_name; but those keywords are unreserved and so could
16500-
* be ColIds. We fix this by making them have the same precedence as IDENT
16501-
* and giving the empty production here a slightly higher precedence, so
16502-
* that the shift/reduce conflict is resolved in favor of reducing the rule.
16503-
* These keywords are thus precluded from being an existing_window_name but
16504-
* are not reserved for any other purpose.
16507+
* If we see PARTITION, RANGE, ROWS, GROUPS, AFTER, INITIAL, SEEK or PATTERN_P
16508+
* as the first token after the '(' of a window_specification, we want the
16509+
* assumption to be that there is no existing_window_name; but those keywords
16510+
* are unreserved and so could be ColIds. We fix this by making them have the
16511+
* same precedence as IDENT and giving the empty production here a slightly
16512+
* higher precedence, so that the shift/reduce conflict is resolved in favor
16513+
* of reducing the rule. These keywords are thus precluded from being an
16514+
* existing_window_name but are not reserved for any other purpose.
1650516515
*/
1650616516
opt_existing_window_name: ColId { $$ = $1; }
1650716517
| /*EMPTY*/ %prec Op { $$ = NULL; }
@@ -16670,6 +16680,76 @@ opt_window_exclusion_clause:
1667016680
| /*EMPTY*/ { $$ = 0; }
1667116681
;
1667216682

16683+
opt_row_pattern_common_syntax:
16684+
opt_row_pattern_skip_to opt_row_pattern_initial_or_seek
16685+
PATTERN_P '(' row_pattern ')'
16686+
DEFINE row_pattern_definition_list
16687+
{
16688+
RPCommonSyntax *n = makeNode(RPCommonSyntax);
16689+
n->rpSkipTo = $1;
16690+
n->initial = $2;
16691+
n->rpPatterns = $5;
16692+
n->rpDefs = $8;
16693+
$$ = (Node *) n;
16694+
}
16695+
| /*EMPTY*/ { $$ = NULL; }
16696+
;
16697+
16698+
opt_row_pattern_skip_to:
16699+
AFTER MATCH SKIP TO NEXT ROW
16700+
{
16701+
$$ = ST_NEXT_ROW;
16702+
}
16703+
| AFTER MATCH SKIP PAST LAST_P ROW
16704+
{
16705+
$$ = ST_PAST_LAST_ROW;
16706+
}
16707+
| /*EMPTY*/
16708+
{
16709+
$$ = ST_PAST_LAST_ROW;
16710+
}
16711+
;
16712+
16713+
opt_row_pattern_initial_or_seek:
16714+
INITIAL { $$ = true; }
16715+
| SEEK
16716+
{
16717+
ereport(ERROR,
16718+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
16719+
errmsg("SEEK is not supported"),
16720+
errhint("Use INITIAL instead."),
16721+
parser_errposition(@1)));
16722+
}
16723+
| /*EMPTY*/ { $$ = true; }
16724+
;
16725+
16726+
row_pattern:
16727+
row_pattern_term { $$ = list_make1($1); }
16728+
| row_pattern row_pattern_term { $$ = lappend($1, $2); }
16729+
;
16730+
16731+
row_pattern_term:
16732+
ColId { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "", (Node *)makeString($1), NULL, @1); }
16733+
| ColId '*' { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "*", (Node *)makeString($1), NULL, @1); }
16734+
| ColId '+' { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "+", (Node *)makeString($1), NULL, @1); }
16735+
| ColId '?' { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "?", (Node *)makeString($1), NULL, @1); }
16736+
;
16737+
16738+
row_pattern_definition_list:
16739+
row_pattern_definition { $$ = list_make1($1); }
16740+
| row_pattern_definition_list ',' row_pattern_definition { $$ = lappend($1, $3); }
16741+
;
16742+
16743+
row_pattern_definition:
16744+
ColId AS a_expr
16745+
{
16746+
$$ = makeNode(ResTarget);
16747+
$$->name = $1;
16748+
$$->indirection = NIL;
16749+
$$->val = (Node *) $3;
16750+
$$->location = @1;
16751+
}
16752+
;
1667316753

1667416754
/*
1667516755
* Supporting nonterminals for expressions.
@@ -17873,6 +17953,7 @@ unreserved_keyword:
1787317953
| INDEXES
1787417954
| INHERIT
1787517955
| INHERITS
17956+
| INITIAL
1787617957
| INLINE_P
1787717958
| INPUT_P
1787817959
| INSENSITIVE
@@ -17946,7 +18027,9 @@ unreserved_keyword:
1794618027
| PARTITION
1794718028
| PASSING
1794818029
| PASSWORD
18030+
| PAST
1794918031
| PATH
18032+
| PATTERN_P
1795018033
| PERIOD
1795118034
| PLAN
1795218035
| PLANS
@@ -17999,6 +18082,7 @@ unreserved_keyword:
1799918082
| SEARCH
1800018083
| SECOND_P
1800118084
| SECURITY
18085+
| SEEK
1800218086
| SEQUENCE
1800318087
| SEQUENCES
1800418088
| SERIALIZABLE
@@ -18221,6 +18305,7 @@ reserved_keyword:
1822118305
| CURRENT_USER
1822218306
| DEFAULT
1822318307
| DEFERRABLE
18308+
| DEFINE
1822418309
| DESC
1822518310
| DISTINCT
1822618311
| DO
@@ -18384,6 +18469,7 @@ bare_label_keyword:
1838418469
| DEFAULTS
1838518470
| DEFERRABLE
1838618471
| DEFERRED
18472+
| DEFINE
1838718473
| DEFINER
1838818474
| DELETE_P
1838918475
| DELIMITER
@@ -18462,6 +18548,7 @@ bare_label_keyword:
1846218548
| INDEXES
1846318549
| INHERIT
1846418550
| INHERITS
18551+
| INITIAL
1846518552
| INITIALLY
1846618553
| INLINE_P
1846718554
| INNER_P
@@ -18573,7 +18660,9 @@ bare_label_keyword:
1857318660
| PARTITION
1857418661
| PASSING
1857518662
| PASSWORD
18663+
| PAST
1857618664
| PATH
18665+
| PATTERN_P
1857718666
| PERIOD
1857818667
| PLACING
1857918668
| PLAN
@@ -18632,6 +18721,7 @@ bare_label_keyword:
1863218721
| SCROLL
1863318722
| SEARCH
1863418723
| SECURITY
18724+
| SEEK
1863518725
| SELECT
1863618726
| SEQUENCE
1863718727
| SEQUENCES

src/include/nodes/parsenodes.h

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -577,6 +577,31 @@ typedef struct SortBy
577577
ParseLoc location; /* operator location, or -1 if none/unknown */
578578
} SortBy;
579579

580+
/*
581+
* AFTER MATCH row pattern skip to types in row pattern common syntax
582+
*/
583+
typedef enum RPSkipTo
584+
{
585+
ST_NONE, /* AFTER MATCH omitted */
586+
ST_NEXT_ROW, /* SKIP TO NEXT ROW */
587+
ST_PAST_LAST_ROW, /* SKIP TO PAST LAST ROW */
588+
} RPSkipTo;
589+
590+
/*
591+
* RowPatternCommonSyntax - raw representation of row pattern common syntax
592+
*
593+
*/
594+
typedef struct RPCommonSyntax
595+
{
596+
NodeTag type;
597+
RPSkipTo rpSkipTo; /* Row Pattern AFTER MATCH SKIP type */
598+
bool initial; /* true if <row pattern initial or seek> is
599+
* initial */
600+
List *rpPatterns; /* PATTERN variables (list of A_Expr) */
601+
List *rpDefs; /* row pattern definitions clause (list of
602+
* ResTarget) */
603+
} RPCommonSyntax;
604+
580605
/*
581606
* WindowDef - raw representation of WINDOW and OVER clauses
582607
*
@@ -592,6 +617,7 @@ typedef struct WindowDef
592617
char *refname; /* referenced window name, if any */
593618
List *partitionClause; /* PARTITION BY expression list */
594619
List *orderClause; /* ORDER BY (list of SortBy) */
620+
RPCommonSyntax *rpCommonSyntax; /* row pattern common syntax */
595621
int frameOptions; /* frame_clause options, see below */
596622
Node *startOffset; /* expression for starting bound, if any */
597623
Node *endOffset; /* expression for ending bound, if any */
@@ -1560,6 +1586,11 @@ typedef struct GroupingSet
15601586
* the orderClause might or might not be copied (see copiedOrder); the framing
15611587
* options are never copied, per spec.
15621588
*
1589+
* "defineClause" is Row Pattern Recognition DEFINE clause (list of
1590+
* TargetEntry). TargetEntry.resname represents row pattern definition
1591+
* variable name. "patternVariable" and "patternRegexp" represents PATTERN
1592+
* clause.
1593+
*
15631594
* The information relevant for the query jumbling is the partition clause
15641595
* type and its bounds.
15651596
*/
@@ -1589,6 +1620,22 @@ typedef struct WindowClause
15891620
Index winref; /* ID referenced by window functions */
15901621
/* did we copy orderClause from refname? */
15911622
bool copiedOrder pg_node_attr(query_jumble_ignore);
1623+
/* Row Pattern AFTER MACH SKIP clause */
1624+
RPSkipTo rpSkipTo; /* Row Pattern Skip To type */
1625+
bool initial; /* true if <row pattern initial or seek> is
1626+
* initial */
1627+
/* Row Pattern DEFINE clause (list of TargetEntry) */
1628+
List *defineClause;
1629+
/* Row Pattern DEFINE variable initial names (list of String) */
1630+
List *defineInitial;
1631+
/* Row Pattern PATTERN variable name (list of String) */
1632+
List *patternVariable;
1633+
1634+
/*
1635+
* Row Pattern PATTERN regular expression quantifier ('+' or ''. list of
1636+
* String)
1637+
*/
1638+
List *patternRegexp;
15921639
} WindowClause;
15931640

15941641
/*

src/include/parser/kwlist.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ PG_KEYWORD("default", DEFAULT, RESERVED_KEYWORD, BARE_LABEL)
129129
PG_KEYWORD("defaults", DEFAULTS, UNRESERVED_KEYWORD, BARE_LABEL)
130130
PG_KEYWORD("deferrable", DEFERRABLE, RESERVED_KEYWORD, BARE_LABEL)
131131
PG_KEYWORD("deferred", DEFERRED, UNRESERVED_KEYWORD, BARE_LABEL)
132+
PG_KEYWORD("define", DEFINE, RESERVED_KEYWORD, BARE_LABEL)
132133
PG_KEYWORD("definer", DEFINER, UNRESERVED_KEYWORD, BARE_LABEL)
133134
PG_KEYWORD("delete", DELETE_P, UNRESERVED_KEYWORD, BARE_LABEL)
134135
PG_KEYWORD("delimiter", DELIMITER, UNRESERVED_KEYWORD, BARE_LABEL)
@@ -216,6 +217,7 @@ PG_KEYWORD("index", INDEX, UNRESERVED_KEYWORD, BARE_LABEL)
216217
PG_KEYWORD("indexes", INDEXES, UNRESERVED_KEYWORD, BARE_LABEL)
217218
PG_KEYWORD("inherit", INHERIT, UNRESERVED_KEYWORD, BARE_LABEL)
218219
PG_KEYWORD("inherits", INHERITS, UNRESERVED_KEYWORD, BARE_LABEL)
220+
PG_KEYWORD("initial", INITIAL, UNRESERVED_KEYWORD, BARE_LABEL)
219221
PG_KEYWORD("initially", INITIALLY, RESERVED_KEYWORD, BARE_LABEL)
220222
PG_KEYWORD("inline", INLINE_P, UNRESERVED_KEYWORD, BARE_LABEL)
221223
PG_KEYWORD("inner", INNER_P, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL)
@@ -339,7 +341,9 @@ PG_KEYWORD("partial", PARTIAL, UNRESERVED_KEYWORD, BARE_LABEL)
339341
PG_KEYWORD("partition", PARTITION, UNRESERVED_KEYWORD, BARE_LABEL)
340342
PG_KEYWORD("passing", PASSING, UNRESERVED_KEYWORD, BARE_LABEL)
341343
PG_KEYWORD("password", PASSWORD, UNRESERVED_KEYWORD, BARE_LABEL)
344+
PG_KEYWORD("past", PAST, UNRESERVED_KEYWORD, BARE_LABEL)
342345
PG_KEYWORD("path", PATH, UNRESERVED_KEYWORD, BARE_LABEL)
346+
PG_KEYWORD("pattern", PATTERN_P, UNRESERVED_KEYWORD, BARE_LABEL)
343347
PG_KEYWORD("period", PERIOD, UNRESERVED_KEYWORD, BARE_LABEL)
344348
PG_KEYWORD("placing", PLACING, RESERVED_KEYWORD, BARE_LABEL)
345349
PG_KEYWORD("plan", PLAN, UNRESERVED_KEYWORD, BARE_LABEL)
@@ -401,6 +405,7 @@ PG_KEYWORD("scroll", SCROLL, UNRESERVED_KEYWORD, BARE_LABEL)
401405
PG_KEYWORD("search", SEARCH, UNRESERVED_KEYWORD, BARE_LABEL)
402406
PG_KEYWORD("second", SECOND_P, UNRESERVED_KEYWORD, AS_LABEL)
403407
PG_KEYWORD("security", SECURITY, UNRESERVED_KEYWORD, BARE_LABEL)
408+
PG_KEYWORD("seek", SEEK, UNRESERVED_KEYWORD, BARE_LABEL)
404409
PG_KEYWORD("select", SELECT, RESERVED_KEYWORD, BARE_LABEL)
405410
PG_KEYWORD("sequence", SEQUENCE, UNRESERVED_KEYWORD, BARE_LABEL)
406411
PG_KEYWORD("sequences", SEQUENCES, UNRESERVED_KEYWORD, BARE_LABEL)

src/include/parser/parse_node.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ typedef enum ParseExprKind
5151
EXPR_KIND_WINDOW_FRAME_RANGE, /* window frame clause with RANGE */
5252
EXPR_KIND_WINDOW_FRAME_ROWS, /* window frame clause with ROWS */
5353
EXPR_KIND_WINDOW_FRAME_GROUPS, /* window frame clause with GROUPS */
54+
EXPR_KIND_RPR_DEFINE, /* DEFINE */
5455
EXPR_KIND_SELECT_TARGET, /* SELECT target list item */
5556
EXPR_KIND_INSERT_TARGET, /* INSERT target list item */
5657
EXPR_KIND_UPDATE_SOURCE, /* UPDATE assignment source item */

0 commit comments

Comments
 (0)