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/explain.h"
37 #include "commands/extension.h"
38 #include "commands/lockcmds.h"
39 #include "commands/portalcmds.h"
40 #include "commands/prepare.h"
41 #include "commands/proclang.h"
42 #include "commands/schemacmds.h"
43 #include "commands/seclabel.h"
44 #include "commands/sequence.h"
45 #include "commands/tablecmds.h"
46 #include "commands/tablespace.h"
47 #include "commands/trigger.h"
48 #include "commands/typecmds.h"
49 #include "commands/user.h"
50 #include "commands/vacuum.h"
51 #include "commands/view.h"
52 #include "miscadmin.h"
53 #include "parser/parse_utilcmd.h"
54 #include "postmaster/bgwriter.h"
55 #include "rewrite/rewriteDefine.h"
56 #include "rewrite/rewriteRemove.h"
57 #include "storage/fd.h"
58 #include "tcop/pquery.h"
59 #include "tcop/utility.h"
60 #include "utils/acl.h"
61 #include "utils/guc.h"
62 #include "utils/syscache.h"
65 /* Hook for plugins to get control in ProcessUtility() */
66 ProcessUtility_hook_type ProcessUtility_hook = NULL;
70 * Verify user has ownership of specified relation, else ereport.
72 * If noCatalogs is true then we also deny access to system catalogs,
73 * except when allowSystemTableMods is true.
76 CheckRelationOwnership(RangeVar *rel, bool noCatalogs)
82 * XXX: This is unsafe in the presence of concurrent DDL, since it is
83 * called before acquiring any lock on the target relation. However,
84 * locking the target relation (especially using something like
85 * AccessExclusiveLock) before verifying that the user has permissions is
86 * not appealing either.
88 relOid = RangeVarGetRelid(rel, NoLock, false);
90 tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relOid));
91 if (!HeapTupleIsValid(tuple)) /* should not happen */
92 elog(ERROR, "cache lookup failed for relation %u", relOid);
94 if (!pg_class_ownercheck(relOid, GetUserId()))
95 aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
100 if (!allowSystemTableMods &&
101 IsSystemClass((Form_pg_class) GETSTRUCT(tuple)))
103 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
104 errmsg("permission denied: \"%s\" is a system catalog",
108 ReleaseSysCache(tuple);
113 * CommandIsReadOnly: is an executable query read-only?
115 * This is a much stricter test than we apply for XactReadOnly mode;
116 * the query must be *in truth* read-only, because the caller wishes
117 * not to do CommandCounterIncrement for it.
119 * Note: currently no need to support Query nodes here
122 CommandIsReadOnly(Node *parsetree)
124 if (IsA(parsetree, PlannedStmt))
126 PlannedStmt *stmt = (PlannedStmt *) parsetree;
128 switch (stmt->commandType)
131 if (stmt->rowMarks != NIL)
132 return false; /* SELECT FOR UPDATE/SHARE */
133 else if (stmt->hasModifyingCTE)
134 return false; /* data-modifying CTE */
142 elog(WARNING, "unrecognized commandType: %d",
143 (int) stmt->commandType);
147 /* For now, treat all utility commands as read/write */
152 * check_xact_readonly: is a utility command read-only?
154 * Here we use the loose rules of XactReadOnly mode: no permanent effects
155 * on the database are allowed.
158 check_xact_readonly(Node *parsetree)
164 * Note: Commands that need to do more complicated checking are handled
165 * elsewhere, in particular COPY and plannable statements do their own
166 * checking. However they should all call PreventCommandIfReadOnly to
167 * actually throw the error.
170 switch (nodeTag(parsetree))
172 case T_AlterDatabaseStmt:
173 case T_AlterDatabaseSetStmt:
174 case T_AlterDomainStmt:
175 case T_AlterFunctionStmt:
176 case T_AlterRoleStmt:
177 case T_AlterRoleSetStmt:
178 case T_AlterObjectSchemaStmt:
179 case T_AlterOwnerStmt:
181 case T_AlterTableStmt:
185 case T_CreateCastStmt:
186 case T_CreateConversionStmt:
188 case T_CreateDomainStmt:
189 case T_CreateFunctionStmt:
190 case T_CreateRoleStmt:
192 case T_CreatePLangStmt:
193 case T_CreateOpClassStmt:
194 case T_CreateOpFamilyStmt:
195 case T_AlterOpFamilyStmt:
197 case T_CreateSchemaStmt:
198 case T_CreateSeqStmt:
200 case T_CreateTableAsStmt:
201 case T_CreateTableSpaceStmt:
202 case T_CreateTrigStmt:
203 case T_CompositeTypeStmt:
204 case T_CreateEnumStmt:
205 case T_CreateRangeStmt:
206 case T_AlterEnumStmt:
210 case T_DropTableSpaceStmt:
213 case T_GrantRoleStmt:
214 case T_AlterDefaultPrivilegesStmt:
216 case T_DropOwnedStmt:
217 case T_ReassignOwnedStmt:
218 case T_AlterTSDictionaryStmt:
219 case T_AlterTSConfigurationStmt:
220 case T_CreateExtensionStmt:
221 case T_AlterExtensionStmt:
222 case T_AlterExtensionContentsStmt:
223 case T_CreateFdwStmt:
225 case T_CreateForeignServerStmt:
226 case T_AlterForeignServerStmt:
227 case T_CreateUserMappingStmt:
228 case T_AlterUserMappingStmt:
229 case T_DropUserMappingStmt:
230 case T_AlterTableSpaceOptionsStmt:
231 case T_CreateForeignTableStmt:
233 PreventCommandIfReadOnly(CreateCommandTag(parsetree));
242 * PreventCommandIfReadOnly: throw error if XactReadOnly
244 * This is useful mainly to ensure consistency of the error message wording;
245 * most callers have checked XactReadOnly for themselves.
248 PreventCommandIfReadOnly(const char *cmdname)
252 (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
253 /* translator: %s is name of a SQL command, eg CREATE */
254 errmsg("cannot execute %s in a read-only transaction",
259 * PreventCommandDuringRecovery: throw error if RecoveryInProgress
261 * The majority of operations that are unsafe in a Hot Standby slave
262 * will be rejected by XactReadOnly tests. However there are a few
263 * commands that are allowed in "read-only" xacts but cannot be allowed
264 * in Hot Standby mode. Those commands should call this function.
267 PreventCommandDuringRecovery(const char *cmdname)
269 if (RecoveryInProgress())
271 (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
272 /* translator: %s is name of a SQL command, eg CREATE */
273 errmsg("cannot execute %s during recovery",
278 * CheckRestrictedOperation: throw error for hazardous command if we're
279 * inside a security restriction context.
281 * This is needed to protect session-local state for which there is not any
282 * better-defined protection mechanism, such as ownership.
285 CheckRestrictedOperation(const char *cmdname)
287 if (InSecurityRestrictedOperation())
289 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
290 /* translator: %s is name of a SQL command, eg PREPARE */
291 errmsg("cannot execute %s within security-restricted operation",
298 * general utility function invoker
300 * parsetree: the parse tree for the utility statement
301 * queryString: original source text of command
302 * params: parameters to use during execution
303 * isTopLevel: true if executing a "top level" (interactively issued) command
304 * dest: where to send results
305 * completionTag: points to a buffer of size COMPLETION_TAG_BUFSIZE
306 * in which to store a command completion status string.
308 * Notes: as of PG 8.4, caller MUST supply a queryString; it is not
309 * allowed anymore to pass NULL. (If you really don't have source text,
310 * you can pass a constant string, perhaps "(query not available)".)
312 * completionTag is only set nonempty if we want to return a nondefault status.
314 * completionTag may be NULL if caller doesn't want a status string.
317 ProcessUtility(Node *parsetree,
318 const char *queryString,
319 ParamListInfo params,
324 Assert(queryString != NULL); /* required as of 8.4 */
327 * We provide a function hook variable that lets loadable plugins get
328 * control when ProcessUtility is called. Such a plugin would normally
329 * call standard_ProcessUtility().
331 if (ProcessUtility_hook)
332 (*ProcessUtility_hook) (parsetree, queryString, params,
333 isTopLevel, dest, completionTag);
335 standard_ProcessUtility(parsetree, queryString, params,
336 isTopLevel, dest, completionTag);
340 standard_ProcessUtility(Node *parsetree,
341 const char *queryString,
342 ParamListInfo params,
347 check_xact_readonly(parsetree);
350 completionTag[0] = '\0';
352 switch (nodeTag(parsetree))
355 * ******************** transactions ********************
357 case T_TransactionStmt:
359 TransactionStmt *stmt = (TransactionStmt *) parsetree;
364 * START TRANSACTION, as defined by SQL99: Identical
365 * to BEGIN. Same code for both.
367 case TRANS_STMT_BEGIN:
368 case TRANS_STMT_START:
372 BeginTransactionBlock();
373 foreach(lc, stmt->options)
375 DefElem *item = (DefElem *) lfirst(lc);
377 if (strcmp(item->defname, "transaction_isolation") == 0)
378 SetPGVariable("transaction_isolation",
379 list_make1(item->arg),
381 else if (strcmp(item->defname, "transaction_read_only") == 0)
382 SetPGVariable("transaction_read_only",
383 list_make1(item->arg),
385 else if (strcmp(item->defname, "transaction_deferrable") == 0)
386 SetPGVariable("transaction_deferrable",
387 list_make1(item->arg),
393 case TRANS_STMT_COMMIT:
394 if (!EndTransactionBlock())
396 /* report unsuccessful commit in completionTag */
398 strcpy(completionTag, "ROLLBACK");
402 case TRANS_STMT_PREPARE:
403 PreventCommandDuringRecovery("PREPARE TRANSACTION");
404 if (!PrepareTransactionBlock(stmt->gid))
406 /* report unsuccessful commit in completionTag */
408 strcpy(completionTag, "ROLLBACK");
412 case TRANS_STMT_COMMIT_PREPARED:
413 PreventTransactionChain(isTopLevel, "COMMIT PREPARED");
414 PreventCommandDuringRecovery("COMMIT PREPARED");
415 FinishPreparedTransaction(stmt->gid, true);
418 case TRANS_STMT_ROLLBACK_PREPARED:
419 PreventTransactionChain(isTopLevel, "ROLLBACK PREPARED");
420 PreventCommandDuringRecovery("ROLLBACK PREPARED");
421 FinishPreparedTransaction(stmt->gid, false);
424 case TRANS_STMT_ROLLBACK:
425 UserAbortTransactionBlock();
428 case TRANS_STMT_SAVEPOINT:
433 RequireTransactionChain(isTopLevel, "SAVEPOINT");
435 foreach(cell, stmt->options)
437 DefElem *elem = lfirst(cell);
439 if (strcmp(elem->defname, "savepoint_name") == 0)
440 name = strVal(elem->arg);
443 Assert(PointerIsValid(name));
445 DefineSavepoint(name);
449 case TRANS_STMT_RELEASE:
450 RequireTransactionChain(isTopLevel, "RELEASE SAVEPOINT");
451 ReleaseSavepoint(stmt->options);
454 case TRANS_STMT_ROLLBACK_TO:
455 RequireTransactionChain(isTopLevel, "ROLLBACK TO SAVEPOINT");
456 RollbackToSavepoint(stmt->options);
459 * CommitTransactionCommand is in charge of
460 * re-defining the savepoint again
468 * Portal (cursor) manipulation
470 * Note: DECLARE CURSOR is processed mostly as a SELECT, and
471 * therefore what we will get here is a PlannedStmt not a bare
476 PlannedStmt *stmt = (PlannedStmt *) parsetree;
478 if (stmt->utilityStmt == NULL ||
479 !IsA(stmt->utilityStmt, DeclareCursorStmt))
480 elog(ERROR, "non-DECLARE CURSOR PlannedStmt passed to ProcessUtility");
481 PerformCursorOpen(stmt, params, queryString, isTopLevel);
485 case T_ClosePortalStmt:
487 ClosePortalStmt *stmt = (ClosePortalStmt *) parsetree;
489 CheckRestrictedOperation("CLOSE");
490 PerformPortalClose(stmt->portalname);
495 PerformPortalFetch((FetchStmt *) parsetree, dest,
500 * relation and attribute manipulation
502 case T_CreateSchemaStmt:
503 CreateSchemaCommand((CreateSchemaStmt *) parsetree,
508 case T_CreateForeignTableStmt:
514 /* Run parse analysis ... */
515 stmts = transformCreateStmt((CreateStmt *) parsetree,
521 Node *stmt = (Node *) lfirst(l);
523 if (IsA(stmt, CreateStmt))
526 static char *validnsps[] = HEAP_RELOPT_NAMESPACES;
528 /* Create the table itself */
529 relOid = DefineRelation((CreateStmt *) stmt,
534 * Let AlterTableCreateToastTable decide if this one
535 * needs a secondary relation too.
537 CommandCounterIncrement();
539 /* parse and validate reloptions for the toast table */
540 toast_options = transformRelOptions((Datum) 0,
541 ((CreateStmt *) stmt)->options,
545 (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options,
548 AlterTableCreateToastTable(relOid, toast_options);
550 else if (IsA(stmt, CreateForeignTableStmt))
552 /* Create the table itself */
553 relOid = DefineRelation((CreateStmt *) stmt,
554 RELKIND_FOREIGN_TABLE,
556 CreateForeignTable((CreateForeignTableStmt *) stmt,
561 /* Recurse for anything else */
570 /* Need CCI between commands */
571 if (lnext(l) != NULL)
572 CommandCounterIncrement();
577 case T_CreateTableSpaceStmt:
578 PreventTransactionChain(isTopLevel, "CREATE TABLESPACE");
579 CreateTableSpace((CreateTableSpaceStmt *) parsetree);
582 case T_DropTableSpaceStmt:
583 PreventTransactionChain(isTopLevel, "DROP TABLESPACE");
584 DropTableSpace((DropTableSpaceStmt *) parsetree);
587 case T_AlterTableSpaceOptionsStmt:
588 AlterTableSpaceOptions((AlterTableSpaceOptionsStmt *) parsetree);
591 case T_CreateExtensionStmt:
592 CreateExtension((CreateExtensionStmt *) parsetree);
595 case T_AlterExtensionStmt:
596 ExecAlterExtensionStmt((AlterExtensionStmt *) parsetree);
599 case T_AlterExtensionContentsStmt:
600 ExecAlterExtensionContentsStmt((AlterExtensionContentsStmt *) parsetree);
603 case T_CreateFdwStmt:
604 CreateForeignDataWrapper((CreateFdwStmt *) parsetree);
608 AlterForeignDataWrapper((AlterFdwStmt *) parsetree);
611 case T_CreateForeignServerStmt:
612 CreateForeignServer((CreateForeignServerStmt *) parsetree);
615 case T_AlterForeignServerStmt:
616 AlterForeignServer((AlterForeignServerStmt *) parsetree);
619 case T_CreateUserMappingStmt:
620 CreateUserMapping((CreateUserMappingStmt *) parsetree);
623 case T_AlterUserMappingStmt:
624 AlterUserMapping((AlterUserMappingStmt *) parsetree);
627 case T_DropUserMappingStmt:
628 RemoveUserMapping((DropUserMappingStmt *) parsetree);
632 switch (((DropStmt *) parsetree)->removeType)
635 if (((DropStmt *) parsetree)->concurrent)
636 PreventTransactionChain(isTopLevel,
637 "DROP INDEX CONCURRENTLY");
641 case OBJECT_SEQUENCE:
643 case OBJECT_FOREIGN_TABLE:
644 RemoveRelations((DropStmt *) parsetree);
647 RemoveObjects((DropStmt *) parsetree);
653 ExecuteTruncate((TruncateStmt *) parsetree);
657 CommentObject((CommentStmt *) parsetree);
661 ExecSecLabelStmt((SecLabelStmt *) parsetree);
668 processed = DoCopy((CopyStmt *) parsetree, queryString);
670 snprintf(completionTag, COMPLETION_TAG_BUFSIZE,
671 "COPY " UINT64_FORMAT, processed);
676 CheckRestrictedOperation("PREPARE");
677 PrepareQuery((PrepareStmt *) parsetree, queryString);
681 ExecuteQuery((ExecuteStmt *) parsetree, NULL,
683 dest, completionTag);
686 case T_DeallocateStmt:
687 CheckRestrictedOperation("DEALLOCATE");
688 DeallocateQuery((DeallocateStmt *) parsetree);
695 ExecRenameStmt((RenameStmt *) parsetree);
698 case T_AlterObjectSchemaStmt:
699 ExecAlterObjectSchemaStmt((AlterObjectSchemaStmt *) parsetree);
702 case T_AlterOwnerStmt:
703 ExecAlterOwnerStmt((AlterOwnerStmt *) parsetree);
706 case T_AlterTableStmt:
708 AlterTableStmt *atstmt = (AlterTableStmt *) parsetree;
715 * Figure out lock mode, and acquire lock. This also does
716 * basic permissions checks, so that we won't wait for a lock
717 * on (for example) a relation on which we have no
720 lockmode = AlterTableGetLockLevel(atstmt->cmds);
721 relid = AlterTableLookupRelation(atstmt, lockmode);
723 if (OidIsValid(relid))
725 /* Run parse analysis ... */
726 stmts = transformAlterTableStmt(atstmt, queryString);
731 Node *stmt = (Node *) lfirst(l);
733 if (IsA(stmt, AlterTableStmt))
735 /* Do the table alteration proper */
736 AlterTable(relid, lockmode, (AlterTableStmt *) stmt);
740 /* Recurse for anything else */
749 /* Need CCI between commands */
750 if (lnext(l) != NULL)
751 CommandCounterIncrement();
756 (errmsg("relation \"%s\" does not exist, skipping",
757 atstmt->relation->relname)));
761 case T_AlterDomainStmt:
763 AlterDomainStmt *stmt = (AlterDomainStmt *) parsetree;
766 * Some or all of these functions are recursive to cover
767 * inherited things, so permission checks are done there.
769 switch (stmt->subtype)
771 case 'T': /* ALTER DOMAIN DEFAULT */
774 * Recursively alter column default for table and, if
775 * requested, for descendants
777 AlterDomainDefault(stmt->typeName,
780 case 'N': /* ALTER DOMAIN DROP NOT NULL */
781 AlterDomainNotNull(stmt->typeName,
784 case 'O': /* ALTER DOMAIN SET NOT NULL */
785 AlterDomainNotNull(stmt->typeName,
788 case 'C': /* ADD CONSTRAINT */
789 AlterDomainAddConstraint(stmt->typeName,
792 case 'X': /* DROP CONSTRAINT */
793 AlterDomainDropConstraint(stmt->typeName,
798 case 'V': /* VALIDATE CONSTRAINT */
799 AlterDomainValidateConstraint(stmt->typeName,
803 elog(ERROR, "unrecognized alter domain type: %d",
804 (int) stmt->subtype);
811 ExecuteGrantStmt((GrantStmt *) parsetree);
814 case T_GrantRoleStmt:
815 GrantRole((GrantRoleStmt *) parsetree);
818 case T_AlterDefaultPrivilegesStmt:
819 ExecAlterDefaultPrivilegesStmt((AlterDefaultPrivilegesStmt *) parsetree);
823 * **************** object creation / destruction *****************
827 DefineStmt *stmt = (DefineStmt *) parsetree;
831 case OBJECT_AGGREGATE:
832 DefineAggregate(stmt->defnames, stmt->args,
833 stmt->oldstyle, stmt->definition);
835 case OBJECT_OPERATOR:
836 Assert(stmt->args == NIL);
837 DefineOperator(stmt->defnames, stmt->definition);
840 Assert(stmt->args == NIL);
841 DefineType(stmt->defnames, stmt->definition);
843 case OBJECT_TSPARSER:
844 Assert(stmt->args == NIL);
845 DefineTSParser(stmt->defnames, stmt->definition);
847 case OBJECT_TSDICTIONARY:
848 Assert(stmt->args == NIL);
849 DefineTSDictionary(stmt->defnames, stmt->definition);
851 case OBJECT_TSTEMPLATE:
852 Assert(stmt->args == NIL);
853 DefineTSTemplate(stmt->defnames, stmt->definition);
855 case OBJECT_TSCONFIGURATION:
856 Assert(stmt->args == NIL);
857 DefineTSConfiguration(stmt->defnames, stmt->definition);
859 case OBJECT_COLLATION:
860 Assert(stmt->args == NIL);
861 DefineCollation(stmt->defnames, stmt->definition);
864 elog(ERROR, "unrecognized define stmt type: %d",
871 case T_CompositeTypeStmt: /* CREATE TYPE (composite) */
873 CompositeTypeStmt *stmt = (CompositeTypeStmt *) parsetree;
875 DefineCompositeType(stmt->typevar, stmt->coldeflist);
879 case T_CreateEnumStmt: /* CREATE TYPE AS ENUM */
880 DefineEnum((CreateEnumStmt *) parsetree);
883 case T_CreateRangeStmt: /* CREATE TYPE AS RANGE */
884 DefineRange((CreateRangeStmt *) parsetree);
887 case T_AlterEnumStmt: /* ALTER TYPE (enum) */
890 * We disallow this in transaction blocks, because we can't cope
891 * with enum OID values getting into indexes and then having their
892 * defining pg_enum entries go away.
894 PreventTransactionChain(isTopLevel, "ALTER TYPE ... ADD");
895 AlterEnum((AlterEnumStmt *) parsetree);
898 case T_ViewStmt: /* CREATE VIEW */
899 DefineView((ViewStmt *) parsetree, queryString);
902 case T_CreateFunctionStmt: /* CREATE FUNCTION */
903 CreateFunction((CreateFunctionStmt *) parsetree, queryString);
906 case T_AlterFunctionStmt: /* ALTER FUNCTION */
907 AlterFunction((AlterFunctionStmt *) parsetree);
910 case T_IndexStmt: /* CREATE INDEX */
912 IndexStmt *stmt = (IndexStmt *) parsetree;
914 if (stmt->concurrent)
915 PreventTransactionChain(isTopLevel,
916 "CREATE INDEX CONCURRENTLY");
918 CheckRelationOwnership(stmt->relation, true);
920 /* Run parse analysis ... */
921 stmt = transformIndexStmt(stmt, queryString);
924 DefineIndex(stmt->relation, /* relation */
925 stmt->idxname, /* index name */
926 InvalidOid, /* no predefined OID */
927 InvalidOid, /* no previous storage */
928 stmt->accessMethod, /* am name */
930 stmt->indexParams, /* parameters */
931 (Expr *) stmt->whereClause,
933 stmt->excludeOpNames,
939 false, /* is_alter_table */
940 true, /* check_rights */
941 false, /* skip_build */
943 stmt->concurrent); /* concurrent */
947 case T_RuleStmt: /* CREATE RULE */
948 DefineRule((RuleStmt *) parsetree, queryString);
951 case T_CreateSeqStmt:
952 DefineSequence((CreateSeqStmt *) parsetree);
956 AlterSequence((AlterSeqStmt *) parsetree);
960 ExecuteDoStmt((DoStmt *) parsetree);
964 PreventTransactionChain(isTopLevel, "CREATE DATABASE");
965 createdb((CreatedbStmt *) parsetree);
968 case T_AlterDatabaseStmt:
969 AlterDatabase((AlterDatabaseStmt *) parsetree, isTopLevel);
972 case T_AlterDatabaseSetStmt:
973 AlterDatabaseSet((AlterDatabaseSetStmt *) parsetree);
978 DropdbStmt *stmt = (DropdbStmt *) parsetree;
980 PreventTransactionChain(isTopLevel, "DROP DATABASE");
981 dropdb(stmt->dbname, stmt->missing_ok);
985 /* Query-level asynchronous notification */
988 NotifyStmt *stmt = (NotifyStmt *) parsetree;
990 PreventCommandDuringRecovery("NOTIFY");
991 Async_Notify(stmt->conditionname, stmt->payload);
997 ListenStmt *stmt = (ListenStmt *) parsetree;
999 PreventCommandDuringRecovery("LISTEN");
1000 CheckRestrictedOperation("LISTEN");
1001 Async_Listen(stmt->conditionname);
1005 case T_UnlistenStmt:
1007 UnlistenStmt *stmt = (UnlistenStmt *) parsetree;
1009 PreventCommandDuringRecovery("UNLISTEN");
1010 CheckRestrictedOperation("UNLISTEN");
1011 if (stmt->conditionname)
1012 Async_Unlisten(stmt->conditionname);
1014 Async_UnlistenAll();
1020 LoadStmt *stmt = (LoadStmt *) parsetree;
1022 closeAllVfds(); /* probably not necessary... */
1023 /* Allowed names are restricted if you're not superuser */
1024 load_file(stmt->filename, !superuser());
1029 /* we choose to allow this during "read only" transactions */
1030 PreventCommandDuringRecovery("CLUSTER");
1031 cluster((ClusterStmt *) parsetree, isTopLevel);
1035 /* we choose to allow this during "read only" transactions */
1036 PreventCommandDuringRecovery("VACUUM");
1037 vacuum((VacuumStmt *) parsetree, InvalidOid, true, NULL, false,
1042 ExplainQuery((ExplainStmt *) parsetree, queryString, params, dest);
1045 case T_CreateTableAsStmt:
1046 ExecCreateTableAs((CreateTableAsStmt *) parsetree,
1047 queryString, params, completionTag);
1050 case T_VariableSetStmt:
1051 ExecSetVariableStmt((VariableSetStmt *) parsetree);
1054 case T_VariableShowStmt:
1056 VariableShowStmt *n = (VariableShowStmt *) parsetree;
1058 GetPGVariable(n->name, dest);
1063 /* should we allow DISCARD PLANS? */
1064 CheckRestrictedOperation("DISCARD");
1065 DiscardCommand((DiscardStmt *) parsetree, isTopLevel);
1068 case T_CreateTrigStmt:
1069 (void) CreateTrigger((CreateTrigStmt *) parsetree, queryString,
1070 InvalidOid, InvalidOid, false);
1073 case T_CreatePLangStmt:
1074 CreateProceduralLanguage((CreatePLangStmt *) parsetree);
1078 * ******************************** DOMAIN statements ****
1080 case T_CreateDomainStmt:
1081 DefineDomain((CreateDomainStmt *) parsetree);
1085 * ******************************** ROLE statements ****
1087 case T_CreateRoleStmt:
1088 CreateRole((CreateRoleStmt *) parsetree);
1091 case T_AlterRoleStmt:
1092 AlterRole((AlterRoleStmt *) parsetree);
1095 case T_AlterRoleSetStmt:
1096 AlterRoleSet((AlterRoleSetStmt *) parsetree);
1099 case T_DropRoleStmt:
1100 DropRole((DropRoleStmt *) parsetree);
1103 case T_DropOwnedStmt:
1104 DropOwnedObjects((DropOwnedStmt *) parsetree);
1107 case T_ReassignOwnedStmt:
1108 ReassignOwnedObjects((ReassignOwnedStmt *) parsetree);
1114 * Since the lock would just get dropped immediately, LOCK TABLE
1115 * outside a transaction block is presumed to be user error.
1117 RequireTransactionChain(isTopLevel, "LOCK TABLE");
1118 LockTableCommand((LockStmt *) parsetree);
1121 case T_ConstraintsSetStmt:
1122 AfterTriggerSetState((ConstraintsSetStmt *) parsetree);
1125 case T_CheckPointStmt:
1128 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1129 errmsg("must be superuser to do CHECKPOINT")));
1132 * You might think we should have a PreventCommandDuringRecovery()
1133 * here, but we interpret a CHECKPOINT command during recovery as
1134 * a request for a restartpoint instead. We allow this since it
1135 * can be a useful way of reducing switchover time when using
1136 * various forms of replication.
1138 RequestCheckpoint(CHECKPOINT_IMMEDIATE | CHECKPOINT_WAIT |
1139 (RecoveryInProgress() ? 0 : CHECKPOINT_FORCE));
1144 ReindexStmt *stmt = (ReindexStmt *) parsetree;
1146 /* we choose to allow this during "read only" transactions */
1147 PreventCommandDuringRecovery("REINDEX");
1151 ReindexIndex(stmt->relation);
1154 ReindexTable(stmt->relation);
1156 case OBJECT_DATABASE:
1159 * This cannot run inside a user transaction block; if
1160 * we were inside a transaction, then its commit- and
1161 * start-transaction-command calls would not have the
1164 PreventTransactionChain(isTopLevel,
1165 "REINDEX DATABASE");
1166 ReindexDatabase(stmt->name,
1167 stmt->do_system, stmt->do_user);
1170 elog(ERROR, "unrecognized object type: %d",
1178 case T_CreateConversionStmt:
1179 CreateConversionCommand((CreateConversionStmt *) parsetree);
1182 case T_CreateCastStmt:
1183 CreateCast((CreateCastStmt *) parsetree);
1186 case T_CreateOpClassStmt:
1187 DefineOpClass((CreateOpClassStmt *) parsetree);
1190 case T_CreateOpFamilyStmt:
1191 DefineOpFamily((CreateOpFamilyStmt *) parsetree);
1194 case T_AlterOpFamilyStmt:
1195 AlterOpFamily((AlterOpFamilyStmt *) parsetree);
1198 case T_AlterTSDictionaryStmt:
1199 AlterTSDictionary((AlterTSDictionaryStmt *) parsetree);
1202 case T_AlterTSConfigurationStmt:
1203 AlterTSConfiguration((AlterTSConfigurationStmt *) parsetree);
1207 elog(ERROR, "unrecognized node type: %d",
1208 (int) nodeTag(parsetree));
1214 * UtilityReturnsTuples
1215 * Return "true" if this utility statement will send output to the
1218 * Generally, there should be a case here for each case in ProcessUtility
1219 * where "dest" is passed on.
1222 UtilityReturnsTuples(Node *parsetree)
1224 switch (nodeTag(parsetree))
1228 FetchStmt *stmt = (FetchStmt *) parsetree;
1233 portal = GetPortalByName(stmt->portalname);
1234 if (!PortalIsValid(portal))
1235 return false; /* not our business to raise error */
1236 return portal->tupDesc ? true : false;
1241 ExecuteStmt *stmt = (ExecuteStmt *) parsetree;
1242 PreparedStatement *entry;
1244 entry = FetchPreparedStatement(stmt->name, false);
1246 return false; /* not our business to raise error */
1247 if (entry->plansource->resultDesc)
1255 case T_VariableShowStmt:
1264 * UtilityTupleDescriptor
1265 * Fetch the actual output tuple descriptor for a utility statement
1266 * for which UtilityReturnsTuples() previously returned "true".
1268 * The returned descriptor is created in (or copied into) the current memory
1272 UtilityTupleDescriptor(Node *parsetree)
1274 switch (nodeTag(parsetree))
1278 FetchStmt *stmt = (FetchStmt *) parsetree;
1283 portal = GetPortalByName(stmt->portalname);
1284 if (!PortalIsValid(portal))
1285 return NULL; /* not our business to raise error */
1286 return CreateTupleDescCopy(portal->tupDesc);
1291 ExecuteStmt *stmt = (ExecuteStmt *) parsetree;
1292 PreparedStatement *entry;
1294 entry = FetchPreparedStatement(stmt->name, false);
1296 return NULL; /* not our business to raise error */
1297 return FetchPreparedStatementResultDesc(entry);
1301 return ExplainResultDesc((ExplainStmt *) parsetree);
1303 case T_VariableShowStmt:
1305 VariableShowStmt *n = (VariableShowStmt *) parsetree;
1307 return GetPGVariableResultDesc(n->name);
1317 * QueryReturnsTuples
1318 * Return "true" if this Query will send output to the destination.
1322 QueryReturnsTuples(Query *parsetree)
1324 switch (parsetree->commandType)
1327 /* returns tuples ... unless it's DECLARE CURSOR */
1328 if (parsetree->utilityStmt == NULL)
1334 /* the forms with RETURNING return tuples */
1335 if (parsetree->returningList)
1339 return UtilityReturnsTuples(parsetree->utilityStmt);
1342 /* probably shouldn't get here */
1345 return false; /* default */
1351 * UtilityContainsQuery
1352 * Return the contained Query, or NULL if there is none
1354 * Certain utility statements, such as EXPLAIN, contain a Query.
1355 * This function encapsulates knowledge of exactly which ones do.
1356 * We assume it is invoked only on already-parse-analyzed statements
1357 * (else the contained parsetree isn't a Query yet).
1360 UtilityContainsQuery(Node *parsetree)
1362 switch (nodeTag(parsetree))
1365 Assert(IsA(((ExplainStmt *) parsetree)->query, Query));
1366 return (Query *) ((ExplainStmt *) parsetree)->query;
1368 case T_CreateTableAsStmt:
1369 /* might or might not contain a Query ... */
1370 if (IsA(((CreateTableAsStmt *) parsetree)->query, Query))
1371 return (Query *) ((CreateTableAsStmt *) parsetree)->query;
1372 Assert(IsA(((CreateTableAsStmt *) parsetree)->query, ExecuteStmt));
1382 * AlterObjectTypeCommandTag
1383 * helper function for CreateCommandTag
1385 * This covers most cases where ALTER is used with an ObjectType enum.
1388 AlterObjectTypeCommandTag(ObjectType objtype)
1394 case OBJECT_AGGREGATE:
1395 tag = "ALTER AGGREGATE";
1397 case OBJECT_ATTRIBUTE:
1403 case OBJECT_COLLATION:
1404 tag = "ALTER COLLATION";
1407 tag = "ALTER TABLE";
1409 case OBJECT_CONSTRAINT:
1410 tag = "ALTER TABLE";
1412 case OBJECT_CONVERSION:
1413 tag = "ALTER CONVERSION";
1415 case OBJECT_DATABASE:
1416 tag = "ALTER DATABASE";
1419 tag = "ALTER DOMAIN";
1421 case OBJECT_EXTENSION:
1422 tag = "ALTER EXTENSION";
1425 tag = "ALTER FOREIGN DATA WRAPPER";
1427 case OBJECT_FOREIGN_SERVER:
1428 tag = "ALTER SERVER";
1430 case OBJECT_FOREIGN_TABLE:
1431 tag = "ALTER FOREIGN TABLE";
1433 case OBJECT_FUNCTION:
1434 tag = "ALTER FUNCTION";
1437 tag = "ALTER INDEX";
1439 case OBJECT_LANGUAGE:
1440 tag = "ALTER LANGUAGE";
1442 case OBJECT_LARGEOBJECT:
1443 tag = "ALTER LARGE OBJECT";
1445 case OBJECT_OPCLASS:
1446 tag = "ALTER OPERATOR CLASS";
1448 case OBJECT_OPERATOR:
1449 tag = "ALTER OPERATOR";
1451 case OBJECT_OPFAMILY:
1452 tag = "ALTER OPERATOR FAMILY";
1461 tag = "ALTER SCHEMA";
1463 case OBJECT_SEQUENCE:
1464 tag = "ALTER SEQUENCE";
1467 tag = "ALTER TABLE";
1469 case OBJECT_TABLESPACE:
1470 tag = "ALTER TABLESPACE";
1472 case OBJECT_TRIGGER:
1473 tag = "ALTER TRIGGER";
1475 case OBJECT_TSCONFIGURATION:
1476 tag = "ALTER TEXT SEARCH CONFIGURATION";
1478 case OBJECT_TSDICTIONARY:
1479 tag = "ALTER TEXT SEARCH DICTIONARY";
1481 case OBJECT_TSPARSER:
1482 tag = "ALTER TEXT SEARCH PARSER";
1484 case OBJECT_TSTEMPLATE:
1485 tag = "ALTER TEXT SEARCH TEMPLATE";
1503 * utility to get a string representation of the command operation,
1504 * given either a raw (un-analyzed) parsetree or a planned query.
1506 * This must handle all command types, but since the vast majority
1507 * of 'em are utility commands, it seems sensible to keep it here.
1509 * NB: all result strings must be shorter than COMPLETION_TAG_BUFSIZE.
1510 * Also, the result must point at a true constant (permanent storage).
1513 CreateCommandTag(Node *parsetree)
1517 switch (nodeTag(parsetree))
1519 /* raw plannable queries */
1536 /* utility statements --- same whether raw or cooked */
1537 case T_TransactionStmt:
1539 TransactionStmt *stmt = (TransactionStmt *) parsetree;
1543 case TRANS_STMT_BEGIN:
1547 case TRANS_STMT_START:
1548 tag = "START TRANSACTION";
1551 case TRANS_STMT_COMMIT:
1555 case TRANS_STMT_ROLLBACK:
1556 case TRANS_STMT_ROLLBACK_TO:
1560 case TRANS_STMT_SAVEPOINT:
1564 case TRANS_STMT_RELEASE:
1568 case TRANS_STMT_PREPARE:
1569 tag = "PREPARE TRANSACTION";
1572 case TRANS_STMT_COMMIT_PREPARED:
1573 tag = "COMMIT PREPARED";
1576 case TRANS_STMT_ROLLBACK_PREPARED:
1577 tag = "ROLLBACK PREPARED";
1587 case T_DeclareCursorStmt:
1588 tag = "DECLARE CURSOR";
1591 case T_ClosePortalStmt:
1593 ClosePortalStmt *stmt = (ClosePortalStmt *) parsetree;
1595 if (stmt->portalname == NULL)
1596 tag = "CLOSE CURSOR ALL";
1598 tag = "CLOSE CURSOR";
1604 FetchStmt *stmt = (FetchStmt *) parsetree;
1606 tag = (stmt->ismove) ? "MOVE" : "FETCH";
1610 case T_CreateDomainStmt:
1611 tag = "CREATE DOMAIN";
1614 case T_CreateSchemaStmt:
1615 tag = "CREATE SCHEMA";
1619 tag = "CREATE TABLE";
1622 case T_CreateTableSpaceStmt:
1623 tag = "CREATE TABLESPACE";
1626 case T_DropTableSpaceStmt:
1627 tag = "DROP TABLESPACE";
1630 case T_AlterTableSpaceOptionsStmt:
1631 tag = "ALTER TABLESPACE";
1634 case T_CreateExtensionStmt:
1635 tag = "CREATE EXTENSION";
1638 case T_AlterExtensionStmt:
1639 tag = "ALTER EXTENSION";
1642 case T_AlterExtensionContentsStmt:
1643 tag = "ALTER EXTENSION";
1646 case T_CreateFdwStmt:
1647 tag = "CREATE FOREIGN DATA WRAPPER";
1650 case T_AlterFdwStmt:
1651 tag = "ALTER FOREIGN DATA WRAPPER";
1654 case T_CreateForeignServerStmt:
1655 tag = "CREATE SERVER";
1658 case T_AlterForeignServerStmt:
1659 tag = "ALTER SERVER";
1662 case T_CreateUserMappingStmt:
1663 tag = "CREATE USER MAPPING";
1666 case T_AlterUserMappingStmt:
1667 tag = "ALTER USER MAPPING";
1670 case T_DropUserMappingStmt:
1671 tag = "DROP USER MAPPING";
1674 case T_CreateForeignTableStmt:
1675 tag = "CREATE FOREIGN TABLE";
1679 switch (((DropStmt *) parsetree)->removeType)
1684 case OBJECT_SEQUENCE:
1685 tag = "DROP SEQUENCE";
1697 tag = "DROP DOMAIN";
1699 case OBJECT_COLLATION:
1700 tag = "DROP COLLATION";
1702 case OBJECT_CONVERSION:
1703 tag = "DROP CONVERSION";
1706 tag = "DROP SCHEMA";
1708 case OBJECT_TSPARSER:
1709 tag = "DROP TEXT SEARCH PARSER";
1711 case OBJECT_TSDICTIONARY:
1712 tag = "DROP TEXT SEARCH DICTIONARY";
1714 case OBJECT_TSTEMPLATE:
1715 tag = "DROP TEXT SEARCH TEMPLATE";
1717 case OBJECT_TSCONFIGURATION:
1718 tag = "DROP TEXT SEARCH CONFIGURATION";
1720 case OBJECT_FOREIGN_TABLE:
1721 tag = "DROP FOREIGN TABLE";
1723 case OBJECT_EXTENSION:
1724 tag = "DROP EXTENSION";
1726 case OBJECT_FUNCTION:
1727 tag = "DROP FUNCTION";
1729 case OBJECT_AGGREGATE:
1730 tag = "DROP AGGREGATE";
1732 case OBJECT_OPERATOR:
1733 tag = "DROP OPERATOR";
1735 case OBJECT_LANGUAGE:
1736 tag = "DROP LANGUAGE";
1741 case OBJECT_TRIGGER:
1742 tag = "DROP TRIGGER";
1748 tag = "DROP FOREIGN DATA WRAPPER";
1750 case OBJECT_FOREIGN_SERVER:
1751 tag = "DROP SERVER";
1753 case OBJECT_OPCLASS:
1754 tag = "DROP OPERATOR CLASS";
1756 case OBJECT_OPFAMILY:
1757 tag = "DROP OPERATOR FAMILY";
1764 case T_TruncateStmt:
1765 tag = "TRUNCATE TABLE";
1772 case T_SecLabelStmt:
1773 tag = "SECURITY LABEL";
1781 tag = AlterObjectTypeCommandTag(((RenameStmt *) parsetree)->renameType);
1784 case T_AlterObjectSchemaStmt:
1785 tag = AlterObjectTypeCommandTag(((AlterObjectSchemaStmt *) parsetree)->objectType);
1788 case T_AlterOwnerStmt:
1789 tag = AlterObjectTypeCommandTag(((AlterOwnerStmt *) parsetree)->objectType);
1792 case T_AlterTableStmt:
1793 tag = AlterObjectTypeCommandTag(((AlterTableStmt *) parsetree)->relkind);
1796 case T_AlterDomainStmt:
1797 tag = "ALTER DOMAIN";
1800 case T_AlterFunctionStmt:
1801 tag = "ALTER FUNCTION";
1806 GrantStmt *stmt = (GrantStmt *) parsetree;
1808 tag = (stmt->is_grant) ? "GRANT" : "REVOKE";
1812 case T_GrantRoleStmt:
1814 GrantRoleStmt *stmt = (GrantRoleStmt *) parsetree;
1816 tag = (stmt->is_grant) ? "GRANT ROLE" : "REVOKE ROLE";
1820 case T_AlterDefaultPrivilegesStmt:
1821 tag = "ALTER DEFAULT PRIVILEGES";
1825 switch (((DefineStmt *) parsetree)->kind)
1827 case OBJECT_AGGREGATE:
1828 tag = "CREATE AGGREGATE";
1830 case OBJECT_OPERATOR:
1831 tag = "CREATE OPERATOR";
1834 tag = "CREATE TYPE";
1836 case OBJECT_TSPARSER:
1837 tag = "CREATE TEXT SEARCH PARSER";
1839 case OBJECT_TSDICTIONARY:
1840 tag = "CREATE TEXT SEARCH DICTIONARY";
1842 case OBJECT_TSTEMPLATE:
1843 tag = "CREATE TEXT SEARCH TEMPLATE";
1845 case OBJECT_TSCONFIGURATION:
1846 tag = "CREATE TEXT SEARCH CONFIGURATION";
1848 case OBJECT_COLLATION:
1849 tag = "CREATE COLLATION";
1856 case T_CompositeTypeStmt:
1857 tag = "CREATE TYPE";
1860 case T_CreateEnumStmt:
1861 tag = "CREATE TYPE";
1864 case T_CreateRangeStmt:
1865 tag = "CREATE TYPE";
1868 case T_AlterEnumStmt:
1873 tag = "CREATE VIEW";
1876 case T_CreateFunctionStmt:
1877 tag = "CREATE FUNCTION";
1881 tag = "CREATE INDEX";
1885 tag = "CREATE RULE";
1888 case T_CreateSeqStmt:
1889 tag = "CREATE SEQUENCE";
1892 case T_AlterSeqStmt:
1893 tag = "ALTER SEQUENCE";
1900 case T_CreatedbStmt:
1901 tag = "CREATE DATABASE";
1904 case T_AlterDatabaseStmt:
1905 tag = "ALTER DATABASE";
1908 case T_AlterDatabaseSetStmt:
1909 tag = "ALTER DATABASE";
1913 tag = "DROP DATABASE";
1924 case T_UnlistenStmt:
1937 if (((VacuumStmt *) parsetree)->options & VACOPT_VACUUM)
1947 case T_CreateTableAsStmt:
1948 if (((CreateTableAsStmt *) parsetree)->is_select_into)
1949 tag = "SELECT INTO";
1951 tag = "CREATE TABLE AS";
1954 case T_VariableSetStmt:
1955 switch (((VariableSetStmt *) parsetree)->kind)
1958 case VAR_SET_CURRENT:
1959 case VAR_SET_DEFAULT:
1972 case T_VariableShowStmt:
1977 switch (((DiscardStmt *) parsetree)->target)
1980 tag = "DISCARD ALL";
1983 tag = "DISCARD PLANS";
1986 tag = "DISCARD TEMP";
1993 case T_CreateTrigStmt:
1994 tag = "CREATE TRIGGER";
1997 case T_CreatePLangStmt:
1998 tag = "CREATE LANGUAGE";
2001 case T_CreateRoleStmt:
2002 tag = "CREATE ROLE";
2005 case T_AlterRoleStmt:
2009 case T_AlterRoleSetStmt:
2013 case T_DropRoleStmt:
2017 case T_DropOwnedStmt:
2021 case T_ReassignOwnedStmt:
2022 tag = "REASSIGN OWNED";
2029 case T_ConstraintsSetStmt:
2030 tag = "SET CONSTRAINTS";
2033 case T_CheckPointStmt:
2041 case T_CreateConversionStmt:
2042 tag = "CREATE CONVERSION";
2045 case T_CreateCastStmt:
2046 tag = "CREATE CAST";
2049 case T_CreateOpClassStmt:
2050 tag = "CREATE OPERATOR CLASS";
2053 case T_CreateOpFamilyStmt:
2054 tag = "CREATE OPERATOR FAMILY";
2057 case T_AlterOpFamilyStmt:
2058 tag = "ALTER OPERATOR FAMILY";
2061 case T_AlterTSDictionaryStmt:
2062 tag = "ALTER TEXT SEARCH DICTIONARY";
2065 case T_AlterTSConfigurationStmt:
2066 tag = "ALTER TEXT SEARCH CONFIGURATION";
2077 case T_DeallocateStmt:
2079 DeallocateStmt *stmt = (DeallocateStmt *) parsetree;
2081 if (stmt->name == NULL)
2082 tag = "DEALLOCATE ALL";
2088 /* already-planned queries */
2091 PlannedStmt *stmt = (PlannedStmt *) parsetree;
2093 switch (stmt->commandType)
2098 * We take a little extra care here so that the result
2099 * will be useful for complaints about read-only
2102 if (stmt->utilityStmt != NULL)
2104 Assert(IsA(stmt->utilityStmt, DeclareCursorStmt));
2105 tag = "DECLARE CURSOR";
2107 else if (stmt->rowMarks != NIL)
2109 /* not 100% but probably close enough */
2110 if (((PlanRowMark *) linitial(stmt->rowMarks))->markType == ROW_MARK_EXCLUSIVE)
2111 tag = "SELECT FOR UPDATE";
2113 tag = "SELECT FOR SHARE";
2128 elog(WARNING, "unrecognized commandType: %d",
2129 (int) stmt->commandType);
2136 /* parsed-and-rewritten-but-not-planned queries */
2139 Query *stmt = (Query *) parsetree;
2141 switch (stmt->commandType)
2146 * We take a little extra care here so that the result
2147 * will be useful for complaints about read-only
2150 if (stmt->utilityStmt != NULL)
2152 Assert(IsA(stmt->utilityStmt, DeclareCursorStmt));
2153 tag = "DECLARE CURSOR";
2155 else if (stmt->rowMarks != NIL)
2157 /* not 100% but probably close enough */
2158 if (((RowMarkClause *) linitial(stmt->rowMarks))->forUpdate)
2159 tag = "SELECT FOR UPDATE";
2161 tag = "SELECT FOR SHARE";
2176 tag = CreateCommandTag(stmt->utilityStmt);
2179 elog(WARNING, "unrecognized commandType: %d",
2180 (int) stmt->commandType);
2188 elog(WARNING, "unrecognized node type: %d",
2189 (int) nodeTag(parsetree));
2199 * GetCommandLogLevel
2200 * utility to get the minimum log_statement level for a command,
2201 * given either a raw (un-analyzed) parsetree or a planned query.
2203 * This must handle all command types, but since the vast majority
2204 * of 'em are utility commands, it seems sensible to keep it here.
2207 GetCommandLogLevel(Node *parsetree)
2211 switch (nodeTag(parsetree))
2213 /* raw plannable queries */
2221 if (((SelectStmt *) parsetree)->intoClause)
2222 lev = LOGSTMT_DDL; /* SELECT INTO */
2227 /* utility statements --- same whether raw or cooked */
2228 case T_TransactionStmt:
2232 case T_DeclareCursorStmt:
2236 case T_ClosePortalStmt:
2244 case T_CreateSchemaStmt:
2249 case T_CreateForeignTableStmt:
2253 case T_CreateTableSpaceStmt:
2254 case T_DropTableSpaceStmt:
2255 case T_AlterTableSpaceOptionsStmt:
2259 case T_CreateExtensionStmt:
2260 case T_AlterExtensionStmt:
2261 case T_AlterExtensionContentsStmt:
2265 case T_CreateFdwStmt:
2266 case T_AlterFdwStmt:
2267 case T_CreateForeignServerStmt:
2268 case T_AlterForeignServerStmt:
2269 case T_CreateUserMappingStmt:
2270 case T_AlterUserMappingStmt:
2271 case T_DropUserMappingStmt:
2279 case T_TruncateStmt:
2287 case T_SecLabelStmt:
2292 if (((CopyStmt *) parsetree)->is_from)
2300 PrepareStmt *stmt = (PrepareStmt *) parsetree;
2302 /* Look through a PREPARE to the contained stmt */
2303 lev = GetCommandLogLevel(stmt->query);
2309 ExecuteStmt *stmt = (ExecuteStmt *) parsetree;
2310 PreparedStatement *ps;
2312 /* Look through an EXECUTE to the referenced stmt */
2313 ps = FetchPreparedStatement(stmt->name, false);
2315 lev = GetCommandLogLevel(ps->plansource->raw_parse_tree);
2321 case T_DeallocateStmt:
2329 case T_AlterObjectSchemaStmt:
2333 case T_AlterOwnerStmt:
2337 case T_AlterTableStmt:
2341 case T_AlterDomainStmt:
2349 case T_GrantRoleStmt:
2353 case T_AlterDefaultPrivilegesStmt:
2361 case T_CompositeTypeStmt:
2365 case T_CreateEnumStmt:
2369 case T_CreateRangeStmt:
2373 case T_AlterEnumStmt:
2381 case T_CreateFunctionStmt:
2385 case T_AlterFunctionStmt:
2397 case T_CreateSeqStmt:
2401 case T_AlterSeqStmt:
2409 case T_CreatedbStmt:
2413 case T_AlterDatabaseStmt:
2417 case T_AlterDatabaseSetStmt:
2433 case T_UnlistenStmt:
2451 ExplainStmt *stmt = (ExplainStmt *) parsetree;
2452 bool analyze = false;
2455 /* Look through an EXPLAIN ANALYZE to the contained stmt */
2456 foreach(lc, stmt->options)
2458 DefElem *opt = (DefElem *) lfirst(lc);
2460 if (strcmp(opt->defname, "analyze") == 0)
2461 analyze = defGetBoolean(opt);
2462 /* don't "break", as explain.c will use the last value */
2465 return GetCommandLogLevel(stmt->query);
2467 /* Plain EXPLAIN isn't so interesting */
2472 case T_CreateTableAsStmt:
2476 case T_VariableSetStmt:
2480 case T_VariableShowStmt:
2488 case T_CreateTrigStmt:
2492 case T_CreatePLangStmt:
2496 case T_CreateDomainStmt:
2500 case T_CreateRoleStmt:
2504 case T_AlterRoleStmt:
2508 case T_AlterRoleSetStmt:
2512 case T_DropRoleStmt:
2516 case T_DropOwnedStmt:
2520 case T_ReassignOwnedStmt:
2528 case T_ConstraintsSetStmt:
2532 case T_CheckPointStmt:
2537 lev = LOGSTMT_ALL; /* should this be DDL? */
2540 case T_CreateConversionStmt:
2544 case T_CreateCastStmt:
2548 case T_CreateOpClassStmt:
2552 case T_CreateOpFamilyStmt:
2556 case T_AlterOpFamilyStmt:
2560 case T_AlterTSDictionaryStmt:
2564 case T_AlterTSConfigurationStmt:
2568 /* already-planned queries */
2571 PlannedStmt *stmt = (PlannedStmt *) parsetree;
2573 switch (stmt->commandType)
2586 elog(WARNING, "unrecognized commandType: %d",
2587 (int) stmt->commandType);
2594 /* parsed-and-rewritten-but-not-planned queries */
2597 Query *stmt = (Query *) parsetree;
2599 switch (stmt->commandType)
2612 lev = GetCommandLogLevel(stmt->utilityStmt);
2616 elog(WARNING, "unrecognized commandType: %d",
2617 (int) stmt->commandType);
2626 elog(WARNING, "unrecognized node type: %d",
2627 (int) nodeTag(parsetree));