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-2014, 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 "catalog/catalog.h"
24 #include "catalog/namespace.h"
25 #include "catalog/toasting.h"
26 #include "commands/alter.h"
27 #include "commands/async.h"
28 #include "commands/cluster.h"
29 #include "commands/comment.h"
30 #include "commands/collationcmds.h"
31 #include "commands/conversioncmds.h"
32 #include "commands/copy.h"
33 #include "commands/createas.h"
34 #include "commands/dbcommands.h"
35 #include "commands/defrem.h"
36 #include "commands/discard.h"
37 #include "commands/event_trigger.h"
38 #include "commands/explain.h"
39 #include "commands/extension.h"
40 #include "commands/matview.h"
41 #include "commands/lockcmds.h"
42 #include "commands/portalcmds.h"
43 #include "commands/prepare.h"
44 #include "commands/proclang.h"
45 #include "commands/schemacmds.h"
46 #include "commands/seclabel.h"
47 #include "commands/sequence.h"
48 #include "commands/tablecmds.h"
49 #include "commands/tablespace.h"
50 #include "commands/trigger.h"
51 #include "commands/typecmds.h"
52 #include "commands/user.h"
53 #include "commands/vacuum.h"
54 #include "commands/view.h"
55 #include "miscadmin.h"
56 #include "parser/parse_utilcmd.h"
57 #include "postmaster/bgwriter.h"
58 #include "rewrite/rewriteDefine.h"
59 #include "rewrite/rewriteRemove.h"
60 #include "storage/fd.h"
61 #include "tcop/pquery.h"
62 #include "tcop/utility.h"
63 #include "utils/acl.h"
64 #include "utils/guc.h"
65 #include "utils/syscache.h"
68 /* Hook for plugins to get control in ProcessUtility() */
69 ProcessUtility_hook_type ProcessUtility_hook = NULL;
71 /* local function declarations */
72 static void ProcessUtilitySlow(Node *parsetree,
73 const char *queryString,
74 ProcessUtilityContext context,
78 static void ExecDropStmt(DropStmt *stmt, bool isTopLevel);
82 * CommandIsReadOnly: is an executable query read-only?
84 * This is a much stricter test than we apply for XactReadOnly mode;
85 * the query must be *in truth* read-only, because the caller wishes
86 * not to do CommandCounterIncrement for it.
88 * Note: currently no need to support Query nodes here
91 CommandIsReadOnly(Node *parsetree)
93 if (IsA(parsetree, PlannedStmt))
95 PlannedStmt *stmt = (PlannedStmt *) parsetree;
97 switch (stmt->commandType)
100 if (stmt->rowMarks != NIL)
101 return false; /* SELECT FOR [KEY] UPDATE/SHARE */
102 else if (stmt->hasModifyingCTE)
103 return false; /* data-modifying CTE */
111 elog(WARNING, "unrecognized commandType: %d",
112 (int) stmt->commandType);
116 /* For now, treat all utility commands as read/write */
121 * check_xact_readonly: is a utility command read-only?
123 * Here we use the loose rules of XactReadOnly mode: no permanent effects
124 * on the database are allowed.
127 check_xact_readonly(Node *parsetree)
133 * Note: Commands that need to do more complicated checking are handled
134 * elsewhere, in particular COPY and plannable statements do their own
135 * checking. However they should all call PreventCommandIfReadOnly to
136 * actually throw the error.
139 switch (nodeTag(parsetree))
141 case T_AlterDatabaseStmt:
142 case T_AlterDatabaseSetStmt:
143 case T_AlterDomainStmt:
144 case T_AlterFunctionStmt:
145 case T_AlterRoleStmt:
146 case T_AlterRoleSetStmt:
147 case T_AlterObjectSchemaStmt:
148 case T_AlterOwnerStmt:
150 case T_AlterTableMoveAllStmt:
151 case T_AlterTableStmt:
155 case T_CreateCastStmt:
156 case T_CreateEventTrigStmt:
157 case T_AlterEventTrigStmt:
158 case T_CreateConversionStmt:
160 case T_CreateDomainStmt:
161 case T_CreateFunctionStmt:
162 case T_CreateRoleStmt:
164 case T_CreatePLangStmt:
165 case T_CreateOpClassStmt:
166 case T_CreateOpFamilyStmt:
167 case T_AlterOpFamilyStmt:
169 case T_CreateSchemaStmt:
170 case T_CreateSeqStmt:
172 case T_CreateTableAsStmt:
173 case T_RefreshMatViewStmt:
174 case T_CreateTableSpaceStmt:
175 case T_CreateTrigStmt:
176 case T_CompositeTypeStmt:
177 case T_CreateEnumStmt:
178 case T_CreateRangeStmt:
179 case T_AlterEnumStmt:
183 case T_DropTableSpaceStmt:
186 case T_GrantRoleStmt:
187 case T_AlterDefaultPrivilegesStmt:
189 case T_DropOwnedStmt:
190 case T_ReassignOwnedStmt:
191 case T_AlterTSDictionaryStmt:
192 case T_AlterTSConfigurationStmt:
193 case T_CreateExtensionStmt:
194 case T_AlterExtensionStmt:
195 case T_AlterExtensionContentsStmt:
196 case T_CreateFdwStmt:
198 case T_CreateForeignServerStmt:
199 case T_AlterForeignServerStmt:
200 case T_CreateUserMappingStmt:
201 case T_AlterUserMappingStmt:
202 case T_DropUserMappingStmt:
203 case T_AlterTableSpaceOptionsStmt:
204 case T_CreateForeignTableStmt:
205 case T_ImportForeignSchemaStmt:
207 PreventCommandIfReadOnly(CreateCommandTag(parsetree));
216 * PreventCommandIfReadOnly: throw error if XactReadOnly
218 * This is useful mainly to ensure consistency of the error message wording;
219 * most callers have checked XactReadOnly for themselves.
222 PreventCommandIfReadOnly(const char *cmdname)
226 (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
227 /* translator: %s is name of a SQL command, eg CREATE */
228 errmsg("cannot execute %s in a read-only transaction",
233 * PreventCommandDuringRecovery: throw error if RecoveryInProgress
235 * The majority of operations that are unsafe in a Hot Standby slave
236 * will be rejected by XactReadOnly tests. However there are a few
237 * commands that are allowed in "read-only" xacts but cannot be allowed
238 * in Hot Standby mode. Those commands should call this function.
241 PreventCommandDuringRecovery(const char *cmdname)
243 if (RecoveryInProgress())
245 (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
246 /* translator: %s is name of a SQL command, eg CREATE */
247 errmsg("cannot execute %s during recovery",
252 * CheckRestrictedOperation: throw error for hazardous command if we're
253 * inside a security restriction context.
255 * This is needed to protect session-local state for which there is not any
256 * better-defined protection mechanism, such as ownership.
259 CheckRestrictedOperation(const char *cmdname)
261 if (InSecurityRestrictedOperation())
263 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
264 /* translator: %s is name of a SQL command, eg PREPARE */
265 errmsg("cannot execute %s within security-restricted operation",
272 * general utility function invoker
274 * parsetree: the parse tree for the utility statement
275 * queryString: original source text of command
276 * context: identifies source of statement (toplevel client command,
277 * non-toplevel client command, subcommand of a larger utility command)
278 * params: parameters to use during execution
279 * dest: where to send results
280 * completionTag: points to a buffer of size COMPLETION_TAG_BUFSIZE
281 * in which to store a command completion status string.
283 * Notes: as of PG 8.4, caller MUST supply a queryString; it is not
284 * allowed anymore to pass NULL. (If you really don't have source text,
285 * you can pass a constant string, perhaps "(query not available)".)
287 * completionTag is only set nonempty if we want to return a nondefault status.
289 * completionTag may be NULL if caller doesn't want a status string.
292 ProcessUtility(Node *parsetree,
293 const char *queryString,
294 ProcessUtilityContext context,
295 ParamListInfo params,
299 Assert(queryString != NULL); /* required as of 8.4 */
302 * We provide a function hook variable that lets loadable plugins get
303 * control when ProcessUtility is called. Such a plugin would normally
304 * call standard_ProcessUtility().
306 if (ProcessUtility_hook)
307 (*ProcessUtility_hook) (parsetree, queryString,
309 dest, completionTag);
311 standard_ProcessUtility(parsetree, queryString,
313 dest, completionTag);
317 * standard_ProcessUtility itself deals only with utility commands for
318 * which we do not provide event trigger support. Commands that do have
319 * such support are passed down to ProcessUtilitySlow, which contains the
320 * necessary infrastructure for such triggers.
322 * This division is not just for performance: it's critical that the
323 * event trigger code not be invoked when doing START TRANSACTION for
324 * example, because we might need to refresh the event trigger cache,
325 * which requires being in a valid transaction.
328 standard_ProcessUtility(Node *parsetree,
329 const char *queryString,
330 ProcessUtilityContext context,
331 ParamListInfo params,
335 bool isTopLevel = (context == PROCESS_UTILITY_TOPLEVEL);
337 check_xact_readonly(parsetree);
340 completionTag[0] = '\0';
342 switch (nodeTag(parsetree))
345 * ******************** transactions ********************
347 case T_TransactionStmt:
349 TransactionStmt *stmt = (TransactionStmt *) parsetree;
354 * START TRANSACTION, as defined by SQL99: Identical
355 * to BEGIN. Same code for both.
357 case TRANS_STMT_BEGIN:
358 case TRANS_STMT_START:
362 BeginTransactionBlock();
363 foreach(lc, stmt->options)
365 DefElem *item = (DefElem *) lfirst(lc);
367 if (strcmp(item->defname, "transaction_isolation") == 0)
368 SetPGVariable("transaction_isolation",
369 list_make1(item->arg),
371 else if (strcmp(item->defname, "transaction_read_only") == 0)
372 SetPGVariable("transaction_read_only",
373 list_make1(item->arg),
375 else if (strcmp(item->defname, "transaction_deferrable") == 0)
376 SetPGVariable("transaction_deferrable",
377 list_make1(item->arg),
383 case TRANS_STMT_COMMIT:
384 if (!EndTransactionBlock())
386 /* report unsuccessful commit in completionTag */
388 strcpy(completionTag, "ROLLBACK");
392 case TRANS_STMT_PREPARE:
393 PreventCommandDuringRecovery("PREPARE TRANSACTION");
394 if (!PrepareTransactionBlock(stmt->gid))
396 /* report unsuccessful commit in completionTag */
398 strcpy(completionTag, "ROLLBACK");
402 case TRANS_STMT_COMMIT_PREPARED:
403 PreventTransactionChain(isTopLevel, "COMMIT PREPARED");
404 PreventCommandDuringRecovery("COMMIT PREPARED");
405 FinishPreparedTransaction(stmt->gid, true);
408 case TRANS_STMT_ROLLBACK_PREPARED:
409 PreventTransactionChain(isTopLevel, "ROLLBACK PREPARED");
410 PreventCommandDuringRecovery("ROLLBACK PREPARED");
411 FinishPreparedTransaction(stmt->gid, false);
414 case TRANS_STMT_ROLLBACK:
415 UserAbortTransactionBlock();
418 case TRANS_STMT_SAVEPOINT:
423 RequireTransactionChain(isTopLevel, "SAVEPOINT");
425 foreach(cell, stmt->options)
427 DefElem *elem = lfirst(cell);
429 if (strcmp(elem->defname, "savepoint_name") == 0)
430 name = strVal(elem->arg);
433 Assert(PointerIsValid(name));
435 DefineSavepoint(name);
439 case TRANS_STMT_RELEASE:
440 RequireTransactionChain(isTopLevel, "RELEASE SAVEPOINT");
441 ReleaseSavepoint(stmt->options);
444 case TRANS_STMT_ROLLBACK_TO:
445 RequireTransactionChain(isTopLevel, "ROLLBACK TO SAVEPOINT");
446 RollbackToSavepoint(stmt->options);
449 * CommitTransactionCommand is in charge of
450 * re-defining the savepoint again
458 * Portal (cursor) manipulation
460 * Note: DECLARE CURSOR is processed mostly as a SELECT, and
461 * therefore what we will get here is a PlannedStmt not a bare
466 PlannedStmt *stmt = (PlannedStmt *) parsetree;
468 if (stmt->utilityStmt == NULL ||
469 !IsA(stmt->utilityStmt, DeclareCursorStmt))
470 elog(ERROR, "non-DECLARE CURSOR PlannedStmt passed to ProcessUtility");
471 PerformCursorOpen(stmt, params, queryString, isTopLevel);
475 case T_ClosePortalStmt:
477 ClosePortalStmt *stmt = (ClosePortalStmt *) parsetree;
479 CheckRestrictedOperation("CLOSE");
480 PerformPortalClose(stmt->portalname);
485 PerformPortalFetch((FetchStmt *) parsetree, dest,
490 ExecuteDoStmt((DoStmt *) parsetree);
493 case T_CreateTableSpaceStmt:
494 /* no event triggers for global objects */
495 PreventTransactionChain(isTopLevel, "CREATE TABLESPACE");
496 CreateTableSpace((CreateTableSpaceStmt *) parsetree);
499 case T_DropTableSpaceStmt:
500 /* no event triggers for global objects */
501 PreventTransactionChain(isTopLevel, "DROP TABLESPACE");
502 DropTableSpace((DropTableSpaceStmt *) parsetree);
505 case T_AlterTableSpaceOptionsStmt:
506 /* no event triggers for global objects */
507 AlterTableSpaceOptions((AlterTableSpaceOptionsStmt *) parsetree);
510 case T_AlterTableMoveAllStmt:
511 AlterTableMoveAll((AlterTableMoveAllStmt *) parsetree);
515 ExecuteTruncate((TruncateStmt *) parsetree);
519 CommentObject((CommentStmt *) parsetree);
523 ExecSecLabelStmt((SecLabelStmt *) parsetree);
530 DoCopy((CopyStmt *) parsetree, queryString, &processed);
532 snprintf(completionTag, COMPLETION_TAG_BUFSIZE,
533 "COPY " UINT64_FORMAT, processed);
538 CheckRestrictedOperation("PREPARE");
539 PrepareQuery((PrepareStmt *) parsetree, queryString);
543 ExecuteQuery((ExecuteStmt *) parsetree, NULL,
545 dest, completionTag);
548 case T_DeallocateStmt:
549 CheckRestrictedOperation("DEALLOCATE");
550 DeallocateQuery((DeallocateStmt *) parsetree);
554 /* no event triggers for global objects */
555 ExecuteGrantStmt((GrantStmt *) parsetree);
558 case T_GrantRoleStmt:
559 /* no event triggers for global objects */
560 GrantRole((GrantRoleStmt *) parsetree);
564 /* no event triggers for global objects */
565 PreventTransactionChain(isTopLevel, "CREATE DATABASE");
566 createdb((CreatedbStmt *) parsetree);
569 case T_AlterDatabaseStmt:
570 /* no event triggers for global objects */
571 AlterDatabase((AlterDatabaseStmt *) parsetree, isTopLevel);
574 case T_AlterDatabaseSetStmt:
575 /* no event triggers for global objects */
576 AlterDatabaseSet((AlterDatabaseSetStmt *) parsetree);
581 DropdbStmt *stmt = (DropdbStmt *) parsetree;
583 /* no event triggers for global objects */
584 PreventTransactionChain(isTopLevel, "DROP DATABASE");
585 dropdb(stmt->dbname, stmt->missing_ok);
589 /* Query-level asynchronous notification */
592 NotifyStmt *stmt = (NotifyStmt *) parsetree;
594 PreventCommandDuringRecovery("NOTIFY");
595 Async_Notify(stmt->conditionname, stmt->payload);
601 ListenStmt *stmt = (ListenStmt *) parsetree;
603 PreventCommandDuringRecovery("LISTEN");
604 CheckRestrictedOperation("LISTEN");
605 Async_Listen(stmt->conditionname);
611 UnlistenStmt *stmt = (UnlistenStmt *) parsetree;
613 PreventCommandDuringRecovery("UNLISTEN");
614 CheckRestrictedOperation("UNLISTEN");
615 if (stmt->conditionname)
616 Async_Unlisten(stmt->conditionname);
624 LoadStmt *stmt = (LoadStmt *) parsetree;
626 closeAllVfds(); /* probably not necessary... */
627 /* Allowed names are restricted if you're not superuser */
628 load_file(stmt->filename, !superuser());
633 /* we choose to allow this during "read only" transactions */
634 PreventCommandDuringRecovery("CLUSTER");
635 cluster((ClusterStmt *) parsetree, isTopLevel);
640 VacuumStmt *stmt = (VacuumStmt *) parsetree;
642 /* we choose to allow this during "read only" transactions */
643 PreventCommandDuringRecovery((stmt->options & VACOPT_VACUUM) ?
644 "VACUUM" : "ANALYZE");
645 vacuum(stmt, InvalidOid, true, NULL, false, isTopLevel);
650 ExplainQuery((ExplainStmt *) parsetree, queryString, params, dest);
653 case T_AlterSystemStmt:
654 PreventTransactionChain(isTopLevel, "ALTER SYSTEM");
655 AlterSystemSetConfigFile((AlterSystemStmt *) parsetree);
658 case T_VariableSetStmt:
659 ExecSetVariableStmt((VariableSetStmt *) parsetree, isTopLevel);
662 case T_VariableShowStmt:
664 VariableShowStmt *n = (VariableShowStmt *) parsetree;
666 GetPGVariable(n->name, dest);
671 /* should we allow DISCARD PLANS? */
672 CheckRestrictedOperation("DISCARD");
673 DiscardCommand((DiscardStmt *) parsetree, isTopLevel);
676 case T_CreateEventTrigStmt:
677 /* no event triggers on event triggers */
678 CreateEventTrigger((CreateEventTrigStmt *) parsetree);
681 case T_AlterEventTrigStmt:
682 /* no event triggers on event triggers */
683 AlterEventTrigger((AlterEventTrigStmt *) parsetree);
687 * ******************************** ROLE statements ****
689 case T_CreateRoleStmt:
690 /* no event triggers for global objects */
691 CreateRole((CreateRoleStmt *) parsetree);
694 case T_AlterRoleStmt:
695 /* no event triggers for global objects */
696 AlterRole((AlterRoleStmt *) parsetree);
699 case T_AlterRoleSetStmt:
700 /* no event triggers for global objects */
701 AlterRoleSet((AlterRoleSetStmt *) parsetree);
705 /* no event triggers for global objects */
706 DropRole((DropRoleStmt *) parsetree);
709 case T_ReassignOwnedStmt:
710 /* no event triggers for global objects */
711 ReassignOwnedObjects((ReassignOwnedStmt *) parsetree);
717 * Since the lock would just get dropped immediately, LOCK TABLE
718 * outside a transaction block is presumed to be user error.
720 RequireTransactionChain(isTopLevel, "LOCK TABLE");
721 LockTableCommand((LockStmt *) parsetree);
724 case T_ConstraintsSetStmt:
725 WarnNoTransactionChain(isTopLevel, "SET CONSTRAINTS");
726 AfterTriggerSetState((ConstraintsSetStmt *) parsetree);
729 case T_CheckPointStmt:
732 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
733 errmsg("must be superuser to do CHECKPOINT")));
736 * You might think we should have a PreventCommandDuringRecovery()
737 * here, but we interpret a CHECKPOINT command during recovery as
738 * a request for a restartpoint instead. We allow this since it
739 * can be a useful way of reducing switchover time when using
740 * various forms of replication.
742 RequestCheckpoint(CHECKPOINT_IMMEDIATE | CHECKPOINT_WAIT |
743 (RecoveryInProgress() ? 0 : CHECKPOINT_FORCE));
748 ReindexStmt *stmt = (ReindexStmt *) parsetree;
750 /* we choose to allow this during "read only" transactions */
751 PreventCommandDuringRecovery("REINDEX");
755 ReindexIndex(stmt->relation);
759 ReindexTable(stmt->relation);
761 case OBJECT_DATABASE:
764 * This cannot run inside a user transaction block; if
765 * we were inside a transaction, then its commit- and
766 * start-transaction-command calls would not have the
769 PreventTransactionChain(isTopLevel,
771 ReindexDatabase(stmt->name,
772 stmt->do_system, stmt->do_user);
775 elog(ERROR, "unrecognized object type: %d",
783 * The following statements are supported by Event Triggers only
784 * in some cases, so we "fast path" them in the other cases.
789 DropStmt *stmt = (DropStmt *) parsetree;
791 if (EventTriggerSupportsObjectType(stmt->removeType))
792 ProcessUtilitySlow(parsetree, queryString,
794 dest, completionTag);
796 ExecDropStmt(stmt, isTopLevel);
802 RenameStmt *stmt = (RenameStmt *) parsetree;
804 if (EventTriggerSupportsObjectType(stmt->renameType))
805 ProcessUtilitySlow(parsetree, queryString,
807 dest, completionTag);
809 ExecRenameStmt(stmt);
813 case T_AlterObjectSchemaStmt:
815 AlterObjectSchemaStmt *stmt = (AlterObjectSchemaStmt *) parsetree;
817 if (EventTriggerSupportsObjectType(stmt->objectType))
818 ProcessUtilitySlow(parsetree, queryString,
820 dest, completionTag);
822 ExecAlterObjectSchemaStmt(stmt);
826 case T_AlterOwnerStmt:
828 AlterOwnerStmt *stmt = (AlterOwnerStmt *) parsetree;
830 if (EventTriggerSupportsObjectType(stmt->objectType))
831 ProcessUtilitySlow(parsetree, queryString,
833 dest, completionTag);
835 ExecAlterOwnerStmt(stmt);
840 /* All other statement types have event trigger support */
841 ProcessUtilitySlow(parsetree, queryString,
843 dest, completionTag);
849 * The "Slow" variant of ProcessUtility should only receive statements
850 * supported by the event triggers facility. Therefore, we always
851 * perform the trigger support calls if the context allows it.
854 ProcessUtilitySlow(Node *parsetree,
855 const char *queryString,
856 ProcessUtilityContext context,
857 ParamListInfo params,
861 bool isTopLevel = (context == PROCESS_UTILITY_TOPLEVEL);
862 bool isCompleteQuery = (context <= PROCESS_UTILITY_QUERY);
865 /* All event trigger calls are done only when isCompleteQuery is true */
866 needCleanup = isCompleteQuery && EventTriggerBeginCompleteQuery();
868 /* PG_TRY block is to ensure we call EventTriggerEndCompleteQuery */
872 EventTriggerDDLCommandStart(parsetree);
874 switch (nodeTag(parsetree))
877 * relation and attribute manipulation
879 case T_CreateSchemaStmt:
880 CreateSchemaCommand((CreateSchemaStmt *) parsetree,
885 case T_CreateForeignTableStmt:
891 /* Run parse analysis ... */
892 stmts = transformCreateStmt((CreateStmt *) parsetree,
898 Node *stmt = (Node *) lfirst(l);
900 if (IsA(stmt, CreateStmt))
903 static char *validnsps[] = HEAP_RELOPT_NAMESPACES;
905 /* Create the table itself */
906 relOid = DefineRelation((CreateStmt *) stmt,
911 * Let NewRelationCreateToastTable decide if this
912 * one needs a secondary relation too.
914 CommandCounterIncrement();
917 * parse and validate reloptions for the toast
920 toast_options = transformRelOptions((Datum) 0,
921 ((CreateStmt *) stmt)->options,
926 (void) heap_reloptions(RELKIND_TOASTVALUE,
930 NewRelationCreateToastTable(relOid, toast_options);
932 else if (IsA(stmt, CreateForeignTableStmt))
934 /* Create the table itself */
935 relOid = DefineRelation((CreateStmt *) stmt,
936 RELKIND_FOREIGN_TABLE,
938 CreateForeignTable((CreateForeignTableStmt *) stmt,
943 /* Recurse for anything else */
946 PROCESS_UTILITY_SUBCOMMAND,
952 /* Need CCI between commands */
953 if (lnext(l) != NULL)
954 CommandCounterIncrement();
959 case T_AlterTableStmt:
961 AlterTableStmt *atstmt = (AlterTableStmt *) parsetree;
968 * Figure out lock mode, and acquire lock. This also does
969 * basic permissions checks, so that we won't wait for a
970 * lock on (for example) a relation on which we have no
973 lockmode = AlterTableGetLockLevel(atstmt->cmds);
974 relid = AlterTableLookupRelation(atstmt, lockmode);
976 if (OidIsValid(relid))
978 /* Run parse analysis ... */
979 stmts = transformAlterTableStmt(relid, atstmt,
985 Node *stmt = (Node *) lfirst(l);
987 if (IsA(stmt, AlterTableStmt))
989 /* Do the table alteration proper */
990 AlterTable(relid, lockmode,
991 (AlterTableStmt *) stmt);
995 /* Recurse for anything else */
998 PROCESS_UTILITY_SUBCOMMAND,
1004 /* Need CCI between commands */
1005 if (lnext(l) != NULL)
1006 CommandCounterIncrement();
1011 (errmsg("relation \"%s\" does not exist, skipping",
1012 atstmt->relation->relname)));
1016 case T_AlterDomainStmt:
1018 AlterDomainStmt *stmt = (AlterDomainStmt *) parsetree;
1021 * Some or all of these functions are recursive to cover
1022 * inherited things, so permission checks are done there.
1024 switch (stmt->subtype)
1026 case 'T': /* ALTER DOMAIN DEFAULT */
1029 * Recursively alter column default for table and,
1030 * if requested, for descendants
1032 AlterDomainDefault(stmt->typeName,
1035 case 'N': /* ALTER DOMAIN DROP NOT NULL */
1036 AlterDomainNotNull(stmt->typeName,
1039 case 'O': /* ALTER DOMAIN SET NOT NULL */
1040 AlterDomainNotNull(stmt->typeName,
1043 case 'C': /* ADD CONSTRAINT */
1044 AlterDomainAddConstraint(stmt->typeName,
1047 case 'X': /* DROP CONSTRAINT */
1048 AlterDomainDropConstraint(stmt->typeName,
1053 case 'V': /* VALIDATE CONSTRAINT */
1054 AlterDomainValidateConstraint(stmt->typeName,
1058 elog(ERROR, "unrecognized alter domain type: %d",
1059 (int) stmt->subtype);
1066 * ************* object creation / destruction **************
1070 DefineStmt *stmt = (DefineStmt *) parsetree;
1074 case OBJECT_AGGREGATE:
1075 DefineAggregate(stmt->defnames, stmt->args,
1076 stmt->oldstyle, stmt->definition,
1079 case OBJECT_OPERATOR:
1080 Assert(stmt->args == NIL);
1081 DefineOperator(stmt->defnames, stmt->definition);
1084 Assert(stmt->args == NIL);
1085 DefineType(stmt->defnames, stmt->definition);
1087 case OBJECT_TSPARSER:
1088 Assert(stmt->args == NIL);
1089 DefineTSParser(stmt->defnames, stmt->definition);
1091 case OBJECT_TSDICTIONARY:
1092 Assert(stmt->args == NIL);
1093 DefineTSDictionary(stmt->defnames,
1096 case OBJECT_TSTEMPLATE:
1097 Assert(stmt->args == NIL);
1098 DefineTSTemplate(stmt->defnames,
1101 case OBJECT_TSCONFIGURATION:
1102 Assert(stmt->args == NIL);
1103 DefineTSConfiguration(stmt->defnames,
1106 case OBJECT_COLLATION:
1107 Assert(stmt->args == NIL);
1108 DefineCollation(stmt->defnames, stmt->definition);
1111 elog(ERROR, "unrecognized define stmt type: %d",
1118 case T_IndexStmt: /* CREATE INDEX */
1120 IndexStmt *stmt = (IndexStmt *) parsetree;
1124 if (stmt->concurrent)
1125 PreventTransactionChain(isTopLevel,
1126 "CREATE INDEX CONCURRENTLY");
1129 * Look up the relation OID just once, right here at the
1130 * beginning, so that we don't end up repeating the name
1131 * lookup later and latching onto a different relation
1132 * partway through. To avoid lock upgrade hazards, it's
1133 * important that we take the strongest lock that will
1134 * eventually be needed here, so the lockmode calculation
1135 * needs to match what DefineIndex() does.
1137 lockmode = stmt->concurrent ? ShareUpdateExclusiveLock
1140 RangeVarGetRelidExtended(stmt->relation, lockmode,
1142 RangeVarCallbackOwnsRelation,
1145 /* Run parse analysis ... */
1146 stmt = transformIndexStmt(relid, stmt, queryString);
1149 DefineIndex(relid, /* OID of heap relation */
1151 InvalidOid, /* no predefined OID */
1152 false, /* is_alter_table */
1153 true, /* check_rights */
1154 false, /* skip_build */
1159 case T_CreateExtensionStmt:
1160 CreateExtension((CreateExtensionStmt *) parsetree);
1163 case T_AlterExtensionStmt:
1164 ExecAlterExtensionStmt((AlterExtensionStmt *) parsetree);
1167 case T_AlterExtensionContentsStmt:
1168 ExecAlterExtensionContentsStmt((AlterExtensionContentsStmt *) parsetree);
1171 case T_CreateFdwStmt:
1172 CreateForeignDataWrapper((CreateFdwStmt *) parsetree);
1175 case T_AlterFdwStmt:
1176 AlterForeignDataWrapper((AlterFdwStmt *) parsetree);
1179 case T_CreateForeignServerStmt:
1180 CreateForeignServer((CreateForeignServerStmt *) parsetree);
1183 case T_AlterForeignServerStmt:
1184 AlterForeignServer((AlterForeignServerStmt *) parsetree);
1187 case T_CreateUserMappingStmt:
1188 CreateUserMapping((CreateUserMappingStmt *) parsetree);
1191 case T_AlterUserMappingStmt:
1192 AlterUserMapping((AlterUserMappingStmt *) parsetree);
1195 case T_DropUserMappingStmt:
1196 RemoveUserMapping((DropUserMappingStmt *) parsetree);
1199 case T_ImportForeignSchemaStmt:
1200 ImportForeignSchema((ImportForeignSchemaStmt *) parsetree);
1203 case T_CompositeTypeStmt: /* CREATE TYPE (composite) */
1205 CompositeTypeStmt *stmt = (CompositeTypeStmt *) parsetree;
1207 DefineCompositeType(stmt->typevar, stmt->coldeflist);
1211 case T_CreateEnumStmt: /* CREATE TYPE AS ENUM */
1212 DefineEnum((CreateEnumStmt *) parsetree);
1215 case T_CreateRangeStmt: /* CREATE TYPE AS RANGE */
1216 DefineRange((CreateRangeStmt *) parsetree);
1219 case T_AlterEnumStmt: /* ALTER TYPE (enum) */
1220 AlterEnum((AlterEnumStmt *) parsetree, isTopLevel);
1223 case T_ViewStmt: /* CREATE VIEW */
1224 DefineView((ViewStmt *) parsetree, queryString);
1227 case T_CreateFunctionStmt: /* CREATE FUNCTION */
1228 CreateFunction((CreateFunctionStmt *) parsetree, queryString);
1231 case T_AlterFunctionStmt: /* ALTER FUNCTION */
1232 AlterFunction((AlterFunctionStmt *) parsetree);
1235 case T_RuleStmt: /* CREATE RULE */
1236 DefineRule((RuleStmt *) parsetree, queryString);
1239 case T_CreateSeqStmt:
1240 DefineSequence((CreateSeqStmt *) parsetree);
1243 case T_AlterSeqStmt:
1244 AlterSequence((AlterSeqStmt *) parsetree);
1247 case T_CreateTableAsStmt:
1248 ExecCreateTableAs((CreateTableAsStmt *) parsetree,
1249 queryString, params, completionTag);
1252 case T_RefreshMatViewStmt:
1253 ExecRefreshMatView((RefreshMatViewStmt *) parsetree,
1254 queryString, params, completionTag);
1257 case T_CreateTrigStmt:
1258 (void) CreateTrigger((CreateTrigStmt *) parsetree, queryString,
1259 InvalidOid, InvalidOid, InvalidOid,
1263 case T_CreatePLangStmt:
1264 CreateProceduralLanguage((CreatePLangStmt *) parsetree);
1267 case T_CreateDomainStmt:
1268 DefineDomain((CreateDomainStmt *) parsetree);
1271 case T_CreateConversionStmt:
1272 CreateConversionCommand((CreateConversionStmt *) parsetree);
1275 case T_CreateCastStmt:
1276 CreateCast((CreateCastStmt *) parsetree);
1279 case T_CreateOpClassStmt:
1280 DefineOpClass((CreateOpClassStmt *) parsetree);
1283 case T_CreateOpFamilyStmt:
1284 DefineOpFamily((CreateOpFamilyStmt *) parsetree);
1287 case T_AlterOpFamilyStmt:
1288 AlterOpFamily((AlterOpFamilyStmt *) parsetree);
1291 case T_AlterTSDictionaryStmt:
1292 AlterTSDictionary((AlterTSDictionaryStmt *) parsetree);
1295 case T_AlterTSConfigurationStmt:
1296 AlterTSConfiguration((AlterTSConfigurationStmt *) parsetree);
1300 ExecDropStmt((DropStmt *) parsetree, isTopLevel);
1304 ExecRenameStmt((RenameStmt *) parsetree);
1307 case T_AlterObjectSchemaStmt:
1308 ExecAlterObjectSchemaStmt((AlterObjectSchemaStmt *) parsetree);
1311 case T_AlterOwnerStmt:
1312 ExecAlterOwnerStmt((AlterOwnerStmt *) parsetree);
1315 case T_DropOwnedStmt:
1316 DropOwnedObjects((DropOwnedStmt *) parsetree);
1319 case T_AlterDefaultPrivilegesStmt:
1320 ExecAlterDefaultPrivilegesStmt((AlterDefaultPrivilegesStmt *) parsetree);
1324 elog(ERROR, "unrecognized node type: %d",
1325 (int) nodeTag(parsetree));
1329 if (isCompleteQuery)
1331 EventTriggerSQLDrop(parsetree);
1332 EventTriggerDDLCommandEnd(parsetree);
1338 EventTriggerEndCompleteQuery();
1344 EventTriggerEndCompleteQuery();
1348 * Dispatch function for DropStmt
1351 ExecDropStmt(DropStmt *stmt, bool isTopLevel)
1353 switch (stmt->removeType)
1356 if (stmt->concurrent)
1357 PreventTransactionChain(isTopLevel,
1358 "DROP INDEX CONCURRENTLY");
1362 case OBJECT_SEQUENCE:
1364 case OBJECT_MATVIEW:
1365 case OBJECT_FOREIGN_TABLE:
1366 RemoveRelations(stmt);
1369 RemoveObjects(stmt);
1376 * UtilityReturnsTuples
1377 * Return "true" if this utility statement will send output to the
1380 * Generally, there should be a case here for each case in ProcessUtility
1381 * where "dest" is passed on.
1384 UtilityReturnsTuples(Node *parsetree)
1386 switch (nodeTag(parsetree))
1390 FetchStmt *stmt = (FetchStmt *) parsetree;
1395 portal = GetPortalByName(stmt->portalname);
1396 if (!PortalIsValid(portal))
1397 return false; /* not our business to raise error */
1398 return portal->tupDesc ? true : false;
1403 ExecuteStmt *stmt = (ExecuteStmt *) parsetree;
1404 PreparedStatement *entry;
1406 entry = FetchPreparedStatement(stmt->name, false);
1408 return false; /* not our business to raise error */
1409 if (entry->plansource->resultDesc)
1417 case T_VariableShowStmt:
1426 * UtilityTupleDescriptor
1427 * Fetch the actual output tuple descriptor for a utility statement
1428 * for which UtilityReturnsTuples() previously returned "true".
1430 * The returned descriptor is created in (or copied into) the current memory
1434 UtilityTupleDescriptor(Node *parsetree)
1436 switch (nodeTag(parsetree))
1440 FetchStmt *stmt = (FetchStmt *) parsetree;
1445 portal = GetPortalByName(stmt->portalname);
1446 if (!PortalIsValid(portal))
1447 return NULL; /* not our business to raise error */
1448 return CreateTupleDescCopy(portal->tupDesc);
1453 ExecuteStmt *stmt = (ExecuteStmt *) parsetree;
1454 PreparedStatement *entry;
1456 entry = FetchPreparedStatement(stmt->name, false);
1458 return NULL; /* not our business to raise error */
1459 return FetchPreparedStatementResultDesc(entry);
1463 return ExplainResultDesc((ExplainStmt *) parsetree);
1465 case T_VariableShowStmt:
1467 VariableShowStmt *n = (VariableShowStmt *) parsetree;
1469 return GetPGVariableResultDesc(n->name);
1479 * QueryReturnsTuples
1480 * Return "true" if this Query will send output to the destination.
1484 QueryReturnsTuples(Query *parsetree)
1486 switch (parsetree->commandType)
1489 /* returns tuples ... unless it's DECLARE CURSOR */
1490 if (parsetree->utilityStmt == NULL)
1496 /* the forms with RETURNING return tuples */
1497 if (parsetree->returningList)
1501 return UtilityReturnsTuples(parsetree->utilityStmt);
1504 /* probably shouldn't get here */
1507 return false; /* default */
1513 * UtilityContainsQuery
1514 * Return the contained Query, or NULL if there is none
1516 * Certain utility statements, such as EXPLAIN, contain a plannable Query.
1517 * This function encapsulates knowledge of exactly which ones do.
1518 * We assume it is invoked only on already-parse-analyzed statements
1519 * (else the contained parsetree isn't a Query yet).
1521 * In some cases (currently, only EXPLAIN of CREATE TABLE AS/SELECT INTO and
1522 * CREATE MATERIALIZED VIEW), potentially Query-containing utility statements
1523 * can be nested. This function will drill down to a non-utility Query, or
1524 * return NULL if none.
1527 UtilityContainsQuery(Node *parsetree)
1531 switch (nodeTag(parsetree))
1534 qry = (Query *) ((ExplainStmt *) parsetree)->query;
1535 Assert(IsA(qry, Query));
1536 if (qry->commandType == CMD_UTILITY)
1537 return UtilityContainsQuery(qry->utilityStmt);
1540 case T_CreateTableAsStmt:
1541 qry = (Query *) ((CreateTableAsStmt *) parsetree)->query;
1542 Assert(IsA(qry, Query));
1543 if (qry->commandType == CMD_UTILITY)
1544 return UtilityContainsQuery(qry->utilityStmt);
1554 * AlterObjectTypeCommandTag
1555 * helper function for CreateCommandTag
1557 * This covers most cases where ALTER is used with an ObjectType enum.
1560 AlterObjectTypeCommandTag(ObjectType objtype)
1566 case OBJECT_AGGREGATE:
1567 tag = "ALTER AGGREGATE";
1569 case OBJECT_ATTRIBUTE:
1575 case OBJECT_COLLATION:
1576 tag = "ALTER COLLATION";
1579 tag = "ALTER TABLE";
1581 case OBJECT_CONSTRAINT:
1582 tag = "ALTER TABLE";
1584 case OBJECT_CONVERSION:
1585 tag = "ALTER CONVERSION";
1587 case OBJECT_DATABASE:
1588 tag = "ALTER DATABASE";
1591 tag = "ALTER DOMAIN";
1593 case OBJECT_EXTENSION:
1594 tag = "ALTER EXTENSION";
1597 tag = "ALTER FOREIGN DATA WRAPPER";
1599 case OBJECT_FOREIGN_SERVER:
1600 tag = "ALTER SERVER";
1602 case OBJECT_FOREIGN_TABLE:
1603 tag = "ALTER FOREIGN TABLE";
1605 case OBJECT_FUNCTION:
1606 tag = "ALTER FUNCTION";
1609 tag = "ALTER INDEX";
1611 case OBJECT_LANGUAGE:
1612 tag = "ALTER LANGUAGE";
1614 case OBJECT_LARGEOBJECT:
1615 tag = "ALTER LARGE OBJECT";
1617 case OBJECT_OPCLASS:
1618 tag = "ALTER OPERATOR CLASS";
1620 case OBJECT_OPERATOR:
1621 tag = "ALTER OPERATOR";
1623 case OBJECT_OPFAMILY:
1624 tag = "ALTER OPERATOR FAMILY";
1633 tag = "ALTER SCHEMA";
1635 case OBJECT_SEQUENCE:
1636 tag = "ALTER SEQUENCE";
1639 tag = "ALTER TABLE";
1641 case OBJECT_TABLESPACE:
1642 tag = "ALTER TABLESPACE";
1644 case OBJECT_TRIGGER:
1645 tag = "ALTER TRIGGER";
1647 case OBJECT_EVENT_TRIGGER:
1648 tag = "ALTER EVENT TRIGGER";
1650 case OBJECT_TSCONFIGURATION:
1651 tag = "ALTER TEXT SEARCH CONFIGURATION";
1653 case OBJECT_TSDICTIONARY:
1654 tag = "ALTER TEXT SEARCH DICTIONARY";
1656 case OBJECT_TSPARSER:
1657 tag = "ALTER TEXT SEARCH PARSER";
1659 case OBJECT_TSTEMPLATE:
1660 tag = "ALTER TEXT SEARCH TEMPLATE";
1668 case OBJECT_MATVIEW:
1669 tag = "ALTER MATERIALIZED VIEW";
1681 * utility to get a string representation of the command operation,
1682 * given either a raw (un-analyzed) parsetree or a planned query.
1684 * This must handle all command types, but since the vast majority
1685 * of 'em are utility commands, it seems sensible to keep it here.
1687 * NB: all result strings must be shorter than COMPLETION_TAG_BUFSIZE.
1688 * Also, the result must point at a true constant (permanent storage).
1691 CreateCommandTag(Node *parsetree)
1695 switch (nodeTag(parsetree))
1697 /* raw plannable queries */
1714 /* utility statements --- same whether raw or cooked */
1715 case T_TransactionStmt:
1717 TransactionStmt *stmt = (TransactionStmt *) parsetree;
1721 case TRANS_STMT_BEGIN:
1725 case TRANS_STMT_START:
1726 tag = "START TRANSACTION";
1729 case TRANS_STMT_COMMIT:
1733 case TRANS_STMT_ROLLBACK:
1734 case TRANS_STMT_ROLLBACK_TO:
1738 case TRANS_STMT_SAVEPOINT:
1742 case TRANS_STMT_RELEASE:
1746 case TRANS_STMT_PREPARE:
1747 tag = "PREPARE TRANSACTION";
1750 case TRANS_STMT_COMMIT_PREPARED:
1751 tag = "COMMIT PREPARED";
1754 case TRANS_STMT_ROLLBACK_PREPARED:
1755 tag = "ROLLBACK PREPARED";
1765 case T_DeclareCursorStmt:
1766 tag = "DECLARE CURSOR";
1769 case T_ClosePortalStmt:
1771 ClosePortalStmt *stmt = (ClosePortalStmt *) parsetree;
1773 if (stmt->portalname == NULL)
1774 tag = "CLOSE CURSOR ALL";
1776 tag = "CLOSE CURSOR";
1782 FetchStmt *stmt = (FetchStmt *) parsetree;
1784 tag = (stmt->ismove) ? "MOVE" : "FETCH";
1788 case T_CreateDomainStmt:
1789 tag = "CREATE DOMAIN";
1792 case T_CreateSchemaStmt:
1793 tag = "CREATE SCHEMA";
1797 tag = "CREATE TABLE";
1800 case T_CreateTableSpaceStmt:
1801 tag = "CREATE TABLESPACE";
1804 case T_DropTableSpaceStmt:
1805 tag = "DROP TABLESPACE";
1808 case T_AlterTableSpaceOptionsStmt:
1809 tag = "ALTER TABLESPACE";
1812 case T_CreateExtensionStmt:
1813 tag = "CREATE EXTENSION";
1816 case T_AlterExtensionStmt:
1817 tag = "ALTER EXTENSION";
1820 case T_AlterExtensionContentsStmt:
1821 tag = "ALTER EXTENSION";
1824 case T_CreateFdwStmt:
1825 tag = "CREATE FOREIGN DATA WRAPPER";
1828 case T_AlterFdwStmt:
1829 tag = "ALTER FOREIGN DATA WRAPPER";
1832 case T_CreateForeignServerStmt:
1833 tag = "CREATE SERVER";
1836 case T_AlterForeignServerStmt:
1837 tag = "ALTER SERVER";
1840 case T_CreateUserMappingStmt:
1841 tag = "CREATE USER MAPPING";
1844 case T_AlterUserMappingStmt:
1845 tag = "ALTER USER MAPPING";
1848 case T_DropUserMappingStmt:
1849 tag = "DROP USER MAPPING";
1852 case T_CreateForeignTableStmt:
1853 tag = "CREATE FOREIGN TABLE";
1856 case T_ImportForeignSchemaStmt:
1857 tag = "IMPORT FOREIGN SCHEMA";
1861 switch (((DropStmt *) parsetree)->removeType)
1866 case OBJECT_SEQUENCE:
1867 tag = "DROP SEQUENCE";
1872 case OBJECT_MATVIEW:
1873 tag = "DROP MATERIALIZED VIEW";
1882 tag = "DROP DOMAIN";
1884 case OBJECT_COLLATION:
1885 tag = "DROP COLLATION";
1887 case OBJECT_CONVERSION:
1888 tag = "DROP CONVERSION";
1891 tag = "DROP SCHEMA";
1893 case OBJECT_TSPARSER:
1894 tag = "DROP TEXT SEARCH PARSER";
1896 case OBJECT_TSDICTIONARY:
1897 tag = "DROP TEXT SEARCH DICTIONARY";
1899 case OBJECT_TSTEMPLATE:
1900 tag = "DROP TEXT SEARCH TEMPLATE";
1902 case OBJECT_TSCONFIGURATION:
1903 tag = "DROP TEXT SEARCH CONFIGURATION";
1905 case OBJECT_FOREIGN_TABLE:
1906 tag = "DROP FOREIGN TABLE";
1908 case OBJECT_EXTENSION:
1909 tag = "DROP EXTENSION";
1911 case OBJECT_FUNCTION:
1912 tag = "DROP FUNCTION";
1914 case OBJECT_AGGREGATE:
1915 tag = "DROP AGGREGATE";
1917 case OBJECT_OPERATOR:
1918 tag = "DROP OPERATOR";
1920 case OBJECT_LANGUAGE:
1921 tag = "DROP LANGUAGE";
1926 case OBJECT_TRIGGER:
1927 tag = "DROP TRIGGER";
1929 case OBJECT_EVENT_TRIGGER:
1930 tag = "DROP EVENT TRIGGER";
1936 tag = "DROP FOREIGN DATA WRAPPER";
1938 case OBJECT_FOREIGN_SERVER:
1939 tag = "DROP SERVER";
1941 case OBJECT_OPCLASS:
1942 tag = "DROP OPERATOR CLASS";
1944 case OBJECT_OPFAMILY:
1945 tag = "DROP OPERATOR FAMILY";
1952 case T_TruncateStmt:
1953 tag = "TRUNCATE TABLE";
1960 case T_SecLabelStmt:
1961 tag = "SECURITY LABEL";
1969 tag = AlterObjectTypeCommandTag(((RenameStmt *) parsetree)->renameType);
1972 case T_AlterObjectSchemaStmt:
1973 tag = AlterObjectTypeCommandTag(((AlterObjectSchemaStmt *) parsetree)->objectType);
1976 case T_AlterOwnerStmt:
1977 tag = AlterObjectTypeCommandTag(((AlterOwnerStmt *) parsetree)->objectType);
1980 case T_AlterTableMoveAllStmt:
1981 tag = AlterObjectTypeCommandTag(((AlterTableMoveAllStmt *) parsetree)->objtype);
1984 case T_AlterTableStmt:
1985 tag = AlterObjectTypeCommandTag(((AlterTableStmt *) parsetree)->relkind);
1988 case T_AlterDomainStmt:
1989 tag = "ALTER DOMAIN";
1992 case T_AlterFunctionStmt:
1993 tag = "ALTER FUNCTION";
1998 GrantStmt *stmt = (GrantStmt *) parsetree;
2000 tag = (stmt->is_grant) ? "GRANT" : "REVOKE";
2004 case T_GrantRoleStmt:
2006 GrantRoleStmt *stmt = (GrantRoleStmt *) parsetree;
2008 tag = (stmt->is_grant) ? "GRANT ROLE" : "REVOKE ROLE";
2012 case T_AlterDefaultPrivilegesStmt:
2013 tag = "ALTER DEFAULT PRIVILEGES";
2017 switch (((DefineStmt *) parsetree)->kind)
2019 case OBJECT_AGGREGATE:
2020 tag = "CREATE AGGREGATE";
2022 case OBJECT_OPERATOR:
2023 tag = "CREATE OPERATOR";
2026 tag = "CREATE TYPE";
2028 case OBJECT_TSPARSER:
2029 tag = "CREATE TEXT SEARCH PARSER";
2031 case OBJECT_TSDICTIONARY:
2032 tag = "CREATE TEXT SEARCH DICTIONARY";
2034 case OBJECT_TSTEMPLATE:
2035 tag = "CREATE TEXT SEARCH TEMPLATE";
2037 case OBJECT_TSCONFIGURATION:
2038 tag = "CREATE TEXT SEARCH CONFIGURATION";
2040 case OBJECT_COLLATION:
2041 tag = "CREATE COLLATION";
2048 case T_CompositeTypeStmt:
2049 tag = "CREATE TYPE";
2052 case T_CreateEnumStmt:
2053 tag = "CREATE TYPE";
2056 case T_CreateRangeStmt:
2057 tag = "CREATE TYPE";
2060 case T_AlterEnumStmt:
2065 tag = "CREATE VIEW";
2068 case T_CreateFunctionStmt:
2069 tag = "CREATE FUNCTION";
2073 tag = "CREATE INDEX";
2077 tag = "CREATE RULE";
2080 case T_CreateSeqStmt:
2081 tag = "CREATE SEQUENCE";
2084 case T_AlterSeqStmt:
2085 tag = "ALTER SEQUENCE";
2092 case T_CreatedbStmt:
2093 tag = "CREATE DATABASE";
2096 case T_AlterDatabaseStmt:
2097 tag = "ALTER DATABASE";
2100 case T_AlterDatabaseSetStmt:
2101 tag = "ALTER DATABASE";
2105 tag = "DROP DATABASE";
2116 case T_UnlistenStmt:
2129 if (((VacuumStmt *) parsetree)->options & VACOPT_VACUUM)
2139 case T_CreateTableAsStmt:
2140 switch (((CreateTableAsStmt *) parsetree)->relkind)
2143 if (((CreateTableAsStmt *) parsetree)->is_select_into)
2144 tag = "SELECT INTO";
2146 tag = "CREATE TABLE AS";
2148 case OBJECT_MATVIEW:
2149 tag = "CREATE MATERIALIZED VIEW";
2156 case T_RefreshMatViewStmt:
2157 tag = "REFRESH MATERIALIZED VIEW";
2160 case T_AlterSystemStmt:
2161 tag = "ALTER SYSTEM";
2164 case T_VariableSetStmt:
2165 switch (((VariableSetStmt *) parsetree)->kind)
2168 case VAR_SET_CURRENT:
2169 case VAR_SET_DEFAULT:
2182 case T_VariableShowStmt:
2187 switch (((DiscardStmt *) parsetree)->target)
2190 tag = "DISCARD ALL";
2193 tag = "DISCARD PLANS";
2196 tag = "DISCARD TEMP";
2198 case DISCARD_SEQUENCES:
2199 tag = "DISCARD SEQUENCES";
2206 case T_CreateTrigStmt:
2207 tag = "CREATE TRIGGER";
2210 case T_CreateEventTrigStmt:
2211 tag = "CREATE EVENT TRIGGER";
2214 case T_AlterEventTrigStmt:
2215 tag = "ALTER EVENT TRIGGER";
2218 case T_CreatePLangStmt:
2219 tag = "CREATE LANGUAGE";
2222 case T_CreateRoleStmt:
2223 tag = "CREATE ROLE";
2226 case T_AlterRoleStmt:
2230 case T_AlterRoleSetStmt:
2234 case T_DropRoleStmt:
2238 case T_DropOwnedStmt:
2242 case T_ReassignOwnedStmt:
2243 tag = "REASSIGN OWNED";
2250 case T_ConstraintsSetStmt:
2251 tag = "SET CONSTRAINTS";
2254 case T_CheckPointStmt:
2262 case T_CreateConversionStmt:
2263 tag = "CREATE CONVERSION";
2266 case T_CreateCastStmt:
2267 tag = "CREATE CAST";
2270 case T_CreateOpClassStmt:
2271 tag = "CREATE OPERATOR CLASS";
2274 case T_CreateOpFamilyStmt:
2275 tag = "CREATE OPERATOR FAMILY";
2278 case T_AlterOpFamilyStmt:
2279 tag = "ALTER OPERATOR FAMILY";
2282 case T_AlterTSDictionaryStmt:
2283 tag = "ALTER TEXT SEARCH DICTIONARY";
2286 case T_AlterTSConfigurationStmt:
2287 tag = "ALTER TEXT SEARCH CONFIGURATION";
2298 case T_DeallocateStmt:
2300 DeallocateStmt *stmt = (DeallocateStmt *) parsetree;
2302 if (stmt->name == NULL)
2303 tag = "DEALLOCATE ALL";
2309 /* already-planned queries */
2312 PlannedStmt *stmt = (PlannedStmt *) parsetree;
2314 switch (stmt->commandType)
2319 * We take a little extra care here so that the result
2320 * will be useful for complaints about read-only
2323 if (stmt->utilityStmt != NULL)
2325 Assert(IsA(stmt->utilityStmt, DeclareCursorStmt));
2326 tag = "DECLARE CURSOR";
2328 else if (stmt->rowMarks != NIL)
2330 /* not 100% but probably close enough */
2331 switch (((PlanRowMark *) linitial(stmt->rowMarks))->markType)
2333 case ROW_MARK_EXCLUSIVE:
2334 tag = "SELECT FOR UPDATE";
2336 case ROW_MARK_NOKEYEXCLUSIVE:
2337 tag = "SELECT FOR NO KEY UPDATE";
2339 case ROW_MARK_SHARE:
2340 tag = "SELECT FOR SHARE";
2342 case ROW_MARK_KEYSHARE:
2343 tag = "SELECT FOR KEY SHARE";
2345 case ROW_MARK_REFERENCE:
2367 elog(WARNING, "unrecognized commandType: %d",
2368 (int) stmt->commandType);
2375 /* parsed-and-rewritten-but-not-planned queries */
2378 Query *stmt = (Query *) parsetree;
2380 switch (stmt->commandType)
2385 * We take a little extra care here so that the result
2386 * will be useful for complaints about read-only
2389 if (stmt->utilityStmt != NULL)
2391 Assert(IsA(stmt->utilityStmt, DeclareCursorStmt));
2392 tag = "DECLARE CURSOR";
2394 else if (stmt->rowMarks != NIL)
2396 /* not 100% but probably close enough */
2397 switch (((RowMarkClause *) linitial(stmt->rowMarks))->strength)
2399 case LCS_FORKEYSHARE:
2400 tag = "SELECT FOR KEY SHARE";
2403 tag = "SELECT FOR SHARE";
2405 case LCS_FORNOKEYUPDATE:
2406 tag = "SELECT FOR NO KEY UPDATE";
2409 tag = "SELECT FOR UPDATE";
2429 tag = CreateCommandTag(stmt->utilityStmt);
2432 elog(WARNING, "unrecognized commandType: %d",
2433 (int) stmt->commandType);
2441 elog(WARNING, "unrecognized node type: %d",
2442 (int) nodeTag(parsetree));
2452 * GetCommandLogLevel
2453 * utility to get the minimum log_statement level for a command,
2454 * given either a raw (un-analyzed) parsetree or a planned query.
2456 * This must handle all command types, but since the vast majority
2457 * of 'em are utility commands, it seems sensible to keep it here.
2460 GetCommandLogLevel(Node *parsetree)
2464 if (parsetree == NULL)
2467 switch (nodeTag(parsetree))
2469 /* raw plannable queries */
2477 if (((SelectStmt *) parsetree)->intoClause)
2478 lev = LOGSTMT_DDL; /* SELECT INTO */
2483 /* utility statements --- same whether raw or cooked */
2484 case T_TransactionStmt:
2488 case T_DeclareCursorStmt:
2492 case T_ClosePortalStmt:
2500 case T_CreateSchemaStmt:
2505 case T_CreateForeignTableStmt:
2509 case T_CreateTableSpaceStmt:
2510 case T_DropTableSpaceStmt:
2511 case T_AlterTableSpaceOptionsStmt:
2515 case T_CreateExtensionStmt:
2516 case T_AlterExtensionStmt:
2517 case T_AlterExtensionContentsStmt:
2521 case T_CreateFdwStmt:
2522 case T_AlterFdwStmt:
2523 case T_CreateForeignServerStmt:
2524 case T_AlterForeignServerStmt:
2525 case T_CreateUserMappingStmt:
2526 case T_AlterUserMappingStmt:
2527 case T_DropUserMappingStmt:
2528 case T_ImportForeignSchemaStmt:
2536 case T_TruncateStmt:
2544 case T_SecLabelStmt:
2549 if (((CopyStmt *) parsetree)->is_from)
2557 PrepareStmt *stmt = (PrepareStmt *) parsetree;
2559 /* Look through a PREPARE to the contained stmt */
2560 lev = GetCommandLogLevel(stmt->query);
2566 ExecuteStmt *stmt = (ExecuteStmt *) parsetree;
2567 PreparedStatement *ps;
2569 /* Look through an EXECUTE to the referenced stmt */
2570 ps = FetchPreparedStatement(stmt->name, false);
2572 lev = GetCommandLogLevel(ps->plansource->raw_parse_tree);
2578 case T_DeallocateStmt:
2586 case T_AlterObjectSchemaStmt:
2590 case T_AlterOwnerStmt:
2594 case T_AlterTableMoveAllStmt:
2595 case T_AlterTableStmt:
2599 case T_AlterDomainStmt:
2607 case T_GrantRoleStmt:
2611 case T_AlterDefaultPrivilegesStmt:
2619 case T_CompositeTypeStmt:
2623 case T_CreateEnumStmt:
2627 case T_CreateRangeStmt:
2631 case T_AlterEnumStmt:
2639 case T_CreateFunctionStmt:
2643 case T_AlterFunctionStmt:
2655 case T_CreateSeqStmt:
2659 case T_AlterSeqStmt:
2667 case T_CreatedbStmt:
2671 case T_AlterDatabaseStmt:
2675 case T_AlterDatabaseSetStmt:
2691 case T_UnlistenStmt:
2709 ExplainStmt *stmt = (ExplainStmt *) parsetree;
2710 bool analyze = false;
2713 /* Look through an EXPLAIN ANALYZE to the contained stmt */
2714 foreach(lc, stmt->options)
2716 DefElem *opt = (DefElem *) lfirst(lc);
2718 if (strcmp(opt->defname, "analyze") == 0)
2719 analyze = defGetBoolean(opt);
2720 /* don't "break", as explain.c will use the last value */
2723 return GetCommandLogLevel(stmt->query);
2725 /* Plain EXPLAIN isn't so interesting */
2730 case T_CreateTableAsStmt:
2734 case T_RefreshMatViewStmt:
2738 case T_AlterSystemStmt:
2742 case T_VariableSetStmt:
2746 case T_VariableShowStmt:
2754 case T_CreateTrigStmt:
2758 case T_CreateEventTrigStmt:
2762 case T_AlterEventTrigStmt:
2766 case T_CreatePLangStmt:
2770 case T_CreateDomainStmt:
2774 case T_CreateRoleStmt:
2778 case T_AlterRoleStmt:
2782 case T_AlterRoleSetStmt:
2786 case T_DropRoleStmt:
2790 case T_DropOwnedStmt:
2794 case T_ReassignOwnedStmt:
2802 case T_ConstraintsSetStmt:
2806 case T_CheckPointStmt:
2811 lev = LOGSTMT_ALL; /* should this be DDL? */
2814 case T_CreateConversionStmt:
2818 case T_CreateCastStmt:
2822 case T_CreateOpClassStmt:
2826 case T_CreateOpFamilyStmt:
2830 case T_AlterOpFamilyStmt:
2834 case T_AlterTSDictionaryStmt:
2838 case T_AlterTSConfigurationStmt:
2842 /* already-planned queries */
2845 PlannedStmt *stmt = (PlannedStmt *) parsetree;
2847 switch (stmt->commandType)
2860 elog(WARNING, "unrecognized commandType: %d",
2861 (int) stmt->commandType);
2868 /* parsed-and-rewritten-but-not-planned queries */
2871 Query *stmt = (Query *) parsetree;
2873 switch (stmt->commandType)
2886 lev = GetCommandLogLevel(stmt->utilityStmt);
2890 elog(WARNING, "unrecognized commandType: %d",
2891 (int) stmt->commandType);
2900 elog(WARNING, "unrecognized node type: %d",
2901 (int) nodeTag(parsetree));