1 /*-------------------------------------------------------------------------
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
8 * Portions Copyright (c) 1996-2016, PostgreSQL Global Development Group
9 * Portions Copyright (c) 1994, Regents of the University of California
13 * src/backend/tcop/utility.c
15 *-------------------------------------------------------------------------
19 #include "access/htup_details.h"
20 #include "access/reloptions.h"
21 #include "access/twophase.h"
22 #include "access/xact.h"
23 #include "access/xlog.h"
24 #include "catalog/catalog.h"
25 #include "catalog/namespace.h"
26 #include "catalog/toasting.h"
27 #include "commands/alter.h"
28 #include "commands/async.h"
29 #include "commands/cluster.h"
30 #include "commands/comment.h"
31 #include "commands/collationcmds.h"
32 #include "commands/conversioncmds.h"
33 #include "commands/copy.h"
34 #include "commands/createas.h"
35 #include "commands/dbcommands.h"
36 #include "commands/defrem.h"
37 #include "commands/discard.h"
38 #include "commands/event_trigger.h"
39 #include "commands/explain.h"
40 #include "commands/extension.h"
41 #include "commands/matview.h"
42 #include "commands/lockcmds.h"
43 #include "commands/policy.h"
44 #include "commands/portalcmds.h"
45 #include "commands/prepare.h"
46 #include "commands/proclang.h"
47 #include "commands/schemacmds.h"
48 #include "commands/seclabel.h"
49 #include "commands/sequence.h"
50 #include "commands/tablecmds.h"
51 #include "commands/tablespace.h"
52 #include "commands/trigger.h"
53 #include "commands/typecmds.h"
54 #include "commands/user.h"
55 #include "commands/vacuum.h"
56 #include "commands/view.h"
57 #include "miscadmin.h"
58 #include "parser/parse_utilcmd.h"
59 #include "postmaster/bgwriter.h"
60 #include "rewrite/rewriteDefine.h"
61 #include "rewrite/rewriteRemove.h"
62 #include "storage/fd.h"
63 #include "tcop/pquery.h"
64 #include "tcop/utility.h"
65 #include "utils/acl.h"
66 #include "utils/guc.h"
67 #include "utils/syscache.h"
70 /* Hook for plugins to get control in ProcessUtility() */
71 ProcessUtility_hook_type ProcessUtility_hook = NULL;
73 /* local function declarations */
74 static void ProcessUtilitySlow(ParseState *pstate,
76 const char *queryString,
77 ProcessUtilityContext context,
81 static void ExecDropStmt(DropStmt *stmt, bool isTopLevel);
85 * CommandIsReadOnly: is an executable query read-only?
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.
91 * Note: currently no need to support Query nodes here
94 CommandIsReadOnly(Node *parsetree)
96 if (IsA(parsetree, PlannedStmt))
98 PlannedStmt *stmt = (PlannedStmt *) parsetree;
100 switch (stmt->commandType)
103 if (stmt->rowMarks != NIL)
104 return false; /* SELECT FOR [KEY] UPDATE/SHARE */
105 else if (stmt->hasModifyingCTE)
106 return false; /* data-modifying CTE */
114 elog(WARNING, "unrecognized commandType: %d",
115 (int) stmt->commandType);
119 /* For now, treat all utility commands as read/write */
124 * check_xact_readonly: is a utility command read-only?
126 * Here we use the loose rules of XactReadOnly mode: no permanent effects
127 * on the database are allowed.
130 check_xact_readonly(Node *parsetree)
132 /* Only perform the check if we have a reason to do so. */
133 if (!XactReadOnly && !IsInParallelMode())
137 * Note: Commands that need to do more complicated checking are handled
138 * elsewhere, in particular COPY and plannable statements do their own
139 * checking. However they should all call PreventCommandIfReadOnly or
140 * PreventCommandIfParallelMode to actually throw the error.
143 switch (nodeTag(parsetree))
145 case T_AlterDatabaseStmt:
146 case T_AlterDatabaseSetStmt:
147 case T_AlterDomainStmt:
148 case T_AlterFunctionStmt:
149 case T_AlterRoleStmt:
150 case T_AlterRoleSetStmt:
151 case T_AlterObjectDependsStmt:
152 case T_AlterObjectSchemaStmt:
153 case T_AlterOwnerStmt:
154 case T_AlterOperatorStmt:
156 case T_AlterTableMoveAllStmt:
157 case T_AlterTableStmt:
161 case T_CreateCastStmt:
162 case T_CreateEventTrigStmt:
163 case T_AlterEventTrigStmt:
164 case T_CreateConversionStmt:
166 case T_CreateDomainStmt:
167 case T_CreateFunctionStmt:
168 case T_CreateRoleStmt:
170 case T_CreatePLangStmt:
171 case T_CreateOpClassStmt:
172 case T_CreateOpFamilyStmt:
173 case T_AlterOpFamilyStmt:
175 case T_CreateSchemaStmt:
176 case T_CreateSeqStmt:
178 case T_CreateTableAsStmt:
179 case T_RefreshMatViewStmt:
180 case T_CreateTableSpaceStmt:
181 case T_CreateTransformStmt:
182 case T_CreateTrigStmt:
183 case T_CompositeTypeStmt:
184 case T_CreateEnumStmt:
185 case T_CreateRangeStmt:
186 case T_AlterEnumStmt:
190 case T_DropTableSpaceStmt:
193 case T_GrantRoleStmt:
194 case T_AlterDefaultPrivilegesStmt:
196 case T_DropOwnedStmt:
197 case T_ReassignOwnedStmt:
198 case T_AlterTSDictionaryStmt:
199 case T_AlterTSConfigurationStmt:
200 case T_CreateExtensionStmt:
201 case T_AlterExtensionStmt:
202 case T_AlterExtensionContentsStmt:
203 case T_CreateFdwStmt:
205 case T_CreateForeignServerStmt:
206 case T_AlterForeignServerStmt:
207 case T_CreateUserMappingStmt:
208 case T_AlterUserMappingStmt:
209 case T_DropUserMappingStmt:
210 case T_AlterTableSpaceOptionsStmt:
211 case T_CreateForeignTableStmt:
212 case T_ImportForeignSchemaStmt:
214 PreventCommandIfReadOnly(CreateCommandTag(parsetree));
215 PreventCommandIfParallelMode(CreateCommandTag(parsetree));
224 * PreventCommandIfReadOnly: throw error if XactReadOnly
226 * This is useful mainly to ensure consistency of the error message wording;
227 * most callers have checked XactReadOnly for themselves.
230 PreventCommandIfReadOnly(const char *cmdname)
234 (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
235 /* translator: %s is name of a SQL command, eg CREATE */
236 errmsg("cannot execute %s in a read-only transaction",
241 * PreventCommandIfParallelMode: throw error if current (sub)transaction is
244 * This is useful mainly to ensure consistency of the error message wording;
245 * most callers have checked IsInParallelMode() for themselves.
248 PreventCommandIfParallelMode(const char *cmdname)
250 if (IsInParallelMode())
252 (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
253 /* translator: %s is name of a SQL command, eg CREATE */
254 errmsg("cannot execute %s during a parallel operation",
259 * PreventCommandDuringRecovery: throw error if RecoveryInProgress
261 * The majority of operations that are unsafe in a Hot Standby slave
262 * will be rejected by XactReadOnly tests. However there are a few
263 * commands that are allowed in "read-only" xacts but cannot be allowed
264 * in Hot Standby mode. Those commands should call this function.
267 PreventCommandDuringRecovery(const char *cmdname)
269 if (RecoveryInProgress())
271 (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
272 /* translator: %s is name of a SQL command, eg CREATE */
273 errmsg("cannot execute %s during recovery",
278 * CheckRestrictedOperation: throw error for hazardous command if we're
279 * inside a security restriction context.
281 * This is needed to protect session-local state for which there is not any
282 * better-defined protection mechanism, such as ownership.
285 CheckRestrictedOperation(const char *cmdname)
287 if (InSecurityRestrictedOperation())
289 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
290 /* translator: %s is name of a SQL command, eg PREPARE */
291 errmsg("cannot execute %s within security-restricted operation",
298 * general utility function invoker
300 * parsetree: the parse tree for the utility statement
301 * queryString: original source text of command
302 * context: identifies source of statement (toplevel client command,
303 * non-toplevel client command, subcommand of a larger utility command)
304 * params: parameters to use during execution
305 * dest: where to send results
306 * completionTag: points to a buffer of size COMPLETION_TAG_BUFSIZE
307 * in which to store a command completion status string.
309 * Notes: as of PG 8.4, caller MUST supply a queryString; it is not
310 * allowed anymore to pass NULL. (If you really don't have source text,
311 * you can pass a constant string, perhaps "(query not available)".)
313 * completionTag is only set nonempty if we want to return a nondefault status.
315 * completionTag may be NULL if caller doesn't want a status string.
318 ProcessUtility(Node *parsetree,
319 const char *queryString,
320 ProcessUtilityContext context,
321 ParamListInfo params,
325 Assert(queryString != NULL); /* required as of 8.4 */
328 * We provide a function hook variable that lets loadable plugins get
329 * control when ProcessUtility is called. Such a plugin would normally
330 * call standard_ProcessUtility().
332 if (ProcessUtility_hook)
333 (*ProcessUtility_hook) (parsetree, queryString,
335 dest, completionTag);
337 standard_ProcessUtility(parsetree, queryString,
339 dest, completionTag);
343 * standard_ProcessUtility itself deals only with utility commands for
344 * which we do not provide event trigger support. Commands that do have
345 * such support are passed down to ProcessUtilitySlow, which contains the
346 * necessary infrastructure for such triggers.
348 * This division is not just for performance: it's critical that the
349 * event trigger code not be invoked when doing START TRANSACTION for
350 * example, because we might need to refresh the event trigger cache,
351 * which requires being in a valid transaction.
354 standard_ProcessUtility(Node *parsetree,
355 const char *queryString,
356 ProcessUtilityContext context,
357 ParamListInfo params,
361 bool isTopLevel = (context == PROCESS_UTILITY_TOPLEVEL);
364 check_xact_readonly(parsetree);
367 completionTag[0] = '\0';
369 pstate = make_parsestate(NULL);
370 pstate->p_sourcetext = queryString;
372 switch (nodeTag(parsetree))
375 * ******************** transactions ********************
377 case T_TransactionStmt:
379 TransactionStmt *stmt = (TransactionStmt *) parsetree;
384 * START TRANSACTION, as defined by SQL99: Identical
385 * to BEGIN. Same code for both.
387 case TRANS_STMT_BEGIN:
388 case TRANS_STMT_START:
392 BeginTransactionBlock();
393 foreach(lc, stmt->options)
395 DefElem *item = (DefElem *) lfirst(lc);
397 if (strcmp(item->defname, "transaction_isolation") == 0)
398 SetPGVariable("transaction_isolation",
399 list_make1(item->arg),
401 else if (strcmp(item->defname, "transaction_read_only") == 0)
402 SetPGVariable("transaction_read_only",
403 list_make1(item->arg),
405 else if (strcmp(item->defname, "transaction_deferrable") == 0)
406 SetPGVariable("transaction_deferrable",
407 list_make1(item->arg),
413 case TRANS_STMT_COMMIT:
414 if (!EndTransactionBlock())
416 /* report unsuccessful commit in completionTag */
418 strcpy(completionTag, "ROLLBACK");
422 case TRANS_STMT_PREPARE:
423 PreventCommandDuringRecovery("PREPARE TRANSACTION");
424 if (!PrepareTransactionBlock(stmt->gid))
426 /* report unsuccessful commit in completionTag */
428 strcpy(completionTag, "ROLLBACK");
432 case TRANS_STMT_COMMIT_PREPARED:
433 PreventTransactionChain(isTopLevel, "COMMIT PREPARED");
434 PreventCommandDuringRecovery("COMMIT PREPARED");
435 FinishPreparedTransaction(stmt->gid, true);
438 case TRANS_STMT_ROLLBACK_PREPARED:
439 PreventTransactionChain(isTopLevel, "ROLLBACK PREPARED");
440 PreventCommandDuringRecovery("ROLLBACK PREPARED");
441 FinishPreparedTransaction(stmt->gid, false);
444 case TRANS_STMT_ROLLBACK:
445 UserAbortTransactionBlock();
448 case TRANS_STMT_SAVEPOINT:
453 RequireTransactionChain(isTopLevel, "SAVEPOINT");
455 foreach(cell, stmt->options)
457 DefElem *elem = lfirst(cell);
459 if (strcmp(elem->defname, "savepoint_name") == 0)
460 name = strVal(elem->arg);
463 Assert(PointerIsValid(name));
465 DefineSavepoint(name);
469 case TRANS_STMT_RELEASE:
470 RequireTransactionChain(isTopLevel, "RELEASE SAVEPOINT");
471 ReleaseSavepoint(stmt->options);
474 case TRANS_STMT_ROLLBACK_TO:
475 RequireTransactionChain(isTopLevel, "ROLLBACK TO SAVEPOINT");
476 RollbackToSavepoint(stmt->options);
479 * CommitTransactionCommand is in charge of
480 * re-defining the savepoint again
488 * Portal (cursor) manipulation
490 * Note: DECLARE CURSOR is processed mostly as a SELECT, and
491 * therefore what we will get here is a PlannedStmt not a bare
496 PlannedStmt *stmt = (PlannedStmt *) parsetree;
498 if (stmt->utilityStmt == NULL ||
499 !IsA(stmt->utilityStmt, DeclareCursorStmt))
500 elog(ERROR, "non-DECLARE CURSOR PlannedStmt passed to ProcessUtility");
501 PerformCursorOpen(stmt, params, queryString, isTopLevel);
505 case T_ClosePortalStmt:
507 ClosePortalStmt *stmt = (ClosePortalStmt *) parsetree;
509 CheckRestrictedOperation("CLOSE");
510 PerformPortalClose(stmt->portalname);
515 PerformPortalFetch((FetchStmt *) parsetree, dest,
520 ExecuteDoStmt((DoStmt *) parsetree);
523 case T_CreateTableSpaceStmt:
524 /* no event triggers for global objects */
525 PreventTransactionChain(isTopLevel, "CREATE TABLESPACE");
526 CreateTableSpace((CreateTableSpaceStmt *) parsetree);
529 case T_DropTableSpaceStmt:
530 /* no event triggers for global objects */
531 PreventTransactionChain(isTopLevel, "DROP TABLESPACE");
532 DropTableSpace((DropTableSpaceStmt *) parsetree);
535 case T_AlterTableSpaceOptionsStmt:
536 /* no event triggers for global objects */
537 AlterTableSpaceOptions((AlterTableSpaceOptionsStmt *) parsetree);
541 ExecuteTruncate((TruncateStmt *) parsetree);
548 DoCopy(pstate, (CopyStmt *) parsetree, &processed);
550 snprintf(completionTag, COMPLETION_TAG_BUFSIZE,
551 "COPY " UINT64_FORMAT, processed);
556 CheckRestrictedOperation("PREPARE");
557 PrepareQuery((PrepareStmt *) parsetree, queryString);
561 ExecuteQuery((ExecuteStmt *) parsetree, NULL,
563 dest, completionTag);
566 case T_DeallocateStmt:
567 CheckRestrictedOperation("DEALLOCATE");
568 DeallocateQuery((DeallocateStmt *) parsetree);
571 case T_GrantRoleStmt:
572 /* no event triggers for global objects */
573 GrantRole((GrantRoleStmt *) parsetree);
577 /* no event triggers for global objects */
578 PreventTransactionChain(isTopLevel, "CREATE DATABASE");
579 createdb(pstate, (CreatedbStmt *) parsetree);
582 case T_AlterDatabaseStmt:
583 /* no event triggers for global objects */
584 AlterDatabase(pstate, (AlterDatabaseStmt *) parsetree, isTopLevel);
587 case T_AlterDatabaseSetStmt:
588 /* no event triggers for global objects */
589 AlterDatabaseSet((AlterDatabaseSetStmt *) parsetree);
594 DropdbStmt *stmt = (DropdbStmt *) parsetree;
596 /* no event triggers for global objects */
597 PreventTransactionChain(isTopLevel, "DROP DATABASE");
598 dropdb(stmt->dbname, stmt->missing_ok);
602 /* Query-level asynchronous notification */
605 NotifyStmt *stmt = (NotifyStmt *) parsetree;
607 PreventCommandDuringRecovery("NOTIFY");
608 Async_Notify(stmt->conditionname, stmt->payload);
614 ListenStmt *stmt = (ListenStmt *) parsetree;
616 PreventCommandDuringRecovery("LISTEN");
617 CheckRestrictedOperation("LISTEN");
618 Async_Listen(stmt->conditionname);
624 UnlistenStmt *stmt = (UnlistenStmt *) parsetree;
626 PreventCommandDuringRecovery("UNLISTEN");
627 CheckRestrictedOperation("UNLISTEN");
628 if (stmt->conditionname)
629 Async_Unlisten(stmt->conditionname);
637 LoadStmt *stmt = (LoadStmt *) parsetree;
639 closeAllVfds(); /* probably not necessary... */
640 /* Allowed names are restricted if you're not superuser */
641 load_file(stmt->filename, !superuser());
646 /* we choose to allow this during "read only" transactions */
647 PreventCommandDuringRecovery("CLUSTER");
648 /* forbidden in parallel mode due to CommandIsReadOnly */
649 cluster((ClusterStmt *) parsetree, isTopLevel);
654 VacuumStmt *stmt = (VacuumStmt *) parsetree;
656 /* we choose to allow this during "read only" transactions */
657 PreventCommandDuringRecovery((stmt->options & VACOPT_VACUUM) ?
658 "VACUUM" : "ANALYZE");
659 /* forbidden in parallel mode due to CommandIsReadOnly */
660 ExecVacuum(stmt, isTopLevel);
665 ExplainQuery(pstate, (ExplainStmt *) parsetree, queryString, params, dest);
668 case T_AlterSystemStmt:
669 PreventTransactionChain(isTopLevel, "ALTER SYSTEM");
670 AlterSystemSetConfigFile((AlterSystemStmt *) parsetree);
673 case T_VariableSetStmt:
674 ExecSetVariableStmt((VariableSetStmt *) parsetree, isTopLevel);
677 case T_VariableShowStmt:
679 VariableShowStmt *n = (VariableShowStmt *) parsetree;
681 GetPGVariable(n->name, dest);
686 /* should we allow DISCARD PLANS? */
687 CheckRestrictedOperation("DISCARD");
688 DiscardCommand((DiscardStmt *) parsetree, isTopLevel);
691 case T_CreateEventTrigStmt:
692 /* no event triggers on event triggers */
693 CreateEventTrigger((CreateEventTrigStmt *) parsetree);
696 case T_AlterEventTrigStmt:
697 /* no event triggers on event triggers */
698 AlterEventTrigger((AlterEventTrigStmt *) parsetree);
702 * ******************************** ROLE statements ****
704 case T_CreateRoleStmt:
705 /* no event triggers for global objects */
706 CreateRole(pstate, (CreateRoleStmt *) parsetree);
709 case T_AlterRoleStmt:
710 /* no event triggers for global objects */
711 AlterRole((AlterRoleStmt *) parsetree);
714 case T_AlterRoleSetStmt:
715 /* no event triggers for global objects */
716 AlterRoleSet((AlterRoleSetStmt *) parsetree);
720 /* no event triggers for global objects */
721 DropRole((DropRoleStmt *) parsetree);
724 case T_ReassignOwnedStmt:
725 /* no event triggers for global objects */
726 ReassignOwnedObjects((ReassignOwnedStmt *) parsetree);
732 * Since the lock would just get dropped immediately, LOCK TABLE
733 * outside a transaction block is presumed to be user error.
735 RequireTransactionChain(isTopLevel, "LOCK TABLE");
736 /* forbidden in parallel mode due to CommandIsReadOnly */
737 LockTableCommand((LockStmt *) parsetree);
740 case T_ConstraintsSetStmt:
741 WarnNoTransactionChain(isTopLevel, "SET CONSTRAINTS");
742 AfterTriggerSetState((ConstraintsSetStmt *) parsetree);
745 case T_CheckPointStmt:
748 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
749 errmsg("must be superuser to do CHECKPOINT")));
752 * You might think we should have a PreventCommandDuringRecovery()
753 * here, but we interpret a CHECKPOINT command during recovery as
754 * a request for a restartpoint instead. We allow this since it
755 * can be a useful way of reducing switchover time when using
756 * various forms of replication.
758 RequestCheckpoint(CHECKPOINT_IMMEDIATE | CHECKPOINT_WAIT |
759 (RecoveryInProgress() ? 0 : CHECKPOINT_FORCE));
764 ReindexStmt *stmt = (ReindexStmt *) parsetree;
766 /* we choose to allow this during "read only" transactions */
767 PreventCommandDuringRecovery("REINDEX");
768 /* forbidden in parallel mode due to CommandIsReadOnly */
771 case REINDEX_OBJECT_INDEX:
772 ReindexIndex(stmt->relation, stmt->options);
774 case REINDEX_OBJECT_TABLE:
775 ReindexTable(stmt->relation, stmt->options);
777 case REINDEX_OBJECT_SCHEMA:
778 case REINDEX_OBJECT_SYSTEM:
779 case REINDEX_OBJECT_DATABASE:
782 * This cannot run inside a user transaction block; if
783 * we were inside a transaction, then its commit- and
784 * start-transaction-command calls would not have the
787 PreventTransactionChain(isTopLevel,
788 (stmt->kind == REINDEX_OBJECT_SCHEMA) ? "REINDEX SCHEMA" :
789 (stmt->kind == REINDEX_OBJECT_SYSTEM) ? "REINDEX SYSTEM" :
791 ReindexMultipleTables(stmt->name, stmt->kind, stmt->options);
794 elog(ERROR, "unrecognized object type: %d",
802 * The following statements are supported by Event Triggers only
803 * in some cases, so we "fast path" them in the other cases.
808 GrantStmt *stmt = (GrantStmt *) parsetree;
810 if (EventTriggerSupportsGrantObjectType(stmt->objtype))
811 ProcessUtilitySlow(pstate, parsetree, queryString,
813 dest, completionTag);
815 ExecuteGrantStmt((GrantStmt *) parsetree);
821 DropStmt *stmt = (DropStmt *) parsetree;
823 if (EventTriggerSupportsObjectType(stmt->removeType))
824 ProcessUtilitySlow(pstate, parsetree, queryString,
826 dest, completionTag);
828 ExecDropStmt(stmt, isTopLevel);
834 RenameStmt *stmt = (RenameStmt *) parsetree;
836 if (EventTriggerSupportsObjectType(stmt->renameType))
837 ProcessUtilitySlow(pstate, parsetree, queryString,
839 dest, completionTag);
841 ExecRenameStmt(stmt);
845 case T_AlterObjectDependsStmt:
847 AlterObjectDependsStmt *stmt = (AlterObjectDependsStmt *) parsetree;
849 if (EventTriggerSupportsObjectType(stmt->objectType))
850 ProcessUtilitySlow(pstate, parsetree, queryString,
852 dest, completionTag);
854 ExecAlterObjectDependsStmt(stmt, NULL);
858 case T_AlterObjectSchemaStmt:
860 AlterObjectSchemaStmt *stmt = (AlterObjectSchemaStmt *) parsetree;
862 if (EventTriggerSupportsObjectType(stmt->objectType))
863 ProcessUtilitySlow(pstate, parsetree, queryString,
865 dest, completionTag);
867 ExecAlterObjectSchemaStmt(stmt, NULL);
871 case T_AlterOwnerStmt:
873 AlterOwnerStmt *stmt = (AlterOwnerStmt *) parsetree;
875 if (EventTriggerSupportsObjectType(stmt->objectType))
876 ProcessUtilitySlow(pstate, parsetree, queryString,
878 dest, completionTag);
880 ExecAlterOwnerStmt(stmt);
886 CommentStmt *stmt = (CommentStmt *) parsetree;
888 if (EventTriggerSupportsObjectType(stmt->objtype))
889 ProcessUtilitySlow(pstate, parsetree, queryString,
891 dest, completionTag);
893 CommentObject((CommentStmt *) parsetree);
899 SecLabelStmt *stmt = (SecLabelStmt *) parsetree;
901 if (EventTriggerSupportsObjectType(stmt->objtype))
902 ProcessUtilitySlow(pstate, parsetree, queryString,
904 dest, completionTag);
906 ExecSecLabelStmt(stmt);
911 /* All other statement types have event trigger support */
912 ProcessUtilitySlow(pstate, parsetree, queryString,
914 dest, completionTag);
918 free_parsestate(pstate);
922 * The "Slow" variant of ProcessUtility should only receive statements
923 * supported by the event triggers facility. Therefore, we always
924 * perform the trigger support calls if the context allows it.
927 ProcessUtilitySlow(ParseState *pstate,
929 const char *queryString,
930 ProcessUtilityContext context,
931 ParamListInfo params,
935 bool isTopLevel = (context == PROCESS_UTILITY_TOPLEVEL);
936 bool isCompleteQuery = (context <= PROCESS_UTILITY_QUERY);
938 bool commandCollected = false;
939 ObjectAddress address;
940 ObjectAddress secondaryObject = InvalidObjectAddress;
942 /* All event trigger calls are done only when isCompleteQuery is true */
943 needCleanup = isCompleteQuery && EventTriggerBeginCompleteQuery();
945 /* PG_TRY block is to ensure we call EventTriggerEndCompleteQuery */
949 EventTriggerDDLCommandStart(parsetree);
951 switch (nodeTag(parsetree))
954 * relation and attribute manipulation
956 case T_CreateSchemaStmt:
957 CreateSchemaCommand((CreateSchemaStmt *) parsetree,
961 * EventTriggerCollectSimpleCommand called by
962 * CreateSchemaCommand
964 commandCollected = true;
968 case T_CreateForeignTableStmt:
973 /* Run parse analysis ... */
974 stmts = transformCreateStmt((CreateStmt *) parsetree,
980 Node *stmt = (Node *) lfirst(l);
982 if (IsA(stmt, CreateStmt))
985 static char *validnsps[] = HEAP_RELOPT_NAMESPACES;
987 /* Create the table itself */
988 address = DefineRelation((CreateStmt *) stmt,
992 EventTriggerCollectSimpleCommand(address,
997 * Let NewRelationCreateToastTable decide if this
998 * one needs a secondary relation too.
1000 CommandCounterIncrement();
1003 * parse and validate reloptions for the toast
1006 toast_options = transformRelOptions((Datum) 0,
1007 ((CreateStmt *) stmt)->options,
1012 (void) heap_reloptions(RELKIND_TOASTVALUE,
1016 NewRelationCreateToastTable(address.objectId,
1019 else if (IsA(stmt, CreateForeignTableStmt))
1021 /* Create the table itself */
1022 address = DefineRelation((CreateStmt *) stmt,
1023 RELKIND_FOREIGN_TABLE,
1026 CreateForeignTable((CreateForeignTableStmt *) stmt,
1028 EventTriggerCollectSimpleCommand(address,
1035 * Recurse for anything else. Note the recursive
1036 * call will stash the objects so created into our
1037 * event trigger context.
1039 ProcessUtility(stmt,
1041 PROCESS_UTILITY_SUBCOMMAND,
1047 /* Need CCI between commands */
1048 if (lnext(l) != NULL)
1049 CommandCounterIncrement();
1053 * The multiple commands generated here are stashed
1054 * individually, so disable collection below.
1056 commandCollected = true;
1060 case T_AlterTableStmt:
1062 AlterTableStmt *atstmt = (AlterTableStmt *) parsetree;
1069 * Figure out lock mode, and acquire lock. This also does
1070 * basic permissions checks, so that we won't wait for a
1071 * lock on (for example) a relation on which we have no
1074 lockmode = AlterTableGetLockLevel(atstmt->cmds);
1075 relid = AlterTableLookupRelation(atstmt, lockmode);
1077 if (OidIsValid(relid))
1079 /* Run parse analysis ... */
1080 stmts = transformAlterTableStmt(relid, atstmt,
1083 /* ... ensure we have an event trigger context ... */
1084 EventTriggerAlterTableStart(parsetree);
1085 EventTriggerAlterTableRelid(relid);
1090 Node *stmt = (Node *) lfirst(l);
1092 if (IsA(stmt, AlterTableStmt))
1094 /* Do the table alteration proper */
1095 AlterTable(relid, lockmode,
1096 (AlterTableStmt *) stmt);
1101 * Recurse for anything else. If we need to
1102 * do so, "close" the current complex-command
1103 * set, and start a new one at the bottom;
1104 * this is needed to ensure the ordering of
1105 * queued commands is consistent with the way
1106 * they are executed here.
1108 EventTriggerAlterTableEnd();
1109 ProcessUtility(stmt,
1111 PROCESS_UTILITY_SUBCOMMAND,
1115 EventTriggerAlterTableStart(parsetree);
1116 EventTriggerAlterTableRelid(relid);
1119 /* Need CCI between commands */
1120 if (lnext(l) != NULL)
1121 CommandCounterIncrement();
1125 EventTriggerAlterTableEnd();
1129 (errmsg("relation \"%s\" does not exist, skipping",
1130 atstmt->relation->relname)));
1133 /* ALTER TABLE stashes commands internally */
1134 commandCollected = true;
1137 case T_AlterDomainStmt:
1139 AlterDomainStmt *stmt = (AlterDomainStmt *) parsetree;
1142 * Some or all of these functions are recursive to cover
1143 * inherited things, so permission checks are done there.
1145 switch (stmt->subtype)
1147 case 'T': /* ALTER DOMAIN DEFAULT */
1150 * Recursively alter column default for table and,
1151 * if requested, for descendants
1154 AlterDomainDefault(stmt->typeName,
1157 case 'N': /* ALTER DOMAIN DROP NOT NULL */
1159 AlterDomainNotNull(stmt->typeName,
1162 case 'O': /* ALTER DOMAIN SET NOT NULL */
1164 AlterDomainNotNull(stmt->typeName,
1167 case 'C': /* ADD CONSTRAINT */
1169 AlterDomainAddConstraint(stmt->typeName,
1173 case 'X': /* DROP CONSTRAINT */
1175 AlterDomainDropConstraint(stmt->typeName,
1180 case 'V': /* VALIDATE CONSTRAINT */
1182 AlterDomainValidateConstraint(stmt->typeName,
1186 elog(ERROR, "unrecognized alter domain type: %d",
1187 (int) stmt->subtype);
1194 * ************* object creation / destruction **************
1198 DefineStmt *stmt = (DefineStmt *) parsetree;
1202 case OBJECT_AGGREGATE:
1204 DefineAggregate(pstate, stmt->defnames, stmt->args,
1208 case OBJECT_OPERATOR:
1209 Assert(stmt->args == NIL);
1210 address = DefineOperator(stmt->defnames,
1214 Assert(stmt->args == NIL);
1215 address = DefineType(pstate,
1219 case OBJECT_TSPARSER:
1220 Assert(stmt->args == NIL);
1221 address = DefineTSParser(stmt->defnames,
1224 case OBJECT_TSDICTIONARY:
1225 Assert(stmt->args == NIL);
1226 address = DefineTSDictionary(stmt->defnames,
1229 case OBJECT_TSTEMPLATE:
1230 Assert(stmt->args == NIL);
1231 address = DefineTSTemplate(stmt->defnames,
1234 case OBJECT_TSCONFIGURATION:
1235 Assert(stmt->args == NIL);
1236 address = DefineTSConfiguration(stmt->defnames,
1240 case OBJECT_COLLATION:
1241 Assert(stmt->args == NIL);
1242 address = DefineCollation(pstate,
1247 elog(ERROR, "unrecognized define stmt type: %d",
1254 case T_IndexStmt: /* CREATE INDEX */
1256 IndexStmt *stmt = (IndexStmt *) parsetree;
1260 if (stmt->concurrent)
1261 PreventTransactionChain(isTopLevel,
1262 "CREATE INDEX CONCURRENTLY");
1265 * Look up the relation OID just once, right here at the
1266 * beginning, so that we don't end up repeating the name
1267 * lookup later and latching onto a different relation
1268 * partway through. To avoid lock upgrade hazards, it's
1269 * important that we take the strongest lock that will
1270 * eventually be needed here, so the lockmode calculation
1271 * needs to match what DefineIndex() does.
1273 lockmode = stmt->concurrent ? ShareUpdateExclusiveLock
1276 RangeVarGetRelidExtended(stmt->relation, lockmode,
1278 RangeVarCallbackOwnsRelation,
1281 /* Run parse analysis ... */
1282 stmt = transformIndexStmt(relid, stmt, queryString);
1285 EventTriggerAlterTableStart(parsetree);
1287 DefineIndex(relid, /* OID of heap relation */
1289 InvalidOid, /* no predefined OID */
1290 false, /* is_alter_table */
1291 true, /* check_rights */
1292 false, /* skip_build */
1296 * Add the CREATE INDEX node itself to stash right away;
1297 * if there were any commands stashed in the ALTER TABLE
1298 * code, we need them to appear after this one.
1300 EventTriggerCollectSimpleCommand(address, secondaryObject,
1302 commandCollected = true;
1303 EventTriggerAlterTableEnd();
1307 case T_CreateExtensionStmt:
1308 address = CreateExtension(pstate, (CreateExtensionStmt *) parsetree);
1311 case T_AlterExtensionStmt:
1312 address = ExecAlterExtensionStmt(pstate, (AlterExtensionStmt *) parsetree);
1315 case T_AlterExtensionContentsStmt:
1316 address = ExecAlterExtensionContentsStmt((AlterExtensionContentsStmt *) parsetree,
1320 case T_CreateFdwStmt:
1321 address = CreateForeignDataWrapper((CreateFdwStmt *) parsetree);
1324 case T_AlterFdwStmt:
1325 address = AlterForeignDataWrapper((AlterFdwStmt *) parsetree);
1328 case T_CreateForeignServerStmt:
1329 address = CreateForeignServer((CreateForeignServerStmt *) parsetree);
1332 case T_AlterForeignServerStmt:
1333 address = AlterForeignServer((AlterForeignServerStmt *) parsetree);
1336 case T_CreateUserMappingStmt:
1337 address = CreateUserMapping((CreateUserMappingStmt *) parsetree);
1340 case T_AlterUserMappingStmt:
1341 address = AlterUserMapping((AlterUserMappingStmt *) parsetree);
1344 case T_DropUserMappingStmt:
1345 RemoveUserMapping((DropUserMappingStmt *) parsetree);
1346 /* no commands stashed for DROP */
1347 commandCollected = true;
1350 case T_ImportForeignSchemaStmt:
1351 ImportForeignSchema((ImportForeignSchemaStmt *) parsetree);
1352 /* commands are stashed inside ImportForeignSchema */
1353 commandCollected = true;
1356 case T_CompositeTypeStmt: /* CREATE TYPE (composite) */
1358 CompositeTypeStmt *stmt = (CompositeTypeStmt *) parsetree;
1360 address = DefineCompositeType(stmt->typevar,
1365 case T_CreateEnumStmt: /* CREATE TYPE AS ENUM */
1366 address = DefineEnum((CreateEnumStmt *) parsetree);
1369 case T_CreateRangeStmt: /* CREATE TYPE AS RANGE */
1370 address = DefineRange((CreateRangeStmt *) parsetree);
1373 case T_AlterEnumStmt: /* ALTER TYPE (enum) */
1374 address = AlterEnum((AlterEnumStmt *) parsetree);
1377 case T_ViewStmt: /* CREATE VIEW */
1378 EventTriggerAlterTableStart(parsetree);
1379 address = DefineView((ViewStmt *) parsetree, queryString);
1380 EventTriggerCollectSimpleCommand(address, secondaryObject,
1382 /* stashed internally */
1383 commandCollected = true;
1384 EventTriggerAlterTableEnd();
1387 case T_CreateFunctionStmt: /* CREATE FUNCTION */
1388 address = CreateFunction(pstate, (CreateFunctionStmt *) parsetree);
1391 case T_AlterFunctionStmt: /* ALTER FUNCTION */
1392 address = AlterFunction(pstate, (AlterFunctionStmt *) parsetree);
1395 case T_RuleStmt: /* CREATE RULE */
1396 address = DefineRule((RuleStmt *) parsetree, queryString);
1399 case T_CreateSeqStmt:
1400 address = DefineSequence(pstate, (CreateSeqStmt *) parsetree);
1403 case T_AlterSeqStmt:
1404 address = AlterSequence(pstate, (AlterSeqStmt *) parsetree);
1407 case T_CreateTableAsStmt:
1408 address = ExecCreateTableAs((CreateTableAsStmt *) parsetree,
1409 queryString, params, completionTag);
1412 case T_RefreshMatViewStmt:
1415 * REFRSH CONCURRENTLY executes some DDL commands internally.
1416 * Inhibit DDL command collection here to avoid those commands
1417 * from showing up in the deparsed command queue. The refresh
1418 * command itself is queued, which is enough.
1420 EventTriggerInhibitCommandCollection();
1423 address = ExecRefreshMatView((RefreshMatViewStmt *) parsetree,
1424 queryString, params, completionTag);
1428 EventTriggerUndoInhibitCommandCollection();
1432 EventTriggerUndoInhibitCommandCollection();
1435 case T_CreateTrigStmt:
1436 address = CreateTrigger((CreateTrigStmt *) parsetree,
1437 queryString, InvalidOid, InvalidOid,
1438 InvalidOid, InvalidOid, false);
1441 case T_CreatePLangStmt:
1442 address = CreateProceduralLanguage((CreatePLangStmt *) parsetree);
1445 case T_CreateDomainStmt:
1446 address = DefineDomain((CreateDomainStmt *) parsetree);
1449 case T_CreateConversionStmt:
1450 address = CreateConversionCommand((CreateConversionStmt *) parsetree);
1453 case T_CreateCastStmt:
1454 address = CreateCast((CreateCastStmt *) parsetree);
1457 case T_CreateOpClassStmt:
1458 DefineOpClass((CreateOpClassStmt *) parsetree);
1459 /* command is stashed in DefineOpClass */
1460 commandCollected = true;
1463 case T_CreateOpFamilyStmt:
1464 address = DefineOpFamily((CreateOpFamilyStmt *) parsetree);
1467 case T_CreateTransformStmt:
1468 address = CreateTransform((CreateTransformStmt *) parsetree);
1471 case T_AlterOpFamilyStmt:
1472 AlterOpFamily((AlterOpFamilyStmt *) parsetree);
1473 /* commands are stashed in AlterOpFamily */
1474 commandCollected = true;
1477 case T_AlterTSDictionaryStmt:
1478 address = AlterTSDictionary((AlterTSDictionaryStmt *) parsetree);
1481 case T_AlterTSConfigurationStmt:
1482 AlterTSConfiguration((AlterTSConfigurationStmt *) parsetree);
1484 * Commands are stashed in MakeConfigurationMapping and
1485 * DropConfigurationMapping, which are called from
1486 * AlterTSConfiguration
1488 commandCollected = true;
1491 case T_AlterTableMoveAllStmt:
1492 AlterTableMoveAll((AlterTableMoveAllStmt *) parsetree);
1493 /* commands are stashed in AlterTableMoveAll */
1494 commandCollected = true;
1498 ExecDropStmt((DropStmt *) parsetree, isTopLevel);
1499 /* no commands stashed for DROP */
1500 commandCollected = true;
1504 address = ExecRenameStmt((RenameStmt *) parsetree);
1507 case T_AlterObjectDependsStmt:
1509 ExecAlterObjectDependsStmt((AlterObjectDependsStmt *) parsetree,
1513 case T_AlterObjectSchemaStmt:
1515 ExecAlterObjectSchemaStmt((AlterObjectSchemaStmt *) parsetree,
1519 case T_AlterOwnerStmt:
1520 address = ExecAlterOwnerStmt((AlterOwnerStmt *) parsetree);
1523 case T_AlterOperatorStmt:
1524 address = AlterOperator((AlterOperatorStmt *) parsetree);
1528 address = CommentObject((CommentStmt *) parsetree);
1532 ExecuteGrantStmt((GrantStmt *) parsetree);
1533 /* commands are stashed in ExecGrantStmt_oids */
1534 commandCollected = true;
1537 case T_DropOwnedStmt:
1538 DropOwnedObjects((DropOwnedStmt *) parsetree);
1539 /* no commands stashed for DROP */
1540 commandCollected = true;
1543 case T_AlterDefaultPrivilegesStmt:
1544 ExecAlterDefaultPrivilegesStmt(pstate, (AlterDefaultPrivilegesStmt *) parsetree);
1545 EventTriggerCollectAlterDefPrivs((AlterDefaultPrivilegesStmt *) parsetree);
1546 commandCollected = true;
1549 case T_CreatePolicyStmt: /* CREATE POLICY */
1550 address = CreatePolicy((CreatePolicyStmt *) parsetree);
1553 case T_AlterPolicyStmt: /* ALTER POLICY */
1554 address = AlterPolicy((AlterPolicyStmt *) parsetree);
1557 case T_SecLabelStmt:
1558 address = ExecSecLabelStmt((SecLabelStmt *) parsetree);
1561 case T_CreateAmStmt:
1562 address = CreateAccessMethod((CreateAmStmt *) parsetree);
1566 elog(ERROR, "unrecognized node type: %d",
1567 (int) nodeTag(parsetree));
1572 * Remember the object so that ddl_command_end event triggers have
1575 if (!commandCollected)
1576 EventTriggerCollectSimpleCommand(address, secondaryObject,
1579 if (isCompleteQuery)
1581 EventTriggerSQLDrop(parsetree);
1582 EventTriggerDDLCommandEnd(parsetree);
1588 EventTriggerEndCompleteQuery();
1594 EventTriggerEndCompleteQuery();
1598 * Dispatch function for DropStmt
1601 ExecDropStmt(DropStmt *stmt, bool isTopLevel)
1603 switch (stmt->removeType)
1606 if (stmt->concurrent)
1607 PreventTransactionChain(isTopLevel,
1608 "DROP INDEX CONCURRENTLY");
1612 case OBJECT_SEQUENCE:
1614 case OBJECT_MATVIEW:
1615 case OBJECT_FOREIGN_TABLE:
1616 RemoveRelations(stmt);
1619 RemoveObjects(stmt);
1626 * UtilityReturnsTuples
1627 * Return "true" if this utility statement will send output to the
1630 * Generally, there should be a case here for each case in ProcessUtility
1631 * where "dest" is passed on.
1634 UtilityReturnsTuples(Node *parsetree)
1636 switch (nodeTag(parsetree))
1640 FetchStmt *stmt = (FetchStmt *) parsetree;
1645 portal = GetPortalByName(stmt->portalname);
1646 if (!PortalIsValid(portal))
1647 return false; /* not our business to raise error */
1648 return portal->tupDesc ? true : false;
1653 ExecuteStmt *stmt = (ExecuteStmt *) parsetree;
1654 PreparedStatement *entry;
1656 entry = FetchPreparedStatement(stmt->name, false);
1658 return false; /* not our business to raise error */
1659 if (entry->plansource->resultDesc)
1667 case T_VariableShowStmt:
1676 * UtilityTupleDescriptor
1677 * Fetch the actual output tuple descriptor for a utility statement
1678 * for which UtilityReturnsTuples() previously returned "true".
1680 * The returned descriptor is created in (or copied into) the current memory
1684 UtilityTupleDescriptor(Node *parsetree)
1686 switch (nodeTag(parsetree))
1690 FetchStmt *stmt = (FetchStmt *) parsetree;
1695 portal = GetPortalByName(stmt->portalname);
1696 if (!PortalIsValid(portal))
1697 return NULL; /* not our business to raise error */
1698 return CreateTupleDescCopy(portal->tupDesc);
1703 ExecuteStmt *stmt = (ExecuteStmt *) parsetree;
1704 PreparedStatement *entry;
1706 entry = FetchPreparedStatement(stmt->name, false);
1708 return NULL; /* not our business to raise error */
1709 return FetchPreparedStatementResultDesc(entry);
1713 return ExplainResultDesc((ExplainStmt *) parsetree);
1715 case T_VariableShowStmt:
1717 VariableShowStmt *n = (VariableShowStmt *) parsetree;
1719 return GetPGVariableResultDesc(n->name);
1729 * QueryReturnsTuples
1730 * Return "true" if this Query will send output to the destination.
1734 QueryReturnsTuples(Query *parsetree)
1736 switch (parsetree->commandType)
1739 /* returns tuples ... unless it's DECLARE CURSOR */
1740 if (parsetree->utilityStmt == NULL)
1746 /* the forms with RETURNING return tuples */
1747 if (parsetree->returningList)
1751 return UtilityReturnsTuples(parsetree->utilityStmt);
1754 /* probably shouldn't get here */
1757 return false; /* default */
1763 * UtilityContainsQuery
1764 * Return the contained Query, or NULL if there is none
1766 * Certain utility statements, such as EXPLAIN, contain a plannable Query.
1767 * This function encapsulates knowledge of exactly which ones do.
1768 * We assume it is invoked only on already-parse-analyzed statements
1769 * (else the contained parsetree isn't a Query yet).
1771 * In some cases (currently, only EXPLAIN of CREATE TABLE AS/SELECT INTO and
1772 * CREATE MATERIALIZED VIEW), potentially Query-containing utility statements
1773 * can be nested. This function will drill down to a non-utility Query, or
1774 * return NULL if none.
1777 UtilityContainsQuery(Node *parsetree)
1781 switch (nodeTag(parsetree))
1784 qry = (Query *) ((ExplainStmt *) parsetree)->query;
1785 Assert(IsA(qry, Query));
1786 if (qry->commandType == CMD_UTILITY)
1787 return UtilityContainsQuery(qry->utilityStmt);
1790 case T_CreateTableAsStmt:
1791 qry = (Query *) ((CreateTableAsStmt *) parsetree)->query;
1792 Assert(IsA(qry, Query));
1793 if (qry->commandType == CMD_UTILITY)
1794 return UtilityContainsQuery(qry->utilityStmt);
1804 * AlterObjectTypeCommandTag
1805 * helper function for CreateCommandTag
1807 * This covers most cases where ALTER is used with an ObjectType enum.
1810 AlterObjectTypeCommandTag(ObjectType objtype)
1816 case OBJECT_AGGREGATE:
1817 tag = "ALTER AGGREGATE";
1819 case OBJECT_ATTRIBUTE:
1825 case OBJECT_COLLATION:
1826 tag = "ALTER COLLATION";
1829 tag = "ALTER TABLE";
1831 case OBJECT_CONVERSION:
1832 tag = "ALTER CONVERSION";
1834 case OBJECT_DATABASE:
1835 tag = "ALTER DATABASE";
1838 case OBJECT_DOMCONSTRAINT:
1839 tag = "ALTER DOMAIN";
1841 case OBJECT_EXTENSION:
1842 tag = "ALTER EXTENSION";
1845 tag = "ALTER FOREIGN DATA WRAPPER";
1847 case OBJECT_FOREIGN_SERVER:
1848 tag = "ALTER SERVER";
1850 case OBJECT_FOREIGN_TABLE:
1851 tag = "ALTER FOREIGN TABLE";
1853 case OBJECT_FUNCTION:
1854 tag = "ALTER FUNCTION";
1857 tag = "ALTER INDEX";
1859 case OBJECT_LANGUAGE:
1860 tag = "ALTER LANGUAGE";
1862 case OBJECT_LARGEOBJECT:
1863 tag = "ALTER LARGE OBJECT";
1865 case OBJECT_OPCLASS:
1866 tag = "ALTER OPERATOR CLASS";
1868 case OBJECT_OPERATOR:
1869 tag = "ALTER OPERATOR";
1871 case OBJECT_OPFAMILY:
1872 tag = "ALTER OPERATOR FAMILY";
1875 tag = "ALTER POLICY";
1884 tag = "ALTER SCHEMA";
1886 case OBJECT_SEQUENCE:
1887 tag = "ALTER SEQUENCE";
1890 case OBJECT_TABCONSTRAINT:
1891 tag = "ALTER TABLE";
1893 case OBJECT_TABLESPACE:
1894 tag = "ALTER TABLESPACE";
1896 case OBJECT_TRIGGER:
1897 tag = "ALTER TRIGGER";
1899 case OBJECT_EVENT_TRIGGER:
1900 tag = "ALTER EVENT TRIGGER";
1902 case OBJECT_TSCONFIGURATION:
1903 tag = "ALTER TEXT SEARCH CONFIGURATION";
1905 case OBJECT_TSDICTIONARY:
1906 tag = "ALTER TEXT SEARCH DICTIONARY";
1908 case OBJECT_TSPARSER:
1909 tag = "ALTER TEXT SEARCH PARSER";
1911 case OBJECT_TSTEMPLATE:
1912 tag = "ALTER TEXT SEARCH TEMPLATE";
1920 case OBJECT_MATVIEW:
1921 tag = "ALTER MATERIALIZED VIEW";
1933 * utility to get a string representation of the command operation,
1934 * given either a raw (un-analyzed) parsetree or a planned query.
1936 * This must handle all command types, but since the vast majority
1937 * of 'em are utility commands, it seems sensible to keep it here.
1939 * NB: all result strings must be shorter than COMPLETION_TAG_BUFSIZE.
1940 * Also, the result must point at a true constant (permanent storage).
1943 CreateCommandTag(Node *parsetree)
1947 switch (nodeTag(parsetree))
1949 /* raw plannable queries */
1966 /* utility statements --- same whether raw or cooked */
1967 case T_TransactionStmt:
1969 TransactionStmt *stmt = (TransactionStmt *) parsetree;
1973 case TRANS_STMT_BEGIN:
1977 case TRANS_STMT_START:
1978 tag = "START TRANSACTION";
1981 case TRANS_STMT_COMMIT:
1985 case TRANS_STMT_ROLLBACK:
1986 case TRANS_STMT_ROLLBACK_TO:
1990 case TRANS_STMT_SAVEPOINT:
1994 case TRANS_STMT_RELEASE:
1998 case TRANS_STMT_PREPARE:
1999 tag = "PREPARE TRANSACTION";
2002 case TRANS_STMT_COMMIT_PREPARED:
2003 tag = "COMMIT PREPARED";
2006 case TRANS_STMT_ROLLBACK_PREPARED:
2007 tag = "ROLLBACK PREPARED";
2017 case T_DeclareCursorStmt:
2018 tag = "DECLARE CURSOR";
2021 case T_ClosePortalStmt:
2023 ClosePortalStmt *stmt = (ClosePortalStmt *) parsetree;
2025 if (stmt->portalname == NULL)
2026 tag = "CLOSE CURSOR ALL";
2028 tag = "CLOSE CURSOR";
2034 FetchStmt *stmt = (FetchStmt *) parsetree;
2036 tag = (stmt->ismove) ? "MOVE" : "FETCH";
2040 case T_CreateDomainStmt:
2041 tag = "CREATE DOMAIN";
2044 case T_CreateSchemaStmt:
2045 tag = "CREATE SCHEMA";
2049 tag = "CREATE TABLE";
2052 case T_CreateTableSpaceStmt:
2053 tag = "CREATE TABLESPACE";
2056 case T_DropTableSpaceStmt:
2057 tag = "DROP TABLESPACE";
2060 case T_AlterTableSpaceOptionsStmt:
2061 tag = "ALTER TABLESPACE";
2064 case T_CreateExtensionStmt:
2065 tag = "CREATE EXTENSION";
2068 case T_AlterExtensionStmt:
2069 tag = "ALTER EXTENSION";
2072 case T_AlterExtensionContentsStmt:
2073 tag = "ALTER EXTENSION";
2076 case T_CreateFdwStmt:
2077 tag = "CREATE FOREIGN DATA WRAPPER";
2080 case T_AlterFdwStmt:
2081 tag = "ALTER FOREIGN DATA WRAPPER";
2084 case T_CreateForeignServerStmt:
2085 tag = "CREATE SERVER";
2088 case T_AlterForeignServerStmt:
2089 tag = "ALTER SERVER";
2092 case T_CreateUserMappingStmt:
2093 tag = "CREATE USER MAPPING";
2096 case T_AlterUserMappingStmt:
2097 tag = "ALTER USER MAPPING";
2100 case T_DropUserMappingStmt:
2101 tag = "DROP USER MAPPING";
2104 case T_CreateForeignTableStmt:
2105 tag = "CREATE FOREIGN TABLE";
2108 case T_ImportForeignSchemaStmt:
2109 tag = "IMPORT FOREIGN SCHEMA";
2113 switch (((DropStmt *) parsetree)->removeType)
2118 case OBJECT_SEQUENCE:
2119 tag = "DROP SEQUENCE";
2124 case OBJECT_MATVIEW:
2125 tag = "DROP MATERIALIZED VIEW";
2134 tag = "DROP DOMAIN";
2136 case OBJECT_COLLATION:
2137 tag = "DROP COLLATION";
2139 case OBJECT_CONVERSION:
2140 tag = "DROP CONVERSION";
2143 tag = "DROP SCHEMA";
2145 case OBJECT_TSPARSER:
2146 tag = "DROP TEXT SEARCH PARSER";
2148 case OBJECT_TSDICTIONARY:
2149 tag = "DROP TEXT SEARCH DICTIONARY";
2151 case OBJECT_TSTEMPLATE:
2152 tag = "DROP TEXT SEARCH TEMPLATE";
2154 case OBJECT_TSCONFIGURATION:
2155 tag = "DROP TEXT SEARCH CONFIGURATION";
2157 case OBJECT_FOREIGN_TABLE:
2158 tag = "DROP FOREIGN TABLE";
2160 case OBJECT_EXTENSION:
2161 tag = "DROP EXTENSION";
2163 case OBJECT_FUNCTION:
2164 tag = "DROP FUNCTION";
2166 case OBJECT_AGGREGATE:
2167 tag = "DROP AGGREGATE";
2169 case OBJECT_OPERATOR:
2170 tag = "DROP OPERATOR";
2172 case OBJECT_LANGUAGE:
2173 tag = "DROP LANGUAGE";
2178 case OBJECT_TRIGGER:
2179 tag = "DROP TRIGGER";
2181 case OBJECT_EVENT_TRIGGER:
2182 tag = "DROP EVENT TRIGGER";
2188 tag = "DROP FOREIGN DATA WRAPPER";
2190 case OBJECT_FOREIGN_SERVER:
2191 tag = "DROP SERVER";
2193 case OBJECT_OPCLASS:
2194 tag = "DROP OPERATOR CLASS";
2196 case OBJECT_OPFAMILY:
2197 tag = "DROP OPERATOR FAMILY";
2200 tag = "DROP POLICY";
2202 case OBJECT_TRANSFORM:
2203 tag = "DROP TRANSFORM";
2205 case OBJECT_ACCESS_METHOD:
2206 tag = "DROP ACCESS METHOD";
2213 case T_TruncateStmt:
2214 tag = "TRUNCATE TABLE";
2221 case T_SecLabelStmt:
2222 tag = "SECURITY LABEL";
2230 tag = AlterObjectTypeCommandTag(((RenameStmt *) parsetree)->renameType);
2233 case T_AlterObjectDependsStmt:
2234 tag = AlterObjectTypeCommandTag(((AlterObjectDependsStmt *) parsetree)->objectType);
2237 case T_AlterObjectSchemaStmt:
2238 tag = AlterObjectTypeCommandTag(((AlterObjectSchemaStmt *) parsetree)->objectType);
2241 case T_AlterOwnerStmt:
2242 tag = AlterObjectTypeCommandTag(((AlterOwnerStmt *) parsetree)->objectType);
2245 case T_AlterTableMoveAllStmt:
2246 tag = AlterObjectTypeCommandTag(((AlterTableMoveAllStmt *) parsetree)->objtype);
2249 case T_AlterTableStmt:
2250 tag = AlterObjectTypeCommandTag(((AlterTableStmt *) parsetree)->relkind);
2253 case T_AlterDomainStmt:
2254 tag = "ALTER DOMAIN";
2257 case T_AlterFunctionStmt:
2258 tag = "ALTER FUNCTION";
2263 GrantStmt *stmt = (GrantStmt *) parsetree;
2265 tag = (stmt->is_grant) ? "GRANT" : "REVOKE";
2269 case T_GrantRoleStmt:
2271 GrantRoleStmt *stmt = (GrantRoleStmt *) parsetree;
2273 tag = (stmt->is_grant) ? "GRANT ROLE" : "REVOKE ROLE";
2277 case T_AlterDefaultPrivilegesStmt:
2278 tag = "ALTER DEFAULT PRIVILEGES";
2282 switch (((DefineStmt *) parsetree)->kind)
2284 case OBJECT_AGGREGATE:
2285 tag = "CREATE AGGREGATE";
2287 case OBJECT_OPERATOR:
2288 tag = "CREATE OPERATOR";
2291 tag = "CREATE TYPE";
2293 case OBJECT_TSPARSER:
2294 tag = "CREATE TEXT SEARCH PARSER";
2296 case OBJECT_TSDICTIONARY:
2297 tag = "CREATE TEXT SEARCH DICTIONARY";
2299 case OBJECT_TSTEMPLATE:
2300 tag = "CREATE TEXT SEARCH TEMPLATE";
2302 case OBJECT_TSCONFIGURATION:
2303 tag = "CREATE TEXT SEARCH CONFIGURATION";
2305 case OBJECT_COLLATION:
2306 tag = "CREATE COLLATION";
2308 case OBJECT_ACCESS_METHOD:
2309 tag = "CREATE ACCESS METHOD";
2316 case T_CompositeTypeStmt:
2317 tag = "CREATE TYPE";
2320 case T_CreateEnumStmt:
2321 tag = "CREATE TYPE";
2324 case T_CreateRangeStmt:
2325 tag = "CREATE TYPE";
2328 case T_AlterEnumStmt:
2333 tag = "CREATE VIEW";
2336 case T_CreateFunctionStmt:
2337 tag = "CREATE FUNCTION";
2341 tag = "CREATE INDEX";
2345 tag = "CREATE RULE";
2348 case T_CreateSeqStmt:
2349 tag = "CREATE SEQUENCE";
2352 case T_AlterSeqStmt:
2353 tag = "ALTER SEQUENCE";
2360 case T_CreatedbStmt:
2361 tag = "CREATE DATABASE";
2364 case T_AlterDatabaseStmt:
2365 tag = "ALTER DATABASE";
2368 case T_AlterDatabaseSetStmt:
2369 tag = "ALTER DATABASE";
2373 tag = "DROP DATABASE";
2384 case T_UnlistenStmt:
2397 if (((VacuumStmt *) parsetree)->options & VACOPT_VACUUM)
2407 case T_CreateTableAsStmt:
2408 switch (((CreateTableAsStmt *) parsetree)->relkind)
2411 if (((CreateTableAsStmt *) parsetree)->is_select_into)
2412 tag = "SELECT INTO";
2414 tag = "CREATE TABLE AS";
2416 case OBJECT_MATVIEW:
2417 tag = "CREATE MATERIALIZED VIEW";
2424 case T_RefreshMatViewStmt:
2425 tag = "REFRESH MATERIALIZED VIEW";
2428 case T_AlterSystemStmt:
2429 tag = "ALTER SYSTEM";
2432 case T_VariableSetStmt:
2433 switch (((VariableSetStmt *) parsetree)->kind)
2436 case VAR_SET_CURRENT:
2437 case VAR_SET_DEFAULT:
2450 case T_VariableShowStmt:
2455 switch (((DiscardStmt *) parsetree)->target)
2458 tag = "DISCARD ALL";
2461 tag = "DISCARD PLANS";
2464 tag = "DISCARD TEMP";
2466 case DISCARD_SEQUENCES:
2467 tag = "DISCARD SEQUENCES";
2474 case T_CreateTransformStmt:
2475 tag = "CREATE TRANSFORM";
2478 case T_CreateTrigStmt:
2479 tag = "CREATE TRIGGER";
2482 case T_CreateEventTrigStmt:
2483 tag = "CREATE EVENT TRIGGER";
2486 case T_AlterEventTrigStmt:
2487 tag = "ALTER EVENT TRIGGER";
2490 case T_CreatePLangStmt:
2491 tag = "CREATE LANGUAGE";
2494 case T_CreateRoleStmt:
2495 tag = "CREATE ROLE";
2498 case T_AlterRoleStmt:
2502 case T_AlterRoleSetStmt:
2506 case T_DropRoleStmt:
2510 case T_DropOwnedStmt:
2514 case T_ReassignOwnedStmt:
2515 tag = "REASSIGN OWNED";
2522 case T_ConstraintsSetStmt:
2523 tag = "SET CONSTRAINTS";
2526 case T_CheckPointStmt:
2534 case T_CreateConversionStmt:
2535 tag = "CREATE CONVERSION";
2538 case T_CreateCastStmt:
2539 tag = "CREATE CAST";
2542 case T_CreateOpClassStmt:
2543 tag = "CREATE OPERATOR CLASS";
2546 case T_CreateOpFamilyStmt:
2547 tag = "CREATE OPERATOR FAMILY";
2550 case T_AlterOpFamilyStmt:
2551 tag = "ALTER OPERATOR FAMILY";
2554 case T_AlterOperatorStmt:
2555 tag = "ALTER OPERATOR";
2558 case T_AlterTSDictionaryStmt:
2559 tag = "ALTER TEXT SEARCH DICTIONARY";
2562 case T_AlterTSConfigurationStmt:
2563 tag = "ALTER TEXT SEARCH CONFIGURATION";
2566 case T_CreatePolicyStmt:
2567 tag = "CREATE POLICY";
2570 case T_AlterPolicyStmt:
2571 tag = "ALTER POLICY";
2574 case T_CreateAmStmt:
2575 tag = "CREATE ACCESS METHOD";
2586 case T_DeallocateStmt:
2588 DeallocateStmt *stmt = (DeallocateStmt *) parsetree;
2590 if (stmt->name == NULL)
2591 tag = "DEALLOCATE ALL";
2597 /* already-planned queries */
2600 PlannedStmt *stmt = (PlannedStmt *) parsetree;
2602 switch (stmt->commandType)
2607 * We take a little extra care here so that the result
2608 * will be useful for complaints about read-only
2611 if (stmt->utilityStmt != NULL)
2613 Assert(IsA(stmt->utilityStmt, DeclareCursorStmt));
2614 tag = "DECLARE CURSOR";
2616 else if (stmt->rowMarks != NIL)
2618 /* not 100% but probably close enough */
2619 switch (((PlanRowMark *) linitial(stmt->rowMarks))->strength)
2621 case LCS_FORKEYSHARE:
2622 tag = "SELECT FOR KEY SHARE";
2625 tag = "SELECT FOR SHARE";
2627 case LCS_FORNOKEYUPDATE:
2628 tag = "SELECT FOR NO KEY UPDATE";
2631 tag = "SELECT FOR UPDATE";
2651 elog(WARNING, "unrecognized commandType: %d",
2652 (int) stmt->commandType);
2659 /* parsed-and-rewritten-but-not-planned queries */
2662 Query *stmt = (Query *) parsetree;
2664 switch (stmt->commandType)
2669 * We take a little extra care here so that the result
2670 * will be useful for complaints about read-only
2673 if (stmt->utilityStmt != NULL)
2675 Assert(IsA(stmt->utilityStmt, DeclareCursorStmt));
2676 tag = "DECLARE CURSOR";
2678 else if (stmt->rowMarks != NIL)
2680 /* not 100% but probably close enough */
2681 switch (((RowMarkClause *) linitial(stmt->rowMarks))->strength)
2683 case LCS_FORKEYSHARE:
2684 tag = "SELECT FOR KEY SHARE";
2687 tag = "SELECT FOR SHARE";
2689 case LCS_FORNOKEYUPDATE:
2690 tag = "SELECT FOR NO KEY UPDATE";
2693 tag = "SELECT FOR UPDATE";
2713 tag = CreateCommandTag(stmt->utilityStmt);
2716 elog(WARNING, "unrecognized commandType: %d",
2717 (int) stmt->commandType);
2725 elog(WARNING, "unrecognized node type: %d",
2726 (int) nodeTag(parsetree));
2736 * GetCommandLogLevel
2737 * utility to get the minimum log_statement level for a command,
2738 * given either a raw (un-analyzed) parsetree or a planned query.
2740 * This must handle all command types, but since the vast majority
2741 * of 'em are utility commands, it seems sensible to keep it here.
2744 GetCommandLogLevel(Node *parsetree)
2748 switch (nodeTag(parsetree))
2750 /* raw plannable queries */
2758 if (((SelectStmt *) parsetree)->intoClause)
2759 lev = LOGSTMT_DDL; /* SELECT INTO */
2764 /* utility statements --- same whether raw or cooked */
2765 case T_TransactionStmt:
2769 case T_DeclareCursorStmt:
2773 case T_ClosePortalStmt:
2781 case T_CreateSchemaStmt:
2786 case T_CreateForeignTableStmt:
2790 case T_CreateTableSpaceStmt:
2791 case T_DropTableSpaceStmt:
2792 case T_AlterTableSpaceOptionsStmt:
2796 case T_CreateExtensionStmt:
2797 case T_AlterExtensionStmt:
2798 case T_AlterExtensionContentsStmt:
2802 case T_CreateFdwStmt:
2803 case T_AlterFdwStmt:
2804 case T_CreateForeignServerStmt:
2805 case T_AlterForeignServerStmt:
2806 case T_CreateUserMappingStmt:
2807 case T_AlterUserMappingStmt:
2808 case T_DropUserMappingStmt:
2809 case T_ImportForeignSchemaStmt:
2817 case T_TruncateStmt:
2825 case T_SecLabelStmt:
2830 if (((CopyStmt *) parsetree)->is_from)
2838 PrepareStmt *stmt = (PrepareStmt *) parsetree;
2840 /* Look through a PREPARE to the contained stmt */
2841 lev = GetCommandLogLevel(stmt->query);
2847 ExecuteStmt *stmt = (ExecuteStmt *) parsetree;
2848 PreparedStatement *ps;
2850 /* Look through an EXECUTE to the referenced stmt */
2851 ps = FetchPreparedStatement(stmt->name, false);
2852 if (ps && ps->plansource->raw_parse_tree)
2853 lev = GetCommandLogLevel(ps->plansource->raw_parse_tree);
2859 case T_DeallocateStmt:
2867 case T_AlterObjectDependsStmt:
2871 case T_AlterObjectSchemaStmt:
2875 case T_AlterOwnerStmt:
2879 case T_AlterTableMoveAllStmt:
2880 case T_AlterTableStmt:
2884 case T_AlterDomainStmt:
2892 case T_GrantRoleStmt:
2896 case T_AlterDefaultPrivilegesStmt:
2904 case T_CompositeTypeStmt:
2908 case T_CreateEnumStmt:
2912 case T_CreateRangeStmt:
2916 case T_AlterEnumStmt:
2924 case T_CreateFunctionStmt:
2928 case T_AlterFunctionStmt:
2940 case T_CreateSeqStmt:
2944 case T_AlterSeqStmt:
2952 case T_CreatedbStmt:
2956 case T_AlterDatabaseStmt:
2960 case T_AlterDatabaseSetStmt:
2976 case T_UnlistenStmt:
2994 ExplainStmt *stmt = (ExplainStmt *) parsetree;
2995 bool analyze = false;
2998 /* Look through an EXPLAIN ANALYZE to the contained stmt */
2999 foreach(lc, stmt->options)
3001 DefElem *opt = (DefElem *) lfirst(lc);
3003 if (strcmp(opt->defname, "analyze") == 0)
3004 analyze = defGetBoolean(opt);
3005 /* don't "break", as explain.c will use the last value */
3008 return GetCommandLogLevel(stmt->query);
3010 /* Plain EXPLAIN isn't so interesting */
3015 case T_CreateTableAsStmt:
3019 case T_RefreshMatViewStmt:
3023 case T_AlterSystemStmt:
3027 case T_VariableSetStmt:
3031 case T_VariableShowStmt:
3039 case T_CreateTrigStmt:
3043 case T_CreateEventTrigStmt:
3047 case T_AlterEventTrigStmt:
3051 case T_CreatePLangStmt:
3055 case T_CreateDomainStmt:
3059 case T_CreateRoleStmt:
3063 case T_AlterRoleStmt:
3067 case T_AlterRoleSetStmt:
3071 case T_DropRoleStmt:
3075 case T_DropOwnedStmt:
3079 case T_ReassignOwnedStmt:
3087 case T_ConstraintsSetStmt:
3091 case T_CheckPointStmt:
3096 lev = LOGSTMT_ALL; /* should this be DDL? */
3099 case T_CreateConversionStmt:
3103 case T_CreateCastStmt:
3107 case T_CreateOpClassStmt:
3111 case T_CreateOpFamilyStmt:
3115 case T_CreateTransformStmt:
3119 case T_AlterOpFamilyStmt:
3123 case T_CreatePolicyStmt:
3127 case T_AlterPolicyStmt:
3131 case T_AlterTSDictionaryStmt:
3135 case T_AlterTSConfigurationStmt:
3139 case T_CreateAmStmt:
3143 /* already-planned queries */
3146 PlannedStmt *stmt = (PlannedStmt *) parsetree;
3148 switch (stmt->commandType)
3161 elog(WARNING, "unrecognized commandType: %d",
3162 (int) stmt->commandType);
3169 /* parsed-and-rewritten-but-not-planned queries */
3172 Query *stmt = (Query *) parsetree;
3174 switch (stmt->commandType)
3187 lev = GetCommandLogLevel(stmt->utilityStmt);
3191 elog(WARNING, "unrecognized commandType: %d",
3192 (int) stmt->commandType);
3201 elog(WARNING, "unrecognized node type: %d",
3202 (int) nodeTag(parsetree));