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-2010, 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/lockcmds.h"
36 #include "commands/portalcmds.h"
37 #include "commands/prepare.h"
38 #include "commands/proclang.h"
39 #include "commands/schemacmds.h"
40 #include "commands/seclabel.h"
41 #include "commands/sequence.h"
42 #include "commands/tablecmds.h"
43 #include "commands/tablespace.h"
44 #include "commands/trigger.h"
45 #include "commands/typecmds.h"
46 #include "commands/user.h"
47 #include "commands/vacuum.h"
48 #include "commands/view.h"
49 #include "miscadmin.h"
50 #include "parser/parse_utilcmd.h"
51 #include "postmaster/bgwriter.h"
52 #include "rewrite/rewriteDefine.h"
53 #include "rewrite/rewriteRemove.h"
54 #include "storage/fd.h"
55 #include "tcop/pquery.h"
56 #include "tcop/utility.h"
57 #include "utils/acl.h"
58 #include "utils/guc.h"
59 #include "utils/syscache.h"
62 /* Hook for plugins to get control in ProcessUtility() */
63 ProcessUtility_hook_type ProcessUtility_hook = NULL;
67 * Verify user has ownership of specified relation, else ereport.
69 * If noCatalogs is true then we also deny access to system catalogs,
70 * except when allowSystemTableMods is true.
73 CheckRelationOwnership(RangeVar *rel, bool noCatalogs)
78 relOid = RangeVarGetRelid(rel, false);
79 tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relOid));
80 if (!HeapTupleIsValid(tuple)) /* should not happen */
81 elog(ERROR, "cache lookup failed for relation %u", relOid);
83 if (!pg_class_ownercheck(relOid, GetUserId()))
84 aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
89 if (!allowSystemTableMods &&
90 IsSystemClass((Form_pg_class) GETSTRUCT(tuple)))
92 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
93 errmsg("permission denied: \"%s\" is a system catalog",
97 ReleaseSysCache(tuple);
102 * CommandIsReadOnly: is an executable query read-only?
104 * This is a much stricter test than we apply for XactReadOnly mode;
105 * the query must be *in truth* read-only, because the caller wishes
106 * not to do CommandCounterIncrement for it.
108 * Note: currently no need to support Query nodes here
111 CommandIsReadOnly(Node *parsetree)
113 if (IsA(parsetree, PlannedStmt))
115 PlannedStmt *stmt = (PlannedStmt *) parsetree;
117 switch (stmt->commandType)
120 if (stmt->intoClause != NULL)
121 return false; /* SELECT INTO */
122 else if (stmt->rowMarks != NIL)
123 return false; /* SELECT FOR UPDATE/SHARE */
131 elog(WARNING, "unrecognized commandType: %d",
132 (int) stmt->commandType);
136 /* For now, treat all utility commands as read/write */
141 * check_xact_readonly: is a utility command read-only?
143 * Here we use the loose rules of XactReadOnly mode: no permanent effects
144 * on the database are allowed.
147 check_xact_readonly(Node *parsetree)
153 * Note: Commands that need to do more complicated checking are handled
154 * elsewhere, in particular COPY and plannable statements do their own
155 * checking. However they should all call PreventCommandIfReadOnly to
156 * actually throw the error.
159 switch (nodeTag(parsetree))
161 case T_AlterDatabaseStmt:
162 case T_AlterDatabaseSetStmt:
163 case T_AlterDomainStmt:
164 case T_AlterFunctionStmt:
165 case T_AlterRoleStmt:
166 case T_AlterRoleSetStmt:
167 case T_AlterObjectSchemaStmt:
168 case T_AlterOwnerStmt:
170 case T_AlterTableStmt:
174 case T_CreateCastStmt:
175 case T_CreateConversionStmt:
177 case T_CreateDomainStmt:
178 case T_CreateFunctionStmt:
179 case T_CreateRoleStmt:
181 case T_CreatePLangStmt:
182 case T_CreateOpClassStmt:
183 case T_CreateOpFamilyStmt:
184 case T_AlterOpFamilyStmt:
186 case T_CreateSchemaStmt:
187 case T_CreateSeqStmt:
189 case T_CreateTableSpaceStmt:
190 case T_CreateTrigStmt:
191 case T_CompositeTypeStmt:
192 case T_CreateEnumStmt:
193 case T_AlterEnumStmt:
198 case T_DropTableSpaceStmt:
199 case T_RemoveFuncStmt:
201 case T_DropPLangStmt:
202 case T_RemoveOpClassStmt:
203 case T_RemoveOpFamilyStmt:
204 case T_DropPropertyStmt:
206 case T_GrantRoleStmt:
207 case T_AlterDefaultPrivilegesStmt:
209 case T_DropOwnedStmt:
210 case T_ReassignOwnedStmt:
211 case T_AlterTSDictionaryStmt:
212 case T_AlterTSConfigurationStmt:
213 case T_CreateFdwStmt:
216 case T_CreateForeignServerStmt:
217 case T_AlterForeignServerStmt:
218 case T_DropForeignServerStmt:
219 case T_CreateUserMappingStmt:
220 case T_AlterUserMappingStmt:
221 case T_DropUserMappingStmt:
222 case T_AlterTableSpaceOptionsStmt:
224 PreventCommandIfReadOnly(CreateCommandTag(parsetree));
233 * PreventCommandIfReadOnly: throw error if XactReadOnly
235 * This is useful mainly to ensure consistency of the error message wording;
236 * most callers have checked XactReadOnly for themselves.
239 PreventCommandIfReadOnly(const char *cmdname)
243 (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
244 /* translator: %s is name of a SQL command, eg CREATE */
245 errmsg("cannot execute %s in a read-only transaction",
250 * PreventCommandDuringRecovery: throw error if RecoveryInProgress
252 * The majority of operations that are unsafe in a Hot Standby slave
253 * will be rejected by XactReadOnly tests. However there are a few
254 * commands that are allowed in "read-only" xacts but cannot be allowed
255 * in Hot Standby mode. Those commands should call this function.
258 PreventCommandDuringRecovery(const char *cmdname)
260 if (RecoveryInProgress())
262 (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
263 /* translator: %s is name of a SQL command, eg CREATE */
264 errmsg("cannot execute %s during recovery",
269 * CheckRestrictedOperation: throw error for hazardous command if we're
270 * inside a security restriction context.
272 * This is needed to protect session-local state for which there is not any
273 * better-defined protection mechanism, such as ownership.
276 CheckRestrictedOperation(const char *cmdname)
278 if (InSecurityRestrictedOperation())
280 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
281 /* translator: %s is name of a SQL command, eg PREPARE */
282 errmsg("cannot execute %s within security-restricted operation",
289 * general utility function invoker
291 * parsetree: the parse tree for the utility statement
292 * queryString: original source text of command
293 * params: parameters to use during execution
294 * isTopLevel: true if executing a "top level" (interactively issued) command
295 * dest: where to send results
296 * completionTag: points to a buffer of size COMPLETION_TAG_BUFSIZE
297 * in which to store a command completion status string.
299 * Notes: as of PG 8.4, caller MUST supply a queryString; it is not
300 * allowed anymore to pass NULL. (If you really don't have source text,
301 * you can pass a constant string, perhaps "(query not available)".)
303 * completionTag is only set nonempty if we want to return a nondefault status.
305 * completionTag may be NULL if caller doesn't want a status string.
308 ProcessUtility(Node *parsetree,
309 const char *queryString,
310 ParamListInfo params,
315 Assert(queryString != NULL); /* required as of 8.4 */
318 * We provide a function hook variable that lets loadable plugins get
319 * control when ProcessUtility is called. Such a plugin would normally
320 * call standard_ProcessUtility().
322 if (ProcessUtility_hook)
323 (*ProcessUtility_hook) (parsetree, queryString, params,
324 isTopLevel, dest, completionTag);
326 standard_ProcessUtility(parsetree, queryString, params,
327 isTopLevel, dest, completionTag);
331 standard_ProcessUtility(Node *parsetree,
332 const char *queryString,
333 ParamListInfo params,
338 check_xact_readonly(parsetree);
341 completionTag[0] = '\0';
343 switch (nodeTag(parsetree))
346 * ******************** transactions ********************
348 case T_TransactionStmt:
350 TransactionStmt *stmt = (TransactionStmt *) parsetree;
355 * START TRANSACTION, as defined by SQL99: Identical
356 * to BEGIN. Same code for both.
358 case TRANS_STMT_BEGIN:
359 case TRANS_STMT_START:
363 BeginTransactionBlock();
364 foreach(lc, stmt->options)
366 DefElem *item = (DefElem *) lfirst(lc);
368 if (strcmp(item->defname, "transaction_isolation") == 0)
369 SetPGVariable("transaction_isolation",
370 list_make1(item->arg),
372 else if (strcmp(item->defname, "transaction_read_only") == 0)
373 SetPGVariable("transaction_read_only",
374 list_make1(item->arg),
380 case TRANS_STMT_COMMIT:
381 if (!EndTransactionBlock())
383 /* report unsuccessful commit in completionTag */
385 strcpy(completionTag, "ROLLBACK");
389 case TRANS_STMT_PREPARE:
390 PreventCommandDuringRecovery("PREPARE TRANSACTION");
391 if (!PrepareTransactionBlock(stmt->gid))
393 /* report unsuccessful commit in completionTag */
395 strcpy(completionTag, "ROLLBACK");
399 case TRANS_STMT_COMMIT_PREPARED:
400 PreventTransactionChain(isTopLevel, "COMMIT PREPARED");
401 PreventCommandDuringRecovery("COMMIT PREPARED");
402 FinishPreparedTransaction(stmt->gid, true);
405 case TRANS_STMT_ROLLBACK_PREPARED:
406 PreventTransactionChain(isTopLevel, "ROLLBACK PREPARED");
407 PreventCommandDuringRecovery("ROLLBACK PREPARED");
408 FinishPreparedTransaction(stmt->gid, false);
411 case TRANS_STMT_ROLLBACK:
412 UserAbortTransactionBlock();
415 case TRANS_STMT_SAVEPOINT:
420 RequireTransactionChain(isTopLevel, "SAVEPOINT");
422 foreach(cell, stmt->options)
424 DefElem *elem = lfirst(cell);
426 if (strcmp(elem->defname, "savepoint_name") == 0)
427 name = strVal(elem->arg);
430 Assert(PointerIsValid(name));
432 DefineSavepoint(name);
436 case TRANS_STMT_RELEASE:
437 RequireTransactionChain(isTopLevel, "RELEASE SAVEPOINT");
438 ReleaseSavepoint(stmt->options);
441 case TRANS_STMT_ROLLBACK_TO:
442 RequireTransactionChain(isTopLevel, "ROLLBACK TO SAVEPOINT");
443 RollbackToSavepoint(stmt->options);
446 * CommitTransactionCommand is in charge of
447 * re-defining the savepoint again
455 * Portal (cursor) manipulation
457 * Note: DECLARE CURSOR is processed mostly as a SELECT, and
458 * therefore what we will get here is a PlannedStmt not a bare
463 PlannedStmt *stmt = (PlannedStmt *) parsetree;
465 if (stmt->utilityStmt == NULL ||
466 !IsA(stmt->utilityStmt, DeclareCursorStmt))
467 elog(ERROR, "non-DECLARE CURSOR PlannedStmt passed to ProcessUtility");
468 PerformCursorOpen(stmt, params, queryString, isTopLevel);
472 case T_ClosePortalStmt:
474 ClosePortalStmt *stmt = (ClosePortalStmt *) parsetree;
476 CheckRestrictedOperation("CLOSE");
477 PerformPortalClose(stmt->portalname);
482 PerformPortalFetch((FetchStmt *) parsetree, dest,
487 * relation and attribute manipulation
489 case T_CreateSchemaStmt:
490 CreateSchemaCommand((CreateSchemaStmt *) parsetree,
500 /* Run parse analysis ... */
501 stmts = transformCreateStmt((CreateStmt *) parsetree,
507 Node *stmt = (Node *) lfirst(l);
509 if (IsA(stmt, CreateStmt))
512 static char *validnsps[] = HEAP_RELOPT_NAMESPACES;
514 /* Create the table itself */
515 relOid = DefineRelation((CreateStmt *) stmt,
520 * If "IF NOT EXISTS" was specified and the relation
521 * already exists, do nothing further.
523 if (relOid == InvalidOid)
527 * Let AlterTableCreateToastTable decide if this one
528 * needs a secondary relation too.
530 CommandCounterIncrement();
532 /* parse and validate reloptions for the toast table */
533 toast_options = transformRelOptions((Datum) 0,
534 ((CreateStmt *) stmt)->options,
538 (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options,
541 AlterTableCreateToastTable(relOid, toast_options);
545 /* Recurse for anything else */
554 /* Need CCI between commands */
555 if (lnext(l) != NULL)
556 CommandCounterIncrement();
561 case T_CreateTableSpaceStmt:
562 PreventTransactionChain(isTopLevel, "CREATE TABLESPACE");
563 CreateTableSpace((CreateTableSpaceStmt *) parsetree);
566 case T_DropTableSpaceStmt:
567 PreventTransactionChain(isTopLevel, "DROP TABLESPACE");
568 DropTableSpace((DropTableSpaceStmt *) parsetree);
571 case T_AlterTableSpaceOptionsStmt:
572 AlterTableSpaceOptions((AlterTableSpaceOptionsStmt *) parsetree);
575 case T_CreateFdwStmt:
576 CreateForeignDataWrapper((CreateFdwStmt *) parsetree);
580 AlterForeignDataWrapper((AlterFdwStmt *) parsetree);
584 RemoveForeignDataWrapper((DropFdwStmt *) parsetree);
587 case T_CreateForeignServerStmt:
588 CreateForeignServer((CreateForeignServerStmt *) parsetree);
591 case T_AlterForeignServerStmt:
592 AlterForeignServer((AlterForeignServerStmt *) parsetree);
595 case T_DropForeignServerStmt:
596 RemoveForeignServer((DropForeignServerStmt *) parsetree);
599 case T_CreateUserMappingStmt:
600 CreateUserMapping((CreateUserMappingStmt *) parsetree);
603 case T_AlterUserMappingStmt:
604 AlterUserMapping((AlterUserMappingStmt *) parsetree);
607 case T_DropUserMappingStmt:
608 RemoveUserMapping((DropUserMappingStmt *) parsetree);
613 DropStmt *stmt = (DropStmt *) parsetree;
615 switch (stmt->removeType)
618 case OBJECT_SEQUENCE:
621 RemoveRelations(stmt);
629 case OBJECT_CONVERSION:
630 DropConversionsCommand(stmt);
637 case OBJECT_TSPARSER:
638 RemoveTSParsers(stmt);
641 case OBJECT_TSDICTIONARY:
642 RemoveTSDictionaries(stmt);
645 case OBJECT_TSTEMPLATE:
646 RemoveTSTemplates(stmt);
649 case OBJECT_TSCONFIGURATION:
650 RemoveTSConfigurations(stmt);
654 elog(ERROR, "unrecognized drop object type: %d",
655 (int) stmt->removeType);
662 ExecuteTruncate((TruncateStmt *) parsetree);
666 CommentObject((CommentStmt *) parsetree);
670 ExecSecLabelStmt((SecLabelStmt *) parsetree);
677 processed = DoCopy((CopyStmt *) parsetree, queryString);
679 snprintf(completionTag, COMPLETION_TAG_BUFSIZE,
680 "COPY " UINT64_FORMAT, processed);
685 CheckRestrictedOperation("PREPARE");
686 PrepareQuery((PrepareStmt *) parsetree, queryString);
690 ExecuteQuery((ExecuteStmt *) parsetree, queryString, params,
691 dest, completionTag);
694 case T_DeallocateStmt:
695 CheckRestrictedOperation("DEALLOCATE");
696 DeallocateQuery((DeallocateStmt *) parsetree);
703 ExecRenameStmt((RenameStmt *) parsetree);
706 case T_AlterObjectSchemaStmt:
707 ExecAlterObjectSchemaStmt((AlterObjectSchemaStmt *) parsetree);
710 case T_AlterOwnerStmt:
711 ExecAlterOwnerStmt((AlterOwnerStmt *) parsetree);
714 case T_AlterTableStmt:
719 /* Run parse analysis ... */
720 stmts = transformAlterTableStmt((AlterTableStmt *) parsetree,
726 Node *stmt = (Node *) lfirst(l);
728 if (IsA(stmt, AlterTableStmt))
730 /* Do the table alteration proper */
731 AlterTable((AlterTableStmt *) stmt);
735 /* Recurse for anything else */
744 /* Need CCI between commands */
745 if (lnext(l) != NULL)
746 CommandCounterIncrement();
751 case T_AlterDomainStmt:
753 AlterDomainStmt *stmt = (AlterDomainStmt *) parsetree;
756 * Some or all of these functions are recursive to cover
757 * inherited things, so permission checks are done there.
759 switch (stmt->subtype)
761 case 'T': /* ALTER DOMAIN DEFAULT */
764 * Recursively alter column default for table and, if
765 * requested, for descendants
767 AlterDomainDefault(stmt->typeName,
770 case 'N': /* ALTER DOMAIN DROP NOT NULL */
771 AlterDomainNotNull(stmt->typeName,
774 case 'O': /* ALTER DOMAIN SET NOT NULL */
775 AlterDomainNotNull(stmt->typeName,
778 case 'C': /* ADD CONSTRAINT */
779 AlterDomainAddConstraint(stmt->typeName,
782 case 'X': /* DROP CONSTRAINT */
783 AlterDomainDropConstraint(stmt->typeName,
788 elog(ERROR, "unrecognized alter domain type: %d",
789 (int) stmt->subtype);
796 ExecuteGrantStmt((GrantStmt *) parsetree);
799 case T_GrantRoleStmt:
800 GrantRole((GrantRoleStmt *) parsetree);
803 case T_AlterDefaultPrivilegesStmt:
804 ExecAlterDefaultPrivilegesStmt((AlterDefaultPrivilegesStmt *) parsetree);
808 * **************** object creation / destruction *****************
812 DefineStmt *stmt = (DefineStmt *) parsetree;
816 case OBJECT_AGGREGATE:
817 DefineAggregate(stmt->defnames, stmt->args,
818 stmt->oldstyle, stmt->definition);
820 case OBJECT_OPERATOR:
821 Assert(stmt->args == NIL);
822 DefineOperator(stmt->defnames, stmt->definition);
825 Assert(stmt->args == NIL);
826 DefineType(stmt->defnames, stmt->definition);
828 case OBJECT_TSPARSER:
829 Assert(stmt->args == NIL);
830 DefineTSParser(stmt->defnames, stmt->definition);
832 case OBJECT_TSDICTIONARY:
833 Assert(stmt->args == NIL);
834 DefineTSDictionary(stmt->defnames, stmt->definition);
836 case OBJECT_TSTEMPLATE:
837 Assert(stmt->args == NIL);
838 DefineTSTemplate(stmt->defnames, stmt->definition);
840 case OBJECT_TSCONFIGURATION:
841 Assert(stmt->args == NIL);
842 DefineTSConfiguration(stmt->defnames, stmt->definition);
845 elog(ERROR, "unrecognized define stmt type: %d",
852 case T_CompositeTypeStmt: /* CREATE TYPE (composite) */
854 CompositeTypeStmt *stmt = (CompositeTypeStmt *) parsetree;
856 DefineCompositeType(stmt->typevar, stmt->coldeflist);
860 case T_CreateEnumStmt: /* CREATE TYPE (enum) */
861 DefineEnum((CreateEnumStmt *) parsetree);
864 case T_AlterEnumStmt: /* ALTER TYPE (enum) */
866 * We disallow this in transaction blocks, because we can't cope
867 * with enum OID values getting into indexes and then having their
868 * defining pg_enum entries go away.
870 PreventTransactionChain(isTopLevel, "ALTER TYPE ... ADD");
871 AlterEnum((AlterEnumStmt *) parsetree);
874 case T_ViewStmt: /* CREATE VIEW */
875 DefineView((ViewStmt *) parsetree, queryString);
878 case T_CreateFunctionStmt: /* CREATE FUNCTION */
879 CreateFunction((CreateFunctionStmt *) parsetree, queryString);
882 case T_AlterFunctionStmt: /* ALTER FUNCTION */
883 AlterFunction((AlterFunctionStmt *) parsetree);
886 case T_IndexStmt: /* CREATE INDEX */
888 IndexStmt *stmt = (IndexStmt *) parsetree;
890 if (stmt->concurrent)
891 PreventTransactionChain(isTopLevel,
892 "CREATE INDEX CONCURRENTLY");
894 CheckRelationOwnership(stmt->relation, true);
896 /* Run parse analysis ... */
897 stmt = transformIndexStmt(stmt, queryString);
900 DefineIndex(stmt->relation, /* relation */
901 stmt->idxname, /* index name */
902 InvalidOid, /* no predefined OID */
903 stmt->accessMethod, /* am name */
905 stmt->indexParams, /* parameters */
906 (Expr *) stmt->whereClause,
908 stmt->excludeOpNames,
914 false, /* is_alter_table */
915 true, /* check_rights */
916 false, /* skip_build */
918 stmt->concurrent); /* concurrent */
922 case T_RuleStmt: /* CREATE RULE */
923 DefineRule((RuleStmt *) parsetree, queryString);
926 case T_CreateSeqStmt:
927 DefineSequence((CreateSeqStmt *) parsetree);
931 AlterSequence((AlterSeqStmt *) parsetree);
934 case T_RemoveFuncStmt:
936 RemoveFuncStmt *stmt = (RemoveFuncStmt *) parsetree;
940 case OBJECT_FUNCTION:
941 RemoveFunction(stmt);
943 case OBJECT_AGGREGATE:
944 RemoveAggregate(stmt);
946 case OBJECT_OPERATOR:
947 RemoveOperator(stmt);
950 elog(ERROR, "unrecognized object type: %d",
958 ExecuteDoStmt((DoStmt *) parsetree);
962 PreventTransactionChain(isTopLevel, "CREATE DATABASE");
963 createdb((CreatedbStmt *) parsetree);
966 case T_AlterDatabaseStmt:
967 AlterDatabase((AlterDatabaseStmt *) parsetree, isTopLevel);
970 case T_AlterDatabaseSetStmt:
971 AlterDatabaseSet((AlterDatabaseSetStmt *) parsetree);
976 DropdbStmt *stmt = (DropdbStmt *) parsetree;
978 PreventTransactionChain(isTopLevel, "DROP DATABASE");
979 dropdb(stmt->dbname, stmt->missing_ok);
983 /* Query-level asynchronous notification */
986 NotifyStmt *stmt = (NotifyStmt *) parsetree;
988 PreventCommandDuringRecovery("NOTIFY");
989 Async_Notify(stmt->conditionname, stmt->payload);
995 ListenStmt *stmt = (ListenStmt *) parsetree;
997 PreventCommandDuringRecovery("LISTEN");
998 CheckRestrictedOperation("LISTEN");
999 Async_Listen(stmt->conditionname);
1003 case T_UnlistenStmt:
1005 UnlistenStmt *stmt = (UnlistenStmt *) parsetree;
1007 PreventCommandDuringRecovery("UNLISTEN");
1008 CheckRestrictedOperation("UNLISTEN");
1009 if (stmt->conditionname)
1010 Async_Unlisten(stmt->conditionname);
1012 Async_UnlistenAll();
1018 LoadStmt *stmt = (LoadStmt *) parsetree;
1020 closeAllVfds(); /* probably not necessary... */
1021 /* Allowed names are restricted if you're not superuser */
1022 load_file(stmt->filename, !superuser());
1027 /* we choose to allow this during "read only" transactions */
1028 PreventCommandDuringRecovery("CLUSTER");
1029 cluster((ClusterStmt *) parsetree, isTopLevel);
1033 /* we choose to allow this during "read only" transactions */
1034 PreventCommandDuringRecovery("VACUUM");
1035 vacuum((VacuumStmt *) parsetree, InvalidOid, true, NULL, false,
1040 ExplainQuery((ExplainStmt *) parsetree, queryString, params, dest);
1043 case T_VariableSetStmt:
1044 ExecSetVariableStmt((VariableSetStmt *) parsetree);
1047 case T_VariableShowStmt:
1049 VariableShowStmt *n = (VariableShowStmt *) parsetree;
1051 GetPGVariable(n->name, dest);
1056 /* should we allow DISCARD PLANS? */
1057 CheckRestrictedOperation("DISCARD");
1058 DiscardCommand((DiscardStmt *) parsetree, isTopLevel);
1061 case T_CreateTrigStmt:
1062 (void) CreateTrigger((CreateTrigStmt *) parsetree, queryString,
1063 InvalidOid, InvalidOid, false);
1066 case T_DropPropertyStmt:
1068 DropPropertyStmt *stmt = (DropPropertyStmt *) parsetree;
1071 relId = RangeVarGetRelid(stmt->relation, false);
1073 switch (stmt->removeType)
1076 /* RemoveRewriteRule checks permissions */
1077 RemoveRewriteRule(relId, stmt->property,
1078 stmt->behavior, stmt->missing_ok);
1080 case OBJECT_TRIGGER:
1081 /* DropTrigger checks permissions */
1082 DropTrigger(relId, stmt->property,
1083 stmt->behavior, stmt->missing_ok);
1086 elog(ERROR, "unrecognized object type: %d",
1087 (int) stmt->removeType);
1093 case T_CreatePLangStmt:
1094 CreateProceduralLanguage((CreatePLangStmt *) parsetree);
1097 case T_DropPLangStmt:
1098 DropProceduralLanguage((DropPLangStmt *) parsetree);
1102 * ******************************** DOMAIN statements ****
1104 case T_CreateDomainStmt:
1105 DefineDomain((CreateDomainStmt *) parsetree);
1109 * ******************************** ROLE statements ****
1111 case T_CreateRoleStmt:
1112 CreateRole((CreateRoleStmt *) parsetree);
1115 case T_AlterRoleStmt:
1116 AlterRole((AlterRoleStmt *) parsetree);
1119 case T_AlterRoleSetStmt:
1120 AlterRoleSet((AlterRoleSetStmt *) parsetree);
1123 case T_DropRoleStmt:
1124 DropRole((DropRoleStmt *) parsetree);
1127 case T_DropOwnedStmt:
1128 DropOwnedObjects((DropOwnedStmt *) parsetree);
1131 case T_ReassignOwnedStmt:
1132 ReassignOwnedObjects((ReassignOwnedStmt *) parsetree);
1138 * Since the lock would just get dropped immediately, LOCK TABLE
1139 * outside a transaction block is presumed to be user error.
1141 RequireTransactionChain(isTopLevel, "LOCK TABLE");
1142 LockTableCommand((LockStmt *) parsetree);
1145 case T_ConstraintsSetStmt:
1146 AfterTriggerSetState((ConstraintsSetStmt *) parsetree);
1149 case T_CheckPointStmt:
1152 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1153 errmsg("must be superuser to do CHECKPOINT")));
1156 * You might think we should have a PreventCommandDuringRecovery()
1157 * here, but we interpret a CHECKPOINT command during recovery as
1158 * a request for a restartpoint instead. We allow this since it
1159 * can be a useful way of reducing switchover time when using
1160 * various forms of replication.
1162 RequestCheckpoint(CHECKPOINT_IMMEDIATE | CHECKPOINT_WAIT |
1163 (RecoveryInProgress() ? 0 : CHECKPOINT_FORCE));
1168 ReindexStmt *stmt = (ReindexStmt *) parsetree;
1170 /* we choose to allow this during "read only" transactions */
1171 PreventCommandDuringRecovery("REINDEX");
1175 ReindexIndex(stmt->relation);
1178 ReindexTable(stmt->relation);
1180 case OBJECT_DATABASE:
1183 * This cannot run inside a user transaction block; if
1184 * we were inside a transaction, then its commit- and
1185 * start-transaction-command calls would not have the
1188 PreventTransactionChain(isTopLevel,
1189 "REINDEX DATABASE");
1190 ReindexDatabase(stmt->name,
1191 stmt->do_system, stmt->do_user);
1194 elog(ERROR, "unrecognized object type: %d",
1202 case T_CreateConversionStmt:
1203 CreateConversionCommand((CreateConversionStmt *) parsetree);
1206 case T_CreateCastStmt:
1207 CreateCast((CreateCastStmt *) parsetree);
1210 case T_DropCastStmt:
1211 DropCast((DropCastStmt *) parsetree);
1214 case T_CreateOpClassStmt:
1215 DefineOpClass((CreateOpClassStmt *) parsetree);
1218 case T_CreateOpFamilyStmt:
1219 DefineOpFamily((CreateOpFamilyStmt *) parsetree);
1222 case T_AlterOpFamilyStmt:
1223 AlterOpFamily((AlterOpFamilyStmt *) parsetree);
1226 case T_RemoveOpClassStmt:
1227 RemoveOpClass((RemoveOpClassStmt *) parsetree);
1230 case T_RemoveOpFamilyStmt:
1231 RemoveOpFamily((RemoveOpFamilyStmt *) parsetree);
1234 case T_AlterTSDictionaryStmt:
1235 AlterTSDictionary((AlterTSDictionaryStmt *) parsetree);
1238 case T_AlterTSConfigurationStmt:
1239 AlterTSConfiguration((AlterTSConfigurationStmt *) parsetree);
1243 elog(ERROR, "unrecognized node type: %d",
1244 (int) nodeTag(parsetree));
1250 * UtilityReturnsTuples
1251 * Return "true" if this utility statement will send output to the
1254 * Generally, there should be a case here for each case in ProcessUtility
1255 * where "dest" is passed on.
1258 UtilityReturnsTuples(Node *parsetree)
1260 switch (nodeTag(parsetree))
1264 FetchStmt *stmt = (FetchStmt *) parsetree;
1269 portal = GetPortalByName(stmt->portalname);
1270 if (!PortalIsValid(portal))
1271 return false; /* not our business to raise error */
1272 return portal->tupDesc ? true : false;
1277 ExecuteStmt *stmt = (ExecuteStmt *) parsetree;
1278 PreparedStatement *entry;
1282 entry = FetchPreparedStatement(stmt->name, false);
1284 return false; /* not our business to raise error */
1285 if (entry->plansource->resultDesc)
1293 case T_VariableShowStmt:
1302 * UtilityTupleDescriptor
1303 * Fetch the actual output tuple descriptor for a utility statement
1304 * for which UtilityReturnsTuples() previously returned "true".
1306 * The returned descriptor is created in (or copied into) the current memory
1310 UtilityTupleDescriptor(Node *parsetree)
1312 switch (nodeTag(parsetree))
1316 FetchStmt *stmt = (FetchStmt *) parsetree;
1321 portal = GetPortalByName(stmt->portalname);
1322 if (!PortalIsValid(portal))
1323 return NULL; /* not our business to raise error */
1324 return CreateTupleDescCopy(portal->tupDesc);
1329 ExecuteStmt *stmt = (ExecuteStmt *) parsetree;
1330 PreparedStatement *entry;
1334 entry = FetchPreparedStatement(stmt->name, false);
1336 return NULL; /* not our business to raise error */
1337 return FetchPreparedStatementResultDesc(entry);
1341 return ExplainResultDesc((ExplainStmt *) parsetree);
1343 case T_VariableShowStmt:
1345 VariableShowStmt *n = (VariableShowStmt *) parsetree;
1347 return GetPGVariableResultDesc(n->name);
1357 * QueryReturnsTuples
1358 * Return "true" if this Query will send output to the destination.
1362 QueryReturnsTuples(Query *parsetree)
1364 switch (parsetree->commandType)
1367 /* returns tuples ... unless it's DECLARE CURSOR or SELECT INTO */
1368 if (parsetree->utilityStmt == NULL &&
1369 parsetree->intoClause == NULL)
1375 /* the forms with RETURNING return tuples */
1376 if (parsetree->returningList)
1380 return UtilityReturnsTuples(parsetree->utilityStmt);
1383 /* probably shouldn't get here */
1386 return false; /* default */
1393 * utility to get a string representation of the command operation,
1394 * given either a raw (un-analyzed) parsetree or a planned query.
1396 * This must handle all command types, but since the vast majority
1397 * of 'em are utility commands, it seems sensible to keep it here.
1399 * NB: all result strings must be shorter than COMPLETION_TAG_BUFSIZE.
1400 * Also, the result must point at a true constant (permanent storage).
1403 CreateCommandTag(Node *parsetree)
1407 switch (nodeTag(parsetree))
1409 /* raw plannable queries */
1426 /* utility statements --- same whether raw or cooked */
1427 case T_TransactionStmt:
1429 TransactionStmt *stmt = (TransactionStmt *) parsetree;
1433 case TRANS_STMT_BEGIN:
1437 case TRANS_STMT_START:
1438 tag = "START TRANSACTION";
1441 case TRANS_STMT_COMMIT:
1445 case TRANS_STMT_ROLLBACK:
1446 case TRANS_STMT_ROLLBACK_TO:
1450 case TRANS_STMT_SAVEPOINT:
1454 case TRANS_STMT_RELEASE:
1458 case TRANS_STMT_PREPARE:
1459 tag = "PREPARE TRANSACTION";
1462 case TRANS_STMT_COMMIT_PREPARED:
1463 tag = "COMMIT PREPARED";
1466 case TRANS_STMT_ROLLBACK_PREPARED:
1467 tag = "ROLLBACK PREPARED";
1477 case T_DeclareCursorStmt:
1478 tag = "DECLARE CURSOR";
1481 case T_ClosePortalStmt:
1483 ClosePortalStmt *stmt = (ClosePortalStmt *) parsetree;
1485 if (stmt->portalname == NULL)
1486 tag = "CLOSE CURSOR ALL";
1488 tag = "CLOSE CURSOR";
1494 FetchStmt *stmt = (FetchStmt *) parsetree;
1496 tag = (stmt->ismove) ? "MOVE" : "FETCH";
1500 case T_CreateDomainStmt:
1501 tag = "CREATE DOMAIN";
1504 case T_CreateSchemaStmt:
1505 tag = "CREATE SCHEMA";
1509 tag = "CREATE TABLE";
1512 case T_CreateTableSpaceStmt:
1513 tag = "CREATE TABLESPACE";
1516 case T_DropTableSpaceStmt:
1517 tag = "DROP TABLESPACE";
1520 case T_AlterTableSpaceOptionsStmt:
1521 tag = "ALTER TABLESPACE";
1524 case T_CreateFdwStmt:
1525 tag = "CREATE FOREIGN DATA WRAPPER";
1528 case T_AlterFdwStmt:
1529 tag = "ALTER FOREIGN DATA WRAPPER";
1533 tag = "DROP FOREIGN DATA WRAPPER";
1536 case T_CreateForeignServerStmt:
1537 tag = "CREATE SERVER";
1540 case T_AlterForeignServerStmt:
1541 tag = "ALTER SERVER";
1544 case T_DropForeignServerStmt:
1545 tag = "DROP SERVER";
1548 case T_CreateUserMappingStmt:
1549 tag = "CREATE USER MAPPING";
1552 case T_AlterUserMappingStmt:
1553 tag = "ALTER USER MAPPING";
1556 case T_DropUserMappingStmt:
1557 tag = "DROP USER MAPPING";
1561 switch (((DropStmt *) parsetree)->removeType)
1566 case OBJECT_SEQUENCE:
1567 tag = "DROP SEQUENCE";
1579 tag = "DROP DOMAIN";
1581 case OBJECT_CONVERSION:
1582 tag = "DROP CONVERSION";
1585 tag = "DROP SCHEMA";
1587 case OBJECT_TSPARSER:
1588 tag = "DROP TEXT SEARCH PARSER";
1590 case OBJECT_TSDICTIONARY:
1591 tag = "DROP TEXT SEARCH DICTIONARY";
1593 case OBJECT_TSTEMPLATE:
1594 tag = "DROP TEXT SEARCH TEMPLATE";
1596 case OBJECT_TSCONFIGURATION:
1597 tag = "DROP TEXT SEARCH CONFIGURATION";
1604 case T_TruncateStmt:
1605 tag = "TRUNCATE TABLE";
1612 case T_SecLabelStmt:
1613 tag = "SECURITY LABEL";
1621 switch (((RenameStmt *) parsetree)->renameType)
1623 case OBJECT_AGGREGATE:
1624 tag = "ALTER AGGREGATE";
1626 case OBJECT_CONVERSION:
1627 tag = "ALTER CONVERSION";
1629 case OBJECT_DATABASE:
1630 tag = "ALTER DATABASE";
1632 case OBJECT_FUNCTION:
1633 tag = "ALTER FUNCTION";
1636 tag = "ALTER INDEX";
1638 case OBJECT_LANGUAGE:
1639 tag = "ALTER LANGUAGE";
1641 case OBJECT_OPCLASS:
1642 tag = "ALTER OPERATOR CLASS";
1644 case OBJECT_OPFAMILY:
1645 tag = "ALTER OPERATOR FAMILY";
1651 tag = "ALTER SCHEMA";
1653 case OBJECT_SEQUENCE:
1654 tag = "ALTER SEQUENCE";
1658 tag = "ALTER TABLE";
1660 case OBJECT_TABLESPACE:
1661 tag = "ALTER TABLESPACE";
1663 case OBJECT_TRIGGER:
1664 tag = "ALTER TRIGGER";
1669 case OBJECT_TSPARSER:
1670 tag = "ALTER TEXT SEARCH PARSER";
1672 case OBJECT_TSDICTIONARY:
1673 tag = "ALTER TEXT SEARCH DICTIONARY";
1675 case OBJECT_TSTEMPLATE:
1676 tag = "ALTER TEXT SEARCH TEMPLATE";
1678 case OBJECT_TSCONFIGURATION:
1679 tag = "ALTER TEXT SEARCH CONFIGURATION";
1681 case OBJECT_ATTRIBUTE:
1691 case T_AlterObjectSchemaStmt:
1692 switch (((AlterObjectSchemaStmt *) parsetree)->objectType)
1694 case OBJECT_AGGREGATE:
1695 tag = "ALTER AGGREGATE";
1697 case OBJECT_CONVERSION:
1698 tag = "ALTER CONVERSION";
1701 tag = "ALTER DOMAIN";
1703 case OBJECT_OPERATOR:
1704 tag = "ALTER OPERATOR";
1706 case OBJECT_OPCLASS:
1707 tag = "ALTER OPERATOR CLASS";
1709 case OBJECT_OPFAMILY:
1710 tag = "ALTER OPERATOR FAMILY";
1712 case OBJECT_FUNCTION:
1713 tag = "ALTER FUNCTION";
1715 case OBJECT_SEQUENCE:
1716 tag = "ALTER SEQUENCE";
1719 tag = "ALTER TABLE";
1724 case OBJECT_TSPARSER:
1725 tag = "ALTER TEXT SEARCH PARSER";
1727 case OBJECT_TSDICTIONARY:
1728 tag = "ALTER TEXT SEARCH DICTIONARY";
1730 case OBJECT_TSTEMPLATE:
1731 tag = "ALTER TEXT SEARCH TEMPLATE";
1733 case OBJECT_TSCONFIGURATION:
1734 tag = "ALTER TEXT SEARCH CONFIGURATION";
1745 case T_AlterOwnerStmt:
1746 switch (((AlterOwnerStmt *) parsetree)->objectType)
1748 case OBJECT_AGGREGATE:
1749 tag = "ALTER AGGREGATE";
1751 case OBJECT_CONVERSION:
1752 tag = "ALTER CONVERSION";
1754 case OBJECT_DATABASE:
1755 tag = "ALTER DATABASE";
1758 tag = "ALTER DOMAIN";
1760 case OBJECT_FUNCTION:
1761 tag = "ALTER FUNCTION";
1763 case OBJECT_LANGUAGE:
1764 tag = "ALTER LANGUAGE";
1766 case OBJECT_LARGEOBJECT:
1767 tag = "ALTER LARGE OBJECT";
1769 case OBJECT_OPERATOR:
1770 tag = "ALTER OPERATOR";
1772 case OBJECT_OPCLASS:
1773 tag = "ALTER OPERATOR CLASS";
1775 case OBJECT_OPFAMILY:
1776 tag = "ALTER OPERATOR FAMILY";
1779 tag = "ALTER SCHEMA";
1781 case OBJECT_TABLESPACE:
1782 tag = "ALTER TABLESPACE";
1787 case OBJECT_TSCONFIGURATION:
1788 tag = "ALTER TEXT SEARCH CONFIGURATION";
1790 case OBJECT_TSDICTIONARY:
1791 tag = "ALTER TEXT SEARCH DICTIONARY";
1794 tag = "ALTER FOREIGN DATA WRAPPER";
1796 case OBJECT_FOREIGN_SERVER:
1797 tag = "ALTER SERVER";
1805 case T_AlterTableStmt:
1806 switch (((AlterTableStmt *) parsetree)->relkind)
1809 tag = "ALTER TABLE";
1812 tag = "ALTER INDEX";
1814 case OBJECT_SEQUENCE:
1815 tag = "ALTER SEQUENCE";
1829 case T_AlterDomainStmt:
1830 tag = "ALTER DOMAIN";
1833 case T_AlterFunctionStmt:
1834 tag = "ALTER FUNCTION";
1839 GrantStmt *stmt = (GrantStmt *) parsetree;
1841 tag = (stmt->is_grant) ? "GRANT" : "REVOKE";
1845 case T_GrantRoleStmt:
1847 GrantRoleStmt *stmt = (GrantRoleStmt *) parsetree;
1849 tag = (stmt->is_grant) ? "GRANT ROLE" : "REVOKE ROLE";
1853 case T_AlterDefaultPrivilegesStmt:
1854 tag = "ALTER DEFAULT PRIVILEGES";
1858 switch (((DefineStmt *) parsetree)->kind)
1860 case OBJECT_AGGREGATE:
1861 tag = "CREATE AGGREGATE";
1863 case OBJECT_OPERATOR:
1864 tag = "CREATE OPERATOR";
1867 tag = "CREATE TYPE";
1869 case OBJECT_TSPARSER:
1870 tag = "CREATE TEXT SEARCH PARSER";
1872 case OBJECT_TSDICTIONARY:
1873 tag = "CREATE TEXT SEARCH DICTIONARY";
1875 case OBJECT_TSTEMPLATE:
1876 tag = "CREATE TEXT SEARCH TEMPLATE";
1878 case OBJECT_TSCONFIGURATION:
1879 tag = "CREATE TEXT SEARCH CONFIGURATION";
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:
2322 case T_CreateTableSpaceStmt:
2326 case T_DropTableSpaceStmt:
2330 case T_AlterTableSpaceOptionsStmt:
2334 case T_CreateFdwStmt:
2335 case T_AlterFdwStmt:
2337 case T_CreateForeignServerStmt:
2338 case T_AlterForeignServerStmt:
2339 case T_DropForeignServerStmt:
2340 case T_CreateUserMappingStmt:
2341 case T_AlterUserMappingStmt:
2342 case T_DropUserMappingStmt:
2350 case T_TruncateStmt:
2358 case T_SecLabelStmt:
2363 if (((CopyStmt *) parsetree)->is_from)
2371 PrepareStmt *stmt = (PrepareStmt *) parsetree;
2373 /* Look through a PREPARE to the contained stmt */
2374 lev = GetCommandLogLevel(stmt->query);
2380 ExecuteStmt *stmt = (ExecuteStmt *) parsetree;
2381 PreparedStatement *ps;
2383 /* Look through an EXECUTE to the referenced stmt */
2384 ps = FetchPreparedStatement(stmt->name, false);
2386 lev = GetCommandLogLevel(ps->plansource->raw_parse_tree);
2392 case T_DeallocateStmt:
2400 case T_AlterObjectSchemaStmt:
2404 case T_AlterOwnerStmt:
2408 case T_AlterTableStmt:
2412 case T_AlterDomainStmt:
2420 case T_GrantRoleStmt:
2424 case T_AlterDefaultPrivilegesStmt:
2432 case T_CompositeTypeStmt:
2436 case T_CreateEnumStmt:
2440 case T_AlterEnumStmt:
2448 case T_CreateFunctionStmt:
2452 case T_AlterFunctionStmt:
2464 case T_CreateSeqStmt:
2468 case T_AlterSeqStmt:
2472 case T_RemoveFuncStmt:
2480 case T_CreatedbStmt:
2484 case T_AlterDatabaseStmt:
2488 case T_AlterDatabaseSetStmt:
2504 case T_UnlistenStmt:
2522 ExplainStmt *stmt = (ExplainStmt *) parsetree;
2523 bool analyze = false;
2526 /* Look through an EXPLAIN ANALYZE to the contained stmt */
2527 foreach(lc, stmt->options)
2529 DefElem *opt = (DefElem *) lfirst(lc);
2531 if (strcmp(opt->defname, "analyze") == 0)
2532 analyze = defGetBoolean(opt);
2533 /* don't "break", as explain.c will use the last value */
2536 return GetCommandLogLevel(stmt->query);
2538 /* Plain EXPLAIN isn't so interesting */
2543 case T_VariableSetStmt:
2547 case T_VariableShowStmt:
2555 case T_CreateTrigStmt:
2559 case T_DropPropertyStmt:
2563 case T_CreatePLangStmt:
2567 case T_DropPLangStmt:
2571 case T_CreateDomainStmt:
2575 case T_CreateRoleStmt:
2579 case T_AlterRoleStmt:
2583 case T_AlterRoleSetStmt:
2587 case T_DropRoleStmt:
2591 case T_DropOwnedStmt:
2595 case T_ReassignOwnedStmt:
2603 case T_ConstraintsSetStmt:
2607 case T_CheckPointStmt:
2612 lev = LOGSTMT_ALL; /* should this be DDL? */
2615 case T_CreateConversionStmt:
2619 case T_CreateCastStmt:
2623 case T_DropCastStmt:
2627 case T_CreateOpClassStmt:
2631 case T_CreateOpFamilyStmt:
2635 case T_AlterOpFamilyStmt:
2639 case T_RemoveOpClassStmt:
2643 case T_RemoveOpFamilyStmt:
2647 case T_AlterTSDictionaryStmt:
2651 case T_AlterTSConfigurationStmt:
2655 /* already-planned queries */
2658 PlannedStmt *stmt = (PlannedStmt *) parsetree;
2660 switch (stmt->commandType)
2663 if (stmt->intoClause != NULL)
2664 lev = LOGSTMT_DDL; /* CREATE AS, SELECT INTO */
2666 lev = LOGSTMT_ALL; /* SELECT or DECLARE CURSOR */
2676 elog(WARNING, "unrecognized commandType: %d",
2677 (int) stmt->commandType);
2684 /* parsed-and-rewritten-but-not-planned queries */
2687 Query *stmt = (Query *) parsetree;
2689 switch (stmt->commandType)
2692 if (stmt->intoClause != NULL)
2693 lev = LOGSTMT_DDL; /* CREATE AS, SELECT INTO */
2695 lev = LOGSTMT_ALL; /* SELECT or DECLARE CURSOR */
2705 lev = GetCommandLogLevel(stmt->utilityStmt);
2709 elog(WARNING, "unrecognized commandType: %d",
2710 (int) stmt->commandType);
2719 elog(WARNING, "unrecognized node type: %d",
2720 (int) nodeTag(parsetree));