@@ -672,6 +672,13 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
672
672
json_object_constructor_null_clause_opt
673
673
json_array_constructor_null_clause_opt
674
674
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
675
682
676
683
/*
677
684
* 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);
715
722
CURRENT_TIME CURRENT_TIMESTAMP CURRENT_USER CURSOR CYCLE
716
723
717
724
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
719
726
DETACH DICTIONARY DISABLE_P DISCARD DISTINCT DO DOCUMENT_P DOMAIN_P
720
727
DOUBLE_P DROP
721
728
@@ -731,7 +738,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
731
738
HANDLER HAVING HEADER_P HOLD HOUR_P
732
739
733
740
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
735
742
INNER_P INOUT INPUT_P INSENSITIVE INSERT INSTEAD INT_P INTEGER
736
743
INTERSECT INTERVAL INTO INVOKER IS ISNULL ISOLATION
737
744
@@ -756,8 +763,8 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
756
763
ORDER ORDINALITY OTHERS OUT_P OUTER_P
757
764
OVER OVERLAPS OVERLAY OVERRIDING OWNED OWNER
758
765
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
761
768
POSITION PRECEDING PRECISION PRESERVE PREPARE PREPARED PRIMARY
762
769
PRIOR PRIVILEGES PROCEDURAL PROCEDURE PROCEDURES PROGRAM PUBLICATION
763
770
@@ -768,7 +775,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
768
775
RESET RESTART RESTRICT RETURN RETURNING RETURNS REVOKE RIGHT ROLE ROLLBACK ROLLUP
769
776
ROUTINE ROUTINES ROW ROWS RULE
770
777
771
- SAVEPOINT SCALAR SCHEMA SCHEMAS SCROLL SEARCH SECOND_P SECURITY SELECT
778
+ SAVEPOINT SCALAR SCHEMA SCHEMAS SCROLL SEARCH SECOND_P SECURITY SEEK SELECT
772
779
SEQUENCE SEQUENCES
773
780
SERIALIZABLE SERVER SESSION SESSION_USER SET SETS SETOF SHARE SHOW
774
781
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);
851
858
* reference point for a precedence level that we can assign to other
852
859
* keywords that lack a natural precedence level.
853
860
*
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).
856
863
*
857
864
* The frame_bound productions UNBOUNDED PRECEDING and UNBOUNDED FOLLOWING
858
865
* are even messier: since UNBOUNDED is an unreserved keyword (per spec!),
@@ -882,6 +889,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
882
889
%nonassoc UNBOUNDED NESTED /* ideally would have same precedence as IDENT */
883
890
%nonassoc IDENT PARTITION RANGE ROWS GROUPS PRECEDING FOLLOWING CUBE ROLLUP
884
891
SET KEYS OBJECT_P SCALAR VALUE_P WITH WITHOUT PATH
892
+ AFTER INITIAL SEEK PATTERN_P
885
893
%left Op OPERATOR /* multi-character ops and user-defined operators */
886
894
%left ' +' ' -'
887
895
%left ' *' ' /' ' %'
@@ -16431,7 +16439,8 @@ over_clause: OVER window_specification
16431
16439
;
16432
16440
16433
16441
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 ' )'
16435
16444
{
16436
16445
WindowDef *n = makeNode(WindowDef);
16437
16446
@@ -16443,20 +16452,21 @@ window_specification: '(' opt_existing_window_name opt_partition_clause
16443
16452
n->frameOptions = $5 ->frameOptions;
16444
16453
n->startOffset = $5 ->startOffset;
16445
16454
n->endOffset = $5 ->endOffset;
16455
+ n->rpCommonSyntax = (RPCommonSyntax *)$6 ;
16446
16456
n->location = @1 ;
16447
16457
$$ = n;
16448
16458
}
16449
16459
;
16450
16460
16451
16461
/*
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.
16460
16470
*/
16461
16471
opt_existing_window_name : ColId { $$ = $1 ; }
16462
16472
| /* EMPTY*/ %prec Op { $$ = NULL ; }
@@ -16625,6 +16635,76 @@ opt_window_exclusion_clause:
16625
16635
| /* EMPTY*/ { $$ = 0 ; }
16626
16636
;
16627
16637
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
+ ;
16628
16708
16629
16709
/*
16630
16710
* Supporting nonterminals for expressions.
@@ -17838,6 +17918,7 @@ unreserved_keyword:
17838
17918
| INDEXES
17839
17919
| INHERIT
17840
17920
| INHERITS
17921
+ | INITIAL
17841
17922
| INLINE_P
17842
17923
| INPUT_P
17843
17924
| INSENSITIVE
@@ -17911,7 +17992,9 @@ unreserved_keyword:
17911
17992
| PARTITION
17912
17993
| PASSING
17913
17994
| PASSWORD
17995
+ | PAST
17914
17996
| PATH
17997
+ | PATTERN_P
17915
17998
| PERIOD
17916
17999
| PLAN
17917
18000
| PLANS
@@ -17964,6 +18047,7 @@ unreserved_keyword:
17964
18047
| SEARCH
17965
18048
| SECOND_P
17966
18049
| SECURITY
18050
+ | SEEK
17967
18051
| SEQUENCE
17968
18052
| SEQUENCES
17969
18053
| SERIALIZABLE
@@ -18186,6 +18270,7 @@ reserved_keyword:
18186
18270
| CURRENT_USER
18187
18271
| DEFAULT
18188
18272
| DEFERRABLE
18273
+ | DEFINE
18189
18274
| DESC
18190
18275
| DISTINCT
18191
18276
| DO
@@ -18349,6 +18434,7 @@ bare_label_keyword:
18349
18434
| DEFAULTS
18350
18435
| DEFERRABLE
18351
18436
| DEFERRED
18437
+ | DEFINE
18352
18438
| DEFINER
18353
18439
| DELETE_P
18354
18440
| DELIMITER
@@ -18427,6 +18513,7 @@ bare_label_keyword:
18427
18513
| INDEXES
18428
18514
| INHERIT
18429
18515
| INHERITS
18516
+ | INITIAL
18430
18517
| INITIALLY
18431
18518
| INLINE_P
18432
18519
| INNER_P
@@ -18538,7 +18625,9 @@ bare_label_keyword:
18538
18625
| PARTITION
18539
18626
| PASSING
18540
18627
| PASSWORD
18628
+ | PAST
18541
18629
| PATH
18630
+ | PATTERN_P
18542
18631
| PERIOD
18543
18632
| PLACING
18544
18633
| PLAN
@@ -18597,6 +18686,7 @@ bare_label_keyword:
18597
18686
| SCROLL
18598
18687
| SEARCH
18599
18688
| SECURITY
18689
+ | SEEK
18600
18690
| SELECT
18601
18691
| SEQUENCE
18602
18692
| SEQUENCES
0 commit comments