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 */
133 elog(WARNING, "unrecognized commandType: %d",
134 (int) stmt->commandType);
138 /* For now, treat all utility commands as read/write */
143 * check_xact_readonly: is a utility command read-only?
145 * Here we use the loose rules of XactReadOnly mode: no permanent effects
146 * on the database are allowed.
149 check_xact_readonly(Node *parsetree)
155 * Note: Commands that need to do more complicated checking are handled
156 * elsewhere, in particular COPY and plannable statements do their own
157 * checking. However they should all call PreventCommandIfReadOnly to
158 * actually throw the error.
161 switch (nodeTag(parsetree))
163 case T_AlterDatabaseStmt:
164 case T_AlterDatabaseSetStmt:
165 case T_AlterDomainStmt:
166 case T_AlterFunctionStmt:
167 case T_AlterRoleStmt:
168 case T_AlterRoleSetStmt:
169 case T_AlterObjectSchemaStmt:
170 case T_AlterOwnerStmt:
172 case T_AlterTableStmt:
176 case T_CreateCastStmt:
177 case T_CreateConversionStmt:
179 case T_CreateDomainStmt:
180 case T_CreateFunctionStmt:
181 case T_CreateRoleStmt:
183 case T_CreatePLangStmt:
184 case T_CreateOpClassStmt:
185 case T_CreateOpFamilyStmt:
186 case T_AlterOpFamilyStmt:
188 case T_CreateSchemaStmt:
189 case T_CreateSeqStmt:
191 case T_CreateTableSpaceStmt:
192 case T_CreateTrigStmt:
193 case T_CompositeTypeStmt:
194 case T_CreateEnumStmt:
195 case T_AlterEnumStmt:
200 case T_DropTableSpaceStmt:
201 case T_RemoveFuncStmt:
203 case T_DropPLangStmt:
204 case T_RemoveOpClassStmt:
205 case T_RemoveOpFamilyStmt:
206 case T_DropPropertyStmt:
208 case T_GrantRoleStmt:
209 case T_AlterDefaultPrivilegesStmt:
211 case T_DropOwnedStmt:
212 case T_ReassignOwnedStmt:
213 case T_AlterTSDictionaryStmt:
214 case T_AlterTSConfigurationStmt:
215 case T_CreateExtensionStmt:
216 case T_AlterExtensionStmt:
217 case T_AlterExtensionContentsStmt:
218 case T_CreateFdwStmt:
221 case T_CreateForeignServerStmt:
222 case T_AlterForeignServerStmt:
223 case T_DropForeignServerStmt:
224 case T_CreateUserMappingStmt:
225 case T_AlterUserMappingStmt:
226 case T_DropUserMappingStmt:
227 case T_AlterTableSpaceOptionsStmt:
228 case T_CreateForeignTableStmt:
230 PreventCommandIfReadOnly(CreateCommandTag(parsetree));
239 * PreventCommandIfReadOnly: throw error if XactReadOnly
241 * This is useful mainly to ensure consistency of the error message wording;
242 * most callers have checked XactReadOnly for themselves.
245 PreventCommandIfReadOnly(const char *cmdname)
249 (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
250 /* translator: %s is name of a SQL command, eg CREATE */
251 errmsg("cannot execute %s in a read-only transaction",
256 * PreventCommandDuringRecovery: throw error if RecoveryInProgress
258 * The majority of operations that are unsafe in a Hot Standby slave
259 * will be rejected by XactReadOnly tests. However there are a few
260 * commands that are allowed in "read-only" xacts but cannot be allowed
261 * in Hot Standby mode. Those commands should call this function.
264 PreventCommandDuringRecovery(const char *cmdname)
266 if (RecoveryInProgress())
268 (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
269 /* translator: %s is name of a SQL command, eg CREATE */
270 errmsg("cannot execute %s during recovery",
275 * CheckRestrictedOperation: throw error for hazardous command if we're
276 * inside a security restriction context.
278 * This is needed to protect session-local state for which there is not any
279 * better-defined protection mechanism, such as ownership.
282 CheckRestrictedOperation(const char *cmdname)
284 if (InSecurityRestrictedOperation())
286 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
287 /* translator: %s is name of a SQL command, eg PREPARE */
288 errmsg("cannot execute %s within security-restricted operation",
295 * general utility function invoker
297 * parsetree: the parse tree for the utility statement
298 * queryString: original source text of command
299 * params: parameters to use during execution
300 * isTopLevel: true if executing a "top level" (interactively issued) command
301 * dest: where to send results
302 * completionTag: points to a buffer of size COMPLETION_TAG_BUFSIZE
303 * in which to store a command completion status string.
305 * Notes: as of PG 8.4, caller MUST supply a queryString; it is not
306 * allowed anymore to pass NULL. (If you really don't have source text,
307 * you can pass a constant string, perhaps "(query not available)".)
309 * completionTag is only set nonempty if we want to return a nondefault status.
311 * completionTag may be NULL if caller doesn't want a status string.
314 ProcessUtility(Node *parsetree,
315 const char *queryString,
316 ParamListInfo params,
321 Assert(queryString != NULL); /* required as of 8.4 */
324 * We provide a function hook variable that lets loadable plugins get
325 * control when ProcessUtility is called. Such a plugin would normally
326 * call standard_ProcessUtility().
328 if (ProcessUtility_hook)
329 (*ProcessUtility_hook) (parsetree, queryString, params,
330 isTopLevel, dest, completionTag);
332 standard_ProcessUtility(parsetree, queryString, params,
333 isTopLevel, dest, completionTag);
337 standard_ProcessUtility(Node *parsetree,
338 const char *queryString,
339 ParamListInfo params,
344 check_xact_readonly(parsetree);
347 completionTag[0] = '\0';
349 switch (nodeTag(parsetree))
352 * ******************** transactions ********************
354 case T_TransactionStmt:
356 TransactionStmt *stmt = (TransactionStmt *) parsetree;
361 * START TRANSACTION, as defined by SQL99: Identical
362 * to BEGIN. Same code for both.
364 case TRANS_STMT_BEGIN:
365 case TRANS_STMT_START:
369 BeginTransactionBlock();
370 foreach(lc, stmt->options)
372 DefElem *item = (DefElem *) lfirst(lc);
374 if (strcmp(item->defname, "transaction_isolation") == 0)
375 SetPGVariable("transaction_isolation",
376 list_make1(item->arg),
378 else if (strcmp(item->defname, "transaction_read_only") == 0)
379 SetPGVariable("transaction_read_only",
380 list_make1(item->arg),
382 else if (strcmp(item->defname, "transaction_deferrable") == 0)
383 SetPGVariable("transaction_deferrable",
384 list_make1(item->arg),
390 case TRANS_STMT_COMMIT:
391 if (!EndTransactionBlock())
393 /* report unsuccessful commit in completionTag */
395 strcpy(completionTag, "ROLLBACK");
399 case TRANS_STMT_PREPARE:
400 PreventCommandDuringRecovery("PREPARE TRANSACTION");
401 if (!PrepareTransactionBlock(stmt->gid))
403 /* report unsuccessful commit in completionTag */
405 strcpy(completionTag, "ROLLBACK");
409 case TRANS_STMT_COMMIT_PREPARED:
410 PreventTransactionChain(isTopLevel, "COMMIT PREPARED");
411 PreventCommandDuringRecovery("COMMIT PREPARED");
412 FinishPreparedTransaction(stmt->gid, true);
415 case TRANS_STMT_ROLLBACK_PREPARED:
416 PreventTransactionChain(isTopLevel, "ROLLBACK PREPARED");
417 PreventCommandDuringRecovery("ROLLBACK PREPARED");
418 FinishPreparedTransaction(stmt->gid, false);
421 case TRANS_STMT_ROLLBACK:
422 UserAbortTransactionBlock();
425 case TRANS_STMT_SAVEPOINT:
430 RequireTransactionChain(isTopLevel, "SAVEPOINT");
432 foreach(cell, stmt->options)
434 DefElem *elem = lfirst(cell);
436 if (strcmp(elem->defname, "savepoint_name") == 0)
437 name = strVal(elem->arg);
440 Assert(PointerIsValid(name));
442 DefineSavepoint(name);
446 case TRANS_STMT_RELEASE:
447 RequireTransactionChain(isTopLevel, "RELEASE SAVEPOINT");
448 ReleaseSavepoint(stmt->options);
451 case TRANS_STMT_ROLLBACK_TO:
452 RequireTransactionChain(isTopLevel, "ROLLBACK TO SAVEPOINT");
453 RollbackToSavepoint(stmt->options);
456 * CommitTransactionCommand is in charge of
457 * re-defining the savepoint again
465 * Portal (cursor) manipulation
467 * Note: DECLARE CURSOR is processed mostly as a SELECT, and
468 * therefore what we will get here is a PlannedStmt not a bare
473 PlannedStmt *stmt = (PlannedStmt *) parsetree;
475 if (stmt->utilityStmt == NULL ||
476 !IsA(stmt->utilityStmt, DeclareCursorStmt))
477 elog(ERROR, "non-DECLARE CURSOR PlannedStmt passed to ProcessUtility");
478 PerformCursorOpen(stmt, params, queryString, isTopLevel);
482 case T_ClosePortalStmt:
484 ClosePortalStmt *stmt = (ClosePortalStmt *) parsetree;
486 CheckRestrictedOperation("CLOSE");
487 PerformPortalClose(stmt->portalname);
492 PerformPortalFetch((FetchStmt *) parsetree, dest,
497 * relation and attribute manipulation
499 case T_CreateSchemaStmt:
500 CreateSchemaCommand((CreateSchemaStmt *) parsetree,
505 case T_CreateForeignTableStmt:
511 /* Run parse analysis ... */
512 stmts = transformCreateStmt((CreateStmt *) parsetree,
518 Node *stmt = (Node *) lfirst(l);
520 if (IsA(stmt, CreateStmt))
523 static char *validnsps[] = HEAP_RELOPT_NAMESPACES;
525 /* Create the table itself */
526 relOid = DefineRelation((CreateStmt *) stmt,
531 * If "IF NOT EXISTS" was specified and the relation
532 * already exists, do nothing further.
534 if (relOid == InvalidOid)
538 * Let AlterTableCreateToastTable decide if this one
539 * needs a secondary relation too.
541 CommandCounterIncrement();
543 /* parse and validate reloptions for the toast table */
544 toast_options = transformRelOptions((Datum) 0,
545 ((CreateStmt *) stmt)->options,
549 (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options,
552 AlterTableCreateToastTable(relOid, toast_options);
554 else if (IsA(stmt, CreateForeignTableStmt))
556 /* Create the table itself */
557 relOid = DefineRelation((CreateStmt *) stmt,
558 RELKIND_FOREIGN_TABLE,
562 * Unless "IF NOT EXISTS" was specified and the
563 * relation already exists, create the pg_foreign_table
566 if (relOid != InvalidOid)
567 CreateForeignTable((CreateForeignTableStmt *) stmt,
572 /* Recurse for anything else */
581 /* Need CCI between commands */
582 if (lnext(l) != NULL)
583 CommandCounterIncrement();
588 case T_CreateTableSpaceStmt:
589 PreventTransactionChain(isTopLevel, "CREATE TABLESPACE");
590 CreateTableSpace((CreateTableSpaceStmt *) parsetree);
593 case T_DropTableSpaceStmt:
594 PreventTransactionChain(isTopLevel, "DROP TABLESPACE");
595 DropTableSpace((DropTableSpaceStmt *) parsetree);
598 case T_AlterTableSpaceOptionsStmt:
599 AlterTableSpaceOptions((AlterTableSpaceOptionsStmt *) parsetree);
602 case T_CreateExtensionStmt:
603 CreateExtension((CreateExtensionStmt *) parsetree);
606 case T_AlterExtensionStmt:
607 ExecAlterExtensionStmt((AlterExtensionStmt *) parsetree);
610 case T_AlterExtensionContentsStmt:
611 ExecAlterExtensionContentsStmt((AlterExtensionContentsStmt *) parsetree);
614 case T_CreateFdwStmt:
615 CreateForeignDataWrapper((CreateFdwStmt *) parsetree);
619 AlterForeignDataWrapper((AlterFdwStmt *) parsetree);
623 RemoveForeignDataWrapper((DropFdwStmt *) parsetree);
626 case T_CreateForeignServerStmt:
627 CreateForeignServer((CreateForeignServerStmt *) parsetree);
630 case T_AlterForeignServerStmt:
631 AlterForeignServer((AlterForeignServerStmt *) parsetree);
634 case T_DropForeignServerStmt:
635 RemoveForeignServer((DropForeignServerStmt *) parsetree);
638 case T_CreateUserMappingStmt:
639 CreateUserMapping((CreateUserMappingStmt *) parsetree);
642 case T_AlterUserMappingStmt:
643 AlterUserMapping((AlterUserMappingStmt *) parsetree);
646 case T_DropUserMappingStmt:
647 RemoveUserMapping((DropUserMappingStmt *) parsetree);
652 DropStmt *stmt = (DropStmt *) parsetree;
654 switch (stmt->removeType)
657 case OBJECT_SEQUENCE:
660 case OBJECT_FOREIGN_TABLE:
661 RemoveRelations(stmt);
669 case OBJECT_COLLATION:
670 DropCollationsCommand(stmt);
673 case OBJECT_CONVERSION:
674 DropConversionsCommand(stmt);
681 case OBJECT_TSPARSER:
682 RemoveTSParsers(stmt);
685 case OBJECT_TSDICTIONARY:
686 RemoveTSDictionaries(stmt);
689 case OBJECT_TSTEMPLATE:
690 RemoveTSTemplates(stmt);
693 case OBJECT_TSCONFIGURATION:
694 RemoveTSConfigurations(stmt);
697 case OBJECT_EXTENSION:
698 RemoveExtensions(stmt);
702 elog(ERROR, "unrecognized drop object type: %d",
703 (int) stmt->removeType);
710 ExecuteTruncate((TruncateStmt *) parsetree);
714 CommentObject((CommentStmt *) parsetree);
718 ExecSecLabelStmt((SecLabelStmt *) parsetree);
725 processed = DoCopy((CopyStmt *) parsetree, queryString);
727 snprintf(completionTag, COMPLETION_TAG_BUFSIZE,
728 "COPY " UINT64_FORMAT, processed);
733 CheckRestrictedOperation("PREPARE");
734 PrepareQuery((PrepareStmt *) parsetree, queryString);
738 ExecuteQuery((ExecuteStmt *) parsetree, queryString, params,
739 dest, completionTag);
742 case T_DeallocateStmt:
743 CheckRestrictedOperation("DEALLOCATE");
744 DeallocateQuery((DeallocateStmt *) parsetree);
751 ExecRenameStmt((RenameStmt *) parsetree);
754 case T_AlterObjectSchemaStmt:
755 ExecAlterObjectSchemaStmt((AlterObjectSchemaStmt *) parsetree);
758 case T_AlterOwnerStmt:
759 ExecAlterOwnerStmt((AlterOwnerStmt *) parsetree);
762 case T_AlterTableStmt:
767 /* Run parse analysis ... */
768 stmts = transformAlterTableStmt((AlterTableStmt *) parsetree,
774 Node *stmt = (Node *) lfirst(l);
776 if (IsA(stmt, AlterTableStmt))
778 /* Do the table alteration proper */
779 AlterTable((AlterTableStmt *) stmt);
783 /* Recurse for anything else */
792 /* Need CCI between commands */
793 if (lnext(l) != NULL)
794 CommandCounterIncrement();
799 case T_AlterDomainStmt:
801 AlterDomainStmt *stmt = (AlterDomainStmt *) parsetree;
804 * Some or all of these functions are recursive to cover
805 * inherited things, so permission checks are done there.
807 switch (stmt->subtype)
809 case 'T': /* ALTER DOMAIN DEFAULT */
812 * Recursively alter column default for table and, if
813 * requested, for descendants
815 AlterDomainDefault(stmt->typeName,
818 case 'N': /* ALTER DOMAIN DROP NOT NULL */
819 AlterDomainNotNull(stmt->typeName,
822 case 'O': /* ALTER DOMAIN SET NOT NULL */
823 AlterDomainNotNull(stmt->typeName,
826 case 'C': /* ADD CONSTRAINT */
827 AlterDomainAddConstraint(stmt->typeName,
830 case 'X': /* DROP CONSTRAINT */
831 AlterDomainDropConstraint(stmt->typeName,
836 elog(ERROR, "unrecognized alter domain type: %d",
837 (int) stmt->subtype);
844 ExecuteGrantStmt((GrantStmt *) parsetree);
847 case T_GrantRoleStmt:
848 GrantRole((GrantRoleStmt *) parsetree);
851 case T_AlterDefaultPrivilegesStmt:
852 ExecAlterDefaultPrivilegesStmt((AlterDefaultPrivilegesStmt *) parsetree);
856 * **************** object creation / destruction *****************
860 DefineStmt *stmt = (DefineStmt *) parsetree;
864 case OBJECT_AGGREGATE:
865 DefineAggregate(stmt->defnames, stmt->args,
866 stmt->oldstyle, stmt->definition);
868 case OBJECT_OPERATOR:
869 Assert(stmt->args == NIL);
870 DefineOperator(stmt->defnames, stmt->definition);
873 Assert(stmt->args == NIL);
874 DefineType(stmt->defnames, stmt->definition);
876 case OBJECT_TSPARSER:
877 Assert(stmt->args == NIL);
878 DefineTSParser(stmt->defnames, stmt->definition);
880 case OBJECT_TSDICTIONARY:
881 Assert(stmt->args == NIL);
882 DefineTSDictionary(stmt->defnames, stmt->definition);
884 case OBJECT_TSTEMPLATE:
885 Assert(stmt->args == NIL);
886 DefineTSTemplate(stmt->defnames, stmt->definition);
888 case OBJECT_TSCONFIGURATION:
889 Assert(stmt->args == NIL);
890 DefineTSConfiguration(stmt->defnames, stmt->definition);
892 case OBJECT_COLLATION:
893 Assert(stmt->args == NIL);
894 DefineCollation(stmt->defnames, stmt->definition);
897 elog(ERROR, "unrecognized define stmt type: %d",
904 case T_CompositeTypeStmt: /* CREATE TYPE (composite) */
906 CompositeTypeStmt *stmt = (CompositeTypeStmt *) parsetree;
908 DefineCompositeType(stmt->typevar, stmt->coldeflist);
912 case T_CreateEnumStmt: /* CREATE TYPE (enum) */
913 DefineEnum((CreateEnumStmt *) parsetree);
916 case T_AlterEnumStmt: /* ALTER TYPE (enum) */
918 * We disallow this in transaction blocks, because we can't cope
919 * with enum OID values getting into indexes and then having their
920 * defining pg_enum entries go away.
922 PreventTransactionChain(isTopLevel, "ALTER TYPE ... ADD");
923 AlterEnum((AlterEnumStmt *) parsetree);
926 case T_ViewStmt: /* CREATE VIEW */
927 DefineView((ViewStmt *) parsetree, queryString);
930 case T_CreateFunctionStmt: /* CREATE FUNCTION */
931 CreateFunction((CreateFunctionStmt *) parsetree, queryString);
934 case T_AlterFunctionStmt: /* ALTER FUNCTION */
935 AlterFunction((AlterFunctionStmt *) parsetree);
938 case T_IndexStmt: /* CREATE INDEX */
940 IndexStmt *stmt = (IndexStmt *) parsetree;
942 if (stmt->concurrent)
943 PreventTransactionChain(isTopLevel,
944 "CREATE INDEX CONCURRENTLY");
946 CheckRelationOwnership(stmt->relation, true);
948 /* Run parse analysis ... */
949 stmt = transformIndexStmt(stmt, queryString);
952 DefineIndex(stmt->relation, /* relation */
953 stmt->idxname, /* index name */
954 InvalidOid, /* no predefined OID */
955 stmt->accessMethod, /* am name */
957 stmt->indexParams, /* parameters */
958 (Expr *) stmt->whereClause,
960 stmt->excludeOpNames,
966 false, /* is_alter_table */
967 true, /* check_rights */
968 false, /* skip_build */
970 stmt->concurrent); /* concurrent */
974 case T_RuleStmt: /* CREATE RULE */
975 DefineRule((RuleStmt *) parsetree, queryString);
978 case T_CreateSeqStmt:
979 DefineSequence((CreateSeqStmt *) parsetree);
983 AlterSequence((AlterSeqStmt *) parsetree);
986 case T_RemoveFuncStmt:
988 RemoveFuncStmt *stmt = (RemoveFuncStmt *) parsetree;
992 case OBJECT_FUNCTION:
993 RemoveFunction(stmt);
995 case OBJECT_AGGREGATE:
996 RemoveAggregate(stmt);
998 case OBJECT_OPERATOR:
999 RemoveOperator(stmt);
1002 elog(ERROR, "unrecognized object type: %d",
1010 ExecuteDoStmt((DoStmt *) parsetree);
1013 case T_CreatedbStmt:
1014 PreventTransactionChain(isTopLevel, "CREATE DATABASE");
1015 createdb((CreatedbStmt *) parsetree);
1018 case T_AlterDatabaseStmt:
1019 AlterDatabase((AlterDatabaseStmt *) parsetree, isTopLevel);
1022 case T_AlterDatabaseSetStmt:
1023 AlterDatabaseSet((AlterDatabaseSetStmt *) parsetree);
1028 DropdbStmt *stmt = (DropdbStmt *) parsetree;
1030 PreventTransactionChain(isTopLevel, "DROP DATABASE");
1031 dropdb(stmt->dbname, stmt->missing_ok);
1035 /* Query-level asynchronous notification */
1038 NotifyStmt *stmt = (NotifyStmt *) parsetree;
1040 PreventCommandDuringRecovery("NOTIFY");
1041 Async_Notify(stmt->conditionname, stmt->payload);
1047 ListenStmt *stmt = (ListenStmt *) parsetree;
1049 PreventCommandDuringRecovery("LISTEN");
1050 CheckRestrictedOperation("LISTEN");
1051 Async_Listen(stmt->conditionname);
1055 case T_UnlistenStmt:
1057 UnlistenStmt *stmt = (UnlistenStmt *) parsetree;
1059 PreventCommandDuringRecovery("UNLISTEN");
1060 CheckRestrictedOperation("UNLISTEN");
1061 if (stmt->conditionname)
1062 Async_Unlisten(stmt->conditionname);
1064 Async_UnlistenAll();
1070 LoadStmt *stmt = (LoadStmt *) parsetree;
1072 closeAllVfds(); /* probably not necessary... */
1073 /* Allowed names are restricted if you're not superuser */
1074 load_file(stmt->filename, !superuser());
1079 /* we choose to allow this during "read only" transactions */
1080 PreventCommandDuringRecovery("CLUSTER");
1081 cluster((ClusterStmt *) parsetree, isTopLevel);
1085 /* we choose to allow this during "read only" transactions */
1086 PreventCommandDuringRecovery("VACUUM");
1087 vacuum((VacuumStmt *) parsetree, InvalidOid, true, NULL, false,
1092 ExplainQuery((ExplainStmt *) parsetree, queryString, params, dest);
1095 case T_VariableSetStmt:
1096 ExecSetVariableStmt((VariableSetStmt *) parsetree);
1099 case T_VariableShowStmt:
1101 VariableShowStmt *n = (VariableShowStmt *) parsetree;
1103 GetPGVariable(n->name, dest);
1108 /* should we allow DISCARD PLANS? */
1109 CheckRestrictedOperation("DISCARD");
1110 DiscardCommand((DiscardStmt *) parsetree, isTopLevel);
1113 case T_CreateTrigStmt:
1114 (void) CreateTrigger((CreateTrigStmt *) parsetree, queryString,
1115 InvalidOid, InvalidOid, false);
1118 case T_DropPropertyStmt:
1120 DropPropertyStmt *stmt = (DropPropertyStmt *) parsetree;
1123 relId = RangeVarGetRelid(stmt->relation, false);
1125 switch (stmt->removeType)
1128 /* RemoveRewriteRule checks permissions */
1129 RemoveRewriteRule(relId, stmt->property,
1130 stmt->behavior, stmt->missing_ok);
1132 case OBJECT_TRIGGER:
1133 /* DropTrigger checks permissions */
1134 DropTrigger(relId, stmt->property,
1135 stmt->behavior, stmt->missing_ok);
1138 elog(ERROR, "unrecognized object type: %d",
1139 (int) stmt->removeType);
1145 case T_CreatePLangStmt:
1146 CreateProceduralLanguage((CreatePLangStmt *) parsetree);
1149 case T_DropPLangStmt:
1150 DropProceduralLanguage((DropPLangStmt *) parsetree);
1154 * ******************************** DOMAIN statements ****
1156 case T_CreateDomainStmt:
1157 DefineDomain((CreateDomainStmt *) parsetree);
1161 * ******************************** ROLE statements ****
1163 case T_CreateRoleStmt:
1164 CreateRole((CreateRoleStmt *) parsetree);
1167 case T_AlterRoleStmt:
1168 AlterRole((AlterRoleStmt *) parsetree);
1171 case T_AlterRoleSetStmt:
1172 AlterRoleSet((AlterRoleSetStmt *) parsetree);
1175 case T_DropRoleStmt:
1176 DropRole((DropRoleStmt *) parsetree);
1179 case T_DropOwnedStmt:
1180 DropOwnedObjects((DropOwnedStmt *) parsetree);
1183 case T_ReassignOwnedStmt:
1184 ReassignOwnedObjects((ReassignOwnedStmt *) parsetree);
1190 * Since the lock would just get dropped immediately, LOCK TABLE
1191 * outside a transaction block is presumed to be user error.
1193 RequireTransactionChain(isTopLevel, "LOCK TABLE");
1194 LockTableCommand((LockStmt *) parsetree);
1197 case T_ConstraintsSetStmt:
1198 AfterTriggerSetState((ConstraintsSetStmt *) parsetree);
1201 case T_CheckPointStmt:
1204 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1205 errmsg("must be superuser to do CHECKPOINT")));
1208 * You might think we should have a PreventCommandDuringRecovery()
1209 * here, but we interpret a CHECKPOINT command during recovery as
1210 * a request for a restartpoint instead. We allow this since it
1211 * can be a useful way of reducing switchover time when using
1212 * various forms of replication.
1214 RequestCheckpoint(CHECKPOINT_IMMEDIATE | CHECKPOINT_WAIT |
1215 (RecoveryInProgress() ? 0 : CHECKPOINT_FORCE));
1220 ReindexStmt *stmt = (ReindexStmt *) parsetree;
1222 /* we choose to allow this during "read only" transactions */
1223 PreventCommandDuringRecovery("REINDEX");
1227 ReindexIndex(stmt->relation);
1230 ReindexTable(stmt->relation);
1232 case OBJECT_DATABASE:
1235 * This cannot run inside a user transaction block; if
1236 * we were inside a transaction, then its commit- and
1237 * start-transaction-command calls would not have the
1240 PreventTransactionChain(isTopLevel,
1241 "REINDEX DATABASE");
1242 ReindexDatabase(stmt->name,
1243 stmt->do_system, stmt->do_user);
1246 elog(ERROR, "unrecognized object type: %d",
1254 case T_CreateConversionStmt:
1255 CreateConversionCommand((CreateConversionStmt *) parsetree);
1258 case T_CreateCastStmt:
1259 CreateCast((CreateCastStmt *) parsetree);
1262 case T_DropCastStmt:
1263 DropCast((DropCastStmt *) parsetree);
1266 case T_CreateOpClassStmt:
1267 DefineOpClass((CreateOpClassStmt *) parsetree);
1270 case T_CreateOpFamilyStmt:
1271 DefineOpFamily((CreateOpFamilyStmt *) parsetree);
1274 case T_AlterOpFamilyStmt:
1275 AlterOpFamily((AlterOpFamilyStmt *) parsetree);
1278 case T_RemoveOpClassStmt:
1279 RemoveOpClass((RemoveOpClassStmt *) parsetree);
1282 case T_RemoveOpFamilyStmt:
1283 RemoveOpFamily((RemoveOpFamilyStmt *) parsetree);
1286 case T_AlterTSDictionaryStmt:
1287 AlterTSDictionary((AlterTSDictionaryStmt *) parsetree);
1290 case T_AlterTSConfigurationStmt:
1291 AlterTSConfiguration((AlterTSConfigurationStmt *) parsetree);
1295 elog(ERROR, "unrecognized node type: %d",
1296 (int) nodeTag(parsetree));
1302 * UtilityReturnsTuples
1303 * Return "true" if this utility statement will send output to the
1306 * Generally, there should be a case here for each case in ProcessUtility
1307 * where "dest" is passed on.
1310 UtilityReturnsTuples(Node *parsetree)
1312 switch (nodeTag(parsetree))
1316 FetchStmt *stmt = (FetchStmt *) parsetree;
1321 portal = GetPortalByName(stmt->portalname);
1322 if (!PortalIsValid(portal))
1323 return false; /* not our business to raise error */
1324 return portal->tupDesc ? true : false;
1329 ExecuteStmt *stmt = (ExecuteStmt *) parsetree;
1330 PreparedStatement *entry;
1334 entry = FetchPreparedStatement(stmt->name, false);
1336 return false; /* not our business to raise error */
1337 if (entry->plansource->resultDesc)
1345 case T_VariableShowStmt:
1354 * UtilityTupleDescriptor
1355 * Fetch the actual output tuple descriptor for a utility statement
1356 * for which UtilityReturnsTuples() previously returned "true".
1358 * The returned descriptor is created in (or copied into) the current memory
1362 UtilityTupleDescriptor(Node *parsetree)
1364 switch (nodeTag(parsetree))
1368 FetchStmt *stmt = (FetchStmt *) parsetree;
1373 portal = GetPortalByName(stmt->portalname);
1374 if (!PortalIsValid(portal))
1375 return NULL; /* not our business to raise error */
1376 return CreateTupleDescCopy(portal->tupDesc);
1381 ExecuteStmt *stmt = (ExecuteStmt *) parsetree;
1382 PreparedStatement *entry;
1386 entry = FetchPreparedStatement(stmt->name, false);
1388 return NULL; /* not our business to raise error */
1389 return FetchPreparedStatementResultDesc(entry);
1393 return ExplainResultDesc((ExplainStmt *) parsetree);
1395 case T_VariableShowStmt:
1397 VariableShowStmt *n = (VariableShowStmt *) parsetree;
1399 return GetPGVariableResultDesc(n->name);
1409 * QueryReturnsTuples
1410 * Return "true" if this Query will send output to the destination.
1414 QueryReturnsTuples(Query *parsetree)
1416 switch (parsetree->commandType)
1419 /* returns tuples ... unless it's DECLARE CURSOR or SELECT INTO */
1420 if (parsetree->utilityStmt == NULL &&
1421 parsetree->intoClause == NULL)
1427 /* the forms with RETURNING return tuples */
1428 if (parsetree->returningList)
1432 return UtilityReturnsTuples(parsetree->utilityStmt);
1435 /* probably shouldn't get here */
1438 return false; /* default */
1444 * AlterObjectTypeCommandTag
1445 * helper function for CreateCommandTag
1447 * This covers most cases where ALTER is used with an ObjectType enum.
1450 AlterObjectTypeCommandTag(ObjectType objtype)
1456 case OBJECT_AGGREGATE:
1457 tag = "ALTER AGGREGATE";
1459 case OBJECT_ATTRIBUTE:
1465 case OBJECT_COLLATION:
1466 tag = "ALTER COLLATION";
1469 tag = "ALTER TABLE";
1471 case OBJECT_CONSTRAINT:
1472 tag = "ALTER TABLE";
1474 case OBJECT_CONVERSION:
1475 tag = "ALTER CONVERSION";
1477 case OBJECT_DATABASE:
1478 tag = "ALTER DATABASE";
1481 tag = "ALTER DOMAIN";
1483 case OBJECT_EXTENSION:
1484 tag = "ALTER EXTENSION";
1487 tag = "ALTER FOREIGN DATA WRAPPER";
1489 case OBJECT_FOREIGN_SERVER:
1490 tag = "ALTER SERVER";
1492 case OBJECT_FOREIGN_TABLE:
1493 tag = "ALTER FOREIGN TABLE";
1495 case OBJECT_FUNCTION:
1496 tag = "ALTER FUNCTION";
1499 tag = "ALTER INDEX";
1501 case OBJECT_LANGUAGE:
1502 tag = "ALTER LANGUAGE";
1504 case OBJECT_LARGEOBJECT:
1505 tag = "ALTER LARGE OBJECT";
1507 case OBJECT_OPCLASS:
1508 tag = "ALTER OPERATOR CLASS";
1510 case OBJECT_OPERATOR:
1511 tag = "ALTER OPERATOR";
1513 case OBJECT_OPFAMILY:
1514 tag = "ALTER OPERATOR FAMILY";
1523 tag = "ALTER SCHEMA";
1525 case OBJECT_SEQUENCE:
1526 tag = "ALTER SEQUENCE";
1529 tag = "ALTER TABLE";
1531 case OBJECT_TABLESPACE:
1532 tag = "ALTER TABLESPACE";
1534 case OBJECT_TRIGGER:
1535 tag = "ALTER TRIGGER";
1537 case OBJECT_TSCONFIGURATION:
1538 tag = "ALTER TEXT SEARCH CONFIGURATION";
1540 case OBJECT_TSDICTIONARY:
1541 tag = "ALTER TEXT SEARCH DICTIONARY";
1543 case OBJECT_TSPARSER:
1544 tag = "ALTER TEXT SEARCH PARSER";
1546 case OBJECT_TSTEMPLATE:
1547 tag = "ALTER TEXT SEARCH TEMPLATE";
1565 * utility to get a string representation of the command operation,
1566 * given either a raw (un-analyzed) parsetree or a planned query.
1568 * This must handle all command types, but since the vast majority
1569 * of 'em are utility commands, it seems sensible to keep it here.
1571 * NB: all result strings must be shorter than COMPLETION_TAG_BUFSIZE.
1572 * Also, the result must point at a true constant (permanent storage).
1575 CreateCommandTag(Node *parsetree)
1579 switch (nodeTag(parsetree))
1581 /* raw plannable queries */
1598 /* utility statements --- same whether raw or cooked */
1599 case T_TransactionStmt:
1601 TransactionStmt *stmt = (TransactionStmt *) parsetree;
1605 case TRANS_STMT_BEGIN:
1609 case TRANS_STMT_START:
1610 tag = "START TRANSACTION";
1613 case TRANS_STMT_COMMIT:
1617 case TRANS_STMT_ROLLBACK:
1618 case TRANS_STMT_ROLLBACK_TO:
1622 case TRANS_STMT_SAVEPOINT:
1626 case TRANS_STMT_RELEASE:
1630 case TRANS_STMT_PREPARE:
1631 tag = "PREPARE TRANSACTION";
1634 case TRANS_STMT_COMMIT_PREPARED:
1635 tag = "COMMIT PREPARED";
1638 case TRANS_STMT_ROLLBACK_PREPARED:
1639 tag = "ROLLBACK PREPARED";
1649 case T_DeclareCursorStmt:
1650 tag = "DECLARE CURSOR";
1653 case T_ClosePortalStmt:
1655 ClosePortalStmt *stmt = (ClosePortalStmt *) parsetree;
1657 if (stmt->portalname == NULL)
1658 tag = "CLOSE CURSOR ALL";
1660 tag = "CLOSE CURSOR";
1666 FetchStmt *stmt = (FetchStmt *) parsetree;
1668 tag = (stmt->ismove) ? "MOVE" : "FETCH";
1672 case T_CreateDomainStmt:
1673 tag = "CREATE DOMAIN";
1676 case T_CreateSchemaStmt:
1677 tag = "CREATE SCHEMA";
1681 tag = "CREATE TABLE";
1684 case T_CreateTableSpaceStmt:
1685 tag = "CREATE TABLESPACE";
1688 case T_DropTableSpaceStmt:
1689 tag = "DROP TABLESPACE";
1692 case T_AlterTableSpaceOptionsStmt:
1693 tag = "ALTER TABLESPACE";
1696 case T_CreateExtensionStmt:
1697 tag = "CREATE EXTENSION";
1700 case T_AlterExtensionStmt:
1701 tag = "ALTER EXTENSION";
1704 case T_AlterExtensionContentsStmt:
1705 tag = "ALTER EXTENSION";
1708 case T_CreateFdwStmt:
1709 tag = "CREATE FOREIGN DATA WRAPPER";
1712 case T_AlterFdwStmt:
1713 tag = "ALTER FOREIGN DATA WRAPPER";
1717 tag = "DROP FOREIGN DATA WRAPPER";
1720 case T_CreateForeignServerStmt:
1721 tag = "CREATE SERVER";
1724 case T_AlterForeignServerStmt:
1725 tag = "ALTER SERVER";
1728 case T_DropForeignServerStmt:
1729 tag = "DROP SERVER";
1732 case T_CreateUserMappingStmt:
1733 tag = "CREATE USER MAPPING";
1736 case T_AlterUserMappingStmt:
1737 tag = "ALTER USER MAPPING";
1740 case T_DropUserMappingStmt:
1741 tag = "DROP USER MAPPING";
1744 case T_CreateForeignTableStmt:
1745 tag = "CREATE FOREIGN TABLE";
1749 switch (((DropStmt *) parsetree)->removeType)
1754 case OBJECT_SEQUENCE:
1755 tag = "DROP SEQUENCE";
1767 tag = "DROP DOMAIN";
1769 case OBJECT_COLLATION:
1770 tag = "DROP COLLATION";
1772 case OBJECT_CONVERSION:
1773 tag = "DROP CONVERSION";
1776 tag = "DROP SCHEMA";
1778 case OBJECT_TSPARSER:
1779 tag = "DROP TEXT SEARCH PARSER";
1781 case OBJECT_TSDICTIONARY:
1782 tag = "DROP TEXT SEARCH DICTIONARY";
1784 case OBJECT_TSTEMPLATE:
1785 tag = "DROP TEXT SEARCH TEMPLATE";
1787 case OBJECT_TSCONFIGURATION:
1788 tag = "DROP TEXT SEARCH CONFIGURATION";
1790 case OBJECT_FOREIGN_TABLE:
1791 tag = "DROP FOREIGN TABLE";
1793 case OBJECT_EXTENSION:
1794 tag = "DROP EXTENSION";
1801 case T_TruncateStmt:
1802 tag = "TRUNCATE TABLE";
1809 case T_SecLabelStmt:
1810 tag = "SECURITY LABEL";
1818 tag = AlterObjectTypeCommandTag(((RenameStmt *) parsetree)->renameType);
1821 case T_AlterObjectSchemaStmt:
1822 tag = AlterObjectTypeCommandTag(((AlterObjectSchemaStmt *) parsetree)->objectType);
1825 case T_AlterOwnerStmt:
1826 tag = AlterObjectTypeCommandTag(((AlterOwnerStmt *) parsetree)->objectType);
1829 case T_AlterTableStmt:
1830 tag = AlterObjectTypeCommandTag(((AlterTableStmt *) parsetree)->relkind);
1833 case T_AlterDomainStmt:
1834 tag = "ALTER DOMAIN";
1837 case T_AlterFunctionStmt:
1838 tag = "ALTER FUNCTION";
1843 GrantStmt *stmt = (GrantStmt *) parsetree;
1845 tag = (stmt->is_grant) ? "GRANT" : "REVOKE";
1849 case T_GrantRoleStmt:
1851 GrantRoleStmt *stmt = (GrantRoleStmt *) parsetree;
1853 tag = (stmt->is_grant) ? "GRANT ROLE" : "REVOKE ROLE";
1857 case T_AlterDefaultPrivilegesStmt:
1858 tag = "ALTER DEFAULT PRIVILEGES";
1862 switch (((DefineStmt *) parsetree)->kind)
1864 case OBJECT_AGGREGATE:
1865 tag = "CREATE AGGREGATE";
1867 case OBJECT_OPERATOR:
1868 tag = "CREATE OPERATOR";
1871 tag = "CREATE TYPE";
1873 case OBJECT_TSPARSER:
1874 tag = "CREATE TEXT SEARCH PARSER";
1876 case OBJECT_TSDICTIONARY:
1877 tag = "CREATE TEXT SEARCH DICTIONARY";
1879 case OBJECT_TSTEMPLATE:
1880 tag = "CREATE TEXT SEARCH TEMPLATE";
1882 case OBJECT_TSCONFIGURATION:
1883 tag = "CREATE TEXT SEARCH CONFIGURATION";
1885 case OBJECT_COLLATION:
1886 tag = "CREATE COLLATION";
1893 case T_CompositeTypeStmt:
1894 tag = "CREATE TYPE";
1897 case T_CreateEnumStmt:
1898 tag = "CREATE TYPE";
1901 case T_AlterEnumStmt:
1906 tag = "CREATE VIEW";
1909 case T_CreateFunctionStmt:
1910 tag = "CREATE FUNCTION";
1914 tag = "CREATE INDEX";
1918 tag = "CREATE RULE";
1921 case T_CreateSeqStmt:
1922 tag = "CREATE SEQUENCE";
1925 case T_AlterSeqStmt:
1926 tag = "ALTER SEQUENCE";
1929 case T_RemoveFuncStmt:
1930 switch (((RemoveFuncStmt *) parsetree)->kind)
1932 case OBJECT_FUNCTION:
1933 tag = "DROP FUNCTION";
1935 case OBJECT_AGGREGATE:
1936 tag = "DROP AGGREGATE";
1938 case OBJECT_OPERATOR:
1939 tag = "DROP OPERATOR";
1950 case T_CreatedbStmt:
1951 tag = "CREATE DATABASE";
1954 case T_AlterDatabaseStmt:
1955 tag = "ALTER DATABASE";
1958 case T_AlterDatabaseSetStmt:
1959 tag = "ALTER DATABASE";
1963 tag = "DROP DATABASE";
1974 case T_UnlistenStmt:
1987 if (((VacuumStmt *) parsetree)->options & VACOPT_VACUUM)
1997 case T_VariableSetStmt:
1998 switch (((VariableSetStmt *) parsetree)->kind)
2001 case VAR_SET_CURRENT:
2002 case VAR_SET_DEFAULT:
2015 case T_VariableShowStmt:
2020 switch (((DiscardStmt *) parsetree)->target)
2023 tag = "DISCARD ALL";
2026 tag = "DISCARD PLANS";
2029 tag = "DISCARD TEMP";
2036 case T_CreateTrigStmt:
2037 tag = "CREATE TRIGGER";
2040 case T_DropPropertyStmt:
2041 switch (((DropPropertyStmt *) parsetree)->removeType)
2043 case OBJECT_TRIGGER:
2044 tag = "DROP TRIGGER";
2054 case T_CreatePLangStmt:
2055 tag = "CREATE LANGUAGE";
2058 case T_DropPLangStmt:
2059 tag = "DROP LANGUAGE";
2062 case T_CreateRoleStmt:
2063 tag = "CREATE ROLE";
2066 case T_AlterRoleStmt:
2070 case T_AlterRoleSetStmt:
2074 case T_DropRoleStmt:
2078 case T_DropOwnedStmt:
2082 case T_ReassignOwnedStmt:
2083 tag = "REASSIGN OWNED";
2090 case T_ConstraintsSetStmt:
2091 tag = "SET CONSTRAINTS";
2094 case T_CheckPointStmt:
2102 case T_CreateConversionStmt:
2103 tag = "CREATE CONVERSION";
2106 case T_CreateCastStmt:
2107 tag = "CREATE CAST";
2110 case T_DropCastStmt:
2114 case T_CreateOpClassStmt:
2115 tag = "CREATE OPERATOR CLASS";
2118 case T_CreateOpFamilyStmt:
2119 tag = "CREATE OPERATOR FAMILY";
2122 case T_AlterOpFamilyStmt:
2123 tag = "ALTER OPERATOR FAMILY";
2126 case T_RemoveOpClassStmt:
2127 tag = "DROP OPERATOR CLASS";
2130 case T_RemoveOpFamilyStmt:
2131 tag = "DROP OPERATOR FAMILY";
2134 case T_AlterTSDictionaryStmt:
2135 tag = "ALTER TEXT SEARCH DICTIONARY";
2138 case T_AlterTSConfigurationStmt:
2139 tag = "ALTER TEXT SEARCH CONFIGURATION";
2150 case T_DeallocateStmt:
2152 DeallocateStmt *stmt = (DeallocateStmt *) parsetree;
2154 if (stmt->name == NULL)
2155 tag = "DEALLOCATE ALL";
2161 /* already-planned queries */
2164 PlannedStmt *stmt = (PlannedStmt *) parsetree;
2166 switch (stmt->commandType)
2171 * We take a little extra care here so that the result
2172 * will be useful for complaints about read-only
2175 if (stmt->utilityStmt != NULL)
2177 Assert(IsA(stmt->utilityStmt, DeclareCursorStmt));
2178 tag = "DECLARE CURSOR";
2180 else if (stmt->intoClause != NULL)
2181 tag = "SELECT INTO";
2182 else if (stmt->rowMarks != NIL)
2184 /* not 100% but probably close enough */
2185 if (((PlanRowMark *) linitial(stmt->rowMarks))->markType == ROW_MARK_EXCLUSIVE)
2186 tag = "SELECT FOR UPDATE";
2188 tag = "SELECT FOR SHARE";
2203 elog(WARNING, "unrecognized commandType: %d",
2204 (int) stmt->commandType);
2211 /* parsed-and-rewritten-but-not-planned queries */
2214 Query *stmt = (Query *) parsetree;
2216 switch (stmt->commandType)
2221 * We take a little extra care here so that the result
2222 * will be useful for complaints about read-only
2225 if (stmt->utilityStmt != NULL)
2227 Assert(IsA(stmt->utilityStmt, DeclareCursorStmt));
2228 tag = "DECLARE CURSOR";
2230 else if (stmt->intoClause != NULL)
2231 tag = "SELECT INTO";
2232 else if (stmt->rowMarks != NIL)
2234 /* not 100% but probably close enough */
2235 if (((RowMarkClause *) linitial(stmt->rowMarks))->forUpdate)
2236 tag = "SELECT FOR UPDATE";
2238 tag = "SELECT FOR SHARE";
2253 tag = CreateCommandTag(stmt->utilityStmt);
2256 elog(WARNING, "unrecognized commandType: %d",
2257 (int) stmt->commandType);
2265 elog(WARNING, "unrecognized node type: %d",
2266 (int) nodeTag(parsetree));
2276 * GetCommandLogLevel
2277 * utility to get the minimum log_statement level for a command,
2278 * given either a raw (un-analyzed) parsetree or a planned query.
2280 * This must handle all command types, but since the vast majority
2281 * of 'em are utility commands, it seems sensible to keep it here.
2284 GetCommandLogLevel(Node *parsetree)
2288 switch (nodeTag(parsetree))
2290 /* raw plannable queries */
2298 if (((SelectStmt *) parsetree)->intoClause)
2299 lev = LOGSTMT_DDL; /* CREATE AS, SELECT INTO */
2304 /* utility statements --- same whether raw or cooked */
2305 case T_TransactionStmt:
2309 case T_DeclareCursorStmt:
2313 case T_ClosePortalStmt:
2321 case T_CreateSchemaStmt:
2326 case T_CreateForeignTableStmt:
2330 case T_CreateTableSpaceStmt:
2331 case T_DropTableSpaceStmt:
2332 case T_AlterTableSpaceOptionsStmt:
2336 case T_CreateExtensionStmt:
2337 case T_AlterExtensionStmt:
2338 case T_AlterExtensionContentsStmt:
2342 case T_CreateFdwStmt:
2343 case T_AlterFdwStmt:
2345 case T_CreateForeignServerStmt:
2346 case T_AlterForeignServerStmt:
2347 case T_DropForeignServerStmt:
2348 case T_CreateUserMappingStmt:
2349 case T_AlterUserMappingStmt:
2350 case T_DropUserMappingStmt:
2358 case T_TruncateStmt:
2366 case T_SecLabelStmt:
2371 if (((CopyStmt *) parsetree)->is_from)
2379 PrepareStmt *stmt = (PrepareStmt *) parsetree;
2381 /* Look through a PREPARE to the contained stmt */
2382 lev = GetCommandLogLevel(stmt->query);
2388 ExecuteStmt *stmt = (ExecuteStmt *) parsetree;
2389 PreparedStatement *ps;
2391 /* Look through an EXECUTE to the referenced stmt */
2392 ps = FetchPreparedStatement(stmt->name, false);
2394 lev = GetCommandLogLevel(ps->plansource->raw_parse_tree);
2400 case T_DeallocateStmt:
2408 case T_AlterObjectSchemaStmt:
2412 case T_AlterOwnerStmt:
2416 case T_AlterTableStmt:
2420 case T_AlterDomainStmt:
2428 case T_GrantRoleStmt:
2432 case T_AlterDefaultPrivilegesStmt:
2440 case T_CompositeTypeStmt:
2444 case T_CreateEnumStmt:
2448 case T_AlterEnumStmt:
2456 case T_CreateFunctionStmt:
2460 case T_AlterFunctionStmt:
2472 case T_CreateSeqStmt:
2476 case T_AlterSeqStmt:
2480 case T_RemoveFuncStmt:
2488 case T_CreatedbStmt:
2492 case T_AlterDatabaseStmt:
2496 case T_AlterDatabaseSetStmt:
2512 case T_UnlistenStmt:
2530 ExplainStmt *stmt = (ExplainStmt *) parsetree;
2531 bool analyze = false;
2534 /* Look through an EXPLAIN ANALYZE to the contained stmt */
2535 foreach(lc, stmt->options)
2537 DefElem *opt = (DefElem *) lfirst(lc);
2539 if (strcmp(opt->defname, "analyze") == 0)
2540 analyze = defGetBoolean(opt);
2541 /* don't "break", as explain.c will use the last value */
2544 return GetCommandLogLevel(stmt->query);
2546 /* Plain EXPLAIN isn't so interesting */
2551 case T_VariableSetStmt:
2555 case T_VariableShowStmt:
2563 case T_CreateTrigStmt:
2567 case T_DropPropertyStmt:
2571 case T_CreatePLangStmt:
2575 case T_DropPLangStmt:
2579 case T_CreateDomainStmt:
2583 case T_CreateRoleStmt:
2587 case T_AlterRoleStmt:
2591 case T_AlterRoleSetStmt:
2595 case T_DropRoleStmt:
2599 case T_DropOwnedStmt:
2603 case T_ReassignOwnedStmt:
2611 case T_ConstraintsSetStmt:
2615 case T_CheckPointStmt:
2620 lev = LOGSTMT_ALL; /* should this be DDL? */
2623 case T_CreateConversionStmt:
2627 case T_CreateCastStmt:
2631 case T_DropCastStmt:
2635 case T_CreateOpClassStmt:
2639 case T_CreateOpFamilyStmt:
2643 case T_AlterOpFamilyStmt:
2647 case T_RemoveOpClassStmt:
2651 case T_RemoveOpFamilyStmt:
2655 case T_AlterTSDictionaryStmt:
2659 case T_AlterTSConfigurationStmt:
2663 /* already-planned queries */
2666 PlannedStmt *stmt = (PlannedStmt *) parsetree;
2668 switch (stmt->commandType)
2671 if (stmt->intoClause != NULL)
2672 lev = LOGSTMT_DDL; /* CREATE AS, SELECT INTO */
2674 lev = LOGSTMT_ALL; /* SELECT or DECLARE CURSOR */
2684 elog(WARNING, "unrecognized commandType: %d",
2685 (int) stmt->commandType);
2692 /* parsed-and-rewritten-but-not-planned queries */
2695 Query *stmt = (Query *) parsetree;
2697 switch (stmt->commandType)
2700 if (stmt->intoClause != NULL)
2701 lev = LOGSTMT_DDL; /* CREATE AS, SELECT INTO */
2703 lev = LOGSTMT_ALL; /* SELECT or DECLARE CURSOR */
2713 lev = GetCommandLogLevel(stmt->utilityStmt);
2717 elog(WARNING, "unrecognized commandType: %d",
2718 (int) stmt->commandType);
2727 elog(WARNING, "unrecognized node type: %d",
2728 (int) nodeTag(parsetree));