Thanks to visit codestin.com
Credit goes to doxygen.postgresql.org

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