Line data Source code
1 : /*-------------------------------------------------------------------------
2 : *
3 : * utility.c
4 : * Contains functions which control the execution of the POSTGRES utility
5 : * commands. At one time acted as an interface between the Lisp and C
6 : * systems.
7 : *
8 : * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
9 : * Portions Copyright (c) 1994, Regents of the University of California
10 : *
11 : *
12 : * IDENTIFICATION
13 : * src/backend/tcop/utility.c
14 : *
15 : *-------------------------------------------------------------------------
16 : */
17 : #include "postgres.h"
18 :
19 : #include "access/reloptions.h"
20 : #include "access/twophase.h"
21 : #include "access/xact.h"
22 : #include "access/xlog.h"
23 : #include "catalog/namespace.h"
24 : #include "catalog/pg_authid.h"
25 : #include "catalog/pg_inherits.h"
26 : #include "catalog/toasting.h"
27 : #include "commands/alter.h"
28 : #include "commands/async.h"
29 : #include "commands/collationcmds.h"
30 : #include "commands/comment.h"
31 : #include "commands/conversioncmds.h"
32 : #include "commands/copy.h"
33 : #include "commands/createas.h"
34 : #include "commands/dbcommands.h"
35 : #include "commands/defrem.h"
36 : #include "commands/discard.h"
37 : #include "commands/event_trigger.h"
38 : #include "commands/explain.h"
39 : #include "commands/extension.h"
40 : #include "commands/lockcmds.h"
41 : #include "commands/matview.h"
42 : #include "commands/policy.h"
43 : #include "commands/portalcmds.h"
44 : #include "commands/prepare.h"
45 : #include "commands/proclang.h"
46 : #include "commands/propgraphcmds.h"
47 : #include "commands/publicationcmds.h"
48 : #include "commands/repack.h"
49 : #include "commands/schemacmds.h"
50 : #include "commands/seclabel.h"
51 : #include "commands/sequence.h"
52 : #include "commands/subscriptioncmds.h"
53 : #include "commands/tablecmds.h"
54 : #include "commands/tablespace.h"
55 : #include "commands/trigger.h"
56 : #include "commands/typecmds.h"
57 : #include "commands/user.h"
58 : #include "commands/vacuum.h"
59 : #include "commands/view.h"
60 : #include "commands/wait.h"
61 : #include "miscadmin.h"
62 : #include "parser/parse_utilcmd.h"
63 : #include "postmaster/bgwriter.h"
64 : #include "rewrite/rewriteDefine.h"
65 : #include "storage/fd.h"
66 : #include "tcop/utility.h"
67 : #include "utils/acl.h"
68 : #include "utils/guc.h"
69 : #include "utils/lsyscache.h"
70 :
71 : /* Hook for plugins to get control in ProcessUtility() */
72 : ProcessUtility_hook_type ProcessUtility_hook = NULL;
73 :
74 : /* local function declarations */
75 : static int ClassifyUtilityCommandAsReadOnly(Node *parsetree);
76 : static void ProcessUtilitySlow(ParseState *pstate,
77 : PlannedStmt *pstmt,
78 : const char *queryString,
79 : ProcessUtilityContext context,
80 : ParamListInfo params,
81 : QueryEnvironment *queryEnv,
82 : DestReceiver *dest,
83 : QueryCompletion *qc);
84 : static void ExecDropStmt(DropStmt *stmt, bool isTopLevel);
85 :
86 : /*
87 : * CommandIsReadOnly: is an executable query read-only?
88 : *
89 : * This is a much stricter test than we apply for XactReadOnly mode;
90 : * the query must be *in truth* read-only, because the caller wishes
91 : * not to do CommandCounterIncrement for it.
92 : *
93 : * Note: currently no need to support raw or analyzed queries here
94 : */
95 : bool
96 12652 : CommandIsReadOnly(PlannedStmt *pstmt)
97 : {
98 : Assert(IsA(pstmt, PlannedStmt));
99 12652 : switch (pstmt->commandType)
100 : {
101 12652 : case CMD_SELECT:
102 12652 : if (pstmt->rowMarks != NIL)
103 0 : return false; /* SELECT FOR [KEY] UPDATE/SHARE */
104 12652 : else if (pstmt->hasModifyingCTE)
105 0 : return false; /* data-modifying CTE */
106 : else
107 12652 : return true;
108 0 : case CMD_UPDATE:
109 : case CMD_INSERT:
110 : case CMD_DELETE:
111 : case CMD_MERGE:
112 0 : return false;
113 0 : case CMD_UTILITY:
114 : /* For now, treat all utility commands as read/write */
115 0 : return false;
116 0 : default:
117 0 : elog(WARNING, "unrecognized commandType: %d",
118 : (int) pstmt->commandType);
119 0 : break;
120 : }
121 0 : return false;
122 : }
123 :
124 : /*
125 : * Determine the degree to which a utility command is read only.
126 : *
127 : * Note the definitions of the relevant flags in src/include/tcop/utility.h.
128 : */
129 : static int
130 261245 : ClassifyUtilityCommandAsReadOnly(Node *parsetree)
131 : {
132 261245 : switch (nodeTag(parsetree))
133 : {
134 152427 : case T_AlterCollationStmt:
135 : case T_AlterDatabaseRefreshCollStmt:
136 : case T_AlterDatabaseSetStmt:
137 : case T_AlterDatabaseStmt:
138 : case T_AlterDefaultPrivilegesStmt:
139 : case T_AlterDomainStmt:
140 : case T_AlterEnumStmt:
141 : case T_AlterEventTrigStmt:
142 : case T_AlterExtensionContentsStmt:
143 : case T_AlterExtensionStmt:
144 : case T_AlterFdwStmt:
145 : case T_AlterForeignServerStmt:
146 : case T_AlterFunctionStmt:
147 : case T_AlterObjectDependsStmt:
148 : case T_AlterObjectSchemaStmt:
149 : case T_AlterOpFamilyStmt:
150 : case T_AlterOperatorStmt:
151 : case T_AlterOwnerStmt:
152 : case T_AlterPolicyStmt:
153 : case T_AlterPropGraphStmt:
154 : case T_AlterPublicationStmt:
155 : case T_AlterRoleSetStmt:
156 : case T_AlterRoleStmt:
157 : case T_AlterSeqStmt:
158 : case T_AlterStatsStmt:
159 : case T_AlterSubscriptionStmt:
160 : case T_AlterTSConfigurationStmt:
161 : case T_AlterTSDictionaryStmt:
162 : case T_AlterTableMoveAllStmt:
163 : case T_AlterTableSpaceOptionsStmt:
164 : case T_AlterTableStmt:
165 : case T_AlterTypeStmt:
166 : case T_AlterUserMappingStmt:
167 : case T_CommentStmt:
168 : case T_CompositeTypeStmt:
169 : case T_CreateAmStmt:
170 : case T_CreateCastStmt:
171 : case T_CreateConversionStmt:
172 : case T_CreateDomainStmt:
173 : case T_CreateEnumStmt:
174 : case T_CreateEventTrigStmt:
175 : case T_CreateExtensionStmt:
176 : case T_CreateFdwStmt:
177 : case T_CreateForeignServerStmt:
178 : case T_CreateForeignTableStmt:
179 : case T_CreateFunctionStmt:
180 : case T_CreateOpClassStmt:
181 : case T_CreateOpFamilyStmt:
182 : case T_CreatePLangStmt:
183 : case T_CreatePolicyStmt:
184 : case T_CreatePropGraphStmt:
185 : case T_CreatePublicationStmt:
186 : case T_CreateRangeStmt:
187 : case T_CreateRoleStmt:
188 : case T_CreateSchemaStmt:
189 : case T_CreateSeqStmt:
190 : case T_CreateStatsStmt:
191 : case T_CreateStmt:
192 : case T_CreateSubscriptionStmt:
193 : case T_CreateTableAsStmt:
194 : case T_CreateTableSpaceStmt:
195 : case T_CreateTransformStmt:
196 : case T_CreateTrigStmt:
197 : case T_CreateUserMappingStmt:
198 : case T_CreatedbStmt:
199 : case T_DefineStmt:
200 : case T_DropOwnedStmt:
201 : case T_DropRoleStmt:
202 : case T_DropStmt:
203 : case T_DropSubscriptionStmt:
204 : case T_DropTableSpaceStmt:
205 : case T_DropUserMappingStmt:
206 : case T_DropdbStmt:
207 : case T_GrantRoleStmt:
208 : case T_GrantStmt:
209 : case T_ImportForeignSchemaStmt:
210 : case T_IndexStmt:
211 : case T_ReassignOwnedStmt:
212 : case T_RefreshMatViewStmt:
213 : case T_RenameStmt:
214 : case T_RuleStmt:
215 : case T_SecLabelStmt:
216 : case T_TruncateStmt:
217 : case T_ViewStmt:
218 : {
219 : /* DDL is not read-only, and neither is TRUNCATE. */
220 152427 : return COMMAND_IS_NOT_READ_ONLY;
221 : }
222 :
223 116 : case T_AlterSystemStmt:
224 : {
225 : /*
226 : * Surprisingly, ALTER SYSTEM meets all our definitions of
227 : * read-only: it changes nothing that affects the output of
228 : * pg_dump, it doesn't write WAL or imperil the application of
229 : * future WAL, and it doesn't depend on any state that needs
230 : * to be synchronized with parallel workers.
231 : *
232 : * So, despite the fact that it writes to a file, it's read
233 : * only!
234 : */
235 116 : return COMMAND_IS_STRICTLY_READ_ONLY;
236 : }
237 :
238 1169 : case T_CallStmt:
239 : case T_DoStmt:
240 : {
241 : /*
242 : * Commands inside the DO block or the called procedure might
243 : * not be read only, but they'll be checked separately when we
244 : * try to execute them. Here we only need to worry about the
245 : * DO or CALL command itself.
246 : */
247 1169 : return COMMAND_IS_STRICTLY_READ_ONLY;
248 : }
249 :
250 467 : case T_CheckPointStmt:
251 : {
252 : /*
253 : * You might think that this should not be permitted in
254 : * recovery, but we interpret a CHECKPOINT command during
255 : * recovery as a request for a restartpoint instead. We allow
256 : * this since it can be a useful way of reducing switchover
257 : * time when using various forms of replication.
258 : */
259 467 : return COMMAND_IS_STRICTLY_READ_ONLY;
260 : }
261 :
262 46184 : case T_ClosePortalStmt:
263 : case T_ConstraintsSetStmt:
264 : case T_DeallocateStmt:
265 : case T_DeclareCursorStmt:
266 : case T_DiscardStmt:
267 : case T_ExecuteStmt:
268 : case T_FetchStmt:
269 : case T_LoadStmt:
270 : case T_PrepareStmt:
271 : case T_UnlistenStmt:
272 : case T_VariableSetStmt:
273 : case T_WaitStmt:
274 : {
275 : /*
276 : * These modify only backend-local state, so they're OK to run
277 : * in a read-only transaction or on a standby. However, they
278 : * are disallowed in parallel mode, because they either rely
279 : * upon or modify backend-local state that might not be
280 : * synchronized among cooperating backends.
281 : */
282 46184 : return COMMAND_OK_IN_RECOVERY | COMMAND_OK_IN_READ_ONLY_TXN;
283 : }
284 :
285 9676 : case T_ReindexStmt:
286 : case T_VacuumStmt:
287 : case T_RepackStmt:
288 : {
289 : /*
290 : * These commands write WAL, so they're not strictly
291 : * read-only, and running them in parallel workers isn't
292 : * supported.
293 : *
294 : * However, they don't change the database state in a way that
295 : * would affect pg_dump output, so it's fine to run them in a
296 : * read-only transaction. (REPACK/CLUSTER might change the
297 : * order of rows on disk, which could affect the ordering of
298 : * pg_dump output, but that's not semantically significant.)
299 : */
300 9676 : return COMMAND_OK_IN_READ_ONLY_TXN;
301 : }
302 :
303 6718 : case T_CopyStmt:
304 : {
305 6718 : CopyStmt *stmt = (CopyStmt *) parsetree;
306 :
307 : /*
308 : * You might think that COPY FROM is not at all read only, but
309 : * it's OK to copy into a temporary table, because that
310 : * wouldn't change the output of pg_dump. If the target table
311 : * turns out to be non-temporary, DoCopy itself will call
312 : * PreventCommandIfReadOnly.
313 : */
314 6718 : if (stmt->is_from)
315 1239 : return COMMAND_OK_IN_READ_ONLY_TXN;
316 : else
317 5479 : return COMMAND_IS_STRICTLY_READ_ONLY;
318 : }
319 :
320 16894 : case T_ExplainStmt:
321 : case T_VariableShowStmt:
322 : {
323 : /*
324 : * These commands don't modify any data and are safe to run in
325 : * a parallel worker.
326 : */
327 16894 : return COMMAND_IS_STRICTLY_READ_ONLY;
328 : }
329 :
330 122 : case T_ListenStmt:
331 : case T_NotifyStmt:
332 : {
333 : /*
334 : * NOTIFY requires an XID assignment, so it can't be permitted
335 : * on a standby. Perhaps LISTEN could, since without NOTIFY it
336 : * would be OK to just do nothing, at least until promotion,
337 : * but we currently prohibit it lest the user get the wrong
338 : * idea.
339 : *
340 : * (We do allow T_UnlistenStmt on a standby, though, because
341 : * it's a no-op.)
342 : */
343 122 : return COMMAND_OK_IN_READ_ONLY_TXN;
344 : }
345 :
346 645 : case T_LockStmt:
347 : {
348 645 : LockStmt *stmt = (LockStmt *) parsetree;
349 :
350 : /*
351 : * Only weaker locker modes are allowed during recovery. The
352 : * restrictions here must match those in
353 : * LockAcquireExtended().
354 : */
355 645 : if (stmt->mode > RowExclusiveLock)
356 296 : return COMMAND_OK_IN_READ_ONLY_TXN;
357 : else
358 349 : return COMMAND_IS_STRICTLY_READ_ONLY;
359 : }
360 :
361 26827 : case T_TransactionStmt:
362 : {
363 26827 : TransactionStmt *stmt = (TransactionStmt *) parsetree;
364 :
365 : /*
366 : * PREPARE, COMMIT PREPARED, and ROLLBACK PREPARED all write
367 : * WAL, so they're not read-only in the strict sense; but the
368 : * first and third do not change pg_dump output, so they're OK
369 : * in a read-only transactions.
370 : *
371 : * We also consider COMMIT PREPARED to be OK in a read-only
372 : * transaction environment, by way of exception.
373 : */
374 26827 : switch (stmt->kind)
375 : {
376 26134 : case TRANS_STMT_BEGIN:
377 : case TRANS_STMT_START:
378 : case TRANS_STMT_COMMIT:
379 : case TRANS_STMT_ROLLBACK:
380 : case TRANS_STMT_SAVEPOINT:
381 : case TRANS_STMT_RELEASE:
382 : case TRANS_STMT_ROLLBACK_TO:
383 26134 : return COMMAND_IS_STRICTLY_READ_ONLY;
384 :
385 693 : case TRANS_STMT_PREPARE:
386 : case TRANS_STMT_COMMIT_PREPARED:
387 : case TRANS_STMT_ROLLBACK_PREPARED:
388 693 : return COMMAND_OK_IN_READ_ONLY_TXN;
389 : }
390 0 : elog(ERROR, "unrecognized TransactionStmtKind: %d",
391 : (int) stmt->kind);
392 : return 0; /* silence stupider compilers */
393 : }
394 :
395 0 : default:
396 0 : elog(ERROR, "unrecognized node type: %d",
397 : (int) nodeTag(parsetree));
398 : return 0; /* silence stupider compilers */
399 : }
400 : }
401 :
402 : /*
403 : * PreventCommandIfReadOnly: throw error if XactReadOnly
404 : *
405 : * This is useful partly to ensure consistency of the error message wording;
406 : * some callers have checked XactReadOnly for themselves.
407 : */
408 : void
409 225404 : PreventCommandIfReadOnly(const char *cmdname)
410 : {
411 225404 : if (XactReadOnly)
412 74 : ereport(ERROR,
413 : (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
414 : /* translator: %s is name of a SQL command, eg CREATE */
415 : errmsg("cannot execute %s in a read-only transaction",
416 : cmdname)));
417 225330 : }
418 :
419 : /*
420 : * PreventCommandIfParallelMode: throw error if current (sub)transaction is
421 : * in parallel mode.
422 : *
423 : * This is useful partly to ensure consistency of the error message wording;
424 : * some callers have checked IsInParallelMode() for themselves.
425 : */
426 : void
427 314668 : PreventCommandIfParallelMode(const char *cmdname)
428 : {
429 314668 : if (IsInParallelMode())
430 0 : ereport(ERROR,
431 : (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
432 : /* translator: %s is name of a SQL command, eg CREATE */
433 : errmsg("cannot execute %s during a parallel operation",
434 : cmdname)));
435 314668 : }
436 :
437 : /*
438 : * PreventCommandDuringRecovery: throw error if RecoveryInProgress
439 : *
440 : * The majority of operations that are unsafe in a Hot Standby
441 : * will be rejected by XactReadOnly tests. However there are a few
442 : * commands that are allowed in "read-only" xacts but cannot be allowed
443 : * in Hot Standby mode. Those commands should call this function.
444 : */
445 : void
446 4246 : PreventCommandDuringRecovery(const char *cmdname)
447 : {
448 4246 : if (RecoveryInProgress())
449 0 : ereport(ERROR,
450 : (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
451 : /* translator: %s is name of a SQL command, eg CREATE */
452 : errmsg("cannot execute %s during recovery",
453 : cmdname)));
454 4246 : }
455 :
456 : /*
457 : * CheckRestrictedOperation: throw error for hazardous command if we're
458 : * inside a security restriction context.
459 : *
460 : * This is needed to protect session-local state for which there is not any
461 : * better-defined protection mechanism, such as ownership.
462 : */
463 : static void
464 4615 : CheckRestrictedOperation(const char *cmdname)
465 : {
466 4615 : if (InSecurityRestrictedOperation())
467 0 : ereport(ERROR,
468 : (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
469 : /* translator: %s is name of a SQL command, eg PREPARE */
470 : errmsg("cannot execute %s within security-restricted operation",
471 : cmdname)));
472 4615 : }
473 :
474 : /*
475 : * ProcessUtility
476 : * general utility function invoker
477 : *
478 : * pstmt: PlannedStmt wrapper for the utility statement
479 : * queryString: original source text of command
480 : * readOnlyTree: if true, pstmt's node tree must not be modified
481 : * context: identifies source of statement (toplevel client command,
482 : * non-toplevel client command, subcommand of a larger utility command)
483 : * params: parameters to use during execution
484 : * queryEnv: environment for parse through execution (e.g., ephemeral named
485 : * tables like trigger transition tables). May be NULL.
486 : * dest: where to send results
487 : * qc: where to store command completion status data. May be NULL,
488 : * but if not, then caller must have initialized it.
489 : *
490 : * Caller MUST supply a queryString; it is not allowed (anymore) to pass NULL.
491 : * If you really don't have source text, you can pass a constant string,
492 : * perhaps "(query not available)".
493 : *
494 : * Note for users of ProcessUtility_hook: the same queryString may be passed
495 : * to multiple invocations of ProcessUtility when processing a query string
496 : * containing multiple semicolon-separated statements. One should use
497 : * pstmt->stmt_location and pstmt->stmt_len to identify the substring
498 : * containing the current statement. Keep in mind also that some utility
499 : * statements (e.g., CREATE SCHEMA) will recurse to ProcessUtility to process
500 : * sub-statements, often passing down the same queryString, stmt_location,
501 : * and stmt_len that were given for the whole statement.
502 : */
503 : void
504 261245 : ProcessUtility(PlannedStmt *pstmt,
505 : const char *queryString,
506 : bool readOnlyTree,
507 : ProcessUtilityContext context,
508 : ParamListInfo params,
509 : QueryEnvironment *queryEnv,
510 : DestReceiver *dest,
511 : QueryCompletion *qc)
512 : {
513 : Assert(IsA(pstmt, PlannedStmt));
514 : Assert(pstmt->commandType == CMD_UTILITY);
515 : Assert(queryString != NULL); /* required as of 8.4 */
516 : Assert(qc == NULL || qc->commandTag == CMDTAG_UNKNOWN);
517 :
518 : /*
519 : * We provide a function hook variable that lets loadable plugins get
520 : * control when ProcessUtility is called. Such a plugin would normally
521 : * call standard_ProcessUtility().
522 : */
523 261245 : if (ProcessUtility_hook)
524 37458 : (*ProcessUtility_hook) (pstmt, queryString, readOnlyTree,
525 : context, params, queryEnv,
526 : dest, qc);
527 : else
528 223787 : standard_ProcessUtility(pstmt, queryString, readOnlyTree,
529 : context, params, queryEnv,
530 : dest, qc);
531 249425 : }
532 :
533 : /*
534 : * standard_ProcessUtility itself deals only with utility commands for
535 : * which we do not provide event trigger support. Commands that do have
536 : * such support are passed down to ProcessUtilitySlow, which contains the
537 : * necessary infrastructure for such triggers.
538 : *
539 : * This division is not just for performance: it's critical that the
540 : * event trigger code not be invoked when doing START TRANSACTION for
541 : * example, because we might need to refresh the event trigger cache,
542 : * which requires being in a valid transaction.
543 : *
544 : * When adding or moving utility commands, check that the documentation in
545 : * event-trigger.sgml is kept up to date.
546 : */
547 : void
548 261245 : standard_ProcessUtility(PlannedStmt *pstmt,
549 : const char *queryString,
550 : bool readOnlyTree,
551 : ProcessUtilityContext context,
552 : ParamListInfo params,
553 : QueryEnvironment *queryEnv,
554 : DestReceiver *dest,
555 : QueryCompletion *qc)
556 : {
557 : Node *parsetree;
558 261245 : bool isTopLevel = (context == PROCESS_UTILITY_TOPLEVEL);
559 261245 : bool isAtomicContext = (!(context == PROCESS_UTILITY_TOPLEVEL || context == PROCESS_UTILITY_QUERY_NONATOMIC) || IsTransactionBlock());
560 : ParseState *pstate;
561 : int readonly_flags;
562 :
563 : /* This can recurse, so check for excessive recursion */
564 261245 : check_stack_depth();
565 :
566 : /*
567 : * If the given node tree is read-only, make a copy to ensure that parse
568 : * transformations don't damage the original tree. This could be
569 : * refactored to avoid making unnecessary copies in more cases, but it's
570 : * not clear that it's worth a great deal of trouble over. Statements
571 : * that are complex enough to be expensive to copy are exactly the ones
572 : * we'd need to copy, so that only marginal savings seem possible.
573 : */
574 261245 : if (readOnlyTree)
575 19559 : pstmt = copyObject(pstmt);
576 261245 : parsetree = pstmt->utilityStmt;
577 :
578 : /* Prohibit read/write commands in read-only states. */
579 261245 : readonly_flags = ClassifyUtilityCommandAsReadOnly(parsetree);
580 261245 : if (readonly_flags != COMMAND_IS_STRICTLY_READ_ONLY &&
581 210637 : (XactReadOnly || IsInParallelMode()))
582 : {
583 8976 : CommandTag commandtag = CreateCommandTag(parsetree);
584 :
585 8976 : if ((readonly_flags & COMMAND_OK_IN_READ_ONLY_TXN) == 0)
586 8 : PreventCommandIfReadOnly(GetCommandTagName(commandtag));
587 8968 : if ((readonly_flags & COMMAND_OK_IN_PARALLEL_MODE) == 0)
588 8968 : PreventCommandIfParallelMode(GetCommandTagName(commandtag));
589 8968 : if ((readonly_flags & COMMAND_OK_IN_RECOVERY) == 0)
590 0 : PreventCommandDuringRecovery(GetCommandTagName(commandtag));
591 : }
592 :
593 261237 : pstate = make_parsestate(NULL);
594 261237 : pstate->p_sourcetext = queryString;
595 261237 : pstate->p_queryEnv = queryEnv;
596 :
597 261237 : switch (nodeTag(parsetree))
598 : {
599 : /*
600 : * ******************** transactions ********************
601 : */
602 26827 : case T_TransactionStmt:
603 : {
604 26827 : TransactionStmt *stmt = (TransactionStmt *) parsetree;
605 :
606 26827 : switch (stmt->kind)
607 : {
608 : /*
609 : * START TRANSACTION, as defined by SQL99: Identical
610 : * to BEGIN. Same code for both.
611 : */
612 12456 : case TRANS_STMT_BEGIN:
613 : case TRANS_STMT_START:
614 : {
615 : ListCell *lc;
616 :
617 12456 : BeginTransactionBlock();
618 16368 : foreach(lc, stmt->options)
619 : {
620 3912 : DefElem *item = (DefElem *) lfirst(lc);
621 :
622 3912 : if (strcmp(item->defname, "transaction_isolation") == 0)
623 3366 : SetPGVariable("transaction_isolation",
624 3366 : list_make1(item->arg),
625 : true);
626 546 : else if (strcmp(item->defname, "transaction_read_only") == 0)
627 512 : SetPGVariable("transaction_read_only",
628 512 : list_make1(item->arg),
629 : true);
630 34 : else if (strcmp(item->defname, "transaction_deferrable") == 0)
631 34 : SetPGVariable("transaction_deferrable",
632 34 : list_make1(item->arg),
633 : true);
634 : }
635 : }
636 12456 : break;
637 :
638 9621 : case TRANS_STMT_COMMIT:
639 9621 : if (!EndTransactionBlock(stmt->chain))
640 : {
641 : /* report unsuccessful commit in qc */
642 471 : if (qc)
643 471 : SetQueryCompletion(qc, CMDTAG_ROLLBACK, 0);
644 : }
645 9601 : break;
646 :
647 372 : case TRANS_STMT_PREPARE:
648 372 : if (!PrepareTransactionBlock(stmt->gid))
649 : {
650 : /* report unsuccessful commit in qc */
651 2 : if (qc)
652 2 : SetQueryCompletion(qc, CMDTAG_ROLLBACK, 0);
653 : }
654 372 : break;
655 :
656 274 : case TRANS_STMT_COMMIT_PREPARED:
657 274 : PreventInTransactionBlock(isTopLevel, "COMMIT PREPARED");
658 274 : FinishPreparedTransaction(stmt->gid, true);
659 264 : break;
660 :
661 47 : case TRANS_STMT_ROLLBACK_PREPARED:
662 47 : PreventInTransactionBlock(isTopLevel, "ROLLBACK PREPARED");
663 47 : FinishPreparedTransaction(stmt->gid, false);
664 43 : break;
665 :
666 2207 : case TRANS_STMT_ROLLBACK:
667 2207 : UserAbortTransactionBlock(stmt->chain);
668 2187 : break;
669 :
670 1176 : case TRANS_STMT_SAVEPOINT:
671 1176 : RequireTransactionBlock(isTopLevel, "SAVEPOINT");
672 1167 : DefineSavepoint(stmt->savepoint_name);
673 1159 : break;
674 :
675 189 : case TRANS_STMT_RELEASE:
676 189 : RequireTransactionBlock(isTopLevel, "RELEASE SAVEPOINT");
677 185 : ReleaseSavepoint(stmt->savepoint_name);
678 181 : break;
679 :
680 485 : case TRANS_STMT_ROLLBACK_TO:
681 485 : RequireTransactionBlock(isTopLevel, "ROLLBACK TO SAVEPOINT");
682 481 : RollbackToSavepoint(stmt->savepoint_name);
683 :
684 : /*
685 : * CommitTransactionCommand is in charge of
686 : * re-defining the savepoint again
687 : */
688 473 : break;
689 : }
690 : }
691 26736 : break;
692 :
693 : /*
694 : * Portal (cursor) manipulation
695 : */
696 2660 : case T_DeclareCursorStmt:
697 2660 : PerformCursorOpen(pstate, (DeclareCursorStmt *) parsetree, params,
698 : isTopLevel);
699 2651 : break;
700 :
701 1173 : case T_ClosePortalStmt:
702 : {
703 1173 : ClosePortalStmt *stmt = (ClosePortalStmt *) parsetree;
704 :
705 1173 : CheckRestrictedOperation("CLOSE");
706 1173 : PerformPortalClose(stmt->portalname);
707 : }
708 1172 : break;
709 :
710 4418 : case T_FetchStmt:
711 4418 : PerformPortalFetch((FetchStmt *) parsetree, dest, qc);
712 4345 : break;
713 :
714 886 : case T_DoStmt:
715 886 : ExecuteDoStmt(pstate, (DoStmt *) parsetree, isAtomicContext);
716 650 : break;
717 :
718 92 : case T_CreateTableSpaceStmt:
719 : /* no event triggers for global objects */
720 92 : PreventInTransactionBlock(isTopLevel, "CREATE TABLESPACE");
721 92 : CreateTableSpace((CreateTableSpaceStmt *) parsetree);
722 72 : break;
723 :
724 52 : case T_DropTableSpaceStmt:
725 : /* no event triggers for global objects */
726 52 : PreventInTransactionBlock(isTopLevel, "DROP TABLESPACE");
727 52 : DropTableSpace((DropTableSpaceStmt *) parsetree);
728 43 : break;
729 :
730 16 : case T_AlterTableSpaceOptionsStmt:
731 : /* no event triggers for global objects */
732 16 : AlterTableSpaceOptions((AlterTableSpaceOptionsStmt *) parsetree);
733 8 : break;
734 :
735 1164 : case T_TruncateStmt:
736 1164 : ExecuteTruncate((TruncateStmt *) parsetree);
737 1076 : break;
738 :
739 6718 : case T_CopyStmt:
740 : {
741 : uint64 processed;
742 :
743 6718 : DoCopy(pstate, (CopyStmt *) parsetree,
744 : pstmt->stmt_location, pstmt->stmt_len,
745 : &processed);
746 5974 : if (qc)
747 5974 : SetQueryCompletion(qc, CMDTAG_COPY, processed);
748 : }
749 5974 : break;
750 :
751 1185 : case T_PrepareStmt:
752 1185 : CheckRestrictedOperation("PREPARE");
753 1185 : PrepareQuery(pstate, (PrepareStmt *) parsetree,
754 : pstmt->stmt_location, pstmt->stmt_len);
755 1177 : break;
756 :
757 8653 : case T_ExecuteStmt:
758 8653 : ExecuteQuery(pstate,
759 : (ExecuteStmt *) parsetree, NULL,
760 : params,
761 : dest, qc);
762 8560 : break;
763 :
764 2093 : case T_DeallocateStmt:
765 2093 : CheckRestrictedOperation("DEALLOCATE");
766 2093 : DeallocateQuery((DeallocateStmt *) parsetree);
767 2093 : break;
768 :
769 452 : case T_GrantRoleStmt:
770 : /* no event triggers for global objects */
771 452 : GrantRole(pstate, (GrantRoleStmt *) parsetree);
772 366 : break;
773 :
774 454 : case T_CreatedbStmt:
775 : /* no event triggers for global objects */
776 454 : PreventInTransactionBlock(isTopLevel, "CREATE DATABASE");
777 454 : createdb(pstate, (CreatedbStmt *) parsetree);
778 429 : break;
779 :
780 56 : case T_AlterDatabaseStmt:
781 : /* no event triggers for global objects */
782 56 : AlterDatabase(pstate, (AlterDatabaseStmt *) parsetree, isTopLevel);
783 55 : break;
784 :
785 4 : case T_AlterDatabaseRefreshCollStmt:
786 : /* no event triggers for global objects */
787 4 : AlterDatabaseRefreshColl((AlterDatabaseRefreshCollStmt *) parsetree);
788 4 : break;
789 :
790 667 : case T_AlterDatabaseSetStmt:
791 : /* no event triggers for global objects */
792 667 : AlterDatabaseSet((AlterDatabaseSetStmt *) parsetree);
793 665 : break;
794 :
795 81 : case T_DropdbStmt:
796 : /* no event triggers for global objects */
797 81 : PreventInTransactionBlock(isTopLevel, "DROP DATABASE");
798 81 : DropDatabase(pstate, (DropdbStmt *) parsetree);
799 70 : break;
800 :
801 : /* Query-level asynchronous notification */
802 62 : case T_NotifyStmt:
803 : {
804 62 : NotifyStmt *stmt = (NotifyStmt *) parsetree;
805 :
806 62 : Async_Notify(stmt->conditionname, stmt->payload);
807 : }
808 62 : break;
809 :
810 60 : case T_ListenStmt:
811 : {
812 60 : ListenStmt *stmt = (ListenStmt *) parsetree;
813 :
814 60 : CheckRestrictedOperation("LISTEN");
815 :
816 : /*
817 : * We don't allow LISTEN in background processes, as there is
818 : * no mechanism for them to collect NOTIFY messages, so they'd
819 : * just block cleanout of the async SLRU indefinitely.
820 : * (Authors of custom background workers could bypass this
821 : * restriction by calling Async_Listen directly, but then it's
822 : * on them to provide some mechanism to process the message
823 : * queue.) Note there seems no reason to forbid UNLISTEN.
824 : */
825 60 : if (MyBackendType != B_BACKEND)
826 0 : ereport(ERROR,
827 : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
828 : /* translator: %s is name of a SQL command, eg LISTEN */
829 : errmsg("cannot execute %s within a background process",
830 : "LISTEN")));
831 :
832 60 : Async_Listen(stmt->conditionname);
833 : }
834 60 : break;
835 :
836 80 : case T_UnlistenStmt:
837 : {
838 80 : UnlistenStmt *stmt = (UnlistenStmt *) parsetree;
839 :
840 80 : CheckRestrictedOperation("UNLISTEN");
841 80 : if (stmt->conditionname)
842 4 : Async_Unlisten(stmt->conditionname);
843 : else
844 76 : Async_UnlistenAll();
845 : }
846 80 : break;
847 :
848 43 : case T_LoadStmt:
849 : {
850 43 : LoadStmt *stmt = (LoadStmt *) parsetree;
851 :
852 43 : closeAllVfds(); /* probably not necessary... */
853 : /* Allowed names are restricted if you're not superuser */
854 43 : load_file(stmt->filename, !superuser());
855 : }
856 43 : break;
857 :
858 283 : case T_CallStmt:
859 283 : ExecuteCallStmt(castNode(CallStmt, parsetree), params, isAtomicContext, dest);
860 259 : break;
861 :
862 8796 : case T_VacuumStmt:
863 8796 : ExecVacuum(pstate, (VacuumStmt *) parsetree, isTopLevel);
864 8665 : break;
865 :
866 183 : case T_RepackStmt:
867 183 : ExecRepack(pstate, (RepackStmt *) parsetree, isTopLevel);
868 155 : break;
869 :
870 16333 : case T_ExplainStmt:
871 16333 : ExplainQuery(pstate, (ExplainStmt *) parsetree, params, dest);
872 16247 : break;
873 :
874 116 : case T_AlterSystemStmt:
875 116 : PreventInTransactionBlock(isTopLevel, "ALTER SYSTEM");
876 116 : AlterSystemSetConfigFile((AlterSystemStmt *) parsetree);
877 87 : break;
878 :
879 25729 : case T_VariableSetStmt:
880 25729 : ExecSetVariableStmt((VariableSetStmt *) parsetree, isTopLevel);
881 25547 : break;
882 :
883 561 : case T_VariableShowStmt:
884 : {
885 561 : VariableShowStmt *n = (VariableShowStmt *) parsetree;
886 :
887 561 : GetPGVariable(n->name, dest);
888 : }
889 561 : break;
890 :
891 24 : case T_DiscardStmt:
892 : /* should we allow DISCARD PLANS? */
893 24 : CheckRestrictedOperation("DISCARD");
894 24 : DiscardCommand((DiscardStmt *) parsetree, isTopLevel);
895 24 : break;
896 :
897 128 : case T_CreateEventTrigStmt:
898 : /* no event triggers on event triggers */
899 128 : CreateEventTrigger((CreateEventTrigStmt *) parsetree);
900 84 : break;
901 :
902 31 : case T_AlterEventTrigStmt:
903 : /* no event triggers on event triggers */
904 31 : AlterEventTrigger((AlterEventTrigStmt *) parsetree);
905 31 : break;
906 :
907 : /*
908 : * ******************************** ROLE statements ****
909 : */
910 1338 : case T_CreateRoleStmt:
911 : /* no event triggers for global objects */
912 1338 : CreateRole(pstate, (CreateRoleStmt *) parsetree);
913 1248 : break;
914 :
915 290 : case T_AlterRoleStmt:
916 : /* no event triggers for global objects */
917 290 : AlterRole(pstate, (AlterRoleStmt *) parsetree);
918 234 : break;
919 :
920 63 : case T_AlterRoleSetStmt:
921 : /* no event triggers for global objects */
922 63 : AlterRoleSet((AlterRoleSetStmt *) parsetree);
923 57 : break;
924 :
925 1279 : case T_DropRoleStmt:
926 : /* no event triggers for global objects */
927 1279 : DropRole((DropRoleStmt *) parsetree);
928 1126 : break;
929 :
930 34 : case T_ReassignOwnedStmt:
931 : /* no event triggers for global objects */
932 34 : ReassignOwnedObjects((ReassignOwnedStmt *) parsetree);
933 22 : break;
934 :
935 645 : case T_LockStmt:
936 :
937 : /*
938 : * Since the lock would just get dropped immediately, LOCK TABLE
939 : * outside a transaction block is presumed to be user error.
940 : */
941 645 : RequireTransactionBlock(isTopLevel, "LOCK TABLE");
942 640 : LockTableCommand((LockStmt *) parsetree);
943 593 : break;
944 :
945 71 : case T_ConstraintsSetStmt:
946 71 : WarnNoTransactionBlock(isTopLevel, "SET CONSTRAINTS");
947 71 : AfterTriggerSetState((ConstraintsSetStmt *) parsetree);
948 61 : break;
949 :
950 467 : case T_CheckPointStmt:
951 467 : ExecCheckpoint(pstate, (CheckPointStmt *) parsetree);
952 459 : break;
953 :
954 : /*
955 : * The following statements are supported by Event Triggers only
956 : * in some cases, so we "fast path" them in the other cases.
957 : */
958 :
959 12589 : case T_GrantStmt:
960 : {
961 12589 : GrantStmt *stmt = (GrantStmt *) parsetree;
962 :
963 12589 : if (EventTriggerSupportsObjectType(stmt->objtype))
964 12327 : ProcessUtilitySlow(pstate, pstmt, queryString,
965 : context, params, queryEnv,
966 : dest, qc);
967 : else
968 262 : ExecuteGrantStmt(stmt);
969 : }
970 12493 : break;
971 :
972 17245 : case T_DropStmt:
973 : {
974 17245 : DropStmt *stmt = (DropStmt *) parsetree;
975 :
976 17245 : if (EventTriggerSupportsObjectType(stmt->removeType))
977 17165 : ProcessUtilitySlow(pstate, pstmt, queryString,
978 : context, params, queryEnv,
979 : dest, qc);
980 : else
981 80 : ExecDropStmt(stmt, isTopLevel);
982 : }
983 16561 : break;
984 :
985 1012 : case T_RenameStmt:
986 : {
987 1012 : RenameStmt *stmt = (RenameStmt *) parsetree;
988 :
989 1012 : if (EventTriggerSupportsObjectType(stmt->renameType))
990 967 : ProcessUtilitySlow(pstate, pstmt, queryString,
991 : context, params, queryEnv,
992 : dest, qc);
993 : else
994 45 : ExecRenameStmt(stmt);
995 : }
996 736 : break;
997 :
998 23 : case T_AlterObjectDependsStmt:
999 : {
1000 23 : AlterObjectDependsStmt *stmt = (AlterObjectDependsStmt *) parsetree;
1001 :
1002 23 : if (EventTriggerSupportsObjectType(stmt->objectType))
1003 23 : ProcessUtilitySlow(pstate, pstmt, queryString,
1004 : context, params, queryEnv,
1005 : dest, qc);
1006 : else
1007 0 : ExecAlterObjectDependsStmt(stmt, NULL);
1008 : }
1009 23 : break;
1010 :
1011 281 : case T_AlterObjectSchemaStmt:
1012 : {
1013 281 : AlterObjectSchemaStmt *stmt = (AlterObjectSchemaStmt *) parsetree;
1014 :
1015 281 : if (EventTriggerSupportsObjectType(stmt->objectType))
1016 281 : ProcessUtilitySlow(pstate, pstmt, queryString,
1017 : context, params, queryEnv,
1018 : dest, qc);
1019 : else
1020 0 : ExecAlterObjectSchemaStmt(stmt, NULL);
1021 : }
1022 186 : break;
1023 :
1024 994 : case T_AlterOwnerStmt:
1025 : {
1026 994 : AlterOwnerStmt *stmt = (AlterOwnerStmt *) parsetree;
1027 :
1028 994 : if (EventTriggerSupportsObjectType(stmt->objectType))
1029 932 : ProcessUtilitySlow(pstate, pstmt, queryString,
1030 : context, params, queryEnv,
1031 : dest, qc);
1032 : else
1033 62 : ExecAlterOwnerStmt(stmt);
1034 : }
1035 814 : break;
1036 :
1037 4456 : case T_CommentStmt:
1038 : {
1039 4456 : CommentStmt *stmt = (CommentStmt *) parsetree;
1040 :
1041 4456 : if (EventTriggerSupportsObjectType(stmt->objtype))
1042 4293 : ProcessUtilitySlow(pstate, pstmt, queryString,
1043 : context, params, queryEnv,
1044 : dest, qc);
1045 : else
1046 163 : CommentObject(stmt);
1047 4347 : break;
1048 : }
1049 :
1050 67 : case T_SecLabelStmt:
1051 : {
1052 67 : SecLabelStmt *stmt = (SecLabelStmt *) parsetree;
1053 :
1054 67 : if (EventTriggerSupportsObjectType(stmt->objtype))
1055 44 : ProcessUtilitySlow(pstate, pstmt, queryString,
1056 : context, params, queryEnv,
1057 : dest, qc);
1058 : else
1059 23 : ExecSecLabelStmt(stmt);
1060 23 : break;
1061 : }
1062 :
1063 55 : case T_WaitStmt:
1064 : {
1065 55 : ExecWaitStmt(pstate, (WaitStmt *) parsetree, dest);
1066 : }
1067 38 : break;
1068 :
1069 110248 : default:
1070 : /* All other statement types have event trigger support */
1071 110248 : ProcessUtilitySlow(pstate, pstmt, queryString,
1072 : context, params, queryEnv,
1073 : dest, qc);
1074 102353 : break;
1075 : }
1076 :
1077 249425 : free_parsestate(pstate);
1078 :
1079 : /*
1080 : * Make effects of commands visible, for instance so that
1081 : * PreCommit_on_commit_actions() can see them (see for example bug
1082 : * #15631).
1083 : */
1084 249425 : CommandCounterIncrement();
1085 249425 : }
1086 :
1087 : /*
1088 : * The "Slow" variant of ProcessUtility should only receive statements
1089 : * supported by the event triggers facility. Therefore, we always
1090 : * perform the trigger support calls if the context allows it.
1091 : */
1092 : static void
1093 146280 : ProcessUtilitySlow(ParseState *pstate,
1094 : PlannedStmt *pstmt,
1095 : const char *queryString,
1096 : ProcessUtilityContext context,
1097 : ParamListInfo params,
1098 : QueryEnvironment *queryEnv,
1099 : DestReceiver *dest,
1100 : QueryCompletion *qc)
1101 : {
1102 146280 : Node *parsetree = pstmt->utilityStmt;
1103 146280 : bool isTopLevel = (context == PROCESS_UTILITY_TOPLEVEL);
1104 146280 : bool isCompleteQuery = (context != PROCESS_UTILITY_SUBCOMMAND);
1105 : bool needCleanup;
1106 146280 : bool commandCollected = false;
1107 : ObjectAddress address;
1108 146280 : ObjectAddress secondaryObject = InvalidObjectAddress;
1109 :
1110 : /* All event trigger calls are done only when isCompleteQuery is true */
1111 146280 : needCleanup = isCompleteQuery && EventTriggerBeginCompleteQuery();
1112 :
1113 : /* PG_TRY block is to ensure we call EventTriggerEndCompleteQuery */
1114 146280 : PG_TRY();
1115 : {
1116 146280 : if (isCompleteQuery)
1117 138211 : EventTriggerDDLCommandStart(parsetree);
1118 :
1119 146280 : switch (nodeTag(parsetree))
1120 : {
1121 : /*
1122 : * relation and attribute manipulation
1123 : */
1124 719 : case T_CreateSchemaStmt:
1125 719 : CreateSchemaCommand((CreateSchemaStmt *) parsetree,
1126 : queryString,
1127 : pstmt->stmt_location,
1128 : pstmt->stmt_len);
1129 :
1130 : /*
1131 : * EventTriggerCollectSimpleCommand called by
1132 : * CreateSchemaCommand
1133 : */
1134 635 : commandCollected = true;
1135 635 : break;
1136 :
1137 26141 : case T_CreateStmt:
1138 : case T_CreateForeignTableStmt:
1139 : {
1140 : List *stmts;
1141 26141 : RangeVar *table_rv = NULL;
1142 :
1143 : /* Run parse analysis ... */
1144 26141 : stmts = transformCreateStmt((CreateStmt *) parsetree,
1145 : queryString);
1146 :
1147 : /*
1148 : * ... and do it. We can't use foreach() because we may
1149 : * modify the list midway through, so pick off the
1150 : * elements one at a time, the hard way.
1151 : */
1152 58084 : while (stmts != NIL)
1153 : {
1154 33385 : Node *stmt = (Node *) linitial(stmts);
1155 :
1156 33385 : stmts = list_delete_first(stmts);
1157 :
1158 33385 : if (IsA(stmt, CreateStmt))
1159 : {
1160 25636 : CreateStmt *cstmt = (CreateStmt *) stmt;
1161 : Datum toast_options;
1162 25636 : const char *const validnsps[] = HEAP_RELOPT_NAMESPACES;
1163 :
1164 : /* Remember transformed RangeVar for LIKE */
1165 25636 : table_rv = cstmt->relation;
1166 :
1167 : /* Create the table itself */
1168 25636 : address = DefineRelation(cstmt,
1169 : RELKIND_RELATION,
1170 : InvalidOid, NULL,
1171 : queryString);
1172 24758 : EventTriggerCollectSimpleCommand(address,
1173 : secondaryObject,
1174 : stmt);
1175 :
1176 : /*
1177 : * Let NewRelationCreateToastTable decide if this
1178 : * one needs a secondary relation too.
1179 : */
1180 24758 : CommandCounterIncrement();
1181 :
1182 : /*
1183 : * parse and validate reloptions for the toast
1184 : * table
1185 : */
1186 24758 : toast_options = transformRelOptions((Datum) 0,
1187 : cstmt->options,
1188 : "toast",
1189 : validnsps,
1190 : true,
1191 : false);
1192 24758 : (void) heap_reloptions(RELKIND_TOASTVALUE,
1193 : toast_options,
1194 : true);
1195 :
1196 24754 : NewRelationCreateToastTable(address.objectId,
1197 : toast_options);
1198 : }
1199 7749 : else if (IsA(stmt, CreateForeignTableStmt))
1200 : {
1201 282 : CreateForeignTableStmt *cstmt = (CreateForeignTableStmt *) stmt;
1202 :
1203 : /* Remember transformed RangeVar for LIKE */
1204 282 : table_rv = cstmt->base.relation;
1205 :
1206 : /* Create the table itself */
1207 282 : address = DefineRelation(&cstmt->base,
1208 : RELKIND_FOREIGN_TABLE,
1209 : InvalidOid, NULL,
1210 : queryString);
1211 265 : CreateForeignTable(cstmt,
1212 : address.objectId);
1213 226 : EventTriggerCollectSimpleCommand(address,
1214 : secondaryObject,
1215 : stmt);
1216 : }
1217 7467 : else if (IsA(stmt, TableLikeClause))
1218 : {
1219 : /*
1220 : * Do delayed processing of LIKE options. This
1221 : * will result in additional sub-statements for us
1222 : * to process. Those should get done before any
1223 : * remaining actions, so prepend them to "stmts".
1224 : */
1225 129 : TableLikeClause *like = (TableLikeClause *) stmt;
1226 : List *morestmts;
1227 :
1228 : Assert(table_rv != NULL);
1229 :
1230 129 : morestmts = expandTableLikeClause(table_rv, like);
1231 129 : stmts = list_concat(morestmts, stmts);
1232 : }
1233 : else
1234 : {
1235 : /*
1236 : * Recurse for anything else. Note the recursive
1237 : * call will stash the objects so created into our
1238 : * event trigger context.
1239 : */
1240 : PlannedStmt *wrapper;
1241 :
1242 7338 : wrapper = makeNode(PlannedStmt);
1243 7338 : wrapper->commandType = CMD_UTILITY;
1244 7338 : wrapper->canSetTag = false;
1245 7338 : wrapper->utilityStmt = stmt;
1246 7338 : wrapper->stmt_location = pstmt->stmt_location;
1247 7338 : wrapper->stmt_len = pstmt->stmt_len;
1248 7338 : wrapper->planOrigin = PLAN_STMT_INTERNAL;
1249 :
1250 7338 : ProcessUtility(wrapper,
1251 : queryString,
1252 : false,
1253 : PROCESS_UTILITY_SUBCOMMAND,
1254 : params,
1255 : NULL,
1256 : None_Receiver,
1257 : NULL);
1258 : }
1259 :
1260 : /* Need CCI between commands */
1261 32157 : if (stmts != NIL)
1262 7463 : CommandCounterIncrement();
1263 : }
1264 :
1265 : /*
1266 : * The multiple commands generated here are stashed
1267 : * individually, so disable collection below.
1268 : */
1269 24699 : commandCollected = true;
1270 : }
1271 24699 : break;
1272 :
1273 21593 : case T_AlterTableStmt:
1274 : {
1275 21593 : AlterTableStmt *atstmt = (AlterTableStmt *) parsetree;
1276 : Oid relid;
1277 : LOCKMODE lockmode;
1278 : ListCell *cell;
1279 :
1280 : /*
1281 : * Disallow ALTER TABLE .. DETACH CONCURRENTLY in a
1282 : * transaction block or function. (Perhaps it could be
1283 : * allowed in a procedure, but don't hold your breath.)
1284 : */
1285 44043 : foreach(cell, atstmt->cmds)
1286 : {
1287 22454 : AlterTableCmd *cmd = (AlterTableCmd *) lfirst(cell);
1288 :
1289 : /* Disallow DETACH CONCURRENTLY in a transaction block */
1290 22454 : if (cmd->subtype == AT_DetachPartition)
1291 : {
1292 389 : if (((PartitionCmd *) cmd->def)->concurrent)
1293 91 : PreventInTransactionBlock(isTopLevel,
1294 : "ALTER TABLE ... DETACH CONCURRENTLY");
1295 : }
1296 : }
1297 :
1298 : /*
1299 : * Figure out lock mode, and acquire lock. This also does
1300 : * basic permissions checks, so that we won't wait for a
1301 : * lock on (for example) a relation on which we have no
1302 : * permissions.
1303 : */
1304 21589 : lockmode = AlterTableGetLockLevel(atstmt->cmds);
1305 21589 : relid = AlterTableLookupRelation(atstmt, lockmode);
1306 :
1307 21524 : if (OidIsValid(relid))
1308 : {
1309 : AlterTableUtilityContext atcontext;
1310 :
1311 : /* Set up info needed for recursive callbacks ... */
1312 21416 : atcontext.pstmt = pstmt;
1313 21416 : atcontext.queryString = queryString;
1314 21416 : atcontext.relid = relid;
1315 21416 : atcontext.params = params;
1316 21416 : atcontext.queryEnv = queryEnv;
1317 :
1318 : /* ... ensure we have an event trigger context ... */
1319 21416 : EventTriggerAlterTableStart(parsetree);
1320 21416 : EventTriggerAlterTableRelid(relid);
1321 :
1322 : /* ... and do it */
1323 21416 : AlterTable(atstmt, lockmode, &atcontext);
1324 :
1325 : /* done */
1326 18533 : EventTriggerAlterTableEnd();
1327 : }
1328 : else
1329 108 : ereport(NOTICE,
1330 : (errmsg("relation \"%s\" does not exist, skipping",
1331 : atstmt->relation->relname)));
1332 : }
1333 :
1334 : /* ALTER TABLE stashes commands internally */
1335 18641 : commandCollected = true;
1336 18641 : break;
1337 :
1338 192 : case T_AlterDomainStmt:
1339 : {
1340 192 : AlterDomainStmt *stmt = (AlterDomainStmt *) parsetree;
1341 :
1342 : /*
1343 : * Some or all of these functions are recursive to cover
1344 : * inherited things, so permission checks are done there.
1345 : */
1346 192 : switch (stmt->subtype)
1347 : {
1348 9 : case AD_AlterDefault:
1349 :
1350 : /*
1351 : * Recursively alter column default for table and,
1352 : * if requested, for descendants
1353 : */
1354 : address =
1355 9 : AlterDomainDefault(stmt->typeName,
1356 : stmt->def);
1357 9 : break;
1358 8 : case AD_DropNotNull:
1359 : address =
1360 8 : AlterDomainNotNull(stmt->typeName,
1361 : false);
1362 8 : break;
1363 16 : case AD_SetNotNull:
1364 : address =
1365 16 : AlterDomainNotNull(stmt->typeName,
1366 : true);
1367 8 : break;
1368 111 : case AD_AddConstraint:
1369 : address =
1370 111 : AlterDomainAddConstraint(stmt->typeName,
1371 : stmt->def,
1372 : &secondaryObject);
1373 63 : break;
1374 40 : case AD_DropConstraint:
1375 : address =
1376 40 : AlterDomainDropConstraint(stmt->typeName,
1377 40 : stmt->name,
1378 : stmt->behavior,
1379 40 : stmt->missing_ok);
1380 36 : break;
1381 8 : case AD_ValidateConstraint:
1382 : address =
1383 8 : AlterDomainValidateConstraint(stmt->typeName,
1384 8 : stmt->name);
1385 4 : break;
1386 0 : default: /* oops */
1387 0 : elog(ERROR, "unrecognized alter domain type: %d",
1388 : (int) stmt->subtype);
1389 : break;
1390 : }
1391 : }
1392 128 : break;
1393 :
1394 : /*
1395 : * ************* object creation / destruction **************
1396 : */
1397 5605 : case T_DefineStmt:
1398 : {
1399 5605 : DefineStmt *stmt = (DefineStmt *) parsetree;
1400 :
1401 5605 : switch (stmt->kind)
1402 : {
1403 581 : case OBJECT_AGGREGATE:
1404 : address =
1405 581 : DefineAggregate(pstate, stmt->defnames, stmt->args,
1406 581 : stmt->oldstyle,
1407 : stmt->definition,
1408 581 : stmt->replace);
1409 361 : break;
1410 885 : case OBJECT_OPERATOR:
1411 : Assert(stmt->args == NIL);
1412 885 : address = DefineOperator(stmt->defnames,
1413 : stmt->definition);
1414 820 : break;
1415 230 : case OBJECT_TYPE:
1416 : Assert(stmt->args == NIL);
1417 230 : address = DefineType(pstate,
1418 : stmt->defnames,
1419 : stmt->definition);
1420 206 : break;
1421 26 : case OBJECT_TSPARSER:
1422 : Assert(stmt->args == NIL);
1423 26 : address = DefineTSParser(stmt->defnames,
1424 : stmt->definition);
1425 22 : break;
1426 1798 : case OBJECT_TSDICTIONARY:
1427 : Assert(stmt->args == NIL);
1428 1798 : address = DefineTSDictionary(stmt->defnames,
1429 : stmt->definition);
1430 1782 : break;
1431 83 : case OBJECT_TSTEMPLATE:
1432 : Assert(stmt->args == NIL);
1433 83 : address = DefineTSTemplate(stmt->defnames,
1434 : stmt->definition);
1435 79 : break;
1436 1762 : case OBJECT_TSCONFIGURATION:
1437 : Assert(stmt->args == NIL);
1438 1762 : address = DefineTSConfiguration(stmt->defnames,
1439 : stmt->definition,
1440 : &secondaryObject);
1441 1762 : break;
1442 240 : case OBJECT_COLLATION:
1443 : Assert(stmt->args == NIL);
1444 240 : address = DefineCollation(pstate,
1445 : stmt->defnames,
1446 : stmt->definition,
1447 240 : stmt->if_not_exists);
1448 143 : break;
1449 0 : default:
1450 0 : elog(ERROR, "unrecognized define stmt type: %d",
1451 : (int) stmt->kind);
1452 : break;
1453 : }
1454 : }
1455 5175 : break;
1456 :
1457 9003 : case T_IndexStmt: /* CREATE INDEX */
1458 : {
1459 9003 : IndexStmt *stmt = (IndexStmt *) parsetree;
1460 : Oid relid;
1461 : LOCKMODE lockmode;
1462 9003 : int nparts = -1;
1463 : bool is_alter_table;
1464 :
1465 9003 : if (stmt->concurrent)
1466 146 : PreventInTransactionBlock(isTopLevel,
1467 : "CREATE INDEX CONCURRENTLY");
1468 :
1469 : /*
1470 : * Look up the relation OID just once, right here at the
1471 : * beginning, so that we don't end up repeating the name
1472 : * lookup later and latching onto a different relation
1473 : * partway through. To avoid lock upgrade hazards, it's
1474 : * important that we take the strongest lock that will
1475 : * eventually be needed here, so the lockmode calculation
1476 : * needs to match what DefineIndex() does.
1477 : */
1478 17990 : lockmode = stmt->concurrent ? ShareUpdateExclusiveLock
1479 8995 : : ShareLock;
1480 : relid =
1481 8995 : RangeVarGetRelidExtended(stmt->relation, lockmode,
1482 : 0,
1483 : RangeVarCallbackOwnsRelation,
1484 : NULL);
1485 :
1486 : /*
1487 : * CREATE INDEX on partitioned tables (but not regular
1488 : * inherited tables) recurses to partitions, so we must
1489 : * acquire locks early to avoid deadlocks.
1490 : *
1491 : * We also take the opportunity to verify that all
1492 : * partitions are something we can put an index on, to
1493 : * avoid building some indexes only to fail later. While
1494 : * at it, also count the partitions, so that DefineIndex
1495 : * needn't do a duplicative find_all_inheritors search.
1496 : */
1497 8994 : if (stmt->relation->inh &&
1498 8861 : get_rel_relkind(relid) == RELKIND_PARTITIONED_TABLE)
1499 : {
1500 : ListCell *lc;
1501 957 : List *inheritors = NIL;
1502 :
1503 957 : inheritors = find_all_inheritors(relid, lockmode, NULL);
1504 2533 : foreach(lc, inheritors)
1505 : {
1506 1584 : Oid partrelid = lfirst_oid(lc);
1507 1584 : char relkind = get_rel_relkind(partrelid);
1508 :
1509 1584 : if (relkind != RELKIND_RELATION &&
1510 1051 : relkind != RELKIND_MATVIEW &&
1511 12 : relkind != RELKIND_PARTITIONED_TABLE &&
1512 : relkind != RELKIND_FOREIGN_TABLE)
1513 0 : elog(ERROR, "unexpected relkind \"%c\" on partition \"%s\"",
1514 : relkind, stmt->relation->relname);
1515 :
1516 1584 : if (relkind == RELKIND_FOREIGN_TABLE &&
1517 12 : (stmt->unique || stmt->primary))
1518 8 : ereport(ERROR,
1519 : (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1520 : errmsg("cannot create unique index on partitioned table \"%s\"",
1521 : stmt->relation->relname),
1522 : errdetail("Table \"%s\" contains partitions that are foreign tables.",
1523 : stmt->relation->relname)));
1524 : }
1525 : /* count direct and indirect children, but not rel */
1526 949 : nparts = list_length(inheritors) - 1;
1527 949 : list_free(inheritors);
1528 : }
1529 :
1530 : /*
1531 : * If the IndexStmt is already transformed, it must have
1532 : * come from generateClonedIndexStmt, which in current
1533 : * usage means it came from expandTableLikeClause rather
1534 : * than from original parse analysis. And that means we
1535 : * must treat it like ALTER TABLE ADD INDEX, not CREATE.
1536 : * (This is a bit grotty, but currently it doesn't seem
1537 : * worth adding a separate bool field for the purpose.)
1538 : */
1539 8986 : is_alter_table = stmt->transformed;
1540 :
1541 : /* Run parse analysis ... */
1542 8986 : stmt = transformIndexStmt(relid, stmt, queryString);
1543 :
1544 : /* ... and do it */
1545 8962 : EventTriggerAlterTableStart(parsetree);
1546 : address =
1547 8962 : DefineIndex(pstate,
1548 : relid, /* OID of heap relation */
1549 : stmt,
1550 : InvalidOid, /* no predefined OID */
1551 : InvalidOid, /* no parent index */
1552 : InvalidOid, /* no parent constraint */
1553 : nparts, /* # of partitions, or -1 */
1554 : is_alter_table,
1555 : true, /* check_rights */
1556 : true, /* check_not_in_use */
1557 : false, /* skip_build */
1558 : false); /* quiet */
1559 :
1560 : /*
1561 : * Add the CREATE INDEX node itself to stash right away;
1562 : * if there were any commands stashed in the ALTER TABLE
1563 : * code, we need them to appear after this one.
1564 : */
1565 8509 : EventTriggerCollectSimpleCommand(address, secondaryObject,
1566 : parsetree);
1567 8509 : commandCollected = true;
1568 8509 : EventTriggerAlterTableEnd();
1569 : }
1570 8509 : break;
1571 :
1572 697 : case T_ReindexStmt:
1573 697 : ExecReindex(pstate, (ReindexStmt *) parsetree, isTopLevel);
1574 :
1575 : /* EventTriggerCollectSimpleCommand is called directly */
1576 487 : commandCollected = true;
1577 487 : break;
1578 :
1579 311 : case T_CreateExtensionStmt:
1580 311 : address = CreateExtension(pstate, (CreateExtensionStmt *) parsetree);
1581 288 : break;
1582 :
1583 19 : case T_AlterExtensionStmt:
1584 19 : address = ExecAlterExtensionStmt(pstate, (AlterExtensionStmt *) parsetree);
1585 17 : break;
1586 :
1587 140 : case T_AlterExtensionContentsStmt:
1588 140 : address = ExecAlterExtensionContentsStmt((AlterExtensionContentsStmt *) parsetree,
1589 : &secondaryObject);
1590 139 : break;
1591 :
1592 133 : case T_CreateFdwStmt:
1593 133 : address = CreateForeignDataWrapper(pstate, (CreateFdwStmt *) parsetree);
1594 100 : break;
1595 :
1596 100 : case T_AlterFdwStmt:
1597 100 : address = AlterForeignDataWrapper(pstate, (AlterFdwStmt *) parsetree);
1598 52 : break;
1599 :
1600 188 : case T_CreateForeignServerStmt:
1601 188 : address = CreateForeignServer((CreateForeignServerStmt *) parsetree);
1602 156 : break;
1603 :
1604 129 : case T_AlterForeignServerStmt:
1605 129 : address = AlterForeignServer((AlterForeignServerStmt *) parsetree);
1606 96 : break;
1607 :
1608 162 : case T_CreateUserMappingStmt:
1609 162 : address = CreateUserMapping((CreateUserMappingStmt *) parsetree);
1610 119 : break;
1611 :
1612 70 : case T_AlterUserMappingStmt:
1613 70 : address = AlterUserMapping((AlterUserMappingStmt *) parsetree);
1614 33 : break;
1615 :
1616 79 : case T_DropUserMappingStmt:
1617 79 : RemoveUserMapping((DropUserMappingStmt *) parsetree);
1618 : /* no commands stashed for DROP */
1619 54 : commandCollected = true;
1620 54 : break;
1621 :
1622 28 : case T_ImportForeignSchemaStmt:
1623 28 : ImportForeignSchema((ImportForeignSchemaStmt *) parsetree);
1624 : /* commands are stashed inside ImportForeignSchema */
1625 7 : commandCollected = true;
1626 7 : break;
1627 :
1628 2358 : case T_CompositeTypeStmt: /* CREATE TYPE (composite) */
1629 : {
1630 2358 : CompositeTypeStmt *stmt = (CompositeTypeStmt *) parsetree;
1631 :
1632 2358 : address = DefineCompositeType(stmt->typevar,
1633 : stmt->coldeflist);
1634 : }
1635 2350 : break;
1636 :
1637 246 : case T_CreateEnumStmt: /* CREATE TYPE AS ENUM */
1638 246 : address = DefineEnum((CreateEnumStmt *) parsetree);
1639 241 : break;
1640 :
1641 131 : case T_CreateRangeStmt: /* CREATE TYPE AS RANGE */
1642 131 : address = DefineRange(pstate, (CreateRangeStmt *) parsetree);
1643 115 : break;
1644 :
1645 246 : case T_AlterEnumStmt: /* ALTER TYPE (enum) */
1646 246 : address = AlterEnum((AlterEnumStmt *) parsetree);
1647 226 : break;
1648 :
1649 10850 : case T_ViewStmt: /* CREATE VIEW */
1650 10850 : EventTriggerAlterTableStart(parsetree);
1651 10850 : address = DefineView((ViewStmt *) parsetree, queryString,
1652 : pstmt->stmt_location, pstmt->stmt_len);
1653 10793 : EventTriggerCollectSimpleCommand(address, secondaryObject,
1654 : parsetree);
1655 : /* stashed internally */
1656 10793 : commandCollected = true;
1657 10793 : EventTriggerAlterTableEnd();
1658 10793 : break;
1659 :
1660 12785 : case T_CreateFunctionStmt: /* CREATE FUNCTION */
1661 12785 : address = CreateFunction(pstate, (CreateFunctionStmt *) parsetree);
1662 12461 : break;
1663 :
1664 208 : case T_AlterFunctionStmt: /* ALTER FUNCTION */
1665 208 : address = AlterFunction(pstate, (AlterFunctionStmt *) parsetree);
1666 188 : break;
1667 :
1668 702 : case T_RuleStmt: /* CREATE RULE */
1669 702 : address = DefineRule((RuleStmt *) parsetree, queryString);
1670 673 : break;
1671 :
1672 1277 : case T_CreateSeqStmt:
1673 1277 : address = DefineSequence(pstate, (CreateSeqStmt *) parsetree);
1674 1212 : break;
1675 :
1676 996 : case T_AlterSeqStmt:
1677 996 : address = AlterSequence(pstate, (AlterSeqStmt *) parsetree);
1678 964 : break;
1679 :
1680 1155 : case T_CreateTableAsStmt:
1681 1155 : address = ExecCreateTableAs(pstate, (CreateTableAsStmt *) parsetree,
1682 : params, queryEnv, qc);
1683 1085 : break;
1684 :
1685 174 : case T_RefreshMatViewStmt:
1686 :
1687 : /*
1688 : * REFRESH CONCURRENTLY executes some DDL commands internally.
1689 : * Inhibit DDL command collection here to avoid those commands
1690 : * from showing up in the deparsed command queue. The refresh
1691 : * command itself is queued, which is enough.
1692 : */
1693 174 : EventTriggerInhibitCommandCollection();
1694 174 : PG_TRY(2);
1695 : {
1696 174 : address = ExecRefreshMatView((RefreshMatViewStmt *) parsetree,
1697 : queryString, qc);
1698 : }
1699 48 : PG_FINALLY(2);
1700 : {
1701 174 : EventTriggerUndoInhibitCommandCollection();
1702 : }
1703 174 : PG_END_TRY(2);
1704 126 : break;
1705 :
1706 2120 : case T_CreateTrigStmt:
1707 2120 : address = CreateTrigger((CreateTrigStmt *) parsetree,
1708 : queryString, InvalidOid, InvalidOid,
1709 : InvalidOid, InvalidOid, InvalidOid,
1710 : InvalidOid, NULL, false, false);
1711 1971 : break;
1712 :
1713 80 : case T_CreatePLangStmt:
1714 80 : address = CreateProceduralLanguage((CreatePLangStmt *) parsetree);
1715 80 : break;
1716 :
1717 978 : case T_CreateDomainStmt:
1718 978 : address = DefineDomain(pstate, (CreateDomainStmt *) parsetree);
1719 902 : break;
1720 :
1721 42 : case T_CreateConversionStmt:
1722 42 : address = CreateConversionCommand((CreateConversionStmt *) parsetree);
1723 34 : break;
1724 :
1725 162 : case T_CreateCastStmt:
1726 162 : address = CreateCast((CreateCastStmt *) parsetree);
1727 158 : break;
1728 :
1729 295 : case T_CreateOpClassStmt:
1730 295 : DefineOpClass((CreateOpClassStmt *) parsetree);
1731 : /* command is stashed in DefineOpClass */
1732 295 : commandCollected = true;
1733 295 : break;
1734 :
1735 95 : case T_CreateOpFamilyStmt:
1736 95 : address = DefineOpFamily((CreateOpFamilyStmt *) parsetree);
1737 :
1738 : /*
1739 : * DefineOpFamily calls EventTriggerCollectSimpleCommand
1740 : * directly.
1741 : */
1742 95 : commandCollected = true;
1743 95 : break;
1744 :
1745 201 : case T_CreatePropGraphStmt:
1746 201 : address = CreatePropGraph(pstate, (CreatePropGraphStmt *) parsetree);
1747 129 : break;
1748 :
1749 124 : case T_AlterPropGraphStmt:
1750 124 : address = AlterPropGraph(pstate, (AlterPropGraphStmt *) parsetree);
1751 76 : break;
1752 :
1753 26 : case T_CreateTransformStmt:
1754 26 : address = CreateTransform((CreateTransformStmt *) parsetree);
1755 21 : break;
1756 :
1757 276 : case T_AlterOpFamilyStmt:
1758 276 : AlterOpFamily((AlterOpFamilyStmt *) parsetree);
1759 : /* commands are stashed in AlterOpFamily */
1760 168 : commandCollected = true;
1761 168 : break;
1762 :
1763 23 : case T_AlterTSDictionaryStmt:
1764 23 : address = AlterTSDictionary((AlterTSDictionaryStmt *) parsetree);
1765 18 : break;
1766 :
1767 5250 : case T_AlterTSConfigurationStmt:
1768 5250 : AlterTSConfiguration((AlterTSConfigurationStmt *) parsetree);
1769 :
1770 : /*
1771 : * Commands are stashed in MakeConfigurationMapping and
1772 : * DropConfigurationMapping, which are called from
1773 : * AlterTSConfiguration
1774 : */
1775 5234 : commandCollected = true;
1776 5234 : break;
1777 :
1778 20 : case T_AlterTableMoveAllStmt:
1779 20 : AlterTableMoveAll((AlterTableMoveAllStmt *) parsetree);
1780 : /* commands are stashed in AlterTableMoveAll */
1781 20 : commandCollected = true;
1782 20 : break;
1783 :
1784 17165 : case T_DropStmt:
1785 17165 : ExecDropStmt((DropStmt *) parsetree, isTopLevel);
1786 : /* no commands stashed for DROP */
1787 16497 : commandCollected = true;
1788 16497 : break;
1789 :
1790 967 : case T_RenameStmt:
1791 967 : address = ExecRenameStmt((RenameStmt *) parsetree);
1792 703 : break;
1793 :
1794 23 : case T_AlterObjectDependsStmt:
1795 : address =
1796 23 : ExecAlterObjectDependsStmt((AlterObjectDependsStmt *) parsetree,
1797 : &secondaryObject);
1798 23 : break;
1799 :
1800 281 : case T_AlterObjectSchemaStmt:
1801 : address =
1802 281 : ExecAlterObjectSchemaStmt((AlterObjectSchemaStmt *) parsetree,
1803 : &secondaryObject);
1804 186 : break;
1805 :
1806 932 : case T_AlterOwnerStmt:
1807 932 : address = ExecAlterOwnerStmt((AlterOwnerStmt *) parsetree);
1808 756 : break;
1809 :
1810 332 : case T_AlterOperatorStmt:
1811 332 : address = AlterOperator((AlterOperatorStmt *) parsetree);
1812 288 : break;
1813 :
1814 36 : case T_AlterTypeStmt:
1815 36 : address = AlterType((AlterTypeStmt *) parsetree);
1816 28 : break;
1817 :
1818 4293 : case T_CommentStmt:
1819 4293 : address = CommentObject((CommentStmt *) parsetree);
1820 4188 : break;
1821 :
1822 12327 : case T_GrantStmt:
1823 12327 : ExecuteGrantStmt((GrantStmt *) parsetree);
1824 : /* commands are stashed in ExecGrantStmt_oids */
1825 12232 : commandCollected = true;
1826 12232 : break;
1827 :
1828 94 : case T_DropOwnedStmt:
1829 94 : DropOwnedObjects((DropOwnedStmt *) parsetree);
1830 : /* no commands stashed for DROP */
1831 82 : commandCollected = true;
1832 82 : break;
1833 :
1834 135 : case T_AlterDefaultPrivilegesStmt:
1835 135 : ExecAlterDefaultPrivilegesStmt(pstate, (AlterDefaultPrivilegesStmt *) parsetree);
1836 127 : EventTriggerCollectAlterDefPrivs((AlterDefaultPrivilegesStmt *) parsetree);
1837 127 : commandCollected = true;
1838 127 : break;
1839 :
1840 567 : case T_CreatePolicyStmt: /* CREATE POLICY */
1841 567 : address = CreatePolicy((CreatePolicyStmt *) parsetree);
1842 558 : break;
1843 :
1844 56 : case T_AlterPolicyStmt: /* ALTER POLICY */
1845 56 : address = AlterPolicy((AlterPolicyStmt *) parsetree);
1846 48 : break;
1847 :
1848 44 : case T_SecLabelStmt:
1849 44 : address = ExecSecLabelStmt((SecLabelStmt *) parsetree);
1850 21 : break;
1851 :
1852 46 : case T_CreateAmStmt:
1853 46 : address = CreateAccessMethod((CreateAmStmt *) parsetree);
1854 30 : break;
1855 :
1856 630 : case T_CreatePublicationStmt:
1857 630 : address = CreatePublication(pstate, (CreatePublicationStmt *) parsetree);
1858 517 : break;
1859 :
1860 781 : case T_AlterPublicationStmt:
1861 781 : AlterPublication(pstate, (AlterPublicationStmt *) parsetree);
1862 :
1863 : /*
1864 : * AlterPublication calls EventTriggerCollectSimpleCommand
1865 : * directly
1866 : */
1867 597 : commandCollected = true;
1868 597 : break;
1869 :
1870 304 : case T_CreateSubscriptionStmt:
1871 304 : address = CreateSubscription(pstate,
1872 : (CreateSubscriptionStmt *) parsetree,
1873 : isTopLevel);
1874 190 : break;
1875 :
1876 335 : case T_AlterSubscriptionStmt:
1877 335 : address = AlterSubscription(pstate,
1878 : (AlterSubscriptionStmt *) parsetree,
1879 : isTopLevel);
1880 256 : break;
1881 :
1882 155 : case T_DropSubscriptionStmt:
1883 155 : DropSubscription((DropSubscriptionStmt *) parsetree, isTopLevel);
1884 : /* no commands stashed for DROP */
1885 142 : commandCollected = true;
1886 142 : break;
1887 :
1888 627 : case T_CreateStatsStmt:
1889 : {
1890 : Oid relid;
1891 627 : CreateStatsStmt *stmt = (CreateStatsStmt *) parsetree;
1892 627 : RangeVar *rel = (RangeVar *) linitial(stmt->relations);
1893 :
1894 627 : if (!IsA(rel, RangeVar))
1895 28 : ereport(ERROR,
1896 : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1897 : errmsg("CREATE STATISTICS only supports relation names in the FROM clause")));
1898 :
1899 : /*
1900 : * CREATE STATISTICS will influence future execution plans
1901 : * but does not interfere with currently executing plans.
1902 : * So it should be enough to take ShareUpdateExclusiveLock
1903 : * on relation, conflicting with ANALYZE and other DDL
1904 : * that sets statistical information, but not with normal
1905 : * queries.
1906 : *
1907 : * XXX RangeVarCallbackOwnsRelation not needed here, to
1908 : * keep the same behavior as before.
1909 : */
1910 599 : relid = RangeVarGetRelid(rel, ShareUpdateExclusiveLock, false);
1911 :
1912 : /* Run parse analysis ... */
1913 595 : stmt = transformStatsStmt(relid, stmt, queryString);
1914 :
1915 595 : address = CreateStatistics(stmt, true);
1916 : }
1917 503 : break;
1918 :
1919 17 : case T_AlterStatsStmt:
1920 17 : address = AlterStatistics((AlterStatsStmt *) parsetree);
1921 13 : break;
1922 :
1923 4 : case T_AlterCollationStmt:
1924 4 : address = AlterCollation((AlterCollationStmt *) parsetree);
1925 4 : break;
1926 :
1927 0 : default:
1928 0 : elog(ERROR, "unrecognized node type: %d",
1929 : (int) nodeTag(parsetree));
1930 : break;
1931 : }
1932 :
1933 : /*
1934 : * Remember the object so that ddl_command_end event triggers have
1935 : * access to it.
1936 : */
1937 136959 : if (!commandCollected)
1938 37645 : EventTriggerCollectSimpleCommand(address, secondaryObject,
1939 : parsetree);
1940 :
1941 136959 : if (isCompleteQuery)
1942 : {
1943 129198 : EventTriggerSQLDrop(parsetree);
1944 129186 : EventTriggerDDLCommandEnd(parsetree);
1945 : }
1946 : }
1947 9333 : PG_FINALLY();
1948 : {
1949 146280 : if (needCleanup)
1950 2004 : EventTriggerEndCompleteQuery();
1951 : }
1952 146280 : PG_END_TRY();
1953 136947 : }
1954 :
1955 : /*
1956 : * ProcessUtilityForAlterTable
1957 : * Recursive entry from ALTER TABLE
1958 : *
1959 : * ALTER TABLE sometimes generates subcommands such as CREATE INDEX.
1960 : * It calls this, not the main entry point ProcessUtility, to execute
1961 : * such subcommands.
1962 : *
1963 : * stmt: the utility command to execute
1964 : * context: opaque passthrough struct with the info we need
1965 : *
1966 : * It's caller's responsibility to do CommandCounterIncrement after
1967 : * calling this, if needed.
1968 : */
1969 : void
1970 371 : ProcessUtilityForAlterTable(Node *stmt, AlterTableUtilityContext *context)
1971 : {
1972 : PlannedStmt *wrapper;
1973 :
1974 : /*
1975 : * For event triggers, we must "close" the current complex-command set,
1976 : * and start a new one afterwards; this is needed to ensure the ordering
1977 : * of command events is consistent with the way they were executed.
1978 : */
1979 371 : EventTriggerAlterTableEnd();
1980 :
1981 : /* Create a suitable wrapper */
1982 371 : wrapper = makeNode(PlannedStmt);
1983 371 : wrapper->commandType = CMD_UTILITY;
1984 371 : wrapper->canSetTag = false;
1985 371 : wrapper->utilityStmt = stmt;
1986 371 : wrapper->stmt_location = context->pstmt->stmt_location;
1987 371 : wrapper->stmt_len = context->pstmt->stmt_len;
1988 371 : wrapper->planOrigin = PLAN_STMT_INTERNAL;
1989 :
1990 371 : ProcessUtility(wrapper,
1991 : context->queryString,
1992 : false,
1993 : PROCESS_UTILITY_SUBCOMMAND,
1994 : context->params,
1995 : context->queryEnv,
1996 : None_Receiver,
1997 : NULL);
1998 :
1999 363 : EventTriggerAlterTableStart(context->pstmt->utilityStmt);
2000 363 : EventTriggerAlterTableRelid(context->relid);
2001 363 : }
2002 :
2003 : /*
2004 : * Dispatch function for DropStmt
2005 : */
2006 : static void
2007 17245 : ExecDropStmt(DropStmt *stmt, bool isTopLevel)
2008 : {
2009 17245 : switch (stmt->removeType)
2010 : {
2011 559 : case OBJECT_INDEX:
2012 559 : if (stmt->concurrent)
2013 109 : PreventInTransactionBlock(isTopLevel,
2014 : "DROP INDEX CONCURRENTLY");
2015 : pg_fallthrough;
2016 :
2017 : case OBJECT_TABLE:
2018 : case OBJECT_SEQUENCE:
2019 : case OBJECT_VIEW:
2020 : case OBJECT_MATVIEW:
2021 : case OBJECT_FOREIGN_TABLE:
2022 : case OBJECT_PROPGRAPH:
2023 11401 : RemoveRelations(stmt);
2024 11184 : break;
2025 5840 : default:
2026 5840 : RemoveObjects(stmt);
2027 5389 : break;
2028 : }
2029 16573 : }
2030 :
2031 :
2032 : /*
2033 : * UtilityReturnsTuples
2034 : * Return "true" if this utility statement will send output to the
2035 : * destination.
2036 : *
2037 : * Generally, there should be a case here for each case in ProcessUtility
2038 : * where "dest" is passed on.
2039 : */
2040 : bool
2041 241929 : UtilityReturnsTuples(Node *parsetree)
2042 : {
2043 241929 : switch (nodeTag(parsetree))
2044 : {
2045 277 : case T_CallStmt:
2046 : {
2047 277 : CallStmt *stmt = (CallStmt *) parsetree;
2048 :
2049 277 : return (stmt->funcexpr->funcresulttype == RECORDOID);
2050 : }
2051 4418 : case T_FetchStmt:
2052 : {
2053 4418 : FetchStmt *stmt = (FetchStmt *) parsetree;
2054 : Portal portal;
2055 :
2056 4418 : if (stmt->ismove)
2057 42 : return false;
2058 4376 : portal = GetPortalByName(stmt->portalname);
2059 4376 : if (!PortalIsValid(portal))
2060 19 : return false; /* not our business to raise error */
2061 4357 : return portal->tupDesc ? true : false;
2062 : }
2063 :
2064 8657 : case T_ExecuteStmt:
2065 : {
2066 8657 : ExecuteStmt *stmt = (ExecuteStmt *) parsetree;
2067 : PreparedStatement *entry;
2068 :
2069 8657 : entry = FetchPreparedStatement(stmt->name, false);
2070 8657 : if (!entry)
2071 0 : return false; /* not our business to raise error */
2072 8657 : if (entry->plansource->resultDesc)
2073 8586 : return true;
2074 71 : return false;
2075 : }
2076 :
2077 21774 : case T_ExplainStmt:
2078 21774 : return true;
2079 :
2080 588 : case T_VariableShowStmt:
2081 588 : return true;
2082 :
2083 55 : case T_WaitStmt:
2084 55 : return true;
2085 :
2086 206160 : default:
2087 206160 : return false;
2088 : }
2089 : }
2090 :
2091 : /*
2092 : * UtilityTupleDescriptor
2093 : * Fetch the actual output tuple descriptor for a utility statement
2094 : * for which UtilityReturnsTuples() previously returned "true".
2095 : *
2096 : * The returned descriptor is created in (or copied into) the current memory
2097 : * context.
2098 : */
2099 : TupleDesc
2100 35474 : UtilityTupleDescriptor(Node *parsetree)
2101 : {
2102 35474 : switch (nodeTag(parsetree))
2103 : {
2104 114 : case T_CallStmt:
2105 114 : return CallStmtResultDesc((CallStmt *) parsetree);
2106 :
2107 4357 : case T_FetchStmt:
2108 : {
2109 4357 : FetchStmt *stmt = (FetchStmt *) parsetree;
2110 : Portal portal;
2111 :
2112 4357 : if (stmt->ismove)
2113 0 : return NULL;
2114 4357 : portal = GetPortalByName(stmt->portalname);
2115 4357 : if (!PortalIsValid(portal))
2116 0 : return NULL; /* not our business to raise error */
2117 4357 : return CreateTupleDescCopy(portal->tupDesc);
2118 : }
2119 :
2120 8586 : case T_ExecuteStmt:
2121 : {
2122 8586 : ExecuteStmt *stmt = (ExecuteStmt *) parsetree;
2123 : PreparedStatement *entry;
2124 :
2125 8586 : entry = FetchPreparedStatement(stmt->name, false);
2126 8586 : if (!entry)
2127 0 : return NULL; /* not our business to raise error */
2128 8586 : return FetchPreparedStatementResultDesc(entry);
2129 : }
2130 :
2131 21774 : case T_ExplainStmt:
2132 21774 : return ExplainResultDesc((ExplainStmt *) parsetree);
2133 :
2134 588 : case T_VariableShowStmt:
2135 : {
2136 588 : VariableShowStmt *n = (VariableShowStmt *) parsetree;
2137 :
2138 588 : return GetPGVariableResultDesc(n->name);
2139 : }
2140 :
2141 55 : case T_WaitStmt:
2142 55 : return WaitStmtResultDesc((WaitStmt *) parsetree);
2143 :
2144 0 : default:
2145 0 : return NULL;
2146 : }
2147 : }
2148 :
2149 :
2150 : /*
2151 : * QueryReturnsTuples
2152 : * Return "true" if this Query will send output to the destination.
2153 : */
2154 : #ifdef NOT_USED
2155 : bool
2156 : QueryReturnsTuples(Query *parsetree)
2157 : {
2158 : switch (parsetree->commandType)
2159 : {
2160 : case CMD_SELECT:
2161 : /* returns tuples */
2162 : return true;
2163 : case CMD_INSERT:
2164 : case CMD_UPDATE:
2165 : case CMD_DELETE:
2166 : case CMD_MERGE:
2167 : /* the forms with RETURNING return tuples */
2168 : if (parsetree->returningList)
2169 : return true;
2170 : break;
2171 : case CMD_UTILITY:
2172 : return UtilityReturnsTuples(parsetree->utilityStmt);
2173 : case CMD_UNKNOWN:
2174 : case CMD_NOTHING:
2175 : /* probably shouldn't get here */
2176 : break;
2177 : }
2178 : return false; /* default */
2179 : }
2180 : #endif
2181 :
2182 :
2183 : /*
2184 : * UtilityContainsQuery
2185 : * Return the contained Query, or NULL if there is none
2186 : *
2187 : * Certain utility statements, such as EXPLAIN, contain a plannable Query.
2188 : * This function encapsulates knowledge of exactly which ones do.
2189 : * We assume it is invoked only on already-parse-analyzed statements
2190 : * (else the contained parsetree isn't a Query yet).
2191 : *
2192 : * In some cases (currently, only EXPLAIN of CREATE TABLE AS/SELECT INTO and
2193 : * CREATE MATERIALIZED VIEW), potentially Query-containing utility statements
2194 : * can be nested. This function will drill down to a non-utility Query, or
2195 : * return NULL if none.
2196 : */
2197 : Query *
2198 25049 : UtilityContainsQuery(Node *parsetree)
2199 : {
2200 : Query *qry;
2201 :
2202 25049 : switch (nodeTag(parsetree))
2203 : {
2204 1764 : case T_DeclareCursorStmt:
2205 1764 : qry = castNode(Query, ((DeclareCursorStmt *) parsetree)->query);
2206 1764 : if (qry->commandType == CMD_UTILITY)
2207 0 : return UtilityContainsQuery(qry->utilityStmt);
2208 1764 : return qry;
2209 :
2210 10882 : case T_ExplainStmt:
2211 10882 : qry = castNode(Query, ((ExplainStmt *) parsetree)->query);
2212 10882 : if (qry->commandType == CMD_UTILITY)
2213 72 : return UtilityContainsQuery(qry->utilityStmt);
2214 10810 : return qry;
2215 :
2216 59 : case T_CreateTableAsStmt:
2217 59 : qry = castNode(Query, ((CreateTableAsStmt *) parsetree)->query);
2218 59 : if (qry->commandType == CMD_UTILITY)
2219 0 : return UtilityContainsQuery(qry->utilityStmt);
2220 59 : return qry;
2221 :
2222 12344 : default:
2223 12344 : return NULL;
2224 : }
2225 : }
2226 :
2227 :
2228 : /*
2229 : * AlterObjectTypeCommandTag
2230 : * helper function for CreateCommandTag
2231 : *
2232 : * This covers most cases where ALTER is used with an ObjectType enum.
2233 : */
2234 : static CommandTag
2235 23054 : AlterObjectTypeCommandTag(ObjectType objtype)
2236 : {
2237 : CommandTag tag;
2238 :
2239 23054 : switch (objtype)
2240 : {
2241 120 : case OBJECT_AGGREGATE:
2242 120 : tag = CMDTAG_ALTER_AGGREGATE;
2243 120 : break;
2244 16 : case OBJECT_ATTRIBUTE:
2245 16 : tag = CMDTAG_ALTER_TYPE;
2246 16 : break;
2247 0 : case OBJECT_CAST:
2248 0 : tag = CMDTAG_ALTER_CAST;
2249 0 : break;
2250 27 : case OBJECT_COLLATION:
2251 27 : tag = CMDTAG_ALTER_COLLATION;
2252 27 : break;
2253 0 : case OBJECT_COLUMN:
2254 0 : tag = CMDTAG_ALTER_TABLE;
2255 0 : break;
2256 48 : case OBJECT_CONVERSION:
2257 48 : tag = CMDTAG_ALTER_CONVERSION;
2258 48 : break;
2259 58 : case OBJECT_DATABASE:
2260 58 : tag = CMDTAG_ALTER_DATABASE;
2261 58 : break;
2262 38 : case OBJECT_DOMAIN:
2263 : case OBJECT_DOMCONSTRAINT:
2264 38 : tag = CMDTAG_ALTER_DOMAIN;
2265 38 : break;
2266 6 : case OBJECT_EXTENSION:
2267 6 : tag = CMDTAG_ALTER_EXTENSION;
2268 6 : break;
2269 29 : case OBJECT_FDW:
2270 29 : tag = CMDTAG_ALTER_FOREIGN_DATA_WRAPPER;
2271 29 : break;
2272 61 : case OBJECT_FOREIGN_SERVER:
2273 61 : tag = CMDTAG_ALTER_SERVER;
2274 61 : break;
2275 359 : case OBJECT_FOREIGN_TABLE:
2276 359 : tag = CMDTAG_ALTER_FOREIGN_TABLE;
2277 359 : break;
2278 372 : case OBJECT_FUNCTION:
2279 372 : tag = CMDTAG_ALTER_FUNCTION;
2280 372 : break;
2281 525 : case OBJECT_INDEX:
2282 525 : tag = CMDTAG_ALTER_INDEX;
2283 525 : break;
2284 32 : case OBJECT_LANGUAGE:
2285 32 : tag = CMDTAG_ALTER_LANGUAGE;
2286 32 : break;
2287 9 : case OBJECT_LARGEOBJECT:
2288 9 : tag = CMDTAG_ALTER_LARGE_OBJECT;
2289 9 : break;
2290 67 : case OBJECT_OPCLASS:
2291 67 : tag = CMDTAG_ALTER_OPERATOR_CLASS;
2292 67 : break;
2293 39 : case OBJECT_OPERATOR:
2294 39 : tag = CMDTAG_ALTER_OPERATOR;
2295 39 : break;
2296 71 : case OBJECT_OPFAMILY:
2297 71 : tag = CMDTAG_ALTER_OPERATOR_FAMILY;
2298 71 : break;
2299 20 : case OBJECT_POLICY:
2300 20 : tag = CMDTAG_ALTER_POLICY;
2301 20 : break;
2302 12 : case OBJECT_PROCEDURE:
2303 12 : tag = CMDTAG_ALTER_PROCEDURE;
2304 12 : break;
2305 77 : case OBJECT_PROPGRAPH:
2306 77 : tag = CMDTAG_ALTER_PROPERTY_GRAPH;
2307 77 : break;
2308 20 : case OBJECT_ROLE:
2309 20 : tag = CMDTAG_ALTER_ROLE;
2310 20 : break;
2311 16 : case OBJECT_ROUTINE:
2312 16 : tag = CMDTAG_ALTER_ROUTINE;
2313 16 : break;
2314 22 : case OBJECT_RULE:
2315 22 : tag = CMDTAG_ALTER_RULE;
2316 22 : break;
2317 54 : case OBJECT_SCHEMA:
2318 54 : tag = CMDTAG_ALTER_SCHEMA;
2319 54 : break;
2320 63 : case OBJECT_SEQUENCE:
2321 63 : tag = CMDTAG_ALTER_SEQUENCE;
2322 63 : break;
2323 20108 : case OBJECT_TABLE:
2324 : case OBJECT_TABCONSTRAINT:
2325 20108 : tag = CMDTAG_ALTER_TABLE;
2326 20108 : break;
2327 12 : case OBJECT_TABLESPACE:
2328 12 : tag = CMDTAG_ALTER_TABLESPACE;
2329 12 : break;
2330 31 : case OBJECT_TRIGGER:
2331 31 : tag = CMDTAG_ALTER_TRIGGER;
2332 31 : break;
2333 17 : case OBJECT_EVENT_TRIGGER:
2334 17 : tag = CMDTAG_ALTER_EVENT_TRIGGER;
2335 17 : break;
2336 52 : case OBJECT_TSCONFIGURATION:
2337 52 : tag = CMDTAG_ALTER_TEXT_SEARCH_CONFIGURATION;
2338 52 : break;
2339 57 : case OBJECT_TSDICTIONARY:
2340 57 : tag = CMDTAG_ALTER_TEXT_SEARCH_DICTIONARY;
2341 57 : break;
2342 20 : case OBJECT_TSPARSER:
2343 20 : tag = CMDTAG_ALTER_TEXT_SEARCH_PARSER;
2344 20 : break;
2345 20 : case OBJECT_TSTEMPLATE:
2346 20 : tag = CMDTAG_ALTER_TEXT_SEARCH_TEMPLATE;
2347 20 : break;
2348 217 : case OBJECT_TYPE:
2349 217 : tag = CMDTAG_ALTER_TYPE;
2350 217 : break;
2351 171 : case OBJECT_VIEW:
2352 171 : tag = CMDTAG_ALTER_VIEW;
2353 171 : break;
2354 50 : case OBJECT_MATVIEW:
2355 50 : tag = CMDTAG_ALTER_MATERIALIZED_VIEW;
2356 50 : break;
2357 50 : case OBJECT_PUBLICATION:
2358 50 : tag = CMDTAG_ALTER_PUBLICATION;
2359 50 : break;
2360 36 : case OBJECT_SUBSCRIPTION:
2361 36 : tag = CMDTAG_ALTER_SUBSCRIPTION;
2362 36 : break;
2363 52 : case OBJECT_STATISTIC_EXT:
2364 52 : tag = CMDTAG_ALTER_STATISTICS;
2365 52 : break;
2366 0 : default:
2367 0 : tag = CMDTAG_UNKNOWN;
2368 0 : break;
2369 : }
2370 :
2371 23054 : return tag;
2372 : }
2373 :
2374 : /*
2375 : * CreateCommandTag
2376 : * utility to get a CommandTag for the command operation,
2377 : * given either a raw (un-analyzed) parsetree, an analyzed Query,
2378 : * or a PlannedStmt.
2379 : *
2380 : * This must handle all command types, but since the vast majority
2381 : * of 'em are utility commands, it seems sensible to keep it here.
2382 : */
2383 : CommandTag
2384 509387 : CreateCommandTag(Node *parsetree)
2385 : {
2386 : CommandTag tag;
2387 :
2388 509387 : switch (nodeTag(parsetree))
2389 : {
2390 : /* recurse if we're given a RawStmt */
2391 0 : case T_RawStmt:
2392 0 : tag = CreateCommandTag(((RawStmt *) parsetree)->stmt);
2393 0 : break;
2394 :
2395 : /* raw plannable queries */
2396 44011 : case T_InsertStmt:
2397 44011 : tag = CMDTAG_INSERT;
2398 44011 : break;
2399 :
2400 2890 : case T_DeleteStmt:
2401 2890 : tag = CMDTAG_DELETE;
2402 2890 : break;
2403 :
2404 8490 : case T_UpdateStmt:
2405 8490 : tag = CMDTAG_UPDATE;
2406 8490 : break;
2407 :
2408 1202 : case T_MergeStmt:
2409 1202 : tag = CMDTAG_MERGE;
2410 1202 : break;
2411 :
2412 204378 : case T_SelectStmt:
2413 204378 : tag = CMDTAG_SELECT;
2414 204378 : break;
2415 :
2416 2298 : case T_PLAssignStmt:
2417 2298 : tag = CMDTAG_SELECT;
2418 2298 : break;
2419 :
2420 : /* utility statements --- same whether raw or cooked */
2421 26634 : case T_TransactionStmt:
2422 : {
2423 26634 : TransactionStmt *stmt = (TransactionStmt *) parsetree;
2424 :
2425 26634 : switch (stmt->kind)
2426 : {
2427 11491 : case TRANS_STMT_BEGIN:
2428 11491 : tag = CMDTAG_BEGIN;
2429 11491 : break;
2430 :
2431 862 : case TRANS_STMT_START:
2432 862 : tag = CMDTAG_START_TRANSACTION;
2433 862 : break;
2434 :
2435 9518 : case TRANS_STMT_COMMIT:
2436 9518 : tag = CMDTAG_COMMIT;
2437 9518 : break;
2438 :
2439 2694 : case TRANS_STMT_ROLLBACK:
2440 : case TRANS_STMT_ROLLBACK_TO:
2441 2694 : tag = CMDTAG_ROLLBACK;
2442 2694 : break;
2443 :
2444 1183 : case TRANS_STMT_SAVEPOINT:
2445 1183 : tag = CMDTAG_SAVEPOINT;
2446 1183 : break;
2447 :
2448 193 : case TRANS_STMT_RELEASE:
2449 193 : tag = CMDTAG_RELEASE;
2450 193 : break;
2451 :
2452 372 : case TRANS_STMT_PREPARE:
2453 372 : tag = CMDTAG_PREPARE_TRANSACTION;
2454 372 : break;
2455 :
2456 274 : case TRANS_STMT_COMMIT_PREPARED:
2457 274 : tag = CMDTAG_COMMIT_PREPARED;
2458 274 : break;
2459 :
2460 47 : case TRANS_STMT_ROLLBACK_PREPARED:
2461 47 : tag = CMDTAG_ROLLBACK_PREPARED;
2462 47 : break;
2463 :
2464 0 : default:
2465 0 : tag = CMDTAG_UNKNOWN;
2466 0 : break;
2467 : }
2468 : }
2469 26634 : break;
2470 :
2471 2774 : case T_DeclareCursorStmt:
2472 2774 : tag = CMDTAG_DECLARE_CURSOR;
2473 2774 : break;
2474 :
2475 1262 : case T_ClosePortalStmt:
2476 : {
2477 1262 : ClosePortalStmt *stmt = (ClosePortalStmt *) parsetree;
2478 :
2479 1262 : if (stmt->portalname == NULL)
2480 8 : tag = CMDTAG_CLOSE_CURSOR_ALL;
2481 : else
2482 1254 : tag = CMDTAG_CLOSE_CURSOR;
2483 : }
2484 1262 : break;
2485 :
2486 4571 : case T_FetchStmt:
2487 : {
2488 4571 : FetchStmt *stmt = (FetchStmt *) parsetree;
2489 :
2490 4571 : tag = (stmt->ismove) ? CMDTAG_MOVE : CMDTAG_FETCH;
2491 : }
2492 4571 : break;
2493 :
2494 983 : case T_CreateDomainStmt:
2495 983 : tag = CMDTAG_CREATE_DOMAIN;
2496 983 : break;
2497 :
2498 736 : case T_CreateSchemaStmt:
2499 736 : tag = CMDTAG_CREATE_SCHEMA;
2500 736 : break;
2501 :
2502 25771 : case T_CreateStmt:
2503 25771 : tag = CMDTAG_CREATE_TABLE;
2504 25771 : break;
2505 :
2506 92 : case T_CreateTableSpaceStmt:
2507 92 : tag = CMDTAG_CREATE_TABLESPACE;
2508 92 : break;
2509 :
2510 52 : case T_DropTableSpaceStmt:
2511 52 : tag = CMDTAG_DROP_TABLESPACE;
2512 52 : break;
2513 :
2514 16 : case T_AlterTableSpaceOptionsStmt:
2515 16 : tag = CMDTAG_ALTER_TABLESPACE;
2516 16 : break;
2517 :
2518 314 : case T_CreateExtensionStmt:
2519 314 : tag = CMDTAG_CREATE_EXTENSION;
2520 314 : break;
2521 :
2522 19 : case T_AlterExtensionStmt:
2523 19 : tag = CMDTAG_ALTER_EXTENSION;
2524 19 : break;
2525 :
2526 91 : case T_AlterExtensionContentsStmt:
2527 91 : tag = CMDTAG_ALTER_EXTENSION;
2528 91 : break;
2529 :
2530 129 : case T_CreateFdwStmt:
2531 129 : tag = CMDTAG_CREATE_FOREIGN_DATA_WRAPPER;
2532 129 : break;
2533 :
2534 96 : case T_AlterFdwStmt:
2535 96 : tag = CMDTAG_ALTER_FOREIGN_DATA_WRAPPER;
2536 96 : break;
2537 :
2538 190 : case T_CreateForeignServerStmt:
2539 190 : tag = CMDTAG_CREATE_SERVER;
2540 190 : break;
2541 :
2542 129 : case T_AlterForeignServerStmt:
2543 129 : tag = CMDTAG_ALTER_SERVER;
2544 129 : break;
2545 :
2546 171 : case T_CreateUserMappingStmt:
2547 171 : tag = CMDTAG_CREATE_USER_MAPPING;
2548 171 : break;
2549 :
2550 70 : case T_AlterUserMappingStmt:
2551 70 : tag = CMDTAG_ALTER_USER_MAPPING;
2552 70 : break;
2553 :
2554 79 : case T_DropUserMappingStmt:
2555 79 : tag = CMDTAG_DROP_USER_MAPPING;
2556 79 : break;
2557 :
2558 264 : case T_CreateForeignTableStmt:
2559 264 : tag = CMDTAG_CREATE_FOREIGN_TABLE;
2560 264 : break;
2561 :
2562 28 : case T_ImportForeignSchemaStmt:
2563 28 : tag = CMDTAG_IMPORT_FOREIGN_SCHEMA;
2564 28 : break;
2565 :
2566 17293 : case T_DropStmt:
2567 17293 : switch (((DropStmt *) parsetree)->removeType)
2568 : {
2569 10023 : case OBJECT_TABLE:
2570 10023 : tag = CMDTAG_DROP_TABLE;
2571 10023 : break;
2572 119 : case OBJECT_SEQUENCE:
2573 119 : tag = CMDTAG_DROP_SEQUENCE;
2574 119 : break;
2575 635 : case OBJECT_VIEW:
2576 635 : tag = CMDTAG_DROP_VIEW;
2577 635 : break;
2578 79 : case OBJECT_MATVIEW:
2579 79 : tag = CMDTAG_DROP_MATERIALIZED_VIEW;
2580 79 : break;
2581 577 : case OBJECT_INDEX:
2582 577 : tag = CMDTAG_DROP_INDEX;
2583 577 : break;
2584 46 : case OBJECT_PROPGRAPH:
2585 46 : tag = CMDTAG_DROP_PROPERTY_GRAPH;
2586 46 : break;
2587 408 : case OBJECT_TYPE:
2588 408 : tag = CMDTAG_DROP_TYPE;
2589 408 : break;
2590 401 : case OBJECT_DOMAIN:
2591 401 : tag = CMDTAG_DROP_DOMAIN;
2592 401 : break;
2593 58 : case OBJECT_COLLATION:
2594 58 : tag = CMDTAG_DROP_COLLATION;
2595 58 : break;
2596 24 : case OBJECT_CONVERSION:
2597 24 : tag = CMDTAG_DROP_CONVERSION;
2598 24 : break;
2599 404 : case OBJECT_SCHEMA:
2600 404 : tag = CMDTAG_DROP_SCHEMA;
2601 404 : break;
2602 12 : case OBJECT_TSPARSER:
2603 12 : tag = CMDTAG_DROP_TEXT_SEARCH_PARSER;
2604 12 : break;
2605 16 : case OBJECT_TSDICTIONARY:
2606 16 : tag = CMDTAG_DROP_TEXT_SEARCH_DICTIONARY;
2607 16 : break;
2608 12 : case OBJECT_TSTEMPLATE:
2609 12 : tag = CMDTAG_DROP_TEXT_SEARCH_TEMPLATE;
2610 12 : break;
2611 20 : case OBJECT_TSCONFIGURATION:
2612 20 : tag = CMDTAG_DROP_TEXT_SEARCH_CONFIGURATION;
2613 20 : break;
2614 107 : case OBJECT_FOREIGN_TABLE:
2615 107 : tag = CMDTAG_DROP_FOREIGN_TABLE;
2616 107 : break;
2617 92 : case OBJECT_EXTENSION:
2618 92 : tag = CMDTAG_DROP_EXTENSION;
2619 92 : break;
2620 2184 : case OBJECT_FUNCTION:
2621 2184 : tag = CMDTAG_DROP_FUNCTION;
2622 2184 : break;
2623 93 : case OBJECT_PROCEDURE:
2624 93 : tag = CMDTAG_DROP_PROCEDURE;
2625 93 : break;
2626 20 : case OBJECT_ROUTINE:
2627 20 : tag = CMDTAG_DROP_ROUTINE;
2628 20 : break;
2629 69 : case OBJECT_AGGREGATE:
2630 69 : tag = CMDTAG_DROP_AGGREGATE;
2631 69 : break;
2632 120 : case OBJECT_OPERATOR:
2633 120 : tag = CMDTAG_DROP_OPERATOR;
2634 120 : break;
2635 17 : case OBJECT_LANGUAGE:
2636 17 : tag = CMDTAG_DROP_LANGUAGE;
2637 17 : break;
2638 40 : case OBJECT_CAST:
2639 40 : tag = CMDTAG_DROP_CAST;
2640 40 : break;
2641 506 : case OBJECT_TRIGGER:
2642 506 : tag = CMDTAG_DROP_TRIGGER;
2643 506 : break;
2644 80 : case OBJECT_EVENT_TRIGGER:
2645 80 : tag = CMDTAG_DROP_EVENT_TRIGGER;
2646 80 : break;
2647 160 : case OBJECT_RULE:
2648 160 : tag = CMDTAG_DROP_RULE;
2649 160 : break;
2650 103 : case OBJECT_FDW:
2651 103 : tag = CMDTAG_DROP_FOREIGN_DATA_WRAPPER;
2652 103 : break;
2653 90 : case OBJECT_FOREIGN_SERVER:
2654 90 : tag = CMDTAG_DROP_SERVER;
2655 90 : break;
2656 37 : case OBJECT_OPCLASS:
2657 37 : tag = CMDTAG_DROP_OPERATOR_CLASS;
2658 37 : break;
2659 85 : case OBJECT_OPFAMILY:
2660 85 : tag = CMDTAG_DROP_OPERATOR_FAMILY;
2661 85 : break;
2662 173 : case OBJECT_POLICY:
2663 173 : tag = CMDTAG_DROP_POLICY;
2664 173 : break;
2665 8 : case OBJECT_TRANSFORM:
2666 8 : tag = CMDTAG_DROP_TRANSFORM;
2667 8 : break;
2668 32 : case OBJECT_ACCESS_METHOD:
2669 32 : tag = CMDTAG_DROP_ACCESS_METHOD;
2670 32 : break;
2671 303 : case OBJECT_PUBLICATION:
2672 303 : tag = CMDTAG_DROP_PUBLICATION;
2673 303 : break;
2674 140 : case OBJECT_STATISTIC_EXT:
2675 140 : tag = CMDTAG_DROP_STATISTICS;
2676 140 : break;
2677 0 : default:
2678 0 : tag = CMDTAG_UNKNOWN;
2679 : }
2680 17293 : break;
2681 :
2682 1164 : case T_TruncateStmt:
2683 1164 : tag = CMDTAG_TRUNCATE_TABLE;
2684 1164 : break;
2685 :
2686 4263 : case T_CommentStmt:
2687 4263 : tag = CMDTAG_COMMENT;
2688 4263 : break;
2689 :
2690 69 : case T_SecLabelStmt:
2691 69 : tag = CMDTAG_SECURITY_LABEL;
2692 69 : break;
2693 :
2694 6722 : case T_CopyStmt:
2695 6722 : tag = CMDTAG_COPY;
2696 6722 : break;
2697 :
2698 1026 : case T_RenameStmt:
2699 :
2700 : /*
2701 : * When the column is renamed, the command tag is created from its
2702 : * relation type
2703 : */
2704 1026 : tag = AlterObjectTypeCommandTag(((RenameStmt *) parsetree)->renameType == OBJECT_COLUMN ?
2705 : ((RenameStmt *) parsetree)->relationType :
2706 : ((RenameStmt *) parsetree)->renameType);
2707 1026 : break;
2708 :
2709 23 : case T_AlterObjectDependsStmt:
2710 23 : tag = AlterObjectTypeCommandTag(((AlterObjectDependsStmt *) parsetree)->objectType);
2711 23 : break;
2712 :
2713 287 : case T_AlterObjectSchemaStmt:
2714 287 : tag = AlterObjectTypeCommandTag(((AlterObjectSchemaStmt *) parsetree)->objectType);
2715 287 : break;
2716 :
2717 931 : case T_AlterOwnerStmt:
2718 931 : tag = AlterObjectTypeCommandTag(((AlterOwnerStmt *) parsetree)->objectType);
2719 931 : break;
2720 :
2721 20 : case T_AlterTableMoveAllStmt:
2722 20 : tag = AlterObjectTypeCommandTag(((AlterTableMoveAllStmt *) parsetree)->objtype);
2723 20 : break;
2724 :
2725 20767 : case T_AlterTableStmt:
2726 20767 : tag = AlterObjectTypeCommandTag(((AlterTableStmt *) parsetree)->objtype);
2727 20767 : break;
2728 :
2729 195 : case T_AlterDomainStmt:
2730 195 : tag = CMDTAG_ALTER_DOMAIN;
2731 195 : break;
2732 :
2733 131 : case T_AlterFunctionStmt:
2734 131 : switch (((AlterFunctionStmt *) parsetree)->objtype)
2735 : {
2736 119 : case OBJECT_FUNCTION:
2737 119 : tag = CMDTAG_ALTER_FUNCTION;
2738 119 : break;
2739 12 : case OBJECT_PROCEDURE:
2740 12 : tag = CMDTAG_ALTER_PROCEDURE;
2741 12 : break;
2742 0 : case OBJECT_ROUTINE:
2743 0 : tag = CMDTAG_ALTER_ROUTINE;
2744 0 : break;
2745 0 : default:
2746 0 : tag = CMDTAG_UNKNOWN;
2747 : }
2748 131 : break;
2749 :
2750 8216 : case T_GrantStmt:
2751 : {
2752 8216 : GrantStmt *stmt = (GrantStmt *) parsetree;
2753 :
2754 8216 : tag = (stmt->is_grant) ? CMDTAG_GRANT : CMDTAG_REVOKE;
2755 : }
2756 8216 : break;
2757 :
2758 418 : case T_GrantRoleStmt:
2759 : {
2760 418 : GrantRoleStmt *stmt = (GrantRoleStmt *) parsetree;
2761 :
2762 418 : tag = (stmt->is_grant) ? CMDTAG_GRANT_ROLE : CMDTAG_REVOKE_ROLE;
2763 : }
2764 418 : break;
2765 :
2766 148 : case T_AlterDefaultPrivilegesStmt:
2767 148 : tag = CMDTAG_ALTER_DEFAULT_PRIVILEGES;
2768 148 : break;
2769 :
2770 4920 : case T_DefineStmt:
2771 4920 : switch (((DefineStmt *) parsetree)->kind)
2772 : {
2773 574 : case OBJECT_AGGREGATE:
2774 574 : tag = CMDTAG_CREATE_AGGREGATE;
2775 574 : break;
2776 271 : case OBJECT_OPERATOR:
2777 271 : tag = CMDTAG_CREATE_OPERATOR;
2778 271 : break;
2779 170 : case OBJECT_TYPE:
2780 170 : tag = CMDTAG_CREATE_TYPE;
2781 170 : break;
2782 26 : case OBJECT_TSPARSER:
2783 26 : tag = CMDTAG_CREATE_TEXT_SEARCH_PARSER;
2784 26 : break;
2785 1796 : case OBJECT_TSDICTIONARY:
2786 1796 : tag = CMDTAG_CREATE_TEXT_SEARCH_DICTIONARY;
2787 1796 : break;
2788 81 : case OBJECT_TSTEMPLATE:
2789 81 : tag = CMDTAG_CREATE_TEXT_SEARCH_TEMPLATE;
2790 81 : break;
2791 1769 : case OBJECT_TSCONFIGURATION:
2792 1769 : tag = CMDTAG_CREATE_TEXT_SEARCH_CONFIGURATION;
2793 1769 : break;
2794 233 : case OBJECT_COLLATION:
2795 233 : tag = CMDTAG_CREATE_COLLATION;
2796 233 : break;
2797 0 : case OBJECT_ACCESS_METHOD:
2798 0 : tag = CMDTAG_CREATE_ACCESS_METHOD;
2799 0 : break;
2800 0 : default:
2801 0 : tag = CMDTAG_UNKNOWN;
2802 : }
2803 4920 : break;
2804 :
2805 2358 : case T_CompositeTypeStmt:
2806 2358 : tag = CMDTAG_CREATE_TYPE;
2807 2358 : break;
2808 :
2809 128 : case T_CreateEnumStmt:
2810 128 : tag = CMDTAG_CREATE_TYPE;
2811 128 : break;
2812 :
2813 134 : case T_CreateRangeStmt:
2814 134 : tag = CMDTAG_CREATE_TYPE;
2815 134 : break;
2816 :
2817 252 : case T_AlterEnumStmt:
2818 252 : tag = CMDTAG_ALTER_TYPE;
2819 252 : break;
2820 :
2821 10831 : case T_ViewStmt:
2822 10831 : tag = CMDTAG_CREATE_VIEW;
2823 10831 : break;
2824 :
2825 9027 : case T_CreateFunctionStmt:
2826 9027 : if (((CreateFunctionStmt *) parsetree)->is_procedure)
2827 226 : tag = CMDTAG_CREATE_PROCEDURE;
2828 : else
2829 8801 : tag = CMDTAG_CREATE_FUNCTION;
2830 9027 : break;
2831 :
2832 4317 : case T_IndexStmt:
2833 4317 : tag = CMDTAG_CREATE_INDEX;
2834 4317 : break;
2835 :
2836 715 : case T_RuleStmt:
2837 715 : tag = CMDTAG_CREATE_RULE;
2838 715 : break;
2839 :
2840 435 : case T_CreateSeqStmt:
2841 435 : tag = CMDTAG_CREATE_SEQUENCE;
2842 435 : break;
2843 :
2844 156 : case T_AlterSeqStmt:
2845 156 : tag = CMDTAG_ALTER_SEQUENCE;
2846 156 : break;
2847 :
2848 663 : case T_DoStmt:
2849 663 : tag = CMDTAG_DO;
2850 663 : break;
2851 :
2852 454 : case T_CreatedbStmt:
2853 454 : tag = CMDTAG_CREATE_DATABASE;
2854 454 : break;
2855 :
2856 727 : case T_AlterDatabaseStmt:
2857 : case T_AlterDatabaseRefreshCollStmt:
2858 : case T_AlterDatabaseSetStmt:
2859 727 : tag = CMDTAG_ALTER_DATABASE;
2860 727 : break;
2861 :
2862 81 : case T_DropdbStmt:
2863 81 : tag = CMDTAG_DROP_DATABASE;
2864 81 : break;
2865 :
2866 62 : case T_NotifyStmt:
2867 62 : tag = CMDTAG_NOTIFY;
2868 62 : break;
2869 :
2870 60 : case T_ListenStmt:
2871 60 : tag = CMDTAG_LISTEN;
2872 60 : break;
2873 :
2874 80 : case T_UnlistenStmt:
2875 80 : tag = CMDTAG_UNLISTEN;
2876 80 : break;
2877 :
2878 43 : case T_LoadStmt:
2879 43 : tag = CMDTAG_LOAD;
2880 43 : break;
2881 :
2882 296 : case T_CallStmt:
2883 296 : tag = CMDTAG_CALL;
2884 296 : break;
2885 :
2886 8762 : case T_VacuumStmt:
2887 8762 : if (((VacuumStmt *) parsetree)->is_vacuumcmd)
2888 5807 : tag = CMDTAG_VACUUM;
2889 : else
2890 2955 : tag = CMDTAG_ANALYZE;
2891 8762 : break;
2892 :
2893 183 : case T_RepackStmt:
2894 183 : if (((RepackStmt *) parsetree)->command == REPACK_COMMAND_CLUSTER)
2895 151 : tag = CMDTAG_CLUSTER;
2896 : else
2897 32 : tag = CMDTAG_REPACK;
2898 183 : break;
2899 :
2900 16346 : case T_ExplainStmt:
2901 16346 : tag = CMDTAG_EXPLAIN;
2902 16346 : break;
2903 :
2904 1124 : case T_CreateTableAsStmt:
2905 1124 : switch (((CreateTableAsStmt *) parsetree)->objtype)
2906 : {
2907 813 : case OBJECT_TABLE:
2908 813 : if (((CreateTableAsStmt *) parsetree)->is_select_into)
2909 0 : tag = CMDTAG_SELECT_INTO;
2910 : else
2911 813 : tag = CMDTAG_CREATE_TABLE_AS;
2912 813 : break;
2913 311 : case OBJECT_MATVIEW:
2914 311 : tag = CMDTAG_CREATE_MATERIALIZED_VIEW;
2915 311 : break;
2916 0 : default:
2917 0 : tag = CMDTAG_UNKNOWN;
2918 : }
2919 1124 : break;
2920 :
2921 177 : case T_RefreshMatViewStmt:
2922 177 : tag = CMDTAG_REFRESH_MATERIALIZED_VIEW;
2923 177 : break;
2924 :
2925 126 : case T_AlterSystemStmt:
2926 126 : tag = CMDTAG_ALTER_SYSTEM;
2927 126 : break;
2928 :
2929 18925 : case T_VariableSetStmt:
2930 18925 : switch (((VariableSetStmt *) parsetree)->kind)
2931 : {
2932 15597 : case VAR_SET_VALUE:
2933 : case VAR_SET_CURRENT:
2934 : case VAR_SET_DEFAULT:
2935 : case VAR_SET_MULTI:
2936 15597 : tag = CMDTAG_SET;
2937 15597 : break;
2938 3328 : case VAR_RESET:
2939 : case VAR_RESET_ALL:
2940 3328 : tag = CMDTAG_RESET;
2941 3328 : break;
2942 0 : default:
2943 0 : tag = CMDTAG_UNKNOWN;
2944 : }
2945 18925 : break;
2946 :
2947 576 : case T_VariableShowStmt:
2948 576 : tag = CMDTAG_SHOW;
2949 576 : break;
2950 :
2951 24 : case T_DiscardStmt:
2952 24 : switch (((DiscardStmt *) parsetree)->target)
2953 : {
2954 4 : case DISCARD_ALL:
2955 4 : tag = CMDTAG_DISCARD_ALL;
2956 4 : break;
2957 3 : case DISCARD_PLANS:
2958 3 : tag = CMDTAG_DISCARD_PLANS;
2959 3 : break;
2960 9 : case DISCARD_TEMP:
2961 9 : tag = CMDTAG_DISCARD_TEMP;
2962 9 : break;
2963 8 : case DISCARD_SEQUENCES:
2964 8 : tag = CMDTAG_DISCARD_SEQUENCES;
2965 8 : break;
2966 0 : default:
2967 0 : tag = CMDTAG_UNKNOWN;
2968 : }
2969 24 : break;
2970 :
2971 201 : case T_CreatePropGraphStmt:
2972 201 : tag = CMDTAG_CREATE_PROPERTY_GRAPH;
2973 201 : break;
2974 :
2975 124 : case T_AlterPropGraphStmt:
2976 124 : tag = CMDTAG_ALTER_PROPERTY_GRAPH;
2977 124 : break;
2978 :
2979 20 : case T_CreateTransformStmt:
2980 20 : tag = CMDTAG_CREATE_TRANSFORM;
2981 20 : break;
2982 :
2983 2141 : case T_CreateTrigStmt:
2984 2141 : tag = CMDTAG_CREATE_TRIGGER;
2985 2141 : break;
2986 :
2987 127 : case T_CreateEventTrigStmt:
2988 127 : tag = CMDTAG_CREATE_EVENT_TRIGGER;
2989 127 : break;
2990 :
2991 30 : case T_AlterEventTrigStmt:
2992 30 : tag = CMDTAG_ALTER_EVENT_TRIGGER;
2993 30 : break;
2994 :
2995 9 : case T_CreatePLangStmt:
2996 9 : tag = CMDTAG_CREATE_LANGUAGE;
2997 9 : break;
2998 :
2999 1339 : case T_CreateRoleStmt:
3000 1339 : tag = CMDTAG_CREATE_ROLE;
3001 1339 : break;
3002 :
3003 290 : case T_AlterRoleStmt:
3004 290 : tag = CMDTAG_ALTER_ROLE;
3005 290 : break;
3006 :
3007 63 : case T_AlterRoleSetStmt:
3008 63 : tag = CMDTAG_ALTER_ROLE;
3009 63 : break;
3010 :
3011 1283 : case T_DropRoleStmt:
3012 1283 : tag = CMDTAG_DROP_ROLE;
3013 1283 : break;
3014 :
3015 99 : case T_DropOwnedStmt:
3016 99 : tag = CMDTAG_DROP_OWNED;
3017 99 : break;
3018 :
3019 34 : case T_ReassignOwnedStmt:
3020 34 : tag = CMDTAG_REASSIGN_OWNED;
3021 34 : break;
3022 :
3023 645 : case T_LockStmt:
3024 645 : tag = CMDTAG_LOCK_TABLE;
3025 645 : break;
3026 :
3027 71 : case T_ConstraintsSetStmt:
3028 71 : tag = CMDTAG_SET_CONSTRAINTS;
3029 71 : break;
3030 :
3031 148 : case T_CheckPointStmt:
3032 148 : tag = CMDTAG_CHECKPOINT;
3033 148 : break;
3034 :
3035 849 : case T_ReindexStmt:
3036 849 : tag = CMDTAG_REINDEX;
3037 849 : break;
3038 :
3039 46 : case T_CreateConversionStmt:
3040 46 : tag = CMDTAG_CREATE_CONVERSION;
3041 46 : break;
3042 :
3043 118 : case T_CreateCastStmt:
3044 118 : tag = CMDTAG_CREATE_CAST;
3045 118 : break;
3046 :
3047 92 : case T_CreateOpClassStmt:
3048 92 : tag = CMDTAG_CREATE_OPERATOR_CLASS;
3049 92 : break;
3050 :
3051 100 : case T_CreateOpFamilyStmt:
3052 100 : tag = CMDTAG_CREATE_OPERATOR_FAMILY;
3053 100 : break;
3054 :
3055 197 : case T_AlterOpFamilyStmt:
3056 197 : tag = CMDTAG_ALTER_OPERATOR_FAMILY;
3057 197 : break;
3058 :
3059 112 : case T_AlterOperatorStmt:
3060 112 : tag = CMDTAG_ALTER_OPERATOR;
3061 112 : break;
3062 :
3063 20 : case T_AlterTypeStmt:
3064 20 : tag = CMDTAG_ALTER_TYPE;
3065 20 : break;
3066 :
3067 23 : case T_AlterTSDictionaryStmt:
3068 23 : tag = CMDTAG_ALTER_TEXT_SEARCH_DICTIONARY;
3069 23 : break;
3070 :
3071 5256 : case T_AlterTSConfigurationStmt:
3072 5256 : tag = CMDTAG_ALTER_TEXT_SEARCH_CONFIGURATION;
3073 5256 : break;
3074 :
3075 591 : case T_CreatePolicyStmt:
3076 591 : tag = CMDTAG_CREATE_POLICY;
3077 591 : break;
3078 :
3079 64 : case T_AlterPolicyStmt:
3080 64 : tag = CMDTAG_ALTER_POLICY;
3081 64 : break;
3082 :
3083 41 : case T_CreateAmStmt:
3084 41 : tag = CMDTAG_CREATE_ACCESS_METHOD;
3085 41 : break;
3086 :
3087 640 : case T_CreatePublicationStmt:
3088 640 : tag = CMDTAG_CREATE_PUBLICATION;
3089 640 : break;
3090 :
3091 790 : case T_AlterPublicationStmt:
3092 790 : tag = CMDTAG_ALTER_PUBLICATION;
3093 790 : break;
3094 :
3095 307 : case T_CreateSubscriptionStmt:
3096 307 : tag = CMDTAG_CREATE_SUBSCRIPTION;
3097 307 : break;
3098 :
3099 335 : case T_AlterSubscriptionStmt:
3100 335 : tag = CMDTAG_ALTER_SUBSCRIPTION;
3101 335 : break;
3102 :
3103 155 : case T_DropSubscriptionStmt:
3104 155 : tag = CMDTAG_DROP_SUBSCRIPTION;
3105 155 : break;
3106 :
3107 4 : case T_AlterCollationStmt:
3108 4 : tag = CMDTAG_ALTER_COLLATION;
3109 4 : break;
3110 :
3111 1986 : case T_PrepareStmt:
3112 1986 : tag = CMDTAG_PREPARE;
3113 1986 : break;
3114 :
3115 16188 : case T_ExecuteStmt:
3116 16188 : tag = CMDTAG_EXECUTE;
3117 16188 : break;
3118 :
3119 602 : case T_CreateStatsStmt:
3120 602 : tag = CMDTAG_CREATE_STATISTICS;
3121 602 : break;
3122 :
3123 18 : case T_AlterStatsStmt:
3124 18 : tag = CMDTAG_ALTER_STATISTICS;
3125 18 : break;
3126 :
3127 2093 : case T_DeallocateStmt:
3128 : {
3129 2093 : DeallocateStmt *stmt = (DeallocateStmt *) parsetree;
3130 :
3131 2093 : if (stmt->name == NULL)
3132 37 : tag = CMDTAG_DEALLOCATE_ALL;
3133 : else
3134 2056 : tag = CMDTAG_DEALLOCATE;
3135 : }
3136 2093 : break;
3137 :
3138 101 : case T_WaitStmt:
3139 101 : tag = CMDTAG_WAIT;
3140 101 : break;
3141 :
3142 : /* already-planned queries */
3143 26 : case T_PlannedStmt:
3144 : {
3145 26 : PlannedStmt *stmt = (PlannedStmt *) parsetree;
3146 :
3147 26 : switch (stmt->commandType)
3148 : {
3149 0 : case CMD_SELECT:
3150 :
3151 : /*
3152 : * We take a little extra care here so that the result
3153 : * will be useful for complaints about read-only
3154 : * statements
3155 : */
3156 0 : if (stmt->rowMarks != NIL)
3157 : {
3158 : /* not 100% but probably close enough */
3159 0 : switch (((PlanRowMark *) linitial(stmt->rowMarks))->strength)
3160 : {
3161 0 : case LCS_FORKEYSHARE:
3162 0 : tag = CMDTAG_SELECT_FOR_KEY_SHARE;
3163 0 : break;
3164 0 : case LCS_FORSHARE:
3165 0 : tag = CMDTAG_SELECT_FOR_SHARE;
3166 0 : break;
3167 0 : case LCS_FORNOKEYUPDATE:
3168 0 : tag = CMDTAG_SELECT_FOR_NO_KEY_UPDATE;
3169 0 : break;
3170 0 : case LCS_FORUPDATE:
3171 0 : tag = CMDTAG_SELECT_FOR_UPDATE;
3172 0 : break;
3173 0 : default:
3174 0 : tag = CMDTAG_SELECT;
3175 0 : break;
3176 : }
3177 : }
3178 : else
3179 0 : tag = CMDTAG_SELECT;
3180 0 : break;
3181 16 : case CMD_UPDATE:
3182 16 : tag = CMDTAG_UPDATE;
3183 16 : break;
3184 6 : case CMD_INSERT:
3185 6 : tag = CMDTAG_INSERT;
3186 6 : break;
3187 4 : case CMD_DELETE:
3188 4 : tag = CMDTAG_DELETE;
3189 4 : break;
3190 0 : case CMD_MERGE:
3191 0 : tag = CMDTAG_MERGE;
3192 0 : break;
3193 0 : case CMD_UTILITY:
3194 0 : tag = CreateCommandTag(stmt->utilityStmt);
3195 0 : break;
3196 0 : default:
3197 0 : elog(WARNING, "unrecognized commandType: %d",
3198 : (int) stmt->commandType);
3199 0 : tag = CMDTAG_UNKNOWN;
3200 0 : break;
3201 : }
3202 : }
3203 26 : break;
3204 :
3205 : /* parsed-and-rewritten-but-not-planned queries */
3206 614 : case T_Query:
3207 : {
3208 614 : Query *stmt = (Query *) parsetree;
3209 :
3210 614 : switch (stmt->commandType)
3211 : {
3212 610 : case CMD_SELECT:
3213 :
3214 : /*
3215 : * We take a little extra care here so that the result
3216 : * will be useful for complaints about read-only
3217 : * statements
3218 : */
3219 610 : if (stmt->rowMarks != NIL)
3220 : {
3221 : /* not 100% but probably close enough */
3222 0 : switch (((RowMarkClause *) linitial(stmt->rowMarks))->strength)
3223 : {
3224 0 : case LCS_FORKEYSHARE:
3225 0 : tag = CMDTAG_SELECT_FOR_KEY_SHARE;
3226 0 : break;
3227 0 : case LCS_FORSHARE:
3228 0 : tag = CMDTAG_SELECT_FOR_SHARE;
3229 0 : break;
3230 0 : case LCS_FORNOKEYUPDATE:
3231 0 : tag = CMDTAG_SELECT_FOR_NO_KEY_UPDATE;
3232 0 : break;
3233 0 : case LCS_FORUPDATE:
3234 0 : tag = CMDTAG_SELECT_FOR_UPDATE;
3235 0 : break;
3236 0 : default:
3237 0 : tag = CMDTAG_UNKNOWN;
3238 0 : break;
3239 : }
3240 : }
3241 : else
3242 610 : tag = CMDTAG_SELECT;
3243 610 : break;
3244 0 : case CMD_UPDATE:
3245 0 : tag = CMDTAG_UPDATE;
3246 0 : break;
3247 4 : case CMD_INSERT:
3248 4 : tag = CMDTAG_INSERT;
3249 4 : break;
3250 0 : case CMD_DELETE:
3251 0 : tag = CMDTAG_DELETE;
3252 0 : break;
3253 0 : case CMD_MERGE:
3254 0 : tag = CMDTAG_MERGE;
3255 0 : break;
3256 0 : case CMD_UTILITY:
3257 0 : tag = CreateCommandTag(stmt->utilityStmt);
3258 0 : break;
3259 0 : default:
3260 0 : elog(WARNING, "unrecognized commandType: %d",
3261 : (int) stmt->commandType);
3262 0 : tag = CMDTAG_UNKNOWN;
3263 0 : break;
3264 : }
3265 : }
3266 614 : break;
3267 :
3268 0 : default:
3269 0 : elog(WARNING, "unrecognized node type: %d",
3270 : (int) nodeTag(parsetree));
3271 0 : tag = CMDTAG_UNKNOWN;
3272 0 : break;
3273 : }
3274 :
3275 509387 : return tag;
3276 : }
3277 :
3278 :
3279 : /*
3280 : * GetCommandLogLevel
3281 : * utility to get the minimum log_statement level for a command,
3282 : * given either a raw (un-analyzed) parsetree, an analyzed Query,
3283 : * or a PlannedStmt.
3284 : *
3285 : * This must handle all command types, but since the vast majority
3286 : * of 'em are utility commands, it seems sensible to keep it here.
3287 : */
3288 : LogStmtLevel
3289 0 : GetCommandLogLevel(Node *parsetree)
3290 : {
3291 : LogStmtLevel lev;
3292 :
3293 0 : switch (nodeTag(parsetree))
3294 : {
3295 : /* recurse if we're given a RawStmt */
3296 0 : case T_RawStmt:
3297 0 : lev = GetCommandLogLevel(((RawStmt *) parsetree)->stmt);
3298 0 : break;
3299 :
3300 : /* raw plannable queries */
3301 0 : case T_InsertStmt:
3302 : case T_DeleteStmt:
3303 : case T_UpdateStmt:
3304 : case T_MergeStmt:
3305 0 : lev = LOGSTMT_MOD;
3306 0 : break;
3307 :
3308 0 : case T_SelectStmt:
3309 0 : if (((SelectStmt *) parsetree)->intoClause)
3310 0 : lev = LOGSTMT_DDL; /* SELECT INTO */
3311 : else
3312 0 : lev = LOGSTMT_ALL;
3313 0 : break;
3314 :
3315 0 : case T_PLAssignStmt:
3316 0 : lev = LOGSTMT_ALL;
3317 0 : break;
3318 :
3319 : /* utility statements --- same whether raw or cooked */
3320 0 : case T_TransactionStmt:
3321 0 : lev = LOGSTMT_ALL;
3322 0 : break;
3323 :
3324 0 : case T_DeclareCursorStmt:
3325 0 : lev = LOGSTMT_ALL;
3326 0 : break;
3327 :
3328 0 : case T_ClosePortalStmt:
3329 0 : lev = LOGSTMT_ALL;
3330 0 : break;
3331 :
3332 0 : case T_FetchStmt:
3333 0 : lev = LOGSTMT_ALL;
3334 0 : break;
3335 :
3336 0 : case T_CreateSchemaStmt:
3337 0 : lev = LOGSTMT_DDL;
3338 0 : break;
3339 :
3340 0 : case T_CreateStmt:
3341 : case T_CreateForeignTableStmt:
3342 0 : lev = LOGSTMT_DDL;
3343 0 : break;
3344 :
3345 0 : case T_CreateTableSpaceStmt:
3346 : case T_DropTableSpaceStmt:
3347 : case T_AlterTableSpaceOptionsStmt:
3348 0 : lev = LOGSTMT_DDL;
3349 0 : break;
3350 :
3351 0 : case T_CreateExtensionStmt:
3352 : case T_AlterExtensionStmt:
3353 : case T_AlterExtensionContentsStmt:
3354 0 : lev = LOGSTMT_DDL;
3355 0 : break;
3356 :
3357 0 : case T_CreateFdwStmt:
3358 : case T_AlterFdwStmt:
3359 : case T_CreateForeignServerStmt:
3360 : case T_AlterForeignServerStmt:
3361 : case T_CreateUserMappingStmt:
3362 : case T_AlterUserMappingStmt:
3363 : case T_DropUserMappingStmt:
3364 : case T_ImportForeignSchemaStmt:
3365 0 : lev = LOGSTMT_DDL;
3366 0 : break;
3367 :
3368 0 : case T_DropStmt:
3369 0 : lev = LOGSTMT_DDL;
3370 0 : break;
3371 :
3372 0 : case T_TruncateStmt:
3373 0 : lev = LOGSTMT_MOD;
3374 0 : break;
3375 :
3376 0 : case T_CommentStmt:
3377 0 : lev = LOGSTMT_DDL;
3378 0 : break;
3379 :
3380 0 : case T_SecLabelStmt:
3381 0 : lev = LOGSTMT_DDL;
3382 0 : break;
3383 :
3384 0 : case T_CopyStmt:
3385 0 : if (((CopyStmt *) parsetree)->is_from)
3386 0 : lev = LOGSTMT_MOD;
3387 : else
3388 0 : lev = LOGSTMT_ALL;
3389 0 : break;
3390 :
3391 0 : case T_PrepareStmt:
3392 : {
3393 0 : PrepareStmt *stmt = (PrepareStmt *) parsetree;
3394 :
3395 : /* Look through a PREPARE to the contained stmt */
3396 0 : lev = GetCommandLogLevel(stmt->query);
3397 : }
3398 0 : break;
3399 :
3400 0 : case T_ExecuteStmt:
3401 : {
3402 0 : ExecuteStmt *stmt = (ExecuteStmt *) parsetree;
3403 : PreparedStatement *ps;
3404 :
3405 : /* Look through an EXECUTE to the referenced stmt */
3406 0 : ps = FetchPreparedStatement(stmt->name, false);
3407 0 : if (ps && ps->plansource->raw_parse_tree)
3408 0 : lev = GetCommandLogLevel(ps->plansource->raw_parse_tree->stmt);
3409 : else
3410 0 : lev = LOGSTMT_ALL;
3411 : }
3412 0 : break;
3413 :
3414 0 : case T_DeallocateStmt:
3415 0 : lev = LOGSTMT_ALL;
3416 0 : break;
3417 :
3418 0 : case T_RenameStmt:
3419 0 : lev = LOGSTMT_DDL;
3420 0 : break;
3421 :
3422 0 : case T_AlterObjectDependsStmt:
3423 0 : lev = LOGSTMT_DDL;
3424 0 : break;
3425 :
3426 0 : case T_AlterObjectSchemaStmt:
3427 0 : lev = LOGSTMT_DDL;
3428 0 : break;
3429 :
3430 0 : case T_AlterOwnerStmt:
3431 0 : lev = LOGSTMT_DDL;
3432 0 : break;
3433 :
3434 0 : case T_AlterOperatorStmt:
3435 0 : lev = LOGSTMT_DDL;
3436 0 : break;
3437 :
3438 0 : case T_AlterTypeStmt:
3439 0 : lev = LOGSTMT_DDL;
3440 0 : break;
3441 :
3442 0 : case T_AlterTableMoveAllStmt:
3443 : case T_AlterTableStmt:
3444 0 : lev = LOGSTMT_DDL;
3445 0 : break;
3446 :
3447 0 : case T_AlterDomainStmt:
3448 0 : lev = LOGSTMT_DDL;
3449 0 : break;
3450 :
3451 0 : case T_GrantStmt:
3452 0 : lev = LOGSTMT_DDL;
3453 0 : break;
3454 :
3455 0 : case T_GrantRoleStmt:
3456 0 : lev = LOGSTMT_DDL;
3457 0 : break;
3458 :
3459 0 : case T_AlterDefaultPrivilegesStmt:
3460 0 : lev = LOGSTMT_DDL;
3461 0 : break;
3462 :
3463 0 : case T_DefineStmt:
3464 0 : lev = LOGSTMT_DDL;
3465 0 : break;
3466 :
3467 0 : case T_CompositeTypeStmt:
3468 0 : lev = LOGSTMT_DDL;
3469 0 : break;
3470 :
3471 0 : case T_CreateEnumStmt:
3472 0 : lev = LOGSTMT_DDL;
3473 0 : break;
3474 :
3475 0 : case T_CreateRangeStmt:
3476 0 : lev = LOGSTMT_DDL;
3477 0 : break;
3478 :
3479 0 : case T_AlterEnumStmt:
3480 0 : lev = LOGSTMT_DDL;
3481 0 : break;
3482 :
3483 0 : case T_ViewStmt:
3484 0 : lev = LOGSTMT_DDL;
3485 0 : break;
3486 :
3487 0 : case T_CreateFunctionStmt:
3488 0 : lev = LOGSTMT_DDL;
3489 0 : break;
3490 :
3491 0 : case T_AlterFunctionStmt:
3492 0 : lev = LOGSTMT_DDL;
3493 0 : break;
3494 :
3495 0 : case T_IndexStmt:
3496 0 : lev = LOGSTMT_DDL;
3497 0 : break;
3498 :
3499 0 : case T_RuleStmt:
3500 0 : lev = LOGSTMT_DDL;
3501 0 : break;
3502 :
3503 0 : case T_CreateSeqStmt:
3504 0 : lev = LOGSTMT_DDL;
3505 0 : break;
3506 :
3507 0 : case T_AlterSeqStmt:
3508 0 : lev = LOGSTMT_DDL;
3509 0 : break;
3510 :
3511 0 : case T_DoStmt:
3512 0 : lev = LOGSTMT_ALL;
3513 0 : break;
3514 :
3515 0 : case T_CreatedbStmt:
3516 0 : lev = LOGSTMT_DDL;
3517 0 : break;
3518 :
3519 0 : case T_AlterDatabaseStmt:
3520 : case T_AlterDatabaseRefreshCollStmt:
3521 : case T_AlterDatabaseSetStmt:
3522 0 : lev = LOGSTMT_DDL;
3523 0 : break;
3524 :
3525 0 : case T_DropdbStmt:
3526 0 : lev = LOGSTMT_DDL;
3527 0 : break;
3528 :
3529 0 : case T_NotifyStmt:
3530 0 : lev = LOGSTMT_ALL;
3531 0 : break;
3532 :
3533 0 : case T_ListenStmt:
3534 0 : lev = LOGSTMT_ALL;
3535 0 : break;
3536 :
3537 0 : case T_UnlistenStmt:
3538 0 : lev = LOGSTMT_ALL;
3539 0 : break;
3540 :
3541 0 : case T_LoadStmt:
3542 0 : lev = LOGSTMT_ALL;
3543 0 : break;
3544 :
3545 0 : case T_CallStmt:
3546 0 : lev = LOGSTMT_ALL;
3547 0 : break;
3548 :
3549 0 : case T_RepackStmt:
3550 0 : lev = LOGSTMT_DDL;
3551 0 : break;
3552 :
3553 0 : case T_VacuumStmt:
3554 0 : lev = LOGSTMT_ALL;
3555 0 : break;
3556 :
3557 0 : case T_ExplainStmt:
3558 : {
3559 0 : ExplainStmt *stmt = (ExplainStmt *) parsetree;
3560 0 : bool analyze = false;
3561 : ListCell *lc;
3562 :
3563 : /* Look through an EXPLAIN ANALYZE to the contained stmt */
3564 0 : foreach(lc, stmt->options)
3565 : {
3566 0 : DefElem *opt = (DefElem *) lfirst(lc);
3567 :
3568 0 : if (strcmp(opt->defname, "analyze") == 0)
3569 0 : analyze = defGetBoolean(opt);
3570 : /* don't "break", as explain.c will use the last value */
3571 : }
3572 0 : if (analyze)
3573 0 : return GetCommandLogLevel(stmt->query);
3574 :
3575 : /* Plain EXPLAIN isn't so interesting */
3576 0 : lev = LOGSTMT_ALL;
3577 : }
3578 0 : break;
3579 :
3580 0 : case T_CreateTableAsStmt:
3581 0 : lev = LOGSTMT_DDL;
3582 0 : break;
3583 :
3584 0 : case T_RefreshMatViewStmt:
3585 0 : lev = LOGSTMT_DDL;
3586 0 : break;
3587 :
3588 0 : case T_AlterSystemStmt:
3589 0 : lev = LOGSTMT_DDL;
3590 0 : break;
3591 :
3592 0 : case T_VariableSetStmt:
3593 0 : lev = LOGSTMT_ALL;
3594 0 : break;
3595 :
3596 0 : case T_VariableShowStmt:
3597 0 : lev = LOGSTMT_ALL;
3598 0 : break;
3599 :
3600 0 : case T_DiscardStmt:
3601 0 : lev = LOGSTMT_ALL;
3602 0 : break;
3603 :
3604 0 : case T_CreateTrigStmt:
3605 0 : lev = LOGSTMT_DDL;
3606 0 : break;
3607 :
3608 0 : case T_CreateEventTrigStmt:
3609 0 : lev = LOGSTMT_DDL;
3610 0 : break;
3611 :
3612 0 : case T_AlterEventTrigStmt:
3613 0 : lev = LOGSTMT_DDL;
3614 0 : break;
3615 :
3616 0 : case T_CreatePLangStmt:
3617 0 : lev = LOGSTMT_DDL;
3618 0 : break;
3619 :
3620 0 : case T_CreateDomainStmt:
3621 0 : lev = LOGSTMT_DDL;
3622 0 : break;
3623 :
3624 0 : case T_CreateRoleStmt:
3625 0 : lev = LOGSTMT_DDL;
3626 0 : break;
3627 :
3628 0 : case T_AlterRoleStmt:
3629 0 : lev = LOGSTMT_DDL;
3630 0 : break;
3631 :
3632 0 : case T_AlterRoleSetStmt:
3633 0 : lev = LOGSTMT_DDL;
3634 0 : break;
3635 :
3636 0 : case T_DropRoleStmt:
3637 0 : lev = LOGSTMT_DDL;
3638 0 : break;
3639 :
3640 0 : case T_DropOwnedStmt:
3641 0 : lev = LOGSTMT_DDL;
3642 0 : break;
3643 :
3644 0 : case T_ReassignOwnedStmt:
3645 0 : lev = LOGSTMT_DDL;
3646 0 : break;
3647 :
3648 0 : case T_LockStmt:
3649 0 : lev = LOGSTMT_ALL;
3650 0 : break;
3651 :
3652 0 : case T_ConstraintsSetStmt:
3653 0 : lev = LOGSTMT_ALL;
3654 0 : break;
3655 :
3656 0 : case T_CheckPointStmt:
3657 0 : lev = LOGSTMT_ALL;
3658 0 : break;
3659 :
3660 0 : case T_ReindexStmt:
3661 0 : lev = LOGSTMT_ALL; /* should this be DDL? */
3662 0 : break;
3663 :
3664 0 : case T_CreateConversionStmt:
3665 0 : lev = LOGSTMT_DDL;
3666 0 : break;
3667 :
3668 0 : case T_CreateCastStmt:
3669 0 : lev = LOGSTMT_DDL;
3670 0 : break;
3671 :
3672 0 : case T_CreateOpClassStmt:
3673 0 : lev = LOGSTMT_DDL;
3674 0 : break;
3675 :
3676 0 : case T_CreateOpFamilyStmt:
3677 0 : lev = LOGSTMT_DDL;
3678 0 : break;
3679 :
3680 0 : case T_CreatePropGraphStmt:
3681 0 : lev = LOGSTMT_DDL;
3682 0 : break;
3683 :
3684 0 : case T_AlterPropGraphStmt:
3685 0 : lev = LOGSTMT_DDL;
3686 0 : break;
3687 :
3688 0 : case T_CreateTransformStmt:
3689 0 : lev = LOGSTMT_DDL;
3690 0 : break;
3691 :
3692 0 : case T_AlterOpFamilyStmt:
3693 0 : lev = LOGSTMT_DDL;
3694 0 : break;
3695 :
3696 0 : case T_CreatePolicyStmt:
3697 0 : lev = LOGSTMT_DDL;
3698 0 : break;
3699 :
3700 0 : case T_AlterPolicyStmt:
3701 0 : lev = LOGSTMT_DDL;
3702 0 : break;
3703 :
3704 0 : case T_AlterTSDictionaryStmt:
3705 0 : lev = LOGSTMT_DDL;
3706 0 : break;
3707 :
3708 0 : case T_AlterTSConfigurationStmt:
3709 0 : lev = LOGSTMT_DDL;
3710 0 : break;
3711 :
3712 0 : case T_CreateAmStmt:
3713 0 : lev = LOGSTMT_DDL;
3714 0 : break;
3715 :
3716 0 : case T_CreatePublicationStmt:
3717 0 : lev = LOGSTMT_DDL;
3718 0 : break;
3719 :
3720 0 : case T_AlterPublicationStmt:
3721 0 : lev = LOGSTMT_DDL;
3722 0 : break;
3723 :
3724 0 : case T_CreateSubscriptionStmt:
3725 0 : lev = LOGSTMT_DDL;
3726 0 : break;
3727 :
3728 0 : case T_AlterSubscriptionStmt:
3729 0 : lev = LOGSTMT_DDL;
3730 0 : break;
3731 :
3732 0 : case T_DropSubscriptionStmt:
3733 0 : lev = LOGSTMT_DDL;
3734 0 : break;
3735 :
3736 0 : case T_CreateStatsStmt:
3737 0 : lev = LOGSTMT_DDL;
3738 0 : break;
3739 :
3740 0 : case T_AlterStatsStmt:
3741 0 : lev = LOGSTMT_DDL;
3742 0 : break;
3743 :
3744 0 : case T_AlterCollationStmt:
3745 0 : lev = LOGSTMT_DDL;
3746 0 : break;
3747 :
3748 0 : case T_WaitStmt:
3749 0 : lev = LOGSTMT_ALL;
3750 0 : break;
3751 :
3752 : /* already-planned queries */
3753 0 : case T_PlannedStmt:
3754 : {
3755 0 : PlannedStmt *stmt = (PlannedStmt *) parsetree;
3756 :
3757 0 : switch (stmt->commandType)
3758 : {
3759 0 : case CMD_SELECT:
3760 0 : lev = LOGSTMT_ALL;
3761 0 : break;
3762 :
3763 0 : case CMD_UPDATE:
3764 : case CMD_INSERT:
3765 : case CMD_DELETE:
3766 : case CMD_MERGE:
3767 0 : lev = LOGSTMT_MOD;
3768 0 : break;
3769 :
3770 0 : case CMD_UTILITY:
3771 0 : lev = GetCommandLogLevel(stmt->utilityStmt);
3772 0 : break;
3773 :
3774 0 : default:
3775 0 : elog(WARNING, "unrecognized commandType: %d",
3776 : (int) stmt->commandType);
3777 0 : lev = LOGSTMT_ALL;
3778 0 : break;
3779 : }
3780 : }
3781 0 : break;
3782 :
3783 : /* parsed-and-rewritten-but-not-planned queries */
3784 0 : case T_Query:
3785 : {
3786 0 : Query *stmt = (Query *) parsetree;
3787 :
3788 0 : switch (stmt->commandType)
3789 : {
3790 0 : case CMD_SELECT:
3791 0 : lev = LOGSTMT_ALL;
3792 0 : break;
3793 :
3794 0 : case CMD_UPDATE:
3795 : case CMD_INSERT:
3796 : case CMD_DELETE:
3797 : case CMD_MERGE:
3798 0 : lev = LOGSTMT_MOD;
3799 0 : break;
3800 :
3801 0 : case CMD_UTILITY:
3802 0 : lev = GetCommandLogLevel(stmt->utilityStmt);
3803 0 : break;
3804 :
3805 0 : default:
3806 0 : elog(WARNING, "unrecognized commandType: %d",
3807 : (int) stmt->commandType);
3808 0 : lev = LOGSTMT_ALL;
3809 0 : break;
3810 : }
3811 : }
3812 0 : break;
3813 :
3814 0 : default:
3815 0 : elog(WARNING, "unrecognized node type: %d",
3816 : (int) nodeTag(parsetree));
3817 0 : lev = LOGSTMT_ALL;
3818 0 : break;
3819 : }
3820 :
3821 0 : return lev;
3822 : }
|