1
1
%{
2
2
/*
3
- * Copyright (C) 2023 PostGraphDB
3
+ * Copyright (C) 2023-2024 PostGraphDB
4
4
*
5
5
* This program is free software: you can redistribute it and/or modify
6
6
* it under the terms of the GNU Affero General Public License as
15
15
* You should have received a copy of the GNU Affero General Public License
16
16
* along with this program. If not, see <https://www.gnu.org/licenses/>.
17
17
*
18
- * For PostgreSQL Database Management System:
19
- * (formerly known as Postgres, then as Postgres95)
20
- *
21
18
* Portions Copyright (c) 2020-2023, Apache Software Foundation
22
19
* Portions Copyright (c) 2019-2020, Bitnine Global
23
20
*/
33
30
#include " nodes/value.h"
34
31
#include " parser/parser.h"
35
32
33
+
36
34
#include " nodes/ag_nodes.h"
37
35
#include " nodes/cypher_nodes.h"
38
36
#include " parser/ag_scanner.h"
75
73
struct DefElem *defelt;
76
74
struct RangeVar *range;
77
75
struct TypeName *typnam;
76
+ struct PartitionElem *partelem;
77
+ struct PartitionSpec *partspec;
78
+ struct PartitionBoundSpec *partboundspec;
79
+ struct Value *value;
78
80
}
79
81
80
82
%token <integer> INTEGER
91
93
/* keywords in alphabetical order */
92
94
%token <keyword> ALL AND ANY AS ASC ASCENDING
93
95
BETWEEN BY
94
- CALL CASE CASCADE COALESCE CONTAINS CREATE CUBE CURRENT CURRENT_DATE CURRENT_TIME CURRENT_TIMESTAMP
96
+ CALL CASE CASCADE COALESCE COLLATE CONTAINS CREATE CUBE CURRENT CURRENT_DATE CURRENT_TIME CURRENT_TIMESTAMP
95
97
DATE DECADE DELETE DESC DESCENDING DETACH DISTINCT DROP
96
98
ELSE END_P ENDS EXCEPT EXCLUDE EXISTS EXTENSION EXTRACT
97
99
GLOBAL GRAPH GROUP GROUPS GROUPING
181
183
%type <string> all_op
182
184
/* names */
183
185
%type <string> property_key_name var_name var_name_opt label_name
184
- %type <string> symbolic_name schema_name temporal_cast attr_name
186
+ %type <string> symbolic_name schema_name temporal_cast attr_name table_access_method_clause
185
187
%type <keyword> reserved_keyword safe_keywords conflicted_keywords
186
188
%type <list> func_name
187
189
TableElementList OptTableElementList OptInherit
190
+ reloptions
191
+ OptWith
188
192
qualified_name_list
189
-
193
+ reloption_list
194
+ opt_collate
195
+ any_name attrs opt_class
196
+ %type <defelt> def_elem reloption_elem
190
197
%type <string> Sconst
191
198
%type <string> ColId ColLabel
192
199
%type <string> NonReservedWord_or_Sconst name
195
202
196
203
%type <integer> OptTemp
197
204
198
- %type <typnam> Typename SimpleTypename GenericType
205
+ %type <typnam> Typename SimpleTypename GenericType func_type
199
206
200
207
%type <range> qualified_name
201
208
205
212
/* set operations*/
206
213
%type <boolean> all_or_distinct
207
214
215
+ %type <integer> SignedIconst
216
+ %type <node> def_arg
217
+ %type <partspec> PartitionSpec OptPartitionSpec
218
+ %type <partelem> part_elem
219
+ %type <list> part_params
220
+ %type <value> NumericOnly
221
+
208
222
/* precedence: lowest to highest */
209
223
%left UNION INTERSECT EXCEPT
210
224
%left OR
@@ -255,7 +269,8 @@ static Node *make_set_op(SetOperation op, bool all_or_distinct, List *larg, List
255
269
256
270
// comparison
257
271
static bool is_A_Expr_a_comparison_operation (A_Expr *a);
258
-
272
+ static void
273
+ doNegateFloat (Value *v);
259
274
%}
260
275
%%
261
276
@@ -1018,8 +1033,8 @@ create:
1018
1033
$$ = (Node *) n;
1019
1034
}
1020
1035
| CREATE OptTemp TABLE qualified_name ' (' OptTableElementList ' )'
1021
- OptInherit /* OptPartitionSpec table_access_method_clause OptWith
1022
- OnCommitOption OptTableSpace*/
1036
+ OptInherit OptPartitionSpec table_access_method_clause OptWith
1037
+ // OnCommitOption OptTableSpace
1023
1038
{
1024
1039
CreateStmt *n = makeNode(CreateStmt);
1025
1040
/*
@@ -1040,11 +1055,11 @@ create:
1040
1055
n->relation = $4 ;
1041
1056
n->tableElts = $6 ;
1042
1057
n->inhRelations = $8 ;
1043
- n->partspec = NULL ;
1058
+ n->partspec = $9 ;
1044
1059
n->ofTypename = NULL ;
1045
1060
n->constraints = NIL;
1046
- n->accessMethod = NULL ;
1047
- n->options = NULL ;
1061
+ n->accessMethod = $10 ;
1062
+ n->options = $11 ;
1048
1063
n->oncommit = ONCOMMIT_NOOP;
1049
1064
n->tablespacename = NULL ;
1050
1065
n->if_not_exists = false ;
@@ -1054,9 +1069,182 @@ create:
1054
1069
;
1055
1070
1056
1071
1072
+ /* WITHOUT OIDS is legacy only */
1073
+ OptWith :
1074
+ WITH reloptions { $$ = $2 ; }
1075
+ /* | WITHOUT OIDS { $$ = NIL; }*/
1076
+ | /* EMPTY*/ { $$ = NIL; }
1077
+ ;
1078
+ reloptions :
1079
+ ' (' reloption_list ' )' { $$ = $2 ; }
1080
+ ;
1081
+ reloption_list :
1082
+ reloption_elem { $$ = list_make1($1 ); }
1083
+ | reloption_list ' ,' reloption_elem { $$ = lappend($1 , $3 ); }
1084
+ ;
1085
+
1086
+ /* This should match def_elem and also allow qualified names */
1087
+ reloption_elem :
1088
+ ColLabel ' =' def_arg
1089
+ {
1090
+ $$ = makeDefElem($1 , (Node *) $3 , @1 );
1091
+ }
1092
+ | ColLabel
1093
+ {
1094
+ $$ = makeDefElem($1 , NULL , @1 );
1095
+ }
1096
+ | ColLabel ' .' ColLabel ' =' def_arg
1097
+ {
1098
+ $$ = makeDefElemExtended($1 , $3 , (Node *) $5 ,
1099
+ DEFELEM_UNSPEC, @1 );
1100
+ }
1101
+ | ColLabel ' .' ColLabel
1102
+ {
1103
+ $$ = makeDefElemExtended($1 , $3 , NULL , DEFELEM_UNSPEC, @1 );
1104
+ }
1105
+ ;
1106
+
1107
+ NumericOnly :
1108
+ DECIMAL { $$ = makeFloat($1 ); }
1109
+ | ' +' DECIMAL { $$ = makeFloat($2 ); }
1110
+ | ' -' DECIMAL
1111
+ {
1112
+ $$ = makeFloat($2 );
1113
+ doNegateFloat ($$);
1114
+ }
1115
+ | SignedIconst { $$ = makeInteger($1 ); }
1116
+ ;
1117
+ SignedIconst : Iconst { $$ = $1 ; }
1118
+ | ' +' Iconst { $$ = + $2 ; }
1119
+ | ' -' Iconst { $$ = - $2 ; }
1120
+ ;
1121
+ Iconst : INTEGER { $$ = $1 ; };
1122
+ /* Note: any simple identifier will be returned as a type name! */
1123
+ def_arg : func_type { $$ = (Node *)$1 ; }
1124
+ //| reserved_keyword { $$ = (Node *)makeString(pstrdup($1 )); }
1125
+ //| qual_all_Op { $$ = (Node *)$1 ; }
1126
+ | NumericOnly { $$ = (Node *)$1 ; }
1127
+ | Sconst { $$ = (Node *)makeString($1 ); }
1128
+ //| NONE { $$ = (Node *)makeString(pstrdup($1 )); }
1129
+ ;
1130
+
1057
1131
OptInherit : INHERITS ' (' qualified_name_list ' )' { $$ = $3 ; }
1058
1132
| /* EMPTY*/ { $$ = NIL; }
1059
1133
;
1134
+
1135
+
1136
+ /* Optional partition key specification */
1137
+ OptPartitionSpec : PartitionSpec { $$ = $1 ; }
1138
+ | /* EMPTY*/ { $$ = NULL ; }
1139
+ ;
1140
+
1141
+ PartitionSpec : PARTITION BY ColId ' (' part_params ' )'
1142
+ {
1143
+ PartitionSpec *n = makeNode(PartitionSpec);
1144
+
1145
+ n->strategy = $3 ;
1146
+ n->partParams = $5 ;
1147
+ n->location = @1 ;
1148
+
1149
+ $$ = n;
1150
+ }
1151
+ ;
1152
+
1153
+ part_params : part_elem { $$ = list_make1($1 ); }
1154
+ | part_params ' ,' part_elem { $$ = lappend($1 , $3 ); }
1155
+ ;
1156
+
1157
+ opt_class : any_name { $$ = $1 ; }
1158
+ | /* EMPTY*/ { $$ = NIL; }
1159
+ ;
1160
+
1161
+ part_elem : ColId opt_collate opt_class
1162
+ {
1163
+ PartitionElem *n = makeNode(PartitionElem);
1164
+
1165
+ n->name = $1 ;
1166
+ n->expr = NULL ;
1167
+ n->collation = $2 ;
1168
+ n->opclass = $3 ;
1169
+ n->location = @1 ;
1170
+
1171
+ $$ = n;
1172
+ }
1173
+ /* | func_expr_windowless opt_collate opt_class
1174
+ {
1175
+ PartitionElem *n = makeNode(PartitionElem);
1176
+
1177
+ n->name = NULL;
1178
+ n->expr = $1;
1179
+ n->collation = $2;
1180
+ n->opclass = $3;
1181
+ n->location = @1;
1182
+ $$ = n;
1183
+ }
1184
+ | '(' a_expr ')' opt_collate opt_class
1185
+ {
1186
+ PartitionElem *n = makeNode(PartitionElem);
1187
+
1188
+ n->name = NULL;
1189
+ n->expr = $2;
1190
+ n->collation = $4;
1191
+ n->opclass = $5;
1192
+ n->location = @1;
1193
+ $$ = n;
1194
+ }*/
1195
+ ;
1196
+
1197
+
1198
+ /*
1199
+ * We would like to make the %TYPE productions here be ColId attrs etc,
1200
+ * but that causes reduce/reduce conflicts. type_function_name
1201
+ * is next best choice.
1202
+ */
1203
+ func_type : Typename { $$ = $1 ; }
1204
+ /* | type_function_name attrs '%' TYPE_P
1205
+ {
1206
+ $$ = makeTypeNameFromNameList(lcons(makeString($1), $2));
1207
+ $$->pct_type = true;
1208
+ $$->location = @1;
1209
+ }
1210
+ | SETOF type_function_name attrs '%' TYPE_P
1211
+ {
1212
+ $$ = makeTypeNameFromNameList(lcons(makeString($2), $3));
1213
+ $$->pct_type = true;
1214
+ $$->setof = true;
1215
+ $$->location = @2;
1216
+ }*/
1217
+ ;
1218
+
1219
+ def_elem : ColLabel ' =' def_arg
1220
+ {
1221
+ $$ = makeDefElem($1 , (Node *) $3 , @1 );
1222
+ }
1223
+ | ColLabel
1224
+ {
1225
+ $$ = makeDefElem($1 , NULL , @1 );
1226
+ }
1227
+ ;
1228
+
1229
+ table_access_method_clause :
1230
+ USING name { $$ = $2 ; }
1231
+ | /* EMPTY*/ { $$ = NULL ; }
1232
+ ;
1233
+
1234
+ any_name : ColId { $$ = list_make1(makeString($1 )); }
1235
+ | ColId attrs { $$ = lcons(makeString($1 ), $2 ); }
1236
+ ;
1237
+
1238
+ opt_collate : COLLATE any_name { $$ = $2 ; }
1239
+ | /* EMPTY*/ { $$ = NIL; }
1240
+ ;
1241
+
1242
+
1243
+ attrs : ' .' attr_name
1244
+ { $$ = list_make1(makeString($2 )); }
1245
+ | attrs ' .' attr_name
1246
+ { $$ = lappend($1 , makeString($3 )); }
1247
+ ;
1060
1248
1061
1249
/*
1062
1250
* Redundancy here is needed to avoid shift/reduce conflicts,
@@ -2799,7 +2987,7 @@ conflicted_keywords:
2799
2987
| FALSE_P { $$ = pnstrdup ($1 , 7 ); }
2800
2988
| NULL_P { $$ = pnstrdup ($1 , 6 ); }
2801
2989
| TRUE_P { $$ = pnstrdup ($1 , 6 ); }
2802
- | WITH { $$ = pnstrdup ($1 , 4 ); }
2990
+ // | WITH { $$ = pnstrdup($1, 4); }
2803
2991
;
2804
2992
2805
2993
%%
@@ -3037,3 +3225,16 @@ static Node *make_set_op(SetOperation op, bool all_or_distinct, List *larg, List
3037
3225
return (Node *) n;
3038
3226
}
3039
3227
3228
+ static void
3229
+ doNegateFloat(Value *v)
3230
+ {
3231
+ char *oldval = v->val.str;
3232
+
3233
+ Assert(IsA(v, Float));
3234
+ if (*oldval == '+')
3235
+ oldval++;
3236
+ if (*oldval == '-')
3237
+ v->val.str = oldval+1; /* just strip the '-' */
3238
+ else
3239
+ v->val.str = psprintf("-%s", oldval);
3240
+ }
0 commit comments