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)
135 * Note: Commands that need to do more complicated checking are handled
136 * elsewhere, in particular COPY and plannable statements do their own
137 * checking. However they should all call PreventCommandIfReadOnly to
138 * actually throw the error.
141 switch (nodeTag(parsetree))
143 case T_AlterDatabaseStmt:
144 case T_AlterDatabaseSetStmt:
145 case T_AlterDomainStmt:
146 case T_AlterFunctionStmt:
147 case T_AlterRoleStmt:
148 case T_AlterRoleSetStmt:
149 case T_AlterObjectSchemaStmt:
150 case T_AlterOwnerStmt:
152 case T_AlterTableMoveAllStmt:
153 case T_AlterTableStmt:
157 case T_CreateCastStmt:
158 case T_CreateEventTrigStmt:
159 case T_AlterEventTrigStmt:
160 case T_CreateConversionStmt:
162 case T_CreateDomainStmt:
163 case T_CreateFunctionStmt:
164 case T_CreateRoleStmt:
166 case T_CreatePLangStmt:
167 case T_CreateOpClassStmt:
168 case T_CreateOpFamilyStmt:
169 case T_AlterOpFamilyStmt:
171 case T_CreateSchemaStmt:
172 case T_CreateSeqStmt:
174 case T_CreateTableAsStmt:
175 case T_RefreshMatViewStmt:
176 case T_CreateTableSpaceStmt:
177 case T_CreateTransformStmt:
178 case T_CreateTrigStmt:
179 case T_CompositeTypeStmt:
180 case T_CreateEnumStmt:
181 case T_CreateRangeStmt:
182 case T_AlterEnumStmt:
186 case T_DropTableSpaceStmt:
189 case T_GrantRoleStmt:
190 case T_AlterDefaultPrivilegesStmt:
192 case T_DropOwnedStmt:
193 case T_ReassignOwnedStmt:
194 case T_AlterTSDictionaryStmt:
195 case T_AlterTSConfigurationStmt:
196 case T_CreateExtensionStmt:
197 case T_AlterExtensionStmt:
198 case T_AlterExtensionContentsStmt:
199 case T_CreateFdwStmt:
201 case T_CreateForeignServerStmt:
202 case T_AlterForeignServerStmt:
203 case T_CreateUserMappingStmt:
204 case T_AlterUserMappingStmt:
205 case T_DropUserMappingStmt:
206 case T_AlterTableSpaceOptionsStmt:
207 case T_CreateForeignTableStmt:
208 case T_ImportForeignSchemaStmt:
210 PreventCommandIfReadOnly(CreateCommandTag(parsetree));
219 * PreventCommandIfReadOnly: throw error if XactReadOnly
221 * This is useful mainly to ensure consistency of the error message wording;
222 * most callers have checked XactReadOnly for themselves.
225 PreventCommandIfReadOnly(const char *cmdname)
229 (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
230 /* translator: %s is name of a SQL command, eg CREATE */
231 errmsg("cannot execute %s in a read-only transaction",
236 * PreventCommandDuringRecovery: throw error if RecoveryInProgress
238 * The majority of operations that are unsafe in a Hot Standby slave
239 * will be rejected by XactReadOnly tests. However there are a few
240 * commands that are allowed in "read-only" xacts but cannot be allowed
241 * in Hot Standby mode. Those commands should call this function.
244 PreventCommandDuringRecovery(const char *cmdname)
246 if (RecoveryInProgress())
248 (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
249 /* translator: %s is name of a SQL command, eg CREATE */
250 errmsg("cannot execute %s during recovery",
255 * CheckRestrictedOperation: throw error for hazardous command if we're
256 * inside a security restriction context.
258 * This is needed to protect session-local state for which there is not any
259 * better-defined protection mechanism, such as ownership.
262 CheckRestrictedOperation(const char *cmdname)
264 if (InSecurityRestrictedOperation())
266 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
267 /* translator: %s is name of a SQL command, eg PREPARE */
268 errmsg("cannot execute %s within security-restricted operation",
275 * general utility function invoker
277 * parsetree: the parse tree for the utility statement
278 * queryString: original source text of command
279 * context: identifies source of statement (toplevel client command,
280 * non-toplevel client command, subcommand of a larger utility command)
281 * params: parameters to use during execution
282 * dest: where to send results
283 * completionTag: points to a buffer of size COMPLETION_TAG_BUFSIZE
284 * in which to store a command completion status string.
286 * Notes: as of PG 8.4, caller MUST supply a queryString; it is not
287 * allowed anymore to pass NULL. (If you really don't have source text,
288 * you can pass a constant string, perhaps "(query not available)".)
290 * completionTag is only set nonempty if we want to return a nondefault status.
292 * completionTag may be NULL if caller doesn't want a status string.
295 ProcessUtility(Node *parsetree,
296 const char *queryString,
297 ProcessUtilityContext context,
298 ParamListInfo params,
302 Assert(queryString != NULL); /* required as of 8.4 */
305 * We provide a function hook variable that lets loadable plugins get
306 * control when ProcessUtility is called. Such a plugin would normally
307 * call standard_ProcessUtility().
309 if (ProcessUtility_hook)
310 (*ProcessUtility_hook) (parsetree, queryString,
312 dest, completionTag);
314 standard_ProcessUtility(parsetree, queryString,
316 dest, completionTag);
320 * standard_ProcessUtility itself deals only with utility commands for
321 * which we do not provide event trigger support. Commands that do have
322 * such support are passed down to ProcessUtilitySlow, which contains the
323 * necessary infrastructure for such triggers.
325 * This division is not just for performance: it's critical that the
326 * event trigger code not be invoked when doing START TRANSACTION for
327 * example, because we might need to refresh the event trigger cache,
328 * which requires being in a valid transaction.
331 standard_ProcessUtility(Node *parsetree,
332 const char *queryString,
333 ProcessUtilityContext context,
334 ParamListInfo params,
338 bool isTopLevel = (context == PROCESS_UTILITY_TOPLEVEL);
340 check_xact_readonly(parsetree);
343 completionTag[0] = '\0';
345 switch (nodeTag(parsetree))
348 * ******************** transactions ********************
350 case T_TransactionStmt:
352 TransactionStmt *stmt = (TransactionStmt *) parsetree;
357 * START TRANSACTION, as defined by SQL99: Identical
358 * to BEGIN. Same code for both.
360 case TRANS_STMT_BEGIN:
361 case TRANS_STMT_START:
365 BeginTransactionBlock();
366 foreach(lc, stmt->options)
368 DefElem *item = (DefElem *) lfirst(lc);
370 if (strcmp(item->defname, "transaction_isolation") == 0)
371 SetPGVariable("transaction_isolation",
372 list_make1(item->arg),
374 else if (strcmp(item->defname, "transaction_read_only") == 0)
375 SetPGVariable("transaction_read_only",
376 list_make1(item->arg),
378 else if (strcmp(item->defname, "transaction_deferrable") == 0)
379 SetPGVariable("transaction_deferrable",
380 list_make1(item->arg),
386 case TRANS_STMT_COMMIT:
387 if (!EndTransactionBlock())
389 /* report unsuccessful commit in completionTag */
391 strcpy(completionTag, "ROLLBACK");
395 case TRANS_STMT_PREPARE:
396 PreventCommandDuringRecovery("PREPARE TRANSACTION");
397 if (!PrepareTransactionBlock(stmt->gid))
399 /* report unsuccessful commit in completionTag */
401 strcpy(completionTag, "ROLLBACK");
405 case TRANS_STMT_COMMIT_PREPARED:
406 PreventTransactionChain(isTopLevel, "COMMIT PREPARED");
407 PreventCommandDuringRecovery("COMMIT PREPARED");
408 FinishPreparedTransaction(stmt->gid, true);
411 case TRANS_STMT_ROLLBACK_PREPARED:
412 PreventTransactionChain(isTopLevel, "ROLLBACK PREPARED");
413 PreventCommandDuringRecovery("ROLLBACK PREPARED");
414 FinishPreparedTransaction(stmt->gid, false);
417 case TRANS_STMT_ROLLBACK:
418 UserAbortTransactionBlock();
421 case TRANS_STMT_SAVEPOINT:
426 RequireTransactionChain(isTopLevel, "SAVEPOINT");
428 foreach(cell, stmt->options)
430 DefElem *elem = lfirst(cell);
432 if (strcmp(elem->defname, "savepoint_name") == 0)
433 name = strVal(elem->arg);
436 Assert(PointerIsValid(name));
438 DefineSavepoint(name);
442 case TRANS_STMT_RELEASE:
443 RequireTransactionChain(isTopLevel, "RELEASE SAVEPOINT");
444 ReleaseSavepoint(stmt->options);
447 case TRANS_STMT_ROLLBACK_TO:
448 RequireTransactionChain(isTopLevel, "ROLLBACK TO SAVEPOINT");
449 RollbackToSavepoint(stmt->options);
452 * CommitTransactionCommand is in charge of
453 * re-defining the savepoint again
461 * Portal (cursor) manipulation
463 * Note: DECLARE CURSOR is processed mostly as a SELECT, and
464 * therefore what we will get here is a PlannedStmt not a bare
469 PlannedStmt *stmt = (PlannedStmt *) parsetree;
471 if (stmt->utilityStmt == NULL ||
472 !IsA(stmt->utilityStmt, DeclareCursorStmt))
473 elog(ERROR, "non-DECLARE CURSOR PlannedStmt passed to ProcessUtility");
474 PerformCursorOpen(stmt, params, queryString, isTopLevel);
478 case T_ClosePortalStmt:
480 ClosePortalStmt *stmt = (ClosePortalStmt *) parsetree;
482 CheckRestrictedOperation("CLOSE");
483 PerformPortalClose(stmt->portalname);
488 PerformPortalFetch((FetchStmt *) parsetree, dest,
493 ExecuteDoStmt((DoStmt *) parsetree);
496 case T_CreateTableSpaceStmt:
497 /* no event triggers for global objects */
498 PreventTransactionChain(isTopLevel, "CREATE TABLESPACE");
499 CreateTableSpace((CreateTableSpaceStmt *) parsetree);
502 case T_DropTableSpaceStmt:
503 /* no event triggers for global objects */
504 PreventTransactionChain(isTopLevel, "DROP TABLESPACE");
505 DropTableSpace((DropTableSpaceStmt *) parsetree);
508 case T_AlterTableSpaceOptionsStmt:
509 /* no event triggers for global objects */
510 AlterTableSpaceOptions((AlterTableSpaceOptionsStmt *) parsetree);
514 ExecuteTruncate((TruncateStmt *) parsetree);
521 DoCopy((CopyStmt *) parsetree, queryString, &processed);
523 snprintf(completionTag, COMPLETION_TAG_BUFSIZE,
524 "COPY " UINT64_FORMAT, processed);
529 CheckRestrictedOperation("PREPARE");
530 PrepareQuery((PrepareStmt *) parsetree, queryString);
534 ExecuteQuery((ExecuteStmt *) parsetree, NULL,
536 dest, completionTag);
539 case T_DeallocateStmt:
540 CheckRestrictedOperation("DEALLOCATE");
541 DeallocateQuery((DeallocateStmt *) parsetree);
544 case T_GrantRoleStmt:
545 /* no event triggers for global objects */
546 GrantRole((GrantRoleStmt *) parsetree);
550 /* no event triggers for global objects */
551 PreventTransactionChain(isTopLevel, "CREATE DATABASE");
552 createdb((CreatedbStmt *) parsetree);
555 case T_AlterDatabaseStmt:
556 /* no event triggers for global objects */
557 AlterDatabase((AlterDatabaseStmt *) parsetree, isTopLevel);
560 case T_AlterDatabaseSetStmt:
561 /* no event triggers for global objects */
562 AlterDatabaseSet((AlterDatabaseSetStmt *) parsetree);
567 DropdbStmt *stmt = (DropdbStmt *) parsetree;
569 /* no event triggers for global objects */
570 PreventTransactionChain(isTopLevel, "DROP DATABASE");
571 dropdb(stmt->dbname, stmt->missing_ok);
575 /* Query-level asynchronous notification */
578 NotifyStmt *stmt = (NotifyStmt *) parsetree;
580 PreventCommandDuringRecovery("NOTIFY");
581 Async_Notify(stmt->conditionname, stmt->payload);
587 ListenStmt *stmt = (ListenStmt *) parsetree;
589 PreventCommandDuringRecovery("LISTEN");
590 CheckRestrictedOperation("LISTEN");
591 Async_Listen(stmt->conditionname);
597 UnlistenStmt *stmt = (UnlistenStmt *) parsetree;
599 PreventCommandDuringRecovery("UNLISTEN");
600 CheckRestrictedOperation("UNLISTEN");
601 if (stmt->conditionname)
602 Async_Unlisten(stmt->conditionname);
610 LoadStmt *stmt = (LoadStmt *) parsetree;
612 closeAllVfds(); /* probably not necessary... */
613 /* Allowed names are restricted if you're not superuser */
614 load_file(stmt->filename, !superuser());
619 /* we choose to allow this during "read only" transactions */
620 PreventCommandDuringRecovery("CLUSTER");
621 cluster((ClusterStmt *) parsetree, isTopLevel);
626 VacuumStmt *stmt = (VacuumStmt *) parsetree;
628 /* we choose to allow this during "read only" transactions */
629 PreventCommandDuringRecovery((stmt->options & VACOPT_VACUUM) ?
630 "VACUUM" : "ANALYZE");
631 ExecVacuum(stmt, isTopLevel);
636 ExplainQuery((ExplainStmt *) parsetree, queryString, params, dest);
639 case T_AlterSystemStmt:
640 PreventTransactionChain(isTopLevel, "ALTER SYSTEM");
641 AlterSystemSetConfigFile((AlterSystemStmt *) parsetree);
644 case T_VariableSetStmt:
645 ExecSetVariableStmt((VariableSetStmt *) parsetree, isTopLevel);
648 case T_VariableShowStmt:
650 VariableShowStmt *n = (VariableShowStmt *) parsetree;
652 GetPGVariable(n->name, dest);
657 /* should we allow DISCARD PLANS? */
658 CheckRestrictedOperation("DISCARD");
659 DiscardCommand((DiscardStmt *) parsetree, isTopLevel);
662 case T_CreateEventTrigStmt:
663 /* no event triggers on event triggers */
664 CreateEventTrigger((CreateEventTrigStmt *) parsetree);
667 case T_AlterEventTrigStmt:
668 /* no event triggers on event triggers */
669 AlterEventTrigger((AlterEventTrigStmt *) parsetree);
673 * ******************************** ROLE statements ****
675 case T_CreateRoleStmt:
676 /* no event triggers for global objects */
677 CreateRole((CreateRoleStmt *) parsetree);
680 case T_AlterRoleStmt:
681 /* no event triggers for global objects */
682 AlterRole((AlterRoleStmt *) parsetree);
685 case T_AlterRoleSetStmt:
686 /* no event triggers for global objects */
687 AlterRoleSet((AlterRoleSetStmt *) parsetree);
691 /* no event triggers for global objects */
692 DropRole((DropRoleStmt *) parsetree);
695 case T_ReassignOwnedStmt:
696 /* no event triggers for global objects */
697 ReassignOwnedObjects((ReassignOwnedStmt *) parsetree);
703 * Since the lock would just get dropped immediately, LOCK TABLE
704 * outside a transaction block is presumed to be user error.
706 RequireTransactionChain(isTopLevel, "LOCK TABLE");
707 LockTableCommand((LockStmt *) parsetree);
710 case T_ConstraintsSetStmt:
711 WarnNoTransactionChain(isTopLevel, "SET CONSTRAINTS");
712 AfterTriggerSetState((ConstraintsSetStmt *) parsetree);
715 case T_CheckPointStmt:
718 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
719 errmsg("must be superuser to do CHECKPOINT")));
722 * You might think we should have a PreventCommandDuringRecovery()
723 * here, but we interpret a CHECKPOINT command during recovery as
724 * a request for a restartpoint instead. We allow this since it
725 * can be a useful way of reducing switchover time when using
726 * various forms of replication.
728 RequestCheckpoint(CHECKPOINT_IMMEDIATE | CHECKPOINT_WAIT |
729 (RecoveryInProgress() ? 0 : CHECKPOINT_FORCE));
734 ReindexStmt *stmt = (ReindexStmt *) parsetree;
736 /* we choose to allow this during "read only" transactions */
737 PreventCommandDuringRecovery("REINDEX");
740 case REINDEX_OBJECT_INDEX:
741 ReindexIndex(stmt->relation);
743 case REINDEX_OBJECT_TABLE:
744 ReindexTable(stmt->relation);
746 case REINDEX_OBJECT_SCHEMA:
747 case REINDEX_OBJECT_SYSTEM:
748 case REINDEX_OBJECT_DATABASE:
751 * This cannot run inside a user transaction block; if
752 * we were inside a transaction, then its commit- and
753 * start-transaction-command calls would not have the
756 PreventTransactionChain(isTopLevel,
757 (stmt->kind == REINDEX_OBJECT_SCHEMA) ? "REINDEX SCHEMA" :
758 (stmt->kind == REINDEX_OBJECT_SYSTEM) ? "REINDEX SYSTEM" :
760 ReindexMultipleTables(stmt->name, stmt->kind);
763 elog(ERROR, "unrecognized object type: %d",
771 * The following statements are supported by Event Triggers only
772 * in some cases, so we "fast path" them in the other cases.
777 GrantStmt *stmt = (GrantStmt *) parsetree;
779 if (EventTriggerSupportsGrantObjectType(stmt->objtype))
780 ProcessUtilitySlow(parsetree, queryString,
782 dest, completionTag);
784 ExecuteGrantStmt((GrantStmt *) parsetree);
790 DropStmt *stmt = (DropStmt *) parsetree;
792 if (EventTriggerSupportsObjectType(stmt->removeType))
793 ProcessUtilitySlow(parsetree, queryString,
795 dest, completionTag);
797 ExecDropStmt(stmt, isTopLevel);
803 RenameStmt *stmt = (RenameStmt *) parsetree;
805 if (EventTriggerSupportsObjectType(stmt->renameType))
806 ProcessUtilitySlow(parsetree, queryString,
808 dest, completionTag);
810 ExecRenameStmt(stmt);
814 case T_AlterObjectSchemaStmt:
816 AlterObjectSchemaStmt *stmt = (AlterObjectSchemaStmt *) parsetree;
818 if (EventTriggerSupportsObjectType(stmt->objectType))
819 ProcessUtilitySlow(parsetree, queryString,
821 dest, completionTag);
823 ExecAlterObjectSchemaStmt(stmt, NULL);
827 case T_AlterOwnerStmt:
829 AlterOwnerStmt *stmt = (AlterOwnerStmt *) parsetree;
831 if (EventTriggerSupportsObjectType(stmt->objectType))
832 ProcessUtilitySlow(parsetree, queryString,
834 dest, completionTag);
836 ExecAlterOwnerStmt(stmt);
842 CommentStmt *stmt = (CommentStmt *) parsetree;
844 if (EventTriggerSupportsObjectType(stmt->objtype))
845 ProcessUtilitySlow(parsetree, queryString,
847 dest, completionTag);
849 CommentObject((CommentStmt *) parsetree);
855 SecLabelStmt *stmt = (SecLabelStmt *) parsetree;
857 if (EventTriggerSupportsObjectType(stmt->objtype))
858 ProcessUtilitySlow(parsetree, queryString,
860 dest, completionTag);
862 ExecSecLabelStmt(stmt);
867 /* All other statement types have event trigger support */
868 ProcessUtilitySlow(parsetree, queryString,
870 dest, completionTag);
876 * The "Slow" variant of ProcessUtility should only receive statements
877 * supported by the event triggers facility. Therefore, we always
878 * perform the trigger support calls if the context allows it.
881 ProcessUtilitySlow(Node *parsetree,
882 const char *queryString,
883 ProcessUtilityContext context,
884 ParamListInfo params,
888 bool isTopLevel = (context == PROCESS_UTILITY_TOPLEVEL);
889 bool isCompleteQuery = (context <= PROCESS_UTILITY_QUERY);
891 ObjectAddress address;
893 /* All event trigger calls are done only when isCompleteQuery is true */
894 needCleanup = isCompleteQuery && EventTriggerBeginCompleteQuery();
896 /* PG_TRY block is to ensure we call EventTriggerEndCompleteQuery */
900 EventTriggerDDLCommandStart(parsetree);
902 switch (nodeTag(parsetree))
905 * relation and attribute manipulation
907 case T_CreateSchemaStmt:
908 CreateSchemaCommand((CreateSchemaStmt *) parsetree,
913 case T_CreateForeignTableStmt:
918 /* Run parse analysis ... */
919 stmts = transformCreateStmt((CreateStmt *) parsetree,
925 Node *stmt = (Node *) lfirst(l);
927 if (IsA(stmt, CreateStmt))
930 static char *validnsps[] = HEAP_RELOPT_NAMESPACES;
932 /* Create the table itself */
933 address = DefineRelation((CreateStmt *) stmt,
938 * Let NewRelationCreateToastTable decide if this
939 * one needs a secondary relation too.
941 CommandCounterIncrement();
944 * parse and validate reloptions for the toast
947 toast_options = transformRelOptions((Datum) 0,
948 ((CreateStmt *) stmt)->options,
953 (void) heap_reloptions(RELKIND_TOASTVALUE,
957 NewRelationCreateToastTable(address.objectId,
960 else if (IsA(stmt, CreateForeignTableStmt))
962 /* Create the table itself */
963 address = DefineRelation((CreateStmt *) stmt,
964 RELKIND_FOREIGN_TABLE,
966 CreateForeignTable((CreateForeignTableStmt *) stmt,
971 /* Recurse for anything else */
974 PROCESS_UTILITY_SUBCOMMAND,
980 /* Need CCI between commands */
981 if (lnext(l) != NULL)
982 CommandCounterIncrement();
987 case T_AlterTableStmt:
989 AlterTableStmt *atstmt = (AlterTableStmt *) parsetree;
996 * Figure out lock mode, and acquire lock. This also does
997 * basic permissions checks, so that we won't wait for a
998 * lock on (for example) a relation on which we have no
1001 lockmode = AlterTableGetLockLevel(atstmt->cmds);
1002 relid = AlterTableLookupRelation(atstmt, lockmode);
1004 if (OidIsValid(relid))
1006 /* Run parse analysis ... */
1007 stmts = transformAlterTableStmt(relid, atstmt,
1013 Node *stmt = (Node *) lfirst(l);
1015 if (IsA(stmt, AlterTableStmt))
1017 /* Do the table alteration proper */
1018 AlterTable(relid, lockmode,
1019 (AlterTableStmt *) stmt);
1023 /* Recurse for anything else */
1024 ProcessUtility(stmt,
1026 PROCESS_UTILITY_SUBCOMMAND,
1032 /* Need CCI between commands */
1033 if (lnext(l) != NULL)
1034 CommandCounterIncrement();
1039 (errmsg("relation \"%s\" does not exist, skipping",
1040 atstmt->relation->relname)));
1044 case T_AlterDomainStmt:
1046 AlterDomainStmt *stmt = (AlterDomainStmt *) parsetree;
1049 * Some or all of these functions are recursive to cover
1050 * inherited things, so permission checks are done there.
1052 switch (stmt->subtype)
1054 case 'T': /* ALTER DOMAIN DEFAULT */
1057 * Recursively alter column default for table and,
1058 * if requested, for descendants
1060 AlterDomainDefault(stmt->typeName,
1063 case 'N': /* ALTER DOMAIN DROP NOT NULL */
1064 AlterDomainNotNull(stmt->typeName,
1067 case 'O': /* ALTER DOMAIN SET NOT NULL */
1068 AlterDomainNotNull(stmt->typeName,
1071 case 'C': /* ADD CONSTRAINT */
1072 AlterDomainAddConstraint(stmt->typeName,
1076 case 'X': /* DROP CONSTRAINT */
1077 AlterDomainDropConstraint(stmt->typeName,
1082 case 'V': /* VALIDATE CONSTRAINT */
1083 AlterDomainValidateConstraint(stmt->typeName,
1087 elog(ERROR, "unrecognized alter domain type: %d",
1088 (int) stmt->subtype);
1095 * ************* object creation / destruction **************
1099 DefineStmt *stmt = (DefineStmt *) parsetree;
1103 case OBJECT_AGGREGATE:
1104 DefineAggregate(stmt->defnames, stmt->args,
1105 stmt->oldstyle, stmt->definition,
1108 case OBJECT_OPERATOR:
1109 Assert(stmt->args == NIL);
1110 DefineOperator(stmt->defnames, stmt->definition);
1113 Assert(stmt->args == NIL);
1114 DefineType(stmt->defnames, stmt->definition);
1116 case OBJECT_TSPARSER:
1117 Assert(stmt->args == NIL);
1118 DefineTSParser(stmt->defnames, stmt->definition);
1120 case OBJECT_TSDICTIONARY:
1121 Assert(stmt->args == NIL);
1122 DefineTSDictionary(stmt->defnames,
1125 case OBJECT_TSTEMPLATE:
1126 Assert(stmt->args == NIL);
1127 DefineTSTemplate(stmt->defnames,
1130 case OBJECT_TSCONFIGURATION:
1131 Assert(stmt->args == NIL);
1132 DefineTSConfiguration(stmt->defnames,
1136 case OBJECT_COLLATION:
1137 Assert(stmt->args == NIL);
1138 DefineCollation(stmt->defnames, stmt->definition);
1141 elog(ERROR, "unrecognized define stmt type: %d",
1148 case T_IndexStmt: /* CREATE INDEX */
1150 IndexStmt *stmt = (IndexStmt *) parsetree;
1154 if (stmt->concurrent)
1155 PreventTransactionChain(isTopLevel,
1156 "CREATE INDEX CONCURRENTLY");
1159 * Look up the relation OID just once, right here at the
1160 * beginning, so that we don't end up repeating the name
1161 * lookup later and latching onto a different relation
1162 * partway through. To avoid lock upgrade hazards, it's
1163 * important that we take the strongest lock that will
1164 * eventually be needed here, so the lockmode calculation
1165 * needs to match what DefineIndex() does.
1167 lockmode = stmt->concurrent ? ShareUpdateExclusiveLock
1170 RangeVarGetRelidExtended(stmt->relation, lockmode,
1172 RangeVarCallbackOwnsRelation,
1175 /* Run parse analysis ... */
1176 stmt = transformIndexStmt(relid, stmt, queryString);
1179 DefineIndex(relid, /* OID of heap relation */
1181 InvalidOid, /* no predefined OID */
1182 false, /* is_alter_table */
1183 true, /* check_rights */
1184 false, /* skip_build */
1189 case T_CreateExtensionStmt:
1190 CreateExtension((CreateExtensionStmt *) parsetree);
1193 case T_AlterExtensionStmt:
1194 ExecAlterExtensionStmt((AlterExtensionStmt *) parsetree);
1197 case T_AlterExtensionContentsStmt:
1198 ExecAlterExtensionContentsStmt((AlterExtensionContentsStmt *) parsetree,
1202 case T_CreateFdwStmt:
1203 CreateForeignDataWrapper((CreateFdwStmt *) parsetree);
1206 case T_AlterFdwStmt:
1207 AlterForeignDataWrapper((AlterFdwStmt *) parsetree);
1210 case T_CreateForeignServerStmt:
1211 CreateForeignServer((CreateForeignServerStmt *) parsetree);
1214 case T_AlterForeignServerStmt:
1215 AlterForeignServer((AlterForeignServerStmt *) parsetree);
1218 case T_CreateUserMappingStmt:
1219 CreateUserMapping((CreateUserMappingStmt *) parsetree);
1222 case T_AlterUserMappingStmt:
1223 AlterUserMapping((AlterUserMappingStmt *) parsetree);
1226 case T_DropUserMappingStmt:
1227 RemoveUserMapping((DropUserMappingStmt *) parsetree);
1230 case T_ImportForeignSchemaStmt:
1231 ImportForeignSchema((ImportForeignSchemaStmt *) parsetree);
1234 case T_CompositeTypeStmt: /* CREATE TYPE (composite) */
1236 CompositeTypeStmt *stmt = (CompositeTypeStmt *) parsetree;
1238 DefineCompositeType(stmt->typevar, stmt->coldeflist);
1242 case T_CreateEnumStmt: /* CREATE TYPE AS ENUM */
1243 DefineEnum((CreateEnumStmt *) parsetree);
1246 case T_CreateRangeStmt: /* CREATE TYPE AS RANGE */
1247 DefineRange((CreateRangeStmt *) parsetree);
1250 case T_AlterEnumStmt: /* ALTER TYPE (enum) */
1251 AlterEnum((AlterEnumStmt *) parsetree, isTopLevel);
1254 case T_ViewStmt: /* CREATE VIEW */
1255 DefineView((ViewStmt *) parsetree, queryString);
1258 case T_CreateFunctionStmt: /* CREATE FUNCTION */
1259 CreateFunction((CreateFunctionStmt *) parsetree, queryString);
1262 case T_AlterFunctionStmt: /* ALTER FUNCTION */
1263 AlterFunction((AlterFunctionStmt *) parsetree);
1266 case T_RuleStmt: /* CREATE RULE */
1267 DefineRule((RuleStmt *) parsetree, queryString);
1270 case T_CreateSeqStmt:
1271 DefineSequence((CreateSeqStmt *) parsetree);
1274 case T_AlterSeqStmt:
1275 AlterSequence((AlterSeqStmt *) parsetree);
1278 case T_CreateTableAsStmt:
1279 ExecCreateTableAs((CreateTableAsStmt *) parsetree,
1280 queryString, params, completionTag);
1283 case T_RefreshMatViewStmt:
1284 ExecRefreshMatView((RefreshMatViewStmt *) parsetree,
1285 queryString, params, completionTag);
1288 case T_CreateTrigStmt:
1289 (void) CreateTrigger((CreateTrigStmt *) parsetree, queryString,
1290 InvalidOid, InvalidOid, InvalidOid,
1294 case T_CreatePLangStmt:
1295 CreateProceduralLanguage((CreatePLangStmt *) parsetree);
1298 case T_CreateDomainStmt:
1299 DefineDomain((CreateDomainStmt *) parsetree);
1302 case T_CreateConversionStmt:
1303 CreateConversionCommand((CreateConversionStmt *) parsetree);
1306 case T_CreateCastStmt:
1307 CreateCast((CreateCastStmt *) parsetree);
1310 case T_CreateOpClassStmt:
1311 DefineOpClass((CreateOpClassStmt *) parsetree);
1314 case T_CreateOpFamilyStmt:
1315 DefineOpFamily((CreateOpFamilyStmt *) parsetree);
1318 case T_CreateTransformStmt:
1319 CreateTransform((CreateTransformStmt *) parsetree);
1322 case T_AlterOpFamilyStmt:
1323 AlterOpFamily((AlterOpFamilyStmt *) parsetree);
1326 case T_AlterTSDictionaryStmt:
1327 AlterTSDictionary((AlterTSDictionaryStmt *) parsetree);
1330 case T_AlterTSConfigurationStmt:
1331 AlterTSConfiguration((AlterTSConfigurationStmt *) parsetree);
1334 case T_AlterTableMoveAllStmt:
1335 AlterTableMoveAll((AlterTableMoveAllStmt *) parsetree);
1339 ExecDropStmt((DropStmt *) parsetree, isTopLevel);
1343 ExecRenameStmt((RenameStmt *) parsetree);
1346 case T_AlterObjectSchemaStmt:
1347 ExecAlterObjectSchemaStmt((AlterObjectSchemaStmt *) parsetree,
1351 case T_AlterOwnerStmt:
1352 ExecAlterOwnerStmt((AlterOwnerStmt *) parsetree);
1356 CommentObject((CommentStmt *) parsetree);
1360 ExecuteGrantStmt((GrantStmt *) parsetree);
1363 case T_DropOwnedStmt:
1364 DropOwnedObjects((DropOwnedStmt *) parsetree);
1367 case T_AlterDefaultPrivilegesStmt:
1368 ExecAlterDefaultPrivilegesStmt((AlterDefaultPrivilegesStmt *) parsetree);
1371 case T_CreatePolicyStmt: /* CREATE POLICY */
1372 CreatePolicy((CreatePolicyStmt *) parsetree);
1375 case T_AlterPolicyStmt: /* ALTER POLICY */
1376 AlterPolicy((AlterPolicyStmt *) parsetree);
1379 case T_SecLabelStmt:
1380 ExecSecLabelStmt((SecLabelStmt *) parsetree);
1384 elog(ERROR, "unrecognized node type: %d",
1385 (int) nodeTag(parsetree));
1389 if (isCompleteQuery)
1391 EventTriggerSQLDrop(parsetree);
1392 EventTriggerDDLCommandEnd(parsetree);
1398 EventTriggerEndCompleteQuery();
1404 EventTriggerEndCompleteQuery();
1408 * Dispatch function for DropStmt
1411 ExecDropStmt(DropStmt *stmt, bool isTopLevel)
1413 switch (stmt->removeType)
1416 if (stmt->concurrent)
1417 PreventTransactionChain(isTopLevel,
1418 "DROP INDEX CONCURRENTLY");
1422 case OBJECT_SEQUENCE:
1424 case OBJECT_MATVIEW:
1425 case OBJECT_FOREIGN_TABLE:
1426 RemoveRelations(stmt);
1429 RemoveObjects(stmt);
1436 * UtilityReturnsTuples
1437 * Return "true" if this utility statement will send output to the
1440 * Generally, there should be a case here for each case in ProcessUtility
1441 * where "dest" is passed on.
1444 UtilityReturnsTuples(Node *parsetree)
1446 switch (nodeTag(parsetree))
1450 FetchStmt *stmt = (FetchStmt *) parsetree;
1455 portal = GetPortalByName(stmt->portalname);
1456 if (!PortalIsValid(portal))
1457 return false; /* not our business to raise error */
1458 return portal->tupDesc ? true : false;
1463 ExecuteStmt *stmt = (ExecuteStmt *) parsetree;
1464 PreparedStatement *entry;
1466 entry = FetchPreparedStatement(stmt->name, false);
1468 return false; /* not our business to raise error */
1469 if (entry->plansource->resultDesc)
1477 case T_VariableShowStmt:
1486 * UtilityTupleDescriptor
1487 * Fetch the actual output tuple descriptor for a utility statement
1488 * for which UtilityReturnsTuples() previously returned "true".
1490 * The returned descriptor is created in (or copied into) the current memory
1494 UtilityTupleDescriptor(Node *parsetree)
1496 switch (nodeTag(parsetree))
1500 FetchStmt *stmt = (FetchStmt *) parsetree;
1505 portal = GetPortalByName(stmt->portalname);
1506 if (!PortalIsValid(portal))
1507 return NULL; /* not our business to raise error */
1508 return CreateTupleDescCopy(portal->tupDesc);
1513 ExecuteStmt *stmt = (ExecuteStmt *) parsetree;
1514 PreparedStatement *entry;
1516 entry = FetchPreparedStatement(stmt->name, false);
1518 return NULL; /* not our business to raise error */
1519 return FetchPreparedStatementResultDesc(entry);
1523 return ExplainResultDesc((ExplainStmt *) parsetree);
1525 case T_VariableShowStmt:
1527 VariableShowStmt *n = (VariableShowStmt *) parsetree;
1529 return GetPGVariableResultDesc(n->name);
1539 * QueryReturnsTuples
1540 * Return "true" if this Query will send output to the destination.
1544 QueryReturnsTuples(Query *parsetree)
1546 switch (parsetree->commandType)
1549 /* returns tuples ... unless it's DECLARE CURSOR */
1550 if (parsetree->utilityStmt == NULL)
1556 /* the forms with RETURNING return tuples */
1557 if (parsetree->returningList)
1561 return UtilityReturnsTuples(parsetree->utilityStmt);
1564 /* probably shouldn't get here */
1567 return false; /* default */
1573 * UtilityContainsQuery
1574 * Return the contained Query, or NULL if there is none
1576 * Certain utility statements, such as EXPLAIN, contain a plannable Query.
1577 * This function encapsulates knowledge of exactly which ones do.
1578 * We assume it is invoked only on already-parse-analyzed statements
1579 * (else the contained parsetree isn't a Query yet).
1581 * In some cases (currently, only EXPLAIN of CREATE TABLE AS/SELECT INTO and
1582 * CREATE MATERIALIZED VIEW), potentially Query-containing utility statements
1583 * can be nested. This function will drill down to a non-utility Query, or
1584 * return NULL if none.
1587 UtilityContainsQuery(Node *parsetree)
1591 switch (nodeTag(parsetree))
1594 qry = (Query *) ((ExplainStmt *) parsetree)->query;
1595 Assert(IsA(qry, Query));
1596 if (qry->commandType == CMD_UTILITY)
1597 return UtilityContainsQuery(qry->utilityStmt);
1600 case T_CreateTableAsStmt:
1601 qry = (Query *) ((CreateTableAsStmt *) parsetree)->query;
1602 Assert(IsA(qry, Query));
1603 if (qry->commandType == CMD_UTILITY)
1604 return UtilityContainsQuery(qry->utilityStmt);
1614 * AlterObjectTypeCommandTag
1615 * helper function for CreateCommandTag
1617 * This covers most cases where ALTER is used with an ObjectType enum.
1620 AlterObjectTypeCommandTag(ObjectType objtype)
1626 case OBJECT_AGGREGATE:
1627 tag = "ALTER AGGREGATE";
1629 case OBJECT_ATTRIBUTE:
1635 case OBJECT_COLLATION:
1636 tag = "ALTER COLLATION";
1639 tag = "ALTER TABLE";
1641 case OBJECT_CONVERSION:
1642 tag = "ALTER CONVERSION";
1644 case OBJECT_DATABASE:
1645 tag = "ALTER DATABASE";
1648 case OBJECT_DOMCONSTRAINT:
1649 tag = "ALTER DOMAIN";
1651 case OBJECT_EXTENSION:
1652 tag = "ALTER EXTENSION";
1655 tag = "ALTER FOREIGN DATA WRAPPER";
1657 case OBJECT_FOREIGN_SERVER:
1658 tag = "ALTER SERVER";
1660 case OBJECT_FOREIGN_TABLE:
1661 tag = "ALTER FOREIGN TABLE";
1663 case OBJECT_FUNCTION:
1664 tag = "ALTER FUNCTION";
1667 tag = "ALTER INDEX";
1669 case OBJECT_LANGUAGE:
1670 tag = "ALTER LANGUAGE";
1672 case OBJECT_LARGEOBJECT:
1673 tag = "ALTER LARGE OBJECT";
1675 case OBJECT_OPCLASS:
1676 tag = "ALTER OPERATOR CLASS";
1678 case OBJECT_OPERATOR:
1679 tag = "ALTER OPERATOR";
1681 case OBJECT_OPFAMILY:
1682 tag = "ALTER OPERATOR FAMILY";
1685 tag = "ALTER POLICY";
1694 tag = "ALTER SCHEMA";
1696 case OBJECT_SEQUENCE:
1697 tag = "ALTER SEQUENCE";
1700 case OBJECT_TABCONSTRAINT:
1701 tag = "ALTER TABLE";
1703 case OBJECT_TABLESPACE:
1704 tag = "ALTER TABLESPACE";
1706 case OBJECT_TRIGGER:
1707 tag = "ALTER TRIGGER";
1709 case OBJECT_EVENT_TRIGGER:
1710 tag = "ALTER EVENT TRIGGER";
1712 case OBJECT_TSCONFIGURATION:
1713 tag = "ALTER TEXT SEARCH CONFIGURATION";
1715 case OBJECT_TSDICTIONARY:
1716 tag = "ALTER TEXT SEARCH DICTIONARY";
1718 case OBJECT_TSPARSER:
1719 tag = "ALTER TEXT SEARCH PARSER";
1721 case OBJECT_TSTEMPLATE:
1722 tag = "ALTER TEXT SEARCH TEMPLATE";
1730 case OBJECT_MATVIEW:
1731 tag = "ALTER MATERIALIZED VIEW";
1743 * utility to get a string representation of the command operation,
1744 * given either a raw (un-analyzed) parsetree or a planned query.
1746 * This must handle all command types, but since the vast majority
1747 * of 'em are utility commands, it seems sensible to keep it here.
1749 * NB: all result strings must be shorter than COMPLETION_TAG_BUFSIZE.
1750 * Also, the result must point at a true constant (permanent storage).
1753 CreateCommandTag(Node *parsetree)
1757 switch (nodeTag(parsetree))
1759 /* raw plannable queries */
1776 /* utility statements --- same whether raw or cooked */
1777 case T_TransactionStmt:
1779 TransactionStmt *stmt = (TransactionStmt *) parsetree;
1783 case TRANS_STMT_BEGIN:
1787 case TRANS_STMT_START:
1788 tag = "START TRANSACTION";
1791 case TRANS_STMT_COMMIT:
1795 case TRANS_STMT_ROLLBACK:
1796 case TRANS_STMT_ROLLBACK_TO:
1800 case TRANS_STMT_SAVEPOINT:
1804 case TRANS_STMT_RELEASE:
1808 case TRANS_STMT_PREPARE:
1809 tag = "PREPARE TRANSACTION";
1812 case TRANS_STMT_COMMIT_PREPARED:
1813 tag = "COMMIT PREPARED";
1816 case TRANS_STMT_ROLLBACK_PREPARED:
1817 tag = "ROLLBACK PREPARED";
1827 case T_DeclareCursorStmt:
1828 tag = "DECLARE CURSOR";
1831 case T_ClosePortalStmt:
1833 ClosePortalStmt *stmt = (ClosePortalStmt *) parsetree;
1835 if (stmt->portalname == NULL)
1836 tag = "CLOSE CURSOR ALL";
1838 tag = "CLOSE CURSOR";
1844 FetchStmt *stmt = (FetchStmt *) parsetree;
1846 tag = (stmt->ismove) ? "MOVE" : "FETCH";
1850 case T_CreateDomainStmt:
1851 tag = "CREATE DOMAIN";
1854 case T_CreateSchemaStmt:
1855 tag = "CREATE SCHEMA";
1859 tag = "CREATE TABLE";
1862 case T_CreateTableSpaceStmt:
1863 tag = "CREATE TABLESPACE";
1866 case T_DropTableSpaceStmt:
1867 tag = "DROP TABLESPACE";
1870 case T_AlterTableSpaceOptionsStmt:
1871 tag = "ALTER TABLESPACE";
1874 case T_CreateExtensionStmt:
1875 tag = "CREATE EXTENSION";
1878 case T_AlterExtensionStmt:
1879 tag = "ALTER EXTENSION";
1882 case T_AlterExtensionContentsStmt:
1883 tag = "ALTER EXTENSION";
1886 case T_CreateFdwStmt:
1887 tag = "CREATE FOREIGN DATA WRAPPER";
1890 case T_AlterFdwStmt:
1891 tag = "ALTER FOREIGN DATA WRAPPER";
1894 case T_CreateForeignServerStmt:
1895 tag = "CREATE SERVER";
1898 case T_AlterForeignServerStmt:
1899 tag = "ALTER SERVER";
1902 case T_CreateUserMappingStmt:
1903 tag = "CREATE USER MAPPING";
1906 case T_AlterUserMappingStmt:
1907 tag = "ALTER USER MAPPING";
1910 case T_DropUserMappingStmt:
1911 tag = "DROP USER MAPPING";
1914 case T_CreateForeignTableStmt:
1915 tag = "CREATE FOREIGN TABLE";
1918 case T_ImportForeignSchemaStmt:
1919 tag = "IMPORT FOREIGN SCHEMA";
1923 switch (((DropStmt *) parsetree)->removeType)
1928 case OBJECT_SEQUENCE:
1929 tag = "DROP SEQUENCE";
1934 case OBJECT_MATVIEW:
1935 tag = "DROP MATERIALIZED VIEW";
1944 tag = "DROP DOMAIN";
1946 case OBJECT_COLLATION:
1947 tag = "DROP COLLATION";
1949 case OBJECT_CONVERSION:
1950 tag = "DROP CONVERSION";
1953 tag = "DROP SCHEMA";
1955 case OBJECT_TSPARSER:
1956 tag = "DROP TEXT SEARCH PARSER";
1958 case OBJECT_TSDICTIONARY:
1959 tag = "DROP TEXT SEARCH DICTIONARY";
1961 case OBJECT_TSTEMPLATE:
1962 tag = "DROP TEXT SEARCH TEMPLATE";
1964 case OBJECT_TSCONFIGURATION:
1965 tag = "DROP TEXT SEARCH CONFIGURATION";
1967 case OBJECT_FOREIGN_TABLE:
1968 tag = "DROP FOREIGN TABLE";
1970 case OBJECT_EXTENSION:
1971 tag = "DROP EXTENSION";
1973 case OBJECT_FUNCTION:
1974 tag = "DROP FUNCTION";
1976 case OBJECT_AGGREGATE:
1977 tag = "DROP AGGREGATE";
1979 case OBJECT_OPERATOR:
1980 tag = "DROP OPERATOR";
1982 case OBJECT_LANGUAGE:
1983 tag = "DROP LANGUAGE";
1988 case OBJECT_TRIGGER:
1989 tag = "DROP TRIGGER";
1991 case OBJECT_EVENT_TRIGGER:
1992 tag = "DROP EVENT TRIGGER";
1998 tag = "DROP FOREIGN DATA WRAPPER";
2000 case OBJECT_FOREIGN_SERVER:
2001 tag = "DROP SERVER";
2003 case OBJECT_OPCLASS:
2004 tag = "DROP OPERATOR CLASS";
2006 case OBJECT_OPFAMILY:
2007 tag = "DROP OPERATOR FAMILY";
2010 tag = "DROP POLICY";
2012 case OBJECT_TRANSFORM:
2013 tag = "DROP TRANSFORM";
2020 case T_TruncateStmt:
2021 tag = "TRUNCATE TABLE";
2028 case T_SecLabelStmt:
2029 tag = "SECURITY LABEL";
2037 tag = AlterObjectTypeCommandTag(((RenameStmt *) parsetree)->renameType);
2040 case T_AlterObjectSchemaStmt:
2041 tag = AlterObjectTypeCommandTag(((AlterObjectSchemaStmt *) parsetree)->objectType);
2044 case T_AlterOwnerStmt:
2045 tag = AlterObjectTypeCommandTag(((AlterOwnerStmt *) parsetree)->objectType);
2048 case T_AlterTableMoveAllStmt:
2049 tag = AlterObjectTypeCommandTag(((AlterTableMoveAllStmt *) parsetree)->objtype);
2052 case T_AlterTableStmt:
2053 tag = AlterObjectTypeCommandTag(((AlterTableStmt *) parsetree)->relkind);
2056 case T_AlterDomainStmt:
2057 tag = "ALTER DOMAIN";
2060 case T_AlterFunctionStmt:
2061 tag = "ALTER FUNCTION";
2066 GrantStmt *stmt = (GrantStmt *) parsetree;
2068 tag = (stmt->is_grant) ? "GRANT" : "REVOKE";
2072 case T_GrantRoleStmt:
2074 GrantRoleStmt *stmt = (GrantRoleStmt *) parsetree;
2076 tag = (stmt->is_grant) ? "GRANT ROLE" : "REVOKE ROLE";
2080 case T_AlterDefaultPrivilegesStmt:
2081 tag = "ALTER DEFAULT PRIVILEGES";
2085 switch (((DefineStmt *) parsetree)->kind)
2087 case OBJECT_AGGREGATE:
2088 tag = "CREATE AGGREGATE";
2090 case OBJECT_OPERATOR:
2091 tag = "CREATE OPERATOR";
2094 tag = "CREATE TYPE";
2096 case OBJECT_TSPARSER:
2097 tag = "CREATE TEXT SEARCH PARSER";
2099 case OBJECT_TSDICTIONARY:
2100 tag = "CREATE TEXT SEARCH DICTIONARY";
2102 case OBJECT_TSTEMPLATE:
2103 tag = "CREATE TEXT SEARCH TEMPLATE";
2105 case OBJECT_TSCONFIGURATION:
2106 tag = "CREATE TEXT SEARCH CONFIGURATION";
2108 case OBJECT_COLLATION:
2109 tag = "CREATE COLLATION";
2116 case T_CompositeTypeStmt:
2117 tag = "CREATE TYPE";
2120 case T_CreateEnumStmt:
2121 tag = "CREATE TYPE";
2124 case T_CreateRangeStmt:
2125 tag = "CREATE TYPE";
2128 case T_AlterEnumStmt:
2133 tag = "CREATE VIEW";
2136 case T_CreateFunctionStmt:
2137 tag = "CREATE FUNCTION";
2141 tag = "CREATE INDEX";
2145 tag = "CREATE RULE";
2148 case T_CreateSeqStmt:
2149 tag = "CREATE SEQUENCE";
2152 case T_AlterSeqStmt:
2153 tag = "ALTER SEQUENCE";
2160 case T_CreatedbStmt:
2161 tag = "CREATE DATABASE";
2164 case T_AlterDatabaseStmt:
2165 tag = "ALTER DATABASE";
2168 case T_AlterDatabaseSetStmt:
2169 tag = "ALTER DATABASE";
2173 tag = "DROP DATABASE";
2184 case T_UnlistenStmt:
2197 if (((VacuumStmt *) parsetree)->options & VACOPT_VACUUM)
2207 case T_CreateTableAsStmt:
2208 switch (((CreateTableAsStmt *) parsetree)->relkind)
2211 if (((CreateTableAsStmt *) parsetree)->is_select_into)
2212 tag = "SELECT INTO";
2214 tag = "CREATE TABLE AS";
2216 case OBJECT_MATVIEW:
2217 tag = "CREATE MATERIALIZED VIEW";
2224 case T_RefreshMatViewStmt:
2225 tag = "REFRESH MATERIALIZED VIEW";
2228 case T_AlterSystemStmt:
2229 tag = "ALTER SYSTEM";
2232 case T_VariableSetStmt:
2233 switch (((VariableSetStmt *) parsetree)->kind)
2236 case VAR_SET_CURRENT:
2237 case VAR_SET_DEFAULT:
2250 case T_VariableShowStmt:
2255 switch (((DiscardStmt *) parsetree)->target)
2258 tag = "DISCARD ALL";
2261 tag = "DISCARD PLANS";
2264 tag = "DISCARD TEMP";
2266 case DISCARD_SEQUENCES:
2267 tag = "DISCARD SEQUENCES";
2274 case T_CreateTransformStmt:
2275 tag = "CREATE TRANSFORM";
2278 case T_CreateTrigStmt:
2279 tag = "CREATE TRIGGER";
2282 case T_CreateEventTrigStmt:
2283 tag = "CREATE EVENT TRIGGER";
2286 case T_AlterEventTrigStmt:
2287 tag = "ALTER EVENT TRIGGER";
2290 case T_CreatePLangStmt:
2291 tag = "CREATE LANGUAGE";
2294 case T_CreateRoleStmt:
2295 tag = "CREATE ROLE";
2298 case T_AlterRoleStmt:
2302 case T_AlterRoleSetStmt:
2306 case T_DropRoleStmt:
2310 case T_DropOwnedStmt:
2314 case T_ReassignOwnedStmt:
2315 tag = "REASSIGN OWNED";
2322 case T_ConstraintsSetStmt:
2323 tag = "SET CONSTRAINTS";
2326 case T_CheckPointStmt:
2334 case T_CreateConversionStmt:
2335 tag = "CREATE CONVERSION";
2338 case T_CreateCastStmt:
2339 tag = "CREATE CAST";
2342 case T_CreateOpClassStmt:
2343 tag = "CREATE OPERATOR CLASS";
2346 case T_CreateOpFamilyStmt:
2347 tag = "CREATE OPERATOR FAMILY";
2350 case T_AlterOpFamilyStmt:
2351 tag = "ALTER OPERATOR FAMILY";
2354 case T_AlterTSDictionaryStmt:
2355 tag = "ALTER TEXT SEARCH DICTIONARY";
2358 case T_AlterTSConfigurationStmt:
2359 tag = "ALTER TEXT SEARCH CONFIGURATION";
2362 case T_CreatePolicyStmt:
2363 tag = "CREATE POLICY";
2366 case T_AlterPolicyStmt:
2367 tag = "ALTER POLICY";
2378 case T_DeallocateStmt:
2380 DeallocateStmt *stmt = (DeallocateStmt *) parsetree;
2382 if (stmt->name == NULL)
2383 tag = "DEALLOCATE ALL";
2389 /* already-planned queries */
2392 PlannedStmt *stmt = (PlannedStmt *) parsetree;
2394 switch (stmt->commandType)
2399 * We take a little extra care here so that the result
2400 * will be useful for complaints about read-only
2403 if (stmt->utilityStmt != NULL)
2405 Assert(IsA(stmt->utilityStmt, DeclareCursorStmt));
2406 tag = "DECLARE CURSOR";
2408 else if (stmt->rowMarks != NIL)
2410 /* not 100% but probably close enough */
2411 switch (((PlanRowMark *) linitial(stmt->rowMarks))->strength)
2413 case LCS_FORKEYSHARE:
2414 tag = "SELECT FOR KEY SHARE";
2417 tag = "SELECT FOR SHARE";
2419 case LCS_FORNOKEYUPDATE:
2420 tag = "SELECT FOR NO KEY UPDATE";
2423 tag = "SELECT FOR UPDATE";
2443 elog(WARNING, "unrecognized commandType: %d",
2444 (int) stmt->commandType);
2451 /* parsed-and-rewritten-but-not-planned queries */
2454 Query *stmt = (Query *) parsetree;
2456 switch (stmt->commandType)
2461 * We take a little extra care here so that the result
2462 * will be useful for complaints about read-only
2465 if (stmt->utilityStmt != NULL)
2467 Assert(IsA(stmt->utilityStmt, DeclareCursorStmt));
2468 tag = "DECLARE CURSOR";
2470 else if (stmt->rowMarks != NIL)
2472 /* not 100% but probably close enough */
2473 switch (((RowMarkClause *) linitial(stmt->rowMarks))->strength)
2475 case LCS_FORKEYSHARE:
2476 tag = "SELECT FOR KEY SHARE";
2479 tag = "SELECT FOR SHARE";
2481 case LCS_FORNOKEYUPDATE:
2482 tag = "SELECT FOR NO KEY UPDATE";
2485 tag = "SELECT FOR UPDATE";
2505 tag = CreateCommandTag(stmt->utilityStmt);
2508 elog(WARNING, "unrecognized commandType: %d",
2509 (int) stmt->commandType);
2517 elog(WARNING, "unrecognized node type: %d",
2518 (int) nodeTag(parsetree));
2528 * GetCommandLogLevel
2529 * utility to get the minimum log_statement level for a command,
2530 * given either a raw (un-analyzed) parsetree or a planned query.
2532 * This must handle all command types, but since the vast majority
2533 * of 'em are utility commands, it seems sensible to keep it here.
2536 GetCommandLogLevel(Node *parsetree)
2540 switch (nodeTag(parsetree))
2542 /* raw plannable queries */
2550 if (((SelectStmt *) parsetree)->intoClause)
2551 lev = LOGSTMT_DDL; /* SELECT INTO */
2556 /* utility statements --- same whether raw or cooked */
2557 case T_TransactionStmt:
2561 case T_DeclareCursorStmt:
2565 case T_ClosePortalStmt:
2573 case T_CreateSchemaStmt:
2578 case T_CreateForeignTableStmt:
2582 case T_CreateTableSpaceStmt:
2583 case T_DropTableSpaceStmt:
2584 case T_AlterTableSpaceOptionsStmt:
2588 case T_CreateExtensionStmt:
2589 case T_AlterExtensionStmt:
2590 case T_AlterExtensionContentsStmt:
2594 case T_CreateFdwStmt:
2595 case T_AlterFdwStmt:
2596 case T_CreateForeignServerStmt:
2597 case T_AlterForeignServerStmt:
2598 case T_CreateUserMappingStmt:
2599 case T_AlterUserMappingStmt:
2600 case T_DropUserMappingStmt:
2601 case T_ImportForeignSchemaStmt:
2609 case T_TruncateStmt:
2617 case T_SecLabelStmt:
2622 if (((CopyStmt *) parsetree)->is_from)
2630 PrepareStmt *stmt = (PrepareStmt *) parsetree;
2632 /* Look through a PREPARE to the contained stmt */
2633 lev = GetCommandLogLevel(stmt->query);
2639 ExecuteStmt *stmt = (ExecuteStmt *) parsetree;
2640 PreparedStatement *ps;
2642 /* Look through an EXECUTE to the referenced stmt */
2643 ps = FetchPreparedStatement(stmt->name, false);
2644 if (ps && ps->plansource->raw_parse_tree)
2645 lev = GetCommandLogLevel(ps->plansource->raw_parse_tree);
2651 case T_DeallocateStmt:
2659 case T_AlterObjectSchemaStmt:
2663 case T_AlterOwnerStmt:
2667 case T_AlterTableMoveAllStmt:
2668 case T_AlterTableStmt:
2672 case T_AlterDomainStmt:
2680 case T_GrantRoleStmt:
2684 case T_AlterDefaultPrivilegesStmt:
2692 case T_CompositeTypeStmt:
2696 case T_CreateEnumStmt:
2700 case T_CreateRangeStmt:
2704 case T_AlterEnumStmt:
2712 case T_CreateFunctionStmt:
2716 case T_AlterFunctionStmt:
2728 case T_CreateSeqStmt:
2732 case T_AlterSeqStmt:
2740 case T_CreatedbStmt:
2744 case T_AlterDatabaseStmt:
2748 case T_AlterDatabaseSetStmt:
2764 case T_UnlistenStmt:
2782 ExplainStmt *stmt = (ExplainStmt *) parsetree;
2783 bool analyze = false;
2786 /* Look through an EXPLAIN ANALYZE to the contained stmt */
2787 foreach(lc, stmt->options)
2789 DefElem *opt = (DefElem *) lfirst(lc);
2791 if (strcmp(opt->defname, "analyze") == 0)
2792 analyze = defGetBoolean(opt);
2793 /* don't "break", as explain.c will use the last value */
2796 return GetCommandLogLevel(stmt->query);
2798 /* Plain EXPLAIN isn't so interesting */
2803 case T_CreateTableAsStmt:
2807 case T_RefreshMatViewStmt:
2811 case T_AlterSystemStmt:
2815 case T_VariableSetStmt:
2819 case T_VariableShowStmt:
2827 case T_CreateTrigStmt:
2831 case T_CreateEventTrigStmt:
2835 case T_AlterEventTrigStmt:
2839 case T_CreatePLangStmt:
2843 case T_CreateDomainStmt:
2847 case T_CreateRoleStmt:
2851 case T_AlterRoleStmt:
2855 case T_AlterRoleSetStmt:
2859 case T_DropRoleStmt:
2863 case T_DropOwnedStmt:
2867 case T_ReassignOwnedStmt:
2875 case T_ConstraintsSetStmt:
2879 case T_CheckPointStmt:
2884 lev = LOGSTMT_ALL; /* should this be DDL? */
2887 case T_CreateConversionStmt:
2891 case T_CreateCastStmt:
2895 case T_CreateOpClassStmt:
2899 case T_CreateOpFamilyStmt:
2903 case T_CreateTransformStmt:
2907 case T_AlterOpFamilyStmt:
2911 case T_CreatePolicyStmt:
2915 case T_AlterPolicyStmt:
2919 case T_AlterTSDictionaryStmt:
2923 case T_AlterTSConfigurationStmt:
2927 /* already-planned queries */
2930 PlannedStmt *stmt = (PlannedStmt *) parsetree;
2932 switch (stmt->commandType)
2945 elog(WARNING, "unrecognized commandType: %d",
2946 (int) stmt->commandType);
2953 /* parsed-and-rewritten-but-not-planned queries */
2956 Query *stmt = (Query *) parsetree;
2958 switch (stmt->commandType)
2971 lev = GetCommandLogLevel(stmt->utilityStmt);
2975 elog(WARNING, "unrecognized commandType: %d",
2976 (int) stmt->commandType);
2985 elog(WARNING, "unrecognized node type: %d",
2986 (int) nodeTag(parsetree));