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