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-2011, 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/conversioncmds.h"
30 #include "commands/copy.h"
31 #include "commands/dbcommands.h"
32 #include "commands/defrem.h"
33 #include "commands/discard.h"
34 #include "commands/explain.h"
35 #include "commands/extension.h"
36 #include "commands/lockcmds.h"
37 #include "commands/portalcmds.h"
38 #include "commands/prepare.h"
39 #include "commands/proclang.h"
40 #include "commands/schemacmds.h"
41 #include "commands/seclabel.h"
42 #include "commands/sequence.h"
43 #include "commands/tablecmds.h"
44 #include "commands/tablespace.h"
45 #include "commands/trigger.h"
46 #include "commands/typecmds.h"
47 #include "commands/user.h"
48 #include "commands/vacuum.h"
49 #include "commands/view.h"
50 #include "miscadmin.h"
51 #include "parser/parse_utilcmd.h"
52 #include "postmaster/bgwriter.h"
53 #include "rewrite/rewriteDefine.h"
54 #include "rewrite/rewriteRemove.h"
55 #include "storage/fd.h"
56 #include "tcop/pquery.h"
57 #include "tcop/utility.h"
58 #include "utils/acl.h"
59 #include "utils/guc.h"
60 #include "utils/syscache.h"
63 /* Hook for plugins to get control in ProcessUtility() */
64 ProcessUtility_hook_type ProcessUtility_hook = NULL;
68 * Verify user has ownership of specified relation, else ereport.
70 * If noCatalogs is true then we also deny access to system catalogs,
71 * except when allowSystemTableMods is true.
74 CheckRelationOwnership(RangeVar *rel, bool noCatalogs)
79 relOid = RangeVarGetRelid(rel, false);
80 tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relOid));
81 if (!HeapTupleIsValid(tuple)) /* should not happen */
82 elog(ERROR, "cache lookup failed for relation %u", relOid);
84 if (!pg_class_ownercheck(relOid, GetUserId()))
85 aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
90 if (!allowSystemTableMods &&
91 IsSystemClass((Form_pg_class) GETSTRUCT(tuple)))
93 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
94 errmsg("permission denied: \"%s\" is a system catalog",
98 ReleaseSysCache(tuple);
103 * CommandIsReadOnly: is an executable query read-only?
105 * This is a much stricter test than we apply for XactReadOnly mode;
106 * the query must be *in truth* read-only, because the caller wishes
107 * not to do CommandCounterIncrement for it.
109 * Note: currently no need to support Query nodes here
112 CommandIsReadOnly(Node *parsetree)
114 if (IsA(parsetree, PlannedStmt))
116 PlannedStmt *stmt = (PlannedStmt *) parsetree;
118 switch (stmt->commandType)
121 if (stmt->intoClause != NULL)
122 return false; /* SELECT INTO */
123 else if (stmt->rowMarks != NIL)
124 return false; /* SELECT FOR UPDATE/SHARE */
132 elog(WARNING, "unrecognized commandType: %d",
133 (int) stmt->commandType);
137 /* For now, treat all utility commands as read/write */
142 * check_xact_readonly: is a utility command read-only?
144 * Here we use the loose rules of XactReadOnly mode: no permanent effects
145 * on the database are allowed.
148 check_xact_readonly(Node *parsetree)
154 * Note: Commands that need to do more complicated checking are handled
155 * elsewhere, in particular COPY and plannable statements do their own
156 * checking. However they should all call PreventCommandIfReadOnly to
157 * actually throw the error.
160 switch (nodeTag(parsetree))
162 case T_AlterDatabaseStmt:
163 case T_AlterDatabaseSetStmt:
164 case T_AlterDomainStmt:
165 case T_AlterFunctionStmt:
166 case T_AlterRoleStmt:
167 case T_AlterRoleSetStmt:
168 case T_AlterObjectSchemaStmt:
169 case T_AlterOwnerStmt:
171 case T_AlterTableStmt:
175 case T_CreateCastStmt:
176 case T_CreateConversionStmt:
178 case T_CreateDomainStmt:
179 case T_CreateFunctionStmt:
180 case T_CreateRoleStmt:
182 case T_CreatePLangStmt:
183 case T_CreateOpClassStmt:
184 case T_CreateOpFamilyStmt:
185 case T_AlterOpFamilyStmt:
187 case T_CreateSchemaStmt:
188 case T_CreateSeqStmt:
190 case T_CreateTableSpaceStmt:
191 case T_CreateTrigStmt:
192 case T_CompositeTypeStmt:
193 case T_CreateEnumStmt:
194 case T_AlterEnumStmt:
199 case T_DropTableSpaceStmt:
200 case T_RemoveFuncStmt:
202 case T_DropPLangStmt:
203 case T_RemoveOpClassStmt:
204 case T_RemoveOpFamilyStmt:
205 case T_DropPropertyStmt:
207 case T_GrantRoleStmt:
208 case T_AlterDefaultPrivilegesStmt:
210 case T_DropOwnedStmt:
211 case T_ReassignOwnedStmt:
212 case T_AlterTSDictionaryStmt:
213 case T_AlterTSConfigurationStmt:
214 case T_CreateExtensionStmt:
215 case T_AlterExtensionContentsStmt:
216 case T_CreateFdwStmt:
219 case T_CreateForeignServerStmt:
220 case T_AlterForeignServerStmt:
221 case T_DropForeignServerStmt:
222 case T_CreateUserMappingStmt:
223 case T_AlterUserMappingStmt:
224 case T_DropUserMappingStmt:
225 case T_AlterTableSpaceOptionsStmt:
226 case T_CreateForeignTableStmt:
228 PreventCommandIfReadOnly(CreateCommandTag(parsetree));
237 * PreventCommandIfReadOnly: throw error if XactReadOnly
239 * This is useful mainly to ensure consistency of the error message wording;
240 * most callers have checked XactReadOnly for themselves.
243 PreventCommandIfReadOnly(const char *cmdname)
247 (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
248 /* translator: %s is name of a SQL command, eg CREATE */
249 errmsg("cannot execute %s in a read-only transaction",
254 * PreventCommandDuringRecovery: throw error if RecoveryInProgress
256 * The majority of operations that are unsafe in a Hot Standby slave
257 * will be rejected by XactReadOnly tests. However there are a few
258 * commands that are allowed in "read-only" xacts but cannot be allowed
259 * in Hot Standby mode. Those commands should call this function.
262 PreventCommandDuringRecovery(const char *cmdname)
264 if (RecoveryInProgress())
266 (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
267 /* translator: %s is name of a SQL command, eg CREATE */
268 errmsg("cannot execute %s during recovery",
273 * CheckRestrictedOperation: throw error for hazardous command if we're
274 * inside a security restriction context.
276 * This is needed to protect session-local state for which there is not any
277 * better-defined protection mechanism, such as ownership.
280 CheckRestrictedOperation(const char *cmdname)
282 if (InSecurityRestrictedOperation())
284 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
285 /* translator: %s is name of a SQL command, eg PREPARE */
286 errmsg("cannot execute %s within security-restricted operation",
293 * general utility function invoker
295 * parsetree: the parse tree for the utility statement
296 * queryString: original source text of command
297 * params: parameters to use during execution
298 * isTopLevel: true if executing a "top level" (interactively issued) command
299 * dest: where to send results
300 * completionTag: points to a buffer of size COMPLETION_TAG_BUFSIZE
301 * in which to store a command completion status string.
303 * Notes: as of PG 8.4, caller MUST supply a queryString; it is not
304 * allowed anymore to pass NULL. (If you really don't have source text,
305 * you can pass a constant string, perhaps "(query not available)".)
307 * completionTag is only set nonempty if we want to return a nondefault status.
309 * completionTag may be NULL if caller doesn't want a status string.
312 ProcessUtility(Node *parsetree,
313 const char *queryString,
314 ParamListInfo params,
319 Assert(queryString != NULL); /* required as of 8.4 */
322 * We provide a function hook variable that lets loadable plugins get
323 * control when ProcessUtility is called. Such a plugin would normally
324 * call standard_ProcessUtility().
326 if (ProcessUtility_hook)
327 (*ProcessUtility_hook) (parsetree, queryString, params,
328 isTopLevel, dest, completionTag);
330 standard_ProcessUtility(parsetree, queryString, params,
331 isTopLevel, dest, completionTag);
335 standard_ProcessUtility(Node *parsetree,
336 const char *queryString,
337 ParamListInfo params,
342 check_xact_readonly(parsetree);
345 completionTag[0] = '\0';
347 switch (nodeTag(parsetree))
350 * ******************** transactions ********************
352 case T_TransactionStmt:
354 TransactionStmt *stmt = (TransactionStmt *) parsetree;
359 * START TRANSACTION, as defined by SQL99: Identical
360 * to BEGIN. Same code for both.
362 case TRANS_STMT_BEGIN:
363 case TRANS_STMT_START:
367 BeginTransactionBlock();
368 foreach(lc, stmt->options)
370 DefElem *item = (DefElem *) lfirst(lc);
372 if (strcmp(item->defname, "transaction_isolation") == 0)
373 SetPGVariable("transaction_isolation",
374 list_make1(item->arg),
376 else if (strcmp(item->defname, "transaction_read_only") == 0)
377 SetPGVariable("transaction_read_only",
378 list_make1(item->arg),
380 else if (strcmp(item->defname, "transaction_deferrable") == 0)
381 SetPGVariable("transaction_deferrable",
382 list_make1(item->arg),
388 case TRANS_STMT_COMMIT:
389 if (!EndTransactionBlock())
391 /* report unsuccessful commit in completionTag */
393 strcpy(completionTag, "ROLLBACK");
397 case TRANS_STMT_PREPARE:
398 PreventCommandDuringRecovery("PREPARE TRANSACTION");
399 if (!PrepareTransactionBlock(stmt->gid))
401 /* report unsuccessful commit in completionTag */
403 strcpy(completionTag, "ROLLBACK");
407 case TRANS_STMT_COMMIT_PREPARED:
408 PreventTransactionChain(isTopLevel, "COMMIT PREPARED");
409 PreventCommandDuringRecovery("COMMIT PREPARED");
410 FinishPreparedTransaction(stmt->gid, true);
413 case TRANS_STMT_ROLLBACK_PREPARED:
414 PreventTransactionChain(isTopLevel, "ROLLBACK PREPARED");
415 PreventCommandDuringRecovery("ROLLBACK PREPARED");
416 FinishPreparedTransaction(stmt->gid, false);
419 case TRANS_STMT_ROLLBACK:
420 UserAbortTransactionBlock();
423 case TRANS_STMT_SAVEPOINT:
428 RequireTransactionChain(isTopLevel, "SAVEPOINT");
430 foreach(cell, stmt->options)
432 DefElem *elem = lfirst(cell);
434 if (strcmp(elem->defname, "savepoint_name") == 0)
435 name = strVal(elem->arg);
438 Assert(PointerIsValid(name));
440 DefineSavepoint(name);
444 case TRANS_STMT_RELEASE:
445 RequireTransactionChain(isTopLevel, "RELEASE SAVEPOINT");
446 ReleaseSavepoint(stmt->options);
449 case TRANS_STMT_ROLLBACK_TO:
450 RequireTransactionChain(isTopLevel, "ROLLBACK TO SAVEPOINT");
451 RollbackToSavepoint(stmt->options);
454 * CommitTransactionCommand is in charge of
455 * re-defining the savepoint again
463 * Portal (cursor) manipulation
465 * Note: DECLARE CURSOR is processed mostly as a SELECT, and
466 * therefore what we will get here is a PlannedStmt not a bare
471 PlannedStmt *stmt = (PlannedStmt *) parsetree;
473 if (stmt->utilityStmt == NULL ||
474 !IsA(stmt->utilityStmt, DeclareCursorStmt))
475 elog(ERROR, "non-DECLARE CURSOR PlannedStmt passed to ProcessUtility");
476 PerformCursorOpen(stmt, params, queryString, isTopLevel);
480 case T_ClosePortalStmt:
482 ClosePortalStmt *stmt = (ClosePortalStmt *) parsetree;
484 CheckRestrictedOperation("CLOSE");
485 PerformPortalClose(stmt->portalname);
490 PerformPortalFetch((FetchStmt *) parsetree, dest,
495 * relation and attribute manipulation
497 case T_CreateSchemaStmt:
498 CreateSchemaCommand((CreateSchemaStmt *) parsetree,
503 case T_CreateForeignTableStmt:
509 /* Run parse analysis ... */
510 stmts = transformCreateStmt((CreateStmt *) parsetree,
516 Node *stmt = (Node *) lfirst(l);
518 if (IsA(stmt, CreateStmt))
521 static char *validnsps[] = HEAP_RELOPT_NAMESPACES;
523 /* Create the table itself */
524 relOid = DefineRelation((CreateStmt *) stmt,
529 * If "IF NOT EXISTS" was specified and the relation
530 * already exists, do nothing further.
532 if (relOid == InvalidOid)
536 * Let AlterTableCreateToastTable decide if this one
537 * needs a secondary relation too.
539 CommandCounterIncrement();
541 /* parse and validate reloptions for the toast table */
542 toast_options = transformRelOptions((Datum) 0,
543 ((CreateStmt *) stmt)->options,
547 (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options,
550 AlterTableCreateToastTable(relOid, toast_options);
552 else if (IsA(stmt, CreateForeignTableStmt))
554 /* Create the table itself */
555 relOid = DefineRelation((CreateStmt *) stmt,
556 RELKIND_FOREIGN_TABLE,
560 * Unless "IF NOT EXISTS" was specified and the
561 * relation already exists, create the pg_foreign_table
564 if (relOid != InvalidOid)
565 CreateForeignTable((CreateForeignTableStmt *) stmt,
570 /* Recurse for anything else */
579 /* Need CCI between commands */
580 if (lnext(l) != NULL)
581 CommandCounterIncrement();
586 case T_CreateTableSpaceStmt:
587 PreventTransactionChain(isTopLevel, "CREATE TABLESPACE");
588 CreateTableSpace((CreateTableSpaceStmt *) parsetree);
591 case T_DropTableSpaceStmt:
592 PreventTransactionChain(isTopLevel, "DROP TABLESPACE");
593 DropTableSpace((DropTableSpaceStmt *) parsetree);
596 case T_AlterTableSpaceOptionsStmt:
597 AlterTableSpaceOptions((AlterTableSpaceOptionsStmt *) parsetree);
600 case T_CreateExtensionStmt:
601 CreateExtension((CreateExtensionStmt *) parsetree);
604 case T_AlterExtensionContentsStmt:
605 ExecAlterExtensionContentsStmt((AlterExtensionContentsStmt *) parsetree);
608 case T_CreateFdwStmt:
609 CreateForeignDataWrapper((CreateFdwStmt *) parsetree);
613 AlterForeignDataWrapper((AlterFdwStmt *) parsetree);
617 RemoveForeignDataWrapper((DropFdwStmt *) parsetree);
620 case T_CreateForeignServerStmt:
621 CreateForeignServer((CreateForeignServerStmt *) parsetree);
624 case T_AlterForeignServerStmt:
625 AlterForeignServer((AlterForeignServerStmt *) parsetree);
628 case T_DropForeignServerStmt:
629 RemoveForeignServer((DropForeignServerStmt *) parsetree);
632 case T_CreateUserMappingStmt:
633 CreateUserMapping((CreateUserMappingStmt *) parsetree);
636 case T_AlterUserMappingStmt:
637 AlterUserMapping((AlterUserMappingStmt *) parsetree);
640 case T_DropUserMappingStmt:
641 RemoveUserMapping((DropUserMappingStmt *) parsetree);
646 DropStmt *stmt = (DropStmt *) parsetree;
648 switch (stmt->removeType)
651 case OBJECT_SEQUENCE:
654 case OBJECT_FOREIGN_TABLE:
655 RemoveRelations(stmt);
663 case OBJECT_CONVERSION:
664 DropConversionsCommand(stmt);
671 case OBJECT_TSPARSER:
672 RemoveTSParsers(stmt);
675 case OBJECT_TSDICTIONARY:
676 RemoveTSDictionaries(stmt);
679 case OBJECT_TSTEMPLATE:
680 RemoveTSTemplates(stmt);
683 case OBJECT_TSCONFIGURATION:
684 RemoveTSConfigurations(stmt);
687 case OBJECT_EXTENSION:
688 RemoveExtensions(stmt);
692 elog(ERROR, "unrecognized drop object type: %d",
693 (int) stmt->removeType);
700 ExecuteTruncate((TruncateStmt *) parsetree);
704 CommentObject((CommentStmt *) parsetree);
708 ExecSecLabelStmt((SecLabelStmt *) parsetree);
715 processed = DoCopy((CopyStmt *) parsetree, queryString);
717 snprintf(completionTag, COMPLETION_TAG_BUFSIZE,
718 "COPY " UINT64_FORMAT, processed);
723 CheckRestrictedOperation("PREPARE");
724 PrepareQuery((PrepareStmt *) parsetree, queryString);
728 ExecuteQuery((ExecuteStmt *) parsetree, queryString, params,
729 dest, completionTag);
732 case T_DeallocateStmt:
733 CheckRestrictedOperation("DEALLOCATE");
734 DeallocateQuery((DeallocateStmt *) parsetree);
741 ExecRenameStmt((RenameStmt *) parsetree);
744 case T_AlterObjectSchemaStmt:
745 ExecAlterObjectSchemaStmt((AlterObjectSchemaStmt *) parsetree);
748 case T_AlterOwnerStmt:
749 ExecAlterOwnerStmt((AlterOwnerStmt *) parsetree);
752 case T_AlterTableStmt:
757 /* Run parse analysis ... */
758 stmts = transformAlterTableStmt((AlterTableStmt *) parsetree,
764 Node *stmt = (Node *) lfirst(l);
766 if (IsA(stmt, AlterTableStmt))
768 /* Do the table alteration proper */
769 AlterTable((AlterTableStmt *) stmt);
773 /* Recurse for anything else */
782 /* Need CCI between commands */
783 if (lnext(l) != NULL)
784 CommandCounterIncrement();
789 case T_AlterDomainStmt:
791 AlterDomainStmt *stmt = (AlterDomainStmt *) parsetree;
794 * Some or all of these functions are recursive to cover
795 * inherited things, so permission checks are done there.
797 switch (stmt->subtype)
799 case 'T': /* ALTER DOMAIN DEFAULT */
802 * Recursively alter column default for table and, if
803 * requested, for descendants
805 AlterDomainDefault(stmt->typeName,
808 case 'N': /* ALTER DOMAIN DROP NOT NULL */
809 AlterDomainNotNull(stmt->typeName,
812 case 'O': /* ALTER DOMAIN SET NOT NULL */
813 AlterDomainNotNull(stmt->typeName,
816 case 'C': /* ADD CONSTRAINT */
817 AlterDomainAddConstraint(stmt->typeName,
820 case 'X': /* DROP CONSTRAINT */
821 AlterDomainDropConstraint(stmt->typeName,
826 elog(ERROR, "unrecognized alter domain type: %d",
827 (int) stmt->subtype);
834 ExecuteGrantStmt((GrantStmt *) parsetree);
837 case T_GrantRoleStmt:
838 GrantRole((GrantRoleStmt *) parsetree);
841 case T_AlterDefaultPrivilegesStmt:
842 ExecAlterDefaultPrivilegesStmt((AlterDefaultPrivilegesStmt *) parsetree);
846 * **************** object creation / destruction *****************
850 DefineStmt *stmt = (DefineStmt *) parsetree;
854 case OBJECT_AGGREGATE:
855 DefineAggregate(stmt->defnames, stmt->args,
856 stmt->oldstyle, stmt->definition);
858 case OBJECT_OPERATOR:
859 Assert(stmt->args == NIL);
860 DefineOperator(stmt->defnames, stmt->definition);
863 Assert(stmt->args == NIL);
864 DefineType(stmt->defnames, stmt->definition);
866 case OBJECT_TSPARSER:
867 Assert(stmt->args == NIL);
868 DefineTSParser(stmt->defnames, stmt->definition);
870 case OBJECT_TSDICTIONARY:
871 Assert(stmt->args == NIL);
872 DefineTSDictionary(stmt->defnames, stmt->definition);
874 case OBJECT_TSTEMPLATE:
875 Assert(stmt->args == NIL);
876 DefineTSTemplate(stmt->defnames, stmt->definition);
878 case OBJECT_TSCONFIGURATION:
879 Assert(stmt->args == NIL);
880 DefineTSConfiguration(stmt->defnames, stmt->definition);
883 elog(ERROR, "unrecognized define stmt type: %d",
890 case T_CompositeTypeStmt: /* CREATE TYPE (composite) */
892 CompositeTypeStmt *stmt = (CompositeTypeStmt *) parsetree;
894 DefineCompositeType(stmt->typevar, stmt->coldeflist);
898 case T_CreateEnumStmt: /* CREATE TYPE (enum) */
899 DefineEnum((CreateEnumStmt *) parsetree);
902 case T_AlterEnumStmt: /* ALTER TYPE (enum) */
904 * We disallow this in transaction blocks, because we can't cope
905 * with enum OID values getting into indexes and then having their
906 * defining pg_enum entries go away.
908 PreventTransactionChain(isTopLevel, "ALTER TYPE ... ADD");
909 AlterEnum((AlterEnumStmt *) parsetree);
912 case T_ViewStmt: /* CREATE VIEW */
913 DefineView((ViewStmt *) parsetree, queryString);
916 case T_CreateFunctionStmt: /* CREATE FUNCTION */
917 CreateFunction((CreateFunctionStmt *) parsetree, queryString);
920 case T_AlterFunctionStmt: /* ALTER FUNCTION */
921 AlterFunction((AlterFunctionStmt *) parsetree);
924 case T_IndexStmt: /* CREATE INDEX */
926 IndexStmt *stmt = (IndexStmt *) parsetree;
928 if (stmt->concurrent)
929 PreventTransactionChain(isTopLevel,
930 "CREATE INDEX CONCURRENTLY");
932 CheckRelationOwnership(stmt->relation, true);
934 /* Run parse analysis ... */
935 stmt = transformIndexStmt(stmt, queryString);
938 DefineIndex(stmt->relation, /* relation */
939 stmt->idxname, /* index name */
940 InvalidOid, /* no predefined OID */
941 stmt->accessMethod, /* am name */
943 stmt->indexParams, /* parameters */
944 (Expr *) stmt->whereClause,
946 stmt->excludeOpNames,
952 false, /* is_alter_table */
953 true, /* check_rights */
954 false, /* skip_build */
956 stmt->concurrent); /* concurrent */
960 case T_RuleStmt: /* CREATE RULE */
961 DefineRule((RuleStmt *) parsetree, queryString);
964 case T_CreateSeqStmt:
965 DefineSequence((CreateSeqStmt *) parsetree);
969 AlterSequence((AlterSeqStmt *) parsetree);
972 case T_RemoveFuncStmt:
974 RemoveFuncStmt *stmt = (RemoveFuncStmt *) parsetree;
978 case OBJECT_FUNCTION:
979 RemoveFunction(stmt);
981 case OBJECT_AGGREGATE:
982 RemoveAggregate(stmt);
984 case OBJECT_OPERATOR:
985 RemoveOperator(stmt);
988 elog(ERROR, "unrecognized object type: %d",
996 ExecuteDoStmt((DoStmt *) parsetree);
1000 PreventTransactionChain(isTopLevel, "CREATE DATABASE");
1001 createdb((CreatedbStmt *) parsetree);
1004 case T_AlterDatabaseStmt:
1005 AlterDatabase((AlterDatabaseStmt *) parsetree, isTopLevel);
1008 case T_AlterDatabaseSetStmt:
1009 AlterDatabaseSet((AlterDatabaseSetStmt *) parsetree);
1014 DropdbStmt *stmt = (DropdbStmt *) parsetree;
1016 PreventTransactionChain(isTopLevel, "DROP DATABASE");
1017 dropdb(stmt->dbname, stmt->missing_ok);
1021 /* Query-level asynchronous notification */
1024 NotifyStmt *stmt = (NotifyStmt *) parsetree;
1026 PreventCommandDuringRecovery("NOTIFY");
1027 Async_Notify(stmt->conditionname, stmt->payload);
1033 ListenStmt *stmt = (ListenStmt *) parsetree;
1035 PreventCommandDuringRecovery("LISTEN");
1036 CheckRestrictedOperation("LISTEN");
1037 Async_Listen(stmt->conditionname);
1041 case T_UnlistenStmt:
1043 UnlistenStmt *stmt = (UnlistenStmt *) parsetree;
1045 PreventCommandDuringRecovery("UNLISTEN");
1046 CheckRestrictedOperation("UNLISTEN");
1047 if (stmt->conditionname)
1048 Async_Unlisten(stmt->conditionname);
1050 Async_UnlistenAll();
1056 LoadStmt *stmt = (LoadStmt *) parsetree;
1058 closeAllVfds(); /* probably not necessary... */
1059 /* Allowed names are restricted if you're not superuser */
1060 load_file(stmt->filename, !superuser());
1065 /* we choose to allow this during "read only" transactions */
1066 PreventCommandDuringRecovery("CLUSTER");
1067 cluster((ClusterStmt *) parsetree, isTopLevel);
1071 /* we choose to allow this during "read only" transactions */
1072 PreventCommandDuringRecovery("VACUUM");
1073 vacuum((VacuumStmt *) parsetree, InvalidOid, true, NULL, false,
1078 ExplainQuery((ExplainStmt *) parsetree, queryString, params, dest);
1081 case T_VariableSetStmt:
1082 ExecSetVariableStmt((VariableSetStmt *) parsetree);
1085 case T_VariableShowStmt:
1087 VariableShowStmt *n = (VariableShowStmt *) parsetree;
1089 GetPGVariable(n->name, dest);
1094 /* should we allow DISCARD PLANS? */
1095 CheckRestrictedOperation("DISCARD");
1096 DiscardCommand((DiscardStmt *) parsetree, isTopLevel);
1099 case T_CreateTrigStmt:
1100 (void) CreateTrigger((CreateTrigStmt *) parsetree, queryString,
1101 InvalidOid, InvalidOid, false);
1104 case T_DropPropertyStmt:
1106 DropPropertyStmt *stmt = (DropPropertyStmt *) parsetree;
1109 relId = RangeVarGetRelid(stmt->relation, false);
1111 switch (stmt->removeType)
1114 /* RemoveRewriteRule checks permissions */
1115 RemoveRewriteRule(relId, stmt->property,
1116 stmt->behavior, stmt->missing_ok);
1118 case OBJECT_TRIGGER:
1119 /* DropTrigger checks permissions */
1120 DropTrigger(relId, stmt->property,
1121 stmt->behavior, stmt->missing_ok);
1124 elog(ERROR, "unrecognized object type: %d",
1125 (int) stmt->removeType);
1131 case T_CreatePLangStmt:
1132 CreateProceduralLanguage((CreatePLangStmt *) parsetree);
1135 case T_DropPLangStmt:
1136 DropProceduralLanguage((DropPLangStmt *) parsetree);
1140 * ******************************** DOMAIN statements ****
1142 case T_CreateDomainStmt:
1143 DefineDomain((CreateDomainStmt *) parsetree);
1147 * ******************************** ROLE statements ****
1149 case T_CreateRoleStmt:
1150 CreateRole((CreateRoleStmt *) parsetree);
1153 case T_AlterRoleStmt:
1154 AlterRole((AlterRoleStmt *) parsetree);
1157 case T_AlterRoleSetStmt:
1158 AlterRoleSet((AlterRoleSetStmt *) parsetree);
1161 case T_DropRoleStmt:
1162 DropRole((DropRoleStmt *) parsetree);
1165 case T_DropOwnedStmt:
1166 DropOwnedObjects((DropOwnedStmt *) parsetree);
1169 case T_ReassignOwnedStmt:
1170 ReassignOwnedObjects((ReassignOwnedStmt *) parsetree);
1176 * Since the lock would just get dropped immediately, LOCK TABLE
1177 * outside a transaction block is presumed to be user error.
1179 RequireTransactionChain(isTopLevel, "LOCK TABLE");
1180 LockTableCommand((LockStmt *) parsetree);
1183 case T_ConstraintsSetStmt:
1184 AfterTriggerSetState((ConstraintsSetStmt *) parsetree);
1187 case T_CheckPointStmt:
1190 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1191 errmsg("must be superuser to do CHECKPOINT")));
1194 * You might think we should have a PreventCommandDuringRecovery()
1195 * here, but we interpret a CHECKPOINT command during recovery as
1196 * a request for a restartpoint instead. We allow this since it
1197 * can be a useful way of reducing switchover time when using
1198 * various forms of replication.
1200 RequestCheckpoint(CHECKPOINT_IMMEDIATE | CHECKPOINT_WAIT |
1201 (RecoveryInProgress() ? 0 : CHECKPOINT_FORCE));
1206 ReindexStmt *stmt = (ReindexStmt *) parsetree;
1208 /* we choose to allow this during "read only" transactions */
1209 PreventCommandDuringRecovery("REINDEX");
1213 ReindexIndex(stmt->relation);
1216 ReindexTable(stmt->relation);
1218 case OBJECT_DATABASE:
1221 * This cannot run inside a user transaction block; if
1222 * we were inside a transaction, then its commit- and
1223 * start-transaction-command calls would not have the
1226 PreventTransactionChain(isTopLevel,
1227 "REINDEX DATABASE");
1228 ReindexDatabase(stmt->name,
1229 stmt->do_system, stmt->do_user);
1232 elog(ERROR, "unrecognized object type: %d",
1240 case T_CreateConversionStmt:
1241 CreateConversionCommand((CreateConversionStmt *) parsetree);
1244 case T_CreateCastStmt:
1245 CreateCast((CreateCastStmt *) parsetree);
1248 case T_DropCastStmt:
1249 DropCast((DropCastStmt *) parsetree);
1252 case T_CreateOpClassStmt:
1253 DefineOpClass((CreateOpClassStmt *) parsetree);
1256 case T_CreateOpFamilyStmt:
1257 DefineOpFamily((CreateOpFamilyStmt *) parsetree);
1260 case T_AlterOpFamilyStmt:
1261 AlterOpFamily((AlterOpFamilyStmt *) parsetree);
1264 case T_RemoveOpClassStmt:
1265 RemoveOpClass((RemoveOpClassStmt *) parsetree);
1268 case T_RemoveOpFamilyStmt:
1269 RemoveOpFamily((RemoveOpFamilyStmt *) parsetree);
1272 case T_AlterTSDictionaryStmt:
1273 AlterTSDictionary((AlterTSDictionaryStmt *) parsetree);
1276 case T_AlterTSConfigurationStmt:
1277 AlterTSConfiguration((AlterTSConfigurationStmt *) parsetree);
1281 elog(ERROR, "unrecognized node type: %d",
1282 (int) nodeTag(parsetree));
1288 * UtilityReturnsTuples
1289 * Return "true" if this utility statement will send output to the
1292 * Generally, there should be a case here for each case in ProcessUtility
1293 * where "dest" is passed on.
1296 UtilityReturnsTuples(Node *parsetree)
1298 switch (nodeTag(parsetree))
1302 FetchStmt *stmt = (FetchStmt *) parsetree;
1307 portal = GetPortalByName(stmt->portalname);
1308 if (!PortalIsValid(portal))
1309 return false; /* not our business to raise error */
1310 return portal->tupDesc ? true : false;
1315 ExecuteStmt *stmt = (ExecuteStmt *) parsetree;
1316 PreparedStatement *entry;
1320 entry = FetchPreparedStatement(stmt->name, false);
1322 return false; /* not our business to raise error */
1323 if (entry->plansource->resultDesc)
1331 case T_VariableShowStmt:
1340 * UtilityTupleDescriptor
1341 * Fetch the actual output tuple descriptor for a utility statement
1342 * for which UtilityReturnsTuples() previously returned "true".
1344 * The returned descriptor is created in (or copied into) the current memory
1348 UtilityTupleDescriptor(Node *parsetree)
1350 switch (nodeTag(parsetree))
1354 FetchStmt *stmt = (FetchStmt *) parsetree;
1359 portal = GetPortalByName(stmt->portalname);
1360 if (!PortalIsValid(portal))
1361 return NULL; /* not our business to raise error */
1362 return CreateTupleDescCopy(portal->tupDesc);
1367 ExecuteStmt *stmt = (ExecuteStmt *) parsetree;
1368 PreparedStatement *entry;
1372 entry = FetchPreparedStatement(stmt->name, false);
1374 return NULL; /* not our business to raise error */
1375 return FetchPreparedStatementResultDesc(entry);
1379 return ExplainResultDesc((ExplainStmt *) parsetree);
1381 case T_VariableShowStmt:
1383 VariableShowStmt *n = (VariableShowStmt *) parsetree;
1385 return GetPGVariableResultDesc(n->name);
1395 * QueryReturnsTuples
1396 * Return "true" if this Query will send output to the destination.
1400 QueryReturnsTuples(Query *parsetree)
1402 switch (parsetree->commandType)
1405 /* returns tuples ... unless it's DECLARE CURSOR or SELECT INTO */
1406 if (parsetree->utilityStmt == NULL &&
1407 parsetree->intoClause == NULL)
1413 /* the forms with RETURNING return tuples */
1414 if (parsetree->returningList)
1418 return UtilityReturnsTuples(parsetree->utilityStmt);
1421 /* probably shouldn't get here */
1424 return false; /* default */
1430 * AlterObjectTypeCommandTag
1431 * helper function for CreateCommandTag
1433 * This covers most cases where ALTER is used with an ObjectType enum.
1436 AlterObjectTypeCommandTag(ObjectType objtype)
1442 case OBJECT_AGGREGATE:
1443 tag = "ALTER AGGREGATE";
1445 case OBJECT_ATTRIBUTE:
1452 tag = "ALTER TABLE";
1454 case OBJECT_CONSTRAINT:
1455 tag = "ALTER TABLE";
1457 case OBJECT_CONVERSION:
1458 tag = "ALTER CONVERSION";
1460 case OBJECT_DATABASE:
1461 tag = "ALTER DATABASE";
1464 tag = "ALTER DOMAIN";
1466 case OBJECT_EXTENSION:
1467 tag = "ALTER EXTENSION";
1470 tag = "ALTER FOREIGN DATA WRAPPER";
1472 case OBJECT_FOREIGN_SERVER:
1473 tag = "ALTER SERVER";
1475 case OBJECT_FOREIGN_TABLE:
1476 tag = "ALTER FOREIGN TABLE";
1478 case OBJECT_FUNCTION:
1479 tag = "ALTER FUNCTION";
1482 tag = "ALTER INDEX";
1484 case OBJECT_LANGUAGE:
1485 tag = "ALTER LANGUAGE";
1487 case OBJECT_LARGEOBJECT:
1488 tag = "ALTER LARGE OBJECT";
1490 case OBJECT_OPCLASS:
1491 tag = "ALTER OPERATOR CLASS";
1493 case OBJECT_OPERATOR:
1494 tag = "ALTER OPERATOR";
1496 case OBJECT_OPFAMILY:
1497 tag = "ALTER OPERATOR FAMILY";
1506 tag = "ALTER SCHEMA";
1508 case OBJECT_SEQUENCE:
1509 tag = "ALTER SEQUENCE";
1512 tag = "ALTER TABLE";
1514 case OBJECT_TABLESPACE:
1515 tag = "ALTER TABLESPACE";
1517 case OBJECT_TRIGGER:
1518 tag = "ALTER TRIGGER";
1520 case OBJECT_TSCONFIGURATION:
1521 tag = "ALTER TEXT SEARCH CONFIGURATION";
1523 case OBJECT_TSDICTIONARY:
1524 tag = "ALTER TEXT SEARCH DICTIONARY";
1526 case OBJECT_TSPARSER:
1527 tag = "ALTER TEXT SEARCH PARSER";
1529 case OBJECT_TSTEMPLATE:
1530 tag = "ALTER TEXT SEARCH TEMPLATE";
1548 * utility to get a string representation of the command operation,
1549 * given either a raw (un-analyzed) parsetree or a planned query.
1551 * This must handle all command types, but since the vast majority
1552 * of 'em are utility commands, it seems sensible to keep it here.
1554 * NB: all result strings must be shorter than COMPLETION_TAG_BUFSIZE.
1555 * Also, the result must point at a true constant (permanent storage).
1558 CreateCommandTag(Node *parsetree)
1562 switch (nodeTag(parsetree))
1564 /* raw plannable queries */
1581 /* utility statements --- same whether raw or cooked */
1582 case T_TransactionStmt:
1584 TransactionStmt *stmt = (TransactionStmt *) parsetree;
1588 case TRANS_STMT_BEGIN:
1592 case TRANS_STMT_START:
1593 tag = "START TRANSACTION";
1596 case TRANS_STMT_COMMIT:
1600 case TRANS_STMT_ROLLBACK:
1601 case TRANS_STMT_ROLLBACK_TO:
1605 case TRANS_STMT_SAVEPOINT:
1609 case TRANS_STMT_RELEASE:
1613 case TRANS_STMT_PREPARE:
1614 tag = "PREPARE TRANSACTION";
1617 case TRANS_STMT_COMMIT_PREPARED:
1618 tag = "COMMIT PREPARED";
1621 case TRANS_STMT_ROLLBACK_PREPARED:
1622 tag = "ROLLBACK PREPARED";
1632 case T_DeclareCursorStmt:
1633 tag = "DECLARE CURSOR";
1636 case T_ClosePortalStmt:
1638 ClosePortalStmt *stmt = (ClosePortalStmt *) parsetree;
1640 if (stmt->portalname == NULL)
1641 tag = "CLOSE CURSOR ALL";
1643 tag = "CLOSE CURSOR";
1649 FetchStmt *stmt = (FetchStmt *) parsetree;
1651 tag = (stmt->ismove) ? "MOVE" : "FETCH";
1655 case T_CreateDomainStmt:
1656 tag = "CREATE DOMAIN";
1659 case T_CreateSchemaStmt:
1660 tag = "CREATE SCHEMA";
1664 tag = "CREATE TABLE";
1667 case T_CreateTableSpaceStmt:
1668 tag = "CREATE TABLESPACE";
1671 case T_DropTableSpaceStmt:
1672 tag = "DROP TABLESPACE";
1675 case T_AlterTableSpaceOptionsStmt:
1676 tag = "ALTER TABLESPACE";
1679 case T_CreateExtensionStmt:
1680 tag = "CREATE EXTENSION";
1683 case T_AlterExtensionContentsStmt:
1684 tag = "ALTER EXTENSION";
1687 case T_CreateFdwStmt:
1688 tag = "CREATE FOREIGN DATA WRAPPER";
1691 case T_AlterFdwStmt:
1692 tag = "ALTER FOREIGN DATA WRAPPER";
1696 tag = "DROP FOREIGN DATA WRAPPER";
1699 case T_CreateForeignServerStmt:
1700 tag = "CREATE SERVER";
1703 case T_AlterForeignServerStmt:
1704 tag = "ALTER SERVER";
1707 case T_DropForeignServerStmt:
1708 tag = "DROP SERVER";
1711 case T_CreateUserMappingStmt:
1712 tag = "CREATE USER MAPPING";
1715 case T_AlterUserMappingStmt:
1716 tag = "ALTER USER MAPPING";
1719 case T_DropUserMappingStmt:
1720 tag = "DROP USER MAPPING";
1723 case T_CreateForeignTableStmt:
1724 tag = "CREATE FOREIGN TABLE";
1728 switch (((DropStmt *) parsetree)->removeType)
1733 case OBJECT_SEQUENCE:
1734 tag = "DROP SEQUENCE";
1746 tag = "DROP DOMAIN";
1748 case OBJECT_CONVERSION:
1749 tag = "DROP CONVERSION";
1752 tag = "DROP SCHEMA";
1754 case OBJECT_TSPARSER:
1755 tag = "DROP TEXT SEARCH PARSER";
1757 case OBJECT_TSDICTIONARY:
1758 tag = "DROP TEXT SEARCH DICTIONARY";
1760 case OBJECT_TSTEMPLATE:
1761 tag = "DROP TEXT SEARCH TEMPLATE";
1763 case OBJECT_TSCONFIGURATION:
1764 tag = "DROP TEXT SEARCH CONFIGURATION";
1766 case OBJECT_FOREIGN_TABLE:
1767 tag = "DROP FOREIGN TABLE";
1769 case OBJECT_EXTENSION:
1770 tag = "DROP EXTENSION";
1777 case T_TruncateStmt:
1778 tag = "TRUNCATE TABLE";
1785 case T_SecLabelStmt:
1786 tag = "SECURITY LABEL";
1794 tag = AlterObjectTypeCommandTag(((RenameStmt *) parsetree)->renameType);
1797 case T_AlterObjectSchemaStmt:
1798 tag = AlterObjectTypeCommandTag(((AlterObjectSchemaStmt *) parsetree)->objectType);
1801 case T_AlterOwnerStmt:
1802 tag = AlterObjectTypeCommandTag(((AlterOwnerStmt *) parsetree)->objectType);
1805 case T_AlterTableStmt:
1806 tag = AlterObjectTypeCommandTag(((AlterTableStmt *) parsetree)->relkind);
1809 case T_AlterDomainStmt:
1810 tag = "ALTER DOMAIN";
1813 case T_AlterFunctionStmt:
1814 tag = "ALTER FUNCTION";
1819 GrantStmt *stmt = (GrantStmt *) parsetree;
1821 tag = (stmt->is_grant) ? "GRANT" : "REVOKE";
1825 case T_GrantRoleStmt:
1827 GrantRoleStmt *stmt = (GrantRoleStmt *) parsetree;
1829 tag = (stmt->is_grant) ? "GRANT ROLE" : "REVOKE ROLE";
1833 case T_AlterDefaultPrivilegesStmt:
1834 tag = "ALTER DEFAULT PRIVILEGES";
1838 switch (((DefineStmt *) parsetree)->kind)
1840 case OBJECT_AGGREGATE:
1841 tag = "CREATE AGGREGATE";
1843 case OBJECT_OPERATOR:
1844 tag = "CREATE OPERATOR";
1847 tag = "CREATE TYPE";
1849 case OBJECT_TSPARSER:
1850 tag = "CREATE TEXT SEARCH PARSER";
1852 case OBJECT_TSDICTIONARY:
1853 tag = "CREATE TEXT SEARCH DICTIONARY";
1855 case OBJECT_TSTEMPLATE:
1856 tag = "CREATE TEXT SEARCH TEMPLATE";
1858 case OBJECT_TSCONFIGURATION:
1859 tag = "CREATE TEXT SEARCH CONFIGURATION";
1866 case T_CompositeTypeStmt:
1867 tag = "CREATE TYPE";
1870 case T_CreateEnumStmt:
1871 tag = "CREATE TYPE";
1874 case T_AlterEnumStmt:
1879 tag = "CREATE VIEW";
1882 case T_CreateFunctionStmt:
1883 tag = "CREATE FUNCTION";
1887 tag = "CREATE INDEX";
1891 tag = "CREATE RULE";
1894 case T_CreateSeqStmt:
1895 tag = "CREATE SEQUENCE";
1898 case T_AlterSeqStmt:
1899 tag = "ALTER SEQUENCE";
1902 case T_RemoveFuncStmt:
1903 switch (((RemoveFuncStmt *) parsetree)->kind)
1905 case OBJECT_FUNCTION:
1906 tag = "DROP FUNCTION";
1908 case OBJECT_AGGREGATE:
1909 tag = "DROP AGGREGATE";
1911 case OBJECT_OPERATOR:
1912 tag = "DROP OPERATOR";
1923 case T_CreatedbStmt:
1924 tag = "CREATE DATABASE";
1927 case T_AlterDatabaseStmt:
1928 tag = "ALTER DATABASE";
1931 case T_AlterDatabaseSetStmt:
1932 tag = "ALTER DATABASE";
1936 tag = "DROP DATABASE";
1947 case T_UnlistenStmt:
1960 if (((VacuumStmt *) parsetree)->options & VACOPT_VACUUM)
1970 case T_VariableSetStmt:
1971 switch (((VariableSetStmt *) parsetree)->kind)
1974 case VAR_SET_CURRENT:
1975 case VAR_SET_DEFAULT:
1988 case T_VariableShowStmt:
1993 switch (((DiscardStmt *) parsetree)->target)
1996 tag = "DISCARD ALL";
1999 tag = "DISCARD PLANS";
2002 tag = "DISCARD TEMP";
2009 case T_CreateTrigStmt:
2010 tag = "CREATE TRIGGER";
2013 case T_DropPropertyStmt:
2014 switch (((DropPropertyStmt *) parsetree)->removeType)
2016 case OBJECT_TRIGGER:
2017 tag = "DROP TRIGGER";
2027 case T_CreatePLangStmt:
2028 tag = "CREATE LANGUAGE";
2031 case T_DropPLangStmt:
2032 tag = "DROP LANGUAGE";
2035 case T_CreateRoleStmt:
2036 tag = "CREATE ROLE";
2039 case T_AlterRoleStmt:
2043 case T_AlterRoleSetStmt:
2047 case T_DropRoleStmt:
2051 case T_DropOwnedStmt:
2055 case T_ReassignOwnedStmt:
2056 tag = "REASSIGN OWNED";
2063 case T_ConstraintsSetStmt:
2064 tag = "SET CONSTRAINTS";
2067 case T_CheckPointStmt:
2075 case T_CreateConversionStmt:
2076 tag = "CREATE CONVERSION";
2079 case T_CreateCastStmt:
2080 tag = "CREATE CAST";
2083 case T_DropCastStmt:
2087 case T_CreateOpClassStmt:
2088 tag = "CREATE OPERATOR CLASS";
2091 case T_CreateOpFamilyStmt:
2092 tag = "CREATE OPERATOR FAMILY";
2095 case T_AlterOpFamilyStmt:
2096 tag = "ALTER OPERATOR FAMILY";
2099 case T_RemoveOpClassStmt:
2100 tag = "DROP OPERATOR CLASS";
2103 case T_RemoveOpFamilyStmt:
2104 tag = "DROP OPERATOR FAMILY";
2107 case T_AlterTSDictionaryStmt:
2108 tag = "ALTER TEXT SEARCH DICTIONARY";
2111 case T_AlterTSConfigurationStmt:
2112 tag = "ALTER TEXT SEARCH CONFIGURATION";
2123 case T_DeallocateStmt:
2125 DeallocateStmt *stmt = (DeallocateStmt *) parsetree;
2127 if (stmt->name == NULL)
2128 tag = "DEALLOCATE ALL";
2134 /* already-planned queries */
2137 PlannedStmt *stmt = (PlannedStmt *) parsetree;
2139 switch (stmt->commandType)
2144 * We take a little extra care here so that the result
2145 * will be useful for complaints about read-only
2148 if (stmt->utilityStmt != NULL)
2150 Assert(IsA(stmt->utilityStmt, DeclareCursorStmt));
2151 tag = "DECLARE CURSOR";
2153 else if (stmt->intoClause != NULL)
2154 tag = "SELECT INTO";
2155 else if (stmt->rowMarks != NIL)
2157 /* not 100% but probably close enough */
2158 if (((PlanRowMark *) linitial(stmt->rowMarks))->markType == ROW_MARK_EXCLUSIVE)
2159 tag = "SELECT FOR UPDATE";
2161 tag = "SELECT FOR SHARE";
2176 elog(WARNING, "unrecognized commandType: %d",
2177 (int) stmt->commandType);
2184 /* parsed-and-rewritten-but-not-planned queries */
2187 Query *stmt = (Query *) parsetree;
2189 switch (stmt->commandType)
2194 * We take a little extra care here so that the result
2195 * will be useful for complaints about read-only
2198 if (stmt->utilityStmt != NULL)
2200 Assert(IsA(stmt->utilityStmt, DeclareCursorStmt));
2201 tag = "DECLARE CURSOR";
2203 else if (stmt->intoClause != NULL)
2204 tag = "SELECT INTO";
2205 else if (stmt->rowMarks != NIL)
2207 /* not 100% but probably close enough */
2208 if (((RowMarkClause *) linitial(stmt->rowMarks))->forUpdate)
2209 tag = "SELECT FOR UPDATE";
2211 tag = "SELECT FOR SHARE";
2226 tag = CreateCommandTag(stmt->utilityStmt);
2229 elog(WARNING, "unrecognized commandType: %d",
2230 (int) stmt->commandType);
2238 elog(WARNING, "unrecognized node type: %d",
2239 (int) nodeTag(parsetree));
2249 * GetCommandLogLevel
2250 * utility to get the minimum log_statement level for a command,
2251 * given either a raw (un-analyzed) parsetree or a planned query.
2253 * This must handle all command types, but since the vast majority
2254 * of 'em are utility commands, it seems sensible to keep it here.
2257 GetCommandLogLevel(Node *parsetree)
2261 switch (nodeTag(parsetree))
2263 /* raw plannable queries */
2271 if (((SelectStmt *) parsetree)->intoClause)
2272 lev = LOGSTMT_DDL; /* CREATE AS, SELECT INTO */
2277 /* utility statements --- same whether raw or cooked */
2278 case T_TransactionStmt:
2282 case T_DeclareCursorStmt:
2286 case T_ClosePortalStmt:
2294 case T_CreateSchemaStmt:
2299 case T_CreateForeignTableStmt:
2303 case T_CreateTableSpaceStmt:
2304 case T_DropTableSpaceStmt:
2305 case T_AlterTableSpaceOptionsStmt:
2309 case T_CreateExtensionStmt:
2310 case T_AlterExtensionContentsStmt:
2314 case T_CreateFdwStmt:
2315 case T_AlterFdwStmt:
2317 case T_CreateForeignServerStmt:
2318 case T_AlterForeignServerStmt:
2319 case T_DropForeignServerStmt:
2320 case T_CreateUserMappingStmt:
2321 case T_AlterUserMappingStmt:
2322 case T_DropUserMappingStmt:
2330 case T_TruncateStmt:
2338 case T_SecLabelStmt:
2343 if (((CopyStmt *) parsetree)->is_from)
2351 PrepareStmt *stmt = (PrepareStmt *) parsetree;
2353 /* Look through a PREPARE to the contained stmt */
2354 lev = GetCommandLogLevel(stmt->query);
2360 ExecuteStmt *stmt = (ExecuteStmt *) parsetree;
2361 PreparedStatement *ps;
2363 /* Look through an EXECUTE to the referenced stmt */
2364 ps = FetchPreparedStatement(stmt->name, false);
2366 lev = GetCommandLogLevel(ps->plansource->raw_parse_tree);
2372 case T_DeallocateStmt:
2380 case T_AlterObjectSchemaStmt:
2384 case T_AlterOwnerStmt:
2388 case T_AlterTableStmt:
2392 case T_AlterDomainStmt:
2400 case T_GrantRoleStmt:
2404 case T_AlterDefaultPrivilegesStmt:
2412 case T_CompositeTypeStmt:
2416 case T_CreateEnumStmt:
2420 case T_AlterEnumStmt:
2428 case T_CreateFunctionStmt:
2432 case T_AlterFunctionStmt:
2444 case T_CreateSeqStmt:
2448 case T_AlterSeqStmt:
2452 case T_RemoveFuncStmt:
2460 case T_CreatedbStmt:
2464 case T_AlterDatabaseStmt:
2468 case T_AlterDatabaseSetStmt:
2484 case T_UnlistenStmt:
2502 ExplainStmt *stmt = (ExplainStmt *) parsetree;
2503 bool analyze = false;
2506 /* Look through an EXPLAIN ANALYZE to the contained stmt */
2507 foreach(lc, stmt->options)
2509 DefElem *opt = (DefElem *) lfirst(lc);
2511 if (strcmp(opt->defname, "analyze") == 0)
2512 analyze = defGetBoolean(opt);
2513 /* don't "break", as explain.c will use the last value */
2516 return GetCommandLogLevel(stmt->query);
2518 /* Plain EXPLAIN isn't so interesting */
2523 case T_VariableSetStmt:
2527 case T_VariableShowStmt:
2535 case T_CreateTrigStmt:
2539 case T_DropPropertyStmt:
2543 case T_CreatePLangStmt:
2547 case T_DropPLangStmt:
2551 case T_CreateDomainStmt:
2555 case T_CreateRoleStmt:
2559 case T_AlterRoleStmt:
2563 case T_AlterRoleSetStmt:
2567 case T_DropRoleStmt:
2571 case T_DropOwnedStmt:
2575 case T_ReassignOwnedStmt:
2583 case T_ConstraintsSetStmt:
2587 case T_CheckPointStmt:
2592 lev = LOGSTMT_ALL; /* should this be DDL? */
2595 case T_CreateConversionStmt:
2599 case T_CreateCastStmt:
2603 case T_DropCastStmt:
2607 case T_CreateOpClassStmt:
2611 case T_CreateOpFamilyStmt:
2615 case T_AlterOpFamilyStmt:
2619 case T_RemoveOpClassStmt:
2623 case T_RemoveOpFamilyStmt:
2627 case T_AlterTSDictionaryStmt:
2631 case T_AlterTSConfigurationStmt:
2635 /* already-planned queries */
2638 PlannedStmt *stmt = (PlannedStmt *) parsetree;
2640 switch (stmt->commandType)
2643 if (stmt->intoClause != NULL)
2644 lev = LOGSTMT_DDL; /* CREATE AS, SELECT INTO */
2646 lev = LOGSTMT_ALL; /* SELECT or DECLARE CURSOR */
2656 elog(WARNING, "unrecognized commandType: %d",
2657 (int) stmt->commandType);
2664 /* parsed-and-rewritten-but-not-planned queries */
2667 Query *stmt = (Query *) parsetree;
2669 switch (stmt->commandType)
2672 if (stmt->intoClause != NULL)
2673 lev = LOGSTMT_DDL; /* CREATE AS, SELECT INTO */
2675 lev = LOGSTMT_ALL; /* SELECT or DECLARE CURSOR */
2685 lev = GetCommandLogLevel(stmt->utilityStmt);
2689 elog(WARNING, "unrecognized commandType: %d",
2690 (int) stmt->commandType);
2699 elog(WARNING, "unrecognized node type: %d",
2700 (int) nodeTag(parsetree));