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)
80 relOid = RangeVarGetRelid(rel, false);
81 tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relOid));
82 if (!HeapTupleIsValid(tuple)) /* should not happen */
83 elog(ERROR, "cache lookup failed for relation %u", relOid);
85 if (!pg_class_ownercheck(relOid, GetUserId()))
86 aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
91 if (!allowSystemTableMods &&
92 IsSystemClass((Form_pg_class) GETSTRUCT(tuple)))
94 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
95 errmsg("permission denied: \"%s\" is a system catalog",
99 ReleaseSysCache(tuple);
104 * CommandIsReadOnly: is an executable query read-only?
106 * This is a much stricter test than we apply for XactReadOnly mode;
107 * the query must be *in truth* read-only, because the caller wishes
108 * not to do CommandCounterIncrement for it.
110 * Note: currently no need to support Query nodes here
113 CommandIsReadOnly(Node *parsetree)
115 if (IsA(parsetree, PlannedStmt))
117 PlannedStmt *stmt = (PlannedStmt *) parsetree;
119 switch (stmt->commandType)
122 if (stmt->intoClause != NULL)
123 return false; /* SELECT INTO */
124 else if (stmt->rowMarks != NIL)
125 return false; /* SELECT FOR UPDATE/SHARE */
126 else if (stmt->hasModifyingCTE)
127 return false; /* data-modifying CTE */
135 elog(WARNING, "unrecognized commandType: %d",
136 (int) stmt->commandType);
140 /* For now, treat all utility commands as read/write */
145 * check_xact_readonly: is a utility command read-only?
147 * Here we use the loose rules of XactReadOnly mode: no permanent effects
148 * on the database are allowed.
151 check_xact_readonly(Node *parsetree)
157 * Note: Commands that need to do more complicated checking are handled
158 * elsewhere, in particular COPY and plannable statements do their own
159 * checking. However they should all call PreventCommandIfReadOnly to
160 * actually throw the error.
163 switch (nodeTag(parsetree))
165 case T_AlterDatabaseStmt:
166 case T_AlterDatabaseSetStmt:
167 case T_AlterDomainStmt:
168 case T_AlterFunctionStmt:
169 case T_AlterRoleStmt:
170 case T_AlterRoleSetStmt:
171 case T_AlterObjectSchemaStmt:
172 case T_AlterOwnerStmt:
174 case T_AlterTableStmt:
178 case T_CreateCastStmt:
179 case T_CreateConversionStmt:
181 case T_CreateDomainStmt:
182 case T_CreateFunctionStmt:
183 case T_CreateRoleStmt:
185 case T_CreatePLangStmt:
186 case T_CreateOpClassStmt:
187 case T_CreateOpFamilyStmt:
188 case T_AlterOpFamilyStmt:
190 case T_CreateSchemaStmt:
191 case T_CreateSeqStmt:
193 case T_CreateTableSpaceStmt:
194 case T_CreateTrigStmt:
195 case T_CompositeTypeStmt:
196 case T_CreateEnumStmt:
197 case T_AlterEnumStmt:
202 case T_DropTableSpaceStmt:
203 case T_RemoveFuncStmt:
205 case T_DropPLangStmt:
206 case T_RemoveOpClassStmt:
207 case T_RemoveOpFamilyStmt:
208 case T_DropPropertyStmt:
210 case T_GrantRoleStmt:
211 case T_AlterDefaultPrivilegesStmt:
213 case T_DropOwnedStmt:
214 case T_ReassignOwnedStmt:
215 case T_AlterTSDictionaryStmt:
216 case T_AlterTSConfigurationStmt:
217 case T_CreateExtensionStmt:
218 case T_AlterExtensionStmt:
219 case T_AlterExtensionContentsStmt:
220 case T_CreateFdwStmt:
223 case T_CreateForeignServerStmt:
224 case T_AlterForeignServerStmt:
225 case T_DropForeignServerStmt:
226 case T_CreateUserMappingStmt:
227 case T_AlterUserMappingStmt:
228 case T_DropUserMappingStmt:
229 case T_AlterTableSpaceOptionsStmt:
230 case T_CreateForeignTableStmt:
232 PreventCommandIfReadOnly(CreateCommandTag(parsetree));
241 * PreventCommandIfReadOnly: throw error if XactReadOnly
243 * This is useful mainly to ensure consistency of the error message wording;
244 * most callers have checked XactReadOnly for themselves.
247 PreventCommandIfReadOnly(const char *cmdname)
251 (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
252 /* translator: %s is name of a SQL command, eg CREATE */
253 errmsg("cannot execute %s in a read-only transaction",
258 * PreventCommandDuringRecovery: throw error if RecoveryInProgress
260 * The majority of operations that are unsafe in a Hot Standby slave
261 * will be rejected by XactReadOnly tests. However there are a few
262 * commands that are allowed in "read-only" xacts but cannot be allowed
263 * in Hot Standby mode. Those commands should call this function.
266 PreventCommandDuringRecovery(const char *cmdname)
268 if (RecoveryInProgress())
270 (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
271 /* translator: %s is name of a SQL command, eg CREATE */
272 errmsg("cannot execute %s during recovery",
277 * CheckRestrictedOperation: throw error for hazardous command if we're
278 * inside a security restriction context.
280 * This is needed to protect session-local state for which there is not any
281 * better-defined protection mechanism, such as ownership.
284 CheckRestrictedOperation(const char *cmdname)
286 if (InSecurityRestrictedOperation())
288 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
289 /* translator: %s is name of a SQL command, eg PREPARE */
290 errmsg("cannot execute %s within security-restricted operation",
297 * general utility function invoker
299 * parsetree: the parse tree for the utility statement
300 * queryString: original source text of command
301 * params: parameters to use during execution
302 * isTopLevel: true if executing a "top level" (interactively issued) command
303 * dest: where to send results
304 * completionTag: points to a buffer of size COMPLETION_TAG_BUFSIZE
305 * in which to store a command completion status string.
307 * Notes: as of PG 8.4, caller MUST supply a queryString; it is not
308 * allowed anymore to pass NULL. (If you really don't have source text,
309 * you can pass a constant string, perhaps "(query not available)".)
311 * completionTag is only set nonempty if we want to return a nondefault status.
313 * completionTag may be NULL if caller doesn't want a status string.
316 ProcessUtility(Node *parsetree,
317 const char *queryString,
318 ParamListInfo params,
323 Assert(queryString != NULL); /* required as of 8.4 */
326 * We provide a function hook variable that lets loadable plugins get
327 * control when ProcessUtility is called. Such a plugin would normally
328 * call standard_ProcessUtility().
330 if (ProcessUtility_hook)
331 (*ProcessUtility_hook) (parsetree, queryString, params,
332 isTopLevel, dest, completionTag);
334 standard_ProcessUtility(parsetree, queryString, params,
335 isTopLevel, dest, completionTag);
339 standard_ProcessUtility(Node *parsetree,
340 const char *queryString,
341 ParamListInfo params,
346 check_xact_readonly(parsetree);
349 completionTag[0] = '\0';
351 switch (nodeTag(parsetree))
354 * ******************** transactions ********************
356 case T_TransactionStmt:
358 TransactionStmt *stmt = (TransactionStmt *) parsetree;
363 * START TRANSACTION, as defined by SQL99: Identical
364 * to BEGIN. Same code for both.
366 case TRANS_STMT_BEGIN:
367 case TRANS_STMT_START:
371 BeginTransactionBlock();
372 foreach(lc, stmt->options)
374 DefElem *item = (DefElem *) lfirst(lc);
376 if (strcmp(item->defname, "transaction_isolation") == 0)
377 SetPGVariable("transaction_isolation",
378 list_make1(item->arg),
380 else if (strcmp(item->defname, "transaction_read_only") == 0)
381 SetPGVariable("transaction_read_only",
382 list_make1(item->arg),
384 else if (strcmp(item->defname, "transaction_deferrable") == 0)
385 SetPGVariable("transaction_deferrable",
386 list_make1(item->arg),
392 case TRANS_STMT_COMMIT:
393 if (!EndTransactionBlock())
395 /* report unsuccessful commit in completionTag */
397 strcpy(completionTag, "ROLLBACK");
401 case TRANS_STMT_PREPARE:
402 PreventCommandDuringRecovery("PREPARE TRANSACTION");
403 if (!PrepareTransactionBlock(stmt->gid))
405 /* report unsuccessful commit in completionTag */
407 strcpy(completionTag, "ROLLBACK");
411 case TRANS_STMT_COMMIT_PREPARED:
412 PreventTransactionChain(isTopLevel, "COMMIT PREPARED");
413 PreventCommandDuringRecovery("COMMIT PREPARED");
414 FinishPreparedTransaction(stmt->gid, true);
417 case TRANS_STMT_ROLLBACK_PREPARED:
418 PreventTransactionChain(isTopLevel, "ROLLBACK PREPARED");
419 PreventCommandDuringRecovery("ROLLBACK PREPARED");
420 FinishPreparedTransaction(stmt->gid, false);
423 case TRANS_STMT_ROLLBACK:
424 UserAbortTransactionBlock();
427 case TRANS_STMT_SAVEPOINT:
432 RequireTransactionChain(isTopLevel, "SAVEPOINT");
434 foreach(cell, stmt->options)
436 DefElem *elem = lfirst(cell);
438 if (strcmp(elem->defname, "savepoint_name") == 0)
439 name = strVal(elem->arg);
442 Assert(PointerIsValid(name));
444 DefineSavepoint(name);
448 case TRANS_STMT_RELEASE:
449 RequireTransactionChain(isTopLevel, "RELEASE SAVEPOINT");
450 ReleaseSavepoint(stmt->options);
453 case TRANS_STMT_ROLLBACK_TO:
454 RequireTransactionChain(isTopLevel, "ROLLBACK TO SAVEPOINT");
455 RollbackToSavepoint(stmt->options);
458 * CommitTransactionCommand is in charge of
459 * re-defining the savepoint again
467 * Portal (cursor) manipulation
469 * Note: DECLARE CURSOR is processed mostly as a SELECT, and
470 * therefore what we will get here is a PlannedStmt not a bare
475 PlannedStmt *stmt = (PlannedStmt *) parsetree;
477 if (stmt->utilityStmt == NULL ||
478 !IsA(stmt->utilityStmt, DeclareCursorStmt))
479 elog(ERROR, "non-DECLARE CURSOR PlannedStmt passed to ProcessUtility");
480 PerformCursorOpen(stmt, params, queryString, isTopLevel);
484 case T_ClosePortalStmt:
486 ClosePortalStmt *stmt = (ClosePortalStmt *) parsetree;
488 CheckRestrictedOperation("CLOSE");
489 PerformPortalClose(stmt->portalname);
494 PerformPortalFetch((FetchStmt *) parsetree, dest,
499 * relation and attribute manipulation
501 case T_CreateSchemaStmt:
502 CreateSchemaCommand((CreateSchemaStmt *) parsetree,
507 case T_CreateForeignTableStmt:
513 /* Run parse analysis ... */
514 stmts = transformCreateStmt((CreateStmt *) parsetree,
520 Node *stmt = (Node *) lfirst(l);
522 if (IsA(stmt, CreateStmt))
525 static char *validnsps[] = HEAP_RELOPT_NAMESPACES;
527 /* Create the table itself */
528 relOid = DefineRelation((CreateStmt *) stmt,
533 * Let AlterTableCreateToastTable decide if this one
534 * needs a secondary relation too.
536 CommandCounterIncrement();
538 /* parse and validate reloptions for the toast table */
539 toast_options = transformRelOptions((Datum) 0,
540 ((CreateStmt *) stmt)->options,
544 (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options,
547 AlterTableCreateToastTable(relOid, toast_options);
549 else if (IsA(stmt, CreateForeignTableStmt))
551 /* Create the table itself */
552 relOid = DefineRelation((CreateStmt *) stmt,
553 RELKIND_FOREIGN_TABLE,
555 CreateForeignTable((CreateForeignTableStmt *) stmt,
560 /* Recurse for anything else */
569 /* Need CCI between commands */
570 if (lnext(l) != NULL)
571 CommandCounterIncrement();
576 case T_CreateTableSpaceStmt:
577 PreventTransactionChain(isTopLevel, "CREATE TABLESPACE");
578 CreateTableSpace((CreateTableSpaceStmt *) parsetree);
581 case T_DropTableSpaceStmt:
582 PreventTransactionChain(isTopLevel, "DROP TABLESPACE");
583 DropTableSpace((DropTableSpaceStmt *) parsetree);
586 case T_AlterTableSpaceOptionsStmt:
587 AlterTableSpaceOptions((AlterTableSpaceOptionsStmt *) parsetree);
590 case T_CreateExtensionStmt:
591 CreateExtension((CreateExtensionStmt *) parsetree);
594 case T_AlterExtensionStmt:
595 ExecAlterExtensionStmt((AlterExtensionStmt *) parsetree);
598 case T_AlterExtensionContentsStmt:
599 ExecAlterExtensionContentsStmt((AlterExtensionContentsStmt *) parsetree);
602 case T_CreateFdwStmt:
603 CreateForeignDataWrapper((CreateFdwStmt *) parsetree);
607 AlterForeignDataWrapper((AlterFdwStmt *) parsetree);
611 RemoveForeignDataWrapper((DropFdwStmt *) parsetree);
614 case T_CreateForeignServerStmt:
615 CreateForeignServer((CreateForeignServerStmt *) parsetree);
618 case T_AlterForeignServerStmt:
619 AlterForeignServer((AlterForeignServerStmt *) parsetree);
622 case T_DropForeignServerStmt:
623 RemoveForeignServer((DropForeignServerStmt *) parsetree);
626 case T_CreateUserMappingStmt:
627 CreateUserMapping((CreateUserMappingStmt *) parsetree);
630 case T_AlterUserMappingStmt:
631 AlterUserMapping((AlterUserMappingStmt *) parsetree);
634 case T_DropUserMappingStmt:
635 RemoveUserMapping((DropUserMappingStmt *) parsetree);
640 DropStmt *stmt = (DropStmt *) parsetree;
642 switch (stmt->removeType)
645 case OBJECT_SEQUENCE:
648 case OBJECT_FOREIGN_TABLE:
649 RemoveRelations(stmt);
657 case OBJECT_COLLATION:
658 DropCollationsCommand(stmt);
661 case OBJECT_CONVERSION:
662 DropConversionsCommand(stmt);
669 case OBJECT_TSPARSER:
670 RemoveTSParsers(stmt);
673 case OBJECT_TSDICTIONARY:
674 RemoveTSDictionaries(stmt);
677 case OBJECT_TSTEMPLATE:
678 RemoveTSTemplates(stmt);
681 case OBJECT_TSCONFIGURATION:
682 RemoveTSConfigurations(stmt);
685 case OBJECT_EXTENSION:
686 RemoveExtensions(stmt);
690 elog(ERROR, "unrecognized drop object type: %d",
691 (int) stmt->removeType);
698 ExecuteTruncate((TruncateStmt *) parsetree);
702 CommentObject((CommentStmt *) parsetree);
706 ExecSecLabelStmt((SecLabelStmt *) parsetree);
713 processed = DoCopy((CopyStmt *) parsetree, queryString);
715 snprintf(completionTag, COMPLETION_TAG_BUFSIZE,
716 "COPY " UINT64_FORMAT, processed);
721 CheckRestrictedOperation("PREPARE");
722 PrepareQuery((PrepareStmt *) parsetree, queryString);
726 ExecuteQuery((ExecuteStmt *) parsetree, queryString, params,
727 dest, completionTag);
730 case T_DeallocateStmt:
731 CheckRestrictedOperation("DEALLOCATE");
732 DeallocateQuery((DeallocateStmt *) parsetree);
739 ExecRenameStmt((RenameStmt *) parsetree);
742 case T_AlterObjectSchemaStmt:
743 ExecAlterObjectSchemaStmt((AlterObjectSchemaStmt *) parsetree);
746 case T_AlterOwnerStmt:
747 ExecAlterOwnerStmt((AlterOwnerStmt *) parsetree);
750 case T_AlterTableStmt:
755 /* Run parse analysis ... */
756 stmts = transformAlterTableStmt((AlterTableStmt *) parsetree,
762 Node *stmt = (Node *) lfirst(l);
764 if (IsA(stmt, AlterTableStmt))
766 /* Do the table alteration proper */
767 AlterTable((AlterTableStmt *) stmt);
771 /* Recurse for anything else */
780 /* Need CCI between commands */
781 if (lnext(l) != NULL)
782 CommandCounterIncrement();
787 case T_AlterDomainStmt:
789 AlterDomainStmt *stmt = (AlterDomainStmt *) parsetree;
792 * Some or all of these functions are recursive to cover
793 * inherited things, so permission checks are done there.
795 switch (stmt->subtype)
797 case 'T': /* ALTER DOMAIN DEFAULT */
800 * Recursively alter column default for table and, if
801 * requested, for descendants
803 AlterDomainDefault(stmt->typeName,
806 case 'N': /* ALTER DOMAIN DROP NOT NULL */
807 AlterDomainNotNull(stmt->typeName,
810 case 'O': /* ALTER DOMAIN SET NOT NULL */
811 AlterDomainNotNull(stmt->typeName,
814 case 'C': /* ADD CONSTRAINT */
815 AlterDomainAddConstraint(stmt->typeName,
818 case 'X': /* DROP CONSTRAINT */
819 AlterDomainDropConstraint(stmt->typeName,
823 case 'V': /* VALIDATE CONSTRAINT */
824 AlterDomainValidateConstraint(stmt->typeName,
828 elog(ERROR, "unrecognized alter domain type: %d",
829 (int) stmt->subtype);
836 ExecuteGrantStmt((GrantStmt *) parsetree);
839 case T_GrantRoleStmt:
840 GrantRole((GrantRoleStmt *) parsetree);
843 case T_AlterDefaultPrivilegesStmt:
844 ExecAlterDefaultPrivilegesStmt((AlterDefaultPrivilegesStmt *) parsetree);
848 * **************** object creation / destruction *****************
852 DefineStmt *stmt = (DefineStmt *) parsetree;
856 case OBJECT_AGGREGATE:
857 DefineAggregate(stmt->defnames, stmt->args,
858 stmt->oldstyle, stmt->definition);
860 case OBJECT_OPERATOR:
861 Assert(stmt->args == NIL);
862 DefineOperator(stmt->defnames, stmt->definition);
865 Assert(stmt->args == NIL);
866 DefineType(stmt->defnames, stmt->definition);
868 case OBJECT_TSPARSER:
869 Assert(stmt->args == NIL);
870 DefineTSParser(stmt->defnames, stmt->definition);
872 case OBJECT_TSDICTIONARY:
873 Assert(stmt->args == NIL);
874 DefineTSDictionary(stmt->defnames, stmt->definition);
876 case OBJECT_TSTEMPLATE:
877 Assert(stmt->args == NIL);
878 DefineTSTemplate(stmt->defnames, stmt->definition);
880 case OBJECT_TSCONFIGURATION:
881 Assert(stmt->args == NIL);
882 DefineTSConfiguration(stmt->defnames, stmt->definition);
884 case OBJECT_COLLATION:
885 Assert(stmt->args == NIL);
886 DefineCollation(stmt->defnames, stmt->definition);
889 elog(ERROR, "unrecognized define stmt type: %d",
896 case T_CompositeTypeStmt: /* CREATE TYPE (composite) */
898 CompositeTypeStmt *stmt = (CompositeTypeStmt *) parsetree;
900 DefineCompositeType(stmt->typevar, stmt->coldeflist);
904 case T_CreateEnumStmt: /* CREATE TYPE (enum) */
905 DefineEnum((CreateEnumStmt *) parsetree);
908 case T_AlterEnumStmt: /* ALTER TYPE (enum) */
911 * We disallow this in transaction blocks, because we can't cope
912 * with enum OID values getting into indexes and then having their
913 * defining pg_enum entries go away.
915 PreventTransactionChain(isTopLevel, "ALTER TYPE ... ADD");
916 AlterEnum((AlterEnumStmt *) parsetree);
919 case T_ViewStmt: /* CREATE VIEW */
920 DefineView((ViewStmt *) parsetree, queryString);
923 case T_CreateFunctionStmt: /* CREATE FUNCTION */
924 CreateFunction((CreateFunctionStmt *) parsetree, queryString);
927 case T_AlterFunctionStmt: /* ALTER FUNCTION */
928 AlterFunction((AlterFunctionStmt *) parsetree);
931 case T_IndexStmt: /* CREATE INDEX */
933 IndexStmt *stmt = (IndexStmt *) parsetree;
935 if (stmt->concurrent)
936 PreventTransactionChain(isTopLevel,
937 "CREATE INDEX CONCURRENTLY");
939 CheckRelationOwnership(stmt->relation, true);
941 /* Run parse analysis ... */
942 stmt = transformIndexStmt(stmt, queryString);
945 DefineIndex(stmt->relation, /* relation */
946 stmt->idxname, /* index name */
947 InvalidOid, /* no predefined OID */
948 stmt->accessMethod, /* am name */
950 stmt->indexParams, /* parameters */
951 (Expr *) stmt->whereClause,
953 stmt->excludeOpNames,
959 false, /* is_alter_table */
960 true, /* check_rights */
961 false, /* skip_build */
963 stmt->concurrent); /* concurrent */
967 case T_RuleStmt: /* CREATE RULE */
968 DefineRule((RuleStmt *) parsetree, queryString);
971 case T_CreateSeqStmt:
972 DefineSequence((CreateSeqStmt *) parsetree);
976 AlterSequence((AlterSeqStmt *) parsetree);
979 case T_RemoveFuncStmt:
981 RemoveFuncStmt *stmt = (RemoveFuncStmt *) parsetree;
985 case OBJECT_FUNCTION:
986 RemoveFunction(stmt);
988 case OBJECT_AGGREGATE:
989 RemoveAggregate(stmt);
991 case OBJECT_OPERATOR:
992 RemoveOperator(stmt);
995 elog(ERROR, "unrecognized object type: %d",
1003 ExecuteDoStmt((DoStmt *) parsetree);
1006 case T_CreatedbStmt:
1007 PreventTransactionChain(isTopLevel, "CREATE DATABASE");
1008 createdb((CreatedbStmt *) parsetree);
1011 case T_AlterDatabaseStmt:
1012 AlterDatabase((AlterDatabaseStmt *) parsetree, isTopLevel);
1015 case T_AlterDatabaseSetStmt:
1016 AlterDatabaseSet((AlterDatabaseSetStmt *) parsetree);
1021 DropdbStmt *stmt = (DropdbStmt *) parsetree;
1023 PreventTransactionChain(isTopLevel, "DROP DATABASE");
1024 dropdb(stmt->dbname, stmt->missing_ok);
1028 /* Query-level asynchronous notification */
1031 NotifyStmt *stmt = (NotifyStmt *) parsetree;
1033 PreventCommandDuringRecovery("NOTIFY");
1034 Async_Notify(stmt->conditionname, stmt->payload);
1040 ListenStmt *stmt = (ListenStmt *) parsetree;
1042 PreventCommandDuringRecovery("LISTEN");
1043 CheckRestrictedOperation("LISTEN");
1044 Async_Listen(stmt->conditionname);
1048 case T_UnlistenStmt:
1050 UnlistenStmt *stmt = (UnlistenStmt *) parsetree;
1052 PreventCommandDuringRecovery("UNLISTEN");
1053 CheckRestrictedOperation("UNLISTEN");
1054 if (stmt->conditionname)
1055 Async_Unlisten(stmt->conditionname);
1057 Async_UnlistenAll();
1063 LoadStmt *stmt = (LoadStmt *) parsetree;
1065 closeAllVfds(); /* probably not necessary... */
1066 /* Allowed names are restricted if you're not superuser */
1067 load_file(stmt->filename, !superuser());
1072 /* we choose to allow this during "read only" transactions */
1073 PreventCommandDuringRecovery("CLUSTER");
1074 cluster((ClusterStmt *) parsetree, isTopLevel);
1078 /* we choose to allow this during "read only" transactions */
1079 PreventCommandDuringRecovery("VACUUM");
1080 vacuum((VacuumStmt *) parsetree, InvalidOid, true, NULL, false,
1085 ExplainQuery((ExplainStmt *) parsetree, queryString, params, dest);
1088 case T_VariableSetStmt:
1089 ExecSetVariableStmt((VariableSetStmt *) parsetree);
1092 case T_VariableShowStmt:
1094 VariableShowStmt *n = (VariableShowStmt *) parsetree;
1096 GetPGVariable(n->name, dest);
1101 /* should we allow DISCARD PLANS? */
1102 CheckRestrictedOperation("DISCARD");
1103 DiscardCommand((DiscardStmt *) parsetree, isTopLevel);
1106 case T_CreateTrigStmt:
1107 (void) CreateTrigger((CreateTrigStmt *) parsetree, queryString,
1108 InvalidOid, InvalidOid, false);
1111 case T_DropPropertyStmt:
1113 DropPropertyStmt *stmt = (DropPropertyStmt *) parsetree;
1116 relId = RangeVarGetRelid(stmt->relation, false);
1118 switch (stmt->removeType)
1121 /* RemoveRewriteRule checks permissions */
1122 RemoveRewriteRule(relId, stmt->property,
1123 stmt->behavior, stmt->missing_ok);
1125 case OBJECT_TRIGGER:
1126 /* DropTrigger checks permissions */
1127 DropTrigger(relId, stmt->property,
1128 stmt->behavior, stmt->missing_ok);
1131 elog(ERROR, "unrecognized object type: %d",
1132 (int) stmt->removeType);
1138 case T_CreatePLangStmt:
1139 CreateProceduralLanguage((CreatePLangStmt *) parsetree);
1142 case T_DropPLangStmt:
1143 DropProceduralLanguage((DropPLangStmt *) parsetree);
1147 * ******************************** DOMAIN statements ****
1149 case T_CreateDomainStmt:
1150 DefineDomain((CreateDomainStmt *) parsetree);
1154 * ******************************** ROLE statements ****
1156 case T_CreateRoleStmt:
1157 CreateRole((CreateRoleStmt *) parsetree);
1160 case T_AlterRoleStmt:
1161 AlterRole((AlterRoleStmt *) parsetree);
1164 case T_AlterRoleSetStmt:
1165 AlterRoleSet((AlterRoleSetStmt *) parsetree);
1168 case T_DropRoleStmt:
1169 DropRole((DropRoleStmt *) parsetree);
1172 case T_DropOwnedStmt:
1173 DropOwnedObjects((DropOwnedStmt *) parsetree);
1176 case T_ReassignOwnedStmt:
1177 ReassignOwnedObjects((ReassignOwnedStmt *) parsetree);
1183 * Since the lock would just get dropped immediately, LOCK TABLE
1184 * outside a transaction block is presumed to be user error.
1186 RequireTransactionChain(isTopLevel, "LOCK TABLE");
1187 LockTableCommand((LockStmt *) parsetree);
1190 case T_ConstraintsSetStmt:
1191 AfterTriggerSetState((ConstraintsSetStmt *) parsetree);
1194 case T_CheckPointStmt:
1197 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1198 errmsg("must be superuser to do CHECKPOINT")));
1201 * You might think we should have a PreventCommandDuringRecovery()
1202 * here, but we interpret a CHECKPOINT command during recovery as
1203 * a request for a restartpoint instead. We allow this since it
1204 * can be a useful way of reducing switchover time when using
1205 * various forms of replication.
1207 RequestCheckpoint(CHECKPOINT_IMMEDIATE | CHECKPOINT_WAIT |
1208 (RecoveryInProgress() ? 0 : CHECKPOINT_FORCE));
1213 ReindexStmt *stmt = (ReindexStmt *) parsetree;
1215 /* we choose to allow this during "read only" transactions */
1216 PreventCommandDuringRecovery("REINDEX");
1220 ReindexIndex(stmt->relation);
1223 ReindexTable(stmt->relation);
1225 case OBJECT_DATABASE:
1228 * This cannot run inside a user transaction block; if
1229 * we were inside a transaction, then its commit- and
1230 * start-transaction-command calls would not have the
1233 PreventTransactionChain(isTopLevel,
1234 "REINDEX DATABASE");
1235 ReindexDatabase(stmt->name,
1236 stmt->do_system, stmt->do_user);
1239 elog(ERROR, "unrecognized object type: %d",
1247 case T_CreateConversionStmt:
1248 CreateConversionCommand((CreateConversionStmt *) parsetree);
1251 case T_CreateCastStmt:
1252 CreateCast((CreateCastStmt *) parsetree);
1255 case T_DropCastStmt:
1256 DropCast((DropCastStmt *) parsetree);
1259 case T_CreateOpClassStmt:
1260 DefineOpClass((CreateOpClassStmt *) parsetree);
1263 case T_CreateOpFamilyStmt:
1264 DefineOpFamily((CreateOpFamilyStmt *) parsetree);
1267 case T_AlterOpFamilyStmt:
1268 AlterOpFamily((AlterOpFamilyStmt *) parsetree);
1271 case T_RemoveOpClassStmt:
1272 RemoveOpClass((RemoveOpClassStmt *) parsetree);
1275 case T_RemoveOpFamilyStmt:
1276 RemoveOpFamily((RemoveOpFamilyStmt *) parsetree);
1279 case T_AlterTSDictionaryStmt:
1280 AlterTSDictionary((AlterTSDictionaryStmt *) parsetree);
1283 case T_AlterTSConfigurationStmt:
1284 AlterTSConfiguration((AlterTSConfigurationStmt *) parsetree);
1288 elog(ERROR, "unrecognized node type: %d",
1289 (int) nodeTag(parsetree));
1295 * UtilityReturnsTuples
1296 * Return "true" if this utility statement will send output to the
1299 * Generally, there should be a case here for each case in ProcessUtility
1300 * where "dest" is passed on.
1303 UtilityReturnsTuples(Node *parsetree)
1305 switch (nodeTag(parsetree))
1309 FetchStmt *stmt = (FetchStmt *) parsetree;
1314 portal = GetPortalByName(stmt->portalname);
1315 if (!PortalIsValid(portal))
1316 return false; /* not our business to raise error */
1317 return portal->tupDesc ? true : false;
1322 ExecuteStmt *stmt = (ExecuteStmt *) parsetree;
1323 PreparedStatement *entry;
1327 entry = FetchPreparedStatement(stmt->name, false);
1329 return false; /* not our business to raise error */
1330 if (entry->plansource->resultDesc)
1338 case T_VariableShowStmt:
1347 * UtilityTupleDescriptor
1348 * Fetch the actual output tuple descriptor for a utility statement
1349 * for which UtilityReturnsTuples() previously returned "true".
1351 * The returned descriptor is created in (or copied into) the current memory
1355 UtilityTupleDescriptor(Node *parsetree)
1357 switch (nodeTag(parsetree))
1361 FetchStmt *stmt = (FetchStmt *) parsetree;
1366 portal = GetPortalByName(stmt->portalname);
1367 if (!PortalIsValid(portal))
1368 return NULL; /* not our business to raise error */
1369 return CreateTupleDescCopy(portal->tupDesc);
1374 ExecuteStmt *stmt = (ExecuteStmt *) parsetree;
1375 PreparedStatement *entry;
1379 entry = FetchPreparedStatement(stmt->name, false);
1381 return NULL; /* not our business to raise error */
1382 return FetchPreparedStatementResultDesc(entry);
1386 return ExplainResultDesc((ExplainStmt *) parsetree);
1388 case T_VariableShowStmt:
1390 VariableShowStmt *n = (VariableShowStmt *) parsetree;
1392 return GetPGVariableResultDesc(n->name);
1402 * QueryReturnsTuples
1403 * Return "true" if this Query will send output to the destination.
1407 QueryReturnsTuples(Query *parsetree)
1409 switch (parsetree->commandType)
1412 /* returns tuples ... unless it's DECLARE CURSOR or SELECT INTO */
1413 if (parsetree->utilityStmt == NULL &&
1414 parsetree->intoClause == NULL)
1420 /* the forms with RETURNING return tuples */
1421 if (parsetree->returningList)
1425 return UtilityReturnsTuples(parsetree->utilityStmt);
1428 /* probably shouldn't get here */
1431 return false; /* default */
1437 * AlterObjectTypeCommandTag
1438 * helper function for CreateCommandTag
1440 * This covers most cases where ALTER is used with an ObjectType enum.
1443 AlterObjectTypeCommandTag(ObjectType objtype)
1449 case OBJECT_AGGREGATE:
1450 tag = "ALTER AGGREGATE";
1452 case OBJECT_ATTRIBUTE:
1458 case OBJECT_COLLATION:
1459 tag = "ALTER COLLATION";
1462 tag = "ALTER TABLE";
1464 case OBJECT_CONSTRAINT:
1465 tag = "ALTER TABLE";
1467 case OBJECT_CONVERSION:
1468 tag = "ALTER CONVERSION";
1470 case OBJECT_DATABASE:
1471 tag = "ALTER DATABASE";
1474 tag = "ALTER DOMAIN";
1476 case OBJECT_EXTENSION:
1477 tag = "ALTER EXTENSION";
1480 tag = "ALTER FOREIGN DATA WRAPPER";
1482 case OBJECT_FOREIGN_SERVER:
1483 tag = "ALTER SERVER";
1485 case OBJECT_FOREIGN_TABLE:
1486 tag = "ALTER FOREIGN TABLE";
1488 case OBJECT_FUNCTION:
1489 tag = "ALTER FUNCTION";
1492 tag = "ALTER INDEX";
1494 case OBJECT_LANGUAGE:
1495 tag = "ALTER LANGUAGE";
1497 case OBJECT_LARGEOBJECT:
1498 tag = "ALTER LARGE OBJECT";
1500 case OBJECT_OPCLASS:
1501 tag = "ALTER OPERATOR CLASS";
1503 case OBJECT_OPERATOR:
1504 tag = "ALTER OPERATOR";
1506 case OBJECT_OPFAMILY:
1507 tag = "ALTER OPERATOR FAMILY";
1516 tag = "ALTER SCHEMA";
1518 case OBJECT_SEQUENCE:
1519 tag = "ALTER SEQUENCE";
1522 tag = "ALTER TABLE";
1524 case OBJECT_TABLESPACE:
1525 tag = "ALTER TABLESPACE";
1527 case OBJECT_TRIGGER:
1528 tag = "ALTER TRIGGER";
1530 case OBJECT_TSCONFIGURATION:
1531 tag = "ALTER TEXT SEARCH CONFIGURATION";
1533 case OBJECT_TSDICTIONARY:
1534 tag = "ALTER TEXT SEARCH DICTIONARY";
1536 case OBJECT_TSPARSER:
1537 tag = "ALTER TEXT SEARCH PARSER";
1539 case OBJECT_TSTEMPLATE:
1540 tag = "ALTER TEXT SEARCH TEMPLATE";
1558 * utility to get a string representation of the command operation,
1559 * given either a raw (un-analyzed) parsetree or a planned query.
1561 * This must handle all command types, but since the vast majority
1562 * of 'em are utility commands, it seems sensible to keep it here.
1564 * NB: all result strings must be shorter than COMPLETION_TAG_BUFSIZE.
1565 * Also, the result must point at a true constant (permanent storage).
1568 CreateCommandTag(Node *parsetree)
1572 switch (nodeTag(parsetree))
1574 /* raw plannable queries */
1591 /* utility statements --- same whether raw or cooked */
1592 case T_TransactionStmt:
1594 TransactionStmt *stmt = (TransactionStmt *) parsetree;
1598 case TRANS_STMT_BEGIN:
1602 case TRANS_STMT_START:
1603 tag = "START TRANSACTION";
1606 case TRANS_STMT_COMMIT:
1610 case TRANS_STMT_ROLLBACK:
1611 case TRANS_STMT_ROLLBACK_TO:
1615 case TRANS_STMT_SAVEPOINT:
1619 case TRANS_STMT_RELEASE:
1623 case TRANS_STMT_PREPARE:
1624 tag = "PREPARE TRANSACTION";
1627 case TRANS_STMT_COMMIT_PREPARED:
1628 tag = "COMMIT PREPARED";
1631 case TRANS_STMT_ROLLBACK_PREPARED:
1632 tag = "ROLLBACK PREPARED";
1642 case T_DeclareCursorStmt:
1643 tag = "DECLARE CURSOR";
1646 case T_ClosePortalStmt:
1648 ClosePortalStmt *stmt = (ClosePortalStmt *) parsetree;
1650 if (stmt->portalname == NULL)
1651 tag = "CLOSE CURSOR ALL";
1653 tag = "CLOSE CURSOR";
1659 FetchStmt *stmt = (FetchStmt *) parsetree;
1661 tag = (stmt->ismove) ? "MOVE" : "FETCH";
1665 case T_CreateDomainStmt:
1666 tag = "CREATE DOMAIN";
1669 case T_CreateSchemaStmt:
1670 tag = "CREATE SCHEMA";
1674 tag = "CREATE TABLE";
1677 case T_CreateTableSpaceStmt:
1678 tag = "CREATE TABLESPACE";
1681 case T_DropTableSpaceStmt:
1682 tag = "DROP TABLESPACE";
1685 case T_AlterTableSpaceOptionsStmt:
1686 tag = "ALTER TABLESPACE";
1689 case T_CreateExtensionStmt:
1690 tag = "CREATE EXTENSION";
1693 case T_AlterExtensionStmt:
1694 tag = "ALTER EXTENSION";
1697 case T_AlterExtensionContentsStmt:
1698 tag = "ALTER EXTENSION";
1701 case T_CreateFdwStmt:
1702 tag = "CREATE FOREIGN DATA WRAPPER";
1705 case T_AlterFdwStmt:
1706 tag = "ALTER FOREIGN DATA WRAPPER";
1710 tag = "DROP FOREIGN DATA WRAPPER";
1713 case T_CreateForeignServerStmt:
1714 tag = "CREATE SERVER";
1717 case T_AlterForeignServerStmt:
1718 tag = "ALTER SERVER";
1721 case T_DropForeignServerStmt:
1722 tag = "DROP SERVER";
1725 case T_CreateUserMappingStmt:
1726 tag = "CREATE USER MAPPING";
1729 case T_AlterUserMappingStmt:
1730 tag = "ALTER USER MAPPING";
1733 case T_DropUserMappingStmt:
1734 tag = "DROP USER MAPPING";
1737 case T_CreateForeignTableStmt:
1738 tag = "CREATE FOREIGN TABLE";
1742 switch (((DropStmt *) parsetree)->removeType)
1747 case OBJECT_SEQUENCE:
1748 tag = "DROP SEQUENCE";
1760 tag = "DROP DOMAIN";
1762 case OBJECT_COLLATION:
1763 tag = "DROP COLLATION";
1765 case OBJECT_CONVERSION:
1766 tag = "DROP CONVERSION";
1769 tag = "DROP SCHEMA";
1771 case OBJECT_TSPARSER:
1772 tag = "DROP TEXT SEARCH PARSER";
1774 case OBJECT_TSDICTIONARY:
1775 tag = "DROP TEXT SEARCH DICTIONARY";
1777 case OBJECT_TSTEMPLATE:
1778 tag = "DROP TEXT SEARCH TEMPLATE";
1780 case OBJECT_TSCONFIGURATION:
1781 tag = "DROP TEXT SEARCH CONFIGURATION";
1783 case OBJECT_FOREIGN_TABLE:
1784 tag = "DROP FOREIGN TABLE";
1786 case OBJECT_EXTENSION:
1787 tag = "DROP EXTENSION";
1794 case T_TruncateStmt:
1795 tag = "TRUNCATE TABLE";
1802 case T_SecLabelStmt:
1803 tag = "SECURITY LABEL";
1811 tag = AlterObjectTypeCommandTag(((RenameStmt *) parsetree)->renameType);
1814 case T_AlterObjectSchemaStmt:
1815 tag = AlterObjectTypeCommandTag(((AlterObjectSchemaStmt *) parsetree)->objectType);
1818 case T_AlterOwnerStmt:
1819 tag = AlterObjectTypeCommandTag(((AlterOwnerStmt *) parsetree)->objectType);
1822 case T_AlterTableStmt:
1823 tag = AlterObjectTypeCommandTag(((AlterTableStmt *) parsetree)->relkind);
1826 case T_AlterDomainStmt:
1827 tag = "ALTER DOMAIN";
1830 case T_AlterFunctionStmt:
1831 tag = "ALTER FUNCTION";
1836 GrantStmt *stmt = (GrantStmt *) parsetree;
1838 tag = (stmt->is_grant) ? "GRANT" : "REVOKE";
1842 case T_GrantRoleStmt:
1844 GrantRoleStmt *stmt = (GrantRoleStmt *) parsetree;
1846 tag = (stmt->is_grant) ? "GRANT ROLE" : "REVOKE ROLE";
1850 case T_AlterDefaultPrivilegesStmt:
1851 tag = "ALTER DEFAULT PRIVILEGES";
1855 switch (((DefineStmt *) parsetree)->kind)
1857 case OBJECT_AGGREGATE:
1858 tag = "CREATE AGGREGATE";
1860 case OBJECT_OPERATOR:
1861 tag = "CREATE OPERATOR";
1864 tag = "CREATE TYPE";
1866 case OBJECT_TSPARSER:
1867 tag = "CREATE TEXT SEARCH PARSER";
1869 case OBJECT_TSDICTIONARY:
1870 tag = "CREATE TEXT SEARCH DICTIONARY";
1872 case OBJECT_TSTEMPLATE:
1873 tag = "CREATE TEXT SEARCH TEMPLATE";
1875 case OBJECT_TSCONFIGURATION:
1876 tag = "CREATE TEXT SEARCH CONFIGURATION";
1878 case OBJECT_COLLATION:
1879 tag = "CREATE COLLATION";
1886 case T_CompositeTypeStmt:
1887 tag = "CREATE TYPE";
1890 case T_CreateEnumStmt:
1891 tag = "CREATE TYPE";
1894 case T_AlterEnumStmt:
1899 tag = "CREATE VIEW";
1902 case T_CreateFunctionStmt:
1903 tag = "CREATE FUNCTION";
1907 tag = "CREATE INDEX";
1911 tag = "CREATE RULE";
1914 case T_CreateSeqStmt:
1915 tag = "CREATE SEQUENCE";
1918 case T_AlterSeqStmt:
1919 tag = "ALTER SEQUENCE";
1922 case T_RemoveFuncStmt:
1923 switch (((RemoveFuncStmt *) parsetree)->kind)
1925 case OBJECT_FUNCTION:
1926 tag = "DROP FUNCTION";
1928 case OBJECT_AGGREGATE:
1929 tag = "DROP AGGREGATE";
1931 case OBJECT_OPERATOR:
1932 tag = "DROP OPERATOR";
1943 case T_CreatedbStmt:
1944 tag = "CREATE DATABASE";
1947 case T_AlterDatabaseStmt:
1948 tag = "ALTER DATABASE";
1951 case T_AlterDatabaseSetStmt:
1952 tag = "ALTER DATABASE";
1956 tag = "DROP DATABASE";
1967 case T_UnlistenStmt:
1980 if (((VacuumStmt *) parsetree)->options & VACOPT_VACUUM)
1990 case T_VariableSetStmt:
1991 switch (((VariableSetStmt *) parsetree)->kind)
1994 case VAR_SET_CURRENT:
1995 case VAR_SET_DEFAULT:
2008 case T_VariableShowStmt:
2013 switch (((DiscardStmt *) parsetree)->target)
2016 tag = "DISCARD ALL";
2019 tag = "DISCARD PLANS";
2022 tag = "DISCARD TEMP";
2029 case T_CreateTrigStmt:
2030 tag = "CREATE TRIGGER";
2033 case T_DropPropertyStmt:
2034 switch (((DropPropertyStmt *) parsetree)->removeType)
2036 case OBJECT_TRIGGER:
2037 tag = "DROP TRIGGER";
2047 case T_CreatePLangStmt:
2048 tag = "CREATE LANGUAGE";
2051 case T_DropPLangStmt:
2052 tag = "DROP LANGUAGE";
2055 case T_CreateRoleStmt:
2056 tag = "CREATE ROLE";
2059 case T_AlterRoleStmt:
2063 case T_AlterRoleSetStmt:
2067 case T_DropRoleStmt:
2071 case T_DropOwnedStmt:
2075 case T_ReassignOwnedStmt:
2076 tag = "REASSIGN OWNED";
2083 case T_ConstraintsSetStmt:
2084 tag = "SET CONSTRAINTS";
2087 case T_CheckPointStmt:
2095 case T_CreateConversionStmt:
2096 tag = "CREATE CONVERSION";
2099 case T_CreateCastStmt:
2100 tag = "CREATE CAST";
2103 case T_DropCastStmt:
2107 case T_CreateOpClassStmt:
2108 tag = "CREATE OPERATOR CLASS";
2111 case T_CreateOpFamilyStmt:
2112 tag = "CREATE OPERATOR FAMILY";
2115 case T_AlterOpFamilyStmt:
2116 tag = "ALTER OPERATOR FAMILY";
2119 case T_RemoveOpClassStmt:
2120 tag = "DROP OPERATOR CLASS";
2123 case T_RemoveOpFamilyStmt:
2124 tag = "DROP OPERATOR FAMILY";
2127 case T_AlterTSDictionaryStmt:
2128 tag = "ALTER TEXT SEARCH DICTIONARY";
2131 case T_AlterTSConfigurationStmt:
2132 tag = "ALTER TEXT SEARCH CONFIGURATION";
2143 case T_DeallocateStmt:
2145 DeallocateStmt *stmt = (DeallocateStmt *) parsetree;
2147 if (stmt->name == NULL)
2148 tag = "DEALLOCATE ALL";
2154 /* already-planned queries */
2157 PlannedStmt *stmt = (PlannedStmt *) parsetree;
2159 switch (stmt->commandType)
2164 * We take a little extra care here so that the result
2165 * will be useful for complaints about read-only
2168 if (stmt->utilityStmt != NULL)
2170 Assert(IsA(stmt->utilityStmt, DeclareCursorStmt));
2171 tag = "DECLARE CURSOR";
2173 else if (stmt->intoClause != NULL)
2174 tag = "SELECT INTO";
2175 else if (stmt->rowMarks != NIL)
2177 /* not 100% but probably close enough */
2178 if (((PlanRowMark *) linitial(stmt->rowMarks))->markType == ROW_MARK_EXCLUSIVE)
2179 tag = "SELECT FOR UPDATE";
2181 tag = "SELECT FOR SHARE";
2196 elog(WARNING, "unrecognized commandType: %d",
2197 (int) stmt->commandType);
2204 /* parsed-and-rewritten-but-not-planned queries */
2207 Query *stmt = (Query *) parsetree;
2209 switch (stmt->commandType)
2214 * We take a little extra care here so that the result
2215 * will be useful for complaints about read-only
2218 if (stmt->utilityStmt != NULL)
2220 Assert(IsA(stmt->utilityStmt, DeclareCursorStmt));
2221 tag = "DECLARE CURSOR";
2223 else if (stmt->intoClause != NULL)
2224 tag = "SELECT INTO";
2225 else if (stmt->rowMarks != NIL)
2227 /* not 100% but probably close enough */
2228 if (((RowMarkClause *) linitial(stmt->rowMarks))->forUpdate)
2229 tag = "SELECT FOR UPDATE";
2231 tag = "SELECT FOR SHARE";
2246 tag = CreateCommandTag(stmt->utilityStmt);
2249 elog(WARNING, "unrecognized commandType: %d",
2250 (int) stmt->commandType);
2258 elog(WARNING, "unrecognized node type: %d",
2259 (int) nodeTag(parsetree));
2269 * GetCommandLogLevel
2270 * utility to get the minimum log_statement level for a command,
2271 * given either a raw (un-analyzed) parsetree or a planned query.
2273 * This must handle all command types, but since the vast majority
2274 * of 'em are utility commands, it seems sensible to keep it here.
2277 GetCommandLogLevel(Node *parsetree)
2281 switch (nodeTag(parsetree))
2283 /* raw plannable queries */
2291 if (((SelectStmt *) parsetree)->intoClause)
2292 lev = LOGSTMT_DDL; /* CREATE AS, SELECT INTO */
2297 /* utility statements --- same whether raw or cooked */
2298 case T_TransactionStmt:
2302 case T_DeclareCursorStmt:
2306 case T_ClosePortalStmt:
2314 case T_CreateSchemaStmt:
2319 case T_CreateForeignTableStmt:
2323 case T_CreateTableSpaceStmt:
2324 case T_DropTableSpaceStmt:
2325 case T_AlterTableSpaceOptionsStmt:
2329 case T_CreateExtensionStmt:
2330 case T_AlterExtensionStmt:
2331 case T_AlterExtensionContentsStmt:
2335 case T_CreateFdwStmt:
2336 case T_AlterFdwStmt:
2338 case T_CreateForeignServerStmt:
2339 case T_AlterForeignServerStmt:
2340 case T_DropForeignServerStmt:
2341 case T_CreateUserMappingStmt:
2342 case T_AlterUserMappingStmt:
2343 case T_DropUserMappingStmt:
2351 case T_TruncateStmt:
2359 case T_SecLabelStmt:
2364 if (((CopyStmt *) parsetree)->is_from)
2372 PrepareStmt *stmt = (PrepareStmt *) parsetree;
2374 /* Look through a PREPARE to the contained stmt */
2375 lev = GetCommandLogLevel(stmt->query);
2381 ExecuteStmt *stmt = (ExecuteStmt *) parsetree;
2382 PreparedStatement *ps;
2384 /* Look through an EXECUTE to the referenced stmt */
2385 ps = FetchPreparedStatement(stmt->name, false);
2387 lev = GetCommandLogLevel(ps->plansource->raw_parse_tree);
2393 case T_DeallocateStmt:
2401 case T_AlterObjectSchemaStmt:
2405 case T_AlterOwnerStmt:
2409 case T_AlterTableStmt:
2413 case T_AlterDomainStmt:
2421 case T_GrantRoleStmt:
2425 case T_AlterDefaultPrivilegesStmt:
2433 case T_CompositeTypeStmt:
2437 case T_CreateEnumStmt:
2441 case T_AlterEnumStmt:
2449 case T_CreateFunctionStmt:
2453 case T_AlterFunctionStmt:
2465 case T_CreateSeqStmt:
2469 case T_AlterSeqStmt:
2473 case T_RemoveFuncStmt:
2481 case T_CreatedbStmt:
2485 case T_AlterDatabaseStmt:
2489 case T_AlterDatabaseSetStmt:
2505 case T_UnlistenStmt:
2523 ExplainStmt *stmt = (ExplainStmt *) parsetree;
2524 bool analyze = false;
2527 /* Look through an EXPLAIN ANALYZE to the contained stmt */
2528 foreach(lc, stmt->options)
2530 DefElem *opt = (DefElem *) lfirst(lc);
2532 if (strcmp(opt->defname, "analyze") == 0)
2533 analyze = defGetBoolean(opt);
2534 /* don't "break", as explain.c will use the last value */
2537 return GetCommandLogLevel(stmt->query);
2539 /* Plain EXPLAIN isn't so interesting */
2544 case T_VariableSetStmt:
2548 case T_VariableShowStmt:
2556 case T_CreateTrigStmt:
2560 case T_DropPropertyStmt:
2564 case T_CreatePLangStmt:
2568 case T_DropPLangStmt:
2572 case T_CreateDomainStmt:
2576 case T_CreateRoleStmt:
2580 case T_AlterRoleStmt:
2584 case T_AlterRoleSetStmt:
2588 case T_DropRoleStmt:
2592 case T_DropOwnedStmt:
2596 case T_ReassignOwnedStmt:
2604 case T_ConstraintsSetStmt:
2608 case T_CheckPointStmt:
2613 lev = LOGSTMT_ALL; /* should this be DDL? */
2616 case T_CreateConversionStmt:
2620 case T_CreateCastStmt:
2624 case T_DropCastStmt:
2628 case T_CreateOpClassStmt:
2632 case T_CreateOpFamilyStmt:
2636 case T_AlterOpFamilyStmt:
2640 case T_RemoveOpClassStmt:
2644 case T_RemoveOpFamilyStmt:
2648 case T_AlterTSDictionaryStmt:
2652 case T_AlterTSConfigurationStmt:
2656 /* already-planned queries */
2659 PlannedStmt *stmt = (PlannedStmt *) parsetree;
2661 switch (stmt->commandType)
2664 if (stmt->intoClause != NULL)
2665 lev = LOGSTMT_DDL; /* CREATE AS, SELECT INTO */
2667 lev = LOGSTMT_ALL; /* SELECT or DECLARE CURSOR */
2677 elog(WARNING, "unrecognized commandType: %d",
2678 (int) stmt->commandType);
2685 /* parsed-and-rewritten-but-not-planned queries */
2688 Query *stmt = (Query *) parsetree;
2690 switch (stmt->commandType)
2693 if (stmt->intoClause != NULL)
2694 lev = LOGSTMT_DDL; /* CREATE AS, SELECT INTO */
2696 lev = LOGSTMT_ALL; /* SELECT or DECLARE CURSOR */
2706 lev = GetCommandLogLevel(stmt->utilityStmt);
2710 elog(WARNING, "unrecognized commandType: %d",
2711 (int) stmt->commandType);
2720 elog(WARNING, "unrecognized node type: %d",
2721 (int) nodeTag(parsetree));