Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 90e5085

Browse files
tatsuo-ishiiCommitfest Bot
authored and
Commitfest Bot
committed
Row pattern recognition patch for raw parser.
1 parent d98cefe commit 90e5085

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 '*' '/' '%'
@@ -16431,7 +16439,8 @@ over_clause: OVER window_specification
1643116439
;
1643216440

1643316441
window_specification: '(' opt_existing_window_name opt_partition_clause
16434-
opt_sort_clause opt_frame_clause ')'
16442+
opt_sort_clause opt_frame_clause
16443+
opt_row_pattern_common_syntax ')'
1643516444
{
1643616445
WindowDef *n = makeNode(WindowDef);
1643716446

@@ -16443,20 +16452,21 @@ window_specification: '(' opt_existing_window_name opt_partition_clause
1644316452
n->frameOptions = $5->frameOptions;
1644416453
n->startOffset = $5->startOffset;
1644516454
n->endOffset = $5->endOffset;
16455+
n->rpCommonSyntax = (RPCommonSyntax *)$6;
1644616456
n->location = @1;
1644716457
$$ = n;
1644816458
}
1644916459
;
1645016460

1645116461
/*
16452-
* If we see PARTITION, RANGE, ROWS or GROUPS as the first token after the '('
16453-
* of a window_specification, we want the assumption to be that there is
16454-
* no existing_window_name; but those keywords are unreserved and so could
16455-
* be ColIds. We fix this by making them have the same precedence as IDENT
16456-
* and giving the empty production here a slightly higher precedence, so
16457-
* that the shift/reduce conflict is resolved in favor of reducing the rule.
16458-
* These keywords are thus precluded from being an existing_window_name but
16459-
* are not reserved for any other purpose.
16462+
* If we see PARTITION, RANGE, ROWS, GROUPS, AFTER, INITIAL, SEEK or PATTERN_P
16463+
* as the first token after the '(' of a window_specification, we want the
16464+
* assumption to be that there is no existing_window_name; but those keywords
16465+
* are unreserved and so could be ColIds. We fix this by making them have the
16466+
* same precedence as IDENT and giving the empty production here a slightly
16467+
* higher precedence, so that the shift/reduce conflict is resolved in favor
16468+
* of reducing the rule. These keywords are thus precluded from being an
16469+
* existing_window_name but are not reserved for any other purpose.
1646016470
*/
1646116471
opt_existing_window_name: ColId { $$ = $1; }
1646216472
| /*EMPTY*/ %prec Op { $$ = NULL; }
@@ -16625,6 +16635,76 @@ opt_window_exclusion_clause:
1662516635
| /*EMPTY*/ { $$ = 0; }
1662616636
;
1662716637

16638+
opt_row_pattern_common_syntax:
16639+
opt_row_pattern_skip_to opt_row_pattern_initial_or_seek
16640+
PATTERN_P '(' row_pattern ')'
16641+
DEFINE row_pattern_definition_list
16642+
{
16643+
RPCommonSyntax *n = makeNode(RPCommonSyntax);
16644+
n->rpSkipTo = $1;
16645+
n->initial = $2;
16646+
n->rpPatterns = $5;
16647+
n->rpDefs = $8;
16648+
$$ = (Node *) n;
16649+
}
16650+
| /*EMPTY*/ { $$ = NULL; }
16651+
;
16652+
16653+
opt_row_pattern_skip_to:
16654+
AFTER MATCH SKIP TO NEXT ROW
16655+
{
16656+
$$ = ST_NEXT_ROW;
16657+
}
16658+
| AFTER MATCH SKIP PAST LAST_P ROW
16659+
{
16660+
$$ = ST_PAST_LAST_ROW;
16661+
}
16662+
| /*EMPTY*/
16663+
{
16664+
$$ = ST_PAST_LAST_ROW;
16665+
}
16666+
;
16667+
16668+
opt_row_pattern_initial_or_seek:
16669+
INITIAL { $$ = true; }
16670+
| SEEK
16671+
{
16672+
ereport(ERROR,
16673+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
16674+
errmsg("SEEK is not supported"),
16675+
errhint("Use INITIAL instead."),
16676+
parser_errposition(@1)));
16677+
}
16678+
| /*EMPTY*/ { $$ = true; }
16679+
;
16680+
16681+
row_pattern:
16682+
row_pattern_term { $$ = list_make1($1); }
16683+
| row_pattern row_pattern_term { $$ = lappend($1, $2); }
16684+
;
16685+
16686+
row_pattern_term:
16687+
ColId { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "", (Node *)makeString($1), NULL, @1); }
16688+
| ColId '*' { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "*", (Node *)makeString($1), NULL, @1); }
16689+
| ColId '+' { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "+", (Node *)makeString($1), NULL, @1); }
16690+
| ColId '?' { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "?", (Node *)makeString($1), NULL, @1); }
16691+
;
16692+
16693+
row_pattern_definition_list:
16694+
row_pattern_definition { $$ = list_make1($1); }
16695+
| row_pattern_definition_list ',' row_pattern_definition { $$ = lappend($1, $3); }
16696+
;
16697+
16698+
row_pattern_definition:
16699+
ColId AS a_expr
16700+
{
16701+
$$ = makeNode(ResTarget);
16702+
$$->name = $1;
16703+
$$->indirection = NIL;
16704+
$$->val = (Node *) $3;
16705+
$$->location = @1;
16706+
}
16707+
;
1662816708

1662916709
/*
1663016710
* Supporting nonterminals for expressions.
@@ -17838,6 +17918,7 @@ unreserved_keyword:
1783817918
| INDEXES
1783917919
| INHERIT
1784017920
| INHERITS
17921+
| INITIAL
1784117922
| INLINE_P
1784217923
| INPUT_P
1784317924
| INSENSITIVE
@@ -17911,7 +17992,9 @@ unreserved_keyword:
1791117992
| PARTITION
1791217993
| PASSING
1791317994
| PASSWORD
17995+
| PAST
1791417996
| PATH
17997+
| PATTERN_P
1791517998
| PERIOD
1791617999
| PLAN
1791718000
| PLANS
@@ -17964,6 +18047,7 @@ unreserved_keyword:
1796418047
| SEARCH
1796518048
| SECOND_P
1796618049
| SECURITY
18050+
| SEEK
1796718051
| SEQUENCE
1796818052
| SEQUENCES
1796918053
| SERIALIZABLE
@@ -18186,6 +18270,7 @@ reserved_keyword:
1818618270
| CURRENT_USER
1818718271
| DEFAULT
1818818272
| DEFERRABLE
18273+
| DEFINE
1818918274
| DESC
1819018275
| DISTINCT
1819118276
| DO
@@ -18349,6 +18434,7 @@ bare_label_keyword:
1834918434
| DEFAULTS
1835018435
| DEFERRABLE
1835118436
| DEFERRED
18437+
| DEFINE
1835218438
| DEFINER
1835318439
| DELETE_P
1835418440
| DELIMITER
@@ -18427,6 +18513,7 @@ bare_label_keyword:
1842718513
| INDEXES
1842818514
| INHERIT
1842918515
| INHERITS
18516+
| INITIAL
1843018517
| INITIALLY
1843118518
| INLINE_P
1843218519
| INNER_P
@@ -18538,7 +18625,9 @@ bare_label_keyword:
1853818625
| PARTITION
1853918626
| PASSING
1854018627
| PASSWORD
18628+
| PAST
1854118629
| PATH
18630+
| PATTERN_P
1854218631
| PERIOD
1854318632
| PLACING
1854418633
| PLAN
@@ -18597,6 +18686,7 @@ bare_label_keyword:
1859718686
| SCROLL
1859818687
| SEARCH
1859918688
| SECURITY
18689+
| SEEK
1860018690
| SELECT
1860118691
| SEQUENCE
1860218692
| SEQUENCES

src/include/nodes/parsenodes.h

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

569+
/*
570+
* AFTER MATCH row pattern skip to types in row pattern common syntax
571+
*/
572+
typedef enum RPSkipTo
573+
{
574+
ST_NONE, /* AFTER MATCH omitted */
575+
ST_NEXT_ROW, /* SKIP TO NEXT ROW */
576+
ST_PAST_LAST_ROW, /* SKIP TO PAST LAST ROW */
577+
} RPSkipTo;
578+
579+
/*
580+
* RowPatternCommonSyntax - raw representation of row pattern common syntax
581+
*
582+
*/
583+
typedef struct RPCommonSyntax
584+
{
585+
NodeTag type;
586+
RPSkipTo rpSkipTo; /* Row Pattern AFTER MATCH SKIP type */
587+
bool initial; /* true if <row pattern initial or seek> is
588+
* initial */
589+
List *rpPatterns; /* PATTERN variables (list of A_Expr) */
590+
List *rpDefs; /* row pattern definitions clause (list of
591+
* ResTarget) */
592+
} RPCommonSyntax;
593+
569594
/*
570595
* WindowDef - raw representation of WINDOW and OVER clauses
571596
*
@@ -581,6 +606,7 @@ typedef struct WindowDef
581606
char *refname; /* referenced window name, if any */
582607
List *partitionClause; /* PARTITION BY expression list */
583608
List *orderClause; /* ORDER BY (list of SortBy) */
609+
RPCommonSyntax *rpCommonSyntax; /* row pattern common syntax */
584610
int frameOptions; /* frame_clause options, see below */
585611
Node *startOffset; /* expression for starting bound, if any */
586612
Node *endOffset; /* expression for ending bound, if any */
@@ -1549,6 +1575,11 @@ typedef struct GroupingSet
15491575
* the orderClause might or might not be copied (see copiedOrder); the framing
15501576
* options are never copied, per spec.
15511577
*
1578+
* "defineClause" is Row Pattern Recognition DEFINE clause (list of
1579+
* TargetEntry). TargetEntry.resname represents row pattern definition
1580+
* variable name. "patternVariable" and "patternRegexp" represents PATTERN
1581+
* clause.
1582+
*
15521583
* The information relevant for the query jumbling is the partition clause
15531584
* type and its bounds.
15541585
*/
@@ -1578,6 +1609,22 @@ typedef struct WindowClause
15781609
Index winref; /* ID referenced by window functions */
15791610
/* did we copy orderClause from refname? */
15801611
bool copiedOrder pg_node_attr(query_jumble_ignore);
1612+
/* Row Pattern AFTER MACH SKIP clause */
1613+
RPSkipTo rpSkipTo; /* Row Pattern Skip To type */
1614+
bool initial; /* true if <row pattern initial or seek> is
1615+
* initial */
1616+
/* Row Pattern DEFINE clause (list of TargetEntry) */
1617+
List *defineClause;
1618+
/* Row Pattern DEFINE variable initial names (list of String) */
1619+
List *defineInitial;
1620+
/* Row Pattern PATTERN variable name (list of String) */
1621+
List *patternVariable;
1622+
1623+
/*
1624+
* Row Pattern PATTERN regular expression quantifier ('+' or ''. list of
1625+
* String)
1626+
*/
1627+
List *patternRegexp;
15811628
} WindowClause;
15821629

15831630
/*

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)