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