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