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-2015, 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(Node *parsetree,
75 const char *queryString,
76 ProcessUtilityContext context,
80 static void ExecDropStmt(DropStmt *stmt, bool isTopLevel);
84 * CommandIsReadOnly: is an executable query read-only?
86 * This is a much stricter test than we apply for XactReadOnly mode;
87 * the query must be *in truth* read-only, because the caller wishes
88 * not to do CommandCounterIncrement for it.
90 * Note: currently no need to support Query nodes here
93 CommandIsReadOnly(Node *parsetree)
95 if (IsA(parsetree, PlannedStmt))
97 PlannedStmt *stmt = (PlannedStmt *) parsetree;
99 switch (stmt->commandType)
102 if (stmt->rowMarks != NIL)
103 return false; /* SELECT FOR [KEY] UPDATE/SHARE */
104 else if (stmt->hasModifyingCTE)
105 return false; /* data-modifying CTE */
113 elog(WARNING, "unrecognized commandType: %d",
114 (int) stmt->commandType);
118 /* For now, treat all utility commands as read/write */
123 * check_xact_readonly: is a utility command read-only?
125 * Here we use the loose rules of XactReadOnly mode: no permanent effects
126 * on the database are allowed.
129 check_xact_readonly(Node *parsetree)
131 /* Only perform the check if we have a reason to do so. */
132 if (!XactReadOnly && !IsInParallelMode())
136 * Note: Commands that need to do more complicated checking are handled
137 * elsewhere, in particular COPY and plannable statements do their own
138 * checking. However they should all call PreventCommandIfReadOnly or
139 * PreventCommandIfParallelMode to actually throw the error.
142 switch (nodeTag(parsetree))
144 case T_AlterDatabaseStmt:
145 case T_AlterDatabaseSetStmt:
146 case T_AlterDomainStmt:
147 case T_AlterFunctionStmt:
148 case T_AlterRoleStmt:
149 case T_AlterRoleSetStmt:
150 case T_AlterObjectSchemaStmt:
151 case T_AlterOwnerStmt:
152 case T_AlterOperatorStmt:
154 case T_AlterTableMoveAllStmt:
155 case T_AlterTableStmt:
159 case T_CreateCastStmt:
160 case T_CreateEventTrigStmt:
161 case T_AlterEventTrigStmt:
162 case T_CreateConversionStmt:
164 case T_CreateDomainStmt:
165 case T_CreateFunctionStmt:
166 case T_CreateRoleStmt:
168 case T_CreatePLangStmt:
169 case T_CreateOpClassStmt:
170 case T_CreateOpFamilyStmt:
171 case T_AlterOpFamilyStmt:
173 case T_CreateSchemaStmt:
174 case T_CreateSeqStmt:
176 case T_CreateTableAsStmt:
177 case T_RefreshMatViewStmt:
178 case T_CreateTableSpaceStmt:
179 case T_CreateTransformStmt:
180 case T_CreateTrigStmt:
181 case T_CompositeTypeStmt:
182 case T_CreateEnumStmt:
183 case T_CreateRangeStmt:
184 case T_AlterEnumStmt:
188 case T_DropTableSpaceStmt:
191 case T_GrantRoleStmt:
192 case T_AlterDefaultPrivilegesStmt:
194 case T_DropOwnedStmt:
195 case T_ReassignOwnedStmt:
196 case T_AlterTSDictionaryStmt:
197 case T_AlterTSConfigurationStmt:
198 case T_CreateExtensionStmt:
199 case T_AlterExtensionStmt:
200 case T_AlterExtensionContentsStmt:
201 case T_CreateFdwStmt:
203 case T_CreateForeignServerStmt:
204 case T_AlterForeignServerStmt:
205 case T_CreateUserMappingStmt:
206 case T_AlterUserMappingStmt:
207 case T_DropUserMappingStmt:
208 case T_AlterTableSpaceOptionsStmt:
209 case T_CreateForeignTableStmt:
210 case T_ImportForeignSchemaStmt:
212 PreventCommandIfReadOnly(CreateCommandTag(parsetree));
213 PreventCommandIfParallelMode(CreateCommandTag(parsetree));
222 * PreventCommandIfReadOnly: throw error if XactReadOnly
224 * This is useful mainly to ensure consistency of the error message wording;
225 * most callers have checked XactReadOnly for themselves.
228 PreventCommandIfReadOnly(const char *cmdname)
232 (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
233 /* translator: %s is name of a SQL command, eg CREATE */
234 errmsg("cannot execute %s in a read-only transaction",
239 * PreventCommandIfParallelMode: throw error if current (sub)transaction is
242 * This is useful mainly to ensure consistency of the error message wording;
243 * most callers have checked IsInParallelMode() for themselves.
246 PreventCommandIfParallelMode(const char *cmdname)
248 if (IsInParallelMode())
250 (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
251 /* translator: %s is name of a SQL command, eg CREATE */
252 errmsg("cannot execute %s during a parallel operation",
257 * PreventCommandDuringRecovery: throw error if RecoveryInProgress
259 * The majority of operations that are unsafe in a Hot Standby slave
260 * will be rejected by XactReadOnly tests. However there are a few
261 * commands that are allowed in "read-only" xacts but cannot be allowed
262 * in Hot Standby mode. Those commands should call this function.
265 PreventCommandDuringRecovery(const char *cmdname)
267 if (RecoveryInProgress())
269 (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
270 /* translator: %s is name of a SQL command, eg CREATE */
271 errmsg("cannot execute %s during recovery",
276 * CheckRestrictedOperation: throw error for hazardous command if we're
277 * inside a security restriction context.
279 * This is needed to protect session-local state for which there is not any
280 * better-defined protection mechanism, such as ownership.
283 CheckRestrictedOperation(const char *cmdname)
285 if (InSecurityRestrictedOperation())
287 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
288 /* translator: %s is name of a SQL command, eg PREPARE */
289 errmsg("cannot execute %s within security-restricted operation",
296 * general utility function invoker
298 * parsetree: the parse tree for the utility statement
299 * queryString: original source text of command
300 * context: identifies source of statement (toplevel client command,
301 * non-toplevel client command, subcommand of a larger utility command)
302 * params: parameters to use during execution
303 * dest: where to send results
304 * completionTag: points to a buffer of size COMPLETION_TAG_BUFSIZE
305 * in which to store a command completion status string.
307 * Notes: as of PG 8.4, caller MUST supply a queryString; it is not
308 * allowed anymore to pass NULL. (If you really don't have source text,
309 * you can pass a constant string, perhaps "(query not available)".)
311 * completionTag is only set nonempty if we want to return a nondefault status.
313 * completionTag may be NULL if caller doesn't want a status string.
316 ProcessUtility(Node *parsetree,
317 const char *queryString,
318 ProcessUtilityContext context,
319 ParamListInfo params,
323 Assert(queryString != NULL); /* required as of 8.4 */
326 * We provide a function hook variable that lets loadable plugins get
327 * control when ProcessUtility is called. Such a plugin would normally
328 * call standard_ProcessUtility().
330 if (ProcessUtility_hook)
331 (*ProcessUtility_hook) (parsetree, queryString,
333 dest, completionTag);
335 standard_ProcessUtility(parsetree, queryString,
337 dest, completionTag);
341 * standard_ProcessUtility itself deals only with utility commands for
342 * which we do not provide event trigger support. Commands that do have
343 * such support are passed down to ProcessUtilitySlow, which contains the
344 * necessary infrastructure for such triggers.
346 * This division is not just for performance: it's critical that the
347 * event trigger code not be invoked when doing START TRANSACTION for
348 * example, because we might need to refresh the event trigger cache,
349 * which requires being in a valid transaction.
352 standard_ProcessUtility(Node *parsetree,
353 const char *queryString,
354 ProcessUtilityContext context,
355 ParamListInfo params,
359 bool isTopLevel = (context == PROCESS_UTILITY_TOPLEVEL);
361 check_xact_readonly(parsetree);
364 completionTag[0] = '\0';
366 switch (nodeTag(parsetree))
369 * ******************** transactions ********************
371 case T_TransactionStmt:
373 TransactionStmt *stmt = (TransactionStmt *) parsetree;
378 * START TRANSACTION, as defined by SQL99: Identical
379 * to BEGIN. Same code for both.
381 case TRANS_STMT_BEGIN:
382 case TRANS_STMT_START:
386 BeginTransactionBlock();
387 foreach(lc, stmt->options)
389 DefElem *item = (DefElem *) lfirst(lc);
391 if (strcmp(item->defname, "transaction_isolation") == 0)
392 SetPGVariable("transaction_isolation",
393 list_make1(item->arg),
395 else if (strcmp(item->defname, "transaction_read_only") == 0)
396 SetPGVariable("transaction_read_only",
397 list_make1(item->arg),
399 else if (strcmp(item->defname, "transaction_deferrable") == 0)
400 SetPGVariable("transaction_deferrable",
401 list_make1(item->arg),
407 case TRANS_STMT_COMMIT:
408 if (!EndTransactionBlock())
410 /* report unsuccessful commit in completionTag */
412 strcpy(completionTag, "ROLLBACK");
416 case TRANS_STMT_PREPARE:
417 PreventCommandDuringRecovery("PREPARE TRANSACTION");
418 if (!PrepareTransactionBlock(stmt->gid))
420 /* report unsuccessful commit in completionTag */
422 strcpy(completionTag, "ROLLBACK");
426 case TRANS_STMT_COMMIT_PREPARED:
427 PreventTransactionChain(isTopLevel, "COMMIT PREPARED");
428 PreventCommandDuringRecovery("COMMIT PREPARED");
429 FinishPreparedTransaction(stmt->gid, true);
432 case TRANS_STMT_ROLLBACK_PREPARED:
433 PreventTransactionChain(isTopLevel, "ROLLBACK PREPARED");
434 PreventCommandDuringRecovery("ROLLBACK PREPARED");
435 FinishPreparedTransaction(stmt->gid, false);
438 case TRANS_STMT_ROLLBACK:
439 UserAbortTransactionBlock();
442 case TRANS_STMT_SAVEPOINT:
447 RequireTransactionChain(isTopLevel, "SAVEPOINT");
449 foreach(cell, stmt->options)
451 DefElem *elem = lfirst(cell);
453 if (strcmp(elem->defname, "savepoint_name") == 0)
454 name = strVal(elem->arg);
457 Assert(PointerIsValid(name));
459 DefineSavepoint(name);
463 case TRANS_STMT_RELEASE:
464 RequireTransactionChain(isTopLevel, "RELEASE SAVEPOINT");
465 ReleaseSavepoint(stmt->options);
468 case TRANS_STMT_ROLLBACK_TO:
469 RequireTransactionChain(isTopLevel, "ROLLBACK TO SAVEPOINT");
470 RollbackToSavepoint(stmt->options);
473 * CommitTransactionCommand is in charge of
474 * re-defining the savepoint again
482 * Portal (cursor) manipulation
484 * Note: DECLARE CURSOR is processed mostly as a SELECT, and
485 * therefore what we will get here is a PlannedStmt not a bare
490 PlannedStmt *stmt = (PlannedStmt *) parsetree;
492 if (stmt->utilityStmt == NULL ||
493 !IsA(stmt->utilityStmt, DeclareCursorStmt))
494 elog(ERROR, "non-DECLARE CURSOR PlannedStmt passed to ProcessUtility");
495 PerformCursorOpen(stmt, params, queryString, isTopLevel);
499 case T_ClosePortalStmt:
501 ClosePortalStmt *stmt = (ClosePortalStmt *) parsetree;
503 CheckRestrictedOperation("CLOSE");
504 PerformPortalClose(stmt->portalname);
509 PerformPortalFetch((FetchStmt *) parsetree, dest,
514 ExecuteDoStmt((DoStmt *) parsetree);
517 case T_CreateTableSpaceStmt:
518 /* no event triggers for global objects */
519 PreventTransactionChain(isTopLevel, "CREATE TABLESPACE");
520 CreateTableSpace((CreateTableSpaceStmt *) parsetree);
523 case T_DropTableSpaceStmt:
524 /* no event triggers for global objects */
525 PreventTransactionChain(isTopLevel, "DROP TABLESPACE");
526 DropTableSpace((DropTableSpaceStmt *) parsetree);
529 case T_AlterTableSpaceOptionsStmt:
530 /* no event triggers for global objects */
531 AlterTableSpaceOptions((AlterTableSpaceOptionsStmt *) parsetree);
535 ExecuteTruncate((TruncateStmt *) parsetree);
542 DoCopy((CopyStmt *) parsetree, queryString, &processed);
544 snprintf(completionTag, COMPLETION_TAG_BUFSIZE,
545 "COPY " UINT64_FORMAT, processed);
550 CheckRestrictedOperation("PREPARE");
551 PrepareQuery((PrepareStmt *) parsetree, queryString);
555 ExecuteQuery((ExecuteStmt *) parsetree, NULL,
557 dest, completionTag);
560 case T_DeallocateStmt:
561 CheckRestrictedOperation("DEALLOCATE");
562 DeallocateQuery((DeallocateStmt *) parsetree);
565 case T_GrantRoleStmt:
566 /* no event triggers for global objects */
567 GrantRole((GrantRoleStmt *) parsetree);
571 /* no event triggers for global objects */
572 PreventTransactionChain(isTopLevel, "CREATE DATABASE");
573 createdb((CreatedbStmt *) parsetree);
576 case T_AlterDatabaseStmt:
577 /* no event triggers for global objects */
578 AlterDatabase((AlterDatabaseStmt *) parsetree, isTopLevel);
581 case T_AlterDatabaseSetStmt:
582 /* no event triggers for global objects */
583 AlterDatabaseSet((AlterDatabaseSetStmt *) parsetree);
588 DropdbStmt *stmt = (DropdbStmt *) parsetree;
590 /* no event triggers for global objects */
591 PreventTransactionChain(isTopLevel, "DROP DATABASE");
592 dropdb(stmt->dbname, stmt->missing_ok);
596 /* Query-level asynchronous notification */
599 NotifyStmt *stmt = (NotifyStmt *) parsetree;
601 PreventCommandDuringRecovery("NOTIFY");
602 Async_Notify(stmt->conditionname, stmt->payload);
608 ListenStmt *stmt = (ListenStmt *) parsetree;
610 PreventCommandDuringRecovery("LISTEN");
611 CheckRestrictedOperation("LISTEN");
612 Async_Listen(stmt->conditionname);
618 UnlistenStmt *stmt = (UnlistenStmt *) parsetree;
620 PreventCommandDuringRecovery("UNLISTEN");
621 CheckRestrictedOperation("UNLISTEN");
622 if (stmt->conditionname)
623 Async_Unlisten(stmt->conditionname);
631 LoadStmt *stmt = (LoadStmt *) parsetree;
633 closeAllVfds(); /* probably not necessary... */
634 /* Allowed names are restricted if you're not superuser */
635 load_file(stmt->filename, !superuser());
640 /* we choose to allow this during "read only" transactions */
641 PreventCommandDuringRecovery("CLUSTER");
642 /* forbidden in parallel mode due to CommandIsReadOnly */
643 cluster((ClusterStmt *) parsetree, isTopLevel);
648 VacuumStmt *stmt = (VacuumStmt *) parsetree;
650 /* we choose to allow this during "read only" transactions */
651 PreventCommandDuringRecovery((stmt->options & VACOPT_VACUUM) ?
652 "VACUUM" : "ANALYZE");
653 /* forbidden in parallel mode due to CommandIsReadOnly */
654 ExecVacuum(stmt, isTopLevel);
659 ExplainQuery((ExplainStmt *) parsetree, queryString, params, dest);
662 case T_AlterSystemStmt:
663 PreventTransactionChain(isTopLevel, "ALTER SYSTEM");
664 AlterSystemSetConfigFile((AlterSystemStmt *) parsetree);
667 case T_VariableSetStmt:
668 ExecSetVariableStmt((VariableSetStmt *) parsetree, isTopLevel);
671 case T_VariableShowStmt:
673 VariableShowStmt *n = (VariableShowStmt *) parsetree;
675 GetPGVariable(n->name, dest);
680 /* should we allow DISCARD PLANS? */
681 CheckRestrictedOperation("DISCARD");
682 DiscardCommand((DiscardStmt *) parsetree, isTopLevel);
685 case T_CreateEventTrigStmt:
686 /* no event triggers on event triggers */
687 CreateEventTrigger((CreateEventTrigStmt *) parsetree);
690 case T_AlterEventTrigStmt:
691 /* no event triggers on event triggers */
692 AlterEventTrigger((AlterEventTrigStmt *) parsetree);
696 * ******************************** ROLE statements ****
698 case T_CreateRoleStmt:
699 /* no event triggers for global objects */
700 CreateRole((CreateRoleStmt *) parsetree);
703 case T_AlterRoleStmt:
704 /* no event triggers for global objects */
705 AlterRole((AlterRoleStmt *) parsetree);
708 case T_AlterRoleSetStmt:
709 /* no event triggers for global objects */
710 AlterRoleSet((AlterRoleSetStmt *) parsetree);
714 /* no event triggers for global objects */
715 DropRole((DropRoleStmt *) parsetree);
718 case T_ReassignOwnedStmt:
719 /* no event triggers for global objects */
720 ReassignOwnedObjects((ReassignOwnedStmt *) parsetree);
726 * Since the lock would just get dropped immediately, LOCK TABLE
727 * outside a transaction block is presumed to be user error.
729 RequireTransactionChain(isTopLevel, "LOCK TABLE");
730 /* forbidden in parallel mode due to CommandIsReadOnly */
731 LockTableCommand((LockStmt *) parsetree);
734 case T_ConstraintsSetStmt:
735 WarnNoTransactionChain(isTopLevel, "SET CONSTRAINTS");
736 AfterTriggerSetState((ConstraintsSetStmt *) parsetree);
739 case T_CheckPointStmt:
742 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
743 errmsg("must be superuser to do CHECKPOINT")));
746 * You might think we should have a PreventCommandDuringRecovery()
747 * here, but we interpret a CHECKPOINT command during recovery as
748 * a request for a restartpoint instead. We allow this since it
749 * can be a useful way of reducing switchover time when using
750 * various forms of replication.
752 RequestCheckpoint(CHECKPOINT_IMMEDIATE | CHECKPOINT_WAIT |
753 (RecoveryInProgress() ? 0 : CHECKPOINT_FORCE));
758 ReindexStmt *stmt = (ReindexStmt *) parsetree;
760 /* we choose to allow this during "read only" transactions */
761 PreventCommandDuringRecovery("REINDEX");
762 /* forbidden in parallel mode due to CommandIsReadOnly */
765 case REINDEX_OBJECT_INDEX:
766 ReindexIndex(stmt->relation, stmt->options);
768 case REINDEX_OBJECT_TABLE:
769 ReindexTable(stmt->relation, stmt->options);
771 case REINDEX_OBJECT_SCHEMA:
772 case REINDEX_OBJECT_SYSTEM:
773 case REINDEX_OBJECT_DATABASE:
776 * This cannot run inside a user transaction block; if
777 * we were inside a transaction, then its commit- and
778 * start-transaction-command calls would not have the
781 PreventTransactionChain(isTopLevel,
782 (stmt->kind == REINDEX_OBJECT_SCHEMA) ? "REINDEX SCHEMA" :
783 (stmt->kind == REINDEX_OBJECT_SYSTEM) ? "REINDEX SYSTEM" :
785 ReindexMultipleTables(stmt->name, stmt->kind, stmt->options);
788 elog(ERROR, "unrecognized object type: %d",
796 * The following statements are supported by Event Triggers only
797 * in some cases, so we "fast path" them in the other cases.
802 GrantStmt *stmt = (GrantStmt *) parsetree;
804 if (EventTriggerSupportsGrantObjectType(stmt->objtype))
805 ProcessUtilitySlow(parsetree, queryString,
807 dest, completionTag);
809 ExecuteGrantStmt((GrantStmt *) parsetree);
815 DropStmt *stmt = (DropStmt *) parsetree;
817 if (EventTriggerSupportsObjectType(stmt->removeType))
818 ProcessUtilitySlow(parsetree, queryString,
820 dest, completionTag);
822 ExecDropStmt(stmt, isTopLevel);
828 RenameStmt *stmt = (RenameStmt *) parsetree;
830 if (EventTriggerSupportsObjectType(stmt->renameType))
831 ProcessUtilitySlow(parsetree, queryString,
833 dest, completionTag);
835 ExecRenameStmt(stmt);
839 case T_AlterObjectSchemaStmt:
841 AlterObjectSchemaStmt *stmt = (AlterObjectSchemaStmt *) parsetree;
843 if (EventTriggerSupportsObjectType(stmt->objectType))
844 ProcessUtilitySlow(parsetree, queryString,
846 dest, completionTag);
848 ExecAlterObjectSchemaStmt(stmt, NULL);
852 case T_AlterOwnerStmt:
854 AlterOwnerStmt *stmt = (AlterOwnerStmt *) parsetree;
856 if (EventTriggerSupportsObjectType(stmt->objectType))
857 ProcessUtilitySlow(parsetree, queryString,
859 dest, completionTag);
861 ExecAlterOwnerStmt(stmt);
867 CommentStmt *stmt = (CommentStmt *) parsetree;
869 if (EventTriggerSupportsObjectType(stmt->objtype))
870 ProcessUtilitySlow(parsetree, queryString,
872 dest, completionTag);
874 CommentObject((CommentStmt *) parsetree);
880 SecLabelStmt *stmt = (SecLabelStmt *) parsetree;
882 if (EventTriggerSupportsObjectType(stmt->objtype))
883 ProcessUtilitySlow(parsetree, queryString,
885 dest, completionTag);
887 ExecSecLabelStmt(stmt);
892 /* All other statement types have event trigger support */
893 ProcessUtilitySlow(parsetree, queryString,
895 dest, completionTag);
901 * The "Slow" variant of ProcessUtility should only receive statements
902 * supported by the event triggers facility. Therefore, we always
903 * perform the trigger support calls if the context allows it.
906 ProcessUtilitySlow(Node *parsetree,
907 const char *queryString,
908 ProcessUtilityContext context,
909 ParamListInfo params,
913 bool isTopLevel = (context == PROCESS_UTILITY_TOPLEVEL);
914 bool isCompleteQuery = (context <= PROCESS_UTILITY_QUERY);
916 bool commandCollected = false;
917 ObjectAddress address;
918 ObjectAddress secondaryObject = InvalidObjectAddress;
920 /* All event trigger calls are done only when isCompleteQuery is true */
921 needCleanup = isCompleteQuery && EventTriggerBeginCompleteQuery();
923 /* PG_TRY block is to ensure we call EventTriggerEndCompleteQuery */
927 EventTriggerDDLCommandStart(parsetree);
929 switch (nodeTag(parsetree))
932 * relation and attribute manipulation
934 case T_CreateSchemaStmt:
935 CreateSchemaCommand((CreateSchemaStmt *) parsetree,
939 * EventTriggerCollectSimpleCommand called by
940 * CreateSchemaCommand
942 commandCollected = true;
946 case T_CreateForeignTableStmt:
951 /* Run parse analysis ... */
952 stmts = transformCreateStmt((CreateStmt *) parsetree,
958 Node *stmt = (Node *) lfirst(l);
960 if (IsA(stmt, CreateStmt))
963 static char *validnsps[] = HEAP_RELOPT_NAMESPACES;
965 /* Create the table itself */
966 address = DefineRelation((CreateStmt *) stmt,
969 EventTriggerCollectSimpleCommand(address,
974 * Let NewRelationCreateToastTable decide if this
975 * one needs a secondary relation too.
977 CommandCounterIncrement();
980 * parse and validate reloptions for the toast
983 toast_options = transformRelOptions((Datum) 0,
984 ((CreateStmt *) stmt)->options,
989 (void) heap_reloptions(RELKIND_TOASTVALUE,
993 NewRelationCreateToastTable(address.objectId,
996 else if (IsA(stmt, CreateForeignTableStmt))
998 /* Create the table itself */
999 address = DefineRelation((CreateStmt *) stmt,
1000 RELKIND_FOREIGN_TABLE,
1002 CreateForeignTable((CreateForeignTableStmt *) stmt,
1004 EventTriggerCollectSimpleCommand(address,
1011 * Recurse for anything else. Note the recursive
1012 * call will stash the objects so created into our
1013 * event trigger context.
1015 ProcessUtility(stmt,
1017 PROCESS_UTILITY_SUBCOMMAND,
1023 /* Need CCI between commands */
1024 if (lnext(l) != NULL)
1025 CommandCounterIncrement();
1029 * The multiple commands generated here are stashed
1030 * individually, so disable collection below.
1032 commandCollected = true;
1036 case T_AlterTableStmt:
1038 AlterTableStmt *atstmt = (AlterTableStmt *) parsetree;
1045 * Figure out lock mode, and acquire lock. This also does
1046 * basic permissions checks, so that we won't wait for a
1047 * lock on (for example) a relation on which we have no
1050 lockmode = AlterTableGetLockLevel(atstmt->cmds);
1051 relid = AlterTableLookupRelation(atstmt, lockmode);
1053 if (OidIsValid(relid))
1055 /* Run parse analysis ... */
1056 stmts = transformAlterTableStmt(relid, atstmt,
1059 /* ... ensure we have an event trigger context ... */
1060 EventTriggerAlterTableStart(parsetree);
1061 EventTriggerAlterTableRelid(relid);
1066 Node *stmt = (Node *) lfirst(l);
1068 if (IsA(stmt, AlterTableStmt))
1070 /* Do the table alteration proper */
1071 AlterTable(relid, lockmode,
1072 (AlterTableStmt *) stmt);
1077 * Recurse for anything else. If we need to
1078 * do so, "close" the current complex-command
1079 * set, and start a new one at the bottom;
1080 * this is needed to ensure the ordering of
1081 * queued commands is consistent with the way
1082 * they are executed here.
1084 EventTriggerAlterTableEnd();
1085 ProcessUtility(stmt,
1087 PROCESS_UTILITY_SUBCOMMAND,
1091 EventTriggerAlterTableStart(parsetree);
1092 EventTriggerAlterTableRelid(relid);
1095 /* Need CCI between commands */
1096 if (lnext(l) != NULL)
1097 CommandCounterIncrement();
1101 EventTriggerAlterTableEnd();
1105 (errmsg("relation \"%s\" does not exist, skipping",
1106 atstmt->relation->relname)));
1109 /* ALTER TABLE stashes commands internally */
1110 commandCollected = true;
1113 case T_AlterDomainStmt:
1115 AlterDomainStmt *stmt = (AlterDomainStmt *) parsetree;
1118 * Some or all of these functions are recursive to cover
1119 * inherited things, so permission checks are done there.
1121 switch (stmt->subtype)
1123 case 'T': /* ALTER DOMAIN DEFAULT */
1126 * Recursively alter column default for table and,
1127 * if requested, for descendants
1130 AlterDomainDefault(stmt->typeName,
1133 case 'N': /* ALTER DOMAIN DROP NOT NULL */
1135 AlterDomainNotNull(stmt->typeName,
1138 case 'O': /* ALTER DOMAIN SET NOT NULL */
1140 AlterDomainNotNull(stmt->typeName,
1143 case 'C': /* ADD CONSTRAINT */
1145 AlterDomainAddConstraint(stmt->typeName,
1149 case 'X': /* DROP CONSTRAINT */
1151 AlterDomainDropConstraint(stmt->typeName,
1156 case 'V': /* VALIDATE CONSTRAINT */
1158 AlterDomainValidateConstraint(stmt->typeName,
1162 elog(ERROR, "unrecognized alter domain type: %d",
1163 (int) stmt->subtype);
1170 * ************* object creation / destruction **************
1174 DefineStmt *stmt = (DefineStmt *) parsetree;
1178 case OBJECT_AGGREGATE:
1180 DefineAggregate(stmt->defnames, stmt->args,
1182 stmt->definition, queryString);
1184 case OBJECT_OPERATOR:
1185 Assert(stmt->args == NIL);
1186 address = DefineOperator(stmt->defnames,
1190 Assert(stmt->args == NIL);
1191 address = DefineType(stmt->defnames,
1194 case OBJECT_TSPARSER:
1195 Assert(stmt->args == NIL);
1196 address = DefineTSParser(stmt->defnames,
1199 case OBJECT_TSDICTIONARY:
1200 Assert(stmt->args == NIL);
1201 address = DefineTSDictionary(stmt->defnames,
1204 case OBJECT_TSTEMPLATE:
1205 Assert(stmt->args == NIL);
1206 address = DefineTSTemplate(stmt->defnames,
1209 case OBJECT_TSCONFIGURATION:
1210 Assert(stmt->args == NIL);
1211 address = DefineTSConfiguration(stmt->defnames,
1215 case OBJECT_COLLATION:
1216 Assert(stmt->args == NIL);
1217 address = DefineCollation(stmt->defnames,
1221 elog(ERROR, "unrecognized define stmt type: %d",
1228 case T_IndexStmt: /* CREATE INDEX */
1230 IndexStmt *stmt = (IndexStmt *) parsetree;
1234 if (stmt->concurrent)
1235 PreventTransactionChain(isTopLevel,
1236 "CREATE INDEX CONCURRENTLY");
1239 * Look up the relation OID just once, right here at the
1240 * beginning, so that we don't end up repeating the name
1241 * lookup later and latching onto a different relation
1242 * partway through. To avoid lock upgrade hazards, it's
1243 * important that we take the strongest lock that will
1244 * eventually be needed here, so the lockmode calculation
1245 * needs to match what DefineIndex() does.
1247 lockmode = stmt->concurrent ? ShareUpdateExclusiveLock
1250 RangeVarGetRelidExtended(stmt->relation, lockmode,
1252 RangeVarCallbackOwnsRelation,
1255 /* Run parse analysis ... */
1256 stmt = transformIndexStmt(relid, stmt, queryString);
1259 EventTriggerAlterTableStart(parsetree);
1261 DefineIndex(relid, /* OID of heap relation */
1263 InvalidOid, /* no predefined OID */
1264 false, /* is_alter_table */
1265 true, /* check_rights */
1266 false, /* skip_build */
1270 * Add the CREATE INDEX node itself to stash right away;
1271 * if there were any commands stashed in the ALTER TABLE
1272 * code, we need them to appear after this one.
1274 EventTriggerCollectSimpleCommand(address, secondaryObject,
1276 commandCollected = true;
1277 EventTriggerAlterTableEnd();
1281 case T_CreateExtensionStmt:
1282 address = CreateExtension((CreateExtensionStmt *) parsetree);
1285 case T_AlterExtensionStmt:
1286 address = ExecAlterExtensionStmt((AlterExtensionStmt *) parsetree);
1289 case T_AlterExtensionContentsStmt:
1290 address = ExecAlterExtensionContentsStmt((AlterExtensionContentsStmt *) parsetree,
1294 case T_CreateFdwStmt:
1295 address = CreateForeignDataWrapper((CreateFdwStmt *) parsetree);
1298 case T_AlterFdwStmt:
1299 address = AlterForeignDataWrapper((AlterFdwStmt *) parsetree);
1302 case T_CreateForeignServerStmt:
1303 address = CreateForeignServer((CreateForeignServerStmt *) parsetree);
1306 case T_AlterForeignServerStmt:
1307 address = AlterForeignServer((AlterForeignServerStmt *) parsetree);
1310 case T_CreateUserMappingStmt:
1311 address = CreateUserMapping((CreateUserMappingStmt *) parsetree);
1314 case T_AlterUserMappingStmt:
1315 address = AlterUserMapping((AlterUserMappingStmt *) parsetree);
1318 case T_DropUserMappingStmt:
1319 RemoveUserMapping((DropUserMappingStmt *) parsetree);
1320 /* no commands stashed for DROP */
1321 commandCollected = true;
1324 case T_ImportForeignSchemaStmt:
1325 ImportForeignSchema((ImportForeignSchemaStmt *) parsetree);
1326 /* commands are stashed inside ImportForeignSchema */
1327 commandCollected = true;
1330 case T_CompositeTypeStmt: /* CREATE TYPE (composite) */
1332 CompositeTypeStmt *stmt = (CompositeTypeStmt *) parsetree;
1334 address = DefineCompositeType(stmt->typevar,
1339 case T_CreateEnumStmt: /* CREATE TYPE AS ENUM */
1340 address = DefineEnum((CreateEnumStmt *) parsetree);
1343 case T_CreateRangeStmt: /* CREATE TYPE AS RANGE */
1344 address = DefineRange((CreateRangeStmt *) parsetree);
1347 case T_AlterEnumStmt: /* ALTER TYPE (enum) */
1348 address = AlterEnum((AlterEnumStmt *) parsetree, isTopLevel);
1351 case T_ViewStmt: /* CREATE VIEW */
1352 EventTriggerAlterTableStart(parsetree);
1353 address = DefineView((ViewStmt *) parsetree, queryString);
1354 EventTriggerCollectSimpleCommand(address, secondaryObject,
1356 /* stashed internally */
1357 commandCollected = true;
1358 EventTriggerAlterTableEnd();
1361 case T_CreateFunctionStmt: /* CREATE FUNCTION */
1362 address = CreateFunction((CreateFunctionStmt *) parsetree, queryString);
1365 case T_AlterFunctionStmt: /* ALTER FUNCTION */
1366 address = AlterFunction((AlterFunctionStmt *) parsetree);
1369 case T_RuleStmt: /* CREATE RULE */
1370 address = DefineRule((RuleStmt *) parsetree, queryString);
1373 case T_CreateSeqStmt:
1374 address = DefineSequence((CreateSeqStmt *) parsetree);
1377 case T_AlterSeqStmt:
1378 address = AlterSequence((AlterSeqStmt *) parsetree);
1381 case T_CreateTableAsStmt:
1382 address = ExecCreateTableAs((CreateTableAsStmt *) parsetree,
1383 queryString, params, completionTag);
1386 case T_RefreshMatViewStmt:
1389 * REFRSH CONCURRENTLY executes some DDL commands internally.
1390 * Inhibit DDL command collection here to avoid those commands
1391 * from showing up in the deparsed command queue. The refresh
1392 * command itself is queued, which is enough.
1394 EventTriggerInhibitCommandCollection();
1397 address = ExecRefreshMatView((RefreshMatViewStmt *) parsetree,
1398 queryString, params, completionTag);
1402 EventTriggerUndoInhibitCommandCollection();
1406 EventTriggerUndoInhibitCommandCollection();
1409 case T_CreateTrigStmt:
1410 address = CreateTrigger((CreateTrigStmt *) parsetree,
1411 queryString, InvalidOid, InvalidOid,
1412 InvalidOid, InvalidOid, false);
1415 case T_CreatePLangStmt:
1416 address = CreateProceduralLanguage((CreatePLangStmt *) parsetree);
1419 case T_CreateDomainStmt:
1420 address = DefineDomain((CreateDomainStmt *) parsetree);
1423 case T_CreateConversionStmt:
1424 address = CreateConversionCommand((CreateConversionStmt *) parsetree);
1427 case T_CreateCastStmt:
1428 address = CreateCast((CreateCastStmt *) parsetree);
1431 case T_CreateOpClassStmt:
1432 DefineOpClass((CreateOpClassStmt *) parsetree);
1433 /* command is stashed in DefineOpClass */
1434 commandCollected = true;
1437 case T_CreateOpFamilyStmt:
1438 address = DefineOpFamily((CreateOpFamilyStmt *) parsetree);
1441 case T_CreateTransformStmt:
1442 address = CreateTransform((CreateTransformStmt *) parsetree);
1445 case T_AlterOpFamilyStmt:
1446 AlterOpFamily((AlterOpFamilyStmt *) parsetree);
1447 /* commands are stashed in AlterOpFamily */
1448 commandCollected = true;
1451 case T_AlterTSDictionaryStmt:
1452 address = AlterTSDictionary((AlterTSDictionaryStmt *) parsetree);
1455 case T_AlterTSConfigurationStmt:
1456 address = AlterTSConfiguration((AlterTSConfigurationStmt *) parsetree);
1459 case T_AlterTableMoveAllStmt:
1460 AlterTableMoveAll((AlterTableMoveAllStmt *) parsetree);
1461 /* commands are stashed in AlterTableMoveAll */
1462 commandCollected = true;
1466 ExecDropStmt((DropStmt *) parsetree, isTopLevel);
1467 /* no commands stashed for DROP */
1468 commandCollected = true;
1472 address = ExecRenameStmt((RenameStmt *) parsetree);
1475 case T_AlterObjectSchemaStmt:
1477 ExecAlterObjectSchemaStmt((AlterObjectSchemaStmt *) parsetree,
1481 case T_AlterOwnerStmt:
1482 address = ExecAlterOwnerStmt((AlterOwnerStmt *) parsetree);
1485 case T_AlterOperatorStmt:
1486 address = AlterOperator((AlterOperatorStmt *) parsetree);
1490 address = CommentObject((CommentStmt *) parsetree);
1494 ExecuteGrantStmt((GrantStmt *) parsetree);
1495 /* commands are stashed in ExecGrantStmt_oids */
1496 commandCollected = true;
1499 case T_DropOwnedStmt:
1500 DropOwnedObjects((DropOwnedStmt *) parsetree);
1501 /* no commands stashed for DROP */
1502 commandCollected = true;
1505 case T_AlterDefaultPrivilegesStmt:
1506 ExecAlterDefaultPrivilegesStmt((AlterDefaultPrivilegesStmt *) parsetree);
1507 EventTriggerCollectAlterDefPrivs((AlterDefaultPrivilegesStmt *) parsetree);
1508 commandCollected = true;
1511 case T_CreatePolicyStmt: /* CREATE POLICY */
1512 address = CreatePolicy((CreatePolicyStmt *) parsetree);
1515 case T_AlterPolicyStmt: /* ALTER POLICY */
1516 address = AlterPolicy((AlterPolicyStmt *) parsetree);
1519 case T_SecLabelStmt:
1520 address = ExecSecLabelStmt((SecLabelStmt *) parsetree);
1524 elog(ERROR, "unrecognized node type: %d",
1525 (int) nodeTag(parsetree));
1530 * Remember the object so that ddl_command_end event triggers have
1533 if (!commandCollected)
1534 EventTriggerCollectSimpleCommand(address, secondaryObject,
1537 if (isCompleteQuery)
1539 EventTriggerSQLDrop(parsetree);
1540 EventTriggerDDLCommandEnd(parsetree);
1546 EventTriggerEndCompleteQuery();
1552 EventTriggerEndCompleteQuery();
1556 * Dispatch function for DropStmt
1559 ExecDropStmt(DropStmt *stmt, bool isTopLevel)
1561 switch (stmt->removeType)
1564 if (stmt->concurrent)
1565 PreventTransactionChain(isTopLevel,
1566 "DROP INDEX CONCURRENTLY");
1570 case OBJECT_SEQUENCE:
1572 case OBJECT_MATVIEW:
1573 case OBJECT_FOREIGN_TABLE:
1574 RemoveRelations(stmt);
1577 RemoveObjects(stmt);
1584 * UtilityReturnsTuples
1585 * Return "true" if this utility statement will send output to the
1588 * Generally, there should be a case here for each case in ProcessUtility
1589 * where "dest" is passed on.
1592 UtilityReturnsTuples(Node *parsetree)
1594 switch (nodeTag(parsetree))
1598 FetchStmt *stmt = (FetchStmt *) parsetree;
1603 portal = GetPortalByName(stmt->portalname);
1604 if (!PortalIsValid(portal))
1605 return false; /* not our business to raise error */
1606 return portal->tupDesc ? true : false;
1611 ExecuteStmt *stmt = (ExecuteStmt *) parsetree;
1612 PreparedStatement *entry;
1614 entry = FetchPreparedStatement(stmt->name, false);
1616 return false; /* not our business to raise error */
1617 if (entry->plansource->resultDesc)
1625 case T_VariableShowStmt:
1634 * UtilityTupleDescriptor
1635 * Fetch the actual output tuple descriptor for a utility statement
1636 * for which UtilityReturnsTuples() previously returned "true".
1638 * The returned descriptor is created in (or copied into) the current memory
1642 UtilityTupleDescriptor(Node *parsetree)
1644 switch (nodeTag(parsetree))
1648 FetchStmt *stmt = (FetchStmt *) parsetree;
1653 portal = GetPortalByName(stmt->portalname);
1654 if (!PortalIsValid(portal))
1655 return NULL; /* not our business to raise error */
1656 return CreateTupleDescCopy(portal->tupDesc);
1661 ExecuteStmt *stmt = (ExecuteStmt *) parsetree;
1662 PreparedStatement *entry;
1664 entry = FetchPreparedStatement(stmt->name, false);
1666 return NULL; /* not our business to raise error */
1667 return FetchPreparedStatementResultDesc(entry);
1671 return ExplainResultDesc((ExplainStmt *) parsetree);
1673 case T_VariableShowStmt:
1675 VariableShowStmt *n = (VariableShowStmt *) parsetree;
1677 return GetPGVariableResultDesc(n->name);
1687 * QueryReturnsTuples
1688 * Return "true" if this Query will send output to the destination.
1692 QueryReturnsTuples(Query *parsetree)
1694 switch (parsetree->commandType)
1697 /* returns tuples ... unless it's DECLARE CURSOR */
1698 if (parsetree->utilityStmt == NULL)
1704 /* the forms with RETURNING return tuples */
1705 if (parsetree->returningList)
1709 return UtilityReturnsTuples(parsetree->utilityStmt);
1712 /* probably shouldn't get here */
1715 return false; /* default */
1721 * UtilityContainsQuery
1722 * Return the contained Query, or NULL if there is none
1724 * Certain utility statements, such as EXPLAIN, contain a plannable Query.
1725 * This function encapsulates knowledge of exactly which ones do.
1726 * We assume it is invoked only on already-parse-analyzed statements
1727 * (else the contained parsetree isn't a Query yet).
1729 * In some cases (currently, only EXPLAIN of CREATE TABLE AS/SELECT INTO and
1730 * CREATE MATERIALIZED VIEW), potentially Query-containing utility statements
1731 * can be nested. This function will drill down to a non-utility Query, or
1732 * return NULL if none.
1735 UtilityContainsQuery(Node *parsetree)
1739 switch (nodeTag(parsetree))
1742 qry = (Query *) ((ExplainStmt *) parsetree)->query;
1743 Assert(IsA(qry, Query));
1744 if (qry->commandType == CMD_UTILITY)
1745 return UtilityContainsQuery(qry->utilityStmt);
1748 case T_CreateTableAsStmt:
1749 qry = (Query *) ((CreateTableAsStmt *) parsetree)->query;
1750 Assert(IsA(qry, Query));
1751 if (qry->commandType == CMD_UTILITY)
1752 return UtilityContainsQuery(qry->utilityStmt);
1762 * AlterObjectTypeCommandTag
1763 * helper function for CreateCommandTag
1765 * This covers most cases where ALTER is used with an ObjectType enum.
1768 AlterObjectTypeCommandTag(ObjectType objtype)
1774 case OBJECT_AGGREGATE:
1775 tag = "ALTER AGGREGATE";
1777 case OBJECT_ATTRIBUTE:
1783 case OBJECT_COLLATION:
1784 tag = "ALTER COLLATION";
1787 tag = "ALTER TABLE";
1789 case OBJECT_CONVERSION:
1790 tag = "ALTER CONVERSION";
1792 case OBJECT_DATABASE:
1793 tag = "ALTER DATABASE";
1796 case OBJECT_DOMCONSTRAINT:
1797 tag = "ALTER DOMAIN";
1799 case OBJECT_EXTENSION:
1800 tag = "ALTER EXTENSION";
1803 tag = "ALTER FOREIGN DATA WRAPPER";
1805 case OBJECT_FOREIGN_SERVER:
1806 tag = "ALTER SERVER";
1808 case OBJECT_FOREIGN_TABLE:
1809 tag = "ALTER FOREIGN TABLE";
1811 case OBJECT_FUNCTION:
1812 tag = "ALTER FUNCTION";
1815 tag = "ALTER INDEX";
1817 case OBJECT_LANGUAGE:
1818 tag = "ALTER LANGUAGE";
1820 case OBJECT_LARGEOBJECT:
1821 tag = "ALTER LARGE OBJECT";
1823 case OBJECT_OPCLASS:
1824 tag = "ALTER OPERATOR CLASS";
1826 case OBJECT_OPERATOR:
1827 tag = "ALTER OPERATOR";
1829 case OBJECT_OPFAMILY:
1830 tag = "ALTER OPERATOR FAMILY";
1833 tag = "ALTER POLICY";
1842 tag = "ALTER SCHEMA";
1844 case OBJECT_SEQUENCE:
1845 tag = "ALTER SEQUENCE";
1848 case OBJECT_TABCONSTRAINT:
1849 tag = "ALTER TABLE";
1851 case OBJECT_TABLESPACE:
1852 tag = "ALTER TABLESPACE";
1854 case OBJECT_TRIGGER:
1855 tag = "ALTER TRIGGER";
1857 case OBJECT_EVENT_TRIGGER:
1858 tag = "ALTER EVENT TRIGGER";
1860 case OBJECT_TSCONFIGURATION:
1861 tag = "ALTER TEXT SEARCH CONFIGURATION";
1863 case OBJECT_TSDICTIONARY:
1864 tag = "ALTER TEXT SEARCH DICTIONARY";
1866 case OBJECT_TSPARSER:
1867 tag = "ALTER TEXT SEARCH PARSER";
1869 case OBJECT_TSTEMPLATE:
1870 tag = "ALTER TEXT SEARCH TEMPLATE";
1878 case OBJECT_MATVIEW:
1879 tag = "ALTER MATERIALIZED VIEW";
1891 * utility to get a string representation of the command operation,
1892 * given either a raw (un-analyzed) parsetree or a planned query.
1894 * This must handle all command types, but since the vast majority
1895 * of 'em are utility commands, it seems sensible to keep it here.
1897 * NB: all result strings must be shorter than COMPLETION_TAG_BUFSIZE.
1898 * Also, the result must point at a true constant (permanent storage).
1901 CreateCommandTag(Node *parsetree)
1905 switch (nodeTag(parsetree))
1907 /* raw plannable queries */
1924 /* utility statements --- same whether raw or cooked */
1925 case T_TransactionStmt:
1927 TransactionStmt *stmt = (TransactionStmt *) parsetree;
1931 case TRANS_STMT_BEGIN:
1935 case TRANS_STMT_START:
1936 tag = "START TRANSACTION";
1939 case TRANS_STMT_COMMIT:
1943 case TRANS_STMT_ROLLBACK:
1944 case TRANS_STMT_ROLLBACK_TO:
1948 case TRANS_STMT_SAVEPOINT:
1952 case TRANS_STMT_RELEASE:
1956 case TRANS_STMT_PREPARE:
1957 tag = "PREPARE TRANSACTION";
1960 case TRANS_STMT_COMMIT_PREPARED:
1961 tag = "COMMIT PREPARED";
1964 case TRANS_STMT_ROLLBACK_PREPARED:
1965 tag = "ROLLBACK PREPARED";
1975 case T_DeclareCursorStmt:
1976 tag = "DECLARE CURSOR";
1979 case T_ClosePortalStmt:
1981 ClosePortalStmt *stmt = (ClosePortalStmt *) parsetree;
1983 if (stmt->portalname == NULL)
1984 tag = "CLOSE CURSOR ALL";
1986 tag = "CLOSE CURSOR";
1992 FetchStmt *stmt = (FetchStmt *) parsetree;
1994 tag = (stmt->ismove) ? "MOVE" : "FETCH";
1998 case T_CreateDomainStmt:
1999 tag = "CREATE DOMAIN";
2002 case T_CreateSchemaStmt:
2003 tag = "CREATE SCHEMA";
2007 tag = "CREATE TABLE";
2010 case T_CreateTableSpaceStmt:
2011 tag = "CREATE TABLESPACE";
2014 case T_DropTableSpaceStmt:
2015 tag = "DROP TABLESPACE";
2018 case T_AlterTableSpaceOptionsStmt:
2019 tag = "ALTER TABLESPACE";
2022 case T_CreateExtensionStmt:
2023 tag = "CREATE EXTENSION";
2026 case T_AlterExtensionStmt:
2027 tag = "ALTER EXTENSION";
2030 case T_AlterExtensionContentsStmt:
2031 tag = "ALTER EXTENSION";
2034 case T_CreateFdwStmt:
2035 tag = "CREATE FOREIGN DATA WRAPPER";
2038 case T_AlterFdwStmt:
2039 tag = "ALTER FOREIGN DATA WRAPPER";
2042 case T_CreateForeignServerStmt:
2043 tag = "CREATE SERVER";
2046 case T_AlterForeignServerStmt:
2047 tag = "ALTER SERVER";
2050 case T_CreateUserMappingStmt:
2051 tag = "CREATE USER MAPPING";
2054 case T_AlterUserMappingStmt:
2055 tag = "ALTER USER MAPPING";
2058 case T_DropUserMappingStmt:
2059 tag = "DROP USER MAPPING";
2062 case T_CreateForeignTableStmt:
2063 tag = "CREATE FOREIGN TABLE";
2066 case T_ImportForeignSchemaStmt:
2067 tag = "IMPORT FOREIGN SCHEMA";
2071 switch (((DropStmt *) parsetree)->removeType)
2076 case OBJECT_SEQUENCE:
2077 tag = "DROP SEQUENCE";
2082 case OBJECT_MATVIEW:
2083 tag = "DROP MATERIALIZED VIEW";
2092 tag = "DROP DOMAIN";
2094 case OBJECT_COLLATION:
2095 tag = "DROP COLLATION";
2097 case OBJECT_CONVERSION:
2098 tag = "DROP CONVERSION";
2101 tag = "DROP SCHEMA";
2103 case OBJECT_TSPARSER:
2104 tag = "DROP TEXT SEARCH PARSER";
2106 case OBJECT_TSDICTIONARY:
2107 tag = "DROP TEXT SEARCH DICTIONARY";
2109 case OBJECT_TSTEMPLATE:
2110 tag = "DROP TEXT SEARCH TEMPLATE";
2112 case OBJECT_TSCONFIGURATION:
2113 tag = "DROP TEXT SEARCH CONFIGURATION";
2115 case OBJECT_FOREIGN_TABLE:
2116 tag = "DROP FOREIGN TABLE";
2118 case OBJECT_EXTENSION:
2119 tag = "DROP EXTENSION";
2121 case OBJECT_FUNCTION:
2122 tag = "DROP FUNCTION";
2124 case OBJECT_AGGREGATE:
2125 tag = "DROP AGGREGATE";
2127 case OBJECT_OPERATOR:
2128 tag = "DROP OPERATOR";
2130 case OBJECT_LANGUAGE:
2131 tag = "DROP LANGUAGE";
2136 case OBJECT_TRIGGER:
2137 tag = "DROP TRIGGER";
2139 case OBJECT_EVENT_TRIGGER:
2140 tag = "DROP EVENT TRIGGER";
2146 tag = "DROP FOREIGN DATA WRAPPER";
2148 case OBJECT_FOREIGN_SERVER:
2149 tag = "DROP SERVER";
2151 case OBJECT_OPCLASS:
2152 tag = "DROP OPERATOR CLASS";
2154 case OBJECT_OPFAMILY:
2155 tag = "DROP OPERATOR FAMILY";
2158 tag = "DROP POLICY";
2160 case OBJECT_TRANSFORM:
2161 tag = "DROP TRANSFORM";
2168 case T_TruncateStmt:
2169 tag = "TRUNCATE TABLE";
2176 case T_SecLabelStmt:
2177 tag = "SECURITY LABEL";
2185 tag = AlterObjectTypeCommandTag(((RenameStmt *) parsetree)->renameType);
2188 case T_AlterObjectSchemaStmt:
2189 tag = AlterObjectTypeCommandTag(((AlterObjectSchemaStmt *) parsetree)->objectType);
2192 case T_AlterOwnerStmt:
2193 tag = AlterObjectTypeCommandTag(((AlterOwnerStmt *) parsetree)->objectType);
2196 case T_AlterTableMoveAllStmt:
2197 tag = AlterObjectTypeCommandTag(((AlterTableMoveAllStmt *) parsetree)->objtype);
2200 case T_AlterTableStmt:
2201 tag = AlterObjectTypeCommandTag(((AlterTableStmt *) parsetree)->relkind);
2204 case T_AlterDomainStmt:
2205 tag = "ALTER DOMAIN";
2208 case T_AlterFunctionStmt:
2209 tag = "ALTER FUNCTION";
2214 GrantStmt *stmt = (GrantStmt *) parsetree;
2216 tag = (stmt->is_grant) ? "GRANT" : "REVOKE";
2220 case T_GrantRoleStmt:
2222 GrantRoleStmt *stmt = (GrantRoleStmt *) parsetree;
2224 tag = (stmt->is_grant) ? "GRANT ROLE" : "REVOKE ROLE";
2228 case T_AlterDefaultPrivilegesStmt:
2229 tag = "ALTER DEFAULT PRIVILEGES";
2233 switch (((DefineStmt *) parsetree)->kind)
2235 case OBJECT_AGGREGATE:
2236 tag = "CREATE AGGREGATE";
2238 case OBJECT_OPERATOR:
2239 tag = "CREATE OPERATOR";
2242 tag = "CREATE TYPE";
2244 case OBJECT_TSPARSER:
2245 tag = "CREATE TEXT SEARCH PARSER";
2247 case OBJECT_TSDICTIONARY:
2248 tag = "CREATE TEXT SEARCH DICTIONARY";
2250 case OBJECT_TSTEMPLATE:
2251 tag = "CREATE TEXT SEARCH TEMPLATE";
2253 case OBJECT_TSCONFIGURATION:
2254 tag = "CREATE TEXT SEARCH CONFIGURATION";
2256 case OBJECT_COLLATION:
2257 tag = "CREATE COLLATION";
2264 case T_CompositeTypeStmt:
2265 tag = "CREATE TYPE";
2268 case T_CreateEnumStmt:
2269 tag = "CREATE TYPE";
2272 case T_CreateRangeStmt:
2273 tag = "CREATE TYPE";
2276 case T_AlterEnumStmt:
2281 tag = "CREATE VIEW";
2284 case T_CreateFunctionStmt:
2285 tag = "CREATE FUNCTION";
2289 tag = "CREATE INDEX";
2293 tag = "CREATE RULE";
2296 case T_CreateSeqStmt:
2297 tag = "CREATE SEQUENCE";
2300 case T_AlterSeqStmt:
2301 tag = "ALTER SEQUENCE";
2308 case T_CreatedbStmt:
2309 tag = "CREATE DATABASE";
2312 case T_AlterDatabaseStmt:
2313 tag = "ALTER DATABASE";
2316 case T_AlterDatabaseSetStmt:
2317 tag = "ALTER DATABASE";
2321 tag = "DROP DATABASE";
2332 case T_UnlistenStmt:
2345 if (((VacuumStmt *) parsetree)->options & VACOPT_VACUUM)
2355 case T_CreateTableAsStmt:
2356 switch (((CreateTableAsStmt *) parsetree)->relkind)
2359 if (((CreateTableAsStmt *) parsetree)->is_select_into)
2360 tag = "SELECT INTO";
2362 tag = "CREATE TABLE AS";
2364 case OBJECT_MATVIEW:
2365 tag = "CREATE MATERIALIZED VIEW";
2372 case T_RefreshMatViewStmt:
2373 tag = "REFRESH MATERIALIZED VIEW";
2376 case T_AlterSystemStmt:
2377 tag = "ALTER SYSTEM";
2380 case T_VariableSetStmt:
2381 switch (((VariableSetStmt *) parsetree)->kind)
2384 case VAR_SET_CURRENT:
2385 case VAR_SET_DEFAULT:
2398 case T_VariableShowStmt:
2403 switch (((DiscardStmt *) parsetree)->target)
2406 tag = "DISCARD ALL";
2409 tag = "DISCARD PLANS";
2412 tag = "DISCARD TEMP";
2414 case DISCARD_SEQUENCES:
2415 tag = "DISCARD SEQUENCES";
2422 case T_CreateTransformStmt:
2423 tag = "CREATE TRANSFORM";
2426 case T_CreateTrigStmt:
2427 tag = "CREATE TRIGGER";
2430 case T_CreateEventTrigStmt:
2431 tag = "CREATE EVENT TRIGGER";
2434 case T_AlterEventTrigStmt:
2435 tag = "ALTER EVENT TRIGGER";
2438 case T_CreatePLangStmt:
2439 tag = "CREATE LANGUAGE";
2442 case T_CreateRoleStmt:
2443 tag = "CREATE ROLE";
2446 case T_AlterRoleStmt:
2450 case T_AlterRoleSetStmt:
2454 case T_DropRoleStmt:
2458 case T_DropOwnedStmt:
2462 case T_ReassignOwnedStmt:
2463 tag = "REASSIGN OWNED";
2470 case T_ConstraintsSetStmt:
2471 tag = "SET CONSTRAINTS";
2474 case T_CheckPointStmt:
2482 case T_CreateConversionStmt:
2483 tag = "CREATE CONVERSION";
2486 case T_CreateCastStmt:
2487 tag = "CREATE CAST";
2490 case T_CreateOpClassStmt:
2491 tag = "CREATE OPERATOR CLASS";
2494 case T_CreateOpFamilyStmt:
2495 tag = "CREATE OPERATOR FAMILY";
2498 case T_AlterOpFamilyStmt:
2499 tag = "ALTER OPERATOR FAMILY";
2502 case T_AlterOperatorStmt:
2503 tag = "ALTER OPERATOR";
2506 case T_AlterTSDictionaryStmt:
2507 tag = "ALTER TEXT SEARCH DICTIONARY";
2510 case T_AlterTSConfigurationStmt:
2511 tag = "ALTER TEXT SEARCH CONFIGURATION";
2514 case T_CreatePolicyStmt:
2515 tag = "CREATE POLICY";
2518 case T_AlterPolicyStmt:
2519 tag = "ALTER POLICY";
2530 case T_DeallocateStmt:
2532 DeallocateStmt *stmt = (DeallocateStmt *) parsetree;
2534 if (stmt->name == NULL)
2535 tag = "DEALLOCATE ALL";
2541 /* already-planned queries */
2544 PlannedStmt *stmt = (PlannedStmt *) parsetree;
2546 switch (stmt->commandType)
2551 * We take a little extra care here so that the result
2552 * will be useful for complaints about read-only
2555 if (stmt->utilityStmt != NULL)
2557 Assert(IsA(stmt->utilityStmt, DeclareCursorStmt));
2558 tag = "DECLARE CURSOR";
2560 else if (stmt->rowMarks != NIL)
2562 /* not 100% but probably close enough */
2563 switch (((PlanRowMark *) linitial(stmt->rowMarks))->strength)
2565 case LCS_FORKEYSHARE:
2566 tag = "SELECT FOR KEY SHARE";
2569 tag = "SELECT FOR SHARE";
2571 case LCS_FORNOKEYUPDATE:
2572 tag = "SELECT FOR NO KEY UPDATE";
2575 tag = "SELECT FOR UPDATE";
2595 elog(WARNING, "unrecognized commandType: %d",
2596 (int) stmt->commandType);
2603 /* parsed-and-rewritten-but-not-planned queries */
2606 Query *stmt = (Query *) parsetree;
2608 switch (stmt->commandType)
2613 * We take a little extra care here so that the result
2614 * will be useful for complaints about read-only
2617 if (stmt->utilityStmt != NULL)
2619 Assert(IsA(stmt->utilityStmt, DeclareCursorStmt));
2620 tag = "DECLARE CURSOR";
2622 else if (stmt->rowMarks != NIL)
2624 /* not 100% but probably close enough */
2625 switch (((RowMarkClause *) linitial(stmt->rowMarks))->strength)
2627 case LCS_FORKEYSHARE:
2628 tag = "SELECT FOR KEY SHARE";
2631 tag = "SELECT FOR SHARE";
2633 case LCS_FORNOKEYUPDATE:
2634 tag = "SELECT FOR NO KEY UPDATE";
2637 tag = "SELECT FOR UPDATE";
2657 tag = CreateCommandTag(stmt->utilityStmt);
2660 elog(WARNING, "unrecognized commandType: %d",
2661 (int) stmt->commandType);
2669 elog(WARNING, "unrecognized node type: %d",
2670 (int) nodeTag(parsetree));
2680 * GetCommandLogLevel
2681 * utility to get the minimum log_statement level for a command,
2682 * given either a raw (un-analyzed) parsetree or a planned query.
2684 * This must handle all command types, but since the vast majority
2685 * of 'em are utility commands, it seems sensible to keep it here.
2688 GetCommandLogLevel(Node *parsetree)
2692 switch (nodeTag(parsetree))
2694 /* raw plannable queries */
2702 if (((SelectStmt *) parsetree)->intoClause)
2703 lev = LOGSTMT_DDL; /* SELECT INTO */
2708 /* utility statements --- same whether raw or cooked */
2709 case T_TransactionStmt:
2713 case T_DeclareCursorStmt:
2717 case T_ClosePortalStmt:
2725 case T_CreateSchemaStmt:
2730 case T_CreateForeignTableStmt:
2734 case T_CreateTableSpaceStmt:
2735 case T_DropTableSpaceStmt:
2736 case T_AlterTableSpaceOptionsStmt:
2740 case T_CreateExtensionStmt:
2741 case T_AlterExtensionStmt:
2742 case T_AlterExtensionContentsStmt:
2746 case T_CreateFdwStmt:
2747 case T_AlterFdwStmt:
2748 case T_CreateForeignServerStmt:
2749 case T_AlterForeignServerStmt:
2750 case T_CreateUserMappingStmt:
2751 case T_AlterUserMappingStmt:
2752 case T_DropUserMappingStmt:
2753 case T_ImportForeignSchemaStmt:
2761 case T_TruncateStmt:
2769 case T_SecLabelStmt:
2774 if (((CopyStmt *) parsetree)->is_from)
2782 PrepareStmt *stmt = (PrepareStmt *) parsetree;
2784 /* Look through a PREPARE to the contained stmt */
2785 lev = GetCommandLogLevel(stmt->query);
2791 ExecuteStmt *stmt = (ExecuteStmt *) parsetree;
2792 PreparedStatement *ps;
2794 /* Look through an EXECUTE to the referenced stmt */
2795 ps = FetchPreparedStatement(stmt->name, false);
2796 if (ps && ps->plansource->raw_parse_tree)
2797 lev = GetCommandLogLevel(ps->plansource->raw_parse_tree);
2803 case T_DeallocateStmt:
2811 case T_AlterObjectSchemaStmt:
2815 case T_AlterOwnerStmt:
2819 case T_AlterTableMoveAllStmt:
2820 case T_AlterTableStmt:
2824 case T_AlterDomainStmt:
2832 case T_GrantRoleStmt:
2836 case T_AlterDefaultPrivilegesStmt:
2844 case T_CompositeTypeStmt:
2848 case T_CreateEnumStmt:
2852 case T_CreateRangeStmt:
2856 case T_AlterEnumStmt:
2864 case T_CreateFunctionStmt:
2868 case T_AlterFunctionStmt:
2880 case T_CreateSeqStmt:
2884 case T_AlterSeqStmt:
2892 case T_CreatedbStmt:
2896 case T_AlterDatabaseStmt:
2900 case T_AlterDatabaseSetStmt:
2916 case T_UnlistenStmt:
2934 ExplainStmt *stmt = (ExplainStmt *) parsetree;
2935 bool analyze = false;
2938 /* Look through an EXPLAIN ANALYZE to the contained stmt */
2939 foreach(lc, stmt->options)
2941 DefElem *opt = (DefElem *) lfirst(lc);
2943 if (strcmp(opt->defname, "analyze") == 0)
2944 analyze = defGetBoolean(opt);
2945 /* don't "break", as explain.c will use the last value */
2948 return GetCommandLogLevel(stmt->query);
2950 /* Plain EXPLAIN isn't so interesting */
2955 case T_CreateTableAsStmt:
2959 case T_RefreshMatViewStmt:
2963 case T_AlterSystemStmt:
2967 case T_VariableSetStmt:
2971 case T_VariableShowStmt:
2979 case T_CreateTrigStmt:
2983 case T_CreateEventTrigStmt:
2987 case T_AlterEventTrigStmt:
2991 case T_CreatePLangStmt:
2995 case T_CreateDomainStmt:
2999 case T_CreateRoleStmt:
3003 case T_AlterRoleStmt:
3007 case T_AlterRoleSetStmt:
3011 case T_DropRoleStmt:
3015 case T_DropOwnedStmt:
3019 case T_ReassignOwnedStmt:
3027 case T_ConstraintsSetStmt:
3031 case T_CheckPointStmt:
3036 lev = LOGSTMT_ALL; /* should this be DDL? */
3039 case T_CreateConversionStmt:
3043 case T_CreateCastStmt:
3047 case T_CreateOpClassStmt:
3051 case T_CreateOpFamilyStmt:
3055 case T_CreateTransformStmt:
3059 case T_AlterOpFamilyStmt:
3063 case T_CreatePolicyStmt:
3067 case T_AlterPolicyStmt:
3071 case T_AlterTSDictionaryStmt:
3075 case T_AlterTSConfigurationStmt:
3079 /* already-planned queries */
3082 PlannedStmt *stmt = (PlannedStmt *) parsetree;
3084 switch (stmt->commandType)
3097 elog(WARNING, "unrecognized commandType: %d",
3098 (int) stmt->commandType);
3105 /* parsed-and-rewritten-but-not-planned queries */
3108 Query *stmt = (Query *) parsetree;
3110 switch (stmt->commandType)
3123 lev = GetCommandLogLevel(stmt->utilityStmt);
3127 elog(WARNING, "unrecognized commandType: %d",
3128 (int) stmt->commandType);
3137 elog(WARNING, "unrecognized node type: %d",
3138 (int) nodeTag(parsetree));