@@ -602,11 +602,31 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
602
602
%type <node> json_format_clause_opt
603
603
json_representation
604
604
json_value_expr
605
+ json_func_expr
605
606
json_output_clause_opt
607
+ json_value_constructor
608
+ json_object_constructor
609
+ json_object_constructor_args_opt
610
+ json_object_args
611
+ json_object_ctor_args_opt
612
+ json_object_func_args
613
+ json_array_constructor
614
+ json_name_and_value
615
+ json_aggregate_func
616
+ json_object_aggregate_constructor
617
+ json_array_aggregate_constructor
618
+
619
+ %type <list> json_name_and_value_list
620
+ json_value_expr_list
621
+ json_array_aggregate_order_by_clause_opt
606
622
607
623
%type <ival> json_encoding
608
624
json_encoding_clause_opt
609
625
626
+ %type <boolean> json_key_uniqueness_constraint_opt
627
+ json_object_constructor_null_clause_opt
628
+ json_array_constructor_null_clause_opt
629
+
610
630
/*
611
631
* Non-keyword token types. These are hard-wired into the "flex" lexer.
612
632
* They must be listed first so that their numeric codes do not depend on
@@ -632,7 +652,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
632
652
*/
633
653
634
654
/* ordinary key words in alphabetical order*/
635
- %token <keyword> ABORT_P ABSOLUTE_P ACCESS ACTION ADD_P ADMIN AFTER
655
+ %token <keyword> ABORT_P ABSENT ABSOLUTE_P ACCESS ACTION ADD_P ADMIN AFTER
636
656
AGGREGATE ALL ALSO ALTER ALWAYS ANALYSE ANALYZE AND ANY ARRAY AS ASC
637
657
ASSERTION ASSIGNMENT ASYMMETRIC AT ATTACH ATTRIBUTE AUTHORIZATION
638
658
@@ -669,9 +689,9 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
669
689
INNER_P INOUT INPUT_P INSENSITIVE INSERT INSTEAD INT_P INTEGER
670
690
INTERSECT INTERVAL INTO INVOKER IS ISNULL ISOLATION
671
691
672
- JOIN JSON
692
+ JOIN JSON JSON_ARRAY JSON_ARRAYAGG JSON_OBJECT JSON_OBJECTAGG
673
693
674
- KEY
694
+ KEY KEYS
675
695
676
696
LABEL LANGUAGE LARGE_P LAST_P LATERAL_P
677
697
LEADING LEAKPROOF LEAST LEFT LEVEL LIKE LIMIT LISTEN LOAD LOCAL
@@ -735,7 +755,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
735
755
* as NOT, at least with respect to their left-hand subexpression.
736
756
* NULLS_LA and WITH_LA are needed to make the grammar LALR(1).
737
757
*/
738
- %token NOT_LA NULLS_LA WITH_LA
758
+ %token NOT_LA NULLS_LA WITH_LA WITH_LA_UNIQUE WITHOUT_LA
739
759
740
760
/* Precedence: lowest to highest*/
741
761
%nonassoc SET /* see relation_expr_opt_alias*/
@@ -778,6 +798,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
778
798
* blame any funny behavior of UNBOUNDED on the SQL standard, though.
779
799
*/
780
800
%nonassoc UNBOUNDED /* ideally should have same precedence as IDENT*/
801
+ %nonassoc ABSENT
781
802
%nonassoc IDENT GENERATED NULL_P PARTITION RANGE ROWS GROUPS PRECEDING FOLLOWING CUBE ROLLUP
782
803
%left Op OPERATOR /* multi-character ops and user-defined operators*/
783
804
%left ' +' ' -'
@@ -802,6 +823,9 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
802
823
/* kluge to keep xml_whitespace_option from causing shift/reduce conflicts*/
803
824
%right PRESERVE STRIP_P
804
825
826
+ %nonassoc empty_json_unique
827
+ %left WITHOUT WITH_LA_UNIQUE
828
+
805
829
%%
806
830
807
831
/*
@@ -12834,7 +12858,7 @@ ConstInterval:
12834
12858
12835
12859
opt_timezone :
12836
12860
WITH_LA TIME ZONE {$$ =true ; }
12837
- | WITHOUT TIME ZONE {$$ =false ; }
12861
+ | WITHOUT_LA TIME ZONE {$$ =false ; }
12838
12862
| /* EMPTY*/ {$$ =false ; }
12839
12863
;
12840
12864
@@ -13443,6 +13467,17 @@ b_expr:c_expr
13443
13467
}
13444
13468
;
13445
13469
13470
+ json_key_uniqueness_constraint_opt :
13471
+ WITH_LA_UNIQUE UNIQUE opt_keys {$$ =true ; }
13472
+ | WITHOUT UNIQUE opt_keys {$$ =false ; }
13473
+ | /* EMPTY*/ %prec empty_json_unique {$$ =false ; }
13474
+ ;
13475
+
13476
+ opt_keys :
13477
+ KEYS { }
13478
+ | /* EMPTY*/ { }
13479
+ ;
13480
+
13446
13481
/*
13447
13482
* Productions that can be used in both a_expr and b_expr.
13448
13483
*
@@ -13703,6 +13738,13 @@ func_expr: func_application within_group_clause filter_clause over_clause
13703
13738
n->over =$4 ;
13704
13739
$$ = (Node *) n;
13705
13740
}
13741
+ | json_aggregate_func filter_clause over_clause
13742
+ {
13743
+ JsonAggCtor *n = (JsonAggCtor *)$1 ;
13744
+ n->agg_filter =$2 ;
13745
+ n->over =$3 ;
13746
+ $$ = (Node *)$1 ;
13747
+ }
13706
13748
| func_expr_common_subexpr
13707
13749
{$$ =$1 ; }
13708
13750
;
@@ -13716,6 +13758,7 @@ func_expr: func_application within_group_clause filter_clause over_clause
13716
13758
func_expr_windowless :
13717
13759
func_application {$$ =$1 ; }
13718
13760
| func_expr_common_subexpr {$$ =$1 ; }
13761
+ | json_aggregate_func {$$ =$1 ; }
13719
13762
;
13720
13763
13721
13764
/*
@@ -13940,6 +13983,8 @@ func_expr_common_subexpr:
13940
13983
n->location =@1 ;
13941
13984
$$ = (Node *)n;
13942
13985
}
13986
+ | json_func_expr
13987
+ {$$ =$1 ; }
13943
13988
;
13944
13989
13945
13990
/*
@@ -14644,6 +14689,9 @@ opt_asymmetric: ASYMMETRIC
14644
14689
;
14645
14690
14646
14691
/* SQL/JSON support*/
14692
+ json_func_expr:
14693
+ json_value_constructor
14694
+ ;
14647
14695
14648
14696
json_value_expr:
14649
14697
a_expr json_format_clause_opt
@@ -14690,6 +14738,188 @@ json_output_clause_opt:
14690
14738
$$ = (Node *) n;
14691
14739
}
14692
14740
|/* EMPTY*/ { $$ =NULL ; }
14741
+ ;
14742
+
14743
+ json_value_constructor:
14744
+ json_object_constructor
14745
+ | json_array_constructor
14746
+ ;
14747
+
14748
+ json_object_constructor:
14749
+ JSON_OBJECT' (' json_object_args' )'
14750
+ {
14751
+ $$ = $3 ;
14752
+ }
14753
+ ;
14754
+
14755
+ json_object_args:
14756
+ json_object_ctor_args_opt
14757
+ | json_object_func_args
14758
+ ;
14759
+
14760
+ json_object_func_args:
14761
+ func_arg_list
14762
+ {
14763
+ List *func =list_make1 (makeString (" json_object" ));
14764
+ $$ = (Node *)makeFuncCall (func, $1 , @1 );
14765
+ }
14766
+ ;
14767
+
14768
+ json_object_ctor_args_opt:
14769
+ json_object_constructor_args_opt json_output_clause_opt
14770
+ {
14771
+ JsonObjectCtor *n = (JsonObjectCtor *) $1 ;
14772
+ n->output = (JsonOutput *) $2 ;
14773
+ n->location = @1 ;
14774
+ $$ = (Node *) n;
14775
+ }
14776
+ ;
14777
+
14778
+ json_object_constructor_args_opt:
14779
+ json_name_and_value_list
14780
+ json_object_constructor_null_clause_opt
14781
+ json_key_uniqueness_constraint_opt
14782
+ {
14783
+ JsonObjectCtor *n =makeNode (JsonObjectCtor);
14784
+ n->exprs = $1 ;
14785
+ n->absent_on_null = $2 ;
14786
+ n->unique = $3 ;
14787
+ $$ = (Node *) n;
14788
+ }
14789
+ |/* EMPTY*/
14790
+ {
14791
+ JsonObjectCtor *n =makeNode (JsonObjectCtor);
14792
+ n->exprs =NULL ;
14793
+ n->absent_on_null =false ;
14794
+ n->unique =false ;
14795
+ $$ = (Node *) n;
14796
+ }
14797
+ ;
14798
+
14799
+ json_name_and_value_list:
14800
+ json_name_and_value
14801
+ { $$ =list_make1 ($1 ); }
14802
+ | json_name_and_value_list' ,' json_name_and_value
14803
+ { $$ =lappend ($1 , $3 ); }
14804
+ ;
14805
+
14806
+ json_name_and_value:
14807
+ /* TODO This is not supported due to conflicts
14808
+ KEY c_expr VALUE_P json_value_expr %prec POSTFIXOP
14809
+ { $$ = makeJsonKeyValue($2, $4); }
14810
+ |
14811
+ */
14812
+ c_expr VALUE_P json_value_expr
14813
+ { $$ =makeJsonKeyValue ($1 , $3 ); }
14814
+ |
14815
+ a_expr' :' json_value_expr
14816
+ { $$ =makeJsonKeyValue ($1 , $3 ); }
14817
+ ;
14818
+
14819
+ json_object_constructor_null_clause_opt:
14820
+ NULL_P ON NULL_P{ $$ =false ; }
14821
+ | ABSENT ON NULL_P{ $$ =true ; }
14822
+ |/* EMPTY*/ { $$ =false ; }
14823
+ ;
14824
+
14825
+ json_array_constructor:
14826
+ JSON_ARRAY' ('
14827
+ json_value_expr_list
14828
+ json_array_constructor_null_clause_opt
14829
+ json_output_clause_opt
14830
+ ' )'
14831
+ {
14832
+ JsonArrayCtor *n =makeNode (JsonArrayCtor);
14833
+ n->exprs = $3 ;
14834
+ n->absent_on_null = $4 ;
14835
+ n->output = (JsonOutput *) $5 ;
14836
+ n->location = @1 ;
14837
+ $$ = (Node *) n;
14838
+ }
14839
+ | JSON_ARRAY' ('
14840
+ select_no_parens
14841
+ /* json_format_clause_opt*/
14842
+ /* json_array_constructor_null_clause_opt*/
14843
+ json_output_clause_opt
14844
+ ' )'
14845
+ {
14846
+ JsonArrayQueryCtor *n =makeNode (JsonArrayQueryCtor);
14847
+ n->query = $3 ;
14848
+ /* n->format = $4;*/
14849
+ n->absent_on_null =true /* $5*/ ;
14850
+ n->output = (JsonOutput *) $4 ;
14851
+ n->location = @1 ;
14852
+ $$ = (Node *) n;
14853
+ }
14854
+ | JSON_ARRAY' ('
14855
+ json_output_clause_opt
14856
+ ' )'
14857
+ {
14858
+ JsonArrayCtor *n =makeNode (JsonArrayCtor);
14859
+ n->exprs = NIL;
14860
+ n->absent_on_null =true ;
14861
+ n->output = (JsonOutput *) $3 ;
14862
+ n->location = @1 ;
14863
+ $$ = (Node *) n;
14864
+ }
14865
+ ;
14866
+
14867
+ json_value_expr_list:
14868
+ json_value_expr{ $$ =list_make1 ($1 ); }
14869
+ | json_value_expr_list' ,' json_value_expr{ $$ =lappend ($1 , $3 );}
14870
+ ;
14871
+
14872
+ json_array_constructor_null_clause_opt:
14873
+ NULL_P ON NULL_P{ $$ =false ; }
14874
+ | ABSENT ON NULL_P{ $$ =true ; }
14875
+ |/* EMPTY*/ { $$ =true ; }
14876
+ ;
14877
+
14878
+ json_aggregate_func:
14879
+ json_object_aggregate_constructor
14880
+ | json_array_aggregate_constructor
14881
+ ;
14882
+
14883
+ json_object_aggregate_constructor:
14884
+ JSON_OBJECTAGG' ('
14885
+ json_name_and_value
14886
+ json_object_constructor_null_clause_opt
14887
+ json_key_uniqueness_constraint_opt
14888
+ json_output_clause_opt
14889
+ ' )'
14890
+ {
14891
+ JsonObjectAgg *n =makeNode (JsonObjectAgg);
14892
+ n->arg = (JsonKeyValue *) $3 ;
14893
+ n->absent_on_null = $4 ;
14894
+ n->unique = $5 ;
14895
+ n->ctor .output = (JsonOutput *) $6 ;
14896
+ n->ctor .agg_order =NULL ;
14897
+ n->ctor .location = @1 ;
14898
+ $$ = (Node *) n;
14899
+ }
14900
+ ;
14901
+
14902
+ json_array_aggregate_constructor:
14903
+ JSON_ARRAYAGG' ('
14904
+ json_value_expr
14905
+ json_array_aggregate_order_by_clause_opt
14906
+ json_array_constructor_null_clause_opt
14907
+ json_output_clause_opt
14908
+ ' )'
14909
+ {
14910
+ JsonArrayAgg *n =makeNode (JsonArrayAgg);
14911
+ n->arg = (JsonValueExpr *) $3 ;
14912
+ n->ctor .agg_order = $4 ;
14913
+ n->absent_on_null = $5 ;
14914
+ n->ctor .output = (JsonOutput *) $6 ;
14915
+ n->ctor .location = @1 ;
14916
+ $$ = (Node *) n;
14917
+ }
14918
+ ;
14919
+
14920
+ json_array_aggregate_order_by_clause_opt:
14921
+ ORDER BY sortby_list{ $$ = $3 ; }
14922
+ |/* EMPTY*/ { $$ = NIL; }
14693
14923
;
14694
14924
14695
14925
/* ****************************************************************************
@@ -15079,6 +15309,7 @@ ColLabel:IDENT{ $$ = $1; }
15079
15309
*/
15080
15310
unreserved_keyword:
15081
15311
ABORT_P
15312
+ | ABSENT
15082
15313
| ABSOLUTE_P
15083
15314
| ACCESS
15084
15315
| ACTION
@@ -15203,6 +15434,7 @@ unreserved_keyword:
15203
15434
| ISOLATION
15204
15435
| JSON
15205
15436
| KEY
15437
+ | KEYS
15206
15438
| LABEL
15207
15439
| LANGUAGE
15208
15440
| LARGE_P
@@ -15410,6 +15642,10 @@ col_name_keyword:
15410
15642
| INT_P
15411
15643
| INTEGER
15412
15644
| INTERVAL
15645
+ | JSON_ARRAY
15646
+ | JSON_ARRAYAGG
15647
+ | JSON_OBJECT
15648
+ | JSON_OBJECTAGG
15413
15649
| LEAST
15414
15650
| NATIONAL
15415
15651
| NCHAR