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