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-2012, 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/reloptions.h"
20 #include "access/twophase.h"
21 #include "access/xact.h"
22 #include "catalog/catalog.h"
23 #include "catalog/namespace.h"
24 #include "catalog/toasting.h"
25 #include "commands/alter.h"
26 #include "commands/async.h"
27 #include "commands/cluster.h"
28 #include "commands/comment.h"
29 #include "commands/collationcmds.h"
30 #include "commands/conversioncmds.h"
31 #include "commands/copy.h"
32 #include "commands/createas.h"
33 #include "commands/dbcommands.h"
34 #include "commands/defrem.h"
35 #include "commands/discard.h"
36 #include "commands/event_trigger.h"
37 #include "commands/explain.h"
38 #include "commands/extension.h"
39 #include "commands/lockcmds.h"
40 #include "commands/portalcmds.h"
41 #include "commands/prepare.h"
42 #include "commands/proclang.h"
43 #include "commands/schemacmds.h"
44 #include "commands/seclabel.h"
45 #include "commands/sequence.h"
46 #include "commands/tablecmds.h"
47 #include "commands/tablespace.h"
48 #include "commands/trigger.h"
49 #include "commands/typecmds.h"
50 #include "commands/user.h"
51 #include "commands/vacuum.h"
52 #include "commands/view.h"
53 #include "miscadmin.h"
54 #include "parser/parse_utilcmd.h"
55 #include "postmaster/bgwriter.h"
56 #include "rewrite/rewriteDefine.h"
57 #include "rewrite/rewriteRemove.h"
58 #include "storage/fd.h"
59 #include "tcop/pquery.h"
60 #include "tcop/utility.h"
61 #include "utils/acl.h"
62 #include "utils/guc.h"
63 #include "utils/syscache.h"
66 /* Hook for plugins to get control in ProcessUtility() */
67 ProcessUtility_hook_type ProcessUtility_hook = NULL;
71 * Verify user has ownership of specified relation, else ereport.
73 * If noCatalogs is true then we also deny access to system catalogs,
74 * except when allowSystemTableMods is true.
77 CheckRelationOwnership(RangeVar *rel, bool noCatalogs)
83 * XXX: This is unsafe in the presence of concurrent DDL, since it is
84 * called before acquiring any lock on the target relation. However,
85 * locking the target relation (especially using something like
86 * AccessExclusiveLock) before verifying that the user has permissions is
87 * not appealing either.
89 relOid = RangeVarGetRelid(rel, NoLock, false);
91 tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relOid));
92 if (!HeapTupleIsValid(tuple)) /* should not happen */
93 elog(ERROR, "cache lookup failed for relation %u", relOid);
95 if (!pg_class_ownercheck(relOid, GetUserId()))
96 aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
101 if (!allowSystemTableMods &&
102 IsSystemClass((Form_pg_class) GETSTRUCT(tuple)))
104 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
105 errmsg("permission denied: \"%s\" is a system catalog",
109 ReleaseSysCache(tuple);
114 * CommandIsReadOnly: is an executable query read-only?
116 * This is a much stricter test than we apply for XactReadOnly mode;
117 * the query must be *in truth* read-only, because the caller wishes
118 * not to do CommandCounterIncrement for it.
120 * Note: currently no need to support Query nodes here
123 CommandIsReadOnly(Node *parsetree)
125 if (IsA(parsetree, PlannedStmt))
127 PlannedStmt *stmt = (PlannedStmt *) parsetree;
129 switch (stmt->commandType)
132 if (stmt->rowMarks != NIL)
133 return false; /* SELECT FOR UPDATE/SHARE */
134 else if (stmt->hasModifyingCTE)
135 return false; /* data-modifying CTE */
143 elog(WARNING, "unrecognized commandType: %d",
144 (int) stmt->commandType);
148 /* For now, treat all utility commands as read/write */
153 * check_xact_readonly: is a utility command read-only?
155 * Here we use the loose rules of XactReadOnly mode: no permanent effects
156 * on the database are allowed.
159 check_xact_readonly(Node *parsetree)
165 * Note: Commands that need to do more complicated checking are handled
166 * elsewhere, in particular COPY and plannable statements do their own
167 * checking. However they should all call PreventCommandIfReadOnly to
168 * actually throw the error.
171 switch (nodeTag(parsetree))
173 case T_AlterDatabaseStmt:
174 case T_AlterDatabaseSetStmt:
175 case T_AlterDomainStmt:
176 case T_AlterFunctionStmt:
177 case T_AlterRoleStmt:
178 case T_AlterRoleSetStmt:
179 case T_AlterObjectSchemaStmt:
180 case T_AlterOwnerStmt:
182 case T_AlterTableStmt:
186 case T_CreateCastStmt:
187 case T_CreateEventTrigStmt:
188 case T_AlterEventTrigStmt:
189 case T_CreateConversionStmt:
191 case T_CreateDomainStmt:
192 case T_CreateFunctionStmt:
193 case T_CreateRoleStmt:
195 case T_CreatePLangStmt:
196 case T_CreateOpClassStmt:
197 case T_CreateOpFamilyStmt:
198 case T_AlterOpFamilyStmt:
200 case T_CreateSchemaStmt:
201 case T_CreateSeqStmt:
203 case T_CreateTableAsStmt:
204 case T_CreateTableSpaceStmt:
205 case T_CreateTrigStmt:
206 case T_CompositeTypeStmt:
207 case T_CreateEnumStmt:
208 case T_CreateRangeStmt:
209 case T_AlterEnumStmt:
213 case T_DropTableSpaceStmt:
216 case T_GrantRoleStmt:
217 case T_AlterDefaultPrivilegesStmt:
219 case T_DropOwnedStmt:
220 case T_ReassignOwnedStmt:
221 case T_AlterTSDictionaryStmt:
222 case T_AlterTSConfigurationStmt:
223 case T_CreateExtensionStmt:
224 case T_AlterExtensionStmt:
225 case T_AlterExtensionContentsStmt:
226 case T_CreateFdwStmt:
228 case T_CreateForeignServerStmt:
229 case T_AlterForeignServerStmt:
230 case T_CreateUserMappingStmt:
231 case T_AlterUserMappingStmt:
232 case T_DropUserMappingStmt:
233 case T_AlterTableSpaceOptionsStmt:
234 case T_CreateForeignTableStmt:
236 PreventCommandIfReadOnly(CreateCommandTag(parsetree));
245 * PreventCommandIfReadOnly: throw error if XactReadOnly
247 * This is useful mainly to ensure consistency of the error message wording;
248 * most callers have checked XactReadOnly for themselves.
251 PreventCommandIfReadOnly(const char *cmdname)
255 (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
256 /* translator: %s is name of a SQL command, eg CREATE */
257 errmsg("cannot execute %s in a read-only transaction",
262 * PreventCommandDuringRecovery: throw error if RecoveryInProgress
264 * The majority of operations that are unsafe in a Hot Standby slave
265 * will be rejected by XactReadOnly tests. However there are a few
266 * commands that are allowed in "read-only" xacts but cannot be allowed
267 * in Hot Standby mode. Those commands should call this function.
270 PreventCommandDuringRecovery(const char *cmdname)
272 if (RecoveryInProgress())
274 (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
275 /* translator: %s is name of a SQL command, eg CREATE */
276 errmsg("cannot execute %s during recovery",
281 * CheckRestrictedOperation: throw error for hazardous command if we're
282 * inside a security restriction context.
284 * This is needed to protect session-local state for which there is not any
285 * better-defined protection mechanism, such as ownership.
288 CheckRestrictedOperation(const char *cmdname)
290 if (InSecurityRestrictedOperation())
292 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
293 /* translator: %s is name of a SQL command, eg PREPARE */
294 errmsg("cannot execute %s within security-restricted operation",
301 * general utility function invoker
303 * parsetree: the parse tree for the utility statement
304 * queryString: original source text of command
305 * params: parameters to use during execution
306 * isTopLevel: true if executing a "top level" (interactively issued) command
307 * dest: where to send results
308 * completionTag: points to a buffer of size COMPLETION_TAG_BUFSIZE
309 * in which to store a command completion status string.
311 * Notes: as of PG 8.4, caller MUST supply a queryString; it is not
312 * allowed anymore to pass NULL. (If you really don't have source text,
313 * you can pass a constant string, perhaps "(query not available)".)
315 * completionTag is only set nonempty if we want to return a nondefault status.
317 * completionTag may be NULL if caller doesn't want a status string.
320 ProcessUtility(Node *parsetree,
321 const char *queryString,
322 ParamListInfo params,
327 Assert(queryString != NULL); /* required as of 8.4 */
330 * We provide a function hook variable that lets loadable plugins get
331 * control when ProcessUtility is called. Such a plugin would normally
332 * call standard_ProcessUtility().
334 if (ProcessUtility_hook)
335 (*ProcessUtility_hook) (parsetree, queryString, params,
336 isTopLevel, dest, completionTag);
338 standard_ProcessUtility(parsetree, queryString, params,
339 isTopLevel, dest, completionTag);
343 standard_ProcessUtility(Node *parsetree,
344 const char *queryString,
345 ParamListInfo params,
350 check_xact_readonly(parsetree);
353 completionTag[0] = '\0';
355 switch (nodeTag(parsetree))
358 * ******************** transactions ********************
360 case T_TransactionStmt:
362 TransactionStmt *stmt = (TransactionStmt *) parsetree;
367 * START TRANSACTION, as defined by SQL99: Identical
368 * to BEGIN. Same code for both.
370 case TRANS_STMT_BEGIN:
371 case TRANS_STMT_START:
375 BeginTransactionBlock();
376 foreach(lc, stmt->options)
378 DefElem *item = (DefElem *) lfirst(lc);
380 if (strcmp(item->defname, "transaction_isolation") == 0)
381 SetPGVariable("transaction_isolation",
382 list_make1(item->arg),
384 else if (strcmp(item->defname, "transaction_read_only") == 0)
385 SetPGVariable("transaction_read_only",
386 list_make1(item->arg),
388 else if (strcmp(item->defname, "transaction_deferrable") == 0)
389 SetPGVariable("transaction_deferrable",
390 list_make1(item->arg),
396 case TRANS_STMT_COMMIT:
397 if (!EndTransactionBlock())
399 /* report unsuccessful commit in completionTag */
401 strcpy(completionTag, "ROLLBACK");
405 case TRANS_STMT_PREPARE:
406 PreventCommandDuringRecovery("PREPARE TRANSACTION");
407 if (!PrepareTransactionBlock(stmt->gid))
409 /* report unsuccessful commit in completionTag */
411 strcpy(completionTag, "ROLLBACK");
415 case TRANS_STMT_COMMIT_PREPARED:
416 PreventTransactionChain(isTopLevel, "COMMIT PREPARED");
417 PreventCommandDuringRecovery("COMMIT PREPARED");
418 FinishPreparedTransaction(stmt->gid, true);
421 case TRANS_STMT_ROLLBACK_PREPARED:
422 PreventTransactionChain(isTopLevel, "ROLLBACK PREPARED");
423 PreventCommandDuringRecovery("ROLLBACK PREPARED");
424 FinishPreparedTransaction(stmt->gid, false);
427 case TRANS_STMT_ROLLBACK:
428 UserAbortTransactionBlock();
431 case TRANS_STMT_SAVEPOINT:
436 RequireTransactionChain(isTopLevel, "SAVEPOINT");
438 foreach(cell, stmt->options)
440 DefElem *elem = lfirst(cell);
442 if (strcmp(elem->defname, "savepoint_name") == 0)
443 name = strVal(elem->arg);
446 Assert(PointerIsValid(name));
448 DefineSavepoint(name);
452 case TRANS_STMT_RELEASE:
453 RequireTransactionChain(isTopLevel, "RELEASE SAVEPOINT");
454 ReleaseSavepoint(stmt->options);
457 case TRANS_STMT_ROLLBACK_TO:
458 RequireTransactionChain(isTopLevel, "ROLLBACK TO SAVEPOINT");
459 RollbackToSavepoint(stmt->options);
462 * CommitTransactionCommand is in charge of
463 * re-defining the savepoint again
471 * Portal (cursor) manipulation
473 * Note: DECLARE CURSOR is processed mostly as a SELECT, and
474 * therefore what we will get here is a PlannedStmt not a bare
479 PlannedStmt *stmt = (PlannedStmt *) parsetree;
481 if (stmt->utilityStmt == NULL ||
482 !IsA(stmt->utilityStmt, DeclareCursorStmt))
483 elog(ERROR, "non-DECLARE CURSOR PlannedStmt passed to ProcessUtility");
484 PerformCursorOpen(stmt, params, queryString, isTopLevel);
488 case T_ClosePortalStmt:
490 ClosePortalStmt *stmt = (ClosePortalStmt *) parsetree;
492 CheckRestrictedOperation("CLOSE");
493 PerformPortalClose(stmt->portalname);
498 PerformPortalFetch((FetchStmt *) parsetree, dest,
503 * relation and attribute manipulation
505 case T_CreateSchemaStmt:
506 CreateSchemaCommand((CreateSchemaStmt *) parsetree,
511 case T_CreateForeignTableStmt:
517 /* Run parse analysis ... */
518 stmts = transformCreateStmt((CreateStmt *) parsetree,
524 Node *stmt = (Node *) lfirst(l);
526 if (IsA(stmt, CreateStmt))
529 static char *validnsps[] = HEAP_RELOPT_NAMESPACES;
531 /* Create the table itself */
532 relOid = DefineRelation((CreateStmt *) stmt,
537 * Let AlterTableCreateToastTable decide if this one
538 * needs a secondary relation too.
540 CommandCounterIncrement();
542 /* parse and validate reloptions for the toast table */
543 toast_options = transformRelOptions((Datum) 0,
544 ((CreateStmt *) stmt)->options,
548 (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options,
551 AlterTableCreateToastTable(relOid, toast_options);
553 else if (IsA(stmt, CreateForeignTableStmt))
555 /* Create the table itself */
556 relOid = DefineRelation((CreateStmt *) stmt,
557 RELKIND_FOREIGN_TABLE,
559 CreateForeignTable((CreateForeignTableStmt *) stmt,
564 /* Recurse for anything else */
573 /* Need CCI between commands */
574 if (lnext(l) != NULL)
575 CommandCounterIncrement();
580 case T_CreateTableSpaceStmt:
581 PreventTransactionChain(isTopLevel, "CREATE TABLESPACE");
582 CreateTableSpace((CreateTableSpaceStmt *) parsetree);
585 case T_DropTableSpaceStmt:
586 PreventTransactionChain(isTopLevel, "DROP TABLESPACE");
587 DropTableSpace((DropTableSpaceStmt *) parsetree);
590 case T_AlterTableSpaceOptionsStmt:
591 AlterTableSpaceOptions((AlterTableSpaceOptionsStmt *) parsetree);
594 case T_CreateExtensionStmt:
595 CreateExtension((CreateExtensionStmt *) parsetree);
598 case T_AlterExtensionStmt:
599 ExecAlterExtensionStmt((AlterExtensionStmt *) parsetree);
602 case T_AlterExtensionContentsStmt:
603 ExecAlterExtensionContentsStmt((AlterExtensionContentsStmt *) parsetree);
606 case T_CreateFdwStmt:
607 CreateForeignDataWrapper((CreateFdwStmt *) parsetree);
611 AlterForeignDataWrapper((AlterFdwStmt *) parsetree);
614 case T_CreateForeignServerStmt:
615 CreateForeignServer((CreateForeignServerStmt *) parsetree);
618 case T_AlterForeignServerStmt:
619 AlterForeignServer((AlterForeignServerStmt *) parsetree);
622 case T_CreateUserMappingStmt:
623 CreateUserMapping((CreateUserMappingStmt *) parsetree);
626 case T_AlterUserMappingStmt:
627 AlterUserMapping((AlterUserMappingStmt *) parsetree);
630 case T_DropUserMappingStmt:
631 RemoveUserMapping((DropUserMappingStmt *) parsetree);
635 switch (((DropStmt *) parsetree)->removeType)
638 if (((DropStmt *) parsetree)->concurrent)
639 PreventTransactionChain(isTopLevel,
640 "DROP INDEX CONCURRENTLY");
644 case OBJECT_SEQUENCE:
646 case OBJECT_FOREIGN_TABLE:
647 RemoveRelations((DropStmt *) parsetree);
650 RemoveObjects((DropStmt *) parsetree);
656 ExecuteTruncate((TruncateStmt *) parsetree);
660 CommentObject((CommentStmt *) parsetree);
664 ExecSecLabelStmt((SecLabelStmt *) parsetree);
671 processed = DoCopy((CopyStmt *) parsetree, queryString);
673 snprintf(completionTag, COMPLETION_TAG_BUFSIZE,
674 "COPY " UINT64_FORMAT, processed);
679 CheckRestrictedOperation("PREPARE");
680 PrepareQuery((PrepareStmt *) parsetree, queryString);
684 ExecuteQuery((ExecuteStmt *) parsetree, NULL,
686 dest, completionTag);
689 case T_DeallocateStmt:
690 CheckRestrictedOperation("DEALLOCATE");
691 DeallocateQuery((DeallocateStmt *) parsetree);
698 ExecRenameStmt((RenameStmt *) parsetree);
701 case T_AlterObjectSchemaStmt:
702 ExecAlterObjectSchemaStmt((AlterObjectSchemaStmt *) parsetree);
705 case T_AlterOwnerStmt:
706 ExecAlterOwnerStmt((AlterOwnerStmt *) parsetree);
709 case T_AlterTableStmt:
711 AlterTableStmt *atstmt = (AlterTableStmt *) parsetree;
718 * Figure out lock mode, and acquire lock. This also does
719 * basic permissions checks, so that we won't wait for a lock
720 * on (for example) a relation on which we have no
723 lockmode = AlterTableGetLockLevel(atstmt->cmds);
724 relid = AlterTableLookupRelation(atstmt, lockmode);
726 if (OidIsValid(relid))
728 /* Run parse analysis ... */
729 stmts = transformAlterTableStmt(atstmt, queryString);
734 Node *stmt = (Node *) lfirst(l);
736 if (IsA(stmt, AlterTableStmt))
738 /* Do the table alteration proper */
739 AlterTable(relid, lockmode, (AlterTableStmt *) stmt);
743 /* Recurse for anything else */
752 /* Need CCI between commands */
753 if (lnext(l) != NULL)
754 CommandCounterIncrement();
759 (errmsg("relation \"%s\" does not exist, skipping",
760 atstmt->relation->relname)));
764 case T_AlterDomainStmt:
766 AlterDomainStmt *stmt = (AlterDomainStmt *) parsetree;
769 * Some or all of these functions are recursive to cover
770 * inherited things, so permission checks are done there.
772 switch (stmt->subtype)
774 case 'T': /* ALTER DOMAIN DEFAULT */
777 * Recursively alter column default for table and, if
778 * requested, for descendants
780 AlterDomainDefault(stmt->typeName,
783 case 'N': /* ALTER DOMAIN DROP NOT NULL */
784 AlterDomainNotNull(stmt->typeName,
787 case 'O': /* ALTER DOMAIN SET NOT NULL */
788 AlterDomainNotNull(stmt->typeName,
791 case 'C': /* ADD CONSTRAINT */
792 AlterDomainAddConstraint(stmt->typeName,
795 case 'X': /* DROP CONSTRAINT */
796 AlterDomainDropConstraint(stmt->typeName,
801 case 'V': /* VALIDATE CONSTRAINT */
802 AlterDomainValidateConstraint(stmt->typeName,
806 elog(ERROR, "unrecognized alter domain type: %d",
807 (int) stmt->subtype);
814 ExecuteGrantStmt((GrantStmt *) parsetree);
817 case T_GrantRoleStmt:
818 GrantRole((GrantRoleStmt *) parsetree);
821 case T_AlterDefaultPrivilegesStmt:
822 ExecAlterDefaultPrivilegesStmt((AlterDefaultPrivilegesStmt *) parsetree);
826 * **************** object creation / destruction *****************
830 DefineStmt *stmt = (DefineStmt *) parsetree;
834 case OBJECT_AGGREGATE:
835 DefineAggregate(stmt->defnames, stmt->args,
836 stmt->oldstyle, stmt->definition);
838 case OBJECT_OPERATOR:
839 Assert(stmt->args == NIL);
840 DefineOperator(stmt->defnames, stmt->definition);
843 Assert(stmt->args == NIL);
844 DefineType(stmt->defnames, stmt->definition);
846 case OBJECT_TSPARSER:
847 Assert(stmt->args == NIL);
848 DefineTSParser(stmt->defnames, stmt->definition);
850 case OBJECT_TSDICTIONARY:
851 Assert(stmt->args == NIL);
852 DefineTSDictionary(stmt->defnames, stmt->definition);
854 case OBJECT_TSTEMPLATE:
855 Assert(stmt->args == NIL);
856 DefineTSTemplate(stmt->defnames, stmt->definition);
858 case OBJECT_TSCONFIGURATION:
859 Assert(stmt->args == NIL);
860 DefineTSConfiguration(stmt->defnames, stmt->definition);
862 case OBJECT_COLLATION:
863 Assert(stmt->args == NIL);
864 DefineCollation(stmt->defnames, stmt->definition);
867 elog(ERROR, "unrecognized define stmt type: %d",
874 case T_CompositeTypeStmt: /* CREATE TYPE (composite) */
876 CompositeTypeStmt *stmt = (CompositeTypeStmt *) parsetree;
878 DefineCompositeType(stmt->typevar, stmt->coldeflist);
882 case T_CreateEnumStmt: /* CREATE TYPE AS ENUM */
883 DefineEnum((CreateEnumStmt *) parsetree);
886 case T_CreateRangeStmt: /* CREATE TYPE AS RANGE */
887 DefineRange((CreateRangeStmt *) parsetree);
890 case T_AlterEnumStmt: /* ALTER TYPE (enum) */
893 * We disallow this in transaction blocks, because we can't cope
894 * with enum OID values getting into indexes and then having their
895 * defining pg_enum entries go away.
897 PreventTransactionChain(isTopLevel, "ALTER TYPE ... ADD");
898 AlterEnum((AlterEnumStmt *) parsetree);
901 case T_ViewStmt: /* CREATE VIEW */
902 DefineView((ViewStmt *) parsetree, queryString);
905 case T_CreateFunctionStmt: /* CREATE FUNCTION */
906 CreateFunction((CreateFunctionStmt *) parsetree, queryString);
909 case T_AlterFunctionStmt: /* ALTER FUNCTION */
910 AlterFunction((AlterFunctionStmt *) parsetree);
913 case T_IndexStmt: /* CREATE INDEX */
915 IndexStmt *stmt = (IndexStmt *) parsetree;
917 if (stmt->concurrent)
918 PreventTransactionChain(isTopLevel,
919 "CREATE INDEX CONCURRENTLY");
921 CheckRelationOwnership(stmt->relation, true);
923 /* Run parse analysis ... */
924 stmt = transformIndexStmt(stmt, queryString);
928 InvalidOid, /* no predefined OID */
929 false, /* is_alter_table */
930 true, /* check_rights */
931 false, /* skip_build */
936 case T_RuleStmt: /* CREATE RULE */
937 DefineRule((RuleStmt *) parsetree, queryString);
940 case T_CreateSeqStmt:
941 DefineSequence((CreateSeqStmt *) parsetree);
945 AlterSequence((AlterSeqStmt *) parsetree);
949 ExecuteDoStmt((DoStmt *) parsetree);
953 PreventTransactionChain(isTopLevel, "CREATE DATABASE");
954 createdb((CreatedbStmt *) parsetree);
957 case T_AlterDatabaseStmt:
958 AlterDatabase((AlterDatabaseStmt *) parsetree, isTopLevel);
961 case T_AlterDatabaseSetStmt:
962 AlterDatabaseSet((AlterDatabaseSetStmt *) parsetree);
967 DropdbStmt *stmt = (DropdbStmt *) parsetree;
969 PreventTransactionChain(isTopLevel, "DROP DATABASE");
970 dropdb(stmt->dbname, stmt->missing_ok);
974 /* Query-level asynchronous notification */
977 NotifyStmt *stmt = (NotifyStmt *) parsetree;
979 PreventCommandDuringRecovery("NOTIFY");
980 Async_Notify(stmt->conditionname, stmt->payload);
986 ListenStmt *stmt = (ListenStmt *) parsetree;
988 PreventCommandDuringRecovery("LISTEN");
989 CheckRestrictedOperation("LISTEN");
990 Async_Listen(stmt->conditionname);
996 UnlistenStmt *stmt = (UnlistenStmt *) parsetree;
998 PreventCommandDuringRecovery("UNLISTEN");
999 CheckRestrictedOperation("UNLISTEN");
1000 if (stmt->conditionname)
1001 Async_Unlisten(stmt->conditionname);
1003 Async_UnlistenAll();
1009 LoadStmt *stmt = (LoadStmt *) parsetree;
1011 closeAllVfds(); /* probably not necessary... */
1012 /* Allowed names are restricted if you're not superuser */
1013 load_file(stmt->filename, !superuser());
1018 /* we choose to allow this during "read only" transactions */
1019 PreventCommandDuringRecovery("CLUSTER");
1020 cluster((ClusterStmt *) parsetree, isTopLevel);
1024 /* we choose to allow this during "read only" transactions */
1025 PreventCommandDuringRecovery("VACUUM");
1026 vacuum((VacuumStmt *) parsetree, InvalidOid, true, NULL, false,
1031 ExplainQuery((ExplainStmt *) parsetree, queryString, params, dest);
1034 case T_CreateTableAsStmt:
1035 ExecCreateTableAs((CreateTableAsStmt *) parsetree,
1036 queryString, params, completionTag);
1039 case T_VariableSetStmt:
1040 ExecSetVariableStmt((VariableSetStmt *) parsetree);
1043 case T_VariableShowStmt:
1045 VariableShowStmt *n = (VariableShowStmt *) parsetree;
1047 GetPGVariable(n->name, dest);
1052 /* should we allow DISCARD PLANS? */
1053 CheckRestrictedOperation("DISCARD");
1054 DiscardCommand((DiscardStmt *) parsetree, isTopLevel);
1057 case T_CreateTrigStmt:
1058 (void) CreateTrigger((CreateTrigStmt *) parsetree, queryString,
1059 InvalidOid, InvalidOid, false);
1062 case T_CreateEventTrigStmt:
1063 CreateEventTrigger((CreateEventTrigStmt *) parsetree);
1066 case T_AlterEventTrigStmt:
1067 AlterEventTrigger((AlterEventTrigStmt *) parsetree);
1070 case T_CreatePLangStmt:
1071 CreateProceduralLanguage((CreatePLangStmt *) parsetree);
1075 * ******************************** DOMAIN statements ****
1077 case T_CreateDomainStmt:
1078 DefineDomain((CreateDomainStmt *) parsetree);
1082 * ******************************** ROLE statements ****
1084 case T_CreateRoleStmt:
1085 CreateRole((CreateRoleStmt *) parsetree);
1088 case T_AlterRoleStmt:
1089 AlterRole((AlterRoleStmt *) parsetree);
1092 case T_AlterRoleSetStmt:
1093 AlterRoleSet((AlterRoleSetStmt *) parsetree);
1096 case T_DropRoleStmt:
1097 DropRole((DropRoleStmt *) parsetree);
1100 case T_DropOwnedStmt:
1101 DropOwnedObjects((DropOwnedStmt *) parsetree);
1104 case T_ReassignOwnedStmt:
1105 ReassignOwnedObjects((ReassignOwnedStmt *) parsetree);
1111 * Since the lock would just get dropped immediately, LOCK TABLE
1112 * outside a transaction block is presumed to be user error.
1114 RequireTransactionChain(isTopLevel, "LOCK TABLE");
1115 LockTableCommand((LockStmt *) parsetree);
1118 case T_ConstraintsSetStmt:
1119 AfterTriggerSetState((ConstraintsSetStmt *) parsetree);
1122 case T_CheckPointStmt:
1125 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1126 errmsg("must be superuser to do CHECKPOINT")));
1129 * You might think we should have a PreventCommandDuringRecovery()
1130 * here, but we interpret a CHECKPOINT command during recovery as
1131 * a request for a restartpoint instead. We allow this since it
1132 * can be a useful way of reducing switchover time when using
1133 * various forms of replication.
1135 RequestCheckpoint(CHECKPOINT_IMMEDIATE | CHECKPOINT_WAIT |
1136 (RecoveryInProgress() ? 0 : CHECKPOINT_FORCE));
1141 ReindexStmt *stmt = (ReindexStmt *) parsetree;
1143 /* we choose to allow this during "read only" transactions */
1144 PreventCommandDuringRecovery("REINDEX");
1148 ReindexIndex(stmt->relation);
1151 ReindexTable(stmt->relation);
1153 case OBJECT_DATABASE:
1156 * This cannot run inside a user transaction block; if
1157 * we were inside a transaction, then its commit- and
1158 * start-transaction-command calls would not have the
1161 PreventTransactionChain(isTopLevel,
1162 "REINDEX DATABASE");
1163 ReindexDatabase(stmt->name,
1164 stmt->do_system, stmt->do_user);
1167 elog(ERROR, "unrecognized object type: %d",
1175 case T_CreateConversionStmt:
1176 CreateConversionCommand((CreateConversionStmt *) parsetree);
1179 case T_CreateCastStmt:
1180 CreateCast((CreateCastStmt *) parsetree);
1183 case T_CreateOpClassStmt:
1184 DefineOpClass((CreateOpClassStmt *) parsetree);
1187 case T_CreateOpFamilyStmt:
1188 DefineOpFamily((CreateOpFamilyStmt *) parsetree);
1191 case T_AlterOpFamilyStmt:
1192 AlterOpFamily((AlterOpFamilyStmt *) parsetree);
1195 case T_AlterTSDictionaryStmt:
1196 AlterTSDictionary((AlterTSDictionaryStmt *) parsetree);
1199 case T_AlterTSConfigurationStmt:
1200 AlterTSConfiguration((AlterTSConfigurationStmt *) parsetree);
1204 elog(ERROR, "unrecognized node type: %d",
1205 (int) nodeTag(parsetree));
1211 * UtilityReturnsTuples
1212 * Return "true" if this utility statement will send output to the
1215 * Generally, there should be a case here for each case in ProcessUtility
1216 * where "dest" is passed on.
1219 UtilityReturnsTuples(Node *parsetree)
1221 switch (nodeTag(parsetree))
1225 FetchStmt *stmt = (FetchStmt *) parsetree;
1230 portal = GetPortalByName(stmt->portalname);
1231 if (!PortalIsValid(portal))
1232 return false; /* not our business to raise error */
1233 return portal->tupDesc ? true : false;
1238 ExecuteStmt *stmt = (ExecuteStmt *) parsetree;
1239 PreparedStatement *entry;
1241 entry = FetchPreparedStatement(stmt->name, false);
1243 return false; /* not our business to raise error */
1244 if (entry->plansource->resultDesc)
1252 case T_VariableShowStmt:
1261 * UtilityTupleDescriptor
1262 * Fetch the actual output tuple descriptor for a utility statement
1263 * for which UtilityReturnsTuples() previously returned "true".
1265 * The returned descriptor is created in (or copied into) the current memory
1269 UtilityTupleDescriptor(Node *parsetree)
1271 switch (nodeTag(parsetree))
1275 FetchStmt *stmt = (FetchStmt *) parsetree;
1280 portal = GetPortalByName(stmt->portalname);
1281 if (!PortalIsValid(portal))
1282 return NULL; /* not our business to raise error */
1283 return CreateTupleDescCopy(portal->tupDesc);
1288 ExecuteStmt *stmt = (ExecuteStmt *) parsetree;
1289 PreparedStatement *entry;
1291 entry = FetchPreparedStatement(stmt->name, false);
1293 return NULL; /* not our business to raise error */
1294 return FetchPreparedStatementResultDesc(entry);
1298 return ExplainResultDesc((ExplainStmt *) parsetree);
1300 case T_VariableShowStmt:
1302 VariableShowStmt *n = (VariableShowStmt *) parsetree;
1304 return GetPGVariableResultDesc(n->name);
1314 * QueryReturnsTuples
1315 * Return "true" if this Query will send output to the destination.
1319 QueryReturnsTuples(Query *parsetree)
1321 switch (parsetree->commandType)
1324 /* returns tuples ... unless it's DECLARE CURSOR */
1325 if (parsetree->utilityStmt == NULL)
1331 /* the forms with RETURNING return tuples */
1332 if (parsetree->returningList)
1336 return UtilityReturnsTuples(parsetree->utilityStmt);
1339 /* probably shouldn't get here */
1342 return false; /* default */
1348 * UtilityContainsQuery
1349 * Return the contained Query, or NULL if there is none
1351 * Certain utility statements, such as EXPLAIN, contain a plannable Query.
1352 * This function encapsulates knowledge of exactly which ones do.
1353 * We assume it is invoked only on already-parse-analyzed statements
1354 * (else the contained parsetree isn't a Query yet).
1356 * In some cases (currently, only EXPLAIN of CREATE TABLE AS/SELECT INTO),
1357 * potentially Query-containing utility statements can be nested. This
1358 * function will drill down to a non-utility Query, or return NULL if none.
1361 UtilityContainsQuery(Node *parsetree)
1365 switch (nodeTag(parsetree))
1368 qry = (Query *) ((ExplainStmt *) parsetree)->query;
1369 Assert(IsA(qry, Query));
1370 if (qry->commandType == CMD_UTILITY)
1371 return UtilityContainsQuery(qry->utilityStmt);
1374 case T_CreateTableAsStmt:
1375 /* might or might not contain a Query ... */
1376 qry = (Query *) ((CreateTableAsStmt *) parsetree)->query;
1377 if (IsA(qry, Query))
1379 /* Recursion currently can't be necessary here */
1380 Assert(qry->commandType != CMD_UTILITY);
1383 Assert(IsA(qry, ExecuteStmt));
1393 * AlterObjectTypeCommandTag
1394 * helper function for CreateCommandTag
1396 * This covers most cases where ALTER is used with an ObjectType enum.
1399 AlterObjectTypeCommandTag(ObjectType objtype)
1405 case OBJECT_AGGREGATE:
1406 tag = "ALTER AGGREGATE";
1408 case OBJECT_ATTRIBUTE:
1414 case OBJECT_COLLATION:
1415 tag = "ALTER COLLATION";
1418 tag = "ALTER TABLE";
1420 case OBJECT_CONSTRAINT:
1421 tag = "ALTER TABLE";
1423 case OBJECT_CONVERSION:
1424 tag = "ALTER CONVERSION";
1426 case OBJECT_DATABASE:
1427 tag = "ALTER DATABASE";
1430 tag = "ALTER DOMAIN";
1432 case OBJECT_EXTENSION:
1433 tag = "ALTER EXTENSION";
1436 tag = "ALTER FOREIGN DATA WRAPPER";
1438 case OBJECT_FOREIGN_SERVER:
1439 tag = "ALTER SERVER";
1441 case OBJECT_FOREIGN_TABLE:
1442 tag = "ALTER FOREIGN TABLE";
1444 case OBJECT_FUNCTION:
1445 tag = "ALTER FUNCTION";
1448 tag = "ALTER INDEX";
1450 case OBJECT_LANGUAGE:
1451 tag = "ALTER LANGUAGE";
1453 case OBJECT_LARGEOBJECT:
1454 tag = "ALTER LARGE OBJECT";
1456 case OBJECT_OPCLASS:
1457 tag = "ALTER OPERATOR CLASS";
1459 case OBJECT_OPERATOR:
1460 tag = "ALTER OPERATOR";
1462 case OBJECT_OPFAMILY:
1463 tag = "ALTER OPERATOR FAMILY";
1472 tag = "ALTER SCHEMA";
1474 case OBJECT_SEQUENCE:
1475 tag = "ALTER SEQUENCE";
1478 tag = "ALTER TABLE";
1480 case OBJECT_TABLESPACE:
1481 tag = "ALTER TABLESPACE";
1483 case OBJECT_TRIGGER:
1484 tag = "ALTER TRIGGER";
1486 case OBJECT_EVENT_TRIGGER:
1487 tag = "ALTER EVENT TRIGGER";
1489 case OBJECT_TSCONFIGURATION:
1490 tag = "ALTER TEXT SEARCH CONFIGURATION";
1492 case OBJECT_TSDICTIONARY:
1493 tag = "ALTER TEXT SEARCH DICTIONARY";
1495 case OBJECT_TSPARSER:
1496 tag = "ALTER TEXT SEARCH PARSER";
1498 case OBJECT_TSTEMPLATE:
1499 tag = "ALTER TEXT SEARCH TEMPLATE";
1517 * utility to get a string representation of the command operation,
1518 * given either a raw (un-analyzed) parsetree or a planned query.
1520 * This must handle all command types, but since the vast majority
1521 * of 'em are utility commands, it seems sensible to keep it here.
1523 * NB: all result strings must be shorter than COMPLETION_TAG_BUFSIZE.
1524 * Also, the result must point at a true constant (permanent storage).
1527 CreateCommandTag(Node *parsetree)
1531 switch (nodeTag(parsetree))
1533 /* raw plannable queries */
1550 /* utility statements --- same whether raw or cooked */
1551 case T_TransactionStmt:
1553 TransactionStmt *stmt = (TransactionStmt *) parsetree;
1557 case TRANS_STMT_BEGIN:
1561 case TRANS_STMT_START:
1562 tag = "START TRANSACTION";
1565 case TRANS_STMT_COMMIT:
1569 case TRANS_STMT_ROLLBACK:
1570 case TRANS_STMT_ROLLBACK_TO:
1574 case TRANS_STMT_SAVEPOINT:
1578 case TRANS_STMT_RELEASE:
1582 case TRANS_STMT_PREPARE:
1583 tag = "PREPARE TRANSACTION";
1586 case TRANS_STMT_COMMIT_PREPARED:
1587 tag = "COMMIT PREPARED";
1590 case TRANS_STMT_ROLLBACK_PREPARED:
1591 tag = "ROLLBACK PREPARED";
1601 case T_DeclareCursorStmt:
1602 tag = "DECLARE CURSOR";
1605 case T_ClosePortalStmt:
1607 ClosePortalStmt *stmt = (ClosePortalStmt *) parsetree;
1609 if (stmt->portalname == NULL)
1610 tag = "CLOSE CURSOR ALL";
1612 tag = "CLOSE CURSOR";
1618 FetchStmt *stmt = (FetchStmt *) parsetree;
1620 tag = (stmt->ismove) ? "MOVE" : "FETCH";
1624 case T_CreateDomainStmt:
1625 tag = "CREATE DOMAIN";
1628 case T_CreateSchemaStmt:
1629 tag = "CREATE SCHEMA";
1633 tag = "CREATE TABLE";
1636 case T_CreateTableSpaceStmt:
1637 tag = "CREATE TABLESPACE";
1640 case T_DropTableSpaceStmt:
1641 tag = "DROP TABLESPACE";
1644 case T_AlterTableSpaceOptionsStmt:
1645 tag = "ALTER TABLESPACE";
1648 case T_CreateExtensionStmt:
1649 tag = "CREATE EXTENSION";
1652 case T_AlterExtensionStmt:
1653 tag = "ALTER EXTENSION";
1656 case T_AlterExtensionContentsStmt:
1657 tag = "ALTER EXTENSION";
1660 case T_CreateFdwStmt:
1661 tag = "CREATE FOREIGN DATA WRAPPER";
1664 case T_AlterFdwStmt:
1665 tag = "ALTER FOREIGN DATA WRAPPER";
1668 case T_CreateForeignServerStmt:
1669 tag = "CREATE SERVER";
1672 case T_AlterForeignServerStmt:
1673 tag = "ALTER SERVER";
1676 case T_CreateUserMappingStmt:
1677 tag = "CREATE USER MAPPING";
1680 case T_AlterUserMappingStmt:
1681 tag = "ALTER USER MAPPING";
1684 case T_DropUserMappingStmt:
1685 tag = "DROP USER MAPPING";
1688 case T_CreateForeignTableStmt:
1689 tag = "CREATE FOREIGN TABLE";
1693 switch (((DropStmt *) parsetree)->removeType)
1698 case OBJECT_SEQUENCE:
1699 tag = "DROP SEQUENCE";
1711 tag = "DROP DOMAIN";
1713 case OBJECT_COLLATION:
1714 tag = "DROP COLLATION";
1716 case OBJECT_CONVERSION:
1717 tag = "DROP CONVERSION";
1720 tag = "DROP SCHEMA";
1722 case OBJECT_TSPARSER:
1723 tag = "DROP TEXT SEARCH PARSER";
1725 case OBJECT_TSDICTIONARY:
1726 tag = "DROP TEXT SEARCH DICTIONARY";
1728 case OBJECT_TSTEMPLATE:
1729 tag = "DROP TEXT SEARCH TEMPLATE";
1731 case OBJECT_TSCONFIGURATION:
1732 tag = "DROP TEXT SEARCH CONFIGURATION";
1734 case OBJECT_FOREIGN_TABLE:
1735 tag = "DROP FOREIGN TABLE";
1737 case OBJECT_EXTENSION:
1738 tag = "DROP EXTENSION";
1740 case OBJECT_FUNCTION:
1741 tag = "DROP FUNCTION";
1743 case OBJECT_AGGREGATE:
1744 tag = "DROP AGGREGATE";
1746 case OBJECT_OPERATOR:
1747 tag = "DROP OPERATOR";
1749 case OBJECT_LANGUAGE:
1750 tag = "DROP LANGUAGE";
1755 case OBJECT_TRIGGER:
1756 tag = "DROP TRIGGER";
1758 case OBJECT_EVENT_TRIGGER:
1759 tag = "DROP EVENT TRIGGER";
1765 tag = "DROP FOREIGN DATA WRAPPER";
1767 case OBJECT_FOREIGN_SERVER:
1768 tag = "DROP SERVER";
1770 case OBJECT_OPCLASS:
1771 tag = "DROP OPERATOR CLASS";
1773 case OBJECT_OPFAMILY:
1774 tag = "DROP OPERATOR FAMILY";
1781 case T_TruncateStmt:
1782 tag = "TRUNCATE TABLE";
1789 case T_SecLabelStmt:
1790 tag = "SECURITY LABEL";
1798 tag = AlterObjectTypeCommandTag(((RenameStmt *) parsetree)->renameType);
1801 case T_AlterObjectSchemaStmt:
1802 tag = AlterObjectTypeCommandTag(((AlterObjectSchemaStmt *) parsetree)->objectType);
1805 case T_AlterOwnerStmt:
1806 tag = AlterObjectTypeCommandTag(((AlterOwnerStmt *) parsetree)->objectType);
1809 case T_AlterTableStmt:
1810 tag = AlterObjectTypeCommandTag(((AlterTableStmt *) parsetree)->relkind);
1813 case T_AlterDomainStmt:
1814 tag = "ALTER DOMAIN";
1817 case T_AlterFunctionStmt:
1818 tag = "ALTER FUNCTION";
1823 GrantStmt *stmt = (GrantStmt *) parsetree;
1825 tag = (stmt->is_grant) ? "GRANT" : "REVOKE";
1829 case T_GrantRoleStmt:
1831 GrantRoleStmt *stmt = (GrantRoleStmt *) parsetree;
1833 tag = (stmt->is_grant) ? "GRANT ROLE" : "REVOKE ROLE";
1837 case T_AlterDefaultPrivilegesStmt:
1838 tag = "ALTER DEFAULT PRIVILEGES";
1842 switch (((DefineStmt *) parsetree)->kind)
1844 case OBJECT_AGGREGATE:
1845 tag = "CREATE AGGREGATE";
1847 case OBJECT_OPERATOR:
1848 tag = "CREATE OPERATOR";
1851 tag = "CREATE TYPE";
1853 case OBJECT_TSPARSER:
1854 tag = "CREATE TEXT SEARCH PARSER";
1856 case OBJECT_TSDICTIONARY:
1857 tag = "CREATE TEXT SEARCH DICTIONARY";
1859 case OBJECT_TSTEMPLATE:
1860 tag = "CREATE TEXT SEARCH TEMPLATE";
1862 case OBJECT_TSCONFIGURATION:
1863 tag = "CREATE TEXT SEARCH CONFIGURATION";
1865 case OBJECT_COLLATION:
1866 tag = "CREATE COLLATION";
1873 case T_CompositeTypeStmt:
1874 tag = "CREATE TYPE";
1877 case T_CreateEnumStmt:
1878 tag = "CREATE TYPE";
1881 case T_CreateRangeStmt:
1882 tag = "CREATE TYPE";
1885 case T_AlterEnumStmt:
1890 tag = "CREATE VIEW";
1893 case T_CreateFunctionStmt:
1894 tag = "CREATE FUNCTION";
1898 tag = "CREATE INDEX";
1902 tag = "CREATE RULE";
1905 case T_CreateSeqStmt:
1906 tag = "CREATE SEQUENCE";
1909 case T_AlterSeqStmt:
1910 tag = "ALTER SEQUENCE";
1917 case T_CreatedbStmt:
1918 tag = "CREATE DATABASE";
1921 case T_AlterDatabaseStmt:
1922 tag = "ALTER DATABASE";
1925 case T_AlterDatabaseSetStmt:
1926 tag = "ALTER DATABASE";
1930 tag = "DROP DATABASE";
1941 case T_UnlistenStmt:
1954 if (((VacuumStmt *) parsetree)->options & VACOPT_VACUUM)
1964 case T_CreateTableAsStmt:
1965 if (((CreateTableAsStmt *) parsetree)->is_select_into)
1966 tag = "SELECT INTO";
1968 tag = "CREATE TABLE AS";
1971 case T_VariableSetStmt:
1972 switch (((VariableSetStmt *) parsetree)->kind)
1975 case VAR_SET_CURRENT:
1976 case VAR_SET_DEFAULT:
1989 case T_VariableShowStmt:
1994 switch (((DiscardStmt *) parsetree)->target)
1997 tag = "DISCARD ALL";
2000 tag = "DISCARD PLANS";
2003 tag = "DISCARD TEMP";
2010 case T_CreateTrigStmt:
2011 tag = "CREATE TRIGGER";
2014 case T_CreateEventTrigStmt:
2015 tag = "CREATE EVENT TRIGGER";
2018 case T_AlterEventTrigStmt:
2019 tag = "ALTER EVENT TRIGGER";
2022 case T_CreatePLangStmt:
2023 tag = "CREATE LANGUAGE";
2026 case T_CreateRoleStmt:
2027 tag = "CREATE ROLE";
2030 case T_AlterRoleStmt:
2034 case T_AlterRoleSetStmt:
2038 case T_DropRoleStmt:
2042 case T_DropOwnedStmt:
2046 case T_ReassignOwnedStmt:
2047 tag = "REASSIGN OWNED";
2054 case T_ConstraintsSetStmt:
2055 tag = "SET CONSTRAINTS";
2058 case T_CheckPointStmt:
2066 case T_CreateConversionStmt:
2067 tag = "CREATE CONVERSION";
2070 case T_CreateCastStmt:
2071 tag = "CREATE CAST";
2074 case T_CreateOpClassStmt:
2075 tag = "CREATE OPERATOR CLASS";
2078 case T_CreateOpFamilyStmt:
2079 tag = "CREATE OPERATOR FAMILY";
2082 case T_AlterOpFamilyStmt:
2083 tag = "ALTER OPERATOR FAMILY";
2086 case T_AlterTSDictionaryStmt:
2087 tag = "ALTER TEXT SEARCH DICTIONARY";
2090 case T_AlterTSConfigurationStmt:
2091 tag = "ALTER TEXT SEARCH CONFIGURATION";
2102 case T_DeallocateStmt:
2104 DeallocateStmt *stmt = (DeallocateStmt *) parsetree;
2106 if (stmt->name == NULL)
2107 tag = "DEALLOCATE ALL";
2113 /* already-planned queries */
2116 PlannedStmt *stmt = (PlannedStmt *) parsetree;
2118 switch (stmt->commandType)
2123 * We take a little extra care here so that the result
2124 * will be useful for complaints about read-only
2127 if (stmt->utilityStmt != NULL)
2129 Assert(IsA(stmt->utilityStmt, DeclareCursorStmt));
2130 tag = "DECLARE CURSOR";
2132 else if (stmt->rowMarks != NIL)
2134 /* not 100% but probably close enough */
2135 if (((PlanRowMark *) linitial(stmt->rowMarks))->markType == ROW_MARK_EXCLUSIVE)
2136 tag = "SELECT FOR UPDATE";
2138 tag = "SELECT FOR SHARE";
2153 elog(WARNING, "unrecognized commandType: %d",
2154 (int) stmt->commandType);
2161 /* parsed-and-rewritten-but-not-planned queries */
2164 Query *stmt = (Query *) parsetree;
2166 switch (stmt->commandType)
2171 * We take a little extra care here so that the result
2172 * will be useful for complaints about read-only
2175 if (stmt->utilityStmt != NULL)
2177 Assert(IsA(stmt->utilityStmt, DeclareCursorStmt));
2178 tag = "DECLARE CURSOR";
2180 else if (stmt->rowMarks != NIL)
2182 /* not 100% but probably close enough */
2183 if (((RowMarkClause *) linitial(stmt->rowMarks))->forUpdate)
2184 tag = "SELECT FOR UPDATE";
2186 tag = "SELECT FOR SHARE";
2201 tag = CreateCommandTag(stmt->utilityStmt);
2204 elog(WARNING, "unrecognized commandType: %d",
2205 (int) stmt->commandType);
2213 elog(WARNING, "unrecognized node type: %d",
2214 (int) nodeTag(parsetree));
2224 * GetCommandLogLevel
2225 * utility to get the minimum log_statement level for a command,
2226 * given either a raw (un-analyzed) parsetree or a planned query.
2228 * This must handle all command types, but since the vast majority
2229 * of 'em are utility commands, it seems sensible to keep it here.
2232 GetCommandLogLevel(Node *parsetree)
2236 switch (nodeTag(parsetree))
2238 /* raw plannable queries */
2246 if (((SelectStmt *) parsetree)->intoClause)
2247 lev = LOGSTMT_DDL; /* SELECT INTO */
2252 /* utility statements --- same whether raw or cooked */
2253 case T_TransactionStmt:
2257 case T_DeclareCursorStmt:
2261 case T_ClosePortalStmt:
2269 case T_CreateSchemaStmt:
2274 case T_CreateForeignTableStmt:
2278 case T_CreateTableSpaceStmt:
2279 case T_DropTableSpaceStmt:
2280 case T_AlterTableSpaceOptionsStmt:
2284 case T_CreateExtensionStmt:
2285 case T_AlterExtensionStmt:
2286 case T_AlterExtensionContentsStmt:
2290 case T_CreateFdwStmt:
2291 case T_AlterFdwStmt:
2292 case T_CreateForeignServerStmt:
2293 case T_AlterForeignServerStmt:
2294 case T_CreateUserMappingStmt:
2295 case T_AlterUserMappingStmt:
2296 case T_DropUserMappingStmt:
2304 case T_TruncateStmt:
2312 case T_SecLabelStmt:
2317 if (((CopyStmt *) parsetree)->is_from)
2325 PrepareStmt *stmt = (PrepareStmt *) parsetree;
2327 /* Look through a PREPARE to the contained stmt */
2328 lev = GetCommandLogLevel(stmt->query);
2334 ExecuteStmt *stmt = (ExecuteStmt *) parsetree;
2335 PreparedStatement *ps;
2337 /* Look through an EXECUTE to the referenced stmt */
2338 ps = FetchPreparedStatement(stmt->name, false);
2340 lev = GetCommandLogLevel(ps->plansource->raw_parse_tree);
2346 case T_DeallocateStmt:
2354 case T_AlterObjectSchemaStmt:
2358 case T_AlterOwnerStmt:
2362 case T_AlterTableStmt:
2366 case T_AlterDomainStmt:
2374 case T_GrantRoleStmt:
2378 case T_AlterDefaultPrivilegesStmt:
2386 case T_CompositeTypeStmt:
2390 case T_CreateEnumStmt:
2394 case T_CreateRangeStmt:
2398 case T_AlterEnumStmt:
2406 case T_CreateFunctionStmt:
2410 case T_AlterFunctionStmt:
2422 case T_CreateSeqStmt:
2426 case T_AlterSeqStmt:
2434 case T_CreatedbStmt:
2438 case T_AlterDatabaseStmt:
2442 case T_AlterDatabaseSetStmt:
2458 case T_UnlistenStmt:
2476 ExplainStmt *stmt = (ExplainStmt *) parsetree;
2477 bool analyze = false;
2480 /* Look through an EXPLAIN ANALYZE to the contained stmt */
2481 foreach(lc, stmt->options)
2483 DefElem *opt = (DefElem *) lfirst(lc);
2485 if (strcmp(opt->defname, "analyze") == 0)
2486 analyze = defGetBoolean(opt);
2487 /* don't "break", as explain.c will use the last value */
2490 return GetCommandLogLevel(stmt->query);
2492 /* Plain EXPLAIN isn't so interesting */
2497 case T_CreateTableAsStmt:
2501 case T_VariableSetStmt:
2505 case T_VariableShowStmt:
2513 case T_CreateTrigStmt:
2517 case T_CreateEventTrigStmt:
2521 case T_AlterEventTrigStmt:
2525 case T_CreatePLangStmt:
2529 case T_CreateDomainStmt:
2533 case T_CreateRoleStmt:
2537 case T_AlterRoleStmt:
2541 case T_AlterRoleSetStmt:
2545 case T_DropRoleStmt:
2549 case T_DropOwnedStmt:
2553 case T_ReassignOwnedStmt:
2561 case T_ConstraintsSetStmt:
2565 case T_CheckPointStmt:
2570 lev = LOGSTMT_ALL; /* should this be DDL? */
2573 case T_CreateConversionStmt:
2577 case T_CreateCastStmt:
2581 case T_CreateOpClassStmt:
2585 case T_CreateOpFamilyStmt:
2589 case T_AlterOpFamilyStmt:
2593 case T_AlterTSDictionaryStmt:
2597 case T_AlterTSConfigurationStmt:
2601 /* already-planned queries */
2604 PlannedStmt *stmt = (PlannedStmt *) parsetree;
2606 switch (stmt->commandType)
2619 elog(WARNING, "unrecognized commandType: %d",
2620 (int) stmt->commandType);
2627 /* parsed-and-rewritten-but-not-planned queries */
2630 Query *stmt = (Query *) parsetree;
2632 switch (stmt->commandType)
2645 lev = GetCommandLogLevel(stmt->utilityStmt);
2649 elog(WARNING, "unrecognized commandType: %d",
2650 (int) stmt->commandType);
2659 elog(WARNING, "unrecognized node type: %d",
2660 (int) nodeTag(parsetree));