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
139 * or 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:
153 case T_AlterTableMoveAllStmt:
154 case T_AlterTableStmt:
158 case T_CreateCastStmt:
159 case T_CreateEventTrigStmt:
160 case T_AlterEventTrigStmt:
161 case T_CreateConversionStmt:
163 case T_CreateDomainStmt:
164 case T_CreateFunctionStmt:
165 case T_CreateRoleStmt:
167 case T_CreatePLangStmt:
168 case T_CreateOpClassStmt:
169 case T_CreateOpFamilyStmt:
170 case T_AlterOpFamilyStmt:
172 case T_CreateSchemaStmt:
173 case T_CreateSeqStmt:
175 case T_CreateTableAsStmt:
176 case T_RefreshMatViewStmt:
177 case T_CreateTableSpaceStmt:
178 case T_CreateTransformStmt:
179 case T_CreateTrigStmt:
180 case T_CompositeTypeStmt:
181 case T_CreateEnumStmt:
182 case T_CreateRangeStmt:
183 case T_AlterEnumStmt:
187 case T_DropTableSpaceStmt:
190 case T_GrantRoleStmt:
191 case T_AlterDefaultPrivilegesStmt:
193 case T_DropOwnedStmt:
194 case T_ReassignOwnedStmt:
195 case T_AlterTSDictionaryStmt:
196 case T_AlterTSConfigurationStmt:
197 case T_CreateExtensionStmt:
198 case T_AlterExtensionStmt:
199 case T_AlterExtensionContentsStmt:
200 case T_CreateFdwStmt:
202 case T_CreateForeignServerStmt:
203 case T_AlterForeignServerStmt:
204 case T_CreateUserMappingStmt:
205 case T_AlterUserMappingStmt:
206 case T_DropUserMappingStmt:
207 case T_AlterTableSpaceOptionsStmt:
208 case T_CreateForeignTableStmt:
209 case T_ImportForeignSchemaStmt:
211 PreventCommandIfReadOnly(CreateCommandTag(parsetree));
212 PreventCommandIfParallelMode(CreateCommandTag(parsetree));
221 * PreventCommandIfReadOnly: throw error if XactReadOnly
223 * This is useful mainly to ensure consistency of the error message wording;
224 * most callers have checked XactReadOnly for themselves.
227 PreventCommandIfReadOnly(const char *cmdname)
231 (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
232 /* translator: %s is name of a SQL command, eg CREATE */
233 errmsg("cannot execute %s in a read-only transaction",
238 * PreventCommandIfParallelMode: throw error if current (sub)transaction is
241 * This is useful mainly to ensure consistency of the error message wording;
242 * most callers have checked IsInParallelMode() for themselves.
245 PreventCommandIfParallelMode(const char *cmdname)
247 if (IsInParallelMode())
249 (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
250 /* translator: %s is name of a SQL command, eg CREATE */
251 errmsg("cannot execute %s during a parallel operation",
256 * PreventCommandDuringRecovery: throw error if RecoveryInProgress
258 * The majority of operations that are unsafe in a Hot Standby slave
259 * will be rejected by XactReadOnly tests. However there are a few
260 * commands that are allowed in "read-only" xacts but cannot be allowed
261 * in Hot Standby mode. Those commands should call this function.
264 PreventCommandDuringRecovery(const char *cmdname)
266 if (RecoveryInProgress())
268 (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
269 /* translator: %s is name of a SQL command, eg CREATE */
270 errmsg("cannot execute %s during recovery",
275 * CheckRestrictedOperation: throw error for hazardous command if we're
276 * inside a security restriction context.
278 * This is needed to protect session-local state for which there is not any
279 * better-defined protection mechanism, such as ownership.
282 CheckRestrictedOperation(const char *cmdname)
284 if (InSecurityRestrictedOperation())
286 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
287 /* translator: %s is name of a SQL command, eg PREPARE */
288 errmsg("cannot execute %s within security-restricted operation",
295 * general utility function invoker
297 * parsetree: the parse tree for the utility statement
298 * queryString: original source text of command
299 * context: identifies source of statement (toplevel client command,
300 * non-toplevel client command, subcommand of a larger utility command)
301 * params: parameters to use during execution
302 * dest: where to send results
303 * completionTag: points to a buffer of size COMPLETION_TAG_BUFSIZE
304 * in which to store a command completion status string.
306 * Notes: as of PG 8.4, caller MUST supply a queryString; it is not
307 * allowed anymore to pass NULL. (If you really don't have source text,
308 * you can pass a constant string, perhaps "(query not available)".)
310 * completionTag is only set nonempty if we want to return a nondefault status.
312 * completionTag may be NULL if caller doesn't want a status string.
315 ProcessUtility(Node *parsetree,
316 const char *queryString,
317 ProcessUtilityContext context,
318 ParamListInfo params,
322 Assert(queryString != NULL); /* required as of 8.4 */
325 * We provide a function hook variable that lets loadable plugins get
326 * control when ProcessUtility is called. Such a plugin would normally
327 * call standard_ProcessUtility().
329 if (ProcessUtility_hook)
330 (*ProcessUtility_hook) (parsetree, queryString,
332 dest, completionTag);
334 standard_ProcessUtility(parsetree, queryString,
336 dest, completionTag);
340 * standard_ProcessUtility itself deals only with utility commands for
341 * which we do not provide event trigger support. Commands that do have
342 * such support are passed down to ProcessUtilitySlow, which contains the
343 * necessary infrastructure for such triggers.
345 * This division is not just for performance: it's critical that the
346 * event trigger code not be invoked when doing START TRANSACTION for
347 * example, because we might need to refresh the event trigger cache,
348 * which requires being in a valid transaction.
351 standard_ProcessUtility(Node *parsetree,
352 const char *queryString,
353 ProcessUtilityContext context,
354 ParamListInfo params,
358 bool isTopLevel = (context == PROCESS_UTILITY_TOPLEVEL);
360 check_xact_readonly(parsetree);
363 completionTag[0] = '\0';
365 switch (nodeTag(parsetree))
368 * ******************** transactions ********************
370 case T_TransactionStmt:
372 TransactionStmt *stmt = (TransactionStmt *) parsetree;
377 * START TRANSACTION, as defined by SQL99: Identical
378 * to BEGIN. Same code for both.
380 case TRANS_STMT_BEGIN:
381 case TRANS_STMT_START:
385 BeginTransactionBlock();
386 foreach(lc, stmt->options)
388 DefElem *item = (DefElem *) lfirst(lc);
390 if (strcmp(item->defname, "transaction_isolation") == 0)
391 SetPGVariable("transaction_isolation",
392 list_make1(item->arg),
394 else if (strcmp(item->defname, "transaction_read_only") == 0)
395 SetPGVariable("transaction_read_only",
396 list_make1(item->arg),
398 else if (strcmp(item->defname, "transaction_deferrable") == 0)
399 SetPGVariable("transaction_deferrable",
400 list_make1(item->arg),
406 case TRANS_STMT_COMMIT:
407 if (!EndTransactionBlock())
409 /* report unsuccessful commit in completionTag */
411 strcpy(completionTag, "ROLLBACK");
415 case TRANS_STMT_PREPARE:
416 PreventCommandDuringRecovery("PREPARE TRANSACTION");
417 if (!PrepareTransactionBlock(stmt->gid))
419 /* report unsuccessful commit in completionTag */
421 strcpy(completionTag, "ROLLBACK");
425 case TRANS_STMT_COMMIT_PREPARED:
426 PreventTransactionChain(isTopLevel, "COMMIT PREPARED");
427 PreventCommandDuringRecovery("COMMIT PREPARED");
428 FinishPreparedTransaction(stmt->gid, true);
431 case TRANS_STMT_ROLLBACK_PREPARED:
432 PreventTransactionChain(isTopLevel, "ROLLBACK PREPARED");
433 PreventCommandDuringRecovery("ROLLBACK PREPARED");
434 FinishPreparedTransaction(stmt->gid, false);
437 case TRANS_STMT_ROLLBACK:
438 UserAbortTransactionBlock();
441 case TRANS_STMT_SAVEPOINT:
446 RequireTransactionChain(isTopLevel, "SAVEPOINT");
448 foreach(cell, stmt->options)
450 DefElem *elem = lfirst(cell);
452 if (strcmp(elem->defname, "savepoint_name") == 0)
453 name = strVal(elem->arg);
456 Assert(PointerIsValid(name));
458 DefineSavepoint(name);
462 case TRANS_STMT_RELEASE:
463 RequireTransactionChain(isTopLevel, "RELEASE SAVEPOINT");
464 ReleaseSavepoint(stmt->options);
467 case TRANS_STMT_ROLLBACK_TO:
468 RequireTransactionChain(isTopLevel, "ROLLBACK TO SAVEPOINT");
469 RollbackToSavepoint(stmt->options);
472 * CommitTransactionCommand is in charge of
473 * re-defining the savepoint again
481 * Portal (cursor) manipulation
483 * Note: DECLARE CURSOR is processed mostly as a SELECT, and
484 * therefore what we will get here is a PlannedStmt not a bare
489 PlannedStmt *stmt = (PlannedStmt *) parsetree;
491 if (stmt->utilityStmt == NULL ||
492 !IsA(stmt->utilityStmt, DeclareCursorStmt))
493 elog(ERROR, "non-DECLARE CURSOR PlannedStmt passed to ProcessUtility");
494 PerformCursorOpen(stmt, params, queryString, isTopLevel);
498 case T_ClosePortalStmt:
500 ClosePortalStmt *stmt = (ClosePortalStmt *) parsetree;
502 CheckRestrictedOperation("CLOSE");
503 PerformPortalClose(stmt->portalname);
508 PerformPortalFetch((FetchStmt *) parsetree, dest,
513 ExecuteDoStmt((DoStmt *) parsetree);
516 case T_CreateTableSpaceStmt:
517 /* no event triggers for global objects */
518 PreventTransactionChain(isTopLevel, "CREATE TABLESPACE");
519 CreateTableSpace((CreateTableSpaceStmt *) parsetree);
522 case T_DropTableSpaceStmt:
523 /* no event triggers for global objects */
524 PreventTransactionChain(isTopLevel, "DROP TABLESPACE");
525 DropTableSpace((DropTableSpaceStmt *) parsetree);
528 case T_AlterTableSpaceOptionsStmt:
529 /* no event triggers for global objects */
530 AlterTableSpaceOptions((AlterTableSpaceOptionsStmt *) parsetree);
534 ExecuteTruncate((TruncateStmt *) parsetree);
541 DoCopy((CopyStmt *) parsetree, queryString, &processed);
543 snprintf(completionTag, COMPLETION_TAG_BUFSIZE,
544 "COPY " UINT64_FORMAT, processed);
549 CheckRestrictedOperation("PREPARE");
550 PrepareQuery((PrepareStmt *) parsetree, queryString);
554 ExecuteQuery((ExecuteStmt *) parsetree, NULL,
556 dest, completionTag);
559 case T_DeallocateStmt:
560 CheckRestrictedOperation("DEALLOCATE");
561 DeallocateQuery((DeallocateStmt *) parsetree);
564 case T_GrantRoleStmt:
565 /* no event triggers for global objects */
566 GrantRole((GrantRoleStmt *) parsetree);
570 /* no event triggers for global objects */
571 PreventTransactionChain(isTopLevel, "CREATE DATABASE");
572 createdb((CreatedbStmt *) parsetree);
575 case T_AlterDatabaseStmt:
576 /* no event triggers for global objects */
577 AlterDatabase((AlterDatabaseStmt *) parsetree, isTopLevel);
580 case T_AlterDatabaseSetStmt:
581 /* no event triggers for global objects */
582 AlterDatabaseSet((AlterDatabaseSetStmt *) parsetree);
587 DropdbStmt *stmt = (DropdbStmt *) parsetree;
589 /* no event triggers for global objects */
590 PreventTransactionChain(isTopLevel, "DROP DATABASE");
591 dropdb(stmt->dbname, stmt->missing_ok);
595 /* Query-level asynchronous notification */
598 NotifyStmt *stmt = (NotifyStmt *) parsetree;
600 PreventCommandDuringRecovery("NOTIFY");
601 Async_Notify(stmt->conditionname, stmt->payload);
607 ListenStmt *stmt = (ListenStmt *) parsetree;
609 PreventCommandDuringRecovery("LISTEN");
610 CheckRestrictedOperation("LISTEN");
611 Async_Listen(stmt->conditionname);
617 UnlistenStmt *stmt = (UnlistenStmt *) parsetree;
619 PreventCommandDuringRecovery("UNLISTEN");
620 CheckRestrictedOperation("UNLISTEN");
621 if (stmt->conditionname)
622 Async_Unlisten(stmt->conditionname);
630 LoadStmt *stmt = (LoadStmt *) parsetree;
632 closeAllVfds(); /* probably not necessary... */
633 /* Allowed names are restricted if you're not superuser */
634 load_file(stmt->filename, !superuser());
639 /* we choose to allow this during "read only" transactions */
640 PreventCommandDuringRecovery("CLUSTER");
641 /* forbidden in parallel mode due to CommandIsReadOnly */
642 cluster((ClusterStmt *) parsetree, isTopLevel);
647 VacuumStmt *stmt = (VacuumStmt *) parsetree;
649 /* we choose to allow this during "read only" transactions */
650 PreventCommandDuringRecovery((stmt->options & VACOPT_VACUUM) ?
651 "VACUUM" : "ANALYZE");
652 /* forbidden in parallel mode due to CommandIsReadOnly */
653 ExecVacuum(stmt, isTopLevel);
658 ExplainQuery((ExplainStmt *) parsetree, queryString, params, dest);
661 case T_AlterSystemStmt:
662 PreventTransactionChain(isTopLevel, "ALTER SYSTEM");
663 AlterSystemSetConfigFile((AlterSystemStmt *) parsetree);
666 case T_VariableSetStmt:
667 ExecSetVariableStmt((VariableSetStmt *) parsetree, isTopLevel);
670 case T_VariableShowStmt:
672 VariableShowStmt *n = (VariableShowStmt *) parsetree;
674 GetPGVariable(n->name, dest);
679 /* should we allow DISCARD PLANS? */
680 CheckRestrictedOperation("DISCARD");
681 DiscardCommand((DiscardStmt *) parsetree, isTopLevel);
684 case T_CreateEventTrigStmt:
685 /* no event triggers on event triggers */
686 CreateEventTrigger((CreateEventTrigStmt *) parsetree);
689 case T_AlterEventTrigStmt:
690 /* no event triggers on event triggers */
691 AlterEventTrigger((AlterEventTrigStmt *) parsetree);
695 * ******************************** ROLE statements ****
697 case T_CreateRoleStmt:
698 /* no event triggers for global objects */
699 CreateRole((CreateRoleStmt *) parsetree);
702 case T_AlterRoleStmt:
703 /* no event triggers for global objects */
704 AlterRole((AlterRoleStmt *) parsetree);
707 case T_AlterRoleSetStmt:
708 /* no event triggers for global objects */
709 AlterRoleSet((AlterRoleSetStmt *) parsetree);
713 /* no event triggers for global objects */
714 DropRole((DropRoleStmt *) parsetree);
717 case T_ReassignOwnedStmt:
718 /* no event triggers for global objects */
719 ReassignOwnedObjects((ReassignOwnedStmt *) parsetree);
725 * Since the lock would just get dropped immediately, LOCK TABLE
726 * outside a transaction block is presumed to be user error.
728 RequireTransactionChain(isTopLevel, "LOCK TABLE");
729 /* forbidden in parallel mode due to CommandIsReadOnly */
730 LockTableCommand((LockStmt *) parsetree);
733 case T_ConstraintsSetStmt:
734 WarnNoTransactionChain(isTopLevel, "SET CONSTRAINTS");
735 AfterTriggerSetState((ConstraintsSetStmt *) parsetree);
738 case T_CheckPointStmt:
741 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
742 errmsg("must be superuser to do CHECKPOINT")));
745 * You might think we should have a PreventCommandDuringRecovery()
746 * here, but we interpret a CHECKPOINT command during recovery as
747 * a request for a restartpoint instead. We allow this since it
748 * can be a useful way of reducing switchover time when using
749 * various forms of replication.
751 RequestCheckpoint(CHECKPOINT_IMMEDIATE | CHECKPOINT_WAIT |
752 (RecoveryInProgress() ? 0 : CHECKPOINT_FORCE));
757 ReindexStmt *stmt = (ReindexStmt *) parsetree;
759 /* we choose to allow this during "read only" transactions */
760 PreventCommandDuringRecovery("REINDEX");
761 /* forbidden in parallel mode due to CommandIsReadOnly */
764 case REINDEX_OBJECT_INDEX:
765 ReindexIndex(stmt->relation);
767 case REINDEX_OBJECT_TABLE:
768 ReindexTable(stmt->relation);
770 case REINDEX_OBJECT_SCHEMA:
771 case REINDEX_OBJECT_SYSTEM:
772 case REINDEX_OBJECT_DATABASE:
775 * This cannot run inside a user transaction block; if
776 * we were inside a transaction, then its commit- and
777 * start-transaction-command calls would not have the
780 PreventTransactionChain(isTopLevel,
781 (stmt->kind == REINDEX_OBJECT_SCHEMA) ? "REINDEX SCHEMA" :
782 (stmt->kind == REINDEX_OBJECT_SYSTEM) ? "REINDEX SYSTEM" :
784 ReindexMultipleTables(stmt->name, stmt->kind);
787 elog(ERROR, "unrecognized object type: %d",
795 * The following statements are supported by Event Triggers only
796 * in some cases, so we "fast path" them in the other cases.
801 GrantStmt *stmt = (GrantStmt *) parsetree;
803 if (EventTriggerSupportsGrantObjectType(stmt->objtype))
804 ProcessUtilitySlow(parsetree, queryString,
806 dest, completionTag);
808 ExecuteGrantStmt((GrantStmt *) parsetree);
814 DropStmt *stmt = (DropStmt *) parsetree;
816 if (EventTriggerSupportsObjectType(stmt->removeType))
817 ProcessUtilitySlow(parsetree, queryString,
819 dest, completionTag);
821 ExecDropStmt(stmt, isTopLevel);
827 RenameStmt *stmt = (RenameStmt *) parsetree;
829 if (EventTriggerSupportsObjectType(stmt->renameType))
830 ProcessUtilitySlow(parsetree, queryString,
832 dest, completionTag);
834 ExecRenameStmt(stmt);
838 case T_AlterObjectSchemaStmt:
840 AlterObjectSchemaStmt *stmt = (AlterObjectSchemaStmt *) parsetree;
842 if (EventTriggerSupportsObjectType(stmt->objectType))
843 ProcessUtilitySlow(parsetree, queryString,
845 dest, completionTag);
847 ExecAlterObjectSchemaStmt(stmt, NULL);
851 case T_AlterOwnerStmt:
853 AlterOwnerStmt *stmt = (AlterOwnerStmt *) parsetree;
855 if (EventTriggerSupportsObjectType(stmt->objectType))
856 ProcessUtilitySlow(parsetree, queryString,
858 dest, completionTag);
860 ExecAlterOwnerStmt(stmt);
866 CommentStmt *stmt = (CommentStmt *) parsetree;
868 if (EventTriggerSupportsObjectType(stmt->objtype))
869 ProcessUtilitySlow(parsetree, queryString,
871 dest, completionTag);
873 CommentObject((CommentStmt *) parsetree);
879 SecLabelStmt *stmt = (SecLabelStmt *) parsetree;
881 if (EventTriggerSupportsObjectType(stmt->objtype))
882 ProcessUtilitySlow(parsetree, queryString,
884 dest, completionTag);
886 ExecSecLabelStmt(stmt);
891 /* All other statement types have event trigger support */
892 ProcessUtilitySlow(parsetree, queryString,
894 dest, completionTag);
900 * The "Slow" variant of ProcessUtility should only receive statements
901 * supported by the event triggers facility. Therefore, we always
902 * perform the trigger support calls if the context allows it.
905 ProcessUtilitySlow(Node *parsetree,
906 const char *queryString,
907 ProcessUtilityContext context,
908 ParamListInfo params,
912 bool isTopLevel = (context == PROCESS_UTILITY_TOPLEVEL);
913 bool isCompleteQuery = (context <= PROCESS_UTILITY_QUERY);
915 bool commandCollected = false;
916 ObjectAddress address;
917 ObjectAddress secondaryObject = InvalidObjectAddress;
919 /* All event trigger calls are done only when isCompleteQuery is true */
920 needCleanup = isCompleteQuery && EventTriggerBeginCompleteQuery();
922 /* PG_TRY block is to ensure we call EventTriggerEndCompleteQuery */
926 EventTriggerDDLCommandStart(parsetree);
928 switch (nodeTag(parsetree))
931 * relation and attribute manipulation
933 case T_CreateSchemaStmt:
934 CreateSchemaCommand((CreateSchemaStmt *) parsetree,
937 * EventTriggerCollectSimpleCommand called by
938 * CreateSchemaCommand
940 commandCollected = true;
944 case T_CreateForeignTableStmt:
949 /* Run parse analysis ... */
950 stmts = transformCreateStmt((CreateStmt *) parsetree,
956 Node *stmt = (Node *) lfirst(l);
958 if (IsA(stmt, CreateStmt))
961 static char *validnsps[] = HEAP_RELOPT_NAMESPACES;
963 /* Create the table itself */
964 address = DefineRelation((CreateStmt *) stmt,
967 EventTriggerCollectSimpleCommand(address,
972 * Let NewRelationCreateToastTable decide if this
973 * one needs a secondary relation too.
975 CommandCounterIncrement();
978 * parse and validate reloptions for the toast
981 toast_options = transformRelOptions((Datum) 0,
982 ((CreateStmt *) stmt)->options,
987 (void) heap_reloptions(RELKIND_TOASTVALUE,
991 NewRelationCreateToastTable(address.objectId,
994 else if (IsA(stmt, CreateForeignTableStmt))
996 /* Create the table itself */
997 address = DefineRelation((CreateStmt *) stmt,
998 RELKIND_FOREIGN_TABLE,
1000 CreateForeignTable((CreateForeignTableStmt *) stmt,
1002 EventTriggerCollectSimpleCommand(address,
1009 * Recurse for anything else. Note the recursive
1010 * call will stash the objects so created into our
1011 * event trigger context.
1013 ProcessUtility(stmt,
1015 PROCESS_UTILITY_SUBCOMMAND,
1021 /* Need CCI between commands */
1022 if (lnext(l) != NULL)
1023 CommandCounterIncrement();
1027 * The multiple commands generated here are stashed
1028 * individually, so disable collection below.
1030 commandCollected = true;
1034 case T_AlterTableStmt:
1036 AlterTableStmt *atstmt = (AlterTableStmt *) parsetree;
1043 * Figure out lock mode, and acquire lock. This also does
1044 * basic permissions checks, so that we won't wait for a
1045 * lock on (for example) a relation on which we have no
1048 lockmode = AlterTableGetLockLevel(atstmt->cmds);
1049 relid = AlterTableLookupRelation(atstmt, lockmode);
1051 if (OidIsValid(relid))
1053 /* Run parse analysis ... */
1054 stmts = transformAlterTableStmt(relid, atstmt,
1057 /* ... ensure we have an event trigger context ... */
1058 EventTriggerAlterTableStart(parsetree);
1059 EventTriggerAlterTableRelid(relid);
1064 Node *stmt = (Node *) lfirst(l);
1066 if (IsA(stmt, AlterTableStmt))
1068 /* Do the table alteration proper */
1069 AlterTable(relid, lockmode,
1070 (AlterTableStmt *) stmt);
1075 * Recurse for anything else. If we need to do
1076 * so, "close" the current complex-command set,
1077 * and start a new one at the bottom; this is
1078 * needed to ensure the ordering of queued
1079 * commands is consistent with the way they are
1082 EventTriggerAlterTableEnd();
1083 ProcessUtility(stmt,
1085 PROCESS_UTILITY_SUBCOMMAND,
1089 EventTriggerAlterTableStart(parsetree);
1090 EventTriggerAlterTableRelid(relid);
1093 /* Need CCI between commands */
1094 if (lnext(l) != NULL)
1095 CommandCounterIncrement();
1099 EventTriggerAlterTableEnd();
1103 (errmsg("relation \"%s\" does not exist, skipping",
1104 atstmt->relation->relname)));
1107 /* ALTER TABLE stashes commands internally */
1108 commandCollected = true;
1111 case T_AlterDomainStmt:
1113 AlterDomainStmt *stmt = (AlterDomainStmt *) parsetree;
1116 * Some or all of these functions are recursive to cover
1117 * inherited things, so permission checks are done there.
1119 switch (stmt->subtype)
1121 case 'T': /* ALTER DOMAIN DEFAULT */
1124 * Recursively alter column default for table and,
1125 * if requested, for descendants
1128 AlterDomainDefault(stmt->typeName,
1131 case 'N': /* ALTER DOMAIN DROP NOT NULL */
1133 AlterDomainNotNull(stmt->typeName,
1136 case 'O': /* ALTER DOMAIN SET NOT NULL */
1138 AlterDomainNotNull(stmt->typeName,
1141 case 'C': /* ADD CONSTRAINT */
1143 AlterDomainAddConstraint(stmt->typeName,
1147 case 'X': /* DROP CONSTRAINT */
1149 AlterDomainDropConstraint(stmt->typeName,
1154 case 'V': /* VALIDATE CONSTRAINT */
1156 AlterDomainValidateConstraint(stmt->typeName,
1160 elog(ERROR, "unrecognized alter domain type: %d",
1161 (int) stmt->subtype);
1168 * ************* object creation / destruction **************
1172 DefineStmt *stmt = (DefineStmt *) parsetree;
1176 case OBJECT_AGGREGATE:
1178 DefineAggregate(stmt->defnames, stmt->args,
1180 stmt->definition, queryString);
1182 case OBJECT_OPERATOR:
1183 Assert(stmt->args == NIL);
1184 address = DefineOperator(stmt->defnames,
1188 Assert(stmt->args == NIL);
1189 address = DefineType(stmt->defnames,
1192 case OBJECT_TSPARSER:
1193 Assert(stmt->args == NIL);
1194 address = DefineTSParser(stmt->defnames,
1197 case OBJECT_TSDICTIONARY:
1198 Assert(stmt->args == NIL);
1199 address = DefineTSDictionary(stmt->defnames,
1202 case OBJECT_TSTEMPLATE:
1203 Assert(stmt->args == NIL);
1204 address = DefineTSTemplate(stmt->defnames,
1207 case OBJECT_TSCONFIGURATION:
1208 Assert(stmt->args == NIL);
1209 address = DefineTSConfiguration(stmt->defnames,
1213 case OBJECT_COLLATION:
1214 Assert(stmt->args == NIL);
1215 address = DefineCollation(stmt->defnames,
1219 elog(ERROR, "unrecognized define stmt type: %d",
1226 case T_IndexStmt: /* CREATE INDEX */
1228 IndexStmt *stmt = (IndexStmt *) parsetree;
1232 if (stmt->concurrent)
1233 PreventTransactionChain(isTopLevel,
1234 "CREATE INDEX CONCURRENTLY");
1237 * Look up the relation OID just once, right here at the
1238 * beginning, so that we don't end up repeating the name
1239 * lookup later and latching onto a different relation
1240 * partway through. To avoid lock upgrade hazards, it's
1241 * important that we take the strongest lock that will
1242 * eventually be needed here, so the lockmode calculation
1243 * needs to match what DefineIndex() does.
1245 lockmode = stmt->concurrent ? ShareUpdateExclusiveLock
1248 RangeVarGetRelidExtended(stmt->relation, lockmode,
1250 RangeVarCallbackOwnsRelation,
1253 /* Run parse analysis ... */
1254 stmt = transformIndexStmt(relid, stmt, queryString);
1257 EventTriggerAlterTableStart(parsetree);
1259 DefineIndex(relid, /* OID of heap relation */
1261 InvalidOid, /* no predefined OID */
1262 false, /* is_alter_table */
1263 true, /* check_rights */
1264 false, /* skip_build */
1267 * Add the CREATE INDEX node itself to stash right away; if
1268 * there were any commands stashed in the ALTER TABLE code,
1269 * we need them to appear after this one.
1271 EventTriggerCollectSimpleCommand(address, secondaryObject,
1273 commandCollected = true;
1274 EventTriggerAlterTableEnd();
1278 case T_CreateExtensionStmt:
1279 address = CreateExtension((CreateExtensionStmt *) parsetree);
1282 case T_AlterExtensionStmt:
1283 address = ExecAlterExtensionStmt((AlterExtensionStmt *) parsetree);
1286 case T_AlterExtensionContentsStmt:
1287 address = ExecAlterExtensionContentsStmt((AlterExtensionContentsStmt *) parsetree,
1291 case T_CreateFdwStmt:
1292 address = CreateForeignDataWrapper((CreateFdwStmt *) parsetree);
1295 case T_AlterFdwStmt:
1296 address = AlterForeignDataWrapper((AlterFdwStmt *) parsetree);
1299 case T_CreateForeignServerStmt:
1300 address = CreateForeignServer((CreateForeignServerStmt *) parsetree);
1303 case T_AlterForeignServerStmt:
1304 address = AlterForeignServer((AlterForeignServerStmt *) parsetree);
1307 case T_CreateUserMappingStmt:
1308 address = CreateUserMapping((CreateUserMappingStmt *) parsetree);
1311 case T_AlterUserMappingStmt:
1312 address = AlterUserMapping((AlterUserMappingStmt *) parsetree);
1315 case T_DropUserMappingStmt:
1316 RemoveUserMapping((DropUserMappingStmt *) parsetree);
1317 /* no commands stashed for DROP */
1318 commandCollected = true;
1321 case T_ImportForeignSchemaStmt:
1322 ImportForeignSchema((ImportForeignSchemaStmt *) parsetree);
1323 /* commands are stashed inside ImportForeignSchema */
1324 commandCollected = true;
1327 case T_CompositeTypeStmt: /* CREATE TYPE (composite) */
1329 CompositeTypeStmt *stmt = (CompositeTypeStmt *) parsetree;
1331 address = DefineCompositeType(stmt->typevar,
1336 case T_CreateEnumStmt: /* CREATE TYPE AS ENUM */
1337 address = DefineEnum((CreateEnumStmt *) parsetree);
1340 case T_CreateRangeStmt: /* CREATE TYPE AS RANGE */
1341 address = DefineRange((CreateRangeStmt *) parsetree);
1344 case T_AlterEnumStmt: /* ALTER TYPE (enum) */
1345 address = AlterEnum((AlterEnumStmt *) parsetree, isTopLevel);
1348 case T_ViewStmt: /* CREATE VIEW */
1349 EventTriggerAlterTableStart(parsetree);
1350 address = DefineView((ViewStmt *) parsetree, queryString);
1351 EventTriggerCollectSimpleCommand(address, secondaryObject,
1353 /* stashed internally */
1354 commandCollected = true;
1355 EventTriggerAlterTableEnd();
1358 case T_CreateFunctionStmt: /* CREATE FUNCTION */
1359 address = CreateFunction((CreateFunctionStmt *) parsetree, queryString);
1362 case T_AlterFunctionStmt: /* ALTER FUNCTION */
1363 address = AlterFunction((AlterFunctionStmt *) parsetree);
1366 case T_RuleStmt: /* CREATE RULE */
1367 address = DefineRule((RuleStmt *) parsetree, queryString);
1370 case T_CreateSeqStmt:
1371 address = DefineSequence((CreateSeqStmt *) parsetree);
1374 case T_AlterSeqStmt:
1375 address = AlterSequence((AlterSeqStmt *) parsetree);
1378 case T_CreateTableAsStmt:
1379 address = ExecCreateTableAs((CreateTableAsStmt *) parsetree,
1380 queryString, params, completionTag);
1383 case T_RefreshMatViewStmt:
1385 * REFRSH CONCURRENTLY executes some DDL commands internally.
1386 * Inhibit DDL command collection here to avoid those commands
1387 * from showing up in the deparsed command queue. The refresh
1388 * command itself is queued, which is enough.
1390 EventTriggerInhibitCommandCollection();
1393 address = ExecRefreshMatView((RefreshMatViewStmt *) parsetree,
1394 queryString, params, completionTag);
1398 EventTriggerUndoInhibitCommandCollection();
1402 EventTriggerUndoInhibitCommandCollection();
1405 case T_CreateTrigStmt:
1406 address = CreateTrigger((CreateTrigStmt *) parsetree,
1407 queryString, InvalidOid, InvalidOid,
1408 InvalidOid, InvalidOid, false);
1411 case T_CreatePLangStmt:
1412 address = CreateProceduralLanguage((CreatePLangStmt *) parsetree);
1415 case T_CreateDomainStmt:
1416 address = DefineDomain((CreateDomainStmt *) parsetree);
1419 case T_CreateConversionStmt:
1420 address = CreateConversionCommand((CreateConversionStmt *) parsetree);
1423 case T_CreateCastStmt:
1424 address = CreateCast((CreateCastStmt *) parsetree);
1427 case T_CreateOpClassStmt:
1428 DefineOpClass((CreateOpClassStmt *) parsetree);
1429 /* command is stashed in DefineOpClass */
1430 commandCollected = true;
1433 case T_CreateOpFamilyStmt:
1434 address = DefineOpFamily((CreateOpFamilyStmt *) parsetree);
1437 case T_CreateTransformStmt:
1438 CreateTransform((CreateTransformStmt *) parsetree);
1441 case T_AlterOpFamilyStmt:
1442 AlterOpFamily((AlterOpFamilyStmt *) parsetree);
1443 /* commands are stashed in AlterOpFamily */
1444 commandCollected = true;
1447 case T_AlterTSDictionaryStmt:
1448 address = AlterTSDictionary((AlterTSDictionaryStmt *) parsetree);
1451 case T_AlterTSConfigurationStmt:
1452 address = AlterTSConfiguration((AlterTSConfigurationStmt *) parsetree);
1455 case T_AlterTableMoveAllStmt:
1456 AlterTableMoveAll((AlterTableMoveAllStmt *) parsetree);
1457 /* commands are stashed in AlterTableMoveAll */
1458 commandCollected = true;
1462 ExecDropStmt((DropStmt *) parsetree, isTopLevel);
1463 /* no commands stashed for DROP */
1464 commandCollected = true;
1468 address = ExecRenameStmt((RenameStmt *) parsetree);
1471 case T_AlterObjectSchemaStmt:
1473 ExecAlterObjectSchemaStmt((AlterObjectSchemaStmt *) parsetree,
1477 case T_AlterOwnerStmt:
1478 address = ExecAlterOwnerStmt((AlterOwnerStmt *) parsetree);
1482 address = CommentObject((CommentStmt *) parsetree);
1486 ExecuteGrantStmt((GrantStmt *) parsetree);
1487 /* commands are stashed in ExecGrantStmt_oids */
1488 commandCollected = true;
1491 case T_DropOwnedStmt:
1492 DropOwnedObjects((DropOwnedStmt *) parsetree);
1493 /* no commands stashed for DROP */
1494 commandCollected = true;
1497 case T_AlterDefaultPrivilegesStmt:
1498 ExecAlterDefaultPrivilegesStmt((AlterDefaultPrivilegesStmt *) parsetree);
1499 EventTriggerCollectAlterDefPrivs((AlterDefaultPrivilegesStmt *) parsetree);
1500 commandCollected = true;
1503 case T_CreatePolicyStmt: /* CREATE POLICY */
1504 address = CreatePolicy((CreatePolicyStmt *) parsetree);
1507 case T_AlterPolicyStmt: /* ALTER POLICY */
1508 address = AlterPolicy((AlterPolicyStmt *) parsetree);
1511 case T_SecLabelStmt:
1512 address = ExecSecLabelStmt((SecLabelStmt *) parsetree);
1516 elog(ERROR, "unrecognized node type: %d",
1517 (int) nodeTag(parsetree));
1522 * Remember the object so that ddl_command_end event triggers have
1525 if (!commandCollected)
1526 EventTriggerCollectSimpleCommand(address, secondaryObject,
1529 if (isCompleteQuery)
1531 EventTriggerSQLDrop(parsetree);
1532 EventTriggerDDLCommandEnd(parsetree);
1538 EventTriggerEndCompleteQuery();
1544 EventTriggerEndCompleteQuery();
1548 * Dispatch function for DropStmt
1551 ExecDropStmt(DropStmt *stmt, bool isTopLevel)
1553 switch (stmt->removeType)
1556 if (stmt->concurrent)
1557 PreventTransactionChain(isTopLevel,
1558 "DROP INDEX CONCURRENTLY");
1562 case OBJECT_SEQUENCE:
1564 case OBJECT_MATVIEW:
1565 case OBJECT_FOREIGN_TABLE:
1566 RemoveRelations(stmt);
1569 RemoveObjects(stmt);
1576 * UtilityReturnsTuples
1577 * Return "true" if this utility statement will send output to the
1580 * Generally, there should be a case here for each case in ProcessUtility
1581 * where "dest" is passed on.
1584 UtilityReturnsTuples(Node *parsetree)
1586 switch (nodeTag(parsetree))
1590 FetchStmt *stmt = (FetchStmt *) parsetree;
1595 portal = GetPortalByName(stmt->portalname);
1596 if (!PortalIsValid(portal))
1597 return false; /* not our business to raise error */
1598 return portal->tupDesc ? true : false;
1603 ExecuteStmt *stmt = (ExecuteStmt *) parsetree;
1604 PreparedStatement *entry;
1606 entry = FetchPreparedStatement(stmt->name, false);
1608 return false; /* not our business to raise error */
1609 if (entry->plansource->resultDesc)
1617 case T_VariableShowStmt:
1626 * UtilityTupleDescriptor
1627 * Fetch the actual output tuple descriptor for a utility statement
1628 * for which UtilityReturnsTuples() previously returned "true".
1630 * The returned descriptor is created in (or copied into) the current memory
1634 UtilityTupleDescriptor(Node *parsetree)
1636 switch (nodeTag(parsetree))
1640 FetchStmt *stmt = (FetchStmt *) parsetree;
1645 portal = GetPortalByName(stmt->portalname);
1646 if (!PortalIsValid(portal))
1647 return NULL; /* not our business to raise error */
1648 return CreateTupleDescCopy(portal->tupDesc);
1653 ExecuteStmt *stmt = (ExecuteStmt *) parsetree;
1654 PreparedStatement *entry;
1656 entry = FetchPreparedStatement(stmt->name, false);
1658 return NULL; /* not our business to raise error */
1659 return FetchPreparedStatementResultDesc(entry);
1663 return ExplainResultDesc((ExplainStmt *) parsetree);
1665 case T_VariableShowStmt:
1667 VariableShowStmt *n = (VariableShowStmt *) parsetree;
1669 return GetPGVariableResultDesc(n->name);
1679 * QueryReturnsTuples
1680 * Return "true" if this Query will send output to the destination.
1684 QueryReturnsTuples(Query *parsetree)
1686 switch (parsetree->commandType)
1689 /* returns tuples ... unless it's DECLARE CURSOR */
1690 if (parsetree->utilityStmt == NULL)
1696 /* the forms with RETURNING return tuples */
1697 if (parsetree->returningList)
1701 return UtilityReturnsTuples(parsetree->utilityStmt);
1704 /* probably shouldn't get here */
1707 return false; /* default */
1713 * UtilityContainsQuery
1714 * Return the contained Query, or NULL if there is none
1716 * Certain utility statements, such as EXPLAIN, contain a plannable Query.
1717 * This function encapsulates knowledge of exactly which ones do.
1718 * We assume it is invoked only on already-parse-analyzed statements
1719 * (else the contained parsetree isn't a Query yet).
1721 * In some cases (currently, only EXPLAIN of CREATE TABLE AS/SELECT INTO and
1722 * CREATE MATERIALIZED VIEW), potentially Query-containing utility statements
1723 * can be nested. This function will drill down to a non-utility Query, or
1724 * return NULL if none.
1727 UtilityContainsQuery(Node *parsetree)
1731 switch (nodeTag(parsetree))
1734 qry = (Query *) ((ExplainStmt *) parsetree)->query;
1735 Assert(IsA(qry, Query));
1736 if (qry->commandType == CMD_UTILITY)
1737 return UtilityContainsQuery(qry->utilityStmt);
1740 case T_CreateTableAsStmt:
1741 qry = (Query *) ((CreateTableAsStmt *) parsetree)->query;
1742 Assert(IsA(qry, Query));
1743 if (qry->commandType == CMD_UTILITY)
1744 return UtilityContainsQuery(qry->utilityStmt);
1754 * AlterObjectTypeCommandTag
1755 * helper function for CreateCommandTag
1757 * This covers most cases where ALTER is used with an ObjectType enum.
1760 AlterObjectTypeCommandTag(ObjectType objtype)
1766 case OBJECT_AGGREGATE:
1767 tag = "ALTER AGGREGATE";
1769 case OBJECT_ATTRIBUTE:
1775 case OBJECT_COLLATION:
1776 tag = "ALTER COLLATION";
1779 tag = "ALTER TABLE";
1781 case OBJECT_CONVERSION:
1782 tag = "ALTER CONVERSION";
1784 case OBJECT_DATABASE:
1785 tag = "ALTER DATABASE";
1788 case OBJECT_DOMCONSTRAINT:
1789 tag = "ALTER DOMAIN";
1791 case OBJECT_EXTENSION:
1792 tag = "ALTER EXTENSION";
1795 tag = "ALTER FOREIGN DATA WRAPPER";
1797 case OBJECT_FOREIGN_SERVER:
1798 tag = "ALTER SERVER";
1800 case OBJECT_FOREIGN_TABLE:
1801 tag = "ALTER FOREIGN TABLE";
1803 case OBJECT_FUNCTION:
1804 tag = "ALTER FUNCTION";
1807 tag = "ALTER INDEX";
1809 case OBJECT_LANGUAGE:
1810 tag = "ALTER LANGUAGE";
1812 case OBJECT_LARGEOBJECT:
1813 tag = "ALTER LARGE OBJECT";
1815 case OBJECT_OPCLASS:
1816 tag = "ALTER OPERATOR CLASS";
1818 case OBJECT_OPERATOR:
1819 tag = "ALTER OPERATOR";
1821 case OBJECT_OPFAMILY:
1822 tag = "ALTER OPERATOR FAMILY";
1825 tag = "ALTER POLICY";
1834 tag = "ALTER SCHEMA";
1836 case OBJECT_SEQUENCE:
1837 tag = "ALTER SEQUENCE";
1840 case OBJECT_TABCONSTRAINT:
1841 tag = "ALTER TABLE";
1843 case OBJECT_TABLESPACE:
1844 tag = "ALTER TABLESPACE";
1846 case OBJECT_TRIGGER:
1847 tag = "ALTER TRIGGER";
1849 case OBJECT_EVENT_TRIGGER:
1850 tag = "ALTER EVENT TRIGGER";
1852 case OBJECT_TSCONFIGURATION:
1853 tag = "ALTER TEXT SEARCH CONFIGURATION";
1855 case OBJECT_TSDICTIONARY:
1856 tag = "ALTER TEXT SEARCH DICTIONARY";
1858 case OBJECT_TSPARSER:
1859 tag = "ALTER TEXT SEARCH PARSER";
1861 case OBJECT_TSTEMPLATE:
1862 tag = "ALTER TEXT SEARCH TEMPLATE";
1870 case OBJECT_MATVIEW:
1871 tag = "ALTER MATERIALIZED VIEW";
1883 * utility to get a string representation of the command operation,
1884 * given either a raw (un-analyzed) parsetree or a planned query.
1886 * This must handle all command types, but since the vast majority
1887 * of 'em are utility commands, it seems sensible to keep it here.
1889 * NB: all result strings must be shorter than COMPLETION_TAG_BUFSIZE.
1890 * Also, the result must point at a true constant (permanent storage).
1893 CreateCommandTag(Node *parsetree)
1897 switch (nodeTag(parsetree))
1899 /* raw plannable queries */
1916 /* utility statements --- same whether raw or cooked */
1917 case T_TransactionStmt:
1919 TransactionStmt *stmt = (TransactionStmt *) parsetree;
1923 case TRANS_STMT_BEGIN:
1927 case TRANS_STMT_START:
1928 tag = "START TRANSACTION";
1931 case TRANS_STMT_COMMIT:
1935 case TRANS_STMT_ROLLBACK:
1936 case TRANS_STMT_ROLLBACK_TO:
1940 case TRANS_STMT_SAVEPOINT:
1944 case TRANS_STMT_RELEASE:
1948 case TRANS_STMT_PREPARE:
1949 tag = "PREPARE TRANSACTION";
1952 case TRANS_STMT_COMMIT_PREPARED:
1953 tag = "COMMIT PREPARED";
1956 case TRANS_STMT_ROLLBACK_PREPARED:
1957 tag = "ROLLBACK PREPARED";
1967 case T_DeclareCursorStmt:
1968 tag = "DECLARE CURSOR";
1971 case T_ClosePortalStmt:
1973 ClosePortalStmt *stmt = (ClosePortalStmt *) parsetree;
1975 if (stmt->portalname == NULL)
1976 tag = "CLOSE CURSOR ALL";
1978 tag = "CLOSE CURSOR";
1984 FetchStmt *stmt = (FetchStmt *) parsetree;
1986 tag = (stmt->ismove) ? "MOVE" : "FETCH";
1990 case T_CreateDomainStmt:
1991 tag = "CREATE DOMAIN";
1994 case T_CreateSchemaStmt:
1995 tag = "CREATE SCHEMA";
1999 tag = "CREATE TABLE";
2002 case T_CreateTableSpaceStmt:
2003 tag = "CREATE TABLESPACE";
2006 case T_DropTableSpaceStmt:
2007 tag = "DROP TABLESPACE";
2010 case T_AlterTableSpaceOptionsStmt:
2011 tag = "ALTER TABLESPACE";
2014 case T_CreateExtensionStmt:
2015 tag = "CREATE EXTENSION";
2018 case T_AlterExtensionStmt:
2019 tag = "ALTER EXTENSION";
2022 case T_AlterExtensionContentsStmt:
2023 tag = "ALTER EXTENSION";
2026 case T_CreateFdwStmt:
2027 tag = "CREATE FOREIGN DATA WRAPPER";
2030 case T_AlterFdwStmt:
2031 tag = "ALTER FOREIGN DATA WRAPPER";
2034 case T_CreateForeignServerStmt:
2035 tag = "CREATE SERVER";
2038 case T_AlterForeignServerStmt:
2039 tag = "ALTER SERVER";
2042 case T_CreateUserMappingStmt:
2043 tag = "CREATE USER MAPPING";
2046 case T_AlterUserMappingStmt:
2047 tag = "ALTER USER MAPPING";
2050 case T_DropUserMappingStmt:
2051 tag = "DROP USER MAPPING";
2054 case T_CreateForeignTableStmt:
2055 tag = "CREATE FOREIGN TABLE";
2058 case T_ImportForeignSchemaStmt:
2059 tag = "IMPORT FOREIGN SCHEMA";
2063 switch (((DropStmt *) parsetree)->removeType)
2068 case OBJECT_SEQUENCE:
2069 tag = "DROP SEQUENCE";
2074 case OBJECT_MATVIEW:
2075 tag = "DROP MATERIALIZED VIEW";
2084 tag = "DROP DOMAIN";
2086 case OBJECT_COLLATION:
2087 tag = "DROP COLLATION";
2089 case OBJECT_CONVERSION:
2090 tag = "DROP CONVERSION";
2093 tag = "DROP SCHEMA";
2095 case OBJECT_TSPARSER:
2096 tag = "DROP TEXT SEARCH PARSER";
2098 case OBJECT_TSDICTIONARY:
2099 tag = "DROP TEXT SEARCH DICTIONARY";
2101 case OBJECT_TSTEMPLATE:
2102 tag = "DROP TEXT SEARCH TEMPLATE";
2104 case OBJECT_TSCONFIGURATION:
2105 tag = "DROP TEXT SEARCH CONFIGURATION";
2107 case OBJECT_FOREIGN_TABLE:
2108 tag = "DROP FOREIGN TABLE";
2110 case OBJECT_EXTENSION:
2111 tag = "DROP EXTENSION";
2113 case OBJECT_FUNCTION:
2114 tag = "DROP FUNCTION";
2116 case OBJECT_AGGREGATE:
2117 tag = "DROP AGGREGATE";
2119 case OBJECT_OPERATOR:
2120 tag = "DROP OPERATOR";
2122 case OBJECT_LANGUAGE:
2123 tag = "DROP LANGUAGE";
2128 case OBJECT_TRIGGER:
2129 tag = "DROP TRIGGER";
2131 case OBJECT_EVENT_TRIGGER:
2132 tag = "DROP EVENT TRIGGER";
2138 tag = "DROP FOREIGN DATA WRAPPER";
2140 case OBJECT_FOREIGN_SERVER:
2141 tag = "DROP SERVER";
2143 case OBJECT_OPCLASS:
2144 tag = "DROP OPERATOR CLASS";
2146 case OBJECT_OPFAMILY:
2147 tag = "DROP OPERATOR FAMILY";
2150 tag = "DROP POLICY";
2152 case OBJECT_TRANSFORM:
2153 tag = "DROP TRANSFORM";
2160 case T_TruncateStmt:
2161 tag = "TRUNCATE TABLE";
2168 case T_SecLabelStmt:
2169 tag = "SECURITY LABEL";
2177 tag = AlterObjectTypeCommandTag(((RenameStmt *) parsetree)->renameType);
2180 case T_AlterObjectSchemaStmt:
2181 tag = AlterObjectTypeCommandTag(((AlterObjectSchemaStmt *) parsetree)->objectType);
2184 case T_AlterOwnerStmt:
2185 tag = AlterObjectTypeCommandTag(((AlterOwnerStmt *) parsetree)->objectType);
2188 case T_AlterTableMoveAllStmt:
2189 tag = AlterObjectTypeCommandTag(((AlterTableMoveAllStmt *) parsetree)->objtype);
2192 case T_AlterTableStmt:
2193 tag = AlterObjectTypeCommandTag(((AlterTableStmt *) parsetree)->relkind);
2196 case T_AlterDomainStmt:
2197 tag = "ALTER DOMAIN";
2200 case T_AlterFunctionStmt:
2201 tag = "ALTER FUNCTION";
2206 GrantStmt *stmt = (GrantStmt *) parsetree;
2208 tag = (stmt->is_grant) ? "GRANT" : "REVOKE";
2212 case T_GrantRoleStmt:
2214 GrantRoleStmt *stmt = (GrantRoleStmt *) parsetree;
2216 tag = (stmt->is_grant) ? "GRANT ROLE" : "REVOKE ROLE";
2220 case T_AlterDefaultPrivilegesStmt:
2221 tag = "ALTER DEFAULT PRIVILEGES";
2225 switch (((DefineStmt *) parsetree)->kind)
2227 case OBJECT_AGGREGATE:
2228 tag = "CREATE AGGREGATE";
2230 case OBJECT_OPERATOR:
2231 tag = "CREATE OPERATOR";
2234 tag = "CREATE TYPE";
2236 case OBJECT_TSPARSER:
2237 tag = "CREATE TEXT SEARCH PARSER";
2239 case OBJECT_TSDICTIONARY:
2240 tag = "CREATE TEXT SEARCH DICTIONARY";
2242 case OBJECT_TSTEMPLATE:
2243 tag = "CREATE TEXT SEARCH TEMPLATE";
2245 case OBJECT_TSCONFIGURATION:
2246 tag = "CREATE TEXT SEARCH CONFIGURATION";
2248 case OBJECT_COLLATION:
2249 tag = "CREATE COLLATION";
2256 case T_CompositeTypeStmt:
2257 tag = "CREATE TYPE";
2260 case T_CreateEnumStmt:
2261 tag = "CREATE TYPE";
2264 case T_CreateRangeStmt:
2265 tag = "CREATE TYPE";
2268 case T_AlterEnumStmt:
2273 tag = "CREATE VIEW";
2276 case T_CreateFunctionStmt:
2277 tag = "CREATE FUNCTION";
2281 tag = "CREATE INDEX";
2285 tag = "CREATE RULE";
2288 case T_CreateSeqStmt:
2289 tag = "CREATE SEQUENCE";
2292 case T_AlterSeqStmt:
2293 tag = "ALTER SEQUENCE";
2300 case T_CreatedbStmt:
2301 tag = "CREATE DATABASE";
2304 case T_AlterDatabaseStmt:
2305 tag = "ALTER DATABASE";
2308 case T_AlterDatabaseSetStmt:
2309 tag = "ALTER DATABASE";
2313 tag = "DROP DATABASE";
2324 case T_UnlistenStmt:
2337 if (((VacuumStmt *) parsetree)->options & VACOPT_VACUUM)
2347 case T_CreateTableAsStmt:
2348 switch (((CreateTableAsStmt *) parsetree)->relkind)
2351 if (((CreateTableAsStmt *) parsetree)->is_select_into)
2352 tag = "SELECT INTO";
2354 tag = "CREATE TABLE AS";
2356 case OBJECT_MATVIEW:
2357 tag = "CREATE MATERIALIZED VIEW";
2364 case T_RefreshMatViewStmt:
2365 tag = "REFRESH MATERIALIZED VIEW";
2368 case T_AlterSystemStmt:
2369 tag = "ALTER SYSTEM";
2372 case T_VariableSetStmt:
2373 switch (((VariableSetStmt *) parsetree)->kind)
2376 case VAR_SET_CURRENT:
2377 case VAR_SET_DEFAULT:
2390 case T_VariableShowStmt:
2395 switch (((DiscardStmt *) parsetree)->target)
2398 tag = "DISCARD ALL";
2401 tag = "DISCARD PLANS";
2404 tag = "DISCARD TEMP";
2406 case DISCARD_SEQUENCES:
2407 tag = "DISCARD SEQUENCES";
2414 case T_CreateTransformStmt:
2415 tag = "CREATE TRANSFORM";
2418 case T_CreateTrigStmt:
2419 tag = "CREATE TRIGGER";
2422 case T_CreateEventTrigStmt:
2423 tag = "CREATE EVENT TRIGGER";
2426 case T_AlterEventTrigStmt:
2427 tag = "ALTER EVENT TRIGGER";
2430 case T_CreatePLangStmt:
2431 tag = "CREATE LANGUAGE";
2434 case T_CreateRoleStmt:
2435 tag = "CREATE ROLE";
2438 case T_AlterRoleStmt:
2442 case T_AlterRoleSetStmt:
2446 case T_DropRoleStmt:
2450 case T_DropOwnedStmt:
2454 case T_ReassignOwnedStmt:
2455 tag = "REASSIGN OWNED";
2462 case T_ConstraintsSetStmt:
2463 tag = "SET CONSTRAINTS";
2466 case T_CheckPointStmt:
2474 case T_CreateConversionStmt:
2475 tag = "CREATE CONVERSION";
2478 case T_CreateCastStmt:
2479 tag = "CREATE CAST";
2482 case T_CreateOpClassStmt:
2483 tag = "CREATE OPERATOR CLASS";
2486 case T_CreateOpFamilyStmt:
2487 tag = "CREATE OPERATOR FAMILY";
2490 case T_AlterOpFamilyStmt:
2491 tag = "ALTER OPERATOR FAMILY";
2494 case T_AlterTSDictionaryStmt:
2495 tag = "ALTER TEXT SEARCH DICTIONARY";
2498 case T_AlterTSConfigurationStmt:
2499 tag = "ALTER TEXT SEARCH CONFIGURATION";
2502 case T_CreatePolicyStmt:
2503 tag = "CREATE POLICY";
2506 case T_AlterPolicyStmt:
2507 tag = "ALTER POLICY";
2518 case T_DeallocateStmt:
2520 DeallocateStmt *stmt = (DeallocateStmt *) parsetree;
2522 if (stmt->name == NULL)
2523 tag = "DEALLOCATE ALL";
2529 /* already-planned queries */
2532 PlannedStmt *stmt = (PlannedStmt *) parsetree;
2534 switch (stmt->commandType)
2539 * We take a little extra care here so that the result
2540 * will be useful for complaints about read-only
2543 if (stmt->utilityStmt != NULL)
2545 Assert(IsA(stmt->utilityStmt, DeclareCursorStmt));
2546 tag = "DECLARE CURSOR";
2548 else if (stmt->rowMarks != NIL)
2550 /* not 100% but probably close enough */
2551 switch (((PlanRowMark *) linitial(stmt->rowMarks))->strength)
2553 case LCS_FORKEYSHARE:
2554 tag = "SELECT FOR KEY SHARE";
2557 tag = "SELECT FOR SHARE";
2559 case LCS_FORNOKEYUPDATE:
2560 tag = "SELECT FOR NO KEY UPDATE";
2563 tag = "SELECT FOR UPDATE";
2583 elog(WARNING, "unrecognized commandType: %d",
2584 (int) stmt->commandType);
2591 /* parsed-and-rewritten-but-not-planned queries */
2594 Query *stmt = (Query *) parsetree;
2596 switch (stmt->commandType)
2601 * We take a little extra care here so that the result
2602 * will be useful for complaints about read-only
2605 if (stmt->utilityStmt != NULL)
2607 Assert(IsA(stmt->utilityStmt, DeclareCursorStmt));
2608 tag = "DECLARE CURSOR";
2610 else if (stmt->rowMarks != NIL)
2612 /* not 100% but probably close enough */
2613 switch (((RowMarkClause *) linitial(stmt->rowMarks))->strength)
2615 case LCS_FORKEYSHARE:
2616 tag = "SELECT FOR KEY SHARE";
2619 tag = "SELECT FOR SHARE";
2621 case LCS_FORNOKEYUPDATE:
2622 tag = "SELECT FOR NO KEY UPDATE";
2625 tag = "SELECT FOR UPDATE";
2645 tag = CreateCommandTag(stmt->utilityStmt);
2648 elog(WARNING, "unrecognized commandType: %d",
2649 (int) stmt->commandType);
2657 elog(WARNING, "unrecognized node type: %d",
2658 (int) nodeTag(parsetree));
2668 * GetCommandLogLevel
2669 * utility to get the minimum log_statement level for a command,
2670 * given either a raw (un-analyzed) parsetree or a planned query.
2672 * This must handle all command types, but since the vast majority
2673 * of 'em are utility commands, it seems sensible to keep it here.
2676 GetCommandLogLevel(Node *parsetree)
2680 switch (nodeTag(parsetree))
2682 /* raw plannable queries */
2690 if (((SelectStmt *) parsetree)->intoClause)
2691 lev = LOGSTMT_DDL; /* SELECT INTO */
2696 /* utility statements --- same whether raw or cooked */
2697 case T_TransactionStmt:
2701 case T_DeclareCursorStmt:
2705 case T_ClosePortalStmt:
2713 case T_CreateSchemaStmt:
2718 case T_CreateForeignTableStmt:
2722 case T_CreateTableSpaceStmt:
2723 case T_DropTableSpaceStmt:
2724 case T_AlterTableSpaceOptionsStmt:
2728 case T_CreateExtensionStmt:
2729 case T_AlterExtensionStmt:
2730 case T_AlterExtensionContentsStmt:
2734 case T_CreateFdwStmt:
2735 case T_AlterFdwStmt:
2736 case T_CreateForeignServerStmt:
2737 case T_AlterForeignServerStmt:
2738 case T_CreateUserMappingStmt:
2739 case T_AlterUserMappingStmt:
2740 case T_DropUserMappingStmt:
2741 case T_ImportForeignSchemaStmt:
2749 case T_TruncateStmt:
2757 case T_SecLabelStmt:
2762 if (((CopyStmt *) parsetree)->is_from)
2770 PrepareStmt *stmt = (PrepareStmt *) parsetree;
2772 /* Look through a PREPARE to the contained stmt */
2773 lev = GetCommandLogLevel(stmt->query);
2779 ExecuteStmt *stmt = (ExecuteStmt *) parsetree;
2780 PreparedStatement *ps;
2782 /* Look through an EXECUTE to the referenced stmt */
2783 ps = FetchPreparedStatement(stmt->name, false);
2784 if (ps && ps->plansource->raw_parse_tree)
2785 lev = GetCommandLogLevel(ps->plansource->raw_parse_tree);
2791 case T_DeallocateStmt:
2799 case T_AlterObjectSchemaStmt:
2803 case T_AlterOwnerStmt:
2807 case T_AlterTableMoveAllStmt:
2808 case T_AlterTableStmt:
2812 case T_AlterDomainStmt:
2820 case T_GrantRoleStmt:
2824 case T_AlterDefaultPrivilegesStmt:
2832 case T_CompositeTypeStmt:
2836 case T_CreateEnumStmt:
2840 case T_CreateRangeStmt:
2844 case T_AlterEnumStmt:
2852 case T_CreateFunctionStmt:
2856 case T_AlterFunctionStmt:
2868 case T_CreateSeqStmt:
2872 case T_AlterSeqStmt:
2880 case T_CreatedbStmt:
2884 case T_AlterDatabaseStmt:
2888 case T_AlterDatabaseSetStmt:
2904 case T_UnlistenStmt:
2922 ExplainStmt *stmt = (ExplainStmt *) parsetree;
2923 bool analyze = false;
2926 /* Look through an EXPLAIN ANALYZE to the contained stmt */
2927 foreach(lc, stmt->options)
2929 DefElem *opt = (DefElem *) lfirst(lc);
2931 if (strcmp(opt->defname, "analyze") == 0)
2932 analyze = defGetBoolean(opt);
2933 /* don't "break", as explain.c will use the last value */
2936 return GetCommandLogLevel(stmt->query);
2938 /* Plain EXPLAIN isn't so interesting */
2943 case T_CreateTableAsStmt:
2947 case T_RefreshMatViewStmt:
2951 case T_AlterSystemStmt:
2955 case T_VariableSetStmt:
2959 case T_VariableShowStmt:
2967 case T_CreateTrigStmt:
2971 case T_CreateEventTrigStmt:
2975 case T_AlterEventTrigStmt:
2979 case T_CreatePLangStmt:
2983 case T_CreateDomainStmt:
2987 case T_CreateRoleStmt:
2991 case T_AlterRoleStmt:
2995 case T_AlterRoleSetStmt:
2999 case T_DropRoleStmt:
3003 case T_DropOwnedStmt:
3007 case T_ReassignOwnedStmt:
3015 case T_ConstraintsSetStmt:
3019 case T_CheckPointStmt:
3024 lev = LOGSTMT_ALL; /* should this be DDL? */
3027 case T_CreateConversionStmt:
3031 case T_CreateCastStmt:
3035 case T_CreateOpClassStmt:
3039 case T_CreateOpFamilyStmt:
3043 case T_CreateTransformStmt:
3047 case T_AlterOpFamilyStmt:
3051 case T_CreatePolicyStmt:
3055 case T_AlterPolicyStmt:
3059 case T_AlterTSDictionaryStmt:
3063 case T_AlterTSConfigurationStmt:
3067 /* already-planned queries */
3070 PlannedStmt *stmt = (PlannedStmt *) parsetree;
3072 switch (stmt->commandType)
3085 elog(WARNING, "unrecognized commandType: %d",
3086 (int) stmt->commandType);
3093 /* parsed-and-rewritten-but-not-planned queries */
3096 Query *stmt = (Query *) parsetree;
3098 switch (stmt->commandType)
3111 lev = GetCommandLogLevel(stmt->utilityStmt);
3115 elog(WARNING, "unrecognized commandType: %d",
3116 (int) stmt->commandType);
3125 elog(WARNING, "unrecognized node type: %d",
3126 (int) nodeTag(parsetree));