1 /*-------------------------------------------------------------------------
4 * Contains functions which control the execution of the POSTGRES utility
5 * commands. At one time acted as an interface between the Lisp and C
8 * Portions Copyright (c) 1996-2011, PostgreSQL Global Development Group
9 * Portions Copyright (c) 1994, Regents of the University of California
13 * src/backend/tcop/utility.c
15 *-------------------------------------------------------------------------
19 #include "access/reloptions.h"
20 #include "access/twophase.h"
21 #include "access/xact.h"
22 #include "catalog/catalog.h"
23 #include "catalog/namespace.h"
24 #include "catalog/toasting.h"
25 #include "commands/alter.h"
26 #include "commands/async.h"
27 #include "commands/cluster.h"
28 #include "commands/comment.h"
29 #include "commands/conversioncmds.h"
30 #include "commands/copy.h"
31 #include "commands/dbcommands.h"
32 #include "commands/defrem.h"
33 #include "commands/discard.h"
34 #include "commands/explain.h"
35 #include "commands/extension.h"
36 #include "commands/lockcmds.h"
37 #include "commands/portalcmds.h"
38 #include "commands/prepare.h"
39 #include "commands/proclang.h"
40 #include "commands/schemacmds.h"
41 #include "commands/seclabel.h"
42 #include "commands/sequence.h"
43 #include "commands/tablecmds.h"
44 #include "commands/tablespace.h"
45 #include "commands/trigger.h"
46 #include "commands/typecmds.h"
47 #include "commands/user.h"
48 #include "commands/vacuum.h"
49 #include "commands/view.h"
50 #include "miscadmin.h"
51 #include "parser/parse_utilcmd.h"
52 #include "postmaster/bgwriter.h"
53 #include "rewrite/rewriteDefine.h"
54 #include "rewrite/rewriteRemove.h"
55 #include "storage/fd.h"
56 #include "tcop/pquery.h"
57 #include "tcop/utility.h"
58 #include "utils/acl.h"
59 #include "utils/guc.h"
60 #include "utils/syscache.h"
63 /* Hook for plugins to get control in ProcessUtility() */
64 ProcessUtility_hook_type ProcessUtility_hook = NULL;
68 * Verify user has ownership of specified relation, else ereport.
70 * If noCatalogs is true then we also deny access to system catalogs,
71 * except when allowSystemTableMods is true.
74 CheckRelationOwnership(RangeVar *rel, bool noCatalogs)
79 relOid = RangeVarGetRelid(rel, false);
80 tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relOid));
81 if (!HeapTupleIsValid(tuple)) /* should not happen */
82 elog(ERROR, "cache lookup failed for relation %u", relOid);
84 if (!pg_class_ownercheck(relOid, GetUserId()))
85 aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
90 if (!allowSystemTableMods &&
91 IsSystemClass((Form_pg_class) GETSTRUCT(tuple)))
93 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
94 errmsg("permission denied: \"%s\" is a system catalog",
98 ReleaseSysCache(tuple);
103 * CommandIsReadOnly: is an executable query read-only?
105 * This is a much stricter test than we apply for XactReadOnly mode;
106 * the query must be *in truth* read-only, because the caller wishes
107 * not to do CommandCounterIncrement for it.
109 * Note: currently no need to support Query nodes here
112 CommandIsReadOnly(Node *parsetree)
114 if (IsA(parsetree, PlannedStmt))
116 PlannedStmt *stmt = (PlannedStmt *) parsetree;
118 switch (stmt->commandType)
121 if (stmt->intoClause != NULL)
122 return false; /* SELECT INTO */
123 else if (stmt->rowMarks != NIL)
124 return false; /* SELECT FOR UPDATE/SHARE */
132 elog(WARNING, "unrecognized commandType: %d",
133 (int) stmt->commandType);
137 /* For now, treat all utility commands as read/write */
142 * check_xact_readonly: is a utility command read-only?
144 * Here we use the loose rules of XactReadOnly mode: no permanent effects
145 * on the database are allowed.
148 check_xact_readonly(Node *parsetree)
154 * Note: Commands that need to do more complicated checking are handled
155 * elsewhere, in particular COPY and plannable statements do their own
156 * checking. However they should all call PreventCommandIfReadOnly to
157 * actually throw the error.
160 switch (nodeTag(parsetree))
162 case T_AlterDatabaseStmt:
163 case T_AlterDatabaseSetStmt:
164 case T_AlterDomainStmt:
165 case T_AlterFunctionStmt:
166 case T_AlterRoleStmt:
167 case T_AlterRoleSetStmt:
168 case T_AlterObjectSchemaStmt:
169 case T_AlterOwnerStmt:
171 case T_AlterTableStmt:
175 case T_CreateCastStmt:
176 case T_CreateConversionStmt:
178 case T_CreateDomainStmt:
179 case T_CreateFunctionStmt:
180 case T_CreateRoleStmt:
182 case T_CreatePLangStmt:
183 case T_CreateOpClassStmt:
184 case T_CreateOpFamilyStmt:
185 case T_AlterOpFamilyStmt:
187 case T_CreateSchemaStmt:
188 case T_CreateSeqStmt:
190 case T_CreateTableSpaceStmt:
191 case T_CreateTrigStmt:
192 case T_CompositeTypeStmt:
193 case T_CreateEnumStmt:
194 case T_AlterEnumStmt:
199 case T_DropTableSpaceStmt:
200 case T_RemoveFuncStmt:
202 case T_DropPLangStmt:
203 case T_RemoveOpClassStmt:
204 case T_RemoveOpFamilyStmt:
205 case T_DropPropertyStmt:
207 case T_GrantRoleStmt:
208 case T_AlterDefaultPrivilegesStmt:
210 case T_DropOwnedStmt:
211 case T_ReassignOwnedStmt:
212 case T_AlterTSDictionaryStmt:
213 case T_AlterTSConfigurationStmt:
214 case T_CreateExtensionStmt:
215 case T_AlterExtensionStmt:
216 case T_AlterExtensionContentsStmt:
217 case T_CreateFdwStmt:
220 case T_CreateForeignServerStmt:
221 case T_AlterForeignServerStmt:
222 case T_DropForeignServerStmt:
223 case T_CreateUserMappingStmt:
224 case T_AlterUserMappingStmt:
225 case T_DropUserMappingStmt:
226 case T_AlterTableSpaceOptionsStmt:
227 case T_CreateForeignTableStmt:
229 PreventCommandIfReadOnly(CreateCommandTag(parsetree));
238 * PreventCommandIfReadOnly: throw error if XactReadOnly
240 * This is useful mainly to ensure consistency of the error message wording;
241 * most callers have checked XactReadOnly for themselves.
244 PreventCommandIfReadOnly(const char *cmdname)
248 (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
249 /* translator: %s is name of a SQL command, eg CREATE */
250 errmsg("cannot execute %s in a read-only transaction",
255 * PreventCommandDuringRecovery: throw error if RecoveryInProgress
257 * The majority of operations that are unsafe in a Hot Standby slave
258 * will be rejected by XactReadOnly tests. However there are a few
259 * commands that are allowed in "read-only" xacts but cannot be allowed
260 * in Hot Standby mode. Those commands should call this function.
263 PreventCommandDuringRecovery(const char *cmdname)
265 if (RecoveryInProgress())
267 (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
268 /* translator: %s is name of a SQL command, eg CREATE */
269 errmsg("cannot execute %s during recovery",
274 * CheckRestrictedOperation: throw error for hazardous command if we're
275 * inside a security restriction context.
277 * This is needed to protect session-local state for which there is not any
278 * better-defined protection mechanism, such as ownership.
281 CheckRestrictedOperation(const char *cmdname)
283 if (InSecurityRestrictedOperation())
285 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
286 /* translator: %s is name of a SQL command, eg PREPARE */
287 errmsg("cannot execute %s within security-restricted operation",
294 * general utility function invoker
296 * parsetree: the parse tree for the utility statement
297 * queryString: original source text of command
298 * params: parameters to use during execution
299 * isTopLevel: true if executing a "top level" (interactively issued) command
300 * dest: where to send results
301 * completionTag: points to a buffer of size COMPLETION_TAG_BUFSIZE
302 * in which to store a command completion status string.
304 * Notes: as of PG 8.4, caller MUST supply a queryString; it is not
305 * allowed anymore to pass NULL. (If you really don't have source text,
306 * you can pass a constant string, perhaps "(query not available)".)
308 * completionTag is only set nonempty if we want to return a nondefault status.
310 * completionTag may be NULL if caller doesn't want a status string.
313 ProcessUtility(Node *parsetree,
314 const char *queryString,
315 ParamListInfo params,
320 Assert(queryString != NULL); /* required as of 8.4 */
323 * We provide a function hook variable that lets loadable plugins get
324 * control when ProcessUtility is called. Such a plugin would normally
325 * call standard_ProcessUtility().
327 if (ProcessUtility_hook)
328 (*ProcessUtility_hook) (parsetree, queryString, params,
329 isTopLevel, dest, completionTag);
331 standard_ProcessUtility(parsetree, queryString, params,
332 isTopLevel, dest, completionTag);
336 standard_ProcessUtility(Node *parsetree,
337 const char *queryString,
338 ParamListInfo params,
343 check_xact_readonly(parsetree);
346 completionTag[0] = '\0';
348 switch (nodeTag(parsetree))
351 * ******************** transactions ********************
353 case T_TransactionStmt:
355 TransactionStmt *stmt = (TransactionStmt *) parsetree;
360 * START TRANSACTION, as defined by SQL99: Identical
361 * to BEGIN. Same code for both.
363 case TRANS_STMT_BEGIN:
364 case TRANS_STMT_START:
368 BeginTransactionBlock();
369 foreach(lc, stmt->options)
371 DefElem *item = (DefElem *) lfirst(lc);
373 if (strcmp(item->defname, "transaction_isolation") == 0)
374 SetPGVariable("transaction_isolation",
375 list_make1(item->arg),
377 else if (strcmp(item->defname, "transaction_read_only") == 0)
378 SetPGVariable("transaction_read_only",
379 list_make1(item->arg),
381 else if (strcmp(item->defname, "transaction_deferrable") == 0)
382 SetPGVariable("transaction_deferrable",
383 list_make1(item->arg),
389 case TRANS_STMT_COMMIT:
390 if (!EndTransactionBlock())
392 /* report unsuccessful commit in completionTag */
394 strcpy(completionTag, "ROLLBACK");
398 case TRANS_STMT_PREPARE:
399 PreventCommandDuringRecovery("PREPARE TRANSACTION");
400 if (!PrepareTransactionBlock(stmt->gid))
402 /* report unsuccessful commit in completionTag */
404 strcpy(completionTag, "ROLLBACK");
408 case TRANS_STMT_COMMIT_PREPARED:
409 PreventTransactionChain(isTopLevel, "COMMIT PREPARED");
410 PreventCommandDuringRecovery("COMMIT PREPARED");
411 FinishPreparedTransaction(stmt->gid, true);
414 case TRANS_STMT_ROLLBACK_PREPARED:
415 PreventTransactionChain(isTopLevel, "ROLLBACK PREPARED");
416 PreventCommandDuringRecovery("ROLLBACK PREPARED");
417 FinishPreparedTransaction(stmt->gid, false);
420 case TRANS_STMT_ROLLBACK:
421 UserAbortTransactionBlock();
424 case TRANS_STMT_SAVEPOINT:
429 RequireTransactionChain(isTopLevel, "SAVEPOINT");
431 foreach(cell, stmt->options)
433 DefElem *elem = lfirst(cell);
435 if (strcmp(elem->defname, "savepoint_name") == 0)
436 name = strVal(elem->arg);
439 Assert(PointerIsValid(name));
441 DefineSavepoint(name);
445 case TRANS_STMT_RELEASE:
446 RequireTransactionChain(isTopLevel, "RELEASE SAVEPOINT");
447 ReleaseSavepoint(stmt->options);
450 case TRANS_STMT_ROLLBACK_TO:
451 RequireTransactionChain(isTopLevel, "ROLLBACK TO SAVEPOINT");
452 RollbackToSavepoint(stmt->options);
455 * CommitTransactionCommand is in charge of
456 * re-defining the savepoint again
464 * Portal (cursor) manipulation
466 * Note: DECLARE CURSOR is processed mostly as a SELECT, and
467 * therefore what we will get here is a PlannedStmt not a bare
472 PlannedStmt *stmt = (PlannedStmt *) parsetree;
474 if (stmt->utilityStmt == NULL ||
475 !IsA(stmt->utilityStmt, DeclareCursorStmt))
476 elog(ERROR, "non-DECLARE CURSOR PlannedStmt passed to ProcessUtility");
477 PerformCursorOpen(stmt, params, queryString, isTopLevel);
481 case T_ClosePortalStmt:
483 ClosePortalStmt *stmt = (ClosePortalStmt *) parsetree;
485 CheckRestrictedOperation("CLOSE");
486 PerformPortalClose(stmt->portalname);
491 PerformPortalFetch((FetchStmt *) parsetree, dest,
496 * relation and attribute manipulation
498 case T_CreateSchemaStmt:
499 CreateSchemaCommand((CreateSchemaStmt *) parsetree,
504 case T_CreateForeignTableStmt:
510 /* Run parse analysis ... */
511 stmts = transformCreateStmt((CreateStmt *) parsetree,
517 Node *stmt = (Node *) lfirst(l);
519 if (IsA(stmt, CreateStmt))
522 static char *validnsps[] = HEAP_RELOPT_NAMESPACES;
524 /* Create the table itself */
525 relOid = DefineRelation((CreateStmt *) stmt,
530 * If "IF NOT EXISTS" was specified and the relation
531 * already exists, do nothing further.
533 if (relOid == InvalidOid)
537 * Let AlterTableCreateToastTable decide if this one
538 * needs a secondary relation too.
540 CommandCounterIncrement();
542 /* parse and validate reloptions for the toast table */
543 toast_options = transformRelOptions((Datum) 0,
544 ((CreateStmt *) stmt)->options,
548 (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options,
551 AlterTableCreateToastTable(relOid, toast_options);
553 else if (IsA(stmt, CreateForeignTableStmt))
555 /* Create the table itself */
556 relOid = DefineRelation((CreateStmt *) stmt,
557 RELKIND_FOREIGN_TABLE,
561 * Unless "IF NOT EXISTS" was specified and the
562 * relation already exists, create the pg_foreign_table
565 if (relOid != InvalidOid)
566 CreateForeignTable((CreateForeignTableStmt *) stmt,
571 /* Recurse for anything else */
580 /* Need CCI between commands */
581 if (lnext(l) != NULL)
582 CommandCounterIncrement();
587 case T_CreateTableSpaceStmt:
588 PreventTransactionChain(isTopLevel, "CREATE TABLESPACE");
589 CreateTableSpace((CreateTableSpaceStmt *) parsetree);
592 case T_DropTableSpaceStmt:
593 PreventTransactionChain(isTopLevel, "DROP TABLESPACE");
594 DropTableSpace((DropTableSpaceStmt *) parsetree);
597 case T_AlterTableSpaceOptionsStmt:
598 AlterTableSpaceOptions((AlterTableSpaceOptionsStmt *) parsetree);
601 case T_CreateExtensionStmt:
602 CreateExtension((CreateExtensionStmt *) parsetree);
605 case T_AlterExtensionStmt:
606 ExecAlterExtensionStmt((AlterExtensionStmt *) parsetree);
609 case T_AlterExtensionContentsStmt:
610 ExecAlterExtensionContentsStmt((AlterExtensionContentsStmt *) parsetree);
613 case T_CreateFdwStmt:
614 CreateForeignDataWrapper((CreateFdwStmt *) parsetree);
618 AlterForeignDataWrapper((AlterFdwStmt *) parsetree);
622 RemoveForeignDataWrapper((DropFdwStmt *) parsetree);
625 case T_CreateForeignServerStmt:
626 CreateForeignServer((CreateForeignServerStmt *) parsetree);
629 case T_AlterForeignServerStmt:
630 AlterForeignServer((AlterForeignServerStmt *) parsetree);
633 case T_DropForeignServerStmt:
634 RemoveForeignServer((DropForeignServerStmt *) parsetree);
637 case T_CreateUserMappingStmt:
638 CreateUserMapping((CreateUserMappingStmt *) parsetree);
641 case T_AlterUserMappingStmt:
642 AlterUserMapping((AlterUserMappingStmt *) parsetree);
645 case T_DropUserMappingStmt:
646 RemoveUserMapping((DropUserMappingStmt *) parsetree);
651 DropStmt *stmt = (DropStmt *) parsetree;
653 switch (stmt->removeType)
656 case OBJECT_SEQUENCE:
659 case OBJECT_FOREIGN_TABLE:
660 RemoveRelations(stmt);
668 case OBJECT_CONVERSION:
669 DropConversionsCommand(stmt);
676 case OBJECT_TSPARSER:
677 RemoveTSParsers(stmt);
680 case OBJECT_TSDICTIONARY:
681 RemoveTSDictionaries(stmt);
684 case OBJECT_TSTEMPLATE:
685 RemoveTSTemplates(stmt);
688 case OBJECT_TSCONFIGURATION:
689 RemoveTSConfigurations(stmt);
692 case OBJECT_EXTENSION:
693 RemoveExtensions(stmt);
697 elog(ERROR, "unrecognized drop object type: %d",
698 (int) stmt->removeType);
705 ExecuteTruncate((TruncateStmt *) parsetree);
709 CommentObject((CommentStmt *) parsetree);
713 ExecSecLabelStmt((SecLabelStmt *) parsetree);
720 processed = DoCopy((CopyStmt *) parsetree, queryString);
722 snprintf(completionTag, COMPLETION_TAG_BUFSIZE,
723 "COPY " UINT64_FORMAT, processed);
728 CheckRestrictedOperation("PREPARE");
729 PrepareQuery((PrepareStmt *) parsetree, queryString);
733 ExecuteQuery((ExecuteStmt *) parsetree, queryString, params,
734 dest, completionTag);
737 case T_DeallocateStmt:
738 CheckRestrictedOperation("DEALLOCATE");
739 DeallocateQuery((DeallocateStmt *) parsetree);
746 ExecRenameStmt((RenameStmt *) parsetree);
749 case T_AlterObjectSchemaStmt:
750 ExecAlterObjectSchemaStmt((AlterObjectSchemaStmt *) parsetree);
753 case T_AlterOwnerStmt:
754 ExecAlterOwnerStmt((AlterOwnerStmt *) parsetree);
757 case T_AlterTableStmt:
762 /* Run parse analysis ... */
763 stmts = transformAlterTableStmt((AlterTableStmt *) parsetree,
769 Node *stmt = (Node *) lfirst(l);
771 if (IsA(stmt, AlterTableStmt))
773 /* Do the table alteration proper */
774 AlterTable((AlterTableStmt *) stmt);
778 /* Recurse for anything else */
787 /* Need CCI between commands */
788 if (lnext(l) != NULL)
789 CommandCounterIncrement();
794 case T_AlterDomainStmt:
796 AlterDomainStmt *stmt = (AlterDomainStmt *) parsetree;
799 * Some or all of these functions are recursive to cover
800 * inherited things, so permission checks are done there.
802 switch (stmt->subtype)
804 case 'T': /* ALTER DOMAIN DEFAULT */
807 * Recursively alter column default for table and, if
808 * requested, for descendants
810 AlterDomainDefault(stmt->typeName,
813 case 'N': /* ALTER DOMAIN DROP NOT NULL */
814 AlterDomainNotNull(stmt->typeName,
817 case 'O': /* ALTER DOMAIN SET NOT NULL */
818 AlterDomainNotNull(stmt->typeName,
821 case 'C': /* ADD CONSTRAINT */
822 AlterDomainAddConstraint(stmt->typeName,
825 case 'X': /* DROP CONSTRAINT */
826 AlterDomainDropConstraint(stmt->typeName,
831 elog(ERROR, "unrecognized alter domain type: %d",
832 (int) stmt->subtype);
839 ExecuteGrantStmt((GrantStmt *) parsetree);
842 case T_GrantRoleStmt:
843 GrantRole((GrantRoleStmt *) parsetree);
846 case T_AlterDefaultPrivilegesStmt:
847 ExecAlterDefaultPrivilegesStmt((AlterDefaultPrivilegesStmt *) parsetree);
851 * **************** object creation / destruction *****************
855 DefineStmt *stmt = (DefineStmt *) parsetree;
859 case OBJECT_AGGREGATE:
860 DefineAggregate(stmt->defnames, stmt->args,
861 stmt->oldstyle, stmt->definition);
863 case OBJECT_OPERATOR:
864 Assert(stmt->args == NIL);
865 DefineOperator(stmt->defnames, stmt->definition);
868 Assert(stmt->args == NIL);
869 DefineType(stmt->defnames, stmt->definition);
871 case OBJECT_TSPARSER:
872 Assert(stmt->args == NIL);
873 DefineTSParser(stmt->defnames, stmt->definition);
875 case OBJECT_TSDICTIONARY:
876 Assert(stmt->args == NIL);
877 DefineTSDictionary(stmt->defnames, stmt->definition);
879 case OBJECT_TSTEMPLATE:
880 Assert(stmt->args == NIL);
881 DefineTSTemplate(stmt->defnames, stmt->definition);
883 case OBJECT_TSCONFIGURATION:
884 Assert(stmt->args == NIL);
885 DefineTSConfiguration(stmt->defnames, stmt->definition);
888 elog(ERROR, "unrecognized define stmt type: %d",
895 case T_CompositeTypeStmt: /* CREATE TYPE (composite) */
897 CompositeTypeStmt *stmt = (CompositeTypeStmt *) parsetree;
899 DefineCompositeType(stmt->typevar, stmt->coldeflist);
903 case T_CreateEnumStmt: /* CREATE TYPE (enum) */
904 DefineEnum((CreateEnumStmt *) parsetree);
907 case T_AlterEnumStmt: /* ALTER TYPE (enum) */
909 * We disallow this in transaction blocks, because we can't cope
910 * with enum OID values getting into indexes and then having their
911 * defining pg_enum entries go away.
913 PreventTransactionChain(isTopLevel, "ALTER TYPE ... ADD");
914 AlterEnum((AlterEnumStmt *) parsetree);
917 case T_ViewStmt: /* CREATE VIEW */
918 DefineView((ViewStmt *) parsetree, queryString);
921 case T_CreateFunctionStmt: /* CREATE FUNCTION */
922 CreateFunction((CreateFunctionStmt *) parsetree, queryString);
925 case T_AlterFunctionStmt: /* ALTER FUNCTION */
926 AlterFunction((AlterFunctionStmt *) parsetree);
929 case T_IndexStmt: /* CREATE INDEX */
931 IndexStmt *stmt = (IndexStmt *) parsetree;
933 if (stmt->concurrent)
934 PreventTransactionChain(isTopLevel,
935 "CREATE INDEX CONCURRENTLY");
937 CheckRelationOwnership(stmt->relation, true);
939 /* Run parse analysis ... */
940 stmt = transformIndexStmt(stmt, queryString);
943 DefineIndex(stmt->relation, /* relation */
944 stmt->idxname, /* index name */
945 InvalidOid, /* no predefined OID */
946 stmt->accessMethod, /* am name */
948 stmt->indexParams, /* parameters */
949 (Expr *) stmt->whereClause,
951 stmt->excludeOpNames,
957 false, /* is_alter_table */
958 true, /* check_rights */
959 false, /* skip_build */
961 stmt->concurrent); /* concurrent */
965 case T_RuleStmt: /* CREATE RULE */
966 DefineRule((RuleStmt *) parsetree, queryString);
969 case T_CreateSeqStmt:
970 DefineSequence((CreateSeqStmt *) parsetree);
974 AlterSequence((AlterSeqStmt *) parsetree);
977 case T_RemoveFuncStmt:
979 RemoveFuncStmt *stmt = (RemoveFuncStmt *) parsetree;
983 case OBJECT_FUNCTION:
984 RemoveFunction(stmt);
986 case OBJECT_AGGREGATE:
987 RemoveAggregate(stmt);
989 case OBJECT_OPERATOR:
990 RemoveOperator(stmt);
993 elog(ERROR, "unrecognized object type: %d",
1001 ExecuteDoStmt((DoStmt *) parsetree);
1004 case T_CreatedbStmt:
1005 PreventTransactionChain(isTopLevel, "CREATE DATABASE");
1006 createdb((CreatedbStmt *) parsetree);
1009 case T_AlterDatabaseStmt:
1010 AlterDatabase((AlterDatabaseStmt *) parsetree, isTopLevel);
1013 case T_AlterDatabaseSetStmt:
1014 AlterDatabaseSet((AlterDatabaseSetStmt *) parsetree);
1019 DropdbStmt *stmt = (DropdbStmt *) parsetree;
1021 PreventTransactionChain(isTopLevel, "DROP DATABASE");
1022 dropdb(stmt->dbname, stmt->missing_ok);
1026 /* Query-level asynchronous notification */
1029 NotifyStmt *stmt = (NotifyStmt *) parsetree;
1031 PreventCommandDuringRecovery("NOTIFY");
1032 Async_Notify(stmt->conditionname, stmt->payload);
1038 ListenStmt *stmt = (ListenStmt *) parsetree;
1040 PreventCommandDuringRecovery("LISTEN");
1041 CheckRestrictedOperation("LISTEN");
1042 Async_Listen(stmt->conditionname);
1046 case T_UnlistenStmt:
1048 UnlistenStmt *stmt = (UnlistenStmt *) parsetree;
1050 PreventCommandDuringRecovery("UNLISTEN");
1051 CheckRestrictedOperation("UNLISTEN");
1052 if (stmt->conditionname)
1053 Async_Unlisten(stmt->conditionname);
1055 Async_UnlistenAll();
1061 LoadStmt *stmt = (LoadStmt *) parsetree;
1063 closeAllVfds(); /* probably not necessary... */
1064 /* Allowed names are restricted if you're not superuser */
1065 load_file(stmt->filename, !superuser());
1070 /* we choose to allow this during "read only" transactions */
1071 PreventCommandDuringRecovery("CLUSTER");
1072 cluster((ClusterStmt *) parsetree, isTopLevel);
1076 /* we choose to allow this during "read only" transactions */
1077 PreventCommandDuringRecovery("VACUUM");
1078 vacuum((VacuumStmt *) parsetree, InvalidOid, true, NULL, false,
1083 ExplainQuery((ExplainStmt *) parsetree, queryString, params, dest);
1086 case T_VariableSetStmt:
1087 ExecSetVariableStmt((VariableSetStmt *) parsetree);
1090 case T_VariableShowStmt:
1092 VariableShowStmt *n = (VariableShowStmt *) parsetree;
1094 GetPGVariable(n->name, dest);
1099 /* should we allow DISCARD PLANS? */
1100 CheckRestrictedOperation("DISCARD");
1101 DiscardCommand((DiscardStmt *) parsetree, isTopLevel);
1104 case T_CreateTrigStmt:
1105 (void) CreateTrigger((CreateTrigStmt *) parsetree, queryString,
1106 InvalidOid, InvalidOid, false);
1109 case T_DropPropertyStmt:
1111 DropPropertyStmt *stmt = (DropPropertyStmt *) parsetree;
1114 relId = RangeVarGetRelid(stmt->relation, false);
1116 switch (stmt->removeType)
1119 /* RemoveRewriteRule checks permissions */
1120 RemoveRewriteRule(relId, stmt->property,
1121 stmt->behavior, stmt->missing_ok);
1123 case OBJECT_TRIGGER:
1124 /* DropTrigger checks permissions */
1125 DropTrigger(relId, stmt->property,
1126 stmt->behavior, stmt->missing_ok);
1129 elog(ERROR, "unrecognized object type: %d",
1130 (int) stmt->removeType);
1136 case T_CreatePLangStmt:
1137 CreateProceduralLanguage((CreatePLangStmt *) parsetree);
1140 case T_DropPLangStmt:
1141 DropProceduralLanguage((DropPLangStmt *) parsetree);
1145 * ******************************** DOMAIN statements ****
1147 case T_CreateDomainStmt:
1148 DefineDomain((CreateDomainStmt *) parsetree);
1152 * ******************************** ROLE statements ****
1154 case T_CreateRoleStmt:
1155 CreateRole((CreateRoleStmt *) parsetree);
1158 case T_AlterRoleStmt:
1159 AlterRole((AlterRoleStmt *) parsetree);
1162 case T_AlterRoleSetStmt:
1163 AlterRoleSet((AlterRoleSetStmt *) parsetree);
1166 case T_DropRoleStmt:
1167 DropRole((DropRoleStmt *) parsetree);
1170 case T_DropOwnedStmt:
1171 DropOwnedObjects((DropOwnedStmt *) parsetree);
1174 case T_ReassignOwnedStmt:
1175 ReassignOwnedObjects((ReassignOwnedStmt *) parsetree);
1181 * Since the lock would just get dropped immediately, LOCK TABLE
1182 * outside a transaction block is presumed to be user error.
1184 RequireTransactionChain(isTopLevel, "LOCK TABLE");
1185 LockTableCommand((LockStmt *) parsetree);
1188 case T_ConstraintsSetStmt:
1189 AfterTriggerSetState((ConstraintsSetStmt *) parsetree);
1192 case T_CheckPointStmt:
1195 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1196 errmsg("must be superuser to do CHECKPOINT")));
1199 * You might think we should have a PreventCommandDuringRecovery()
1200 * here, but we interpret a CHECKPOINT command during recovery as
1201 * a request for a restartpoint instead. We allow this since it
1202 * can be a useful way of reducing switchover time when using
1203 * various forms of replication.
1205 RequestCheckpoint(CHECKPOINT_IMMEDIATE | CHECKPOINT_WAIT |
1206 (RecoveryInProgress() ? 0 : CHECKPOINT_FORCE));
1211 ReindexStmt *stmt = (ReindexStmt *) parsetree;
1213 /* we choose to allow this during "read only" transactions */
1214 PreventCommandDuringRecovery("REINDEX");
1218 ReindexIndex(stmt->relation);
1221 ReindexTable(stmt->relation);
1223 case OBJECT_DATABASE:
1226 * This cannot run inside a user transaction block; if
1227 * we were inside a transaction, then its commit- and
1228 * start-transaction-command calls would not have the
1231 PreventTransactionChain(isTopLevel,
1232 "REINDEX DATABASE");
1233 ReindexDatabase(stmt->name,
1234 stmt->do_system, stmt->do_user);
1237 elog(ERROR, "unrecognized object type: %d",
1245 case T_CreateConversionStmt:
1246 CreateConversionCommand((CreateConversionStmt *) parsetree);
1249 case T_CreateCastStmt:
1250 CreateCast((CreateCastStmt *) parsetree);
1253 case T_DropCastStmt:
1254 DropCast((DropCastStmt *) parsetree);
1257 case T_CreateOpClassStmt:
1258 DefineOpClass((CreateOpClassStmt *) parsetree);
1261 case T_CreateOpFamilyStmt:
1262 DefineOpFamily((CreateOpFamilyStmt *) parsetree);
1265 case T_AlterOpFamilyStmt:
1266 AlterOpFamily((AlterOpFamilyStmt *) parsetree);
1269 case T_RemoveOpClassStmt:
1270 RemoveOpClass((RemoveOpClassStmt *) parsetree);
1273 case T_RemoveOpFamilyStmt:
1274 RemoveOpFamily((RemoveOpFamilyStmt *) parsetree);
1277 case T_AlterTSDictionaryStmt:
1278 AlterTSDictionary((AlterTSDictionaryStmt *) parsetree);
1281 case T_AlterTSConfigurationStmt:
1282 AlterTSConfiguration((AlterTSConfigurationStmt *) parsetree);
1286 elog(ERROR, "unrecognized node type: %d",
1287 (int) nodeTag(parsetree));
1293 * UtilityReturnsTuples
1294 * Return "true" if this utility statement will send output to the
1297 * Generally, there should be a case here for each case in ProcessUtility
1298 * where "dest" is passed on.
1301 UtilityReturnsTuples(Node *parsetree)
1303 switch (nodeTag(parsetree))
1307 FetchStmt *stmt = (FetchStmt *) parsetree;
1312 portal = GetPortalByName(stmt->portalname);
1313 if (!PortalIsValid(portal))
1314 return false; /* not our business to raise error */
1315 return portal->tupDesc ? true : false;
1320 ExecuteStmt *stmt = (ExecuteStmt *) parsetree;
1321 PreparedStatement *entry;
1325 entry = FetchPreparedStatement(stmt->name, false);
1327 return false; /* not our business to raise error */
1328 if (entry->plansource->resultDesc)
1336 case T_VariableShowStmt:
1345 * UtilityTupleDescriptor
1346 * Fetch the actual output tuple descriptor for a utility statement
1347 * for which UtilityReturnsTuples() previously returned "true".
1349 * The returned descriptor is created in (or copied into) the current memory
1353 UtilityTupleDescriptor(Node *parsetree)
1355 switch (nodeTag(parsetree))
1359 FetchStmt *stmt = (FetchStmt *) parsetree;
1364 portal = GetPortalByName(stmt->portalname);
1365 if (!PortalIsValid(portal))
1366 return NULL; /* not our business to raise error */
1367 return CreateTupleDescCopy(portal->tupDesc);
1372 ExecuteStmt *stmt = (ExecuteStmt *) parsetree;
1373 PreparedStatement *entry;
1377 entry = FetchPreparedStatement(stmt->name, false);
1379 return NULL; /* not our business to raise error */
1380 return FetchPreparedStatementResultDesc(entry);
1384 return ExplainResultDesc((ExplainStmt *) parsetree);
1386 case T_VariableShowStmt:
1388 VariableShowStmt *n = (VariableShowStmt *) parsetree;
1390 return GetPGVariableResultDesc(n->name);
1400 * QueryReturnsTuples
1401 * Return "true" if this Query will send output to the destination.
1405 QueryReturnsTuples(Query *parsetree)
1407 switch (parsetree->commandType)
1410 /* returns tuples ... unless it's DECLARE CURSOR or SELECT INTO */
1411 if (parsetree->utilityStmt == NULL &&
1412 parsetree->intoClause == NULL)
1418 /* the forms with RETURNING return tuples */
1419 if (parsetree->returningList)
1423 return UtilityReturnsTuples(parsetree->utilityStmt);
1426 /* probably shouldn't get here */
1429 return false; /* default */
1435 * AlterObjectTypeCommandTag
1436 * helper function for CreateCommandTag
1438 * This covers most cases where ALTER is used with an ObjectType enum.
1441 AlterObjectTypeCommandTag(ObjectType objtype)
1447 case OBJECT_AGGREGATE:
1448 tag = "ALTER AGGREGATE";
1450 case OBJECT_ATTRIBUTE:
1457 tag = "ALTER TABLE";
1459 case OBJECT_CONSTRAINT:
1460 tag = "ALTER TABLE";
1462 case OBJECT_CONVERSION:
1463 tag = "ALTER CONVERSION";
1465 case OBJECT_DATABASE:
1466 tag = "ALTER DATABASE";
1469 tag = "ALTER DOMAIN";
1471 case OBJECT_EXTENSION:
1472 tag = "ALTER EXTENSION";
1475 tag = "ALTER FOREIGN DATA WRAPPER";
1477 case OBJECT_FOREIGN_SERVER:
1478 tag = "ALTER SERVER";
1480 case OBJECT_FOREIGN_TABLE:
1481 tag = "ALTER FOREIGN TABLE";
1483 case OBJECT_FUNCTION:
1484 tag = "ALTER FUNCTION";
1487 tag = "ALTER INDEX";
1489 case OBJECT_LANGUAGE:
1490 tag = "ALTER LANGUAGE";
1492 case OBJECT_LARGEOBJECT:
1493 tag = "ALTER LARGE OBJECT";
1495 case OBJECT_OPCLASS:
1496 tag = "ALTER OPERATOR CLASS";
1498 case OBJECT_OPERATOR:
1499 tag = "ALTER OPERATOR";
1501 case OBJECT_OPFAMILY:
1502 tag = "ALTER OPERATOR FAMILY";
1511 tag = "ALTER SCHEMA";
1513 case OBJECT_SEQUENCE:
1514 tag = "ALTER SEQUENCE";
1517 tag = "ALTER TABLE";
1519 case OBJECT_TABLESPACE:
1520 tag = "ALTER TABLESPACE";
1522 case OBJECT_TRIGGER:
1523 tag = "ALTER TRIGGER";
1525 case OBJECT_TSCONFIGURATION:
1526 tag = "ALTER TEXT SEARCH CONFIGURATION";
1528 case OBJECT_TSDICTIONARY:
1529 tag = "ALTER TEXT SEARCH DICTIONARY";
1531 case OBJECT_TSPARSER:
1532 tag = "ALTER TEXT SEARCH PARSER";
1534 case OBJECT_TSTEMPLATE:
1535 tag = "ALTER TEXT SEARCH TEMPLATE";
1553 * utility to get a string representation of the command operation,
1554 * given either a raw (un-analyzed) parsetree or a planned query.
1556 * This must handle all command types, but since the vast majority
1557 * of 'em are utility commands, it seems sensible to keep it here.
1559 * NB: all result strings must be shorter than COMPLETION_TAG_BUFSIZE.
1560 * Also, the result must point at a true constant (permanent storage).
1563 CreateCommandTag(Node *parsetree)
1567 switch (nodeTag(parsetree))
1569 /* raw plannable queries */
1586 /* utility statements --- same whether raw or cooked */
1587 case T_TransactionStmt:
1589 TransactionStmt *stmt = (TransactionStmt *) parsetree;
1593 case TRANS_STMT_BEGIN:
1597 case TRANS_STMT_START:
1598 tag = "START TRANSACTION";
1601 case TRANS_STMT_COMMIT:
1605 case TRANS_STMT_ROLLBACK:
1606 case TRANS_STMT_ROLLBACK_TO:
1610 case TRANS_STMT_SAVEPOINT:
1614 case TRANS_STMT_RELEASE:
1618 case TRANS_STMT_PREPARE:
1619 tag = "PREPARE TRANSACTION";
1622 case TRANS_STMT_COMMIT_PREPARED:
1623 tag = "COMMIT PREPARED";
1626 case TRANS_STMT_ROLLBACK_PREPARED:
1627 tag = "ROLLBACK PREPARED";
1637 case T_DeclareCursorStmt:
1638 tag = "DECLARE CURSOR";
1641 case T_ClosePortalStmt:
1643 ClosePortalStmt *stmt = (ClosePortalStmt *) parsetree;
1645 if (stmt->portalname == NULL)
1646 tag = "CLOSE CURSOR ALL";
1648 tag = "CLOSE CURSOR";
1654 FetchStmt *stmt = (FetchStmt *) parsetree;
1656 tag = (stmt->ismove) ? "MOVE" : "FETCH";
1660 case T_CreateDomainStmt:
1661 tag = "CREATE DOMAIN";
1664 case T_CreateSchemaStmt:
1665 tag = "CREATE SCHEMA";
1669 tag = "CREATE TABLE";
1672 case T_CreateTableSpaceStmt:
1673 tag = "CREATE TABLESPACE";
1676 case T_DropTableSpaceStmt:
1677 tag = "DROP TABLESPACE";
1680 case T_AlterTableSpaceOptionsStmt:
1681 tag = "ALTER TABLESPACE";
1684 case T_CreateExtensionStmt:
1685 tag = "CREATE EXTENSION";
1688 case T_AlterExtensionStmt:
1689 tag = "ALTER EXTENSION";
1692 case T_AlterExtensionContentsStmt:
1693 tag = "ALTER EXTENSION";
1696 case T_CreateFdwStmt:
1697 tag = "CREATE FOREIGN DATA WRAPPER";
1700 case T_AlterFdwStmt:
1701 tag = "ALTER FOREIGN DATA WRAPPER";
1705 tag = "DROP FOREIGN DATA WRAPPER";
1708 case T_CreateForeignServerStmt:
1709 tag = "CREATE SERVER";
1712 case T_AlterForeignServerStmt:
1713 tag = "ALTER SERVER";
1716 case T_DropForeignServerStmt:
1717 tag = "DROP SERVER";
1720 case T_CreateUserMappingStmt:
1721 tag = "CREATE USER MAPPING";
1724 case T_AlterUserMappingStmt:
1725 tag = "ALTER USER MAPPING";
1728 case T_DropUserMappingStmt:
1729 tag = "DROP USER MAPPING";
1732 case T_CreateForeignTableStmt:
1733 tag = "CREATE FOREIGN TABLE";
1737 switch (((DropStmt *) parsetree)->removeType)
1742 case OBJECT_SEQUENCE:
1743 tag = "DROP SEQUENCE";
1755 tag = "DROP DOMAIN";
1757 case OBJECT_CONVERSION:
1758 tag = "DROP CONVERSION";
1761 tag = "DROP SCHEMA";
1763 case OBJECT_TSPARSER:
1764 tag = "DROP TEXT SEARCH PARSER";
1766 case OBJECT_TSDICTIONARY:
1767 tag = "DROP TEXT SEARCH DICTIONARY";
1769 case OBJECT_TSTEMPLATE:
1770 tag = "DROP TEXT SEARCH TEMPLATE";
1772 case OBJECT_TSCONFIGURATION:
1773 tag = "DROP TEXT SEARCH CONFIGURATION";
1775 case OBJECT_FOREIGN_TABLE:
1776 tag = "DROP FOREIGN TABLE";
1778 case OBJECT_EXTENSION:
1779 tag = "DROP EXTENSION";
1786 case T_TruncateStmt:
1787 tag = "TRUNCATE TABLE";
1794 case T_SecLabelStmt:
1795 tag = "SECURITY LABEL";
1803 tag = AlterObjectTypeCommandTag(((RenameStmt *) parsetree)->renameType);
1806 case T_AlterObjectSchemaStmt:
1807 tag = AlterObjectTypeCommandTag(((AlterObjectSchemaStmt *) parsetree)->objectType);
1810 case T_AlterOwnerStmt:
1811 tag = AlterObjectTypeCommandTag(((AlterOwnerStmt *) parsetree)->objectType);
1814 case T_AlterTableStmt:
1815 tag = AlterObjectTypeCommandTag(((AlterTableStmt *) parsetree)->relkind);
1818 case T_AlterDomainStmt:
1819 tag = "ALTER DOMAIN";
1822 case T_AlterFunctionStmt:
1823 tag = "ALTER FUNCTION";
1828 GrantStmt *stmt = (GrantStmt *) parsetree;
1830 tag = (stmt->is_grant) ? "GRANT" : "REVOKE";
1834 case T_GrantRoleStmt:
1836 GrantRoleStmt *stmt = (GrantRoleStmt *) parsetree;
1838 tag = (stmt->is_grant) ? "GRANT ROLE" : "REVOKE ROLE";
1842 case T_AlterDefaultPrivilegesStmt:
1843 tag = "ALTER DEFAULT PRIVILEGES";
1847 switch (((DefineStmt *) parsetree)->kind)
1849 case OBJECT_AGGREGATE:
1850 tag = "CREATE AGGREGATE";
1852 case OBJECT_OPERATOR:
1853 tag = "CREATE OPERATOR";
1856 tag = "CREATE TYPE";
1858 case OBJECT_TSPARSER:
1859 tag = "CREATE TEXT SEARCH PARSER";
1861 case OBJECT_TSDICTIONARY:
1862 tag = "CREATE TEXT SEARCH DICTIONARY";
1864 case OBJECT_TSTEMPLATE:
1865 tag = "CREATE TEXT SEARCH TEMPLATE";
1867 case OBJECT_TSCONFIGURATION:
1868 tag = "CREATE TEXT SEARCH CONFIGURATION";
1875 case T_CompositeTypeStmt:
1876 tag = "CREATE TYPE";
1879 case T_CreateEnumStmt:
1880 tag = "CREATE TYPE";
1883 case T_AlterEnumStmt:
1888 tag = "CREATE VIEW";
1891 case T_CreateFunctionStmt:
1892 tag = "CREATE FUNCTION";
1896 tag = "CREATE INDEX";
1900 tag = "CREATE RULE";
1903 case T_CreateSeqStmt:
1904 tag = "CREATE SEQUENCE";
1907 case T_AlterSeqStmt:
1908 tag = "ALTER SEQUENCE";
1911 case T_RemoveFuncStmt:
1912 switch (((RemoveFuncStmt *) parsetree)->kind)
1914 case OBJECT_FUNCTION:
1915 tag = "DROP FUNCTION";
1917 case OBJECT_AGGREGATE:
1918 tag = "DROP AGGREGATE";
1920 case OBJECT_OPERATOR:
1921 tag = "DROP OPERATOR";
1932 case T_CreatedbStmt:
1933 tag = "CREATE DATABASE";
1936 case T_AlterDatabaseStmt:
1937 tag = "ALTER DATABASE";
1940 case T_AlterDatabaseSetStmt:
1941 tag = "ALTER DATABASE";
1945 tag = "DROP DATABASE";
1956 case T_UnlistenStmt:
1969 if (((VacuumStmt *) parsetree)->options & VACOPT_VACUUM)
1979 case T_VariableSetStmt:
1980 switch (((VariableSetStmt *) parsetree)->kind)
1983 case VAR_SET_CURRENT:
1984 case VAR_SET_DEFAULT:
1997 case T_VariableShowStmt:
2002 switch (((DiscardStmt *) parsetree)->target)
2005 tag = "DISCARD ALL";
2008 tag = "DISCARD PLANS";
2011 tag = "DISCARD TEMP";
2018 case T_CreateTrigStmt:
2019 tag = "CREATE TRIGGER";
2022 case T_DropPropertyStmt:
2023 switch (((DropPropertyStmt *) parsetree)->removeType)
2025 case OBJECT_TRIGGER:
2026 tag = "DROP TRIGGER";
2036 case T_CreatePLangStmt:
2037 tag = "CREATE LANGUAGE";
2040 case T_DropPLangStmt:
2041 tag = "DROP LANGUAGE";
2044 case T_CreateRoleStmt:
2045 tag = "CREATE ROLE";
2048 case T_AlterRoleStmt:
2052 case T_AlterRoleSetStmt:
2056 case T_DropRoleStmt:
2060 case T_DropOwnedStmt:
2064 case T_ReassignOwnedStmt:
2065 tag = "REASSIGN OWNED";
2072 case T_ConstraintsSetStmt:
2073 tag = "SET CONSTRAINTS";
2076 case T_CheckPointStmt:
2084 case T_CreateConversionStmt:
2085 tag = "CREATE CONVERSION";
2088 case T_CreateCastStmt:
2089 tag = "CREATE CAST";
2092 case T_DropCastStmt:
2096 case T_CreateOpClassStmt:
2097 tag = "CREATE OPERATOR CLASS";
2100 case T_CreateOpFamilyStmt:
2101 tag = "CREATE OPERATOR FAMILY";
2104 case T_AlterOpFamilyStmt:
2105 tag = "ALTER OPERATOR FAMILY";
2108 case T_RemoveOpClassStmt:
2109 tag = "DROP OPERATOR CLASS";
2112 case T_RemoveOpFamilyStmt:
2113 tag = "DROP OPERATOR FAMILY";
2116 case T_AlterTSDictionaryStmt:
2117 tag = "ALTER TEXT SEARCH DICTIONARY";
2120 case T_AlterTSConfigurationStmt:
2121 tag = "ALTER TEXT SEARCH CONFIGURATION";
2132 case T_DeallocateStmt:
2134 DeallocateStmt *stmt = (DeallocateStmt *) parsetree;
2136 if (stmt->name == NULL)
2137 tag = "DEALLOCATE ALL";
2143 /* already-planned queries */
2146 PlannedStmt *stmt = (PlannedStmt *) parsetree;
2148 switch (stmt->commandType)
2153 * We take a little extra care here so that the result
2154 * will be useful for complaints about read-only
2157 if (stmt->utilityStmt != NULL)
2159 Assert(IsA(stmt->utilityStmt, DeclareCursorStmt));
2160 tag = "DECLARE CURSOR";
2162 else if (stmt->intoClause != NULL)
2163 tag = "SELECT INTO";
2164 else if (stmt->rowMarks != NIL)
2166 /* not 100% but probably close enough */
2167 if (((PlanRowMark *) linitial(stmt->rowMarks))->markType == ROW_MARK_EXCLUSIVE)
2168 tag = "SELECT FOR UPDATE";
2170 tag = "SELECT FOR SHARE";
2185 elog(WARNING, "unrecognized commandType: %d",
2186 (int) stmt->commandType);
2193 /* parsed-and-rewritten-but-not-planned queries */
2196 Query *stmt = (Query *) parsetree;
2198 switch (stmt->commandType)
2203 * We take a little extra care here so that the result
2204 * will be useful for complaints about read-only
2207 if (stmt->utilityStmt != NULL)
2209 Assert(IsA(stmt->utilityStmt, DeclareCursorStmt));
2210 tag = "DECLARE CURSOR";
2212 else if (stmt->intoClause != NULL)
2213 tag = "SELECT INTO";
2214 else if (stmt->rowMarks != NIL)
2216 /* not 100% but probably close enough */
2217 if (((RowMarkClause *) linitial(stmt->rowMarks))->forUpdate)
2218 tag = "SELECT FOR UPDATE";
2220 tag = "SELECT FOR SHARE";
2235 tag = CreateCommandTag(stmt->utilityStmt);
2238 elog(WARNING, "unrecognized commandType: %d",
2239 (int) stmt->commandType);
2247 elog(WARNING, "unrecognized node type: %d",
2248 (int) nodeTag(parsetree));
2258 * GetCommandLogLevel
2259 * utility to get the minimum log_statement level for a command,
2260 * given either a raw (un-analyzed) parsetree or a planned query.
2262 * This must handle all command types, but since the vast majority
2263 * of 'em are utility commands, it seems sensible to keep it here.
2266 GetCommandLogLevel(Node *parsetree)
2270 switch (nodeTag(parsetree))
2272 /* raw plannable queries */
2280 if (((SelectStmt *) parsetree)->intoClause)
2281 lev = LOGSTMT_DDL; /* CREATE AS, SELECT INTO */
2286 /* utility statements --- same whether raw or cooked */
2287 case T_TransactionStmt:
2291 case T_DeclareCursorStmt:
2295 case T_ClosePortalStmt:
2303 case T_CreateSchemaStmt:
2308 case T_CreateForeignTableStmt:
2312 case T_CreateTableSpaceStmt:
2313 case T_DropTableSpaceStmt:
2314 case T_AlterTableSpaceOptionsStmt:
2318 case T_CreateExtensionStmt:
2319 case T_AlterExtensionStmt:
2320 case T_AlterExtensionContentsStmt:
2324 case T_CreateFdwStmt:
2325 case T_AlterFdwStmt:
2327 case T_CreateForeignServerStmt:
2328 case T_AlterForeignServerStmt:
2329 case T_DropForeignServerStmt:
2330 case T_CreateUserMappingStmt:
2331 case T_AlterUserMappingStmt:
2332 case T_DropUserMappingStmt:
2340 case T_TruncateStmt:
2348 case T_SecLabelStmt:
2353 if (((CopyStmt *) parsetree)->is_from)
2361 PrepareStmt *stmt = (PrepareStmt *) parsetree;
2363 /* Look through a PREPARE to the contained stmt */
2364 lev = GetCommandLogLevel(stmt->query);
2370 ExecuteStmt *stmt = (ExecuteStmt *) parsetree;
2371 PreparedStatement *ps;
2373 /* Look through an EXECUTE to the referenced stmt */
2374 ps = FetchPreparedStatement(stmt->name, false);
2376 lev = GetCommandLogLevel(ps->plansource->raw_parse_tree);
2382 case T_DeallocateStmt:
2390 case T_AlterObjectSchemaStmt:
2394 case T_AlterOwnerStmt:
2398 case T_AlterTableStmt:
2402 case T_AlterDomainStmt:
2410 case T_GrantRoleStmt:
2414 case T_AlterDefaultPrivilegesStmt:
2422 case T_CompositeTypeStmt:
2426 case T_CreateEnumStmt:
2430 case T_AlterEnumStmt:
2438 case T_CreateFunctionStmt:
2442 case T_AlterFunctionStmt:
2454 case T_CreateSeqStmt:
2458 case T_AlterSeqStmt:
2462 case T_RemoveFuncStmt:
2470 case T_CreatedbStmt:
2474 case T_AlterDatabaseStmt:
2478 case T_AlterDatabaseSetStmt:
2494 case T_UnlistenStmt:
2512 ExplainStmt *stmt = (ExplainStmt *) parsetree;
2513 bool analyze = false;
2516 /* Look through an EXPLAIN ANALYZE to the contained stmt */
2517 foreach(lc, stmt->options)
2519 DefElem *opt = (DefElem *) lfirst(lc);
2521 if (strcmp(opt->defname, "analyze") == 0)
2522 analyze = defGetBoolean(opt);
2523 /* don't "break", as explain.c will use the last value */
2526 return GetCommandLogLevel(stmt->query);
2528 /* Plain EXPLAIN isn't so interesting */
2533 case T_VariableSetStmt:
2537 case T_VariableShowStmt:
2545 case T_CreateTrigStmt:
2549 case T_DropPropertyStmt:
2553 case T_CreatePLangStmt:
2557 case T_DropPLangStmt:
2561 case T_CreateDomainStmt:
2565 case T_CreateRoleStmt:
2569 case T_AlterRoleStmt:
2573 case T_AlterRoleSetStmt:
2577 case T_DropRoleStmt:
2581 case T_DropOwnedStmt:
2585 case T_ReassignOwnedStmt:
2593 case T_ConstraintsSetStmt:
2597 case T_CheckPointStmt:
2602 lev = LOGSTMT_ALL; /* should this be DDL? */
2605 case T_CreateConversionStmt:
2609 case T_CreateCastStmt:
2613 case T_DropCastStmt:
2617 case T_CreateOpClassStmt:
2621 case T_CreateOpFamilyStmt:
2625 case T_AlterOpFamilyStmt:
2629 case T_RemoveOpClassStmt:
2633 case T_RemoveOpFamilyStmt:
2637 case T_AlterTSDictionaryStmt:
2641 case T_AlterTSConfigurationStmt:
2645 /* already-planned queries */
2648 PlannedStmt *stmt = (PlannedStmt *) parsetree;
2650 switch (stmt->commandType)
2653 if (stmt->intoClause != NULL)
2654 lev = LOGSTMT_DDL; /* CREATE AS, SELECT INTO */
2656 lev = LOGSTMT_ALL; /* SELECT or DECLARE CURSOR */
2666 elog(WARNING, "unrecognized commandType: %d",
2667 (int) stmt->commandType);
2674 /* parsed-and-rewritten-but-not-planned queries */
2677 Query *stmt = (Query *) parsetree;
2679 switch (stmt->commandType)
2682 if (stmt->intoClause != NULL)
2683 lev = LOGSTMT_DDL; /* CREATE AS, SELECT INTO */
2685 lev = LOGSTMT_ALL; /* SELECT or DECLARE CURSOR */
2695 lev = GetCommandLogLevel(stmt->utilityStmt);
2699 elog(WARNING, "unrecognized commandType: %d",
2700 (int) stmt->commandType);
2709 elog(WARNING, "unrecognized node type: %d",
2710 (int) nodeTag(parsetree));