Branch data Line data Source code
1 : : %{
2 : :
3 : : /*#define YYDEBUG 1*/
4 : : /*-------------------------------------------------------------------------
5 : : *
6 : : * gram.y
7 : : * POSTGRESQL BISON rules/actions
8 : : *
9 : : * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
10 : : * Portions Copyright (c) 1994, Regents of the University of California
11 : : *
12 : : *
13 : : * IDENTIFICATION
14 : : * src/backend/parser/gram.y
15 : : *
16 : : * HISTORY
17 : : * AUTHOR DATE MAJOR EVENT
18 : : * Andrew Yu Sept, 1994 POSTQUEL to SQL conversion
19 : : * Andrew Yu Oct, 1994 lispy code conversion
20 : : *
21 : : * NOTES
22 : : * CAPITALS are used to represent terminal symbols.
23 : : * non-capitals are used to represent non-terminals.
24 : : *
25 : : * In general, nothing in this file should initiate database accesses
26 : : * nor depend on changeable state (such as SET variables). If you do
27 : : * database accesses, your code will fail when we have aborted the
28 : : * current transaction and are just parsing commands to find the next
29 : : * ROLLBACK or COMMIT. If you make use of SET variables, then you
30 : : * will do the wrong thing in multi-query strings like this:
31 : : * SET constraint_exclusion TO off; SELECT * FROM foo;
32 : : * because the entire string is parsed by gram.y before the SET gets
33 : : * executed. Anything that depends on the database or changeable state
34 : : * should be handled during parse analysis so that it happens at the
35 : : * right time not the wrong time.
36 : : *
37 : : * WARNINGS
38 : : * If you use a list, make sure the datum is a node so that the printing
39 : : * routines work.
40 : : *
41 : : * Sometimes we assign constants to makeStrings. Make sure we don't free
42 : : * those.
43 : : *
44 : : *-------------------------------------------------------------------------
45 : : */
46 : : #include "postgres.h"
47 : :
48 : : #include <ctype.h>
49 : : #include <limits.h>
50 : :
51 : : #include "catalog/index.h"
52 : : #include "catalog/namespace.h"
53 : : #include "catalog/pg_am.h"
54 : : #include "catalog/pg_trigger.h"
55 : : #include "commands/defrem.h"
56 : : #include "commands/trigger.h"
57 : : #include "gramparse.h"
58 : : #include "nodes/makefuncs.h"
59 : : #include "nodes/nodeFuncs.h"
60 : : #include "parser/parser.h"
61 : : #include "utils/datetime.h"
62 : : #include "utils/xml.h"
63 : :
64 : :
65 : : /*
66 : : * Location tracking support. Unlike bison's default, we only want
67 : : * to track the start position not the end position of each nonterminal.
68 : : * Nonterminals that reduce to empty receive position "-1". Since a
69 : : * production's leading RHS nonterminal(s) may have reduced to empty,
70 : : * we have to scan to find the first one that's not -1.
71 : : */
72 : : #define YYLLOC_DEFAULT(Current, Rhs, N) \
73 : : do { \
74 : : (Current) = (-1); \
75 : : for (int _i = 1; _i <= (N); _i++) \
76 : : { \
77 : : if ((Rhs)[_i] >= 0) \
78 : : { \
79 : : (Current) = (Rhs)[_i]; \
80 : : break; \
81 : : } \
82 : : } \
83 : : } while (0)
84 : :
85 : : /*
86 : : * Bison doesn't allocate anything that needs to live across parser calls,
87 : : * so we can easily have it use palloc instead of malloc. This prevents
88 : : * memory leaks if we error out during parsing.
89 : : */
90 : : #define YYMALLOC palloc
91 : : #define YYFREE pfree
92 : :
93 : : /* Private struct for the result of privilege_target production */
94 : : typedef struct PrivTarget
95 : : {
96 : : GrantTargetType targtype;
97 : : ObjectType objtype;
98 : : List *objs;
99 : : } PrivTarget;
100 : :
101 : : /* Private struct for the result of import_qualification production */
102 : : typedef struct ImportQual
103 : : {
104 : : ImportForeignSchemaType type;
105 : : List *table_names;
106 : : } ImportQual;
107 : :
108 : : /* Private struct for the result of select_limit & limit_clause productions */
109 : : typedef struct SelectLimit
110 : : {
111 : : Node *limitOffset;
112 : : Node *limitCount;
113 : : LimitOption limitOption; /* indicates presence of WITH TIES */
114 : : ParseLoc offsetLoc; /* location of OFFSET token, if present */
115 : : ParseLoc countLoc; /* location of LIMIT/FETCH token, if present */
116 : : ParseLoc optionLoc; /* location of WITH TIES, if present */
117 : : } SelectLimit;
118 : :
119 : : /* Private struct for the result of group_clause production */
120 : : typedef struct GroupClause
121 : : {
122 : : bool distinct;
123 : : bool all;
124 : : List *list;
125 : : } GroupClause;
126 : :
127 : : /* Private structs for the result of key_actions and key_action productions */
128 : : typedef struct KeyAction
129 : : {
130 : : char action;
131 : : List *cols;
132 : : } KeyAction;
133 : :
134 : : typedef struct KeyActions
135 : : {
136 : : KeyAction *updateAction;
137 : : KeyAction *deleteAction;
138 : : } KeyActions;
139 : :
140 : : /* ConstraintAttributeSpec yields an integer bitmask of these flags: */
141 : : #define CAS_NOT_DEFERRABLE 0x01
142 : : #define CAS_DEFERRABLE 0x02
143 : : #define CAS_INITIALLY_IMMEDIATE 0x04
144 : : #define CAS_INITIALLY_DEFERRED 0x08
145 : : #define CAS_NOT_VALID 0x10
146 : : #define CAS_NO_INHERIT 0x20
147 : : #define CAS_NOT_ENFORCED 0x40
148 : : #define CAS_ENFORCED 0x80
149 : :
150 : :
151 : : #define parser_yyerror(msg) scanner_yyerror(msg, yyscanner)
152 : : #define parser_errposition(pos) scanner_errposition(pos, yyscanner)
153 : :
154 : : static void base_yyerror(YYLTYPE *yylloc, core_yyscan_t yyscanner,
155 : : const char *msg);
156 : : static RawStmt *makeRawStmt(Node *stmt, int stmt_location);
157 : : static void updateRawStmtEnd(RawStmt *rs, int end_location);
158 : : static Node *makeColumnRef(char *colname, List *indirection,
159 : : int location, core_yyscan_t yyscanner);
160 : : static Node *makeTypeCast(Node *arg, TypeName *typename, int location);
161 : : static Node *makeStringConstCast(char *str, int location, TypeName *typename);
162 : : static Node *makeIntConst(int val, int location);
163 : : static Node *makeFloatConst(char *str, int location);
164 : : static Node *makeBoolAConst(bool state, int location);
165 : : static Node *makeBitStringConst(char *str, int location);
166 : : static Node *makeNullAConst(int location);
167 : : static Node *makeAConst(Node *v, int location);
168 : : static RoleSpec *makeRoleSpec(RoleSpecType type, int location);
169 : : static void check_qualified_name(List *names, core_yyscan_t yyscanner);
170 : : static List *check_func_name(List *names, core_yyscan_t yyscanner);
171 : : static List *check_indirection(List *indirection, core_yyscan_t yyscanner);
172 : : static List *extractArgTypes(List *parameters);
173 : : static List *extractAggrArgTypes(List *aggrargs);
174 : : static List *makeOrderedSetArgs(List *directargs, List *orderedargs,
175 : : core_yyscan_t yyscanner);
176 : : static void insertSelectOptions(SelectStmt *stmt,
177 : : List *sortClause, List *lockingClause,
178 : : SelectLimit *limitClause,
179 : : WithClause *withClause,
180 : : core_yyscan_t yyscanner);
181 : : static Node *makeSetOp(SetOperation op, bool all, Node *larg, Node *rarg);
182 : : static Node *doNegate(Node *n, int location);
183 : : static void doNegateFloat(Float *v);
184 : : static Node *makeAndExpr(Node *lexpr, Node *rexpr, int location);
185 : : static Node *makeOrExpr(Node *lexpr, Node *rexpr, int location);
186 : : static Node *makeNotExpr(Node *expr, int location);
187 : : static Node *makeAArrayExpr(List *elements, int location, int end_location);
188 : : static Node *makeSQLValueFunction(SQLValueFunctionOp op, int32 typmod,
189 : : int location);
190 : : static Node *makeXmlExpr(XmlExprOp op, char *name, List *named_args,
191 : : List *args, int location);
192 : : static List *mergeTableFuncParameters(List *func_args, List *columns, core_yyscan_t yyscanner);
193 : : static TypeName *TableFuncTypeName(List *columns);
194 : : static RangeVar *makeRangeVarFromAnyName(List *names, int position, core_yyscan_t yyscanner);
195 : : static RangeVar *makeRangeVarFromQualifiedName(char *name, List *namelist, int location,
196 : : core_yyscan_t yyscanner);
197 : : static void SplitColQualList(List *qualList,
198 : : List **constraintList, CollateClause **collClause,
199 : : core_yyscan_t yyscanner);
200 : : static void processCASbits(int cas_bits, int location, const char *constrType,
201 : : bool *deferrable, bool *initdeferred, bool *is_enforced,
202 : : bool *not_valid, bool *no_inherit, core_yyscan_t yyscanner);
203 : : static PartitionStrategy parsePartitionStrategy(char *strategy, int location,
204 : : core_yyscan_t yyscanner);
205 : : static void preprocess_pub_all_objtype_list(List *all_objects_list,
206 : : bool *all_tables,
207 : : bool *all_sequences,
208 : : core_yyscan_t yyscanner);
209 : : static void preprocess_pubobj_list(List *pubobjspec_list,
210 : : core_yyscan_t yyscanner);
211 : : static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
212 : :
213 : : %}
214 : :
215 : : %pure-parser
216 : : %expect 0
217 : : %name-prefix="base_yy"
218 : : %locations
219 : :
220 : : %parse-param {core_yyscan_t yyscanner}
221 : : %lex-param {core_yyscan_t yyscanner}
222 : :
223 : : %union
224 : : {
225 : : core_YYSTYPE core_yystype;
226 : : /* these fields must match core_YYSTYPE: */
227 : : int ival;
228 : : char *str;
229 : : const char *keyword;
230 : :
231 : : char chr;
232 : : bool boolean;
233 : : JoinType jtype;
234 : : DropBehavior dbehavior;
235 : : OnCommitAction oncommit;
236 : : List *list;
237 : : Node *node;
238 : : ObjectType objtype;
239 : : TypeName *typnam;
240 : : FunctionParameter *fun_param;
241 : : FunctionParameterMode fun_param_mode;
242 : : ObjectWithArgs *objwithargs;
243 : : DefElem *defelt;
244 : : SortBy *sortby;
245 : : WindowDef *windef;
246 : : JoinExpr *jexpr;
247 : : IndexElem *ielem;
248 : : StatsElem *selem;
249 : : Alias *alias;
250 : : RangeVar *range;
251 : : IntoClause *into;
252 : : WithClause *with;
253 : : InferClause *infer;
254 : : OnConflictClause *onconflict;
255 : : A_Indices *aind;
256 : : ResTarget *target;
257 : : struct PrivTarget *privtarget;
258 : : AccessPriv *accesspriv;
259 : : struct ImportQual *importqual;
260 : : InsertStmt *istmt;
261 : : VariableSetStmt *vsetstmt;
262 : : PartitionElem *partelem;
263 : : PartitionSpec *partspec;
264 : : PartitionBoundSpec *partboundspec;
265 : : SinglePartitionSpec *singlepartspec;
266 : : RoleSpec *rolespec;
267 : : PublicationObjSpec *publicationobjectspec;
268 : : PublicationAllObjSpec *publicationallobjectspec;
269 : : struct SelectLimit *selectlimit;
270 : : SetQuantifier setquantifier;
271 : : struct GroupClause *groupclause;
272 : : MergeMatchKind mergematch;
273 : : MergeWhenClause *mergewhen;
274 : : struct KeyActions *keyactions;
275 : : struct KeyAction *keyaction;
276 : : ReturningClause *retclause;
277 : : ReturningOptionKind retoptionkind;
278 : : }
279 : :
280 : : %type <node> stmt toplevel_stmt schema_stmt routine_body_stmt
281 : : AlterEventTrigStmt AlterCollationStmt
282 : : AlterDatabaseStmt AlterDatabaseSetStmt AlterDomainStmt AlterEnumStmt
283 : : AlterFdwStmt AlterForeignServerStmt AlterGroupStmt
284 : : AlterObjectDependsStmt AlterObjectSchemaStmt AlterOwnerStmt
285 : : AlterOperatorStmt AlterTypeStmt AlterSeqStmt AlterSystemStmt AlterTableStmt
286 : : AlterTblSpcStmt AlterExtensionStmt AlterExtensionContentsStmt
287 : : AlterCompositeTypeStmt AlterUserMappingStmt
288 : : AlterRoleStmt AlterRoleSetStmt AlterPolicyStmt AlterStatsStmt
289 : : AlterDefaultPrivilegesStmt DefACLAction
290 : : AnalyzeStmt CallStmt ClosePortalStmt ClusterStmt CommentStmt
291 : : ConstraintsSetStmt CopyStmt CreateAsStmt CreateCastStmt
292 : : CreateDomainStmt CreateExtensionStmt CreateGroupStmt CreateOpClassStmt
293 : : CreateOpFamilyStmt AlterOpFamilyStmt CreatePLangStmt
294 : : CreateSchemaStmt CreateSeqStmt CreateStmt CreateStatsStmt CreateTableSpaceStmt
295 : : CreateFdwStmt CreateForeignServerStmt CreateForeignTableStmt
296 : : CreateAssertionStmt CreateTransformStmt CreateTrigStmt CreateEventTrigStmt
297 : : CreateUserStmt CreateUserMappingStmt CreateRoleStmt CreatePolicyStmt
298 : : CreatedbStmt DeclareCursorStmt DefineStmt DeleteStmt DiscardStmt DoStmt
299 : : DropOpClassStmt DropOpFamilyStmt DropStmt
300 : : DropCastStmt DropRoleStmt
301 : : DropdbStmt DropTableSpaceStmt
302 : : DropTransformStmt
303 : : DropUserMappingStmt ExplainStmt FetchStmt
304 : : GrantStmt GrantRoleStmt ImportForeignSchemaStmt IndexStmt InsertStmt
305 : : ListenStmt LoadStmt LockStmt MergeStmt NotifyStmt ExplainableStmt PreparableStmt
306 : : CreateFunctionStmt AlterFunctionStmt ReindexStmt RemoveAggrStmt
307 : : RemoveFuncStmt RemoveOperStmt RenameStmt ReturnStmt RevokeStmt RevokeRoleStmt
308 : : RuleActionStmt RuleActionStmtOrEmpty RuleStmt
309 : : SecLabelStmt SelectStmt TransactionStmt TransactionStmtLegacy TruncateStmt
310 : : UnlistenStmt UpdateStmt VacuumStmt
311 : : VariableResetStmt VariableSetStmt VariableShowStmt
312 : : ViewStmt WaitStmt CheckPointStmt CreateConversionStmt
313 : : DeallocateStmt PrepareStmt ExecuteStmt
314 : : DropOwnedStmt ReassignOwnedStmt
315 : : AlterTSConfigurationStmt AlterTSDictionaryStmt
316 : : CreateMatViewStmt RefreshMatViewStmt CreateAmStmt
317 : : CreatePublicationStmt AlterPublicationStmt
318 : : CreateSubscriptionStmt AlterSubscriptionStmt DropSubscriptionStmt
319 : :
320 : : %type <node> select_no_parens select_with_parens select_clause
321 : : simple_select values_clause
322 : : PLpgSQL_Expr PLAssignStmt
323 : :
324 : : %type <str> opt_single_name
325 : : %type <list> opt_qualified_name
326 : : %type <boolean> opt_concurrently
327 : : %type <dbehavior> opt_drop_behavior
328 : : %type <list> opt_utility_option_list
329 : : %type <list> opt_wait_with_clause
330 : : %type <list> utility_option_list
331 : : %type <defelt> utility_option_elem
332 : : %type <str> utility_option_name
333 : : %type <node> utility_option_arg
334 : :
335 : : %type <node> alter_column_default opclass_item opclass_drop alter_using
336 : : %type <ival> add_drop opt_asc_desc opt_nulls_order
337 : :
338 : : %type <node> alter_table_cmd alter_type_cmd opt_collate_clause
339 : : replica_identity partition_cmd index_partition_cmd
340 : : %type <list> alter_table_cmds alter_type_cmds
341 : : %type <list> alter_identity_column_option_list
342 : : %type <defelt> alter_identity_column_option
343 : : %type <node> set_statistics_value
344 : : %type <str> set_access_method_name
345 : :
346 : : %type <list> createdb_opt_list createdb_opt_items copy_opt_list
347 : : transaction_mode_list
348 : : create_extension_opt_list alter_extension_opt_list
349 : : %type <defelt> createdb_opt_item copy_opt_item
350 : : transaction_mode_item
351 : : create_extension_opt_item alter_extension_opt_item
352 : :
353 : : %type <ival> opt_lock lock_type cast_context
354 : : %type <defelt> drop_option
355 : : %type <boolean> opt_or_replace opt_no
356 : : opt_grant_grant_option
357 : : opt_nowait opt_if_exists opt_with_data
358 : : opt_transaction_chain
359 : : %type <list> grant_role_opt_list
360 : : %type <defelt> grant_role_opt
361 : : %type <node> grant_role_opt_value
362 : : %type <ival> opt_nowait_or_skip
363 : :
364 : : %type <list> OptRoleList AlterOptRoleList
365 : : %type <defelt> CreateOptRoleElem AlterOptRoleElem
366 : :
367 : : %type <str> opt_type
368 : : %type <str> foreign_server_version opt_foreign_server_version
369 : : %type <str> opt_in_database
370 : :
371 : : %type <str> parameter_name
372 : : %type <list> OptSchemaEltList parameter_name_list
373 : :
374 : : %type <chr> am_type
375 : :
376 : : %type <boolean> TriggerForSpec TriggerForType
377 : : %type <ival> TriggerActionTime
378 : : %type <list> TriggerEvents TriggerOneEvent
379 : : %type <node> TriggerFuncArg
380 : : %type <node> TriggerWhen
381 : : %type <str> TransitionRelName
382 : : %type <boolean> TransitionRowOrTable TransitionOldOrNew
383 : : %type <node> TriggerTransition
384 : :
385 : : %type <list> event_trigger_when_list event_trigger_value_list
386 : : %type <defelt> event_trigger_when_item
387 : : %type <chr> enable_trigger
388 : :
389 : : %type <str> copy_file_name
390 : : access_method_clause attr_name
391 : : table_access_method_clause name cursor_name file_name
392 : : cluster_index_specification
393 : :
394 : : %type <list> func_name handler_name qual_Op qual_all_Op subquery_Op
395 : : opt_inline_handler opt_validator validator_clause
396 : : opt_collate
397 : :
398 : : %type <range> qualified_name insert_target OptConstrFromTable
399 : :
400 : : %type <str> all_Op MathOp
401 : :
402 : : %type <str> row_security_cmd RowSecurityDefaultForCmd
403 : : %type <boolean> RowSecurityDefaultPermissive
404 : : %type <node> RowSecurityOptionalWithCheck RowSecurityOptionalExpr
405 : : %type <list> RowSecurityDefaultToRole RowSecurityOptionalToRole
406 : :
407 : : %type <str> iso_level opt_encoding
408 : : %type <rolespec> grantee
409 : : %type <list> grantee_list
410 : : %type <accesspriv> privilege
411 : : %type <list> privileges privilege_list
412 : : %type <privtarget> privilege_target
413 : : %type <objwithargs> function_with_argtypes aggregate_with_argtypes operator_with_argtypes
414 : : %type <list> function_with_argtypes_list aggregate_with_argtypes_list operator_with_argtypes_list
415 : : %type <ival> defacl_privilege_target
416 : : %type <defelt> DefACLOption
417 : : %type <list> DefACLOptionList
418 : : %type <ival> import_qualification_type
419 : : %type <importqual> import_qualification
420 : : %type <node> vacuum_relation
421 : : %type <selectlimit> opt_select_limit select_limit limit_clause
422 : :
423 : : %type <list> parse_toplevel stmtmulti routine_body_stmt_list
424 : : OptTableElementList TableElementList OptInherit definition
425 : : OptTypedTableElementList TypedTableElementList
426 : : reloptions opt_reloptions
427 : : OptWith opt_definition func_args func_args_list
428 : : func_args_with_defaults func_args_with_defaults_list
429 : : aggr_args aggr_args_list
430 : : func_as createfunc_opt_list opt_createfunc_opt_list alterfunc_opt_list
431 : : old_aggr_definition old_aggr_list
432 : : oper_argtypes RuleActionList RuleActionMulti
433 : : opt_column_list columnList opt_name_list
434 : : sort_clause opt_sort_clause sortby_list index_params
435 : : stats_params
436 : : opt_include opt_c_include index_including_params
437 : : name_list role_list from_clause from_list opt_array_bounds
438 : : qualified_name_list any_name any_name_list type_name_list
439 : : any_operator expr_list attrs
440 : : distinct_clause opt_distinct_clause
441 : : target_list opt_target_list insert_column_list set_target_list
442 : : merge_values_clause
443 : : set_clause_list set_clause
444 : : def_list operator_def_list indirection opt_indirection
445 : : reloption_list TriggerFuncArgs opclass_item_list opclass_drop_list
446 : : opclass_purpose opt_opfamily transaction_mode_list_or_empty
447 : : OptTableFuncElementList TableFuncElementList opt_type_modifiers
448 : : prep_type_clause
449 : : execute_param_clause using_clause
450 : : returning_with_clause returning_options
451 : : opt_enum_val_list enum_val_list table_func_column_list
452 : : create_generic_options alter_generic_options
453 : : relation_expr_list dostmt_opt_list
454 : : transform_element_list transform_type_list
455 : : TriggerTransitions TriggerReferencing
456 : : vacuum_relation_list opt_vacuum_relation_list
457 : : drop_option_list pub_obj_list pub_all_obj_type_list
458 : :
459 : : %type <retclause> returning_clause
460 : : %type <node> returning_option
461 : : %type <retoptionkind> returning_option_kind
462 : : %type <node> opt_routine_body
463 : : %type <groupclause> group_clause
464 : : %type <list> group_by_list
465 : : %type <node> group_by_item empty_grouping_set rollup_clause cube_clause
466 : : %type <node> grouping_sets_clause
467 : :
468 : : %type <list> opt_fdw_options fdw_options
469 : : %type <defelt> fdw_option
470 : :
471 : : %type <range> OptTempTableName
472 : : %type <into> into_clause create_as_target create_mv_target
473 : :
474 : : %type <defelt> createfunc_opt_item common_func_opt_item dostmt_opt_item
475 : : %type <fun_param> func_arg func_arg_with_default table_func_column aggr_arg
476 : : %type <fun_param_mode> arg_class
477 : : %type <typnam> func_return func_type
478 : :
479 : : %type <boolean> opt_trusted opt_restart_seqs
480 : : %type <ival> OptTemp
481 : : %type <ival> OptNoLog
482 : : %type <oncommit> OnCommitOption
483 : :
484 : : %type <ival> for_locking_strength
485 : : %type <node> for_locking_item
486 : : %type <list> for_locking_clause opt_for_locking_clause for_locking_items
487 : : %type <list> locked_rels_list
488 : : %type <setquantifier> set_quantifier
489 : :
490 : : %type <node> join_qual
491 : : %type <jtype> join_type
492 : :
493 : : %type <list> extract_list overlay_list position_list
494 : : %type <list> substr_list trim_list
495 : : %type <list> opt_interval interval_second
496 : : %type <str> unicode_normal_form
497 : :
498 : : %type <boolean> opt_instead
499 : : %type <boolean> opt_unique opt_verbose opt_full
500 : : %type <boolean> opt_freeze opt_analyze opt_default
501 : : %type <defelt> opt_binary copy_delimiter
502 : :
503 : : %type <boolean> copy_from opt_program
504 : :
505 : : %type <ival> event cursor_options opt_hold opt_set_data
506 : : %type <objtype> object_type_any_name object_type_name object_type_name_on_any_name
507 : : drop_type_name
508 : :
509 : : %type <node> fetch_args select_limit_value
510 : : offset_clause select_offset_value
511 : : select_fetch_first_value I_or_F_const
512 : : %type <ival> row_or_rows first_or_next
513 : :
514 : : %type <list> OptSeqOptList SeqOptList OptParenthesizedSeqOptList
515 : : %type <defelt> SeqOptElem
516 : :
517 : : %type <istmt> insert_rest
518 : : %type <infer> opt_conf_expr
519 : : %type <onconflict> opt_on_conflict
520 : : %type <mergewhen> merge_insert merge_update merge_delete
521 : :
522 : : %type <mergematch> merge_when_tgt_matched merge_when_tgt_not_matched
523 : : %type <node> merge_when_clause opt_merge_when_condition
524 : : %type <list> merge_when_list
525 : :
526 : : %type <vsetstmt> generic_set set_rest set_rest_more generic_reset reset_rest
527 : : SetResetClause FunctionSetResetClause
528 : :
529 : : %type <node> TableElement TypedTableElement ConstraintElem DomainConstraintElem TableFuncElement
530 : : %type <node> columnDef columnOptions optionalPeriodName
531 : : %type <defelt> def_elem reloption_elem old_aggr_elem operator_def_elem
532 : : %type <node> def_arg columnElem where_clause where_or_current_clause
533 : : a_expr b_expr c_expr AexprConst indirection_el opt_slice_bound
534 : : columnref having_clause func_table xmltable array_expr
535 : : OptWhereClause operator_def_arg
536 : : %type <list> opt_column_and_period_list
537 : : %type <list> rowsfrom_item rowsfrom_list opt_col_def_list
538 : : %type <boolean> opt_ordinality opt_without_overlaps
539 : : %type <list> ExclusionConstraintList ExclusionConstraintElem
540 : : %type <list> func_arg_list func_arg_list_opt
541 : : %type <node> func_arg_expr
542 : : %type <list> row explicit_row implicit_row type_list array_expr_list
543 : : %type <node> case_expr case_arg when_clause case_default
544 : : %type <list> when_clause_list
545 : : %type <node> opt_search_clause opt_cycle_clause
546 : : %type <ival> sub_type opt_materialized
547 : : %type <node> NumericOnly
548 : : %type <list> NumericOnly_list
549 : : %type <alias> alias_clause opt_alias_clause opt_alias_clause_for_join_using
550 : : %type <list> func_alias_clause
551 : : %type <sortby> sortby
552 : : %type <ielem> index_elem index_elem_options
553 : : %type <selem> stats_param
554 : : %type <node> table_ref
555 : : %type <jexpr> joined_table
556 : : %type <range> relation_expr
557 : : %type <range> extended_relation_expr
558 : : %type <range> relation_expr_opt_alias
559 : : %type <node> tablesample_clause opt_repeatable_clause
560 : : %type <target> target_el set_target insert_column_item
561 : :
562 : : %type <str> generic_option_name
563 : : %type <node> generic_option_arg
564 : : %type <defelt> generic_option_elem alter_generic_option_elem
565 : : %type <list> generic_option_list alter_generic_option_list
566 : :
567 : : %type <ival> reindex_target_relation reindex_target_all
568 : :
569 : : %type <node> copy_generic_opt_arg copy_generic_opt_arg_list_item
570 : : %type <defelt> copy_generic_opt_elem
571 : : %type <list> copy_generic_opt_list copy_generic_opt_arg_list
572 : : %type <list> copy_options
573 : :
574 : : %type <typnam> Typename SimpleTypename ConstTypename
575 : : GenericType Numeric opt_float JsonType
576 : : Character ConstCharacter
577 : : CharacterWithLength CharacterWithoutLength
578 : : ConstDatetime ConstInterval
579 : : Bit ConstBit BitWithLength BitWithoutLength
580 : : %type <str> character
581 : : %type <str> extract_arg
582 : : %type <boolean> opt_varying opt_timezone opt_no_inherit
583 : :
584 : : %type <ival> Iconst SignedIconst
585 : : %type <str> Sconst comment_text notify_payload
586 : : %type <str> RoleId opt_boolean_or_string
587 : : %type <list> var_list
588 : : %type <str> ColId ColLabel BareColLabel
589 : : %type <str> NonReservedWord NonReservedWord_or_Sconst
590 : : %type <str> var_name type_function_name param_name
591 : : %type <str> createdb_opt_name plassign_target
592 : : %type <node> var_value zone_value
593 : : %type <rolespec> auth_ident RoleSpec opt_granted_by
594 : : %type <publicationobjectspec> PublicationObjSpec
595 : : %type <publicationallobjectspec> PublicationAllObjSpec
596 : :
597 : : %type <keyword> unreserved_keyword type_func_name_keyword
598 : : %type <keyword> col_name_keyword reserved_keyword
599 : : %type <keyword> bare_label_keyword
600 : :
601 : : %type <node> DomainConstraint TableConstraint TableLikeClause
602 : : %type <ival> TableLikeOptionList TableLikeOption
603 : : %type <str> column_compression opt_column_compression column_storage opt_column_storage
604 : : %type <list> ColQualList
605 : : %type <node> ColConstraint ColConstraintElem ConstraintAttr
606 : : %type <ival> key_match
607 : : %type <keyaction> key_delete key_update key_action
608 : : %type <keyactions> key_actions
609 : : %type <ival> ConstraintAttributeSpec ConstraintAttributeElem
610 : : %type <str> ExistingIndex
611 : :
612 : : %type <list> constraints_set_list
613 : : %type <boolean> constraints_set_mode
614 : : %type <str> OptTableSpace OptConsTableSpace
615 : : %type <rolespec> OptTableSpaceOwner
616 : : %type <ival> opt_check_option
617 : :
618 : : %type <str> opt_provider security_label
619 : :
620 : : %type <target> xml_attribute_el
621 : : %type <list> xml_attribute_list xml_attributes
622 : : %type <node> xml_root_version opt_xml_root_standalone
623 : : %type <node> xmlexists_argument
624 : : %type <ival> document_or_content
625 : : %type <boolean> xml_indent_option xml_whitespace_option
626 : : %type <list> xmltable_column_list xmltable_column_option_list
627 : : %type <node> xmltable_column_el
628 : : %type <defelt> xmltable_column_option_el
629 : : %type <list> xml_namespace_list
630 : : %type <target> xml_namespace_el
631 : :
632 : : %type <node> func_application func_expr_common_subexpr
633 : : %type <node> func_expr func_expr_windowless
634 : : %type <node> common_table_expr
635 : : %type <with> with_clause opt_with_clause
636 : : %type <list> cte_list
637 : :
638 : : %type <list> within_group_clause
639 : : %type <node> filter_clause
640 : : %type <list> window_clause window_definition_list opt_partition_clause
641 : : %type <windef> window_definition over_clause window_specification
642 : : opt_frame_clause frame_extent frame_bound
643 : : %type <ival> null_treatment opt_window_exclusion_clause
644 : : %type <str> opt_existing_window_name
645 : : %type <boolean> opt_if_not_exists
646 : : %type <boolean> opt_unique_null_treatment
647 : : %type <ival> generated_when override_kind opt_virtual_or_stored
648 : : %type <partspec> PartitionSpec OptPartitionSpec
649 : : %type <partelem> part_elem
650 : : %type <list> part_params
651 : : %type <partboundspec> PartitionBoundSpec
652 : : %type <singlepartspec> SinglePartitionSpec
653 : : %type <list> partitions_list
654 : : %type <list> hash_partbound
655 : : %type <defelt> hash_partbound_elem
656 : :
657 : : %type <node> json_format_clause
658 : : json_format_clause_opt
659 : : json_value_expr
660 : : json_returning_clause_opt
661 : : json_name_and_value
662 : : json_aggregate_func
663 : : json_argument
664 : : json_behavior
665 : : json_on_error_clause_opt
666 : : json_table
667 : : json_table_column_definition
668 : : json_table_column_path_clause_opt
669 : : %type <list> json_name_and_value_list
670 : : json_value_expr_list
671 : : json_array_aggregate_order_by_clause_opt
672 : : json_arguments
673 : : json_behavior_clause_opt
674 : : json_passing_clause_opt
675 : : json_table_column_definition_list
676 : : %type <str> json_table_path_name_opt
677 : : %type <ival> json_behavior_type
678 : : json_predicate_type_constraint
679 : : json_quotes_clause_opt
680 : : json_wrapper_behavior
681 : : %type <boolean> json_key_uniqueness_constraint_opt
682 : : json_object_constructor_null_clause_opt
683 : : json_array_constructor_null_clause_opt
684 : :
685 : : /*
686 : : * Non-keyword token types. These are hard-wired into the "flex" lexer.
687 : : * They must be listed first so that their numeric codes do not depend on
688 : : * the set of keywords. PL/pgSQL depends on this so that it can share the
689 : : * same lexer. If you add/change tokens here, fix PL/pgSQL to match!
690 : : *
691 : : * UIDENT and USCONST are reduced to IDENT and SCONST in parser.c, so that
692 : : * they need no productions here; but we must assign token codes to them.
693 : : *
694 : : * DOT_DOT is unused in the core SQL grammar, and so will always provoke
695 : : * parse errors. It is needed by PL/pgSQL.
696 : : */
697 : : %token <str> IDENT UIDENT FCONST SCONST USCONST BCONST XCONST Op
698 : : %token <ival> ICONST PARAM
699 : : %token TYPECAST DOT_DOT COLON_EQUALS EQUALS_GREATER
700 : : %token LESS_EQUALS GREATER_EQUALS NOT_EQUALS
701 : :
702 : : /*
703 : : * If you want to make any keyword changes, update the keyword table in
704 : : * src/include/parser/kwlist.h and add new keywords to the appropriate one
705 : : * of the reserved-or-not-so-reserved keyword lists, below; search
706 : : * this file for "Keyword category lists".
707 : : */
708 : :
709 : : /* ordinary key words in alphabetical order */
710 : : %token <keyword> ABORT_P ABSENT ABSOLUTE_P ACCESS ACTION ADD_P ADMIN AFTER
711 : : AGGREGATE ALL ALSO ALTER ALWAYS ANALYSE ANALYZE AND ANY ARRAY AS ASC
712 : : ASENSITIVE ASSERTION ASSIGNMENT ASYMMETRIC ATOMIC AT ATTACH ATTRIBUTE AUTHORIZATION
713 : :
714 : : BACKWARD BEFORE BEGIN_P BETWEEN BIGINT BINARY BIT
715 : : BOOLEAN_P BOTH BREADTH BY
716 : :
717 : : CACHE CALL CALLED CASCADE CASCADED CASE CAST CATALOG_P CHAIN CHAR_P
718 : : CHARACTER CHARACTERISTICS CHECK CHECKPOINT CLASS CLOSE
719 : : CLUSTER COALESCE COLLATE COLLATION COLUMN COLUMNS COMMENT COMMENTS COMMIT
720 : : COMMITTED COMPRESSION CONCURRENTLY CONDITIONAL CONFIGURATION CONFLICT
721 : : CONNECTION CONSTRAINT CONSTRAINTS CONTENT_P CONTINUE_P CONVERSION_P COPY
722 : : COST CREATE CROSS CSV CUBE CURRENT_P
723 : : CURRENT_CATALOG CURRENT_DATE CURRENT_ROLE CURRENT_SCHEMA
724 : : CURRENT_TIME CURRENT_TIMESTAMP CURRENT_USER CURSOR CYCLE
725 : :
726 : : DATA_P DATABASE DAY_P DEALLOCATE DEC DECIMAL_P DECLARE DEFAULT DEFAULTS
727 : : DEFERRABLE DEFERRED DEFINER DELETE_P DELIMITER DELIMITERS DEPENDS DEPTH DESC
728 : : DETACH DICTIONARY DISABLE_P DISCARD DISTINCT DO DOCUMENT_P DOMAIN_P
729 : : DOUBLE_P DROP
730 : :
731 : : EACH ELSE EMPTY_P ENABLE_P ENCODING ENCRYPTED END_P ENFORCED ENUM_P ERROR_P
732 : : ESCAPE EVENT EXCEPT EXCLUDE EXCLUDING EXCLUSIVE EXECUTE EXISTS EXPLAIN
733 : : EXPRESSION EXTENSION EXTERNAL EXTRACT
734 : :
735 : : FALSE_P FAMILY FETCH FILTER FINALIZE FIRST_P FLOAT_P FOLLOWING FOR
736 : : FORCE FOREIGN FORMAT FORWARD FREEZE FROM FULL FUNCTION FUNCTIONS
737 : :
738 : : GENERATED GLOBAL GRANT GRANTED GREATEST GROUP_P GROUPING GROUPS
739 : :
740 : : HANDLER HAVING HEADER_P HOLD HOUR_P
741 : :
742 : : IDENTITY_P IF_P IGNORE_P ILIKE IMMEDIATE IMMUTABLE IMPLICIT_P IMPORT_P IN_P INCLUDE
743 : : INCLUDING INCREMENT INDENT INDEX INDEXES INHERIT INHERITS INITIALLY INLINE_P
744 : : INNER_P INOUT INPUT_P INSENSITIVE INSERT INSTEAD INT_P INTEGER
745 : : INTERSECT INTERVAL INTO INVOKER IS ISNULL ISOLATION
746 : :
747 : : JOIN JSON JSON_ARRAY JSON_ARRAYAGG JSON_EXISTS JSON_OBJECT JSON_OBJECTAGG
748 : : JSON_QUERY JSON_SCALAR JSON_SERIALIZE JSON_TABLE JSON_VALUE
749 : :
750 : : KEEP KEY KEYS
751 : :
752 : : LABEL LANGUAGE LARGE_P LAST_P LATERAL_P
753 : : LEADING LEAKPROOF LEAST LEFT LEVEL LIKE LIMIT LISTEN LOAD LOCAL
754 : : LOCALTIME LOCALTIMESTAMP LOCATION LOCK_P LOCKED LOGGED LSN_P
755 : :
756 : : MAPPING MATCH MATCHED MATERIALIZED MAXVALUE MERGE MERGE_ACTION METHOD
757 : : MINUTE_P MINVALUE MODE MONTH_P MOVE
758 : :
759 : : NAME_P NAMES NATIONAL NATURAL NCHAR NESTED NEW NEXT NFC NFD NFKC NFKD NO
760 : : NONE NORMALIZE NORMALIZED
761 : : NOT NOTHING NOTIFY NOTNULL NOWAIT NULL_P NULLIF
762 : : NULLS_P NUMERIC
763 : :
764 : : OBJECT_P OBJECTS_P OF OFF OFFSET OIDS OLD OMIT ON ONLY OPERATOR OPTION OPTIONS OR
765 : : ORDER ORDINALITY OTHERS OUT_P OUTER_P
766 : : OVER OVERLAPS OVERLAY OVERRIDING OWNED OWNER
767 : :
768 : : PARALLEL PARAMETER PARSER PARTIAL PARTITION PARTITIONS PASSING PASSWORD PATH
769 : : PERIOD PLACING PLAN PLANS POLICY
770 : : POSITION PRECEDING PRECISION PRESERVE PREPARE PREPARED PRIMARY
771 : : PRIOR PRIVILEGES PROCEDURAL PROCEDURE PROCEDURES PROGRAM PUBLICATION
772 : :
773 : : QUOTE QUOTES
774 : :
775 : : RANGE READ REAL REASSIGN RECURSIVE REF_P REFERENCES REFERENCING
776 : : REFRESH REINDEX RELATIVE_P RELEASE RENAME REPEATABLE REPLACE REPLICA
777 : : RESET RESPECT_P RESTART RESTRICT RETURN RETURNING RETURNS REVOKE RIGHT ROLE ROLLBACK ROLLUP
778 : : ROUTINE ROUTINES ROW ROWS RULE
779 : :
780 : : SAVEPOINT SCALAR SCHEMA SCHEMAS SCROLL SEARCH SECOND_P SECURITY SELECT
781 : : SEQUENCE SEQUENCES
782 : : SERIALIZABLE SERVER SESSION SESSION_USER SET SETS SETOF SHARE SHOW
783 : : SIMILAR SIMPLE SKIP SMALLINT SNAPSHOT SOME SPLIT SOURCE SQL_P STABLE STANDALONE_P
784 : : START STATEMENT STATISTICS STDIN STDOUT STORAGE STORED STRICT_P STRING_P STRIP_P
785 : : SUBSCRIPTION SUBSTRING SUPPORT SYMMETRIC SYSID SYSTEM_P SYSTEM_USER
786 : :
787 : : TABLE TABLES TABLESAMPLE TABLESPACE TARGET TEMP TEMPLATE TEMPORARY TEXT_P THEN
788 : : TIES TIME TIMESTAMP TO TRAILING TRANSACTION TRANSFORM
789 : : TREAT TRIGGER TRIM TRUE_P
790 : : TRUNCATE TRUSTED TYPE_P TYPES_P
791 : :
792 : : UESCAPE UNBOUNDED UNCONDITIONAL UNCOMMITTED UNENCRYPTED UNION UNIQUE UNKNOWN
793 : : UNLISTEN UNLOGGED UNTIL UPDATE USER USING
794 : :
795 : : VACUUM VALID VALIDATE VALIDATOR VALUE_P VALUES VARCHAR VARIADIC VARYING
796 : : VERBOSE VERSION_P VIEW VIEWS VIRTUAL VOLATILE
797 : :
798 : : WAIT WHEN WHERE WHITESPACE_P WINDOW WITH WITHIN WITHOUT WORK WRAPPER WRITE
799 : :
800 : : XML_P XMLATTRIBUTES XMLCONCAT XMLELEMENT XMLEXISTS XMLFOREST XMLNAMESPACES
801 : : XMLPARSE XMLPI XMLROOT XMLSERIALIZE XMLTABLE
802 : :
803 : : YEAR_P YES_P
804 : :
805 : : ZONE
806 : :
807 : : /*
808 : : * The grammar thinks these are keywords, but they are not in the kwlist.h
809 : : * list and so can never be entered directly. The filter in parser.c
810 : : * creates these tokens when required (based on looking one token ahead).
811 : : *
812 : : * NOT_LA exists so that productions such as NOT LIKE can be given the same
813 : : * precedence as LIKE; otherwise they'd effectively have the same precedence
814 : : * as NOT, at least with respect to their left-hand subexpression.
815 : : * FORMAT_LA, NULLS_LA, WITH_LA, and WITHOUT_LA are needed to make the grammar
816 : : * LALR(1).
817 : : */
818 : : %token FORMAT_LA NOT_LA NULLS_LA WITH_LA WITHOUT_LA
819 : :
820 : : /*
821 : : * The grammar likewise thinks these tokens are keywords, but they are never
822 : : * generated by the scanner. Rather, they can be injected by parser.c as
823 : : * the initial token of the string (using the lookahead-token mechanism
824 : : * implemented there). This provides a way to tell the grammar to parse
825 : : * something other than the usual list of SQL commands.
826 : : */
827 : : %token MODE_TYPE_NAME
828 : : %token MODE_PLPGSQL_EXPR
829 : : %token MODE_PLPGSQL_ASSIGN1
830 : : %token MODE_PLPGSQL_ASSIGN2
831 : : %token MODE_PLPGSQL_ASSIGN3
832 : :
833 : :
834 : : /* Precedence: lowest to highest */
835 : : %left UNION EXCEPT
836 : : %left INTERSECT
837 : : %left OR
838 : : %left AND
839 : : %right NOT
840 : : %nonassoc IS ISNULL NOTNULL /* IS sets precedence for IS NULL, etc */
841 : : %nonassoc '<' '>' '=' LESS_EQUALS GREATER_EQUALS NOT_EQUALS
842 : : %nonassoc BETWEEN IN_P LIKE ILIKE SIMILAR NOT_LA
843 : : %nonassoc ESCAPE /* ESCAPE must be just above LIKE/ILIKE/SIMILAR */
844 : :
845 : : /*
846 : : * Sometimes it is necessary to assign precedence to keywords that are not
847 : : * really part of the operator hierarchy, in order to resolve grammar
848 : : * ambiguities. It's best to avoid doing so whenever possible, because such
849 : : * assignments have global effect and may hide ambiguities besides the one
850 : : * you intended to solve. (Attaching a precedence to a single rule with
851 : : * %prec is far safer and should be preferred.) If you must give precedence
852 : : * to a new keyword, try very hard to give it the same precedence as IDENT.
853 : : * If the keyword has IDENT's precedence then it clearly acts the same as
854 : : * non-keywords and other similar keywords, thus reducing the risk of
855 : : * unexpected precedence effects.
856 : : *
857 : : * We used to need to assign IDENT an explicit precedence just less than Op,
858 : : * to support target_el without AS. While that's not really necessary since
859 : : * we removed postfix operators, we continue to do so because it provides a
860 : : * reference point for a precedence level that we can assign to other
861 : : * keywords that lack a natural precedence level.
862 : : *
863 : : * We need to do this for PARTITION, RANGE, ROWS, and GROUPS to support
864 : : * opt_existing_window_name (see comment there).
865 : : *
866 : : * The frame_bound productions UNBOUNDED PRECEDING and UNBOUNDED FOLLOWING
867 : : * are even messier: since UNBOUNDED is an unreserved keyword (per spec!),
868 : : * there is no principled way to distinguish these from the productions
869 : : * a_expr PRECEDING/FOLLOWING. We hack this up by giving UNBOUNDED slightly
870 : : * lower precedence than PRECEDING and FOLLOWING. At present this doesn't
871 : : * appear to cause UNBOUNDED to be treated differently from other unreserved
872 : : * keywords anywhere else in the grammar, but it's definitely risky. We can
873 : : * blame any funny behavior of UNBOUNDED on the SQL standard, though.
874 : : *
875 : : * To support CUBE and ROLLUP in GROUP BY without reserving them, we give them
876 : : * an explicit priority lower than '(', so that a rule with CUBE '(' will shift
877 : : * rather than reducing a conflicting rule that takes CUBE as a function name.
878 : : * Using the same precedence as IDENT seems right for the reasons given above.
879 : : *
880 : : * SET is likewise assigned the same precedence as IDENT, to support the
881 : : * relation_expr_opt_alias production (see comment there).
882 : : *
883 : : * KEYS, OBJECT_P, SCALAR, VALUE_P, WITH, and WITHOUT are similarly assigned
884 : : * the same precedence as IDENT. This allows resolving conflicts in the
885 : : * json_predicate_type_constraint and json_key_uniqueness_constraint_opt
886 : : * productions (see comments there).
887 : : *
888 : : * Like the UNBOUNDED PRECEDING/FOLLOWING case, NESTED is assigned a lower
889 : : * precedence than PATH to fix ambiguity in the json_table production.
890 : : */
891 : : %nonassoc UNBOUNDED NESTED /* ideally would have same precedence as IDENT */
892 : : %nonassoc IDENT PARTITION RANGE ROWS GROUPS PRECEDING FOLLOWING CUBE ROLLUP
893 : : SET KEYS OBJECT_P SCALAR VALUE_P WITH WITHOUT PATH
894 : : %left Op OPERATOR /* multi-character ops and user-defined operators */
895 : : %left '+' '-'
896 : : %left '*' '/' '%'
897 : : %left '^'
898 : : /* Unary Operators */
899 : : %left AT /* sets precedence for AT TIME ZONE, AT LOCAL */
900 : : %left COLLATE
901 : : %right UMINUS
902 : : %left '[' ']'
903 : : %left '(' ')'
904 : : %left TYPECAST
905 : : %left '.'
906 : : /*
907 : : * These might seem to be low-precedence, but actually they are not part
908 : : * of the arithmetic hierarchy at all in their use as JOIN operators.
909 : : * We make them high-precedence to support their use as function names.
910 : : * They wouldn't be given a precedence at all, were it not that we need
911 : : * left-associativity among the JOIN rules themselves.
912 : : */
913 : : %left JOIN CROSS LEFT FULL RIGHT INNER_P NATURAL
914 : :
915 : : %%
916 : :
917 : : /*
918 : : * The target production for the whole parse.
919 : : *
920 : : * Ordinarily we parse a list of statements, but if we see one of the
921 : : * special MODE_XXX symbols as first token, we parse something else.
922 : : * The options here correspond to enum RawParseMode, which see for details.
923 : : */
924 : : parse_toplevel:
925 : : stmtmulti
926 : : {
927 : : pg_yyget_extra(yyscanner)->parsetree = $1;
928 : : (void) yynerrs; /* suppress compiler warning */
929 : : }
930 : : | MODE_TYPE_NAME Typename
931 : : {
932 : : pg_yyget_extra(yyscanner)->parsetree = list_make1($2);
933 : : }
934 : : | MODE_PLPGSQL_EXPR PLpgSQL_Expr
935 : : {
936 : : pg_yyget_extra(yyscanner)->parsetree =
937 : : list_make1(makeRawStmt($2, @2));
938 : : }
939 : : | MODE_PLPGSQL_ASSIGN1 PLAssignStmt
940 : : {
941 : : PLAssignStmt *n = (PLAssignStmt *) $2;
942 : :
943 : : n->nnames = 1;
944 : : pg_yyget_extra(yyscanner)->parsetree =
945 : : list_make1(makeRawStmt((Node *) n, @2));
946 : : }
947 : : | MODE_PLPGSQL_ASSIGN2 PLAssignStmt
948 : : {
949 : : PLAssignStmt *n = (PLAssignStmt *) $2;
950 : :
951 : : n->nnames = 2;
952 : : pg_yyget_extra(yyscanner)->parsetree =
953 : : list_make1(makeRawStmt((Node *) n, @2));
954 : : }
955 : : | MODE_PLPGSQL_ASSIGN3 PLAssignStmt
956 : : {
957 : : PLAssignStmt *n = (PLAssignStmt *) $2;
958 : :
959 : : n->nnames = 3;
960 : : pg_yyget_extra(yyscanner)->parsetree =
961 : : list_make1(makeRawStmt((Node *) n, @2));
962 : : }
963 : : ;
964 : :
965 : : /*
966 : : * At top level, we wrap each stmt with a RawStmt node carrying start location
967 : : * and length of the stmt's text.
968 : : * We also take care to discard empty statements entirely (which among other
969 : : * things dodges the problem of assigning them a location).
970 : : */
971 : : stmtmulti: stmtmulti ';' toplevel_stmt
972 : : {
973 : : if ($1 != NIL)
974 : : {
975 : : /* update length of previous stmt */
976 : : updateRawStmtEnd(llast_node(RawStmt, $1), @2);
977 : : }
978 : : if ($3 != NULL)
979 : : $$ = lappend($1, makeRawStmt($3, @3));
980 : : else
981 : : $$ = $1;
982 : : }
983 : : | toplevel_stmt
984 : : {
985 : : if ($1 != NULL)
986 : : $$ = list_make1(makeRawStmt($1, @1));
987 : : else
988 : : $$ = NIL;
989 : : }
990 : : ;
991 : :
992 : : /*
993 : : * toplevel_stmt includes BEGIN and END. stmt does not include them, because
994 : : * those words have different meanings in function bodies.
995 : : */
996 : : toplevel_stmt:
997 : : stmt
998 : : | TransactionStmtLegacy
999 : : ;
1000 : :
1001 : : stmt:
1002 : : AlterEventTrigStmt
1003 : : | AlterCollationStmt
1004 : : | AlterDatabaseStmt
1005 : : | AlterDatabaseSetStmt
1006 : : | AlterDefaultPrivilegesStmt
1007 : : | AlterDomainStmt
1008 : : | AlterEnumStmt
1009 : : | AlterExtensionStmt
1010 : : | AlterExtensionContentsStmt
1011 : : | AlterFdwStmt
1012 : : | AlterForeignServerStmt
1013 : : | AlterFunctionStmt
1014 : : | AlterGroupStmt
1015 : : | AlterObjectDependsStmt
1016 : : | AlterObjectSchemaStmt
1017 : : | AlterOwnerStmt
1018 : : | AlterOperatorStmt
1019 : : | AlterTypeStmt
1020 : : | AlterPolicyStmt
1021 : : | AlterSeqStmt
1022 : : | AlterSystemStmt
1023 : : | AlterTableStmt
1024 : : | AlterTblSpcStmt
1025 : : | AlterCompositeTypeStmt
1026 : : | AlterPublicationStmt
1027 : : | AlterRoleSetStmt
1028 : : | AlterRoleStmt
1029 : : | AlterSubscriptionStmt
1030 : : | AlterStatsStmt
1031 : : | AlterTSConfigurationStmt
1032 : : | AlterTSDictionaryStmt
1033 : : | AlterUserMappingStmt
1034 : : | AnalyzeStmt
1035 : : | CallStmt
1036 : : | CheckPointStmt
1037 : : | ClosePortalStmt
1038 : : | ClusterStmt
1039 : : | CommentStmt
1040 : : | ConstraintsSetStmt
1041 : : | CopyStmt
1042 : : | CreateAmStmt
1043 : : | CreateAsStmt
1044 : : | CreateAssertionStmt
1045 : : | CreateCastStmt
1046 : : | CreateConversionStmt
1047 : : | CreateDomainStmt
1048 : : | CreateExtensionStmt
1049 : : | CreateFdwStmt
1050 : : | CreateForeignServerStmt
1051 : : | CreateForeignTableStmt
1052 : : | CreateFunctionStmt
1053 : : | CreateGroupStmt
1054 : : | CreateMatViewStmt
1055 : : | CreateOpClassStmt
1056 : : | CreateOpFamilyStmt
1057 : : | CreatePublicationStmt
1058 : : | AlterOpFamilyStmt
1059 : : | CreatePolicyStmt
1060 : : | CreatePLangStmt
1061 : : | CreateSchemaStmt
1062 : : | CreateSeqStmt
1063 : : | CreateStmt
1064 : : | CreateSubscriptionStmt
1065 : : | CreateStatsStmt
1066 : : | CreateTableSpaceStmt
1067 : : | CreateTransformStmt
1068 : : | CreateTrigStmt
1069 : : | CreateEventTrigStmt
1070 : : | CreateRoleStmt
1071 : : | CreateUserStmt
1072 : : | CreateUserMappingStmt
1073 : : | CreatedbStmt
1074 : : | DeallocateStmt
1075 : : | DeclareCursorStmt
1076 : : | DefineStmt
1077 : : | DeleteStmt
1078 : : | DiscardStmt
1079 : : | DoStmt
1080 : : | DropCastStmt
1081 : : | DropOpClassStmt
1082 : : | DropOpFamilyStmt
1083 : : | DropOwnedStmt
1084 : : | DropStmt
1085 : : | DropSubscriptionStmt
1086 : : | DropTableSpaceStmt
1087 : : | DropTransformStmt
1088 : : | DropRoleStmt
1089 : : | DropUserMappingStmt
1090 : : | DropdbStmt
1091 : : | ExecuteStmt
1092 : : | ExplainStmt
1093 : : | FetchStmt
1094 : : | GrantStmt
1095 : : | GrantRoleStmt
1096 : : | ImportForeignSchemaStmt
1097 : : | IndexStmt
1098 : : | InsertStmt
1099 : : | ListenStmt
1100 : : | RefreshMatViewStmt
1101 : : | LoadStmt
1102 : : | LockStmt
1103 : : | MergeStmt
1104 : : | NotifyStmt
1105 : : | PrepareStmt
1106 : : | ReassignOwnedStmt
1107 : : | ReindexStmt
1108 : : | RemoveAggrStmt
1109 : : | RemoveFuncStmt
1110 : : | RemoveOperStmt
1111 : : | RenameStmt
1112 : : | RevokeStmt
1113 : : | RevokeRoleStmt
1114 : : | RuleStmt
1115 : : | SecLabelStmt
1116 : : | SelectStmt
1117 : : | TransactionStmt
1118 : : | TruncateStmt
1119 : : | UnlistenStmt
1120 : : | UpdateStmt
1121 : : | VacuumStmt
1122 : : | VariableResetStmt
1123 : : | VariableSetStmt
1124 : : | VariableShowStmt
1125 : : | ViewStmt
1126 : : | WaitStmt
1127 : : | /*EMPTY*/
1128 : : { $$ = NULL; }
1129 : : ;
1130 : :
1131 : : /*
1132 : : * Generic supporting productions for DDL
1133 : : */
1134 : : opt_single_name:
1135 : : ColId { $$ = $1; }
1136 : : | /* EMPTY */ { $$ = NULL; }
1137 : : ;
1138 : :
1139 : : opt_qualified_name:
1140 : : any_name { $$ = $1; }
1141 : : | /*EMPTY*/ { $$ = NIL; }
1142 : : ;
1143 : :
1144 : : opt_concurrently:
1145 : : CONCURRENTLY { $$ = true; }
1146 : : | /*EMPTY*/ { $$ = false; }
1147 : : ;
1148 : :
1149 : : opt_drop_behavior:
1150 : : CASCADE { $$ = DROP_CASCADE; }
1151 : : | RESTRICT { $$ = DROP_RESTRICT; }
1152 : : | /* EMPTY */ { $$ = DROP_RESTRICT; /* default */ }
1153 : : ;
1154 : :
1155 : : opt_utility_option_list:
1156 : : '(' utility_option_list ')' { $$ = $2; }
1157 : : | /* EMPTY */ { $$ = NULL; }
1158 : : ;
1159 : :
1160 : : utility_option_list:
1161 : : utility_option_elem
1162 : : {
1163 : : $$ = list_make1($1);
1164 : : }
1165 : : | utility_option_list ',' utility_option_elem
1166 : : {
1167 : : $$ = lappend($1, $3);
1168 : : }
1169 : : ;
1170 : :
1171 : : utility_option_elem:
1172 : : utility_option_name utility_option_arg
1173 : : {
1174 : : $$ = makeDefElem($1, $2, @1);
1175 : : }
1176 : : ;
1177 : :
1178 : : utility_option_name:
1179 : : NonReservedWord { $$ = $1; }
1180 : : | analyze_keyword { $$ = "analyze"; }
1181 : : | FORMAT_LA { $$ = "format"; }
1182 : : ;
1183 : :
1184 : : utility_option_arg:
1185 : : opt_boolean_or_string { $$ = (Node *) makeString($1); }
1186 : : | NumericOnly { $$ = (Node *) $1; }
1187 : : | /* EMPTY */ { $$ = NULL; }
1188 : : ;
1189 : :
1190 : : /*****************************************************************************
1191 : : *
1192 : : * CALL statement
1193 : : *
1194 : : *****************************************************************************/
1195 : :
1196 : : CallStmt: CALL func_application
1197 : : {
1198 : : CallStmt *n = makeNode(CallStmt);
1199 : :
1200 : : n->funccall = castNode(FuncCall, $2);
1201 : : $$ = (Node *) n;
1202 : : }
1203 : : ;
1204 : :
1205 : : /*****************************************************************************
1206 : : *
1207 : : * Create a new Postgres DBMS role
1208 : : *
1209 : : *****************************************************************************/
1210 : :
1211 : : CreateRoleStmt:
1212 : : CREATE ROLE RoleId opt_with OptRoleList
1213 : : {
1214 : : CreateRoleStmt *n = makeNode(CreateRoleStmt);
1215 : :
1216 : : n->stmt_type = ROLESTMT_ROLE;
1217 : : n->role = $3;
1218 : : n->options = $5;
1219 : : $$ = (Node *) n;
1220 : : }
1221 : : ;
1222 : :
1223 : :
1224 : : opt_with: WITH
1225 : : | WITH_LA
1226 : : | /*EMPTY*/
1227 : : ;
1228 : :
1229 : : /*
1230 : : * Options for CREATE ROLE and ALTER ROLE (also used by CREATE/ALTER USER
1231 : : * for backwards compatibility). Note: the only option required by SQL99
1232 : : * is "WITH ADMIN name".
1233 : : */
1234 : : OptRoleList:
1235 : : OptRoleList CreateOptRoleElem { $$ = lappend($1, $2); }
1236 : : | /* EMPTY */ { $$ = NIL; }
1237 : : ;
1238 : :
1239 : : AlterOptRoleList:
1240 : : AlterOptRoleList AlterOptRoleElem { $$ = lappend($1, $2); }
1241 : : | /* EMPTY */ { $$ = NIL; }
1242 : : ;
1243 : :
1244 : : AlterOptRoleElem:
1245 : : PASSWORD Sconst
1246 : : {
1247 : : $$ = makeDefElem("password",
1248 : : (Node *) makeString($2), @1);
1249 : : }
1250 : : | PASSWORD NULL_P
1251 : : {
1252 : : $$ = makeDefElem("password", NULL, @1);
1253 : : }
1254 : : | ENCRYPTED PASSWORD Sconst
1255 : : {
1256 : : /*
1257 : : * These days, passwords are always stored in encrypted
1258 : : * form, so there is no difference between PASSWORD and
1259 : : * ENCRYPTED PASSWORD.
1260 : : */
1261 : : $$ = makeDefElem("password",
1262 : : (Node *) makeString($3), @1);
1263 : : }
1264 : : | UNENCRYPTED PASSWORD Sconst
1265 : : {
1266 : : ereport(ERROR,
1267 : : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1268 : : errmsg("UNENCRYPTED PASSWORD is no longer supported"),
1269 : : errhint("Remove UNENCRYPTED to store the password in encrypted form instead."),
1270 : : parser_errposition(@1)));
1271 : : }
1272 : : | INHERIT
1273 : : {
1274 : : $$ = makeDefElem("inherit", (Node *) makeBoolean(true), @1);
1275 : : }
1276 : : | CONNECTION LIMIT SignedIconst
1277 : : {
1278 : : $$ = makeDefElem("connectionlimit", (Node *) makeInteger($3), @1);
1279 : : }
1280 : : | VALID UNTIL Sconst
1281 : : {
1282 : : $$ = makeDefElem("validUntil", (Node *) makeString($3), @1);
1283 : : }
1284 : : /* Supported but not documented for roles, for use by ALTER GROUP. */
1285 : : | USER role_list
1286 : : {
1287 : : $$ = makeDefElem("rolemembers", (Node *) $2, @1);
1288 : : }
1289 : : | IDENT
1290 : : {
1291 : : /*
1292 : : * We handle identifiers that aren't parser keywords with
1293 : : * the following special-case codes, to avoid bloating the
1294 : : * size of the main parser.
1295 : : */
1296 : : if (strcmp($1, "superuser") == 0)
1297 : : $$ = makeDefElem("superuser", (Node *) makeBoolean(true), @1);
1298 : : else if (strcmp($1, "nosuperuser") == 0)
1299 : : $$ = makeDefElem("superuser", (Node *) makeBoolean(false), @1);
1300 : : else if (strcmp($1, "createrole") == 0)
1301 : : $$ = makeDefElem("createrole", (Node *) makeBoolean(true), @1);
1302 : : else if (strcmp($1, "nocreaterole") == 0)
1303 : : $$ = makeDefElem("createrole", (Node *) makeBoolean(false), @1);
1304 : : else if (strcmp($1, "replication") == 0)
1305 : : $$ = makeDefElem("isreplication", (Node *) makeBoolean(true), @1);
1306 : : else if (strcmp($1, "noreplication") == 0)
1307 : : $$ = makeDefElem("isreplication", (Node *) makeBoolean(false), @1);
1308 : : else if (strcmp($1, "createdb") == 0)
1309 : : $$ = makeDefElem("createdb", (Node *) makeBoolean(true), @1);
1310 : : else if (strcmp($1, "nocreatedb") == 0)
1311 : : $$ = makeDefElem("createdb", (Node *) makeBoolean(false), @1);
1312 : : else if (strcmp($1, "login") == 0)
1313 : : $$ = makeDefElem("canlogin", (Node *) makeBoolean(true), @1);
1314 : : else if (strcmp($1, "nologin") == 0)
1315 : : $$ = makeDefElem("canlogin", (Node *) makeBoolean(false), @1);
1316 : : else if (strcmp($1, "bypassrls") == 0)
1317 : : $$ = makeDefElem("bypassrls", (Node *) makeBoolean(true), @1);
1318 : : else if (strcmp($1, "nobypassrls") == 0)
1319 : : $$ = makeDefElem("bypassrls", (Node *) makeBoolean(false), @1);
1320 : : else if (strcmp($1, "noinherit") == 0)
1321 : : {
1322 : : /*
1323 : : * Note that INHERIT is a keyword, so it's handled by main parser, but
1324 : : * NOINHERIT is handled here.
1325 : : */
1326 : : $$ = makeDefElem("inherit", (Node *) makeBoolean(false), @1);
1327 : : }
1328 : : else
1329 : : ereport(ERROR,
1330 : : (errcode(ERRCODE_SYNTAX_ERROR),
1331 : : errmsg("unrecognized role option \"%s\"", $1),
1332 : : parser_errposition(@1)));
1333 : : }
1334 : : ;
1335 : :
1336 : : CreateOptRoleElem:
1337 : : AlterOptRoleElem { $$ = $1; }
1338 : : /* The following are not supported by ALTER ROLE/USER/GROUP */
1339 : : | SYSID Iconst
1340 : : {
1341 : : $$ = makeDefElem("sysid", (Node *) makeInteger($2), @1);
1342 : : }
1343 : : | ADMIN role_list
1344 : : {
1345 : : $$ = makeDefElem("adminmembers", (Node *) $2, @1);
1346 : : }
1347 : : | ROLE role_list
1348 : : {
1349 : : $$ = makeDefElem("rolemembers", (Node *) $2, @1);
1350 : : }
1351 : : | IN_P ROLE role_list
1352 : : {
1353 : : $$ = makeDefElem("addroleto", (Node *) $3, @1);
1354 : : }
1355 : : | IN_P GROUP_P role_list
1356 : : {
1357 : : $$ = makeDefElem("addroleto", (Node *) $3, @1);
1358 : : }
1359 : : ;
1360 : :
1361 : :
1362 : : /*****************************************************************************
1363 : : *
1364 : : * Create a new Postgres DBMS user (role with implied login ability)
1365 : : *
1366 : : *****************************************************************************/
1367 : :
1368 : : CreateUserStmt:
1369 : : CREATE USER RoleId opt_with OptRoleList
1370 : : {
1371 : : CreateRoleStmt *n = makeNode(CreateRoleStmt);
1372 : :
1373 : : n->stmt_type = ROLESTMT_USER;
1374 : : n->role = $3;
1375 : : n->options = $5;
1376 : : $$ = (Node *) n;
1377 : : }
1378 : : ;
1379 : :
1380 : :
1381 : : /*****************************************************************************
1382 : : *
1383 : : * Alter a postgresql DBMS role
1384 : : *
1385 : : *****************************************************************************/
1386 : :
1387 : : AlterRoleStmt:
1388 : : ALTER ROLE RoleSpec opt_with AlterOptRoleList
1389 : : {
1390 : : AlterRoleStmt *n = makeNode(AlterRoleStmt);
1391 : :
1392 : : n->role = $3;
1393 : : n->action = +1; /* add, if there are members */
1394 : : n->options = $5;
1395 : : $$ = (Node *) n;
1396 : : }
1397 : : | ALTER USER RoleSpec opt_with AlterOptRoleList
1398 : : {
1399 : : AlterRoleStmt *n = makeNode(AlterRoleStmt);
1400 : :
1401 : : n->role = $3;
1402 : : n->action = +1; /* add, if there are members */
1403 : : n->options = $5;
1404 : : $$ = (Node *) n;
1405 : : }
1406 : : ;
1407 : :
1408 : : opt_in_database:
1409 : : /* EMPTY */ { $$ = NULL; }
1410 : : | IN_P DATABASE name { $$ = $3; }
1411 : : ;
1412 : :
1413 : : AlterRoleSetStmt:
1414 : : ALTER ROLE RoleSpec opt_in_database SetResetClause
1415 : : {
1416 : : AlterRoleSetStmt *n = makeNode(AlterRoleSetStmt);
1417 : :
1418 : : n->role = $3;
1419 : : n->database = $4;
1420 : : n->setstmt = $5;
1421 : : $$ = (Node *) n;
1422 : : }
1423 : : | ALTER ROLE ALL opt_in_database SetResetClause
1424 : : {
1425 : : AlterRoleSetStmt *n = makeNode(AlterRoleSetStmt);
1426 : :
1427 : : n->role = NULL;
1428 : : n->database = $4;
1429 : : n->setstmt = $5;
1430 : : $$ = (Node *) n;
1431 : : }
1432 : : | ALTER USER RoleSpec opt_in_database SetResetClause
1433 : : {
1434 : : AlterRoleSetStmt *n = makeNode(AlterRoleSetStmt);
1435 : :
1436 : : n->role = $3;
1437 : : n->database = $4;
1438 : : n->setstmt = $5;
1439 : : $$ = (Node *) n;
1440 : : }
1441 : : | ALTER USER ALL opt_in_database SetResetClause
1442 : : {
1443 : : AlterRoleSetStmt *n = makeNode(AlterRoleSetStmt);
1444 : :
1445 : : n->role = NULL;
1446 : : n->database = $4;
1447 : : n->setstmt = $5;
1448 : : $$ = (Node *) n;
1449 : : }
1450 : : ;
1451 : :
1452 : :
1453 : : /*****************************************************************************
1454 : : *
1455 : : * Drop a postgresql DBMS role
1456 : : *
1457 : : * XXX Ideally this would have CASCADE/RESTRICT options, but a role
1458 : : * might own objects in multiple databases, and there is presently no way to
1459 : : * implement cascading to other databases. So we always behave as RESTRICT.
1460 : : *****************************************************************************/
1461 : :
1462 : : DropRoleStmt:
1463 : : DROP ROLE role_list
1464 : : {
1465 : : DropRoleStmt *n = makeNode(DropRoleStmt);
1466 : :
1467 : : n->missing_ok = false;
1468 : : n->roles = $3;
1469 : : $$ = (Node *) n;
1470 : : }
1471 : : | DROP ROLE IF_P EXISTS role_list
1472 : : {
1473 : : DropRoleStmt *n = makeNode(DropRoleStmt);
1474 : :
1475 : : n->missing_ok = true;
1476 : : n->roles = $5;
1477 : : $$ = (Node *) n;
1478 : : }
1479 : : | DROP USER role_list
1480 : : {
1481 : : DropRoleStmt *n = makeNode(DropRoleStmt);
1482 : :
1483 : : n->missing_ok = false;
1484 : : n->roles = $3;
1485 : : $$ = (Node *) n;
1486 : : }
1487 : : | DROP USER IF_P EXISTS role_list
1488 : : {
1489 : : DropRoleStmt *n = makeNode(DropRoleStmt);
1490 : :
1491 : : n->roles = $5;
1492 : : n->missing_ok = true;
1493 : : $$ = (Node *) n;
1494 : : }
1495 : : | DROP GROUP_P role_list
1496 : : {
1497 : : DropRoleStmt *n = makeNode(DropRoleStmt);
1498 : :
1499 : : n->missing_ok = false;
1500 : : n->roles = $3;
1501 : : $$ = (Node *) n;
1502 : : }
1503 : : | DROP GROUP_P IF_P EXISTS role_list
1504 : : {
1505 : : DropRoleStmt *n = makeNode(DropRoleStmt);
1506 : :
1507 : : n->missing_ok = true;
1508 : : n->roles = $5;
1509 : : $$ = (Node *) n;
1510 : : }
1511 : : ;
1512 : :
1513 : :
1514 : : /*****************************************************************************
1515 : : *
1516 : : * Create a postgresql group (role without login ability)
1517 : : *
1518 : : *****************************************************************************/
1519 : :
1520 : : CreateGroupStmt:
1521 : : CREATE GROUP_P RoleId opt_with OptRoleList
1522 : : {
1523 : : CreateRoleStmt *n = makeNode(CreateRoleStmt);
1524 : :
1525 : : n->stmt_type = ROLESTMT_GROUP;
1526 : : n->role = $3;
1527 : : n->options = $5;
1528 : : $$ = (Node *) n;
1529 : : }
1530 : : ;
1531 : :
1532 : :
1533 : : /*****************************************************************************
1534 : : *
1535 : : * Alter a postgresql group
1536 : : *
1537 : : *****************************************************************************/
1538 : :
1539 : : AlterGroupStmt:
1540 : : ALTER GROUP_P RoleSpec add_drop USER role_list
1541 : : {
1542 : : AlterRoleStmt *n = makeNode(AlterRoleStmt);
1543 : :
1544 : : n->role = $3;
1545 : : n->action = $4;
1546 : : n->options = list_make1(makeDefElem("rolemembers",
1547 : : (Node *) $6, @6));
1548 : : $$ = (Node *) n;
1549 : : }
1550 : : ;
1551 : :
1552 : : add_drop: ADD_P { $$ = +1; }
1553 : : | DROP { $$ = -1; }
1554 : : ;
1555 : :
1556 : :
1557 : : /*****************************************************************************
1558 : : *
1559 : : * Manipulate a schema
1560 : : *
1561 : : *****************************************************************************/
1562 : :
1563 : : CreateSchemaStmt:
1564 : : CREATE SCHEMA opt_single_name AUTHORIZATION RoleSpec OptSchemaEltList
1565 : : {
1566 : : CreateSchemaStmt *n = makeNode(CreateSchemaStmt);
1567 : :
1568 : : /* One can omit the schema name or the authorization id. */
1569 : : n->schemaname = $3;
1570 : : n->authrole = $5;
1571 : : n->schemaElts = $6;
1572 : : n->if_not_exists = false;
1573 : : $$ = (Node *) n;
1574 : : }
1575 : : | CREATE SCHEMA ColId OptSchemaEltList
1576 : : {
1577 : : CreateSchemaStmt *n = makeNode(CreateSchemaStmt);
1578 : :
1579 : : /* ...but not both */
1580 : : n->schemaname = $3;
1581 : : n->authrole = NULL;
1582 : : n->schemaElts = $4;
1583 : : n->if_not_exists = false;
1584 : : $$ = (Node *) n;
1585 : : }
1586 : : | CREATE SCHEMA IF_P NOT EXISTS opt_single_name AUTHORIZATION RoleSpec OptSchemaEltList
1587 : : {
1588 : : CreateSchemaStmt *n = makeNode(CreateSchemaStmt);
1589 : :
1590 : : /* schema name can be omitted here, too */
1591 : : n->schemaname = $6;
1592 : : n->authrole = $8;
1593 : : if ($9 != NIL)
1594 : : ereport(ERROR,
1595 : : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1596 : : errmsg("CREATE SCHEMA IF NOT EXISTS cannot include schema elements"),
1597 : : parser_errposition(@9)));
1598 : : n->schemaElts = $9;
1599 : : n->if_not_exists = true;
1600 : : $$ = (Node *) n;
1601 : : }
1602 : : | CREATE SCHEMA IF_P NOT EXISTS ColId OptSchemaEltList
1603 : : {
1604 : : CreateSchemaStmt *n = makeNode(CreateSchemaStmt);
1605 : :
1606 : : /* ...but not here */
1607 : : n->schemaname = $6;
1608 : : n->authrole = NULL;
1609 : : if ($7 != NIL)
1610 : : ereport(ERROR,
1611 : : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1612 : : errmsg("CREATE SCHEMA IF NOT EXISTS cannot include schema elements"),
1613 : : parser_errposition(@7)));
1614 : : n->schemaElts = $7;
1615 : : n->if_not_exists = true;
1616 : : $$ = (Node *) n;
1617 : : }
1618 : : ;
1619 : :
1620 : : OptSchemaEltList:
1621 : : OptSchemaEltList schema_stmt
1622 : : {
1623 : : $$ = lappend($1, $2);
1624 : : }
1625 : : | /* EMPTY */
1626 : : { $$ = NIL; }
1627 : : ;
1628 : :
1629 : : /*
1630 : : * schema_stmt are the ones that can show up inside a CREATE SCHEMA
1631 : : * statement (in addition to by themselves).
1632 : : */
1633 : : schema_stmt:
1634 : : CreateStmt
1635 : : | IndexStmt
1636 : : | CreateSeqStmt
1637 : : | CreateTrigStmt
1638 : : | GrantStmt
1639 : : | ViewStmt
1640 : : ;
1641 : :
1642 : :
1643 : : /*****************************************************************************
1644 : : *
1645 : : * Set PG internal variable
1646 : : * SET name TO 'var_value'
1647 : : * Include SQL syntax (thomas 1997-10-22):
1648 : : * SET TIME ZONE 'var_value'
1649 : : *
1650 : : *****************************************************************************/
1651 : :
1652 : : VariableSetStmt:
1653 : : SET set_rest
1654 : : {
1655 : : VariableSetStmt *n = $2;
1656 : :
1657 : : n->is_local = false;
1658 : : $$ = (Node *) n;
1659 : : }
1660 : : | SET LOCAL set_rest
1661 : : {
1662 : : VariableSetStmt *n = $3;
1663 : :
1664 : : n->is_local = true;
1665 : : $$ = (Node *) n;
1666 : : }
1667 : : | SET SESSION set_rest
1668 : : {
1669 : : VariableSetStmt *n = $3;
1670 : :
1671 : : n->is_local = false;
1672 : : $$ = (Node *) n;
1673 : : }
1674 : : ;
1675 : :
1676 : : set_rest:
1677 : : TRANSACTION transaction_mode_list
1678 : : {
1679 : : VariableSetStmt *n = makeNode(VariableSetStmt);
1680 : :
1681 : : n->kind = VAR_SET_MULTI;
1682 : : n->name = "TRANSACTION";
1683 : : n->args = $2;
1684 : : n->jumble_args = true;
1685 : : n->location = -1;
1686 : : $$ = n;
1687 : : }
1688 : : | SESSION CHARACTERISTICS AS TRANSACTION transaction_mode_list
1689 : : {
1690 : : VariableSetStmt *n = makeNode(VariableSetStmt);
1691 : :
1692 : : n->kind = VAR_SET_MULTI;
1693 : : n->name = "SESSION CHARACTERISTICS";
1694 : : n->args = $5;
1695 : : n->jumble_args = true;
1696 : : n->location = -1;
1697 : : $$ = n;
1698 : : }
1699 : : | set_rest_more
1700 : : ;
1701 : :
1702 : : generic_set:
1703 : : var_name TO var_list
1704 : : {
1705 : : VariableSetStmt *n = makeNode(VariableSetStmt);
1706 : :
1707 : : n->kind = VAR_SET_VALUE;
1708 : : n->name = $1;
1709 : : n->args = $3;
1710 : : n->location = @3;
1711 : : $$ = n;
1712 : : }
1713 : : | var_name '=' var_list
1714 : : {
1715 : : VariableSetStmt *n = makeNode(VariableSetStmt);
1716 : :
1717 : : n->kind = VAR_SET_VALUE;
1718 : : n->name = $1;
1719 : : n->args = $3;
1720 : : n->location = @3;
1721 : : $$ = n;
1722 : : }
1723 : : | var_name TO NULL_P
1724 : : {
1725 : : VariableSetStmt *n = makeNode(VariableSetStmt);
1726 : :
1727 : : n->kind = VAR_SET_VALUE;
1728 : : n->name = $1;
1729 : : n->args = list_make1(makeNullAConst(@3));
1730 : : n->location = @3;
1731 : : $$ = n;
1732 : : }
1733 : : | var_name '=' NULL_P
1734 : : {
1735 : : VariableSetStmt *n = makeNode(VariableSetStmt);
1736 : :
1737 : : n->kind = VAR_SET_VALUE;
1738 : : n->name = $1;
1739 : : n->args = list_make1(makeNullAConst(@3));
1740 : : n->location = @3;
1741 : : $$ = n;
1742 : : }
1743 : : | var_name TO DEFAULT
1744 : : {
1745 : : VariableSetStmt *n = makeNode(VariableSetStmt);
1746 : :
1747 : : n->kind = VAR_SET_DEFAULT;
1748 : : n->name = $1;
1749 : : n->location = -1;
1750 : : $$ = n;
1751 : : }
1752 : : | var_name '=' DEFAULT
1753 : : {
1754 : : VariableSetStmt *n = makeNode(VariableSetStmt);
1755 : :
1756 : : n->kind = VAR_SET_DEFAULT;
1757 : : n->name = $1;
1758 : : n->location = -1;
1759 : : $$ = n;
1760 : : }
1761 : : ;
1762 : :
1763 : : set_rest_more: /* Generic SET syntaxes: */
1764 : : generic_set {$$ = $1;}
1765 : : | var_name FROM CURRENT_P
1766 : : {
1767 : : VariableSetStmt *n = makeNode(VariableSetStmt);
1768 : :
1769 : : n->kind = VAR_SET_CURRENT;
1770 : : n->name = $1;
1771 : : n->location = -1;
1772 : : $$ = n;
1773 : : }
1774 : : /* Special syntaxes mandated by SQL standard: */
1775 : : | TIME ZONE zone_value
1776 : : {
1777 : : VariableSetStmt *n = makeNode(VariableSetStmt);
1778 : :
1779 : : n->kind = VAR_SET_VALUE;
1780 : : n->name = "timezone";
1781 : : n->location = -1;
1782 : : n->jumble_args = true;
1783 : : if ($3 != NULL)
1784 : : n->args = list_make1($3);
1785 : : else
1786 : : n->kind = VAR_SET_DEFAULT;
1787 : : $$ = n;
1788 : : }
1789 : : | CATALOG_P Sconst
1790 : : {
1791 : : ereport(ERROR,
1792 : : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1793 : : errmsg("current database cannot be changed"),
1794 : : parser_errposition(@2)));
1795 : : $$ = NULL; /*not reached*/
1796 : : }
1797 : : | SCHEMA Sconst
1798 : : {
1799 : : VariableSetStmt *n = makeNode(VariableSetStmt);
1800 : :
1801 : : n->kind = VAR_SET_VALUE;
1802 : : n->name = "search_path";
1803 : : n->args = list_make1(makeStringConst($2, @2));
1804 : : n->location = @2;
1805 : : $$ = n;
1806 : : }
1807 : : | NAMES opt_encoding
1808 : : {
1809 : : VariableSetStmt *n = makeNode(VariableSetStmt);
1810 : :
1811 : : n->kind = VAR_SET_VALUE;
1812 : : n->name = "client_encoding";
1813 : : n->location = @2;
1814 : : if ($2 != NULL)
1815 : : n->args = list_make1(makeStringConst($2, @2));
1816 : : else
1817 : : n->kind = VAR_SET_DEFAULT;
1818 : : $$ = n;
1819 : : }
1820 : : | ROLE NonReservedWord_or_Sconst
1821 : : {
1822 : : VariableSetStmt *n = makeNode(VariableSetStmt);
1823 : :
1824 : : n->kind = VAR_SET_VALUE;
1825 : : n->name = "role";
1826 : : n->args = list_make1(makeStringConst($2, @2));
1827 : : n->location = @2;
1828 : : $$ = n;
1829 : : }
1830 : : | SESSION AUTHORIZATION NonReservedWord_or_Sconst
1831 : : {
1832 : : VariableSetStmt *n = makeNode(VariableSetStmt);
1833 : :
1834 : : n->kind = VAR_SET_VALUE;
1835 : : n->name = "session_authorization";
1836 : : n->args = list_make1(makeStringConst($3, @3));
1837 : : n->location = @3;
1838 : : $$ = n;
1839 : : }
1840 : : | SESSION AUTHORIZATION DEFAULT
1841 : : {
1842 : : VariableSetStmt *n = makeNode(VariableSetStmt);
1843 : :
1844 : : n->kind = VAR_SET_DEFAULT;
1845 : : n->name = "session_authorization";
1846 : : n->location = -1;
1847 : : $$ = n;
1848 : : }
1849 : : | XML_P OPTION document_or_content
1850 : : {
1851 : : VariableSetStmt *n = makeNode(VariableSetStmt);
1852 : :
1853 : : n->kind = VAR_SET_VALUE;
1854 : : n->name = "xmloption";
1855 : : n->args = list_make1(makeStringConst($3 == XMLOPTION_DOCUMENT ? "DOCUMENT" : "CONTENT", @3));
1856 : : n->jumble_args = true;
1857 : : n->location = -1;
1858 : : $$ = n;
1859 : : }
1860 : : /* Special syntaxes invented by PostgreSQL: */
1861 : : | TRANSACTION SNAPSHOT Sconst
1862 : : {
1863 : : VariableSetStmt *n = makeNode(VariableSetStmt);
1864 : :
1865 : : n->kind = VAR_SET_MULTI;
1866 : : n->name = "TRANSACTION SNAPSHOT";
1867 : : n->args = list_make1(makeStringConst($3, @3));
1868 : : n->location = @3;
1869 : : $$ = n;
1870 : : }
1871 : : ;
1872 : :
1873 : : var_name: ColId { $$ = $1; }
1874 : : | var_name '.' ColId
1875 : : { $$ = psprintf("%s.%s", $1, $3); }
1876 : : ;
1877 : :
1878 : : var_list: var_value { $$ = list_make1($1); }
1879 : : | var_list ',' var_value { $$ = lappend($1, $3); }
1880 : : ;
1881 : :
1882 : : var_value: opt_boolean_or_string
1883 : : { $$ = makeStringConst($1, @1); }
1884 : : | NumericOnly
1885 : : { $$ = makeAConst($1, @1); }
1886 : : ;
1887 : :
1888 : : iso_level: READ UNCOMMITTED { $$ = "read uncommitted"; }
1889 : : | READ COMMITTED { $$ = "read committed"; }
1890 : : | REPEATABLE READ { $$ = "repeatable read"; }
1891 : : | SERIALIZABLE { $$ = "serializable"; }
1892 : : ;
1893 : :
1894 : : opt_boolean_or_string:
1895 : : TRUE_P { $$ = "true"; }
1896 : : | FALSE_P { $$ = "false"; }
1897 : : | ON { $$ = "on"; }
1898 : : /*
1899 : : * OFF is also accepted as a boolean value, but is handled by
1900 : : * the NonReservedWord rule. The action for booleans and strings
1901 : : * is the same, so we don't need to distinguish them here.
1902 : : */
1903 : : | NonReservedWord_or_Sconst { $$ = $1; }
1904 : : ;
1905 : :
1906 : : /* Timezone values can be:
1907 : : * - a string such as 'pst8pdt'
1908 : : * - an identifier such as "pst8pdt"
1909 : : * - an integer or floating point number
1910 : : * - a time interval per SQL99
1911 : : * ColId gives reduce/reduce errors against ConstInterval and LOCAL,
1912 : : * so use IDENT (meaning we reject anything that is a key word).
1913 : : */
1914 : : zone_value:
1915 : : Sconst
1916 : : {
1917 : : $$ = makeStringConst($1, @1);
1918 : : }
1919 : : | IDENT
1920 : : {
1921 : : $$ = makeStringConst($1, @1);
1922 : : }
1923 : : | ConstInterval Sconst opt_interval
1924 : : {
1925 : : TypeName *t = $1;
1926 : :
1927 : : if ($3 != NIL)
1928 : : {
1929 : : A_Const *n = (A_Const *) linitial($3);
1930 : :
1931 : : if ((n->val.ival.ival & ~(INTERVAL_MASK(HOUR) | INTERVAL_MASK(MINUTE))) != 0)
1932 : : ereport(ERROR,
1933 : : (errcode(ERRCODE_SYNTAX_ERROR),
1934 : : errmsg("time zone interval must be HOUR or HOUR TO MINUTE"),
1935 : : parser_errposition(@3)));
1936 : : }
1937 : : t->typmods = $3;
1938 : : $$ = makeStringConstCast($2, @2, t);
1939 : : }
1940 : : | ConstInterval '(' Iconst ')' Sconst
1941 : : {
1942 : : TypeName *t = $1;
1943 : :
1944 : : t->typmods = list_make2(makeIntConst(INTERVAL_FULL_RANGE, -1),
1945 : : makeIntConst($3, @3));
1946 : : $$ = makeStringConstCast($5, @5, t);
1947 : : }
1948 : : | NumericOnly { $$ = makeAConst($1, @1); }
1949 : : | DEFAULT { $$ = NULL; }
1950 : : | LOCAL { $$ = NULL; }
1951 : : ;
1952 : :
1953 : : opt_encoding:
1954 : : Sconst { $$ = $1; }
1955 : : | DEFAULT { $$ = NULL; }
1956 : : | /*EMPTY*/ { $$ = NULL; }
1957 : : ;
1958 : :
1959 : : NonReservedWord_or_Sconst:
1960 : : NonReservedWord { $$ = $1; }
1961 : : | Sconst { $$ = $1; }
1962 : : ;
1963 : :
1964 : : VariableResetStmt:
1965 : : RESET reset_rest { $$ = (Node *) $2; }
1966 : : ;
1967 : :
1968 : : reset_rest:
1969 : : generic_reset { $$ = $1; }
1970 : : | TIME ZONE
1971 : : {
1972 : : VariableSetStmt *n = makeNode(VariableSetStmt);
1973 : :
1974 : : n->kind = VAR_RESET;
1975 : : n->name = "timezone";
1976 : : n->location = -1;
1977 : : $$ = n;
1978 : : }
1979 : : | TRANSACTION ISOLATION LEVEL
1980 : : {
1981 : : VariableSetStmt *n = makeNode(VariableSetStmt);
1982 : :
1983 : : n->kind = VAR_RESET;
1984 : : n->name = "transaction_isolation";
1985 : : n->location = -1;
1986 : : $$ = n;
1987 : : }
1988 : : | SESSION AUTHORIZATION
1989 : : {
1990 : : VariableSetStmt *n = makeNode(VariableSetStmt);
1991 : :
1992 : : n->kind = VAR_RESET;
1993 : : n->name = "session_authorization";
1994 : : n->location = -1;
1995 : : $$ = n;
1996 : : }
1997 : : ;
1998 : :
1999 : : generic_reset:
2000 : : var_name
2001 : : {
2002 : : VariableSetStmt *n = makeNode(VariableSetStmt);
2003 : :
2004 : : n->kind = VAR_RESET;
2005 : : n->name = $1;
2006 : : n->location = -1;
2007 : : $$ = n;
2008 : : }
2009 : : | ALL
2010 : : {
2011 : : VariableSetStmt *n = makeNode(VariableSetStmt);
2012 : :
2013 : : n->kind = VAR_RESET_ALL;
2014 : : n->location = -1;
2015 : : $$ = n;
2016 : : }
2017 : : ;
2018 : :
2019 : : /* SetResetClause allows SET or RESET without LOCAL */
2020 : : SetResetClause:
2021 : : SET set_rest { $$ = $2; }
2022 : : | VariableResetStmt { $$ = (VariableSetStmt *) $1; }
2023 : : ;
2024 : :
2025 : : /* SetResetClause allows SET or RESET without LOCAL */
2026 : : FunctionSetResetClause:
2027 : : SET set_rest_more { $$ = $2; }
2028 : : | VariableResetStmt { $$ = (VariableSetStmt *) $1; }
2029 : : ;
2030 : :
2031 : :
2032 : : VariableShowStmt:
2033 : : SHOW var_name
2034 : : {
2035 : : VariableShowStmt *n = makeNode(VariableShowStmt);
2036 : :
2037 : : n->name = $2;
2038 : : $$ = (Node *) n;
2039 : : }
2040 : : | SHOW TIME ZONE
2041 : : {
2042 : : VariableShowStmt *n = makeNode(VariableShowStmt);
2043 : :
2044 : : n->name = "timezone";
2045 : : $$ = (Node *) n;
2046 : : }
2047 : : | SHOW TRANSACTION ISOLATION LEVEL
2048 : : {
2049 : : VariableShowStmt *n = makeNode(VariableShowStmt);
2050 : :
2051 : : n->name = "transaction_isolation";
2052 : : $$ = (Node *) n;
2053 : : }
2054 : : | SHOW SESSION AUTHORIZATION
2055 : : {
2056 : : VariableShowStmt *n = makeNode(VariableShowStmt);
2057 : :
2058 : : n->name = "session_authorization";
2059 : : $$ = (Node *) n;
2060 : : }
2061 : : | SHOW ALL
2062 : : {
2063 : : VariableShowStmt *n = makeNode(VariableShowStmt);
2064 : :
2065 : : n->name = "all";
2066 : : $$ = (Node *) n;
2067 : : }
2068 : : ;
2069 : :
2070 : :
2071 : : ConstraintsSetStmt:
2072 : : SET CONSTRAINTS constraints_set_list constraints_set_mode
2073 : : {
2074 : : ConstraintsSetStmt *n = makeNode(ConstraintsSetStmt);
2075 : :
2076 : : n->constraints = $3;
2077 : : n->deferred = $4;
2078 : : $$ = (Node *) n;
2079 : : }
2080 : : ;
2081 : :
2082 : : constraints_set_list:
2083 : : ALL { $$ = NIL; }
2084 : : | qualified_name_list { $$ = $1; }
2085 : : ;
2086 : :
2087 : : constraints_set_mode:
2088 : : DEFERRED { $$ = true; }
2089 : : | IMMEDIATE { $$ = false; }
2090 : : ;
2091 : :
2092 : :
2093 : : /*
2094 : : * Checkpoint statement
2095 : : */
2096 : : CheckPointStmt:
2097 : : CHECKPOINT opt_utility_option_list
2098 : : {
2099 : : CheckPointStmt *n = makeNode(CheckPointStmt);
2100 : :
2101 : : $$ = (Node *) n;
2102 : : n->options = $2;
2103 : : }
2104 : : ;
2105 : :
2106 : :
2107 : : /*****************************************************************************
2108 : : *
2109 : : * DISCARD { ALL | TEMP | PLANS | SEQUENCES }
2110 : : *
2111 : : *****************************************************************************/
2112 : :
2113 : : DiscardStmt:
2114 : : DISCARD ALL
2115 : : {
2116 : : DiscardStmt *n = makeNode(DiscardStmt);
2117 : :
2118 : : n->target = DISCARD_ALL;
2119 : : $$ = (Node *) n;
2120 : : }
2121 : : | DISCARD TEMP
2122 : : {
2123 : : DiscardStmt *n = makeNode(DiscardStmt);
2124 : :
2125 : : n->target = DISCARD_TEMP;
2126 : : $$ = (Node *) n;
2127 : : }
2128 : : | DISCARD TEMPORARY
2129 : : {
2130 : : DiscardStmt *n = makeNode(DiscardStmt);
2131 : :
2132 : : n->target = DISCARD_TEMP;
2133 : : $$ = (Node *) n;
2134 : : }
2135 : : | DISCARD PLANS
2136 : : {
2137 : : DiscardStmt *n = makeNode(DiscardStmt);
2138 : :
2139 : : n->target = DISCARD_PLANS;
2140 : : $$ = (Node *) n;
2141 : : }
2142 : : | DISCARD SEQUENCES
2143 : : {
2144 : : DiscardStmt *n = makeNode(DiscardStmt);
2145 : :
2146 : : n->target = DISCARD_SEQUENCES;
2147 : : $$ = (Node *) n;
2148 : : }
2149 : :
2150 : : ;
2151 : :
2152 : :
2153 : : /*****************************************************************************
2154 : : *
2155 : : * ALTER [ TABLE | INDEX | SEQUENCE | VIEW | MATERIALIZED VIEW | FOREIGN TABLE ] variations
2156 : : *
2157 : : * Note: we accept all subcommands for each of the variants, and sort
2158 : : * out what's really legal at execution time.
2159 : : *****************************************************************************/
2160 : :
2161 : : AlterTableStmt:
2162 : : ALTER TABLE relation_expr alter_table_cmds
2163 : : {
2164 : : AlterTableStmt *n = makeNode(AlterTableStmt);
2165 : :
2166 : : n->relation = $3;
2167 : : n->cmds = $4;
2168 : : n->objtype = OBJECT_TABLE;
2169 : : n->missing_ok = false;
2170 : : $$ = (Node *) n;
2171 : : }
2172 : : | ALTER TABLE IF_P EXISTS relation_expr alter_table_cmds
2173 : : {
2174 : : AlterTableStmt *n = makeNode(AlterTableStmt);
2175 : :
2176 : : n->relation = $5;
2177 : : n->cmds = $6;
2178 : : n->objtype = OBJECT_TABLE;
2179 : : n->missing_ok = true;
2180 : : $$ = (Node *) n;
2181 : : }
2182 : : | ALTER TABLE relation_expr partition_cmd
2183 : : {
2184 : : AlterTableStmt *n = makeNode(AlterTableStmt);
2185 : :
2186 : : n->relation = $3;
2187 : : n->cmds = list_make1($4);
2188 : : n->objtype = OBJECT_TABLE;
2189 : : n->missing_ok = false;
2190 : : $$ = (Node *) n;
2191 : : }
2192 : : | ALTER TABLE IF_P EXISTS relation_expr partition_cmd
2193 : : {
2194 : : AlterTableStmt *n = makeNode(AlterTableStmt);
2195 : :
2196 : : n->relation = $5;
2197 : : n->cmds = list_make1($6);
2198 : : n->objtype = OBJECT_TABLE;
2199 : : n->missing_ok = true;
2200 : : $$ = (Node *) n;
2201 : : }
2202 : : | ALTER TABLE ALL IN_P TABLESPACE name SET TABLESPACE name opt_nowait
2203 : : {
2204 : : AlterTableMoveAllStmt *n =
2205 : : makeNode(AlterTableMoveAllStmt);
2206 : :
2207 : : n->orig_tablespacename = $6;
2208 : : n->objtype = OBJECT_TABLE;
2209 : : n->roles = NIL;
2210 : : n->new_tablespacename = $9;
2211 : : n->nowait = $10;
2212 : : $$ = (Node *) n;
2213 : : }
2214 : : | ALTER TABLE ALL IN_P TABLESPACE name OWNED BY role_list SET TABLESPACE name opt_nowait
2215 : : {
2216 : : AlterTableMoveAllStmt *n =
2217 : : makeNode(AlterTableMoveAllStmt);
2218 : :
2219 : : n->orig_tablespacename = $6;
2220 : : n->objtype = OBJECT_TABLE;
2221 : : n->roles = $9;
2222 : : n->new_tablespacename = $12;
2223 : : n->nowait = $13;
2224 : : $$ = (Node *) n;
2225 : : }
2226 : : | ALTER INDEX qualified_name alter_table_cmds
2227 : : {
2228 : : AlterTableStmt *n = makeNode(AlterTableStmt);
2229 : :
2230 : : n->relation = $3;
2231 : : n->cmds = $4;
2232 : : n->objtype = OBJECT_INDEX;
2233 : : n->missing_ok = false;
2234 : : $$ = (Node *) n;
2235 : : }
2236 : : | ALTER INDEX IF_P EXISTS qualified_name alter_table_cmds
2237 : : {
2238 : : AlterTableStmt *n = makeNode(AlterTableStmt);
2239 : :
2240 : : n->relation = $5;
2241 : : n->cmds = $6;
2242 : : n->objtype = OBJECT_INDEX;
2243 : : n->missing_ok = true;
2244 : : $$ = (Node *) n;
2245 : : }
2246 : : | ALTER INDEX qualified_name index_partition_cmd
2247 : : {
2248 : : AlterTableStmt *n = makeNode(AlterTableStmt);
2249 : :
2250 : : n->relation = $3;
2251 : : n->cmds = list_make1($4);
2252 : : n->objtype = OBJECT_INDEX;
2253 : : n->missing_ok = false;
2254 : : $$ = (Node *) n;
2255 : : }
2256 : : | ALTER INDEX ALL IN_P TABLESPACE name SET TABLESPACE name opt_nowait
2257 : : {
2258 : : AlterTableMoveAllStmt *n =
2259 : : makeNode(AlterTableMoveAllStmt);
2260 : :
2261 : : n->orig_tablespacename = $6;
2262 : : n->objtype = OBJECT_INDEX;
2263 : : n->roles = NIL;
2264 : : n->new_tablespacename = $9;
2265 : : n->nowait = $10;
2266 : : $$ = (Node *) n;
2267 : : }
2268 : : | ALTER INDEX ALL IN_P TABLESPACE name OWNED BY role_list SET TABLESPACE name opt_nowait
2269 : : {
2270 : : AlterTableMoveAllStmt *n =
2271 : : makeNode(AlterTableMoveAllStmt);
2272 : :
2273 : : n->orig_tablespacename = $6;
2274 : : n->objtype = OBJECT_INDEX;
2275 : : n->roles = $9;
2276 : : n->new_tablespacename = $12;
2277 : : n->nowait = $13;
2278 : : $$ = (Node *) n;
2279 : : }
2280 : : | ALTER SEQUENCE qualified_name alter_table_cmds
2281 : : {
2282 : : AlterTableStmt *n = makeNode(AlterTableStmt);
2283 : :
2284 : : n->relation = $3;
2285 : : n->cmds = $4;
2286 : : n->objtype = OBJECT_SEQUENCE;
2287 : : n->missing_ok = false;
2288 : : $$ = (Node *) n;
2289 : : }
2290 : : | ALTER SEQUENCE IF_P EXISTS qualified_name alter_table_cmds
2291 : : {
2292 : : AlterTableStmt *n = makeNode(AlterTableStmt);
2293 : :
2294 : : n->relation = $5;
2295 : : n->cmds = $6;
2296 : : n->objtype = OBJECT_SEQUENCE;
2297 : : n->missing_ok = true;
2298 : : $$ = (Node *) n;
2299 : : }
2300 : : | ALTER VIEW qualified_name alter_table_cmds
2301 : : {
2302 : : AlterTableStmt *n = makeNode(AlterTableStmt);
2303 : :
2304 : : n->relation = $3;
2305 : : n->cmds = $4;
2306 : : n->objtype = OBJECT_VIEW;
2307 : : n->missing_ok = false;
2308 : : $$ = (Node *) n;
2309 : : }
2310 : : | ALTER VIEW IF_P EXISTS qualified_name alter_table_cmds
2311 : : {
2312 : : AlterTableStmt *n = makeNode(AlterTableStmt);
2313 : :
2314 : : n->relation = $5;
2315 : : n->cmds = $6;
2316 : : n->objtype = OBJECT_VIEW;
2317 : : n->missing_ok = true;
2318 : : $$ = (Node *) n;
2319 : : }
2320 : : | ALTER MATERIALIZED VIEW qualified_name alter_table_cmds
2321 : : {
2322 : : AlterTableStmt *n = makeNode(AlterTableStmt);
2323 : :
2324 : : n->relation = $4;
2325 : : n->cmds = $5;
2326 : : n->objtype = OBJECT_MATVIEW;
2327 : : n->missing_ok = false;
2328 : : $$ = (Node *) n;
2329 : : }
2330 : : | ALTER MATERIALIZED VIEW IF_P EXISTS qualified_name alter_table_cmds
2331 : : {
2332 : : AlterTableStmt *n = makeNode(AlterTableStmt);
2333 : :
2334 : : n->relation = $6;
2335 : : n->cmds = $7;
2336 : : n->objtype = OBJECT_MATVIEW;
2337 : : n->missing_ok = true;
2338 : : $$ = (Node *) n;
2339 : : }
2340 : : | ALTER MATERIALIZED VIEW ALL IN_P TABLESPACE name SET TABLESPACE name opt_nowait
2341 : : {
2342 : : AlterTableMoveAllStmt *n =
2343 : : makeNode(AlterTableMoveAllStmt);
2344 : :
2345 : : n->orig_tablespacename = $7;
2346 : : n->objtype = OBJECT_MATVIEW;
2347 : : n->roles = NIL;
2348 : : n->new_tablespacename = $10;
2349 : : n->nowait = $11;
2350 : : $$ = (Node *) n;
2351 : : }
2352 : : | ALTER MATERIALIZED VIEW ALL IN_P TABLESPACE name OWNED BY role_list SET TABLESPACE name opt_nowait
2353 : : {
2354 : : AlterTableMoveAllStmt *n =
2355 : : makeNode(AlterTableMoveAllStmt);
2356 : :
2357 : : n->orig_tablespacename = $7;
2358 : : n->objtype = OBJECT_MATVIEW;
2359 : : n->roles = $10;
2360 : : n->new_tablespacename = $13;
2361 : : n->nowait = $14;
2362 : : $$ = (Node *) n;
2363 : : }
2364 : : | ALTER FOREIGN TABLE relation_expr alter_table_cmds
2365 : : {
2366 : : AlterTableStmt *n = makeNode(AlterTableStmt);
2367 : :
2368 : : n->relation = $4;
2369 : : n->cmds = $5;
2370 : : n->objtype = OBJECT_FOREIGN_TABLE;
2371 : : n->missing_ok = false;
2372 : : $$ = (Node *) n;
2373 : : }
2374 : : | ALTER FOREIGN TABLE IF_P EXISTS relation_expr alter_table_cmds
2375 : : {
2376 : : AlterTableStmt *n = makeNode(AlterTableStmt);
2377 : :
2378 : : n->relation = $6;
2379 : : n->cmds = $7;
2380 : : n->objtype = OBJECT_FOREIGN_TABLE;
2381 : : n->missing_ok = true;
2382 : : $$ = (Node *) n;
2383 : : }
2384 : : ;
2385 : :
2386 : : alter_table_cmds:
2387 : : alter_table_cmd { $$ = list_make1($1); }
2388 : : | alter_table_cmds ',' alter_table_cmd { $$ = lappend($1, $3); }
2389 : : ;
2390 : :
2391 : : partitions_list:
2392 : : SinglePartitionSpec { $$ = list_make1($1); }
2393 : : | partitions_list ',' SinglePartitionSpec { $$ = lappend($1, $3); }
2394 : : ;
2395 : :
2396 : : SinglePartitionSpec:
2397 : : PARTITION qualified_name PartitionBoundSpec
2398 : : {
2399 : : SinglePartitionSpec *n = makeNode(SinglePartitionSpec);
2400 : :
2401 : : n->name = $2;
2402 : : n->bound = $3;
2403 : :
2404 : : $$ = n;
2405 : : }
2406 : : ;
2407 : :
2408 : : partition_cmd:
2409 : : /* ALTER TABLE <name> ATTACH PARTITION <table_name> FOR VALUES */
2410 : : ATTACH PARTITION qualified_name PartitionBoundSpec
2411 : : {
2412 : : AlterTableCmd *n = makeNode(AlterTableCmd);
2413 : : PartitionCmd *cmd = makeNode(PartitionCmd);
2414 : :
2415 : : n->subtype = AT_AttachPartition;
2416 : : cmd->name = $3;
2417 : : cmd->bound = $4;
2418 : : cmd->partlist = NIL;
2419 : : cmd->concurrent = false;
2420 : : n->def = (Node *) cmd;
2421 : :
2422 : : $$ = (Node *) n;
2423 : : }
2424 : : /* ALTER TABLE <name> DETACH PARTITION <partition_name> [CONCURRENTLY] */
2425 : : | DETACH PARTITION qualified_name opt_concurrently
2426 : : {
2427 : : AlterTableCmd *n = makeNode(AlterTableCmd);
2428 : : PartitionCmd *cmd = makeNode(PartitionCmd);
2429 : :
2430 : : n->subtype = AT_DetachPartition;
2431 : : cmd->name = $3;
2432 : : cmd->bound = NULL;
2433 : : cmd->partlist = NIL;
2434 : : cmd->concurrent = $4;
2435 : : n->def = (Node *) cmd;
2436 : :
2437 : : $$ = (Node *) n;
2438 : : }
2439 : : | DETACH PARTITION qualified_name FINALIZE
2440 : : {
2441 : : AlterTableCmd *n = makeNode(AlterTableCmd);
2442 : : PartitionCmd *cmd = makeNode(PartitionCmd);
2443 : :
2444 : : n->subtype = AT_DetachPartitionFinalize;
2445 : : cmd->name = $3;
2446 : : cmd->bound = NULL;
2447 : : cmd->partlist = NIL;
2448 : : cmd->concurrent = false;
2449 : : n->def = (Node *) cmd;
2450 : : $$ = (Node *) n;
2451 : : }
2452 : : /* ALTER TABLE <name> SPLIT PARTITION <partition_name> INTO () */
2453 : : | SPLIT PARTITION qualified_name INTO '(' partitions_list ')'
2454 : : {
2455 : : AlterTableCmd *n = makeNode(AlterTableCmd);
2456 : : PartitionCmd *cmd = makeNode(PartitionCmd);
2457 : :
2458 : : n->subtype = AT_SplitPartition;
2459 : : cmd->name = $3;
2460 : : cmd->bound = NULL;
2461 : : cmd->partlist = $6;
2462 : : cmd->concurrent = false;
2463 : : n->def = (Node *) cmd;
2464 : : $$ = (Node *) n;
2465 : : }
2466 : : /* ALTER TABLE <name> MERGE PARTITIONS () INTO <partition_name> */
2467 : : | MERGE PARTITIONS '(' qualified_name_list ')' INTO qualified_name
2468 : : {
2469 : : AlterTableCmd *n = makeNode(AlterTableCmd);
2470 : : PartitionCmd *cmd = makeNode(PartitionCmd);
2471 : :
2472 : : n->subtype = AT_MergePartitions;
2473 : : cmd->name = $7;
2474 : : cmd->bound = NULL;
2475 : : cmd->partlist = $4;
2476 : : cmd->concurrent = false;
2477 : : n->def = (Node *) cmd;
2478 : : $$ = (Node *) n;
2479 : : }
2480 : : ;
2481 : :
2482 : : index_partition_cmd:
2483 : : /* ALTER INDEX <name> ATTACH PARTITION <index_name> */
2484 : : ATTACH PARTITION qualified_name
2485 : : {
2486 : : AlterTableCmd *n = makeNode(AlterTableCmd);
2487 : : PartitionCmd *cmd = makeNode(PartitionCmd);
2488 : :
2489 : : n->subtype = AT_AttachPartition;
2490 : : cmd->name = $3;
2491 : : cmd->bound = NULL;
2492 : : cmd->partlist = NIL;
2493 : : cmd->concurrent = false;
2494 : : n->def = (Node *) cmd;
2495 : :
2496 : : $$ = (Node *) n;
2497 : : }
2498 : : ;
2499 : :
2500 : : alter_table_cmd:
2501 : : /* ALTER TABLE <name> ADD <coldef> */
2502 : : ADD_P columnDef
2503 : : {
2504 : : AlterTableCmd *n = makeNode(AlterTableCmd);
2505 : :
2506 : : n->subtype = AT_AddColumn;
2507 : : n->def = $2;
2508 : : n->missing_ok = false;
2509 : : $$ = (Node *) n;
2510 : : }
2511 : : /* ALTER TABLE <name> ADD IF NOT EXISTS <coldef> */
2512 : : | ADD_P IF_P NOT EXISTS columnDef
2513 : : {
2514 : : AlterTableCmd *n = makeNode(AlterTableCmd);
2515 : :
2516 : : n->subtype = AT_AddColumn;
2517 : : n->def = $5;
2518 : : n->missing_ok = true;
2519 : : $$ = (Node *) n;
2520 : : }
2521 : : /* ALTER TABLE <name> ADD COLUMN <coldef> */
2522 : : | ADD_P COLUMN columnDef
2523 : : {
2524 : : AlterTableCmd *n = makeNode(AlterTableCmd);
2525 : :
2526 : : n->subtype = AT_AddColumn;
2527 : : n->def = $3;
2528 : : n->missing_ok = false;
2529 : : $$ = (Node *) n;
2530 : : }
2531 : : /* ALTER TABLE <name> ADD COLUMN IF NOT EXISTS <coldef> */
2532 : : | ADD_P COLUMN IF_P NOT EXISTS columnDef
2533 : : {
2534 : : AlterTableCmd *n = makeNode(AlterTableCmd);
2535 : :
2536 : : n->subtype = AT_AddColumn;
2537 : : n->def = $6;
2538 : : n->missing_ok = true;
2539 : : $$ = (Node *) n;
2540 : : }
2541 : : /* ALTER TABLE <name> ALTER [COLUMN] <colname> {SET DEFAULT <expr>|DROP DEFAULT} */
2542 : : | ALTER opt_column ColId alter_column_default
2543 : : {
2544 : : AlterTableCmd *n = makeNode(AlterTableCmd);
2545 : :
2546 : : n->subtype = AT_ColumnDefault;
2547 : : n->name = $3;
2548 : : n->def = $4;
2549 : : $$ = (Node *) n;
2550 : : }
2551 : : /* ALTER TABLE <name> ALTER [COLUMN] <colname> DROP NOT NULL */
2552 : : | ALTER opt_column ColId DROP NOT NULL_P
2553 : : {
2554 : : AlterTableCmd *n = makeNode(AlterTableCmd);
2555 : :
2556 : : n->subtype = AT_DropNotNull;
2557 : : n->name = $3;
2558 : : $$ = (Node *) n;
2559 : : }
2560 : : /* ALTER TABLE <name> ALTER [COLUMN] <colname> SET NOT NULL */
2561 : : | ALTER opt_column ColId SET NOT NULL_P
2562 : : {
2563 : : AlterTableCmd *n = makeNode(AlterTableCmd);
2564 : :
2565 : : n->subtype = AT_SetNotNull;
2566 : : n->name = $3;
2567 : : $$ = (Node *) n;
2568 : : }
2569 : : /* ALTER TABLE <name> ALTER [COLUMN] <colname> SET EXPRESSION AS <expr> */
2570 : : | ALTER opt_column ColId SET EXPRESSION AS '(' a_expr ')'
2571 : : {
2572 : : AlterTableCmd *n = makeNode(AlterTableCmd);
2573 : :
2574 : : n->subtype = AT_SetExpression;
2575 : : n->name = $3;
2576 : : n->def = $8;
2577 : : $$ = (Node *) n;
2578 : : }
2579 : : /* ALTER TABLE <name> ALTER [COLUMN] <colname> DROP EXPRESSION */
2580 : : | ALTER opt_column ColId DROP EXPRESSION
2581 : : {
2582 : : AlterTableCmd *n = makeNode(AlterTableCmd);
2583 : :
2584 : : n->subtype = AT_DropExpression;
2585 : : n->name = $3;
2586 : : $$ = (Node *) n;
2587 : : }
2588 : : /* ALTER TABLE <name> ALTER [COLUMN] <colname> DROP EXPRESSION IF EXISTS */
2589 : : | ALTER opt_column ColId DROP EXPRESSION IF_P EXISTS
2590 : : {
2591 : : AlterTableCmd *n = makeNode(AlterTableCmd);
2592 : :
2593 : : n->subtype = AT_DropExpression;
2594 : : n->name = $3;
2595 : : n->missing_ok = true;
2596 : : $$ = (Node *) n;
2597 : : }
2598 : : /* ALTER TABLE <name> ALTER [COLUMN] <colname> SET STATISTICS */
2599 : : | ALTER opt_column ColId SET STATISTICS set_statistics_value
2600 : : {
2601 : : AlterTableCmd *n = makeNode(AlterTableCmd);
2602 : :
2603 : : n->subtype = AT_SetStatistics;
2604 : : n->name = $3;
2605 : : n->def = $6;
2606 : : $$ = (Node *) n;
2607 : : }
2608 : : /* ALTER TABLE <name> ALTER [COLUMN] <colnum> SET STATISTICS */
2609 : : | ALTER opt_column Iconst SET STATISTICS set_statistics_value
2610 : : {
2611 : : AlterTableCmd *n = makeNode(AlterTableCmd);
2612 : :
2613 : : if ($3 <= 0 || $3 > PG_INT16_MAX)
2614 : : ereport(ERROR,
2615 : : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
2616 : : errmsg("column number must be in range from 1 to %d", PG_INT16_MAX),
2617 : : parser_errposition(@3)));
2618 : :
2619 : : n->subtype = AT_SetStatistics;
2620 : : n->num = (int16) $3;
2621 : : n->def = $6;
2622 : : $$ = (Node *) n;
2623 : : }
2624 : : /* ALTER TABLE <name> ALTER [COLUMN] <colname> SET ( column_parameter = value [, ... ] ) */
2625 : : | ALTER opt_column ColId SET reloptions
2626 : : {
2627 : : AlterTableCmd *n = makeNode(AlterTableCmd);
2628 : :
2629 : : n->subtype = AT_SetOptions;
2630 : : n->name = $3;
2631 : : n->def = (Node *) $5;
2632 : : $$ = (Node *) n;
2633 : : }
2634 : : /* ALTER TABLE <name> ALTER [COLUMN] <colname> RESET ( column_parameter [, ... ] ) */
2635 : : | ALTER opt_column ColId RESET reloptions
2636 : : {
2637 : : AlterTableCmd *n = makeNode(AlterTableCmd);
2638 : :
2639 : : n->subtype = AT_ResetOptions;
2640 : : n->name = $3;
2641 : : n->def = (Node *) $5;
2642 : : $$ = (Node *) n;
2643 : : }
2644 : : /* ALTER TABLE <name> ALTER [COLUMN] <colname> SET STORAGE <storagemode> */
2645 : : | ALTER opt_column ColId SET column_storage
2646 : : {
2647 : : AlterTableCmd *n = makeNode(AlterTableCmd);
2648 : :
2649 : : n->subtype = AT_SetStorage;
2650 : : n->name = $3;
2651 : : n->def = (Node *) makeString($5);
2652 : : $$ = (Node *) n;
2653 : : }
2654 : : /* ALTER TABLE <name> ALTER [COLUMN] <colname> SET COMPRESSION <cm> */
2655 : : | ALTER opt_column ColId SET column_compression
2656 : : {
2657 : : AlterTableCmd *n = makeNode(AlterTableCmd);
2658 : :
2659 : : n->subtype = AT_SetCompression;
2660 : : n->name = $3;
2661 : : n->def = (Node *) makeString($5);
2662 : : $$ = (Node *) n;
2663 : : }
2664 : : /* ALTER TABLE <name> ALTER [COLUMN] <colname> ADD GENERATED ... AS IDENTITY ... */
2665 : : | ALTER opt_column ColId ADD_P GENERATED generated_when AS IDENTITY_P OptParenthesizedSeqOptList
2666 : : {
2667 : : AlterTableCmd *n = makeNode(AlterTableCmd);
2668 : : Constraint *c = makeNode(Constraint);
2669 : :
2670 : : c->contype = CONSTR_IDENTITY;
2671 : : c->generated_when = $6;
2672 : : c->options = $9;
2673 : : c->location = @5;
2674 : :
2675 : : n->subtype = AT_AddIdentity;
2676 : : n->name = $3;
2677 : : n->def = (Node *) c;
2678 : :
2679 : : $$ = (Node *) n;
2680 : : }
2681 : : /* ALTER TABLE <name> ALTER [COLUMN] <colname> SET <sequence options>/RESET */
2682 : : | ALTER opt_column ColId alter_identity_column_option_list
2683 : : {
2684 : : AlterTableCmd *n = makeNode(AlterTableCmd);
2685 : :
2686 : : n->subtype = AT_SetIdentity;
2687 : : n->name = $3;
2688 : : n->def = (Node *) $4;
2689 : : $$ = (Node *) n;
2690 : : }
2691 : : /* ALTER TABLE <name> ALTER [COLUMN] <colname> DROP IDENTITY */
2692 : : | ALTER opt_column ColId DROP IDENTITY_P
2693 : : {
2694 : : AlterTableCmd *n = makeNode(AlterTableCmd);
2695 : :
2696 : : n->subtype = AT_DropIdentity;
2697 : : n->name = $3;
2698 : : n->missing_ok = false;
2699 : : $$ = (Node *) n;
2700 : : }
2701 : : /* ALTER TABLE <name> ALTER [COLUMN] <colname> DROP IDENTITY IF EXISTS */
2702 : : | ALTER opt_column ColId DROP IDENTITY_P IF_P EXISTS
2703 : : {
2704 : : AlterTableCmd *n = makeNode(AlterTableCmd);
2705 : :
2706 : : n->subtype = AT_DropIdentity;
2707 : : n->name = $3;
2708 : : n->missing_ok = true;
2709 : : $$ = (Node *) n;
2710 : : }
2711 : : /* ALTER TABLE <name> DROP [COLUMN] IF EXISTS <colname> [RESTRICT|CASCADE] */
2712 : : | DROP opt_column IF_P EXISTS ColId opt_drop_behavior
2713 : : {
2714 : : AlterTableCmd *n = makeNode(AlterTableCmd);
2715 : :
2716 : : n->subtype = AT_DropColumn;
2717 : : n->name = $5;
2718 : : n->behavior = $6;
2719 : : n->missing_ok = true;
2720 : : $$ = (Node *) n;
2721 : : }
2722 : : /* ALTER TABLE <name> DROP [COLUMN] <colname> [RESTRICT|CASCADE] */
2723 : : | DROP opt_column ColId opt_drop_behavior
2724 : : {
2725 : : AlterTableCmd *n = makeNode(AlterTableCmd);
2726 : :
2727 : : n->subtype = AT_DropColumn;
2728 : : n->name = $3;
2729 : : n->behavior = $4;
2730 : : n->missing_ok = false;
2731 : : $$ = (Node *) n;
2732 : : }
2733 : : /*
2734 : : * ALTER TABLE <name> ALTER [COLUMN] <colname> [SET DATA] TYPE <typename>
2735 : : * [ USING <expression> ]
2736 : : */
2737 : : | ALTER opt_column ColId opt_set_data TYPE_P Typename opt_collate_clause alter_using
2738 : : {
2739 : : AlterTableCmd *n = makeNode(AlterTableCmd);
2740 : : ColumnDef *def = makeNode(ColumnDef);
2741 : :
2742 : : n->subtype = AT_AlterColumnType;
2743 : : n->name = $3;
2744 : : n->def = (Node *) def;
2745 : : /* We only use these fields of the ColumnDef node */
2746 : : def->typeName = $6;
2747 : : def->collClause = (CollateClause *) $7;
2748 : : def->raw_default = $8;
2749 : : def->location = @3;
2750 : : $$ = (Node *) n;
2751 : : }
2752 : : /* ALTER FOREIGN TABLE <name> ALTER [COLUMN] <colname> OPTIONS */
2753 : : | ALTER opt_column ColId alter_generic_options
2754 : : {
2755 : : AlterTableCmd *n = makeNode(AlterTableCmd);
2756 : :
2757 : : n->subtype = AT_AlterColumnGenericOptions;
2758 : : n->name = $3;
2759 : : n->def = (Node *) $4;
2760 : : $$ = (Node *) n;
2761 : : }
2762 : : /* ALTER TABLE <name> ADD CONSTRAINT ... */
2763 : : | ADD_P TableConstraint
2764 : : {
2765 : : AlterTableCmd *n = makeNode(AlterTableCmd);
2766 : :
2767 : : n->subtype = AT_AddConstraint;
2768 : : n->def = $2;
2769 : : $$ = (Node *) n;
2770 : : }
2771 : : /* ALTER TABLE <name> ALTER CONSTRAINT ... */
2772 : : | ALTER CONSTRAINT name ConstraintAttributeSpec
2773 : : {
2774 : : AlterTableCmd *n = makeNode(AlterTableCmd);
2775 : : ATAlterConstraint *c = makeNode(ATAlterConstraint);
2776 : :
2777 : : n->subtype = AT_AlterConstraint;
2778 : : n->def = (Node *) c;
2779 : : c->conname = $3;
2780 : : if ($4 & (CAS_NOT_ENFORCED | CAS_ENFORCED))
2781 : : c->alterEnforceability = true;
2782 : : if ($4 & (CAS_DEFERRABLE | CAS_NOT_DEFERRABLE |
2783 : : CAS_INITIALLY_DEFERRED | CAS_INITIALLY_IMMEDIATE))
2784 : : c->alterDeferrability = true;
2785 : : if ($4 & CAS_NO_INHERIT)
2786 : : c->alterInheritability = true;
2787 : : /* handle unsupported case with specific error message */
2788 : : if ($4 & CAS_NOT_VALID)
2789 : : ereport(ERROR,
2790 : : errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2791 : : errmsg("constraints cannot be altered to be NOT VALID"),
2792 : : parser_errposition(@4));
2793 : : processCASbits($4, @4, "FOREIGN KEY",
2794 : : &c->deferrable,
2795 : : &c->initdeferred,
2796 : : &c->is_enforced,
2797 : : NULL,
2798 : : &c->noinherit,
2799 : : yyscanner);
2800 : : $$ = (Node *) n;
2801 : : }
2802 : : /* ALTER TABLE <name> ALTER CONSTRAINT INHERIT */
2803 : : | ALTER CONSTRAINT name INHERIT
2804 : : {
2805 : : AlterTableCmd *n = makeNode(AlterTableCmd);
2806 : : ATAlterConstraint *c = makeNode(ATAlterConstraint);
2807 : :
2808 : : n->subtype = AT_AlterConstraint;
2809 : : n->def = (Node *) c;
2810 : : c->conname = $3;
2811 : : c->alterInheritability = true;
2812 : : c->noinherit = false;
2813 : :
2814 : : $$ = (Node *) n;
2815 : : }
2816 : : /* ALTER TABLE <name> VALIDATE CONSTRAINT ... */
2817 : : | VALIDATE CONSTRAINT name
2818 : : {
2819 : : AlterTableCmd *n = makeNode(AlterTableCmd);
2820 : :
2821 : : n->subtype = AT_ValidateConstraint;
2822 : : n->name = $3;
2823 : : $$ = (Node *) n;
2824 : : }
2825 : : /* ALTER TABLE <name> DROP CONSTRAINT IF EXISTS <name> [RESTRICT|CASCADE] */
2826 : : | DROP CONSTRAINT IF_P EXISTS name opt_drop_behavior
2827 : : {
2828 : : AlterTableCmd *n = makeNode(AlterTableCmd);
2829 : :
2830 : : n->subtype = AT_DropConstraint;
2831 : : n->name = $5;
2832 : : n->behavior = $6;
2833 : : n->missing_ok = true;
2834 : : $$ = (Node *) n;
2835 : : }
2836 : : /* ALTER TABLE <name> DROP CONSTRAINT <name> [RESTRICT|CASCADE] */
2837 : : | DROP CONSTRAINT name opt_drop_behavior
2838 : : {
2839 : : AlterTableCmd *n = makeNode(AlterTableCmd);
2840 : :
2841 : : n->subtype = AT_DropConstraint;
2842 : : n->name = $3;
2843 : : n->behavior = $4;
2844 : : n->missing_ok = false;
2845 : : $$ = (Node *) n;
2846 : : }
2847 : : /* ALTER TABLE <name> SET WITHOUT OIDS, for backward compat */
2848 : : | SET WITHOUT OIDS
2849 : : {
2850 : : AlterTableCmd *n = makeNode(AlterTableCmd);
2851 : :
2852 : : n->subtype = AT_DropOids;
2853 : : $$ = (Node *) n;
2854 : : }
2855 : : /* ALTER TABLE <name> CLUSTER ON <indexname> */
2856 : : | CLUSTER ON name
2857 : : {
2858 : : AlterTableCmd *n = makeNode(AlterTableCmd);
2859 : :
2860 : : n->subtype = AT_ClusterOn;
2861 : : n->name = $3;
2862 : : $$ = (Node *) n;
2863 : : }
2864 : : /* ALTER TABLE <name> SET WITHOUT CLUSTER */
2865 : : | SET WITHOUT CLUSTER
2866 : : {
2867 : : AlterTableCmd *n = makeNode(AlterTableCmd);
2868 : :
2869 : : n->subtype = AT_DropCluster;
2870 : : n->name = NULL;
2871 : : $$ = (Node *) n;
2872 : : }
2873 : : /* ALTER TABLE <name> SET LOGGED */
2874 : : | SET LOGGED
2875 : : {
2876 : : AlterTableCmd *n = makeNode(AlterTableCmd);
2877 : :
2878 : : n->subtype = AT_SetLogged;
2879 : : $$ = (Node *) n;
2880 : : }
2881 : : /* ALTER TABLE <name> SET UNLOGGED */
2882 : : | SET UNLOGGED
2883 : : {
2884 : : AlterTableCmd *n = makeNode(AlterTableCmd);
2885 : :
2886 : : n->subtype = AT_SetUnLogged;
2887 : : $$ = (Node *) n;
2888 : : }
2889 : : /* ALTER TABLE <name> ENABLE TRIGGER <trig> */
2890 : : | ENABLE_P TRIGGER name
2891 : : {
2892 : : AlterTableCmd *n = makeNode(AlterTableCmd);
2893 : :
2894 : : n->subtype = AT_EnableTrig;
2895 : : n->name = $3;
2896 : : $$ = (Node *) n;
2897 : : }
2898 : : /* ALTER TABLE <name> ENABLE ALWAYS TRIGGER <trig> */
2899 : : | ENABLE_P ALWAYS TRIGGER name
2900 : : {
2901 : : AlterTableCmd *n = makeNode(AlterTableCmd);
2902 : :
2903 : : n->subtype = AT_EnableAlwaysTrig;
2904 : : n->name = $4;
2905 : : $$ = (Node *) n;
2906 : : }
2907 : : /* ALTER TABLE <name> ENABLE REPLICA TRIGGER <trig> */
2908 : : | ENABLE_P REPLICA TRIGGER name
2909 : : {
2910 : : AlterTableCmd *n = makeNode(AlterTableCmd);
2911 : :
2912 : : n->subtype = AT_EnableReplicaTrig;
2913 : : n->name = $4;
2914 : : $$ = (Node *) n;
2915 : : }
2916 : : /* ALTER TABLE <name> ENABLE TRIGGER ALL */
2917 : : | ENABLE_P TRIGGER ALL
2918 : : {
2919 : : AlterTableCmd *n = makeNode(AlterTableCmd);
2920 : :
2921 : : n->subtype = AT_EnableTrigAll;
2922 : : $$ = (Node *) n;
2923 : : }
2924 : : /* ALTER TABLE <name> ENABLE TRIGGER USER */
2925 : : | ENABLE_P TRIGGER USER
2926 : : {
2927 : : AlterTableCmd *n = makeNode(AlterTableCmd);
2928 : :
2929 : : n->subtype = AT_EnableTrigUser;
2930 : : $$ = (Node *) n;
2931 : : }
2932 : : /* ALTER TABLE <name> DISABLE TRIGGER <trig> */
2933 : : | DISABLE_P TRIGGER name
2934 : : {
2935 : : AlterTableCmd *n = makeNode(AlterTableCmd);
2936 : :
2937 : : n->subtype = AT_DisableTrig;
2938 : : n->name = $3;
2939 : : $$ = (Node *) n;
2940 : : }
2941 : : /* ALTER TABLE <name> DISABLE TRIGGER ALL */
2942 : : | DISABLE_P TRIGGER ALL
2943 : : {
2944 : : AlterTableCmd *n = makeNode(AlterTableCmd);
2945 : :
2946 : : n->subtype = AT_DisableTrigAll;
2947 : : $$ = (Node *) n;
2948 : : }
2949 : : /* ALTER TABLE <name> DISABLE TRIGGER USER */
2950 : : | DISABLE_P TRIGGER USER
2951 : : {
2952 : : AlterTableCmd *n = makeNode(AlterTableCmd);
2953 : :
2954 : : n->subtype = AT_DisableTrigUser;
2955 : : $$ = (Node *) n;
2956 : : }
2957 : : /* ALTER TABLE <name> ENABLE RULE <rule> */
2958 : : | ENABLE_P RULE name
2959 : : {
2960 : : AlterTableCmd *n = makeNode(AlterTableCmd);
2961 : :
2962 : : n->subtype = AT_EnableRule;
2963 : : n->name = $3;
2964 : : $$ = (Node *) n;
2965 : : }
2966 : : /* ALTER TABLE <name> ENABLE ALWAYS RULE <rule> */
2967 : : | ENABLE_P ALWAYS RULE name
2968 : : {
2969 : : AlterTableCmd *n = makeNode(AlterTableCmd);
2970 : :
2971 : : n->subtype = AT_EnableAlwaysRule;
2972 : : n->name = $4;
2973 : : $$ = (Node *) n;
2974 : : }
2975 : : /* ALTER TABLE <name> ENABLE REPLICA RULE <rule> */
2976 : : | ENABLE_P REPLICA RULE name
2977 : : {
2978 : : AlterTableCmd *n = makeNode(AlterTableCmd);
2979 : :
2980 : : n->subtype = AT_EnableReplicaRule;
2981 : : n->name = $4;
2982 : : $$ = (Node *) n;
2983 : : }
2984 : : /* ALTER TABLE <name> DISABLE RULE <rule> */
2985 : : | DISABLE_P RULE name
2986 : : {
2987 : : AlterTableCmd *n = makeNode(AlterTableCmd);
2988 : :
2989 : : n->subtype = AT_DisableRule;
2990 : : n->name = $3;
2991 : : $$ = (Node *) n;
2992 : : }
2993 : : /* ALTER TABLE <name> INHERIT <parent> */
2994 : : | INHERIT qualified_name
2995 : : {
2996 : : AlterTableCmd *n = makeNode(AlterTableCmd);
2997 : :
2998 : : n->subtype = AT_AddInherit;
2999 : : n->def = (Node *) $2;
3000 : : $$ = (Node *) n;
3001 : : }
3002 : : /* ALTER TABLE <name> NO INHERIT <parent> */
3003 : : | NO INHERIT qualified_name
3004 : : {
3005 : : AlterTableCmd *n = makeNode(AlterTableCmd);
3006 : :
3007 : : n->subtype = AT_DropInherit;
3008 : : n->def = (Node *) $3;
3009 : : $$ = (Node *) n;
3010 : : }
3011 : : /* ALTER TABLE <name> OF <type_name> */
3012 : : | OF any_name
3013 : : {
3014 : : AlterTableCmd *n = makeNode(AlterTableCmd);
3015 : : TypeName *def = makeTypeNameFromNameList($2);
3016 : :
3017 : : def->location = @2;
3018 : : n->subtype = AT_AddOf;
3019 : : n->def = (Node *) def;
3020 : : $$ = (Node *) n;
3021 : : }
3022 : : /* ALTER TABLE <name> NOT OF */
3023 : : | NOT OF
3024 : : {
3025 : : AlterTableCmd *n = makeNode(AlterTableCmd);
3026 : :
3027 : : n->subtype = AT_DropOf;
3028 : : $$ = (Node *) n;
3029 : : }
3030 : : /* ALTER TABLE <name> OWNER TO RoleSpec */
3031 : : | OWNER TO RoleSpec
3032 : : {
3033 : : AlterTableCmd *n = makeNode(AlterTableCmd);
3034 : :
3035 : : n->subtype = AT_ChangeOwner;
3036 : : n->newowner = $3;
3037 : : $$ = (Node *) n;
3038 : : }
3039 : : /* ALTER TABLE <name> SET ACCESS METHOD { <amname> | DEFAULT } */
3040 : : | SET ACCESS METHOD set_access_method_name
3041 : : {
3042 : : AlterTableCmd *n = makeNode(AlterTableCmd);
3043 : :
3044 : : n->subtype = AT_SetAccessMethod;
3045 : : n->name = $4;
3046 : : $$ = (Node *) n;
3047 : : }
3048 : : /* ALTER TABLE <name> SET TABLESPACE <tablespacename> */
3049 : : | SET TABLESPACE name
3050 : : {
3051 : : AlterTableCmd *n = makeNode(AlterTableCmd);
3052 : :
3053 : : n->subtype = AT_SetTableSpace;
3054 : : n->name = $3;
3055 : : $$ = (Node *) n;
3056 : : }
3057 : : /* ALTER TABLE <name> SET (...) */
3058 : : | SET reloptions
3059 : : {
3060 : : AlterTableCmd *n = makeNode(AlterTableCmd);
3061 : :
3062 : : n->subtype = AT_SetRelOptions;
3063 : : n->def = (Node *) $2;
3064 : : $$ = (Node *) n;
3065 : : }
3066 : : /* ALTER TABLE <name> RESET (...) */
3067 : : | RESET reloptions
3068 : : {
3069 : : AlterTableCmd *n = makeNode(AlterTableCmd);
3070 : :
3071 : : n->subtype = AT_ResetRelOptions;
3072 : : n->def = (Node *) $2;
3073 : : $$ = (Node *) n;
3074 : : }
3075 : : /* ALTER TABLE <name> REPLICA IDENTITY */
3076 : : | REPLICA IDENTITY_P replica_identity
3077 : : {
3078 : : AlterTableCmd *n = makeNode(AlterTableCmd);
3079 : :
3080 : : n->subtype = AT_ReplicaIdentity;
3081 : : n->def = $3;
3082 : : $$ = (Node *) n;
3083 : : }
3084 : : /* ALTER TABLE <name> ENABLE ROW LEVEL SECURITY */
3085 : : | ENABLE_P ROW LEVEL SECURITY
3086 : : {
3087 : : AlterTableCmd *n = makeNode(AlterTableCmd);
3088 : :
3089 : : n->subtype = AT_EnableRowSecurity;
3090 : : $$ = (Node *) n;
3091 : : }
3092 : : /* ALTER TABLE <name> DISABLE ROW LEVEL SECURITY */
3093 : : | DISABLE_P ROW LEVEL SECURITY
3094 : : {
3095 : : AlterTableCmd *n = makeNode(AlterTableCmd);
3096 : :
3097 : : n->subtype = AT_DisableRowSecurity;
3098 : : $$ = (Node *) n;
3099 : : }
3100 : : /* ALTER TABLE <name> FORCE ROW LEVEL SECURITY */
3101 : : | FORCE ROW LEVEL SECURITY
3102 : : {
3103 : : AlterTableCmd *n = makeNode(AlterTableCmd);
3104 : :
3105 : : n->subtype = AT_ForceRowSecurity;
3106 : : $$ = (Node *) n;
3107 : : }
3108 : : /* ALTER TABLE <name> NO FORCE ROW LEVEL SECURITY */
3109 : : | NO FORCE ROW LEVEL SECURITY
3110 : : {
3111 : : AlterTableCmd *n = makeNode(AlterTableCmd);
3112 : :
3113 : : n->subtype = AT_NoForceRowSecurity;
3114 : : $$ = (Node *) n;
3115 : : }
3116 : : | alter_generic_options
3117 : : {
3118 : : AlterTableCmd *n = makeNode(AlterTableCmd);
3119 : :
3120 : : n->subtype = AT_GenericOptions;
3121 : : n->def = (Node *) $1;
3122 : : $$ = (Node *) n;
3123 : : }
3124 : : ;
3125 : :
3126 : : alter_column_default:
3127 : : SET DEFAULT a_expr { $$ = $3; }
3128 : : | DROP DEFAULT { $$ = NULL; }
3129 : : ;
3130 : :
3131 : : opt_collate_clause:
3132 : : COLLATE any_name
3133 : : {
3134 : : CollateClause *n = makeNode(CollateClause);
3135 : :
3136 : : n->arg = NULL;
3137 : : n->collname = $2;
3138 : : n->location = @1;
3139 : : $$ = (Node *) n;
3140 : : }
3141 : : | /* EMPTY */ { $$ = NULL; }
3142 : : ;
3143 : :
3144 : : alter_using:
3145 : : USING a_expr { $$ = $2; }
3146 : : | /* EMPTY */ { $$ = NULL; }
3147 : : ;
3148 : :
3149 : : replica_identity:
3150 : : NOTHING
3151 : : {
3152 : : ReplicaIdentityStmt *n = makeNode(ReplicaIdentityStmt);
3153 : :
3154 : : n->identity_type = REPLICA_IDENTITY_NOTHING;
3155 : : n->name = NULL;
3156 : : $$ = (Node *) n;
3157 : : }
3158 : : | FULL
3159 : : {
3160 : : ReplicaIdentityStmt *n = makeNode(ReplicaIdentityStmt);
3161 : :
3162 : : n->identity_type = REPLICA_IDENTITY_FULL;
3163 : : n->name = NULL;
3164 : : $$ = (Node *) n;
3165 : : }
3166 : : | DEFAULT
3167 : : {
3168 : : ReplicaIdentityStmt *n = makeNode(ReplicaIdentityStmt);
3169 : :
3170 : : n->identity_type = REPLICA_IDENTITY_DEFAULT;
3171 : : n->name = NULL;
3172 : : $$ = (Node *) n;
3173 : : }
3174 : : | USING INDEX name
3175 : : {
3176 : : ReplicaIdentityStmt *n = makeNode(ReplicaIdentityStmt);
3177 : :
3178 : : n->identity_type = REPLICA_IDENTITY_INDEX;
3179 : : n->name = $3;
3180 : : $$ = (Node *) n;
3181 : : }
3182 : : ;
3183 : :
3184 : : reloptions:
3185 : : '(' reloption_list ')' { $$ = $2; }
3186 : : ;
3187 : :
3188 : : opt_reloptions: WITH reloptions { $$ = $2; }
3189 : : | /* EMPTY */ { $$ = NIL; }
3190 : : ;
3191 : :
3192 : : reloption_list:
3193 : : reloption_elem { $$ = list_make1($1); }
3194 : : | reloption_list ',' reloption_elem { $$ = lappend($1, $3); }
3195 : : ;
3196 : :
3197 : : /* This should match def_elem and also allow qualified names */
3198 : : reloption_elem:
3199 : : ColLabel '=' def_arg
3200 : : {
3201 : : $$ = makeDefElem($1, (Node *) $3, @1);
3202 : : }
3203 : : | ColLabel
3204 : : {
3205 : : $$ = makeDefElem($1, NULL, @1);
3206 : : }
3207 : : | ColLabel '.' ColLabel '=' def_arg
3208 : : {
3209 : : $$ = makeDefElemExtended($1, $3, (Node *) $5,
3210 : : DEFELEM_UNSPEC, @1);
3211 : : }
3212 : : | ColLabel '.' ColLabel
3213 : : {
3214 : : $$ = makeDefElemExtended($1, $3, NULL, DEFELEM_UNSPEC, @1);
3215 : : }
3216 : : ;
3217 : :
3218 : : alter_identity_column_option_list:
3219 : : alter_identity_column_option
3220 : : { $$ = list_make1($1); }
3221 : : | alter_identity_column_option_list alter_identity_column_option
3222 : : { $$ = lappend($1, $2); }
3223 : : ;
3224 : :
3225 : : alter_identity_column_option:
3226 : : RESTART
3227 : : {
3228 : : $$ = makeDefElem("restart", NULL, @1);
3229 : : }
3230 : : | RESTART opt_with NumericOnly
3231 : : {
3232 : : $$ = makeDefElem("restart", (Node *) $3, @1);
3233 : : }
3234 : : | SET SeqOptElem
3235 : : {
3236 : : if (strcmp($2->defname, "as") == 0 ||
3237 : : strcmp($2->defname, "restart") == 0 ||
3238 : : strcmp($2->defname, "owned_by") == 0)
3239 : : ereport(ERROR,
3240 : : (errcode(ERRCODE_SYNTAX_ERROR),
3241 : : errmsg("sequence option \"%s\" not supported here", $2->defname),
3242 : : parser_errposition(@2)));
3243 : : $$ = $2;
3244 : : }
3245 : : | SET GENERATED generated_when
3246 : : {
3247 : : $$ = makeDefElem("generated", (Node *) makeInteger($3), @1);
3248 : : }
3249 : : ;
3250 : :
3251 : : set_statistics_value:
3252 : : SignedIconst { $$ = (Node *) makeInteger($1); }
3253 : : | DEFAULT { $$ = NULL; }
3254 : : ;
3255 : :
3256 : : set_access_method_name:
3257 : : ColId { $$ = $1; }
3258 : : | DEFAULT { $$ = NULL; }
3259 : : ;
3260 : :
3261 : : PartitionBoundSpec:
3262 : : /* a HASH partition */
3263 : : FOR VALUES WITH '(' hash_partbound ')'
3264 : : {
3265 : : ListCell *lc;
3266 : : PartitionBoundSpec *n = makeNode(PartitionBoundSpec);
3267 : :
3268 : : n->strategy = PARTITION_STRATEGY_HASH;
3269 : : n->modulus = n->remainder = -1;
3270 : :
3271 : : foreach (lc, $5)
3272 : : {
3273 : : DefElem *opt = lfirst_node(DefElem, lc);
3274 : :
3275 : : if (strcmp(opt->defname, "modulus") == 0)
3276 : : {
3277 : : if (n->modulus != -1)
3278 : : ereport(ERROR,
3279 : : (errcode(ERRCODE_DUPLICATE_OBJECT),
3280 : : errmsg("modulus for hash partition provided more than once"),
3281 : : parser_errposition(opt->location)));
3282 : : n->modulus = defGetInt32(opt);
3283 : : }
3284 : : else if (strcmp(opt->defname, "remainder") == 0)
3285 : : {
3286 : : if (n->remainder != -1)
3287 : : ereport(ERROR,
3288 : : (errcode(ERRCODE_DUPLICATE_OBJECT),
3289 : : errmsg("remainder for hash partition provided more than once"),
3290 : : parser_errposition(opt->location)));
3291 : : n->remainder = defGetInt32(opt);
3292 : : }
3293 : : else
3294 : : ereport(ERROR,
3295 : : (errcode(ERRCODE_SYNTAX_ERROR),
3296 : : errmsg("unrecognized hash partition bound specification \"%s\"",
3297 : : opt->defname),
3298 : : parser_errposition(opt->location)));
3299 : : }
3300 : :
3301 : : if (n->modulus == -1)
3302 : : ereport(ERROR,
3303 : : (errcode(ERRCODE_SYNTAX_ERROR),
3304 : : errmsg("modulus for hash partition must be specified"),
3305 : : parser_errposition(@3)));
3306 : : if (n->remainder == -1)
3307 : : ereport(ERROR,
3308 : : (errcode(ERRCODE_SYNTAX_ERROR),
3309 : : errmsg("remainder for hash partition must be specified"),
3310 : : parser_errposition(@3)));
3311 : :
3312 : : n->location = @3;
3313 : :
3314 : : $$ = n;
3315 : : }
3316 : :
3317 : : /* a LIST partition */
3318 : : | FOR VALUES IN_P '(' expr_list ')'
3319 : : {
3320 : : PartitionBoundSpec *n = makeNode(PartitionBoundSpec);
3321 : :
3322 : : n->strategy = PARTITION_STRATEGY_LIST;
3323 : : n->is_default = false;
3324 : : n->listdatums = $5;
3325 : : n->location = @3;
3326 : :
3327 : : $$ = n;
3328 : : }
3329 : :
3330 : : /* a RANGE partition */
3331 : : | FOR VALUES FROM '(' expr_list ')' TO '(' expr_list ')'
3332 : : {
3333 : : PartitionBoundSpec *n = makeNode(PartitionBoundSpec);
3334 : :
3335 : : n->strategy = PARTITION_STRATEGY_RANGE;
3336 : : n->is_default = false;
3337 : : n->lowerdatums = $5;
3338 : : n->upperdatums = $9;
3339 : : n->location = @3;
3340 : :
3341 : : $$ = n;
3342 : : }
3343 : :
3344 : : /* a DEFAULT partition */
3345 : : | DEFAULT
3346 : : {
3347 : : PartitionBoundSpec *n = makeNode(PartitionBoundSpec);
3348 : :
3349 : : n->is_default = true;
3350 : : n->location = @1;
3351 : :
3352 : : $$ = n;
3353 : : }
3354 : : ;
3355 : :
3356 : : hash_partbound_elem:
3357 : : NonReservedWord Iconst
3358 : : {
3359 : : $$ = makeDefElem($1, (Node *) makeInteger($2), @1);
3360 : : }
3361 : : ;
3362 : :
3363 : : hash_partbound:
3364 : : hash_partbound_elem
3365 : : {
3366 : : $$ = list_make1($1);
3367 : : }
3368 : : | hash_partbound ',' hash_partbound_elem
3369 : : {
3370 : : $$ = lappend($1, $3);
3371 : : }
3372 : : ;
3373 : :
3374 : : /*****************************************************************************
3375 : : *
3376 : : * ALTER TYPE
3377 : : *
3378 : : * really variants of the ALTER TABLE subcommands with different spellings
3379 : : *****************************************************************************/
3380 : :
3381 : : AlterCompositeTypeStmt:
3382 : : ALTER TYPE_P any_name alter_type_cmds
3383 : : {
3384 : : AlterTableStmt *n = makeNode(AlterTableStmt);
3385 : :
3386 : : /* can't use qualified_name, sigh */
3387 : : n->relation = makeRangeVarFromAnyName($3, @3, yyscanner);
3388 : : n->cmds = $4;
3389 : : n->objtype = OBJECT_TYPE;
3390 : : $$ = (Node *) n;
3391 : : }
3392 : : ;
3393 : :
3394 : : alter_type_cmds:
3395 : : alter_type_cmd { $$ = list_make1($1); }
3396 : : | alter_type_cmds ',' alter_type_cmd { $$ = lappend($1, $3); }
3397 : : ;
3398 : :
3399 : : alter_type_cmd:
3400 : : /* ALTER TYPE <name> ADD ATTRIBUTE <coldef> [RESTRICT|CASCADE] */
3401 : : ADD_P ATTRIBUTE TableFuncElement opt_drop_behavior
3402 : : {
3403 : : AlterTableCmd *n = makeNode(AlterTableCmd);
3404 : :
3405 : : n->subtype = AT_AddColumn;
3406 : : n->def = $3;
3407 : : n->behavior = $4;
3408 : : $$ = (Node *) n;
3409 : : }
3410 : : /* ALTER TYPE <name> DROP ATTRIBUTE IF EXISTS <attname> [RESTRICT|CASCADE] */
3411 : : | DROP ATTRIBUTE IF_P EXISTS ColId opt_drop_behavior
3412 : : {
3413 : : AlterTableCmd *n = makeNode(AlterTableCmd);
3414 : :
3415 : : n->subtype = AT_DropColumn;
3416 : : n->name = $5;
3417 : : n->behavior = $6;
3418 : : n->missing_ok = true;
3419 : : $$ = (Node *) n;
3420 : : }
3421 : : /* ALTER TYPE <name> DROP ATTRIBUTE <attname> [RESTRICT|CASCADE] */
3422 : : | DROP ATTRIBUTE ColId opt_drop_behavior
3423 : : {
3424 : : AlterTableCmd *n = makeNode(AlterTableCmd);
3425 : :
3426 : : n->subtype = AT_DropColumn;
3427 : : n->name = $3;
3428 : : n->behavior = $4;
3429 : : n->missing_ok = false;
3430 : : $$ = (Node *) n;
3431 : : }
3432 : : /* ALTER TYPE <name> ALTER ATTRIBUTE <attname> [SET DATA] TYPE <typename> [RESTRICT|CASCADE] */
3433 : : | ALTER ATTRIBUTE ColId opt_set_data TYPE_P Typename opt_collate_clause opt_drop_behavior
3434 : : {
3435 : : AlterTableCmd *n = makeNode(AlterTableCmd);
3436 : : ColumnDef *def = makeNode(ColumnDef);
3437 : :
3438 : : n->subtype = AT_AlterColumnType;
3439 : : n->name = $3;
3440 : : n->def = (Node *) def;
3441 : : n->behavior = $8;
3442 : : /* We only use these fields of the ColumnDef node */
3443 : : def->typeName = $6;
3444 : : def->collClause = (CollateClause *) $7;
3445 : : def->raw_default = NULL;
3446 : : def->location = @3;
3447 : : $$ = (Node *) n;
3448 : : }
3449 : : ;
3450 : :
3451 : :
3452 : : /*****************************************************************************
3453 : : *
3454 : : * QUERY :
3455 : : * close <portalname>
3456 : : *
3457 : : *****************************************************************************/
3458 : :
3459 : : ClosePortalStmt:
3460 : : CLOSE cursor_name
3461 : : {
3462 : : ClosePortalStmt *n = makeNode(ClosePortalStmt);
3463 : :
3464 : : n->portalname = $2;
3465 : : $$ = (Node *) n;
3466 : : }
3467 : : | CLOSE ALL
3468 : : {
3469 : : ClosePortalStmt *n = makeNode(ClosePortalStmt);
3470 : :
3471 : : n->portalname = NULL;
3472 : : $$ = (Node *) n;
3473 : : }
3474 : : ;
3475 : :
3476 : :
3477 : : /*****************************************************************************
3478 : : *
3479 : : * QUERY :
3480 : : * COPY relname [(columnList)] FROM/TO file [WITH] [(options)]
3481 : : * COPY ( query ) TO file [WITH] [(options)]
3482 : : *
3483 : : * where 'query' can be one of:
3484 : : * { SELECT | UPDATE | INSERT | DELETE | MERGE }
3485 : : *
3486 : : * and 'file' can be one of:
3487 : : * { PROGRAM 'command' | STDIN | STDOUT | 'filename' }
3488 : : *
3489 : : * In the preferred syntax the options are comma-separated
3490 : : * and use generic identifiers instead of keywords. The pre-9.0
3491 : : * syntax had a hard-wired, space-separated set of options.
3492 : : *
3493 : : * Really old syntax, from versions 7.2 and prior:
3494 : : * COPY [ BINARY ] table FROM/TO file
3495 : : * [ [ USING ] DELIMITERS 'delimiter' ] ]
3496 : : * [ WITH NULL AS 'null string' ]
3497 : : * This option placement is not supported with COPY (query...).
3498 : : *
3499 : : *****************************************************************************/
3500 : :
3501 : : CopyStmt: COPY opt_binary qualified_name opt_column_list
3502 : : copy_from opt_program copy_file_name copy_delimiter opt_with
3503 : : copy_options where_clause
3504 : : {
3505 : : CopyStmt *n = makeNode(CopyStmt);
3506 : :
3507 : : n->relation = $3;
3508 : : n->query = NULL;
3509 : : n->attlist = $4;
3510 : : n->is_from = $5;
3511 : : n->is_program = $6;
3512 : : n->filename = $7;
3513 : : n->whereClause = $11;
3514 : :
3515 : : if (n->is_program && n->filename == NULL)
3516 : : ereport(ERROR,
3517 : : (errcode(ERRCODE_SYNTAX_ERROR),
3518 : : errmsg("STDIN/STDOUT not allowed with PROGRAM"),
3519 : : parser_errposition(@8)));
3520 : :
3521 : : if (!n->is_from && n->whereClause != NULL)
3522 : : ereport(ERROR,
3523 : : (errcode(ERRCODE_SYNTAX_ERROR),
3524 : : errmsg("WHERE clause not allowed with COPY TO"),
3525 : : errhint("Try the COPY (SELECT ... WHERE ...) TO variant."),
3526 : : parser_errposition(@11)));
3527 : :
3528 : : n->options = NIL;
3529 : : /* Concatenate user-supplied flags */
3530 : : if ($2)
3531 : : n->options = lappend(n->options, $2);
3532 : : if ($8)
3533 : : n->options = lappend(n->options, $8);
3534 : : if ($10)
3535 : : n->options = list_concat(n->options, $10);
3536 : : $$ = (Node *) n;
3537 : : }
3538 : : | COPY '(' PreparableStmt ')' TO opt_program copy_file_name opt_with copy_options
3539 : : {
3540 : : CopyStmt *n = makeNode(CopyStmt);
3541 : :
3542 : : n->relation = NULL;
3543 : : n->query = $3;
3544 : : n->attlist = NIL;
3545 : : n->is_from = false;
3546 : : n->is_program = $6;
3547 : : n->filename = $7;
3548 : : n->options = $9;
3549 : :
3550 : : if (n->is_program && n->filename == NULL)
3551 : : ereport(ERROR,
3552 : : (errcode(ERRCODE_SYNTAX_ERROR),
3553 : : errmsg("STDIN/STDOUT not allowed with PROGRAM"),
3554 : : parser_errposition(@5)));
3555 : :
3556 : : $$ = (Node *) n;
3557 : : }
3558 : : ;
3559 : :
3560 : : copy_from:
3561 : : FROM { $$ = true; }
3562 : : | TO { $$ = false; }
3563 : : ;
3564 : :
3565 : : opt_program:
3566 : : PROGRAM { $$ = true; }
3567 : : | /* EMPTY */ { $$ = false; }
3568 : : ;
3569 : :
3570 : : /*
3571 : : * copy_file_name NULL indicates stdio is used. Whether stdin or stdout is
3572 : : * used depends on the direction. (It really doesn't make sense to copy from
3573 : : * stdout. We silently correct the "typo".) - AY 9/94
3574 : : */
3575 : : copy_file_name:
3576 : : Sconst { $$ = $1; }
3577 : : | STDIN { $$ = NULL; }
3578 : : | STDOUT { $$ = NULL; }
3579 : : ;
3580 : :
3581 : : copy_options: copy_opt_list { $$ = $1; }
3582 : : | '(' copy_generic_opt_list ')' { $$ = $2; }
3583 : : ;
3584 : :
3585 : : /* old COPY option syntax */
3586 : : copy_opt_list:
3587 : : copy_opt_list copy_opt_item { $$ = lappend($1, $2); }
3588 : : | /* EMPTY */ { $$ = NIL; }
3589 : : ;
3590 : :
3591 : : copy_opt_item:
3592 : : BINARY
3593 : : {
3594 : : $$ = makeDefElem("format", (Node *) makeString("binary"), @1);
3595 : : }
3596 : : | FREEZE
3597 : : {
3598 : : $$ = makeDefElem("freeze", (Node *) makeBoolean(true), @1);
3599 : : }
3600 : : | DELIMITER opt_as Sconst
3601 : : {
3602 : : $$ = makeDefElem("delimiter", (Node *) makeString($3), @1);
3603 : : }
3604 : : | NULL_P opt_as Sconst
3605 : : {
3606 : : $$ = makeDefElem("null", (Node *) makeString($3), @1);
3607 : : }
3608 : : | CSV
3609 : : {
3610 : : $$ = makeDefElem("format", (Node *) makeString("csv"), @1);
3611 : : }
3612 : : | HEADER_P
3613 : : {
3614 : : $$ = makeDefElem("header", (Node *) makeBoolean(true), @1);
3615 : : }
3616 : : | QUOTE opt_as Sconst
3617 : : {
3618 : : $$ = makeDefElem("quote", (Node *) makeString($3), @1);
3619 : : }
3620 : : | ESCAPE opt_as Sconst
3621 : : {
3622 : : $$ = makeDefElem("escape", (Node *) makeString($3), @1);
3623 : : }
3624 : : | FORCE QUOTE columnList
3625 : : {
3626 : : $$ = makeDefElem("force_quote", (Node *) $3, @1);
3627 : : }
3628 : : | FORCE QUOTE '*'
3629 : : {
3630 : : $$ = makeDefElem("force_quote", (Node *) makeNode(A_Star), @1);
3631 : : }
3632 : : | FORCE NOT NULL_P columnList
3633 : : {
3634 : : $$ = makeDefElem("force_not_null", (Node *) $4, @1);
3635 : : }
3636 : : | FORCE NOT NULL_P '*'
3637 : : {
3638 : : $$ = makeDefElem("force_not_null", (Node *) makeNode(A_Star), @1);
3639 : : }
3640 : : | FORCE NULL_P columnList
3641 : : {
3642 : : $$ = makeDefElem("force_null", (Node *) $3, @1);
3643 : : }
3644 : : | FORCE NULL_P '*'
3645 : : {
3646 : : $$ = makeDefElem("force_null", (Node *) makeNode(A_Star), @1);
3647 : : }
3648 : : | ENCODING Sconst
3649 : : {
3650 : : $$ = makeDefElem("encoding", (Node *) makeString($2), @1);
3651 : : }
3652 : : ;
3653 : :
3654 : : /* The following exist for backward compatibility with very old versions */
3655 : :
3656 : : opt_binary:
3657 : : BINARY
3658 : : {
3659 : : $$ = makeDefElem("format", (Node *) makeString("binary"), @1);
3660 : : }
3661 : : | /*EMPTY*/ { $$ = NULL; }
3662 : : ;
3663 : :
3664 : : copy_delimiter:
3665 : : opt_using DELIMITERS Sconst
3666 : : {
3667 : : $$ = makeDefElem("delimiter", (Node *) makeString($3), @2);
3668 : : }
3669 : : | /*EMPTY*/ { $$ = NULL; }
3670 : : ;
3671 : :
3672 : : opt_using:
3673 : : USING
3674 : : | /*EMPTY*/
3675 : : ;
3676 : :
3677 : : /* new COPY option syntax */
3678 : : copy_generic_opt_list:
3679 : : copy_generic_opt_elem
3680 : : {
3681 : : $$ = list_make1($1);
3682 : : }
3683 : : | copy_generic_opt_list ',' copy_generic_opt_elem
3684 : : {
3685 : : $$ = lappend($1, $3);
3686 : : }
3687 : : ;
3688 : :
3689 : : copy_generic_opt_elem:
3690 : : ColLabel copy_generic_opt_arg
3691 : : {
3692 : : $$ = makeDefElem($1, $2, @1);
3693 : : }
3694 : : ;
3695 : :
3696 : : copy_generic_opt_arg:
3697 : : opt_boolean_or_string { $$ = (Node *) makeString($1); }
3698 : : | NumericOnly { $$ = (Node *) $1; }
3699 : : | '*' { $$ = (Node *) makeNode(A_Star); }
3700 : : | DEFAULT { $$ = (Node *) makeString("default"); }
3701 : : | '(' copy_generic_opt_arg_list ')' { $$ = (Node *) $2; }
3702 : : | /* EMPTY */ { $$ = NULL; }
3703 : : ;
3704 : :
3705 : : copy_generic_opt_arg_list:
3706 : : copy_generic_opt_arg_list_item
3707 : : {
3708 : : $$ = list_make1($1);
3709 : : }
3710 : : | copy_generic_opt_arg_list ',' copy_generic_opt_arg_list_item
3711 : : {
3712 : : $$ = lappend($1, $3);
3713 : : }
3714 : : ;
3715 : :
3716 : : /* beware of emitting non-string list elements here; see commands/define.c */
3717 : : copy_generic_opt_arg_list_item:
3718 : : opt_boolean_or_string { $$ = (Node *) makeString($1); }
3719 : : ;
3720 : :
3721 : :
3722 : : /*****************************************************************************
3723 : : *
3724 : : * QUERY :
3725 : : * CREATE TABLE relname
3726 : : *
3727 : : *****************************************************************************/
3728 : :
3729 : : CreateStmt: CREATE OptTemp TABLE qualified_name '(' OptTableElementList ')'
3730 : : OptInherit OptPartitionSpec table_access_method_clause OptWith
3731 : : OnCommitOption OptTableSpace
3732 : : {
3733 : : CreateStmt *n = makeNode(CreateStmt);
3734 : :
3735 : : $4->relpersistence = $2;
3736 : : n->relation = $4;
3737 : : n->tableElts = $6;
3738 : : n->inhRelations = $8;
3739 : : n->partspec = $9;
3740 : : n->ofTypename = NULL;
3741 : : n->constraints = NIL;
3742 : : n->accessMethod = $10;
3743 : : n->options = $11;
3744 : : n->oncommit = $12;
3745 : : n->tablespacename = $13;
3746 : : n->if_not_exists = false;
3747 : : $$ = (Node *) n;
3748 : : }
3749 : : | CREATE OptTemp TABLE IF_P NOT EXISTS qualified_name '('
3750 : : OptTableElementList ')' OptInherit OptPartitionSpec table_access_method_clause
3751 : : OptWith OnCommitOption OptTableSpace
3752 : : {
3753 : : CreateStmt *n = makeNode(CreateStmt);
3754 : :
3755 : : $7->relpersistence = $2;
3756 : : n->relation = $7;
3757 : : n->tableElts = $9;
3758 : : n->inhRelations = $11;
3759 : : n->partspec = $12;
3760 : : n->ofTypename = NULL;
3761 : : n->constraints = NIL;
3762 : : n->accessMethod = $13;
3763 : : n->options = $14;
3764 : : n->oncommit = $15;
3765 : : n->tablespacename = $16;
3766 : : n->if_not_exists = true;
3767 : : $$ = (Node *) n;
3768 : : }
3769 : : | CREATE OptTemp TABLE qualified_name OF any_name
3770 : : OptTypedTableElementList OptPartitionSpec table_access_method_clause
3771 : : OptWith OnCommitOption OptTableSpace
3772 : : {
3773 : : CreateStmt *n = makeNode(CreateStmt);
3774 : :
3775 : : $4->relpersistence = $2;
3776 : : n->relation = $4;
3777 : : n->tableElts = $7;
3778 : : n->inhRelations = NIL;
3779 : : n->partspec = $8;
3780 : : n->ofTypename = makeTypeNameFromNameList($6);
3781 : : n->ofTypename->location = @6;
3782 : : n->constraints = NIL;
3783 : : n->accessMethod = $9;
3784 : : n->options = $10;
3785 : : n->oncommit = $11;
3786 : : n->tablespacename = $12;
3787 : : n->if_not_exists = false;
3788 : : $$ = (Node *) n;
3789 : : }
3790 : : | CREATE OptTemp TABLE IF_P NOT EXISTS qualified_name OF any_name
3791 : : OptTypedTableElementList OptPartitionSpec table_access_method_clause
3792 : : OptWith OnCommitOption OptTableSpace
3793 : : {
3794 : : CreateStmt *n = makeNode(CreateStmt);
3795 : :
3796 : : $7->relpersistence = $2;
3797 : : n->relation = $7;
3798 : : n->tableElts = $10;
3799 : : n->inhRelations = NIL;
3800 : : n->partspec = $11;
3801 : : n->ofTypename = makeTypeNameFromNameList($9);
3802 : : n->ofTypename->location = @9;
3803 : : n->constraints = NIL;
3804 : : n->accessMethod = $12;
3805 : : n->options = $13;
3806 : : n->oncommit = $14;
3807 : : n->tablespacename = $15;
3808 : : n->if_not_exists = true;
3809 : : $$ = (Node *) n;
3810 : : }
3811 : : | CREATE OptTemp TABLE qualified_name PARTITION OF qualified_name
3812 : : OptTypedTableElementList PartitionBoundSpec OptPartitionSpec
3813 : : table_access_method_clause OptWith OnCommitOption OptTableSpace
3814 : : {
3815 : : CreateStmt *n = makeNode(CreateStmt);
3816 : :
3817 : : $4->relpersistence = $2;
3818 : : n->relation = $4;
3819 : : n->tableElts = $8;
3820 : : n->inhRelations = list_make1($7);
3821 : : n->partbound = $9;
3822 : : n->partspec = $10;
3823 : : n->ofTypename = NULL;
3824 : : n->constraints = NIL;
3825 : : n->accessMethod = $11;
3826 : : n->options = $12;
3827 : : n->oncommit = $13;
3828 : : n->tablespacename = $14;
3829 : : n->if_not_exists = false;
3830 : : $$ = (Node *) n;
3831 : : }
3832 : : | CREATE OptTemp TABLE IF_P NOT EXISTS qualified_name PARTITION OF
3833 : : qualified_name OptTypedTableElementList PartitionBoundSpec OptPartitionSpec
3834 : : table_access_method_clause OptWith OnCommitOption OptTableSpace
3835 : : {
3836 : : CreateStmt *n = makeNode(CreateStmt);
3837 : :
3838 : : $7->relpersistence = $2;
3839 : : n->relation = $7;
3840 : : n->tableElts = $11;
3841 : : n->inhRelations = list_make1($10);
3842 : : n->partbound = $12;
3843 : : n->partspec = $13;
3844 : : n->ofTypename = NULL;
3845 : : n->constraints = NIL;
3846 : : n->accessMethod = $14;
3847 : : n->options = $15;
3848 : : n->oncommit = $16;
3849 : : n->tablespacename = $17;
3850 : : n->if_not_exists = true;
3851 : : $$ = (Node *) n;
3852 : : }
3853 : : ;
3854 : :
3855 : : /*
3856 : : * Redundancy here is needed to avoid shift/reduce conflicts,
3857 : : * since TEMP is not a reserved word. See also OptTempTableName.
3858 : : *
3859 : : * NOTE: we accept both GLOBAL and LOCAL options. They currently do nothing,
3860 : : * but future versions might consider GLOBAL to request SQL-spec-compliant
3861 : : * temp table behavior, so warn about that. Since we have no modules the
3862 : : * LOCAL keyword is really meaningless; furthermore, some other products
3863 : : * implement LOCAL as meaning the same as our default temp table behavior,
3864 : : * so we'll probably continue to treat LOCAL as a noise word.
3865 : : */
3866 : : OptTemp: TEMPORARY { $$ = RELPERSISTENCE_TEMP; }
3867 : : | TEMP { $$ = RELPERSISTENCE_TEMP; }
3868 : : | LOCAL TEMPORARY { $$ = RELPERSISTENCE_TEMP; }
3869 : : | LOCAL TEMP { $$ = RELPERSISTENCE_TEMP; }
3870 : : | GLOBAL TEMPORARY
3871 : : {
3872 : : ereport(WARNING,
3873 : : (errmsg("GLOBAL is deprecated in temporary table creation"),
3874 : : parser_errposition(@1)));
3875 : : $$ = RELPERSISTENCE_TEMP;
3876 : : }
3877 : : | GLOBAL TEMP
3878 : : {
3879 : : ereport(WARNING,
3880 : : (errmsg("GLOBAL is deprecated in temporary table creation"),
3881 : : parser_errposition(@1)));
3882 : : $$ = RELPERSISTENCE_TEMP;
3883 : : }
3884 : : | UNLOGGED { $$ = RELPERSISTENCE_UNLOGGED; }
3885 : : | /*EMPTY*/ { $$ = RELPERSISTENCE_PERMANENT; }
3886 : : ;
3887 : :
3888 : : OptTableElementList:
3889 : : TableElementList { $$ = $1; }
3890 : : | /*EMPTY*/ { $$ = NIL; }
3891 : : ;
3892 : :
3893 : : OptTypedTableElementList:
3894 : : '(' TypedTableElementList ')' { $$ = $2; }
3895 : : | /*EMPTY*/ { $$ = NIL; }
3896 : : ;
3897 : :
3898 : : TableElementList:
3899 : : TableElement
3900 : : {
3901 : : $$ = list_make1($1);
3902 : : }
3903 : : | TableElementList ',' TableElement
3904 : : {
3905 : : $$ = lappend($1, $3);
3906 : : }
3907 : : ;
3908 : :
3909 : : TypedTableElementList:
3910 : : TypedTableElement
3911 : : {
3912 : : $$ = list_make1($1);
3913 : : }
3914 : : | TypedTableElementList ',' TypedTableElement
3915 : : {
3916 : : $$ = lappend($1, $3);
3917 : : }
3918 : : ;
3919 : :
3920 : : TableElement:
3921 : : columnDef { $$ = $1; }
3922 : : | TableLikeClause { $$ = $1; }
3923 : : | TableConstraint { $$ = $1; }
3924 : : ;
3925 : :
3926 : : TypedTableElement:
3927 : : columnOptions { $$ = $1; }
3928 : : | TableConstraint { $$ = $1; }
3929 : : ;
3930 : :
3931 : : columnDef: ColId Typename opt_column_storage opt_column_compression create_generic_options ColQualList
3932 : : {
3933 : : ColumnDef *n = makeNode(ColumnDef);
3934 : :
3935 : : n->colname = $1;
3936 : : n->typeName = $2;
3937 : : n->storage_name = $3;
3938 : : n->compression = $4;
3939 : : n->inhcount = 0;
3940 : : n->is_local = true;
3941 : : n->is_not_null = false;
3942 : : n->is_from_type = false;
3943 : : n->storage = 0;
3944 : : n->raw_default = NULL;
3945 : : n->cooked_default = NULL;
3946 : : n->collOid = InvalidOid;
3947 : : n->fdwoptions = $5;
3948 : : SplitColQualList($6, &n->constraints, &n->collClause,
3949 : : yyscanner);
3950 : : n->location = @1;
3951 : : $$ = (Node *) n;
3952 : : }
3953 : : ;
3954 : :
3955 : : columnOptions: ColId ColQualList
3956 : : {
3957 : : ColumnDef *n = makeNode(ColumnDef);
3958 : :
3959 : : n->colname = $1;
3960 : : n->typeName = NULL;
3961 : : n->inhcount = 0;
3962 : : n->is_local = true;
3963 : : n->is_not_null = false;
3964 : : n->is_from_type = false;
3965 : : n->storage = 0;
3966 : : n->raw_default = NULL;
3967 : : n->cooked_default = NULL;
3968 : : n->collOid = InvalidOid;
3969 : : SplitColQualList($2, &n->constraints, &n->collClause,
3970 : : yyscanner);
3971 : : n->location = @1;
3972 : : $$ = (Node *) n;
3973 : : }
3974 : : | ColId WITH OPTIONS ColQualList
3975 : : {
3976 : : ColumnDef *n = makeNode(ColumnDef);
3977 : :
3978 : : n->colname = $1;
3979 : : n->typeName = NULL;
3980 : : n->inhcount = 0;
3981 : : n->is_local = true;
3982 : : n->is_not_null = false;
3983 : : n->is_from_type = false;
3984 : : n->storage = 0;
3985 : : n->raw_default = NULL;
3986 : : n->cooked_default = NULL;
3987 : : n->collOid = InvalidOid;
3988 : : SplitColQualList($4, &n->constraints, &n->collClause,
3989 : : yyscanner);
3990 : : n->location = @1;
3991 : : $$ = (Node *) n;
3992 : : }
3993 : : ;
3994 : :
3995 : : column_compression:
3996 : : COMPRESSION ColId { $$ = $2; }
3997 : : | COMPRESSION DEFAULT { $$ = pstrdup("default"); }
3998 : : ;
3999 : :
4000 : : opt_column_compression:
4001 : : column_compression { $$ = $1; }
4002 : : | /*EMPTY*/ { $$ = NULL; }
4003 : : ;
4004 : :
4005 : : column_storage:
4006 : : STORAGE ColId { $$ = $2; }
4007 : : | STORAGE DEFAULT { $$ = pstrdup("default"); }
4008 : : ;
4009 : :
4010 : : opt_column_storage:
4011 : : column_storage { $$ = $1; }
4012 : : | /*EMPTY*/ { $$ = NULL; }
4013 : : ;
4014 : :
4015 : : ColQualList:
4016 : : ColQualList ColConstraint { $$ = lappend($1, $2); }
4017 : : | /*EMPTY*/ { $$ = NIL; }
4018 : : ;
4019 : :
4020 : : ColConstraint:
4021 : : CONSTRAINT name ColConstraintElem
4022 : : {
4023 : : Constraint *n = castNode(Constraint, $3);
4024 : :
4025 : : n->conname = $2;
4026 : : n->location = @1;
4027 : : $$ = (Node *) n;
4028 : : }
4029 : : | ColConstraintElem { $$ = $1; }
4030 : : | ConstraintAttr { $$ = $1; }
4031 : : | COLLATE any_name
4032 : : {
4033 : : /*
4034 : : * Note: the CollateClause is momentarily included in
4035 : : * the list built by ColQualList, but we split it out
4036 : : * again in SplitColQualList.
4037 : : */
4038 : : CollateClause *n = makeNode(CollateClause);
4039 : :
4040 : : n->arg = NULL;
4041 : : n->collname = $2;
4042 : : n->location = @1;
4043 : : $$ = (Node *) n;
4044 : : }
4045 : : ;
4046 : :
4047 : : /* DEFAULT NULL is already the default for Postgres.
4048 : : * But define it here and carry it forward into the system
4049 : : * to make it explicit.
4050 : : * - thomas 1998-09-13
4051 : : *
4052 : : * WITH NULL and NULL are not SQL-standard syntax elements,
4053 : : * so leave them out. Use DEFAULT NULL to explicitly indicate
4054 : : * that a column may have that value. WITH NULL leads to
4055 : : * shift/reduce conflicts with WITH TIME ZONE anyway.
4056 : : * - thomas 1999-01-08
4057 : : *
4058 : : * DEFAULT expression must be b_expr not a_expr to prevent shift/reduce
4059 : : * conflict on NOT (since NOT might start a subsequent NOT NULL constraint,
4060 : : * or be part of a_expr NOT LIKE or similar constructs).
4061 : : */
4062 : : ColConstraintElem:
4063 : : NOT NULL_P opt_no_inherit
4064 : : {
4065 : : Constraint *n = makeNode(Constraint);
4066 : :
4067 : : n->contype = CONSTR_NOTNULL;
4068 : : n->location = @1;
4069 : : n->is_no_inherit = $3;
4070 : : n->is_enforced = true;
4071 : : n->skip_validation = false;
4072 : : n->initially_valid = true;
4073 : : $$ = (Node *) n;
4074 : : }
4075 : : | NULL_P
4076 : : {
4077 : : Constraint *n = makeNode(Constraint);
4078 : :
4079 : : n->contype = CONSTR_NULL;
4080 : : n->location = @1;
4081 : : $$ = (Node *) n;
4082 : : }
4083 : : | UNIQUE opt_unique_null_treatment opt_definition OptConsTableSpace
4084 : : {
4085 : : Constraint *n = makeNode(Constraint);
4086 : :
4087 : : n->contype = CONSTR_UNIQUE;
4088 : : n->location = @1;
4089 : : n->nulls_not_distinct = !$2;
4090 : : n->keys = NULL;
4091 : : n->options = $3;
4092 : : n->indexname = NULL;
4093 : : n->indexspace = $4;
4094 : : $$ = (Node *) n;
4095 : : }
4096 : : | PRIMARY KEY opt_definition OptConsTableSpace
4097 : : {
4098 : : Constraint *n = makeNode(Constraint);
4099 : :
4100 : : n->contype = CONSTR_PRIMARY;
4101 : : n->location = @1;
4102 : : n->keys = NULL;
4103 : : n->options = $3;
4104 : : n->indexname = NULL;
4105 : : n->indexspace = $4;
4106 : : $$ = (Node *) n;
4107 : : }
4108 : : | CHECK '(' a_expr ')' opt_no_inherit
4109 : : {
4110 : : Constraint *n = makeNode(Constraint);
4111 : :
4112 : : n->contype = CONSTR_CHECK;
4113 : : n->location = @1;
4114 : : n->is_no_inherit = $5;
4115 : : n->raw_expr = $3;
4116 : : n->cooked_expr = NULL;
4117 : : n->is_enforced = true;
4118 : : n->skip_validation = false;
4119 : : n->initially_valid = true;
4120 : : $$ = (Node *) n;
4121 : : }
4122 : : | DEFAULT b_expr
4123 : : {
4124 : : Constraint *n = makeNode(Constraint);
4125 : :
4126 : : n->contype = CONSTR_DEFAULT;
4127 : : n->location = @1;
4128 : : n->raw_expr = $2;
4129 : : n->cooked_expr = NULL;
4130 : : $$ = (Node *) n;
4131 : : }
4132 : : | GENERATED generated_when AS IDENTITY_P OptParenthesizedSeqOptList
4133 : : {
4134 : : Constraint *n = makeNode(Constraint);
4135 : :
4136 : : n->contype = CONSTR_IDENTITY;
4137 : : n->generated_when = $2;
4138 : : n->options = $5;
4139 : : n->location = @1;
4140 : : $$ = (Node *) n;
4141 : : }
4142 : : | GENERATED generated_when AS '(' a_expr ')' opt_virtual_or_stored
4143 : : {
4144 : : Constraint *n = makeNode(Constraint);
4145 : :
4146 : : n->contype = CONSTR_GENERATED;
4147 : : n->generated_when = $2;
4148 : : n->raw_expr = $5;
4149 : : n->cooked_expr = NULL;
4150 : : n->generated_kind = $7;
4151 : : n->location = @1;
4152 : :
4153 : : /*
4154 : : * Can't do this in the grammar because of shift/reduce
4155 : : * conflicts. (IDENTITY allows both ALWAYS and BY
4156 : : * DEFAULT, but generated columns only allow ALWAYS.) We
4157 : : * can also give a more useful error message and location.
4158 : : */
4159 : : if ($2 != ATTRIBUTE_IDENTITY_ALWAYS)
4160 : : ereport(ERROR,
4161 : : (errcode(ERRCODE_SYNTAX_ERROR),
4162 : : errmsg("for a generated column, GENERATED ALWAYS must be specified"),
4163 : : parser_errposition(@2)));
4164 : :
4165 : : $$ = (Node *) n;
4166 : : }
4167 : : | REFERENCES qualified_name opt_column_list key_match key_actions
4168 : : {
4169 : : Constraint *n = makeNode(Constraint);
4170 : :
4171 : : n->contype = CONSTR_FOREIGN;
4172 : : n->location = @1;
4173 : : n->pktable = $2;
4174 : : n->fk_attrs = NIL;
4175 : : n->pk_attrs = $3;
4176 : : n->fk_matchtype = $4;
4177 : : n->fk_upd_action = ($5)->updateAction->action;
4178 : : n->fk_del_action = ($5)->deleteAction->action;
4179 : : n->fk_del_set_cols = ($5)->deleteAction->cols;
4180 : : n->is_enforced = true;
4181 : : n->skip_validation = false;
4182 : : n->initially_valid = true;
4183 : : $$ = (Node *) n;
4184 : : }
4185 : : ;
4186 : :
4187 : : opt_unique_null_treatment:
4188 : : NULLS_P DISTINCT { $$ = true; }
4189 : : | NULLS_P NOT DISTINCT { $$ = false; }
4190 : : | /*EMPTY*/ { $$ = true; }
4191 : : ;
4192 : :
4193 : : generated_when:
4194 : : ALWAYS { $$ = ATTRIBUTE_IDENTITY_ALWAYS; }
4195 : : | BY DEFAULT { $$ = ATTRIBUTE_IDENTITY_BY_DEFAULT; }
4196 : : ;
4197 : :
4198 : : opt_virtual_or_stored:
4199 : : STORED { $$ = ATTRIBUTE_GENERATED_STORED; }
4200 : : | VIRTUAL { $$ = ATTRIBUTE_GENERATED_VIRTUAL; }
4201 : : | /*EMPTY*/ { $$ = ATTRIBUTE_GENERATED_VIRTUAL; }
4202 : : ;
4203 : :
4204 : : /*
4205 : : * ConstraintAttr represents constraint attributes, which we parse as if
4206 : : * they were independent constraint clauses, in order to avoid shift/reduce
4207 : : * conflicts (since NOT might start either an independent NOT NULL clause
4208 : : * or an attribute). parse_utilcmd.c is responsible for attaching the
4209 : : * attribute information to the preceding "real" constraint node, and for
4210 : : * complaining if attribute clauses appear in the wrong place or wrong
4211 : : * combinations.
4212 : : *
4213 : : * See also ConstraintAttributeSpec, which can be used in places where
4214 : : * there is no parsing conflict. (Note: currently, NOT VALID and NO INHERIT
4215 : : * are allowed clauses in ConstraintAttributeSpec, but not here. Someday we
4216 : : * might need to allow them here too, but for the moment it doesn't seem
4217 : : * useful in the statements that use ConstraintAttr.)
4218 : : */
4219 : : ConstraintAttr:
4220 : : DEFERRABLE
4221 : : {
4222 : : Constraint *n = makeNode(Constraint);
4223 : :
4224 : : n->contype = CONSTR_ATTR_DEFERRABLE;
4225 : : n->location = @1;
4226 : : $$ = (Node *) n;
4227 : : }
4228 : : | NOT DEFERRABLE
4229 : : {
4230 : : Constraint *n = makeNode(Constraint);
4231 : :
4232 : : n->contype = CONSTR_ATTR_NOT_DEFERRABLE;
4233 : : n->location = @1;
4234 : : $$ = (Node *) n;
4235 : : }
4236 : : | INITIALLY DEFERRED
4237 : : {
4238 : : Constraint *n = makeNode(Constraint);
4239 : :
4240 : : n->contype = CONSTR_ATTR_DEFERRED;
4241 : : n->location = @1;
4242 : : $$ = (Node *) n;
4243 : : }
4244 : : | INITIALLY IMMEDIATE
4245 : : {
4246 : : Constraint *n = makeNode(Constraint);
4247 : :
4248 : : n->contype = CONSTR_ATTR_IMMEDIATE;
4249 : : n->location = @1;
4250 : : $$ = (Node *) n;
4251 : : }
4252 : : | ENFORCED
4253 : : {
4254 : : Constraint *n = makeNode(Constraint);
4255 : :
4256 : : n->contype = CONSTR_ATTR_ENFORCED;
4257 : : n->location = @1;
4258 : : $$ = (Node *) n;
4259 : : }
4260 : : | NOT ENFORCED
4261 : : {
4262 : : Constraint *n = makeNode(Constraint);
4263 : :
4264 : : n->contype = CONSTR_ATTR_NOT_ENFORCED;
4265 : : n->location = @1;
4266 : : $$ = (Node *) n;
4267 : : }
4268 : : ;
4269 : :
4270 : :
4271 : : TableLikeClause:
4272 : : LIKE qualified_name TableLikeOptionList
4273 : : {
4274 : : TableLikeClause *n = makeNode(TableLikeClause);
4275 : :
4276 : : n->relation = $2;
4277 : : n->options = $3;
4278 : : n->relationOid = InvalidOid;
4279 : : $$ = (Node *) n;
4280 : : }
4281 : : ;
4282 : :
4283 : : TableLikeOptionList:
4284 : : TableLikeOptionList INCLUDING TableLikeOption { $$ = $1 | $3; }
4285 : : | TableLikeOptionList EXCLUDING TableLikeOption { $$ = $1 & ~$3; }
4286 : : | /* EMPTY */ { $$ = 0; }
4287 : : ;
4288 : :
4289 : : TableLikeOption:
4290 : : COMMENTS { $$ = CREATE_TABLE_LIKE_COMMENTS; }
4291 : : | COMPRESSION { $$ = CREATE_TABLE_LIKE_COMPRESSION; }
4292 : : | CONSTRAINTS { $$ = CREATE_TABLE_LIKE_CONSTRAINTS; }
4293 : : | DEFAULTS { $$ = CREATE_TABLE_LIKE_DEFAULTS; }
4294 : : | IDENTITY_P { $$ = CREATE_TABLE_LIKE_IDENTITY; }
4295 : : | GENERATED { $$ = CREATE_TABLE_LIKE_GENERATED; }
4296 : : | INDEXES { $$ = CREATE_TABLE_LIKE_INDEXES; }
4297 : : | STATISTICS { $$ = CREATE_TABLE_LIKE_STATISTICS; }
4298 : : | STORAGE { $$ = CREATE_TABLE_LIKE_STORAGE; }
4299 : : | ALL { $$ = CREATE_TABLE_LIKE_ALL; }
4300 : : ;
4301 : :
4302 : :
4303 : : /* ConstraintElem specifies constraint syntax which is not embedded into
4304 : : * a column definition. ColConstraintElem specifies the embedded form.
4305 : : * - thomas 1997-12-03
4306 : : */
4307 : : TableConstraint:
4308 : : CONSTRAINT name ConstraintElem
4309 : : {
4310 : : Constraint *n = castNode(Constraint, $3);
4311 : :
4312 : : n->conname = $2;
4313 : : n->location = @1;
4314 : : $$ = (Node *) n;
4315 : : }
4316 : : | ConstraintElem { $$ = $1; }
4317 : : ;
4318 : :
4319 : : ConstraintElem:
4320 : : CHECK '(' a_expr ')' ConstraintAttributeSpec
4321 : : {
4322 : : Constraint *n = makeNode(Constraint);
4323 : :
4324 : : n->contype = CONSTR_CHECK;
4325 : : n->location = @1;
4326 : : n->raw_expr = $3;
4327 : : n->cooked_expr = NULL;
4328 : : processCASbits($5, @5, "CHECK",
4329 : : NULL, NULL, &n->is_enforced, &n->skip_validation,
4330 : : &n->is_no_inherit, yyscanner);
4331 : : n->initially_valid = !n->skip_validation;
4332 : : $$ = (Node *) n;
4333 : : }
4334 : : | NOT NULL_P ColId ConstraintAttributeSpec
4335 : : {
4336 : : Constraint *n = makeNode(Constraint);
4337 : :
4338 : : n->contype = CONSTR_NOTNULL;
4339 : : n->location = @1;
4340 : : n->keys = list_make1(makeString($3));
4341 : : processCASbits($4, @4, "NOT NULL",
4342 : : NULL, NULL, NULL, &n->skip_validation,
4343 : : &n->is_no_inherit, yyscanner);
4344 : : n->initially_valid = !n->skip_validation;
4345 : : $$ = (Node *) n;
4346 : : }
4347 : : | UNIQUE opt_unique_null_treatment '(' columnList opt_without_overlaps ')' opt_c_include opt_definition OptConsTableSpace
4348 : : ConstraintAttributeSpec
4349 : : {
4350 : : Constraint *n = makeNode(Constraint);
4351 : :
4352 : : n->contype = CONSTR_UNIQUE;
4353 : : n->location = @1;
4354 : : n->nulls_not_distinct = !$2;
4355 : : n->keys = $4;
4356 : : n->without_overlaps = $5;
4357 : : n->including = $7;
4358 : : n->options = $8;
4359 : : n->indexname = NULL;
4360 : : n->indexspace = $9;
4361 : : processCASbits($10, @10, "UNIQUE",
4362 : : &n->deferrable, &n->initdeferred, NULL,
4363 : : NULL, NULL, yyscanner);
4364 : : $$ = (Node *) n;
4365 : : }
4366 : : | UNIQUE ExistingIndex ConstraintAttributeSpec
4367 : : {
4368 : : Constraint *n = makeNode(Constraint);
4369 : :
4370 : : n->contype = CONSTR_UNIQUE;
4371 : : n->location = @1;
4372 : : n->keys = NIL;
4373 : : n->including = NIL;
4374 : : n->options = NIL;
4375 : : n->indexname = $2;
4376 : : n->indexspace = NULL;
4377 : : processCASbits($3, @3, "UNIQUE",
4378 : : &n->deferrable, &n->initdeferred, NULL,
4379 : : NULL, NULL, yyscanner);
4380 : : $$ = (Node *) n;
4381 : : }
4382 : : | PRIMARY KEY '(' columnList opt_without_overlaps ')' opt_c_include opt_definition OptConsTableSpace
4383 : : ConstraintAttributeSpec
4384 : : {
4385 : : Constraint *n = makeNode(Constraint);
4386 : :
4387 : : n->contype = CONSTR_PRIMARY;
4388 : : n->location = @1;
4389 : : n->keys = $4;
4390 : : n->without_overlaps = $5;
4391 : : n->including = $7;
4392 : : n->options = $8;
4393 : : n->indexname = NULL;
4394 : : n->indexspace = $9;
4395 : : processCASbits($10, @10, "PRIMARY KEY",
4396 : : &n->deferrable, &n->initdeferred, NULL,
4397 : : NULL, NULL, yyscanner);
4398 : : $$ = (Node *) n;
4399 : : }
4400 : : | PRIMARY KEY ExistingIndex ConstraintAttributeSpec
4401 : : {
4402 : : Constraint *n = makeNode(Constraint);
4403 : :
4404 : : n->contype = CONSTR_PRIMARY;
4405 : : n->location = @1;
4406 : : n->keys = NIL;
4407 : : n->including = NIL;
4408 : : n->options = NIL;
4409 : : n->indexname = $3;
4410 : : n->indexspace = NULL;
4411 : : processCASbits($4, @4, "PRIMARY KEY",
4412 : : &n->deferrable, &n->initdeferred, NULL,
4413 : : NULL, NULL, yyscanner);
4414 : : $$ = (Node *) n;
4415 : : }
4416 : : | EXCLUDE access_method_clause '(' ExclusionConstraintList ')'
4417 : : opt_c_include opt_definition OptConsTableSpace OptWhereClause
4418 : : ConstraintAttributeSpec
4419 : : {
4420 : : Constraint *n = makeNode(Constraint);
4421 : :
4422 : : n->contype = CONSTR_EXCLUSION;
4423 : : n->location = @1;
4424 : : n->access_method = $2;
4425 : : n->exclusions = $4;
4426 : : n->including = $6;
4427 : : n->options = $7;
4428 : : n->indexname = NULL;
4429 : : n->indexspace = $8;
4430 : : n->where_clause = $9;
4431 : : processCASbits($10, @10, "EXCLUDE",
4432 : : &n->deferrable, &n->initdeferred, NULL,
4433 : : NULL, NULL, yyscanner);
4434 : : $$ = (Node *) n;
4435 : : }
4436 : : | FOREIGN KEY '(' columnList optionalPeriodName ')' REFERENCES qualified_name
4437 : : opt_column_and_period_list key_match key_actions ConstraintAttributeSpec
4438 : : {
4439 : : Constraint *n = makeNode(Constraint);
4440 : :
4441 : : n->contype = CONSTR_FOREIGN;
4442 : : n->location = @1;
4443 : : n->pktable = $8;
4444 : : n->fk_attrs = $4;
4445 : : if ($5)
4446 : : {
4447 : : n->fk_attrs = lappend(n->fk_attrs, $5);
4448 : : n->fk_with_period = true;
4449 : : }
4450 : : n->pk_attrs = linitial($9);
4451 : : if (lsecond($9))
4452 : : {
4453 : : n->pk_attrs = lappend(n->pk_attrs, lsecond($9));
4454 : : n->pk_with_period = true;
4455 : : }
4456 : : n->fk_matchtype = $10;
4457 : : n->fk_upd_action = ($11)->updateAction->action;
4458 : : n->fk_del_action = ($11)->deleteAction->action;
4459 : : n->fk_del_set_cols = ($11)->deleteAction->cols;
4460 : : processCASbits($12, @12, "FOREIGN KEY",
4461 : : &n->deferrable, &n->initdeferred,
4462 : : &n->is_enforced, &n->skip_validation, NULL,
4463 : : yyscanner);
4464 : : n->initially_valid = !n->skip_validation;
4465 : : $$ = (Node *) n;
4466 : : }
4467 : : ;
4468 : :
4469 : : /*
4470 : : * DomainConstraint is separate from TableConstraint because the syntax for
4471 : : * NOT NULL constraints is different. For table constraints, we need to
4472 : : * accept a column name, but for domain constraints, we don't. (We could
4473 : : * accept something like NOT NULL VALUE, but that seems weird.) CREATE DOMAIN
4474 : : * (which uses ColQualList) has for a long time accepted NOT NULL without a
4475 : : * column name, so it makes sense that ALTER DOMAIN (which uses
4476 : : * DomainConstraint) does as well. None of these syntaxes are per SQL
4477 : : * standard; we are just living with the bits of inconsistency that have built
4478 : : * up over time.
4479 : : */
4480 : : DomainConstraint:
4481 : : CONSTRAINT name DomainConstraintElem
4482 : : {
4483 : : Constraint *n = castNode(Constraint, $3);
4484 : :
4485 : : n->conname = $2;
4486 : : n->location = @1;
4487 : : $$ = (Node *) n;
4488 : : }
4489 : : | DomainConstraintElem { $$ = $1; }
4490 : : ;
4491 : :
4492 : : DomainConstraintElem:
4493 : : CHECK '(' a_expr ')' ConstraintAttributeSpec
4494 : : {
4495 : : Constraint *n = makeNode(Constraint);
4496 : :
4497 : : n->contype = CONSTR_CHECK;
4498 : : n->location = @1;
4499 : : n->raw_expr = $3;
4500 : : n->cooked_expr = NULL;
4501 : : processCASbits($5, @5, "CHECK",
4502 : : NULL, NULL, NULL, &n->skip_validation,
4503 : : &n->is_no_inherit, yyscanner);
4504 : : n->is_enforced = true;
4505 : : n->initially_valid = !n->skip_validation;
4506 : : $$ = (Node *) n;
4507 : : }
4508 : : | NOT NULL_P ConstraintAttributeSpec
4509 : : {
4510 : : Constraint *n = makeNode(Constraint);
4511 : :
4512 : : n->contype = CONSTR_NOTNULL;
4513 : : n->location = @1;
4514 : : n->keys = list_make1(makeString("value"));
4515 : : /* no NOT VALID, NO INHERIT support */
4516 : : processCASbits($3, @3, "NOT NULL",
4517 : : NULL, NULL, NULL,
4518 : : NULL, NULL, yyscanner);
4519 : : n->initially_valid = true;
4520 : : $$ = (Node *) n;
4521 : : }
4522 : : ;
4523 : :
4524 : : opt_no_inherit: NO INHERIT { $$ = true; }
4525 : : | /* EMPTY */ { $$ = false; }
4526 : : ;
4527 : :
4528 : : opt_without_overlaps:
4529 : : WITHOUT OVERLAPS { $$ = true; }
4530 : : | /*EMPTY*/ { $$ = false; }
4531 : : ;
4532 : :
4533 : : opt_column_list:
4534 : : '(' columnList ')' { $$ = $2; }
4535 : : | /*EMPTY*/ { $$ = NIL; }
4536 : : ;
4537 : :
4538 : : columnList:
4539 : : columnElem { $$ = list_make1($1); }
4540 : : | columnList ',' columnElem { $$ = lappend($1, $3); }
4541 : : ;
4542 : :
4543 : : optionalPeriodName:
4544 : : ',' PERIOD columnElem { $$ = $3; }
4545 : : | /*EMPTY*/ { $$ = NULL; }
4546 : : ;
4547 : :
4548 : : opt_column_and_period_list:
4549 : : '(' columnList optionalPeriodName ')' { $$ = list_make2($2, $3); }
4550 : : | /*EMPTY*/ { $$ = list_make2(NIL, NULL); }
4551 : : ;
4552 : :
4553 : : columnElem: ColId
4554 : : {
4555 : : $$ = (Node *) makeString($1);
4556 : : }
4557 : : ;
4558 : :
4559 : : opt_c_include: INCLUDE '(' columnList ')' { $$ = $3; }
4560 : : | /* EMPTY */ { $$ = NIL; }
4561 : : ;
4562 : :
4563 : : key_match: MATCH FULL
4564 : : {
4565 : : $$ = FKCONSTR_MATCH_FULL;
4566 : : }
4567 : : | MATCH PARTIAL
4568 : : {
4569 : : ereport(ERROR,
4570 : : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4571 : : errmsg("MATCH PARTIAL not yet implemented"),
4572 : : parser_errposition(@1)));
4573 : : $$ = FKCONSTR_MATCH_PARTIAL;
4574 : : }
4575 : : | MATCH SIMPLE
4576 : : {
4577 : : $$ = FKCONSTR_MATCH_SIMPLE;
4578 : : }
4579 : : | /*EMPTY*/
4580 : : {
4581 : : $$ = FKCONSTR_MATCH_SIMPLE;
4582 : : }
4583 : : ;
4584 : :
4585 : : ExclusionConstraintList:
4586 : : ExclusionConstraintElem { $$ = list_make1($1); }
4587 : : | ExclusionConstraintList ',' ExclusionConstraintElem
4588 : : { $$ = lappend($1, $3); }
4589 : : ;
4590 : :
4591 : : ExclusionConstraintElem: index_elem WITH any_operator
4592 : : {
4593 : : $$ = list_make2($1, $3);
4594 : : }
4595 : : /* allow OPERATOR() decoration for the benefit of ruleutils.c */
4596 : : | index_elem WITH OPERATOR '(' any_operator ')'
4597 : : {
4598 : : $$ = list_make2($1, $5);
4599 : : }
4600 : : ;
4601 : :
4602 : : OptWhereClause:
4603 : : WHERE '(' a_expr ')' { $$ = $3; }
4604 : : | /*EMPTY*/ { $$ = NULL; }
4605 : : ;
4606 : :
4607 : : key_actions:
4608 : : key_update
4609 : : {
4610 : : KeyActions *n = palloc_object(KeyActions);
4611 : :
4612 : : n->updateAction = $1;
4613 : : n->deleteAction = palloc_object(KeyAction);
4614 : : n->deleteAction->action = FKCONSTR_ACTION_NOACTION;
4615 : : n->deleteAction->cols = NIL;
4616 : : $$ = n;
4617 : : }
4618 : : | key_delete
4619 : : {
4620 : : KeyActions *n = palloc_object(KeyActions);
4621 : :
4622 : : n->updateAction = palloc_object(KeyAction);
4623 : : n->updateAction->action = FKCONSTR_ACTION_NOACTION;
4624 : : n->updateAction->cols = NIL;
4625 : : n->deleteAction = $1;
4626 : : $$ = n;
4627 : : }
4628 : : | key_update key_delete
4629 : : {
4630 : : KeyActions *n = palloc_object(KeyActions);
4631 : :
4632 : : n->updateAction = $1;
4633 : : n->deleteAction = $2;
4634 : : $$ = n;
4635 : : }
4636 : : | key_delete key_update
4637 : : {
4638 : : KeyActions *n = palloc_object(KeyActions);
4639 : :
4640 : : n->updateAction = $2;
4641 : : n->deleteAction = $1;
4642 : : $$ = n;
4643 : : }
4644 : : | /*EMPTY*/
4645 : : {
4646 : : KeyActions *n = palloc_object(KeyActions);
4647 : :
4648 : : n->updateAction = palloc_object(KeyAction);
4649 : : n->updateAction->action = FKCONSTR_ACTION_NOACTION;
4650 : : n->updateAction->cols = NIL;
4651 : : n->deleteAction = palloc_object(KeyAction);
4652 : : n->deleteAction->action = FKCONSTR_ACTION_NOACTION;
4653 : : n->deleteAction->cols = NIL;
4654 : : $$ = n;
4655 : : }
4656 : : ;
4657 : :
4658 : : key_update: ON UPDATE key_action
4659 : : {
4660 : : if (($3)->cols)
4661 : : ereport(ERROR,
4662 : : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4663 : : errmsg("a column list with %s is only supported for ON DELETE actions",
4664 : : ($3)->action == FKCONSTR_ACTION_SETNULL ? "SET NULL" : "SET DEFAULT"),
4665 : : parser_errposition(@1)));
4666 : : $$ = $3;
4667 : : }
4668 : : ;
4669 : :
4670 : : key_delete: ON DELETE_P key_action
4671 : : {
4672 : : $$ = $3;
4673 : : }
4674 : : ;
4675 : :
4676 : : key_action:
4677 : : NO ACTION
4678 : : {
4679 : : KeyAction *n = palloc_object(KeyAction);
4680 : :
4681 : : n->action = FKCONSTR_ACTION_NOACTION;
4682 : : n->cols = NIL;
4683 : : $$ = n;
4684 : : }
4685 : : | RESTRICT
4686 : : {
4687 : : KeyAction *n = palloc_object(KeyAction);
4688 : :
4689 : : n->action = FKCONSTR_ACTION_RESTRICT;
4690 : : n->cols = NIL;
4691 : : $$ = n;
4692 : : }
4693 : : | CASCADE
4694 : : {
4695 : : KeyAction *n = palloc_object(KeyAction);
4696 : :
4697 : : n->action = FKCONSTR_ACTION_CASCADE;
4698 : : n->cols = NIL;
4699 : : $$ = n;
4700 : : }
4701 : : | SET NULL_P opt_column_list
4702 : : {
4703 : : KeyAction *n = palloc_object(KeyAction);
4704 : :
4705 : : n->action = FKCONSTR_ACTION_SETNULL;
4706 : : n->cols = $3;
4707 : : $$ = n;
4708 : : }
4709 : : | SET DEFAULT opt_column_list
4710 : : {
4711 : : KeyAction *n = palloc_object(KeyAction);
4712 : :
4713 : : n->action = FKCONSTR_ACTION_SETDEFAULT;
4714 : : n->cols = $3;
4715 : : $$ = n;
4716 : : }
4717 : : ;
4718 : :
4719 : : OptInherit: INHERITS '(' qualified_name_list ')' { $$ = $3; }
4720 : : | /*EMPTY*/ { $$ = NIL; }
4721 : : ;
4722 : :
4723 : : /* Optional partition key specification */
4724 : : OptPartitionSpec: PartitionSpec { $$ = $1; }
4725 : : | /*EMPTY*/ { $$ = NULL; }
4726 : : ;
4727 : :
4728 : : PartitionSpec: PARTITION BY ColId '(' part_params ')'
4729 : : {
4730 : : PartitionSpec *n = makeNode(PartitionSpec);
4731 : :
4732 : : n->strategy = parsePartitionStrategy($3, @3, yyscanner);
4733 : : n->partParams = $5;
4734 : : n->location = @1;
4735 : :
4736 : : $$ = n;
4737 : : }
4738 : : ;
4739 : :
4740 : : part_params: part_elem { $$ = list_make1($1); }
4741 : : | part_params ',' part_elem { $$ = lappend($1, $3); }
4742 : : ;
4743 : :
4744 : : part_elem: ColId opt_collate opt_qualified_name
4745 : : {
4746 : : PartitionElem *n = makeNode(PartitionElem);
4747 : :
4748 : : n->name = $1;
4749 : : n->expr = NULL;
4750 : : n->collation = $2;
4751 : : n->opclass = $3;
4752 : : n->location = @1;
4753 : : $$ = n;
4754 : : }
4755 : : | func_expr_windowless opt_collate opt_qualified_name
4756 : : {
4757 : : PartitionElem *n = makeNode(PartitionElem);
4758 : :
4759 : : n->name = NULL;
4760 : : n->expr = $1;
4761 : : n->collation = $2;
4762 : : n->opclass = $3;
4763 : : n->location = @1;
4764 : : $$ = n;
4765 : : }
4766 : : | '(' a_expr ')' opt_collate opt_qualified_name
4767 : : {
4768 : : PartitionElem *n = makeNode(PartitionElem);
4769 : :
4770 : : n->name = NULL;
4771 : : n->expr = $2;
4772 : : n->collation = $4;
4773 : : n->opclass = $5;
4774 : : n->location = @1;
4775 : : $$ = n;
4776 : : }
4777 : : ;
4778 : :
4779 : : table_access_method_clause:
4780 : : USING name { $$ = $2; }
4781 : : | /*EMPTY*/ { $$ = NULL; }
4782 : : ;
4783 : :
4784 : : /* WITHOUT OIDS is legacy only */
4785 : : OptWith:
4786 : : WITH reloptions { $$ = $2; }
4787 : : | WITHOUT OIDS { $$ = NIL; }
4788 : : | /*EMPTY*/ { $$ = NIL; }
4789 : : ;
4790 : :
4791 : : OnCommitOption: ON COMMIT DROP { $$ = ONCOMMIT_DROP; }
4792 : : | ON COMMIT DELETE_P ROWS { $$ = ONCOMMIT_DELETE_ROWS; }
4793 : : | ON COMMIT PRESERVE ROWS { $$ = ONCOMMIT_PRESERVE_ROWS; }
4794 : : | /*EMPTY*/ { $$ = ONCOMMIT_NOOP; }
4795 : : ;
4796 : :
4797 : : OptTableSpace: TABLESPACE name { $$ = $2; }
4798 : : | /*EMPTY*/ { $$ = NULL; }
4799 : : ;
4800 : :
4801 : : OptConsTableSpace: USING INDEX TABLESPACE name { $$ = $4; }
4802 : : | /*EMPTY*/ { $$ = NULL; }
4803 : : ;
4804 : :
4805 : : ExistingIndex: USING INDEX name { $$ = $3; }
4806 : : ;
4807 : :
4808 : : /*****************************************************************************
4809 : : *
4810 : : * QUERY :
4811 : : * CREATE STATISTICS [[IF NOT EXISTS] stats_name] [(stat types)]
4812 : : * ON expression-list FROM from_list
4813 : : *
4814 : : * Note: the expectation here is that the clauses after ON are a subset of
4815 : : * SELECT syntax, allowing for expressions and joined tables, and probably
4816 : : * someday a WHERE clause. Much less than that is currently implemented,
4817 : : * but the grammar accepts it and then we'll throw FEATURE_NOT_SUPPORTED
4818 : : * errors as necessary at execution.
4819 : : *
4820 : : * Statistics name is optional unless IF NOT EXISTS is specified.
4821 : : *
4822 : : *****************************************************************************/
4823 : :
4824 : : CreateStatsStmt:
4825 : : CREATE STATISTICS opt_qualified_name
4826 : : opt_name_list ON stats_params FROM from_list
4827 : : {
4828 : : CreateStatsStmt *n = makeNode(CreateStatsStmt);
4829 : :
4830 : : n->defnames = $3;
4831 : : n->stat_types = $4;
4832 : : n->exprs = $6;
4833 : : n->relations = $8;
4834 : : n->stxcomment = NULL;
4835 : : n->if_not_exists = false;
4836 : : $$ = (Node *) n;
4837 : : }
4838 : : | CREATE STATISTICS IF_P NOT EXISTS any_name
4839 : : opt_name_list ON stats_params FROM from_list
4840 : : {
4841 : : CreateStatsStmt *n = makeNode(CreateStatsStmt);
4842 : :
4843 : : n->defnames = $6;
4844 : : n->stat_types = $7;
4845 : : n->exprs = $9;
4846 : : n->relations = $11;
4847 : : n->stxcomment = NULL;
4848 : : n->if_not_exists = true;
4849 : : $$ = (Node *) n;
4850 : : }
4851 : : ;
4852 : :
4853 : : /*
4854 : : * Statistics attributes can be either simple column references, or arbitrary
4855 : : * expressions in parens. For compatibility with index attributes permitted
4856 : : * in CREATE INDEX, we allow an expression that's just a function call to be
4857 : : * written without parens.
4858 : : */
4859 : :
4860 : : stats_params: stats_param { $$ = list_make1($1); }
4861 : : | stats_params ',' stats_param { $$ = lappend($1, $3); }
4862 : : ;
4863 : :
4864 : : stats_param: ColId
4865 : : {
4866 : : $$ = makeNode(StatsElem);
4867 : : $$->name = $1;
4868 : : $$->expr = NULL;
4869 : : }
4870 : : | func_expr_windowless
4871 : : {
4872 : : $$ = makeNode(StatsElem);
4873 : : $$->name = NULL;
4874 : : $$->expr = $1;
4875 : : }
4876 : : | '(' a_expr ')'
4877 : : {
4878 : : $$ = makeNode(StatsElem);
4879 : : $$->name = NULL;
4880 : : $$->expr = $2;
4881 : : }
4882 : : ;
4883 : :
4884 : : /*****************************************************************************
4885 : : *
4886 : : * QUERY :
4887 : : * ALTER STATISTICS [IF EXISTS] stats_name
4888 : : * SET STATISTICS <SignedIconst>
4889 : : *
4890 : : *****************************************************************************/
4891 : :
4892 : : AlterStatsStmt:
4893 : : ALTER STATISTICS any_name SET STATISTICS set_statistics_value
4894 : : {
4895 : : AlterStatsStmt *n = makeNode(AlterStatsStmt);
4896 : :
4897 : : n->defnames = $3;
4898 : : n->missing_ok = false;
4899 : : n->stxstattarget = $6;
4900 : : $$ = (Node *) n;
4901 : : }
4902 : : | ALTER STATISTICS IF_P EXISTS any_name SET STATISTICS set_statistics_value
4903 : : {
4904 : : AlterStatsStmt *n = makeNode(AlterStatsStmt);
4905 : :
4906 : : n->defnames = $5;
4907 : : n->missing_ok = true;
4908 : : n->stxstattarget = $8;
4909 : : $$ = (Node *) n;
4910 : : }
4911 : : ;
4912 : :
4913 : : /*****************************************************************************
4914 : : *
4915 : : * QUERY :
4916 : : * CREATE TABLE relname AS SelectStmt [ WITH [NO] DATA ]
4917 : : *
4918 : : *
4919 : : * Note: SELECT ... INTO is a now-deprecated alternative for this.
4920 : : *
4921 : : *****************************************************************************/
4922 : :
4923 : : CreateAsStmt:
4924 : : CREATE OptTemp TABLE create_as_target AS SelectStmt opt_with_data
4925 : : {
4926 : : CreateTableAsStmt *ctas = makeNode(CreateTableAsStmt);
4927 : :
4928 : : ctas->query = $6;
4929 : : ctas->into = $4;
4930 : : ctas->objtype = OBJECT_TABLE;
4931 : : ctas->is_select_into = false;
4932 : : ctas->if_not_exists = false;
4933 : : /* cram additional flags into the IntoClause */
4934 : : $4->rel->relpersistence = $2;
4935 : : $4->skipData = !($7);
4936 : : $$ = (Node *) ctas;
4937 : : }
4938 : : | CREATE OptTemp TABLE IF_P NOT EXISTS create_as_target AS SelectStmt opt_with_data
4939 : : {
4940 : : CreateTableAsStmt *ctas = makeNode(CreateTableAsStmt);
4941 : :
4942 : : ctas->query = $9;
4943 : : ctas->into = $7;
4944 : : ctas->objtype = OBJECT_TABLE;
4945 : : ctas->is_select_into = false;
4946 : : ctas->if_not_exists = true;
4947 : : /* cram additional flags into the IntoClause */
4948 : : $7->rel->relpersistence = $2;
4949 : : $7->skipData = !($10);
4950 : : $$ = (Node *) ctas;
4951 : : }
4952 : : ;
4953 : :
4954 : : create_as_target:
4955 : : qualified_name opt_column_list table_access_method_clause
4956 : : OptWith OnCommitOption OptTableSpace
4957 : : {
4958 : : $$ = makeNode(IntoClause);
4959 : : $$->rel = $1;
4960 : : $$->colNames = $2;
4961 : : $$->accessMethod = $3;
4962 : : $$->options = $4;
4963 : : $$->onCommit = $5;
4964 : : $$->tableSpaceName = $6;
4965 : : $$->viewQuery = NULL;
4966 : : $$->skipData = false; /* might get changed later */
4967 : : }
4968 : : ;
4969 : :
4970 : : opt_with_data:
4971 : : WITH DATA_P { $$ = true; }
4972 : : | WITH NO DATA_P { $$ = false; }
4973 : : | /*EMPTY*/ { $$ = true; }
4974 : : ;
4975 : :
4976 : :
4977 : : /*****************************************************************************
4978 : : *
4979 : : * QUERY :
4980 : : * CREATE MATERIALIZED VIEW relname AS SelectStmt
4981 : : *
4982 : : *****************************************************************************/
4983 : :
4984 : : CreateMatViewStmt:
4985 : : CREATE OptNoLog MATERIALIZED VIEW create_mv_target AS SelectStmt opt_with_data
4986 : : {
4987 : : CreateTableAsStmt *ctas = makeNode(CreateTableAsStmt);
4988 : :
4989 : : ctas->query = $7;
4990 : : ctas->into = $5;
4991 : : ctas->objtype = OBJECT_MATVIEW;
4992 : : ctas->is_select_into = false;
4993 : : ctas->if_not_exists = false;
4994 : : /* cram additional flags into the IntoClause */
4995 : : $5->rel->relpersistence = $2;
4996 : : $5->skipData = !($8);
4997 : : $$ = (Node *) ctas;
4998 : : }
4999 : : | CREATE OptNoLog MATERIALIZED VIEW IF_P NOT EXISTS create_mv_target AS SelectStmt opt_with_data
5000 : : {
5001 : : CreateTableAsStmt *ctas = makeNode(CreateTableAsStmt);
5002 : :
5003 : : ctas->query = $10;
5004 : : ctas->into = $8;
5005 : : ctas->objtype = OBJECT_MATVIEW;
5006 : : ctas->is_select_into = false;
5007 : : ctas->if_not_exists = true;
5008 : : /* cram additional flags into the IntoClause */
5009 : : $8->rel->relpersistence = $2;
5010 : : $8->skipData = !($11);
5011 : : $$ = (Node *) ctas;
5012 : : }
5013 : : ;
5014 : :
5015 : : create_mv_target:
5016 : : qualified_name opt_column_list table_access_method_clause opt_reloptions OptTableSpace
5017 : : {
5018 : : $$ = makeNode(IntoClause);
5019 : : $$->rel = $1;
5020 : : $$->colNames = $2;
5021 : : $$->accessMethod = $3;
5022 : : $$->options = $4;
5023 : : $$->onCommit = ONCOMMIT_NOOP;
5024 : : $$->tableSpaceName = $5;
5025 : : $$->viewQuery = NULL; /* filled at analysis time */
5026 : : $$->skipData = false; /* might get changed later */
5027 : : }
5028 : : ;
5029 : :
5030 : : OptNoLog: UNLOGGED { $$ = RELPERSISTENCE_UNLOGGED; }
5031 : : | /*EMPTY*/ { $$ = RELPERSISTENCE_PERMANENT; }
5032 : : ;
5033 : :
5034 : :
5035 : : /*****************************************************************************
5036 : : *
5037 : : * QUERY :
5038 : : * REFRESH MATERIALIZED VIEW qualified_name
5039 : : *
5040 : : *****************************************************************************/
5041 : :
5042 : : RefreshMatViewStmt:
5043 : : REFRESH MATERIALIZED VIEW opt_concurrently qualified_name opt_with_data
5044 : : {
5045 : : RefreshMatViewStmt *n = makeNode(RefreshMatViewStmt);
5046 : :
5047 : : n->concurrent = $4;
5048 : : n->relation = $5;
5049 : : n->skipData = !($6);
5050 : : $$ = (Node *) n;
5051 : : }
5052 : : ;
5053 : :
5054 : :
5055 : : /*****************************************************************************
5056 : : *
5057 : : * QUERY :
5058 : : * CREATE SEQUENCE seqname
5059 : : * ALTER SEQUENCE seqname
5060 : : *
5061 : : *****************************************************************************/
5062 : :
5063 : : CreateSeqStmt:
5064 : : CREATE OptTemp SEQUENCE qualified_name OptSeqOptList
5065 : : {
5066 : : CreateSeqStmt *n = makeNode(CreateSeqStmt);
5067 : :
5068 : : $4->relpersistence = $2;
5069 : : n->sequence = $4;
5070 : : n->options = $5;
5071 : : n->ownerId = InvalidOid;
5072 : : n->if_not_exists = false;
5073 : : $$ = (Node *) n;
5074 : : }
5075 : : | CREATE OptTemp SEQUENCE IF_P NOT EXISTS qualified_name OptSeqOptList
5076 : : {
5077 : : CreateSeqStmt *n = makeNode(CreateSeqStmt);
5078 : :
5079 : : $7->relpersistence = $2;
5080 : : n->sequence = $7;
5081 : : n->options = $8;
5082 : : n->ownerId = InvalidOid;
5083 : : n->if_not_exists = true;
5084 : : $$ = (Node *) n;
5085 : : }
5086 : : ;
5087 : :
5088 : : AlterSeqStmt:
5089 : : ALTER SEQUENCE qualified_name SeqOptList
5090 : : {
5091 : : AlterSeqStmt *n = makeNode(AlterSeqStmt);
5092 : :
5093 : : n->sequence = $3;
5094 : : n->options = $4;
5095 : : n->missing_ok = false;
5096 : : $$ = (Node *) n;
5097 : : }
5098 : : | ALTER SEQUENCE IF_P EXISTS qualified_name SeqOptList
5099 : : {
5100 : : AlterSeqStmt *n = makeNode(AlterSeqStmt);
5101 : :
5102 : : n->sequence = $5;
5103 : : n->options = $6;
5104 : : n->missing_ok = true;
5105 : : $$ = (Node *) n;
5106 : : }
5107 : :
5108 : : ;
5109 : :
5110 : : OptSeqOptList: SeqOptList { $$ = $1; }
5111 : : | /*EMPTY*/ { $$ = NIL; }
5112 : : ;
5113 : :
5114 : : OptParenthesizedSeqOptList: '(' SeqOptList ')' { $$ = $2; }
5115 : : | /*EMPTY*/ { $$ = NIL; }
5116 : : ;
5117 : :
5118 : : SeqOptList: SeqOptElem { $$ = list_make1($1); }
5119 : : | SeqOptList SeqOptElem { $$ = lappend($1, $2); }
5120 : : ;
5121 : :
5122 : : SeqOptElem: AS SimpleTypename
5123 : : {
5124 : : $$ = makeDefElem("as", (Node *) $2, @1);
5125 : : }
5126 : : | CACHE NumericOnly
5127 : : {
5128 : : $$ = makeDefElem("cache", (Node *) $2, @1);
5129 : : }
5130 : : | CYCLE
5131 : : {
5132 : : $$ = makeDefElem("cycle", (Node *) makeBoolean(true), @1);
5133 : : }
5134 : : | NO CYCLE
5135 : : {
5136 : : $$ = makeDefElem("cycle", (Node *) makeBoolean(false), @1);
5137 : : }
5138 : : | INCREMENT opt_by NumericOnly
5139 : : {
5140 : : $$ = makeDefElem("increment", (Node *) $3, @1);
5141 : : }
5142 : : | LOGGED
5143 : : {
5144 : : $$ = makeDefElem("logged", NULL, @1);
5145 : : }
5146 : : | MAXVALUE NumericOnly
5147 : : {
5148 : : $$ = makeDefElem("maxvalue", (Node *) $2, @1);
5149 : : }
5150 : : | MINVALUE NumericOnly
5151 : : {
5152 : : $$ = makeDefElem("minvalue", (Node *) $2, @1);
5153 : : }
5154 : : | NO MAXVALUE
5155 : : {
5156 : : $$ = makeDefElem("maxvalue", NULL, @1);
5157 : : }
5158 : : | NO MINVALUE
5159 : : {
5160 : : $$ = makeDefElem("minvalue", NULL, @1);
5161 : : }
5162 : : | OWNED BY any_name
5163 : : {
5164 : : $$ = makeDefElem("owned_by", (Node *) $3, @1);
5165 : : }
5166 : : | SEQUENCE NAME_P any_name
5167 : : {
5168 : : $$ = makeDefElem("sequence_name", (Node *) $3, @1);
5169 : : }
5170 : : | START opt_with NumericOnly
5171 : : {
5172 : : $$ = makeDefElem("start", (Node *) $3, @1);
5173 : : }
5174 : : | RESTART
5175 : : {
5176 : : $$ = makeDefElem("restart", NULL, @1);
5177 : : }
5178 : : | RESTART opt_with NumericOnly
5179 : : {
5180 : : $$ = makeDefElem("restart", (Node *) $3, @1);
5181 : : }
5182 : : | UNLOGGED
5183 : : {
5184 : : $$ = makeDefElem("unlogged", NULL, @1);
5185 : : }
5186 : : ;
5187 : :
5188 : : opt_by: BY
5189 : : | /* EMPTY */
5190 : : ;
5191 : :
5192 : : NumericOnly:
5193 : : FCONST { $$ = (Node *) makeFloat($1); }
5194 : : | '+' FCONST { $$ = (Node *) makeFloat($2); }
5195 : : | '-' FCONST
5196 : : {
5197 : : Float *f = makeFloat($2);
5198 : :
5199 : : doNegateFloat(f);
5200 : : $$ = (Node *) f;
5201 : : }
5202 : : | SignedIconst { $$ = (Node *) makeInteger($1); }
5203 : : ;
5204 : :
5205 : : NumericOnly_list: NumericOnly { $$ = list_make1($1); }
5206 : : | NumericOnly_list ',' NumericOnly { $$ = lappend($1, $3); }
5207 : : ;
5208 : :
5209 : : /*****************************************************************************
5210 : : *
5211 : : * QUERIES :
5212 : : * CREATE [OR REPLACE] [TRUSTED] [PROCEDURAL] LANGUAGE ...
5213 : : * DROP [PROCEDURAL] LANGUAGE ...
5214 : : *
5215 : : *****************************************************************************/
5216 : :
5217 : : CreatePLangStmt:
5218 : : CREATE opt_or_replace opt_trusted opt_procedural LANGUAGE name
5219 : : {
5220 : : /*
5221 : : * We now interpret parameterless CREATE LANGUAGE as
5222 : : * CREATE EXTENSION. "OR REPLACE" is silently translated
5223 : : * to "IF NOT EXISTS", which isn't quite the same, but
5224 : : * seems more useful than throwing an error. We just
5225 : : * ignore TRUSTED, as the previous code would have too.
5226 : : */
5227 : : CreateExtensionStmt *n = makeNode(CreateExtensionStmt);
5228 : :
5229 : : n->if_not_exists = $2;
5230 : : n->extname = $6;
5231 : : n->options = NIL;
5232 : : $$ = (Node *) n;
5233 : : }
5234 : : | CREATE opt_or_replace opt_trusted opt_procedural LANGUAGE name
5235 : : HANDLER handler_name opt_inline_handler opt_validator
5236 : : {
5237 : : CreatePLangStmt *n = makeNode(CreatePLangStmt);
5238 : :
5239 : : n->replace = $2;
5240 : : n->plname = $6;
5241 : : n->plhandler = $8;
5242 : : n->plinline = $9;
5243 : : n->plvalidator = $10;
5244 : : n->pltrusted = $3;
5245 : : $$ = (Node *) n;
5246 : : }
5247 : : ;
5248 : :
5249 : : opt_trusted:
5250 : : TRUSTED { $$ = true; }
5251 : : | /*EMPTY*/ { $$ = false; }
5252 : : ;
5253 : :
5254 : : /* This ought to be just func_name, but that causes reduce/reduce conflicts
5255 : : * (CREATE LANGUAGE is the only place where func_name isn't followed by '(').
5256 : : * Work around by using simple names, instead.
5257 : : */
5258 : : handler_name:
5259 : : name { $$ = list_make1(makeString($1)); }
5260 : : | name attrs { $$ = lcons(makeString($1), $2); }
5261 : : ;
5262 : :
5263 : : opt_inline_handler:
5264 : : INLINE_P handler_name { $$ = $2; }
5265 : : | /*EMPTY*/ { $$ = NIL; }
5266 : : ;
5267 : :
5268 : : validator_clause:
5269 : : VALIDATOR handler_name { $$ = $2; }
5270 : : | NO VALIDATOR { $$ = NIL; }
5271 : : ;
5272 : :
5273 : : opt_validator:
5274 : : validator_clause { $$ = $1; }
5275 : : | /*EMPTY*/ { $$ = NIL; }
5276 : : ;
5277 : :
5278 : : opt_procedural:
5279 : : PROCEDURAL
5280 : : | /*EMPTY*/
5281 : : ;
5282 : :
5283 : : /*****************************************************************************
5284 : : *
5285 : : * QUERY:
5286 : : * CREATE TABLESPACE tablespace LOCATION '/path/to/tablespace/'
5287 : : *
5288 : : *****************************************************************************/
5289 : :
5290 : : CreateTableSpaceStmt: CREATE TABLESPACE name OptTableSpaceOwner LOCATION Sconst opt_reloptions
5291 : : {
5292 : : CreateTableSpaceStmt *n = makeNode(CreateTableSpaceStmt);
5293 : :
5294 : : n->tablespacename = $3;
5295 : : n->owner = $4;
5296 : : n->location = $6;
5297 : : n->options = $7;
5298 : : $$ = (Node *) n;
5299 : : }
5300 : : ;
5301 : :
5302 : : OptTableSpaceOwner: OWNER RoleSpec { $$ = $2; }
5303 : : | /*EMPTY */ { $$ = NULL; }
5304 : : ;
5305 : :
5306 : : /*****************************************************************************
5307 : : *
5308 : : * QUERY :
5309 : : * DROP TABLESPACE <tablespace>
5310 : : *
5311 : : * No need for drop behaviour as we cannot implement dependencies for
5312 : : * objects in other databases; we can only support RESTRICT.
5313 : : *
5314 : : ****************************************************************************/
5315 : :
5316 : : DropTableSpaceStmt: DROP TABLESPACE name
5317 : : {
5318 : : DropTableSpaceStmt *n = makeNode(DropTableSpaceStmt);
5319 : :
5320 : : n->tablespacename = $3;
5321 : : n->missing_ok = false;
5322 : : $$ = (Node *) n;
5323 : : }
5324 : : | DROP TABLESPACE IF_P EXISTS name
5325 : : {
5326 : : DropTableSpaceStmt *n = makeNode(DropTableSpaceStmt);
5327 : :
5328 : : n->tablespacename = $5;
5329 : : n->missing_ok = true;
5330 : : $$ = (Node *) n;
5331 : : }
5332 : : ;
5333 : :
5334 : : /*****************************************************************************
5335 : : *
5336 : : * QUERY:
5337 : : * CREATE EXTENSION extension
5338 : : * [ WITH ] [ SCHEMA schema ] [ VERSION version ]
5339 : : *
5340 : : *****************************************************************************/
5341 : :
5342 : : CreateExtensionStmt: CREATE EXTENSION name opt_with create_extension_opt_list
5343 : : {
5344 : : CreateExtensionStmt *n = makeNode(CreateExtensionStmt);
5345 : :
5346 : : n->extname = $3;
5347 : : n->if_not_exists = false;
5348 : : n->options = $5;
5349 : : $$ = (Node *) n;
5350 : : }
5351 : : | CREATE EXTENSION IF_P NOT EXISTS name opt_with create_extension_opt_list
5352 : : {
5353 : : CreateExtensionStmt *n = makeNode(CreateExtensionStmt);
5354 : :
5355 : : n->extname = $6;
5356 : : n->if_not_exists = true;
5357 : : n->options = $8;
5358 : : $$ = (Node *) n;
5359 : : }
5360 : : ;
5361 : :
5362 : : create_extension_opt_list:
5363 : : create_extension_opt_list create_extension_opt_item
5364 : : { $$ = lappend($1, $2); }
5365 : : | /* EMPTY */
5366 : : { $$ = NIL; }
5367 : : ;
5368 : :
5369 : : create_extension_opt_item:
5370 : : SCHEMA name
5371 : : {
5372 : : $$ = makeDefElem("schema", (Node *) makeString($2), @1);
5373 : : }
5374 : : | VERSION_P NonReservedWord_or_Sconst
5375 : : {
5376 : : $$ = makeDefElem("new_version", (Node *) makeString($2), @1);
5377 : : }
5378 : : | FROM NonReservedWord_or_Sconst
5379 : : {
5380 : : ereport(ERROR,
5381 : : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
5382 : : errmsg("CREATE EXTENSION ... FROM is no longer supported"),
5383 : : parser_errposition(@1)));
5384 : : }
5385 : : | CASCADE
5386 : : {
5387 : : $$ = makeDefElem("cascade", (Node *) makeBoolean(true), @1);
5388 : : }
5389 : : ;
5390 : :
5391 : : /*****************************************************************************
5392 : : *
5393 : : * ALTER EXTENSION name UPDATE [ TO version ]
5394 : : *
5395 : : *****************************************************************************/
5396 : :
5397 : : AlterExtensionStmt: ALTER EXTENSION name UPDATE alter_extension_opt_list
5398 : : {
5399 : : AlterExtensionStmt *n = makeNode(AlterExtensionStmt);
5400 : :
5401 : : n->extname = $3;
5402 : : n->options = $5;
5403 : : $$ = (Node *) n;
5404 : : }
5405 : : ;
5406 : :
5407 : : alter_extension_opt_list:
5408 : : alter_extension_opt_list alter_extension_opt_item
5409 : : { $$ = lappend($1, $2); }
5410 : : | /* EMPTY */
5411 : : { $$ = NIL; }
5412 : : ;
5413 : :
5414 : : alter_extension_opt_item:
5415 : : TO NonReservedWord_or_Sconst
5416 : : {
5417 : : $$ = makeDefElem("new_version", (Node *) makeString($2), @1);
5418 : : }
5419 : : ;
5420 : :
5421 : : /*****************************************************************************
5422 : : *
5423 : : * ALTER EXTENSION name ADD/DROP object-identifier
5424 : : *
5425 : : *****************************************************************************/
5426 : :
5427 : : AlterExtensionContentsStmt:
5428 : : ALTER EXTENSION name add_drop object_type_name name
5429 : : {
5430 : : AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt);
5431 : :
5432 : : n->extname = $3;
5433 : : n->action = $4;
5434 : : n->objtype = $5;
5435 : : n->object = (Node *) makeString($6);
5436 : : $$ = (Node *) n;
5437 : : }
5438 : : | ALTER EXTENSION name add_drop object_type_any_name any_name
5439 : : {
5440 : : AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt);
5441 : :
5442 : : n->extname = $3;
5443 : : n->action = $4;
5444 : : n->objtype = $5;
5445 : : n->object = (Node *) $6;
5446 : : $$ = (Node *) n;
5447 : : }
5448 : : | ALTER EXTENSION name add_drop AGGREGATE aggregate_with_argtypes
5449 : : {
5450 : : AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt);
5451 : :
5452 : : n->extname = $3;
5453 : : n->action = $4;
5454 : : n->objtype = OBJECT_AGGREGATE;
5455 : : n->object = (Node *) $6;
5456 : : $$ = (Node *) n;
5457 : : }
5458 : : | ALTER EXTENSION name add_drop CAST '(' Typename AS Typename ')'
5459 : : {
5460 : : AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt);
5461 : :
5462 : : n->extname = $3;
5463 : : n->action = $4;
5464 : : n->objtype = OBJECT_CAST;
5465 : : n->object = (Node *) list_make2($7, $9);
5466 : : $$ = (Node *) n;
5467 : : }
5468 : : | ALTER EXTENSION name add_drop DOMAIN_P Typename
5469 : : {
5470 : : AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt);
5471 : :
5472 : : n->extname = $3;
5473 : : n->action = $4;
5474 : : n->objtype = OBJECT_DOMAIN;
5475 : : n->object = (Node *) $6;
5476 : : $$ = (Node *) n;
5477 : : }
5478 : : | ALTER EXTENSION name add_drop FUNCTION function_with_argtypes
5479 : : {
5480 : : AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt);
5481 : :
5482 : : n->extname = $3;
5483 : : n->action = $4;
5484 : : n->objtype = OBJECT_FUNCTION;
5485 : : n->object = (Node *) $6;
5486 : : $$ = (Node *) n;
5487 : : }
5488 : : | ALTER EXTENSION name add_drop OPERATOR operator_with_argtypes
5489 : : {
5490 : : AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt);
5491 : :
5492 : : n->extname = $3;
5493 : : n->action = $4;
5494 : : n->objtype = OBJECT_OPERATOR;
5495 : : n->object = (Node *) $6;
5496 : : $$ = (Node *) n;
5497 : : }
5498 : : | ALTER EXTENSION name add_drop OPERATOR CLASS any_name USING name
5499 : : {
5500 : : AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt);
5501 : :
5502 : : n->extname = $3;
5503 : : n->action = $4;
5504 : : n->objtype = OBJECT_OPCLASS;
5505 : : n->object = (Node *) lcons(makeString($9), $7);
5506 : : $$ = (Node *) n;
5507 : : }
5508 : : | ALTER EXTENSION name add_drop OPERATOR FAMILY any_name USING name
5509 : : {
5510 : : AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt);
5511 : :
5512 : : n->extname = $3;
5513 : : n->action = $4;
5514 : : n->objtype = OBJECT_OPFAMILY;
5515 : : n->object = (Node *) lcons(makeString($9), $7);
5516 : : $$ = (Node *) n;
5517 : : }
5518 : : | ALTER EXTENSION name add_drop PROCEDURE function_with_argtypes
5519 : : {
5520 : : AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt);
5521 : :
5522 : : n->extname = $3;
5523 : : n->action = $4;
5524 : : n->objtype = OBJECT_PROCEDURE;
5525 : : n->object = (Node *) $6;
5526 : : $$ = (Node *) n;
5527 : : }
5528 : : | ALTER EXTENSION name add_drop ROUTINE function_with_argtypes
5529 : : {
5530 : : AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt);
5531 : :
5532 : : n->extname = $3;
5533 : : n->action = $4;
5534 : : n->objtype = OBJECT_ROUTINE;
5535 : : n->object = (Node *) $6;
5536 : : $$ = (Node *) n;
5537 : : }
5538 : : | ALTER EXTENSION name add_drop TRANSFORM FOR Typename LANGUAGE name
5539 : : {
5540 : : AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt);
5541 : :
5542 : : n->extname = $3;
5543 : : n->action = $4;
5544 : : n->objtype = OBJECT_TRANSFORM;
5545 : : n->object = (Node *) list_make2($7, makeString($9));
5546 : : $$ = (Node *) n;
5547 : : }
5548 : : | ALTER EXTENSION name add_drop TYPE_P Typename
5549 : : {
5550 : : AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt);
5551 : :
5552 : : n->extname = $3;
5553 : : n->action = $4;
5554 : : n->objtype = OBJECT_TYPE;
5555 : : n->object = (Node *) $6;
5556 : : $$ = (Node *) n;
5557 : : }
5558 : : ;
5559 : :
5560 : : /*****************************************************************************
5561 : : *
5562 : : * QUERY:
5563 : : * CREATE FOREIGN DATA WRAPPER name options
5564 : : *
5565 : : *****************************************************************************/
5566 : :
5567 : : CreateFdwStmt: CREATE FOREIGN DATA_P WRAPPER name opt_fdw_options create_generic_options
5568 : : {
5569 : : CreateFdwStmt *n = makeNode(CreateFdwStmt);
5570 : :
5571 : : n->fdwname = $5;
5572 : : n->func_options = $6;
5573 : : n->options = $7;
5574 : : $$ = (Node *) n;
5575 : : }
5576 : : ;
5577 : :
5578 : : fdw_option:
5579 : : HANDLER handler_name { $$ = makeDefElem("handler", (Node *) $2, @1); }
5580 : : | NO HANDLER { $$ = makeDefElem("handler", NULL, @1); }
5581 : : | VALIDATOR handler_name { $$ = makeDefElem("validator", (Node *) $2, @1); }
5582 : : | NO VALIDATOR { $$ = makeDefElem("validator", NULL, @1); }
5583 : : ;
5584 : :
5585 : : fdw_options:
5586 : : fdw_option { $$ = list_make1($1); }
5587 : : | fdw_options fdw_option { $$ = lappend($1, $2); }
5588 : : ;
5589 : :
5590 : : opt_fdw_options:
5591 : : fdw_options { $$ = $1; }
5592 : : | /*EMPTY*/ { $$ = NIL; }
5593 : : ;
5594 : :
5595 : : /*****************************************************************************
5596 : : *
5597 : : * QUERY :
5598 : : * ALTER FOREIGN DATA WRAPPER name options
5599 : : *
5600 : : ****************************************************************************/
5601 : :
5602 : : AlterFdwStmt: ALTER FOREIGN DATA_P WRAPPER name opt_fdw_options alter_generic_options
5603 : : {
5604 : : AlterFdwStmt *n = makeNode(AlterFdwStmt);
5605 : :
5606 : : n->fdwname = $5;
5607 : : n->func_options = $6;
5608 : : n->options = $7;
5609 : : $$ = (Node *) n;
5610 : : }
5611 : : | ALTER FOREIGN DATA_P WRAPPER name fdw_options
5612 : : {
5613 : : AlterFdwStmt *n = makeNode(AlterFdwStmt);
5614 : :
5615 : : n->fdwname = $5;
5616 : : n->func_options = $6;
5617 : : n->options = NIL;
5618 : : $$ = (Node *) n;
5619 : : }
5620 : : ;
5621 : :
5622 : : /* Options definition for CREATE FDW, SERVER and USER MAPPING */
5623 : : create_generic_options:
5624 : : OPTIONS '(' generic_option_list ')' { $$ = $3; }
5625 : : | /*EMPTY*/ { $$ = NIL; }
5626 : : ;
5627 : :
5628 : : generic_option_list:
5629 : : generic_option_elem
5630 : : {
5631 : : $$ = list_make1($1);
5632 : : }
5633 : : | generic_option_list ',' generic_option_elem
5634 : : {
5635 : : $$ = lappend($1, $3);
5636 : : }
5637 : : ;
5638 : :
5639 : : /* Options definition for ALTER FDW, SERVER and USER MAPPING */
5640 : : alter_generic_options:
5641 : : OPTIONS '(' alter_generic_option_list ')' { $$ = $3; }
5642 : : ;
5643 : :
5644 : : alter_generic_option_list:
5645 : : alter_generic_option_elem
5646 : : {
5647 : : $$ = list_make1($1);
5648 : : }
5649 : : | alter_generic_option_list ',' alter_generic_option_elem
5650 : : {
5651 : : $$ = lappend($1, $3);
5652 : : }
5653 : : ;
5654 : :
5655 : : alter_generic_option_elem:
5656 : : generic_option_elem
5657 : : {
5658 : : $$ = $1;
5659 : : }
5660 : : | SET generic_option_elem
5661 : : {
5662 : : $$ = $2;
5663 : : $$->defaction = DEFELEM_SET;
5664 : : }
5665 : : | ADD_P generic_option_elem
5666 : : {
5667 : : $$ = $2;
5668 : : $$->defaction = DEFELEM_ADD;
5669 : : }
5670 : : | DROP generic_option_name
5671 : : {
5672 : : $$ = makeDefElemExtended(NULL, $2, NULL, DEFELEM_DROP, @2);
5673 : : }
5674 : : ;
5675 : :
5676 : : generic_option_elem:
5677 : : generic_option_name generic_option_arg
5678 : : {
5679 : : $$ = makeDefElem($1, $2, @1);
5680 : : }
5681 : : ;
5682 : :
5683 : : generic_option_name:
5684 : : ColLabel { $$ = $1; }
5685 : : ;
5686 : :
5687 : : /* We could use def_arg here, but the spec only requires string literals */
5688 : : generic_option_arg:
5689 : : Sconst { $$ = (Node *) makeString($1); }
5690 : : ;
5691 : :
5692 : : /*****************************************************************************
5693 : : *
5694 : : * QUERY:
5695 : : * CREATE SERVER name [TYPE] [VERSION] [OPTIONS]
5696 : : *
5697 : : *****************************************************************************/
5698 : :
5699 : : CreateForeignServerStmt: CREATE SERVER name opt_type opt_foreign_server_version
5700 : : FOREIGN DATA_P WRAPPER name create_generic_options
5701 : : {
5702 : : CreateForeignServerStmt *n = makeNode(CreateForeignServerStmt);
5703 : :
5704 : : n->servername = $3;
5705 : : n->servertype = $4;
5706 : : n->version = $5;
5707 : : n->fdwname = $9;
5708 : : n->options = $10;
5709 : : n->if_not_exists = false;
5710 : : $$ = (Node *) n;
5711 : : }
5712 : : | CREATE SERVER IF_P NOT EXISTS name opt_type opt_foreign_server_version
5713 : : FOREIGN DATA_P WRAPPER name create_generic_options
5714 : : {
5715 : : CreateForeignServerStmt *n = makeNode(CreateForeignServerStmt);
5716 : :
5717 : : n->servername = $6;
5718 : : n->servertype = $7;
5719 : : n->version = $8;
5720 : : n->fdwname = $12;
5721 : : n->options = $13;
5722 : : n->if_not_exists = true;
5723 : : $$ = (Node *) n;
5724 : : }
5725 : : ;
5726 : :
5727 : : opt_type:
5728 : : TYPE_P Sconst { $$ = $2; }
5729 : : | /*EMPTY*/ { $$ = NULL; }
5730 : : ;
5731 : :
5732 : :
5733 : : foreign_server_version:
5734 : : VERSION_P Sconst { $$ = $2; }
5735 : : | VERSION_P NULL_P { $$ = NULL; }
5736 : : ;
5737 : :
5738 : : opt_foreign_server_version:
5739 : : foreign_server_version { $$ = $1; }
5740 : : | /*EMPTY*/ { $$ = NULL; }
5741 : : ;
5742 : :
5743 : : /*****************************************************************************
5744 : : *
5745 : : * QUERY :
5746 : : * ALTER SERVER name [VERSION] [OPTIONS]
5747 : : *
5748 : : ****************************************************************************/
5749 : :
5750 : : AlterForeignServerStmt: ALTER SERVER name foreign_server_version alter_generic_options
5751 : : {
5752 : : AlterForeignServerStmt *n = makeNode(AlterForeignServerStmt);
5753 : :
5754 : : n->servername = $3;
5755 : : n->version = $4;
5756 : : n->options = $5;
5757 : : n->has_version = true;
5758 : : $$ = (Node *) n;
5759 : : }
5760 : : | ALTER SERVER name foreign_server_version
5761 : : {
5762 : : AlterForeignServerStmt *n = makeNode(AlterForeignServerStmt);
5763 : :
5764 : : n->servername = $3;
5765 : : n->version = $4;
5766 : : n->has_version = true;
5767 : : $$ = (Node *) n;
5768 : : }
5769 : : | ALTER SERVER name alter_generic_options
5770 : : {
5771 : : AlterForeignServerStmt *n = makeNode(AlterForeignServerStmt);
5772 : :
5773 : : n->servername = $3;
5774 : : n->options = $4;
5775 : : $$ = (Node *) n;
5776 : : }
5777 : : ;
5778 : :
5779 : : /*****************************************************************************
5780 : : *
5781 : : * QUERY:
5782 : : * CREATE FOREIGN TABLE relname (...) SERVER name (...)
5783 : : *
5784 : : *****************************************************************************/
5785 : :
5786 : : CreateForeignTableStmt:
5787 : : CREATE FOREIGN TABLE qualified_name
5788 : : '(' OptTableElementList ')'
5789 : : OptInherit SERVER name create_generic_options
5790 : : {
5791 : : CreateForeignTableStmt *n = makeNode(CreateForeignTableStmt);
5792 : :
5793 : : $4->relpersistence = RELPERSISTENCE_PERMANENT;
5794 : : n->base.relation = $4;
5795 : : n->base.tableElts = $6;
5796 : : n->base.inhRelations = $8;
5797 : : n->base.ofTypename = NULL;
5798 : : n->base.constraints = NIL;
5799 : : n->base.options = NIL;
5800 : : n->base.oncommit = ONCOMMIT_NOOP;
5801 : : n->base.tablespacename = NULL;
5802 : : n->base.if_not_exists = false;
5803 : : /* FDW-specific data */
5804 : : n->servername = $10;
5805 : : n->options = $11;
5806 : : $$ = (Node *) n;
5807 : : }
5808 : : | CREATE FOREIGN TABLE IF_P NOT EXISTS qualified_name
5809 : : '(' OptTableElementList ')'
5810 : : OptInherit SERVER name create_generic_options
5811 : : {
5812 : : CreateForeignTableStmt *n = makeNode(CreateForeignTableStmt);
5813 : :
5814 : : $7->relpersistence = RELPERSISTENCE_PERMANENT;
5815 : : n->base.relation = $7;
5816 : : n->base.tableElts = $9;
5817 : : n->base.inhRelations = $11;
5818 : : n->base.ofTypename = NULL;
5819 : : n->base.constraints = NIL;
5820 : : n->base.options = NIL;
5821 : : n->base.oncommit = ONCOMMIT_NOOP;
5822 : : n->base.tablespacename = NULL;
5823 : : n->base.if_not_exists = true;
5824 : : /* FDW-specific data */
5825 : : n->servername = $13;
5826 : : n->options = $14;
5827 : : $$ = (Node *) n;
5828 : : }
5829 : : | CREATE FOREIGN TABLE qualified_name
5830 : : PARTITION OF qualified_name OptTypedTableElementList PartitionBoundSpec
5831 : : SERVER name create_generic_options
5832 : : {
5833 : : CreateForeignTableStmt *n = makeNode(CreateForeignTableStmt);
5834 : :
5835 : : $4->relpersistence = RELPERSISTENCE_PERMANENT;
5836 : : n->base.relation = $4;
5837 : : n->base.inhRelations = list_make1($7);
5838 : : n->base.tableElts = $8;
5839 : : n->base.partbound = $9;
5840 : : n->base.ofTypename = NULL;
5841 : : n->base.constraints = NIL;
5842 : : n->base.options = NIL;
5843 : : n->base.oncommit = ONCOMMIT_NOOP;
5844 : : n->base.tablespacename = NULL;
5845 : : n->base.if_not_exists = false;
5846 : : /* FDW-specific data */
5847 : : n->servername = $11;
5848 : : n->options = $12;
5849 : : $$ = (Node *) n;
5850 : : }
5851 : : | CREATE FOREIGN TABLE IF_P NOT EXISTS qualified_name
5852 : : PARTITION OF qualified_name OptTypedTableElementList PartitionBoundSpec
5853 : : SERVER name create_generic_options
5854 : : {
5855 : : CreateForeignTableStmt *n = makeNode(CreateForeignTableStmt);
5856 : :
5857 : : $7->relpersistence = RELPERSISTENCE_PERMANENT;
5858 : : n->base.relation = $7;
5859 : : n->base.inhRelations = list_make1($10);
5860 : : n->base.tableElts = $11;
5861 : : n->base.partbound = $12;
5862 : : n->base.ofTypename = NULL;
5863 : : n->base.constraints = NIL;
5864 : : n->base.options = NIL;
5865 : : n->base.oncommit = ONCOMMIT_NOOP;
5866 : : n->base.tablespacename = NULL;
5867 : : n->base.if_not_exists = true;
5868 : : /* FDW-specific data */
5869 : : n->servername = $14;
5870 : : n->options = $15;
5871 : : $$ = (Node *) n;
5872 : : }
5873 : : ;
5874 : :
5875 : : /*****************************************************************************
5876 : : *
5877 : : * QUERY:
5878 : : * IMPORT FOREIGN SCHEMA remote_schema
5879 : : * [ { LIMIT TO | EXCEPT } ( table_list ) ]
5880 : : * FROM SERVER server_name INTO local_schema [ OPTIONS (...) ]
5881 : : *
5882 : : ****************************************************************************/
5883 : :
5884 : : ImportForeignSchemaStmt:
5885 : : IMPORT_P FOREIGN SCHEMA name import_qualification
5886 : : FROM SERVER name INTO name create_generic_options
5887 : : {
5888 : : ImportForeignSchemaStmt *n = makeNode(ImportForeignSchemaStmt);
5889 : :
5890 : : n->server_name = $8;
5891 : : n->remote_schema = $4;
5892 : : n->local_schema = $10;
5893 : : n->list_type = $5->type;
5894 : : n->table_list = $5->table_names;
5895 : : n->options = $11;
5896 : : $$ = (Node *) n;
5897 : : }
5898 : : ;
5899 : :
5900 : : import_qualification_type:
5901 : : LIMIT TO { $$ = FDW_IMPORT_SCHEMA_LIMIT_TO; }
5902 : : | EXCEPT { $$ = FDW_IMPORT_SCHEMA_EXCEPT; }
5903 : : ;
5904 : :
5905 : : import_qualification:
5906 : : import_qualification_type '(' relation_expr_list ')'
5907 : : {
5908 : : ImportQual *n = palloc_object(ImportQual);
5909 : :
5910 : : n->type = $1;
5911 : : n->table_names = $3;
5912 : : $$ = n;
5913 : : }
5914 : : | /*EMPTY*/
5915 : : {
5916 : : ImportQual *n = palloc_object(ImportQual);
5917 : : n->type = FDW_IMPORT_SCHEMA_ALL;
5918 : : n->table_names = NIL;
5919 : : $$ = n;
5920 : : }
5921 : : ;
5922 : :
5923 : : /*****************************************************************************
5924 : : *
5925 : : * QUERY:
5926 : : * CREATE USER MAPPING FOR auth_ident SERVER name [OPTIONS]
5927 : : *
5928 : : *****************************************************************************/
5929 : :
5930 : : CreateUserMappingStmt: CREATE USER MAPPING FOR auth_ident SERVER name create_generic_options
5931 : : {
5932 : : CreateUserMappingStmt *n = makeNode(CreateUserMappingStmt);
5933 : :
5934 : : n->user = $5;
5935 : : n->servername = $7;
5936 : : n->options = $8;
5937 : : n->if_not_exists = false;
5938 : : $$ = (Node *) n;
5939 : : }
5940 : : | CREATE USER MAPPING IF_P NOT EXISTS FOR auth_ident SERVER name create_generic_options
5941 : : {
5942 : : CreateUserMappingStmt *n = makeNode(CreateUserMappingStmt);
5943 : :
5944 : : n->user = $8;
5945 : : n->servername = $10;
5946 : : n->options = $11;
5947 : : n->if_not_exists = true;
5948 : : $$ = (Node *) n;
5949 : : }
5950 : : ;
5951 : :
5952 : : /* User mapping authorization identifier */
5953 : : auth_ident: RoleSpec { $$ = $1; }
5954 : : | USER { $$ = makeRoleSpec(ROLESPEC_CURRENT_USER, @1); }
5955 : : ;
5956 : :
5957 : : /*****************************************************************************
5958 : : *
5959 : : * QUERY :
5960 : : * DROP USER MAPPING FOR auth_ident SERVER name
5961 : : *
5962 : : * XXX you'd think this should have a CASCADE/RESTRICT option, even if it's
5963 : : * only pro forma; but the SQL standard doesn't show one.
5964 : : ****************************************************************************/
5965 : :
5966 : : DropUserMappingStmt: DROP USER MAPPING FOR auth_ident SERVER name
5967 : : {
5968 : : DropUserMappingStmt *n = makeNode(DropUserMappingStmt);
5969 : :
5970 : : n->user = $5;
5971 : : n->servername = $7;
5972 : : n->missing_ok = false;
5973 : : $$ = (Node *) n;
5974 : : }
5975 : : | DROP USER MAPPING IF_P EXISTS FOR auth_ident SERVER name
5976 : : {
5977 : : DropUserMappingStmt *n = makeNode(DropUserMappingStmt);
5978 : :
5979 : : n->user = $7;
5980 : : n->servername = $9;
5981 : : n->missing_ok = true;
5982 : : $$ = (Node *) n;
5983 : : }
5984 : : ;
5985 : :
5986 : : /*****************************************************************************
5987 : : *
5988 : : * QUERY :
5989 : : * ALTER USER MAPPING FOR auth_ident SERVER name OPTIONS
5990 : : *
5991 : : ****************************************************************************/
5992 : :
5993 : : AlterUserMappingStmt: ALTER USER MAPPING FOR auth_ident SERVER name alter_generic_options
5994 : : {
5995 : : AlterUserMappingStmt *n = makeNode(AlterUserMappingStmt);
5996 : :
5997 : : n->user = $5;
5998 : : n->servername = $7;
5999 : : n->options = $8;
6000 : : $$ = (Node *) n;
6001 : : }
6002 : : ;
6003 : :
6004 : : /*****************************************************************************
6005 : : *
6006 : : * QUERIES:
6007 : : * CREATE POLICY name ON table
6008 : : * [AS { PERMISSIVE | RESTRICTIVE } ]
6009 : : * [FOR { SELECT | INSERT | UPDATE | DELETE } ]
6010 : : * [TO role, ...]
6011 : : * [USING (qual)] [WITH CHECK (with check qual)]
6012 : : * ALTER POLICY name ON table [TO role, ...]
6013 : : * [USING (qual)] [WITH CHECK (with check qual)]
6014 : : *
6015 : : *****************************************************************************/
6016 : :
6017 : : CreatePolicyStmt:
6018 : : CREATE POLICY name ON qualified_name RowSecurityDefaultPermissive
6019 : : RowSecurityDefaultForCmd RowSecurityDefaultToRole
6020 : : RowSecurityOptionalExpr RowSecurityOptionalWithCheck
6021 : : {
6022 : : CreatePolicyStmt *n = makeNode(CreatePolicyStmt);
6023 : :
6024 : : n->policy_name = $3;
6025 : : n->table = $5;
6026 : : n->permissive = $6;
6027 : : n->cmd_name = $7;
6028 : : n->roles = $8;
6029 : : n->qual = $9;
6030 : : n->with_check = $10;
6031 : : $$ = (Node *) n;
6032 : : }
6033 : : ;
6034 : :
6035 : : AlterPolicyStmt:
6036 : : ALTER POLICY name ON qualified_name RowSecurityOptionalToRole
6037 : : RowSecurityOptionalExpr RowSecurityOptionalWithCheck
6038 : : {
6039 : : AlterPolicyStmt *n = makeNode(AlterPolicyStmt);
6040 : :
6041 : : n->policy_name = $3;
6042 : : n->table = $5;
6043 : : n->roles = $6;
6044 : : n->qual = $7;
6045 : : n->with_check = $8;
6046 : : $$ = (Node *) n;
6047 : : }
6048 : : ;
6049 : :
6050 : : RowSecurityOptionalExpr:
6051 : : USING '(' a_expr ')' { $$ = $3; }
6052 : : | /* EMPTY */ { $$ = NULL; }
6053 : : ;
6054 : :
6055 : : RowSecurityOptionalWithCheck:
6056 : : WITH CHECK '(' a_expr ')' { $$ = $4; }
6057 : : | /* EMPTY */ { $$ = NULL; }
6058 : : ;
6059 : :
6060 : : RowSecurityDefaultToRole:
6061 : : TO role_list { $$ = $2; }
6062 : : | /* EMPTY */ { $$ = list_make1(makeRoleSpec(ROLESPEC_PUBLIC, -1)); }
6063 : : ;
6064 : :
6065 : : RowSecurityOptionalToRole:
6066 : : TO role_list { $$ = $2; }
6067 : : | /* EMPTY */ { $$ = NULL; }
6068 : : ;
6069 : :
6070 : : RowSecurityDefaultPermissive:
6071 : : AS IDENT
6072 : : {
6073 : : if (strcmp($2, "permissive") == 0)
6074 : : $$ = true;
6075 : : else if (strcmp($2, "restrictive") == 0)
6076 : : $$ = false;
6077 : : else
6078 : : ereport(ERROR,
6079 : : (errcode(ERRCODE_SYNTAX_ERROR),
6080 : : errmsg("unrecognized row security option \"%s\"", $2),
6081 : : errhint("Only PERMISSIVE or RESTRICTIVE policies are supported currently."),
6082 : : parser_errposition(@2)));
6083 : :
6084 : : }
6085 : : | /* EMPTY */ { $$ = true; }
6086 : : ;
6087 : :
6088 : : RowSecurityDefaultForCmd:
6089 : : FOR row_security_cmd { $$ = $2; }
6090 : : | /* EMPTY */ { $$ = "all"; }
6091 : : ;
6092 : :
6093 : : row_security_cmd:
6094 : : ALL { $$ = "all"; }
6095 : : | SELECT { $$ = "select"; }
6096 : : | INSERT { $$ = "insert"; }
6097 : : | UPDATE { $$ = "update"; }
6098 : : | DELETE_P { $$ = "delete"; }
6099 : : ;
6100 : :
6101 : : /*****************************************************************************
6102 : : *
6103 : : * QUERY:
6104 : : * CREATE ACCESS METHOD name HANDLER handler_name
6105 : : *
6106 : : *****************************************************************************/
6107 : :
6108 : : CreateAmStmt: CREATE ACCESS METHOD name TYPE_P am_type HANDLER handler_name
6109 : : {
6110 : : CreateAmStmt *n = makeNode(CreateAmStmt);
6111 : :
6112 : : n->amname = $4;
6113 : : n->handler_name = $8;
6114 : : n->amtype = $6;
6115 : : $$ = (Node *) n;
6116 : : }
6117 : : ;
6118 : :
6119 : : am_type:
6120 : : INDEX { $$ = AMTYPE_INDEX; }
6121 : : | TABLE { $$ = AMTYPE_TABLE; }
6122 : : ;
6123 : :
6124 : : /*****************************************************************************
6125 : : *
6126 : : * QUERIES :
6127 : : * CREATE TRIGGER ...
6128 : : *
6129 : : *****************************************************************************/
6130 : :
6131 : : CreateTrigStmt:
6132 : : CREATE opt_or_replace TRIGGER name TriggerActionTime TriggerEvents ON
6133 : : qualified_name TriggerReferencing TriggerForSpec TriggerWhen
6134 : : EXECUTE FUNCTION_or_PROCEDURE func_name '(' TriggerFuncArgs ')'
6135 : : {
6136 : : CreateTrigStmt *n = makeNode(CreateTrigStmt);
6137 : :
6138 : : n->replace = $2;
6139 : : n->isconstraint = false;
6140 : : n->trigname = $4;
6141 : : n->relation = $8;
6142 : : n->funcname = $14;
6143 : : n->args = $16;
6144 : : n->row = $10;
6145 : : n->timing = $5;
6146 : : n->events = intVal(linitial($6));
6147 : : n->columns = (List *) lsecond($6);
6148 : : n->whenClause = $11;
6149 : : n->transitionRels = $9;
6150 : : n->deferrable = false;
6151 : : n->initdeferred = false;
6152 : : n->constrrel = NULL;
6153 : : $$ = (Node *) n;
6154 : : }
6155 : : | CREATE opt_or_replace CONSTRAINT TRIGGER name AFTER TriggerEvents ON
6156 : : qualified_name OptConstrFromTable ConstraintAttributeSpec
6157 : : FOR EACH ROW TriggerWhen
6158 : : EXECUTE FUNCTION_or_PROCEDURE func_name '(' TriggerFuncArgs ')'
6159 : : {
6160 : : CreateTrigStmt *n = makeNode(CreateTrigStmt);
6161 : : bool dummy;
6162 : :
6163 : : if (($11 & CAS_NOT_VALID) != 0)
6164 : : ereport(ERROR,
6165 : : errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
6166 : : errmsg("constraint triggers cannot be marked %s",
6167 : : "NOT VALID"),
6168 : : parser_errposition(@11));
6169 : : if (($11 & CAS_NO_INHERIT) != 0)
6170 : : ereport(ERROR,
6171 : : errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
6172 : : errmsg("constraint triggers cannot be marked %s",
6173 : : "NO INHERIT"),
6174 : : parser_errposition(@11));
6175 : : if (($11 & CAS_NOT_ENFORCED) != 0)
6176 : : ereport(ERROR,
6177 : : errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
6178 : : errmsg("constraint triggers cannot be marked %s",
6179 : : "NOT ENFORCED"),
6180 : : parser_errposition(@11));
6181 : :
6182 : : n->replace = $2;
6183 : : if (n->replace) /* not supported, see CreateTrigger */
6184 : : ereport(ERROR,
6185 : : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
6186 : : errmsg("CREATE OR REPLACE CONSTRAINT TRIGGER is not supported"),
6187 : : parser_errposition(@1)));
6188 : : n->isconstraint = true;
6189 : : n->trigname = $5;
6190 : : n->relation = $9;
6191 : : n->funcname = $18;
6192 : : n->args = $20;
6193 : : n->row = true;
6194 : : n->timing = TRIGGER_TYPE_AFTER;
6195 : : n->events = intVal(linitial($7));
6196 : : n->columns = (List *) lsecond($7);
6197 : : n->whenClause = $15;
6198 : : n->transitionRels = NIL;
6199 : : processCASbits($11, @11, "TRIGGER",
6200 : : &n->deferrable, &n->initdeferred, &dummy,
6201 : : NULL, NULL, yyscanner);
6202 : : n->constrrel = $10;
6203 : : $$ = (Node *) n;
6204 : : }
6205 : : ;
6206 : :
6207 : : TriggerActionTime:
6208 : : BEFORE { $$ = TRIGGER_TYPE_BEFORE; }
6209 : : | AFTER { $$ = TRIGGER_TYPE_AFTER; }
6210 : : | INSTEAD OF { $$ = TRIGGER_TYPE_INSTEAD; }
6211 : : ;
6212 : :
6213 : : TriggerEvents:
6214 : : TriggerOneEvent
6215 : : { $$ = $1; }
6216 : : | TriggerEvents OR TriggerOneEvent
6217 : : {
6218 : : int events1 = intVal(linitial($1));
6219 : : int events2 = intVal(linitial($3));
6220 : : List *columns1 = (List *) lsecond($1);
6221 : : List *columns2 = (List *) lsecond($3);
6222 : :
6223 : : if (events1 & events2)
6224 : : parser_yyerror("duplicate trigger events specified");
6225 : : /*
6226 : : * concat'ing the columns lists loses information about
6227 : : * which columns went with which event, but so long as
6228 : : * only UPDATE carries columns and we disallow multiple
6229 : : * UPDATE items, it doesn't matter. Command execution
6230 : : * should just ignore the columns for non-UPDATE events.
6231 : : */
6232 : : $$ = list_make2(makeInteger(events1 | events2),
6233 : : list_concat(columns1, columns2));
6234 : : }
6235 : : ;
6236 : :
6237 : : TriggerOneEvent:
6238 : : INSERT
6239 : : { $$ = list_make2(makeInteger(TRIGGER_TYPE_INSERT), NIL); }
6240 : : | DELETE_P
6241 : : { $$ = list_make2(makeInteger(TRIGGER_TYPE_DELETE), NIL); }
6242 : : | UPDATE
6243 : : { $$ = list_make2(makeInteger(TRIGGER_TYPE_UPDATE), NIL); }
6244 : : | UPDATE OF columnList
6245 : : { $$ = list_make2(makeInteger(TRIGGER_TYPE_UPDATE), $3); }
6246 : : | TRUNCATE
6247 : : { $$ = list_make2(makeInteger(TRIGGER_TYPE_TRUNCATE), NIL); }
6248 : : ;
6249 : :
6250 : : TriggerReferencing:
6251 : : REFERENCING TriggerTransitions { $$ = $2; }
6252 : : | /*EMPTY*/ { $$ = NIL; }
6253 : : ;
6254 : :
6255 : : TriggerTransitions:
6256 : : TriggerTransition { $$ = list_make1($1); }
6257 : : | TriggerTransitions TriggerTransition { $$ = lappend($1, $2); }
6258 : : ;
6259 : :
6260 : : TriggerTransition:
6261 : : TransitionOldOrNew TransitionRowOrTable opt_as TransitionRelName
6262 : : {
6263 : : TriggerTransition *n = makeNode(TriggerTransition);
6264 : :
6265 : : n->name = $4;
6266 : : n->isNew = $1;
6267 : : n->isTable = $2;
6268 : : $$ = (Node *) n;
6269 : : }
6270 : : ;
6271 : :
6272 : : TransitionOldOrNew:
6273 : : NEW { $$ = true; }
6274 : : | OLD { $$ = false; }
6275 : : ;
6276 : :
6277 : : TransitionRowOrTable:
6278 : : TABLE { $$ = true; }
6279 : : /*
6280 : : * According to the standard, lack of a keyword here implies ROW.
6281 : : * Support for that would require prohibiting ROW entirely here,
6282 : : * reserving the keyword ROW, and/or requiring AS (instead of
6283 : : * allowing it to be optional, as the standard specifies) as the
6284 : : * next token. Requiring ROW seems cleanest and easiest to
6285 : : * explain.
6286 : : */
6287 : : | ROW { $$ = false; }
6288 : : ;
6289 : :
6290 : : TransitionRelName:
6291 : : ColId { $$ = $1; }
6292 : : ;
6293 : :
6294 : : TriggerForSpec:
6295 : : FOR TriggerForOptEach TriggerForType
6296 : : {
6297 : : $$ = $3;
6298 : : }
6299 : : | /* EMPTY */
6300 : : {
6301 : : /*
6302 : : * If ROW/STATEMENT not specified, default to
6303 : : * STATEMENT, per SQL
6304 : : */
6305 : : $$ = false;
6306 : : }
6307 : : ;
6308 : :
6309 : : TriggerForOptEach:
6310 : : EACH
6311 : : | /*EMPTY*/
6312 : : ;
6313 : :
6314 : : TriggerForType:
6315 : : ROW { $$ = true; }
6316 : : | STATEMENT { $$ = false; }
6317 : : ;
6318 : :
6319 : : TriggerWhen:
6320 : : WHEN '(' a_expr ')' { $$ = $3; }
6321 : : | /*EMPTY*/ { $$ = NULL; }
6322 : : ;
6323 : :
6324 : : FUNCTION_or_PROCEDURE:
6325 : : FUNCTION
6326 : : | PROCEDURE
6327 : : ;
6328 : :
6329 : : TriggerFuncArgs:
6330 : : TriggerFuncArg { $$ = list_make1($1); }
6331 : : | TriggerFuncArgs ',' TriggerFuncArg { $$ = lappend($1, $3); }
6332 : : | /*EMPTY*/ { $$ = NIL; }
6333 : : ;
6334 : :
6335 : : TriggerFuncArg:
6336 : : Iconst
6337 : : {
6338 : : $$ = (Node *) makeString(psprintf("%d", $1));
6339 : : }
6340 : : | FCONST { $$ = (Node *) makeString($1); }
6341 : : | Sconst { $$ = (Node *) makeString($1); }
6342 : : | ColLabel { $$ = (Node *) makeString($1); }
6343 : : ;
6344 : :
6345 : : OptConstrFromTable:
6346 : : FROM qualified_name { $$ = $2; }
6347 : : | /*EMPTY*/ { $$ = NULL; }
6348 : : ;
6349 : :
6350 : : ConstraintAttributeSpec:
6351 : : /*EMPTY*/
6352 : : { $$ = 0; }
6353 : : | ConstraintAttributeSpec ConstraintAttributeElem
6354 : : {
6355 : : /*
6356 : : * We must complain about conflicting options.
6357 : : * We could, but choose not to, complain about redundant
6358 : : * options (ie, where $2's bit is already set in $1).
6359 : : */
6360 : : int newspec = $1 | $2;
6361 : :
6362 : : /* special message for this case */
6363 : : if ((newspec & (CAS_NOT_DEFERRABLE | CAS_INITIALLY_DEFERRED)) == (CAS_NOT_DEFERRABLE | CAS_INITIALLY_DEFERRED))
6364 : : ereport(ERROR,
6365 : : (errcode(ERRCODE_SYNTAX_ERROR),
6366 : : errmsg("constraint declared INITIALLY DEFERRED must be DEFERRABLE"),
6367 : : parser_errposition(@2)));
6368 : : /* generic message for other conflicts */
6369 : : if ((newspec & (CAS_NOT_DEFERRABLE | CAS_DEFERRABLE)) == (CAS_NOT_DEFERRABLE | CAS_DEFERRABLE) ||
6370 : : (newspec & (CAS_INITIALLY_IMMEDIATE | CAS_INITIALLY_DEFERRED)) == (CAS_INITIALLY_IMMEDIATE | CAS_INITIALLY_DEFERRED) ||
6371 : : (newspec & (CAS_NOT_ENFORCED | CAS_ENFORCED)) == (CAS_NOT_ENFORCED | CAS_ENFORCED))
6372 : : ereport(ERROR,
6373 : : (errcode(ERRCODE_SYNTAX_ERROR),
6374 : : errmsg("conflicting constraint properties"),
6375 : : parser_errposition(@2)));
6376 : : $$ = newspec;
6377 : : }
6378 : : ;
6379 : :
6380 : : ConstraintAttributeElem:
6381 : : NOT DEFERRABLE { $$ = CAS_NOT_DEFERRABLE; }
6382 : : | DEFERRABLE { $$ = CAS_DEFERRABLE; }
6383 : : | INITIALLY IMMEDIATE { $$ = CAS_INITIALLY_IMMEDIATE; }
6384 : : | INITIALLY DEFERRED { $$ = CAS_INITIALLY_DEFERRED; }
6385 : : | NOT VALID { $$ = CAS_NOT_VALID; }
6386 : : | NO INHERIT { $$ = CAS_NO_INHERIT; }
6387 : : | NOT ENFORCED { $$ = CAS_NOT_ENFORCED; }
6388 : : | ENFORCED { $$ = CAS_ENFORCED; }
6389 : : ;
6390 : :
6391 : :
6392 : : /*****************************************************************************
6393 : : *
6394 : : * QUERIES :
6395 : : * CREATE EVENT TRIGGER ...
6396 : : * ALTER EVENT TRIGGER ...
6397 : : *
6398 : : *****************************************************************************/
6399 : :
6400 : : CreateEventTrigStmt:
6401 : : CREATE EVENT TRIGGER name ON ColLabel
6402 : : EXECUTE FUNCTION_or_PROCEDURE func_name '(' ')'
6403 : : {
6404 : : CreateEventTrigStmt *n = makeNode(CreateEventTrigStmt);
6405 : :
6406 : : n->trigname = $4;
6407 : : n->eventname = $6;
6408 : : n->whenclause = NULL;
6409 : : n->funcname = $9;
6410 : : $$ = (Node *) n;
6411 : : }
6412 : : | CREATE EVENT TRIGGER name ON ColLabel
6413 : : WHEN event_trigger_when_list
6414 : : EXECUTE FUNCTION_or_PROCEDURE func_name '(' ')'
6415 : : {
6416 : : CreateEventTrigStmt *n = makeNode(CreateEventTrigStmt);
6417 : :
6418 : : n->trigname = $4;
6419 : : n->eventname = $6;
6420 : : n->whenclause = $8;
6421 : : n->funcname = $11;
6422 : : $$ = (Node *) n;
6423 : : }
6424 : : ;
6425 : :
6426 : : event_trigger_when_list:
6427 : : event_trigger_when_item
6428 : : { $$ = list_make1($1); }
6429 : : | event_trigger_when_list AND event_trigger_when_item
6430 : : { $$ = lappend($1, $3); }
6431 : : ;
6432 : :
6433 : : event_trigger_when_item:
6434 : : ColId IN_P '(' event_trigger_value_list ')'
6435 : : { $$ = makeDefElem($1, (Node *) $4, @1); }
6436 : : ;
6437 : :
6438 : : event_trigger_value_list:
6439 : : SCONST
6440 : : { $$ = list_make1(makeString($1)); }
6441 : : | event_trigger_value_list ',' SCONST
6442 : : { $$ = lappend($1, makeString($3)); }
6443 : : ;
6444 : :
6445 : : AlterEventTrigStmt:
6446 : : ALTER EVENT TRIGGER name enable_trigger
6447 : : {
6448 : : AlterEventTrigStmt *n = makeNode(AlterEventTrigStmt);
6449 : :
6450 : : n->trigname = $4;
6451 : : n->tgenabled = $5;
6452 : : $$ = (Node *) n;
6453 : : }
6454 : : ;
6455 : :
6456 : : enable_trigger:
6457 : : ENABLE_P { $$ = TRIGGER_FIRES_ON_ORIGIN; }
6458 : : | ENABLE_P REPLICA { $$ = TRIGGER_FIRES_ON_REPLICA; }
6459 : : | ENABLE_P ALWAYS { $$ = TRIGGER_FIRES_ALWAYS; }
6460 : : | DISABLE_P { $$ = TRIGGER_DISABLED; }
6461 : : ;
6462 : :
6463 : : /*****************************************************************************
6464 : : *
6465 : : * QUERY :
6466 : : * CREATE ASSERTION ...
6467 : : *
6468 : : *****************************************************************************/
6469 : :
6470 : : CreateAssertionStmt:
6471 : : CREATE ASSERTION any_name CHECK '(' a_expr ')' ConstraintAttributeSpec
6472 : : {
6473 : : ereport(ERROR,
6474 : : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
6475 : : errmsg("CREATE ASSERTION is not yet implemented"),
6476 : : parser_errposition(@1)));
6477 : :
6478 : : $$ = NULL;
6479 : : }
6480 : : ;
6481 : :
6482 : :
6483 : : /*****************************************************************************
6484 : : *
6485 : : * QUERY :
6486 : : * define (aggregate,operator,type)
6487 : : *
6488 : : *****************************************************************************/
6489 : :
6490 : : DefineStmt:
6491 : : CREATE opt_or_replace AGGREGATE func_name aggr_args definition
6492 : : {
6493 : : DefineStmt *n = makeNode(DefineStmt);
6494 : :
6495 : : n->kind = OBJECT_AGGREGATE;
6496 : : n->oldstyle = false;
6497 : : n->replace = $2;
6498 : : n->defnames = $4;
6499 : : n->args = $5;
6500 : : n->definition = $6;
6501 : : $$ = (Node *) n;
6502 : : }
6503 : : | CREATE opt_or_replace AGGREGATE func_name old_aggr_definition
6504 : : {
6505 : : /* old-style (pre-8.2) syntax for CREATE AGGREGATE */
6506 : : DefineStmt *n = makeNode(DefineStmt);
6507 : :
6508 : : n->kind = OBJECT_AGGREGATE;
6509 : : n->oldstyle = true;
6510 : : n->replace = $2;
6511 : : n->defnames = $4;
6512 : : n->args = NIL;
6513 : : n->definition = $5;
6514 : : $$ = (Node *) n;
6515 : : }
6516 : : | CREATE OPERATOR any_operator definition
6517 : : {
6518 : : DefineStmt *n = makeNode(DefineStmt);
6519 : :
6520 : : n->kind = OBJECT_OPERATOR;
6521 : : n->oldstyle = false;
6522 : : n->defnames = $3;
6523 : : n->args = NIL;
6524 : : n->definition = $4;
6525 : : $$ = (Node *) n;
6526 : : }
6527 : : | CREATE TYPE_P any_name definition
6528 : : {
6529 : : DefineStmt *n = makeNode(DefineStmt);
6530 : :
6531 : : n->kind = OBJECT_TYPE;
6532 : : n->oldstyle = false;
6533 : : n->defnames = $3;
6534 : : n->args = NIL;
6535 : : n->definition = $4;
6536 : : $$ = (Node *) n;
6537 : : }
6538 : : | CREATE TYPE_P any_name
6539 : : {
6540 : : /* Shell type (identified by lack of definition) */
6541 : : DefineStmt *n = makeNode(DefineStmt);
6542 : :
6543 : : n->kind = OBJECT_TYPE;
6544 : : n->oldstyle = false;
6545 : : n->defnames = $3;
6546 : : n->args = NIL;
6547 : : n->definition = NIL;
6548 : : $$ = (Node *) n;
6549 : : }
6550 : : | CREATE TYPE_P any_name AS '(' OptTableFuncElementList ')'
6551 : : {
6552 : : CompositeTypeStmt *n = makeNode(CompositeTypeStmt);
6553 : :
6554 : : /* can't use qualified_name, sigh */
6555 : : n->typevar = makeRangeVarFromAnyName($3, @3, yyscanner);
6556 : : n->coldeflist = $6;
6557 : : $$ = (Node *) n;
6558 : : }
6559 : : | CREATE TYPE_P any_name AS ENUM_P '(' opt_enum_val_list ')'
6560 : : {
6561 : : CreateEnumStmt *n = makeNode(CreateEnumStmt);
6562 : :
6563 : : n->typeName = $3;
6564 : : n->vals = $7;
6565 : : $$ = (Node *) n;
6566 : : }
6567 : : | CREATE TYPE_P any_name AS RANGE definition
6568 : : {
6569 : : CreateRangeStmt *n = makeNode(CreateRangeStmt);
6570 : :
6571 : : n->typeName = $3;
6572 : : n->params = $6;
6573 : : $$ = (Node *) n;
6574 : : }
6575 : : | CREATE TEXT_P SEARCH PARSER any_name definition
6576 : : {
6577 : : DefineStmt *n = makeNode(DefineStmt);
6578 : :
6579 : : n->kind = OBJECT_TSPARSER;
6580 : : n->args = NIL;
6581 : : n->defnames = $5;
6582 : : n->definition = $6;
6583 : : $$ = (Node *) n;
6584 : : }
6585 : : | CREATE TEXT_P SEARCH DICTIONARY any_name definition
6586 : : {
6587 : : DefineStmt *n = makeNode(DefineStmt);
6588 : :
6589 : : n->kind = OBJECT_TSDICTIONARY;
6590 : : n->args = NIL;
6591 : : n->defnames = $5;
6592 : : n->definition = $6;
6593 : : $$ = (Node *) n;
6594 : : }
6595 : : | CREATE TEXT_P SEARCH TEMPLATE any_name definition
6596 : : {
6597 : : DefineStmt *n = makeNode(DefineStmt);
6598 : :
6599 : : n->kind = OBJECT_TSTEMPLATE;
6600 : : n->args = NIL;
6601 : : n->defnames = $5;
6602 : : n->definition = $6;
6603 : : $$ = (Node *) n;
6604 : : }
6605 : : | CREATE TEXT_P SEARCH CONFIGURATION any_name definition
6606 : : {
6607 : : DefineStmt *n = makeNode(DefineStmt);
6608 : :
6609 : : n->kind = OBJECT_TSCONFIGURATION;
6610 : : n->args = NIL;
6611 : : n->defnames = $5;
6612 : : n->definition = $6;
6613 : : $$ = (Node *) n;
6614 : : }
6615 : : | CREATE COLLATION any_name definition
6616 : : {
6617 : : DefineStmt *n = makeNode(DefineStmt);
6618 : :
6619 : : n->kind = OBJECT_COLLATION;
6620 : : n->args = NIL;
6621 : : n->defnames = $3;
6622 : : n->definition = $4;
6623 : : $$ = (Node *) n;
6624 : : }
6625 : : | CREATE COLLATION IF_P NOT EXISTS any_name definition
6626 : : {
6627 : : DefineStmt *n = makeNode(DefineStmt);
6628 : :
6629 : : n->kind = OBJECT_COLLATION;
6630 : : n->args = NIL;
6631 : : n->defnames = $6;
6632 : : n->definition = $7;
6633 : : n->if_not_exists = true;
6634 : : $$ = (Node *) n;
6635 : : }
6636 : : | CREATE COLLATION any_name FROM any_name
6637 : : {
6638 : : DefineStmt *n = makeNode(DefineStmt);
6639 : :
6640 : : n->kind = OBJECT_COLLATION;
6641 : : n->args = NIL;
6642 : : n->defnames = $3;
6643 : : n->definition = list_make1(makeDefElem("from", (Node *) $5, @5));
6644 : : $$ = (Node *) n;
6645 : : }
6646 : : | CREATE COLLATION IF_P NOT EXISTS any_name FROM any_name
6647 : : {
6648 : : DefineStmt *n = makeNode(DefineStmt);
6649 : :
6650 : : n->kind = OBJECT_COLLATION;
6651 : : n->args = NIL;
6652 : : n->defnames = $6;
6653 : : n->definition = list_make1(makeDefElem("from", (Node *) $8, @8));
6654 : : n->if_not_exists = true;
6655 : : $$ = (Node *) n;
6656 : : }
6657 : : ;
6658 : :
6659 : : definition: '(' def_list ')' { $$ = $2; }
6660 : : ;
6661 : :
6662 : : def_list: def_elem { $$ = list_make1($1); }
6663 : : | def_list ',' def_elem { $$ = lappend($1, $3); }
6664 : : ;
6665 : :
6666 : : def_elem: ColLabel '=' def_arg
6667 : : {
6668 : : $$ = makeDefElem($1, (Node *) $3, @1);
6669 : : }
6670 : : | ColLabel
6671 : : {
6672 : : $$ = makeDefElem($1, NULL, @1);
6673 : : }
6674 : : ;
6675 : :
6676 : : /* Note: any simple identifier will be returned as a type name! */
6677 : : def_arg: func_type { $$ = (Node *) $1; }
6678 : : | reserved_keyword { $$ = (Node *) makeString(pstrdup($1)); }
6679 : : | qual_all_Op { $$ = (Node *) $1; }
6680 : : | NumericOnly { $$ = (Node *) $1; }
6681 : : | Sconst { $$ = (Node *) makeString($1); }
6682 : : | NONE { $$ = (Node *) makeString(pstrdup($1)); }
6683 : : ;
6684 : :
6685 : : old_aggr_definition: '(' old_aggr_list ')' { $$ = $2; }
6686 : : ;
6687 : :
6688 : : old_aggr_list: old_aggr_elem { $$ = list_make1($1); }
6689 : : | old_aggr_list ',' old_aggr_elem { $$ = lappend($1, $3); }
6690 : : ;
6691 : :
6692 : : /*
6693 : : * Must use IDENT here to avoid reduce/reduce conflicts; fortunately none of
6694 : : * the item names needed in old aggregate definitions are likely to become
6695 : : * SQL keywords.
6696 : : */
6697 : : old_aggr_elem: IDENT '=' def_arg
6698 : : {
6699 : : $$ = makeDefElem($1, (Node *) $3, @1);
6700 : : }
6701 : : ;
6702 : :
6703 : : opt_enum_val_list:
6704 : : enum_val_list { $$ = $1; }
6705 : : | /*EMPTY*/ { $$ = NIL; }
6706 : : ;
6707 : :
6708 : : enum_val_list: Sconst
6709 : : { $$ = list_make1(makeString($1)); }
6710 : : | enum_val_list ',' Sconst
6711 : : { $$ = lappend($1, makeString($3)); }
6712 : : ;
6713 : :
6714 : : /*****************************************************************************
6715 : : *
6716 : : * ALTER TYPE enumtype ADD ...
6717 : : *
6718 : : *****************************************************************************/
6719 : :
6720 : : AlterEnumStmt:
6721 : : ALTER TYPE_P any_name ADD_P VALUE_P opt_if_not_exists Sconst
6722 : : {
6723 : : AlterEnumStmt *n = makeNode(AlterEnumStmt);
6724 : :
6725 : : n->typeName = $3;
6726 : : n->oldVal = NULL;
6727 : : n->newVal = $7;
6728 : : n->newValNeighbor = NULL;
6729 : : n->newValIsAfter = true;
6730 : : n->skipIfNewValExists = $6;
6731 : : $$ = (Node *) n;
6732 : : }
6733 : : | ALTER TYPE_P any_name ADD_P VALUE_P opt_if_not_exists Sconst BEFORE Sconst
6734 : : {
6735 : : AlterEnumStmt *n = makeNode(AlterEnumStmt);
6736 : :
6737 : : n->typeName = $3;
6738 : : n->oldVal = NULL;
6739 : : n->newVal = $7;
6740 : : n->newValNeighbor = $9;
6741 : : n->newValIsAfter = false;
6742 : : n->skipIfNewValExists = $6;
6743 : : $$ = (Node *) n;
6744 : : }
6745 : : | ALTER TYPE_P any_name ADD_P VALUE_P opt_if_not_exists Sconst AFTER Sconst
6746 : : {
6747 : : AlterEnumStmt *n = makeNode(AlterEnumStmt);
6748 : :
6749 : : n->typeName = $3;
6750 : : n->oldVal = NULL;
6751 : : n->newVal = $7;
6752 : : n->newValNeighbor = $9;
6753 : : n->newValIsAfter = true;
6754 : : n->skipIfNewValExists = $6;
6755 : : $$ = (Node *) n;
6756 : : }
6757 : : | ALTER TYPE_P any_name RENAME VALUE_P Sconst TO Sconst
6758 : : {
6759 : : AlterEnumStmt *n = makeNode(AlterEnumStmt);
6760 : :
6761 : : n->typeName = $3;
6762 : : n->oldVal = $6;
6763 : : n->newVal = $8;
6764 : : n->newValNeighbor = NULL;
6765 : : n->newValIsAfter = false;
6766 : : n->skipIfNewValExists = false;
6767 : : $$ = (Node *) n;
6768 : : }
6769 : : | ALTER TYPE_P any_name DROP VALUE_P Sconst
6770 : : {
6771 : : /*
6772 : : * The following problems must be solved before this can be
6773 : : * implemented:
6774 : : *
6775 : : * - There must be no instance of the target value in
6776 : : * any table.
6777 : : *
6778 : : * - The value must not appear in any catalog metadata,
6779 : : * such as stored view expressions or column defaults.
6780 : : *
6781 : : * - The value must not appear in any non-leaf page of a
6782 : : * btree (and similar issues with other index types).
6783 : : * This is problematic because a value could persist
6784 : : * there long after it's gone from user-visible data.
6785 : : *
6786 : : * - Concurrent sessions must not be able to insert the
6787 : : * value while the preceding conditions are being checked.
6788 : : *
6789 : : * - Possibly more...
6790 : : */
6791 : : ereport(ERROR,
6792 : : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
6793 : : errmsg("dropping an enum value is not implemented"),
6794 : : parser_errposition(@4)));
6795 : : }
6796 : : ;
6797 : :
6798 : : opt_if_not_exists: IF_P NOT EXISTS { $$ = true; }
6799 : : | /* EMPTY */ { $$ = false; }
6800 : : ;
6801 : :
6802 : :
6803 : : /*****************************************************************************
6804 : : *
6805 : : * QUERIES :
6806 : : * CREATE OPERATOR CLASS ...
6807 : : * CREATE OPERATOR FAMILY ...
6808 : : * ALTER OPERATOR FAMILY ...
6809 : : * DROP OPERATOR CLASS ...
6810 : : * DROP OPERATOR FAMILY ...
6811 : : *
6812 : : *****************************************************************************/
6813 : :
6814 : : CreateOpClassStmt:
6815 : : CREATE OPERATOR CLASS any_name opt_default FOR TYPE_P Typename
6816 : : USING name opt_opfamily AS opclass_item_list
6817 : : {
6818 : : CreateOpClassStmt *n = makeNode(CreateOpClassStmt);
6819 : :
6820 : : n->opclassname = $4;
6821 : : n->isDefault = $5;
6822 : : n->datatype = $8;
6823 : : n->amname = $10;
6824 : : n->opfamilyname = $11;
6825 : : n->items = $13;
6826 : : $$ = (Node *) n;
6827 : : }
6828 : : ;
6829 : :
6830 : : opclass_item_list:
6831 : : opclass_item { $$ = list_make1($1); }
6832 : : | opclass_item_list ',' opclass_item { $$ = lappend($1, $3); }
6833 : : ;
6834 : :
6835 : : opclass_item:
6836 : : OPERATOR Iconst any_operator opclass_purpose
6837 : : {
6838 : : CreateOpClassItem *n = makeNode(CreateOpClassItem);
6839 : : ObjectWithArgs *owa = makeNode(ObjectWithArgs);
6840 : :
6841 : : owa->objname = $3;
6842 : : owa->objargs = NIL;
6843 : : n->itemtype = OPCLASS_ITEM_OPERATOR;
6844 : : n->name = owa;
6845 : : n->number = $2;
6846 : : n->order_family = $4;
6847 : : $$ = (Node *) n;
6848 : : }
6849 : : | OPERATOR Iconst operator_with_argtypes opclass_purpose
6850 : : {
6851 : : CreateOpClassItem *n = makeNode(CreateOpClassItem);
6852 : :
6853 : : n->itemtype = OPCLASS_ITEM_OPERATOR;
6854 : : n->name = $3;
6855 : : n->number = $2;
6856 : : n->order_family = $4;
6857 : : $$ = (Node *) n;
6858 : : }
6859 : : | FUNCTION Iconst function_with_argtypes
6860 : : {
6861 : : CreateOpClassItem *n = makeNode(CreateOpClassItem);
6862 : :
6863 : : n->itemtype = OPCLASS_ITEM_FUNCTION;
6864 : : n->name = $3;
6865 : : n->number = $2;
6866 : : $$ = (Node *) n;
6867 : : }
6868 : : | FUNCTION Iconst '(' type_list ')' function_with_argtypes
6869 : : {
6870 : : CreateOpClassItem *n = makeNode(CreateOpClassItem);
6871 : :
6872 : : n->itemtype = OPCLASS_ITEM_FUNCTION;
6873 : : n->name = $6;
6874 : : n->number = $2;
6875 : : n->class_args = $4;
6876 : : $$ = (Node *) n;
6877 : : }
6878 : : | STORAGE Typename
6879 : : {
6880 : : CreateOpClassItem *n = makeNode(CreateOpClassItem);
6881 : :
6882 : : n->itemtype = OPCLASS_ITEM_STORAGETYPE;
6883 : : n->storedtype = $2;
6884 : : $$ = (Node *) n;
6885 : : }
6886 : : ;
6887 : :
6888 : : opt_default: DEFAULT { $$ = true; }
6889 : : | /*EMPTY*/ { $$ = false; }
6890 : : ;
6891 : :
6892 : : opt_opfamily: FAMILY any_name { $$ = $2; }
6893 : : | /*EMPTY*/ { $$ = NIL; }
6894 : : ;
6895 : :
6896 : : opclass_purpose: FOR SEARCH { $$ = NIL; }
6897 : : | FOR ORDER BY any_name { $$ = $4; }
6898 : : | /*EMPTY*/ { $$ = NIL; }
6899 : : ;
6900 : :
6901 : :
6902 : : CreateOpFamilyStmt:
6903 : : CREATE OPERATOR FAMILY any_name USING name
6904 : : {
6905 : : CreateOpFamilyStmt *n = makeNode(CreateOpFamilyStmt);
6906 : :
6907 : : n->opfamilyname = $4;
6908 : : n->amname = $6;
6909 : : $$ = (Node *) n;
6910 : : }
6911 : : ;
6912 : :
6913 : : AlterOpFamilyStmt:
6914 : : ALTER OPERATOR FAMILY any_name USING name ADD_P opclass_item_list
6915 : : {
6916 : : AlterOpFamilyStmt *n = makeNode(AlterOpFamilyStmt);
6917 : :
6918 : : n->opfamilyname = $4;
6919 : : n->amname = $6;
6920 : : n->isDrop = false;
6921 : : n->items = $8;
6922 : : $$ = (Node *) n;
6923 : : }
6924 : : | ALTER OPERATOR FAMILY any_name USING name DROP opclass_drop_list
6925 : : {
6926 : : AlterOpFamilyStmt *n = makeNode(AlterOpFamilyStmt);
6927 : :
6928 : : n->opfamilyname = $4;
6929 : : n->amname = $6;
6930 : : n->isDrop = true;
6931 : : n->items = $8;
6932 : : $$ = (Node *) n;
6933 : : }
6934 : : ;
6935 : :
6936 : : opclass_drop_list:
6937 : : opclass_drop { $$ = list_make1($1); }
6938 : : | opclass_drop_list ',' opclass_drop { $$ = lappend($1, $3); }
6939 : : ;
6940 : :
6941 : : opclass_drop:
6942 : : OPERATOR Iconst '(' type_list ')'
6943 : : {
6944 : : CreateOpClassItem *n = makeNode(CreateOpClassItem);
6945 : :
6946 : : n->itemtype = OPCLASS_ITEM_OPERATOR;
6947 : : n->number = $2;
6948 : : n->class_args = $4;
6949 : : $$ = (Node *) n;
6950 : : }
6951 : : | FUNCTION Iconst '(' type_list ')'
6952 : : {
6953 : : CreateOpClassItem *n = makeNode(CreateOpClassItem);
6954 : :
6955 : : n->itemtype = OPCLASS_ITEM_FUNCTION;
6956 : : n->number = $2;
6957 : : n->class_args = $4;
6958 : : $$ = (Node *) n;
6959 : : }
6960 : : ;
6961 : :
6962 : :
6963 : : DropOpClassStmt:
6964 : : DROP OPERATOR CLASS any_name USING name opt_drop_behavior
6965 : : {
6966 : : DropStmt *n = makeNode(DropStmt);
6967 : :
6968 : : n->objects = list_make1(lcons(makeString($6), $4));
6969 : : n->removeType = OBJECT_OPCLASS;
6970 : : n->behavior = $7;
6971 : : n->missing_ok = false;
6972 : : n->concurrent = false;
6973 : : $$ = (Node *) n;
6974 : : }
6975 : : | DROP OPERATOR CLASS IF_P EXISTS any_name USING name opt_drop_behavior
6976 : : {
6977 : : DropStmt *n = makeNode(DropStmt);
6978 : :
6979 : : n->objects = list_make1(lcons(makeString($8), $6));
6980 : : n->removeType = OBJECT_OPCLASS;
6981 : : n->behavior = $9;
6982 : : n->missing_ok = true;
6983 : : n->concurrent = false;
6984 : : $$ = (Node *) n;
6985 : : }
6986 : : ;
6987 : :
6988 : : DropOpFamilyStmt:
6989 : : DROP OPERATOR FAMILY any_name USING name opt_drop_behavior
6990 : : {
6991 : : DropStmt *n = makeNode(DropStmt);
6992 : :
6993 : : n->objects = list_make1(lcons(makeString($6), $4));
6994 : : n->removeType = OBJECT_OPFAMILY;
6995 : : n->behavior = $7;
6996 : : n->missing_ok = false;
6997 : : n->concurrent = false;
6998 : : $$ = (Node *) n;
6999 : : }
7000 : : | DROP OPERATOR FAMILY IF_P EXISTS any_name USING name opt_drop_behavior
7001 : : {
7002 : : DropStmt *n = makeNode(DropStmt);
7003 : :
7004 : : n->objects = list_make1(lcons(makeString($8), $6));
7005 : : n->removeType = OBJECT_OPFAMILY;
7006 : : n->behavior = $9;
7007 : : n->missing_ok = true;
7008 : : n->concurrent = false;
7009 : : $$ = (Node *) n;
7010 : : }
7011 : : ;
7012 : :
7013 : :
7014 : : /*****************************************************************************
7015 : : *
7016 : : * QUERY:
7017 : : *
7018 : : * DROP OWNED BY username [, username ...] [ RESTRICT | CASCADE ]
7019 : : * REASSIGN OWNED BY username [, username ...] TO username
7020 : : *
7021 : : *****************************************************************************/
7022 : : DropOwnedStmt:
7023 : : DROP OWNED BY role_list opt_drop_behavior
7024 : : {
7025 : : DropOwnedStmt *n = makeNode(DropOwnedStmt);
7026 : :
7027 : : n->roles = $4;
7028 : : n->behavior = $5;
7029 : : $$ = (Node *) n;
7030 : : }
7031 : : ;
7032 : :
7033 : : ReassignOwnedStmt:
7034 : : REASSIGN OWNED BY role_list TO RoleSpec
7035 : : {
7036 : : ReassignOwnedStmt *n = makeNode(ReassignOwnedStmt);
7037 : :
7038 : : n->roles = $4;
7039 : : n->newrole = $6;
7040 : : $$ = (Node *) n;
7041 : : }
7042 : : ;
7043 : :
7044 : : /*****************************************************************************
7045 : : *
7046 : : * QUERY:
7047 : : *
7048 : : * DROP itemtype [ IF EXISTS ] itemname [, itemname ...]
7049 : : * [ RESTRICT | CASCADE ]
7050 : : *
7051 : : *****************************************************************************/
7052 : :
7053 : : DropStmt: DROP object_type_any_name IF_P EXISTS any_name_list opt_drop_behavior
7054 : : {
7055 : : DropStmt *n = makeNode(DropStmt);
7056 : :
7057 : : n->removeType = $2;
7058 : : n->missing_ok = true;
7059 : : n->objects = $5;
7060 : : n->behavior = $6;
7061 : : n->concurrent = false;
7062 : : $$ = (Node *) n;
7063 : : }
7064 : : | DROP object_type_any_name any_name_list opt_drop_behavior
7065 : : {
7066 : : DropStmt *n = makeNode(DropStmt);
7067 : :
7068 : : n->removeType = $2;
7069 : : n->missing_ok = false;
7070 : : n->objects = $3;
7071 : : n->behavior = $4;
7072 : : n->concurrent = false;
7073 : : $$ = (Node *) n;
7074 : : }
7075 : : | DROP drop_type_name IF_P EXISTS name_list opt_drop_behavior
7076 : : {
7077 : : DropStmt *n = makeNode(DropStmt);
7078 : :
7079 : : n->removeType = $2;
7080 : : n->missing_ok = true;
7081 : : n->objects = $5;
7082 : : n->behavior = $6;
7083 : : n->concurrent = false;
7084 : : $$ = (Node *) n;
7085 : : }
7086 : : | DROP drop_type_name name_list opt_drop_behavior
7087 : : {
7088 : : DropStmt *n = makeNode(DropStmt);
7089 : :
7090 : : n->removeType = $2;
7091 : : n->missing_ok = false;
7092 : : n->objects = $3;
7093 : : n->behavior = $4;
7094 : : n->concurrent = false;
7095 : : $$ = (Node *) n;
7096 : : }
7097 : : | DROP object_type_name_on_any_name name ON any_name opt_drop_behavior
7098 : : {
7099 : : DropStmt *n = makeNode(DropStmt);
7100 : :
7101 : : n->removeType = $2;
7102 : : n->objects = list_make1(lappend($5, makeString($3)));
7103 : : n->behavior = $6;
7104 : : n->missing_ok = false;
7105 : : n->concurrent = false;
7106 : : $$ = (Node *) n;
7107 : : }
7108 : : | DROP object_type_name_on_any_name IF_P EXISTS name ON any_name opt_drop_behavior
7109 : : {
7110 : : DropStmt *n = makeNode(DropStmt);
7111 : :
7112 : : n->removeType = $2;
7113 : : n->objects = list_make1(lappend($7, makeString($5)));
7114 : : n->behavior = $8;
7115 : : n->missing_ok = true;
7116 : : n->concurrent = false;
7117 : : $$ = (Node *) n;
7118 : : }
7119 : : | DROP TYPE_P type_name_list opt_drop_behavior
7120 : : {
7121 : : DropStmt *n = makeNode(DropStmt);
7122 : :
7123 : : n->removeType = OBJECT_TYPE;
7124 : : n->missing_ok = false;
7125 : : n->objects = $3;
7126 : : n->behavior = $4;
7127 : : n->concurrent = false;
7128 : : $$ = (Node *) n;
7129 : : }
7130 : : | DROP TYPE_P IF_P EXISTS type_name_list opt_drop_behavior
7131 : : {
7132 : : DropStmt *n = makeNode(DropStmt);
7133 : :
7134 : : n->removeType = OBJECT_TYPE;
7135 : : n->missing_ok = true;
7136 : : n->objects = $5;
7137 : : n->behavior = $6;
7138 : : n->concurrent = false;
7139 : : $$ = (Node *) n;
7140 : : }
7141 : : | DROP DOMAIN_P type_name_list opt_drop_behavior
7142 : : {
7143 : : DropStmt *n = makeNode(DropStmt);
7144 : :
7145 : : n->removeType = OBJECT_DOMAIN;
7146 : : n->missing_ok = false;
7147 : : n->objects = $3;
7148 : : n->behavior = $4;
7149 : : n->concurrent = false;
7150 : : $$ = (Node *) n;
7151 : : }
7152 : : | DROP DOMAIN_P IF_P EXISTS type_name_list opt_drop_behavior
7153 : : {
7154 : : DropStmt *n = makeNode(DropStmt);
7155 : :
7156 : : n->removeType = OBJECT_DOMAIN;
7157 : : n->missing_ok = true;
7158 : : n->objects = $5;
7159 : : n->behavior = $6;
7160 : : n->concurrent = false;
7161 : : $$ = (Node *) n;
7162 : : }
7163 : : | DROP INDEX CONCURRENTLY any_name_list opt_drop_behavior
7164 : : {
7165 : : DropStmt *n = makeNode(DropStmt);
7166 : :
7167 : : n->removeType = OBJECT_INDEX;
7168 : : n->missing_ok = false;
7169 : : n->objects = $4;
7170 : : n->behavior = $5;
7171 : : n->concurrent = true;
7172 : : $$ = (Node *) n;
7173 : : }
7174 : : | DROP INDEX CONCURRENTLY IF_P EXISTS any_name_list opt_drop_behavior
7175 : : {
7176 : : DropStmt *n = makeNode(DropStmt);
7177 : :
7178 : : n->removeType = OBJECT_INDEX;
7179 : : n->missing_ok = true;
7180 : : n->objects = $6;
7181 : : n->behavior = $7;
7182 : : n->concurrent = true;
7183 : : $$ = (Node *) n;
7184 : : }
7185 : : ;
7186 : :
7187 : : /* object types taking any_name/any_name_list */
7188 : : object_type_any_name:
7189 : : TABLE { $$ = OBJECT_TABLE; }
7190 : : | SEQUENCE { $$ = OBJECT_SEQUENCE; }
7191 : : | VIEW { $$ = OBJECT_VIEW; }
7192 : : | MATERIALIZED VIEW { $$ = OBJECT_MATVIEW; }
7193 : : | INDEX { $$ = OBJECT_INDEX; }
7194 : : | FOREIGN TABLE { $$ = OBJECT_FOREIGN_TABLE; }
7195 : : | COLLATION { $$ = OBJECT_COLLATION; }
7196 : : | CONVERSION_P { $$ = OBJECT_CONVERSION; }
7197 : : | STATISTICS { $$ = OBJECT_STATISTIC_EXT; }
7198 : : | TEXT_P SEARCH PARSER { $$ = OBJECT_TSPARSER; }
7199 : : | TEXT_P SEARCH DICTIONARY { $$ = OBJECT_TSDICTIONARY; }
7200 : : | TEXT_P SEARCH TEMPLATE { $$ = OBJECT_TSTEMPLATE; }
7201 : : | TEXT_P SEARCH CONFIGURATION { $$ = OBJECT_TSCONFIGURATION; }
7202 : : ;
7203 : :
7204 : : /*
7205 : : * object types taking name/name_list
7206 : : *
7207 : : * DROP handles some of them separately
7208 : : */
7209 : :
7210 : : object_type_name:
7211 : : drop_type_name { $$ = $1; }
7212 : : | DATABASE { $$ = OBJECT_DATABASE; }
7213 : : | ROLE { $$ = OBJECT_ROLE; }
7214 : : | SUBSCRIPTION { $$ = OBJECT_SUBSCRIPTION; }
7215 : : | TABLESPACE { $$ = OBJECT_TABLESPACE; }
7216 : : ;
7217 : :
7218 : : drop_type_name:
7219 : : ACCESS METHOD { $$ = OBJECT_ACCESS_METHOD; }
7220 : : | EVENT TRIGGER { $$ = OBJECT_EVENT_TRIGGER; }
7221 : : | EXTENSION { $$ = OBJECT_EXTENSION; }
7222 : : | FOREIGN DATA_P WRAPPER { $$ = OBJECT_FDW; }
7223 : : | opt_procedural LANGUAGE { $$ = OBJECT_LANGUAGE; }
7224 : : | PUBLICATION { $$ = OBJECT_PUBLICATION; }
7225 : : | SCHEMA { $$ = OBJECT_SCHEMA; }
7226 : : | SERVER { $$ = OBJECT_FOREIGN_SERVER; }
7227 : : ;
7228 : :
7229 : : /* object types attached to a table */
7230 : : object_type_name_on_any_name:
7231 : : POLICY { $$ = OBJECT_POLICY; }
7232 : : | RULE { $$ = OBJECT_RULE; }
7233 : : | TRIGGER { $$ = OBJECT_TRIGGER; }
7234 : : ;
7235 : :
7236 : : any_name_list:
7237 : : any_name { $$ = list_make1($1); }
7238 : : | any_name_list ',' any_name { $$ = lappend($1, $3); }
7239 : : ;
7240 : :
7241 : : any_name: ColId { $$ = list_make1(makeString($1)); }
7242 : : | ColId attrs { $$ = lcons(makeString($1), $2); }
7243 : : ;
7244 : :
7245 : : attrs: '.' attr_name
7246 : : { $$ = list_make1(makeString($2)); }
7247 : : | attrs '.' attr_name
7248 : : { $$ = lappend($1, makeString($3)); }
7249 : : ;
7250 : :
7251 : : type_name_list:
7252 : : Typename { $$ = list_make1($1); }
7253 : : | type_name_list ',' Typename { $$ = lappend($1, $3); }
7254 : : ;
7255 : :
7256 : : /*****************************************************************************
7257 : : *
7258 : : * QUERY:
7259 : : * truncate table relname1, relname2, ...
7260 : : *
7261 : : *****************************************************************************/
7262 : :
7263 : : TruncateStmt:
7264 : : TRUNCATE opt_table relation_expr_list opt_restart_seqs opt_drop_behavior
7265 : : {
7266 : : TruncateStmt *n = makeNode(TruncateStmt);
7267 : :
7268 : : n->relations = $3;
7269 : : n->restart_seqs = $4;
7270 : : n->behavior = $5;
7271 : : $$ = (Node *) n;
7272 : : }
7273 : : ;
7274 : :
7275 : : opt_restart_seqs:
7276 : : CONTINUE_P IDENTITY_P { $$ = false; }
7277 : : | RESTART IDENTITY_P { $$ = true; }
7278 : : | /* EMPTY */ { $$ = false; }
7279 : : ;
7280 : :
7281 : : /*****************************************************************************
7282 : : *
7283 : : * COMMENT ON <object> IS <text>
7284 : : *
7285 : : *****************************************************************************/
7286 : :
7287 : : CommentStmt:
7288 : : COMMENT ON object_type_any_name any_name IS comment_text
7289 : : {
7290 : : CommentStmt *n = makeNode(CommentStmt);
7291 : :
7292 : : n->objtype = $3;
7293 : : n->object = (Node *) $4;
7294 : : n->comment = $6;
7295 : : $$ = (Node *) n;
7296 : : }
7297 : : | COMMENT ON COLUMN any_name IS comment_text
7298 : : {
7299 : : CommentStmt *n = makeNode(CommentStmt);
7300 : :
7301 : : n->objtype = OBJECT_COLUMN;
7302 : : n->object = (Node *) $4;
7303 : : n->comment = $6;
7304 : : $$ = (Node *) n;
7305 : : }
7306 : : | COMMENT ON object_type_name name IS comment_text
7307 : : {
7308 : : CommentStmt *n = makeNode(CommentStmt);
7309 : :
7310 : : n->objtype = $3;
7311 : : n->object = (Node *) makeString($4);
7312 : : n->comment = $6;
7313 : : $$ = (Node *) n;
7314 : : }
7315 : : | COMMENT ON TYPE_P Typename IS comment_text
7316 : : {
7317 : : CommentStmt *n = makeNode(CommentStmt);
7318 : :
7319 : : n->objtype = OBJECT_TYPE;
7320 : : n->object = (Node *) $4;
7321 : : n->comment = $6;
7322 : : $$ = (Node *) n;
7323 : : }
7324 : : | COMMENT ON DOMAIN_P Typename IS comment_text
7325 : : {
7326 : : CommentStmt *n = makeNode(CommentStmt);
7327 : :
7328 : : n->objtype = OBJECT_DOMAIN;
7329 : : n->object = (Node *) $4;
7330 : : n->comment = $6;
7331 : : $$ = (Node *) n;
7332 : : }
7333 : : | COMMENT ON AGGREGATE aggregate_with_argtypes IS comment_text
7334 : : {
7335 : : CommentStmt *n = makeNode(CommentStmt);
7336 : :
7337 : : n->objtype = OBJECT_AGGREGATE;
7338 : : n->object = (Node *) $4;
7339 : : n->comment = $6;
7340 : : $$ = (Node *) n;
7341 : : }
7342 : : | COMMENT ON FUNCTION function_with_argtypes IS comment_text
7343 : : {
7344 : : CommentStmt *n = makeNode(CommentStmt);
7345 : :
7346 : : n->objtype = OBJECT_FUNCTION;
7347 : : n->object = (Node *) $4;
7348 : : n->comment = $6;
7349 : : $$ = (Node *) n;
7350 : : }
7351 : : | COMMENT ON OPERATOR operator_with_argtypes IS comment_text
7352 : : {
7353 : : CommentStmt *n = makeNode(CommentStmt);
7354 : :
7355 : : n->objtype = OBJECT_OPERATOR;
7356 : : n->object = (Node *) $4;
7357 : : n->comment = $6;
7358 : : $$ = (Node *) n;
7359 : : }
7360 : : | COMMENT ON CONSTRAINT name ON any_name IS comment_text
7361 : : {
7362 : : CommentStmt *n = makeNode(CommentStmt);
7363 : :
7364 : : n->objtype = OBJECT_TABCONSTRAINT;
7365 : : n->object = (Node *) lappend($6, makeString($4));
7366 : : n->comment = $8;
7367 : : $$ = (Node *) n;
7368 : : }
7369 : : | COMMENT ON CONSTRAINT name ON DOMAIN_P any_name IS comment_text
7370 : : {
7371 : : CommentStmt *n = makeNode(CommentStmt);
7372 : :
7373 : : n->objtype = OBJECT_DOMCONSTRAINT;
7374 : : /*
7375 : : * should use Typename not any_name in the production, but
7376 : : * there's a shift/reduce conflict if we do that, so fix it
7377 : : * up here.
7378 : : */
7379 : : n->object = (Node *) list_make2(makeTypeNameFromNameList($7), makeString($4));
7380 : : n->comment = $9;
7381 : : $$ = (Node *) n;
7382 : : }
7383 : : | COMMENT ON object_type_name_on_any_name name ON any_name IS comment_text
7384 : : {
7385 : : CommentStmt *n = makeNode(CommentStmt);
7386 : :
7387 : : n->objtype = $3;
7388 : : n->object = (Node *) lappend($6, makeString($4));
7389 : : n->comment = $8;
7390 : : $$ = (Node *) n;
7391 : : }
7392 : : | COMMENT ON PROCEDURE function_with_argtypes IS comment_text
7393 : : {
7394 : : CommentStmt *n = makeNode(CommentStmt);
7395 : :
7396 : : n->objtype = OBJECT_PROCEDURE;
7397 : : n->object = (Node *) $4;
7398 : : n->comment = $6;
7399 : : $$ = (Node *) n;
7400 : : }
7401 : : | COMMENT ON ROUTINE function_with_argtypes IS comment_text
7402 : : {
7403 : : CommentStmt *n = makeNode(CommentStmt);
7404 : :
7405 : : n->objtype = OBJECT_ROUTINE;
7406 : : n->object = (Node *) $4;
7407 : : n->comment = $6;
7408 : : $$ = (Node *) n;
7409 : : }
7410 : : | COMMENT ON TRANSFORM FOR Typename LANGUAGE name IS comment_text
7411 : : {
7412 : : CommentStmt *n = makeNode(CommentStmt);
7413 : :
7414 : : n->objtype = OBJECT_TRANSFORM;
7415 : : n->object = (Node *) list_make2($5, makeString($7));
7416 : : n->comment = $9;
7417 : : $$ = (Node *) n;
7418 : : }
7419 : : | COMMENT ON OPERATOR CLASS any_name USING name IS comment_text
7420 : : {
7421 : : CommentStmt *n = makeNode(CommentStmt);
7422 : :
7423 : : n->objtype = OBJECT_OPCLASS;
7424 : : n->object = (Node *) lcons(makeString($7), $5);
7425 : : n->comment = $9;
7426 : : $$ = (Node *) n;
7427 : : }
7428 : : | COMMENT ON OPERATOR FAMILY any_name USING name IS comment_text
7429 : : {
7430 : : CommentStmt *n = makeNode(CommentStmt);
7431 : :
7432 : : n->objtype = OBJECT_OPFAMILY;
7433 : : n->object = (Node *) lcons(makeString($7), $5);
7434 : : n->comment = $9;
7435 : : $$ = (Node *) n;
7436 : : }
7437 : : | COMMENT ON LARGE_P OBJECT_P NumericOnly IS comment_text
7438 : : {
7439 : : CommentStmt *n = makeNode(CommentStmt);
7440 : :
7441 : : n->objtype = OBJECT_LARGEOBJECT;
7442 : : n->object = (Node *) $5;
7443 : : n->comment = $7;
7444 : : $$ = (Node *) n;
7445 : : }
7446 : : | COMMENT ON CAST '(' Typename AS Typename ')' IS comment_text
7447 : : {
7448 : : CommentStmt *n = makeNode(CommentStmt);
7449 : :
7450 : : n->objtype = OBJECT_CAST;
7451 : : n->object = (Node *) list_make2($5, $7);
7452 : : n->comment = $10;
7453 : : $$ = (Node *) n;
7454 : : }
7455 : : ;
7456 : :
7457 : : comment_text:
7458 : : Sconst { $$ = $1; }
7459 : : | NULL_P { $$ = NULL; }
7460 : : ;
7461 : :
7462 : :
7463 : : /*****************************************************************************
7464 : : *
7465 : : * SECURITY LABEL [FOR <provider>] ON <object> IS <label>
7466 : : *
7467 : : * As with COMMENT ON, <object> can refer to various types of database
7468 : : * objects (e.g. TABLE, COLUMN, etc.).
7469 : : *
7470 : : *****************************************************************************/
7471 : :
7472 : : SecLabelStmt:
7473 : : SECURITY LABEL opt_provider ON object_type_any_name any_name
7474 : : IS security_label
7475 : : {
7476 : : SecLabelStmt *n = makeNode(SecLabelStmt);
7477 : :
7478 : : n->provider = $3;
7479 : : n->objtype = $5;
7480 : : n->object = (Node *) $6;
7481 : : n->label = $8;
7482 : : $$ = (Node *) n;
7483 : : }
7484 : : | SECURITY LABEL opt_provider ON COLUMN any_name
7485 : : IS security_label
7486 : : {
7487 : : SecLabelStmt *n = makeNode(SecLabelStmt);
7488 : :
7489 : : n->provider = $3;
7490 : : n->objtype = OBJECT_COLUMN;
7491 : : n->object = (Node *) $6;
7492 : : n->label = $8;
7493 : : $$ = (Node *) n;
7494 : : }
7495 : : | SECURITY LABEL opt_provider ON object_type_name name
7496 : : IS security_label
7497 : : {
7498 : : SecLabelStmt *n = makeNode(SecLabelStmt);
7499 : :
7500 : : n->provider = $3;
7501 : : n->objtype = $5;
7502 : : n->object = (Node *) makeString($6);
7503 : : n->label = $8;
7504 : : $$ = (Node *) n;
7505 : : }
7506 : : | SECURITY LABEL opt_provider ON TYPE_P Typename
7507 : : IS security_label
7508 : : {
7509 : : SecLabelStmt *n = makeNode(SecLabelStmt);
7510 : :
7511 : : n->provider = $3;
7512 : : n->objtype = OBJECT_TYPE;
7513 : : n->object = (Node *) $6;
7514 : : n->label = $8;
7515 : : $$ = (Node *) n;
7516 : : }
7517 : : | SECURITY LABEL opt_provider ON DOMAIN_P Typename
7518 : : IS security_label
7519 : : {
7520 : : SecLabelStmt *n = makeNode(SecLabelStmt);
7521 : :
7522 : : n->provider = $3;
7523 : : n->objtype = OBJECT_DOMAIN;
7524 : : n->object = (Node *) $6;
7525 : : n->label = $8;
7526 : : $$ = (Node *) n;
7527 : : }
7528 : : | SECURITY LABEL opt_provider ON AGGREGATE aggregate_with_argtypes
7529 : : IS security_label
7530 : : {
7531 : : SecLabelStmt *n = makeNode(SecLabelStmt);
7532 : :
7533 : : n->provider = $3;
7534 : : n->objtype = OBJECT_AGGREGATE;
7535 : : n->object = (Node *) $6;
7536 : : n->label = $8;
7537 : : $$ = (Node *) n;
7538 : : }
7539 : : | SECURITY LABEL opt_provider ON FUNCTION function_with_argtypes
7540 : : IS security_label
7541 : : {
7542 : : SecLabelStmt *n = makeNode(SecLabelStmt);
7543 : :
7544 : : n->provider = $3;
7545 : : n->objtype = OBJECT_FUNCTION;
7546 : : n->object = (Node *) $6;
7547 : : n->label = $8;
7548 : : $$ = (Node *) n;
7549 : : }
7550 : : | SECURITY LABEL opt_provider ON LARGE_P OBJECT_P NumericOnly
7551 : : IS security_label
7552 : : {
7553 : : SecLabelStmt *n = makeNode(SecLabelStmt);
7554 : :
7555 : : n->provider = $3;
7556 : : n->objtype = OBJECT_LARGEOBJECT;
7557 : : n->object = (Node *) $7;
7558 : : n->label = $9;
7559 : : $$ = (Node *) n;
7560 : : }
7561 : : | SECURITY LABEL opt_provider ON PROCEDURE function_with_argtypes
7562 : : IS security_label
7563 : : {
7564 : : SecLabelStmt *n = makeNode(SecLabelStmt);
7565 : :
7566 : : n->provider = $3;
7567 : : n->objtype = OBJECT_PROCEDURE;
7568 : : n->object = (Node *) $6;
7569 : : n->label = $8;
7570 : : $$ = (Node *) n;
7571 : : }
7572 : : | SECURITY LABEL opt_provider ON ROUTINE function_with_argtypes
7573 : : IS security_label
7574 : : {
7575 : : SecLabelStmt *n = makeNode(SecLabelStmt);
7576 : :
7577 : : n->provider = $3;
7578 : : n->objtype = OBJECT_ROUTINE;
7579 : : n->object = (Node *) $6;
7580 : : n->label = $8;
7581 : : $$ = (Node *) n;
7582 : : }
7583 : : ;
7584 : :
7585 : : opt_provider: FOR NonReservedWord_or_Sconst { $$ = $2; }
7586 : : | /* EMPTY */ { $$ = NULL; }
7587 : : ;
7588 : :
7589 : : security_label: Sconst { $$ = $1; }
7590 : : | NULL_P { $$ = NULL; }
7591 : : ;
7592 : :
7593 : : /*****************************************************************************
7594 : : *
7595 : : * QUERY:
7596 : : * fetch/move
7597 : : *
7598 : : *****************************************************************************/
7599 : :
7600 : : FetchStmt: FETCH fetch_args
7601 : : {
7602 : : FetchStmt *n = (FetchStmt *) $2;
7603 : :
7604 : : n->ismove = false;
7605 : : $$ = (Node *) n;
7606 : : }
7607 : : | MOVE fetch_args
7608 : : {
7609 : : FetchStmt *n = (FetchStmt *) $2;
7610 : :
7611 : : n->ismove = true;
7612 : : $$ = (Node *) n;
7613 : : }
7614 : : ;
7615 : :
7616 : : fetch_args: cursor_name
7617 : : {
7618 : : FetchStmt *n = makeNode(FetchStmt);
7619 : :
7620 : : n->portalname = $1;
7621 : : n->direction = FETCH_FORWARD;
7622 : : n->howMany = 1;
7623 : : n->location = -1;
7624 : : n->direction_keyword = FETCH_KEYWORD_NONE;
7625 : : $$ = (Node *) n;
7626 : : }
7627 : : | from_in cursor_name
7628 : : {
7629 : : FetchStmt *n = makeNode(FetchStmt);
7630 : :
7631 : : n->portalname = $2;
7632 : : n->direction = FETCH_FORWARD;
7633 : : n->howMany = 1;
7634 : : n->location = -1;
7635 : : n->direction_keyword = FETCH_KEYWORD_NONE;
7636 : : $$ = (Node *) n;
7637 : : }
7638 : : | SignedIconst opt_from_in cursor_name
7639 : : {
7640 : : FetchStmt *n = makeNode(FetchStmt);
7641 : :
7642 : : n->portalname = $3;
7643 : : n->direction = FETCH_FORWARD;
7644 : : n->howMany = $1;
7645 : : n->location = @1;
7646 : : n->direction_keyword = FETCH_KEYWORD_NONE;
7647 : : $$ = (Node *) n;
7648 : : }
7649 : : | NEXT opt_from_in cursor_name
7650 : : {
7651 : : FetchStmt *n = makeNode(FetchStmt);
7652 : :
7653 : : n->portalname = $3;
7654 : : n->direction = FETCH_FORWARD;
7655 : : n->howMany = 1;
7656 : : n->location = -1;
7657 : : n->direction_keyword = FETCH_KEYWORD_NEXT;
7658 : : $$ = (Node *) n;
7659 : : }
7660 : : | PRIOR opt_from_in cursor_name
7661 : : {
7662 : : FetchStmt *n = makeNode(FetchStmt);
7663 : :
7664 : : n->portalname = $3;
7665 : : n->direction = FETCH_BACKWARD;
7666 : : n->howMany = 1;
7667 : : n->location = -1;
7668 : : n->direction_keyword = FETCH_KEYWORD_PRIOR;
7669 : : $$ = (Node *) n;
7670 : : }
7671 : : | FIRST_P opt_from_in cursor_name
7672 : : {
7673 : : FetchStmt *n = makeNode(FetchStmt);
7674 : :
7675 : : n->portalname = $3;
7676 : : n->direction = FETCH_ABSOLUTE;
7677 : : n->howMany = 1;
7678 : : n->location = -1;
7679 : : n->direction_keyword = FETCH_KEYWORD_FIRST;
7680 : : $$ = (Node *) n;
7681 : : }
7682 : : | LAST_P opt_from_in cursor_name
7683 : : {
7684 : : FetchStmt *n = makeNode(FetchStmt);
7685 : :
7686 : : n->portalname = $3;
7687 : : n->direction = FETCH_ABSOLUTE;
7688 : : n->howMany = -1;
7689 : : n->location = -1;
7690 : : n->direction_keyword = FETCH_KEYWORD_LAST;
7691 : : $$ = (Node *) n;
7692 : : }
7693 : : | ABSOLUTE_P SignedIconst opt_from_in cursor_name
7694 : : {
7695 : : FetchStmt *n = makeNode(FetchStmt);
7696 : :
7697 : : n->portalname = $4;
7698 : : n->direction = FETCH_ABSOLUTE;
7699 : : n->howMany = $2;
7700 : : n->location = @2;
7701 : : n->direction_keyword = FETCH_KEYWORD_ABSOLUTE;
7702 : : $$ = (Node *) n;
7703 : : }
7704 : : | RELATIVE_P SignedIconst opt_from_in cursor_name
7705 : : {
7706 : : FetchStmt *n = makeNode(FetchStmt);
7707 : :
7708 : : n->portalname = $4;
7709 : : n->direction = FETCH_RELATIVE;
7710 : : n->howMany = $2;
7711 : : n->location = @2;
7712 : : n->direction_keyword = FETCH_KEYWORD_RELATIVE;
7713 : : $$ = (Node *) n;
7714 : : }
7715 : : | ALL opt_from_in cursor_name
7716 : : {
7717 : : FetchStmt *n = makeNode(FetchStmt);
7718 : :
7719 : : n->portalname = $3;
7720 : : n->direction = FETCH_FORWARD;
7721 : : n->howMany = FETCH_ALL;
7722 : : n->location = -1;
7723 : : n->direction_keyword = FETCH_KEYWORD_ALL;
7724 : : $$ = (Node *) n;
7725 : : }
7726 : : | FORWARD opt_from_in cursor_name
7727 : : {
7728 : : FetchStmt *n = makeNode(FetchStmt);
7729 : :
7730 : : n->portalname = $3;
7731 : : n->direction = FETCH_FORWARD;
7732 : : n->howMany = 1;
7733 : : n->location = -1;
7734 : : n->direction_keyword = FETCH_KEYWORD_FORWARD;
7735 : : $$ = (Node *) n;
7736 : : }
7737 : : | FORWARD SignedIconst opt_from_in cursor_name
7738 : : {
7739 : : FetchStmt *n = makeNode(FetchStmt);
7740 : :
7741 : : n->portalname = $4;
7742 : : n->direction = FETCH_FORWARD;
7743 : : n->howMany = $2;
7744 : : n->location = @2;
7745 : : n->direction_keyword = FETCH_KEYWORD_FORWARD;
7746 : : $$ = (Node *) n;
7747 : : }
7748 : : | FORWARD ALL opt_from_in cursor_name
7749 : : {
7750 : : FetchStmt *n = makeNode(FetchStmt);
7751 : :
7752 : : n->portalname = $4;
7753 : : n->direction = FETCH_FORWARD;
7754 : : n->howMany = FETCH_ALL;
7755 : : n->location = -1;
7756 : : n->direction_keyword = FETCH_KEYWORD_FORWARD_ALL;
7757 : : $$ = (Node *) n;
7758 : : }
7759 : : | BACKWARD opt_from_in cursor_name
7760 : : {
7761 : : FetchStmt *n = makeNode(FetchStmt);
7762 : :
7763 : : n->portalname = $3;
7764 : : n->direction = FETCH_BACKWARD;
7765 : : n->howMany = 1;
7766 : : n->location = -1;
7767 : : n->direction_keyword = FETCH_KEYWORD_BACKWARD;
7768 : : $$ = (Node *) n;
7769 : : }
7770 : : | BACKWARD SignedIconst opt_from_in cursor_name
7771 : : {
7772 : : FetchStmt *n = makeNode(FetchStmt);
7773 : :
7774 : : n->portalname = $4;
7775 : : n->direction = FETCH_BACKWARD;
7776 : : n->howMany = $2;
7777 : : n->location = @2;
7778 : : n->direction_keyword = FETCH_KEYWORD_BACKWARD;
7779 : : $$ = (Node *) n;
7780 : : }
7781 : : | BACKWARD ALL opt_from_in cursor_name
7782 : : {
7783 : : FetchStmt *n = makeNode(FetchStmt);
7784 : :
7785 : : n->portalname = $4;
7786 : : n->direction = FETCH_BACKWARD;
7787 : : n->howMany = FETCH_ALL;
7788 : : n->location = -1;
7789 : : n->direction_keyword = FETCH_KEYWORD_BACKWARD_ALL;
7790 : : $$ = (Node *) n;
7791 : : }
7792 : : ;
7793 : :
7794 : : from_in: FROM
7795 : : | IN_P
7796 : : ;
7797 : :
7798 : : opt_from_in: from_in
7799 : : | /* EMPTY */
7800 : : ;
7801 : :
7802 : :
7803 : : /*****************************************************************************
7804 : : *
7805 : : * GRANT and REVOKE statements
7806 : : *
7807 : : *****************************************************************************/
7808 : :
7809 : : GrantStmt: GRANT privileges ON privilege_target TO grantee_list
7810 : : opt_grant_grant_option opt_granted_by
7811 : : {
7812 : : GrantStmt *n = makeNode(GrantStmt);
7813 : :
7814 : : n->is_grant = true;
7815 : : n->privileges = $2;
7816 : : n->targtype = ($4)->targtype;
7817 : : n->objtype = ($4)->objtype;
7818 : : n->objects = ($4)->objs;
7819 : : n->grantees = $6;
7820 : : n->grant_option = $7;
7821 : : n->grantor = $8;
7822 : : $$ = (Node *) n;
7823 : : }
7824 : : ;
7825 : :
7826 : : RevokeStmt:
7827 : : REVOKE privileges ON privilege_target
7828 : : FROM grantee_list opt_granted_by opt_drop_behavior
7829 : : {
7830 : : GrantStmt *n = makeNode(GrantStmt);
7831 : :
7832 : : n->is_grant = false;
7833 : : n->grant_option = false;
7834 : : n->privileges = $2;
7835 : : n->targtype = ($4)->targtype;
7836 : : n->objtype = ($4)->objtype;
7837 : : n->objects = ($4)->objs;
7838 : : n->grantees = $6;
7839 : : n->grantor = $7;
7840 : : n->behavior = $8;
7841 : : $$ = (Node *) n;
7842 : : }
7843 : : | REVOKE GRANT OPTION FOR privileges ON privilege_target
7844 : : FROM grantee_list opt_granted_by opt_drop_behavior
7845 : : {
7846 : : GrantStmt *n = makeNode(GrantStmt);
7847 : :
7848 : : n->is_grant = false;
7849 : : n->grant_option = true;
7850 : : n->privileges = $5;
7851 : : n->targtype = ($7)->targtype;
7852 : : n->objtype = ($7)->objtype;
7853 : : n->objects = ($7)->objs;
7854 : : n->grantees = $9;
7855 : : n->grantor = $10;
7856 : : n->behavior = $11;
7857 : : $$ = (Node *) n;
7858 : : }
7859 : : ;
7860 : :
7861 : :
7862 : : /*
7863 : : * Privilege names are represented as strings; the validity of the privilege
7864 : : * names gets checked at execution. This is a bit annoying but we have little
7865 : : * choice because of the syntactic conflict with lists of role names in
7866 : : * GRANT/REVOKE. What's more, we have to call out in the "privilege"
7867 : : * production any reserved keywords that need to be usable as privilege names.
7868 : : */
7869 : :
7870 : : /* either ALL [PRIVILEGES] or a list of individual privileges */
7871 : : privileges: privilege_list
7872 : : { $$ = $1; }
7873 : : | ALL
7874 : : { $$ = NIL; }
7875 : : | ALL PRIVILEGES
7876 : : { $$ = NIL; }
7877 : : | ALL '(' columnList ')'
7878 : : {
7879 : : AccessPriv *n = makeNode(AccessPriv);
7880 : :
7881 : : n->priv_name = NULL;
7882 : : n->cols = $3;
7883 : : $$ = list_make1(n);
7884 : : }
7885 : : | ALL PRIVILEGES '(' columnList ')'
7886 : : {
7887 : : AccessPriv *n = makeNode(AccessPriv);
7888 : :
7889 : : n->priv_name = NULL;
7890 : : n->cols = $4;
7891 : : $$ = list_make1(n);
7892 : : }
7893 : : ;
7894 : :
7895 : : privilege_list: privilege { $$ = list_make1($1); }
7896 : : | privilege_list ',' privilege { $$ = lappend($1, $3); }
7897 : : ;
7898 : :
7899 : : privilege: SELECT opt_column_list
7900 : : {
7901 : : AccessPriv *n = makeNode(AccessPriv);
7902 : :
7903 : : n->priv_name = pstrdup($1);
7904 : : n->cols = $2;
7905 : : $$ = n;
7906 : : }
7907 : : | REFERENCES opt_column_list
7908 : : {
7909 : : AccessPriv *n = makeNode(AccessPriv);
7910 : :
7911 : : n->priv_name = pstrdup($1);
7912 : : n->cols = $2;
7913 : : $$ = n;
7914 : : }
7915 : : | CREATE opt_column_list
7916 : : {
7917 : : AccessPriv *n = makeNode(AccessPriv);
7918 : :
7919 : : n->priv_name = pstrdup($1);
7920 : : n->cols = $2;
7921 : : $$ = n;
7922 : : }
7923 : : | ALTER SYSTEM_P
7924 : : {
7925 : : AccessPriv *n = makeNode(AccessPriv);
7926 : : n->priv_name = pstrdup("alter system");
7927 : : n->cols = NIL;
7928 : : $$ = n;
7929 : : }
7930 : : | ColId opt_column_list
7931 : : {
7932 : : AccessPriv *n = makeNode(AccessPriv);
7933 : :
7934 : : n->priv_name = $1;
7935 : : n->cols = $2;
7936 : : $$ = n;
7937 : : }
7938 : : ;
7939 : :
7940 : : parameter_name_list:
7941 : : parameter_name
7942 : : {
7943 : : $$ = list_make1(makeString($1));
7944 : : }
7945 : : | parameter_name_list ',' parameter_name
7946 : : {
7947 : : $$ = lappend($1, makeString($3));
7948 : : }
7949 : : ;
7950 : :
7951 : : parameter_name:
7952 : : ColId
7953 : : {
7954 : : $$ = $1;
7955 : : }
7956 : : | parameter_name '.' ColId
7957 : : {
7958 : : $$ = psprintf("%s.%s", $1, $3);
7959 : : }
7960 : : ;
7961 : :
7962 : :
7963 : : /* Don't bother trying to fold the first two rules into one using
7964 : : * opt_table. You're going to get conflicts.
7965 : : */
7966 : : privilege_target:
7967 : : qualified_name_list
7968 : : {
7969 : : PrivTarget *n = palloc_object(PrivTarget);
7970 : :
7971 : : n->targtype = ACL_TARGET_OBJECT;
7972 : : n->objtype = OBJECT_TABLE;
7973 : : n->objs = $1;
7974 : : $$ = n;
7975 : : }
7976 : : | TABLE qualified_name_list
7977 : : {
7978 : : PrivTarget *n = palloc_object(PrivTarget);
7979 : :
7980 : : n->targtype = ACL_TARGET_OBJECT;
7981 : : n->objtype = OBJECT_TABLE;
7982 : : n->objs = $2;
7983 : : $$ = n;
7984 : : }
7985 : : | SEQUENCE qualified_name_list
7986 : : {
7987 : : PrivTarget *n = palloc_object(PrivTarget);
7988 : :
7989 : : n->targtype = ACL_TARGET_OBJECT;
7990 : : n->objtype = OBJECT_SEQUENCE;
7991 : : n->objs = $2;
7992 : : $$ = n;
7993 : : }
7994 : : | FOREIGN DATA_P WRAPPER name_list
7995 : : {
7996 : : PrivTarget *n = palloc_object(PrivTarget);
7997 : :
7998 : : n->targtype = ACL_TARGET_OBJECT;
7999 : : n->objtype = OBJECT_FDW;
8000 : : n->objs = $4;
8001 : : $$ = n;
8002 : : }
8003 : : | FOREIGN SERVER name_list
8004 : : {
8005 : : PrivTarget *n = palloc_object(PrivTarget);
8006 : :
8007 : : n->targtype = ACL_TARGET_OBJECT;
8008 : : n->objtype = OBJECT_FOREIGN_SERVER;
8009 : : n->objs = $3;
8010 : : $$ = n;
8011 : : }
8012 : : | FUNCTION function_with_argtypes_list
8013 : : {
8014 : : PrivTarget *n = palloc_object(PrivTarget);
8015 : :
8016 : : n->targtype = ACL_TARGET_OBJECT;
8017 : : n->objtype = OBJECT_FUNCTION;
8018 : : n->objs = $2;
8019 : : $$ = n;
8020 : : }
8021 : : | PROCEDURE function_with_argtypes_list
8022 : : {
8023 : : PrivTarget *n = palloc_object(PrivTarget);
8024 : :
8025 : : n->targtype = ACL_TARGET_OBJECT;
8026 : : n->objtype = OBJECT_PROCEDURE;
8027 : : n->objs = $2;
8028 : : $$ = n;
8029 : : }
8030 : : | ROUTINE function_with_argtypes_list
8031 : : {
8032 : : PrivTarget *n = palloc_object(PrivTarget);
8033 : :
8034 : : n->targtype = ACL_TARGET_OBJECT;
8035 : : n->objtype = OBJECT_ROUTINE;
8036 : : n->objs = $2;
8037 : : $$ = n;
8038 : : }
8039 : : | DATABASE name_list
8040 : : {
8041 : : PrivTarget *n = palloc_object(PrivTarget);
8042 : :
8043 : : n->targtype = ACL_TARGET_OBJECT;
8044 : : n->objtype = OBJECT_DATABASE;
8045 : : n->objs = $2;
8046 : : $$ = n;
8047 : : }
8048 : : | DOMAIN_P any_name_list
8049 : : {
8050 : : PrivTarget *n = palloc_object(PrivTarget);
8051 : :
8052 : : n->targtype = ACL_TARGET_OBJECT;
8053 : : n->objtype = OBJECT_DOMAIN;
8054 : : n->objs = $2;
8055 : : $$ = n;
8056 : : }
8057 : : | LANGUAGE name_list
8058 : : {
8059 : : PrivTarget *n = palloc_object(PrivTarget);
8060 : :
8061 : : n->targtype = ACL_TARGET_OBJECT;
8062 : : n->objtype = OBJECT_LANGUAGE;
8063 : : n->objs = $2;
8064 : : $$ = n;
8065 : : }
8066 : : | LARGE_P OBJECT_P NumericOnly_list
8067 : : {
8068 : : PrivTarget *n = palloc_object(PrivTarget);
8069 : :
8070 : : n->targtype = ACL_TARGET_OBJECT;
8071 : : n->objtype = OBJECT_LARGEOBJECT;
8072 : : n->objs = $3;
8073 : : $$ = n;
8074 : : }
8075 : : | PARAMETER parameter_name_list
8076 : : {
8077 : : PrivTarget *n = palloc_object(PrivTarget);
8078 : : n->targtype = ACL_TARGET_OBJECT;
8079 : : n->objtype = OBJECT_PARAMETER_ACL;
8080 : : n->objs = $2;
8081 : : $$ = n;
8082 : : }
8083 : : | SCHEMA name_list
8084 : : {
8085 : : PrivTarget *n = palloc_object(PrivTarget);
8086 : :
8087 : : n->targtype = ACL_TARGET_OBJECT;
8088 : : n->objtype = OBJECT_SCHEMA;
8089 : : n->objs = $2;
8090 : : $$ = n;
8091 : : }
8092 : : | TABLESPACE name_list
8093 : : {
8094 : : PrivTarget *n = palloc_object(PrivTarget);
8095 : :
8096 : : n->targtype = ACL_TARGET_OBJECT;
8097 : : n->objtype = OBJECT_TABLESPACE;
8098 : : n->objs = $2;
8099 : : $$ = n;
8100 : : }
8101 : : | TYPE_P any_name_list
8102 : : {
8103 : : PrivTarget *n = palloc_object(PrivTarget);
8104 : :
8105 : : n->targtype = ACL_TARGET_OBJECT;
8106 : : n->objtype = OBJECT_TYPE;
8107 : : n->objs = $2;
8108 : : $$ = n;
8109 : : }
8110 : : | ALL TABLES IN_P SCHEMA name_list
8111 : : {
8112 : : PrivTarget *n = palloc_object(PrivTarget);
8113 : :
8114 : : n->targtype = ACL_TARGET_ALL_IN_SCHEMA;
8115 : : n->objtype = OBJECT_TABLE;
8116 : : n->objs = $5;
8117 : : $$ = n;
8118 : : }
8119 : : | ALL SEQUENCES IN_P SCHEMA name_list
8120 : : {
8121 : : PrivTarget *n = palloc_object(PrivTarget);
8122 : :
8123 : : n->targtype = ACL_TARGET_ALL_IN_SCHEMA;
8124 : : n->objtype = OBJECT_SEQUENCE;
8125 : : n->objs = $5;
8126 : : $$ = n;
8127 : : }
8128 : : | ALL FUNCTIONS IN_P SCHEMA name_list
8129 : : {
8130 : : PrivTarget *n = palloc_object(PrivTarget);
8131 : :
8132 : : n->targtype = ACL_TARGET_ALL_IN_SCHEMA;
8133 : : n->objtype = OBJECT_FUNCTION;
8134 : : n->objs = $5;
8135 : : $$ = n;
8136 : : }
8137 : : | ALL PROCEDURES IN_P SCHEMA name_list
8138 : : {
8139 : : PrivTarget *n = palloc_object(PrivTarget);
8140 : :
8141 : : n->targtype = ACL_TARGET_ALL_IN_SCHEMA;
8142 : : n->objtype = OBJECT_PROCEDURE;
8143 : : n->objs = $5;
8144 : : $$ = n;
8145 : : }
8146 : : | ALL ROUTINES IN_P SCHEMA name_list
8147 : : {
8148 : : PrivTarget *n = palloc_object(PrivTarget);
8149 : :
8150 : : n->targtype = ACL_TARGET_ALL_IN_SCHEMA;
8151 : : n->objtype = OBJECT_ROUTINE;
8152 : : n->objs = $5;
8153 : : $$ = n;
8154 : : }
8155 : : ;
8156 : :
8157 : :
8158 : : grantee_list:
8159 : : grantee { $$ = list_make1($1); }
8160 : : | grantee_list ',' grantee { $$ = lappend($1, $3); }
8161 : : ;
8162 : :
8163 : : grantee:
8164 : : RoleSpec { $$ = $1; }
8165 : : | GROUP_P RoleSpec { $$ = $2; }
8166 : : ;
8167 : :
8168 : :
8169 : : opt_grant_grant_option:
8170 : : WITH GRANT OPTION { $$ = true; }
8171 : : | /*EMPTY*/ { $$ = false; }
8172 : : ;
8173 : :
8174 : : /*****************************************************************************
8175 : : *
8176 : : * GRANT and REVOKE ROLE statements
8177 : : *
8178 : : *****************************************************************************/
8179 : :
8180 : : GrantRoleStmt:
8181 : : GRANT privilege_list TO role_list opt_granted_by
8182 : : {
8183 : : GrantRoleStmt *n = makeNode(GrantRoleStmt);
8184 : :
8185 : : n->is_grant = true;
8186 : : n->granted_roles = $2;
8187 : : n->grantee_roles = $4;
8188 : : n->opt = NIL;
8189 : : n->grantor = $5;
8190 : : $$ = (Node *) n;
8191 : : }
8192 : : | GRANT privilege_list TO role_list WITH grant_role_opt_list opt_granted_by
8193 : : {
8194 : : GrantRoleStmt *n = makeNode(GrantRoleStmt);
8195 : :
8196 : : n->is_grant = true;
8197 : : n->granted_roles = $2;
8198 : : n->grantee_roles = $4;
8199 : : n->opt = $6;
8200 : : n->grantor = $7;
8201 : : $$ = (Node *) n;
8202 : : }
8203 : : ;
8204 : :
8205 : : RevokeRoleStmt:
8206 : : REVOKE privilege_list FROM role_list opt_granted_by opt_drop_behavior
8207 : : {
8208 : : GrantRoleStmt *n = makeNode(GrantRoleStmt);
8209 : :
8210 : : n->is_grant = false;
8211 : : n->opt = NIL;
8212 : : n->granted_roles = $2;
8213 : : n->grantee_roles = $4;
8214 : : n->grantor = $5;
8215 : : n->behavior = $6;
8216 : : $$ = (Node *) n;
8217 : : }
8218 : : | REVOKE ColId OPTION FOR privilege_list FROM role_list opt_granted_by opt_drop_behavior
8219 : : {
8220 : : GrantRoleStmt *n = makeNode(GrantRoleStmt);
8221 : : DefElem *opt;
8222 : :
8223 : : opt = makeDefElem(pstrdup($2),
8224 : : (Node *) makeBoolean(false), @2);
8225 : : n->is_grant = false;
8226 : : n->opt = list_make1(opt);
8227 : : n->granted_roles = $5;
8228 : : n->grantee_roles = $7;
8229 : : n->grantor = $8;
8230 : : n->behavior = $9;
8231 : : $$ = (Node *) n;
8232 : : }
8233 : : ;
8234 : :
8235 : : grant_role_opt_list:
8236 : : grant_role_opt_list ',' grant_role_opt { $$ = lappend($1, $3); }
8237 : : | grant_role_opt { $$ = list_make1($1); }
8238 : : ;
8239 : :
8240 : : grant_role_opt:
8241 : : ColLabel grant_role_opt_value
8242 : : {
8243 : : $$ = makeDefElem(pstrdup($1), $2, @1);
8244 : : }
8245 : : ;
8246 : :
8247 : : grant_role_opt_value:
8248 : : OPTION { $$ = (Node *) makeBoolean(true); }
8249 : : | TRUE_P { $$ = (Node *) makeBoolean(true); }
8250 : : | FALSE_P { $$ = (Node *) makeBoolean(false); }
8251 : : ;
8252 : :
8253 : : opt_granted_by: GRANTED BY RoleSpec { $$ = $3; }
8254 : : | /*EMPTY*/ { $$ = NULL; }
8255 : : ;
8256 : :
8257 : : /*****************************************************************************
8258 : : *
8259 : : * ALTER DEFAULT PRIVILEGES statement
8260 : : *
8261 : : *****************************************************************************/
8262 : :
8263 : : AlterDefaultPrivilegesStmt:
8264 : : ALTER DEFAULT PRIVILEGES DefACLOptionList DefACLAction
8265 : : {
8266 : : AlterDefaultPrivilegesStmt *n = makeNode(AlterDefaultPrivilegesStmt);
8267 : :
8268 : : n->options = $4;
8269 : : n->action = (GrantStmt *) $5;
8270 : : $$ = (Node *) n;
8271 : : }
8272 : : ;
8273 : :
8274 : : DefACLOptionList:
8275 : : DefACLOptionList DefACLOption { $$ = lappend($1, $2); }
8276 : : | /* EMPTY */ { $$ = NIL; }
8277 : : ;
8278 : :
8279 : : DefACLOption:
8280 : : IN_P SCHEMA name_list
8281 : : {
8282 : : $$ = makeDefElem("schemas", (Node *) $3, @1);
8283 : : }
8284 : : | FOR ROLE role_list
8285 : : {
8286 : : $$ = makeDefElem("roles", (Node *) $3, @1);
8287 : : }
8288 : : | FOR USER role_list
8289 : : {
8290 : : $$ = makeDefElem("roles", (Node *) $3, @1);
8291 : : }
8292 : : ;
8293 : :
8294 : : /*
8295 : : * This should match GRANT/REVOKE, except that individual target objects
8296 : : * are not mentioned and we only allow a subset of object types.
8297 : : */
8298 : : DefACLAction:
8299 : : GRANT privileges ON defacl_privilege_target TO grantee_list
8300 : : opt_grant_grant_option
8301 : : {
8302 : : GrantStmt *n = makeNode(GrantStmt);
8303 : :
8304 : : n->is_grant = true;
8305 : : n->privileges = $2;
8306 : : n->targtype = ACL_TARGET_DEFAULTS;
8307 : : n->objtype = $4;
8308 : : n->objects = NIL;
8309 : : n->grantees = $6;
8310 : : n->grant_option = $7;
8311 : : $$ = (Node *) n;
8312 : : }
8313 : : | REVOKE privileges ON defacl_privilege_target
8314 : : FROM grantee_list opt_drop_behavior
8315 : : {
8316 : : GrantStmt *n = makeNode(GrantStmt);
8317 : :
8318 : : n->is_grant = false;
8319 : : n->grant_option = false;
8320 : : n->privileges = $2;
8321 : : n->targtype = ACL_TARGET_DEFAULTS;
8322 : : n->objtype = $4;
8323 : : n->objects = NIL;
8324 : : n->grantees = $6;
8325 : : n->behavior = $7;
8326 : : $$ = (Node *) n;
8327 : : }
8328 : : | REVOKE GRANT OPTION FOR privileges ON defacl_privilege_target
8329 : : FROM grantee_list opt_drop_behavior
8330 : : {
8331 : : GrantStmt *n = makeNode(GrantStmt);
8332 : :
8333 : : n->is_grant = false;
8334 : : n->grant_option = true;
8335 : : n->privileges = $5;
8336 : : n->targtype = ACL_TARGET_DEFAULTS;
8337 : : n->objtype = $7;
8338 : : n->objects = NIL;
8339 : : n->grantees = $9;
8340 : : n->behavior = $10;
8341 : : $$ = (Node *) n;
8342 : : }
8343 : : ;
8344 : :
8345 : : defacl_privilege_target:
8346 : : TABLES { $$ = OBJECT_TABLE; }
8347 : : | FUNCTIONS { $$ = OBJECT_FUNCTION; }
8348 : : | ROUTINES { $$ = OBJECT_FUNCTION; }
8349 : : | SEQUENCES { $$ = OBJECT_SEQUENCE; }
8350 : : | TYPES_P { $$ = OBJECT_TYPE; }
8351 : : | SCHEMAS { $$ = OBJECT_SCHEMA; }
8352 : : | LARGE_P OBJECTS_P { $$ = OBJECT_LARGEOBJECT; }
8353 : : ;
8354 : :
8355 : :
8356 : : /*****************************************************************************
8357 : : *
8358 : : * QUERY: CREATE INDEX
8359 : : *
8360 : : * Note: we cannot put TABLESPACE clause after WHERE clause unless we are
8361 : : * willing to make TABLESPACE a fully reserved word.
8362 : : *****************************************************************************/
8363 : :
8364 : : IndexStmt: CREATE opt_unique INDEX opt_concurrently opt_single_name
8365 : : ON relation_expr access_method_clause '(' index_params ')'
8366 : : opt_include opt_unique_null_treatment opt_reloptions OptTableSpace where_clause
8367 : : {
8368 : : IndexStmt *n = makeNode(IndexStmt);
8369 : :
8370 : : n->unique = $2;
8371 : : n->concurrent = $4;
8372 : : n->idxname = $5;
8373 : : n->relation = $7;
8374 : : n->accessMethod = $8;
8375 : : n->indexParams = $10;
8376 : : n->indexIncludingParams = $12;
8377 : : n->nulls_not_distinct = !$13;
8378 : : n->options = $14;
8379 : : n->tableSpace = $15;
8380 : : n->whereClause = $16;
8381 : : n->excludeOpNames = NIL;
8382 : : n->idxcomment = NULL;
8383 : : n->indexOid = InvalidOid;
8384 : : n->oldNumber = InvalidRelFileNumber;
8385 : : n->oldCreateSubid = InvalidSubTransactionId;
8386 : : n->oldFirstRelfilelocatorSubid = InvalidSubTransactionId;
8387 : : n->primary = false;
8388 : : n->isconstraint = false;
8389 : : n->deferrable = false;
8390 : : n->initdeferred = false;
8391 : : n->transformed = false;
8392 : : n->if_not_exists = false;
8393 : : n->reset_default_tblspc = false;
8394 : : $$ = (Node *) n;
8395 : : }
8396 : : | CREATE opt_unique INDEX opt_concurrently IF_P NOT EXISTS name
8397 : : ON relation_expr access_method_clause '(' index_params ')'
8398 : : opt_include opt_unique_null_treatment opt_reloptions OptTableSpace where_clause
8399 : : {
8400 : : IndexStmt *n = makeNode(IndexStmt);
8401 : :
8402 : : n->unique = $2;
8403 : : n->concurrent = $4;
8404 : : n->idxname = $8;
8405 : : n->relation = $10;
8406 : : n->accessMethod = $11;
8407 : : n->indexParams = $13;
8408 : : n->indexIncludingParams = $15;
8409 : : n->nulls_not_distinct = !$16;
8410 : : n->options = $17;
8411 : : n->tableSpace = $18;
8412 : : n->whereClause = $19;
8413 : : n->excludeOpNames = NIL;
8414 : : n->idxcomment = NULL;
8415 : : n->indexOid = InvalidOid;
8416 : : n->oldNumber = InvalidRelFileNumber;
8417 : : n->oldCreateSubid = InvalidSubTransactionId;
8418 : : n->oldFirstRelfilelocatorSubid = InvalidSubTransactionId;
8419 : : n->primary = false;
8420 : : n->isconstraint = false;
8421 : : n->deferrable = false;
8422 : : n->initdeferred = false;
8423 : : n->transformed = false;
8424 : : n->if_not_exists = true;
8425 : : n->reset_default_tblspc = false;
8426 : : $$ = (Node *) n;
8427 : : }
8428 : : ;
8429 : :
8430 : : opt_unique:
8431 : : UNIQUE { $$ = true; }
8432 : : | /*EMPTY*/ { $$ = false; }
8433 : : ;
8434 : :
8435 : : access_method_clause:
8436 : : USING name { $$ = $2; }
8437 : : | /*EMPTY*/ { $$ = DEFAULT_INDEX_TYPE; }
8438 : : ;
8439 : :
8440 : : index_params: index_elem { $$ = list_make1($1); }
8441 : : | index_params ',' index_elem { $$ = lappend($1, $3); }
8442 : : ;
8443 : :
8444 : :
8445 : : index_elem_options:
8446 : : opt_collate opt_qualified_name opt_asc_desc opt_nulls_order
8447 : : {
8448 : : $$ = makeNode(IndexElem);
8449 : : $$->name = NULL;
8450 : : $$->expr = NULL;
8451 : : $$->indexcolname = NULL;
8452 : : $$->collation = $1;
8453 : : $$->opclass = $2;
8454 : : $$->opclassopts = NIL;
8455 : : $$->ordering = $3;
8456 : : $$->nulls_ordering = $4;
8457 : : /* location will be filled in index_elem production */
8458 : : }
8459 : : | opt_collate any_name reloptions opt_asc_desc opt_nulls_order
8460 : : {
8461 : : $$ = makeNode(IndexElem);
8462 : : $$->name = NULL;
8463 : : $$->expr = NULL;
8464 : : $$->indexcolname = NULL;
8465 : : $$->collation = $1;
8466 : : $$->opclass = $2;
8467 : : $$->opclassopts = $3;
8468 : : $$->ordering = $4;
8469 : : $$->nulls_ordering = $5;
8470 : : /* location will be filled in index_elem production */
8471 : : }
8472 : : ;
8473 : :
8474 : : /*
8475 : : * Index attributes can be either simple column references, or arbitrary
8476 : : * expressions in parens. For backwards-compatibility reasons, we allow
8477 : : * an expression that's just a function call to be written without parens.
8478 : : */
8479 : : index_elem: ColId index_elem_options
8480 : : {
8481 : : $$ = $2;
8482 : : $$->name = $1;
8483 : : $$->location = @1;
8484 : : }
8485 : : | func_expr_windowless index_elem_options
8486 : : {
8487 : : $$ = $2;
8488 : : $$->expr = $1;
8489 : : $$->location = @1;
8490 : : }
8491 : : | '(' a_expr ')' index_elem_options
8492 : : {
8493 : : $$ = $4;
8494 : : $$->expr = $2;
8495 : : $$->location = @1;
8496 : : }
8497 : : ;
8498 : :
8499 : : opt_include: INCLUDE '(' index_including_params ')' { $$ = $3; }
8500 : : | /* EMPTY */ { $$ = NIL; }
8501 : : ;
8502 : :
8503 : : index_including_params: index_elem { $$ = list_make1($1); }
8504 : : | index_including_params ',' index_elem { $$ = lappend($1, $3); }
8505 : : ;
8506 : :
8507 : : opt_collate: COLLATE any_name { $$ = $2; }
8508 : : | /*EMPTY*/ { $$ = NIL; }
8509 : : ;
8510 : :
8511 : :
8512 : : opt_asc_desc: ASC { $$ = SORTBY_ASC; }
8513 : : | DESC { $$ = SORTBY_DESC; }
8514 : : | /*EMPTY*/ { $$ = SORTBY_DEFAULT; }
8515 : : ;
8516 : :
8517 : : opt_nulls_order: NULLS_LA FIRST_P { $$ = SORTBY_NULLS_FIRST; }
8518 : : | NULLS_LA LAST_P { $$ = SORTBY_NULLS_LAST; }
8519 : : | /*EMPTY*/ { $$ = SORTBY_NULLS_DEFAULT; }
8520 : : ;
8521 : :
8522 : :
8523 : : /*****************************************************************************
8524 : : *
8525 : : * QUERY:
8526 : : * create [or replace] function <fname>
8527 : : * [(<type-1> { , <type-n>})]
8528 : : * returns <type-r>
8529 : : * as <filename or code in language as appropriate>
8530 : : * language <lang> [with parameters]
8531 : : *
8532 : : *****************************************************************************/
8533 : :
8534 : : CreateFunctionStmt:
8535 : : CREATE opt_or_replace FUNCTION func_name func_args_with_defaults
8536 : : RETURNS func_return opt_createfunc_opt_list opt_routine_body
8537 : : {
8538 : : CreateFunctionStmt *n = makeNode(CreateFunctionStmt);
8539 : :
8540 : : n->is_procedure = false;
8541 : : n->replace = $2;
8542 : : n->funcname = $4;
8543 : : n->parameters = $5;
8544 : : n->returnType = $7;
8545 : : n->options = $8;
8546 : : n->sql_body = $9;
8547 : : $$ = (Node *) n;
8548 : : }
8549 : : | CREATE opt_or_replace FUNCTION func_name func_args_with_defaults
8550 : : RETURNS TABLE '(' table_func_column_list ')' opt_createfunc_opt_list opt_routine_body
8551 : : {
8552 : : CreateFunctionStmt *n = makeNode(CreateFunctionStmt);
8553 : :
8554 : : n->is_procedure = false;
8555 : : n->replace = $2;
8556 : : n->funcname = $4;
8557 : : n->parameters = mergeTableFuncParameters($5, $9, yyscanner);
8558 : : n->returnType = TableFuncTypeName($9);
8559 : : n->returnType->location = @7;
8560 : : n->options = $11;
8561 : : n->sql_body = $12;
8562 : : $$ = (Node *) n;
8563 : : }
8564 : : | CREATE opt_or_replace FUNCTION func_name func_args_with_defaults
8565 : : opt_createfunc_opt_list opt_routine_body
8566 : : {
8567 : : CreateFunctionStmt *n = makeNode(CreateFunctionStmt);
8568 : :
8569 : : n->is_procedure = false;
8570 : : n->replace = $2;
8571 : : n->funcname = $4;
8572 : : n->parameters = $5;
8573 : : n->returnType = NULL;
8574 : : n->options = $6;
8575 : : n->sql_body = $7;
8576 : : $$ = (Node *) n;
8577 : : }
8578 : : | CREATE opt_or_replace PROCEDURE func_name func_args_with_defaults
8579 : : opt_createfunc_opt_list opt_routine_body
8580 : : {
8581 : : CreateFunctionStmt *n = makeNode(CreateFunctionStmt);
8582 : :
8583 : : n->is_procedure = true;
8584 : : n->replace = $2;
8585 : : n->funcname = $4;
8586 : : n->parameters = $5;
8587 : : n->returnType = NULL;
8588 : : n->options = $6;
8589 : : n->sql_body = $7;
8590 : : $$ = (Node *) n;
8591 : : }
8592 : : ;
8593 : :
8594 : : opt_or_replace:
8595 : : OR REPLACE { $$ = true; }
8596 : : | /*EMPTY*/ { $$ = false; }
8597 : : ;
8598 : :
8599 : : func_args: '(' func_args_list ')' { $$ = $2; }
8600 : : | '(' ')' { $$ = NIL; }
8601 : : ;
8602 : :
8603 : : func_args_list:
8604 : : func_arg { $$ = list_make1($1); }
8605 : : | func_args_list ',' func_arg { $$ = lappend($1, $3); }
8606 : : ;
8607 : :
8608 : : function_with_argtypes_list:
8609 : : function_with_argtypes { $$ = list_make1($1); }
8610 : : | function_with_argtypes_list ',' function_with_argtypes
8611 : : { $$ = lappend($1, $3); }
8612 : : ;
8613 : :
8614 : : function_with_argtypes:
8615 : : func_name func_args
8616 : : {
8617 : : ObjectWithArgs *n = makeNode(ObjectWithArgs);
8618 : :
8619 : : n->objname = $1;
8620 : : n->objargs = extractArgTypes($2);
8621 : : n->objfuncargs = $2;
8622 : : $$ = n;
8623 : : }
8624 : : /*
8625 : : * Because of reduce/reduce conflicts, we can't use func_name
8626 : : * below, but we can write it out the long way, which actually
8627 : : * allows more cases.
8628 : : */
8629 : : | type_func_name_keyword
8630 : : {
8631 : : ObjectWithArgs *n = makeNode(ObjectWithArgs);
8632 : :
8633 : : n->objname = list_make1(makeString(pstrdup($1)));
8634 : : n->args_unspecified = true;
8635 : : $$ = n;
8636 : : }
8637 : : | ColId
8638 : : {
8639 : : ObjectWithArgs *n = makeNode(ObjectWithArgs);
8640 : :
8641 : : n->objname = list_make1(makeString($1));
8642 : : n->args_unspecified = true;
8643 : : $$ = n;
8644 : : }
8645 : : | ColId indirection
8646 : : {
8647 : : ObjectWithArgs *n = makeNode(ObjectWithArgs);
8648 : :
8649 : : n->objname = check_func_name(lcons(makeString($1), $2),
8650 : : yyscanner);
8651 : : n->args_unspecified = true;
8652 : : $$ = n;
8653 : : }
8654 : : ;
8655 : :
8656 : : /*
8657 : : * func_args_with_defaults is separate because we only want to accept
8658 : : * defaults in CREATE FUNCTION, not in ALTER etc.
8659 : : */
8660 : : func_args_with_defaults:
8661 : : '(' func_args_with_defaults_list ')' { $$ = $2; }
8662 : : | '(' ')' { $$ = NIL; }
8663 : : ;
8664 : :
8665 : : func_args_with_defaults_list:
8666 : : func_arg_with_default { $$ = list_make1($1); }
8667 : : | func_args_with_defaults_list ',' func_arg_with_default
8668 : : { $$ = lappend($1, $3); }
8669 : : ;
8670 : :
8671 : : /*
8672 : : * The style with arg_class first is SQL99 standard, but Oracle puts
8673 : : * param_name first; accept both since it's likely people will try both
8674 : : * anyway. Don't bother trying to save productions by letting arg_class
8675 : : * have an empty alternative ... you'll get shift/reduce conflicts.
8676 : : *
8677 : : * We can catch over-specified arguments here if we want to,
8678 : : * but for now better to silently swallow typmod, etc.
8679 : : * - thomas 2000-03-22
8680 : : */
8681 : : func_arg:
8682 : : arg_class param_name func_type
8683 : : {
8684 : : FunctionParameter *n = makeNode(FunctionParameter);
8685 : :
8686 : : n->name = $2;
8687 : : n->argType = $3;
8688 : : n->mode = $1;
8689 : : n->defexpr = NULL;
8690 : : n->location = @1;
8691 : : $$ = n;
8692 : : }
8693 : : | param_name arg_class func_type
8694 : : {
8695 : : FunctionParameter *n = makeNode(FunctionParameter);
8696 : :
8697 : : n->name = $1;
8698 : : n->argType = $3;
8699 : : n->mode = $2;
8700 : : n->defexpr = NULL;
8701 : : n->location = @1;
8702 : : $$ = n;
8703 : : }
8704 : : | param_name func_type
8705 : : {
8706 : : FunctionParameter *n = makeNode(FunctionParameter);
8707 : :
8708 : : n->name = $1;
8709 : : n->argType = $2;
8710 : : n->mode = FUNC_PARAM_DEFAULT;
8711 : : n->defexpr = NULL;
8712 : : n->location = @1;
8713 : : $$ = n;
8714 : : }
8715 : : | arg_class func_type
8716 : : {
8717 : : FunctionParameter *n = makeNode(FunctionParameter);
8718 : :
8719 : : n->name = NULL;
8720 : : n->argType = $2;
8721 : : n->mode = $1;
8722 : : n->defexpr = NULL;
8723 : : n->location = @1;
8724 : : $$ = n;
8725 : : }
8726 : : | func_type
8727 : : {
8728 : : FunctionParameter *n = makeNode(FunctionParameter);
8729 : :
8730 : : n->name = NULL;
8731 : : n->argType = $1;
8732 : : n->mode = FUNC_PARAM_DEFAULT;
8733 : : n->defexpr = NULL;
8734 : : n->location = @1;
8735 : : $$ = n;
8736 : : }
8737 : : ;
8738 : :
8739 : : /* INOUT is SQL99 standard, IN OUT is for Oracle compatibility */
8740 : : arg_class: IN_P { $$ = FUNC_PARAM_IN; }
8741 : : | OUT_P { $$ = FUNC_PARAM_OUT; }
8742 : : | INOUT { $$ = FUNC_PARAM_INOUT; }
8743 : : | IN_P OUT_P { $$ = FUNC_PARAM_INOUT; }
8744 : : | VARIADIC { $$ = FUNC_PARAM_VARIADIC; }
8745 : : ;
8746 : :
8747 : : /*
8748 : : * Ideally param_name should be ColId, but that causes too many conflicts.
8749 : : */
8750 : : param_name: type_function_name
8751 : : ;
8752 : :
8753 : : func_return:
8754 : : func_type
8755 : : {
8756 : : /* We can catch over-specified results here if we want to,
8757 : : * but for now better to silently swallow typmod, etc.
8758 : : * - thomas 2000-03-22
8759 : : */
8760 : : $$ = $1;
8761 : : }
8762 : : ;
8763 : :
8764 : : /*
8765 : : * We would like to make the %TYPE productions here be ColId attrs etc,
8766 : : * but that causes reduce/reduce conflicts. type_function_name
8767 : : * is next best choice.
8768 : : */
8769 : : func_type: Typename { $$ = $1; }
8770 : : | type_function_name attrs '%' TYPE_P
8771 : : {
8772 : : $$ = makeTypeNameFromNameList(lcons(makeString($1), $2));
8773 : : $$->pct_type = true;
8774 : : $$->location = @1;
8775 : : }
8776 : : | SETOF type_function_name attrs '%' TYPE_P
8777 : : {
8778 : : $$ = makeTypeNameFromNameList(lcons(makeString($2), $3));
8779 : : $$->pct_type = true;
8780 : : $$->setof = true;
8781 : : $$->location = @2;
8782 : : }
8783 : : ;
8784 : :
8785 : : func_arg_with_default:
8786 : : func_arg
8787 : : {
8788 : : $$ = $1;
8789 : : }
8790 : : | func_arg DEFAULT a_expr
8791 : : {
8792 : : $$ = $1;
8793 : : $$->defexpr = $3;
8794 : : }
8795 : : | func_arg '=' a_expr
8796 : : {
8797 : : $$ = $1;
8798 : : $$->defexpr = $3;
8799 : : }
8800 : : ;
8801 : :
8802 : : /* Aggregate args can be most things that function args can be */
8803 : : aggr_arg: func_arg
8804 : : {
8805 : : if (!($1->mode == FUNC_PARAM_DEFAULT ||
8806 : : $1->mode == FUNC_PARAM_IN ||
8807 : : $1->mode == FUNC_PARAM_VARIADIC))
8808 : : ereport(ERROR,
8809 : : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
8810 : : errmsg("aggregates cannot have output arguments"),
8811 : : parser_errposition(@1)));
8812 : : $$ = $1;
8813 : : }
8814 : : ;
8815 : :
8816 : : /*
8817 : : * The SQL standard offers no guidance on how to declare aggregate argument
8818 : : * lists, since it doesn't have CREATE AGGREGATE etc. We accept these cases:
8819 : : *
8820 : : * (*) - normal agg with no args
8821 : : * (aggr_arg,...) - normal agg with args
8822 : : * (ORDER BY aggr_arg,...) - ordered-set agg with no direct args
8823 : : * (aggr_arg,... ORDER BY aggr_arg,...) - ordered-set agg with direct args
8824 : : *
8825 : : * The zero-argument case is spelled with '*' for consistency with COUNT(*).
8826 : : *
8827 : : * An additional restriction is that if the direct-args list ends in a
8828 : : * VARIADIC item, the ordered-args list must contain exactly one item that
8829 : : * is also VARIADIC with the same type. This allows us to collapse the two
8830 : : * VARIADIC items into one, which is necessary to represent the aggregate in
8831 : : * pg_proc. We check this at the grammar stage so that we can return a list
8832 : : * in which the second VARIADIC item is already discarded, avoiding extra work
8833 : : * in cases such as DROP AGGREGATE.
8834 : : *
8835 : : * The return value of this production is a two-element list, in which the
8836 : : * first item is a sublist of FunctionParameter nodes (with any duplicate
8837 : : * VARIADIC item already dropped, as per above) and the second is an Integer
8838 : : * node, containing -1 if there was no ORDER BY and otherwise the number
8839 : : * of argument declarations before the ORDER BY. (If this number is equal
8840 : : * to the first sublist's length, then we dropped a duplicate VARIADIC item.)
8841 : : * This representation is passed as-is to CREATE AGGREGATE; for operations
8842 : : * on existing aggregates, we can just apply extractArgTypes to the first
8843 : : * sublist.
8844 : : */
8845 : : aggr_args: '(' '*' ')'
8846 : : {
8847 : : $$ = list_make2(NIL, makeInteger(-1));
8848 : : }
8849 : : | '(' aggr_args_list ')'
8850 : : {
8851 : : $$ = list_make2($2, makeInteger(-1));
8852 : : }
8853 : : | '(' ORDER BY aggr_args_list ')'
8854 : : {
8855 : : $$ = list_make2($4, makeInteger(0));
8856 : : }
8857 : : | '(' aggr_args_list ORDER BY aggr_args_list ')'
8858 : : {
8859 : : /* this is the only case requiring consistency checking */
8860 : : $$ = makeOrderedSetArgs($2, $5, yyscanner);
8861 : : }
8862 : : ;
8863 : :
8864 : : aggr_args_list:
8865 : : aggr_arg { $$ = list_make1($1); }
8866 : : | aggr_args_list ',' aggr_arg { $$ = lappend($1, $3); }
8867 : : ;
8868 : :
8869 : : aggregate_with_argtypes:
8870 : : func_name aggr_args
8871 : : {
8872 : : ObjectWithArgs *n = makeNode(ObjectWithArgs);
8873 : :
8874 : : n->objname = $1;
8875 : : n->objargs = extractAggrArgTypes($2);
8876 : : n->objfuncargs = (List *) linitial($2);
8877 : : $$ = n;
8878 : : }
8879 : : ;
8880 : :
8881 : : aggregate_with_argtypes_list:
8882 : : aggregate_with_argtypes { $$ = list_make1($1); }
8883 : : | aggregate_with_argtypes_list ',' aggregate_with_argtypes
8884 : : { $$ = lappend($1, $3); }
8885 : : ;
8886 : :
8887 : : opt_createfunc_opt_list:
8888 : : createfunc_opt_list
8889 : : | /*EMPTY*/ { $$ = NIL; }
8890 : : ;
8891 : :
8892 : : createfunc_opt_list:
8893 : : /* Must be at least one to prevent conflict */
8894 : : createfunc_opt_item { $$ = list_make1($1); }
8895 : : | createfunc_opt_list createfunc_opt_item { $$ = lappend($1, $2); }
8896 : : ;
8897 : :
8898 : : /*
8899 : : * Options common to both CREATE FUNCTION and ALTER FUNCTION
8900 : : */
8901 : : common_func_opt_item:
8902 : : CALLED ON NULL_P INPUT_P
8903 : : {
8904 : : $$ = makeDefElem("strict", (Node *) makeBoolean(false), @1);
8905 : : }
8906 : : | RETURNS NULL_P ON NULL_P INPUT_P
8907 : : {
8908 : : $$ = makeDefElem("strict", (Node *) makeBoolean(true), @1);
8909 : : }
8910 : : | STRICT_P
8911 : : {
8912 : : $$ = makeDefElem("strict", (Node *) makeBoolean(true), @1);
8913 : : }
8914 : : | IMMUTABLE
8915 : : {
8916 : : $$ = makeDefElem("volatility", (Node *) makeString("immutable"), @1);
8917 : : }
8918 : : | STABLE
8919 : : {
8920 : : $$ = makeDefElem("volatility", (Node *) makeString("stable"), @1);
8921 : : }
8922 : : | VOLATILE
8923 : : {
8924 : : $$ = makeDefElem("volatility", (Node *) makeString("volatile"), @1);
8925 : : }
8926 : : | EXTERNAL SECURITY DEFINER
8927 : : {
8928 : : $$ = makeDefElem("security", (Node *) makeBoolean(true), @1);
8929 : : }
8930 : : | EXTERNAL SECURITY INVOKER
8931 : : {
8932 : : $$ = makeDefElem("security", (Node *) makeBoolean(false), @1);
8933 : : }
8934 : : | SECURITY DEFINER
8935 : : {
8936 : : $$ = makeDefElem("security", (Node *) makeBoolean(true), @1);
8937 : : }
8938 : : | SECURITY INVOKER
8939 : : {
8940 : : $$ = makeDefElem("security", (Node *) makeBoolean(false), @1);
8941 : : }
8942 : : | LEAKPROOF
8943 : : {
8944 : : $$ = makeDefElem("leakproof", (Node *) makeBoolean(true), @1);
8945 : : }
8946 : : | NOT LEAKPROOF
8947 : : {
8948 : : $$ = makeDefElem("leakproof", (Node *) makeBoolean(false), @1);
8949 : : }
8950 : : | COST NumericOnly
8951 : : {
8952 : : $$ = makeDefElem("cost", (Node *) $2, @1);
8953 : : }
8954 : : | ROWS NumericOnly
8955 : : {
8956 : : $$ = makeDefElem("rows", (Node *) $2, @1);
8957 : : }
8958 : : | SUPPORT any_name
8959 : : {
8960 : : $$ = makeDefElem("support", (Node *) $2, @1);
8961 : : }
8962 : : | FunctionSetResetClause
8963 : : {
8964 : : /* we abuse the normal content of a DefElem here */
8965 : : $$ = makeDefElem("set", (Node *) $1, @1);
8966 : : }
8967 : : | PARALLEL ColId
8968 : : {
8969 : : $$ = makeDefElem("parallel", (Node *) makeString($2), @1);
8970 : : }
8971 : : ;
8972 : :
8973 : : createfunc_opt_item:
8974 : : AS func_as
8975 : : {
8976 : : $$ = makeDefElem("as", (Node *) $2, @1);
8977 : : }
8978 : : | LANGUAGE NonReservedWord_or_Sconst
8979 : : {
8980 : : $$ = makeDefElem("language", (Node *) makeString($2), @1);
8981 : : }
8982 : : | TRANSFORM transform_type_list
8983 : : {
8984 : : $$ = makeDefElem("transform", (Node *) $2, @1);
8985 : : }
8986 : : | WINDOW
8987 : : {
8988 : : $$ = makeDefElem("window", (Node *) makeBoolean(true), @1);
8989 : : }
8990 : : | common_func_opt_item
8991 : : {
8992 : : $$ = $1;
8993 : : }
8994 : : ;
8995 : :
8996 : : func_as: Sconst { $$ = list_make1(makeString($1)); }
8997 : : | Sconst ',' Sconst
8998 : : {
8999 : : $$ = list_make2(makeString($1), makeString($3));
9000 : : }
9001 : : ;
9002 : :
9003 : : ReturnStmt: RETURN a_expr
9004 : : {
9005 : : ReturnStmt *r = makeNode(ReturnStmt);
9006 : :
9007 : : r->returnval = (Node *) $2;
9008 : : $$ = (Node *) r;
9009 : : }
9010 : : ;
9011 : :
9012 : : opt_routine_body:
9013 : : ReturnStmt
9014 : : {
9015 : : $$ = $1;
9016 : : }
9017 : : | BEGIN_P ATOMIC routine_body_stmt_list END_P
9018 : : {
9019 : : /*
9020 : : * A compound statement is stored as a single-item list
9021 : : * containing the list of statements as its member. That
9022 : : * way, the parse analysis code can tell apart an empty
9023 : : * body from no body at all.
9024 : : */
9025 : : $$ = (Node *) list_make1($3);
9026 : : }
9027 : : | /*EMPTY*/
9028 : : {
9029 : : $$ = NULL;
9030 : : }
9031 : : ;
9032 : :
9033 : : routine_body_stmt_list:
9034 : : routine_body_stmt_list routine_body_stmt ';'
9035 : : {
9036 : : /* As in stmtmulti, discard empty statements */
9037 : : if ($2 != NULL)
9038 : : $$ = lappend($1, $2);
9039 : : else
9040 : : $$ = $1;
9041 : : }
9042 : : | /*EMPTY*/
9043 : : {
9044 : : $$ = NIL;
9045 : : }
9046 : : ;
9047 : :
9048 : : routine_body_stmt:
9049 : : stmt
9050 : : | ReturnStmt
9051 : : ;
9052 : :
9053 : : transform_type_list:
9054 : : FOR TYPE_P Typename { $$ = list_make1($3); }
9055 : : | transform_type_list ',' FOR TYPE_P Typename { $$ = lappend($1, $5); }
9056 : : ;
9057 : :
9058 : : opt_definition:
9059 : : WITH definition { $$ = $2; }
9060 : : | /*EMPTY*/ { $$ = NIL; }
9061 : : ;
9062 : :
9063 : : table_func_column: param_name func_type
9064 : : {
9065 : : FunctionParameter *n = makeNode(FunctionParameter);
9066 : :
9067 : : n->name = $1;
9068 : : n->argType = $2;
9069 : : n->mode = FUNC_PARAM_TABLE;
9070 : : n->defexpr = NULL;
9071 : : n->location = @1;
9072 : : $$ = n;
9073 : : }
9074 : : ;
9075 : :
9076 : : table_func_column_list:
9077 : : table_func_column
9078 : : {
9079 : : $$ = list_make1($1);
9080 : : }
9081 : : | table_func_column_list ',' table_func_column
9082 : : {
9083 : : $$ = lappend($1, $3);
9084 : : }
9085 : : ;
9086 : :
9087 : : /*****************************************************************************
9088 : : * ALTER FUNCTION / ALTER PROCEDURE / ALTER ROUTINE
9089 : : *
9090 : : * RENAME and OWNER subcommands are already provided by the generic
9091 : : * ALTER infrastructure, here we just specify alterations that can
9092 : : * only be applied to functions.
9093 : : *
9094 : : *****************************************************************************/
9095 : : AlterFunctionStmt:
9096 : : ALTER FUNCTION function_with_argtypes alterfunc_opt_list opt_restrict
9097 : : {
9098 : : AlterFunctionStmt *n = makeNode(AlterFunctionStmt);
9099 : :
9100 : : n->objtype = OBJECT_FUNCTION;
9101 : : n->func = $3;
9102 : : n->actions = $4;
9103 : : $$ = (Node *) n;
9104 : : }
9105 : : | ALTER PROCEDURE function_with_argtypes alterfunc_opt_list opt_restrict
9106 : : {
9107 : : AlterFunctionStmt *n = makeNode(AlterFunctionStmt);
9108 : :
9109 : : n->objtype = OBJECT_PROCEDURE;
9110 : : n->func = $3;
9111 : : n->actions = $4;
9112 : : $$ = (Node *) n;
9113 : : }
9114 : : | ALTER ROUTINE function_with_argtypes alterfunc_opt_list opt_restrict
9115 : : {
9116 : : AlterFunctionStmt *n = makeNode(AlterFunctionStmt);
9117 : :
9118 : : n->objtype = OBJECT_ROUTINE;
9119 : : n->func = $3;
9120 : : n->actions = $4;
9121 : : $$ = (Node *) n;
9122 : : }
9123 : : ;
9124 : :
9125 : : alterfunc_opt_list:
9126 : : /* At least one option must be specified */
9127 : : common_func_opt_item { $$ = list_make1($1); }
9128 : : | alterfunc_opt_list common_func_opt_item { $$ = lappend($1, $2); }
9129 : : ;
9130 : :
9131 : : /* Ignored, merely for SQL compliance */
9132 : : opt_restrict:
9133 : : RESTRICT
9134 : : | /* EMPTY */
9135 : : ;
9136 : :
9137 : :
9138 : : /*****************************************************************************
9139 : : *
9140 : : * QUERY:
9141 : : *
9142 : : * DROP FUNCTION funcname (arg1, arg2, ...) [ RESTRICT | CASCADE ]
9143 : : * DROP PROCEDURE procname (arg1, arg2, ...) [ RESTRICT | CASCADE ]
9144 : : * DROP ROUTINE routname (arg1, arg2, ...) [ RESTRICT | CASCADE ]
9145 : : * DROP AGGREGATE aggname (arg1, ...) [ RESTRICT | CASCADE ]
9146 : : * DROP OPERATOR opname (leftoperand_typ, rightoperand_typ) [ RESTRICT | CASCADE ]
9147 : : *
9148 : : *****************************************************************************/
9149 : :
9150 : : RemoveFuncStmt:
9151 : : DROP FUNCTION function_with_argtypes_list opt_drop_behavior
9152 : : {
9153 : : DropStmt *n = makeNode(DropStmt);
9154 : :
9155 : : n->removeType = OBJECT_FUNCTION;
9156 : : n->objects = $3;
9157 : : n->behavior = $4;
9158 : : n->missing_ok = false;
9159 : : n->concurrent = false;
9160 : : $$ = (Node *) n;
9161 : : }
9162 : : | DROP FUNCTION IF_P EXISTS function_with_argtypes_list opt_drop_behavior
9163 : : {
9164 : : DropStmt *n = makeNode(DropStmt);
9165 : :
9166 : : n->removeType = OBJECT_FUNCTION;
9167 : : n->objects = $5;
9168 : : n->behavior = $6;
9169 : : n->missing_ok = true;
9170 : : n->concurrent = false;
9171 : : $$ = (Node *) n;
9172 : : }
9173 : : | DROP PROCEDURE function_with_argtypes_list opt_drop_behavior
9174 : : {
9175 : : DropStmt *n = makeNode(DropStmt);
9176 : :
9177 : : n->removeType = OBJECT_PROCEDURE;
9178 : : n->objects = $3;
9179 : : n->behavior = $4;
9180 : : n->missing_ok = false;
9181 : : n->concurrent = false;
9182 : : $$ = (Node *) n;
9183 : : }
9184 : : | DROP PROCEDURE IF_P EXISTS function_with_argtypes_list opt_drop_behavior
9185 : : {
9186 : : DropStmt *n = makeNode(DropStmt);
9187 : :
9188 : : n->removeType = OBJECT_PROCEDURE;
9189 : : n->objects = $5;
9190 : : n->behavior = $6;
9191 : : n->missing_ok = true;
9192 : : n->concurrent = false;
9193 : : $$ = (Node *) n;
9194 : : }
9195 : : | DROP ROUTINE function_with_argtypes_list opt_drop_behavior
9196 : : {
9197 : : DropStmt *n = makeNode(DropStmt);
9198 : :
9199 : : n->removeType = OBJECT_ROUTINE;
9200 : : n->objects = $3;
9201 : : n->behavior = $4;
9202 : : n->missing_ok = false;
9203 : : n->concurrent = false;
9204 : : $$ = (Node *) n;
9205 : : }
9206 : : | DROP ROUTINE IF_P EXISTS function_with_argtypes_list opt_drop_behavior
9207 : : {
9208 : : DropStmt *n = makeNode(DropStmt);
9209 : :
9210 : : n->removeType = OBJECT_ROUTINE;
9211 : : n->objects = $5;
9212 : : n->behavior = $6;
9213 : : n->missing_ok = true;
9214 : : n->concurrent = false;
9215 : : $$ = (Node *) n;
9216 : : }
9217 : : ;
9218 : :
9219 : : RemoveAggrStmt:
9220 : : DROP AGGREGATE aggregate_with_argtypes_list opt_drop_behavior
9221 : : {
9222 : : DropStmt *n = makeNode(DropStmt);
9223 : :
9224 : : n->removeType = OBJECT_AGGREGATE;
9225 : : n->objects = $3;
9226 : : n->behavior = $4;
9227 : : n->missing_ok = false;
9228 : : n->concurrent = false;
9229 : : $$ = (Node *) n;
9230 : : }
9231 : : | DROP AGGREGATE IF_P EXISTS aggregate_with_argtypes_list opt_drop_behavior
9232 : : {
9233 : : DropStmt *n = makeNode(DropStmt);
9234 : :
9235 : : n->removeType = OBJECT_AGGREGATE;
9236 : : n->objects = $5;
9237 : : n->behavior = $6;
9238 : : n->missing_ok = true;
9239 : : n->concurrent = false;
9240 : : $$ = (Node *) n;
9241 : : }
9242 : : ;
9243 : :
9244 : : RemoveOperStmt:
9245 : : DROP OPERATOR operator_with_argtypes_list opt_drop_behavior
9246 : : {
9247 : : DropStmt *n = makeNode(DropStmt);
9248 : :
9249 : : n->removeType = OBJECT_OPERATOR;
9250 : : n->objects = $3;
9251 : : n->behavior = $4;
9252 : : n->missing_ok = false;
9253 : : n->concurrent = false;
9254 : : $$ = (Node *) n;
9255 : : }
9256 : : | DROP OPERATOR IF_P EXISTS operator_with_argtypes_list opt_drop_behavior
9257 : : {
9258 : : DropStmt *n = makeNode(DropStmt);
9259 : :
9260 : : n->removeType = OBJECT_OPERATOR;
9261 : : n->objects = $5;
9262 : : n->behavior = $6;
9263 : : n->missing_ok = true;
9264 : : n->concurrent = false;
9265 : : $$ = (Node *) n;
9266 : : }
9267 : : ;
9268 : :
9269 : : oper_argtypes:
9270 : : '(' Typename ')'
9271 : : {
9272 : : ereport(ERROR,
9273 : : (errcode(ERRCODE_SYNTAX_ERROR),
9274 : : errmsg("missing argument"),
9275 : : errhint("Use NONE to denote the missing argument of a unary operator."),
9276 : : parser_errposition(@3)));
9277 : : }
9278 : : | '(' Typename ',' Typename ')'
9279 : : { $$ = list_make2($2, $4); }
9280 : : | '(' NONE ',' Typename ')' /* left unary */
9281 : : { $$ = list_make2(NULL, $4); }
9282 : : | '(' Typename ',' NONE ')' /* right unary */
9283 : : { $$ = list_make2($2, NULL); }
9284 : : ;
9285 : :
9286 : : any_operator:
9287 : : all_Op
9288 : : { $$ = list_make1(makeString($1)); }
9289 : : | ColId '.' any_operator
9290 : : { $$ = lcons(makeString($1), $3); }
9291 : : ;
9292 : :
9293 : : operator_with_argtypes_list:
9294 : : operator_with_argtypes { $$ = list_make1($1); }
9295 : : | operator_with_argtypes_list ',' operator_with_argtypes
9296 : : { $$ = lappend($1, $3); }
9297 : : ;
9298 : :
9299 : : operator_with_argtypes:
9300 : : any_operator oper_argtypes
9301 : : {
9302 : : ObjectWithArgs *n = makeNode(ObjectWithArgs);
9303 : :
9304 : : n->objname = $1;
9305 : : n->objargs = $2;
9306 : : $$ = n;
9307 : : }
9308 : : ;
9309 : :
9310 : : /*****************************************************************************
9311 : : *
9312 : : * DO <anonymous code block> [ LANGUAGE language ]
9313 : : *
9314 : : * We use a DefElem list for future extensibility, and to allow flexibility
9315 : : * in the clause order.
9316 : : *
9317 : : *****************************************************************************/
9318 : :
9319 : : DoStmt: DO dostmt_opt_list
9320 : : {
9321 : : DoStmt *n = makeNode(DoStmt);
9322 : :
9323 : : n->args = $2;
9324 : : $$ = (Node *) n;
9325 : : }
9326 : : ;
9327 : :
9328 : : dostmt_opt_list:
9329 : : dostmt_opt_item { $$ = list_make1($1); }
9330 : : | dostmt_opt_list dostmt_opt_item { $$ = lappend($1, $2); }
9331 : : ;
9332 : :
9333 : : dostmt_opt_item:
9334 : : Sconst
9335 : : {
9336 : : $$ = makeDefElem("as", (Node *) makeString($1), @1);
9337 : : }
9338 : : | LANGUAGE NonReservedWord_or_Sconst
9339 : : {
9340 : : $$ = makeDefElem("language", (Node *) makeString($2), @1);
9341 : : }
9342 : : ;
9343 : :
9344 : : /*****************************************************************************
9345 : : *
9346 : : * CREATE CAST / DROP CAST
9347 : : *
9348 : : *****************************************************************************/
9349 : :
9350 : : CreateCastStmt: CREATE CAST '(' Typename AS Typename ')'
9351 : : WITH FUNCTION function_with_argtypes cast_context
9352 : : {
9353 : : CreateCastStmt *n = makeNode(CreateCastStmt);
9354 : :
9355 : : n->sourcetype = $4;
9356 : : n->targettype = $6;
9357 : : n->func = $10;
9358 : : n->context = (CoercionContext) $11;
9359 : : n->inout = false;
9360 : : $$ = (Node *) n;
9361 : : }
9362 : : | CREATE CAST '(' Typename AS Typename ')'
9363 : : WITHOUT FUNCTION cast_context
9364 : : {
9365 : : CreateCastStmt *n = makeNode(CreateCastStmt);
9366 : :
9367 : : n->sourcetype = $4;
9368 : : n->targettype = $6;
9369 : : n->func = NULL;
9370 : : n->context = (CoercionContext) $10;
9371 : : n->inout = false;
9372 : : $$ = (Node *) n;
9373 : : }
9374 : : | CREATE CAST '(' Typename AS Typename ')'
9375 : : WITH INOUT cast_context
9376 : : {
9377 : : CreateCastStmt *n = makeNode(CreateCastStmt);
9378 : :
9379 : : n->sourcetype = $4;
9380 : : n->targettype = $6;
9381 : : n->func = NULL;
9382 : : n->context = (CoercionContext) $10;
9383 : : n->inout = true;
9384 : : $$ = (Node *) n;
9385 : : }
9386 : : ;
9387 : :
9388 : : cast_context: AS IMPLICIT_P { $$ = COERCION_IMPLICIT; }
9389 : : | AS ASSIGNMENT { $$ = COERCION_ASSIGNMENT; }
9390 : : | /*EMPTY*/ { $$ = COERCION_EXPLICIT; }
9391 : : ;
9392 : :
9393 : :
9394 : : DropCastStmt: DROP CAST opt_if_exists '(' Typename AS Typename ')' opt_drop_behavior
9395 : : {
9396 : : DropStmt *n = makeNode(DropStmt);
9397 : :
9398 : : n->removeType = OBJECT_CAST;
9399 : : n->objects = list_make1(list_make2($5, $7));
9400 : : n->behavior = $9;
9401 : : n->missing_ok = $3;
9402 : : n->concurrent = false;
9403 : : $$ = (Node *) n;
9404 : : }
9405 : : ;
9406 : :
9407 : : opt_if_exists: IF_P EXISTS { $$ = true; }
9408 : : | /*EMPTY*/ { $$ = false; }
9409 : : ;
9410 : :
9411 : :
9412 : : /*****************************************************************************
9413 : : *
9414 : : * CREATE TRANSFORM / DROP TRANSFORM
9415 : : *
9416 : : *****************************************************************************/
9417 : :
9418 : : CreateTransformStmt: CREATE opt_or_replace TRANSFORM FOR Typename LANGUAGE name '(' transform_element_list ')'
9419 : : {
9420 : : CreateTransformStmt *n = makeNode(CreateTransformStmt);
9421 : :
9422 : : n->replace = $2;
9423 : : n->type_name = $5;
9424 : : n->lang = $7;
9425 : : n->fromsql = linitial($9);
9426 : : n->tosql = lsecond($9);
9427 : : $$ = (Node *) n;
9428 : : }
9429 : : ;
9430 : :
9431 : : transform_element_list: FROM SQL_P WITH FUNCTION function_with_argtypes ',' TO SQL_P WITH FUNCTION function_with_argtypes
9432 : : {
9433 : : $$ = list_make2($5, $11);
9434 : : }
9435 : : | TO SQL_P WITH FUNCTION function_with_argtypes ',' FROM SQL_P WITH FUNCTION function_with_argtypes
9436 : : {
9437 : : $$ = list_make2($11, $5);
9438 : : }
9439 : : | FROM SQL_P WITH FUNCTION function_with_argtypes
9440 : : {
9441 : : $$ = list_make2($5, NULL);
9442 : : }
9443 : : | TO SQL_P WITH FUNCTION function_with_argtypes
9444 : : {
9445 : : $$ = list_make2(NULL, $5);
9446 : : }
9447 : : ;
9448 : :
9449 : :
9450 : : DropTransformStmt: DROP TRANSFORM opt_if_exists FOR Typename LANGUAGE name opt_drop_behavior
9451 : : {
9452 : : DropStmt *n = makeNode(DropStmt);
9453 : :
9454 : : n->removeType = OBJECT_TRANSFORM;
9455 : : n->objects = list_make1(list_make2($5, makeString($7)));
9456 : : n->behavior = $8;
9457 : : n->missing_ok = $3;
9458 : : $$ = (Node *) n;
9459 : : }
9460 : : ;
9461 : :
9462 : :
9463 : : /*****************************************************************************
9464 : : *
9465 : : * QUERY:
9466 : : *
9467 : : * REINDEX [ (options) ] {INDEX | TABLE | SCHEMA} [CONCURRENTLY] <name>
9468 : : * REINDEX [ (options) ] {DATABASE | SYSTEM} [CONCURRENTLY] [<name>]
9469 : : *****************************************************************************/
9470 : :
9471 : : ReindexStmt:
9472 : : REINDEX opt_utility_option_list reindex_target_relation opt_concurrently qualified_name
9473 : : {
9474 : : ReindexStmt *n = makeNode(ReindexStmt);
9475 : :
9476 : : n->kind = $3;
9477 : : n->relation = $5;
9478 : : n->name = NULL;
9479 : : n->params = $2;
9480 : : if ($4)
9481 : : n->params = lappend(n->params,
9482 : : makeDefElem("concurrently", NULL, @4));
9483 : : $$ = (Node *) n;
9484 : : }
9485 : : | REINDEX opt_utility_option_list SCHEMA opt_concurrently name
9486 : : {
9487 : : ReindexStmt *n = makeNode(ReindexStmt);
9488 : :
9489 : : n->kind = REINDEX_OBJECT_SCHEMA;
9490 : : n->relation = NULL;
9491 : : n->name = $5;
9492 : : n->params = $2;
9493 : : if ($4)
9494 : : n->params = lappend(n->params,
9495 : : makeDefElem("concurrently", NULL, @4));
9496 : : $$ = (Node *) n;
9497 : : }
9498 : : | REINDEX opt_utility_option_list reindex_target_all opt_concurrently opt_single_name
9499 : : {
9500 : : ReindexStmt *n = makeNode(ReindexStmt);
9501 : :
9502 : : n->kind = $3;
9503 : : n->relation = NULL;
9504 : : n->name = $5;
9505 : : n->params = $2;
9506 : : if ($4)
9507 : : n->params = lappend(n->params,
9508 : : makeDefElem("concurrently", NULL, @4));
9509 : : $$ = (Node *) n;
9510 : : }
9511 : : ;
9512 : : reindex_target_relation:
9513 : : INDEX { $$ = REINDEX_OBJECT_INDEX; }
9514 : : | TABLE { $$ = REINDEX_OBJECT_TABLE; }
9515 : : ;
9516 : : reindex_target_all:
9517 : : SYSTEM_P { $$ = REINDEX_OBJECT_SYSTEM; }
9518 : : | DATABASE { $$ = REINDEX_OBJECT_DATABASE; }
9519 : : ;
9520 : :
9521 : : /*****************************************************************************
9522 : : *
9523 : : * ALTER TABLESPACE
9524 : : *
9525 : : *****************************************************************************/
9526 : :
9527 : : AlterTblSpcStmt:
9528 : : ALTER TABLESPACE name SET reloptions
9529 : : {
9530 : : AlterTableSpaceOptionsStmt *n =
9531 : : makeNode(AlterTableSpaceOptionsStmt);
9532 : :
9533 : : n->tablespacename = $3;
9534 : : n->options = $5;
9535 : : n->isReset = false;
9536 : : $$ = (Node *) n;
9537 : : }
9538 : : | ALTER TABLESPACE name RESET reloptions
9539 : : {
9540 : : AlterTableSpaceOptionsStmt *n =
9541 : : makeNode(AlterTableSpaceOptionsStmt);
9542 : :
9543 : : n->tablespacename = $3;
9544 : : n->options = $5;
9545 : : n->isReset = true;
9546 : : $$ = (Node *) n;
9547 : : }
9548 : : ;
9549 : :
9550 : : /*****************************************************************************
9551 : : *
9552 : : * ALTER THING name RENAME TO newname
9553 : : *
9554 : : *****************************************************************************/
9555 : :
9556 : : RenameStmt: ALTER AGGREGATE aggregate_with_argtypes RENAME TO name
9557 : : {
9558 : : RenameStmt *n = makeNode(RenameStmt);
9559 : :
9560 : : n->renameType = OBJECT_AGGREGATE;
9561 : : n->object = (Node *) $3;
9562 : : n->newname = $6;
9563 : : n->missing_ok = false;
9564 : : $$ = (Node *) n;
9565 : : }
9566 : : | ALTER COLLATION any_name RENAME TO name
9567 : : {
9568 : : RenameStmt *n = makeNode(RenameStmt);
9569 : :
9570 : : n->renameType = OBJECT_COLLATION;
9571 : : n->object = (Node *) $3;
9572 : : n->newname = $6;
9573 : : n->missing_ok = false;
9574 : : $$ = (Node *) n;
9575 : : }
9576 : : | ALTER CONVERSION_P any_name RENAME TO name
9577 : : {
9578 : : RenameStmt *n = makeNode(RenameStmt);
9579 : :
9580 : : n->renameType = OBJECT_CONVERSION;
9581 : : n->object = (Node *) $3;
9582 : : n->newname = $6;
9583 : : n->missing_ok = false;
9584 : : $$ = (Node *) n;
9585 : : }
9586 : : | ALTER DATABASE name RENAME TO name
9587 : : {
9588 : : RenameStmt *n = makeNode(RenameStmt);
9589 : :
9590 : : n->renameType = OBJECT_DATABASE;
9591 : : n->subname = $3;
9592 : : n->newname = $6;
9593 : : n->missing_ok = false;
9594 : : $$ = (Node *) n;
9595 : : }
9596 : : | ALTER DOMAIN_P any_name RENAME TO name
9597 : : {
9598 : : RenameStmt *n = makeNode(RenameStmt);
9599 : :
9600 : : n->renameType = OBJECT_DOMAIN;
9601 : : n->object = (Node *) $3;
9602 : : n->newname = $6;
9603 : : n->missing_ok = false;
9604 : : $$ = (Node *) n;
9605 : : }
9606 : : | ALTER DOMAIN_P any_name RENAME CONSTRAINT name TO name
9607 : : {
9608 : : RenameStmt *n = makeNode(RenameStmt);
9609 : :
9610 : : n->renameType = OBJECT_DOMCONSTRAINT;
9611 : : n->object = (Node *) $3;
9612 : : n->subname = $6;
9613 : : n->newname = $8;
9614 : : $$ = (Node *) n;
9615 : : }
9616 : : | ALTER FOREIGN DATA_P WRAPPER name RENAME TO name
9617 : : {
9618 : : RenameStmt *n = makeNode(RenameStmt);
9619 : :
9620 : : n->renameType = OBJECT_FDW;
9621 : : n->object = (Node *) makeString($5);
9622 : : n->newname = $8;
9623 : : n->missing_ok = false;
9624 : : $$ = (Node *) n;
9625 : : }
9626 : : | ALTER FUNCTION function_with_argtypes RENAME TO name
9627 : : {
9628 : : RenameStmt *n = makeNode(RenameStmt);
9629 : :
9630 : : n->renameType = OBJECT_FUNCTION;
9631 : : n->object = (Node *) $3;
9632 : : n->newname = $6;
9633 : : n->missing_ok = false;
9634 : : $$ = (Node *) n;
9635 : : }
9636 : : | ALTER GROUP_P RoleId RENAME TO RoleId
9637 : : {
9638 : : RenameStmt *n = makeNode(RenameStmt);
9639 : :
9640 : : n->renameType = OBJECT_ROLE;
9641 : : n->subname = $3;
9642 : : n->newname = $6;
9643 : : n->missing_ok = false;
9644 : : $$ = (Node *) n;
9645 : : }
9646 : : | ALTER opt_procedural LANGUAGE name RENAME TO name
9647 : : {
9648 : : RenameStmt *n = makeNode(RenameStmt);
9649 : :
9650 : : n->renameType = OBJECT_LANGUAGE;
9651 : : n->object = (Node *) makeString($4);
9652 : : n->newname = $7;
9653 : : n->missing_ok = false;
9654 : : $$ = (Node *) n;
9655 : : }
9656 : : | ALTER OPERATOR CLASS any_name USING name RENAME TO name
9657 : : {
9658 : : RenameStmt *n = makeNode(RenameStmt);
9659 : :
9660 : : n->renameType = OBJECT_OPCLASS;
9661 : : n->object = (Node *) lcons(makeString($6), $4);
9662 : : n->newname = $9;
9663 : : n->missing_ok = false;
9664 : : $$ = (Node *) n;
9665 : : }
9666 : : | ALTER OPERATOR FAMILY any_name USING name RENAME TO name
9667 : : {
9668 : : RenameStmt *n = makeNode(RenameStmt);
9669 : :
9670 : : n->renameType = OBJECT_OPFAMILY;
9671 : : n->object = (Node *) lcons(makeString($6), $4);
9672 : : n->newname = $9;
9673 : : n->missing_ok = false;
9674 : : $$ = (Node *) n;
9675 : : }
9676 : : | ALTER POLICY name ON qualified_name RENAME TO name
9677 : : {
9678 : : RenameStmt *n = makeNode(RenameStmt);
9679 : :
9680 : : n->renameType = OBJECT_POLICY;
9681 : : n->relation = $5;
9682 : : n->subname = $3;
9683 : : n->newname = $8;
9684 : : n->missing_ok = false;
9685 : : $$ = (Node *) n;
9686 : : }
9687 : : | ALTER POLICY IF_P EXISTS name ON qualified_name RENAME TO name
9688 : : {
9689 : : RenameStmt *n = makeNode(RenameStmt);
9690 : :
9691 : : n->renameType = OBJECT_POLICY;
9692 : : n->relation = $7;
9693 : : n->subname = $5;
9694 : : n->newname = $10;
9695 : : n->missing_ok = true;
9696 : : $$ = (Node *) n;
9697 : : }
9698 : : | ALTER PROCEDURE function_with_argtypes RENAME TO name
9699 : : {
9700 : : RenameStmt *n = makeNode(RenameStmt);
9701 : :
9702 : : n->renameType = OBJECT_PROCEDURE;
9703 : : n->object = (Node *) $3;
9704 : : n->newname = $6;
9705 : : n->missing_ok = false;
9706 : : $$ = (Node *) n;
9707 : : }
9708 : : | ALTER PUBLICATION name RENAME TO name
9709 : : {
9710 : : RenameStmt *n = makeNode(RenameStmt);
9711 : :
9712 : : n->renameType = OBJECT_PUBLICATION;
9713 : : n->object = (Node *) makeString($3);
9714 : : n->newname = $6;
9715 : : n->missing_ok = false;
9716 : : $$ = (Node *) n;
9717 : : }
9718 : : | ALTER ROUTINE function_with_argtypes RENAME TO name
9719 : : {
9720 : : RenameStmt *n = makeNode(RenameStmt);
9721 : :
9722 : : n->renameType = OBJECT_ROUTINE;
9723 : : n->object = (Node *) $3;
9724 : : n->newname = $6;
9725 : : n->missing_ok = false;
9726 : : $$ = (Node *) n;
9727 : : }
9728 : : | ALTER SCHEMA name RENAME TO name
9729 : : {
9730 : : RenameStmt *n = makeNode(RenameStmt);
9731 : :
9732 : : n->renameType = OBJECT_SCHEMA;
9733 : : n->subname = $3;
9734 : : n->newname = $6;
9735 : : n->missing_ok = false;
9736 : : $$ = (Node *) n;
9737 : : }
9738 : : | ALTER SERVER name RENAME TO name
9739 : : {
9740 : : RenameStmt *n = makeNode(RenameStmt);
9741 : :
9742 : : n->renameType = OBJECT_FOREIGN_SERVER;
9743 : : n->object = (Node *) makeString($3);
9744 : : n->newname = $6;
9745 : : n->missing_ok = false;
9746 : : $$ = (Node *) n;
9747 : : }
9748 : : | ALTER SUBSCRIPTION name RENAME TO name
9749 : : {
9750 : : RenameStmt *n = makeNode(RenameStmt);
9751 : :
9752 : : n->renameType = OBJECT_SUBSCRIPTION;
9753 : : n->object = (Node *) makeString($3);
9754 : : n->newname = $6;
9755 : : n->missing_ok = false;
9756 : : $$ = (Node *) n;
9757 : : }
9758 : : | ALTER TABLE relation_expr RENAME TO name
9759 : : {
9760 : : RenameStmt *n = makeNode(RenameStmt);
9761 : :
9762 : : n->renameType = OBJECT_TABLE;
9763 : : n->relation = $3;
9764 : : n->subname = NULL;
9765 : : n->newname = $6;
9766 : : n->missing_ok = false;
9767 : : $$ = (Node *) n;
9768 : : }
9769 : : | ALTER TABLE IF_P EXISTS relation_expr RENAME TO name
9770 : : {
9771 : : RenameStmt *n = makeNode(RenameStmt);
9772 : :
9773 : : n->renameType = OBJECT_TABLE;
9774 : : n->relation = $5;
9775 : : n->subname = NULL;
9776 : : n->newname = $8;
9777 : : n->missing_ok = true;
9778 : : $$ = (Node *) n;
9779 : : }
9780 : : | ALTER SEQUENCE qualified_name RENAME TO name
9781 : : {
9782 : : RenameStmt *n = makeNode(RenameStmt);
9783 : :
9784 : : n->renameType = OBJECT_SEQUENCE;
9785 : : n->relation = $3;
9786 : : n->subname = NULL;
9787 : : n->newname = $6;
9788 : : n->missing_ok = false;
9789 : : $$ = (Node *) n;
9790 : : }
9791 : : | ALTER SEQUENCE IF_P EXISTS qualified_name RENAME TO name
9792 : : {
9793 : : RenameStmt *n = makeNode(RenameStmt);
9794 : :
9795 : : n->renameType = OBJECT_SEQUENCE;
9796 : : n->relation = $5;
9797 : : n->subname = NULL;
9798 : : n->newname = $8;
9799 : : n->missing_ok = true;
9800 : : $$ = (Node *) n;
9801 : : }
9802 : : | ALTER VIEW qualified_name RENAME TO name
9803 : : {
9804 : : RenameStmt *n = makeNode(RenameStmt);
9805 : :
9806 : : n->renameType = OBJECT_VIEW;
9807 : : n->relation = $3;
9808 : : n->subname = NULL;
9809 : : n->newname = $6;
9810 : : n->missing_ok = false;
9811 : : $$ = (Node *) n;
9812 : : }
9813 : : | ALTER VIEW IF_P EXISTS qualified_name RENAME TO name
9814 : : {
9815 : : RenameStmt *n = makeNode(RenameStmt);
9816 : :
9817 : : n->renameType = OBJECT_VIEW;
9818 : : n->relation = $5;
9819 : : n->subname = NULL;
9820 : : n->newname = $8;
9821 : : n->missing_ok = true;
9822 : : $$ = (Node *) n;
9823 : : }
9824 : : | ALTER MATERIALIZED VIEW qualified_name RENAME TO name
9825 : : {
9826 : : RenameStmt *n = makeNode(RenameStmt);
9827 : :
9828 : : n->renameType = OBJECT_MATVIEW;
9829 : : n->relation = $4;
9830 : : n->subname = NULL;
9831 : : n->newname = $7;
9832 : : n->missing_ok = false;
9833 : : $$ = (Node *) n;
9834 : : }
9835 : : | ALTER MATERIALIZED VIEW IF_P EXISTS qualified_name RENAME TO name
9836 : : {
9837 : : RenameStmt *n = makeNode(RenameStmt);
9838 : :
9839 : : n->renameType = OBJECT_MATVIEW;
9840 : : n->relation = $6;
9841 : : n->subname = NULL;
9842 : : n->newname = $9;
9843 : : n->missing_ok = true;
9844 : : $$ = (Node *) n;
9845 : : }
9846 : : | ALTER INDEX qualified_name RENAME TO name
9847 : : {
9848 : : RenameStmt *n = makeNode(RenameStmt);
9849 : :
9850 : : n->renameType = OBJECT_INDEX;
9851 : : n->relation = $3;
9852 : : n->subname = NULL;
9853 : : n->newname = $6;
9854 : : n->missing_ok = false;
9855 : : $$ = (Node *) n;
9856 : : }
9857 : : | ALTER INDEX IF_P EXISTS qualified_name RENAME TO name
9858 : : {
9859 : : RenameStmt *n = makeNode(RenameStmt);
9860 : :
9861 : : n->renameType = OBJECT_INDEX;
9862 : : n->relation = $5;
9863 : : n->subname = NULL;
9864 : : n->newname = $8;
9865 : : n->missing_ok = true;
9866 : : $$ = (Node *) n;
9867 : : }
9868 : : | ALTER FOREIGN TABLE relation_expr RENAME TO name
9869 : : {
9870 : : RenameStmt *n = makeNode(RenameStmt);
9871 : :
9872 : : n->renameType = OBJECT_FOREIGN_TABLE;
9873 : : n->relation = $4;
9874 : : n->subname = NULL;
9875 : : n->newname = $7;
9876 : : n->missing_ok = false;
9877 : : $$ = (Node *) n;
9878 : : }
9879 : : | ALTER FOREIGN TABLE IF_P EXISTS relation_expr RENAME TO name
9880 : : {
9881 : : RenameStmt *n = makeNode(RenameStmt);
9882 : :
9883 : : n->renameType = OBJECT_FOREIGN_TABLE;
9884 : : n->relation = $6;
9885 : : n->subname = NULL;
9886 : : n->newname = $9;
9887 : : n->missing_ok = true;
9888 : : $$ = (Node *) n;
9889 : : }
9890 : : | ALTER TABLE relation_expr RENAME opt_column name TO name
9891 : : {
9892 : : RenameStmt *n = makeNode(RenameStmt);
9893 : :
9894 : : n->renameType = OBJECT_COLUMN;
9895 : : n->relationType = OBJECT_TABLE;
9896 : : n->relation = $3;
9897 : : n->subname = $6;
9898 : : n->newname = $8;
9899 : : n->missing_ok = false;
9900 : : $$ = (Node *) n;
9901 : : }
9902 : : | ALTER TABLE IF_P EXISTS relation_expr RENAME opt_column name TO name
9903 : : {
9904 : : RenameStmt *n = makeNode(RenameStmt);
9905 : :
9906 : : n->renameType = OBJECT_COLUMN;
9907 : : n->relationType = OBJECT_TABLE;
9908 : : n->relation = $5;
9909 : : n->subname = $8;
9910 : : n->newname = $10;
9911 : : n->missing_ok = true;
9912 : : $$ = (Node *) n;
9913 : : }
9914 : : | ALTER VIEW qualified_name RENAME opt_column name TO name
9915 : : {
9916 : : RenameStmt *n = makeNode(RenameStmt);
9917 : :
9918 : : n->renameType = OBJECT_COLUMN;
9919 : : n->relationType = OBJECT_VIEW;
9920 : : n->relation = $3;
9921 : : n->subname = $6;
9922 : : n->newname = $8;
9923 : : n->missing_ok = false;
9924 : : $$ = (Node *) n;
9925 : : }
9926 : : | ALTER VIEW IF_P EXISTS qualified_name RENAME opt_column name TO name
9927 : : {
9928 : : RenameStmt *n = makeNode(RenameStmt);
9929 : :
9930 : : n->renameType = OBJECT_COLUMN;
9931 : : n->relationType = OBJECT_VIEW;
9932 : : n->relation = $5;
9933 : : n->subname = $8;
9934 : : n->newname = $10;
9935 : : n->missing_ok = true;
9936 : : $$ = (Node *) n;
9937 : : }
9938 : : | ALTER MATERIALIZED VIEW qualified_name RENAME opt_column name TO name
9939 : : {
9940 : : RenameStmt *n = makeNode(RenameStmt);
9941 : :
9942 : : n->renameType = OBJECT_COLUMN;
9943 : : n->relationType = OBJECT_MATVIEW;
9944 : : n->relation = $4;
9945 : : n->subname = $7;
9946 : : n->newname = $9;
9947 : : n->missing_ok = false;
9948 : : $$ = (Node *) n;
9949 : : }
9950 : : | ALTER MATERIALIZED VIEW IF_P EXISTS qualified_name RENAME opt_column name TO name
9951 : : {
9952 : : RenameStmt *n = makeNode(RenameStmt);
9953 : :
9954 : : n->renameType = OBJECT_COLUMN;
9955 : : n->relationType = OBJECT_MATVIEW;
9956 : : n->relation = $6;
9957 : : n->subname = $9;
9958 : : n->newname = $11;
9959 : : n->missing_ok = true;
9960 : : $$ = (Node *) n;
9961 : : }
9962 : : | ALTER TABLE relation_expr RENAME CONSTRAINT name TO name
9963 : : {
9964 : : RenameStmt *n = makeNode(RenameStmt);
9965 : :
9966 : : n->renameType = OBJECT_TABCONSTRAINT;
9967 : : n->relation = $3;
9968 : : n->subname = $6;
9969 : : n->newname = $8;
9970 : : n->missing_ok = false;
9971 : : $$ = (Node *) n;
9972 : : }
9973 : : | ALTER TABLE IF_P EXISTS relation_expr RENAME CONSTRAINT name TO name
9974 : : {
9975 : : RenameStmt *n = makeNode(RenameStmt);
9976 : :
9977 : : n->renameType = OBJECT_TABCONSTRAINT;
9978 : : n->relation = $5;
9979 : : n->subname = $8;
9980 : : n->newname = $10;
9981 : : n->missing_ok = true;
9982 : : $$ = (Node *) n;
9983 : : }
9984 : : | ALTER FOREIGN TABLE relation_expr RENAME opt_column name TO name
9985 : : {
9986 : : RenameStmt *n = makeNode(RenameStmt);
9987 : :
9988 : : n->renameType = OBJECT_COLUMN;
9989 : : n->relationType = OBJECT_FOREIGN_TABLE;
9990 : : n->relation = $4;
9991 : : n->subname = $7;
9992 : : n->newname = $9;
9993 : : n->missing_ok = false;
9994 : : $$ = (Node *) n;
9995 : : }
9996 : : | ALTER FOREIGN TABLE IF_P EXISTS relation_expr RENAME opt_column name TO name
9997 : : {
9998 : : RenameStmt *n = makeNode(RenameStmt);
9999 : :
10000 : : n->renameType = OBJECT_COLUMN;
10001 : : n->relationType = OBJECT_FOREIGN_TABLE;
10002 : : n->relation = $6;
10003 : : n->subname = $9;
10004 : : n->newname = $11;
10005 : : n->missing_ok = true;
10006 : : $$ = (Node *) n;
10007 : : }
10008 : : | ALTER RULE name ON qualified_name RENAME TO name
10009 : : {
10010 : : RenameStmt *n = makeNode(RenameStmt);
10011 : :
10012 : : n->renameType = OBJECT_RULE;
10013 : : n->relation = $5;
10014 : : n->subname = $3;
10015 : : n->newname = $8;
10016 : : n->missing_ok = false;
10017 : : $$ = (Node *) n;
10018 : : }
10019 : : | ALTER TRIGGER name ON qualified_name RENAME TO name
10020 : : {
10021 : : RenameStmt *n = makeNode(RenameStmt);
10022 : :
10023 : : n->renameType = OBJECT_TRIGGER;
10024 : : n->relation = $5;
10025 : : n->subname = $3;
10026 : : n->newname = $8;
10027 : : n->missing_ok = false;
10028 : : $$ = (Node *) n;
10029 : : }
10030 : : | ALTER EVENT TRIGGER name RENAME TO name
10031 : : {
10032 : : RenameStmt *n = makeNode(RenameStmt);
10033 : :
10034 : : n->renameType = OBJECT_EVENT_TRIGGER;
10035 : : n->object = (Node *) makeString($4);
10036 : : n->newname = $7;
10037 : : $$ = (Node *) n;
10038 : : }
10039 : : | ALTER ROLE RoleId RENAME TO RoleId
10040 : : {
10041 : : RenameStmt *n = makeNode(RenameStmt);
10042 : :
10043 : : n->renameType = OBJECT_ROLE;
10044 : : n->subname = $3;
10045 : : n->newname = $6;
10046 : : n->missing_ok = false;
10047 : : $$ = (Node *) n;
10048 : : }
10049 : : | ALTER USER RoleId RENAME TO RoleId
10050 : : {
10051 : : RenameStmt *n = makeNode(RenameStmt);
10052 : :
10053 : : n->renameType = OBJECT_ROLE;
10054 : : n->subname = $3;
10055 : : n->newname = $6;
10056 : : n->missing_ok = false;
10057 : : $$ = (Node *) n;
10058 : : }
10059 : : | ALTER TABLESPACE name RENAME TO name
10060 : : {
10061 : : RenameStmt *n = makeNode(RenameStmt);
10062 : :
10063 : : n->renameType = OBJECT_TABLESPACE;
10064 : : n->subname = $3;
10065 : : n->newname = $6;
10066 : : n->missing_ok = false;
10067 : : $$ = (Node *) n;
10068 : : }
10069 : : | ALTER STATISTICS any_name RENAME TO name
10070 : : {
10071 : : RenameStmt *n = makeNode(RenameStmt);
10072 : :
10073 : : n->renameType = OBJECT_STATISTIC_EXT;
10074 : : n->object = (Node *) $3;
10075 : : n->newname = $6;
10076 : : n->missing_ok = false;
10077 : : $$ = (Node *) n;
10078 : : }
10079 : : | ALTER TEXT_P SEARCH PARSER any_name RENAME TO name
10080 : : {
10081 : : RenameStmt *n = makeNode(RenameStmt);
10082 : :
10083 : : n->renameType = OBJECT_TSPARSER;
10084 : : n->object = (Node *) $5;
10085 : : n->newname = $8;
10086 : : n->missing_ok = false;
10087 : : $$ = (Node *) n;
10088 : : }
10089 : : | ALTER TEXT_P SEARCH DICTIONARY any_name RENAME TO name
10090 : : {
10091 : : RenameStmt *n = makeNode(RenameStmt);
10092 : :
10093 : : n->renameType = OBJECT_TSDICTIONARY;
10094 : : n->object = (Node *) $5;
10095 : : n->newname = $8;
10096 : : n->missing_ok = false;
10097 : : $$ = (Node *) n;
10098 : : }
10099 : : | ALTER TEXT_P SEARCH TEMPLATE any_name RENAME TO name
10100 : : {
10101 : : RenameStmt *n = makeNode(RenameStmt);
10102 : :
10103 : : n->renameType = OBJECT_TSTEMPLATE;
10104 : : n->object = (Node *) $5;
10105 : : n->newname = $8;
10106 : : n->missing_ok = false;
10107 : : $$ = (Node *) n;
10108 : : }
10109 : : | ALTER TEXT_P SEARCH CONFIGURATION any_name RENAME TO name
10110 : : {
10111 : : RenameStmt *n = makeNode(RenameStmt);
10112 : :
10113 : : n->renameType = OBJECT_TSCONFIGURATION;
10114 : : n->object = (Node *) $5;
10115 : : n->newname = $8;
10116 : : n->missing_ok = false;
10117 : : $$ = (Node *) n;
10118 : : }
10119 : : | ALTER TYPE_P any_name RENAME TO name
10120 : : {
10121 : : RenameStmt *n = makeNode(RenameStmt);
10122 : :
10123 : : n->renameType = OBJECT_TYPE;
10124 : : n->object = (Node *) $3;
10125 : : n->newname = $6;
10126 : : n->missing_ok = false;
10127 : : $$ = (Node *) n;
10128 : : }
10129 : : | ALTER TYPE_P any_name RENAME ATTRIBUTE name TO name opt_drop_behavior
10130 : : {
10131 : : RenameStmt *n = makeNode(RenameStmt);
10132 : :
10133 : : n->renameType = OBJECT_ATTRIBUTE;
10134 : : n->relationType = OBJECT_TYPE;
10135 : : n->relation = makeRangeVarFromAnyName($3, @3, yyscanner);
10136 : : n->subname = $6;
10137 : : n->newname = $8;
10138 : : n->behavior = $9;
10139 : : n->missing_ok = false;
10140 : : $$ = (Node *) n;
10141 : : }
10142 : : ;
10143 : :
10144 : : opt_column: COLUMN
10145 : : | /*EMPTY*/
10146 : : ;
10147 : :
10148 : : opt_set_data: SET DATA_P { $$ = 1; }
10149 : : | /*EMPTY*/ { $$ = 0; }
10150 : : ;
10151 : :
10152 : : /*****************************************************************************
10153 : : *
10154 : : * ALTER THING name DEPENDS ON EXTENSION name
10155 : : *
10156 : : *****************************************************************************/
10157 : :
10158 : : AlterObjectDependsStmt:
10159 : : ALTER FUNCTION function_with_argtypes opt_no DEPENDS ON EXTENSION name
10160 : : {
10161 : : AlterObjectDependsStmt *n = makeNode(AlterObjectDependsStmt);
10162 : :
10163 : : n->objectType = OBJECT_FUNCTION;
10164 : : n->object = (Node *) $3;
10165 : : n->extname = makeString($8);
10166 : : n->remove = $4;
10167 : : $$ = (Node *) n;
10168 : : }
10169 : : | ALTER PROCEDURE function_with_argtypes opt_no DEPENDS ON EXTENSION name
10170 : : {
10171 : : AlterObjectDependsStmt *n = makeNode(AlterObjectDependsStmt);
10172 : :
10173 : : n->objectType = OBJECT_PROCEDURE;
10174 : : n->object = (Node *) $3;
10175 : : n->extname = makeString($8);
10176 : : n->remove = $4;
10177 : : $$ = (Node *) n;
10178 : : }
10179 : : | ALTER ROUTINE function_with_argtypes opt_no DEPENDS ON EXTENSION name
10180 : : {
10181 : : AlterObjectDependsStmt *n = makeNode(AlterObjectDependsStmt);
10182 : :
10183 : : n->objectType = OBJECT_ROUTINE;
10184 : : n->object = (Node *) $3;
10185 : : n->extname = makeString($8);
10186 : : n->remove = $4;
10187 : : $$ = (Node *) n;
10188 : : }
10189 : : | ALTER TRIGGER name ON qualified_name opt_no DEPENDS ON EXTENSION name
10190 : : {
10191 : : AlterObjectDependsStmt *n = makeNode(AlterObjectDependsStmt);
10192 : :
10193 : : n->objectType = OBJECT_TRIGGER;
10194 : : n->relation = $5;
10195 : : n->object = (Node *) list_make1(makeString($3));
10196 : : n->extname = makeString($10);
10197 : : n->remove = $6;
10198 : : $$ = (Node *) n;
10199 : : }
10200 : : | ALTER MATERIALIZED VIEW qualified_name opt_no DEPENDS ON EXTENSION name
10201 : : {
10202 : : AlterObjectDependsStmt *n = makeNode(AlterObjectDependsStmt);
10203 : :
10204 : : n->objectType = OBJECT_MATVIEW;
10205 : : n->relation = $4;
10206 : : n->extname = makeString($9);
10207 : : n->remove = $5;
10208 : : $$ = (Node *) n;
10209 : : }
10210 : : | ALTER INDEX qualified_name opt_no DEPENDS ON EXTENSION name
10211 : : {
10212 : : AlterObjectDependsStmt *n = makeNode(AlterObjectDependsStmt);
10213 : :
10214 : : n->objectType = OBJECT_INDEX;
10215 : : n->relation = $3;
10216 : : n->extname = makeString($8);
10217 : : n->remove = $4;
10218 : : $$ = (Node *) n;
10219 : : }
10220 : : ;
10221 : :
10222 : : opt_no: NO { $$ = true; }
10223 : : | /* EMPTY */ { $$ = false; }
10224 : : ;
10225 : :
10226 : : /*****************************************************************************
10227 : : *
10228 : : * ALTER THING name SET SCHEMA name
10229 : : *
10230 : : *****************************************************************************/
10231 : :
10232 : : AlterObjectSchemaStmt:
10233 : : ALTER AGGREGATE aggregate_with_argtypes SET SCHEMA name
10234 : : {
10235 : : AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt);
10236 : :
10237 : : n->objectType = OBJECT_AGGREGATE;
10238 : : n->object = (Node *) $3;
10239 : : n->newschema = $6;
10240 : : n->missing_ok = false;
10241 : : $$ = (Node *) n;
10242 : : }
10243 : : | ALTER COLLATION any_name SET SCHEMA name
10244 : : {
10245 : : AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt);
10246 : :
10247 : : n->objectType = OBJECT_COLLATION;
10248 : : n->object = (Node *) $3;
10249 : : n->newschema = $6;
10250 : : n->missing_ok = false;
10251 : : $$ = (Node *) n;
10252 : : }
10253 : : | ALTER CONVERSION_P any_name SET SCHEMA name
10254 : : {
10255 : : AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt);
10256 : :
10257 : : n->objectType = OBJECT_CONVERSION;
10258 : : n->object = (Node *) $3;
10259 : : n->newschema = $6;
10260 : : n->missing_ok = false;
10261 : : $$ = (Node *) n;
10262 : : }
10263 : : | ALTER DOMAIN_P any_name SET SCHEMA name
10264 : : {
10265 : : AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt);
10266 : :
10267 : : n->objectType = OBJECT_DOMAIN;
10268 : : n->object = (Node *) $3;
10269 : : n->newschema = $6;
10270 : : n->missing_ok = false;
10271 : : $$ = (Node *) n;
10272 : : }
10273 : : | ALTER EXTENSION name SET SCHEMA name
10274 : : {
10275 : : AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt);
10276 : :
10277 : : n->objectType = OBJECT_EXTENSION;
10278 : : n->object = (Node *) makeString($3);
10279 : : n->newschema = $6;
10280 : : n->missing_ok = false;
10281 : : $$ = (Node *) n;
10282 : : }
10283 : : | ALTER FUNCTION function_with_argtypes SET SCHEMA name
10284 : : {
10285 : : AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt);
10286 : :
10287 : : n->objectType = OBJECT_FUNCTION;
10288 : : n->object = (Node *) $3;
10289 : : n->newschema = $6;
10290 : : n->missing_ok = false;
10291 : : $$ = (Node *) n;
10292 : : }
10293 : : | ALTER OPERATOR operator_with_argtypes SET SCHEMA name
10294 : : {
10295 : : AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt);
10296 : :
10297 : : n->objectType = OBJECT_OPERATOR;
10298 : : n->object = (Node *) $3;
10299 : : n->newschema = $6;
10300 : : n->missing_ok = false;
10301 : : $$ = (Node *) n;
10302 : : }
10303 : : | ALTER OPERATOR CLASS any_name USING name SET SCHEMA name
10304 : : {
10305 : : AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt);
10306 : :
10307 : : n->objectType = OBJECT_OPCLASS;
10308 : : n->object = (Node *) lcons(makeString($6), $4);
10309 : : n->newschema = $9;
10310 : : n->missing_ok = false;
10311 : : $$ = (Node *) n;
10312 : : }
10313 : : | ALTER OPERATOR FAMILY any_name USING name SET SCHEMA name
10314 : : {
10315 : : AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt);
10316 : :
10317 : : n->objectType = OBJECT_OPFAMILY;
10318 : : n->object = (Node *) lcons(makeString($6), $4);
10319 : : n->newschema = $9;
10320 : : n->missing_ok = false;
10321 : : $$ = (Node *) n;
10322 : : }
10323 : : | ALTER PROCEDURE function_with_argtypes SET SCHEMA name
10324 : : {
10325 : : AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt);
10326 : :
10327 : : n->objectType = OBJECT_PROCEDURE;
10328 : : n->object = (Node *) $3;
10329 : : n->newschema = $6;
10330 : : n->missing_ok = false;
10331 : : $$ = (Node *) n;
10332 : : }
10333 : : | ALTER ROUTINE function_with_argtypes SET SCHEMA name
10334 : : {
10335 : : AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt);
10336 : :
10337 : : n->objectType = OBJECT_ROUTINE;
10338 : : n->object = (Node *) $3;
10339 : : n->newschema = $6;
10340 : : n->missing_ok = false;
10341 : : $$ = (Node *) n;
10342 : : }
10343 : : | ALTER TABLE relation_expr SET SCHEMA name
10344 : : {
10345 : : AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt);
10346 : :
10347 : : n->objectType = OBJECT_TABLE;
10348 : : n->relation = $3;
10349 : : n->newschema = $6;
10350 : : n->missing_ok = false;
10351 : : $$ = (Node *) n;
10352 : : }
10353 : : | ALTER TABLE IF_P EXISTS relation_expr SET SCHEMA name
10354 : : {
10355 : : AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt);
10356 : :
10357 : : n->objectType = OBJECT_TABLE;
10358 : : n->relation = $5;
10359 : : n->newschema = $8;
10360 : : n->missing_ok = true;
10361 : : $$ = (Node *) n;
10362 : : }
10363 : : | ALTER STATISTICS any_name SET SCHEMA name
10364 : : {
10365 : : AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt);
10366 : :
10367 : : n->objectType = OBJECT_STATISTIC_EXT;
10368 : : n->object = (Node *) $3;
10369 : : n->newschema = $6;
10370 : : n->missing_ok = false;
10371 : : $$ = (Node *) n;
10372 : : }
10373 : : | ALTER TEXT_P SEARCH PARSER any_name SET SCHEMA name
10374 : : {
10375 : : AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt);
10376 : :
10377 : : n->objectType = OBJECT_TSPARSER;
10378 : : n->object = (Node *) $5;
10379 : : n->newschema = $8;
10380 : : n->missing_ok = false;
10381 : : $$ = (Node *) n;
10382 : : }
10383 : : | ALTER TEXT_P SEARCH DICTIONARY any_name SET SCHEMA name
10384 : : {
10385 : : AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt);
10386 : :
10387 : : n->objectType = OBJECT_TSDICTIONARY;
10388 : : n->object = (Node *) $5;
10389 : : n->newschema = $8;
10390 : : n->missing_ok = false;
10391 : : $$ = (Node *) n;
10392 : : }
10393 : : | ALTER TEXT_P SEARCH TEMPLATE any_name SET SCHEMA name
10394 : : {
10395 : : AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt);
10396 : :
10397 : : n->objectType = OBJECT_TSTEMPLATE;
10398 : : n->object = (Node *) $5;
10399 : : n->newschema = $8;
10400 : : n->missing_ok = false;
10401 : : $$ = (Node *) n;
10402 : : }
10403 : : | ALTER TEXT_P SEARCH CONFIGURATION any_name SET SCHEMA name
10404 : : {
10405 : : AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt);
10406 : :
10407 : : n->objectType = OBJECT_TSCONFIGURATION;
10408 : : n->object = (Node *) $5;
10409 : : n->newschema = $8;
10410 : : n->missing_ok = false;
10411 : : $$ = (Node *) n;
10412 : : }
10413 : : | ALTER SEQUENCE qualified_name SET SCHEMA name
10414 : : {
10415 : : AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt);
10416 : :
10417 : : n->objectType = OBJECT_SEQUENCE;
10418 : : n->relation = $3;
10419 : : n->newschema = $6;
10420 : : n->missing_ok = false;
10421 : : $$ = (Node *) n;
10422 : : }
10423 : : | ALTER SEQUENCE IF_P EXISTS qualified_name SET SCHEMA name
10424 : : {
10425 : : AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt);
10426 : :
10427 : : n->objectType = OBJECT_SEQUENCE;
10428 : : n->relation = $5;
10429 : : n->newschema = $8;
10430 : : n->missing_ok = true;
10431 : : $$ = (Node *) n;
10432 : : }
10433 : : | ALTER VIEW qualified_name SET SCHEMA name
10434 : : {
10435 : : AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt);
10436 : :
10437 : : n->objectType = OBJECT_VIEW;
10438 : : n->relation = $3;
10439 : : n->newschema = $6;
10440 : : n->missing_ok = false;
10441 : : $$ = (Node *) n;
10442 : : }
10443 : : | ALTER VIEW IF_P EXISTS qualified_name SET SCHEMA name
10444 : : {
10445 : : AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt);
10446 : :
10447 : : n->objectType = OBJECT_VIEW;
10448 : : n->relation = $5;
10449 : : n->newschema = $8;
10450 : : n->missing_ok = true;
10451 : : $$ = (Node *) n;
10452 : : }
10453 : : | ALTER MATERIALIZED VIEW qualified_name SET SCHEMA name
10454 : : {
10455 : : AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt);
10456 : :
10457 : : n->objectType = OBJECT_MATVIEW;
10458 : : n->relation = $4;
10459 : : n->newschema = $7;
10460 : : n->missing_ok = false;
10461 : : $$ = (Node *) n;
10462 : : }
10463 : : | ALTER MATERIALIZED VIEW IF_P EXISTS qualified_name SET SCHEMA name
10464 : : {
10465 : : AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt);
10466 : :
10467 : : n->objectType = OBJECT_MATVIEW;
10468 : : n->relation = $6;
10469 : : n->newschema = $9;
10470 : : n->missing_ok = true;
10471 : : $$ = (Node *) n;
10472 : : }
10473 : : | ALTER FOREIGN TABLE relation_expr SET SCHEMA name
10474 : : {
10475 : : AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt);
10476 : :
10477 : : n->objectType = OBJECT_FOREIGN_TABLE;
10478 : : n->relation = $4;
10479 : : n->newschema = $7;
10480 : : n->missing_ok = false;
10481 : : $$ = (Node *) n;
10482 : : }
10483 : : | ALTER FOREIGN TABLE IF_P EXISTS relation_expr SET SCHEMA name
10484 : : {
10485 : : AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt);
10486 : :
10487 : : n->objectType = OBJECT_FOREIGN_TABLE;
10488 : : n->relation = $6;
10489 : : n->newschema = $9;
10490 : : n->missing_ok = true;
10491 : : $$ = (Node *) n;
10492 : : }
10493 : : | ALTER TYPE_P any_name SET SCHEMA name
10494 : : {
10495 : : AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt);
10496 : :
10497 : : n->objectType = OBJECT_TYPE;
10498 : : n->object = (Node *) $3;
10499 : : n->newschema = $6;
10500 : : n->missing_ok = false;
10501 : : $$ = (Node *) n;
10502 : : }
10503 : : ;
10504 : :
10505 : : /*****************************************************************************
10506 : : *
10507 : : * ALTER OPERATOR name SET define
10508 : : *
10509 : : *****************************************************************************/
10510 : :
10511 : : AlterOperatorStmt:
10512 : : ALTER OPERATOR operator_with_argtypes SET '(' operator_def_list ')'
10513 : : {
10514 : : AlterOperatorStmt *n = makeNode(AlterOperatorStmt);
10515 : :
10516 : : n->opername = $3;
10517 : : n->options = $6;
10518 : : $$ = (Node *) n;
10519 : : }
10520 : : ;
10521 : :
10522 : : operator_def_list: operator_def_elem { $$ = list_make1($1); }
10523 : : | operator_def_list ',' operator_def_elem { $$ = lappend($1, $3); }
10524 : : ;
10525 : :
10526 : : operator_def_elem: ColLabel '=' NONE
10527 : : { $$ = makeDefElem($1, NULL, @1); }
10528 : : | ColLabel '=' operator_def_arg
10529 : : { $$ = makeDefElem($1, (Node *) $3, @1); }
10530 : : | ColLabel
10531 : : { $$ = makeDefElem($1, NULL, @1); }
10532 : : ;
10533 : :
10534 : : /* must be similar enough to def_arg to avoid reduce/reduce conflicts */
10535 : : operator_def_arg:
10536 : : func_type { $$ = (Node *) $1; }
10537 : : | reserved_keyword { $$ = (Node *) makeString(pstrdup($1)); }
10538 : : | qual_all_Op { $$ = (Node *) $1; }
10539 : : | NumericOnly { $$ = (Node *) $1; }
10540 : : | Sconst { $$ = (Node *) makeString($1); }
10541 : : ;
10542 : :
10543 : : /*****************************************************************************
10544 : : *
10545 : : * ALTER TYPE name SET define
10546 : : *
10547 : : * We repurpose ALTER OPERATOR's version of "definition" here
10548 : : *
10549 : : *****************************************************************************/
10550 : :
10551 : : AlterTypeStmt:
10552 : : ALTER TYPE_P any_name SET '(' operator_def_list ')'
10553 : : {
10554 : : AlterTypeStmt *n = makeNode(AlterTypeStmt);
10555 : :
10556 : : n->typeName = $3;
10557 : : n->options = $6;
10558 : : $$ = (Node *) n;
10559 : : }
10560 : : ;
10561 : :
10562 : : /*****************************************************************************
10563 : : *
10564 : : * ALTER THING name OWNER TO newname
10565 : : *
10566 : : *****************************************************************************/
10567 : :
10568 : : AlterOwnerStmt: ALTER AGGREGATE aggregate_with_argtypes OWNER TO RoleSpec
10569 : : {
10570 : : AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
10571 : :
10572 : : n->objectType = OBJECT_AGGREGATE;
10573 : : n->object = (Node *) $3;
10574 : : n->newowner = $6;
10575 : : $$ = (Node *) n;
10576 : : }
10577 : : | ALTER COLLATION any_name OWNER TO RoleSpec
10578 : : {
10579 : : AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
10580 : :
10581 : : n->objectType = OBJECT_COLLATION;
10582 : : n->object = (Node *) $3;
10583 : : n->newowner = $6;
10584 : : $$ = (Node *) n;
10585 : : }
10586 : : | ALTER CONVERSION_P any_name OWNER TO RoleSpec
10587 : : {
10588 : : AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
10589 : :
10590 : : n->objectType = OBJECT_CONVERSION;
10591 : : n->object = (Node *) $3;
10592 : : n->newowner = $6;
10593 : : $$ = (Node *) n;
10594 : : }
10595 : : | ALTER DATABASE name OWNER TO RoleSpec
10596 : : {
10597 : : AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
10598 : :
10599 : : n->objectType = OBJECT_DATABASE;
10600 : : n->object = (Node *) makeString($3);
10601 : : n->newowner = $6;
10602 : : $$ = (Node *) n;
10603 : : }
10604 : : | ALTER DOMAIN_P any_name OWNER TO RoleSpec
10605 : : {
10606 : : AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
10607 : :
10608 : : n->objectType = OBJECT_DOMAIN;
10609 : : n->object = (Node *) $3;
10610 : : n->newowner = $6;
10611 : : $$ = (Node *) n;
10612 : : }
10613 : : | ALTER FUNCTION function_with_argtypes OWNER TO RoleSpec
10614 : : {
10615 : : AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
10616 : :
10617 : : n->objectType = OBJECT_FUNCTION;
10618 : : n->object = (Node *) $3;
10619 : : n->newowner = $6;
10620 : : $$ = (Node *) n;
10621 : : }
10622 : : | ALTER opt_procedural LANGUAGE name OWNER TO RoleSpec
10623 : : {
10624 : : AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
10625 : :
10626 : : n->objectType = OBJECT_LANGUAGE;
10627 : : n->object = (Node *) makeString($4);
10628 : : n->newowner = $7;
10629 : : $$ = (Node *) n;
10630 : : }
10631 : : | ALTER LARGE_P OBJECT_P NumericOnly OWNER TO RoleSpec
10632 : : {
10633 : : AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
10634 : :
10635 : : n->objectType = OBJECT_LARGEOBJECT;
10636 : : n->object = (Node *) $4;
10637 : : n->newowner = $7;
10638 : : $$ = (Node *) n;
10639 : : }
10640 : : | ALTER OPERATOR operator_with_argtypes OWNER TO RoleSpec
10641 : : {
10642 : : AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
10643 : :
10644 : : n->objectType = OBJECT_OPERATOR;
10645 : : n->object = (Node *) $3;
10646 : : n->newowner = $6;
10647 : : $$ = (Node *) n;
10648 : : }
10649 : : | ALTER OPERATOR CLASS any_name USING name OWNER TO RoleSpec
10650 : : {
10651 : : AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
10652 : :
10653 : : n->objectType = OBJECT_OPCLASS;
10654 : : n->object = (Node *) lcons(makeString($6), $4);
10655 : : n->newowner = $9;
10656 : : $$ = (Node *) n;
10657 : : }
10658 : : | ALTER OPERATOR FAMILY any_name USING name OWNER TO RoleSpec
10659 : : {
10660 : : AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
10661 : :
10662 : : n->objectType = OBJECT_OPFAMILY;
10663 : : n->object = (Node *) lcons(makeString($6), $4);
10664 : : n->newowner = $9;
10665 : : $$ = (Node *) n;
10666 : : }
10667 : : | ALTER PROCEDURE function_with_argtypes OWNER TO RoleSpec
10668 : : {
10669 : : AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
10670 : :
10671 : : n->objectType = OBJECT_PROCEDURE;
10672 : : n->object = (Node *) $3;
10673 : : n->newowner = $6;
10674 : : $$ = (Node *) n;
10675 : : }
10676 : : | ALTER ROUTINE function_with_argtypes OWNER TO RoleSpec
10677 : : {
10678 : : AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
10679 : :
10680 : : n->objectType = OBJECT_ROUTINE;
10681 : : n->object = (Node *) $3;
10682 : : n->newowner = $6;
10683 : : $$ = (Node *) n;
10684 : : }
10685 : : | ALTER SCHEMA name OWNER TO RoleSpec
10686 : : {
10687 : : AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
10688 : :
10689 : : n->objectType = OBJECT_SCHEMA;
10690 : : n->object = (Node *) makeString($3);
10691 : : n->newowner = $6;
10692 : : $$ = (Node *) n;
10693 : : }
10694 : : | ALTER TYPE_P any_name OWNER TO RoleSpec
10695 : : {
10696 : : AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
10697 : :
10698 : : n->objectType = OBJECT_TYPE;
10699 : : n->object = (Node *) $3;
10700 : : n->newowner = $6;
10701 : : $$ = (Node *) n;
10702 : : }
10703 : : | ALTER TABLESPACE name OWNER TO RoleSpec
10704 : : {
10705 : : AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
10706 : :
10707 : : n->objectType = OBJECT_TABLESPACE;
10708 : : n->object = (Node *) makeString($3);
10709 : : n->newowner = $6;
10710 : : $$ = (Node *) n;
10711 : : }
10712 : : | ALTER STATISTICS any_name OWNER TO RoleSpec
10713 : : {
10714 : : AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
10715 : :
10716 : : n->objectType = OBJECT_STATISTIC_EXT;
10717 : : n->object = (Node *) $3;
10718 : : n->newowner = $6;
10719 : : $$ = (Node *) n;
10720 : : }
10721 : : | ALTER TEXT_P SEARCH DICTIONARY any_name OWNER TO RoleSpec
10722 : : {
10723 : : AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
10724 : :
10725 : : n->objectType = OBJECT_TSDICTIONARY;
10726 : : n->object = (Node *) $5;
10727 : : n->newowner = $8;
10728 : : $$ = (Node *) n;
10729 : : }
10730 : : | ALTER TEXT_P SEARCH CONFIGURATION any_name OWNER TO RoleSpec
10731 : : {
10732 : : AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
10733 : :
10734 : : n->objectType = OBJECT_TSCONFIGURATION;
10735 : : n->object = (Node *) $5;
10736 : : n->newowner = $8;
10737 : : $$ = (Node *) n;
10738 : : }
10739 : : | ALTER FOREIGN DATA_P WRAPPER name OWNER TO RoleSpec
10740 : : {
10741 : : AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
10742 : :
10743 : : n->objectType = OBJECT_FDW;
10744 : : n->object = (Node *) makeString($5);
10745 : : n->newowner = $8;
10746 : : $$ = (Node *) n;
10747 : : }
10748 : : | ALTER SERVER name OWNER TO RoleSpec
10749 : : {
10750 : : AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
10751 : :
10752 : : n->objectType = OBJECT_FOREIGN_SERVER;
10753 : : n->object = (Node *) makeString($3);
10754 : : n->newowner = $6;
10755 : : $$ = (Node *) n;
10756 : : }
10757 : : | ALTER EVENT TRIGGER name OWNER TO RoleSpec
10758 : : {
10759 : : AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
10760 : :
10761 : : n->objectType = OBJECT_EVENT_TRIGGER;
10762 : : n->object = (Node *) makeString($4);
10763 : : n->newowner = $7;
10764 : : $$ = (Node *) n;
10765 : : }
10766 : : | ALTER PUBLICATION name OWNER TO RoleSpec
10767 : : {
10768 : : AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
10769 : :
10770 : : n->objectType = OBJECT_PUBLICATION;
10771 : : n->object = (Node *) makeString($3);
10772 : : n->newowner = $6;
10773 : : $$ = (Node *) n;
10774 : : }
10775 : : | ALTER SUBSCRIPTION name OWNER TO RoleSpec
10776 : : {
10777 : : AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
10778 : :
10779 : : n->objectType = OBJECT_SUBSCRIPTION;
10780 : : n->object = (Node *) makeString($3);
10781 : : n->newowner = $6;
10782 : : $$ = (Node *) n;
10783 : : }
10784 : : ;
10785 : :
10786 : :
10787 : : /*****************************************************************************
10788 : : *
10789 : : * CREATE PUBLICATION name [WITH options]
10790 : : *
10791 : : * CREATE PUBLICATION FOR ALL pub_all_obj_type [, ...] [WITH options]
10792 : : *
10793 : : * pub_all_obj_type is one of:
10794 : : *
10795 : : * TABLES
10796 : : * SEQUENCES
10797 : : *
10798 : : * CREATE PUBLICATION FOR pub_obj [, ...] [WITH options]
10799 : : *
10800 : : * pub_obj is one of:
10801 : : *
10802 : : * TABLE table [, ...]
10803 : : * TABLES IN SCHEMA schema [, ...]
10804 : : *
10805 : : *****************************************************************************/
10806 : :
10807 : : CreatePublicationStmt:
10808 : : CREATE PUBLICATION name opt_definition
10809 : : {
10810 : : CreatePublicationStmt *n = makeNode(CreatePublicationStmt);
10811 : :
10812 : : n->pubname = $3;
10813 : : n->options = $4;
10814 : : $$ = (Node *) n;
10815 : : }
10816 : : | CREATE PUBLICATION name FOR pub_all_obj_type_list opt_definition
10817 : : {
10818 : : CreatePublicationStmt *n = makeNode(CreatePublicationStmt);
10819 : :
10820 : : n->pubname = $3;
10821 : : preprocess_pub_all_objtype_list($5, &n->for_all_tables,
10822 : : &n->for_all_sequences,
10823 : : yyscanner);
10824 : : n->options = $6;
10825 : : $$ = (Node *) n;
10826 : : }
10827 : : | CREATE PUBLICATION name FOR pub_obj_list opt_definition
10828 : : {
10829 : : CreatePublicationStmt *n = makeNode(CreatePublicationStmt);
10830 : :
10831 : : n->pubname = $3;
10832 : : n->options = $6;
10833 : : n->pubobjects = (List *) $5;
10834 : : preprocess_pubobj_list(n->pubobjects, yyscanner);
10835 : : $$ = (Node *) n;
10836 : : }
10837 : : ;
10838 : :
10839 : : /*
10840 : : * FOR TABLE and FOR TABLES IN SCHEMA specifications
10841 : : *
10842 : : * This rule parses publication objects with and without keyword prefixes.
10843 : : *
10844 : : * The actual type of the object without keyword prefix depends on the previous
10845 : : * one with keyword prefix. It will be preprocessed in preprocess_pubobj_list().
10846 : : *
10847 : : * For the object without keyword prefix, we cannot just use relation_expr here,
10848 : : * because some extended expressions in relation_expr cannot be used as a
10849 : : * schemaname and we cannot differentiate it. So, we extract the rules from
10850 : : * relation_expr here.
10851 : : */
10852 : : PublicationObjSpec:
10853 : : TABLE relation_expr opt_column_list OptWhereClause
10854 : : {
10855 : : $$ = makeNode(PublicationObjSpec);
10856 : : $$->pubobjtype = PUBLICATIONOBJ_TABLE;
10857 : : $$->pubtable = makeNode(PublicationTable);
10858 : : $$->pubtable->relation = $2;
10859 : : $$->pubtable->columns = $3;
10860 : : $$->pubtable->whereClause = $4;
10861 : : }
10862 : : | TABLES IN_P SCHEMA ColId
10863 : : {
10864 : : $$ = makeNode(PublicationObjSpec);
10865 : : $$->pubobjtype = PUBLICATIONOBJ_TABLES_IN_SCHEMA;
10866 : : $$->name = $4;
10867 : : $$->location = @4;
10868 : : }
10869 : : | TABLES IN_P SCHEMA CURRENT_SCHEMA
10870 : : {
10871 : : $$ = makeNode(PublicationObjSpec);
10872 : : $$->pubobjtype = PUBLICATIONOBJ_TABLES_IN_CUR_SCHEMA;
10873 : : $$->location = @4;
10874 : : }
10875 : : | ColId opt_column_list OptWhereClause
10876 : : {
10877 : : $$ = makeNode(PublicationObjSpec);
10878 : : $$->pubobjtype = PUBLICATIONOBJ_CONTINUATION;
10879 : : /*
10880 : : * If either a row filter or column list is specified, create
10881 : : * a PublicationTable object.
10882 : : */
10883 : : if ($2 || $3)
10884 : : {
10885 : : /*
10886 : : * The OptWhereClause must be stored here but it is
10887 : : * valid only for tables. For non-table objects, an
10888 : : * error will be thrown later via
10889 : : * preprocess_pubobj_list().
10890 : : */
10891 : : $$->pubtable = makeNode(PublicationTable);
10892 : : $$->pubtable->relation = makeRangeVar(NULL, $1, @1);
10893 : : $$->pubtable->columns = $2;
10894 : : $$->pubtable->whereClause = $3;
10895 : : }
10896 : : else
10897 : : {
10898 : : $$->name = $1;
10899 : : }
10900 : : $$->location = @1;
10901 : : }
10902 : : | ColId indirection opt_column_list OptWhereClause
10903 : : {
10904 : : $$ = makeNode(PublicationObjSpec);
10905 : : $$->pubobjtype = PUBLICATIONOBJ_CONTINUATION;
10906 : : $$->pubtable = makeNode(PublicationTable);
10907 : : $$->pubtable->relation = makeRangeVarFromQualifiedName($1, $2, @1, yyscanner);
10908 : : $$->pubtable->columns = $3;
10909 : : $$->pubtable->whereClause = $4;
10910 : : $$->location = @1;
10911 : : }
10912 : : /* grammar like tablename * , ONLY tablename, ONLY ( tablename ) */
10913 : : | extended_relation_expr opt_column_list OptWhereClause
10914 : : {
10915 : : $$ = makeNode(PublicationObjSpec);
10916 : : $$->pubobjtype = PUBLICATIONOBJ_CONTINUATION;
10917 : : $$->pubtable = makeNode(PublicationTable);
10918 : : $$->pubtable->relation = $1;
10919 : : $$->pubtable->columns = $2;
10920 : : $$->pubtable->whereClause = $3;
10921 : : }
10922 : : | CURRENT_SCHEMA
10923 : : {
10924 : : $$ = makeNode(PublicationObjSpec);
10925 : : $$->pubobjtype = PUBLICATIONOBJ_CONTINUATION;
10926 : : $$->location = @1;
10927 : : }
10928 : : ;
10929 : :
10930 : : pub_obj_list: PublicationObjSpec
10931 : : { $$ = list_make1($1); }
10932 : : | pub_obj_list ',' PublicationObjSpec
10933 : : { $$ = lappend($1, $3); }
10934 : : ;
10935 : :
10936 : : PublicationAllObjSpec:
10937 : : ALL TABLES
10938 : : {
10939 : : $$ = makeNode(PublicationAllObjSpec);
10940 : : $$->pubobjtype = PUBLICATION_ALL_TABLES;
10941 : : $$->location = @1;
10942 : : }
10943 : : | ALL SEQUENCES
10944 : : {
10945 : : $$ = makeNode(PublicationAllObjSpec);
10946 : : $$->pubobjtype = PUBLICATION_ALL_SEQUENCES;
10947 : : $$->location = @1;
10948 : : }
10949 : : ;
10950 : :
10951 : : pub_all_obj_type_list: PublicationAllObjSpec
10952 : : { $$ = list_make1($1); }
10953 : : | pub_all_obj_type_list ',' PublicationAllObjSpec
10954 : : { $$ = lappend($1, $3); }
10955 : : ;
10956 : :
10957 : :
10958 : : /*****************************************************************************
10959 : : *
10960 : : * ALTER PUBLICATION name SET ( options )
10961 : : *
10962 : : * ALTER PUBLICATION name ADD pub_obj [, ...]
10963 : : *
10964 : : * ALTER PUBLICATION name DROP pub_obj [, ...]
10965 : : *
10966 : : * ALTER PUBLICATION name SET pub_obj [, ...]
10967 : : *
10968 : : * pub_obj is one of:
10969 : : *
10970 : : * TABLE table_name [, ...]
10971 : : * TABLES IN SCHEMA schema_name [, ...]
10972 : : *
10973 : : *****************************************************************************/
10974 : :
10975 : : AlterPublicationStmt:
10976 : : ALTER PUBLICATION name SET definition
10977 : : {
10978 : : AlterPublicationStmt *n = makeNode(AlterPublicationStmt);
10979 : :
10980 : : n->pubname = $3;
10981 : : n->options = $5;
10982 : : $$ = (Node *) n;
10983 : : }
10984 : : | ALTER PUBLICATION name ADD_P pub_obj_list
10985 : : {
10986 : : AlterPublicationStmt *n = makeNode(AlterPublicationStmt);
10987 : :
10988 : : n->pubname = $3;
10989 : : n->pubobjects = $5;
10990 : : preprocess_pubobj_list(n->pubobjects, yyscanner);
10991 : : n->action = AP_AddObjects;
10992 : : $$ = (Node *) n;
10993 : : }
10994 : : | ALTER PUBLICATION name SET pub_obj_list
10995 : : {
10996 : : AlterPublicationStmt *n = makeNode(AlterPublicationStmt);
10997 : :
10998 : : n->pubname = $3;
10999 : : n->pubobjects = $5;
11000 : : preprocess_pubobj_list(n->pubobjects, yyscanner);
11001 : : n->action = AP_SetObjects;
11002 : : $$ = (Node *) n;
11003 : : }
11004 : : | ALTER PUBLICATION name DROP pub_obj_list
11005 : : {
11006 : : AlterPublicationStmt *n = makeNode(AlterPublicationStmt);
11007 : :
11008 : : n->pubname = $3;
11009 : : n->pubobjects = $5;
11010 : : preprocess_pubobj_list(n->pubobjects, yyscanner);
11011 : : n->action = AP_DropObjects;
11012 : : $$ = (Node *) n;
11013 : : }
11014 : : ;
11015 : :
11016 : : /*****************************************************************************
11017 : : *
11018 : : * CREATE SUBSCRIPTION name ...
11019 : : *
11020 : : *****************************************************************************/
11021 : :
11022 : : CreateSubscriptionStmt:
11023 : : CREATE SUBSCRIPTION name CONNECTION Sconst PUBLICATION name_list opt_definition
11024 : : {
11025 : : CreateSubscriptionStmt *n =
11026 : : makeNode(CreateSubscriptionStmt);
11027 : : n->subname = $3;
11028 : : n->conninfo = $5;
11029 : : n->publication = $7;
11030 : : n->options = $8;
11031 : : $$ = (Node *) n;
11032 : : }
11033 : : ;
11034 : :
11035 : : /*****************************************************************************
11036 : : *
11037 : : * ALTER SUBSCRIPTION name ...
11038 : : *
11039 : : *****************************************************************************/
11040 : :
11041 : : AlterSubscriptionStmt:
11042 : : ALTER SUBSCRIPTION name SET definition
11043 : : {
11044 : : AlterSubscriptionStmt *n =
11045 : : makeNode(AlterSubscriptionStmt);
11046 : :
11047 : : n->kind = ALTER_SUBSCRIPTION_OPTIONS;
11048 : : n->subname = $3;
11049 : : n->options = $5;
11050 : : $$ = (Node *) n;
11051 : : }
11052 : : | ALTER SUBSCRIPTION name CONNECTION Sconst
11053 : : {
11054 : : AlterSubscriptionStmt *n =
11055 : : makeNode(AlterSubscriptionStmt);
11056 : :
11057 : : n->kind = ALTER_SUBSCRIPTION_CONNECTION;
11058 : : n->subname = $3;
11059 : : n->conninfo = $5;
11060 : : $$ = (Node *) n;
11061 : : }
11062 : : | ALTER SUBSCRIPTION name REFRESH PUBLICATION opt_definition
11063 : : {
11064 : : AlterSubscriptionStmt *n =
11065 : : makeNode(AlterSubscriptionStmt);
11066 : :
11067 : : n->kind = ALTER_SUBSCRIPTION_REFRESH_PUBLICATION;
11068 : : n->subname = $3;
11069 : : n->options = $6;
11070 : : $$ = (Node *) n;
11071 : : }
11072 : : | ALTER SUBSCRIPTION name REFRESH SEQUENCES
11073 : : {
11074 : : AlterSubscriptionStmt *n =
11075 : : makeNode(AlterSubscriptionStmt);
11076 : :
11077 : : n->kind = ALTER_SUBSCRIPTION_REFRESH_SEQUENCES;
11078 : : n->subname = $3;
11079 : : $$ = (Node *) n;
11080 : : }
11081 : : | ALTER SUBSCRIPTION name ADD_P PUBLICATION name_list opt_definition
11082 : : {
11083 : : AlterSubscriptionStmt *n =
11084 : : makeNode(AlterSubscriptionStmt);
11085 : :
11086 : : n->kind = ALTER_SUBSCRIPTION_ADD_PUBLICATION;
11087 : : n->subname = $3;
11088 : : n->publication = $6;
11089 : : n->options = $7;
11090 : : $$ = (Node *) n;
11091 : : }
11092 : : | ALTER SUBSCRIPTION name DROP PUBLICATION name_list opt_definition
11093 : : {
11094 : : AlterSubscriptionStmt *n =
11095 : : makeNode(AlterSubscriptionStmt);
11096 : :
11097 : : n->kind = ALTER_SUBSCRIPTION_DROP_PUBLICATION;
11098 : : n->subname = $3;
11099 : : n->publication = $6;
11100 : : n->options = $7;
11101 : : $$ = (Node *) n;
11102 : : }
11103 : : | ALTER SUBSCRIPTION name SET PUBLICATION name_list opt_definition
11104 : : {
11105 : : AlterSubscriptionStmt *n =
11106 : : makeNode(AlterSubscriptionStmt);
11107 : :
11108 : : n->kind = ALTER_SUBSCRIPTION_SET_PUBLICATION;
11109 : : n->subname = $3;
11110 : : n->publication = $6;
11111 : : n->options = $7;
11112 : : $$ = (Node *) n;
11113 : : }
11114 : : | ALTER SUBSCRIPTION name ENABLE_P
11115 : : {
11116 : : AlterSubscriptionStmt *n =
11117 : : makeNode(AlterSubscriptionStmt);
11118 : :
11119 : : n->kind = ALTER_SUBSCRIPTION_ENABLED;
11120 : : n->subname = $3;
11121 : : n->options = list_make1(makeDefElem("enabled",
11122 : : (Node *) makeBoolean(true), @1));
11123 : : $$ = (Node *) n;
11124 : : }
11125 : : | ALTER SUBSCRIPTION name DISABLE_P
11126 : : {
11127 : : AlterSubscriptionStmt *n =
11128 : : makeNode(AlterSubscriptionStmt);
11129 : :
11130 : : n->kind = ALTER_SUBSCRIPTION_ENABLED;
11131 : : n->subname = $3;
11132 : : n->options = list_make1(makeDefElem("enabled",
11133 : : (Node *) makeBoolean(false), @1));
11134 : : $$ = (Node *) n;
11135 : : }
11136 : : | ALTER SUBSCRIPTION name SKIP definition
11137 : : {
11138 : : AlterSubscriptionStmt *n =
11139 : : makeNode(AlterSubscriptionStmt);
11140 : :
11141 : : n->kind = ALTER_SUBSCRIPTION_SKIP;
11142 : : n->subname = $3;
11143 : : n->options = $5;
11144 : : $$ = (Node *) n;
11145 : : }
11146 : : ;
11147 : :
11148 : : /*****************************************************************************
11149 : : *
11150 : : * DROP SUBSCRIPTION [ IF EXISTS ] name
11151 : : *
11152 : : *****************************************************************************/
11153 : :
11154 : : DropSubscriptionStmt: DROP SUBSCRIPTION name opt_drop_behavior
11155 : : {
11156 : : DropSubscriptionStmt *n = makeNode(DropSubscriptionStmt);
11157 : :
11158 : : n->subname = $3;
11159 : : n->missing_ok = false;
11160 : : n->behavior = $4;
11161 : : $$ = (Node *) n;
11162 : : }
11163 : : | DROP SUBSCRIPTION IF_P EXISTS name opt_drop_behavior
11164 : : {
11165 : : DropSubscriptionStmt *n = makeNode(DropSubscriptionStmt);
11166 : :
11167 : : n->subname = $5;
11168 : : n->missing_ok = true;
11169 : : n->behavior = $6;
11170 : : $$ = (Node *) n;
11171 : : }
11172 : : ;
11173 : :
11174 : : /*****************************************************************************
11175 : : *
11176 : : * QUERY: Define Rewrite Rule
11177 : : *
11178 : : *****************************************************************************/
11179 : :
11180 : : RuleStmt: CREATE opt_or_replace RULE name AS
11181 : : ON event TO qualified_name where_clause
11182 : : DO opt_instead RuleActionList
11183 : : {
11184 : : RuleStmt *n = makeNode(RuleStmt);
11185 : :
11186 : : n->replace = $2;
11187 : : n->relation = $9;
11188 : : n->rulename = $4;
11189 : : n->whereClause = $10;
11190 : : n->event = $7;
11191 : : n->instead = $12;
11192 : : n->actions = $13;
11193 : : $$ = (Node *) n;
11194 : : }
11195 : : ;
11196 : :
11197 : : RuleActionList:
11198 : : NOTHING { $$ = NIL; }
11199 : : | RuleActionStmt { $$ = list_make1($1); }
11200 : : | '(' RuleActionMulti ')' { $$ = $2; }
11201 : : ;
11202 : :
11203 : : /* the thrashing around here is to discard "empty" statements... */
11204 : : RuleActionMulti:
11205 : : RuleActionMulti ';' RuleActionStmtOrEmpty
11206 : : { if ($3 != NULL)
11207 : : $$ = lappend($1, $3);
11208 : : else
11209 : : $$ = $1;
11210 : : }
11211 : : | RuleActionStmtOrEmpty
11212 : : { if ($1 != NULL)
11213 : : $$ = list_make1($1);
11214 : : else
11215 : : $$ = NIL;
11216 : : }
11217 : : ;
11218 : :
11219 : : RuleActionStmt:
11220 : : SelectStmt
11221 : : | InsertStmt
11222 : : | UpdateStmt
11223 : : | DeleteStmt
11224 : : | NotifyStmt
11225 : : ;
11226 : :
11227 : : RuleActionStmtOrEmpty:
11228 : : RuleActionStmt { $$ = $1; }
11229 : : | /*EMPTY*/ { $$ = NULL; }
11230 : : ;
11231 : :
11232 : : event: SELECT { $$ = CMD_SELECT; }
11233 : : | UPDATE { $$ = CMD_UPDATE; }
11234 : : | DELETE_P { $$ = CMD_DELETE; }
11235 : : | INSERT { $$ = CMD_INSERT; }
11236 : : ;
11237 : :
11238 : : opt_instead:
11239 : : INSTEAD { $$ = true; }
11240 : : | ALSO { $$ = false; }
11241 : : | /*EMPTY*/ { $$ = false; }
11242 : : ;
11243 : :
11244 : :
11245 : : /*****************************************************************************
11246 : : *
11247 : : * QUERY:
11248 : : * NOTIFY <identifier> can appear both in rule bodies and
11249 : : * as a query-level command
11250 : : *
11251 : : *****************************************************************************/
11252 : :
11253 : : NotifyStmt: NOTIFY ColId notify_payload
11254 : : {
11255 : : NotifyStmt *n = makeNode(NotifyStmt);
11256 : :
11257 : : n->conditionname = $2;
11258 : : n->payload = $3;
11259 : : $$ = (Node *) n;
11260 : : }
11261 : : ;
11262 : :
11263 : : notify_payload:
11264 : : ',' Sconst { $$ = $2; }
11265 : : | /*EMPTY*/ { $$ = NULL; }
11266 : : ;
11267 : :
11268 : : ListenStmt: LISTEN ColId
11269 : : {
11270 : : ListenStmt *n = makeNode(ListenStmt);
11271 : :
11272 : : n->conditionname = $2;
11273 : : $$ = (Node *) n;
11274 : : }
11275 : : ;
11276 : :
11277 : : UnlistenStmt:
11278 : : UNLISTEN ColId
11279 : : {
11280 : : UnlistenStmt *n = makeNode(UnlistenStmt);
11281 : :
11282 : : n->conditionname = $2;
11283 : : $$ = (Node *) n;
11284 : : }
11285 : : | UNLISTEN '*'
11286 : : {
11287 : : UnlistenStmt *n = makeNode(UnlistenStmt);
11288 : :
11289 : : n->conditionname = NULL;
11290 : : $$ = (Node *) n;
11291 : : }
11292 : : ;
11293 : :
11294 : :
11295 : : /*****************************************************************************
11296 : : *
11297 : : * Transactions:
11298 : : *
11299 : : * BEGIN / COMMIT / ROLLBACK
11300 : : * (also older versions END / ABORT)
11301 : : *
11302 : : *****************************************************************************/
11303 : :
11304 : : TransactionStmt:
11305 : : ABORT_P opt_transaction opt_transaction_chain
11306 : : {
11307 : : TransactionStmt *n = makeNode(TransactionStmt);
11308 : :
11309 : : n->kind = TRANS_STMT_ROLLBACK;
11310 : : n->options = NIL;
11311 : : n->chain = $3;
11312 : : n->location = -1;
11313 : : $$ = (Node *) n;
11314 : : }
11315 : : | START TRANSACTION transaction_mode_list_or_empty
11316 : : {
11317 : : TransactionStmt *n = makeNode(TransactionStmt);
11318 : :
11319 : : n->kind = TRANS_STMT_START;
11320 : : n->options = $3;
11321 : : n->location = -1;
11322 : : $$ = (Node *) n;
11323 : : }
11324 : : | COMMIT opt_transaction opt_transaction_chain
11325 : : {
11326 : : TransactionStmt *n = makeNode(TransactionStmt);
11327 : :
11328 : : n->kind = TRANS_STMT_COMMIT;
11329 : : n->options = NIL;
11330 : : n->chain = $3;
11331 : : n->location = -1;
11332 : : $$ = (Node *) n;
11333 : : }
11334 : : | ROLLBACK opt_transaction opt_transaction_chain
11335 : : {
11336 : : TransactionStmt *n = makeNode(TransactionStmt);
11337 : :
11338 : : n->kind = TRANS_STMT_ROLLBACK;
11339 : : n->options = NIL;
11340 : : n->chain = $3;
11341 : : n->location = -1;
11342 : : $$ = (Node *) n;
11343 : : }
11344 : : | SAVEPOINT ColId
11345 : : {
11346 : : TransactionStmt *n = makeNode(TransactionStmt);
11347 : :
11348 : : n->kind = TRANS_STMT_SAVEPOINT;
11349 : : n->savepoint_name = $2;
11350 : : n->location = @2;
11351 : : $$ = (Node *) n;
11352 : : }
11353 : : | RELEASE SAVEPOINT ColId
11354 : : {
11355 : : TransactionStmt *n = makeNode(TransactionStmt);
11356 : :
11357 : : n->kind = TRANS_STMT_RELEASE;
11358 : : n->savepoint_name = $3;
11359 : : n->location = @3;
11360 : : $$ = (Node *) n;
11361 : : }
11362 : : | RELEASE ColId
11363 : : {
11364 : : TransactionStmt *n = makeNode(TransactionStmt);
11365 : :
11366 : : n->kind = TRANS_STMT_RELEASE;
11367 : : n->savepoint_name = $2;
11368 : : n->location = @2;
11369 : : $$ = (Node *) n;
11370 : : }
11371 : : | ROLLBACK opt_transaction TO SAVEPOINT ColId
11372 : : {
11373 : : TransactionStmt *n = makeNode(TransactionStmt);
11374 : :
11375 : : n->kind = TRANS_STMT_ROLLBACK_TO;
11376 : : n->savepoint_name = $5;
11377 : : n->location = @5;
11378 : : $$ = (Node *) n;
11379 : : }
11380 : : | ROLLBACK opt_transaction TO ColId
11381 : : {
11382 : : TransactionStmt *n = makeNode(TransactionStmt);
11383 : :
11384 : : n->kind = TRANS_STMT_ROLLBACK_TO;
11385 : : n->savepoint_name = $4;
11386 : : n->location = @4;
11387 : : $$ = (Node *) n;
11388 : : }
11389 : : | PREPARE TRANSACTION Sconst
11390 : : {
11391 : : TransactionStmt *n = makeNode(TransactionStmt);
11392 : :
11393 : : n->kind = TRANS_STMT_PREPARE;
11394 : : n->gid = $3;
11395 : : n->location = @3;
11396 : : $$ = (Node *) n;
11397 : : }
11398 : : | COMMIT PREPARED Sconst
11399 : : {
11400 : : TransactionStmt *n = makeNode(TransactionStmt);
11401 : :
11402 : : n->kind = TRANS_STMT_COMMIT_PREPARED;
11403 : : n->gid = $3;
11404 : : n->location = @3;
11405 : : $$ = (Node *) n;
11406 : : }
11407 : : | ROLLBACK PREPARED Sconst
11408 : : {
11409 : : TransactionStmt *n = makeNode(TransactionStmt);
11410 : :
11411 : : n->kind = TRANS_STMT_ROLLBACK_PREPARED;
11412 : : n->gid = $3;
11413 : : n->location = @3;
11414 : : $$ = (Node *) n;
11415 : : }
11416 : : ;
11417 : :
11418 : : TransactionStmtLegacy:
11419 : : BEGIN_P opt_transaction transaction_mode_list_or_empty
11420 : : {
11421 : : TransactionStmt *n = makeNode(TransactionStmt);
11422 : :
11423 : : n->kind = TRANS_STMT_BEGIN;
11424 : : n->options = $3;
11425 : : n->location = -1;
11426 : : $$ = (Node *) n;
11427 : : }
11428 : : | END_P opt_transaction opt_transaction_chain
11429 : : {
11430 : : TransactionStmt *n = makeNode(TransactionStmt);
11431 : :
11432 : : n->kind = TRANS_STMT_COMMIT;
11433 : : n->options = NIL;
11434 : : n->chain = $3;
11435 : : n->location = -1;
11436 : : $$ = (Node *) n;
11437 : : }
11438 : : ;
11439 : :
11440 : : opt_transaction: WORK
11441 : : | TRANSACTION
11442 : : | /*EMPTY*/
11443 : : ;
11444 : :
11445 : : transaction_mode_item:
11446 : : ISOLATION LEVEL iso_level
11447 : : { $$ = makeDefElem("transaction_isolation",
11448 : : makeStringConst($3, @3), @1); }
11449 : : | READ ONLY
11450 : : { $$ = makeDefElem("transaction_read_only",
11451 : : makeIntConst(true, @1), @1); }
11452 : : | READ WRITE
11453 : : { $$ = makeDefElem("transaction_read_only",
11454 : : makeIntConst(false, @1), @1); }
11455 : : | DEFERRABLE
11456 : : { $$ = makeDefElem("transaction_deferrable",
11457 : : makeIntConst(true, @1), @1); }
11458 : : | NOT DEFERRABLE
11459 : : { $$ = makeDefElem("transaction_deferrable",
11460 : : makeIntConst(false, @1), @1); }
11461 : : ;
11462 : :
11463 : : /* Syntax with commas is SQL-spec, without commas is Postgres historical */
11464 : : transaction_mode_list:
11465 : : transaction_mode_item
11466 : : { $$ = list_make1($1); }
11467 : : | transaction_mode_list ',' transaction_mode_item
11468 : : { $$ = lappend($1, $3); }
11469 : : | transaction_mode_list transaction_mode_item
11470 : : { $$ = lappend($1, $2); }
11471 : : ;
11472 : :
11473 : : transaction_mode_list_or_empty:
11474 : : transaction_mode_list
11475 : : | /* EMPTY */
11476 : : { $$ = NIL; }
11477 : : ;
11478 : :
11479 : : opt_transaction_chain:
11480 : : AND CHAIN { $$ = true; }
11481 : : | AND NO CHAIN { $$ = false; }
11482 : : | /* EMPTY */ { $$ = false; }
11483 : : ;
11484 : :
11485 : :
11486 : : /*****************************************************************************
11487 : : *
11488 : : * QUERY:
11489 : : * CREATE [ OR REPLACE ] [ TEMP ] VIEW <viewname> '('target-list ')'
11490 : : * AS <query> [ WITH [ CASCADED | LOCAL ] CHECK OPTION ]
11491 : : *
11492 : : *****************************************************************************/
11493 : :
11494 : : ViewStmt: CREATE OptTemp VIEW qualified_name opt_column_list opt_reloptions
11495 : : AS SelectStmt opt_check_option
11496 : : {
11497 : : ViewStmt *n = makeNode(ViewStmt);
11498 : :
11499 : : n->view = $4;
11500 : : n->view->relpersistence = $2;
11501 : : n->aliases = $5;
11502 : : n->query = $8;
11503 : : n->replace = false;
11504 : : n->options = $6;
11505 : : n->withCheckOption = $9;
11506 : : $$ = (Node *) n;
11507 : : }
11508 : : | CREATE OR REPLACE OptTemp VIEW qualified_name opt_column_list opt_reloptions
11509 : : AS SelectStmt opt_check_option
11510 : : {
11511 : : ViewStmt *n = makeNode(ViewStmt);
11512 : :
11513 : : n->view = $6;
11514 : : n->view->relpersistence = $4;
11515 : : n->aliases = $7;
11516 : : n->query = $10;
11517 : : n->replace = true;
11518 : : n->options = $8;
11519 : : n->withCheckOption = $11;
11520 : : $$ = (Node *) n;
11521 : : }
11522 : : | CREATE OptTemp RECURSIVE VIEW qualified_name '(' columnList ')' opt_reloptions
11523 : : AS SelectStmt opt_check_option
11524 : : {
11525 : : ViewStmt *n = makeNode(ViewStmt);
11526 : :
11527 : : n->view = $5;
11528 : : n->view->relpersistence = $2;
11529 : : n->aliases = $7;
11530 : : n->query = makeRecursiveViewSelect(n->view->relname, n->aliases, $11);
11531 : : n->replace = false;
11532 : : n->options = $9;
11533 : : n->withCheckOption = $12;
11534 : : if (n->withCheckOption != NO_CHECK_OPTION)
11535 : : ereport(ERROR,
11536 : : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
11537 : : errmsg("WITH CHECK OPTION not supported on recursive views"),
11538 : : parser_errposition(@12)));
11539 : : $$ = (Node *) n;
11540 : : }
11541 : : | CREATE OR REPLACE OptTemp RECURSIVE VIEW qualified_name '(' columnList ')' opt_reloptions
11542 : : AS SelectStmt opt_check_option
11543 : : {
11544 : : ViewStmt *n = makeNode(ViewStmt);
11545 : :
11546 : : n->view = $7;
11547 : : n->view->relpersistence = $4;
11548 : : n->aliases = $9;
11549 : : n->query = makeRecursiveViewSelect(n->view->relname, n->aliases, $13);
11550 : : n->replace = true;
11551 : : n->options = $11;
11552 : : n->withCheckOption = $14;
11553 : : if (n->withCheckOption != NO_CHECK_OPTION)
11554 : : ereport(ERROR,
11555 : : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
11556 : : errmsg("WITH CHECK OPTION not supported on recursive views"),
11557 : : parser_errposition(@14)));
11558 : : $$ = (Node *) n;
11559 : : }
11560 : : ;
11561 : :
11562 : : opt_check_option:
11563 : : WITH CHECK OPTION { $$ = CASCADED_CHECK_OPTION; }
11564 : : | WITH CASCADED CHECK OPTION { $$ = CASCADED_CHECK_OPTION; }
11565 : : | WITH LOCAL CHECK OPTION { $$ = LOCAL_CHECK_OPTION; }
11566 : : | /* EMPTY */ { $$ = NO_CHECK_OPTION; }
11567 : : ;
11568 : :
11569 : : /*****************************************************************************
11570 : : *
11571 : : * QUERY:
11572 : : * LOAD "filename"
11573 : : *
11574 : : *****************************************************************************/
11575 : :
11576 : : LoadStmt: LOAD file_name
11577 : : {
11578 : : LoadStmt *n = makeNode(LoadStmt);
11579 : :
11580 : : n->filename = $2;
11581 : : $$ = (Node *) n;
11582 : : }
11583 : : ;
11584 : :
11585 : :
11586 : : /*****************************************************************************
11587 : : *
11588 : : * CREATE DATABASE
11589 : : *
11590 : : *****************************************************************************/
11591 : :
11592 : : CreatedbStmt:
11593 : : CREATE DATABASE name opt_with createdb_opt_list
11594 : : {
11595 : : CreatedbStmt *n = makeNode(CreatedbStmt);
11596 : :
11597 : : n->dbname = $3;
11598 : : n->options = $5;
11599 : : $$ = (Node *) n;
11600 : : }
11601 : : ;
11602 : :
11603 : : createdb_opt_list:
11604 : : createdb_opt_items { $$ = $1; }
11605 : : | /* EMPTY */ { $$ = NIL; }
11606 : : ;
11607 : :
11608 : : createdb_opt_items:
11609 : : createdb_opt_item { $$ = list_make1($1); }
11610 : : | createdb_opt_items createdb_opt_item { $$ = lappend($1, $2); }
11611 : : ;
11612 : :
11613 : : createdb_opt_item:
11614 : : createdb_opt_name opt_equal NumericOnly
11615 : : {
11616 : : $$ = makeDefElem($1, $3, @1);
11617 : : }
11618 : : | createdb_opt_name opt_equal opt_boolean_or_string
11619 : : {
11620 : : $$ = makeDefElem($1, (Node *) makeString($3), @1);
11621 : : }
11622 : : | createdb_opt_name opt_equal DEFAULT
11623 : : {
11624 : : $$ = makeDefElem($1, NULL, @1);
11625 : : }
11626 : : ;
11627 : :
11628 : : /*
11629 : : * Ideally we'd use ColId here, but that causes shift/reduce conflicts against
11630 : : * the ALTER DATABASE SET/RESET syntaxes. Instead call out specific keywords
11631 : : * we need, and allow IDENT so that database option names don't have to be
11632 : : * parser keywords unless they are already keywords for other reasons.
11633 : : *
11634 : : * XXX this coding technique is fragile since if someone makes a formerly
11635 : : * non-keyword option name into a keyword and forgets to add it here, the
11636 : : * option will silently break. Best defense is to provide a regression test
11637 : : * exercising every such option, at least at the syntax level.
11638 : : */
11639 : : createdb_opt_name:
11640 : : IDENT { $$ = $1; }
11641 : : | CONNECTION LIMIT { $$ = pstrdup("connection_limit"); }
11642 : : | ENCODING { $$ = pstrdup($1); }
11643 : : | LOCATION { $$ = pstrdup($1); }
11644 : : | OWNER { $$ = pstrdup($1); }
11645 : : | TABLESPACE { $$ = pstrdup($1); }
11646 : : | TEMPLATE { $$ = pstrdup($1); }
11647 : : ;
11648 : :
11649 : : /*
11650 : : * Though the equals sign doesn't match other WITH options, pg_dump uses
11651 : : * equals for backward compatibility, and it doesn't seem worth removing it.
11652 : : */
11653 : : opt_equal: '='
11654 : : | /*EMPTY*/
11655 : : ;
11656 : :
11657 : :
11658 : : /*****************************************************************************
11659 : : *
11660 : : * ALTER DATABASE
11661 : : *
11662 : : *****************************************************************************/
11663 : :
11664 : : AlterDatabaseStmt:
11665 : : ALTER DATABASE name WITH createdb_opt_list
11666 : : {
11667 : : AlterDatabaseStmt *n = makeNode(AlterDatabaseStmt);
11668 : :
11669 : : n->dbname = $3;
11670 : : n->options = $5;
11671 : : $$ = (Node *) n;
11672 : : }
11673 : : | ALTER DATABASE name createdb_opt_list
11674 : : {
11675 : : AlterDatabaseStmt *n = makeNode(AlterDatabaseStmt);
11676 : :
11677 : : n->dbname = $3;
11678 : : n->options = $4;
11679 : : $$ = (Node *) n;
11680 : : }
11681 : : | ALTER DATABASE name SET TABLESPACE name
11682 : : {
11683 : : AlterDatabaseStmt *n = makeNode(AlterDatabaseStmt);
11684 : :
11685 : : n->dbname = $3;
11686 : : n->options = list_make1(makeDefElem("tablespace",
11687 : : (Node *) makeString($6), @6));
11688 : : $$ = (Node *) n;
11689 : : }
11690 : : | ALTER DATABASE name REFRESH COLLATION VERSION_P
11691 : : {
11692 : : AlterDatabaseRefreshCollStmt *n = makeNode(AlterDatabaseRefreshCollStmt);
11693 : :
11694 : : n->dbname = $3;
11695 : : $$ = (Node *) n;
11696 : : }
11697 : : ;
11698 : :
11699 : : AlterDatabaseSetStmt:
11700 : : ALTER DATABASE name SetResetClause
11701 : : {
11702 : : AlterDatabaseSetStmt *n = makeNode(AlterDatabaseSetStmt);
11703 : :
11704 : : n->dbname = $3;
11705 : : n->setstmt = $4;
11706 : : $$ = (Node *) n;
11707 : : }
11708 : : ;
11709 : :
11710 : :
11711 : : /*****************************************************************************
11712 : : *
11713 : : * DROP DATABASE [ IF EXISTS ] dbname [ [ WITH ] ( options ) ]
11714 : : *
11715 : : * This is implicitly CASCADE, no need for drop behavior
11716 : : *****************************************************************************/
11717 : :
11718 : : DropdbStmt: DROP DATABASE name
11719 : : {
11720 : : DropdbStmt *n = makeNode(DropdbStmt);
11721 : :
11722 : : n->dbname = $3;
11723 : : n->missing_ok = false;
11724 : : n->options = NULL;
11725 : : $$ = (Node *) n;
11726 : : }
11727 : : | DROP DATABASE IF_P EXISTS name
11728 : : {
11729 : : DropdbStmt *n = makeNode(DropdbStmt);
11730 : :
11731 : : n->dbname = $5;
11732 : : n->missing_ok = true;
11733 : : n->options = NULL;
11734 : : $$ = (Node *) n;
11735 : : }
11736 : : | DROP DATABASE name opt_with '(' drop_option_list ')'
11737 : : {
11738 : : DropdbStmt *n = makeNode(DropdbStmt);
11739 : :
11740 : : n->dbname = $3;
11741 : : n->missing_ok = false;
11742 : : n->options = $6;
11743 : : $$ = (Node *) n;
11744 : : }
11745 : : | DROP DATABASE IF_P EXISTS name opt_with '(' drop_option_list ')'
11746 : : {
11747 : : DropdbStmt *n = makeNode(DropdbStmt);
11748 : :
11749 : : n->dbname = $5;
11750 : : n->missing_ok = true;
11751 : : n->options = $8;
11752 : : $$ = (Node *) n;
11753 : : }
11754 : : ;
11755 : :
11756 : : drop_option_list:
11757 : : drop_option
11758 : : {
11759 : : $$ = list_make1((Node *) $1);
11760 : : }
11761 : : | drop_option_list ',' drop_option
11762 : : {
11763 : : $$ = lappend($1, (Node *) $3);
11764 : : }
11765 : : ;
11766 : :
11767 : : /*
11768 : : * Currently only the FORCE option is supported, but the syntax is designed
11769 : : * to be extensible so that we can add more options in the future if required.
11770 : : */
11771 : : drop_option:
11772 : : FORCE
11773 : : {
11774 : : $$ = makeDefElem("force", NULL, @1);
11775 : : }
11776 : : ;
11777 : :
11778 : : /*****************************************************************************
11779 : : *
11780 : : * ALTER COLLATION
11781 : : *
11782 : : *****************************************************************************/
11783 : :
11784 : : AlterCollationStmt: ALTER COLLATION any_name REFRESH VERSION_P
11785 : : {
11786 : : AlterCollationStmt *n = makeNode(AlterCollationStmt);
11787 : :
11788 : : n->collname = $3;
11789 : : $$ = (Node *) n;
11790 : : }
11791 : : ;
11792 : :
11793 : :
11794 : : /*****************************************************************************
11795 : : *
11796 : : * ALTER SYSTEM
11797 : : *
11798 : : * This is used to change configuration parameters persistently.
11799 : : *****************************************************************************/
11800 : :
11801 : : AlterSystemStmt:
11802 : : ALTER SYSTEM_P SET generic_set
11803 : : {
11804 : : AlterSystemStmt *n = makeNode(AlterSystemStmt);
11805 : :
11806 : : n->setstmt = $4;
11807 : : $$ = (Node *) n;
11808 : : }
11809 : : | ALTER SYSTEM_P RESET generic_reset
11810 : : {
11811 : : AlterSystemStmt *n = makeNode(AlterSystemStmt);
11812 : :
11813 : : n->setstmt = $4;
11814 : : $$ = (Node *) n;
11815 : : }
11816 : : ;
11817 : :
11818 : :
11819 : : /*****************************************************************************
11820 : : *
11821 : : * Manipulate a domain
11822 : : *
11823 : : *****************************************************************************/
11824 : :
11825 : : CreateDomainStmt:
11826 : : CREATE DOMAIN_P any_name opt_as Typename ColQualList
11827 : : {
11828 : : CreateDomainStmt *n = makeNode(CreateDomainStmt);
11829 : :
11830 : : n->domainname = $3;
11831 : : n->typeName = $5;
11832 : : SplitColQualList($6, &n->constraints, &n->collClause,
11833 : : yyscanner);
11834 : : $$ = (Node *) n;
11835 : : }
11836 : : ;
11837 : :
11838 : : AlterDomainStmt:
11839 : : /* ALTER DOMAIN <domain> {SET DEFAULT <expr>|DROP DEFAULT} */
11840 : : ALTER DOMAIN_P any_name alter_column_default
11841 : : {
11842 : : AlterDomainStmt *n = makeNode(AlterDomainStmt);
11843 : :
11844 : : n->subtype = AD_AlterDefault;
11845 : : n->typeName = $3;
11846 : : n->def = $4;
11847 : : $$ = (Node *) n;
11848 : : }
11849 : : /* ALTER DOMAIN <domain> DROP NOT NULL */
11850 : : | ALTER DOMAIN_P any_name DROP NOT NULL_P
11851 : : {
11852 : : AlterDomainStmt *n = makeNode(AlterDomainStmt);
11853 : :
11854 : : n->subtype = AD_DropNotNull;
11855 : : n->typeName = $3;
11856 : : $$ = (Node *) n;
11857 : : }
11858 : : /* ALTER DOMAIN <domain> SET NOT NULL */
11859 : : | ALTER DOMAIN_P any_name SET NOT NULL_P
11860 : : {
11861 : : AlterDomainStmt *n = makeNode(AlterDomainStmt);
11862 : :
11863 : : n->subtype = AD_SetNotNull;
11864 : : n->typeName = $3;
11865 : : $$ = (Node *) n;
11866 : : }
11867 : : /* ALTER DOMAIN <domain> ADD CONSTRAINT ... */
11868 : : | ALTER DOMAIN_P any_name ADD_P DomainConstraint
11869 : : {
11870 : : AlterDomainStmt *n = makeNode(AlterDomainStmt);
11871 : :
11872 : : n->subtype = AD_AddConstraint;
11873 : : n->typeName = $3;
11874 : : n->def = $5;
11875 : : $$ = (Node *) n;
11876 : : }
11877 : : /* ALTER DOMAIN <domain> DROP CONSTRAINT <name> [RESTRICT|CASCADE] */
11878 : : | ALTER DOMAIN_P any_name DROP CONSTRAINT name opt_drop_behavior
11879 : : {
11880 : : AlterDomainStmt *n = makeNode(AlterDomainStmt);
11881 : :
11882 : : n->subtype = AD_DropConstraint;
11883 : : n->typeName = $3;
11884 : : n->name = $6;
11885 : : n->behavior = $7;
11886 : : n->missing_ok = false;
11887 : : $$ = (Node *) n;
11888 : : }
11889 : : /* ALTER DOMAIN <domain> DROP CONSTRAINT IF EXISTS <name> [RESTRICT|CASCADE] */
11890 : : | ALTER DOMAIN_P any_name DROP CONSTRAINT IF_P EXISTS name opt_drop_behavior
11891 : : {
11892 : : AlterDomainStmt *n = makeNode(AlterDomainStmt);
11893 : :
11894 : : n->subtype = AD_DropConstraint;
11895 : : n->typeName = $3;
11896 : : n->name = $8;
11897 : : n->behavior = $9;
11898 : : n->missing_ok = true;
11899 : : $$ = (Node *) n;
11900 : : }
11901 : : /* ALTER DOMAIN <domain> VALIDATE CONSTRAINT <name> */
11902 : : | ALTER DOMAIN_P any_name VALIDATE CONSTRAINT name
11903 : : {
11904 : : AlterDomainStmt *n = makeNode(AlterDomainStmt);
11905 : :
11906 : : n->subtype = AD_ValidateConstraint;
11907 : : n->typeName = $3;
11908 : : n->name = $6;
11909 : : $$ = (Node *) n;
11910 : : }
11911 : : ;
11912 : :
11913 : : opt_as: AS
11914 : : | /* EMPTY */
11915 : : ;
11916 : :
11917 : :
11918 : : /*****************************************************************************
11919 : : *
11920 : : * Manipulate a text search dictionary or configuration
11921 : : *
11922 : : *****************************************************************************/
11923 : :
11924 : : AlterTSDictionaryStmt:
11925 : : ALTER TEXT_P SEARCH DICTIONARY any_name definition
11926 : : {
11927 : : AlterTSDictionaryStmt *n = makeNode(AlterTSDictionaryStmt);
11928 : :
11929 : : n->dictname = $5;
11930 : : n->options = $6;
11931 : : $$ = (Node *) n;
11932 : : }
11933 : : ;
11934 : :
11935 : : AlterTSConfigurationStmt:
11936 : : ALTER TEXT_P SEARCH CONFIGURATION any_name ADD_P MAPPING FOR name_list any_with any_name_list
11937 : : {
11938 : : AlterTSConfigurationStmt *n = makeNode(AlterTSConfigurationStmt);
11939 : :
11940 : : n->kind = ALTER_TSCONFIG_ADD_MAPPING;
11941 : : n->cfgname = $5;
11942 : : n->tokentype = $9;
11943 : : n->dicts = $11;
11944 : : n->override = false;
11945 : : n->replace = false;
11946 : : $$ = (Node *) n;
11947 : : }
11948 : : | ALTER TEXT_P SEARCH CONFIGURATION any_name ALTER MAPPING FOR name_list any_with any_name_list
11949 : : {
11950 : : AlterTSConfigurationStmt *n = makeNode(AlterTSConfigurationStmt);
11951 : :
11952 : : n->kind = ALTER_TSCONFIG_ALTER_MAPPING_FOR_TOKEN;
11953 : : n->cfgname = $5;
11954 : : n->tokentype = $9;
11955 : : n->dicts = $11;
11956 : : n->override = true;
11957 : : n->replace = false;
11958 : : $$ = (Node *) n;
11959 : : }
11960 : : | ALTER TEXT_P SEARCH CONFIGURATION any_name ALTER MAPPING REPLACE any_name any_with any_name
11961 : : {
11962 : : AlterTSConfigurationStmt *n = makeNode(AlterTSConfigurationStmt);
11963 : :
11964 : : n->kind = ALTER_TSCONFIG_REPLACE_DICT;
11965 : : n->cfgname = $5;
11966 : : n->tokentype = NIL;
11967 : : n->dicts = list_make2($9,$11);
11968 : : n->override = false;
11969 : : n->replace = true;
11970 : : $$ = (Node *) n;
11971 : : }
11972 : : | ALTER TEXT_P SEARCH CONFIGURATION any_name ALTER MAPPING FOR name_list REPLACE any_name any_with any_name
11973 : : {
11974 : : AlterTSConfigurationStmt *n = makeNode(AlterTSConfigurationStmt);
11975 : :
11976 : : n->kind = ALTER_TSCONFIG_REPLACE_DICT_FOR_TOKEN;
11977 : : n->cfgname = $5;
11978 : : n->tokentype = $9;
11979 : : n->dicts = list_make2($11,$13);
11980 : : n->override = false;
11981 : : n->replace = true;
11982 : : $$ = (Node *) n;
11983 : : }
11984 : : | ALTER TEXT_P SEARCH CONFIGURATION any_name DROP MAPPING FOR name_list
11985 : : {
11986 : : AlterTSConfigurationStmt *n = makeNode(AlterTSConfigurationStmt);
11987 : :
11988 : : n->kind = ALTER_TSCONFIG_DROP_MAPPING;
11989 : : n->cfgname = $5;
11990 : : n->tokentype = $9;
11991 : : n->missing_ok = false;
11992 : : $$ = (Node *) n;
11993 : : }
11994 : : | ALTER TEXT_P SEARCH CONFIGURATION any_name DROP MAPPING IF_P EXISTS FOR name_list
11995 : : {
11996 : : AlterTSConfigurationStmt *n = makeNode(AlterTSConfigurationStmt);
11997 : :
11998 : : n->kind = ALTER_TSCONFIG_DROP_MAPPING;
11999 : : n->cfgname = $5;
12000 : : n->tokentype = $11;
12001 : : n->missing_ok = true;
12002 : : $$ = (Node *) n;
12003 : : }
12004 : : ;
12005 : :
12006 : : /* Use this if TIME or ORDINALITY after WITH should be taken as an identifier */
12007 : : any_with: WITH
12008 : : | WITH_LA
12009 : : ;
12010 : :
12011 : :
12012 : : /*****************************************************************************
12013 : : *
12014 : : * Manipulate a conversion
12015 : : *
12016 : : * CREATE [DEFAULT] CONVERSION <conversion_name>
12017 : : * FOR <encoding_name> TO <encoding_name> FROM <func_name>
12018 : : *
12019 : : *****************************************************************************/
12020 : :
12021 : : CreateConversionStmt:
12022 : : CREATE opt_default CONVERSION_P any_name FOR Sconst
12023 : : TO Sconst FROM any_name
12024 : : {
12025 : : CreateConversionStmt *n = makeNode(CreateConversionStmt);
12026 : :
12027 : : n->conversion_name = $4;
12028 : : n->for_encoding_name = $6;
12029 : : n->to_encoding_name = $8;
12030 : : n->func_name = $10;
12031 : : n->def = $2;
12032 : : $$ = (Node *) n;
12033 : : }
12034 : : ;
12035 : :
12036 : : /*****************************************************************************
12037 : : *
12038 : : * QUERY:
12039 : : * CLUSTER (options) [ <qualified_name> [ USING <index_name> ] ]
12040 : : * CLUSTER [VERBOSE] [ <qualified_name> [ USING <index_name> ] ]
12041 : : * CLUSTER [VERBOSE] <index_name> ON <qualified_name> (for pre-8.3)
12042 : : *
12043 : : *****************************************************************************/
12044 : :
12045 : : ClusterStmt:
12046 : : CLUSTER '(' utility_option_list ')' qualified_name cluster_index_specification
12047 : : {
12048 : : ClusterStmt *n = makeNode(ClusterStmt);
12049 : :
12050 : : n->relation = $5;
12051 : : n->indexname = $6;
12052 : : n->params = $3;
12053 : : $$ = (Node *) n;
12054 : : }
12055 : : | CLUSTER opt_utility_option_list
12056 : : {
12057 : : ClusterStmt *n = makeNode(ClusterStmt);
12058 : :
12059 : : n->relation = NULL;
12060 : : n->indexname = NULL;
12061 : : n->params = $2;
12062 : : $$ = (Node *) n;
12063 : : }
12064 : : /* unparenthesized VERBOSE kept for pre-14 compatibility */
12065 : : | CLUSTER opt_verbose qualified_name cluster_index_specification
12066 : : {
12067 : : ClusterStmt *n = makeNode(ClusterStmt);
12068 : :
12069 : : n->relation = $3;
12070 : : n->indexname = $4;
12071 : : if ($2)
12072 : : n->params = list_make1(makeDefElem("verbose", NULL, @2));
12073 : : $$ = (Node *) n;
12074 : : }
12075 : : /* unparenthesized VERBOSE kept for pre-17 compatibility */
12076 : : | CLUSTER VERBOSE
12077 : : {
12078 : : ClusterStmt *n = makeNode(ClusterStmt);
12079 : :
12080 : : n->relation = NULL;
12081 : : n->indexname = NULL;
12082 : : n->params = list_make1(makeDefElem("verbose", NULL, @2));
12083 : : $$ = (Node *) n;
12084 : : }
12085 : : /* kept for pre-8.3 compatibility */
12086 : : | CLUSTER opt_verbose name ON qualified_name
12087 : : {
12088 : : ClusterStmt *n = makeNode(ClusterStmt);
12089 : :
12090 : : n->relation = $5;
12091 : : n->indexname = $3;
12092 : : if ($2)
12093 : : n->params = list_make1(makeDefElem("verbose", NULL, @2));
12094 : : $$ = (Node *) n;
12095 : : }
12096 : : ;
12097 : :
12098 : : cluster_index_specification:
12099 : : USING name { $$ = $2; }
12100 : : | /*EMPTY*/ { $$ = NULL; }
12101 : : ;
12102 : :
12103 : :
12104 : : /*****************************************************************************
12105 : : *
12106 : : * QUERY:
12107 : : * VACUUM
12108 : : * ANALYZE
12109 : : *
12110 : : *****************************************************************************/
12111 : :
12112 : : VacuumStmt: VACUUM opt_full opt_freeze opt_verbose opt_analyze opt_vacuum_relation_list
12113 : : {
12114 : : VacuumStmt *n = makeNode(VacuumStmt);
12115 : :
12116 : : n->options = NIL;
12117 : : if ($2)
12118 : : n->options = lappend(n->options,
12119 : : makeDefElem("full", NULL, @2));
12120 : : if ($3)
12121 : : n->options = lappend(n->options,
12122 : : makeDefElem("freeze", NULL, @3));
12123 : : if ($4)
12124 : : n->options = lappend(n->options,
12125 : : makeDefElem("verbose", NULL, @4));
12126 : : if ($5)
12127 : : n->options = lappend(n->options,
12128 : : makeDefElem("analyze", NULL, @5));
12129 : : n->rels = $6;
12130 : : n->is_vacuumcmd = true;
12131 : : $$ = (Node *) n;
12132 : : }
12133 : : | VACUUM '(' utility_option_list ')' opt_vacuum_relation_list
12134 : : {
12135 : : VacuumStmt *n = makeNode(VacuumStmt);
12136 : :
12137 : : n->options = $3;
12138 : : n->rels = $5;
12139 : : n->is_vacuumcmd = true;
12140 : : $$ = (Node *) n;
12141 : : }
12142 : : ;
12143 : :
12144 : : AnalyzeStmt: analyze_keyword opt_utility_option_list opt_vacuum_relation_list
12145 : : {
12146 : : VacuumStmt *n = makeNode(VacuumStmt);
12147 : :
12148 : : n->options = $2;
12149 : : n->rels = $3;
12150 : : n->is_vacuumcmd = false;
12151 : : $$ = (Node *) n;
12152 : : }
12153 : : | analyze_keyword VERBOSE opt_vacuum_relation_list
12154 : : {
12155 : : VacuumStmt *n = makeNode(VacuumStmt);
12156 : :
12157 : : n->options = list_make1(makeDefElem("verbose", NULL, @2));
12158 : : n->rels = $3;
12159 : : n->is_vacuumcmd = false;
12160 : : $$ = (Node *) n;
12161 : : }
12162 : : ;
12163 : :
12164 : : analyze_keyword:
12165 : : ANALYZE
12166 : : | ANALYSE /* British */
12167 : : ;
12168 : :
12169 : : opt_analyze:
12170 : : analyze_keyword { $$ = true; }
12171 : : | /*EMPTY*/ { $$ = false; }
12172 : : ;
12173 : :
12174 : : opt_verbose:
12175 : : VERBOSE { $$ = true; }
12176 : : | /*EMPTY*/ { $$ = false; }
12177 : : ;
12178 : :
12179 : : opt_full: FULL { $$ = true; }
12180 : : | /*EMPTY*/ { $$ = false; }
12181 : : ;
12182 : :
12183 : : opt_freeze: FREEZE { $$ = true; }
12184 : : | /*EMPTY*/ { $$ = false; }
12185 : : ;
12186 : :
12187 : : opt_name_list:
12188 : : '(' name_list ')' { $$ = $2; }
12189 : : | /*EMPTY*/ { $$ = NIL; }
12190 : : ;
12191 : :
12192 : : vacuum_relation:
12193 : : relation_expr opt_name_list
12194 : : {
12195 : : $$ = (Node *) makeVacuumRelation($1, InvalidOid, $2);
12196 : : }
12197 : : ;
12198 : :
12199 : : vacuum_relation_list:
12200 : : vacuum_relation
12201 : : { $$ = list_make1($1); }
12202 : : | vacuum_relation_list ',' vacuum_relation
12203 : : { $$ = lappend($1, $3); }
12204 : : ;
12205 : :
12206 : : opt_vacuum_relation_list:
12207 : : vacuum_relation_list { $$ = $1; }
12208 : : | /*EMPTY*/ { $$ = NIL; }
12209 : : ;
12210 : :
12211 : :
12212 : : /*****************************************************************************
12213 : : *
12214 : : * QUERY:
12215 : : * EXPLAIN [ANALYZE] [VERBOSE] query
12216 : : * EXPLAIN ( options ) query
12217 : : *
12218 : : *****************************************************************************/
12219 : :
12220 : : ExplainStmt:
12221 : : EXPLAIN ExplainableStmt
12222 : : {
12223 : : ExplainStmt *n = makeNode(ExplainStmt);
12224 : :
12225 : : n->query = $2;
12226 : : n->options = NIL;
12227 : : $$ = (Node *) n;
12228 : : }
12229 : : | EXPLAIN analyze_keyword opt_verbose ExplainableStmt
12230 : : {
12231 : : ExplainStmt *n = makeNode(ExplainStmt);
12232 : :
12233 : : n->query = $4;
12234 : : n->options = list_make1(makeDefElem("analyze", NULL, @2));
12235 : : if ($3)
12236 : : n->options = lappend(n->options,
12237 : : makeDefElem("verbose", NULL, @3));
12238 : : $$ = (Node *) n;
12239 : : }
12240 : : | EXPLAIN VERBOSE ExplainableStmt
12241 : : {
12242 : : ExplainStmt *n = makeNode(ExplainStmt);
12243 : :
12244 : : n->query = $3;
12245 : : n->options = list_make1(makeDefElem("verbose", NULL, @2));
12246 : : $$ = (Node *) n;
12247 : : }
12248 : : | EXPLAIN '(' utility_option_list ')' ExplainableStmt
12249 : : {
12250 : : ExplainStmt *n = makeNode(ExplainStmt);
12251 : :
12252 : : n->query = $5;
12253 : : n->options = $3;
12254 : : $$ = (Node *) n;
12255 : : }
12256 : : ;
12257 : :
12258 : : ExplainableStmt:
12259 : : SelectStmt
12260 : : | InsertStmt
12261 : : | UpdateStmt
12262 : : | DeleteStmt
12263 : : | MergeStmt
12264 : : | DeclareCursorStmt
12265 : : | CreateAsStmt
12266 : : | CreateMatViewStmt
12267 : : | RefreshMatViewStmt
12268 : : | ExecuteStmt /* by default all are $$=$1 */
12269 : : ;
12270 : :
12271 : : /*****************************************************************************
12272 : : *
12273 : : * QUERY:
12274 : : * PREPARE <plan_name> [(args, ...)] AS <query>
12275 : : *
12276 : : *****************************************************************************/
12277 : :
12278 : : PrepareStmt: PREPARE name prep_type_clause AS PreparableStmt
12279 : : {
12280 : : PrepareStmt *n = makeNode(PrepareStmt);
12281 : :
12282 : : n->name = $2;
12283 : : n->argtypes = $3;
12284 : : n->query = $5;
12285 : : $$ = (Node *) n;
12286 : : }
12287 : : ;
12288 : :
12289 : : prep_type_clause: '(' type_list ')' { $$ = $2; }
12290 : : | /* EMPTY */ { $$ = NIL; }
12291 : : ;
12292 : :
12293 : : PreparableStmt:
12294 : : SelectStmt
12295 : : | InsertStmt
12296 : : | UpdateStmt
12297 : : | DeleteStmt
12298 : : | MergeStmt /* by default all are $$=$1 */
12299 : : ;
12300 : :
12301 : : /*****************************************************************************
12302 : : *
12303 : : * EXECUTE <plan_name> [(params, ...)]
12304 : : * CREATE TABLE <name> AS EXECUTE <plan_name> [(params, ...)]
12305 : : *
12306 : : *****************************************************************************/
12307 : :
12308 : : ExecuteStmt: EXECUTE name execute_param_clause
12309 : : {
12310 : : ExecuteStmt *n = makeNode(ExecuteStmt);
12311 : :
12312 : : n->name = $2;
12313 : : n->params = $3;
12314 : : $$ = (Node *) n;
12315 : : }
12316 : : | CREATE OptTemp TABLE create_as_target AS
12317 : : EXECUTE name execute_param_clause opt_with_data
12318 : : {
12319 : : CreateTableAsStmt *ctas = makeNode(CreateTableAsStmt);
12320 : : ExecuteStmt *n = makeNode(ExecuteStmt);
12321 : :
12322 : : n->name = $7;
12323 : : n->params = $8;
12324 : : ctas->query = (Node *) n;
12325 : : ctas->into = $4;
12326 : : ctas->objtype = OBJECT_TABLE;
12327 : : ctas->is_select_into = false;
12328 : : ctas->if_not_exists = false;
12329 : : /* cram additional flags into the IntoClause */
12330 : : $4->rel->relpersistence = $2;
12331 : : $4->skipData = !($9);
12332 : : $$ = (Node *) ctas;
12333 : : }
12334 : : | CREATE OptTemp TABLE IF_P NOT EXISTS create_as_target AS
12335 : : EXECUTE name execute_param_clause opt_with_data
12336 : : {
12337 : : CreateTableAsStmt *ctas = makeNode(CreateTableAsStmt);
12338 : : ExecuteStmt *n = makeNode(ExecuteStmt);
12339 : :
12340 : : n->name = $10;
12341 : : n->params = $11;
12342 : : ctas->query = (Node *) n;
12343 : : ctas->into = $7;
12344 : : ctas->objtype = OBJECT_TABLE;
12345 : : ctas->is_select_into = false;
12346 : : ctas->if_not_exists = true;
12347 : : /* cram additional flags into the IntoClause */
12348 : : $7->rel->relpersistence = $2;
12349 : : $7->skipData = !($12);
12350 : : $$ = (Node *) ctas;
12351 : : }
12352 : : ;
12353 : :
12354 : : execute_param_clause: '(' expr_list ')' { $$ = $2; }
12355 : : | /* EMPTY */ { $$ = NIL; }
12356 : : ;
12357 : :
12358 : : /*****************************************************************************
12359 : : *
12360 : : * QUERY:
12361 : : * DEALLOCATE [PREPARE] <plan_name>
12362 : : *
12363 : : *****************************************************************************/
12364 : :
12365 : : DeallocateStmt: DEALLOCATE name
12366 : : {
12367 : : DeallocateStmt *n = makeNode(DeallocateStmt);
12368 : :
12369 : : n->name = $2;
12370 : : n->isall = false;
12371 : : n->location = @2;
12372 : : $$ = (Node *) n;
12373 : : }
12374 : : | DEALLOCATE PREPARE name
12375 : : {
12376 : : DeallocateStmt *n = makeNode(DeallocateStmt);
12377 : :
12378 : : n->name = $3;
12379 : : n->isall = false;
12380 : : n->location = @3;
12381 : : $$ = (Node *) n;
12382 : : }
12383 : : | DEALLOCATE ALL
12384 : : {
12385 : : DeallocateStmt *n = makeNode(DeallocateStmt);
12386 : :
12387 : : n->name = NULL;
12388 : : n->isall = true;
12389 : : n->location = -1;
12390 : : $$ = (Node *) n;
12391 : : }
12392 : : | DEALLOCATE PREPARE ALL
12393 : : {
12394 : : DeallocateStmt *n = makeNode(DeallocateStmt);
12395 : :
12396 : : n->name = NULL;
12397 : : n->isall = true;
12398 : : n->location = -1;
12399 : : $$ = (Node *) n;
12400 : : }
12401 : : ;
12402 : :
12403 : : /*****************************************************************************
12404 : : *
12405 : : * QUERY:
12406 : : * INSERT STATEMENTS
12407 : : *
12408 : : *****************************************************************************/
12409 : :
12410 : : InsertStmt:
12411 : : opt_with_clause INSERT INTO insert_target insert_rest
12412 : : opt_on_conflict returning_clause
12413 : : {
12414 : : $5->relation = $4;
12415 : : $5->onConflictClause = $6;
12416 : : $5->returningClause = $7;
12417 : : $5->withClause = $1;
12418 : : $$ = (Node *) $5;
12419 : : }
12420 : : ;
12421 : :
12422 : : /*
12423 : : * Can't easily make AS optional here, because VALUES in insert_rest would
12424 : : * have a shift/reduce conflict with VALUES as an optional alias. We could
12425 : : * easily allow unreserved_keywords as optional aliases, but that'd be an odd
12426 : : * divergence from other places. So just require AS for now.
12427 : : */
12428 : : insert_target:
12429 : : qualified_name
12430 : : {
12431 : : $$ = $1;
12432 : : }
12433 : : | qualified_name AS ColId
12434 : : {
12435 : : $1->alias = makeAlias($3, NIL);
12436 : : $$ = $1;
12437 : : }
12438 : : ;
12439 : :
12440 : : insert_rest:
12441 : : SelectStmt
12442 : : {
12443 : : $$ = makeNode(InsertStmt);
12444 : : $$->cols = NIL;
12445 : : $$->selectStmt = $1;
12446 : : }
12447 : : | OVERRIDING override_kind VALUE_P SelectStmt
12448 : : {
12449 : : $$ = makeNode(InsertStmt);
12450 : : $$->cols = NIL;
12451 : : $$->override = $2;
12452 : : $$->selectStmt = $4;
12453 : : }
12454 : : | '(' insert_column_list ')' SelectStmt
12455 : : {
12456 : : $$ = makeNode(InsertStmt);
12457 : : $$->cols = $2;
12458 : : $$->selectStmt = $4;
12459 : : }
12460 : : | '(' insert_column_list ')' OVERRIDING override_kind VALUE_P SelectStmt
12461 : : {
12462 : : $$ = makeNode(InsertStmt);
12463 : : $$->cols = $2;
12464 : : $$->override = $5;
12465 : : $$->selectStmt = $7;
12466 : : }
12467 : : | DEFAULT VALUES
12468 : : {
12469 : : $$ = makeNode(InsertStmt);
12470 : : $$->cols = NIL;
12471 : : $$->selectStmt = NULL;
12472 : : }
12473 : : ;
12474 : :
12475 : : override_kind:
12476 : : USER { $$ = OVERRIDING_USER_VALUE; }
12477 : : | SYSTEM_P { $$ = OVERRIDING_SYSTEM_VALUE; }
12478 : : ;
12479 : :
12480 : : insert_column_list:
12481 : : insert_column_item
12482 : : { $$ = list_make1($1); }
12483 : : | insert_column_list ',' insert_column_item
12484 : : { $$ = lappend($1, $3); }
12485 : : ;
12486 : :
12487 : : insert_column_item:
12488 : : ColId opt_indirection
12489 : : {
12490 : : $$ = makeNode(ResTarget);
12491 : : $$->name = $1;
12492 : : $$->indirection = check_indirection($2, yyscanner);
12493 : : $$->val = NULL;
12494 : : $$->location = @1;
12495 : : }
12496 : : ;
12497 : :
12498 : : opt_on_conflict:
12499 : : ON CONFLICT opt_conf_expr DO UPDATE SET set_clause_list where_clause
12500 : : {
12501 : : $$ = makeNode(OnConflictClause);
12502 : : $$->action = ONCONFLICT_UPDATE;
12503 : : $$->infer = $3;
12504 : : $$->targetList = $7;
12505 : : $$->whereClause = $8;
12506 : : $$->location = @1;
12507 : : }
12508 : : |
12509 : : ON CONFLICT opt_conf_expr DO NOTHING
12510 : : {
12511 : : $$ = makeNode(OnConflictClause);
12512 : : $$->action = ONCONFLICT_NOTHING;
12513 : : $$->infer = $3;
12514 : : $$->targetList = NIL;
12515 : : $$->whereClause = NULL;
12516 : : $$->location = @1;
12517 : : }
12518 : : | /*EMPTY*/
12519 : : {
12520 : : $$ = NULL;
12521 : : }
12522 : : ;
12523 : :
12524 : : opt_conf_expr:
12525 : : '(' index_params ')' where_clause
12526 : : {
12527 : : $$ = makeNode(InferClause);
12528 : : $$->indexElems = $2;
12529 : : $$->whereClause = $4;
12530 : : $$->conname = NULL;
12531 : : $$->location = @1;
12532 : : }
12533 : : |
12534 : : ON CONSTRAINT name
12535 : : {
12536 : : $$ = makeNode(InferClause);
12537 : : $$->indexElems = NIL;
12538 : : $$->whereClause = NULL;
12539 : : $$->conname = $3;
12540 : : $$->location = @1;
12541 : : }
12542 : : | /*EMPTY*/
12543 : : {
12544 : : $$ = NULL;
12545 : : }
12546 : : ;
12547 : :
12548 : : returning_clause:
12549 : : RETURNING returning_with_clause target_list
12550 : : {
12551 : : ReturningClause *n = makeNode(ReturningClause);
12552 : :
12553 : : n->options = $2;
12554 : : n->exprs = $3;
12555 : : $$ = n;
12556 : : }
12557 : : | /* EMPTY */
12558 : : {
12559 : : $$ = NULL;
12560 : : }
12561 : : ;
12562 : :
12563 : : returning_with_clause:
12564 : : WITH '(' returning_options ')' { $$ = $3; }
12565 : : | /* EMPTY */ { $$ = NIL; }
12566 : : ;
12567 : :
12568 : : returning_options:
12569 : : returning_option { $$ = list_make1($1); }
12570 : : | returning_options ',' returning_option { $$ = lappend($1, $3); }
12571 : : ;
12572 : :
12573 : : returning_option:
12574 : : returning_option_kind AS ColId
12575 : : {
12576 : : ReturningOption *n = makeNode(ReturningOption);
12577 : :
12578 : : n->option = $1;
12579 : : n->value = $3;
12580 : : n->location = @1;
12581 : : $$ = (Node *) n;
12582 : : }
12583 : : ;
12584 : :
12585 : : returning_option_kind:
12586 : : OLD { $$ = RETURNING_OPTION_OLD; }
12587 : : | NEW { $$ = RETURNING_OPTION_NEW; }
12588 : : ;
12589 : :
12590 : :
12591 : : /*****************************************************************************
12592 : : *
12593 : : * QUERY:
12594 : : * DELETE STATEMENTS
12595 : : *
12596 : : *****************************************************************************/
12597 : :
12598 : : DeleteStmt: opt_with_clause DELETE_P FROM relation_expr_opt_alias
12599 : : using_clause where_or_current_clause returning_clause
12600 : : {
12601 : : DeleteStmt *n = makeNode(DeleteStmt);
12602 : :
12603 : : n->relation = $4;
12604 : : n->usingClause = $5;
12605 : : n->whereClause = $6;
12606 : : n->returningClause = $7;
12607 : : n->withClause = $1;
12608 : : $$ = (Node *) n;
12609 : : }
12610 : : ;
12611 : :
12612 : : using_clause:
12613 : : USING from_list { $$ = $2; }
12614 : : | /*EMPTY*/ { $$ = NIL; }
12615 : : ;
12616 : :
12617 : :
12618 : : /*****************************************************************************
12619 : : *
12620 : : * QUERY:
12621 : : * LOCK TABLE
12622 : : *
12623 : : *****************************************************************************/
12624 : :
12625 : : LockStmt: LOCK_P opt_table relation_expr_list opt_lock opt_nowait
12626 : : {
12627 : : LockStmt *n = makeNode(LockStmt);
12628 : :
12629 : : n->relations = $3;
12630 : : n->mode = $4;
12631 : : n->nowait = $5;
12632 : : $$ = (Node *) n;
12633 : : }
12634 : : ;
12635 : :
12636 : : opt_lock: IN_P lock_type MODE { $$ = $2; }
12637 : : | /*EMPTY*/ { $$ = AccessExclusiveLock; }
12638 : : ;
12639 : :
12640 : : lock_type: ACCESS SHARE { $$ = AccessShareLock; }
12641 : : | ROW SHARE { $$ = RowShareLock; }
12642 : : | ROW EXCLUSIVE { $$ = RowExclusiveLock; }
12643 : : | SHARE UPDATE EXCLUSIVE { $$ = ShareUpdateExclusiveLock; }
12644 : : | SHARE { $$ = ShareLock; }
12645 : : | SHARE ROW EXCLUSIVE { $$ = ShareRowExclusiveLock; }
12646 : : | EXCLUSIVE { $$ = ExclusiveLock; }
12647 : : | ACCESS EXCLUSIVE { $$ = AccessExclusiveLock; }
12648 : : ;
12649 : :
12650 : : opt_nowait: NOWAIT { $$ = true; }
12651 : : | /*EMPTY*/ { $$ = false; }
12652 : : ;
12653 : :
12654 : : opt_nowait_or_skip:
12655 : : NOWAIT { $$ = LockWaitError; }
12656 : : | SKIP LOCKED { $$ = LockWaitSkip; }
12657 : : | /*EMPTY*/ { $$ = LockWaitBlock; }
12658 : : ;
12659 : :
12660 : :
12661 : : /*****************************************************************************
12662 : : *
12663 : : * QUERY:
12664 : : * UpdateStmt (UPDATE)
12665 : : *
12666 : : *****************************************************************************/
12667 : :
12668 : : UpdateStmt: opt_with_clause UPDATE relation_expr_opt_alias
12669 : : SET set_clause_list
12670 : : from_clause
12671 : : where_or_current_clause
12672 : : returning_clause
12673 : : {
12674 : : UpdateStmt *n = makeNode(UpdateStmt);
12675 : :
12676 : : n->relation = $3;
12677 : : n->targetList = $5;
12678 : : n->fromClause = $6;
12679 : : n->whereClause = $7;
12680 : : n->returningClause = $8;
12681 : : n->withClause = $1;
12682 : : $$ = (Node *) n;
12683 : : }
12684 : : ;
12685 : :
12686 : : set_clause_list:
12687 : : set_clause { $$ = $1; }
12688 : : | set_clause_list ',' set_clause { $$ = list_concat($1,$3); }
12689 : : ;
12690 : :
12691 : : set_clause:
12692 : : set_target '=' a_expr
12693 : : {
12694 : : $1->val = (Node *) $3;
12695 : : $$ = list_make1($1);
12696 : : }
12697 : : | '(' set_target_list ')' '=' a_expr
12698 : : {
12699 : : int ncolumns = list_length($2);
12700 : : int i = 1;
12701 : : ListCell *col_cell;
12702 : :
12703 : : /* Create a MultiAssignRef source for each target */
12704 : : foreach(col_cell, $2)
12705 : : {
12706 : : ResTarget *res_col = (ResTarget *) lfirst(col_cell);
12707 : : MultiAssignRef *r = makeNode(MultiAssignRef);
12708 : :
12709 : : r->source = (Node *) $5;
12710 : : r->colno = i;
12711 : : r->ncolumns = ncolumns;
12712 : : res_col->val = (Node *) r;
12713 : : i++;
12714 : : }
12715 : :
12716 : : $$ = $2;
12717 : : }
12718 : : ;
12719 : :
12720 : : set_target:
12721 : : ColId opt_indirection
12722 : : {
12723 : : $$ = makeNode(ResTarget);
12724 : : $$->name = $1;
12725 : : $$->indirection = check_indirection($2, yyscanner);
12726 : : $$->val = NULL; /* upper production sets this */
12727 : : $$->location = @1;
12728 : : }
12729 : : ;
12730 : :
12731 : : set_target_list:
12732 : : set_target { $$ = list_make1($1); }
12733 : : | set_target_list ',' set_target { $$ = lappend($1,$3); }
12734 : : ;
12735 : :
12736 : :
12737 : : /*****************************************************************************
12738 : : *
12739 : : * QUERY:
12740 : : * MERGE
12741 : : *
12742 : : *****************************************************************************/
12743 : :
12744 : : MergeStmt:
12745 : : opt_with_clause MERGE INTO relation_expr_opt_alias
12746 : : USING table_ref
12747 : : ON a_expr
12748 : : merge_when_list
12749 : : returning_clause
12750 : : {
12751 : : MergeStmt *m = makeNode(MergeStmt);
12752 : :
12753 : : m->withClause = $1;
12754 : : m->relation = $4;
12755 : : m->sourceRelation = $6;
12756 : : m->joinCondition = $8;
12757 : : m->mergeWhenClauses = $9;
12758 : : m->returningClause = $10;
12759 : :
12760 : : $$ = (Node *) m;
12761 : : }
12762 : : ;
12763 : :
12764 : : merge_when_list:
12765 : : merge_when_clause { $$ = list_make1($1); }
12766 : : | merge_when_list merge_when_clause { $$ = lappend($1,$2); }
12767 : : ;
12768 : :
12769 : : /*
12770 : : * A WHEN clause may be WHEN MATCHED, WHEN NOT MATCHED BY SOURCE, or WHEN NOT
12771 : : * MATCHED [BY TARGET]. The first two cases match target tuples, and support
12772 : : * UPDATE/DELETE/DO NOTHING actions. The third case does not match target
12773 : : * tuples, and only supports INSERT/DO NOTHING actions.
12774 : : */
12775 : : merge_when_clause:
12776 : : merge_when_tgt_matched opt_merge_when_condition THEN merge_update
12777 : : {
12778 : : $4->matchKind = $1;
12779 : : $4->condition = $2;
12780 : :
12781 : : $$ = (Node *) $4;
12782 : : }
12783 : : | merge_when_tgt_matched opt_merge_when_condition THEN merge_delete
12784 : : {
12785 : : $4->matchKind = $1;
12786 : : $4->condition = $2;
12787 : :
12788 : : $$ = (Node *) $4;
12789 : : }
12790 : : | merge_when_tgt_not_matched opt_merge_when_condition THEN merge_insert
12791 : : {
12792 : : $4->matchKind = $1;
12793 : : $4->condition = $2;
12794 : :
12795 : : $$ = (Node *) $4;
12796 : : }
12797 : : | merge_when_tgt_matched opt_merge_when_condition THEN DO NOTHING
12798 : : {
12799 : : MergeWhenClause *m = makeNode(MergeWhenClause);
12800 : :
12801 : : m->matchKind = $1;
12802 : : m->commandType = CMD_NOTHING;
12803 : : m->condition = $2;
12804 : :
12805 : : $$ = (Node *) m;
12806 : : }
12807 : : | merge_when_tgt_not_matched opt_merge_when_condition THEN DO NOTHING
12808 : : {
12809 : : MergeWhenClause *m = makeNode(MergeWhenClause);
12810 : :
12811 : : m->matchKind = $1;
12812 : : m->commandType = CMD_NOTHING;
12813 : : m->condition = $2;
12814 : :
12815 : : $$ = (Node *) m;
12816 : : }
12817 : : ;
12818 : :
12819 : : merge_when_tgt_matched:
12820 : : WHEN MATCHED { $$ = MERGE_WHEN_MATCHED; }
12821 : : | WHEN NOT MATCHED BY SOURCE { $$ = MERGE_WHEN_NOT_MATCHED_BY_SOURCE; }
12822 : : ;
12823 : :
12824 : : merge_when_tgt_not_matched:
12825 : : WHEN NOT MATCHED { $$ = MERGE_WHEN_NOT_MATCHED_BY_TARGET; }
12826 : : | WHEN NOT MATCHED BY TARGET { $$ = MERGE_WHEN_NOT_MATCHED_BY_TARGET; }
12827 : : ;
12828 : :
12829 : : opt_merge_when_condition:
12830 : : AND a_expr { $$ = $2; }
12831 : : | { $$ = NULL; }
12832 : : ;
12833 : :
12834 : : merge_update:
12835 : : UPDATE SET set_clause_list
12836 : : {
12837 : : MergeWhenClause *n = makeNode(MergeWhenClause);
12838 : : n->commandType = CMD_UPDATE;
12839 : : n->override = OVERRIDING_NOT_SET;
12840 : : n->targetList = $3;
12841 : : n->values = NIL;
12842 : :
12843 : : $$ = n;
12844 : : }
12845 : : ;
12846 : :
12847 : : merge_delete:
12848 : : DELETE_P
12849 : : {
12850 : : MergeWhenClause *n = makeNode(MergeWhenClause);
12851 : : n->commandType = CMD_DELETE;
12852 : : n->override = OVERRIDING_NOT_SET;
12853 : : n->targetList = NIL;
12854 : : n->values = NIL;
12855 : :
12856 : : $$ = n;
12857 : : }
12858 : : ;
12859 : :
12860 : : merge_insert:
12861 : : INSERT merge_values_clause
12862 : : {
12863 : : MergeWhenClause *n = makeNode(MergeWhenClause);
12864 : : n->commandType = CMD_INSERT;
12865 : : n->override = OVERRIDING_NOT_SET;
12866 : : n->targetList = NIL;
12867 : : n->values = $2;
12868 : : $$ = n;
12869 : : }
12870 : : | INSERT OVERRIDING override_kind VALUE_P merge_values_clause
12871 : : {
12872 : : MergeWhenClause *n = makeNode(MergeWhenClause);
12873 : : n->commandType = CMD_INSERT;
12874 : : n->override = $3;
12875 : : n->targetList = NIL;
12876 : : n->values = $5;
12877 : : $$ = n;
12878 : : }
12879 : : | INSERT '(' insert_column_list ')' merge_values_clause
12880 : : {
12881 : : MergeWhenClause *n = makeNode(MergeWhenClause);
12882 : : n->commandType = CMD_INSERT;
12883 : : n->override = OVERRIDING_NOT_SET;
12884 : : n->targetList = $3;
12885 : : n->values = $5;
12886 : : $$ = n;
12887 : : }
12888 : : | INSERT '(' insert_column_list ')' OVERRIDING override_kind VALUE_P merge_values_clause
12889 : : {
12890 : : MergeWhenClause *n = makeNode(MergeWhenClause);
12891 : : n->commandType = CMD_INSERT;
12892 : : n->override = $6;
12893 : : n->targetList = $3;
12894 : : n->values = $8;
12895 : : $$ = n;
12896 : : }
12897 : : | INSERT DEFAULT VALUES
12898 : : {
12899 : : MergeWhenClause *n = makeNode(MergeWhenClause);
12900 : : n->commandType = CMD_INSERT;
12901 : : n->override = OVERRIDING_NOT_SET;
12902 : : n->targetList = NIL;
12903 : : n->values = NIL;
12904 : : $$ = n;
12905 : : }
12906 : : ;
12907 : :
12908 : : merge_values_clause:
12909 : : VALUES '(' expr_list ')'
12910 : : {
12911 : : $$ = $3;
12912 : : }
12913 : : ;
12914 : :
12915 : : /*****************************************************************************
12916 : : *
12917 : : * QUERY:
12918 : : * CURSOR STATEMENTS
12919 : : *
12920 : : *****************************************************************************/
12921 : : DeclareCursorStmt: DECLARE cursor_name cursor_options CURSOR opt_hold FOR SelectStmt
12922 : : {
12923 : : DeclareCursorStmt *n = makeNode(DeclareCursorStmt);
12924 : :
12925 : : n->portalname = $2;
12926 : : /* currently we always set FAST_PLAN option */
12927 : : n->options = $3 | $5 | CURSOR_OPT_FAST_PLAN;
12928 : : n->query = $7;
12929 : : $$ = (Node *) n;
12930 : : }
12931 : : ;
12932 : :
12933 : : cursor_name: name { $$ = $1; }
12934 : : ;
12935 : :
12936 : : cursor_options: /*EMPTY*/ { $$ = 0; }
12937 : : | cursor_options NO SCROLL { $$ = $1 | CURSOR_OPT_NO_SCROLL; }
12938 : : | cursor_options SCROLL { $$ = $1 | CURSOR_OPT_SCROLL; }
12939 : : | cursor_options BINARY { $$ = $1 | CURSOR_OPT_BINARY; }
12940 : : | cursor_options ASENSITIVE { $$ = $1 | CURSOR_OPT_ASENSITIVE; }
12941 : : | cursor_options INSENSITIVE { $$ = $1 | CURSOR_OPT_INSENSITIVE; }
12942 : : ;
12943 : :
12944 : : opt_hold: /* EMPTY */ { $$ = 0; }
12945 : : | WITH HOLD { $$ = CURSOR_OPT_HOLD; }
12946 : : | WITHOUT HOLD { $$ = 0; }
12947 : : ;
12948 : :
12949 : : /*****************************************************************************
12950 : : *
12951 : : * QUERY:
12952 : : * SELECT STATEMENTS
12953 : : *
12954 : : *****************************************************************************/
12955 : :
12956 : : /* A complete SELECT statement looks like this.
12957 : : *
12958 : : * The rule returns either a single SelectStmt node or a tree of them,
12959 : : * representing a set-operation tree.
12960 : : *
12961 : : * There is an ambiguity when a sub-SELECT is within an a_expr and there
12962 : : * are excess parentheses: do the parentheses belong to the sub-SELECT or
12963 : : * to the surrounding a_expr? We don't really care, but bison wants to know.
12964 : : * To resolve the ambiguity, we are careful to define the grammar so that
12965 : : * the decision is staved off as long as possible: as long as we can keep
12966 : : * absorbing parentheses into the sub-SELECT, we will do so, and only when
12967 : : * it's no longer possible to do that will we decide that parens belong to
12968 : : * the expression. For example, in "SELECT (((SELECT 2)) + 3)" the extra
12969 : : * parentheses are treated as part of the sub-select. The necessity of doing
12970 : : * it that way is shown by "SELECT (((SELECT 2)) UNION SELECT 2)". Had we
12971 : : * parsed "((SELECT 2))" as an a_expr, it'd be too late to go back to the
12972 : : * SELECT viewpoint when we see the UNION.
12973 : : *
12974 : : * This approach is implemented by defining a nonterminal select_with_parens,
12975 : : * which represents a SELECT with at least one outer layer of parentheses,
12976 : : * and being careful to use select_with_parens, never '(' SelectStmt ')',
12977 : : * in the expression grammar. We will then have shift-reduce conflicts
12978 : : * which we can resolve in favor of always treating '(' <select> ')' as
12979 : : * a select_with_parens. To resolve the conflicts, the productions that
12980 : : * conflict with the select_with_parens productions are manually given
12981 : : * precedences lower than the precedence of ')', thereby ensuring that we
12982 : : * shift ')' (and then reduce to select_with_parens) rather than trying to
12983 : : * reduce the inner <select> nonterminal to something else. We use UMINUS
12984 : : * precedence for this, which is a fairly arbitrary choice.
12985 : : *
12986 : : * To be able to define select_with_parens itself without ambiguity, we need
12987 : : * a nonterminal select_no_parens that represents a SELECT structure with no
12988 : : * outermost parentheses. This is a little bit tedious, but it works.
12989 : : *
12990 : : * In non-expression contexts, we use SelectStmt which can represent a SELECT
12991 : : * with or without outer parentheses.
12992 : : */
12993 : :
12994 : : SelectStmt: select_no_parens %prec UMINUS
12995 : : | select_with_parens %prec UMINUS
12996 : : ;
12997 : :
12998 : : select_with_parens:
12999 : : '(' select_no_parens ')' { $$ = $2; }
13000 : : | '(' select_with_parens ')' { $$ = $2; }
13001 : : ;
13002 : :
13003 : : /*
13004 : : * This rule parses the equivalent of the standard's <query expression>.
13005 : : * The duplicative productions are annoying, but hard to get rid of without
13006 : : * creating shift/reduce conflicts.
13007 : : *
13008 : : * The locking clause (FOR UPDATE etc) may be before or after LIMIT/OFFSET.
13009 : : * In <=7.2.X, LIMIT/OFFSET had to be after FOR UPDATE
13010 : : * We now support both orderings, but prefer LIMIT/OFFSET before the locking
13011 : : * clause.
13012 : : * 2002-08-28 bjm
13013 : : */
13014 : : select_no_parens:
13015 : : simple_select { $$ = $1; }
13016 : : | select_clause sort_clause
13017 : : {
13018 : : insertSelectOptions((SelectStmt *) $1, $2, NIL,
13019 : : NULL, NULL,
13020 : : yyscanner);
13021 : : $$ = $1;
13022 : : }
13023 : : | select_clause opt_sort_clause for_locking_clause opt_select_limit
13024 : : {
13025 : : insertSelectOptions((SelectStmt *) $1, $2, $3,
13026 : : $4,
13027 : : NULL,
13028 : : yyscanner);
13029 : : $$ = $1;
13030 : : }
13031 : : | select_clause opt_sort_clause select_limit opt_for_locking_clause
13032 : : {
13033 : : insertSelectOptions((SelectStmt *) $1, $2, $4,
13034 : : $3,
13035 : : NULL,
13036 : : yyscanner);
13037 : : $$ = $1;
13038 : : }
13039 : : | with_clause select_clause
13040 : : {
13041 : : insertSelectOptions((SelectStmt *) $2, NULL, NIL,
13042 : : NULL,
13043 : : $1,
13044 : : yyscanner);
13045 : : $$ = $2;
13046 : : }
13047 : : | with_clause select_clause sort_clause
13048 : : {
13049 : : insertSelectOptions((SelectStmt *) $2, $3, NIL,
13050 : : NULL,
13051 : : $1,
13052 : : yyscanner);
13053 : : $$ = $2;
13054 : : }
13055 : : | with_clause select_clause opt_sort_clause for_locking_clause opt_select_limit
13056 : : {
13057 : : insertSelectOptions((SelectStmt *) $2, $3, $4,
13058 : : $5,
13059 : : $1,
13060 : : yyscanner);
13061 : : $$ = $2;
13062 : : }
13063 : : | with_clause select_clause opt_sort_clause select_limit opt_for_locking_clause
13064 : : {
13065 : : insertSelectOptions((SelectStmt *) $2, $3, $5,
13066 : : $4,
13067 : : $1,
13068 : : yyscanner);
13069 : : $$ = $2;
13070 : : }
13071 : : ;
13072 : :
13073 : : select_clause:
13074 : : simple_select { $$ = $1; }
13075 : : | select_with_parens { $$ = $1; }
13076 : : ;
13077 : :
13078 : : /*
13079 : : * This rule parses SELECT statements that can appear within set operations,
13080 : : * including UNION, INTERSECT and EXCEPT. '(' and ')' can be used to specify
13081 : : * the ordering of the set operations. Without '(' and ')' we want the
13082 : : * operations to be ordered per the precedence specs at the head of this file.
13083 : : *
13084 : : * As with select_no_parens, simple_select cannot have outer parentheses,
13085 : : * but can have parenthesized subclauses.
13086 : : *
13087 : : * It might appear that we could fold the first two alternatives into one
13088 : : * by using opt_distinct_clause. However, that causes a shift/reduce conflict
13089 : : * against INSERT ... SELECT ... ON CONFLICT. We avoid the ambiguity by
13090 : : * requiring SELECT DISTINCT [ON] to be followed by a non-empty target_list.
13091 : : *
13092 : : * Note that sort clauses cannot be included at this level --- SQL requires
13093 : : * SELECT foo UNION SELECT bar ORDER BY baz
13094 : : * to be parsed as
13095 : : * (SELECT foo UNION SELECT bar) ORDER BY baz
13096 : : * not
13097 : : * SELECT foo UNION (SELECT bar ORDER BY baz)
13098 : : * Likewise for WITH, FOR UPDATE and LIMIT. Therefore, those clauses are
13099 : : * described as part of the select_no_parens production, not simple_select.
13100 : : * This does not limit functionality, because you can reintroduce these
13101 : : * clauses inside parentheses.
13102 : : *
13103 : : * NOTE: only the leftmost component SelectStmt should have INTO.
13104 : : * However, this is not checked by the grammar; parse analysis must check it.
13105 : : */
13106 : : simple_select:
13107 : : SELECT opt_all_clause opt_target_list
13108 : : into_clause from_clause where_clause
13109 : : group_clause having_clause window_clause
13110 : : {
13111 : : SelectStmt *n = makeNode(SelectStmt);
13112 : :
13113 : : n->targetList = $3;
13114 : : n->intoClause = $4;
13115 : : n->fromClause = $5;
13116 : : n->whereClause = $6;
13117 : : n->groupClause = ($7)->list;
13118 : : n->groupDistinct = ($7)->distinct;
13119 : : n->groupByAll = ($7)->all;
13120 : : n->havingClause = $8;
13121 : : n->windowClause = $9;
13122 : : $$ = (Node *) n;
13123 : : }
13124 : : | SELECT distinct_clause target_list
13125 : : into_clause from_clause where_clause
13126 : : group_clause having_clause window_clause
13127 : : {
13128 : : SelectStmt *n = makeNode(SelectStmt);
13129 : :
13130 : : n->distinctClause = $2;
13131 : : n->targetList = $3;
13132 : : n->intoClause = $4;
13133 : : n->fromClause = $5;
13134 : : n->whereClause = $6;
13135 : : n->groupClause = ($7)->list;
13136 : : n->groupDistinct = ($7)->distinct;
13137 : : n->groupByAll = ($7)->all;
13138 : : n->havingClause = $8;
13139 : : n->windowClause = $9;
13140 : : $$ = (Node *) n;
13141 : : }
13142 : : | values_clause { $$ = $1; }
13143 : : | TABLE relation_expr
13144 : : {
13145 : : /* same as SELECT * FROM relation_expr */
13146 : : ColumnRef *cr = makeNode(ColumnRef);
13147 : : ResTarget *rt = makeNode(ResTarget);
13148 : : SelectStmt *n = makeNode(SelectStmt);
13149 : :
13150 : : cr->fields = list_make1(makeNode(A_Star));
13151 : : cr->location = -1;
13152 : :
13153 : : rt->name = NULL;
13154 : : rt->indirection = NIL;
13155 : : rt->val = (Node *) cr;
13156 : : rt->location = -1;
13157 : :
13158 : : n->targetList = list_make1(rt);
13159 : : n->fromClause = list_make1($2);
13160 : : $$ = (Node *) n;
13161 : : }
13162 : : | select_clause UNION set_quantifier select_clause
13163 : : {
13164 : : $$ = makeSetOp(SETOP_UNION, $3 == SET_QUANTIFIER_ALL, $1, $4);
13165 : : }
13166 : : | select_clause INTERSECT set_quantifier select_clause
13167 : : {
13168 : : $$ = makeSetOp(SETOP_INTERSECT, $3 == SET_QUANTIFIER_ALL, $1, $4);
13169 : : }
13170 : : | select_clause EXCEPT set_quantifier select_clause
13171 : : {
13172 : : $$ = makeSetOp(SETOP_EXCEPT, $3 == SET_QUANTIFIER_ALL, $1, $4);
13173 : : }
13174 : : ;
13175 : :
13176 : : /*
13177 : : * SQL standard WITH clause looks like:
13178 : : *
13179 : : * WITH [ RECURSIVE ] <query name> [ (<column>,...) ]
13180 : : * AS (query) [ SEARCH or CYCLE clause ]
13181 : : *
13182 : : * Recognizing WITH_LA here allows a CTE to be named TIME or ORDINALITY.
13183 : : */
13184 : : with_clause:
13185 : : WITH cte_list
13186 : : {
13187 : : $$ = makeNode(WithClause);
13188 : : $$->ctes = $2;
13189 : : $$->recursive = false;
13190 : : $$->location = @1;
13191 : : }
13192 : : | WITH_LA cte_list
13193 : : {
13194 : : $$ = makeNode(WithClause);
13195 : : $$->ctes = $2;
13196 : : $$->recursive = false;
13197 : : $$->location = @1;
13198 : : }
13199 : : | WITH RECURSIVE cte_list
13200 : : {
13201 : : $$ = makeNode(WithClause);
13202 : : $$->ctes = $3;
13203 : : $$->recursive = true;
13204 : : $$->location = @1;
13205 : : }
13206 : : ;
13207 : :
13208 : : cte_list:
13209 : : common_table_expr { $$ = list_make1($1); }
13210 : : | cte_list ',' common_table_expr { $$ = lappend($1, $3); }
13211 : : ;
13212 : :
13213 : : common_table_expr: name opt_name_list AS opt_materialized '(' PreparableStmt ')' opt_search_clause opt_cycle_clause
13214 : : {
13215 : : CommonTableExpr *n = makeNode(CommonTableExpr);
13216 : :
13217 : : n->ctename = $1;
13218 : : n->aliascolnames = $2;
13219 : : n->ctematerialized = $4;
13220 : : n->ctequery = $6;
13221 : : n->search_clause = castNode(CTESearchClause, $8);
13222 : : n->cycle_clause = castNode(CTECycleClause, $9);
13223 : : n->location = @1;
13224 : : $$ = (Node *) n;
13225 : : }
13226 : : ;
13227 : :
13228 : : opt_materialized:
13229 : : MATERIALIZED { $$ = CTEMaterializeAlways; }
13230 : : | NOT MATERIALIZED { $$ = CTEMaterializeNever; }
13231 : : | /*EMPTY*/ { $$ = CTEMaterializeDefault; }
13232 : : ;
13233 : :
13234 : : opt_search_clause:
13235 : : SEARCH DEPTH FIRST_P BY columnList SET ColId
13236 : : {
13237 : : CTESearchClause *n = makeNode(CTESearchClause);
13238 : :
13239 : : n->search_col_list = $5;
13240 : : n->search_breadth_first = false;
13241 : : n->search_seq_column = $7;
13242 : : n->location = @1;
13243 : : $$ = (Node *) n;
13244 : : }
13245 : : | SEARCH BREADTH FIRST_P BY columnList SET ColId
13246 : : {
13247 : : CTESearchClause *n = makeNode(CTESearchClause);
13248 : :
13249 : : n->search_col_list = $5;
13250 : : n->search_breadth_first = true;
13251 : : n->search_seq_column = $7;
13252 : : n->location = @1;
13253 : : $$ = (Node *) n;
13254 : : }
13255 : : | /*EMPTY*/
13256 : : {
13257 : : $$ = NULL;
13258 : : }
13259 : : ;
13260 : :
13261 : : opt_cycle_clause:
13262 : : CYCLE columnList SET ColId TO AexprConst DEFAULT AexprConst USING ColId
13263 : : {
13264 : : CTECycleClause *n = makeNode(CTECycleClause);
13265 : :
13266 : : n->cycle_col_list = $2;
13267 : : n->cycle_mark_column = $4;
13268 : : n->cycle_mark_value = $6;
13269 : : n->cycle_mark_default = $8;
13270 : : n->cycle_path_column = $10;
13271 : : n->location = @1;
13272 : : $$ = (Node *) n;
13273 : : }
13274 : : | CYCLE columnList SET ColId USING ColId
13275 : : {
13276 : : CTECycleClause *n = makeNode(CTECycleClause);
13277 : :
13278 : : n->cycle_col_list = $2;
13279 : : n->cycle_mark_column = $4;
13280 : : n->cycle_mark_value = makeBoolAConst(true, -1);
13281 : : n->cycle_mark_default = makeBoolAConst(false, -1);
13282 : : n->cycle_path_column = $6;
13283 : : n->location = @1;
13284 : : $$ = (Node *) n;
13285 : : }
13286 : : | /*EMPTY*/
13287 : : {
13288 : : $$ = NULL;
13289 : : }
13290 : : ;
13291 : :
13292 : : opt_with_clause:
13293 : : with_clause { $$ = $1; }
13294 : : | /*EMPTY*/ { $$ = NULL; }
13295 : : ;
13296 : :
13297 : : into_clause:
13298 : : INTO OptTempTableName
13299 : : {
13300 : : $$ = makeNode(IntoClause);
13301 : : $$->rel = $2;
13302 : : $$->colNames = NIL;
13303 : : $$->options = NIL;
13304 : : $$->onCommit = ONCOMMIT_NOOP;
13305 : : $$->tableSpaceName = NULL;
13306 : : $$->viewQuery = NULL;
13307 : : $$->skipData = false;
13308 : : }
13309 : : | /*EMPTY*/
13310 : : { $$ = NULL; }
13311 : : ;
13312 : :
13313 : : /*
13314 : : * Redundancy here is needed to avoid shift/reduce conflicts,
13315 : : * since TEMP is not a reserved word. See also OptTemp.
13316 : : */
13317 : : OptTempTableName:
13318 : : TEMPORARY opt_table qualified_name
13319 : : {
13320 : : $$ = $3;
13321 : : $$->relpersistence = RELPERSISTENCE_TEMP;
13322 : : }
13323 : : | TEMP opt_table qualified_name
13324 : : {
13325 : : $$ = $3;
13326 : : $$->relpersistence = RELPERSISTENCE_TEMP;
13327 : : }
13328 : : | LOCAL TEMPORARY opt_table qualified_name
13329 : : {
13330 : : $$ = $4;
13331 : : $$->relpersistence = RELPERSISTENCE_TEMP;
13332 : : }
13333 : : | LOCAL TEMP opt_table qualified_name
13334 : : {
13335 : : $$ = $4;
13336 : : $$->relpersistence = RELPERSISTENCE_TEMP;
13337 : : }
13338 : : | GLOBAL TEMPORARY opt_table qualified_name
13339 : : {
13340 : : ereport(WARNING,
13341 : : (errmsg("GLOBAL is deprecated in temporary table creation"),
13342 : : parser_errposition(@1)));
13343 : : $$ = $4;
13344 : : $$->relpersistence = RELPERSISTENCE_TEMP;
13345 : : }
13346 : : | GLOBAL TEMP opt_table qualified_name
13347 : : {
13348 : : ereport(WARNING,
13349 : : (errmsg("GLOBAL is deprecated in temporary table creation"),
13350 : : parser_errposition(@1)));
13351 : : $$ = $4;
13352 : : $$->relpersistence = RELPERSISTENCE_TEMP;
13353 : : }
13354 : : | UNLOGGED opt_table qualified_name
13355 : : {
13356 : : $$ = $3;
13357 : : $$->relpersistence = RELPERSISTENCE_UNLOGGED;
13358 : : }
13359 : : | TABLE qualified_name
13360 : : {
13361 : : $$ = $2;
13362 : : $$->relpersistence = RELPERSISTENCE_PERMANENT;
13363 : : }
13364 : : | qualified_name
13365 : : {
13366 : : $$ = $1;
13367 : : $$->relpersistence = RELPERSISTENCE_PERMANENT;
13368 : : }
13369 : : ;
13370 : :
13371 : : opt_table: TABLE
13372 : : | /*EMPTY*/
13373 : : ;
13374 : :
13375 : : set_quantifier:
13376 : : ALL { $$ = SET_QUANTIFIER_ALL; }
13377 : : | DISTINCT { $$ = SET_QUANTIFIER_DISTINCT; }
13378 : : | /*EMPTY*/ { $$ = SET_QUANTIFIER_DEFAULT; }
13379 : : ;
13380 : :
13381 : : /* We use (NIL) as a placeholder to indicate that all target expressions
13382 : : * should be placed in the DISTINCT list during parsetree analysis.
13383 : : */
13384 : : distinct_clause:
13385 : : DISTINCT { $$ = list_make1(NIL); }
13386 : : | DISTINCT ON '(' expr_list ')' { $$ = $4; }
13387 : : ;
13388 : :
13389 : : opt_all_clause:
13390 : : ALL
13391 : : | /*EMPTY*/
13392 : : ;
13393 : :
13394 : : opt_distinct_clause:
13395 : : distinct_clause { $$ = $1; }
13396 : : | opt_all_clause { $$ = NIL; }
13397 : : ;
13398 : :
13399 : : opt_sort_clause:
13400 : : sort_clause { $$ = $1; }
13401 : : | /*EMPTY*/ { $$ = NIL; }
13402 : : ;
13403 : :
13404 : : sort_clause:
13405 : : ORDER BY sortby_list { $$ = $3; }
13406 : : ;
13407 : :
13408 : : sortby_list:
13409 : : sortby { $$ = list_make1($1); }
13410 : : | sortby_list ',' sortby { $$ = lappend($1, $3); }
13411 : : ;
13412 : :
13413 : : sortby: a_expr USING qual_all_Op opt_nulls_order
13414 : : {
13415 : : $$ = makeNode(SortBy);
13416 : : $$->node = $1;
13417 : : $$->sortby_dir = SORTBY_USING;
13418 : : $$->sortby_nulls = $4;
13419 : : $$->useOp = $3;
13420 : : $$->location = @3;
13421 : : }
13422 : : | a_expr opt_asc_desc opt_nulls_order
13423 : : {
13424 : : $$ = makeNode(SortBy);
13425 : : $$->node = $1;
13426 : : $$->sortby_dir = $2;
13427 : : $$->sortby_nulls = $3;
13428 : : $$->useOp = NIL;
13429 : : $$->location = -1; /* no operator */
13430 : : }
13431 : : ;
13432 : :
13433 : :
13434 : : select_limit:
13435 : : limit_clause offset_clause
13436 : : {
13437 : : $$ = $1;
13438 : : ($$)->limitOffset = $2;
13439 : : ($$)->offsetLoc = @2;
13440 : : }
13441 : : | offset_clause limit_clause
13442 : : {
13443 : : $$ = $2;
13444 : : ($$)->limitOffset = $1;
13445 : : ($$)->offsetLoc = @1;
13446 : : }
13447 : : | limit_clause
13448 : : {
13449 : : $$ = $1;
13450 : : }
13451 : : | offset_clause
13452 : : {
13453 : : SelectLimit *n = palloc_object(SelectLimit);
13454 : :
13455 : : n->limitOffset = $1;
13456 : : n->limitCount = NULL;
13457 : : n->limitOption = LIMIT_OPTION_COUNT;
13458 : : n->offsetLoc = @1;
13459 : : n->countLoc = -1;
13460 : : n->optionLoc = -1;
13461 : : $$ = n;
13462 : : }
13463 : : ;
13464 : :
13465 : : opt_select_limit:
13466 : : select_limit { $$ = $1; }
13467 : : | /* EMPTY */ { $$ = NULL; }
13468 : : ;
13469 : :
13470 : : limit_clause:
13471 : : LIMIT select_limit_value
13472 : : {
13473 : : SelectLimit *n = palloc_object(SelectLimit);
13474 : :
13475 : : n->limitOffset = NULL;
13476 : : n->limitCount = $2;
13477 : : n->limitOption = LIMIT_OPTION_COUNT;
13478 : : n->offsetLoc = -1;
13479 : : n->countLoc = @1;
13480 : : n->optionLoc = -1;
13481 : : $$ = n;
13482 : : }
13483 : : | LIMIT select_limit_value ',' select_offset_value
13484 : : {
13485 : : /* Disabled because it was too confusing, bjm 2002-02-18 */
13486 : : ereport(ERROR,
13487 : : (errcode(ERRCODE_SYNTAX_ERROR),
13488 : : errmsg("LIMIT #,# syntax is not supported"),
13489 : : errhint("Use separate LIMIT and OFFSET clauses."),
13490 : : parser_errposition(@1)));
13491 : : }
13492 : : /* SQL:2008 syntax */
13493 : : /* to avoid shift/reduce conflicts, handle the optional value with
13494 : : * a separate production rather than an opt_ expression. The fact
13495 : : * that ONLY is fully reserved means that this way, we defer any
13496 : : * decision about what rule reduces ROW or ROWS to the point where
13497 : : * we can see the ONLY token in the lookahead slot.
13498 : : */
13499 : : | FETCH first_or_next select_fetch_first_value row_or_rows ONLY
13500 : : {
13501 : : SelectLimit *n = palloc_object(SelectLimit);
13502 : :
13503 : : n->limitOffset = NULL;
13504 : : n->limitCount = $3;
13505 : : n->limitOption = LIMIT_OPTION_COUNT;
13506 : : n->offsetLoc = -1;
13507 : : n->countLoc = @1;
13508 : : n->optionLoc = -1;
13509 : : $$ = n;
13510 : : }
13511 : : | FETCH first_or_next select_fetch_first_value row_or_rows WITH TIES
13512 : : {
13513 : : SelectLimit *n = palloc_object(SelectLimit);
13514 : :
13515 : : n->limitOffset = NULL;
13516 : : n->limitCount = $3;
13517 : : n->limitOption = LIMIT_OPTION_WITH_TIES;
13518 : : n->offsetLoc = -1;
13519 : : n->countLoc = @1;
13520 : : n->optionLoc = @5;
13521 : : $$ = n;
13522 : : }
13523 : : | FETCH first_or_next row_or_rows ONLY
13524 : : {
13525 : : SelectLimit *n = palloc_object(SelectLimit);
13526 : :
13527 : : n->limitOffset = NULL;
13528 : : n->limitCount = makeIntConst(1, -1);
13529 : : n->limitOption = LIMIT_OPTION_COUNT;
13530 : : n->offsetLoc = -1;
13531 : : n->countLoc = @1;
13532 : : n->optionLoc = -1;
13533 : : $$ = n;
13534 : : }
13535 : : | FETCH first_or_next row_or_rows WITH TIES
13536 : : {
13537 : : SelectLimit *n = palloc_object(SelectLimit);
13538 : :
13539 : : n->limitOffset = NULL;
13540 : : n->limitCount = makeIntConst(1, -1);
13541 : : n->limitOption = LIMIT_OPTION_WITH_TIES;
13542 : : n->offsetLoc = -1;
13543 : : n->countLoc = @1;
13544 : : n->optionLoc = @4;
13545 : : $$ = n;
13546 : : }
13547 : : ;
13548 : :
13549 : : offset_clause:
13550 : : OFFSET select_offset_value
13551 : : { $$ = $2; }
13552 : : /* SQL:2008 syntax */
13553 : : | OFFSET select_fetch_first_value row_or_rows
13554 : : { $$ = $2; }
13555 : : ;
13556 : :
13557 : : select_limit_value:
13558 : : a_expr { $$ = $1; }
13559 : : | ALL
13560 : : {
13561 : : /* LIMIT ALL is represented as a NULL constant */
13562 : : $$ = makeNullAConst(@1);
13563 : : }
13564 : : ;
13565 : :
13566 : : select_offset_value:
13567 : : a_expr { $$ = $1; }
13568 : : ;
13569 : :
13570 : : /*
13571 : : * Allowing full expressions without parentheses causes various parsing
13572 : : * problems with the trailing ROW/ROWS key words. SQL spec only calls for
13573 : : * <simple value specification>, which is either a literal or a parameter (but
13574 : : * an <SQL parameter reference> could be an identifier, bringing up conflicts
13575 : : * with ROW/ROWS). We solve this by leveraging the presence of ONLY (see above)
13576 : : * to determine whether the expression is missing rather than trying to make it
13577 : : * optional in this rule.
13578 : : *
13579 : : * c_expr covers almost all the spec-required cases (and more), but it doesn't
13580 : : * cover signed numeric literals, which are allowed by the spec. So we include
13581 : : * those here explicitly. We need FCONST as well as ICONST because values that
13582 : : * don't fit in the platform's "long", but do fit in bigint, should still be
13583 : : * accepted here. (This is possible in 64-bit Windows as well as all 32-bit
13584 : : * builds.)
13585 : : */
13586 : : select_fetch_first_value:
13587 : : c_expr { $$ = $1; }
13588 : : | '+' I_or_F_const
13589 : : { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "+", NULL, $2, @1); }
13590 : : | '-' I_or_F_const
13591 : : { $$ = doNegate($2, @1); }
13592 : : ;
13593 : :
13594 : : I_or_F_const:
13595 : : Iconst { $$ = makeIntConst($1,@1); }
13596 : : | FCONST { $$ = makeFloatConst($1,@1); }
13597 : : ;
13598 : :
13599 : : /* noise words */
13600 : : row_or_rows: ROW { $$ = 0; }
13601 : : | ROWS { $$ = 0; }
13602 : : ;
13603 : :
13604 : : first_or_next: FIRST_P { $$ = 0; }
13605 : : | NEXT { $$ = 0; }
13606 : : ;
13607 : :
13608 : :
13609 : : /*
13610 : : * This syntax for group_clause tries to follow the spec quite closely.
13611 : : * However, the spec allows only column references, not expressions,
13612 : : * which introduces an ambiguity between implicit row constructors
13613 : : * (a,b) and lists of column references.
13614 : : *
13615 : : * We handle this by using the a_expr production for what the spec calls
13616 : : * <ordinary grouping set>, which in the spec represents either one column
13617 : : * reference or a parenthesized list of column references. Then, we check the
13618 : : * top node of the a_expr to see if it's an implicit RowExpr, and if so, just
13619 : : * grab and use the list, discarding the node. (this is done in parse analysis,
13620 : : * not here)
13621 : : *
13622 : : * (we abuse the row_format field of RowExpr to distinguish implicit and
13623 : : * explicit row constructors; it's debatable if anyone sanely wants to use them
13624 : : * in a group clause, but if they have a reason to, we make it possible.)
13625 : : *
13626 : : * Each item in the group_clause list is either an expression tree or a
13627 : : * GroupingSet node of some type.
13628 : : */
13629 : : group_clause:
13630 : : GROUP_P BY set_quantifier group_by_list
13631 : : {
13632 : : GroupClause *n = palloc_object(GroupClause);
13633 : :
13634 : : n->distinct = $3 == SET_QUANTIFIER_DISTINCT;
13635 : : n->all = false;
13636 : : n->list = $4;
13637 : : $$ = n;
13638 : : }
13639 : : | GROUP_P BY ALL
13640 : : {
13641 : : GroupClause *n = palloc_object(GroupClause);
13642 : : n->distinct = false;
13643 : : n->all = true;
13644 : : n->list = NIL;
13645 : : $$ = n;
13646 : : }
13647 : : | /*EMPTY*/
13648 : : {
13649 : : GroupClause *n = palloc_object(GroupClause);
13650 : :
13651 : : n->distinct = false;
13652 : : n->all = false;
13653 : : n->list = NIL;
13654 : : $$ = n;
13655 : : }
13656 : : ;
13657 : :
13658 : : group_by_list:
13659 : : group_by_item { $$ = list_make1($1); }
13660 : : | group_by_list ',' group_by_item { $$ = lappend($1,$3); }
13661 : : ;
13662 : :
13663 : : group_by_item:
13664 : : a_expr { $$ = $1; }
13665 : : | empty_grouping_set { $$ = $1; }
13666 : : | cube_clause { $$ = $1; }
13667 : : | rollup_clause { $$ = $1; }
13668 : : | grouping_sets_clause { $$ = $1; }
13669 : : ;
13670 : :
13671 : : empty_grouping_set:
13672 : : '(' ')'
13673 : : {
13674 : : $$ = (Node *) makeGroupingSet(GROUPING_SET_EMPTY, NIL, @1);
13675 : : }
13676 : : ;
13677 : :
13678 : : /*
13679 : : * These hacks rely on setting precedence of CUBE and ROLLUP below that of '(',
13680 : : * so that they shift in these rules rather than reducing the conflicting
13681 : : * unreserved_keyword rule.
13682 : : */
13683 : :
13684 : : rollup_clause:
13685 : : ROLLUP '(' expr_list ')'
13686 : : {
13687 : : $$ = (Node *) makeGroupingSet(GROUPING_SET_ROLLUP, $3, @1);
13688 : : }
13689 : : ;
13690 : :
13691 : : cube_clause:
13692 : : CUBE '(' expr_list ')'
13693 : : {
13694 : : $$ = (Node *) makeGroupingSet(GROUPING_SET_CUBE, $3, @1);
13695 : : }
13696 : : ;
13697 : :
13698 : : grouping_sets_clause:
13699 : : GROUPING SETS '(' group_by_list ')'
13700 : : {
13701 : : $$ = (Node *) makeGroupingSet(GROUPING_SET_SETS, $4, @1);
13702 : : }
13703 : : ;
13704 : :
13705 : : having_clause:
13706 : : HAVING a_expr { $$ = $2; }
13707 : : | /*EMPTY*/ { $$ = NULL; }
13708 : : ;
13709 : :
13710 : : for_locking_clause:
13711 : : for_locking_items { $$ = $1; }
13712 : : | FOR READ ONLY { $$ = NIL; }
13713 : : ;
13714 : :
13715 : : opt_for_locking_clause:
13716 : : for_locking_clause { $$ = $1; }
13717 : : | /* EMPTY */ { $$ = NIL; }
13718 : : ;
13719 : :
13720 : : for_locking_items:
13721 : : for_locking_item { $$ = list_make1($1); }
13722 : : | for_locking_items for_locking_item { $$ = lappend($1, $2); }
13723 : : ;
13724 : :
13725 : : for_locking_item:
13726 : : for_locking_strength locked_rels_list opt_nowait_or_skip
13727 : : {
13728 : : LockingClause *n = makeNode(LockingClause);
13729 : :
13730 : : n->lockedRels = $2;
13731 : : n->strength = $1;
13732 : : n->waitPolicy = $3;
13733 : : $$ = (Node *) n;
13734 : : }
13735 : : ;
13736 : :
13737 : : for_locking_strength:
13738 : : FOR UPDATE { $$ = LCS_FORUPDATE; }
13739 : : | FOR NO KEY UPDATE { $$ = LCS_FORNOKEYUPDATE; }
13740 : : | FOR SHARE { $$ = LCS_FORSHARE; }
13741 : : | FOR KEY SHARE { $$ = LCS_FORKEYSHARE; }
13742 : : ;
13743 : :
13744 : : locked_rels_list:
13745 : : OF qualified_name_list { $$ = $2; }
13746 : : | /* EMPTY */ { $$ = NIL; }
13747 : : ;
13748 : :
13749 : :
13750 : : /*
13751 : : * We should allow ROW '(' expr_list ')' too, but that seems to require
13752 : : * making VALUES a fully reserved word, which will probably break more apps
13753 : : * than allowing the noise-word is worth.
13754 : : */
13755 : : values_clause:
13756 : : VALUES '(' expr_list ')'
13757 : : {
13758 : : SelectStmt *n = makeNode(SelectStmt);
13759 : :
13760 : : n->valuesLists = list_make1($3);
13761 : : $$ = (Node *) n;
13762 : : }
13763 : : | values_clause ',' '(' expr_list ')'
13764 : : {
13765 : : SelectStmt *n = (SelectStmt *) $1;
13766 : :
13767 : : n->valuesLists = lappend(n->valuesLists, $4);
13768 : : $$ = (Node *) n;
13769 : : }
13770 : : ;
13771 : :
13772 : :
13773 : : /*****************************************************************************
13774 : : *
13775 : : * clauses common to all Optimizable Stmts:
13776 : : * from_clause - allow list of both JOIN expressions and table names
13777 : : * where_clause - qualifications for joins or restrictions
13778 : : *
13779 : : *****************************************************************************/
13780 : :
13781 : : from_clause:
13782 : : FROM from_list { $$ = $2; }
13783 : : | /*EMPTY*/ { $$ = NIL; }
13784 : : ;
13785 : :
13786 : : from_list:
13787 : : table_ref { $$ = list_make1($1); }
13788 : : | from_list ',' table_ref { $$ = lappend($1, $3); }
13789 : : ;
13790 : :
13791 : : /*
13792 : : * table_ref is where an alias clause can be attached.
13793 : : */
13794 : : table_ref: relation_expr opt_alias_clause
13795 : : {
13796 : : $1->alias = $2;
13797 : : $$ = (Node *) $1;
13798 : : }
13799 : : | relation_expr opt_alias_clause tablesample_clause
13800 : : {
13801 : : RangeTableSample *n = (RangeTableSample *) $3;
13802 : :
13803 : : $1->alias = $2;
13804 : : /* relation_expr goes inside the RangeTableSample node */
13805 : : n->relation = (Node *) $1;
13806 : : $$ = (Node *) n;
13807 : : }
13808 : : | func_table func_alias_clause
13809 : : {
13810 : : RangeFunction *n = (RangeFunction *) $1;
13811 : :
13812 : : n->alias = linitial($2);
13813 : : n->coldeflist = lsecond($2);
13814 : : $$ = (Node *) n;
13815 : : }
13816 : : | LATERAL_P func_table func_alias_clause
13817 : : {
13818 : : RangeFunction *n = (RangeFunction *) $2;
13819 : :
13820 : : n->lateral = true;
13821 : : n->alias = linitial($3);
13822 : : n->coldeflist = lsecond($3);
13823 : : $$ = (Node *) n;
13824 : : }
13825 : : | xmltable opt_alias_clause
13826 : : {
13827 : : RangeTableFunc *n = (RangeTableFunc *) $1;
13828 : :
13829 : : n->alias = $2;
13830 : : $$ = (Node *) n;
13831 : : }
13832 : : | LATERAL_P xmltable opt_alias_clause
13833 : : {
13834 : : RangeTableFunc *n = (RangeTableFunc *) $2;
13835 : :
13836 : : n->lateral = true;
13837 : : n->alias = $3;
13838 : : $$ = (Node *) n;
13839 : : }
13840 : : | select_with_parens opt_alias_clause
13841 : : {
13842 : : RangeSubselect *n = makeNode(RangeSubselect);
13843 : :
13844 : : n->lateral = false;
13845 : : n->subquery = $1;
13846 : : n->alias = $2;
13847 : : $$ = (Node *) n;
13848 : : }
13849 : : | LATERAL_P select_with_parens opt_alias_clause
13850 : : {
13851 : : RangeSubselect *n = makeNode(RangeSubselect);
13852 : :
13853 : : n->lateral = true;
13854 : : n->subquery = $2;
13855 : : n->alias = $3;
13856 : : $$ = (Node *) n;
13857 : : }
13858 : : | joined_table
13859 : : {
13860 : : $$ = (Node *) $1;
13861 : : }
13862 : : | '(' joined_table ')' alias_clause
13863 : : {
13864 : : $2->alias = $4;
13865 : : $$ = (Node *) $2;
13866 : : }
13867 : : | json_table opt_alias_clause
13868 : : {
13869 : : JsonTable *jt = castNode(JsonTable, $1);
13870 : :
13871 : : jt->alias = $2;
13872 : : $$ = (Node *) jt;
13873 : : }
13874 : : | LATERAL_P json_table opt_alias_clause
13875 : : {
13876 : : JsonTable *jt = castNode(JsonTable, $2);
13877 : :
13878 : : jt->alias = $3;
13879 : : jt->lateral = true;
13880 : : $$ = (Node *) jt;
13881 : : }
13882 : : ;
13883 : :
13884 : :
13885 : : /*
13886 : : * It may seem silly to separate joined_table from table_ref, but there is
13887 : : * method in SQL's madness: if you don't do it this way you get reduce-
13888 : : * reduce conflicts, because it's not clear to the parser generator whether
13889 : : * to expect alias_clause after ')' or not. For the same reason we must
13890 : : * treat 'JOIN' and 'join_type JOIN' separately, rather than allowing
13891 : : * join_type to expand to empty; if we try it, the parser generator can't
13892 : : * figure out when to reduce an empty join_type right after table_ref.
13893 : : *
13894 : : * Note that a CROSS JOIN is the same as an unqualified
13895 : : * INNER JOIN, and an INNER JOIN/ON has the same shape
13896 : : * but a qualification expression to limit membership.
13897 : : * A NATURAL JOIN implicitly matches column names between
13898 : : * tables and the shape is determined by which columns are
13899 : : * in common. We'll collect columns during the later transformations.
13900 : : */
13901 : :
13902 : : joined_table:
13903 : : '(' joined_table ')'
13904 : : {
13905 : : $$ = $2;
13906 : : }
13907 : : | table_ref CROSS JOIN table_ref
13908 : : {
13909 : : /* CROSS JOIN is same as unqualified inner join */
13910 : : JoinExpr *n = makeNode(JoinExpr);
13911 : :
13912 : : n->jointype = JOIN_INNER;
13913 : : n->isNatural = false;
13914 : : n->larg = $1;
13915 : : n->rarg = $4;
13916 : : n->usingClause = NIL;
13917 : : n->join_using_alias = NULL;
13918 : : n->quals = NULL;
13919 : : $$ = n;
13920 : : }
13921 : : | table_ref join_type JOIN table_ref join_qual
13922 : : {
13923 : : JoinExpr *n = makeNode(JoinExpr);
13924 : :
13925 : : n->jointype = $2;
13926 : : n->isNatural = false;
13927 : : n->larg = $1;
13928 : : n->rarg = $4;
13929 : : if ($5 != NULL && IsA($5, List))
13930 : : {
13931 : : /* USING clause */
13932 : : n->usingClause = linitial_node(List, castNode(List, $5));
13933 : : n->join_using_alias = lsecond_node(Alias, castNode(List, $5));
13934 : : }
13935 : : else
13936 : : {
13937 : : /* ON clause */
13938 : : n->quals = $5;
13939 : : }
13940 : : $$ = n;
13941 : : }
13942 : : | table_ref JOIN table_ref join_qual
13943 : : {
13944 : : /* letting join_type reduce to empty doesn't work */
13945 : : JoinExpr *n = makeNode(JoinExpr);
13946 : :
13947 : : n->jointype = JOIN_INNER;
13948 : : n->isNatural = false;
13949 : : n->larg = $1;
13950 : : n->rarg = $3;
13951 : : if ($4 != NULL && IsA($4, List))
13952 : : {
13953 : : /* USING clause */
13954 : : n->usingClause = linitial_node(List, castNode(List, $4));
13955 : : n->join_using_alias = lsecond_node(Alias, castNode(List, $4));
13956 : : }
13957 : : else
13958 : : {
13959 : : /* ON clause */
13960 : : n->quals = $4;
13961 : : }
13962 : : $$ = n;
13963 : : }
13964 : : | table_ref NATURAL join_type JOIN table_ref
13965 : : {
13966 : : JoinExpr *n = makeNode(JoinExpr);
13967 : :
13968 : : n->jointype = $3;
13969 : : n->isNatural = true;
13970 : : n->larg = $1;
13971 : : n->rarg = $5;
13972 : : n->usingClause = NIL; /* figure out which columns later... */
13973 : : n->join_using_alias = NULL;
13974 : : n->quals = NULL; /* fill later */
13975 : : $$ = n;
13976 : : }
13977 : : | table_ref NATURAL JOIN table_ref
13978 : : {
13979 : : /* letting join_type reduce to empty doesn't work */
13980 : : JoinExpr *n = makeNode(JoinExpr);
13981 : :
13982 : : n->jointype = JOIN_INNER;
13983 : : n->isNatural = true;
13984 : : n->larg = $1;
13985 : : n->rarg = $4;
13986 : : n->usingClause = NIL; /* figure out which columns later... */
13987 : : n->join_using_alias = NULL;
13988 : : n->quals = NULL; /* fill later */
13989 : : $$ = n;
13990 : : }
13991 : : ;
13992 : :
13993 : : alias_clause:
13994 : : AS ColId '(' name_list ')'
13995 : : {
13996 : : $$ = makeNode(Alias);
13997 : : $$->aliasname = $2;
13998 : : $$->colnames = $4;
13999 : : }
14000 : : | AS ColId
14001 : : {
14002 : : $$ = makeNode(Alias);
14003 : : $$->aliasname = $2;
14004 : : }
14005 : : | ColId '(' name_list ')'
14006 : : {
14007 : : $$ = makeNode(Alias);
14008 : : $$->aliasname = $1;
14009 : : $$->colnames = $3;
14010 : : }
14011 : : | ColId
14012 : : {
14013 : : $$ = makeNode(Alias);
14014 : : $$->aliasname = $1;
14015 : : }
14016 : : ;
14017 : :
14018 : : opt_alias_clause: alias_clause { $$ = $1; }
14019 : : | /*EMPTY*/ { $$ = NULL; }
14020 : : ;
14021 : :
14022 : : /*
14023 : : * The alias clause after JOIN ... USING only accepts the AS ColId spelling,
14024 : : * per SQL standard. (The grammar could parse the other variants, but they
14025 : : * don't seem to be useful, and it might lead to parser problems in the
14026 : : * future.)
14027 : : */
14028 : : opt_alias_clause_for_join_using:
14029 : : AS ColId
14030 : : {
14031 : : $$ = makeNode(Alias);
14032 : : $$->aliasname = $2;
14033 : : /* the column name list will be inserted later */
14034 : : }
14035 : : | /*EMPTY*/ { $$ = NULL; }
14036 : : ;
14037 : :
14038 : : /*
14039 : : * func_alias_clause can include both an Alias and a coldeflist, so we make it
14040 : : * return a 2-element list that gets disassembled by calling production.
14041 : : */
14042 : : func_alias_clause:
14043 : : alias_clause
14044 : : {
14045 : : $$ = list_make2($1, NIL);
14046 : : }
14047 : : | AS '(' TableFuncElementList ')'
14048 : : {
14049 : : $$ = list_make2(NULL, $3);
14050 : : }
14051 : : | AS ColId '(' TableFuncElementList ')'
14052 : : {
14053 : : Alias *a = makeNode(Alias);
14054 : :
14055 : : a->aliasname = $2;
14056 : : $$ = list_make2(a, $4);
14057 : : }
14058 : : | ColId '(' TableFuncElementList ')'
14059 : : {
14060 : : Alias *a = makeNode(Alias);
14061 : :
14062 : : a->aliasname = $1;
14063 : : $$ = list_make2(a, $3);
14064 : : }
14065 : : | /*EMPTY*/
14066 : : {
14067 : : $$ = list_make2(NULL, NIL);
14068 : : }
14069 : : ;
14070 : :
14071 : : join_type: FULL opt_outer { $$ = JOIN_FULL; }
14072 : : | LEFT opt_outer { $$ = JOIN_LEFT; }
14073 : : | RIGHT opt_outer { $$ = JOIN_RIGHT; }
14074 : : | INNER_P { $$ = JOIN_INNER; }
14075 : : ;
14076 : :
14077 : : /* OUTER is just noise... */
14078 : : opt_outer: OUTER_P
14079 : : | /*EMPTY*/
14080 : : ;
14081 : :
14082 : : /* JOIN qualification clauses
14083 : : * Possibilities are:
14084 : : * USING ( column list ) [ AS alias ]
14085 : : * allows only unqualified column names,
14086 : : * which must match between tables.
14087 : : * ON expr allows more general qualifications.
14088 : : *
14089 : : * We return USING as a two-element List (the first item being a sub-List
14090 : : * of the common column names, and the second either an Alias item or NULL).
14091 : : * An ON-expr will not be a List, so it can be told apart that way.
14092 : : */
14093 : :
14094 : : join_qual: USING '(' name_list ')' opt_alias_clause_for_join_using
14095 : : {
14096 : : $$ = (Node *) list_make2($3, $5);
14097 : : }
14098 : : | ON a_expr
14099 : : {
14100 : : $$ = $2;
14101 : : }
14102 : : ;
14103 : :
14104 : :
14105 : : relation_expr:
14106 : : qualified_name
14107 : : {
14108 : : /* inheritance query, implicitly */
14109 : : $$ = $1;
14110 : : $$->inh = true;
14111 : : $$->alias = NULL;
14112 : : }
14113 : : | extended_relation_expr
14114 : : {
14115 : : $$ = $1;
14116 : : }
14117 : : ;
14118 : :
14119 : : extended_relation_expr:
14120 : : qualified_name '*'
14121 : : {
14122 : : /* inheritance query, explicitly */
14123 : : $$ = $1;
14124 : : $$->inh = true;
14125 : : $$->alias = NULL;
14126 : : }
14127 : : | ONLY qualified_name
14128 : : {
14129 : : /* no inheritance */
14130 : : $$ = $2;
14131 : : $$->inh = false;
14132 : : $$->alias = NULL;
14133 : : }
14134 : : | ONLY '(' qualified_name ')'
14135 : : {
14136 : : /* no inheritance, SQL99-style syntax */
14137 : : $$ = $3;
14138 : : $$->inh = false;
14139 : : $$->alias = NULL;
14140 : : }
14141 : : ;
14142 : :
14143 : :
14144 : : relation_expr_list:
14145 : : relation_expr { $$ = list_make1($1); }
14146 : : | relation_expr_list ',' relation_expr { $$ = lappend($1, $3); }
14147 : : ;
14148 : :
14149 : :
14150 : : /*
14151 : : * Given "UPDATE foo set set ...", we have to decide without looking any
14152 : : * further ahead whether the first "set" is an alias or the UPDATE's SET
14153 : : * keyword. Since "set" is allowed as a column name both interpretations
14154 : : * are feasible. We resolve the shift/reduce conflict by giving the first
14155 : : * relation_expr_opt_alias production a higher precedence than the SET token
14156 : : * has, causing the parser to prefer to reduce, in effect assuming that the
14157 : : * SET is not an alias.
14158 : : */
14159 : : relation_expr_opt_alias: relation_expr %prec UMINUS
14160 : : {
14161 : : $$ = $1;
14162 : : }
14163 : : | relation_expr ColId
14164 : : {
14165 : : Alias *alias = makeNode(Alias);
14166 : :
14167 : : alias->aliasname = $2;
14168 : : $1->alias = alias;
14169 : : $$ = $1;
14170 : : }
14171 : : | relation_expr AS ColId
14172 : : {
14173 : : Alias *alias = makeNode(Alias);
14174 : :
14175 : : alias->aliasname = $3;
14176 : : $1->alias = alias;
14177 : : $$ = $1;
14178 : : }
14179 : : ;
14180 : :
14181 : : /*
14182 : : * TABLESAMPLE decoration in a FROM item
14183 : : */
14184 : : tablesample_clause:
14185 : : TABLESAMPLE func_name '(' expr_list ')' opt_repeatable_clause
14186 : : {
14187 : : RangeTableSample *n = makeNode(RangeTableSample);
14188 : :
14189 : : /* n->relation will be filled in later */
14190 : : n->method = $2;
14191 : : n->args = $4;
14192 : : n->repeatable = $6;
14193 : : n->location = @2;
14194 : : $$ = (Node *) n;
14195 : : }
14196 : : ;
14197 : :
14198 : : opt_repeatable_clause:
14199 : : REPEATABLE '(' a_expr ')' { $$ = (Node *) $3; }
14200 : : | /*EMPTY*/ { $$ = NULL; }
14201 : : ;
14202 : :
14203 : : /*
14204 : : * func_table represents a function invocation in a FROM list. It can be
14205 : : * a plain function call, like "foo(...)", or a ROWS FROM expression with
14206 : : * one or more function calls, "ROWS FROM (foo(...), bar(...))",
14207 : : * optionally with WITH ORDINALITY attached.
14208 : : * In the ROWS FROM syntax, a column definition list can be given for each
14209 : : * function, for example:
14210 : : * ROWS FROM (foo() AS (foo_res_a text, foo_res_b text),
14211 : : * bar() AS (bar_res_a text, bar_res_b text))
14212 : : * It's also possible to attach a column definition list to the RangeFunction
14213 : : * as a whole, but that's handled by the table_ref production.
14214 : : */
14215 : : func_table: func_expr_windowless opt_ordinality
14216 : : {
14217 : : RangeFunction *n = makeNode(RangeFunction);
14218 : :
14219 : : n->lateral = false;
14220 : : n->ordinality = $2;
14221 : : n->is_rowsfrom = false;
14222 : : n->functions = list_make1(list_make2($1, NIL));
14223 : : /* alias and coldeflist are set by table_ref production */
14224 : : $$ = (Node *) n;
14225 : : }
14226 : : | ROWS FROM '(' rowsfrom_list ')' opt_ordinality
14227 : : {
14228 : : RangeFunction *n = makeNode(RangeFunction);
14229 : :
14230 : : n->lateral = false;
14231 : : n->ordinality = $6;
14232 : : n->is_rowsfrom = true;
14233 : : n->functions = $4;
14234 : : /* alias and coldeflist are set by table_ref production */
14235 : : $$ = (Node *) n;
14236 : : }
14237 : : ;
14238 : :
14239 : : rowsfrom_item: func_expr_windowless opt_col_def_list
14240 : : { $$ = list_make2($1, $2); }
14241 : : ;
14242 : :
14243 : : rowsfrom_list:
14244 : : rowsfrom_item { $$ = list_make1($1); }
14245 : : | rowsfrom_list ',' rowsfrom_item { $$ = lappend($1, $3); }
14246 : : ;
14247 : :
14248 : : opt_col_def_list: AS '(' TableFuncElementList ')' { $$ = $3; }
14249 : : | /*EMPTY*/ { $$ = NIL; }
14250 : : ;
14251 : :
14252 : : opt_ordinality: WITH_LA ORDINALITY { $$ = true; }
14253 : : | /*EMPTY*/ { $$ = false; }
14254 : : ;
14255 : :
14256 : :
14257 : : where_clause:
14258 : : WHERE a_expr { $$ = $2; }
14259 : : | /*EMPTY*/ { $$ = NULL; }
14260 : : ;
14261 : :
14262 : : /* variant for UPDATE and DELETE */
14263 : : where_or_current_clause:
14264 : : WHERE a_expr { $$ = $2; }
14265 : : | WHERE CURRENT_P OF cursor_name
14266 : : {
14267 : : CurrentOfExpr *n = makeNode(CurrentOfExpr);
14268 : :
14269 : : /* cvarno is filled in by parse analysis */
14270 : : n->cursor_name = $4;
14271 : : n->cursor_param = 0;
14272 : : $$ = (Node *) n;
14273 : : }
14274 : : | /*EMPTY*/ { $$ = NULL; }
14275 : : ;
14276 : :
14277 : :
14278 : : OptTableFuncElementList:
14279 : : TableFuncElementList { $$ = $1; }
14280 : : | /*EMPTY*/ { $$ = NIL; }
14281 : : ;
14282 : :
14283 : : TableFuncElementList:
14284 : : TableFuncElement
14285 : : {
14286 : : $$ = list_make1($1);
14287 : : }
14288 : : | TableFuncElementList ',' TableFuncElement
14289 : : {
14290 : : $$ = lappend($1, $3);
14291 : : }
14292 : : ;
14293 : :
14294 : : TableFuncElement: ColId Typename opt_collate_clause
14295 : : {
14296 : : ColumnDef *n = makeNode(ColumnDef);
14297 : :
14298 : : n->colname = $1;
14299 : : n->typeName = $2;
14300 : : n->inhcount = 0;
14301 : : n->is_local = true;
14302 : : n->is_not_null = false;
14303 : : n->is_from_type = false;
14304 : : n->storage = 0;
14305 : : n->raw_default = NULL;
14306 : : n->cooked_default = NULL;
14307 : : n->collClause = (CollateClause *) $3;
14308 : : n->collOid = InvalidOid;
14309 : : n->constraints = NIL;
14310 : : n->location = @1;
14311 : : $$ = (Node *) n;
14312 : : }
14313 : : ;
14314 : :
14315 : : /*
14316 : : * XMLTABLE
14317 : : */
14318 : : xmltable:
14319 : : XMLTABLE '(' c_expr xmlexists_argument COLUMNS xmltable_column_list ')'
14320 : : {
14321 : : RangeTableFunc *n = makeNode(RangeTableFunc);
14322 : :
14323 : : n->rowexpr = $3;
14324 : : n->docexpr = $4;
14325 : : n->columns = $6;
14326 : : n->namespaces = NIL;
14327 : : n->location = @1;
14328 : : $$ = (Node *) n;
14329 : : }
14330 : : | XMLTABLE '(' XMLNAMESPACES '(' xml_namespace_list ')' ','
14331 : : c_expr xmlexists_argument COLUMNS xmltable_column_list ')'
14332 : : {
14333 : : RangeTableFunc *n = makeNode(RangeTableFunc);
14334 : :
14335 : : n->rowexpr = $8;
14336 : : n->docexpr = $9;
14337 : : n->columns = $11;
14338 : : n->namespaces = $5;
14339 : : n->location = @1;
14340 : : $$ = (Node *) n;
14341 : : }
14342 : : ;
14343 : :
14344 : : xmltable_column_list: xmltable_column_el { $$ = list_make1($1); }
14345 : : | xmltable_column_list ',' xmltable_column_el { $$ = lappend($1, $3); }
14346 : : ;
14347 : :
14348 : : xmltable_column_el:
14349 : : ColId Typename
14350 : : {
14351 : : RangeTableFuncCol *fc = makeNode(RangeTableFuncCol);
14352 : :
14353 : : fc->colname = $1;
14354 : : fc->for_ordinality = false;
14355 : : fc->typeName = $2;
14356 : : fc->is_not_null = false;
14357 : : fc->colexpr = NULL;
14358 : : fc->coldefexpr = NULL;
14359 : : fc->location = @1;
14360 : :
14361 : : $$ = (Node *) fc;
14362 : : }
14363 : : | ColId Typename xmltable_column_option_list
14364 : : {
14365 : : RangeTableFuncCol *fc = makeNode(RangeTableFuncCol);
14366 : : ListCell *option;
14367 : : bool nullability_seen = false;
14368 : :
14369 : : fc->colname = $1;
14370 : : fc->typeName = $2;
14371 : : fc->for_ordinality = false;
14372 : : fc->is_not_null = false;
14373 : : fc->colexpr = NULL;
14374 : : fc->coldefexpr = NULL;
14375 : : fc->location = @1;
14376 : :
14377 : : foreach(option, $3)
14378 : : {
14379 : : DefElem *defel = (DefElem *) lfirst(option);
14380 : :
14381 : : if (strcmp(defel->defname, "default") == 0)
14382 : : {
14383 : : if (fc->coldefexpr != NULL)
14384 : : ereport(ERROR,
14385 : : (errcode(ERRCODE_SYNTAX_ERROR),
14386 : : errmsg("only one DEFAULT value is allowed"),
14387 : : parser_errposition(defel->location)));
14388 : : fc->coldefexpr = defel->arg;
14389 : : }
14390 : : else if (strcmp(defel->defname, "path") == 0)
14391 : : {
14392 : : if (fc->colexpr != NULL)
14393 : : ereport(ERROR,
14394 : : (errcode(ERRCODE_SYNTAX_ERROR),
14395 : : errmsg("only one PATH value per column is allowed"),
14396 : : parser_errposition(defel->location)));
14397 : : fc->colexpr = defel->arg;
14398 : : }
14399 : : else if (strcmp(defel->defname, "__pg__is_not_null") == 0)
14400 : : {
14401 : : if (nullability_seen)
14402 : : ereport(ERROR,
14403 : : (errcode(ERRCODE_SYNTAX_ERROR),
14404 : : errmsg("conflicting or redundant NULL / NOT NULL declarations for column \"%s\"", fc->colname),
14405 : : parser_errposition(defel->location)));
14406 : : fc->is_not_null = boolVal(defel->arg);
14407 : : nullability_seen = true;
14408 : : }
14409 : : else
14410 : : {
14411 : : ereport(ERROR,
14412 : : (errcode(ERRCODE_SYNTAX_ERROR),
14413 : : errmsg("unrecognized column option \"%s\"",
14414 : : defel->defname),
14415 : : parser_errposition(defel->location)));
14416 : : }
14417 : : }
14418 : : $$ = (Node *) fc;
14419 : : }
14420 : : | ColId FOR ORDINALITY
14421 : : {
14422 : : RangeTableFuncCol *fc = makeNode(RangeTableFuncCol);
14423 : :
14424 : : fc->colname = $1;
14425 : : fc->for_ordinality = true;
14426 : : /* other fields are ignored, initialized by makeNode */
14427 : : fc->location = @1;
14428 : :
14429 : : $$ = (Node *) fc;
14430 : : }
14431 : : ;
14432 : :
14433 : : xmltable_column_option_list:
14434 : : xmltable_column_option_el
14435 : : { $$ = list_make1($1); }
14436 : : | xmltable_column_option_list xmltable_column_option_el
14437 : : { $$ = lappend($1, $2); }
14438 : : ;
14439 : :
14440 : : xmltable_column_option_el:
14441 : : IDENT b_expr
14442 : : {
14443 : : if (strcmp($1, "__pg__is_not_null") == 0)
14444 : : ereport(ERROR,
14445 : : (errcode(ERRCODE_SYNTAX_ERROR),
14446 : : errmsg("option name \"%s\" cannot be used in XMLTABLE", $1),
14447 : : parser_errposition(@1)));
14448 : : $$ = makeDefElem($1, $2, @1);
14449 : : }
14450 : : | DEFAULT b_expr
14451 : : { $$ = makeDefElem("default", $2, @1); }
14452 : : | NOT NULL_P
14453 : : { $$ = makeDefElem("__pg__is_not_null", (Node *) makeBoolean(true), @1); }
14454 : : | NULL_P
14455 : : { $$ = makeDefElem("__pg__is_not_null", (Node *) makeBoolean(false), @1); }
14456 : : | PATH b_expr
14457 : : { $$ = makeDefElem("path", $2, @1); }
14458 : : ;
14459 : :
14460 : : xml_namespace_list:
14461 : : xml_namespace_el
14462 : : { $$ = list_make1($1); }
14463 : : | xml_namespace_list ',' xml_namespace_el
14464 : : { $$ = lappend($1, $3); }
14465 : : ;
14466 : :
14467 : : xml_namespace_el:
14468 : : b_expr AS ColLabel
14469 : : {
14470 : : $$ = makeNode(ResTarget);
14471 : : $$->name = $3;
14472 : : $$->indirection = NIL;
14473 : : $$->val = $1;
14474 : : $$->location = @1;
14475 : : }
14476 : : | DEFAULT b_expr
14477 : : {
14478 : : $$ = makeNode(ResTarget);
14479 : : $$->name = NULL;
14480 : : $$->indirection = NIL;
14481 : : $$->val = $2;
14482 : : $$->location = @1;
14483 : : }
14484 : : ;
14485 : :
14486 : : json_table:
14487 : : JSON_TABLE '('
14488 : : json_value_expr ',' a_expr json_table_path_name_opt
14489 : : json_passing_clause_opt
14490 : : COLUMNS '(' json_table_column_definition_list ')'
14491 : : json_on_error_clause_opt
14492 : : ')'
14493 : : {
14494 : : JsonTable *n = makeNode(JsonTable);
14495 : : char *pathstring;
14496 : :
14497 : : n->context_item = (JsonValueExpr *) $3;
14498 : : if (!IsA($5, A_Const) ||
14499 : : castNode(A_Const, $5)->val.node.type != T_String)
14500 : : ereport(ERROR,
14501 : : errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
14502 : : errmsg("only string constants are supported in JSON_TABLE path specification"),
14503 : : parser_errposition(@5));
14504 : : pathstring = castNode(A_Const, $5)->val.sval.sval;
14505 : : n->pathspec = makeJsonTablePathSpec(pathstring, $6, @5, @6);
14506 : : n->passing = $7;
14507 : : n->columns = $10;
14508 : : n->on_error = (JsonBehavior *) $12;
14509 : : n->location = @1;
14510 : : $$ = (Node *) n;
14511 : : }
14512 : : ;
14513 : :
14514 : : json_table_path_name_opt:
14515 : : AS name { $$ = $2; }
14516 : : | /* empty */ { $$ = NULL; }
14517 : : ;
14518 : :
14519 : : json_table_column_definition_list:
14520 : : json_table_column_definition
14521 : : { $$ = list_make1($1); }
14522 : : | json_table_column_definition_list ',' json_table_column_definition
14523 : : { $$ = lappend($1, $3); }
14524 : : ;
14525 : :
14526 : : json_table_column_definition:
14527 : : ColId FOR ORDINALITY
14528 : : {
14529 : : JsonTableColumn *n = makeNode(JsonTableColumn);
14530 : :
14531 : : n->coltype = JTC_FOR_ORDINALITY;
14532 : : n->name = $1;
14533 : : n->location = @1;
14534 : : $$ = (Node *) n;
14535 : : }
14536 : : | ColId Typename
14537 : : json_table_column_path_clause_opt
14538 : : json_wrapper_behavior
14539 : : json_quotes_clause_opt
14540 : : json_behavior_clause_opt
14541 : : {
14542 : : JsonTableColumn *n = makeNode(JsonTableColumn);
14543 : :
14544 : : n->coltype = JTC_REGULAR;
14545 : : n->name = $1;
14546 : : n->typeName = $2;
14547 : : n->format = makeJsonFormat(JS_FORMAT_DEFAULT, JS_ENC_DEFAULT, -1);
14548 : : n->pathspec = (JsonTablePathSpec *) $3;
14549 : : n->wrapper = $4;
14550 : : n->quotes = $5;
14551 : : n->on_empty = (JsonBehavior *) linitial($6);
14552 : : n->on_error = (JsonBehavior *) lsecond($6);
14553 : : n->location = @1;
14554 : : $$ = (Node *) n;
14555 : : }
14556 : : | ColId Typename json_format_clause
14557 : : json_table_column_path_clause_opt
14558 : : json_wrapper_behavior
14559 : : json_quotes_clause_opt
14560 : : json_behavior_clause_opt
14561 : : {
14562 : : JsonTableColumn *n = makeNode(JsonTableColumn);
14563 : :
14564 : : n->coltype = JTC_FORMATTED;
14565 : : n->name = $1;
14566 : : n->typeName = $2;
14567 : : n->format = (JsonFormat *) $3;
14568 : : n->pathspec = (JsonTablePathSpec *) $4;
14569 : : n->wrapper = $5;
14570 : : n->quotes = $6;
14571 : : n->on_empty = (JsonBehavior *) linitial($7);
14572 : : n->on_error = (JsonBehavior *) lsecond($7);
14573 : : n->location = @1;
14574 : : $$ = (Node *) n;
14575 : : }
14576 : : | ColId Typename
14577 : : EXISTS json_table_column_path_clause_opt
14578 : : json_on_error_clause_opt
14579 : : {
14580 : : JsonTableColumn *n = makeNode(JsonTableColumn);
14581 : :
14582 : : n->coltype = JTC_EXISTS;
14583 : : n->name = $1;
14584 : : n->typeName = $2;
14585 : : n->format = makeJsonFormat(JS_FORMAT_DEFAULT, JS_ENC_DEFAULT, -1);
14586 : : n->wrapper = JSW_NONE;
14587 : : n->quotes = JS_QUOTES_UNSPEC;
14588 : : n->pathspec = (JsonTablePathSpec *) $4;
14589 : : n->on_empty = NULL;
14590 : : n->on_error = (JsonBehavior *) $5;
14591 : : n->location = @1;
14592 : : $$ = (Node *) n;
14593 : : }
14594 : : | NESTED path_opt Sconst
14595 : : COLUMNS '(' json_table_column_definition_list ')'
14596 : : {
14597 : : JsonTableColumn *n = makeNode(JsonTableColumn);
14598 : :
14599 : : n->coltype = JTC_NESTED;
14600 : : n->pathspec = (JsonTablePathSpec *)
14601 : : makeJsonTablePathSpec($3, NULL, @3, -1);
14602 : : n->columns = $6;
14603 : : n->location = @1;
14604 : : $$ = (Node *) n;
14605 : : }
14606 : : | NESTED path_opt Sconst AS name
14607 : : COLUMNS '(' json_table_column_definition_list ')'
14608 : : {
14609 : : JsonTableColumn *n = makeNode(JsonTableColumn);
14610 : :
14611 : : n->coltype = JTC_NESTED;
14612 : : n->pathspec = (JsonTablePathSpec *)
14613 : : makeJsonTablePathSpec($3, $5, @3, @5);
14614 : : n->columns = $8;
14615 : : n->location = @1;
14616 : : $$ = (Node *) n;
14617 : : }
14618 : : ;
14619 : :
14620 : : path_opt:
14621 : : PATH
14622 : : | /* EMPTY */
14623 : : ;
14624 : :
14625 : : json_table_column_path_clause_opt:
14626 : : PATH Sconst
14627 : : { $$ = (Node *) makeJsonTablePathSpec($2, NULL, @2, -1); }
14628 : : | /* EMPTY */
14629 : : { $$ = NULL; }
14630 : : ;
14631 : :
14632 : : /*****************************************************************************
14633 : : *
14634 : : * Type syntax
14635 : : * SQL introduces a large amount of type-specific syntax.
14636 : : * Define individual clauses to handle these cases, and use
14637 : : * the generic case to handle regular type-extensible Postgres syntax.
14638 : : * - thomas 1997-10-10
14639 : : *
14640 : : *****************************************************************************/
14641 : :
14642 : : Typename: SimpleTypename opt_array_bounds
14643 : : {
14644 : : $$ = $1;
14645 : : $$->arrayBounds = $2;
14646 : : }
14647 : : | SETOF SimpleTypename opt_array_bounds
14648 : : {
14649 : : $$ = $2;
14650 : : $$->arrayBounds = $3;
14651 : : $$->setof = true;
14652 : : }
14653 : : /* SQL standard syntax, currently only one-dimensional */
14654 : : | SimpleTypename ARRAY '[' Iconst ']'
14655 : : {
14656 : : $$ = $1;
14657 : : $$->arrayBounds = list_make1(makeInteger($4));
14658 : : }
14659 : : | SETOF SimpleTypename ARRAY '[' Iconst ']'
14660 : : {
14661 : : $$ = $2;
14662 : : $$->arrayBounds = list_make1(makeInteger($5));
14663 : : $$->setof = true;
14664 : : }
14665 : : | SimpleTypename ARRAY
14666 : : {
14667 : : $$ = $1;
14668 : : $$->arrayBounds = list_make1(makeInteger(-1));
14669 : : }
14670 : : | SETOF SimpleTypename ARRAY
14671 : : {
14672 : : $$ = $2;
14673 : : $$->arrayBounds = list_make1(makeInteger(-1));
14674 : : $$->setof = true;
14675 : : }
14676 : : ;
14677 : :
14678 : : opt_array_bounds:
14679 : : opt_array_bounds '[' ']'
14680 : : { $$ = lappend($1, makeInteger(-1)); }
14681 : : | opt_array_bounds '[' Iconst ']'
14682 : : { $$ = lappend($1, makeInteger($3)); }
14683 : : | /*EMPTY*/
14684 : : { $$ = NIL; }
14685 : : ;
14686 : :
14687 : : SimpleTypename:
14688 : : GenericType { $$ = $1; }
14689 : : | Numeric { $$ = $1; }
14690 : : | Bit { $$ = $1; }
14691 : : | Character { $$ = $1; }
14692 : : | ConstDatetime { $$ = $1; }
14693 : : | ConstInterval opt_interval
14694 : : {
14695 : : $$ = $1;
14696 : : $$->typmods = $2;
14697 : : }
14698 : : | ConstInterval '(' Iconst ')'
14699 : : {
14700 : : $$ = $1;
14701 : : $$->typmods = list_make2(makeIntConst(INTERVAL_FULL_RANGE, -1),
14702 : : makeIntConst($3, @3));
14703 : : }
14704 : : | JsonType { $$ = $1; }
14705 : : ;
14706 : :
14707 : : /* We have a separate ConstTypename to allow defaulting fixed-length
14708 : : * types such as CHAR() and BIT() to an unspecified length.
14709 : : * SQL9x requires that these default to a length of one, but this
14710 : : * makes no sense for constructs like CHAR 'hi' and BIT '0101',
14711 : : * where there is an obvious better choice to make.
14712 : : * Note that ConstInterval is not included here since it must
14713 : : * be pushed up higher in the rules to accommodate the postfix
14714 : : * options (e.g. INTERVAL '1' YEAR). Likewise, we have to handle
14715 : : * the generic-type-name case in AexprConst to avoid premature
14716 : : * reduce/reduce conflicts against function names.
14717 : : */
14718 : : ConstTypename:
14719 : : Numeric { $$ = $1; }
14720 : : | ConstBit { $$ = $1; }
14721 : : | ConstCharacter { $$ = $1; }
14722 : : | ConstDatetime { $$ = $1; }
14723 : : | JsonType { $$ = $1; }
14724 : : ;
14725 : :
14726 : : /*
14727 : : * GenericType covers all type names that don't have special syntax mandated
14728 : : * by the standard, including qualified names. We also allow type modifiers.
14729 : : * To avoid parsing conflicts against function invocations, the modifiers
14730 : : * have to be shown as expr_list here, but parse analysis will only accept
14731 : : * constants for them.
14732 : : */
14733 : : GenericType:
14734 : : type_function_name opt_type_modifiers
14735 : : {
14736 : : $$ = makeTypeName($1);
14737 : : $$->typmods = $2;
14738 : : $$->location = @1;
14739 : : }
14740 : : | type_function_name attrs opt_type_modifiers
14741 : : {
14742 : : $$ = makeTypeNameFromNameList(lcons(makeString($1), $2));
14743 : : $$->typmods = $3;
14744 : : $$->location = @1;
14745 : : }
14746 : : ;
14747 : :
14748 : : opt_type_modifiers: '(' expr_list ')' { $$ = $2; }
14749 : : | /* EMPTY */ { $$ = NIL; }
14750 : : ;
14751 : :
14752 : : /*
14753 : : * SQL numeric data types
14754 : : */
14755 : : Numeric: INT_P
14756 : : {
14757 : : $$ = SystemTypeName("int4");
14758 : : $$->location = @1;
14759 : : }
14760 : : | INTEGER
14761 : : {
14762 : : $$ = SystemTypeName("int4");
14763 : : $$->location = @1;
14764 : : }
14765 : : | SMALLINT
14766 : : {
14767 : : $$ = SystemTypeName("int2");
14768 : : $$->location = @1;
14769 : : }
14770 : : | BIGINT
14771 : : {
14772 : : $$ = SystemTypeName("int8");
14773 : : $$->location = @1;
14774 : : }
14775 : : | REAL
14776 : : {
14777 : : $$ = SystemTypeName("float4");
14778 : : $$->location = @1;
14779 : : }
14780 : : | FLOAT_P opt_float
14781 : : {
14782 : : $$ = $2;
14783 : : $$->location = @1;
14784 : : }
14785 : : | DOUBLE_P PRECISION
14786 : : {
14787 : : $$ = SystemTypeName("float8");
14788 : : $$->location = @1;
14789 : : }
14790 : : | DECIMAL_P opt_type_modifiers
14791 : : {
14792 : : $$ = SystemTypeName("numeric");
14793 : : $$->typmods = $2;
14794 : : $$->location = @1;
14795 : : }
14796 : : | DEC opt_type_modifiers
14797 : : {
14798 : : $$ = SystemTypeName("numeric");
14799 : : $$->typmods = $2;
14800 : : $$->location = @1;
14801 : : }
14802 : : | NUMERIC opt_type_modifiers
14803 : : {
14804 : : $$ = SystemTypeName("numeric");
14805 : : $$->typmods = $2;
14806 : : $$->location = @1;
14807 : : }
14808 : : | BOOLEAN_P
14809 : : {
14810 : : $$ = SystemTypeName("bool");
14811 : : $$->location = @1;
14812 : : }
14813 : : ;
14814 : :
14815 : : opt_float: '(' Iconst ')'
14816 : : {
14817 : : /*
14818 : : * Check FLOAT() precision limits assuming IEEE floating
14819 : : * types - thomas 1997-09-18
14820 : : */
14821 : : if ($2 < 1)
14822 : : ereport(ERROR,
14823 : : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
14824 : : errmsg("precision for type float must be at least 1 bit"),
14825 : : parser_errposition(@2)));
14826 : : else if ($2 <= 24)
14827 : : $$ = SystemTypeName("float4");
14828 : : else if ($2 <= 53)
14829 : : $$ = SystemTypeName("float8");
14830 : : else
14831 : : ereport(ERROR,
14832 : : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
14833 : : errmsg("precision for type float must be less than 54 bits"),
14834 : : parser_errposition(@2)));
14835 : : }
14836 : : | /*EMPTY*/
14837 : : {
14838 : : $$ = SystemTypeName("float8");
14839 : : }
14840 : : ;
14841 : :
14842 : : /*
14843 : : * SQL bit-field data types
14844 : : * The following implements BIT() and BIT VARYING().
14845 : : */
14846 : : Bit: BitWithLength
14847 : : {
14848 : : $$ = $1;
14849 : : }
14850 : : | BitWithoutLength
14851 : : {
14852 : : $$ = $1;
14853 : : }
14854 : : ;
14855 : :
14856 : : /* ConstBit is like Bit except "BIT" defaults to unspecified length */
14857 : : /* See notes for ConstCharacter, which addresses same issue for "CHAR" */
14858 : : ConstBit: BitWithLength
14859 : : {
14860 : : $$ = $1;
14861 : : }
14862 : : | BitWithoutLength
14863 : : {
14864 : : $$ = $1;
14865 : : $$->typmods = NIL;
14866 : : }
14867 : : ;
14868 : :
14869 : : BitWithLength:
14870 : : BIT opt_varying '(' expr_list ')'
14871 : : {
14872 : : char *typname;
14873 : :
14874 : : typname = $2 ? "varbit" : "bit";
14875 : : $$ = SystemTypeName(typname);
14876 : : $$->typmods = $4;
14877 : : $$->location = @1;
14878 : : }
14879 : : ;
14880 : :
14881 : : BitWithoutLength:
14882 : : BIT opt_varying
14883 : : {
14884 : : /* bit defaults to bit(1), varbit to no limit */
14885 : : if ($2)
14886 : : {
14887 : : $$ = SystemTypeName("varbit");
14888 : : }
14889 : : else
14890 : : {
14891 : : $$ = SystemTypeName("bit");
14892 : : $$->typmods = list_make1(makeIntConst(1, -1));
14893 : : }
14894 : : $$->location = @1;
14895 : : }
14896 : : ;
14897 : :
14898 : :
14899 : : /*
14900 : : * SQL character data types
14901 : : * The following implements CHAR() and VARCHAR().
14902 : : */
14903 : : Character: CharacterWithLength
14904 : : {
14905 : : $$ = $1;
14906 : : }
14907 : : | CharacterWithoutLength
14908 : : {
14909 : : $$ = $1;
14910 : : }
14911 : : ;
14912 : :
14913 : : ConstCharacter: CharacterWithLength
14914 : : {
14915 : : $$ = $1;
14916 : : }
14917 : : | CharacterWithoutLength
14918 : : {
14919 : : /* Length was not specified so allow to be unrestricted.
14920 : : * This handles problems with fixed-length (bpchar) strings
14921 : : * which in column definitions must default to a length
14922 : : * of one, but should not be constrained if the length
14923 : : * was not specified.
14924 : : */
14925 : : $$ = $1;
14926 : : $$->typmods = NIL;
14927 : : }
14928 : : ;
14929 : :
14930 : : CharacterWithLength: character '(' Iconst ')'
14931 : : {
14932 : : $$ = SystemTypeName($1);
14933 : : $$->typmods = list_make1(makeIntConst($3, @3));
14934 : : $$->location = @1;
14935 : : }
14936 : : ;
14937 : :
14938 : : CharacterWithoutLength: character
14939 : : {
14940 : : $$ = SystemTypeName($1);
14941 : : /* char defaults to char(1), varchar to no limit */
14942 : : if (strcmp($1, "bpchar") == 0)
14943 : : $$->typmods = list_make1(makeIntConst(1, -1));
14944 : : $$->location = @1;
14945 : : }
14946 : : ;
14947 : :
14948 : : character: CHARACTER opt_varying
14949 : : { $$ = $2 ? "varchar": "bpchar"; }
14950 : : | CHAR_P opt_varying
14951 : : { $$ = $2 ? "varchar": "bpchar"; }
14952 : : | VARCHAR
14953 : : { $$ = "varchar"; }
14954 : : | NATIONAL CHARACTER opt_varying
14955 : : { $$ = $3 ? "varchar": "bpchar"; }
14956 : : | NATIONAL CHAR_P opt_varying
14957 : : { $$ = $3 ? "varchar": "bpchar"; }
14958 : : | NCHAR opt_varying
14959 : : { $$ = $2 ? "varchar": "bpchar"; }
14960 : : ;
14961 : :
14962 : : opt_varying:
14963 : : VARYING { $$ = true; }
14964 : : | /*EMPTY*/ { $$ = false; }
14965 : : ;
14966 : :
14967 : : /*
14968 : : * SQL date/time types
14969 : : */
14970 : : ConstDatetime:
14971 : : TIMESTAMP '(' Iconst ')' opt_timezone
14972 : : {
14973 : : if ($5)
14974 : : $$ = SystemTypeName("timestamptz");
14975 : : else
14976 : : $$ = SystemTypeName("timestamp");
14977 : : $$->typmods = list_make1(makeIntConst($3, @3));
14978 : : $$->location = @1;
14979 : : }
14980 : : | TIMESTAMP opt_timezone
14981 : : {
14982 : : if ($2)
14983 : : $$ = SystemTypeName("timestamptz");
14984 : : else
14985 : : $$ = SystemTypeName("timestamp");
14986 : : $$->location = @1;
14987 : : }
14988 : : | TIME '(' Iconst ')' opt_timezone
14989 : : {
14990 : : if ($5)
14991 : : $$ = SystemTypeName("timetz");
14992 : : else
14993 : : $$ = SystemTypeName("time");
14994 : : $$->typmods = list_make1(makeIntConst($3, @3));
14995 : : $$->location = @1;
14996 : : }
14997 : : | TIME opt_timezone
14998 : : {
14999 : : if ($2)
15000 : : $$ = SystemTypeName("timetz");
15001 : : else
15002 : : $$ = SystemTypeName("time");
15003 : : $$->location = @1;
15004 : : }
15005 : : ;
15006 : :
15007 : : ConstInterval:
15008 : : INTERVAL
15009 : : {
15010 : : $$ = SystemTypeName("interval");
15011 : : $$->location = @1;
15012 : : }
15013 : : ;
15014 : :
15015 : : opt_timezone:
15016 : : WITH_LA TIME ZONE { $$ = true; }
15017 : : | WITHOUT_LA TIME ZONE { $$ = false; }
15018 : : | /*EMPTY*/ { $$ = false; }
15019 : : ;
15020 : :
15021 : : opt_interval:
15022 : : YEAR_P
15023 : : { $$ = list_make1(makeIntConst(INTERVAL_MASK(YEAR), @1)); }
15024 : : | MONTH_P
15025 : : { $$ = list_make1(makeIntConst(INTERVAL_MASK(MONTH), @1)); }
15026 : : | DAY_P
15027 : : { $$ = list_make1(makeIntConst(INTERVAL_MASK(DAY), @1)); }
15028 : : | HOUR_P
15029 : : { $$ = list_make1(makeIntConst(INTERVAL_MASK(HOUR), @1)); }
15030 : : | MINUTE_P
15031 : : { $$ = list_make1(makeIntConst(INTERVAL_MASK(MINUTE), @1)); }
15032 : : | interval_second
15033 : : { $$ = $1; }
15034 : : | YEAR_P TO MONTH_P
15035 : : {
15036 : : $$ = list_make1(makeIntConst(INTERVAL_MASK(YEAR) |
15037 : : INTERVAL_MASK(MONTH), @1));
15038 : : }
15039 : : | DAY_P TO HOUR_P
15040 : : {
15041 : : $$ = list_make1(makeIntConst(INTERVAL_MASK(DAY) |
15042 : : INTERVAL_MASK(HOUR), @1));
15043 : : }
15044 : : | DAY_P TO MINUTE_P
15045 : : {
15046 : : $$ = list_make1(makeIntConst(INTERVAL_MASK(DAY) |
15047 : : INTERVAL_MASK(HOUR) |
15048 : : INTERVAL_MASK(MINUTE), @1));
15049 : : }
15050 : : | DAY_P TO interval_second
15051 : : {
15052 : : $$ = $3;
15053 : : linitial($$) = makeIntConst(INTERVAL_MASK(DAY) |
15054 : : INTERVAL_MASK(HOUR) |
15055 : : INTERVAL_MASK(MINUTE) |
15056 : : INTERVAL_MASK(SECOND), @1);
15057 : : }
15058 : : | HOUR_P TO MINUTE_P
15059 : : {
15060 : : $$ = list_make1(makeIntConst(INTERVAL_MASK(HOUR) |
15061 : : INTERVAL_MASK(MINUTE), @1));
15062 : : }
15063 : : | HOUR_P TO interval_second
15064 : : {
15065 : : $$ = $3;
15066 : : linitial($$) = makeIntConst(INTERVAL_MASK(HOUR) |
15067 : : INTERVAL_MASK(MINUTE) |
15068 : : INTERVAL_MASK(SECOND), @1);
15069 : : }
15070 : : | MINUTE_P TO interval_second
15071 : : {
15072 : : $$ = $3;
15073 : : linitial($$) = makeIntConst(INTERVAL_MASK(MINUTE) |
15074 : : INTERVAL_MASK(SECOND), @1);
15075 : : }
15076 : : | /*EMPTY*/
15077 : : { $$ = NIL; }
15078 : : ;
15079 : :
15080 : : interval_second:
15081 : : SECOND_P
15082 : : {
15083 : : $$ = list_make1(makeIntConst(INTERVAL_MASK(SECOND), @1));
15084 : : }
15085 : : | SECOND_P '(' Iconst ')'
15086 : : {
15087 : : $$ = list_make2(makeIntConst(INTERVAL_MASK(SECOND), @1),
15088 : : makeIntConst($3, @3));
15089 : : }
15090 : : ;
15091 : :
15092 : : JsonType:
15093 : : JSON
15094 : : {
15095 : : $$ = SystemTypeName("json");
15096 : : $$->location = @1;
15097 : : }
15098 : : ;
15099 : :
15100 : : /*****************************************************************************
15101 : : *
15102 : : * expression grammar
15103 : : *
15104 : : *****************************************************************************/
15105 : :
15106 : : /*
15107 : : * General expressions
15108 : : * This is the heart of the expression syntax.
15109 : : *
15110 : : * We have two expression types: a_expr is the unrestricted kind, and
15111 : : * b_expr is a subset that must be used in some places to avoid shift/reduce
15112 : : * conflicts. For example, we can't do BETWEEN as "BETWEEN a_expr AND a_expr"
15113 : : * because that use of AND conflicts with AND as a boolean operator. So,
15114 : : * b_expr is used in BETWEEN and we remove boolean keywords from b_expr.
15115 : : *
15116 : : * Note that '(' a_expr ')' is a b_expr, so an unrestricted expression can
15117 : : * always be used by surrounding it with parens.
15118 : : *
15119 : : * c_expr is all the productions that are common to a_expr and b_expr;
15120 : : * it's factored out just to eliminate redundant coding.
15121 : : *
15122 : : * Be careful of productions involving more than one terminal token.
15123 : : * By default, bison will assign such productions the precedence of their
15124 : : * last terminal, but in nearly all cases you want it to be the precedence
15125 : : * of the first terminal instead; otherwise you will not get the behavior
15126 : : * you expect! So we use %prec annotations freely to set precedences.
15127 : : */
15128 : : a_expr: c_expr { $$ = $1; }
15129 : : | a_expr TYPECAST Typename
15130 : : { $$ = makeTypeCast($1, $3, @2); }
15131 : : | a_expr COLLATE any_name
15132 : : {
15133 : : CollateClause *n = makeNode(CollateClause);
15134 : :
15135 : : n->arg = $1;
15136 : : n->collname = $3;
15137 : : n->location = @2;
15138 : : $$ = (Node *) n;
15139 : : }
15140 : : | a_expr AT TIME ZONE a_expr %prec AT
15141 : : {
15142 : : $$ = (Node *) makeFuncCall(SystemFuncName("timezone"),
15143 : : list_make2($5, $1),
15144 : : COERCE_SQL_SYNTAX,
15145 : : @2);
15146 : : }
15147 : : | a_expr AT LOCAL %prec AT
15148 : : {
15149 : : $$ = (Node *) makeFuncCall(SystemFuncName("timezone"),
15150 : : list_make1($1),
15151 : : COERCE_SQL_SYNTAX,
15152 : : -1);
15153 : : }
15154 : : /*
15155 : : * These operators must be called out explicitly in order to make use
15156 : : * of bison's automatic operator-precedence handling. All other
15157 : : * operator names are handled by the generic productions using "Op",
15158 : : * below; and all those operators will have the same precedence.
15159 : : *
15160 : : * If you add more explicitly-known operators, be sure to add them
15161 : : * also to b_expr and to the MathOp list below.
15162 : : */
15163 : : | '+' a_expr %prec UMINUS
15164 : : { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "+", NULL, $2, @1); }
15165 : : | '-' a_expr %prec UMINUS
15166 : : { $$ = doNegate($2, @1); }
15167 : : | a_expr '+' a_expr
15168 : : { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "+", $1, $3, @2); }
15169 : : | a_expr '-' a_expr
15170 : : { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "-", $1, $3, @2); }
15171 : : | a_expr '*' a_expr
15172 : : { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "*", $1, $3, @2); }
15173 : : | a_expr '/' a_expr
15174 : : { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "/", $1, $3, @2); }
15175 : : | a_expr '%' a_expr
15176 : : { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "%", $1, $3, @2); }
15177 : : | a_expr '^' a_expr
15178 : : { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "^", $1, $3, @2); }
15179 : : | a_expr '<' a_expr
15180 : : { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "<", $1, $3, @2); }
15181 : : | a_expr '>' a_expr
15182 : : { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, ">", $1, $3, @2); }
15183 : : | a_expr '=' a_expr
15184 : : { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "=", $1, $3, @2); }
15185 : : | a_expr LESS_EQUALS a_expr
15186 : : { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "<=", $1, $3, @2); }
15187 : : | a_expr GREATER_EQUALS a_expr
15188 : : { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, ">=", $1, $3, @2); }
15189 : : | a_expr NOT_EQUALS a_expr
15190 : : { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "<>", $1, $3, @2); }
15191 : :
15192 : : | a_expr qual_Op a_expr %prec Op
15193 : : { $$ = (Node *) makeA_Expr(AEXPR_OP, $2, $1, $3, @2); }
15194 : : | qual_Op a_expr %prec Op
15195 : : { $$ = (Node *) makeA_Expr(AEXPR_OP, $1, NULL, $2, @1); }
15196 : :
15197 : : | a_expr AND a_expr
15198 : : { $$ = makeAndExpr($1, $3, @2); }
15199 : : | a_expr OR a_expr
15200 : : { $$ = makeOrExpr($1, $3, @2); }
15201 : : | NOT a_expr
15202 : : { $$ = makeNotExpr($2, @1); }
15203 : : | NOT_LA a_expr %prec NOT
15204 : : { $$ = makeNotExpr($2, @1); }
15205 : :
15206 : : | a_expr LIKE a_expr
15207 : : {
15208 : : $$ = (Node *) makeSimpleA_Expr(AEXPR_LIKE, "~~",
15209 : : $1, $3, @2);
15210 : : }
15211 : : | a_expr LIKE a_expr ESCAPE a_expr %prec LIKE
15212 : : {
15213 : : FuncCall *n = makeFuncCall(SystemFuncName("like_escape"),
15214 : : list_make2($3, $5),
15215 : : COERCE_EXPLICIT_CALL,
15216 : : @2);
15217 : : $$ = (Node *) makeSimpleA_Expr(AEXPR_LIKE, "~~",
15218 : : $1, (Node *) n, @2);
15219 : : }
15220 : : | a_expr NOT_LA LIKE a_expr %prec NOT_LA
15221 : : {
15222 : : $$ = (Node *) makeSimpleA_Expr(AEXPR_LIKE, "!~~",
15223 : : $1, $4, @2);
15224 : : }
15225 : : | a_expr NOT_LA LIKE a_expr ESCAPE a_expr %prec NOT_LA
15226 : : {
15227 : : FuncCall *n = makeFuncCall(SystemFuncName("like_escape"),
15228 : : list_make2($4, $6),
15229 : : COERCE_EXPLICIT_CALL,
15230 : : @2);
15231 : : $$ = (Node *) makeSimpleA_Expr(AEXPR_LIKE, "!~~",
15232 : : $1, (Node *) n, @2);
15233 : : }
15234 : : | a_expr ILIKE a_expr
15235 : : {
15236 : : $$ = (Node *) makeSimpleA_Expr(AEXPR_ILIKE, "~~*",
15237 : : $1, $3, @2);
15238 : : }
15239 : : | a_expr ILIKE a_expr ESCAPE a_expr %prec ILIKE
15240 : : {
15241 : : FuncCall *n = makeFuncCall(SystemFuncName("like_escape"),
15242 : : list_make2($3, $5),
15243 : : COERCE_EXPLICIT_CALL,
15244 : : @2);
15245 : : $$ = (Node *) makeSimpleA_Expr(AEXPR_ILIKE, "~~*",
15246 : : $1, (Node *) n, @2);
15247 : : }
15248 : : | a_expr NOT_LA ILIKE a_expr %prec NOT_LA
15249 : : {
15250 : : $$ = (Node *) makeSimpleA_Expr(AEXPR_ILIKE, "!~~*",
15251 : : $1, $4, @2);
15252 : : }
15253 : : | a_expr NOT_LA ILIKE a_expr ESCAPE a_expr %prec NOT_LA
15254 : : {
15255 : : FuncCall *n = makeFuncCall(SystemFuncName("like_escape"),
15256 : : list_make2($4, $6),
15257 : : COERCE_EXPLICIT_CALL,
15258 : : @2);
15259 : : $$ = (Node *) makeSimpleA_Expr(AEXPR_ILIKE, "!~~*",
15260 : : $1, (Node *) n, @2);
15261 : : }
15262 : :
15263 : : | a_expr SIMILAR TO a_expr %prec SIMILAR
15264 : : {
15265 : : FuncCall *n = makeFuncCall(SystemFuncName("similar_to_escape"),
15266 : : list_make1($4),
15267 : : COERCE_EXPLICIT_CALL,
15268 : : @2);
15269 : : $$ = (Node *) makeSimpleA_Expr(AEXPR_SIMILAR, "~",
15270 : : $1, (Node *) n, @2);
15271 : : }
15272 : : | a_expr SIMILAR TO a_expr ESCAPE a_expr %prec SIMILAR
15273 : : {
15274 : : FuncCall *n = makeFuncCall(SystemFuncName("similar_to_escape"),
15275 : : list_make2($4, $6),
15276 : : COERCE_EXPLICIT_CALL,
15277 : : @2);
15278 : : $$ = (Node *) makeSimpleA_Expr(AEXPR_SIMILAR, "~",
15279 : : $1, (Node *) n, @2);
15280 : : }
15281 : : | a_expr NOT_LA SIMILAR TO a_expr %prec NOT_LA
15282 : : {
15283 : : FuncCall *n = makeFuncCall(SystemFuncName("similar_to_escape"),
15284 : : list_make1($5),
15285 : : COERCE_EXPLICIT_CALL,
15286 : : @2);
15287 : : $$ = (Node *) makeSimpleA_Expr(AEXPR_SIMILAR, "!~",
15288 : : $1, (Node *) n, @2);
15289 : : }
15290 : : | a_expr NOT_LA SIMILAR TO a_expr ESCAPE a_expr %prec NOT_LA
15291 : : {
15292 : : FuncCall *n = makeFuncCall(SystemFuncName("similar_to_escape"),
15293 : : list_make2($5, $7),
15294 : : COERCE_EXPLICIT_CALL,
15295 : : @2);
15296 : : $$ = (Node *) makeSimpleA_Expr(AEXPR_SIMILAR, "!~",
15297 : : $1, (Node *) n, @2);
15298 : : }
15299 : :
15300 : : /* NullTest clause
15301 : : * Define SQL-style Null test clause.
15302 : : * Allow two forms described in the standard:
15303 : : * a IS NULL
15304 : : * a IS NOT NULL
15305 : : * Allow two SQL extensions
15306 : : * a ISNULL
15307 : : * a NOTNULL
15308 : : */
15309 : : | a_expr IS NULL_P %prec IS
15310 : : {
15311 : : NullTest *n = makeNode(NullTest);
15312 : :
15313 : : n->arg = (Expr *) $1;
15314 : : n->nulltesttype = IS_NULL;
15315 : : n->location = @2;
15316 : : $$ = (Node *) n;
15317 : : }
15318 : : | a_expr ISNULL
15319 : : {
15320 : : NullTest *n = makeNode(NullTest);
15321 : :
15322 : : n->arg = (Expr *) $1;
15323 : : n->nulltesttype = IS_NULL;
15324 : : n->location = @2;
15325 : : $$ = (Node *) n;
15326 : : }
15327 : : | a_expr IS NOT NULL_P %prec IS
15328 : : {
15329 : : NullTest *n = makeNode(NullTest);
15330 : :
15331 : : n->arg = (Expr *) $1;
15332 : : n->nulltesttype = IS_NOT_NULL;
15333 : : n->location = @2;
15334 : : $$ = (Node *) n;
15335 : : }
15336 : : | a_expr NOTNULL
15337 : : {
15338 : : NullTest *n = makeNode(NullTest);
15339 : :
15340 : : n->arg = (Expr *) $1;
15341 : : n->nulltesttype = IS_NOT_NULL;
15342 : : n->location = @2;
15343 : : $$ = (Node *) n;
15344 : : }
15345 : : | row OVERLAPS row
15346 : : {
15347 : : if (list_length($1) != 2)
15348 : : ereport(ERROR,
15349 : : (errcode(ERRCODE_SYNTAX_ERROR),
15350 : : errmsg("wrong number of parameters on left side of OVERLAPS expression"),
15351 : : parser_errposition(@1)));
15352 : : if (list_length($3) != 2)
15353 : : ereport(ERROR,
15354 : : (errcode(ERRCODE_SYNTAX_ERROR),
15355 : : errmsg("wrong number of parameters on right side of OVERLAPS expression"),
15356 : : parser_errposition(@3)));
15357 : : $$ = (Node *) makeFuncCall(SystemFuncName("overlaps"),
15358 : : list_concat($1, $3),
15359 : : COERCE_SQL_SYNTAX,
15360 : : @2);
15361 : : }
15362 : : | a_expr IS TRUE_P %prec IS
15363 : : {
15364 : : BooleanTest *b = makeNode(BooleanTest);
15365 : :
15366 : : b->arg = (Expr *) $1;
15367 : : b->booltesttype = IS_TRUE;
15368 : : b->location = @2;
15369 : : $$ = (Node *) b;
15370 : : }
15371 : : | a_expr IS NOT TRUE_P %prec IS
15372 : : {
15373 : : BooleanTest *b = makeNode(BooleanTest);
15374 : :
15375 : : b->arg = (Expr *) $1;
15376 : : b->booltesttype = IS_NOT_TRUE;
15377 : : b->location = @2;
15378 : : $$ = (Node *) b;
15379 : : }
15380 : : | a_expr IS FALSE_P %prec IS
15381 : : {
15382 : : BooleanTest *b = makeNode(BooleanTest);
15383 : :
15384 : : b->arg = (Expr *) $1;
15385 : : b->booltesttype = IS_FALSE;
15386 : : b->location = @2;
15387 : : $$ = (Node *) b;
15388 : : }
15389 : : | a_expr IS NOT FALSE_P %prec IS
15390 : : {
15391 : : BooleanTest *b = makeNode(BooleanTest);
15392 : :
15393 : : b->arg = (Expr *) $1;
15394 : : b->booltesttype = IS_NOT_FALSE;
15395 : : b->location = @2;
15396 : : $$ = (Node *) b;
15397 : : }
15398 : : | a_expr IS UNKNOWN %prec IS
15399 : : {
15400 : : BooleanTest *b = makeNode(BooleanTest);
15401 : :
15402 : : b->arg = (Expr *) $1;
15403 : : b->booltesttype = IS_UNKNOWN;
15404 : : b->location = @2;
15405 : : $$ = (Node *) b;
15406 : : }
15407 : : | a_expr IS NOT UNKNOWN %prec IS
15408 : : {
15409 : : BooleanTest *b = makeNode(BooleanTest);
15410 : :
15411 : : b->arg = (Expr *) $1;
15412 : : b->booltesttype = IS_NOT_UNKNOWN;
15413 : : b->location = @2;
15414 : : $$ = (Node *) b;
15415 : : }
15416 : : | a_expr IS DISTINCT FROM a_expr %prec IS
15417 : : {
15418 : : $$ = (Node *) makeSimpleA_Expr(AEXPR_DISTINCT, "=", $1, $5, @2);
15419 : : }
15420 : : | a_expr IS NOT DISTINCT FROM a_expr %prec IS
15421 : : {
15422 : : $$ = (Node *) makeSimpleA_Expr(AEXPR_NOT_DISTINCT, "=", $1, $6, @2);
15423 : : }
15424 : : | a_expr BETWEEN opt_asymmetric b_expr AND a_expr %prec BETWEEN
15425 : : {
15426 : : $$ = (Node *) makeSimpleA_Expr(AEXPR_BETWEEN,
15427 : : "BETWEEN",
15428 : : $1,
15429 : : (Node *) list_make2($4, $6),
15430 : : @2);
15431 : : }
15432 : : | a_expr NOT_LA BETWEEN opt_asymmetric b_expr AND a_expr %prec NOT_LA
15433 : : {
15434 : : $$ = (Node *) makeSimpleA_Expr(AEXPR_NOT_BETWEEN,
15435 : : "NOT BETWEEN",
15436 : : $1,
15437 : : (Node *) list_make2($5, $7),
15438 : : @2);
15439 : : }
15440 : : | a_expr BETWEEN SYMMETRIC b_expr AND a_expr %prec BETWEEN
15441 : : {
15442 : : $$ = (Node *) makeSimpleA_Expr(AEXPR_BETWEEN_SYM,
15443 : : "BETWEEN SYMMETRIC",
15444 : : $1,
15445 : : (Node *) list_make2($4, $6),
15446 : : @2);
15447 : : }
15448 : : | a_expr NOT_LA BETWEEN SYMMETRIC b_expr AND a_expr %prec NOT_LA
15449 : : {
15450 : : $$ = (Node *) makeSimpleA_Expr(AEXPR_NOT_BETWEEN_SYM,
15451 : : "NOT BETWEEN SYMMETRIC",
15452 : : $1,
15453 : : (Node *) list_make2($5, $7),
15454 : : @2);
15455 : : }
15456 : : | a_expr IN_P select_with_parens
15457 : : {
15458 : : /* generate foo = ANY (subquery) */
15459 : : SubLink *n = makeNode(SubLink);
15460 : :
15461 : : n->subselect = $3;
15462 : : n->subLinkType = ANY_SUBLINK;
15463 : : n->subLinkId = 0;
15464 : : n->testexpr = $1;
15465 : : n->operName = NIL; /* show it's IN not = ANY */
15466 : : n->location = @2;
15467 : : $$ = (Node *) n;
15468 : : }
15469 : : | a_expr IN_P '(' expr_list ')'
15470 : : {
15471 : : /* generate scalar IN expression */
15472 : : A_Expr *n = makeSimpleA_Expr(AEXPR_IN, "=", $1, (Node *) $4, @2);
15473 : :
15474 : : n->rexpr_list_start = @3;
15475 : : n->rexpr_list_end = @5;
15476 : : $$ = (Node *) n;
15477 : : }
15478 : : | a_expr NOT_LA IN_P select_with_parens %prec NOT_LA
15479 : : {
15480 : : /* generate NOT (foo = ANY (subquery)) */
15481 : : SubLink *n = makeNode(SubLink);
15482 : :
15483 : : n->subselect = $4;
15484 : : n->subLinkType = ANY_SUBLINK;
15485 : : n->subLinkId = 0;
15486 : : n->testexpr = $1;
15487 : : n->operName = NIL; /* show it's IN not = ANY */
15488 : : n->location = @2;
15489 : : /* Stick a NOT on top; must have same parse location */
15490 : : $$ = makeNotExpr((Node *) n, @2);
15491 : : }
15492 : : | a_expr NOT_LA IN_P '(' expr_list ')'
15493 : : {
15494 : : /* generate scalar NOT IN expression */
15495 : : A_Expr *n = makeSimpleA_Expr(AEXPR_IN, "<>", $1, (Node *) $5, @2);
15496 : :
15497 : : n->rexpr_list_start = @4;
15498 : : n->rexpr_list_end = @6;
15499 : : $$ = (Node *) n;
15500 : : }
15501 : : | a_expr subquery_Op sub_type select_with_parens %prec Op
15502 : : {
15503 : : SubLink *n = makeNode(SubLink);
15504 : :
15505 : : n->subLinkType = $3;
15506 : : n->subLinkId = 0;
15507 : : n->testexpr = $1;
15508 : : n->operName = $2;
15509 : : n->subselect = $4;
15510 : : n->location = @2;
15511 : : $$ = (Node *) n;
15512 : : }
15513 : : | a_expr subquery_Op sub_type '(' a_expr ')' %prec Op
15514 : : {
15515 : : if ($3 == ANY_SUBLINK)
15516 : : $$ = (Node *) makeA_Expr(AEXPR_OP_ANY, $2, $1, $5, @2);
15517 : : else
15518 : : $$ = (Node *) makeA_Expr(AEXPR_OP_ALL, $2, $1, $5, @2);
15519 : : }
15520 : : | UNIQUE opt_unique_null_treatment select_with_parens
15521 : : {
15522 : : /* Not sure how to get rid of the parentheses
15523 : : * but there are lots of shift/reduce errors without them.
15524 : : *
15525 : : * Should be able to implement this by plopping the entire
15526 : : * select into a node, then transforming the target expressions
15527 : : * from whatever they are into count(*), and testing the
15528 : : * entire result equal to one.
15529 : : * But, will probably implement a separate node in the executor.
15530 : : */
15531 : : ereport(ERROR,
15532 : : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
15533 : : errmsg("UNIQUE predicate is not yet implemented"),
15534 : : parser_errposition(@1)));
15535 : : }
15536 : : | a_expr IS DOCUMENT_P %prec IS
15537 : : {
15538 : : $$ = makeXmlExpr(IS_DOCUMENT, NULL, NIL,
15539 : : list_make1($1), @2);
15540 : : }
15541 : : | a_expr IS NOT DOCUMENT_P %prec IS
15542 : : {
15543 : : $$ = makeNotExpr(makeXmlExpr(IS_DOCUMENT, NULL, NIL,
15544 : : list_make1($1), @2),
15545 : : @2);
15546 : : }
15547 : : | a_expr IS NORMALIZED %prec IS
15548 : : {
15549 : : $$ = (Node *) makeFuncCall(SystemFuncName("is_normalized"),
15550 : : list_make1($1),
15551 : : COERCE_SQL_SYNTAX,
15552 : : @2);
15553 : : }
15554 : : | a_expr IS unicode_normal_form NORMALIZED %prec IS
15555 : : {
15556 : : $$ = (Node *) makeFuncCall(SystemFuncName("is_normalized"),
15557 : : list_make2($1, makeStringConst($3, @3)),
15558 : : COERCE_SQL_SYNTAX,
15559 : : @2);
15560 : : }
15561 : : | a_expr IS NOT NORMALIZED %prec IS
15562 : : {
15563 : : $$ = makeNotExpr((Node *) makeFuncCall(SystemFuncName("is_normalized"),
15564 : : list_make1($1),
15565 : : COERCE_SQL_SYNTAX,
15566 : : @2),
15567 : : @2);
15568 : : }
15569 : : | a_expr IS NOT unicode_normal_form NORMALIZED %prec IS
15570 : : {
15571 : : $$ = makeNotExpr((Node *) makeFuncCall(SystemFuncName("is_normalized"),
15572 : : list_make2($1, makeStringConst($4, @4)),
15573 : : COERCE_SQL_SYNTAX,
15574 : : @2),
15575 : : @2);
15576 : : }
15577 : : | a_expr IS json_predicate_type_constraint
15578 : : json_key_uniqueness_constraint_opt %prec IS
15579 : : {
15580 : : JsonFormat *format = makeJsonFormat(JS_FORMAT_DEFAULT, JS_ENC_DEFAULT, -1);
15581 : :
15582 : : $$ = makeJsonIsPredicate($1, format, $3, $4, @1);
15583 : : }
15584 : : /*
15585 : : * Required by SQL/JSON, but there are conflicts
15586 : : | a_expr
15587 : : json_format_clause
15588 : : IS json_predicate_type_constraint
15589 : : json_key_uniqueness_constraint_opt %prec IS
15590 : : {
15591 : : $$ = makeJsonIsPredicate($1, $2, $4, $5, @1);
15592 : : }
15593 : : */
15594 : : | a_expr IS NOT
15595 : : json_predicate_type_constraint
15596 : : json_key_uniqueness_constraint_opt %prec IS
15597 : : {
15598 : : JsonFormat *format = makeJsonFormat(JS_FORMAT_DEFAULT, JS_ENC_DEFAULT, -1);
15599 : :
15600 : : $$ = makeNotExpr(makeJsonIsPredicate($1, format, $4, $5, @1), @1);
15601 : : }
15602 : : /*
15603 : : * Required by SQL/JSON, but there are conflicts
15604 : : | a_expr
15605 : : json_format_clause
15606 : : IS NOT
15607 : : json_predicate_type_constraint
15608 : : json_key_uniqueness_constraint_opt %prec IS
15609 : : {
15610 : : $$ = makeNotExpr(makeJsonIsPredicate($1, $2, $5, $6, @1), @1);
15611 : : }
15612 : : */
15613 : : | DEFAULT
15614 : : {
15615 : : /*
15616 : : * The SQL spec only allows DEFAULT in "contextually typed
15617 : : * expressions", but for us, it's easier to allow it in
15618 : : * any a_expr and then throw error during parse analysis
15619 : : * if it's in an inappropriate context. This way also
15620 : : * lets us say something smarter than "syntax error".
15621 : : */
15622 : : SetToDefault *n = makeNode(SetToDefault);
15623 : :
15624 : : /* parse analysis will fill in the rest */
15625 : : n->location = @1;
15626 : : $$ = (Node *) n;
15627 : : }
15628 : : ;
15629 : :
15630 : : /*
15631 : : * Restricted expressions
15632 : : *
15633 : : * b_expr is a subset of the complete expression syntax defined by a_expr.
15634 : : *
15635 : : * Presently, AND, NOT, IS, and IN are the a_expr keywords that would
15636 : : * cause trouble in the places where b_expr is used. For simplicity, we
15637 : : * just eliminate all the boolean-keyword-operator productions from b_expr.
15638 : : */
15639 : : b_expr: c_expr
15640 : : { $$ = $1; }
15641 : : | b_expr TYPECAST Typename
15642 : : { $$ = makeTypeCast($1, $3, @2); }
15643 : : | '+' b_expr %prec UMINUS
15644 : : { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "+", NULL, $2, @1); }
15645 : : | '-' b_expr %prec UMINUS
15646 : : { $$ = doNegate($2, @1); }
15647 : : | b_expr '+' b_expr
15648 : : { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "+", $1, $3, @2); }
15649 : : | b_expr '-' b_expr
15650 : : { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "-", $1, $3, @2); }
15651 : : | b_expr '*' b_expr
15652 : : { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "*", $1, $3, @2); }
15653 : : | b_expr '/' b_expr
15654 : : { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "/", $1, $3, @2); }
15655 : : | b_expr '%' b_expr
15656 : : { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "%", $1, $3, @2); }
15657 : : | b_expr '^' b_expr
15658 : : { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "^", $1, $3, @2); }
15659 : : | b_expr '<' b_expr
15660 : : { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "<", $1, $3, @2); }
15661 : : | b_expr '>' b_expr
15662 : : { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, ">", $1, $3, @2); }
15663 : : | b_expr '=' b_expr
15664 : : { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "=", $1, $3, @2); }
15665 : : | b_expr LESS_EQUALS b_expr
15666 : : { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "<=", $1, $3, @2); }
15667 : : | b_expr GREATER_EQUALS b_expr
15668 : : { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, ">=", $1, $3, @2); }
15669 : : | b_expr NOT_EQUALS b_expr
15670 : : { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "<>", $1, $3, @2); }
15671 : : | b_expr qual_Op b_expr %prec Op
15672 : : { $$ = (Node *) makeA_Expr(AEXPR_OP, $2, $1, $3, @2); }
15673 : : | qual_Op b_expr %prec Op
15674 : : { $$ = (Node *) makeA_Expr(AEXPR_OP, $1, NULL, $2, @1); }
15675 : : | b_expr IS DISTINCT FROM b_expr %prec IS
15676 : : {
15677 : : $$ = (Node *) makeSimpleA_Expr(AEXPR_DISTINCT, "=", $1, $5, @2);
15678 : : }
15679 : : | b_expr IS NOT DISTINCT FROM b_expr %prec IS
15680 : : {
15681 : : $$ = (Node *) makeSimpleA_Expr(AEXPR_NOT_DISTINCT, "=", $1, $6, @2);
15682 : : }
15683 : : | b_expr IS DOCUMENT_P %prec IS
15684 : : {
15685 : : $$ = makeXmlExpr(IS_DOCUMENT, NULL, NIL,
15686 : : list_make1($1), @2);
15687 : : }
15688 : : | b_expr IS NOT DOCUMENT_P %prec IS
15689 : : {
15690 : : $$ = makeNotExpr(makeXmlExpr(IS_DOCUMENT, NULL, NIL,
15691 : : list_make1($1), @2),
15692 : : @2);
15693 : : }
15694 : : ;
15695 : :
15696 : : /*
15697 : : * Productions that can be used in both a_expr and b_expr.
15698 : : *
15699 : : * Note: productions that refer recursively to a_expr or b_expr mostly
15700 : : * cannot appear here. However, it's OK to refer to a_exprs that occur
15701 : : * inside parentheses, such as function arguments; that cannot introduce
15702 : : * ambiguity to the b_expr syntax.
15703 : : */
15704 : : c_expr: columnref { $$ = $1; }
15705 : : | AexprConst { $$ = $1; }
15706 : : | PARAM opt_indirection
15707 : : {
15708 : : ParamRef *p = makeNode(ParamRef);
15709 : :
15710 : : p->number = $1;
15711 : : p->location = @1;
15712 : : if ($2)
15713 : : {
15714 : : A_Indirection *n = makeNode(A_Indirection);
15715 : :
15716 : : n->arg = (Node *) p;
15717 : : n->indirection = check_indirection($2, yyscanner);
15718 : : $$ = (Node *) n;
15719 : : }
15720 : : else
15721 : : $$ = (Node *) p;
15722 : : }
15723 : : | '(' a_expr ')' opt_indirection
15724 : : {
15725 : : if ($4)
15726 : : {
15727 : : A_Indirection *n = makeNode(A_Indirection);
15728 : :
15729 : : n->arg = $2;
15730 : : n->indirection = check_indirection($4, yyscanner);
15731 : : $$ = (Node *) n;
15732 : : }
15733 : : else
15734 : : $$ = $2;
15735 : : }
15736 : : | case_expr
15737 : : { $$ = $1; }
15738 : : | func_expr
15739 : : { $$ = $1; }
15740 : : | select_with_parens %prec UMINUS
15741 : : {
15742 : : SubLink *n = makeNode(SubLink);
15743 : :
15744 : : n->subLinkType = EXPR_SUBLINK;
15745 : : n->subLinkId = 0;
15746 : : n->testexpr = NULL;
15747 : : n->operName = NIL;
15748 : : n->subselect = $1;
15749 : : n->location = @1;
15750 : : $$ = (Node *) n;
15751 : : }
15752 : : | select_with_parens indirection
15753 : : {
15754 : : /*
15755 : : * Because the select_with_parens nonterminal is designed
15756 : : * to "eat" as many levels of parens as possible, the
15757 : : * '(' a_expr ')' opt_indirection production above will
15758 : : * fail to match a sub-SELECT with indirection decoration;
15759 : : * the sub-SELECT won't be regarded as an a_expr as long
15760 : : * as there are parens around it. To support applying
15761 : : * subscripting or field selection to a sub-SELECT result,
15762 : : * we need this redundant-looking production.
15763 : : */
15764 : : SubLink *n = makeNode(SubLink);
15765 : : A_Indirection *a = makeNode(A_Indirection);
15766 : :
15767 : : n->subLinkType = EXPR_SUBLINK;
15768 : : n->subLinkId = 0;
15769 : : n->testexpr = NULL;
15770 : : n->operName = NIL;
15771 : : n->subselect = $1;
15772 : : n->location = @1;
15773 : : a->arg = (Node *) n;
15774 : : a->indirection = check_indirection($2, yyscanner);
15775 : : $$ = (Node *) a;
15776 : : }
15777 : : | EXISTS select_with_parens
15778 : : {
15779 : : SubLink *n = makeNode(SubLink);
15780 : :
15781 : : n->subLinkType = EXISTS_SUBLINK;
15782 : : n->subLinkId = 0;
15783 : : n->testexpr = NULL;
15784 : : n->operName = NIL;
15785 : : n->subselect = $2;
15786 : : n->location = @1;
15787 : : $$ = (Node *) n;
15788 : : }
15789 : : | ARRAY select_with_parens
15790 : : {
15791 : : SubLink *n = makeNode(SubLink);
15792 : :
15793 : : n->subLinkType = ARRAY_SUBLINK;
15794 : : n->subLinkId = 0;
15795 : : n->testexpr = NULL;
15796 : : n->operName = NIL;
15797 : : n->subselect = $2;
15798 : : n->location = @1;
15799 : : $$ = (Node *) n;
15800 : : }
15801 : : | ARRAY array_expr
15802 : : {
15803 : : A_ArrayExpr *n = castNode(A_ArrayExpr, $2);
15804 : :
15805 : : /* point outermost A_ArrayExpr to the ARRAY keyword */
15806 : : n->location = @1;
15807 : : $$ = (Node *) n;
15808 : : }
15809 : : | explicit_row
15810 : : {
15811 : : RowExpr *r = makeNode(RowExpr);
15812 : :
15813 : : r->args = $1;
15814 : : r->row_typeid = InvalidOid; /* not analyzed yet */
15815 : : r->colnames = NIL; /* to be filled in during analysis */
15816 : : r->row_format = COERCE_EXPLICIT_CALL; /* abuse */
15817 : : r->location = @1;
15818 : : $$ = (Node *) r;
15819 : : }
15820 : : | implicit_row
15821 : : {
15822 : : RowExpr *r = makeNode(RowExpr);
15823 : :
15824 : : r->args = $1;
15825 : : r->row_typeid = InvalidOid; /* not analyzed yet */
15826 : : r->colnames = NIL; /* to be filled in during analysis */
15827 : : r->row_format = COERCE_IMPLICIT_CAST; /* abuse */
15828 : : r->location = @1;
15829 : : $$ = (Node *) r;
15830 : : }
15831 : : | GROUPING '(' expr_list ')'
15832 : : {
15833 : : GroupingFunc *g = makeNode(GroupingFunc);
15834 : :
15835 : : g->args = $3;
15836 : : g->location = @1;
15837 : : $$ = (Node *) g;
15838 : : }
15839 : : ;
15840 : :
15841 : : func_application: func_name '(' ')'
15842 : : {
15843 : : $$ = (Node *) makeFuncCall($1, NIL,
15844 : : COERCE_EXPLICIT_CALL,
15845 : : @1);
15846 : : }
15847 : : | func_name '(' func_arg_list opt_sort_clause ')'
15848 : : {
15849 : : FuncCall *n = makeFuncCall($1, $3,
15850 : : COERCE_EXPLICIT_CALL,
15851 : : @1);
15852 : :
15853 : : n->agg_order = $4;
15854 : : $$ = (Node *) n;
15855 : : }
15856 : : | func_name '(' VARIADIC func_arg_expr opt_sort_clause ')'
15857 : : {
15858 : : FuncCall *n = makeFuncCall($1, list_make1($4),
15859 : : COERCE_EXPLICIT_CALL,
15860 : : @1);
15861 : :
15862 : : n->func_variadic = true;
15863 : : n->agg_order = $5;
15864 : : $$ = (Node *) n;
15865 : : }
15866 : : | func_name '(' func_arg_list ',' VARIADIC func_arg_expr opt_sort_clause ')'
15867 : : {
15868 : : FuncCall *n = makeFuncCall($1, lappend($3, $6),
15869 : : COERCE_EXPLICIT_CALL,
15870 : : @1);
15871 : :
15872 : : n->func_variadic = true;
15873 : : n->agg_order = $7;
15874 : : $$ = (Node *) n;
15875 : : }
15876 : : | func_name '(' ALL func_arg_list opt_sort_clause ')'
15877 : : {
15878 : : FuncCall *n = makeFuncCall($1, $4,
15879 : : COERCE_EXPLICIT_CALL,
15880 : : @1);
15881 : :
15882 : : n->agg_order = $5;
15883 : : /* Ideally we'd mark the FuncCall node to indicate
15884 : : * "must be an aggregate", but there's no provision
15885 : : * for that in FuncCall at the moment.
15886 : : */
15887 : : $$ = (Node *) n;
15888 : : }
15889 : : | func_name '(' DISTINCT func_arg_list opt_sort_clause ')'
15890 : : {
15891 : : FuncCall *n = makeFuncCall($1, $4,
15892 : : COERCE_EXPLICIT_CALL,
15893 : : @1);
15894 : :
15895 : : n->agg_order = $5;
15896 : : n->agg_distinct = true;
15897 : : $$ = (Node *) n;
15898 : : }
15899 : : | func_name '(' '*' ')'
15900 : : {
15901 : : /*
15902 : : * We consider AGGREGATE(*) to invoke a parameterless
15903 : : * aggregate. This does the right thing for COUNT(*),
15904 : : * and there are no other aggregates in SQL that accept
15905 : : * '*' as parameter.
15906 : : *
15907 : : * The FuncCall node is also marked agg_star = true,
15908 : : * so that later processing can detect what the argument
15909 : : * really was.
15910 : : */
15911 : : FuncCall *n = makeFuncCall($1, NIL,
15912 : : COERCE_EXPLICIT_CALL,
15913 : : @1);
15914 : :
15915 : : n->agg_star = true;
15916 : : $$ = (Node *) n;
15917 : : }
15918 : : ;
15919 : :
15920 : :
15921 : : /*
15922 : : * func_expr and its cousin func_expr_windowless are split out from c_expr just
15923 : : * so that we have classifications for "everything that is a function call or
15924 : : * looks like one". This isn't very important, but it saves us having to
15925 : : * document which variants are legal in places like "FROM function()" or the
15926 : : * backwards-compatible functional-index syntax for CREATE INDEX.
15927 : : * (Note that many of the special SQL functions wouldn't actually make any
15928 : : * sense as functional index entries, but we ignore that consideration here.)
15929 : : */
15930 : : func_expr: func_application within_group_clause filter_clause null_treatment over_clause
15931 : : {
15932 : : FuncCall *n = (FuncCall *) $1;
15933 : :
15934 : : /*
15935 : : * The order clause for WITHIN GROUP and the one for
15936 : : * plain-aggregate ORDER BY share a field, so we have to
15937 : : * check here that at most one is present. We also check
15938 : : * for DISTINCT and VARIADIC here to give a better error
15939 : : * location. Other consistency checks are deferred to
15940 : : * parse analysis.
15941 : : */
15942 : : if ($2 != NIL)
15943 : : {
15944 : : if (n->agg_order != NIL)
15945 : : ereport(ERROR,
15946 : : (errcode(ERRCODE_SYNTAX_ERROR),
15947 : : errmsg("cannot use multiple ORDER BY clauses with WITHIN GROUP"),
15948 : : parser_errposition(@2)));
15949 : : if (n->agg_distinct)
15950 : : ereport(ERROR,
15951 : : (errcode(ERRCODE_SYNTAX_ERROR),
15952 : : errmsg("cannot use DISTINCT with WITHIN GROUP"),
15953 : : parser_errposition(@2)));
15954 : : if (n->func_variadic)
15955 : : ereport(ERROR,
15956 : : (errcode(ERRCODE_SYNTAX_ERROR),
15957 : : errmsg("cannot use VARIADIC with WITHIN GROUP"),
15958 : : parser_errposition(@2)));
15959 : : n->agg_order = $2;
15960 : : n->agg_within_group = true;
15961 : : }
15962 : : n->agg_filter = $3;
15963 : : n->ignore_nulls = $4;
15964 : : n->over = $5;
15965 : : $$ = (Node *) n;
15966 : : }
15967 : : | json_aggregate_func filter_clause over_clause
15968 : : {
15969 : : JsonAggConstructor *n = IsA($1, JsonObjectAgg) ?
15970 : : ((JsonObjectAgg *) $1)->constructor :
15971 : : ((JsonArrayAgg *) $1)->constructor;
15972 : :
15973 : : n->agg_filter = $2;
15974 : : n->over = $3;
15975 : : $$ = (Node *) $1;
15976 : : }
15977 : : | func_expr_common_subexpr
15978 : : { $$ = $1; }
15979 : : ;
15980 : :
15981 : : /*
15982 : : * Like func_expr but does not accept WINDOW functions directly
15983 : : * (but they can still be contained in arguments for functions etc).
15984 : : * Use this when window expressions are not allowed, where needed to
15985 : : * disambiguate the grammar (e.g. in CREATE INDEX).
15986 : : */
15987 : : func_expr_windowless:
15988 : : func_application { $$ = $1; }
15989 : : | func_expr_common_subexpr { $$ = $1; }
15990 : : | json_aggregate_func { $$ = $1; }
15991 : : ;
15992 : :
15993 : : /*
15994 : : * Special expressions that are considered to be functions.
15995 : : */
15996 : : func_expr_common_subexpr:
15997 : : COLLATION FOR '(' a_expr ')'
15998 : : {
15999 : : $$ = (Node *) makeFuncCall(SystemFuncName("pg_collation_for"),
16000 : : list_make1($4),
16001 : : COERCE_SQL_SYNTAX,
16002 : : @1);
16003 : : }
16004 : : | CURRENT_DATE
16005 : : {
16006 : : $$ = makeSQLValueFunction(SVFOP_CURRENT_DATE, -1, @1);
16007 : : }
16008 : : | CURRENT_TIME
16009 : : {
16010 : : $$ = makeSQLValueFunction(SVFOP_CURRENT_TIME, -1, @1);
16011 : : }
16012 : : | CURRENT_TIME '(' Iconst ')'
16013 : : {
16014 : : $$ = makeSQLValueFunction(SVFOP_CURRENT_TIME_N, $3, @1);
16015 : : }
16016 : : | CURRENT_TIMESTAMP
16017 : : {
16018 : : $$ = makeSQLValueFunction(SVFOP_CURRENT_TIMESTAMP, -1, @1);
16019 : : }
16020 : : | CURRENT_TIMESTAMP '(' Iconst ')'
16021 : : {
16022 : : $$ = makeSQLValueFunction(SVFOP_CURRENT_TIMESTAMP_N, $3, @1);
16023 : : }
16024 : : | LOCALTIME
16025 : : {
16026 : : $$ = makeSQLValueFunction(SVFOP_LOCALTIME, -1, @1);
16027 : : }
16028 : : | LOCALTIME '(' Iconst ')'
16029 : : {
16030 : : $$ = makeSQLValueFunction(SVFOP_LOCALTIME_N, $3, @1);
16031 : : }
16032 : : | LOCALTIMESTAMP
16033 : : {
16034 : : $$ = makeSQLValueFunction(SVFOP_LOCALTIMESTAMP, -1, @1);
16035 : : }
16036 : : | LOCALTIMESTAMP '(' Iconst ')'
16037 : : {
16038 : : $$ = makeSQLValueFunction(SVFOP_LOCALTIMESTAMP_N, $3, @1);
16039 : : }
16040 : : | CURRENT_ROLE
16041 : : {
16042 : : $$ = makeSQLValueFunction(SVFOP_CURRENT_ROLE, -1, @1);
16043 : : }
16044 : : | CURRENT_USER
16045 : : {
16046 : : $$ = makeSQLValueFunction(SVFOP_CURRENT_USER, -1, @1);
16047 : : }
16048 : : | SESSION_USER
16049 : : {
16050 : : $$ = makeSQLValueFunction(SVFOP_SESSION_USER, -1, @1);
16051 : : }
16052 : : | SYSTEM_USER
16053 : : {
16054 : : $$ = (Node *) makeFuncCall(SystemFuncName("system_user"),
16055 : : NIL,
16056 : : COERCE_SQL_SYNTAX,
16057 : : @1);
16058 : : }
16059 : : | USER
16060 : : {
16061 : : $$ = makeSQLValueFunction(SVFOP_USER, -1, @1);
16062 : : }
16063 : : | CURRENT_CATALOG
16064 : : {
16065 : : $$ = makeSQLValueFunction(SVFOP_CURRENT_CATALOG, -1, @1);
16066 : : }
16067 : : | CURRENT_SCHEMA
16068 : : {
16069 : : $$ = makeSQLValueFunction(SVFOP_CURRENT_SCHEMA, -1, @1);
16070 : : }
16071 : : | CAST '(' a_expr AS Typename ')'
16072 : : { $$ = makeTypeCast($3, $5, @1); }
16073 : : | EXTRACT '(' extract_list ')'
16074 : : {
16075 : : $$ = (Node *) makeFuncCall(SystemFuncName("extract"),
16076 : : $3,
16077 : : COERCE_SQL_SYNTAX,
16078 : : @1);
16079 : : }
16080 : : | NORMALIZE '(' a_expr ')'
16081 : : {
16082 : : $$ = (Node *) makeFuncCall(SystemFuncName("normalize"),
16083 : : list_make1($3),
16084 : : COERCE_SQL_SYNTAX,
16085 : : @1);
16086 : : }
16087 : : | NORMALIZE '(' a_expr ',' unicode_normal_form ')'
16088 : : {
16089 : : $$ = (Node *) makeFuncCall(SystemFuncName("normalize"),
16090 : : list_make2($3, makeStringConst($5, @5)),
16091 : : COERCE_SQL_SYNTAX,
16092 : : @1);
16093 : : }
16094 : : | OVERLAY '(' overlay_list ')'
16095 : : {
16096 : : $$ = (Node *) makeFuncCall(SystemFuncName("overlay"),
16097 : : $3,
16098 : : COERCE_SQL_SYNTAX,
16099 : : @1);
16100 : : }
16101 : : | OVERLAY '(' func_arg_list_opt ')'
16102 : : {
16103 : : /*
16104 : : * allow functions named overlay() to be called without
16105 : : * special syntax
16106 : : */
16107 : : $$ = (Node *) makeFuncCall(list_make1(makeString("overlay")),
16108 : : $3,
16109 : : COERCE_EXPLICIT_CALL,
16110 : : @1);
16111 : : }
16112 : : | POSITION '(' position_list ')'
16113 : : {
16114 : : /*
16115 : : * position(A in B) is converted to position(B, A)
16116 : : *
16117 : : * We deliberately don't offer a "plain syntax" option
16118 : : * for position(), because the reversal of the arguments
16119 : : * creates too much risk of confusion.
16120 : : */
16121 : : $$ = (Node *) makeFuncCall(SystemFuncName("position"),
16122 : : $3,
16123 : : COERCE_SQL_SYNTAX,
16124 : : @1);
16125 : : }
16126 : : | SUBSTRING '(' substr_list ')'
16127 : : {
16128 : : /* substring(A from B for C) is converted to
16129 : : * substring(A, B, C) - thomas 2000-11-28
16130 : : */
16131 : : $$ = (Node *) makeFuncCall(SystemFuncName("substring"),
16132 : : $3,
16133 : : COERCE_SQL_SYNTAX,
16134 : : @1);
16135 : : }
16136 : : | SUBSTRING '(' func_arg_list_opt ')'
16137 : : {
16138 : : /*
16139 : : * allow functions named substring() to be called without
16140 : : * special syntax
16141 : : */
16142 : : $$ = (Node *) makeFuncCall(list_make1(makeString("substring")),
16143 : : $3,
16144 : : COERCE_EXPLICIT_CALL,
16145 : : @1);
16146 : : }
16147 : : | TREAT '(' a_expr AS Typename ')'
16148 : : {
16149 : : /* TREAT(expr AS target) converts expr of a particular type to target,
16150 : : * which is defined to be a subtype of the original expression.
16151 : : * In SQL99, this is intended for use with structured UDTs,
16152 : : * but let's make this a generally useful form allowing stronger
16153 : : * coercions than are handled by implicit casting.
16154 : : *
16155 : : * Convert SystemTypeName() to SystemFuncName() even though
16156 : : * at the moment they result in the same thing.
16157 : : */
16158 : : $$ = (Node *) makeFuncCall(SystemFuncName(strVal(llast($5->names))),
16159 : : list_make1($3),
16160 : : COERCE_EXPLICIT_CALL,
16161 : : @1);
16162 : : }
16163 : : | TRIM '(' BOTH trim_list ')'
16164 : : {
16165 : : /* various trim expressions are defined in SQL
16166 : : * - thomas 1997-07-19
16167 : : */
16168 : : $$ = (Node *) makeFuncCall(SystemFuncName("btrim"),
16169 : : $4,
16170 : : COERCE_SQL_SYNTAX,
16171 : : @1);
16172 : : }
16173 : : | TRIM '(' LEADING trim_list ')'
16174 : : {
16175 : : $$ = (Node *) makeFuncCall(SystemFuncName("ltrim"),
16176 : : $4,
16177 : : COERCE_SQL_SYNTAX,
16178 : : @1);
16179 : : }
16180 : : | TRIM '(' TRAILING trim_list ')'
16181 : : {
16182 : : $$ = (Node *) makeFuncCall(SystemFuncName("rtrim"),
16183 : : $4,
16184 : : COERCE_SQL_SYNTAX,
16185 : : @1);
16186 : : }
16187 : : | TRIM '(' trim_list ')'
16188 : : {
16189 : : $$ = (Node *) makeFuncCall(SystemFuncName("btrim"),
16190 : : $3,
16191 : : COERCE_SQL_SYNTAX,
16192 : : @1);
16193 : : }
16194 : : | NULLIF '(' a_expr ',' a_expr ')'
16195 : : {
16196 : : $$ = (Node *) makeSimpleA_Expr(AEXPR_NULLIF, "=", $3, $5, @1);
16197 : : }
16198 : : | COALESCE '(' expr_list ')'
16199 : : {
16200 : : CoalesceExpr *c = makeNode(CoalesceExpr);
16201 : :
16202 : : c->args = $3;
16203 : : c->location = @1;
16204 : : $$ = (Node *) c;
16205 : : }
16206 : : | GREATEST '(' expr_list ')'
16207 : : {
16208 : : MinMaxExpr *v = makeNode(MinMaxExpr);
16209 : :
16210 : : v->args = $3;
16211 : : v->op = IS_GREATEST;
16212 : : v->location = @1;
16213 : : $$ = (Node *) v;
16214 : : }
16215 : : | LEAST '(' expr_list ')'
16216 : : {
16217 : : MinMaxExpr *v = makeNode(MinMaxExpr);
16218 : :
16219 : : v->args = $3;
16220 : : v->op = IS_LEAST;
16221 : : v->location = @1;
16222 : : $$ = (Node *) v;
16223 : : }
16224 : : | XMLCONCAT '(' expr_list ')'
16225 : : {
16226 : : $$ = makeXmlExpr(IS_XMLCONCAT, NULL, NIL, $3, @1);
16227 : : }
16228 : : | XMLELEMENT '(' NAME_P ColLabel ')'
16229 : : {
16230 : : $$ = makeXmlExpr(IS_XMLELEMENT, $4, NIL, NIL, @1);
16231 : : }
16232 : : | XMLELEMENT '(' NAME_P ColLabel ',' xml_attributes ')'
16233 : : {
16234 : : $$ = makeXmlExpr(IS_XMLELEMENT, $4, $6, NIL, @1);
16235 : : }
16236 : : | XMLELEMENT '(' NAME_P ColLabel ',' expr_list ')'
16237 : : {
16238 : : $$ = makeXmlExpr(IS_XMLELEMENT, $4, NIL, $6, @1);
16239 : : }
16240 : : | XMLELEMENT '(' NAME_P ColLabel ',' xml_attributes ',' expr_list ')'
16241 : : {
16242 : : $$ = makeXmlExpr(IS_XMLELEMENT, $4, $6, $8, @1);
16243 : : }
16244 : : | XMLEXISTS '(' c_expr xmlexists_argument ')'
16245 : : {
16246 : : /* xmlexists(A PASSING [BY REF] B [BY REF]) is
16247 : : * converted to xmlexists(A, B)*/
16248 : : $$ = (Node *) makeFuncCall(SystemFuncName("xmlexists"),
16249 : : list_make2($3, $4),
16250 : : COERCE_SQL_SYNTAX,
16251 : : @1);
16252 : : }
16253 : : | XMLFOREST '(' xml_attribute_list ')'
16254 : : {
16255 : : $$ = makeXmlExpr(IS_XMLFOREST, NULL, $3, NIL, @1);
16256 : : }
16257 : : | XMLPARSE '(' document_or_content a_expr xml_whitespace_option ')'
16258 : : {
16259 : : XmlExpr *x = (XmlExpr *)
16260 : : makeXmlExpr(IS_XMLPARSE, NULL, NIL,
16261 : : list_make2($4, makeBoolAConst($5, -1)),
16262 : : @1);
16263 : :
16264 : : x->xmloption = $3;
16265 : : $$ = (Node *) x;
16266 : : }
16267 : : | XMLPI '(' NAME_P ColLabel ')'
16268 : : {
16269 : : $$ = makeXmlExpr(IS_XMLPI, $4, NULL, NIL, @1);
16270 : : }
16271 : : | XMLPI '(' NAME_P ColLabel ',' a_expr ')'
16272 : : {
16273 : : $$ = makeXmlExpr(IS_XMLPI, $4, NULL, list_make1($6), @1);
16274 : : }
16275 : : | XMLROOT '(' a_expr ',' xml_root_version opt_xml_root_standalone ')'
16276 : : {
16277 : : $$ = makeXmlExpr(IS_XMLROOT, NULL, NIL,
16278 : : list_make3($3, $5, $6), @1);
16279 : : }
16280 : : | XMLSERIALIZE '(' document_or_content a_expr AS SimpleTypename xml_indent_option ')'
16281 : : {
16282 : : XmlSerialize *n = makeNode(XmlSerialize);
16283 : :
16284 : : n->xmloption = $3;
16285 : : n->expr = $4;
16286 : : n->typeName = $6;
16287 : : n->indent = $7;
16288 : : n->location = @1;
16289 : : $$ = (Node *) n;
16290 : : }
16291 : : | JSON_OBJECT '(' func_arg_list ')'
16292 : : {
16293 : : /* Support for legacy (non-standard) json_object() */
16294 : : $$ = (Node *) makeFuncCall(SystemFuncName("json_object"),
16295 : : $3, COERCE_EXPLICIT_CALL, @1);
16296 : : }
16297 : : | JSON_OBJECT '(' json_name_and_value_list
16298 : : json_object_constructor_null_clause_opt
16299 : : json_key_uniqueness_constraint_opt
16300 : : json_returning_clause_opt ')'
16301 : : {
16302 : : JsonObjectConstructor *n = makeNode(JsonObjectConstructor);
16303 : :
16304 : : n->exprs = $3;
16305 : : n->absent_on_null = $4;
16306 : : n->unique = $5;
16307 : : n->output = (JsonOutput *) $6;
16308 : : n->location = @1;
16309 : : $$ = (Node *) n;
16310 : : }
16311 : : | JSON_OBJECT '(' json_returning_clause_opt ')'
16312 : : {
16313 : : JsonObjectConstructor *n = makeNode(JsonObjectConstructor);
16314 : :
16315 : : n->exprs = NULL;
16316 : : n->absent_on_null = false;
16317 : : n->unique = false;
16318 : : n->output = (JsonOutput *) $3;
16319 : : n->location = @1;
16320 : : $$ = (Node *) n;
16321 : : }
16322 : : | JSON_ARRAY '('
16323 : : json_value_expr_list
16324 : : json_array_constructor_null_clause_opt
16325 : : json_returning_clause_opt
16326 : : ')'
16327 : : {
16328 : : JsonArrayConstructor *n = makeNode(JsonArrayConstructor);
16329 : :
16330 : : n->exprs = $3;
16331 : : n->absent_on_null = $4;
16332 : : n->output = (JsonOutput *) $5;
16333 : : n->location = @1;
16334 : : $$ = (Node *) n;
16335 : : }
16336 : : | JSON_ARRAY '('
16337 : : select_no_parens
16338 : : json_format_clause_opt
16339 : : /* json_array_constructor_null_clause_opt */
16340 : : json_returning_clause_opt
16341 : : ')'
16342 : : {
16343 : : JsonArrayQueryConstructor *n = makeNode(JsonArrayQueryConstructor);
16344 : :
16345 : : n->query = $3;
16346 : : n->format = (JsonFormat *) $4;
16347 : : n->absent_on_null = true; /* XXX */
16348 : : n->output = (JsonOutput *) $5;
16349 : : n->location = @1;
16350 : : $$ = (Node *) n;
16351 : : }
16352 : : | JSON_ARRAY '('
16353 : : json_returning_clause_opt
16354 : : ')'
16355 : : {
16356 : : JsonArrayConstructor *n = makeNode(JsonArrayConstructor);
16357 : :
16358 : : n->exprs = NIL;
16359 : : n->absent_on_null = true;
16360 : : n->output = (JsonOutput *) $3;
16361 : : n->location = @1;
16362 : : $$ = (Node *) n;
16363 : : }
16364 : : | JSON '(' json_value_expr json_key_uniqueness_constraint_opt ')'
16365 : : {
16366 : : JsonParseExpr *n = makeNode(JsonParseExpr);
16367 : :
16368 : : n->expr = (JsonValueExpr *) $3;
16369 : : n->unique_keys = $4;
16370 : : n->output = NULL;
16371 : : n->location = @1;
16372 : : $$ = (Node *) n;
16373 : : }
16374 : : | JSON_SCALAR '(' a_expr ')'
16375 : : {
16376 : : JsonScalarExpr *n = makeNode(JsonScalarExpr);
16377 : :
16378 : : n->expr = (Expr *) $3;
16379 : : n->output = NULL;
16380 : : n->location = @1;
16381 : : $$ = (Node *) n;
16382 : : }
16383 : : | JSON_SERIALIZE '(' json_value_expr json_returning_clause_opt ')'
16384 : : {
16385 : : JsonSerializeExpr *n = makeNode(JsonSerializeExpr);
16386 : :
16387 : : n->expr = (JsonValueExpr *) $3;
16388 : : n->output = (JsonOutput *) $4;
16389 : : n->location = @1;
16390 : : $$ = (Node *) n;
16391 : : }
16392 : : | MERGE_ACTION '(' ')'
16393 : : {
16394 : : MergeSupportFunc *m = makeNode(MergeSupportFunc);
16395 : :
16396 : : m->msftype = TEXTOID;
16397 : : m->location = @1;
16398 : : $$ = (Node *) m;
16399 : : }
16400 : : | JSON_QUERY '('
16401 : : json_value_expr ',' a_expr json_passing_clause_opt
16402 : : json_returning_clause_opt
16403 : : json_wrapper_behavior
16404 : : json_quotes_clause_opt
16405 : : json_behavior_clause_opt
16406 : : ')'
16407 : : {
16408 : : JsonFuncExpr *n = makeNode(JsonFuncExpr);
16409 : :
16410 : : n->op = JSON_QUERY_OP;
16411 : : n->context_item = (JsonValueExpr *) $3;
16412 : : n->pathspec = $5;
16413 : : n->passing = $6;
16414 : : n->output = (JsonOutput *) $7;
16415 : : n->wrapper = $8;
16416 : : n->quotes = $9;
16417 : : n->on_empty = (JsonBehavior *) linitial($10);
16418 : : n->on_error = (JsonBehavior *) lsecond($10);
16419 : : n->location = @1;
16420 : : $$ = (Node *) n;
16421 : : }
16422 : : | JSON_EXISTS '('
16423 : : json_value_expr ',' a_expr json_passing_clause_opt
16424 : : json_on_error_clause_opt
16425 : : ')'
16426 : : {
16427 : : JsonFuncExpr *n = makeNode(JsonFuncExpr);
16428 : :
16429 : : n->op = JSON_EXISTS_OP;
16430 : : n->context_item = (JsonValueExpr *) $3;
16431 : : n->pathspec = $5;
16432 : : n->passing = $6;
16433 : : n->output = NULL;
16434 : : n->on_error = (JsonBehavior *) $7;
16435 : : n->location = @1;
16436 : : $$ = (Node *) n;
16437 : : }
16438 : : | JSON_VALUE '('
16439 : : json_value_expr ',' a_expr json_passing_clause_opt
16440 : : json_returning_clause_opt
16441 : : json_behavior_clause_opt
16442 : : ')'
16443 : : {
16444 : : JsonFuncExpr *n = makeNode(JsonFuncExpr);
16445 : :
16446 : : n->op = JSON_VALUE_OP;
16447 : : n->context_item = (JsonValueExpr *) $3;
16448 : : n->pathspec = $5;
16449 : : n->passing = $6;
16450 : : n->output = (JsonOutput *) $7;
16451 : : n->on_empty = (JsonBehavior *) linitial($8);
16452 : : n->on_error = (JsonBehavior *) lsecond($8);
16453 : : n->location = @1;
16454 : : $$ = (Node *) n;
16455 : : }
16456 : : ;
16457 : :
16458 : :
16459 : : /*
16460 : : * SQL/XML support
16461 : : */
16462 : : xml_root_version: VERSION_P a_expr
16463 : : { $$ = $2; }
16464 : : | VERSION_P NO VALUE_P
16465 : : { $$ = makeNullAConst(-1); }
16466 : : ;
16467 : :
16468 : : opt_xml_root_standalone: ',' STANDALONE_P YES_P
16469 : : { $$ = makeIntConst(XML_STANDALONE_YES, -1); }
16470 : : | ',' STANDALONE_P NO
16471 : : { $$ = makeIntConst(XML_STANDALONE_NO, -1); }
16472 : : | ',' STANDALONE_P NO VALUE_P
16473 : : { $$ = makeIntConst(XML_STANDALONE_NO_VALUE, -1); }
16474 : : | /*EMPTY*/
16475 : : { $$ = makeIntConst(XML_STANDALONE_OMITTED, -1); }
16476 : : ;
16477 : :
16478 : : xml_attributes: XMLATTRIBUTES '(' xml_attribute_list ')' { $$ = $3; }
16479 : : ;
16480 : :
16481 : : xml_attribute_list: xml_attribute_el { $$ = list_make1($1); }
16482 : : | xml_attribute_list ',' xml_attribute_el { $$ = lappend($1, $3); }
16483 : : ;
16484 : :
16485 : : xml_attribute_el: a_expr AS ColLabel
16486 : : {
16487 : : $$ = makeNode(ResTarget);
16488 : : $$->name = $3;
16489 : : $$->indirection = NIL;
16490 : : $$->val = (Node *) $1;
16491 : : $$->location = @1;
16492 : : }
16493 : : | a_expr
16494 : : {
16495 : : $$ = makeNode(ResTarget);
16496 : : $$->name = NULL;
16497 : : $$->indirection = NIL;
16498 : : $$->val = (Node *) $1;
16499 : : $$->location = @1;
16500 : : }
16501 : : ;
16502 : :
16503 : : document_or_content: DOCUMENT_P { $$ = XMLOPTION_DOCUMENT; }
16504 : : | CONTENT_P { $$ = XMLOPTION_CONTENT; }
16505 : : ;
16506 : :
16507 : : xml_indent_option: INDENT { $$ = true; }
16508 : : | NO INDENT { $$ = false; }
16509 : : | /*EMPTY*/ { $$ = false; }
16510 : : ;
16511 : :
16512 : : xml_whitespace_option: PRESERVE WHITESPACE_P { $$ = true; }
16513 : : | STRIP_P WHITESPACE_P { $$ = false; }
16514 : : | /*EMPTY*/ { $$ = false; }
16515 : : ;
16516 : :
16517 : : /* We allow several variants for SQL and other compatibility. */
16518 : : xmlexists_argument:
16519 : : PASSING c_expr
16520 : : {
16521 : : $$ = $2;
16522 : : }
16523 : : | PASSING c_expr xml_passing_mech
16524 : : {
16525 : : $$ = $2;
16526 : : }
16527 : : | PASSING xml_passing_mech c_expr
16528 : : {
16529 : : $$ = $3;
16530 : : }
16531 : : | PASSING xml_passing_mech c_expr xml_passing_mech
16532 : : {
16533 : : $$ = $3;
16534 : : }
16535 : : ;
16536 : :
16537 : : xml_passing_mech:
16538 : : BY REF_P
16539 : : | BY VALUE_P
16540 : : ;
16541 : :
16542 : : /*****************************************************************************
16543 : : *
16544 : : * WAIT FOR LSN
16545 : : *
16546 : : *****************************************************************************/
16547 : :
16548 : : WaitStmt:
16549 : : WAIT FOR LSN_P Sconst opt_wait_with_clause
16550 : : {
16551 : : WaitStmt *n = makeNode(WaitStmt);
16552 : : n->lsn_literal = $4;
16553 : : n->options = $5;
16554 : : $$ = (Node *) n;
16555 : : }
16556 : : ;
16557 : :
16558 : : opt_wait_with_clause:
16559 : : WITH '(' utility_option_list ')' { $$ = $3; }
16560 : : | /*EMPTY*/ { $$ = NIL; }
16561 : : ;
16562 : :
16563 : : /*
16564 : : * Aggregate decoration clauses
16565 : : */
16566 : : within_group_clause:
16567 : : WITHIN GROUP_P '(' sort_clause ')' { $$ = $4; }
16568 : : | /*EMPTY*/ { $$ = NIL; }
16569 : : ;
16570 : :
16571 : : filter_clause:
16572 : : FILTER '(' WHERE a_expr ')' { $$ = $4; }
16573 : : | /*EMPTY*/ { $$ = NULL; }
16574 : : ;
16575 : :
16576 : :
16577 : : /*
16578 : : * Window Definitions
16579 : : */
16580 : : null_treatment:
16581 : : IGNORE_P NULLS_P { $$ = PARSER_IGNORE_NULLS; }
16582 : : | RESPECT_P NULLS_P { $$ = PARSER_RESPECT_NULLS; }
16583 : : | /*EMPTY*/ { $$ = NO_NULLTREATMENT; }
16584 : : ;
16585 : :
16586 : : window_clause:
16587 : : WINDOW window_definition_list { $$ = $2; }
16588 : : | /*EMPTY*/ { $$ = NIL; }
16589 : : ;
16590 : :
16591 : : window_definition_list:
16592 : : window_definition { $$ = list_make1($1); }
16593 : : | window_definition_list ',' window_definition
16594 : : { $$ = lappend($1, $3); }
16595 : : ;
16596 : :
16597 : : window_definition:
16598 : : ColId AS window_specification
16599 : : {
16600 : : WindowDef *n = $3;
16601 : :
16602 : : n->name = $1;
16603 : : $$ = n;
16604 : : }
16605 : : ;
16606 : :
16607 : : over_clause: OVER window_specification
16608 : : { $$ = $2; }
16609 : : | OVER ColId
16610 : : {
16611 : : WindowDef *n = makeNode(WindowDef);
16612 : :
16613 : : n->name = $2;
16614 : : n->refname = NULL;
16615 : : n->partitionClause = NIL;
16616 : : n->orderClause = NIL;
16617 : : n->frameOptions = FRAMEOPTION_DEFAULTS;
16618 : : n->startOffset = NULL;
16619 : : n->endOffset = NULL;
16620 : : n->location = @2;
16621 : : $$ = n;
16622 : : }
16623 : : | /*EMPTY*/
16624 : : { $$ = NULL; }
16625 : : ;
16626 : :
16627 : : window_specification: '(' opt_existing_window_name opt_partition_clause
16628 : : opt_sort_clause opt_frame_clause ')'
16629 : : {
16630 : : WindowDef *n = makeNode(WindowDef);
16631 : :
16632 : : n->name = NULL;
16633 : : n->refname = $2;
16634 : : n->partitionClause = $3;
16635 : : n->orderClause = $4;
16636 : : /* copy relevant fields of opt_frame_clause */
16637 : : n->frameOptions = $5->frameOptions;
16638 : : n->startOffset = $5->startOffset;
16639 : : n->endOffset = $5->endOffset;
16640 : : n->location = @1;
16641 : : $$ = n;
16642 : : }
16643 : : ;
16644 : :
16645 : : /*
16646 : : * If we see PARTITION, RANGE, ROWS or GROUPS as the first token after the '('
16647 : : * of a window_specification, we want the assumption to be that there is
16648 : : * no existing_window_name; but those keywords are unreserved and so could
16649 : : * be ColIds. We fix this by making them have the same precedence as IDENT
16650 : : * and giving the empty production here a slightly higher precedence, so
16651 : : * that the shift/reduce conflict is resolved in favor of reducing the rule.
16652 : : * These keywords are thus precluded from being an existing_window_name but
16653 : : * are not reserved for any other purpose.
16654 : : */
16655 : : opt_existing_window_name: ColId { $$ = $1; }
16656 : : | /*EMPTY*/ %prec Op { $$ = NULL; }
16657 : : ;
16658 : :
16659 : : opt_partition_clause: PARTITION BY expr_list { $$ = $3; }
16660 : : | /*EMPTY*/ { $$ = NIL; }
16661 : : ;
16662 : :
16663 : : /*
16664 : : * For frame clauses, we return a WindowDef, but only some fields are used:
16665 : : * frameOptions, startOffset, and endOffset.
16666 : : */
16667 : : opt_frame_clause:
16668 : : RANGE frame_extent opt_window_exclusion_clause
16669 : : {
16670 : : WindowDef *n = $2;
16671 : :
16672 : : n->frameOptions |= FRAMEOPTION_NONDEFAULT | FRAMEOPTION_RANGE;
16673 : : n->frameOptions |= $3;
16674 : : $$ = n;
16675 : : }
16676 : : | ROWS frame_extent opt_window_exclusion_clause
16677 : : {
16678 : : WindowDef *n = $2;
16679 : :
16680 : : n->frameOptions |= FRAMEOPTION_NONDEFAULT | FRAMEOPTION_ROWS;
16681 : : n->frameOptions |= $3;
16682 : : $$ = n;
16683 : : }
16684 : : | GROUPS frame_extent opt_window_exclusion_clause
16685 : : {
16686 : : WindowDef *n = $2;
16687 : :
16688 : : n->frameOptions |= FRAMEOPTION_NONDEFAULT | FRAMEOPTION_GROUPS;
16689 : : n->frameOptions |= $3;
16690 : : $$ = n;
16691 : : }
16692 : : | /*EMPTY*/
16693 : : {
16694 : : WindowDef *n = makeNode(WindowDef);
16695 : :
16696 : : n->frameOptions = FRAMEOPTION_DEFAULTS;
16697 : : n->startOffset = NULL;
16698 : : n->endOffset = NULL;
16699 : : $$ = n;
16700 : : }
16701 : : ;
16702 : :
16703 : : frame_extent: frame_bound
16704 : : {
16705 : : WindowDef *n = $1;
16706 : :
16707 : : /* reject invalid cases */
16708 : : if (n->frameOptions & FRAMEOPTION_START_UNBOUNDED_FOLLOWING)
16709 : : ereport(ERROR,
16710 : : (errcode(ERRCODE_WINDOWING_ERROR),
16711 : : errmsg("frame start cannot be UNBOUNDED FOLLOWING"),
16712 : : parser_errposition(@1)));
16713 : : if (n->frameOptions & FRAMEOPTION_START_OFFSET_FOLLOWING)
16714 : : ereport(ERROR,
16715 : : (errcode(ERRCODE_WINDOWING_ERROR),
16716 : : errmsg("frame starting from following row cannot end with current row"),
16717 : : parser_errposition(@1)));
16718 : : n->frameOptions |= FRAMEOPTION_END_CURRENT_ROW;
16719 : : $$ = n;
16720 : : }
16721 : : | BETWEEN frame_bound AND frame_bound
16722 : : {
16723 : : WindowDef *n1 = $2;
16724 : : WindowDef *n2 = $4;
16725 : :
16726 : : /* form merged options */
16727 : : int frameOptions = n1->frameOptions;
16728 : : /* shift converts START_ options to END_ options */
16729 : : frameOptions |= n2->frameOptions << 1;
16730 : : frameOptions |= FRAMEOPTION_BETWEEN;
16731 : : /* reject invalid cases */
16732 : : if (frameOptions & FRAMEOPTION_START_UNBOUNDED_FOLLOWING)
16733 : : ereport(ERROR,
16734 : : (errcode(ERRCODE_WINDOWING_ERROR),
16735 : : errmsg("frame start cannot be UNBOUNDED FOLLOWING"),
16736 : : parser_errposition(@2)));
16737 : : if (frameOptions & FRAMEOPTION_END_UNBOUNDED_PRECEDING)
16738 : : ereport(ERROR,
16739 : : (errcode(ERRCODE_WINDOWING_ERROR),
16740 : : errmsg("frame end cannot be UNBOUNDED PRECEDING"),
16741 : : parser_errposition(@4)));
16742 : : if ((frameOptions & FRAMEOPTION_START_CURRENT_ROW) &&
16743 : : (frameOptions & FRAMEOPTION_END_OFFSET_PRECEDING))
16744 : : ereport(ERROR,
16745 : : (errcode(ERRCODE_WINDOWING_ERROR),
16746 : : errmsg("frame starting from current row cannot have preceding rows"),
16747 : : parser_errposition(@4)));
16748 : : if ((frameOptions & FRAMEOPTION_START_OFFSET_FOLLOWING) &&
16749 : : (frameOptions & (FRAMEOPTION_END_OFFSET_PRECEDING |
16750 : : FRAMEOPTION_END_CURRENT_ROW)))
16751 : : ereport(ERROR,
16752 : : (errcode(ERRCODE_WINDOWING_ERROR),
16753 : : errmsg("frame starting from following row cannot have preceding rows"),
16754 : : parser_errposition(@4)));
16755 : : n1->frameOptions = frameOptions;
16756 : : n1->endOffset = n2->startOffset;
16757 : : $$ = n1;
16758 : : }
16759 : : ;
16760 : :
16761 : : /*
16762 : : * This is used for both frame start and frame end, with output set up on
16763 : : * the assumption it's frame start; the frame_extent productions must reject
16764 : : * invalid cases.
16765 : : */
16766 : : frame_bound:
16767 : : UNBOUNDED PRECEDING
16768 : : {
16769 : : WindowDef *n = makeNode(WindowDef);
16770 : :
16771 : : n->frameOptions = FRAMEOPTION_START_UNBOUNDED_PRECEDING;
16772 : : n->startOffset = NULL;
16773 : : n->endOffset = NULL;
16774 : : $$ = n;
16775 : : }
16776 : : | UNBOUNDED FOLLOWING
16777 : : {
16778 : : WindowDef *n = makeNode(WindowDef);
16779 : :
16780 : : n->frameOptions = FRAMEOPTION_START_UNBOUNDED_FOLLOWING;
16781 : : n->startOffset = NULL;
16782 : : n->endOffset = NULL;
16783 : : $$ = n;
16784 : : }
16785 : : | CURRENT_P ROW
16786 : : {
16787 : : WindowDef *n = makeNode(WindowDef);
16788 : :
16789 : : n->frameOptions = FRAMEOPTION_START_CURRENT_ROW;
16790 : : n->startOffset = NULL;
16791 : : n->endOffset = NULL;
16792 : : $$ = n;
16793 : : }
16794 : : | a_expr PRECEDING
16795 : : {
16796 : : WindowDef *n = makeNode(WindowDef);
16797 : :
16798 : : n->frameOptions = FRAMEOPTION_START_OFFSET_PRECEDING;
16799 : : n->startOffset = $1;
16800 : : n->endOffset = NULL;
16801 : : $$ = n;
16802 : : }
16803 : : | a_expr FOLLOWING
16804 : : {
16805 : : WindowDef *n = makeNode(WindowDef);
16806 : :
16807 : : n->frameOptions = FRAMEOPTION_START_OFFSET_FOLLOWING;
16808 : : n->startOffset = $1;
16809 : : n->endOffset = NULL;
16810 : : $$ = n;
16811 : : }
16812 : : ;
16813 : :
16814 : : opt_window_exclusion_clause:
16815 : : EXCLUDE CURRENT_P ROW { $$ = FRAMEOPTION_EXCLUDE_CURRENT_ROW; }
16816 : : | EXCLUDE GROUP_P { $$ = FRAMEOPTION_EXCLUDE_GROUP; }
16817 : : | EXCLUDE TIES { $$ = FRAMEOPTION_EXCLUDE_TIES; }
16818 : : | EXCLUDE NO OTHERS { $$ = 0; }
16819 : : | /*EMPTY*/ { $$ = 0; }
16820 : : ;
16821 : :
16822 : :
16823 : : /*
16824 : : * Supporting nonterminals for expressions.
16825 : : */
16826 : :
16827 : : /* Explicit row production.
16828 : : *
16829 : : * SQL99 allows an optional ROW keyword, so we can now do single-element rows
16830 : : * without conflicting with the parenthesized a_expr production. Without the
16831 : : * ROW keyword, there must be more than one a_expr inside the parens.
16832 : : */
16833 : : row: ROW '(' expr_list ')' { $$ = $3; }
16834 : : | ROW '(' ')' { $$ = NIL; }
16835 : : | '(' expr_list ',' a_expr ')' { $$ = lappend($2, $4); }
16836 : : ;
16837 : :
16838 : : explicit_row: ROW '(' expr_list ')' { $$ = $3; }
16839 : : | ROW '(' ')' { $$ = NIL; }
16840 : : ;
16841 : :
16842 : : implicit_row: '(' expr_list ',' a_expr ')' { $$ = lappend($2, $4); }
16843 : : ;
16844 : :
16845 : : sub_type: ANY { $$ = ANY_SUBLINK; }
16846 : : | SOME { $$ = ANY_SUBLINK; }
16847 : : | ALL { $$ = ALL_SUBLINK; }
16848 : : ;
16849 : :
16850 : : all_Op: Op { $$ = $1; }
16851 : : | MathOp { $$ = $1; }
16852 : : ;
16853 : :
16854 : : MathOp: '+' { $$ = "+"; }
16855 : : | '-' { $$ = "-"; }
16856 : : | '*' { $$ = "*"; }
16857 : : | '/' { $$ = "/"; }
16858 : : | '%' { $$ = "%"; }
16859 : : | '^' { $$ = "^"; }
16860 : : | '<' { $$ = "<"; }
16861 : : | '>' { $$ = ">"; }
16862 : : | '=' { $$ = "="; }
16863 : : | LESS_EQUALS { $$ = "<="; }
16864 : : | GREATER_EQUALS { $$ = ">="; }
16865 : : | NOT_EQUALS { $$ = "<>"; }
16866 : : ;
16867 : :
16868 : : qual_Op: Op
16869 : : { $$ = list_make1(makeString($1)); }
16870 : : | OPERATOR '(' any_operator ')'
16871 : : { $$ = $3; }
16872 : : ;
16873 : :
16874 : : qual_all_Op:
16875 : : all_Op
16876 : : { $$ = list_make1(makeString($1)); }
16877 : : | OPERATOR '(' any_operator ')'
16878 : : { $$ = $3; }
16879 : : ;
16880 : :
16881 : : subquery_Op:
16882 : : all_Op
16883 : : { $$ = list_make1(makeString($1)); }
16884 : : | OPERATOR '(' any_operator ')'
16885 : : { $$ = $3; }
16886 : : | LIKE
16887 : : { $$ = list_make1(makeString("~~")); }
16888 : : | NOT_LA LIKE
16889 : : { $$ = list_make1(makeString("!~~")); }
16890 : : | ILIKE
16891 : : { $$ = list_make1(makeString("~~*")); }
16892 : : | NOT_LA ILIKE
16893 : : { $$ = list_make1(makeString("!~~*")); }
16894 : : /* cannot put SIMILAR TO here, because SIMILAR TO is a hack.
16895 : : * the regular expression is preprocessed by a function (similar_to_escape),
16896 : : * and the ~ operator for posix regular expressions is used.
16897 : : * x SIMILAR TO y -> x ~ similar_to_escape(y)
16898 : : * this transformation is made on the fly by the parser upwards.
16899 : : * however the SubLink structure which handles any/some/all stuff
16900 : : * is not ready for such a thing.
16901 : : */
16902 : : ;
16903 : :
16904 : : expr_list: a_expr
16905 : : {
16906 : : $$ = list_make1($1);
16907 : : }
16908 : : | expr_list ',' a_expr
16909 : : {
16910 : : $$ = lappend($1, $3);
16911 : : }
16912 : : ;
16913 : :
16914 : : /* function arguments can have names */
16915 : : func_arg_list: func_arg_expr
16916 : : {
16917 : : $$ = list_make1($1);
16918 : : }
16919 : : | func_arg_list ',' func_arg_expr
16920 : : {
16921 : : $$ = lappend($1, $3);
16922 : : }
16923 : : ;
16924 : :
16925 : : func_arg_expr: a_expr
16926 : : {
16927 : : $$ = $1;
16928 : : }
16929 : : | param_name COLON_EQUALS a_expr
16930 : : {
16931 : : NamedArgExpr *na = makeNode(NamedArgExpr);
16932 : :
16933 : : na->name = $1;
16934 : : na->arg = (Expr *) $3;
16935 : : na->argnumber = -1; /* until determined */
16936 : : na->location = @1;
16937 : : $$ = (Node *) na;
16938 : : }
16939 : : | param_name EQUALS_GREATER a_expr
16940 : : {
16941 : : NamedArgExpr *na = makeNode(NamedArgExpr);
16942 : :
16943 : : na->name = $1;
16944 : : na->arg = (Expr *) $3;
16945 : : na->argnumber = -1; /* until determined */
16946 : : na->location = @1;
16947 : : $$ = (Node *) na;
16948 : : }
16949 : : ;
16950 : :
16951 : : func_arg_list_opt: func_arg_list { $$ = $1; }
16952 : : | /*EMPTY*/ { $$ = NIL; }
16953 : : ;
16954 : :
16955 : : type_list: Typename { $$ = list_make1($1); }
16956 : : | type_list ',' Typename { $$ = lappend($1, $3); }
16957 : : ;
16958 : :
16959 : : array_expr: '[' expr_list ']'
16960 : : {
16961 : : $$ = makeAArrayExpr($2, @1, @3);
16962 : : }
16963 : : | '[' array_expr_list ']'
16964 : : {
16965 : : $$ = makeAArrayExpr($2, @1, @3);
16966 : : }
16967 : : | '[' ']'
16968 : : {
16969 : : $$ = makeAArrayExpr(NIL, @1, @2);
16970 : : }
16971 : : ;
16972 : :
16973 : : array_expr_list: array_expr { $$ = list_make1($1); }
16974 : : | array_expr_list ',' array_expr { $$ = lappend($1, $3); }
16975 : : ;
16976 : :
16977 : :
16978 : : extract_list:
16979 : : extract_arg FROM a_expr
16980 : : {
16981 : : $$ = list_make2(makeStringConst($1, @1), $3);
16982 : : }
16983 : : ;
16984 : :
16985 : : /* Allow delimited string Sconst in extract_arg as an SQL extension.
16986 : : * - thomas 2001-04-12
16987 : : */
16988 : : extract_arg:
16989 : : IDENT { $$ = $1; }
16990 : : | YEAR_P { $$ = "year"; }
16991 : : | MONTH_P { $$ = "month"; }
16992 : : | DAY_P { $$ = "day"; }
16993 : : | HOUR_P { $$ = "hour"; }
16994 : : | MINUTE_P { $$ = "minute"; }
16995 : : | SECOND_P { $$ = "second"; }
16996 : : | Sconst { $$ = $1; }
16997 : : ;
16998 : :
16999 : : unicode_normal_form:
17000 : : NFC { $$ = "NFC"; }
17001 : : | NFD { $$ = "NFD"; }
17002 : : | NFKC { $$ = "NFKC"; }
17003 : : | NFKD { $$ = "NFKD"; }
17004 : : ;
17005 : :
17006 : : /* OVERLAY() arguments */
17007 : : overlay_list:
17008 : : a_expr PLACING a_expr FROM a_expr FOR a_expr
17009 : : {
17010 : : /* overlay(A PLACING B FROM C FOR D) is converted to overlay(A, B, C, D) */
17011 : : $$ = list_make4($1, $3, $5, $7);
17012 : : }
17013 : : | a_expr PLACING a_expr FROM a_expr
17014 : : {
17015 : : /* overlay(A PLACING B FROM C) is converted to overlay(A, B, C) */
17016 : : $$ = list_make3($1, $3, $5);
17017 : : }
17018 : : ;
17019 : :
17020 : : /* position_list uses b_expr not a_expr to avoid conflict with general IN */
17021 : : position_list:
17022 : : b_expr IN_P b_expr { $$ = list_make2($3, $1); }
17023 : : ;
17024 : :
17025 : : /*
17026 : : * SUBSTRING() arguments
17027 : : *
17028 : : * Note that SQL:1999 has both
17029 : : * text FROM int FOR int
17030 : : * and
17031 : : * text FROM pattern FOR escape
17032 : : *
17033 : : * In the parser we map them both to a call to the substring() function and
17034 : : * rely on type resolution to pick the right one.
17035 : : *
17036 : : * In SQL:2003, the second variant was changed to
17037 : : * text SIMILAR pattern ESCAPE escape
17038 : : * We could in theory map that to a different function internally, but
17039 : : * since we still support the SQL:1999 version, we don't. However,
17040 : : * ruleutils.c will reverse-list the call in the newer style.
17041 : : */
17042 : : substr_list:
17043 : : a_expr FROM a_expr FOR a_expr
17044 : : {
17045 : : $$ = list_make3($1, $3, $5);
17046 : : }
17047 : : | a_expr FOR a_expr FROM a_expr
17048 : : {
17049 : : /* not legal per SQL, but might as well allow it */
17050 : : $$ = list_make3($1, $5, $3);
17051 : : }
17052 : : | a_expr FROM a_expr
17053 : : {
17054 : : /*
17055 : : * Because we aren't restricting data types here, this
17056 : : * syntax can end up resolving to textregexsubstr().
17057 : : * We've historically allowed that to happen, so continue
17058 : : * to accept it. However, ruleutils.c will reverse-list
17059 : : * such a call in regular function call syntax.
17060 : : */
17061 : : $$ = list_make2($1, $3);
17062 : : }
17063 : : | a_expr FOR a_expr
17064 : : {
17065 : : /* not legal per SQL */
17066 : :
17067 : : /*
17068 : : * Since there are no cases where this syntax allows
17069 : : * a textual FOR value, we forcibly cast the argument
17070 : : * to int4. The possible matches in pg_proc are
17071 : : * substring(text,int4) and substring(text,text),
17072 : : * and we don't want the parser to choose the latter,
17073 : : * which it is likely to do if the second argument
17074 : : * is unknown or doesn't have an implicit cast to int4.
17075 : : */
17076 : : $$ = list_make3($1, makeIntConst(1, -1),
17077 : : makeTypeCast($3,
17078 : : SystemTypeName("int4"), -1));
17079 : : }
17080 : : | a_expr SIMILAR a_expr ESCAPE a_expr
17081 : : {
17082 : : $$ = list_make3($1, $3, $5);
17083 : : }
17084 : : ;
17085 : :
17086 : : trim_list: a_expr FROM expr_list { $$ = lappend($3, $1); }
17087 : : | FROM expr_list { $$ = $2; }
17088 : : | expr_list { $$ = $1; }
17089 : : ;
17090 : :
17091 : : /*
17092 : : * Define SQL-style CASE clause.
17093 : : * - Full specification
17094 : : * CASE WHEN a = b THEN c ... ELSE d END
17095 : : * - Implicit argument
17096 : : * CASE a WHEN b THEN c ... ELSE d END
17097 : : */
17098 : : case_expr: CASE case_arg when_clause_list case_default END_P
17099 : : {
17100 : : CaseExpr *c = makeNode(CaseExpr);
17101 : :
17102 : : c->casetype = InvalidOid; /* not analyzed yet */
17103 : : c->arg = (Expr *) $2;
17104 : : c->args = $3;
17105 : : c->defresult = (Expr *) $4;
17106 : : c->location = @1;
17107 : : $$ = (Node *) c;
17108 : : }
17109 : : ;
17110 : :
17111 : : when_clause_list:
17112 : : /* There must be at least one */
17113 : : when_clause { $$ = list_make1($1); }
17114 : : | when_clause_list when_clause { $$ = lappend($1, $2); }
17115 : : ;
17116 : :
17117 : : when_clause:
17118 : : WHEN a_expr THEN a_expr
17119 : : {
17120 : : CaseWhen *w = makeNode(CaseWhen);
17121 : :
17122 : : w->expr = (Expr *) $2;
17123 : : w->result = (Expr *) $4;
17124 : : w->location = @1;
17125 : : $$ = (Node *) w;
17126 : : }
17127 : : ;
17128 : :
17129 : : case_default:
17130 : : ELSE a_expr { $$ = $2; }
17131 : : | /*EMPTY*/ { $$ = NULL; }
17132 : : ;
17133 : :
17134 : : case_arg: a_expr { $$ = $1; }
17135 : : | /*EMPTY*/ { $$ = NULL; }
17136 : : ;
17137 : :
17138 : : columnref: ColId
17139 : : {
17140 : : $$ = makeColumnRef($1, NIL, @1, yyscanner);
17141 : : }
17142 : : | ColId indirection
17143 : : {
17144 : : $$ = makeColumnRef($1, $2, @1, yyscanner);
17145 : : }
17146 : : ;
17147 : :
17148 : : indirection_el:
17149 : : '.' attr_name
17150 : : {
17151 : : $$ = (Node *) makeString($2);
17152 : : }
17153 : : | '.' '*'
17154 : : {
17155 : : $$ = (Node *) makeNode(A_Star);
17156 : : }
17157 : : | '[' a_expr ']'
17158 : : {
17159 : : A_Indices *ai = makeNode(A_Indices);
17160 : :
17161 : : ai->is_slice = false;
17162 : : ai->lidx = NULL;
17163 : : ai->uidx = $2;
17164 : : $$ = (Node *) ai;
17165 : : }
17166 : : | '[' opt_slice_bound ':' opt_slice_bound ']'
17167 : : {
17168 : : A_Indices *ai = makeNode(A_Indices);
17169 : :
17170 : : ai->is_slice = true;
17171 : : ai->lidx = $2;
17172 : : ai->uidx = $4;
17173 : : $$ = (Node *) ai;
17174 : : }
17175 : : ;
17176 : :
17177 : : opt_slice_bound:
17178 : : a_expr { $$ = $1; }
17179 : : | /*EMPTY*/ { $$ = NULL; }
17180 : : ;
17181 : :
17182 : : indirection:
17183 : : indirection_el { $$ = list_make1($1); }
17184 : : | indirection indirection_el { $$ = lappend($1, $2); }
17185 : : ;
17186 : :
17187 : : opt_indirection:
17188 : : /*EMPTY*/ { $$ = NIL; }
17189 : : | opt_indirection indirection_el { $$ = lappend($1, $2); }
17190 : : ;
17191 : :
17192 : : opt_asymmetric: ASYMMETRIC
17193 : : | /*EMPTY*/
17194 : : ;
17195 : :
17196 : : /* SQL/JSON support */
17197 : : json_passing_clause_opt:
17198 : : PASSING json_arguments { $$ = $2; }
17199 : : | /*EMPTY*/ { $$ = NIL; }
17200 : : ;
17201 : :
17202 : : json_arguments:
17203 : : json_argument { $$ = list_make1($1); }
17204 : : | json_arguments ',' json_argument { $$ = lappend($1, $3); }
17205 : : ;
17206 : :
17207 : : json_argument:
17208 : : json_value_expr AS ColLabel
17209 : : {
17210 : : JsonArgument *n = makeNode(JsonArgument);
17211 : :
17212 : : n->val = (JsonValueExpr *) $1;
17213 : : n->name = $3;
17214 : : $$ = (Node *) n;
17215 : : }
17216 : : ;
17217 : :
17218 : : /* ARRAY is a noise word */
17219 : : json_wrapper_behavior:
17220 : : WITHOUT WRAPPER { $$ = JSW_NONE; }
17221 : : | WITHOUT ARRAY WRAPPER { $$ = JSW_NONE; }
17222 : : | WITH WRAPPER { $$ = JSW_UNCONDITIONAL; }
17223 : : | WITH ARRAY WRAPPER { $$ = JSW_UNCONDITIONAL; }
17224 : : | WITH CONDITIONAL ARRAY WRAPPER { $$ = JSW_CONDITIONAL; }
17225 : : | WITH UNCONDITIONAL ARRAY WRAPPER { $$ = JSW_UNCONDITIONAL; }
17226 : : | WITH CONDITIONAL WRAPPER { $$ = JSW_CONDITIONAL; }
17227 : : | WITH UNCONDITIONAL WRAPPER { $$ = JSW_UNCONDITIONAL; }
17228 : : | /* empty */ { $$ = JSW_UNSPEC; }
17229 : : ;
17230 : :
17231 : : json_behavior:
17232 : : DEFAULT a_expr
17233 : : { $$ = (Node *) makeJsonBehavior(JSON_BEHAVIOR_DEFAULT, $2, @1); }
17234 : : | json_behavior_type
17235 : : { $$ = (Node *) makeJsonBehavior($1, NULL, @1); }
17236 : : ;
17237 : :
17238 : : json_behavior_type:
17239 : : ERROR_P { $$ = JSON_BEHAVIOR_ERROR; }
17240 : : | NULL_P { $$ = JSON_BEHAVIOR_NULL; }
17241 : : | TRUE_P { $$ = JSON_BEHAVIOR_TRUE; }
17242 : : | FALSE_P { $$ = JSON_BEHAVIOR_FALSE; }
17243 : : | UNKNOWN { $$ = JSON_BEHAVIOR_UNKNOWN; }
17244 : : | EMPTY_P ARRAY { $$ = JSON_BEHAVIOR_EMPTY_ARRAY; }
17245 : : | EMPTY_P OBJECT_P { $$ = JSON_BEHAVIOR_EMPTY_OBJECT; }
17246 : : /* non-standard, for Oracle compatibility only */
17247 : : | EMPTY_P { $$ = JSON_BEHAVIOR_EMPTY_ARRAY; }
17248 : : ;
17249 : :
17250 : : json_behavior_clause_opt:
17251 : : json_behavior ON EMPTY_P
17252 : : { $$ = list_make2($1, NULL); }
17253 : : | json_behavior ON ERROR_P
17254 : : { $$ = list_make2(NULL, $1); }
17255 : : | json_behavior ON EMPTY_P json_behavior ON ERROR_P
17256 : : { $$ = list_make2($1, $4); }
17257 : : | /* EMPTY */
17258 : : { $$ = list_make2(NULL, NULL); }
17259 : : ;
17260 : :
17261 : : json_on_error_clause_opt:
17262 : : json_behavior ON ERROR_P
17263 : : { $$ = $1; }
17264 : : | /* EMPTY */
17265 : : { $$ = NULL; }
17266 : : ;
17267 : :
17268 : : json_value_expr:
17269 : : a_expr json_format_clause_opt
17270 : : {
17271 : : /* formatted_expr will be set during parse-analysis. */
17272 : : $$ = (Node *) makeJsonValueExpr((Expr *) $1, NULL,
17273 : : castNode(JsonFormat, $2));
17274 : : }
17275 : : ;
17276 : :
17277 : : json_format_clause:
17278 : : FORMAT_LA JSON ENCODING name
17279 : : {
17280 : : int encoding;
17281 : :
17282 : : if (!pg_strcasecmp($4, "utf8"))
17283 : : encoding = JS_ENC_UTF8;
17284 : : else if (!pg_strcasecmp($4, "utf16"))
17285 : : encoding = JS_ENC_UTF16;
17286 : : else if (!pg_strcasecmp($4, "utf32"))
17287 : : encoding = JS_ENC_UTF32;
17288 : : else
17289 : : ereport(ERROR,
17290 : : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
17291 : : errmsg("unrecognized JSON encoding: %s", $4),
17292 : : parser_errposition(@4)));
17293 : :
17294 : : $$ = (Node *) makeJsonFormat(JS_FORMAT_JSON, encoding, @1);
17295 : : }
17296 : : | FORMAT_LA JSON
17297 : : {
17298 : : $$ = (Node *) makeJsonFormat(JS_FORMAT_JSON, JS_ENC_DEFAULT, @1);
17299 : : }
17300 : : ;
17301 : :
17302 : : json_format_clause_opt:
17303 : : json_format_clause
17304 : : {
17305 : : $$ = $1;
17306 : : }
17307 : : | /* EMPTY */
17308 : : {
17309 : : $$ = (Node *) makeJsonFormat(JS_FORMAT_DEFAULT, JS_ENC_DEFAULT, -1);
17310 : : }
17311 : : ;
17312 : :
17313 : : json_quotes_clause_opt:
17314 : : KEEP QUOTES ON SCALAR STRING_P { $$ = JS_QUOTES_KEEP; }
17315 : : | KEEP QUOTES { $$ = JS_QUOTES_KEEP; }
17316 : : | OMIT QUOTES ON SCALAR STRING_P { $$ = JS_QUOTES_OMIT; }
17317 : : | OMIT QUOTES { $$ = JS_QUOTES_OMIT; }
17318 : : | /* EMPTY */ { $$ = JS_QUOTES_UNSPEC; }
17319 : : ;
17320 : :
17321 : : json_returning_clause_opt:
17322 : : RETURNING Typename json_format_clause_opt
17323 : : {
17324 : : JsonOutput *n = makeNode(JsonOutput);
17325 : :
17326 : : n->typeName = $2;
17327 : : n->returning = makeNode(JsonReturning);
17328 : : n->returning->format = (JsonFormat *) $3;
17329 : : $$ = (Node *) n;
17330 : : }
17331 : : | /* EMPTY */ { $$ = NULL; }
17332 : : ;
17333 : :
17334 : : /*
17335 : : * We must assign the only-JSON production a precedence less than IDENT in
17336 : : * order to favor shifting over reduction when JSON is followed by VALUE_P,
17337 : : * OBJECT_P, or SCALAR. (ARRAY doesn't need that treatment, because it's a
17338 : : * fully reserved word.) Because json_predicate_type_constraint is always
17339 : : * followed by json_key_uniqueness_constraint_opt, we also need the only-JSON
17340 : : * production to have precedence less than WITH and WITHOUT. UNBOUNDED isn't
17341 : : * really related to this syntax, but it's a convenient choice because it
17342 : : * already has a precedence less than IDENT for other reasons.
17343 : : */
17344 : : json_predicate_type_constraint:
17345 : : JSON %prec UNBOUNDED { $$ = JS_TYPE_ANY; }
17346 : : | JSON VALUE_P { $$ = JS_TYPE_ANY; }
17347 : : | JSON ARRAY { $$ = JS_TYPE_ARRAY; }
17348 : : | JSON OBJECT_P { $$ = JS_TYPE_OBJECT; }
17349 : : | JSON SCALAR { $$ = JS_TYPE_SCALAR; }
17350 : : ;
17351 : :
17352 : : /*
17353 : : * KEYS is a noise word here. To avoid shift/reduce conflicts, assign the
17354 : : * KEYS-less productions a precedence less than IDENT (i.e., less than KEYS).
17355 : : * This prevents reducing them when the next token is KEYS.
17356 : : */
17357 : : json_key_uniqueness_constraint_opt:
17358 : : WITH UNIQUE KEYS { $$ = true; }
17359 : : | WITH UNIQUE %prec UNBOUNDED { $$ = true; }
17360 : : | WITHOUT UNIQUE KEYS { $$ = false; }
17361 : : | WITHOUT UNIQUE %prec UNBOUNDED { $$ = false; }
17362 : : | /* EMPTY */ %prec UNBOUNDED { $$ = false; }
17363 : : ;
17364 : :
17365 : : json_name_and_value_list:
17366 : : json_name_and_value
17367 : : { $$ = list_make1($1); }
17368 : : | json_name_and_value_list ',' json_name_and_value
17369 : : { $$ = lappend($1, $3); }
17370 : : ;
17371 : :
17372 : : json_name_and_value:
17373 : : /* Supporting this syntax seems to require major surgery
17374 : : KEY c_expr VALUE_P json_value_expr
17375 : : { $$ = makeJsonKeyValue($2, $4); }
17376 : : |
17377 : : */
17378 : : c_expr VALUE_P json_value_expr
17379 : : { $$ = makeJsonKeyValue($1, $3); }
17380 : : |
17381 : : a_expr ':' json_value_expr
17382 : : { $$ = makeJsonKeyValue($1, $3); }
17383 : : ;
17384 : :
17385 : : /* empty means false for objects, true for arrays */
17386 : : json_object_constructor_null_clause_opt:
17387 : : NULL_P ON NULL_P { $$ = false; }
17388 : : | ABSENT ON NULL_P { $$ = true; }
17389 : : | /* EMPTY */ { $$ = false; }
17390 : : ;
17391 : :
17392 : : json_array_constructor_null_clause_opt:
17393 : : NULL_P ON NULL_P { $$ = false; }
17394 : : | ABSENT ON NULL_P { $$ = true; }
17395 : : | /* EMPTY */ { $$ = true; }
17396 : : ;
17397 : :
17398 : : json_value_expr_list:
17399 : : json_value_expr { $$ = list_make1($1); }
17400 : : | json_value_expr_list ',' json_value_expr { $$ = lappend($1, $3);}
17401 : : ;
17402 : :
17403 : : json_aggregate_func:
17404 : : JSON_OBJECTAGG '('
17405 : : json_name_and_value
17406 : : json_object_constructor_null_clause_opt
17407 : : json_key_uniqueness_constraint_opt
17408 : : json_returning_clause_opt
17409 : : ')'
17410 : : {
17411 : : JsonObjectAgg *n = makeNode(JsonObjectAgg);
17412 : :
17413 : : n->arg = (JsonKeyValue *) $3;
17414 : : n->absent_on_null = $4;
17415 : : n->unique = $5;
17416 : : n->constructor = makeNode(JsonAggConstructor);
17417 : : n->constructor->output = (JsonOutput *) $6;
17418 : : n->constructor->agg_order = NULL;
17419 : : n->constructor->location = @1;
17420 : : $$ = (Node *) n;
17421 : : }
17422 : : | JSON_ARRAYAGG '('
17423 : : json_value_expr
17424 : : json_array_aggregate_order_by_clause_opt
17425 : : json_array_constructor_null_clause_opt
17426 : : json_returning_clause_opt
17427 : : ')'
17428 : : {
17429 : : JsonArrayAgg *n = makeNode(JsonArrayAgg);
17430 : :
17431 : : n->arg = (JsonValueExpr *) $3;
17432 : : n->absent_on_null = $5;
17433 : : n->constructor = makeNode(JsonAggConstructor);
17434 : : n->constructor->agg_order = $4;
17435 : : n->constructor->output = (JsonOutput *) $6;
17436 : : n->constructor->location = @1;
17437 : : $$ = (Node *) n;
17438 : : }
17439 : : ;
17440 : :
17441 : : json_array_aggregate_order_by_clause_opt:
17442 : : ORDER BY sortby_list { $$ = $3; }
17443 : : | /* EMPTY */ { $$ = NIL; }
17444 : : ;
17445 : :
17446 : : /*****************************************************************************
17447 : : *
17448 : : * target list for SELECT
17449 : : *
17450 : : *****************************************************************************/
17451 : :
17452 : : opt_target_list: target_list { $$ = $1; }
17453 : : | /* EMPTY */ { $$ = NIL; }
17454 : : ;
17455 : :
17456 : : target_list:
17457 : : target_el { $$ = list_make1($1); }
17458 : : | target_list ',' target_el { $$ = lappend($1, $3); }
17459 : : ;
17460 : :
17461 : : target_el: a_expr AS ColLabel
17462 : : {
17463 : : $$ = makeNode(ResTarget);
17464 : : $$->name = $3;
17465 : : $$->indirection = NIL;
17466 : : $$->val = (Node *) $1;
17467 : : $$->location = @1;
17468 : : }
17469 : : | a_expr BareColLabel
17470 : : {
17471 : : $$ = makeNode(ResTarget);
17472 : : $$->name = $2;
17473 : : $$->indirection = NIL;
17474 : : $$->val = (Node *) $1;
17475 : : $$->location = @1;
17476 : : }
17477 : : | a_expr
17478 : : {
17479 : : $$ = makeNode(ResTarget);
17480 : : $$->name = NULL;
17481 : : $$->indirection = NIL;
17482 : : $$->val = (Node *) $1;
17483 : : $$->location = @1;
17484 : : }
17485 : : | '*'
17486 : : {
17487 : : ColumnRef *n = makeNode(ColumnRef);
17488 : :
17489 : : n->fields = list_make1(makeNode(A_Star));
17490 : : n->location = @1;
17491 : :
17492 : : $$ = makeNode(ResTarget);
17493 : : $$->name = NULL;
17494 : : $$->indirection = NIL;
17495 : : $$->val = (Node *) n;
17496 : : $$->location = @1;
17497 : : }
17498 : : ;
17499 : :
17500 : :
17501 : : /*****************************************************************************
17502 : : *
17503 : : * Names and constants
17504 : : *
17505 : : *****************************************************************************/
17506 : :
17507 : : qualified_name_list:
17508 : : qualified_name { $$ = list_make1($1); }
17509 : : | qualified_name_list ',' qualified_name { $$ = lappend($1, $3); }
17510 : : ;
17511 : :
17512 : : /*
17513 : : * The production for a qualified relation name has to exactly match the
17514 : : * production for a qualified func_name, because in a FROM clause we cannot
17515 : : * tell which we are parsing until we see what comes after it ('(' for a
17516 : : * func_name, something else for a relation). Therefore we allow 'indirection'
17517 : : * which may contain subscripts, and reject that case in the C code.
17518 : : */
17519 : : qualified_name:
17520 : : ColId
17521 : : {
17522 : : $$ = makeRangeVar(NULL, $1, @1);
17523 : : }
17524 : : | ColId indirection
17525 : : {
17526 : : $$ = makeRangeVarFromQualifiedName($1, $2, @1, yyscanner);
17527 : : }
17528 : : ;
17529 : :
17530 : : name_list: name
17531 : : { $$ = list_make1(makeString($1)); }
17532 : : | name_list ',' name
17533 : : { $$ = lappend($1, makeString($3)); }
17534 : : ;
17535 : :
17536 : :
17537 : : name: ColId { $$ = $1; };
17538 : :
17539 : : attr_name: ColLabel { $$ = $1; };
17540 : :
17541 : : file_name: Sconst { $$ = $1; };
17542 : :
17543 : : /*
17544 : : * The production for a qualified func_name has to exactly match the
17545 : : * production for a qualified columnref, because we cannot tell which we
17546 : : * are parsing until we see what comes after it ('(' or Sconst for a func_name,
17547 : : * anything else for a columnref). Therefore we allow 'indirection' which
17548 : : * may contain subscripts, and reject that case in the C code. (If we
17549 : : * ever implement SQL99-like methods, such syntax may actually become legal!)
17550 : : */
17551 : : func_name: type_function_name
17552 : : { $$ = list_make1(makeString($1)); }
17553 : : | ColId indirection
17554 : : {
17555 : : $$ = check_func_name(lcons(makeString($1), $2),
17556 : : yyscanner);
17557 : : }
17558 : : ;
17559 : :
17560 : :
17561 : : /*
17562 : : * Constants
17563 : : */
17564 : : AexprConst: Iconst
17565 : : {
17566 : : $$ = makeIntConst($1, @1);
17567 : : }
17568 : : | FCONST
17569 : : {
17570 : : $$ = makeFloatConst($1, @1);
17571 : : }
17572 : : | Sconst
17573 : : {
17574 : : $$ = makeStringConst($1, @1);
17575 : : }
17576 : : | BCONST
17577 : : {
17578 : : $$ = makeBitStringConst($1, @1);
17579 : : }
17580 : : | XCONST
17581 : : {
17582 : : /* This is a bit constant per SQL99:
17583 : : * Without Feature F511, "BIT data type",
17584 : : * a <general literal> shall not be a
17585 : : * <bit string literal> or a <hex string literal>.
17586 : : */
17587 : : $$ = makeBitStringConst($1, @1);
17588 : : }
17589 : : | func_name Sconst
17590 : : {
17591 : : /* generic type 'literal' syntax */
17592 : : TypeName *t = makeTypeNameFromNameList($1);
17593 : :
17594 : : t->location = @1;
17595 : : $$ = makeStringConstCast($2, @2, t);
17596 : : }
17597 : : | func_name '(' func_arg_list opt_sort_clause ')' Sconst
17598 : : {
17599 : : /* generic syntax with a type modifier */
17600 : : TypeName *t = makeTypeNameFromNameList($1);
17601 : : ListCell *lc;
17602 : :
17603 : : /*
17604 : : * We must use func_arg_list and opt_sort_clause in the
17605 : : * production to avoid reduce/reduce conflicts, but we
17606 : : * don't actually wish to allow NamedArgExpr in this
17607 : : * context, nor ORDER BY.
17608 : : */
17609 : : foreach(lc, $3)
17610 : : {
17611 : : NamedArgExpr *arg = (NamedArgExpr *) lfirst(lc);
17612 : :
17613 : : if (IsA(arg, NamedArgExpr))
17614 : : ereport(ERROR,
17615 : : (errcode(ERRCODE_SYNTAX_ERROR),
17616 : : errmsg("type modifier cannot have parameter name"),
17617 : : parser_errposition(arg->location)));
17618 : : }
17619 : : if ($4 != NIL)
17620 : : ereport(ERROR,
17621 : : (errcode(ERRCODE_SYNTAX_ERROR),
17622 : : errmsg("type modifier cannot have ORDER BY"),
17623 : : parser_errposition(@4)));
17624 : :
17625 : : t->typmods = $3;
17626 : : t->location = @1;
17627 : : $$ = makeStringConstCast($6, @6, t);
17628 : : }
17629 : : | ConstTypename Sconst
17630 : : {
17631 : : $$ = makeStringConstCast($2, @2, $1);
17632 : : }
17633 : : | ConstInterval Sconst opt_interval
17634 : : {
17635 : : TypeName *t = $1;
17636 : :
17637 : : t->typmods = $3;
17638 : : $$ = makeStringConstCast($2, @2, t);
17639 : : }
17640 : : | ConstInterval '(' Iconst ')' Sconst
17641 : : {
17642 : : TypeName *t = $1;
17643 : :
17644 : : t->typmods = list_make2(makeIntConst(INTERVAL_FULL_RANGE, -1),
17645 : : makeIntConst($3, @3));
17646 : : $$ = makeStringConstCast($5, @5, t);
17647 : : }
17648 : : | TRUE_P
17649 : : {
17650 : : $$ = makeBoolAConst(true, @1);
17651 : : }
17652 : : | FALSE_P
17653 : : {
17654 : : $$ = makeBoolAConst(false, @1);
17655 : : }
17656 : : | NULL_P
17657 : : {
17658 : : $$ = makeNullAConst(@1);
17659 : : }
17660 : : ;
17661 : :
17662 : : Iconst: ICONST { $$ = $1; };
17663 : : Sconst: SCONST { $$ = $1; };
17664 : :
17665 : : SignedIconst: Iconst { $$ = $1; }
17666 : : | '+' Iconst { $$ = + $2; }
17667 : : | '-' Iconst { $$ = - $2; }
17668 : : ;
17669 : :
17670 : : /* Role specifications */
17671 : : RoleId: RoleSpec
17672 : : {
17673 : : RoleSpec *spc = (RoleSpec *) $1;
17674 : :
17675 : : switch (spc->roletype)
17676 : : {
17677 : : case ROLESPEC_CSTRING:
17678 : : $$ = spc->rolename;
17679 : : break;
17680 : : case ROLESPEC_PUBLIC:
17681 : : ereport(ERROR,
17682 : : (errcode(ERRCODE_RESERVED_NAME),
17683 : : errmsg("role name \"%s\" is reserved",
17684 : : "public"),
17685 : : parser_errposition(@1)));
17686 : : break;
17687 : : case ROLESPEC_SESSION_USER:
17688 : : ereport(ERROR,
17689 : : (errcode(ERRCODE_RESERVED_NAME),
17690 : : errmsg("%s cannot be used as a role name here",
17691 : : "SESSION_USER"),
17692 : : parser_errposition(@1)));
17693 : : break;
17694 : : case ROLESPEC_CURRENT_USER:
17695 : : ereport(ERROR,
17696 : : (errcode(ERRCODE_RESERVED_NAME),
17697 : : errmsg("%s cannot be used as a role name here",
17698 : : "CURRENT_USER"),
17699 : : parser_errposition(@1)));
17700 : : break;
17701 : : case ROLESPEC_CURRENT_ROLE:
17702 : : ereport(ERROR,
17703 : : (errcode(ERRCODE_RESERVED_NAME),
17704 : : errmsg("%s cannot be used as a role name here",
17705 : : "CURRENT_ROLE"),
17706 : : parser_errposition(@1)));
17707 : : break;
17708 : : }
17709 : : }
17710 : : ;
17711 : :
17712 : : RoleSpec: NonReservedWord
17713 : : {
17714 : : /*
17715 : : * "public" and "none" are not keywords, but they must
17716 : : * be treated specially here.
17717 : : */
17718 : : RoleSpec *n;
17719 : :
17720 : : if (strcmp($1, "public") == 0)
17721 : : {
17722 : : n = (RoleSpec *) makeRoleSpec(ROLESPEC_PUBLIC, @1);
17723 : : n->roletype = ROLESPEC_PUBLIC;
17724 : : }
17725 : : else if (strcmp($1, "none") == 0)
17726 : : {
17727 : : ereport(ERROR,
17728 : : (errcode(ERRCODE_RESERVED_NAME),
17729 : : errmsg("role name \"%s\" is reserved",
17730 : : "none"),
17731 : : parser_errposition(@1)));
17732 : : }
17733 : : else
17734 : : {
17735 : : n = makeRoleSpec(ROLESPEC_CSTRING, @1);
17736 : : n->rolename = pstrdup($1);
17737 : : }
17738 : : $$ = n;
17739 : : }
17740 : : | CURRENT_ROLE
17741 : : {
17742 : : $$ = makeRoleSpec(ROLESPEC_CURRENT_ROLE, @1);
17743 : : }
17744 : : | CURRENT_USER
17745 : : {
17746 : : $$ = makeRoleSpec(ROLESPEC_CURRENT_USER, @1);
17747 : : }
17748 : : | SESSION_USER
17749 : : {
17750 : : $$ = makeRoleSpec(ROLESPEC_SESSION_USER, @1);
17751 : : }
17752 : : ;
17753 : :
17754 : : role_list: RoleSpec
17755 : : { $$ = list_make1($1); }
17756 : : | role_list ',' RoleSpec
17757 : : { $$ = lappend($1, $3); }
17758 : : ;
17759 : :
17760 : :
17761 : : /*****************************************************************************
17762 : : *
17763 : : * PL/pgSQL extensions
17764 : : *
17765 : : * You'd think a PL/pgSQL "expression" should be just an a_expr, but
17766 : : * historically it can include just about anything that can follow SELECT.
17767 : : * Therefore the returned struct is a SelectStmt.
17768 : : *****************************************************************************/
17769 : :
17770 : : PLpgSQL_Expr: opt_distinct_clause opt_target_list
17771 : : from_clause where_clause
17772 : : group_clause having_clause window_clause
17773 : : opt_sort_clause opt_select_limit opt_for_locking_clause
17774 : : {
17775 : : SelectStmt *n = makeNode(SelectStmt);
17776 : :
17777 : : n->distinctClause = $1;
17778 : : n->targetList = $2;
17779 : : n->fromClause = $3;
17780 : : n->whereClause = $4;
17781 : : n->groupClause = ($5)->list;
17782 : : n->groupDistinct = ($5)->distinct;
17783 : : n->groupByAll = ($5)->all;
17784 : : n->havingClause = $6;
17785 : : n->windowClause = $7;
17786 : : n->sortClause = $8;
17787 : : if ($9)
17788 : : {
17789 : : n->limitOffset = $9->limitOffset;
17790 : : n->limitCount = $9->limitCount;
17791 : : if (!n->sortClause &&
17792 : : $9->limitOption == LIMIT_OPTION_WITH_TIES)
17793 : : ereport(ERROR,
17794 : : (errcode(ERRCODE_SYNTAX_ERROR),
17795 : : errmsg("WITH TIES cannot be specified without ORDER BY clause"),
17796 : : parser_errposition($9->optionLoc)));
17797 : : n->limitOption = $9->limitOption;
17798 : : }
17799 : : n->lockingClause = $10;
17800 : : $$ = (Node *) n;
17801 : : }
17802 : : ;
17803 : :
17804 : : /*
17805 : : * PL/pgSQL Assignment statement: name opt_indirection := PLpgSQL_Expr
17806 : : */
17807 : :
17808 : : PLAssignStmt: plassign_target opt_indirection plassign_equals PLpgSQL_Expr
17809 : : {
17810 : : PLAssignStmt *n = makeNode(PLAssignStmt);
17811 : :
17812 : : n->name = $1;
17813 : : n->indirection = check_indirection($2, yyscanner);
17814 : : /* nnames will be filled by calling production */
17815 : : n->val = (SelectStmt *) $4;
17816 : : n->location = @1;
17817 : : $$ = (Node *) n;
17818 : : }
17819 : : ;
17820 : :
17821 : : plassign_target: ColId { $$ = $1; }
17822 : : | PARAM { $$ = psprintf("$%d", $1); }
17823 : : ;
17824 : :
17825 : : plassign_equals: COLON_EQUALS
17826 : : | '='
17827 : : ;
17828 : :
17829 : :
17830 : : /*
17831 : : * Name classification hierarchy.
17832 : : *
17833 : : * IDENT is the lexeme returned by the lexer for identifiers that match
17834 : : * no known keyword. In most cases, we can accept certain keywords as
17835 : : * names, not only IDENTs. We prefer to accept as many such keywords
17836 : : * as possible to minimize the impact of "reserved words" on programmers.
17837 : : * So, we divide names into several possible classes. The classification
17838 : : * is chosen in part to make keywords acceptable as names wherever possible.
17839 : : */
17840 : :
17841 : : /* Column identifier --- names that can be column, table, etc names.
17842 : : */
17843 : : ColId: IDENT { $$ = $1; }
17844 : : | unreserved_keyword { $$ = pstrdup($1); }
17845 : : | col_name_keyword { $$ = pstrdup($1); }
17846 : : ;
17847 : :
17848 : : /* Type/function identifier --- names that can be type or function names.
17849 : : */
17850 : : type_function_name: IDENT { $$ = $1; }
17851 : : | unreserved_keyword { $$ = pstrdup($1); }
17852 : : | type_func_name_keyword { $$ = pstrdup($1); }
17853 : : ;
17854 : :
17855 : : /* Any not-fully-reserved word --- these names can be, eg, role names.
17856 : : */
17857 : : NonReservedWord: IDENT { $$ = $1; }
17858 : : | unreserved_keyword { $$ = pstrdup($1); }
17859 : : | col_name_keyword { $$ = pstrdup($1); }
17860 : : | type_func_name_keyword { $$ = pstrdup($1); }
17861 : : ;
17862 : :
17863 : : /* Column label --- allowed labels in "AS" clauses.
17864 : : * This presently includes *all* Postgres keywords.
17865 : : */
17866 : : ColLabel: IDENT { $$ = $1; }
17867 : : | unreserved_keyword { $$ = pstrdup($1); }
17868 : : | col_name_keyword { $$ = pstrdup($1); }
17869 : : | type_func_name_keyword { $$ = pstrdup($1); }
17870 : : | reserved_keyword { $$ = pstrdup($1); }
17871 : : ;
17872 : :
17873 : : /* Bare column label --- names that can be column labels without writing "AS".
17874 : : * This classification is orthogonal to the other keyword categories.
17875 : : */
17876 : : BareColLabel: IDENT { $$ = $1; }
17877 : : | bare_label_keyword { $$ = pstrdup($1); }
17878 : : ;
17879 : :
17880 : :
17881 : : /*
17882 : : * Keyword category lists. Generally, every keyword present in
17883 : : * the Postgres grammar should appear in exactly one of these lists.
17884 : : *
17885 : : * Put a new keyword into the first list that it can go into without causing
17886 : : * shift or reduce conflicts. The earlier lists define "less reserved"
17887 : : * categories of keywords.
17888 : : *
17889 : : * Make sure that each keyword's category in kwlist.h matches where
17890 : : * it is listed here. (Someday we may be able to generate these lists and
17891 : : * kwlist.h's table from one source of truth.)
17892 : : */
17893 : :
17894 : : /* "Unreserved" keywords --- available for use as any kind of name.
17895 : : */
17896 : : unreserved_keyword:
17897 : : ABORT_P
17898 : : | ABSENT
17899 : : | ABSOLUTE_P
17900 : : | ACCESS
17901 : : | ACTION
17902 : : | ADD_P
17903 : : | ADMIN
17904 : : | AFTER
17905 : : | AGGREGATE
17906 : : | ALSO
17907 : : | ALTER
17908 : : | ALWAYS
17909 : : | ASENSITIVE
17910 : : | ASSERTION
17911 : : | ASSIGNMENT
17912 : : | AT
17913 : : | ATOMIC
17914 : : | ATTACH
17915 : : | ATTRIBUTE
17916 : : | BACKWARD
17917 : : | BEFORE
17918 : : | BEGIN_P
17919 : : | BREADTH
17920 : : | BY
17921 : : | CACHE
17922 : : | CALL
17923 : : | CALLED
17924 : : | CASCADE
17925 : : | CASCADED
17926 : : | CATALOG_P
17927 : : | CHAIN
17928 : : | CHARACTERISTICS
17929 : : | CHECKPOINT
17930 : : | CLASS
17931 : : | CLOSE
17932 : : | CLUSTER
17933 : : | COLUMNS
17934 : : | COMMENT
17935 : : | COMMENTS
17936 : : | COMMIT
17937 : : | COMMITTED
17938 : : | COMPRESSION
17939 : : | CONDITIONAL
17940 : : | CONFIGURATION
17941 : : | CONFLICT
17942 : : | CONNECTION
17943 : : | CONSTRAINTS
17944 : : | CONTENT_P
17945 : : | CONTINUE_P
17946 : : | CONVERSION_P
17947 : : | COPY
17948 : : | COST
17949 : : | CSV
17950 : : | CUBE
17951 : : | CURRENT_P
17952 : : | CURSOR
17953 : : | CYCLE
17954 : : | DATA_P
17955 : : | DATABASE
17956 : : | DAY_P
17957 : : | DEALLOCATE
17958 : : | DECLARE
17959 : : | DEFAULTS
17960 : : | DEFERRED
17961 : : | DEFINER
17962 : : | DELETE_P
17963 : : | DELIMITER
17964 : : | DELIMITERS
17965 : : | DEPENDS
17966 : : | DEPTH
17967 : : | DETACH
17968 : : | DICTIONARY
17969 : : | DISABLE_P
17970 : : | DISCARD
17971 : : | DOCUMENT_P
17972 : : | DOMAIN_P
17973 : : | DOUBLE_P
17974 : : | DROP
17975 : : | EACH
17976 : : | EMPTY_P
17977 : : | ENABLE_P
17978 : : | ENCODING
17979 : : | ENCRYPTED
17980 : : | ENFORCED
17981 : : | ENUM_P
17982 : : | ERROR_P
17983 : : | ESCAPE
17984 : : | EVENT
17985 : : | EXCLUDE
17986 : : | EXCLUDING
17987 : : | EXCLUSIVE
17988 : : | EXECUTE
17989 : : | EXPLAIN
17990 : : | EXPRESSION
17991 : : | EXTENSION
17992 : : | EXTERNAL
17993 : : | FAMILY
17994 : : | FILTER
17995 : : | FINALIZE
17996 : : | FIRST_P
17997 : : | FOLLOWING
17998 : : | FORCE
17999 : : | FORMAT
18000 : : | FORWARD
18001 : : | FUNCTION
18002 : : | FUNCTIONS
18003 : : | GENERATED
18004 : : | GLOBAL
18005 : : | GRANTED
18006 : : | GROUPS
18007 : : | HANDLER
18008 : : | HEADER_P
18009 : : | HOLD
18010 : : | HOUR_P
18011 : : | IDENTITY_P
18012 : : | IF_P
18013 : : | IGNORE_P
18014 : : | IMMEDIATE
18015 : : | IMMUTABLE
18016 : : | IMPLICIT_P
18017 : : | IMPORT_P
18018 : : | INCLUDE
18019 : : | INCLUDING
18020 : : | INCREMENT
18021 : : | INDENT
18022 : : | INDEX
18023 : : | INDEXES
18024 : : | INHERIT
18025 : : | INHERITS
18026 : : | INLINE_P
18027 : : | INPUT_P
18028 : : | INSENSITIVE
18029 : : | INSERT
18030 : : | INSTEAD
18031 : : | INVOKER
18032 : : | ISOLATION
18033 : : | KEEP
18034 : : | KEY
18035 : : | KEYS
18036 : : | LABEL
18037 : : | LANGUAGE
18038 : : | LARGE_P
18039 : : | LAST_P
18040 : : | LEAKPROOF
18041 : : | LEVEL
18042 : : | LISTEN
18043 : : | LOAD
18044 : : | LOCAL
18045 : : | LOCATION
18046 : : | LOCK_P
18047 : : | LOCKED
18048 : : | LOGGED
18049 : : | LSN_P
18050 : : | MAPPING
18051 : : | MATCH
18052 : : | MATCHED
18053 : : | MATERIALIZED
18054 : : | MAXVALUE
18055 : : | MERGE
18056 : : | METHOD
18057 : : | MINUTE_P
18058 : : | MINVALUE
18059 : : | MODE
18060 : : | MONTH_P
18061 : : | MOVE
18062 : : | NAME_P
18063 : : | NAMES
18064 : : | NESTED
18065 : : | NEW
18066 : : | NEXT
18067 : : | NFC
18068 : : | NFD
18069 : : | NFKC
18070 : : | NFKD
18071 : : | NO
18072 : : | NORMALIZED
18073 : : | NOTHING
18074 : : | NOTIFY
18075 : : | NOWAIT
18076 : : | NULLS_P
18077 : : | OBJECT_P
18078 : : | OBJECTS_P
18079 : : | OF
18080 : : | OFF
18081 : : | OIDS
18082 : : | OLD
18083 : : | OMIT
18084 : : | OPERATOR
18085 : : | OPTION
18086 : : | OPTIONS
18087 : : | ORDINALITY
18088 : : | OTHERS
18089 : : | OVER
18090 : : | OVERRIDING
18091 : : | OWNED
18092 : : | OWNER
18093 : : | PARALLEL
18094 : : | PARAMETER
18095 : : | PARSER
18096 : : | PARTIAL
18097 : : | PARTITION
18098 : : | PARTITIONS
18099 : : | PASSING
18100 : : | PASSWORD
18101 : : | PATH
18102 : : | PERIOD
18103 : : | PLAN
18104 : : | PLANS
18105 : : | POLICY
18106 : : | PRECEDING
18107 : : | PREPARE
18108 : : | PREPARED
18109 : : | PRESERVE
18110 : : | PRIOR
18111 : : | PRIVILEGES
18112 : : | PROCEDURAL
18113 : : | PROCEDURE
18114 : : | PROCEDURES
18115 : : | PROGRAM
18116 : : | PUBLICATION
18117 : : | QUOTE
18118 : : | QUOTES
18119 : : | RANGE
18120 : : | READ
18121 : : | REASSIGN
18122 : : | RECURSIVE
18123 : : | REF_P
18124 : : | REFERENCING
18125 : : | REFRESH
18126 : : | REINDEX
18127 : : | RELATIVE_P
18128 : : | RELEASE
18129 : : | RENAME
18130 : : | REPEATABLE
18131 : : | REPLACE
18132 : : | REPLICA
18133 : : | RESET
18134 : : | RESPECT_P
18135 : : | RESTART
18136 : : | RESTRICT
18137 : : | RETURN
18138 : : | RETURNS
18139 : : | REVOKE
18140 : : | ROLE
18141 : : | ROLLBACK
18142 : : | ROLLUP
18143 : : | ROUTINE
18144 : : | ROUTINES
18145 : : | ROWS
18146 : : | RULE
18147 : : | SAVEPOINT
18148 : : | SCALAR
18149 : : | SCHEMA
18150 : : | SCHEMAS
18151 : : | SCROLL
18152 : : | SEARCH
18153 : : | SECOND_P
18154 : : | SECURITY
18155 : : | SEQUENCE
18156 : : | SEQUENCES
18157 : : | SERIALIZABLE
18158 : : | SERVER
18159 : : | SESSION
18160 : : | SET
18161 : : | SETS
18162 : : | SHARE
18163 : : | SHOW
18164 : : | SIMPLE
18165 : : | SKIP
18166 : : | SNAPSHOT
18167 : : | SOURCE
18168 : : | SPLIT
18169 : : | SQL_P
18170 : : | STABLE
18171 : : | STANDALONE_P
18172 : : | START
18173 : : | STATEMENT
18174 : : | STATISTICS
18175 : : | STDIN
18176 : : | STDOUT
18177 : : | STORAGE
18178 : : | STORED
18179 : : | STRICT_P
18180 : : | STRING_P
18181 : : | STRIP_P
18182 : : | SUBSCRIPTION
18183 : : | SUPPORT
18184 : : | SYSID
18185 : : | SYSTEM_P
18186 : : | TABLES
18187 : : | TABLESPACE
18188 : : | TARGET
18189 : : | TEMP
18190 : : | TEMPLATE
18191 : : | TEMPORARY
18192 : : | TEXT_P
18193 : : | TIES
18194 : : | TRANSACTION
18195 : : | TRANSFORM
18196 : : | TRIGGER
18197 : : | TRUNCATE
18198 : : | TRUSTED
18199 : : | TYPE_P
18200 : : | TYPES_P
18201 : : | UESCAPE
18202 : : | UNBOUNDED
18203 : : | UNCOMMITTED
18204 : : | UNCONDITIONAL
18205 : : | UNENCRYPTED
18206 : : | UNKNOWN
18207 : : | UNLISTEN
18208 : : | UNLOGGED
18209 : : | UNTIL
18210 : : | UPDATE
18211 : : | VACUUM
18212 : : | VALID
18213 : : | VALIDATE
18214 : : | VALIDATOR
18215 : : | VALUE_P
18216 : : | VARYING
18217 : : | VERSION_P
18218 : : | VIEW
18219 : : | VIEWS
18220 : : | VIRTUAL
18221 : : | VOLATILE
18222 : : | WAIT
18223 : : | WHITESPACE_P
18224 : : | WITHIN
18225 : : | WITHOUT
18226 : : | WORK
18227 : : | WRAPPER
18228 : : | WRITE
18229 : : | XML_P
18230 : : | YEAR_P
18231 : : | YES_P
18232 : : | ZONE
18233 : : ;
18234 : :
18235 : : /* Column identifier --- keywords that can be column, table, etc names.
18236 : : *
18237 : : * Many of these keywords will in fact be recognized as type or function
18238 : : * names too; but they have special productions for the purpose, and so
18239 : : * can't be treated as "generic" type or function names.
18240 : : *
18241 : : * The type names appearing here are not usable as function names
18242 : : * because they can be followed by '(' in typename productions, which
18243 : : * looks too much like a function call for an LR(1) parser.
18244 : : */
18245 : : col_name_keyword:
18246 : : BETWEEN
18247 : : | BIGINT
18248 : : | BIT
18249 : : | BOOLEAN_P
18250 : : | CHAR_P
18251 : : | CHARACTER
18252 : : | COALESCE
18253 : : | DEC
18254 : : | DECIMAL_P
18255 : : | EXISTS
18256 : : | EXTRACT
18257 : : | FLOAT_P
18258 : : | GREATEST
18259 : : | GROUPING
18260 : : | INOUT
18261 : : | INT_P
18262 : : | INTEGER
18263 : : | INTERVAL
18264 : : | JSON
18265 : : | JSON_ARRAY
18266 : : | JSON_ARRAYAGG
18267 : : | JSON_EXISTS
18268 : : | JSON_OBJECT
18269 : : | JSON_OBJECTAGG
18270 : : | JSON_QUERY
18271 : : | JSON_SCALAR
18272 : : | JSON_SERIALIZE
18273 : : | JSON_TABLE
18274 : : | JSON_VALUE
18275 : : | LEAST
18276 : : | MERGE_ACTION
18277 : : | NATIONAL
18278 : : | NCHAR
18279 : : | NONE
18280 : : | NORMALIZE
18281 : : | NULLIF
18282 : : | NUMERIC
18283 : : | OUT_P
18284 : : | OVERLAY
18285 : : | POSITION
18286 : : | PRECISION
18287 : : | REAL
18288 : : | ROW
18289 : : | SETOF
18290 : : | SMALLINT
18291 : : | SUBSTRING
18292 : : | TIME
18293 : : | TIMESTAMP
18294 : : | TREAT
18295 : : | TRIM
18296 : : | VALUES
18297 : : | VARCHAR
18298 : : | XMLATTRIBUTES
18299 : : | XMLCONCAT
18300 : : | XMLELEMENT
18301 : : | XMLEXISTS
18302 : : | XMLFOREST
18303 : : | XMLNAMESPACES
18304 : : | XMLPARSE
18305 : : | XMLPI
18306 : : | XMLROOT
18307 : : | XMLSERIALIZE
18308 : : | XMLTABLE
18309 : : ;
18310 : :
18311 : : /* Type/function identifier --- keywords that can be type or function names.
18312 : : *
18313 : : * Most of these are keywords that are used as operators in expressions;
18314 : : * in general such keywords can't be column names because they would be
18315 : : * ambiguous with variables, but they are unambiguous as function identifiers.
18316 : : *
18317 : : * Do not include POSITION, SUBSTRING, etc here since they have explicit
18318 : : * productions in a_expr to support the goofy SQL9x argument syntax.
18319 : : * - thomas 2000-11-28
18320 : : */
18321 : : type_func_name_keyword:
18322 : : AUTHORIZATION
18323 : : | BINARY
18324 : : | COLLATION
18325 : : | CONCURRENTLY
18326 : : | CROSS
18327 : : | CURRENT_SCHEMA
18328 : : | FREEZE
18329 : : | FULL
18330 : : | ILIKE
18331 : : | INNER_P
18332 : : | IS
18333 : : | ISNULL
18334 : : | JOIN
18335 : : | LEFT
18336 : : | LIKE
18337 : : | NATURAL
18338 : : | NOTNULL
18339 : : | OUTER_P
18340 : : | OVERLAPS
18341 : : | RIGHT
18342 : : | SIMILAR
18343 : : | TABLESAMPLE
18344 : : | VERBOSE
18345 : : ;
18346 : :
18347 : : /* Reserved keyword --- these keywords are usable only as a ColLabel.
18348 : : *
18349 : : * Keywords appear here if they could not be distinguished from variable,
18350 : : * type, or function names in some contexts. Don't put things here unless
18351 : : * forced to.
18352 : : */
18353 : : reserved_keyword:
18354 : : ALL
18355 : : | ANALYSE
18356 : : | ANALYZE
18357 : : | AND
18358 : : | ANY
18359 : : | ARRAY
18360 : : | AS
18361 : : | ASC
18362 : : | ASYMMETRIC
18363 : : | BOTH
18364 : : | CASE
18365 : : | CAST
18366 : : | CHECK
18367 : : | COLLATE
18368 : : | COLUMN
18369 : : | CONSTRAINT
18370 : : | CREATE
18371 : : | CURRENT_CATALOG
18372 : : | CURRENT_DATE
18373 : : | CURRENT_ROLE
18374 : : | CURRENT_TIME
18375 : : | CURRENT_TIMESTAMP
18376 : : | CURRENT_USER
18377 : : | DEFAULT
18378 : : | DEFERRABLE
18379 : : | DESC
18380 : : | DISTINCT
18381 : : | DO
18382 : : | ELSE
18383 : : | END_P
18384 : : | EXCEPT
18385 : : | FALSE_P
18386 : : | FETCH
18387 : : | FOR
18388 : : | FOREIGN
18389 : : | FROM
18390 : : | GRANT
18391 : : | GROUP_P
18392 : : | HAVING
18393 : : | IN_P
18394 : : | INITIALLY
18395 : : | INTERSECT
18396 : : | INTO
18397 : : | LATERAL_P
18398 : : | LEADING
18399 : : | LIMIT
18400 : : | LOCALTIME
18401 : : | LOCALTIMESTAMP
18402 : : | NOT
18403 : : | NULL_P
18404 : : | OFFSET
18405 : : | ON
18406 : : | ONLY
18407 : : | OR
18408 : : | ORDER
18409 : : | PLACING
18410 : : | PRIMARY
18411 : : | REFERENCES
18412 : : | RETURNING
18413 : : | SELECT
18414 : : | SESSION_USER
18415 : : | SOME
18416 : : | SYMMETRIC
18417 : : | SYSTEM_USER
18418 : : | TABLE
18419 : : | THEN
18420 : : | TO
18421 : : | TRAILING
18422 : : | TRUE_P
18423 : : | UNION
18424 : : | UNIQUE
18425 : : | USER
18426 : : | USING
18427 : : | VARIADIC
18428 : : | WHEN
18429 : : | WHERE
18430 : : | WINDOW
18431 : : | WITH
18432 : : ;
18433 : :
18434 : : /*
18435 : : * While all keywords can be used as column labels when preceded by AS,
18436 : : * not all of them can be used as a "bare" column label without AS.
18437 : : * Those that can be used as a bare label must be listed here,
18438 : : * in addition to appearing in one of the category lists above.
18439 : : *
18440 : : * Always add a new keyword to this list if possible. Mark it BARE_LABEL
18441 : : * in kwlist.h if it is included here, or AS_LABEL if it is not.
18442 : : */
18443 : : bare_label_keyword:
18444 : : ABORT_P
18445 : : | ABSENT
18446 : : | ABSOLUTE_P
18447 : : | ACCESS
18448 : : | ACTION
18449 : : | ADD_P
18450 : : | ADMIN
18451 : : | AFTER
18452 : : | AGGREGATE
18453 : : | ALL
18454 : : | ALSO
18455 : : | ALTER
18456 : : | ALWAYS
18457 : : | ANALYSE
18458 : : | ANALYZE
18459 : : | AND
18460 : : | ANY
18461 : : | ASC
18462 : : | ASENSITIVE
18463 : : | ASSERTION
18464 : : | ASSIGNMENT
18465 : : | ASYMMETRIC
18466 : : | AT
18467 : : | ATOMIC
18468 : : | ATTACH
18469 : : | ATTRIBUTE
18470 : : | AUTHORIZATION
18471 : : | BACKWARD
18472 : : | BEFORE
18473 : : | BEGIN_P
18474 : : | BETWEEN
18475 : : | BIGINT
18476 : : | BINARY
18477 : : | BIT
18478 : : | BOOLEAN_P
18479 : : | BOTH
18480 : : | BREADTH
18481 : : | BY
18482 : : | CACHE
18483 : : | CALL
18484 : : | CALLED
18485 : : | CASCADE
18486 : : | CASCADED
18487 : : | CASE
18488 : : | CAST
18489 : : | CATALOG_P
18490 : : | CHAIN
18491 : : | CHARACTERISTICS
18492 : : | CHECK
18493 : : | CHECKPOINT
18494 : : | CLASS
18495 : : | CLOSE
18496 : : | CLUSTER
18497 : : | COALESCE
18498 : : | COLLATE
18499 : : | COLLATION
18500 : : | COLUMN
18501 : : | COLUMNS
18502 : : | COMMENT
18503 : : | COMMENTS
18504 : : | COMMIT
18505 : : | COMMITTED
18506 : : | COMPRESSION
18507 : : | CONCURRENTLY
18508 : : | CONDITIONAL
18509 : : | CONFIGURATION
18510 : : | CONFLICT
18511 : : | CONNECTION
18512 : : | CONSTRAINT
18513 : : | CONSTRAINTS
18514 : : | CONTENT_P
18515 : : | CONTINUE_P
18516 : : | CONVERSION_P
18517 : : | COPY
18518 : : | COST
18519 : : | CROSS
18520 : : | CSV
18521 : : | CUBE
18522 : : | CURRENT_P
18523 : : | CURRENT_CATALOG
18524 : : | CURRENT_DATE
18525 : : | CURRENT_ROLE
18526 : : | CURRENT_SCHEMA
18527 : : | CURRENT_TIME
18528 : : | CURRENT_TIMESTAMP
18529 : : | CURRENT_USER
18530 : : | CURSOR
18531 : : | CYCLE
18532 : : | DATA_P
18533 : : | DATABASE
18534 : : | DEALLOCATE
18535 : : | DEC
18536 : : | DECIMAL_P
18537 : : | DECLARE
18538 : : | DEFAULT
18539 : : | DEFAULTS
18540 : : | DEFERRABLE
18541 : : | DEFERRED
18542 : : | DEFINER
18543 : : | DELETE_P
18544 : : | DELIMITER
18545 : : | DELIMITERS
18546 : : | DEPENDS
18547 : : | DEPTH
18548 : : | DESC
18549 : : | DETACH
18550 : : | DICTIONARY
18551 : : | DISABLE_P
18552 : : | DISCARD
18553 : : | DISTINCT
18554 : : | DO
18555 : : | DOCUMENT_P
18556 : : | DOMAIN_P
18557 : : | DOUBLE_P
18558 : : | DROP
18559 : : | EACH
18560 : : | ELSE
18561 : : | EMPTY_P
18562 : : | ENABLE_P
18563 : : | ENCODING
18564 : : | ENCRYPTED
18565 : : | END_P
18566 : : | ENFORCED
18567 : : | ENUM_P
18568 : : | ERROR_P
18569 : : | ESCAPE
18570 : : | EVENT
18571 : : | EXCLUDE
18572 : : | EXCLUDING
18573 : : | EXCLUSIVE
18574 : : | EXECUTE
18575 : : | EXISTS
18576 : : | EXPLAIN
18577 : : | EXPRESSION
18578 : : | EXTENSION
18579 : : | EXTERNAL
18580 : : | EXTRACT
18581 : : | FALSE_P
18582 : : | FAMILY
18583 : : | FINALIZE
18584 : : | FIRST_P
18585 : : | FLOAT_P
18586 : : | FOLLOWING
18587 : : | FORCE
18588 : : | FOREIGN
18589 : : | FORMAT
18590 : : | FORWARD
18591 : : | FREEZE
18592 : : | FULL
18593 : : | FUNCTION
18594 : : | FUNCTIONS
18595 : : | GENERATED
18596 : : | GLOBAL
18597 : : | GRANTED
18598 : : | GREATEST
18599 : : | GROUPING
18600 : : | GROUPS
18601 : : | HANDLER
18602 : : | HEADER_P
18603 : : | HOLD
18604 : : | IDENTITY_P
18605 : : | IF_P
18606 : : | ILIKE
18607 : : | IMMEDIATE
18608 : : | IMMUTABLE
18609 : : | IMPLICIT_P
18610 : : | IMPORT_P
18611 : : | IN_P
18612 : : | INCLUDE
18613 : : | INCLUDING
18614 : : | INCREMENT
18615 : : | INDENT
18616 : : | INDEX
18617 : : | INDEXES
18618 : : | INHERIT
18619 : : | INHERITS
18620 : : | INITIALLY
18621 : : | INLINE_P
18622 : : | INNER_P
18623 : : | INOUT
18624 : : | INPUT_P
18625 : : | INSENSITIVE
18626 : : | INSERT
18627 : : | INSTEAD
18628 : : | INT_P
18629 : : | INTEGER
18630 : : | INTERVAL
18631 : : | INVOKER
18632 : : | IS
18633 : : | ISOLATION
18634 : : | JOIN
18635 : : | JSON
18636 : : | JSON_ARRAY
18637 : : | JSON_ARRAYAGG
18638 : : | JSON_EXISTS
18639 : : | JSON_OBJECT
18640 : : | JSON_OBJECTAGG
18641 : : | JSON_QUERY
18642 : : | JSON_SCALAR
18643 : : | JSON_SERIALIZE
18644 : : | JSON_TABLE
18645 : : | JSON_VALUE
18646 : : | KEEP
18647 : : | KEY
18648 : : | KEYS
18649 : : | LABEL
18650 : : | LANGUAGE
18651 : : | LARGE_P
18652 : : | LAST_P
18653 : : | LATERAL_P
18654 : : | LEADING
18655 : : | LEAKPROOF
18656 : : | LEAST
18657 : : | LEFT
18658 : : | LEVEL
18659 : : | LIKE
18660 : : | LISTEN
18661 : : | LOAD
18662 : : | LOCAL
18663 : : | LOCALTIME
18664 : : | LOCALTIMESTAMP
18665 : : | LOCATION
18666 : : | LOCK_P
18667 : : | LOCKED
18668 : : | LOGGED
18669 : : | LSN_P
18670 : : | MAPPING
18671 : : | MATCH
18672 : : | MATCHED
18673 : : | MATERIALIZED
18674 : : | MAXVALUE
18675 : : | MERGE
18676 : : | MERGE_ACTION
18677 : : | METHOD
18678 : : | MINVALUE
18679 : : | MODE
18680 : : | MOVE
18681 : : | NAME_P
18682 : : | NAMES
18683 : : | NATIONAL
18684 : : | NATURAL
18685 : : | NCHAR
18686 : : | NESTED
18687 : : | NEW
18688 : : | NEXT
18689 : : | NFC
18690 : : | NFD
18691 : : | NFKC
18692 : : | NFKD
18693 : : | NO
18694 : : | NONE
18695 : : | NORMALIZE
18696 : : | NORMALIZED
18697 : : | NOT
18698 : : | NOTHING
18699 : : | NOTIFY
18700 : : | NOWAIT
18701 : : | NULL_P
18702 : : | NULLIF
18703 : : | NULLS_P
18704 : : | NUMERIC
18705 : : | OBJECT_P
18706 : : | OBJECTS_P
18707 : : | OF
18708 : : | OFF
18709 : : | OIDS
18710 : : | OLD
18711 : : | OMIT
18712 : : | ONLY
18713 : : | OPERATOR
18714 : : | OPTION
18715 : : | OPTIONS
18716 : : | OR
18717 : : | ORDINALITY
18718 : : | OTHERS
18719 : : | OUT_P
18720 : : | OUTER_P
18721 : : | OVERLAY
18722 : : | OVERRIDING
18723 : : | OWNED
18724 : : | OWNER
18725 : : | PARALLEL
18726 : : | PARAMETER
18727 : : | PARSER
18728 : : | PARTIAL
18729 : : | PARTITION
18730 : : | PARTITIONS
18731 : : | PASSING
18732 : : | PASSWORD
18733 : : | PATH
18734 : : | PERIOD
18735 : : | PLACING
18736 : : | PLAN
18737 : : | PLANS
18738 : : | POLICY
18739 : : | POSITION
18740 : : | PRECEDING
18741 : : | PREPARE
18742 : : | PREPARED
18743 : : | PRESERVE
18744 : : | PRIMARY
18745 : : | PRIOR
18746 : : | PRIVILEGES
18747 : : | PROCEDURAL
18748 : : | PROCEDURE
18749 : : | PROCEDURES
18750 : : | PROGRAM
18751 : : | PUBLICATION
18752 : : | QUOTE
18753 : : | QUOTES
18754 : : | RANGE
18755 : : | READ
18756 : : | REAL
18757 : : | REASSIGN
18758 : : | RECURSIVE
18759 : : | REF_P
18760 : : | REFERENCES
18761 : : | REFERENCING
18762 : : | REFRESH
18763 : : | REINDEX
18764 : : | RELATIVE_P
18765 : : | RELEASE
18766 : : | RENAME
18767 : : | REPEATABLE
18768 : : | REPLACE
18769 : : | REPLICA
18770 : : | RESET
18771 : : | RESTART
18772 : : | RESTRICT
18773 : : | RETURN
18774 : : | RETURNS
18775 : : | REVOKE
18776 : : | RIGHT
18777 : : | ROLE
18778 : : | ROLLBACK
18779 : : | ROLLUP
18780 : : | ROUTINE
18781 : : | ROUTINES
18782 : : | ROW
18783 : : | ROWS
18784 : : | RULE
18785 : : | SAVEPOINT
18786 : : | SCALAR
18787 : : | SCHEMA
18788 : : | SCHEMAS
18789 : : | SCROLL
18790 : : | SEARCH
18791 : : | SECURITY
18792 : : | SELECT
18793 : : | SEQUENCE
18794 : : | SEQUENCES
18795 : : | SERIALIZABLE
18796 : : | SERVER
18797 : : | SESSION
18798 : : | SESSION_USER
18799 : : | SET
18800 : : | SETOF
18801 : : | SETS
18802 : : | SHARE
18803 : : | SHOW
18804 : : | SIMILAR
18805 : : | SIMPLE
18806 : : | SKIP
18807 : : | SMALLINT
18808 : : | SNAPSHOT
18809 : : | SOME
18810 : : | SOURCE
18811 : : | SPLIT
18812 : : | SQL_P
18813 : : | STABLE
18814 : : | STANDALONE_P
18815 : : | START
18816 : : | STATEMENT
18817 : : | STATISTICS
18818 : : | STDIN
18819 : : | STDOUT
18820 : : | STORAGE
18821 : : | STORED
18822 : : | STRICT_P
18823 : : | STRING_P
18824 : : | STRIP_P
18825 : : | SUBSCRIPTION
18826 : : | SUBSTRING
18827 : : | SUPPORT
18828 : : | SYMMETRIC
18829 : : | SYSID
18830 : : | SYSTEM_P
18831 : : | SYSTEM_USER
18832 : : | TABLE
18833 : : | TABLES
18834 : : | TABLESAMPLE
18835 : : | TABLESPACE
18836 : : | TARGET
18837 : : | TEMP
18838 : : | TEMPLATE
18839 : : | TEMPORARY
18840 : : | TEXT_P
18841 : : | THEN
18842 : : | TIES
18843 : : | TIME
18844 : : | TIMESTAMP
18845 : : | TRAILING
18846 : : | TRANSACTION
18847 : : | TRANSFORM
18848 : : | TREAT
18849 : : | TRIGGER
18850 : : | TRIM
18851 : : | TRUE_P
18852 : : | TRUNCATE
18853 : : | TRUSTED
18854 : : | TYPE_P
18855 : : | TYPES_P
18856 : : | UESCAPE
18857 : : | UNBOUNDED
18858 : : | UNCOMMITTED
18859 : : | UNCONDITIONAL
18860 : : | UNENCRYPTED
18861 : : | UNIQUE
18862 : : | UNKNOWN
18863 : : | UNLISTEN
18864 : : | UNLOGGED
18865 : : | UNTIL
18866 : : | UPDATE
18867 : : | USER
18868 : : | USING
18869 : : | VACUUM
18870 : : | VALID
18871 : : | VALIDATE
18872 : : | VALIDATOR
18873 : : | VALUE_P
18874 : : | VALUES
18875 : : | VARCHAR
18876 : : | VARIADIC
18877 : : | VERBOSE
18878 : : | VERSION_P
18879 : : | VIEW
18880 : : | VIEWS
18881 : : | VIRTUAL
18882 : : | VOLATILE
18883 : : | WAIT
18884 : : | WHEN
18885 : : | WHITESPACE_P
18886 : : | WORK
18887 : : | WRAPPER
18888 : : | WRITE
18889 : : | XML_P
18890 : : | XMLATTRIBUTES
18891 : : | XMLCONCAT
18892 : : | XMLELEMENT
18893 : : | XMLEXISTS
18894 : : | XMLFOREST
18895 : : | XMLNAMESPACES
18896 : : | XMLPARSE
18897 : : | XMLPI
18898 : : | XMLROOT
18899 : : | XMLSERIALIZE
18900 : : | XMLTABLE
18901 : : | YES_P
18902 : : | ZONE
18903 : : ;
18904 : :
18905 : : %%
18906 : :
18907 : : /*
18908 : : * The signature of this function is required by bison. However, we
18909 : : * ignore the passed yylloc and instead use the last token position
18910 : : * available from the scanner.
18911 : : */
18912 : : static void
18913 : 108 : base_yyerror(YYLTYPE *yylloc, core_yyscan_t yyscanner, const char *msg)
18914 : : {
18915 : 108 : parser_yyerror(msg);
18916 : : }
18917 : :
18918 : : static RawStmt *
18919 : 70240 : makeRawStmt(Node *stmt, int stmt_location)
18920 : : {
18921 : 70240 : RawStmt *rs = makeNode(RawStmt);
18922 : :
18923 : 70240 : rs->stmt = stmt;
18924 : 70240 : rs->stmt_location = stmt_location;
18925 : 70240 : rs->stmt_len = 0; /* might get changed later */
18926 : 140480 : return rs;
18927 : 70240 : }
18928 : :
18929 : : /* Adjust a RawStmt to reflect that it doesn't run to the end of the string */
18930 : : static void
18931 : 57978 : updateRawStmtEnd(RawStmt *rs, int end_location)
18932 : : {
18933 : : /*
18934 : : * If we already set the length, don't change it. This is for situations
18935 : : * like "select foo ;; select bar" where the same statement will be last
18936 : : * in the string for more than one semicolon.
18937 : : */
18938 [ - + ]: 57978 : if (rs->stmt_len > 0)
18939 : 0 : return;
18940 : :
18941 : : /* OK, update length of RawStmt */
18942 : 57978 : rs->stmt_len = end_location - rs->stmt_location;
18943 : 57978 : }
18944 : :
18945 : : static Node *
18946 : 148046 : makeColumnRef(char *colname, List *indirection,
18947 : : int location, core_yyscan_t yyscanner)
18948 : : {
18949 : : /*
18950 : : * Generate a ColumnRef node, with an A_Indirection node added if there is
18951 : : * any subscripting in the specified indirection list. However, any field
18952 : : * selection at the start of the indirection list must be transposed into
18953 : : * the "fields" part of the ColumnRef node.
18954 : : */
18955 : 148046 : ColumnRef *c = makeNode(ColumnRef);
18956 : 148046 : int nfields = 0;
18957 : 148046 : ListCell *l;
18958 : :
18959 : 148046 : c->location = location;
18960 [ + + + + : 237998 : foreach(l, indirection)
+ + + + ]
18961 : : {
18962 [ + + ]: 89952 : if (IsA(lfirst(l), A_Indices))
18963 : : {
18964 : 1232 : A_Indirection *i = makeNode(A_Indirection);
18965 : :
18966 [ + + ]: 1232 : if (nfields == 0)
18967 : : {
18968 : : /* easy case - all indirection goes to A_Indirection */
18969 : 812 : c->fields = list_make1(makeString(colname));
18970 : 812 : i->indirection = check_indirection(indirection, yyscanner);
18971 : 812 : }
18972 : : else
18973 : : {
18974 : : /* got to split the list in two */
18975 : 1260 : i->indirection = check_indirection(list_copy_tail(indirection,
18976 : 420 : nfields),
18977 : 420 : yyscanner);
18978 : 420 : indirection = list_truncate(indirection, nfields);
18979 : 420 : c->fields = lcons(makeString(colname), indirection);
18980 : : }
18981 : 1232 : i->arg = (Node *) c;
18982 : 1232 : return (Node *) i;
18983 : 1232 : }
18984 [ + + ]: 88720 : else if (IsA(lfirst(l), A_Star))
18985 : : {
18986 : : /* We only allow '*' at the end of a ColumnRef */
18987 [ - + ]: 763 : if (lnext(indirection, l) != NULL)
18988 : 0 : parser_yyerror("improper use of \"*\"");
18989 : 763 : }
18990 : 88720 : nfields++;
18991 : 88720 : }
18992 : : /* No subscripting, so all indirection gets added to field list */
18993 : 146814 : c->fields = lcons(makeString(colname), indirection);
18994 : 146814 : return (Node *) c;
18995 : 148046 : }
18996 : :
18997 : : static Node *
18998 : 21850 : makeTypeCast(Node *arg, TypeName *typename, int location)
18999 : : {
19000 : 21850 : TypeCast *n = makeNode(TypeCast);
19001 : :
19002 : 21850 : n->arg = arg;
19003 : 21850 : n->typeName = typename;
19004 : 21850 : n->location = location;
19005 : 43700 : return (Node *) n;
19006 : 21850 : }
19007 : :
19008 : : static Node *
19009 : 2381 : makeStringConstCast(char *str, int location, TypeName *typename)
19010 : : {
19011 : 2381 : Node *s = makeStringConst(str, location);
19012 : :
19013 : 4762 : return makeTypeCast(s, typename, -1);
19014 : 2381 : }
19015 : :
19016 : : static Node *
19017 : 42082 : makeIntConst(int val, int location)
19018 : : {
19019 : 42082 : A_Const *n = makeNode(A_Const);
19020 : :
19021 : 42082 : n->val.ival.type = T_Integer;
19022 : 42082 : n->val.ival.ival = val;
19023 : 42082 : n->location = location;
19024 : :
19025 : 84164 : return (Node *) n;
19026 : 42082 : }
19027 : :
19028 : : static Node *
19029 : 1634 : makeFloatConst(char *str, int location)
19030 : : {
19031 : 1634 : A_Const *n = makeNode(A_Const);
19032 : :
19033 : 1634 : n->val.fval.type = T_Float;
19034 : 1634 : n->val.fval.fval = str;
19035 : 1634 : n->location = location;
19036 : :
19037 : 3268 : return (Node *) n;
19038 : 1634 : }
19039 : :
19040 : : static Node *
19041 : 4651 : makeBoolAConst(bool state, int location)
19042 : : {
19043 : 4651 : A_Const *n = makeNode(A_Const);
19044 : :
19045 : 4651 : n->val.boolval.type = T_Boolean;
19046 : 4651 : n->val.boolval.boolval = state;
19047 : 4651 : n->location = location;
19048 : :
19049 : 9302 : return (Node *) n;
19050 : 4651 : }
19051 : :
19052 : : static Node *
19053 : 670 : makeBitStringConst(char *str, int location)
19054 : : {
19055 : 670 : A_Const *n = makeNode(A_Const);
19056 : :
19057 : 670 : n->val.bsval.type = T_BitString;
19058 : 670 : n->val.bsval.bsval = str;
19059 : 670 : n->location = location;
19060 : :
19061 : 1340 : return (Node *) n;
19062 : 670 : }
19063 : :
19064 : : static Node *
19065 : 5549 : makeNullAConst(int location)
19066 : : {
19067 : 5549 : A_Const *n = makeNode(A_Const);
19068 : :
19069 : 5549 : n->isnull = true;
19070 : 5549 : n->location = location;
19071 : :
19072 : 11098 : return (Node *) n;
19073 : 5549 : }
19074 : :
19075 : : static Node *
19076 : 308 : makeAConst(Node *v, int location)
19077 : : {
19078 : 308 : Node *n;
19079 : :
19080 [ + - + ]: 308 : switch (v->type)
19081 : : {
19082 : : case T_Float:
19083 : 25 : n = makeFloatConst(castNode(Float, v)->fval, location);
19084 : 25 : break;
19085 : :
19086 : : case T_Integer:
19087 : 283 : n = makeIntConst(castNode(Integer, v)->ival, location);
19088 : 283 : break;
19089 : :
19090 : : default:
19091 : : /* currently not used */
19092 : 0 : Assert(false);
19093 : 0 : n = NULL;
19094 : 0 : }
19095 : :
19096 : 616 : return n;
19097 : 308 : }
19098 : :
19099 : : /* makeRoleSpec
19100 : : * Create a RoleSpec with the given type
19101 : : */
19102 : : static RoleSpec *
19103 : 1764 : makeRoleSpec(RoleSpecType type, int location)
19104 : : {
19105 : 1764 : RoleSpec *spec = makeNode(RoleSpec);
19106 : :
19107 : 1764 : spec->roletype = type;
19108 : 1764 : spec->location = location;
19109 : :
19110 : 3528 : return spec;
19111 : 1764 : }
19112 : :
19113 : : /* check_qualified_name --- check the result of qualified_name production
19114 : : *
19115 : : * It's easiest to let the grammar production for qualified_name allow
19116 : : * subscripts and '*', which we then must reject here.
19117 : : */
19118 : : static void
19119 : 19563 : check_qualified_name(List *names, core_yyscan_t yyscanner)
19120 : : {
19121 : 19563 : ListCell *i;
19122 : :
19123 [ + - + + : 39126 : foreach(i, names)
+ + ]
19124 : : {
19125 [ + - ]: 19563 : if (!IsA(lfirst(i), String))
19126 : 0 : parser_yyerror("syntax error");
19127 : 19563 : }
19128 : 19563 : }
19129 : :
19130 : : /* check_func_name --- check the result of func_name production
19131 : : *
19132 : : * It's easiest to let the grammar production for func_name allow subscripts
19133 : : * and '*', which we then must reject here.
19134 : : */
19135 : : static List *
19136 : 12181 : check_func_name(List *names, core_yyscan_t yyscanner)
19137 : : {
19138 : 12181 : ListCell *i;
19139 : :
19140 [ + - + + : 36543 : foreach(i, names)
+ + ]
19141 : : {
19142 [ + - ]: 24362 : if (!IsA(lfirst(i), String))
19143 : 0 : parser_yyerror("syntax error");
19144 : 24362 : }
19145 : 24362 : return names;
19146 : 12181 : }
19147 : :
19148 : : /* check_indirection --- check the result of indirection production
19149 : : *
19150 : : * We only allow '*' at the end of the list, but it's hard to enforce that
19151 : : * in the grammar, so do it here.
19152 : : */
19153 : : static List *
19154 : 6706 : check_indirection(List *indirection, core_yyscan_t yyscanner)
19155 : : {
19156 : 6706 : ListCell *l;
19157 : :
19158 [ + + + + : 8932 : foreach(l, indirection)
+ + ]
19159 : : {
19160 [ + + ]: 2226 : if (IsA(lfirst(l), A_Star))
19161 : : {
19162 [ - + ]: 55 : if (lnext(indirection, l) != NULL)
19163 : 0 : parser_yyerror("improper use of \"*\"");
19164 : 55 : }
19165 : 2226 : }
19166 : 13412 : return indirection;
19167 : 6706 : }
19168 : :
19169 : : /* extractArgTypes()
19170 : : * Given a list of FunctionParameter nodes, extract a list of just the
19171 : : * argument types (TypeNames) for input parameters only. This is what
19172 : : * is needed to look up an existing function, which is what is wanted by
19173 : : * the productions that use this call.
19174 : : */
19175 : : static List *
19176 : 609 : extractArgTypes(List *parameters)
19177 : : {
19178 : 609 : List *result = NIL;
19179 : 609 : ListCell *i;
19180 : :
19181 [ + + + + : 1196 : foreach(i, parameters)
+ + ]
19182 : : {
19183 : 587 : FunctionParameter *p = (FunctionParameter *) lfirst(i);
19184 : :
19185 [ + + - + ]: 587 : if (p->mode != FUNC_PARAM_OUT && p->mode != FUNC_PARAM_TABLE)
19186 : 584 : result = lappend(result, p->argType);
19187 : 587 : }
19188 : 1218 : return result;
19189 : 609 : }
19190 : :
19191 : : /* extractAggrArgTypes()
19192 : : * As above, but work from the output of the aggr_args production.
19193 : : */
19194 : : static List *
19195 : 39 : extractAggrArgTypes(List *aggrargs)
19196 : : {
19197 [ + - ]: 39 : Assert(list_length(aggrargs) == 2);
19198 : 39 : return extractArgTypes((List *) linitial(aggrargs));
19199 : : }
19200 : :
19201 : : /* makeOrderedSetArgs()
19202 : : * Build the result of the aggr_args production (which see the comments for).
19203 : : * This handles only the case where both given lists are nonempty, so that
19204 : : * we have to deal with multiple VARIADIC arguments.
19205 : : */
19206 : : static List *
19207 : 4 : makeOrderedSetArgs(List *directargs, List *orderedargs,
19208 : : core_yyscan_t yyscanner)
19209 : : {
19210 : 4 : FunctionParameter *lastd = (FunctionParameter *) llast(directargs);
19211 : 4 : Integer *ndirectargs;
19212 : :
19213 : : /* No restriction unless last direct arg is VARIADIC */
19214 [ + + ]: 4 : if (lastd->mode == FUNC_PARAM_VARIADIC)
19215 : : {
19216 : 2 : FunctionParameter *firsto = (FunctionParameter *) linitial(orderedargs);
19217 : :
19218 : : /*
19219 : : * We ignore the names, though the aggr_arg production allows them; it
19220 : : * doesn't allow default values, so those need not be checked.
19221 : : */
19222 [ + - ]: 2 : if (list_length(orderedargs) != 1 ||
19223 : 2 : firsto->mode != FUNC_PARAM_VARIADIC ||
19224 : 2 : !equal(lastd->argType, firsto->argType))
19225 [ # # # # ]: 0 : ereport(ERROR,
19226 : : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
19227 : : errmsg("an ordered-set aggregate with a VARIADIC direct argument must have one VARIADIC aggregated argument of the same data type"),
19228 : : parser_errposition(firsto->location)));
19229 : :
19230 : : /* OK, drop the duplicate VARIADIC argument from the internal form */
19231 : 2 : orderedargs = NIL;
19232 : 2 : }
19233 : :
19234 : : /* don't merge into the next line, as list_concat changes directargs */
19235 : 4 : ndirectargs = makeInteger(list_length(directargs));
19236 : :
19237 : 8 : return list_make2(list_concat(directargs, orderedargs),
19238 : : ndirectargs);
19239 : 4 : }
19240 : :
19241 : : /* insertSelectOptions()
19242 : : * Insert ORDER BY, etc into an already-constructed SelectStmt.
19243 : : *
19244 : : * This routine is just to avoid duplicating code in SelectStmt productions.
19245 : : */
19246 : : static void
19247 : 9841 : insertSelectOptions(SelectStmt *stmt,
19248 : : List *sortClause, List *lockingClause,
19249 : : SelectLimit *limitClause,
19250 : : WithClause *withClause,
19251 : : core_yyscan_t yyscanner)
19252 : : {
19253 [ + - ]: 9841 : Assert(IsA(stmt, SelectStmt));
19254 : :
19255 : : /*
19256 : : * Tests here are to reject constructs like
19257 : : * (SELECT foo ORDER BY bar) ORDER BY baz
19258 : : */
19259 [ + + ]: 9841 : if (sortClause)
19260 : : {
19261 [ + - ]: 8989 : if (stmt->sortClause)
19262 [ # # # # ]: 0 : ereport(ERROR,
19263 : : (errcode(ERRCODE_SYNTAX_ERROR),
19264 : : errmsg("multiple ORDER BY clauses not allowed"),
19265 : : parser_errposition(exprLocation((Node *) sortClause))));
19266 : 8989 : stmt->sortClause = sortClause;
19267 : 8989 : }
19268 : : /* We can handle multiple locking clauses, though */
19269 : 9841 : stmt->lockingClause = list_concat(stmt->lockingClause, lockingClause);
19270 [ + + + + ]: 9841 : if (limitClause && limitClause->limitOffset)
19271 : : {
19272 [ + - ]: 97 : if (stmt->limitOffset)
19273 [ # # # # ]: 0 : ereport(ERROR,
19274 : : (errcode(ERRCODE_SYNTAX_ERROR),
19275 : : errmsg("multiple OFFSET clauses not allowed"),
19276 : : parser_errposition(limitClause->offsetLoc)));
19277 : 97 : stmt->limitOffset = limitClause->limitOffset;
19278 : 97 : }
19279 [ + + + + ]: 9841 : if (limitClause && limitClause->limitCount)
19280 : : {
19281 [ + - ]: 411 : if (stmt->limitCount)
19282 [ # # # # ]: 0 : ereport(ERROR,
19283 : : (errcode(ERRCODE_SYNTAX_ERROR),
19284 : : errmsg("multiple LIMIT clauses not allowed"),
19285 : : parser_errposition(limitClause->countLoc)));
19286 : 411 : stmt->limitCount = limitClause->limitCount;
19287 : 411 : }
19288 [ + + ]: 9841 : if (limitClause)
19289 : : {
19290 : : /* If there was a conflict, we must have detected it above */
19291 [ + - ]: 493 : Assert(!stmt->limitOption);
19292 [ + + + + ]: 493 : if (!stmt->sortClause && limitClause->limitOption == LIMIT_OPTION_WITH_TIES)
19293 [ + - + - ]: 1 : ereport(ERROR,
19294 : : (errcode(ERRCODE_SYNTAX_ERROR),
19295 : : errmsg("WITH TIES cannot be specified without ORDER BY clause"),
19296 : : parser_errposition(limitClause->optionLoc)));
19297 [ + + + + ]: 492 : if (limitClause->limitOption == LIMIT_OPTION_WITH_TIES && stmt->lockingClause)
19298 : : {
19299 : 1 : ListCell *lc;
19300 : :
19301 [ + - - + : 1 : foreach(lc, stmt->lockingClause)
- + ]
19302 : : {
19303 : 1 : LockingClause *lock = lfirst_node(LockingClause, lc);
19304 : :
19305 [ - + ]: 1 : if (lock->waitPolicy == LockWaitSkip)
19306 [ + - + - ]: 1 : ereport(ERROR,
19307 : : (errcode(ERRCODE_SYNTAX_ERROR),
19308 : : errmsg("%s and %s options cannot be used together",
19309 : : "SKIP LOCKED", "WITH TIES"),
19310 : : parser_errposition(limitClause->optionLoc)));
19311 : 0 : }
19312 : 0 : }
19313 : 491 : stmt->limitOption = limitClause->limitOption;
19314 : 491 : }
19315 [ + + ]: 9839 : if (withClause)
19316 : : {
19317 [ + - ]: 296 : if (stmt->withClause)
19318 [ # # # # ]: 0 : ereport(ERROR,
19319 : : (errcode(ERRCODE_SYNTAX_ERROR),
19320 : : errmsg("multiple WITH clauses not allowed"),
19321 : : parser_errposition(exprLocation((Node *) withClause))));
19322 : 296 : stmt->withClause = withClause;
19323 : 296 : }
19324 : 9839 : }
19325 : :
19326 : : static Node *
19327 : 2148 : makeSetOp(SetOperation op, bool all, Node *larg, Node *rarg)
19328 : : {
19329 : 2148 : SelectStmt *n = makeNode(SelectStmt);
19330 : :
19331 : 2148 : n->op = op;
19332 : 2148 : n->all = all;
19333 : 2148 : n->larg = (SelectStmt *) larg;
19334 : 2148 : n->rarg = (SelectStmt *) rarg;
19335 : 4296 : return (Node *) n;
19336 : 2148 : }
19337 : :
19338 : : /* SystemFuncName()
19339 : : * Build a properly-qualified reference to a built-in function.
19340 : : */
19341 : : List *
19342 : 2310 : SystemFuncName(char *name)
19343 : : {
19344 : 2310 : return list_make2(makeString("pg_catalog"), makeString(name));
19345 : : }
19346 : :
19347 : : /* SystemTypeName()
19348 : : * Build a properly-qualified reference to a built-in type.
19349 : : *
19350 : : * typmod is defaulted, but may be changed afterwards by caller.
19351 : : * Likewise for the location.
19352 : : */
19353 : : TypeName *
19354 : 9617 : SystemTypeName(char *name)
19355 : : {
19356 : 9617 : return makeTypeNameFromNameList(list_make2(makeString("pg_catalog"),
19357 : : makeString(name)));
19358 : : }
19359 : :
19360 : : /* doNegate()
19361 : : * Handle negation of a numeric constant.
19362 : : *
19363 : : * Formerly, we did this here because the optimizer couldn't cope with
19364 : : * indexquals that looked like "var = -4" --- it wants "var = const"
19365 : : * and a unary minus operator applied to a constant didn't qualify.
19366 : : * As of Postgres 7.0, that problem doesn't exist anymore because there
19367 : : * is a constant-subexpression simplifier in the optimizer. However,
19368 : : * there's still a good reason for doing this here, which is that we can
19369 : : * postpone committing to a particular internal representation for simple
19370 : : * negative constants. It's better to leave "-123.456" in string form
19371 : : * until we know what the desired type is.
19372 : : */
19373 : : static Node *
19374 : 1139 : doNegate(Node *n, int location)
19375 : : {
19376 [ + + ]: 1139 : if (IsA(n, A_Const))
19377 : : {
19378 : 990 : A_Const *con = (A_Const *) n;
19379 : :
19380 : : /* report the constant's location as that of the '-' sign */
19381 : 990 : con->location = location;
19382 : :
19383 [ + + ]: 990 : if (IsA(&con->val, Integer))
19384 : : {
19385 : 838 : con->val.ival.ival = -con->val.ival.ival;
19386 : 838 : return n;
19387 : : }
19388 [ + - ]: 152 : if (IsA(&con->val, Float))
19389 : : {
19390 : 152 : doNegateFloat(&con->val.fval);
19391 : 152 : return n;
19392 : : }
19393 [ - + - ]: 990 : }
19394 : :
19395 : 149 : return (Node *) makeSimpleA_Expr(AEXPR_OP, "-", NULL, n, location);
19396 : 1139 : }
19397 : :
19398 : : static void
19399 : 155 : doNegateFloat(Float *v)
19400 : : {
19401 : 155 : char *oldval = v->fval;
19402 : :
19403 [ + - ]: 155 : if (*oldval == '+')
19404 : 0 : oldval++;
19405 [ - + ]: 155 : if (*oldval == '-')
19406 : 0 : v->fval = oldval + 1; /* just strip the '-' */
19407 : : else
19408 : 155 : v->fval = psprintf("-%s", oldval);
19409 : 155 : }
19410 : :
19411 : : static Node *
19412 : 16747 : makeAndExpr(Node *lexpr, Node *rexpr, int location)
19413 : : {
19414 : : /* Flatten "a AND b AND c ..." to a single BoolExpr on sight */
19415 [ + + ]: 16747 : if (IsA(lexpr, BoolExpr))
19416 : : {
19417 : 6263 : BoolExpr *blexpr = (BoolExpr *) lexpr;
19418 : :
19419 [ + + ]: 6263 : if (blexpr->boolop == AND_EXPR)
19420 : : {
19421 : 6056 : blexpr->args = lappend(blexpr->args, rexpr);
19422 : 6056 : return (Node *) blexpr;
19423 : : }
19424 [ - + + ]: 6263 : }
19425 : 10691 : return (Node *) makeBoolExpr(AND_EXPR, list_make2(lexpr, rexpr), location);
19426 : 16747 : }
19427 : :
19428 : : static Node *
19429 : 890 : makeOrExpr(Node *lexpr, Node *rexpr, int location)
19430 : : {
19431 : : /* Flatten "a OR b OR c ..." to a single BoolExpr on sight */
19432 [ + + ]: 890 : if (IsA(lexpr, BoolExpr))
19433 : : {
19434 : 414 : BoolExpr *blexpr = (BoolExpr *) lexpr;
19435 : :
19436 [ + + ]: 414 : if (blexpr->boolop == OR_EXPR)
19437 : : {
19438 : 308 : blexpr->args = lappend(blexpr->args, rexpr);
19439 : 308 : return (Node *) blexpr;
19440 : : }
19441 [ - + + ]: 414 : }
19442 : 582 : return (Node *) makeBoolExpr(OR_EXPR, list_make2(lexpr, rexpr), location);
19443 : 890 : }
19444 : :
19445 : : static Node *
19446 : 1475 : makeNotExpr(Node *expr, int location)
19447 : : {
19448 : 1475 : return (Node *) makeBoolExpr(NOT_EXPR, list_make1(expr), location);
19449 : : }
19450 : :
19451 : : static Node *
19452 : 1061 : makeAArrayExpr(List *elements, int location, int location_end)
19453 : : {
19454 : 1061 : A_ArrayExpr *n = makeNode(A_ArrayExpr);
19455 : :
19456 : 1061 : n->elements = elements;
19457 : 1061 : n->location = location;
19458 : 1061 : n->list_start = location;
19459 : 1061 : n->list_end = location_end;
19460 : 2122 : return (Node *) n;
19461 : 1061 : }
19462 : :
19463 : : static Node *
19464 : 201 : makeSQLValueFunction(SQLValueFunctionOp op, int32 typmod, int location)
19465 : : {
19466 : 201 : SQLValueFunction *svf = makeNode(SQLValueFunction);
19467 : :
19468 : 201 : svf->op = op;
19469 : : /* svf->type will be filled during parse analysis */
19470 : 201 : svf->typmod = typmod;
19471 : 201 : svf->location = location;
19472 : 402 : return (Node *) svf;
19473 : 201 : }
19474 : :
19475 : : static Node *
19476 : 97 : makeXmlExpr(XmlExprOp op, char *name, List *named_args, List *args,
19477 : : int location)
19478 : : {
19479 : 97 : XmlExpr *x = makeNode(XmlExpr);
19480 : :
19481 : 97 : x->op = op;
19482 : 97 : x->name = name;
19483 : :
19484 : : /*
19485 : : * named_args is a list of ResTarget; it'll be split apart into separate
19486 : : * expression and name lists in transformXmlExpr().
19487 : : */
19488 : 97 : x->named_args = named_args;
19489 : 97 : x->arg_names = NIL;
19490 : 97 : x->args = args;
19491 : : /* xmloption, if relevant, must be filled in by caller */
19492 : : /* type and typmod will be filled in during parse analysis */
19493 : 97 : x->type = InvalidOid; /* marks the node as not analyzed */
19494 : 97 : x->location = location;
19495 : 194 : return (Node *) x;
19496 : 97 : }
19497 : :
19498 : : /*
19499 : : * Merge the input and output parameters of a table function.
19500 : : */
19501 : : static List *
19502 : 28 : mergeTableFuncParameters(List *func_args, List *columns, core_yyscan_t yyscanner)
19503 : : {
19504 : 28 : ListCell *lc;
19505 : :
19506 : : /* Explicit OUT and INOUT parameters shouldn't be used in this syntax */
19507 [ + + + + : 58 : foreach(lc, func_args)
+ + ]
19508 : : {
19509 : 30 : FunctionParameter *p = (FunctionParameter *) lfirst(lc);
19510 : :
19511 [ - + ]: 30 : if (p->mode != FUNC_PARAM_DEFAULT &&
19512 [ # # # # ]: 0 : p->mode != FUNC_PARAM_IN &&
19513 : 0 : p->mode != FUNC_PARAM_VARIADIC)
19514 [ # # # # ]: 0 : ereport(ERROR,
19515 : : (errcode(ERRCODE_SYNTAX_ERROR),
19516 : : errmsg("OUT and INOUT arguments aren't allowed in TABLE functions"),
19517 : : parser_errposition(p->location)));
19518 : 30 : }
19519 : :
19520 : 56 : return list_concat(func_args, columns);
19521 : 28 : }
19522 : :
19523 : : /*
19524 : : * Determine return type of a TABLE function. A single result column
19525 : : * returns setof that column's type; otherwise return setof record.
19526 : : */
19527 : : static TypeName *
19528 : 28 : TableFuncTypeName(List *columns)
19529 : : {
19530 : 28 : TypeName *result;
19531 : :
19532 [ + + ]: 28 : if (list_length(columns) == 1)
19533 : : {
19534 : 9 : FunctionParameter *p = (FunctionParameter *) linitial(columns);
19535 : :
19536 : 9 : result = copyObject(p->argType);
19537 : 9 : }
19538 : : else
19539 : 19 : result = SystemTypeName("record");
19540 : :
19541 : 28 : result->setof = true;
19542 : :
19543 : 56 : return result;
19544 : 28 : }
19545 : :
19546 : : /*
19547 : : * Convert a list of (dotted) names to a RangeVar (like
19548 : : * makeRangeVarFromNameList, but with position support). The
19549 : : * "AnyName" refers to the any_name production in the grammar.
19550 : : */
19551 : : static RangeVar *
19552 : 131 : makeRangeVarFromAnyName(List *names, int position, core_yyscan_t yyscanner)
19553 : : {
19554 : 131 : RangeVar *r = makeNode(RangeVar);
19555 : :
19556 [ + + - - ]: 131 : switch (list_length(names))
19557 : : {
19558 : : case 1:
19559 : 126 : r->catalogname = NULL;
19560 : 126 : r->schemaname = NULL;
19561 : 126 : r->relname = strVal(linitial(names));
19562 : 126 : break;
19563 : : case 2:
19564 : 5 : r->catalogname = NULL;
19565 : 5 : r->schemaname = strVal(linitial(names));
19566 : 5 : r->relname = strVal(lsecond(names));
19567 : 5 : break;
19568 : : case 3:
19569 : 0 : r->catalogname = strVal(linitial(names));
19570 : 0 : r->schemaname = strVal(lsecond(names));
19571 : 0 : r->relname = strVal(lthird(names));
19572 : 0 : break;
19573 : : default:
19574 [ # # # # ]: 0 : ereport(ERROR,
19575 : : (errcode(ERRCODE_SYNTAX_ERROR),
19576 : : errmsg("improper qualified name (too many dotted names): %s",
19577 : : NameListToString(names)),
19578 : : parser_errposition(position)));
19579 : 0 : break;
19580 : : }
19581 : :
19582 : 131 : r->relpersistence = RELPERSISTENCE_PERMANENT;
19583 : 131 : r->location = position;
19584 : :
19585 : 262 : return r;
19586 : 131 : }
19587 : :
19588 : : /*
19589 : : * Convert a relation_name with name and namelist to a RangeVar using
19590 : : * makeRangeVar.
19591 : : */
19592 : : static RangeVar *
19593 : 19563 : makeRangeVarFromQualifiedName(char *name, List *namelist, int location,
19594 : : core_yyscan_t yyscanner)
19595 : : {
19596 : 19563 : RangeVar *r;
19597 : :
19598 : 19563 : check_qualified_name(namelist, yyscanner);
19599 : 19563 : r = makeRangeVar(NULL, NULL, location);
19600 : :
19601 [ - + - ]: 19563 : switch (list_length(namelist))
19602 : : {
19603 : : case 1:
19604 : 19563 : r->catalogname = NULL;
19605 : 19563 : r->schemaname = name;
19606 : 19563 : r->relname = strVal(linitial(namelist));
19607 : 19563 : break;
19608 : : case 2:
19609 : 0 : r->catalogname = name;
19610 : 0 : r->schemaname = strVal(linitial(namelist));
19611 : 0 : r->relname = strVal(lsecond(namelist));
19612 : 0 : break;
19613 : : default:
19614 [ # # # # ]: 0 : ereport(ERROR,
19615 : : errcode(ERRCODE_SYNTAX_ERROR),
19616 : : errmsg("improper qualified name (too many dotted names): %s",
19617 : : NameListToString(lcons(makeString(name), namelist))),
19618 : : parser_errposition(location));
19619 : 0 : break;
19620 : : }
19621 : :
19622 : 39126 : return r;
19623 : 19563 : }
19624 : :
19625 : : /* Separate Constraint nodes from COLLATE clauses in a ColQualList */
19626 : : static void
19627 : 7489 : SplitColQualList(List *qualList,
19628 : : List **constraintList, CollateClause **collClause,
19629 : : core_yyscan_t yyscanner)
19630 : : {
19631 : 7489 : ListCell *cell;
19632 : :
19633 : 7489 : *collClause = NULL;
19634 [ + + + + : 9275 : foreach(cell, qualList)
+ + ]
19635 : : {
19636 : 1786 : Node *n = (Node *) lfirst(cell);
19637 : :
19638 [ + + ]: 1786 : if (IsA(n, Constraint))
19639 : : {
19640 : : /* keep it in list */
19641 : 1697 : continue;
19642 : : }
19643 [ + - ]: 89 : if (IsA(n, CollateClause))
19644 : : {
19645 : 89 : CollateClause *c = (CollateClause *) n;
19646 : :
19647 [ + - ]: 89 : if (*collClause)
19648 [ # # # # ]: 0 : ereport(ERROR,
19649 : : (errcode(ERRCODE_SYNTAX_ERROR),
19650 : : errmsg("multiple COLLATE clauses not allowed"),
19651 : : parser_errposition(c->location)));
19652 : 89 : *collClause = c;
19653 : 89 : }
19654 : : else
19655 [ # # # # ]: 0 : elog(ERROR, "unexpected node type %d", (int) n->type);
19656 : : /* remove non-Constraint nodes from qualList */
19657 : 89 : qualList = foreach_delete_current(qualList, cell);
19658 [ - + + ]: 1786 : }
19659 : 7489 : *constraintList = qualList;
19660 : 7489 : }
19661 : :
19662 : : /*
19663 : : * Process result of ConstraintAttributeSpec, and set appropriate bool flags
19664 : : * in the output command node. Pass NULL for any flags the particular
19665 : : * command doesn't support.
19666 : : */
19667 : : static void
19668 : 1106 : processCASbits(int cas_bits, int location, const char *constrType,
19669 : : bool *deferrable, bool *initdeferred, bool *is_enforced,
19670 : : bool *not_valid, bool *no_inherit, core_yyscan_t yyscanner)
19671 : : {
19672 : : /* defaults */
19673 [ + + ]: 1106 : if (deferrable)
19674 : 779 : *deferrable = false;
19675 [ + + ]: 1106 : if (initdeferred)
19676 : 779 : *initdeferred = false;
19677 [ + + ]: 1106 : if (not_valid)
19678 : 551 : *not_valid = false;
19679 [ + + ]: 1106 : if (is_enforced)
19680 : 475 : *is_enforced = true;
19681 : :
19682 [ + + ]: 1106 : if (cas_bits & (CAS_DEFERRABLE | CAS_INITIALLY_DEFERRED))
19683 : : {
19684 [ + - ]: 36 : if (deferrable)
19685 : 36 : *deferrable = true;
19686 : : else
19687 [ # # # # ]: 0 : ereport(ERROR,
19688 : : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
19689 : : /* translator: %s is CHECK, UNIQUE, or similar */
19690 : : errmsg("%s constraints cannot be marked DEFERRABLE",
19691 : : constrType),
19692 : : parser_errposition(location)));
19693 : 36 : }
19694 : :
19695 [ + + ]: 1106 : if (cas_bits & CAS_INITIALLY_DEFERRED)
19696 : : {
19697 [ + - ]: 23 : if (initdeferred)
19698 : 23 : *initdeferred = true;
19699 : : else
19700 [ # # # # ]: 0 : ereport(ERROR,
19701 : : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
19702 : : /* translator: %s is CHECK, UNIQUE, or similar */
19703 : : errmsg("%s constraints cannot be marked DEFERRABLE",
19704 : : constrType),
19705 : : parser_errposition(location)));
19706 : 23 : }
19707 : :
19708 [ + + ]: 1106 : if (cas_bits & CAS_NOT_VALID)
19709 : : {
19710 [ + - ]: 58 : if (not_valid)
19711 : 58 : *not_valid = true;
19712 : : else
19713 [ # # # # ]: 0 : ereport(ERROR,
19714 : : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
19715 : : /* translator: %s is CHECK, UNIQUE, or similar */
19716 : : errmsg("%s constraints cannot be marked NOT VALID",
19717 : : constrType),
19718 : : parser_errposition(location)));
19719 : 58 : }
19720 : :
19721 [ + + ]: 1106 : if (cas_bits & CAS_NO_INHERIT)
19722 : : {
19723 [ + - ]: 40 : if (no_inherit)
19724 : 40 : *no_inherit = true;
19725 : : else
19726 [ # # # # ]: 0 : ereport(ERROR,
19727 : : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
19728 : : /* translator: %s is CHECK, UNIQUE, or similar */
19729 : : errmsg("%s constraints cannot be marked NO INHERIT",
19730 : : constrType),
19731 : : parser_errposition(location)));
19732 : 40 : }
19733 : :
19734 [ + + ]: 1106 : if (cas_bits & CAS_NOT_ENFORCED)
19735 : : {
19736 [ + + ]: 28 : if (is_enforced)
19737 : 27 : *is_enforced = false;
19738 : : else
19739 [ + - + - ]: 1 : ereport(ERROR,
19740 : : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
19741 : : /* translator: %s is CHECK, UNIQUE, or similar */
19742 : : errmsg("%s constraints cannot be marked NOT ENFORCED",
19743 : : constrType),
19744 : : parser_errposition(location)));
19745 : :
19746 : : /*
19747 : : * NB: The validated status is irrelevant when the constraint is set to
19748 : : * NOT ENFORCED, but for consistency, it should be set accordingly.
19749 : : * This ensures that if the constraint is later changed to ENFORCED, it
19750 : : * will automatically be in the correct NOT VALIDATED state.
19751 : : */
19752 [ + + ]: 27 : if (not_valid)
19753 : 21 : *not_valid = true;
19754 : 27 : }
19755 : :
19756 [ + + ]: 1105 : if (cas_bits & CAS_ENFORCED)
19757 : : {
19758 [ + + ]: 18 : if (is_enforced)
19759 : 17 : *is_enforced = true;
19760 : : else
19761 [ + - + - ]: 1 : ereport(ERROR,
19762 : : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
19763 : : /* translator: %s is CHECK, UNIQUE, or similar */
19764 : : errmsg("%s constraints cannot be marked ENFORCED",
19765 : : constrType),
19766 : : parser_errposition(location)));
19767 : 17 : }
19768 : 1104 : }
19769 : :
19770 : : /*
19771 : : * Parse a user-supplied partition strategy string into parse node
19772 : : * PartitionStrategy representation, or die trying.
19773 : : */
19774 : : static PartitionStrategy
19775 : 731 : parsePartitionStrategy(char *strategy, int location, core_yyscan_t yyscanner)
19776 : : {
19777 [ + + ]: 731 : if (pg_strcasecmp(strategy, "list") == 0)
19778 : 292 : return PARTITION_STRATEGY_LIST;
19779 [ + + ]: 439 : else if (pg_strcasecmp(strategy, "range") == 0)
19780 : 398 : return PARTITION_STRATEGY_RANGE;
19781 [ + + ]: 41 : else if (pg_strcasecmp(strategy, "hash") == 0)
19782 : 40 : return PARTITION_STRATEGY_HASH;
19783 : :
19784 [ + - + - ]: 1 : ereport(ERROR,
19785 : : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
19786 : : errmsg("unrecognized partitioning strategy \"%s\"", strategy),
19787 : : parser_errposition(location)));
19788 : 0 : return PARTITION_STRATEGY_LIST; /* keep compiler quiet */
19789 : :
19790 : 730 : }
19791 : :
19792 : : /*
19793 : : * Process all_objects_list to set all_tables and/or all_sequences.
19794 : : * Also, checks if the pub_object_type has been specified more than once.
19795 : : */
19796 : : static void
19797 : 11 : preprocess_pub_all_objtype_list(List *all_objects_list, bool *all_tables,
19798 : : bool *all_sequences, core_yyscan_t yyscanner)
19799 : : {
19800 [ + - ]: 11 : if (!all_objects_list)
19801 : 0 : return;
19802 : :
19803 : 11 : *all_tables = false;
19804 : 11 : *all_sequences = false;
19805 : :
19806 [ + + + - : 34 : foreach_ptr(PublicationAllObjSpec, obj, all_objects_list)
+ + + + ]
19807 : : {
19808 [ + + ]: 16 : if (obj->pubobjtype == PUBLICATION_ALL_TABLES)
19809 : : {
19810 [ + + ]: 10 : if (*all_tables)
19811 [ + - + - ]: 1 : ereport(ERROR,
19812 : : errcode(ERRCODE_SYNTAX_ERROR),
19813 : : errmsg("invalid publication object list"),
19814 : : errdetail("ALL TABLES can be specified only once."),
19815 : : parser_errposition(obj->location));
19816 : :
19817 : 9 : *all_tables = true;
19818 : 9 : }
19819 [ - + ]: 6 : else if (obj->pubobjtype == PUBLICATION_ALL_SEQUENCES)
19820 : : {
19821 [ + + ]: 6 : if (*all_sequences)
19822 [ + - + - ]: 1 : ereport(ERROR,
19823 : : errcode(ERRCODE_SYNTAX_ERROR),
19824 : : errmsg("invalid publication object list"),
19825 : : errdetail("ALL SEQUENCES can be specified only once."),
19826 : : parser_errposition(obj->location));
19827 : :
19828 : 5 : *all_sequences = true;
19829 : 5 : }
19830 : 23 : }
19831 : 9 : }
19832 : :
19833 : : /*
19834 : : * Process pubobjspec_list to check for errors in any of the objects and
19835 : : * convert PUBLICATIONOBJ_CONTINUATION into appropriate PublicationObjSpecType.
19836 : : */
19837 : : static void
19838 : 224 : preprocess_pubobj_list(List *pubobjspec_list, core_yyscan_t yyscanner)
19839 : : {
19840 : 224 : ListCell *cell;
19841 : 224 : PublicationObjSpec *pubobj;
19842 : 224 : PublicationObjSpecType prevobjtype = PUBLICATIONOBJ_CONTINUATION;
19843 : :
19844 [ + - ]: 224 : if (!pubobjspec_list)
19845 : 0 : return;
19846 : :
19847 : 224 : pubobj = (PublicationObjSpec *) linitial(pubobjspec_list);
19848 [ + + ]: 224 : if (pubobj->pubobjtype == PUBLICATIONOBJ_CONTINUATION)
19849 [ + - + - ]: 2 : ereport(ERROR,
19850 : : errcode(ERRCODE_SYNTAX_ERROR),
19851 : : errmsg("invalid publication object list"),
19852 : : errdetail("One of TABLE or TABLES IN SCHEMA must be specified before a standalone table or schema name."),
19853 : : parser_errposition(pubobj->location));
19854 : :
19855 [ + - + + : 473 : foreach(cell, pubobjspec_list)
+ + ]
19856 : : {
19857 : 255 : pubobj = (PublicationObjSpec *) lfirst(cell);
19858 : :
19859 [ + + ]: 255 : if (pubobj->pubobjtype == PUBLICATIONOBJ_CONTINUATION)
19860 : 20 : pubobj->pubobjtype = prevobjtype;
19861 : :
19862 [ + + ]: 255 : if (pubobj->pubobjtype == PUBLICATIONOBJ_TABLE)
19863 : : {
19864 : : /* relation name or pubtable must be set for this type of object */
19865 [ + + + + ]: 185 : if (!pubobj->name && !pubobj->pubtable)
19866 [ + - + - ]: 1 : ereport(ERROR,
19867 : : errcode(ERRCODE_SYNTAX_ERROR),
19868 : : errmsg("invalid table name"),
19869 : : parser_errposition(pubobj->location));
19870 : :
19871 [ + + ]: 184 : if (pubobj->name)
19872 : : {
19873 : : /* convert it to PublicationTable */
19874 : 3 : PublicationTable *pubtable = makeNode(PublicationTable);
19875 : :
19876 : 3 : pubtable->relation =
19877 : 3 : makeRangeVar(NULL, pubobj->name, pubobj->location);
19878 : 3 : pubobj->pubtable = pubtable;
19879 : 3 : pubobj->name = NULL;
19880 : 3 : }
19881 : 184 : }
19882 [ + + + - ]: 70 : else if (pubobj->pubobjtype == PUBLICATIONOBJ_TABLES_IN_SCHEMA ||
19883 : 4 : pubobj->pubobjtype == PUBLICATIONOBJ_TABLES_IN_CUR_SCHEMA)
19884 : : {
19885 : : /* WHERE clause is not allowed on a schema object */
19886 [ + + + + ]: 70 : if (pubobj->pubtable && pubobj->pubtable->whereClause)
19887 [ + - + - ]: 1 : ereport(ERROR,
19888 : : errcode(ERRCODE_SYNTAX_ERROR),
19889 : : errmsg("WHERE clause not allowed for schema"),
19890 : : parser_errposition(pubobj->location));
19891 : :
19892 : : /* Column list is not allowed on a schema object */
19893 [ + + + + ]: 69 : if (pubobj->pubtable && pubobj->pubtable->columns)
19894 [ + - + - ]: 1 : ereport(ERROR,
19895 : : errcode(ERRCODE_SYNTAX_ERROR),
19896 : : errmsg("column specification not allowed for schema"),
19897 : : parser_errposition(pubobj->location));
19898 : :
19899 : : /*
19900 : : * We can distinguish between the different type of schema objects
19901 : : * based on whether name and pubtable is set.
19902 : : */
19903 [ + + ]: 68 : if (pubobj->name)
19904 : 63 : pubobj->pubobjtype = PUBLICATIONOBJ_TABLES_IN_SCHEMA;
19905 [ + + ]: 5 : else if (!pubobj->name && !pubobj->pubtable)
19906 : 4 : pubobj->pubobjtype = PUBLICATIONOBJ_TABLES_IN_CUR_SCHEMA;
19907 : : else
19908 [ + - + - ]: 1 : ereport(ERROR,
19909 : : errcode(ERRCODE_SYNTAX_ERROR),
19910 : : errmsg("invalid schema name"),
19911 : : parser_errposition(pubobj->location));
19912 : 67 : }
19913 : :
19914 : 251 : prevobjtype = pubobj->pubobjtype;
19915 : 251 : }
19916 [ - + ]: 218 : }
19917 : :
19918 : : /*----------
19919 : : * Recursive view transformation
19920 : : *
19921 : : * Convert
19922 : : *
19923 : : * CREATE RECURSIVE VIEW relname (aliases) AS query
19924 : : *
19925 : : * to
19926 : : *
19927 : : * CREATE VIEW relname (aliases) AS
19928 : : * WITH RECURSIVE relname (aliases) AS (query)
19929 : : * SELECT aliases FROM relname
19930 : : *
19931 : : * Actually, just the WITH ... part, which is then inserted into the original
19932 : : * view definition as the query.
19933 : : * ----------
19934 : : */
19935 : : static Node *
19936 : 2 : makeRecursiveViewSelect(char *relname, List *aliases, Node *query)
19937 : : {
19938 : 2 : SelectStmt *s = makeNode(SelectStmt);
19939 : 2 : WithClause *w = makeNode(WithClause);
19940 : 2 : CommonTableExpr *cte = makeNode(CommonTableExpr);
19941 : 2 : List *tl = NIL;
19942 : 2 : ListCell *lc;
19943 : :
19944 : : /* create common table expression */
19945 : 2 : cte->ctename = relname;
19946 : 2 : cte->aliascolnames = aliases;
19947 : 2 : cte->ctematerialized = CTEMaterializeDefault;
19948 : 2 : cte->ctequery = query;
19949 : 2 : cte->location = -1;
19950 : :
19951 : : /* create WITH clause and attach CTE */
19952 : 2 : w->recursive = true;
19953 : 2 : w->ctes = list_make1(cte);
19954 : 2 : w->location = -1;
19955 : :
19956 : : /*
19957 : : * create target list for the new SELECT from the alias list of the
19958 : : * recursive view specification
19959 : : */
19960 [ + - + + : 4 : foreach(lc, aliases)
+ + ]
19961 : : {
19962 : 2 : ResTarget *rt = makeNode(ResTarget);
19963 : :
19964 : 2 : rt->name = NULL;
19965 : 2 : rt->indirection = NIL;
19966 : 2 : rt->val = makeColumnRef(strVal(lfirst(lc)), NIL, -1, 0);
19967 : 2 : rt->location = -1;
19968 : :
19969 : 2 : tl = lappend(tl, rt);
19970 : 2 : }
19971 : :
19972 : : /*
19973 : : * create new SELECT combining WITH clause, target list, and fake FROM
19974 : : * clause
19975 : : */
19976 : 2 : s->withClause = w;
19977 : 2 : s->targetList = tl;
19978 : 2 : s->fromClause = list_make1(makeRangeVar(NULL, relname, -1));
19979 : :
19980 : 4 : return (Node *) s;
19981 : 2 : }
19982 : :
19983 : : /* parser_init()
19984 : : * Initialize to parse one query string
19985 : : */
19986 : : void
19987 : 71354 : parser_init(base_yy_extra_type *yyext)
19988 : : {
19989 : 71354 : yyext->parsetree = NIL; /* in case grammar forgets to set it */
19990 : 71354 : }
|