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-2013, 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 * Verify user has ownership of specified relation, else ereport.
84 * If noCatalogs is true then we also deny access to system catalogs,
85 * except when allowSystemTableMods is true.
88 CheckRelationOwnership(RangeVar *rel, bool noCatalogs)
94 * XXX: This is unsafe in the presence of concurrent DDL, since it is
95 * called before acquiring any lock on the target relation. However,
96 * locking the target relation (especially using something like
97 * AccessExclusiveLock) before verifying that the user has permissions is
98 * not appealing either.
100 relOid = RangeVarGetRelid(rel, NoLock, false);
102 tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relOid));
103 if (!HeapTupleIsValid(tuple)) /* should not happen */
104 elog(ERROR, "cache lookup failed for relation %u", relOid);
106 if (!pg_class_ownercheck(relOid, GetUserId()))
107 aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
112 if (!allowSystemTableMods &&
113 IsSystemClass(relOid, (Form_pg_class) GETSTRUCT(tuple)))
115 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
116 errmsg("permission denied: \"%s\" is a system catalog",
120 ReleaseSysCache(tuple);
125 * CommandIsReadOnly: is an executable query read-only?
127 * This is a much stricter test than we apply for XactReadOnly mode;
128 * the query must be *in truth* read-only, because the caller wishes
129 * not to do CommandCounterIncrement for it.
131 * Note: currently no need to support Query nodes here
134 CommandIsReadOnly(Node *parsetree)
136 if (IsA(parsetree, PlannedStmt))
138 PlannedStmt *stmt = (PlannedStmt *) parsetree;
140 switch (stmt->commandType)
143 if (stmt->rowMarks != NIL)
144 return false; /* SELECT FOR [KEY] UPDATE/SHARE */
145 else if (stmt->hasModifyingCTE)
146 return false; /* data-modifying CTE */
154 elog(WARNING, "unrecognized commandType: %d",
155 (int) stmt->commandType);
159 /* For now, treat all utility commands as read/write */
164 * check_xact_readonly: is a utility command read-only?
166 * Here we use the loose rules of XactReadOnly mode: no permanent effects
167 * on the database are allowed.
170 check_xact_readonly(Node *parsetree)
176 * Note: Commands that need to do more complicated checking are handled
177 * elsewhere, in particular COPY and plannable statements do their own
178 * checking. However they should all call PreventCommandIfReadOnly to
179 * actually throw the error.
182 switch (nodeTag(parsetree))
184 case T_AlterDatabaseStmt:
185 case T_AlterDatabaseSetStmt:
186 case T_AlterDomainStmt:
187 case T_AlterFunctionStmt:
188 case T_AlterRoleStmt:
189 case T_AlterRoleSetStmt:
190 case T_AlterObjectSchemaStmt:
191 case T_AlterOwnerStmt:
193 case T_AlterTableStmt:
197 case T_CreateCastStmt:
198 case T_CreateEventTrigStmt:
199 case T_AlterEventTrigStmt:
200 case T_CreateConversionStmt:
202 case T_CreateDomainStmt:
203 case T_CreateFunctionStmt:
204 case T_CreateRoleStmt:
206 case T_CreatePLangStmt:
207 case T_CreateOpClassStmt:
208 case T_CreateOpFamilyStmt:
209 case T_AlterOpFamilyStmt:
211 case T_CreateSchemaStmt:
212 case T_CreateSeqStmt:
214 case T_CreateTableAsStmt:
215 case T_RefreshMatViewStmt:
216 case T_CreateTableSpaceStmt:
217 case T_CreateTrigStmt:
218 case T_CompositeTypeStmt:
219 case T_CreateEnumStmt:
220 case T_CreateRangeStmt:
221 case T_AlterEnumStmt:
225 case T_DropTableSpaceStmt:
228 case T_GrantRoleStmt:
229 case T_AlterDefaultPrivilegesStmt:
231 case T_DropOwnedStmt:
232 case T_ReassignOwnedStmt:
233 case T_AlterTSDictionaryStmt:
234 case T_AlterTSConfigurationStmt:
235 case T_CreateExtensionStmt:
236 case T_AlterExtensionStmt:
237 case T_AlterExtensionContentsStmt:
238 case T_CreateFdwStmt:
240 case T_CreateForeignServerStmt:
241 case T_AlterForeignServerStmt:
242 case T_CreateUserMappingStmt:
243 case T_AlterUserMappingStmt:
244 case T_DropUserMappingStmt:
245 case T_AlterTableSpaceOptionsStmt:
246 case T_CreateForeignTableStmt:
248 PreventCommandIfReadOnly(CreateCommandTag(parsetree));
257 * PreventCommandIfReadOnly: throw error if XactReadOnly
259 * This is useful mainly to ensure consistency of the error message wording;
260 * most callers have checked XactReadOnly for themselves.
263 PreventCommandIfReadOnly(const char *cmdname)
267 (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
268 /* translator: %s is name of a SQL command, eg CREATE */
269 errmsg("cannot execute %s in a read-only transaction",
274 * PreventCommandDuringRecovery: throw error if RecoveryInProgress
276 * The majority of operations that are unsafe in a Hot Standby slave
277 * will be rejected by XactReadOnly tests. However there are a few
278 * commands that are allowed in "read-only" xacts but cannot be allowed
279 * in Hot Standby mode. Those commands should call this function.
282 PreventCommandDuringRecovery(const char *cmdname)
284 if (RecoveryInProgress())
286 (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
287 /* translator: %s is name of a SQL command, eg CREATE */
288 errmsg("cannot execute %s during recovery",
293 * CheckRestrictedOperation: throw error for hazardous command if we're
294 * inside a security restriction context.
296 * This is needed to protect session-local state for which there is not any
297 * better-defined protection mechanism, such as ownership.
300 CheckRestrictedOperation(const char *cmdname)
302 if (InSecurityRestrictedOperation())
304 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
305 /* translator: %s is name of a SQL command, eg PREPARE */
306 errmsg("cannot execute %s within security-restricted operation",
313 * general utility function invoker
315 * parsetree: the parse tree for the utility statement
316 * queryString: original source text of command
317 * context: identifies source of statement (toplevel client command,
318 * non-toplevel client command, subcommand of a larger utility command)
319 * params: parameters to use during execution
320 * dest: where to send results
321 * completionTag: points to a buffer of size COMPLETION_TAG_BUFSIZE
322 * in which to store a command completion status string.
324 * Notes: as of PG 8.4, caller MUST supply a queryString; it is not
325 * allowed anymore to pass NULL. (If you really don't have source text,
326 * you can pass a constant string, perhaps "(query not available)".)
328 * completionTag is only set nonempty if we want to return a nondefault status.
330 * completionTag may be NULL if caller doesn't want a status string.
333 ProcessUtility(Node *parsetree,
334 const char *queryString,
335 ProcessUtilityContext context,
336 ParamListInfo params,
340 Assert(queryString != NULL); /* required as of 8.4 */
343 * We provide a function hook variable that lets loadable plugins get
344 * control when ProcessUtility is called. Such a plugin would normally
345 * call standard_ProcessUtility().
347 if (ProcessUtility_hook)
348 (*ProcessUtility_hook) (parsetree, queryString,
350 dest, completionTag);
352 standard_ProcessUtility(parsetree, queryString,
354 dest, completionTag);
358 * standard_ProcessUtility itself deals only with utility commands for
359 * which we do not provide event trigger support. Commands that do have
360 * such support are passed down to ProcessUtilitySlow, which contains the
361 * necessary infrastructure for such triggers.
363 * This division is not just for performance: it's critical that the
364 * event trigger code not be invoked when doing START TRANSACTION for
365 * example, because we might need to refresh the event trigger cache,
366 * which requires being in a valid transaction.
369 standard_ProcessUtility(Node *parsetree,
370 const char *queryString,
371 ProcessUtilityContext context,
372 ParamListInfo params,
376 bool isTopLevel = (context == PROCESS_UTILITY_TOPLEVEL);
378 check_xact_readonly(parsetree);
381 completionTag[0] = '\0';
383 switch (nodeTag(parsetree))
386 * ******************** transactions ********************
388 case T_TransactionStmt:
390 TransactionStmt *stmt = (TransactionStmt *) parsetree;
395 * START TRANSACTION, as defined by SQL99: Identical
396 * to BEGIN. Same code for both.
398 case TRANS_STMT_BEGIN:
399 case TRANS_STMT_START:
403 BeginTransactionBlock();
404 foreach(lc, stmt->options)
406 DefElem *item = (DefElem *) lfirst(lc);
408 if (strcmp(item->defname, "transaction_isolation") == 0)
409 SetPGVariable("transaction_isolation",
410 list_make1(item->arg),
412 else if (strcmp(item->defname, "transaction_read_only") == 0)
413 SetPGVariable("transaction_read_only",
414 list_make1(item->arg),
416 else if (strcmp(item->defname, "transaction_deferrable") == 0)
417 SetPGVariable("transaction_deferrable",
418 list_make1(item->arg),
424 case TRANS_STMT_COMMIT:
425 if (!EndTransactionBlock())
427 /* report unsuccessful commit in completionTag */
429 strcpy(completionTag, "ROLLBACK");
433 case TRANS_STMT_PREPARE:
434 PreventCommandDuringRecovery("PREPARE TRANSACTION");
435 if (!PrepareTransactionBlock(stmt->gid))
437 /* report unsuccessful commit in completionTag */
439 strcpy(completionTag, "ROLLBACK");
443 case TRANS_STMT_COMMIT_PREPARED:
444 PreventTransactionChain(isTopLevel, "COMMIT PREPARED");
445 PreventCommandDuringRecovery("COMMIT PREPARED");
446 FinishPreparedTransaction(stmt->gid, true);
449 case TRANS_STMT_ROLLBACK_PREPARED:
450 PreventTransactionChain(isTopLevel, "ROLLBACK PREPARED");
451 PreventCommandDuringRecovery("ROLLBACK PREPARED");
452 FinishPreparedTransaction(stmt->gid, false);
455 case TRANS_STMT_ROLLBACK:
456 UserAbortTransactionBlock();
459 case TRANS_STMT_SAVEPOINT:
464 RequireTransactionChain(isTopLevel, "SAVEPOINT");
466 foreach(cell, stmt->options)
468 DefElem *elem = lfirst(cell);
470 if (strcmp(elem->defname, "savepoint_name") == 0)
471 name = strVal(elem->arg);
474 Assert(PointerIsValid(name));
476 DefineSavepoint(name);
480 case TRANS_STMT_RELEASE:
481 RequireTransactionChain(isTopLevel, "RELEASE SAVEPOINT");
482 ReleaseSavepoint(stmt->options);
485 case TRANS_STMT_ROLLBACK_TO:
486 RequireTransactionChain(isTopLevel, "ROLLBACK TO SAVEPOINT");
487 RollbackToSavepoint(stmt->options);
490 * CommitTransactionCommand is in charge of
491 * re-defining the savepoint again
499 * Portal (cursor) manipulation
501 * Note: DECLARE CURSOR is processed mostly as a SELECT, and
502 * therefore what we will get here is a PlannedStmt not a bare
507 PlannedStmt *stmt = (PlannedStmt *) parsetree;
509 if (stmt->utilityStmt == NULL ||
510 !IsA(stmt->utilityStmt, DeclareCursorStmt))
511 elog(ERROR, "non-DECLARE CURSOR PlannedStmt passed to ProcessUtility");
512 PerformCursorOpen(stmt, params, queryString, isTopLevel);
516 case T_ClosePortalStmt:
518 ClosePortalStmt *stmt = (ClosePortalStmt *) parsetree;
520 CheckRestrictedOperation("CLOSE");
521 PerformPortalClose(stmt->portalname);
526 PerformPortalFetch((FetchStmt *) parsetree, dest,
531 ExecuteDoStmt((DoStmt *) parsetree);
534 case T_CreateTableSpaceStmt:
535 /* no event triggers for global objects */
536 PreventTransactionChain(isTopLevel, "CREATE TABLESPACE");
537 CreateTableSpace((CreateTableSpaceStmt *) parsetree);
540 case T_DropTableSpaceStmt:
541 /* no event triggers for global objects */
542 PreventTransactionChain(isTopLevel, "DROP TABLESPACE");
543 DropTableSpace((DropTableSpaceStmt *) parsetree);
546 case T_AlterTableSpaceOptionsStmt:
547 /* no event triggers for global objects */
548 AlterTableSpaceOptions((AlterTableSpaceOptionsStmt *) parsetree);
552 ExecuteTruncate((TruncateStmt *) parsetree);
556 CommentObject((CommentStmt *) parsetree);
560 ExecSecLabelStmt((SecLabelStmt *) parsetree);
567 DoCopy((CopyStmt *) parsetree, queryString, &processed);
569 snprintf(completionTag, COMPLETION_TAG_BUFSIZE,
570 "COPY " UINT64_FORMAT, processed);
575 CheckRestrictedOperation("PREPARE");
576 PrepareQuery((PrepareStmt *) parsetree, queryString);
580 ExecuteQuery((ExecuteStmt *) parsetree, NULL,
582 dest, completionTag);
585 case T_DeallocateStmt:
586 CheckRestrictedOperation("DEALLOCATE");
587 DeallocateQuery((DeallocateStmt *) parsetree);
591 /* no event triggers for global objects */
592 ExecuteGrantStmt((GrantStmt *) parsetree);
595 case T_GrantRoleStmt:
596 /* no event triggers for global objects */
597 GrantRole((GrantRoleStmt *) parsetree);
601 /* no event triggers for global objects */
602 PreventTransactionChain(isTopLevel, "CREATE DATABASE");
603 createdb((CreatedbStmt *) parsetree);
606 case T_AlterDatabaseStmt:
607 /* no event triggers for global objects */
608 AlterDatabase((AlterDatabaseStmt *) parsetree, isTopLevel);
611 case T_AlterDatabaseSetStmt:
612 /* no event triggers for global objects */
613 AlterDatabaseSet((AlterDatabaseSetStmt *) parsetree);
618 DropdbStmt *stmt = (DropdbStmt *) parsetree;
620 /* no event triggers for global objects */
621 PreventTransactionChain(isTopLevel, "DROP DATABASE");
622 dropdb(stmt->dbname, stmt->missing_ok);
626 /* Query-level asynchronous notification */
629 NotifyStmt *stmt = (NotifyStmt *) parsetree;
631 PreventCommandDuringRecovery("NOTIFY");
632 Async_Notify(stmt->conditionname, stmt->payload);
638 ListenStmt *stmt = (ListenStmt *) parsetree;
640 PreventCommandDuringRecovery("LISTEN");
641 CheckRestrictedOperation("LISTEN");
642 Async_Listen(stmt->conditionname);
648 UnlistenStmt *stmt = (UnlistenStmt *) parsetree;
650 PreventCommandDuringRecovery("UNLISTEN");
651 CheckRestrictedOperation("UNLISTEN");
652 if (stmt->conditionname)
653 Async_Unlisten(stmt->conditionname);
661 LoadStmt *stmt = (LoadStmt *) parsetree;
663 closeAllVfds(); /* probably not necessary... */
664 /* Allowed names are restricted if you're not superuser */
665 load_file(stmt->filename, !superuser());
670 /* we choose to allow this during "read only" transactions */
671 PreventCommandDuringRecovery("CLUSTER");
672 cluster((ClusterStmt *) parsetree, isTopLevel);
677 VacuumStmt *stmt = (VacuumStmt *) parsetree;
679 /* we choose to allow this during "read only" transactions */
680 PreventCommandDuringRecovery((stmt->options & VACOPT_VACUUM) ?
681 "VACUUM" : "ANALYZE");
682 vacuum(stmt, InvalidOid, true, NULL, false, isTopLevel);
687 ExplainQuery((ExplainStmt *) parsetree, queryString, params, dest);
690 case T_VariableSetStmt:
691 ExecSetVariableStmt((VariableSetStmt *) parsetree, isTopLevel);
694 case T_VariableShowStmt:
696 VariableShowStmt *n = (VariableShowStmt *) parsetree;
698 GetPGVariable(n->name, dest);
703 /* should we allow DISCARD PLANS? */
704 CheckRestrictedOperation("DISCARD");
705 DiscardCommand((DiscardStmt *) parsetree, isTopLevel);
708 case T_CreateEventTrigStmt:
709 /* no event triggers on event triggers */
710 CreateEventTrigger((CreateEventTrigStmt *) parsetree);
713 case T_AlterEventTrigStmt:
714 /* no event triggers on event triggers */
715 AlterEventTrigger((AlterEventTrigStmt *) parsetree);
719 * ******************************** ROLE statements ****
721 case T_CreateRoleStmt:
722 /* no event triggers for global objects */
723 CreateRole((CreateRoleStmt *) parsetree);
726 case T_AlterRoleStmt:
727 /* no event triggers for global objects */
728 AlterRole((AlterRoleStmt *) parsetree);
731 case T_AlterRoleSetStmt:
732 /* no event triggers for global objects */
733 AlterRoleSet((AlterRoleSetStmt *) parsetree);
737 /* no event triggers for global objects */
738 DropRole((DropRoleStmt *) parsetree);
741 case T_ReassignOwnedStmt:
742 /* no event triggers for global objects */
743 ReassignOwnedObjects((ReassignOwnedStmt *) parsetree);
749 * Since the lock would just get dropped immediately, LOCK TABLE
750 * outside a transaction block is presumed to be user error.
752 RequireTransactionChain(isTopLevel, "LOCK TABLE");
753 LockTableCommand((LockStmt *) parsetree);
756 case T_ConstraintsSetStmt:
757 WarnNoTransactionChain(isTopLevel, "SET CONSTRAINTS");
758 AfterTriggerSetState((ConstraintsSetStmt *) parsetree);
761 case T_CheckPointStmt:
764 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
765 errmsg("must be superuser to do CHECKPOINT")));
768 * You might think we should have a PreventCommandDuringRecovery()
769 * here, but we interpret a CHECKPOINT command during recovery as
770 * a request for a restartpoint instead. We allow this since it
771 * can be a useful way of reducing switchover time when using
772 * various forms of replication.
774 RequestCheckpoint(CHECKPOINT_IMMEDIATE | CHECKPOINT_WAIT |
775 (RecoveryInProgress() ? 0 : CHECKPOINT_FORCE));
780 ReindexStmt *stmt = (ReindexStmt *) parsetree;
782 /* we choose to allow this during "read only" transactions */
783 PreventCommandDuringRecovery("REINDEX");
787 ReindexIndex(stmt->relation);
791 ReindexTable(stmt->relation);
793 case OBJECT_DATABASE:
796 * This cannot run inside a user transaction block; if
797 * we were inside a transaction, then its commit- and
798 * start-transaction-command calls would not have the
801 PreventTransactionChain(isTopLevel,
803 ReindexDatabase(stmt->name,
804 stmt->do_system, stmt->do_user);
807 elog(ERROR, "unrecognized object type: %d",
815 * The following statements are supported by Event Triggers only
816 * in some cases, so we "fast path" them in the other cases.
821 DropStmt *stmt = (DropStmt *) parsetree;
823 if (EventTriggerSupportsObjectType(stmt->removeType))
824 ProcessUtilitySlow(parsetree, queryString,
826 dest, completionTag);
828 ExecDropStmt(stmt, isTopLevel);
834 RenameStmt *stmt = (RenameStmt *) parsetree;
836 if (EventTriggerSupportsObjectType(stmt->renameType))
837 ProcessUtilitySlow(parsetree, queryString,
839 dest, completionTag);
841 ExecRenameStmt(stmt);
845 case T_AlterObjectSchemaStmt:
847 AlterObjectSchemaStmt *stmt = (AlterObjectSchemaStmt *) parsetree;
849 if (EventTriggerSupportsObjectType(stmt->objectType))
850 ProcessUtilitySlow(parsetree, queryString,
852 dest, completionTag);
854 ExecAlterObjectSchemaStmt(stmt);
858 case T_AlterOwnerStmt:
860 AlterOwnerStmt *stmt = (AlterOwnerStmt *) parsetree;
862 if (EventTriggerSupportsObjectType(stmt->objectType))
863 ProcessUtilitySlow(parsetree, queryString,
865 dest, completionTag);
867 ExecAlterOwnerStmt(stmt);
872 /* All other statement types have event trigger support */
873 ProcessUtilitySlow(parsetree, queryString,
875 dest, completionTag);
881 * The "Slow" variant of ProcessUtility should only receive statements
882 * supported by the event triggers facility. Therefore, we always
883 * perform the trigger support calls if the context allows it.
886 ProcessUtilitySlow(Node *parsetree,
887 const char *queryString,
888 ProcessUtilityContext context,
889 ParamListInfo params,
893 bool isTopLevel = (context == PROCESS_UTILITY_TOPLEVEL);
894 bool isCompleteQuery = (context <= PROCESS_UTILITY_QUERY);
897 /* All event trigger calls are done only when isCompleteQuery is true */
898 needCleanup = isCompleteQuery && EventTriggerBeginCompleteQuery();
900 /* PG_TRY block is to ensure we call EventTriggerEndCompleteQuery */
904 EventTriggerDDLCommandStart(parsetree);
906 switch (nodeTag(parsetree))
909 * relation and attribute manipulation
911 case T_CreateSchemaStmt:
912 CreateSchemaCommand((CreateSchemaStmt *) parsetree,
917 case T_CreateForeignTableStmt:
923 /* Run parse analysis ... */
924 stmts = transformCreateStmt((CreateStmt *) parsetree,
930 Node *stmt = (Node *) lfirst(l);
932 if (IsA(stmt, CreateStmt))
935 static char *validnsps[] = HEAP_RELOPT_NAMESPACES;
937 /* Create the table itself */
938 relOid = DefineRelation((CreateStmt *) stmt,
943 * Let AlterTableCreateToastTable decide if this
944 * one needs a secondary relation too.
946 CommandCounterIncrement();
949 * parse and validate reloptions for the toast
952 toast_options = transformRelOptions((Datum) 0,
953 ((CreateStmt *) stmt)->options,
958 (void) heap_reloptions(RELKIND_TOASTVALUE,
962 AlterTableCreateToastTable(relOid, toast_options);
964 else if (IsA(stmt, CreateForeignTableStmt))
966 /* Create the table itself */
967 relOid = DefineRelation((CreateStmt *) stmt,
968 RELKIND_FOREIGN_TABLE,
970 CreateForeignTable((CreateForeignTableStmt *) stmt,
975 /* Recurse for anything else */
978 PROCESS_UTILITY_SUBCOMMAND,
984 /* Need CCI between commands */
985 if (lnext(l) != NULL)
986 CommandCounterIncrement();
991 case T_AlterTableStmt:
993 AlterTableStmt *atstmt = (AlterTableStmt *) parsetree;
1000 * Figure out lock mode, and acquire lock. This also does
1001 * basic permissions checks, so that we won't wait for a
1002 * lock on (for example) a relation on which we have no
1005 lockmode = AlterTableGetLockLevel(atstmt->cmds);
1006 relid = AlterTableLookupRelation(atstmt, lockmode);
1008 if (OidIsValid(relid))
1010 /* Run parse analysis ... */
1011 stmts = transformAlterTableStmt(atstmt, queryString);
1016 Node *stmt = (Node *) lfirst(l);
1018 if (IsA(stmt, AlterTableStmt))
1020 /* Do the table alteration proper */
1021 AlterTable(relid, lockmode,
1022 (AlterTableStmt *) stmt);
1026 /* Recurse for anything else */
1027 ProcessUtility(stmt,
1029 PROCESS_UTILITY_SUBCOMMAND,
1035 /* Need CCI between commands */
1036 if (lnext(l) != NULL)
1037 CommandCounterIncrement();
1042 (errmsg("relation \"%s\" does not exist, skipping",
1043 atstmt->relation->relname)));
1047 case T_AlterDomainStmt:
1049 AlterDomainStmt *stmt = (AlterDomainStmt *) parsetree;
1052 * Some or all of these functions are recursive to cover
1053 * inherited things, so permission checks are done there.
1055 switch (stmt->subtype)
1057 case 'T': /* ALTER DOMAIN DEFAULT */
1060 * Recursively alter column default for table and,
1061 * if requested, for descendants
1063 AlterDomainDefault(stmt->typeName,
1066 case 'N': /* ALTER DOMAIN DROP NOT NULL */
1067 AlterDomainNotNull(stmt->typeName,
1070 case 'O': /* ALTER DOMAIN SET NOT NULL */
1071 AlterDomainNotNull(stmt->typeName,
1074 case 'C': /* ADD CONSTRAINT */
1075 AlterDomainAddConstraint(stmt->typeName,
1078 case 'X': /* DROP CONSTRAINT */
1079 AlterDomainDropConstraint(stmt->typeName,
1084 case 'V': /* VALIDATE CONSTRAINT */
1085 AlterDomainValidateConstraint(stmt->typeName,
1089 elog(ERROR, "unrecognized alter domain type: %d",
1090 (int) stmt->subtype);
1097 * ************* object creation / destruction **************
1101 DefineStmt *stmt = (DefineStmt *) parsetree;
1105 case OBJECT_AGGREGATE:
1106 DefineAggregate(stmt->defnames, stmt->args,
1107 stmt->oldstyle, stmt->definition,
1110 case OBJECT_OPERATOR:
1111 Assert(stmt->args == NIL);
1112 DefineOperator(stmt->defnames, stmt->definition);
1115 Assert(stmt->args == NIL);
1116 DefineType(stmt->defnames, stmt->definition);
1118 case OBJECT_TSPARSER:
1119 Assert(stmt->args == NIL);
1120 DefineTSParser(stmt->defnames, stmt->definition);
1122 case OBJECT_TSDICTIONARY:
1123 Assert(stmt->args == NIL);
1124 DefineTSDictionary(stmt->defnames,
1127 case OBJECT_TSTEMPLATE:
1128 Assert(stmt->args == NIL);
1129 DefineTSTemplate(stmt->defnames,
1132 case OBJECT_TSCONFIGURATION:
1133 Assert(stmt->args == NIL);
1134 DefineTSConfiguration(stmt->defnames,
1137 case OBJECT_COLLATION:
1138 Assert(stmt->args == NIL);
1139 DefineCollation(stmt->defnames, stmt->definition);
1142 elog(ERROR, "unrecognized define stmt type: %d",
1149 case T_IndexStmt: /* CREATE INDEX */
1151 IndexStmt *stmt = (IndexStmt *) parsetree;
1153 if (stmt->concurrent)
1154 PreventTransactionChain(isTopLevel,
1155 "CREATE INDEX CONCURRENTLY");
1157 CheckRelationOwnership(stmt->relation, true);
1159 /* Run parse analysis ... */
1160 stmt = transformIndexStmt(stmt, queryString);
1164 InvalidOid, /* no predefined OID */
1165 false, /* is_alter_table */
1166 true, /* check_rights */
1167 false, /* skip_build */
1172 case T_CreateExtensionStmt:
1173 CreateExtension((CreateExtensionStmt *) parsetree);
1176 case T_AlterExtensionStmt:
1177 ExecAlterExtensionStmt((AlterExtensionStmt *) parsetree);
1180 case T_AlterExtensionContentsStmt:
1181 ExecAlterExtensionContentsStmt((AlterExtensionContentsStmt *) parsetree);
1184 case T_CreateFdwStmt:
1185 CreateForeignDataWrapper((CreateFdwStmt *) parsetree);
1188 case T_AlterFdwStmt:
1189 AlterForeignDataWrapper((AlterFdwStmt *) parsetree);
1192 case T_CreateForeignServerStmt:
1193 CreateForeignServer((CreateForeignServerStmt *) parsetree);
1196 case T_AlterForeignServerStmt:
1197 AlterForeignServer((AlterForeignServerStmt *) parsetree);
1200 case T_CreateUserMappingStmt:
1201 CreateUserMapping((CreateUserMappingStmt *) parsetree);
1204 case T_AlterUserMappingStmt:
1205 AlterUserMapping((AlterUserMappingStmt *) parsetree);
1208 case T_DropUserMappingStmt:
1209 RemoveUserMapping((DropUserMappingStmt *) parsetree);
1212 case T_CompositeTypeStmt: /* CREATE TYPE (composite) */
1214 CompositeTypeStmt *stmt = (CompositeTypeStmt *) parsetree;
1216 DefineCompositeType(stmt->typevar, stmt->coldeflist);
1220 case T_CreateEnumStmt: /* CREATE TYPE AS ENUM */
1221 DefineEnum((CreateEnumStmt *) parsetree);
1224 case T_CreateRangeStmt: /* CREATE TYPE AS RANGE */
1225 DefineRange((CreateRangeStmt *) parsetree);
1228 case T_AlterEnumStmt: /* ALTER TYPE (enum) */
1229 AlterEnum((AlterEnumStmt *) parsetree, isTopLevel);
1232 case T_ViewStmt: /* CREATE VIEW */
1233 DefineView((ViewStmt *) parsetree, queryString);
1236 case T_CreateFunctionStmt: /* CREATE FUNCTION */
1237 CreateFunction((CreateFunctionStmt *) parsetree, queryString);
1240 case T_AlterFunctionStmt: /* ALTER FUNCTION */
1241 AlterFunction((AlterFunctionStmt *) parsetree);
1244 case T_RuleStmt: /* CREATE RULE */
1245 DefineRule((RuleStmt *) parsetree, queryString);
1248 case T_CreateSeqStmt:
1249 DefineSequence((CreateSeqStmt *) parsetree);
1252 case T_AlterSeqStmt:
1253 AlterSequence((AlterSeqStmt *) parsetree);
1256 case T_CreateTableAsStmt:
1257 ExecCreateTableAs((CreateTableAsStmt *) parsetree,
1258 queryString, params, completionTag);
1261 case T_RefreshMatViewStmt:
1262 ExecRefreshMatView((RefreshMatViewStmt *) parsetree,
1263 queryString, params, completionTag);
1266 case T_CreateTrigStmt:
1267 (void) CreateTrigger((CreateTrigStmt *) parsetree, queryString,
1268 InvalidOid, InvalidOid, false);
1271 case T_CreatePLangStmt:
1272 CreateProceduralLanguage((CreatePLangStmt *) parsetree);
1275 case T_CreateDomainStmt:
1276 DefineDomain((CreateDomainStmt *) parsetree);
1279 case T_CreateConversionStmt:
1280 CreateConversionCommand((CreateConversionStmt *) parsetree);
1283 case T_CreateCastStmt:
1284 CreateCast((CreateCastStmt *) parsetree);
1287 case T_CreateOpClassStmt:
1288 DefineOpClass((CreateOpClassStmt *) parsetree);
1291 case T_CreateOpFamilyStmt:
1292 DefineOpFamily((CreateOpFamilyStmt *) parsetree);
1295 case T_AlterOpFamilyStmt:
1296 AlterOpFamily((AlterOpFamilyStmt *) parsetree);
1299 case T_AlterTSDictionaryStmt:
1300 AlterTSDictionary((AlterTSDictionaryStmt *) parsetree);
1303 case T_AlterTSConfigurationStmt:
1304 AlterTSConfiguration((AlterTSConfigurationStmt *) parsetree);
1308 ExecDropStmt((DropStmt *) parsetree, isTopLevel);
1312 ExecRenameStmt((RenameStmt *) parsetree);
1315 case T_AlterObjectSchemaStmt:
1316 ExecAlterObjectSchemaStmt((AlterObjectSchemaStmt *) parsetree);
1319 case T_AlterOwnerStmt:
1320 ExecAlterOwnerStmt((AlterOwnerStmt *) parsetree);
1323 case T_DropOwnedStmt:
1324 DropOwnedObjects((DropOwnedStmt *) parsetree);
1327 case T_AlterDefaultPrivilegesStmt:
1328 ExecAlterDefaultPrivilegesStmt((AlterDefaultPrivilegesStmt *) parsetree);
1332 elog(ERROR, "unrecognized node type: %d",
1333 (int) nodeTag(parsetree));
1337 if (isCompleteQuery)
1339 EventTriggerSQLDrop(parsetree);
1340 EventTriggerDDLCommandEnd(parsetree);
1346 EventTriggerEndCompleteQuery();
1352 EventTriggerEndCompleteQuery();
1356 * Dispatch function for DropStmt
1359 ExecDropStmt(DropStmt *stmt, bool isTopLevel)
1361 switch (stmt->removeType)
1364 if (stmt->concurrent)
1365 PreventTransactionChain(isTopLevel,
1366 "DROP INDEX CONCURRENTLY");
1370 case OBJECT_SEQUENCE:
1372 case OBJECT_MATVIEW:
1373 case OBJECT_FOREIGN_TABLE:
1374 RemoveRelations(stmt);
1377 RemoveObjects(stmt);
1384 * UtilityReturnsTuples
1385 * Return "true" if this utility statement will send output to the
1388 * Generally, there should be a case here for each case in ProcessUtility
1389 * where "dest" is passed on.
1392 UtilityReturnsTuples(Node *parsetree)
1394 switch (nodeTag(parsetree))
1398 FetchStmt *stmt = (FetchStmt *) parsetree;
1403 portal = GetPortalByName(stmt->portalname);
1404 if (!PortalIsValid(portal))
1405 return false; /* not our business to raise error */
1406 return portal->tupDesc ? true : false;
1411 ExecuteStmt *stmt = (ExecuteStmt *) parsetree;
1412 PreparedStatement *entry;
1414 entry = FetchPreparedStatement(stmt->name, false);
1416 return false; /* not our business to raise error */
1417 if (entry->plansource->resultDesc)
1425 case T_VariableShowStmt:
1434 * UtilityTupleDescriptor
1435 * Fetch the actual output tuple descriptor for a utility statement
1436 * for which UtilityReturnsTuples() previously returned "true".
1438 * The returned descriptor is created in (or copied into) the current memory
1442 UtilityTupleDescriptor(Node *parsetree)
1444 switch (nodeTag(parsetree))
1448 FetchStmt *stmt = (FetchStmt *) parsetree;
1453 portal = GetPortalByName(stmt->portalname);
1454 if (!PortalIsValid(portal))
1455 return NULL; /* not our business to raise error */
1456 return CreateTupleDescCopy(portal->tupDesc);
1461 ExecuteStmt *stmt = (ExecuteStmt *) parsetree;
1462 PreparedStatement *entry;
1464 entry = FetchPreparedStatement(stmt->name, false);
1466 return NULL; /* not our business to raise error */
1467 return FetchPreparedStatementResultDesc(entry);
1471 return ExplainResultDesc((ExplainStmt *) parsetree);
1473 case T_VariableShowStmt:
1475 VariableShowStmt *n = (VariableShowStmt *) parsetree;
1477 return GetPGVariableResultDesc(n->name);
1487 * QueryReturnsTuples
1488 * Return "true" if this Query will send output to the destination.
1492 QueryReturnsTuples(Query *parsetree)
1494 switch (parsetree->commandType)
1497 /* returns tuples ... unless it's DECLARE CURSOR */
1498 if (parsetree->utilityStmt == NULL)
1504 /* the forms with RETURNING return tuples */
1505 if (parsetree->returningList)
1509 return UtilityReturnsTuples(parsetree->utilityStmt);
1512 /* probably shouldn't get here */
1515 return false; /* default */
1521 * UtilityContainsQuery
1522 * Return the contained Query, or NULL if there is none
1524 * Certain utility statements, such as EXPLAIN, contain a plannable Query.
1525 * This function encapsulates knowledge of exactly which ones do.
1526 * We assume it is invoked only on already-parse-analyzed statements
1527 * (else the contained parsetree isn't a Query yet).
1529 * In some cases (currently, only EXPLAIN of CREATE TABLE AS/SELECT INTO and
1530 * CREATE MATERIALIZED VIEW), potentially Query-containing utility statements
1531 * can be nested. This function will drill down to a non-utility Query, or
1532 * return NULL if none.
1535 UtilityContainsQuery(Node *parsetree)
1539 switch (nodeTag(parsetree))
1542 qry = (Query *) ((ExplainStmt *) parsetree)->query;
1543 Assert(IsA(qry, Query));
1544 if (qry->commandType == CMD_UTILITY)
1545 return UtilityContainsQuery(qry->utilityStmt);
1548 case T_CreateTableAsStmt:
1549 qry = (Query *) ((CreateTableAsStmt *) parsetree)->query;
1550 Assert(IsA(qry, Query));
1551 if (qry->commandType == CMD_UTILITY)
1552 return UtilityContainsQuery(qry->utilityStmt);
1562 * AlterObjectTypeCommandTag
1563 * helper function for CreateCommandTag
1565 * This covers most cases where ALTER is used with an ObjectType enum.
1568 AlterObjectTypeCommandTag(ObjectType objtype)
1574 case OBJECT_AGGREGATE:
1575 tag = "ALTER AGGREGATE";
1577 case OBJECT_ATTRIBUTE:
1583 case OBJECT_COLLATION:
1584 tag = "ALTER COLLATION";
1587 tag = "ALTER TABLE";
1589 case OBJECT_CONSTRAINT:
1590 tag = "ALTER TABLE";
1592 case OBJECT_CONVERSION:
1593 tag = "ALTER CONVERSION";
1595 case OBJECT_DATABASE:
1596 tag = "ALTER DATABASE";
1599 tag = "ALTER DOMAIN";
1601 case OBJECT_EXTENSION:
1602 tag = "ALTER EXTENSION";
1605 tag = "ALTER FOREIGN DATA WRAPPER";
1607 case OBJECT_FOREIGN_SERVER:
1608 tag = "ALTER SERVER";
1610 case OBJECT_FOREIGN_TABLE:
1611 tag = "ALTER FOREIGN TABLE";
1613 case OBJECT_FUNCTION:
1614 tag = "ALTER FUNCTION";
1617 tag = "ALTER INDEX";
1619 case OBJECT_LANGUAGE:
1620 tag = "ALTER LANGUAGE";
1622 case OBJECT_LARGEOBJECT:
1623 tag = "ALTER LARGE OBJECT";
1625 case OBJECT_OPCLASS:
1626 tag = "ALTER OPERATOR CLASS";
1628 case OBJECT_OPERATOR:
1629 tag = "ALTER OPERATOR";
1631 case OBJECT_OPFAMILY:
1632 tag = "ALTER OPERATOR FAMILY";
1641 tag = "ALTER SCHEMA";
1643 case OBJECT_SEQUENCE:
1644 tag = "ALTER SEQUENCE";
1647 tag = "ALTER TABLE";
1649 case OBJECT_TABLESPACE:
1650 tag = "ALTER TABLESPACE";
1652 case OBJECT_TRIGGER:
1653 tag = "ALTER TRIGGER";
1655 case OBJECT_EVENT_TRIGGER:
1656 tag = "ALTER EVENT TRIGGER";
1658 case OBJECT_TSCONFIGURATION:
1659 tag = "ALTER TEXT SEARCH CONFIGURATION";
1661 case OBJECT_TSDICTIONARY:
1662 tag = "ALTER TEXT SEARCH DICTIONARY";
1664 case OBJECT_TSPARSER:
1665 tag = "ALTER TEXT SEARCH PARSER";
1667 case OBJECT_TSTEMPLATE:
1668 tag = "ALTER TEXT SEARCH TEMPLATE";
1676 case OBJECT_MATVIEW:
1677 tag = "ALTER MATERIALIZED VIEW";
1689 * utility to get a string representation of the command operation,
1690 * given either a raw (un-analyzed) parsetree or a planned query.
1692 * This must handle all command types, but since the vast majority
1693 * of 'em are utility commands, it seems sensible to keep it here.
1695 * NB: all result strings must be shorter than COMPLETION_TAG_BUFSIZE.
1696 * Also, the result must point at a true constant (permanent storage).
1699 CreateCommandTag(Node *parsetree)
1703 switch (nodeTag(parsetree))
1705 /* raw plannable queries */
1722 /* utility statements --- same whether raw or cooked */
1723 case T_TransactionStmt:
1725 TransactionStmt *stmt = (TransactionStmt *) parsetree;
1729 case TRANS_STMT_BEGIN:
1733 case TRANS_STMT_START:
1734 tag = "START TRANSACTION";
1737 case TRANS_STMT_COMMIT:
1741 case TRANS_STMT_ROLLBACK:
1742 case TRANS_STMT_ROLLBACK_TO:
1746 case TRANS_STMT_SAVEPOINT:
1750 case TRANS_STMT_RELEASE:
1754 case TRANS_STMT_PREPARE:
1755 tag = "PREPARE TRANSACTION";
1758 case TRANS_STMT_COMMIT_PREPARED:
1759 tag = "COMMIT PREPARED";
1762 case TRANS_STMT_ROLLBACK_PREPARED:
1763 tag = "ROLLBACK PREPARED";
1773 case T_DeclareCursorStmt:
1774 tag = "DECLARE CURSOR";
1777 case T_ClosePortalStmt:
1779 ClosePortalStmt *stmt = (ClosePortalStmt *) parsetree;
1781 if (stmt->portalname == NULL)
1782 tag = "CLOSE CURSOR ALL";
1784 tag = "CLOSE CURSOR";
1790 FetchStmt *stmt = (FetchStmt *) parsetree;
1792 tag = (stmt->ismove) ? "MOVE" : "FETCH";
1796 case T_CreateDomainStmt:
1797 tag = "CREATE DOMAIN";
1800 case T_CreateSchemaStmt:
1801 tag = "CREATE SCHEMA";
1805 tag = "CREATE TABLE";
1808 case T_CreateTableSpaceStmt:
1809 tag = "CREATE TABLESPACE";
1812 case T_DropTableSpaceStmt:
1813 tag = "DROP TABLESPACE";
1816 case T_AlterTableSpaceOptionsStmt:
1817 tag = "ALTER TABLESPACE";
1820 case T_CreateExtensionStmt:
1821 tag = "CREATE EXTENSION";
1824 case T_AlterExtensionStmt:
1825 tag = "ALTER EXTENSION";
1828 case T_AlterExtensionContentsStmt:
1829 tag = "ALTER EXTENSION";
1832 case T_CreateFdwStmt:
1833 tag = "CREATE FOREIGN DATA WRAPPER";
1836 case T_AlterFdwStmt:
1837 tag = "ALTER FOREIGN DATA WRAPPER";
1840 case T_CreateForeignServerStmt:
1841 tag = "CREATE SERVER";
1844 case T_AlterForeignServerStmt:
1845 tag = "ALTER SERVER";
1848 case T_CreateUserMappingStmt:
1849 tag = "CREATE USER MAPPING";
1852 case T_AlterUserMappingStmt:
1853 tag = "ALTER USER MAPPING";
1856 case T_DropUserMappingStmt:
1857 tag = "DROP USER MAPPING";
1860 case T_CreateForeignTableStmt:
1861 tag = "CREATE FOREIGN TABLE";
1865 switch (((DropStmt *) parsetree)->removeType)
1870 case OBJECT_SEQUENCE:
1871 tag = "DROP SEQUENCE";
1876 case OBJECT_MATVIEW:
1877 tag = "DROP MATERIALIZED VIEW";
1886 tag = "DROP DOMAIN";
1888 case OBJECT_COLLATION:
1889 tag = "DROP COLLATION";
1891 case OBJECT_CONVERSION:
1892 tag = "DROP CONVERSION";
1895 tag = "DROP SCHEMA";
1897 case OBJECT_TSPARSER:
1898 tag = "DROP TEXT SEARCH PARSER";
1900 case OBJECT_TSDICTIONARY:
1901 tag = "DROP TEXT SEARCH DICTIONARY";
1903 case OBJECT_TSTEMPLATE:
1904 tag = "DROP TEXT SEARCH TEMPLATE";
1906 case OBJECT_TSCONFIGURATION:
1907 tag = "DROP TEXT SEARCH CONFIGURATION";
1909 case OBJECT_FOREIGN_TABLE:
1910 tag = "DROP FOREIGN TABLE";
1912 case OBJECT_EXTENSION:
1913 tag = "DROP EXTENSION";
1915 case OBJECT_FUNCTION:
1916 tag = "DROP FUNCTION";
1918 case OBJECT_AGGREGATE:
1919 tag = "DROP AGGREGATE";
1921 case OBJECT_OPERATOR:
1922 tag = "DROP OPERATOR";
1924 case OBJECT_LANGUAGE:
1925 tag = "DROP LANGUAGE";
1930 case OBJECT_TRIGGER:
1931 tag = "DROP TRIGGER";
1933 case OBJECT_EVENT_TRIGGER:
1934 tag = "DROP EVENT TRIGGER";
1940 tag = "DROP FOREIGN DATA WRAPPER";
1942 case OBJECT_FOREIGN_SERVER:
1943 tag = "DROP SERVER";
1945 case OBJECT_OPCLASS:
1946 tag = "DROP OPERATOR CLASS";
1948 case OBJECT_OPFAMILY:
1949 tag = "DROP OPERATOR FAMILY";
1956 case T_TruncateStmt:
1957 tag = "TRUNCATE TABLE";
1964 case T_SecLabelStmt:
1965 tag = "SECURITY LABEL";
1973 tag = AlterObjectTypeCommandTag(((RenameStmt *) parsetree)->renameType);
1976 case T_AlterObjectSchemaStmt:
1977 tag = AlterObjectTypeCommandTag(((AlterObjectSchemaStmt *) parsetree)->objectType);
1980 case T_AlterOwnerStmt:
1981 tag = AlterObjectTypeCommandTag(((AlterOwnerStmt *) parsetree)->objectType);
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_VariableSetStmt:
2161 switch (((VariableSetStmt *) parsetree)->kind)
2164 case VAR_SET_CURRENT:
2165 case VAR_SET_DEFAULT:
2178 case T_VariableShowStmt:
2183 switch (((DiscardStmt *) parsetree)->target)
2186 tag = "DISCARD ALL";
2189 tag = "DISCARD PLANS";
2192 tag = "DISCARD TEMP";
2194 case DISCARD_SEQUENCES:
2195 tag = "DISCARD SEQUENCES";
2202 case T_CreateTrigStmt:
2203 tag = "CREATE TRIGGER";
2206 case T_CreateEventTrigStmt:
2207 tag = "CREATE EVENT TRIGGER";
2210 case T_AlterEventTrigStmt:
2211 tag = "ALTER EVENT TRIGGER";
2214 case T_CreatePLangStmt:
2215 tag = "CREATE LANGUAGE";
2218 case T_CreateRoleStmt:
2219 tag = "CREATE ROLE";
2222 case T_AlterRoleStmt:
2226 case T_AlterRoleSetStmt:
2230 case T_DropRoleStmt:
2234 case T_DropOwnedStmt:
2238 case T_ReassignOwnedStmt:
2239 tag = "REASSIGN OWNED";
2246 case T_ConstraintsSetStmt:
2247 tag = "SET CONSTRAINTS";
2250 case T_CheckPointStmt:
2258 case T_CreateConversionStmt:
2259 tag = "CREATE CONVERSION";
2262 case T_CreateCastStmt:
2263 tag = "CREATE CAST";
2266 case T_CreateOpClassStmt:
2267 tag = "CREATE OPERATOR CLASS";
2270 case T_CreateOpFamilyStmt:
2271 tag = "CREATE OPERATOR FAMILY";
2274 case T_AlterOpFamilyStmt:
2275 tag = "ALTER OPERATOR FAMILY";
2278 case T_AlterTSDictionaryStmt:
2279 tag = "ALTER TEXT SEARCH DICTIONARY";
2282 case T_AlterTSConfigurationStmt:
2283 tag = "ALTER TEXT SEARCH CONFIGURATION";
2294 case T_DeallocateStmt:
2296 DeallocateStmt *stmt = (DeallocateStmt *) parsetree;
2298 if (stmt->name == NULL)
2299 tag = "DEALLOCATE ALL";
2305 /* already-planned queries */
2308 PlannedStmt *stmt = (PlannedStmt *) parsetree;
2310 switch (stmt->commandType)
2315 * We take a little extra care here so that the result
2316 * will be useful for complaints about read-only
2319 if (stmt->utilityStmt != NULL)
2321 Assert(IsA(stmt->utilityStmt, DeclareCursorStmt));
2322 tag = "DECLARE CURSOR";
2324 else if (stmt->rowMarks != NIL)
2326 /* not 100% but probably close enough */
2327 switch (((PlanRowMark *) linitial(stmt->rowMarks))->markType)
2329 case ROW_MARK_EXCLUSIVE:
2330 tag = "SELECT FOR UPDATE";
2332 case ROW_MARK_NOKEYEXCLUSIVE:
2333 tag = "SELECT FOR NO KEY UPDATE";
2335 case ROW_MARK_SHARE:
2336 tag = "SELECT FOR SHARE";
2338 case ROW_MARK_KEYSHARE:
2339 tag = "SELECT FOR KEY SHARE";
2341 case ROW_MARK_REFERENCE:
2363 elog(WARNING, "unrecognized commandType: %d",
2364 (int) stmt->commandType);
2371 /* parsed-and-rewritten-but-not-planned queries */
2374 Query *stmt = (Query *) parsetree;
2376 switch (stmt->commandType)
2381 * We take a little extra care here so that the result
2382 * will be useful for complaints about read-only
2385 if (stmt->utilityStmt != NULL)
2387 Assert(IsA(stmt->utilityStmt, DeclareCursorStmt));
2388 tag = "DECLARE CURSOR";
2390 else if (stmt->rowMarks != NIL)
2392 /* not 100% but probably close enough */
2393 switch (((RowMarkClause *) linitial(stmt->rowMarks))->strength)
2395 case LCS_FORKEYSHARE:
2396 tag = "SELECT FOR KEY SHARE";
2399 tag = "SELECT FOR SHARE";
2401 case LCS_FORNOKEYUPDATE:
2402 tag = "SELECT FOR NO KEY UPDATE";
2405 tag = "SELECT FOR UPDATE";
2425 tag = CreateCommandTag(stmt->utilityStmt);
2428 elog(WARNING, "unrecognized commandType: %d",
2429 (int) stmt->commandType);
2437 elog(WARNING, "unrecognized node type: %d",
2438 (int) nodeTag(parsetree));
2448 * GetCommandLogLevel
2449 * utility to get the minimum log_statement level for a command,
2450 * given either a raw (un-analyzed) parsetree or a planned query.
2452 * This must handle all command types, but since the vast majority
2453 * of 'em are utility commands, it seems sensible to keep it here.
2456 GetCommandLogLevel(Node *parsetree)
2460 switch (nodeTag(parsetree))
2462 /* raw plannable queries */
2470 if (((SelectStmt *) parsetree)->intoClause)
2471 lev = LOGSTMT_DDL; /* SELECT INTO */
2476 /* utility statements --- same whether raw or cooked */
2477 case T_TransactionStmt:
2481 case T_DeclareCursorStmt:
2485 case T_ClosePortalStmt:
2493 case T_CreateSchemaStmt:
2498 case T_CreateForeignTableStmt:
2502 case T_CreateTableSpaceStmt:
2503 case T_DropTableSpaceStmt:
2504 case T_AlterTableSpaceOptionsStmt:
2508 case T_CreateExtensionStmt:
2509 case T_AlterExtensionStmt:
2510 case T_AlterExtensionContentsStmt:
2514 case T_CreateFdwStmt:
2515 case T_AlterFdwStmt:
2516 case T_CreateForeignServerStmt:
2517 case T_AlterForeignServerStmt:
2518 case T_CreateUserMappingStmt:
2519 case T_AlterUserMappingStmt:
2520 case T_DropUserMappingStmt:
2528 case T_TruncateStmt:
2536 case T_SecLabelStmt:
2541 if (((CopyStmt *) parsetree)->is_from)
2549 PrepareStmt *stmt = (PrepareStmt *) parsetree;
2551 /* Look through a PREPARE to the contained stmt */
2552 lev = GetCommandLogLevel(stmt->query);
2558 ExecuteStmt *stmt = (ExecuteStmt *) parsetree;
2559 PreparedStatement *ps;
2561 /* Look through an EXECUTE to the referenced stmt */
2562 ps = FetchPreparedStatement(stmt->name, false);
2564 lev = GetCommandLogLevel(ps->plansource->raw_parse_tree);
2570 case T_DeallocateStmt:
2578 case T_AlterObjectSchemaStmt:
2582 case T_AlterOwnerStmt:
2586 case T_AlterTableStmt:
2590 case T_AlterDomainStmt:
2598 case T_GrantRoleStmt:
2602 case T_AlterDefaultPrivilegesStmt:
2610 case T_CompositeTypeStmt:
2614 case T_CreateEnumStmt:
2618 case T_CreateRangeStmt:
2622 case T_AlterEnumStmt:
2630 case T_CreateFunctionStmt:
2634 case T_AlterFunctionStmt:
2646 case T_CreateSeqStmt:
2650 case T_AlterSeqStmt:
2658 case T_CreatedbStmt:
2662 case T_AlterDatabaseStmt:
2666 case T_AlterDatabaseSetStmt:
2682 case T_UnlistenStmt:
2700 ExplainStmt *stmt = (ExplainStmt *) parsetree;
2701 bool analyze = false;
2704 /* Look through an EXPLAIN ANALYZE to the contained stmt */
2705 foreach(lc, stmt->options)
2707 DefElem *opt = (DefElem *) lfirst(lc);
2709 if (strcmp(opt->defname, "analyze") == 0)
2710 analyze = defGetBoolean(opt);
2711 /* don't "break", as explain.c will use the last value */
2714 return GetCommandLogLevel(stmt->query);
2716 /* Plain EXPLAIN isn't so interesting */
2721 case T_CreateTableAsStmt:
2725 case T_RefreshMatViewStmt:
2729 case T_VariableSetStmt:
2733 case T_VariableShowStmt:
2741 case T_CreateTrigStmt:
2745 case T_CreateEventTrigStmt:
2749 case T_AlterEventTrigStmt:
2753 case T_CreatePLangStmt:
2757 case T_CreateDomainStmt:
2761 case T_CreateRoleStmt:
2765 case T_AlterRoleStmt:
2769 case T_AlterRoleSetStmt:
2773 case T_DropRoleStmt:
2777 case T_DropOwnedStmt:
2781 case T_ReassignOwnedStmt:
2789 case T_ConstraintsSetStmt:
2793 case T_CheckPointStmt:
2798 lev = LOGSTMT_ALL; /* should this be DDL? */
2801 case T_CreateConversionStmt:
2805 case T_CreateCastStmt:
2809 case T_CreateOpClassStmt:
2813 case T_CreateOpFamilyStmt:
2817 case T_AlterOpFamilyStmt:
2821 case T_AlterTSDictionaryStmt:
2825 case T_AlterTSConfigurationStmt:
2829 /* already-planned queries */
2832 PlannedStmt *stmt = (PlannedStmt *) parsetree;
2834 switch (stmt->commandType)
2847 elog(WARNING, "unrecognized commandType: %d",
2848 (int) stmt->commandType);
2855 /* parsed-and-rewritten-but-not-planned queries */
2858 Query *stmt = (Query *) parsetree;
2860 switch (stmt->commandType)
2873 lev = GetCommandLogLevel(stmt->utilityStmt);
2877 elog(WARNING, "unrecognized commandType: %d",
2878 (int) stmt->commandType);
2887 elog(WARNING, "unrecognized node type: %d",
2888 (int) nodeTag(parsetree));