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/collationcmds.h"
30 #include "commands/conversioncmds.h"
31 #include "commands/copy.h"
32 #include "commands/dbcommands.h"
33 #include "commands/defrem.h"
34 #include "commands/discard.h"
35 #include "commands/explain.h"
36 #include "commands/extension.h"
37 #include "commands/lockcmds.h"
38 #include "commands/portalcmds.h"
39 #include "commands/prepare.h"
40 #include "commands/proclang.h"
41 #include "commands/schemacmds.h"
42 #include "commands/seclabel.h"
43 #include "commands/sequence.h"
44 #include "commands/tablecmds.h"
45 #include "commands/tablespace.h"
46 #include "commands/trigger.h"
47 #include "commands/typecmds.h"
48 #include "commands/user.h"
49 #include "commands/vacuum.h"
50 #include "commands/view.h"
51 #include "miscadmin.h"
52 #include "parser/parse_utilcmd.h"
53 #include "postmaster/bgwriter.h"
54 #include "rewrite/rewriteDefine.h"
55 #include "rewrite/rewriteRemove.h"
56 #include "storage/fd.h"
57 #include "tcop/pquery.h"
58 #include "tcop/utility.h"
59 #include "utils/acl.h"
60 #include "utils/guc.h"
61 #include "utils/syscache.h"
64 /* Hook for plugins to get control in ProcessUtility() */
65 ProcessUtility_hook_type ProcessUtility_hook = NULL;
69 * Verify user has ownership of specified relation, else ereport.
71 * If noCatalogs is true then we also deny access to system catalogs,
72 * except when allowSystemTableMods is true.
75 CheckRelationOwnership(RangeVar *rel, bool noCatalogs)
81 * XXX: This is unsafe in the presence of concurrent DDL, since it is
82 * called before acquiring any lock on the target relation. However,
83 * locking the target relation (especially using something like
84 * AccessExclusiveLock) before verifying that the user has permissions
85 * is not appealing either.
87 relOid = RangeVarGetRelid(rel, NoLock, false, false);
89 tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relOid));
90 if (!HeapTupleIsValid(tuple)) /* should not happen */
91 elog(ERROR, "cache lookup failed for relation %u", relOid);
93 if (!pg_class_ownercheck(relOid, GetUserId()))
94 aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
99 if (!allowSystemTableMods &&
100 IsSystemClass((Form_pg_class) GETSTRUCT(tuple)))
102 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
103 errmsg("permission denied: \"%s\" is a system catalog",
107 ReleaseSysCache(tuple);
112 * CommandIsReadOnly: is an executable query read-only?
114 * This is a much stricter test than we apply for XactReadOnly mode;
115 * the query must be *in truth* read-only, because the caller wishes
116 * not to do CommandCounterIncrement for it.
118 * Note: currently no need to support Query nodes here
121 CommandIsReadOnly(Node *parsetree)
123 if (IsA(parsetree, PlannedStmt))
125 PlannedStmt *stmt = (PlannedStmt *) parsetree;
127 switch (stmt->commandType)
130 if (stmt->intoClause != NULL)
131 return false; /* SELECT INTO */
132 else 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_CreateConversionStmt:
189 case T_CreateDomainStmt:
190 case T_CreateFunctionStmt:
191 case T_CreateRoleStmt:
193 case T_CreatePLangStmt:
194 case T_CreateOpClassStmt:
195 case T_CreateOpFamilyStmt:
196 case T_AlterOpFamilyStmt:
198 case T_CreateSchemaStmt:
199 case T_CreateSeqStmt:
201 case T_CreateTableSpaceStmt:
202 case T_CreateTrigStmt:
203 case T_CompositeTypeStmt:
204 case T_CreateEnumStmt:
205 case T_AlterEnumStmt:
210 case T_DropTableSpaceStmt:
211 case T_RemoveFuncStmt:
213 case T_DropPLangStmt:
214 case T_RemoveOpClassStmt:
215 case T_RemoveOpFamilyStmt:
216 case T_DropPropertyStmt:
218 case T_GrantRoleStmt:
219 case T_AlterDefaultPrivilegesStmt:
221 case T_DropOwnedStmt:
222 case T_ReassignOwnedStmt:
223 case T_AlterTSDictionaryStmt:
224 case T_AlterTSConfigurationStmt:
225 case T_CreateExtensionStmt:
226 case T_AlterExtensionStmt:
227 case T_AlterExtensionContentsStmt:
228 case T_CreateFdwStmt:
231 case T_CreateForeignServerStmt:
232 case T_AlterForeignServerStmt:
233 case T_DropForeignServerStmt:
234 case T_CreateUserMappingStmt:
235 case T_AlterUserMappingStmt:
236 case T_DropUserMappingStmt:
237 case T_AlterTableSpaceOptionsStmt:
238 case T_CreateForeignTableStmt:
240 PreventCommandIfReadOnly(CreateCommandTag(parsetree));
249 * PreventCommandIfReadOnly: throw error if XactReadOnly
251 * This is useful mainly to ensure consistency of the error message wording;
252 * most callers have checked XactReadOnly for themselves.
255 PreventCommandIfReadOnly(const char *cmdname)
259 (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
260 /* translator: %s is name of a SQL command, eg CREATE */
261 errmsg("cannot execute %s in a read-only transaction",
266 * PreventCommandDuringRecovery: throw error if RecoveryInProgress
268 * The majority of operations that are unsafe in a Hot Standby slave
269 * will be rejected by XactReadOnly tests. However there are a few
270 * commands that are allowed in "read-only" xacts but cannot be allowed
271 * in Hot Standby mode. Those commands should call this function.
274 PreventCommandDuringRecovery(const char *cmdname)
276 if (RecoveryInProgress())
278 (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
279 /* translator: %s is name of a SQL command, eg CREATE */
280 errmsg("cannot execute %s during recovery",
285 * CheckRestrictedOperation: throw error for hazardous command if we're
286 * inside a security restriction context.
288 * This is needed to protect session-local state for which there is not any
289 * better-defined protection mechanism, such as ownership.
292 CheckRestrictedOperation(const char *cmdname)
294 if (InSecurityRestrictedOperation())
296 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
297 /* translator: %s is name of a SQL command, eg PREPARE */
298 errmsg("cannot execute %s within security-restricted operation",
305 * general utility function invoker
307 * parsetree: the parse tree for the utility statement
308 * queryString: original source text of command
309 * params: parameters to use during execution
310 * isTopLevel: true if executing a "top level" (interactively issued) command
311 * dest: where to send results
312 * completionTag: points to a buffer of size COMPLETION_TAG_BUFSIZE
313 * in which to store a command completion status string.
315 * Notes: as of PG 8.4, caller MUST supply a queryString; it is not
316 * allowed anymore to pass NULL. (If you really don't have source text,
317 * you can pass a constant string, perhaps "(query not available)".)
319 * completionTag is only set nonempty if we want to return a nondefault status.
321 * completionTag may be NULL if caller doesn't want a status string.
324 ProcessUtility(Node *parsetree,
325 const char *queryString,
326 ParamListInfo params,
331 Assert(queryString != NULL); /* required as of 8.4 */
334 * We provide a function hook variable that lets loadable plugins get
335 * control when ProcessUtility is called. Such a plugin would normally
336 * call standard_ProcessUtility().
338 if (ProcessUtility_hook)
339 (*ProcessUtility_hook) (parsetree, queryString, params,
340 isTopLevel, dest, completionTag);
342 standard_ProcessUtility(parsetree, queryString, params,
343 isTopLevel, dest, completionTag);
347 standard_ProcessUtility(Node *parsetree,
348 const char *queryString,
349 ParamListInfo params,
354 check_xact_readonly(parsetree);
357 completionTag[0] = '\0';
359 switch (nodeTag(parsetree))
362 * ******************** transactions ********************
364 case T_TransactionStmt:
366 TransactionStmt *stmt = (TransactionStmt *) parsetree;
371 * START TRANSACTION, as defined by SQL99: Identical
372 * to BEGIN. Same code for both.
374 case TRANS_STMT_BEGIN:
375 case TRANS_STMT_START:
379 BeginTransactionBlock();
380 foreach(lc, stmt->options)
382 DefElem *item = (DefElem *) lfirst(lc);
384 if (strcmp(item->defname, "transaction_isolation") == 0)
385 SetPGVariable("transaction_isolation",
386 list_make1(item->arg),
388 else if (strcmp(item->defname, "transaction_read_only") == 0)
389 SetPGVariable("transaction_read_only",
390 list_make1(item->arg),
392 else if (strcmp(item->defname, "transaction_deferrable") == 0)
393 SetPGVariable("transaction_deferrable",
394 list_make1(item->arg),
400 case TRANS_STMT_COMMIT:
401 if (!EndTransactionBlock())
403 /* report unsuccessful commit in completionTag */
405 strcpy(completionTag, "ROLLBACK");
409 case TRANS_STMT_PREPARE:
410 PreventCommandDuringRecovery("PREPARE TRANSACTION");
411 if (!PrepareTransactionBlock(stmt->gid))
413 /* report unsuccessful commit in completionTag */
415 strcpy(completionTag, "ROLLBACK");
419 case TRANS_STMT_COMMIT_PREPARED:
420 PreventTransactionChain(isTopLevel, "COMMIT PREPARED");
421 PreventCommandDuringRecovery("COMMIT PREPARED");
422 FinishPreparedTransaction(stmt->gid, true);
425 case TRANS_STMT_ROLLBACK_PREPARED:
426 PreventTransactionChain(isTopLevel, "ROLLBACK PREPARED");
427 PreventCommandDuringRecovery("ROLLBACK PREPARED");
428 FinishPreparedTransaction(stmt->gid, false);
431 case TRANS_STMT_ROLLBACK:
432 UserAbortTransactionBlock();
435 case TRANS_STMT_SAVEPOINT:
440 RequireTransactionChain(isTopLevel, "SAVEPOINT");
442 foreach(cell, stmt->options)
444 DefElem *elem = lfirst(cell);
446 if (strcmp(elem->defname, "savepoint_name") == 0)
447 name = strVal(elem->arg);
450 Assert(PointerIsValid(name));
452 DefineSavepoint(name);
456 case TRANS_STMT_RELEASE:
457 RequireTransactionChain(isTopLevel, "RELEASE SAVEPOINT");
458 ReleaseSavepoint(stmt->options);
461 case TRANS_STMT_ROLLBACK_TO:
462 RequireTransactionChain(isTopLevel, "ROLLBACK TO SAVEPOINT");
463 RollbackToSavepoint(stmt->options);
466 * CommitTransactionCommand is in charge of
467 * re-defining the savepoint again
475 * Portal (cursor) manipulation
477 * Note: DECLARE CURSOR is processed mostly as a SELECT, and
478 * therefore what we will get here is a PlannedStmt not a bare
483 PlannedStmt *stmt = (PlannedStmt *) parsetree;
485 if (stmt->utilityStmt == NULL ||
486 !IsA(stmt->utilityStmt, DeclareCursorStmt))
487 elog(ERROR, "non-DECLARE CURSOR PlannedStmt passed to ProcessUtility");
488 PerformCursorOpen(stmt, params, queryString, isTopLevel);
492 case T_ClosePortalStmt:
494 ClosePortalStmt *stmt = (ClosePortalStmt *) parsetree;
496 CheckRestrictedOperation("CLOSE");
497 PerformPortalClose(stmt->portalname);
502 PerformPortalFetch((FetchStmt *) parsetree, dest,
507 * relation and attribute manipulation
509 case T_CreateSchemaStmt:
510 CreateSchemaCommand((CreateSchemaStmt *) parsetree,
515 case T_CreateForeignTableStmt:
521 /* Run parse analysis ... */
522 stmts = transformCreateStmt((CreateStmt *) parsetree,
528 Node *stmt = (Node *) lfirst(l);
530 if (IsA(stmt, CreateStmt))
533 static char *validnsps[] = HEAP_RELOPT_NAMESPACES;
535 /* Create the table itself */
536 relOid = DefineRelation((CreateStmt *) stmt,
541 * Let AlterTableCreateToastTable decide if this one
542 * needs a secondary relation too.
544 CommandCounterIncrement();
546 /* parse and validate reloptions for the toast table */
547 toast_options = transformRelOptions((Datum) 0,
548 ((CreateStmt *) stmt)->options,
552 (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options,
555 AlterTableCreateToastTable(relOid, toast_options);
557 else if (IsA(stmt, CreateForeignTableStmt))
559 /* Create the table itself */
560 relOid = DefineRelation((CreateStmt *) stmt,
561 RELKIND_FOREIGN_TABLE,
563 CreateForeignTable((CreateForeignTableStmt *) stmt,
568 /* Recurse for anything else */
577 /* Need CCI between commands */
578 if (lnext(l) != NULL)
579 CommandCounterIncrement();
584 case T_CreateTableSpaceStmt:
585 PreventTransactionChain(isTopLevel, "CREATE TABLESPACE");
586 CreateTableSpace((CreateTableSpaceStmt *) parsetree);
589 case T_DropTableSpaceStmt:
590 PreventTransactionChain(isTopLevel, "DROP TABLESPACE");
591 DropTableSpace((DropTableSpaceStmt *) parsetree);
594 case T_AlterTableSpaceOptionsStmt:
595 AlterTableSpaceOptions((AlterTableSpaceOptionsStmt *) parsetree);
598 case T_CreateExtensionStmt:
599 CreateExtension((CreateExtensionStmt *) parsetree);
602 case T_AlterExtensionStmt:
603 ExecAlterExtensionStmt((AlterExtensionStmt *) parsetree);
606 case T_AlterExtensionContentsStmt:
607 ExecAlterExtensionContentsStmt((AlterExtensionContentsStmt *) parsetree);
610 case T_CreateFdwStmt:
611 CreateForeignDataWrapper((CreateFdwStmt *) parsetree);
615 AlterForeignDataWrapper((AlterFdwStmt *) parsetree);
619 RemoveForeignDataWrapper((DropFdwStmt *) parsetree);
622 case T_CreateForeignServerStmt:
623 CreateForeignServer((CreateForeignServerStmt *) parsetree);
626 case T_AlterForeignServerStmt:
627 AlterForeignServer((AlterForeignServerStmt *) parsetree);
630 case T_DropForeignServerStmt:
631 RemoveForeignServer((DropForeignServerStmt *) parsetree);
634 case T_CreateUserMappingStmt:
635 CreateUserMapping((CreateUserMappingStmt *) parsetree);
638 case T_AlterUserMappingStmt:
639 AlterUserMapping((AlterUserMappingStmt *) parsetree);
642 case T_DropUserMappingStmt:
643 RemoveUserMapping((DropUserMappingStmt *) parsetree);
647 switch (((DropStmt *) parsetree)->removeType)
650 case OBJECT_SEQUENCE:
653 case OBJECT_FOREIGN_TABLE:
654 RemoveRelations((DropStmt *) parsetree);
657 RemoveObjects((DropStmt *) parsetree);
663 ExecuteTruncate((TruncateStmt *) parsetree);
667 CommentObject((CommentStmt *) parsetree);
671 ExecSecLabelStmt((SecLabelStmt *) parsetree);
678 processed = DoCopy((CopyStmt *) parsetree, queryString);
680 snprintf(completionTag, COMPLETION_TAG_BUFSIZE,
681 "COPY " UINT64_FORMAT, processed);
686 CheckRestrictedOperation("PREPARE");
687 PrepareQuery((PrepareStmt *) parsetree, queryString);
691 ExecuteQuery((ExecuteStmt *) parsetree, queryString, params,
692 dest, completionTag);
695 case T_DeallocateStmt:
696 CheckRestrictedOperation("DEALLOCATE");
697 DeallocateQuery((DeallocateStmt *) parsetree);
704 ExecRenameStmt((RenameStmt *) parsetree);
707 case T_AlterObjectSchemaStmt:
708 ExecAlterObjectSchemaStmt((AlterObjectSchemaStmt *) parsetree);
711 case T_AlterOwnerStmt:
712 ExecAlterOwnerStmt((AlterOwnerStmt *) parsetree);
715 case T_AlterTableStmt:
720 /* Run parse analysis ... */
721 stmts = transformAlterTableStmt((AlterTableStmt *) parsetree,
727 Node *stmt = (Node *) lfirst(l);
729 if (IsA(stmt, AlterTableStmt))
731 /* Do the table alteration proper */
732 AlterTable((AlterTableStmt *) stmt);
736 /* Recurse for anything else */
745 /* Need CCI between commands */
746 if (lnext(l) != NULL)
747 CommandCounterIncrement();
752 case T_AlterDomainStmt:
754 AlterDomainStmt *stmt = (AlterDomainStmt *) parsetree;
757 * Some or all of these functions are recursive to cover
758 * inherited things, so permission checks are done there.
760 switch (stmt->subtype)
762 case 'T': /* ALTER DOMAIN DEFAULT */
765 * Recursively alter column default for table and, if
766 * requested, for descendants
768 AlterDomainDefault(stmt->typeName,
771 case 'N': /* ALTER DOMAIN DROP NOT NULL */
772 AlterDomainNotNull(stmt->typeName,
775 case 'O': /* ALTER DOMAIN SET NOT NULL */
776 AlterDomainNotNull(stmt->typeName,
779 case 'C': /* ADD CONSTRAINT */
780 AlterDomainAddConstraint(stmt->typeName,
783 case 'X': /* DROP CONSTRAINT */
784 AlterDomainDropConstraint(stmt->typeName,
788 case 'V': /* VALIDATE CONSTRAINT */
789 AlterDomainValidateConstraint(stmt->typeName,
793 elog(ERROR, "unrecognized alter domain type: %d",
794 (int) stmt->subtype);
801 ExecuteGrantStmt((GrantStmt *) parsetree);
804 case T_GrantRoleStmt:
805 GrantRole((GrantRoleStmt *) parsetree);
808 case T_AlterDefaultPrivilegesStmt:
809 ExecAlterDefaultPrivilegesStmt((AlterDefaultPrivilegesStmt *) parsetree);
813 * **************** object creation / destruction *****************
817 DefineStmt *stmt = (DefineStmt *) parsetree;
821 case OBJECT_AGGREGATE:
822 DefineAggregate(stmt->defnames, stmt->args,
823 stmt->oldstyle, stmt->definition);
825 case OBJECT_OPERATOR:
826 Assert(stmt->args == NIL);
827 DefineOperator(stmt->defnames, stmt->definition);
830 Assert(stmt->args == NIL);
831 DefineType(stmt->defnames, stmt->definition);
833 case OBJECT_TSPARSER:
834 Assert(stmt->args == NIL);
835 DefineTSParser(stmt->defnames, stmt->definition);
837 case OBJECT_TSDICTIONARY:
838 Assert(stmt->args == NIL);
839 DefineTSDictionary(stmt->defnames, stmt->definition);
841 case OBJECT_TSTEMPLATE:
842 Assert(stmt->args == NIL);
843 DefineTSTemplate(stmt->defnames, stmt->definition);
845 case OBJECT_TSCONFIGURATION:
846 Assert(stmt->args == NIL);
847 DefineTSConfiguration(stmt->defnames, stmt->definition);
849 case OBJECT_COLLATION:
850 Assert(stmt->args == NIL);
851 DefineCollation(stmt->defnames, stmt->definition);
854 elog(ERROR, "unrecognized define stmt type: %d",
861 case T_CompositeTypeStmt: /* CREATE TYPE (composite) */
863 CompositeTypeStmt *stmt = (CompositeTypeStmt *) parsetree;
865 DefineCompositeType(stmt->typevar, stmt->coldeflist);
869 case T_CreateEnumStmt: /* CREATE TYPE (enum) */
870 DefineEnum((CreateEnumStmt *) parsetree);
873 case T_AlterEnumStmt: /* ALTER TYPE (enum) */
876 * We disallow this in transaction blocks, because we can't cope
877 * with enum OID values getting into indexes and then having their
878 * defining pg_enum entries go away.
880 PreventTransactionChain(isTopLevel, "ALTER TYPE ... ADD");
881 AlterEnum((AlterEnumStmt *) parsetree);
884 case T_ViewStmt: /* CREATE VIEW */
885 DefineView((ViewStmt *) parsetree, queryString);
888 case T_CreateFunctionStmt: /* CREATE FUNCTION */
889 CreateFunction((CreateFunctionStmt *) parsetree, queryString);
892 case T_AlterFunctionStmt: /* ALTER FUNCTION */
893 AlterFunction((AlterFunctionStmt *) parsetree);
896 case T_IndexStmt: /* CREATE INDEX */
898 IndexStmt *stmt = (IndexStmt *) parsetree;
900 if (stmt->concurrent)
901 PreventTransactionChain(isTopLevel,
902 "CREATE INDEX CONCURRENTLY");
904 CheckRelationOwnership(stmt->relation, true);
906 /* Run parse analysis ... */
907 stmt = transformIndexStmt(stmt, queryString);
910 DefineIndex(stmt->relation, /* relation */
911 stmt->idxname, /* index name */
912 InvalidOid, /* no predefined OID */
913 InvalidOid, /* no previous storage */
914 stmt->accessMethod, /* am name */
916 stmt->indexParams, /* parameters */
917 (Expr *) stmt->whereClause,
919 stmt->excludeOpNames,
925 false, /* is_alter_table */
926 true, /* check_rights */
927 false, /* skip_build */
929 stmt->concurrent); /* concurrent */
933 case T_RuleStmt: /* CREATE RULE */
934 DefineRule((RuleStmt *) parsetree, queryString);
937 case T_CreateSeqStmt:
938 DefineSequence((CreateSeqStmt *) parsetree);
942 AlterSequence((AlterSeqStmt *) parsetree);
945 case T_RemoveFuncStmt:
947 RemoveFuncStmt *stmt = (RemoveFuncStmt *) parsetree;
951 case OBJECT_FUNCTION:
952 RemoveFunction(stmt);
954 case OBJECT_AGGREGATE:
955 RemoveAggregate(stmt);
957 case OBJECT_OPERATOR:
958 RemoveOperator(stmt);
961 elog(ERROR, "unrecognized object type: %d",
969 ExecuteDoStmt((DoStmt *) parsetree);
973 PreventTransactionChain(isTopLevel, "CREATE DATABASE");
974 createdb((CreatedbStmt *) parsetree);
977 case T_AlterDatabaseStmt:
978 AlterDatabase((AlterDatabaseStmt *) parsetree, isTopLevel);
981 case T_AlterDatabaseSetStmt:
982 AlterDatabaseSet((AlterDatabaseSetStmt *) parsetree);
987 DropdbStmt *stmt = (DropdbStmt *) parsetree;
989 PreventTransactionChain(isTopLevel, "DROP DATABASE");
990 dropdb(stmt->dbname, stmt->missing_ok);
994 /* Query-level asynchronous notification */
997 NotifyStmt *stmt = (NotifyStmt *) parsetree;
999 PreventCommandDuringRecovery("NOTIFY");
1000 Async_Notify(stmt->conditionname, stmt->payload);
1006 ListenStmt *stmt = (ListenStmt *) parsetree;
1008 PreventCommandDuringRecovery("LISTEN");
1009 CheckRestrictedOperation("LISTEN");
1010 Async_Listen(stmt->conditionname);
1014 case T_UnlistenStmt:
1016 UnlistenStmt *stmt = (UnlistenStmt *) parsetree;
1018 PreventCommandDuringRecovery("UNLISTEN");
1019 CheckRestrictedOperation("UNLISTEN");
1020 if (stmt->conditionname)
1021 Async_Unlisten(stmt->conditionname);
1023 Async_UnlistenAll();
1029 LoadStmt *stmt = (LoadStmt *) parsetree;
1031 closeAllVfds(); /* probably not necessary... */
1032 /* Allowed names are restricted if you're not superuser */
1033 load_file(stmt->filename, !superuser());
1038 /* we choose to allow this during "read only" transactions */
1039 PreventCommandDuringRecovery("CLUSTER");
1040 cluster((ClusterStmt *) parsetree, isTopLevel);
1044 /* we choose to allow this during "read only" transactions */
1045 PreventCommandDuringRecovery("VACUUM");
1046 vacuum((VacuumStmt *) parsetree, InvalidOid, true, NULL, false,
1051 ExplainQuery((ExplainStmt *) parsetree, queryString, params, dest);
1054 case T_VariableSetStmt:
1055 ExecSetVariableStmt((VariableSetStmt *) parsetree);
1058 case T_VariableShowStmt:
1060 VariableShowStmt *n = (VariableShowStmt *) parsetree;
1062 GetPGVariable(n->name, dest);
1067 /* should we allow DISCARD PLANS? */
1068 CheckRestrictedOperation("DISCARD");
1069 DiscardCommand((DiscardStmt *) parsetree, isTopLevel);
1072 case T_CreateTrigStmt:
1073 (void) CreateTrigger((CreateTrigStmt *) parsetree, queryString,
1074 InvalidOid, InvalidOid, false);
1077 case T_DropPropertyStmt:
1079 DropPropertyStmt *stmt = (DropPropertyStmt *) parsetree;
1081 switch (stmt->removeType)
1084 /* RemoveRewriteRule checks permissions */
1085 RemoveRewriteRule(stmt->relation, stmt->property,
1086 stmt->behavior, stmt->missing_ok);
1088 case OBJECT_TRIGGER:
1089 /* DropTrigger checks permissions */
1090 DropTrigger(stmt->relation, stmt->property,
1091 stmt->behavior, stmt->missing_ok);
1094 elog(ERROR, "unrecognized object type: %d",
1095 (int) stmt->removeType);
1101 case T_CreatePLangStmt:
1102 CreateProceduralLanguage((CreatePLangStmt *) parsetree);
1105 case T_DropPLangStmt:
1106 DropProceduralLanguage((DropPLangStmt *) parsetree);
1110 * ******************************** DOMAIN statements ****
1112 case T_CreateDomainStmt:
1113 DefineDomain((CreateDomainStmt *) parsetree);
1117 * ******************************** ROLE statements ****
1119 case T_CreateRoleStmt:
1120 CreateRole((CreateRoleStmt *) parsetree);
1123 case T_AlterRoleStmt:
1124 AlterRole((AlterRoleStmt *) parsetree);
1127 case T_AlterRoleSetStmt:
1128 AlterRoleSet((AlterRoleSetStmt *) parsetree);
1131 case T_DropRoleStmt:
1132 DropRole((DropRoleStmt *) parsetree);
1135 case T_DropOwnedStmt:
1136 DropOwnedObjects((DropOwnedStmt *) parsetree);
1139 case T_ReassignOwnedStmt:
1140 ReassignOwnedObjects((ReassignOwnedStmt *) parsetree);
1146 * Since the lock would just get dropped immediately, LOCK TABLE
1147 * outside a transaction block is presumed to be user error.
1149 RequireTransactionChain(isTopLevel, "LOCK TABLE");
1150 LockTableCommand((LockStmt *) parsetree);
1153 case T_ConstraintsSetStmt:
1154 AfterTriggerSetState((ConstraintsSetStmt *) parsetree);
1157 case T_CheckPointStmt:
1160 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1161 errmsg("must be superuser to do CHECKPOINT")));
1164 * You might think we should have a PreventCommandDuringRecovery()
1165 * here, but we interpret a CHECKPOINT command during recovery as
1166 * a request for a restartpoint instead. We allow this since it
1167 * can be a useful way of reducing switchover time when using
1168 * various forms of replication.
1170 RequestCheckpoint(CHECKPOINT_IMMEDIATE | CHECKPOINT_WAIT |
1171 (RecoveryInProgress() ? 0 : CHECKPOINT_FORCE));
1176 ReindexStmt *stmt = (ReindexStmt *) parsetree;
1178 /* we choose to allow this during "read only" transactions */
1179 PreventCommandDuringRecovery("REINDEX");
1183 ReindexIndex(stmt->relation);
1186 ReindexTable(stmt->relation);
1188 case OBJECT_DATABASE:
1191 * This cannot run inside a user transaction block; if
1192 * we were inside a transaction, then its commit- and
1193 * start-transaction-command calls would not have the
1196 PreventTransactionChain(isTopLevel,
1197 "REINDEX DATABASE");
1198 ReindexDatabase(stmt->name,
1199 stmt->do_system, stmt->do_user);
1202 elog(ERROR, "unrecognized object type: %d",
1210 case T_CreateConversionStmt:
1211 CreateConversionCommand((CreateConversionStmt *) parsetree);
1214 case T_CreateCastStmt:
1215 CreateCast((CreateCastStmt *) parsetree);
1218 case T_DropCastStmt:
1219 DropCast((DropCastStmt *) parsetree);
1222 case T_CreateOpClassStmt:
1223 DefineOpClass((CreateOpClassStmt *) parsetree);
1226 case T_CreateOpFamilyStmt:
1227 DefineOpFamily((CreateOpFamilyStmt *) parsetree);
1230 case T_AlterOpFamilyStmt:
1231 AlterOpFamily((AlterOpFamilyStmt *) parsetree);
1234 case T_RemoveOpClassStmt:
1235 RemoveOpClass((RemoveOpClassStmt *) parsetree);
1238 case T_RemoveOpFamilyStmt:
1239 RemoveOpFamily((RemoveOpFamilyStmt *) parsetree);
1242 case T_AlterTSDictionaryStmt:
1243 AlterTSDictionary((AlterTSDictionaryStmt *) parsetree);
1246 case T_AlterTSConfigurationStmt:
1247 AlterTSConfiguration((AlterTSConfigurationStmt *) parsetree);
1251 elog(ERROR, "unrecognized node type: %d",
1252 (int) nodeTag(parsetree));
1258 * UtilityReturnsTuples
1259 * Return "true" if this utility statement will send output to the
1262 * Generally, there should be a case here for each case in ProcessUtility
1263 * where "dest" is passed on.
1266 UtilityReturnsTuples(Node *parsetree)
1268 switch (nodeTag(parsetree))
1272 FetchStmt *stmt = (FetchStmt *) parsetree;
1277 portal = GetPortalByName(stmt->portalname);
1278 if (!PortalIsValid(portal))
1279 return false; /* not our business to raise error */
1280 return portal->tupDesc ? true : false;
1285 ExecuteStmt *stmt = (ExecuteStmt *) parsetree;
1286 PreparedStatement *entry;
1290 entry = FetchPreparedStatement(stmt->name, false);
1292 return false; /* not our business to raise error */
1293 if (entry->plansource->resultDesc)
1301 case T_VariableShowStmt:
1310 * UtilityTupleDescriptor
1311 * Fetch the actual output tuple descriptor for a utility statement
1312 * for which UtilityReturnsTuples() previously returned "true".
1314 * The returned descriptor is created in (or copied into) the current memory
1318 UtilityTupleDescriptor(Node *parsetree)
1320 switch (nodeTag(parsetree))
1324 FetchStmt *stmt = (FetchStmt *) parsetree;
1329 portal = GetPortalByName(stmt->portalname);
1330 if (!PortalIsValid(portal))
1331 return NULL; /* not our business to raise error */
1332 return CreateTupleDescCopy(portal->tupDesc);
1337 ExecuteStmt *stmt = (ExecuteStmt *) parsetree;
1338 PreparedStatement *entry;
1342 entry = FetchPreparedStatement(stmt->name, false);
1344 return NULL; /* not our business to raise error */
1345 return FetchPreparedStatementResultDesc(entry);
1349 return ExplainResultDesc((ExplainStmt *) parsetree);
1351 case T_VariableShowStmt:
1353 VariableShowStmt *n = (VariableShowStmt *) parsetree;
1355 return GetPGVariableResultDesc(n->name);
1365 * QueryReturnsTuples
1366 * Return "true" if this Query will send output to the destination.
1370 QueryReturnsTuples(Query *parsetree)
1372 switch (parsetree->commandType)
1375 /* returns tuples ... unless it's DECLARE CURSOR or SELECT INTO */
1376 if (parsetree->utilityStmt == NULL &&
1377 parsetree->intoClause == NULL)
1383 /* the forms with RETURNING return tuples */
1384 if (parsetree->returningList)
1388 return UtilityReturnsTuples(parsetree->utilityStmt);
1391 /* probably shouldn't get here */
1394 return false; /* default */
1400 * AlterObjectTypeCommandTag
1401 * helper function for CreateCommandTag
1403 * This covers most cases where ALTER is used with an ObjectType enum.
1406 AlterObjectTypeCommandTag(ObjectType objtype)
1412 case OBJECT_AGGREGATE:
1413 tag = "ALTER AGGREGATE";
1415 case OBJECT_ATTRIBUTE:
1421 case OBJECT_COLLATION:
1422 tag = "ALTER COLLATION";
1425 tag = "ALTER TABLE";
1427 case OBJECT_CONSTRAINT:
1428 tag = "ALTER TABLE";
1430 case OBJECT_CONVERSION:
1431 tag = "ALTER CONVERSION";
1433 case OBJECT_DATABASE:
1434 tag = "ALTER DATABASE";
1437 tag = "ALTER DOMAIN";
1439 case OBJECT_EXTENSION:
1440 tag = "ALTER EXTENSION";
1443 tag = "ALTER FOREIGN DATA WRAPPER";
1445 case OBJECT_FOREIGN_SERVER:
1446 tag = "ALTER SERVER";
1448 case OBJECT_FOREIGN_TABLE:
1449 tag = "ALTER FOREIGN TABLE";
1451 case OBJECT_FUNCTION:
1452 tag = "ALTER FUNCTION";
1455 tag = "ALTER INDEX";
1457 case OBJECT_LANGUAGE:
1458 tag = "ALTER LANGUAGE";
1460 case OBJECT_LARGEOBJECT:
1461 tag = "ALTER LARGE OBJECT";
1463 case OBJECT_OPCLASS:
1464 tag = "ALTER OPERATOR CLASS";
1466 case OBJECT_OPERATOR:
1467 tag = "ALTER OPERATOR";
1469 case OBJECT_OPFAMILY:
1470 tag = "ALTER OPERATOR FAMILY";
1479 tag = "ALTER SCHEMA";
1481 case OBJECT_SEQUENCE:
1482 tag = "ALTER SEQUENCE";
1485 tag = "ALTER TABLE";
1487 case OBJECT_TABLESPACE:
1488 tag = "ALTER TABLESPACE";
1490 case OBJECT_TRIGGER:
1491 tag = "ALTER TRIGGER";
1493 case OBJECT_TSCONFIGURATION:
1494 tag = "ALTER TEXT SEARCH CONFIGURATION";
1496 case OBJECT_TSDICTIONARY:
1497 tag = "ALTER TEXT SEARCH DICTIONARY";
1499 case OBJECT_TSPARSER:
1500 tag = "ALTER TEXT SEARCH PARSER";
1502 case OBJECT_TSTEMPLATE:
1503 tag = "ALTER TEXT SEARCH TEMPLATE";
1521 * utility to get a string representation of the command operation,
1522 * given either a raw (un-analyzed) parsetree or a planned query.
1524 * This must handle all command types, but since the vast majority
1525 * of 'em are utility commands, it seems sensible to keep it here.
1527 * NB: all result strings must be shorter than COMPLETION_TAG_BUFSIZE.
1528 * Also, the result must point at a true constant (permanent storage).
1531 CreateCommandTag(Node *parsetree)
1535 switch (nodeTag(parsetree))
1537 /* raw plannable queries */
1554 /* utility statements --- same whether raw or cooked */
1555 case T_TransactionStmt:
1557 TransactionStmt *stmt = (TransactionStmt *) parsetree;
1561 case TRANS_STMT_BEGIN:
1565 case TRANS_STMT_START:
1566 tag = "START TRANSACTION";
1569 case TRANS_STMT_COMMIT:
1573 case TRANS_STMT_ROLLBACK:
1574 case TRANS_STMT_ROLLBACK_TO:
1578 case TRANS_STMT_SAVEPOINT:
1582 case TRANS_STMT_RELEASE:
1586 case TRANS_STMT_PREPARE:
1587 tag = "PREPARE TRANSACTION";
1590 case TRANS_STMT_COMMIT_PREPARED:
1591 tag = "COMMIT PREPARED";
1594 case TRANS_STMT_ROLLBACK_PREPARED:
1595 tag = "ROLLBACK PREPARED";
1605 case T_DeclareCursorStmt:
1606 tag = "DECLARE CURSOR";
1609 case T_ClosePortalStmt:
1611 ClosePortalStmt *stmt = (ClosePortalStmt *) parsetree;
1613 if (stmt->portalname == NULL)
1614 tag = "CLOSE CURSOR ALL";
1616 tag = "CLOSE CURSOR";
1622 FetchStmt *stmt = (FetchStmt *) parsetree;
1624 tag = (stmt->ismove) ? "MOVE" : "FETCH";
1628 case T_CreateDomainStmt:
1629 tag = "CREATE DOMAIN";
1632 case T_CreateSchemaStmt:
1633 tag = "CREATE SCHEMA";
1637 tag = "CREATE TABLE";
1640 case T_CreateTableSpaceStmt:
1641 tag = "CREATE TABLESPACE";
1644 case T_DropTableSpaceStmt:
1645 tag = "DROP TABLESPACE";
1648 case T_AlterTableSpaceOptionsStmt:
1649 tag = "ALTER TABLESPACE";
1652 case T_CreateExtensionStmt:
1653 tag = "CREATE EXTENSION";
1656 case T_AlterExtensionStmt:
1657 tag = "ALTER EXTENSION";
1660 case T_AlterExtensionContentsStmt:
1661 tag = "ALTER EXTENSION";
1664 case T_CreateFdwStmt:
1665 tag = "CREATE FOREIGN DATA WRAPPER";
1668 case T_AlterFdwStmt:
1669 tag = "ALTER FOREIGN DATA WRAPPER";
1673 tag = "DROP FOREIGN DATA WRAPPER";
1676 case T_CreateForeignServerStmt:
1677 tag = "CREATE SERVER";
1680 case T_AlterForeignServerStmt:
1681 tag = "ALTER SERVER";
1684 case T_DropForeignServerStmt:
1685 tag = "DROP SERVER";
1688 case T_CreateUserMappingStmt:
1689 tag = "CREATE USER MAPPING";
1692 case T_AlterUserMappingStmt:
1693 tag = "ALTER USER MAPPING";
1696 case T_DropUserMappingStmt:
1697 tag = "DROP USER MAPPING";
1700 case T_CreateForeignTableStmt:
1701 tag = "CREATE FOREIGN TABLE";
1705 switch (((DropStmt *) parsetree)->removeType)
1710 case OBJECT_SEQUENCE:
1711 tag = "DROP SEQUENCE";
1723 tag = "DROP DOMAIN";
1725 case OBJECT_COLLATION:
1726 tag = "DROP COLLATION";
1728 case OBJECT_CONVERSION:
1729 tag = "DROP CONVERSION";
1732 tag = "DROP SCHEMA";
1734 case OBJECT_TSPARSER:
1735 tag = "DROP TEXT SEARCH PARSER";
1737 case OBJECT_TSDICTIONARY:
1738 tag = "DROP TEXT SEARCH DICTIONARY";
1740 case OBJECT_TSTEMPLATE:
1741 tag = "DROP TEXT SEARCH TEMPLATE";
1743 case OBJECT_TSCONFIGURATION:
1744 tag = "DROP TEXT SEARCH CONFIGURATION";
1746 case OBJECT_FOREIGN_TABLE:
1747 tag = "DROP FOREIGN TABLE";
1749 case OBJECT_EXTENSION:
1750 tag = "DROP EXTENSION";
1757 case T_TruncateStmt:
1758 tag = "TRUNCATE TABLE";
1765 case T_SecLabelStmt:
1766 tag = "SECURITY LABEL";
1774 tag = AlterObjectTypeCommandTag(((RenameStmt *) parsetree)->renameType);
1777 case T_AlterObjectSchemaStmt:
1778 tag = AlterObjectTypeCommandTag(((AlterObjectSchemaStmt *) parsetree)->objectType);
1781 case T_AlterOwnerStmt:
1782 tag = AlterObjectTypeCommandTag(((AlterOwnerStmt *) parsetree)->objectType);
1785 case T_AlterTableStmt:
1786 tag = AlterObjectTypeCommandTag(((AlterTableStmt *) parsetree)->relkind);
1789 case T_AlterDomainStmt:
1790 tag = "ALTER DOMAIN";
1793 case T_AlterFunctionStmt:
1794 tag = "ALTER FUNCTION";
1799 GrantStmt *stmt = (GrantStmt *) parsetree;
1801 tag = (stmt->is_grant) ? "GRANT" : "REVOKE";
1805 case T_GrantRoleStmt:
1807 GrantRoleStmt *stmt = (GrantRoleStmt *) parsetree;
1809 tag = (stmt->is_grant) ? "GRANT ROLE" : "REVOKE ROLE";
1813 case T_AlterDefaultPrivilegesStmt:
1814 tag = "ALTER DEFAULT PRIVILEGES";
1818 switch (((DefineStmt *) parsetree)->kind)
1820 case OBJECT_AGGREGATE:
1821 tag = "CREATE AGGREGATE";
1823 case OBJECT_OPERATOR:
1824 tag = "CREATE OPERATOR";
1827 tag = "CREATE TYPE";
1829 case OBJECT_TSPARSER:
1830 tag = "CREATE TEXT SEARCH PARSER";
1832 case OBJECT_TSDICTIONARY:
1833 tag = "CREATE TEXT SEARCH DICTIONARY";
1835 case OBJECT_TSTEMPLATE:
1836 tag = "CREATE TEXT SEARCH TEMPLATE";
1838 case OBJECT_TSCONFIGURATION:
1839 tag = "CREATE TEXT SEARCH CONFIGURATION";
1841 case OBJECT_COLLATION:
1842 tag = "CREATE COLLATION";
1849 case T_CompositeTypeStmt:
1850 tag = "CREATE TYPE";
1853 case T_CreateEnumStmt:
1854 tag = "CREATE TYPE";
1857 case T_AlterEnumStmt:
1862 tag = "CREATE VIEW";
1865 case T_CreateFunctionStmt:
1866 tag = "CREATE FUNCTION";
1870 tag = "CREATE INDEX";
1874 tag = "CREATE RULE";
1877 case T_CreateSeqStmt:
1878 tag = "CREATE SEQUENCE";
1881 case T_AlterSeqStmt:
1882 tag = "ALTER SEQUENCE";
1885 case T_RemoveFuncStmt:
1886 switch (((RemoveFuncStmt *) parsetree)->kind)
1888 case OBJECT_FUNCTION:
1889 tag = "DROP FUNCTION";
1891 case OBJECT_AGGREGATE:
1892 tag = "DROP AGGREGATE";
1894 case OBJECT_OPERATOR:
1895 tag = "DROP OPERATOR";
1906 case T_CreatedbStmt:
1907 tag = "CREATE DATABASE";
1910 case T_AlterDatabaseStmt:
1911 tag = "ALTER DATABASE";
1914 case T_AlterDatabaseSetStmt:
1915 tag = "ALTER DATABASE";
1919 tag = "DROP DATABASE";
1930 case T_UnlistenStmt:
1943 if (((VacuumStmt *) parsetree)->options & VACOPT_VACUUM)
1953 case T_VariableSetStmt:
1954 switch (((VariableSetStmt *) parsetree)->kind)
1957 case VAR_SET_CURRENT:
1958 case VAR_SET_DEFAULT:
1971 case T_VariableShowStmt:
1976 switch (((DiscardStmt *) parsetree)->target)
1979 tag = "DISCARD ALL";
1982 tag = "DISCARD PLANS";
1985 tag = "DISCARD TEMP";
1992 case T_CreateTrigStmt:
1993 tag = "CREATE TRIGGER";
1996 case T_DropPropertyStmt:
1997 switch (((DropPropertyStmt *) parsetree)->removeType)
1999 case OBJECT_TRIGGER:
2000 tag = "DROP TRIGGER";
2010 case T_CreatePLangStmt:
2011 tag = "CREATE LANGUAGE";
2014 case T_DropPLangStmt:
2015 tag = "DROP LANGUAGE";
2018 case T_CreateRoleStmt:
2019 tag = "CREATE ROLE";
2022 case T_AlterRoleStmt:
2026 case T_AlterRoleSetStmt:
2030 case T_DropRoleStmt:
2034 case T_DropOwnedStmt:
2038 case T_ReassignOwnedStmt:
2039 tag = "REASSIGN OWNED";
2046 case T_ConstraintsSetStmt:
2047 tag = "SET CONSTRAINTS";
2050 case T_CheckPointStmt:
2058 case T_CreateConversionStmt:
2059 tag = "CREATE CONVERSION";
2062 case T_CreateCastStmt:
2063 tag = "CREATE CAST";
2066 case T_DropCastStmt:
2070 case T_CreateOpClassStmt:
2071 tag = "CREATE OPERATOR CLASS";
2074 case T_CreateOpFamilyStmt:
2075 tag = "CREATE OPERATOR FAMILY";
2078 case T_AlterOpFamilyStmt:
2079 tag = "ALTER OPERATOR FAMILY";
2082 case T_RemoveOpClassStmt:
2083 tag = "DROP OPERATOR CLASS";
2086 case T_RemoveOpFamilyStmt:
2087 tag = "DROP OPERATOR FAMILY";
2090 case T_AlterTSDictionaryStmt:
2091 tag = "ALTER TEXT SEARCH DICTIONARY";
2094 case T_AlterTSConfigurationStmt:
2095 tag = "ALTER TEXT SEARCH CONFIGURATION";
2106 case T_DeallocateStmt:
2108 DeallocateStmt *stmt = (DeallocateStmt *) parsetree;
2110 if (stmt->name == NULL)
2111 tag = "DEALLOCATE ALL";
2117 /* already-planned queries */
2120 PlannedStmt *stmt = (PlannedStmt *) parsetree;
2122 switch (stmt->commandType)
2127 * We take a little extra care here so that the result
2128 * will be useful for complaints about read-only
2131 if (stmt->utilityStmt != NULL)
2133 Assert(IsA(stmt->utilityStmt, DeclareCursorStmt));
2134 tag = "DECLARE CURSOR";
2136 else if (stmt->intoClause != NULL)
2137 tag = "SELECT INTO";
2138 else if (stmt->rowMarks != NIL)
2140 /* not 100% but probably close enough */
2141 if (((PlanRowMark *) linitial(stmt->rowMarks))->markType == ROW_MARK_EXCLUSIVE)
2142 tag = "SELECT FOR UPDATE";
2144 tag = "SELECT FOR SHARE";
2159 elog(WARNING, "unrecognized commandType: %d",
2160 (int) stmt->commandType);
2167 /* parsed-and-rewritten-but-not-planned queries */
2170 Query *stmt = (Query *) parsetree;
2172 switch (stmt->commandType)
2177 * We take a little extra care here so that the result
2178 * will be useful for complaints about read-only
2181 if (stmt->utilityStmt != NULL)
2183 Assert(IsA(stmt->utilityStmt, DeclareCursorStmt));
2184 tag = "DECLARE CURSOR";
2186 else if (stmt->intoClause != NULL)
2187 tag = "SELECT INTO";
2188 else if (stmt->rowMarks != NIL)
2190 /* not 100% but probably close enough */
2191 if (((RowMarkClause *) linitial(stmt->rowMarks))->forUpdate)
2192 tag = "SELECT FOR UPDATE";
2194 tag = "SELECT FOR SHARE";
2209 tag = CreateCommandTag(stmt->utilityStmt);
2212 elog(WARNING, "unrecognized commandType: %d",
2213 (int) stmt->commandType);
2221 elog(WARNING, "unrecognized node type: %d",
2222 (int) nodeTag(parsetree));
2232 * GetCommandLogLevel
2233 * utility to get the minimum log_statement level for a command,
2234 * given either a raw (un-analyzed) parsetree or a planned query.
2236 * This must handle all command types, but since the vast majority
2237 * of 'em are utility commands, it seems sensible to keep it here.
2240 GetCommandLogLevel(Node *parsetree)
2244 switch (nodeTag(parsetree))
2246 /* raw plannable queries */
2254 if (((SelectStmt *) parsetree)->intoClause)
2255 lev = LOGSTMT_DDL; /* CREATE AS, SELECT INTO */
2260 /* utility statements --- same whether raw or cooked */
2261 case T_TransactionStmt:
2265 case T_DeclareCursorStmt:
2269 case T_ClosePortalStmt:
2277 case T_CreateSchemaStmt:
2282 case T_CreateForeignTableStmt:
2286 case T_CreateTableSpaceStmt:
2287 case T_DropTableSpaceStmt:
2288 case T_AlterTableSpaceOptionsStmt:
2292 case T_CreateExtensionStmt:
2293 case T_AlterExtensionStmt:
2294 case T_AlterExtensionContentsStmt:
2298 case T_CreateFdwStmt:
2299 case T_AlterFdwStmt:
2301 case T_CreateForeignServerStmt:
2302 case T_AlterForeignServerStmt:
2303 case T_DropForeignServerStmt:
2304 case T_CreateUserMappingStmt:
2305 case T_AlterUserMappingStmt:
2306 case T_DropUserMappingStmt:
2314 case T_TruncateStmt:
2322 case T_SecLabelStmt:
2327 if (((CopyStmt *) parsetree)->is_from)
2335 PrepareStmt *stmt = (PrepareStmt *) parsetree;
2337 /* Look through a PREPARE to the contained stmt */
2338 lev = GetCommandLogLevel(stmt->query);
2344 ExecuteStmt *stmt = (ExecuteStmt *) parsetree;
2345 PreparedStatement *ps;
2347 /* Look through an EXECUTE to the referenced stmt */
2348 ps = FetchPreparedStatement(stmt->name, false);
2350 lev = GetCommandLogLevel(ps->plansource->raw_parse_tree);
2356 case T_DeallocateStmt:
2364 case T_AlterObjectSchemaStmt:
2368 case T_AlterOwnerStmt:
2372 case T_AlterTableStmt:
2376 case T_AlterDomainStmt:
2384 case T_GrantRoleStmt:
2388 case T_AlterDefaultPrivilegesStmt:
2396 case T_CompositeTypeStmt:
2400 case T_CreateEnumStmt:
2404 case T_AlterEnumStmt:
2412 case T_CreateFunctionStmt:
2416 case T_AlterFunctionStmt:
2428 case T_CreateSeqStmt:
2432 case T_AlterSeqStmt:
2436 case T_RemoveFuncStmt:
2444 case T_CreatedbStmt:
2448 case T_AlterDatabaseStmt:
2452 case T_AlterDatabaseSetStmt:
2468 case T_UnlistenStmt:
2486 ExplainStmt *stmt = (ExplainStmt *) parsetree;
2487 bool analyze = false;
2490 /* Look through an EXPLAIN ANALYZE to the contained stmt */
2491 foreach(lc, stmt->options)
2493 DefElem *opt = (DefElem *) lfirst(lc);
2495 if (strcmp(opt->defname, "analyze") == 0)
2496 analyze = defGetBoolean(opt);
2497 /* don't "break", as explain.c will use the last value */
2500 return GetCommandLogLevel(stmt->query);
2502 /* Plain EXPLAIN isn't so interesting */
2507 case T_VariableSetStmt:
2511 case T_VariableShowStmt:
2519 case T_CreateTrigStmt:
2523 case T_DropPropertyStmt:
2527 case T_CreatePLangStmt:
2531 case T_DropPLangStmt:
2535 case T_CreateDomainStmt:
2539 case T_CreateRoleStmt:
2543 case T_AlterRoleStmt:
2547 case T_AlterRoleSetStmt:
2551 case T_DropRoleStmt:
2555 case T_DropOwnedStmt:
2559 case T_ReassignOwnedStmt:
2567 case T_ConstraintsSetStmt:
2571 case T_CheckPointStmt:
2576 lev = LOGSTMT_ALL; /* should this be DDL? */
2579 case T_CreateConversionStmt:
2583 case T_CreateCastStmt:
2587 case T_DropCastStmt:
2591 case T_CreateOpClassStmt:
2595 case T_CreateOpFamilyStmt:
2599 case T_AlterOpFamilyStmt:
2603 case T_RemoveOpClassStmt:
2607 case T_RemoveOpFamilyStmt:
2611 case T_AlterTSDictionaryStmt:
2615 case T_AlterTSConfigurationStmt:
2619 /* already-planned queries */
2622 PlannedStmt *stmt = (PlannedStmt *) parsetree;
2624 switch (stmt->commandType)
2627 if (stmt->intoClause != NULL)
2628 lev = LOGSTMT_DDL; /* CREATE AS, SELECT INTO */
2630 lev = LOGSTMT_ALL; /* SELECT or DECLARE CURSOR */
2640 elog(WARNING, "unrecognized commandType: %d",
2641 (int) stmt->commandType);
2648 /* parsed-and-rewritten-but-not-planned queries */
2651 Query *stmt = (Query *) parsetree;
2653 switch (stmt->commandType)
2656 if (stmt->intoClause != NULL)
2657 lev = LOGSTMT_DDL; /* CREATE AS, SELECT INTO */
2659 lev = LOGSTMT_ALL; /* SELECT or DECLARE CURSOR */
2669 lev = GetCommandLogLevel(stmt->utilityStmt);
2673 elog(WARNING, "unrecognized commandType: %d",
2674 (int) stmt->commandType);
2683 elog(WARNING, "unrecognized node type: %d",
2684 (int) nodeTag(parsetree));