1 /*-------------------------------------------------------------------------
4 * Contains functions which control the execution of the POSTGRES utility
5 * commands. At one time acted as an interface between the Lisp and C
8 * Portions Copyright (c) 1996-2011, PostgreSQL Global Development Group
9 * Portions Copyright (c) 1994, Regents of the University of California
13 * src/backend/tcop/utility.c
15 *-------------------------------------------------------------------------
19 #include "access/reloptions.h"
20 #include "access/twophase.h"
21 #include "access/xact.h"
22 #include "catalog/catalog.h"
23 #include "catalog/namespace.h"
24 #include "catalog/toasting.h"
25 #include "commands/alter.h"
26 #include "commands/async.h"
27 #include "commands/cluster.h"
28 #include "commands/comment.h"
29 #include "commands/collationcmds.h"
30 #include "commands/conversioncmds.h"
31 #include "commands/copy.h"
32 #include "commands/dbcommands.h"
33 #include "commands/defrem.h"
34 #include "commands/discard.h"
35 #include "commands/explain.h"
36 #include "commands/extension.h"
37 #include "commands/lockcmds.h"
38 #include "commands/portalcmds.h"
39 #include "commands/prepare.h"
40 #include "commands/proclang.h"
41 #include "commands/schemacmds.h"
42 #include "commands/seclabel.h"
43 #include "commands/sequence.h"
44 #include "commands/tablecmds.h"
45 #include "commands/tablespace.h"
46 #include "commands/trigger.h"
47 #include "commands/typecmds.h"
48 #include "commands/user.h"
49 #include "commands/vacuum.h"
50 #include "commands/view.h"
51 #include "miscadmin.h"
52 #include "parser/parse_utilcmd.h"
53 #include "postmaster/bgwriter.h"
54 #include "rewrite/rewriteDefine.h"
55 #include "rewrite/rewriteRemove.h"
56 #include "storage/fd.h"
57 #include "tcop/pquery.h"
58 #include "tcop/utility.h"
59 #include "utils/acl.h"
60 #include "utils/guc.h"
61 #include "utils/syscache.h"
64 /* Hook for plugins to get control in ProcessUtility() */
65 ProcessUtility_hook_type ProcessUtility_hook = NULL;
69 * Verify user has ownership of specified relation, else ereport.
71 * If noCatalogs is true then we also deny access to system catalogs,
72 * except when allowSystemTableMods is true.
75 CheckRelationOwnership(RangeVar *rel, bool noCatalogs)
80 relOid = RangeVarGetRelid(rel, false);
81 tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relOid));
82 if (!HeapTupleIsValid(tuple)) /* should not happen */
83 elog(ERROR, "cache lookup failed for relation %u", relOid);
85 if (!pg_class_ownercheck(relOid, GetUserId()))
86 aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
91 if (!allowSystemTableMods &&
92 IsSystemClass((Form_pg_class) GETSTRUCT(tuple)))
94 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
95 errmsg("permission denied: \"%s\" is a system catalog",
99 ReleaseSysCache(tuple);
104 * CommandIsReadOnly: is an executable query read-only?
106 * This is a much stricter test than we apply for XactReadOnly mode;
107 * the query must be *in truth* read-only, because the caller wishes
108 * not to do CommandCounterIncrement for it.
110 * Note: currently no need to support Query nodes here
113 CommandIsReadOnly(Node *parsetree)
115 if (IsA(parsetree, PlannedStmt))
117 PlannedStmt *stmt = (PlannedStmt *) parsetree;
119 switch (stmt->commandType)
122 if (stmt->intoClause != NULL)
123 return false; /* SELECT INTO */
124 else if (stmt->rowMarks != NIL)
125 return false; /* SELECT FOR UPDATE/SHARE */
126 else if (stmt->hasModifyingCTE)
127 return false; /* data-modifying CTE */
135 elog(WARNING, "unrecognized commandType: %d",
136 (int) stmt->commandType);
140 /* For now, treat all utility commands as read/write */
145 * check_xact_readonly: is a utility command read-only?
147 * Here we use the loose rules of XactReadOnly mode: no permanent effects
148 * on the database are allowed.
151 check_xact_readonly(Node *parsetree)
157 * Note: Commands that need to do more complicated checking are handled
158 * elsewhere, in particular COPY and plannable statements do their own
159 * checking. However they should all call PreventCommandIfReadOnly to
160 * actually throw the error.
163 switch (nodeTag(parsetree))
165 case T_AlterDatabaseStmt:
166 case T_AlterDatabaseSetStmt:
167 case T_AlterDomainStmt:
168 case T_AlterFunctionStmt:
169 case T_AlterRoleStmt:
170 case T_AlterRoleSetStmt:
171 case T_AlterObjectSchemaStmt:
172 case T_AlterOwnerStmt:
174 case T_AlterTableStmt:
178 case T_CreateCastStmt:
179 case T_CreateConversionStmt:
181 case T_CreateDomainStmt:
182 case T_CreateFunctionStmt:
183 case T_CreateRoleStmt:
185 case T_CreatePLangStmt:
186 case T_CreateOpClassStmt:
187 case T_CreateOpFamilyStmt:
188 case T_AlterOpFamilyStmt:
190 case T_CreateSchemaStmt:
191 case T_CreateSeqStmt:
193 case T_CreateTableSpaceStmt:
194 case T_CreateTrigStmt:
195 case T_CompositeTypeStmt:
196 case T_CreateEnumStmt:
197 case T_AlterEnumStmt:
202 case T_DropTableSpaceStmt:
203 case T_RemoveFuncStmt:
205 case T_DropPLangStmt:
206 case T_RemoveOpClassStmt:
207 case T_RemoveOpFamilyStmt:
208 case T_DropPropertyStmt:
210 case T_GrantRoleStmt:
211 case T_AlterDefaultPrivilegesStmt:
213 case T_DropOwnedStmt:
214 case T_ReassignOwnedStmt:
215 case T_AlterTSDictionaryStmt:
216 case T_AlterTSConfigurationStmt:
217 case T_CreateExtensionStmt:
218 case T_AlterExtensionStmt:
219 case T_AlterExtensionContentsStmt:
220 case T_CreateFdwStmt:
223 case T_CreateForeignServerStmt:
224 case T_AlterForeignServerStmt:
225 case T_DropForeignServerStmt:
226 case T_CreateUserMappingStmt:
227 case T_AlterUserMappingStmt:
228 case T_DropUserMappingStmt:
229 case T_AlterTableSpaceOptionsStmt:
230 case T_CreateForeignTableStmt:
232 PreventCommandIfReadOnly(CreateCommandTag(parsetree));
241 * PreventCommandIfReadOnly: throw error if XactReadOnly
243 * This is useful mainly to ensure consistency of the error message wording;
244 * most callers have checked XactReadOnly for themselves.
247 PreventCommandIfReadOnly(const char *cmdname)
251 (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
252 /* translator: %s is name of a SQL command, eg CREATE */
253 errmsg("cannot execute %s in a read-only transaction",
258 * PreventCommandDuringRecovery: throw error if RecoveryInProgress
260 * The majority of operations that are unsafe in a Hot Standby slave
261 * will be rejected by XactReadOnly tests. However there are a few
262 * commands that are allowed in "read-only" xacts but cannot be allowed
263 * in Hot Standby mode. Those commands should call this function.
266 PreventCommandDuringRecovery(const char *cmdname)
268 if (RecoveryInProgress())
270 (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
271 /* translator: %s is name of a SQL command, eg CREATE */
272 errmsg("cannot execute %s during recovery",
277 * CheckRestrictedOperation: throw error for hazardous command if we're
278 * inside a security restriction context.
280 * This is needed to protect session-local state for which there is not any
281 * better-defined protection mechanism, such as ownership.
284 CheckRestrictedOperation(const char *cmdname)
286 if (InSecurityRestrictedOperation())
288 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
289 /* translator: %s is name of a SQL command, eg PREPARE */
290 errmsg("cannot execute %s within security-restricted operation",
297 * general utility function invoker
299 * parsetree: the parse tree for the utility statement
300 * queryString: original source text of command
301 * params: parameters to use during execution
302 * isTopLevel: true if executing a "top level" (interactively issued) command
303 * dest: where to send results
304 * completionTag: points to a buffer of size COMPLETION_TAG_BUFSIZE
305 * in which to store a command completion status string.
307 * Notes: as of PG 8.4, caller MUST supply a queryString; it is not
308 * allowed anymore to pass NULL. (If you really don't have source text,
309 * you can pass a constant string, perhaps "(query not available)".)
311 * completionTag is only set nonempty if we want to return a nondefault status.
313 * completionTag may be NULL if caller doesn't want a status string.
316 ProcessUtility(Node *parsetree,
317 const char *queryString,
318 ParamListInfo params,
323 Assert(queryString != NULL); /* required as of 8.4 */
326 * We provide a function hook variable that lets loadable plugins get
327 * control when ProcessUtility is called. Such a plugin would normally
328 * call standard_ProcessUtility().
330 if (ProcessUtility_hook)
331 (*ProcessUtility_hook) (parsetree, queryString, params,
332 isTopLevel, dest, completionTag);
334 standard_ProcessUtility(parsetree, queryString, params,
335 isTopLevel, dest, completionTag);
339 standard_ProcessUtility(Node *parsetree,
340 const char *queryString,
341 ParamListInfo params,
346 check_xact_readonly(parsetree);
349 completionTag[0] = '\0';
351 switch (nodeTag(parsetree))
354 * ******************** transactions ********************
356 case T_TransactionStmt:
358 TransactionStmt *stmt = (TransactionStmt *) parsetree;
363 * START TRANSACTION, as defined by SQL99: Identical
364 * to BEGIN. Same code for both.
366 case TRANS_STMT_BEGIN:
367 case TRANS_STMT_START:
371 BeginTransactionBlock();
372 foreach(lc, stmt->options)
374 DefElem *item = (DefElem *) lfirst(lc);
376 if (strcmp(item->defname, "transaction_isolation") == 0)
377 SetPGVariable("transaction_isolation",
378 list_make1(item->arg),
380 else if (strcmp(item->defname, "transaction_read_only") == 0)
381 SetPGVariable("transaction_read_only",
382 list_make1(item->arg),
384 else if (strcmp(item->defname, "transaction_deferrable") == 0)
385 SetPGVariable("transaction_deferrable",
386 list_make1(item->arg),
392 case TRANS_STMT_COMMIT:
393 if (!EndTransactionBlock())
395 /* report unsuccessful commit in completionTag */
397 strcpy(completionTag, "ROLLBACK");
401 case TRANS_STMT_PREPARE:
402 PreventCommandDuringRecovery("PREPARE TRANSACTION");
403 if (!PrepareTransactionBlock(stmt->gid))
405 /* report unsuccessful commit in completionTag */
407 strcpy(completionTag, "ROLLBACK");
411 case TRANS_STMT_COMMIT_PREPARED:
412 PreventTransactionChain(isTopLevel, "COMMIT PREPARED");
413 PreventCommandDuringRecovery("COMMIT PREPARED");
414 FinishPreparedTransaction(stmt->gid, true);
417 case TRANS_STMT_ROLLBACK_PREPARED:
418 PreventTransactionChain(isTopLevel, "ROLLBACK PREPARED");
419 PreventCommandDuringRecovery("ROLLBACK PREPARED");
420 FinishPreparedTransaction(stmt->gid, false);
423 case TRANS_STMT_ROLLBACK:
424 UserAbortTransactionBlock();
427 case TRANS_STMT_SAVEPOINT:
432 RequireTransactionChain(isTopLevel, "SAVEPOINT");
434 foreach(cell, stmt->options)
436 DefElem *elem = lfirst(cell);
438 if (strcmp(elem->defname, "savepoint_name") == 0)
439 name = strVal(elem->arg);
442 Assert(PointerIsValid(name));
444 DefineSavepoint(name);
448 case TRANS_STMT_RELEASE:
449 RequireTransactionChain(isTopLevel, "RELEASE SAVEPOINT");
450 ReleaseSavepoint(stmt->options);
453 case TRANS_STMT_ROLLBACK_TO:
454 RequireTransactionChain(isTopLevel, "ROLLBACK TO SAVEPOINT");
455 RollbackToSavepoint(stmt->options);
458 * CommitTransactionCommand is in charge of
459 * re-defining the savepoint again
467 * Portal (cursor) manipulation
469 * Note: DECLARE CURSOR is processed mostly as a SELECT, and
470 * therefore what we will get here is a PlannedStmt not a bare
475 PlannedStmt *stmt = (PlannedStmt *) parsetree;
477 if (stmt->utilityStmt == NULL ||
478 !IsA(stmt->utilityStmt, DeclareCursorStmt))
479 elog(ERROR, "non-DECLARE CURSOR PlannedStmt passed to ProcessUtility");
480 PerformCursorOpen(stmt, params, queryString, isTopLevel);
484 case T_ClosePortalStmt:
486 ClosePortalStmt *stmt = (ClosePortalStmt *) parsetree;
488 CheckRestrictedOperation("CLOSE");
489 PerformPortalClose(stmt->portalname);
494 PerformPortalFetch((FetchStmt *) parsetree, dest,
499 * relation and attribute manipulation
501 case T_CreateSchemaStmt:
502 CreateSchemaCommand((CreateSchemaStmt *) parsetree,
507 case T_CreateForeignTableStmt:
513 /* Run parse analysis ... */
514 stmts = transformCreateStmt((CreateStmt *) parsetree,
520 Node *stmt = (Node *) lfirst(l);
522 if (IsA(stmt, CreateStmt))
525 static char *validnsps[] = HEAP_RELOPT_NAMESPACES;
527 /* Create the table itself */
528 relOid = DefineRelation((CreateStmt *) stmt,
533 * If "IF NOT EXISTS" was specified and the relation
534 * already exists, do nothing further.
536 if (relOid == InvalidOid)
540 * Let AlterTableCreateToastTable decide if this one
541 * needs a secondary relation too.
543 CommandCounterIncrement();
545 /* parse and validate reloptions for the toast table */
546 toast_options = transformRelOptions((Datum) 0,
547 ((CreateStmt *) stmt)->options,
551 (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options,
554 AlterTableCreateToastTable(relOid, toast_options);
556 else if (IsA(stmt, CreateForeignTableStmt))
558 /* Create the table itself */
559 relOid = DefineRelation((CreateStmt *) stmt,
560 RELKIND_FOREIGN_TABLE,
564 * Unless "IF NOT EXISTS" was specified and the
565 * relation already exists, create the pg_foreign_table
568 if (relOid != InvalidOid)
569 CreateForeignTable((CreateForeignTableStmt *) stmt,
574 /* Recurse for anything else */
583 /* Need CCI between commands */
584 if (lnext(l) != NULL)
585 CommandCounterIncrement();
590 case T_CreateTableSpaceStmt:
591 PreventTransactionChain(isTopLevel, "CREATE TABLESPACE");
592 CreateTableSpace((CreateTableSpaceStmt *) parsetree);
595 case T_DropTableSpaceStmt:
596 PreventTransactionChain(isTopLevel, "DROP TABLESPACE");
597 DropTableSpace((DropTableSpaceStmt *) parsetree);
600 case T_AlterTableSpaceOptionsStmt:
601 AlterTableSpaceOptions((AlterTableSpaceOptionsStmt *) parsetree);
604 case T_CreateExtensionStmt:
605 CreateExtension((CreateExtensionStmt *) parsetree);
608 case T_AlterExtensionStmt:
609 ExecAlterExtensionStmt((AlterExtensionStmt *) parsetree);
612 case T_AlterExtensionContentsStmt:
613 ExecAlterExtensionContentsStmt((AlterExtensionContentsStmt *) parsetree);
616 case T_CreateFdwStmt:
617 CreateForeignDataWrapper((CreateFdwStmt *) parsetree);
621 AlterForeignDataWrapper((AlterFdwStmt *) parsetree);
625 RemoveForeignDataWrapper((DropFdwStmt *) parsetree);
628 case T_CreateForeignServerStmt:
629 CreateForeignServer((CreateForeignServerStmt *) parsetree);
632 case T_AlterForeignServerStmt:
633 AlterForeignServer((AlterForeignServerStmt *) parsetree);
636 case T_DropForeignServerStmt:
637 RemoveForeignServer((DropForeignServerStmt *) parsetree);
640 case T_CreateUserMappingStmt:
641 CreateUserMapping((CreateUserMappingStmt *) parsetree);
644 case T_AlterUserMappingStmt:
645 AlterUserMapping((AlterUserMappingStmt *) parsetree);
648 case T_DropUserMappingStmt:
649 RemoveUserMapping((DropUserMappingStmt *) parsetree);
654 DropStmt *stmt = (DropStmt *) parsetree;
656 switch (stmt->removeType)
659 case OBJECT_SEQUENCE:
662 case OBJECT_FOREIGN_TABLE:
663 RemoveRelations(stmt);
671 case OBJECT_COLLATION:
672 DropCollationsCommand(stmt);
675 case OBJECT_CONVERSION:
676 DropConversionsCommand(stmt);
683 case OBJECT_TSPARSER:
684 RemoveTSParsers(stmt);
687 case OBJECT_TSDICTIONARY:
688 RemoveTSDictionaries(stmt);
691 case OBJECT_TSTEMPLATE:
692 RemoveTSTemplates(stmt);
695 case OBJECT_TSCONFIGURATION:
696 RemoveTSConfigurations(stmt);
699 case OBJECT_EXTENSION:
700 RemoveExtensions(stmt);
704 elog(ERROR, "unrecognized drop object type: %d",
705 (int) stmt->removeType);
712 ExecuteTruncate((TruncateStmt *) parsetree);
716 CommentObject((CommentStmt *) parsetree);
720 ExecSecLabelStmt((SecLabelStmt *) parsetree);
727 processed = DoCopy((CopyStmt *) parsetree, queryString);
729 snprintf(completionTag, COMPLETION_TAG_BUFSIZE,
730 "COPY " UINT64_FORMAT, processed);
735 CheckRestrictedOperation("PREPARE");
736 PrepareQuery((PrepareStmt *) parsetree, queryString);
740 ExecuteQuery((ExecuteStmt *) parsetree, queryString, params,
741 dest, completionTag);
744 case T_DeallocateStmt:
745 CheckRestrictedOperation("DEALLOCATE");
746 DeallocateQuery((DeallocateStmt *) parsetree);
753 ExecRenameStmt((RenameStmt *) parsetree);
756 case T_AlterObjectSchemaStmt:
757 ExecAlterObjectSchemaStmt((AlterObjectSchemaStmt *) parsetree);
760 case T_AlterOwnerStmt:
761 ExecAlterOwnerStmt((AlterOwnerStmt *) parsetree);
764 case T_AlterTableStmt:
769 /* Run parse analysis ... */
770 stmts = transformAlterTableStmt((AlterTableStmt *) parsetree,
776 Node *stmt = (Node *) lfirst(l);
778 if (IsA(stmt, AlterTableStmt))
780 /* Do the table alteration proper */
781 AlterTable((AlterTableStmt *) stmt);
785 /* Recurse for anything else */
794 /* Need CCI between commands */
795 if (lnext(l) != NULL)
796 CommandCounterIncrement();
801 case T_AlterDomainStmt:
803 AlterDomainStmt *stmt = (AlterDomainStmt *) parsetree;
806 * Some or all of these functions are recursive to cover
807 * inherited things, so permission checks are done there.
809 switch (stmt->subtype)
811 case 'T': /* ALTER DOMAIN DEFAULT */
814 * Recursively alter column default for table and, if
815 * requested, for descendants
817 AlterDomainDefault(stmt->typeName,
820 case 'N': /* ALTER DOMAIN DROP NOT NULL */
821 AlterDomainNotNull(stmt->typeName,
824 case 'O': /* ALTER DOMAIN SET NOT NULL */
825 AlterDomainNotNull(stmt->typeName,
828 case 'C': /* ADD CONSTRAINT */
829 AlterDomainAddConstraint(stmt->typeName,
832 case 'X': /* DROP CONSTRAINT */
833 AlterDomainDropConstraint(stmt->typeName,
838 elog(ERROR, "unrecognized alter domain type: %d",
839 (int) stmt->subtype);
846 ExecuteGrantStmt((GrantStmt *) parsetree);
849 case T_GrantRoleStmt:
850 GrantRole((GrantRoleStmt *) parsetree);
853 case T_AlterDefaultPrivilegesStmt:
854 ExecAlterDefaultPrivilegesStmt((AlterDefaultPrivilegesStmt *) parsetree);
858 * **************** object creation / destruction *****************
862 DefineStmt *stmt = (DefineStmt *) parsetree;
866 case OBJECT_AGGREGATE:
867 DefineAggregate(stmt->defnames, stmt->args,
868 stmt->oldstyle, stmt->definition);
870 case OBJECT_OPERATOR:
871 Assert(stmt->args == NIL);
872 DefineOperator(stmt->defnames, stmt->definition);
875 Assert(stmt->args == NIL);
876 DefineType(stmt->defnames, stmt->definition);
878 case OBJECT_TSPARSER:
879 Assert(stmt->args == NIL);
880 DefineTSParser(stmt->defnames, stmt->definition);
882 case OBJECT_TSDICTIONARY:
883 Assert(stmt->args == NIL);
884 DefineTSDictionary(stmt->defnames, stmt->definition);
886 case OBJECT_TSTEMPLATE:
887 Assert(stmt->args == NIL);
888 DefineTSTemplate(stmt->defnames, stmt->definition);
890 case OBJECT_TSCONFIGURATION:
891 Assert(stmt->args == NIL);
892 DefineTSConfiguration(stmt->defnames, stmt->definition);
894 case OBJECT_COLLATION:
895 Assert(stmt->args == NIL);
896 DefineCollation(stmt->defnames, stmt->definition);
899 elog(ERROR, "unrecognized define stmt type: %d",
906 case T_CompositeTypeStmt: /* CREATE TYPE (composite) */
908 CompositeTypeStmt *stmt = (CompositeTypeStmt *) parsetree;
910 DefineCompositeType(stmt->typevar, stmt->coldeflist);
914 case T_CreateEnumStmt: /* CREATE TYPE (enum) */
915 DefineEnum((CreateEnumStmt *) parsetree);
918 case T_AlterEnumStmt: /* ALTER TYPE (enum) */
920 * We disallow this in transaction blocks, because we can't cope
921 * with enum OID values getting into indexes and then having their
922 * defining pg_enum entries go away.
924 PreventTransactionChain(isTopLevel, "ALTER TYPE ... ADD");
925 AlterEnum((AlterEnumStmt *) parsetree);
928 case T_ViewStmt: /* CREATE VIEW */
929 DefineView((ViewStmt *) parsetree, queryString);
932 case T_CreateFunctionStmt: /* CREATE FUNCTION */
933 CreateFunction((CreateFunctionStmt *) parsetree, queryString);
936 case T_AlterFunctionStmt: /* ALTER FUNCTION */
937 AlterFunction((AlterFunctionStmt *) parsetree);
940 case T_IndexStmt: /* CREATE INDEX */
942 IndexStmt *stmt = (IndexStmt *) parsetree;
944 if (stmt->concurrent)
945 PreventTransactionChain(isTopLevel,
946 "CREATE INDEX CONCURRENTLY");
948 CheckRelationOwnership(stmt->relation, true);
950 /* Run parse analysis ... */
951 stmt = transformIndexStmt(stmt, queryString);
954 DefineIndex(stmt->relation, /* relation */
955 stmt->idxname, /* index name */
956 InvalidOid, /* no predefined OID */
957 stmt->accessMethod, /* am name */
959 stmt->indexParams, /* parameters */
960 (Expr *) stmt->whereClause,
962 stmt->excludeOpNames,
968 false, /* is_alter_table */
969 true, /* check_rights */
970 false, /* skip_build */
972 stmt->concurrent); /* concurrent */
976 case T_RuleStmt: /* CREATE RULE */
977 DefineRule((RuleStmt *) parsetree, queryString);
980 case T_CreateSeqStmt:
981 DefineSequence((CreateSeqStmt *) parsetree);
985 AlterSequence((AlterSeqStmt *) parsetree);
988 case T_RemoveFuncStmt:
990 RemoveFuncStmt *stmt = (RemoveFuncStmt *) parsetree;
994 case OBJECT_FUNCTION:
995 RemoveFunction(stmt);
997 case OBJECT_AGGREGATE:
998 RemoveAggregate(stmt);
1000 case OBJECT_OPERATOR:
1001 RemoveOperator(stmt);
1004 elog(ERROR, "unrecognized object type: %d",
1012 ExecuteDoStmt((DoStmt *) parsetree);
1015 case T_CreatedbStmt:
1016 PreventTransactionChain(isTopLevel, "CREATE DATABASE");
1017 createdb((CreatedbStmt *) parsetree);
1020 case T_AlterDatabaseStmt:
1021 AlterDatabase((AlterDatabaseStmt *) parsetree, isTopLevel);
1024 case T_AlterDatabaseSetStmt:
1025 AlterDatabaseSet((AlterDatabaseSetStmt *) parsetree);
1030 DropdbStmt *stmt = (DropdbStmt *) parsetree;
1032 PreventTransactionChain(isTopLevel, "DROP DATABASE");
1033 dropdb(stmt->dbname, stmt->missing_ok);
1037 /* Query-level asynchronous notification */
1040 NotifyStmt *stmt = (NotifyStmt *) parsetree;
1042 PreventCommandDuringRecovery("NOTIFY");
1043 Async_Notify(stmt->conditionname, stmt->payload);
1049 ListenStmt *stmt = (ListenStmt *) parsetree;
1051 PreventCommandDuringRecovery("LISTEN");
1052 CheckRestrictedOperation("LISTEN");
1053 Async_Listen(stmt->conditionname);
1057 case T_UnlistenStmt:
1059 UnlistenStmt *stmt = (UnlistenStmt *) parsetree;
1061 PreventCommandDuringRecovery("UNLISTEN");
1062 CheckRestrictedOperation("UNLISTEN");
1063 if (stmt->conditionname)
1064 Async_Unlisten(stmt->conditionname);
1066 Async_UnlistenAll();
1072 LoadStmt *stmt = (LoadStmt *) parsetree;
1074 closeAllVfds(); /* probably not necessary... */
1075 /* Allowed names are restricted if you're not superuser */
1076 load_file(stmt->filename, !superuser());
1081 /* we choose to allow this during "read only" transactions */
1082 PreventCommandDuringRecovery("CLUSTER");
1083 cluster((ClusterStmt *) parsetree, isTopLevel);
1087 /* we choose to allow this during "read only" transactions */
1088 PreventCommandDuringRecovery("VACUUM");
1089 vacuum((VacuumStmt *) parsetree, InvalidOid, true, NULL, false,
1094 ExplainQuery((ExplainStmt *) parsetree, queryString, params, dest);
1097 case T_VariableSetStmt:
1098 ExecSetVariableStmt((VariableSetStmt *) parsetree);
1101 case T_VariableShowStmt:
1103 VariableShowStmt *n = (VariableShowStmt *) parsetree;
1105 GetPGVariable(n->name, dest);
1110 /* should we allow DISCARD PLANS? */
1111 CheckRestrictedOperation("DISCARD");
1112 DiscardCommand((DiscardStmt *) parsetree, isTopLevel);
1115 case T_CreateTrigStmt:
1116 (void) CreateTrigger((CreateTrigStmt *) parsetree, queryString,
1117 InvalidOid, InvalidOid, false);
1120 case T_DropPropertyStmt:
1122 DropPropertyStmt *stmt = (DropPropertyStmt *) parsetree;
1125 relId = RangeVarGetRelid(stmt->relation, false);
1127 switch (stmt->removeType)
1130 /* RemoveRewriteRule checks permissions */
1131 RemoveRewriteRule(relId, stmt->property,
1132 stmt->behavior, stmt->missing_ok);
1134 case OBJECT_TRIGGER:
1135 /* DropTrigger checks permissions */
1136 DropTrigger(relId, stmt->property,
1137 stmt->behavior, stmt->missing_ok);
1140 elog(ERROR, "unrecognized object type: %d",
1141 (int) stmt->removeType);
1147 case T_CreatePLangStmt:
1148 CreateProceduralLanguage((CreatePLangStmt *) parsetree);
1151 case T_DropPLangStmt:
1152 DropProceduralLanguage((DropPLangStmt *) parsetree);
1156 * ******************************** DOMAIN statements ****
1158 case T_CreateDomainStmt:
1159 DefineDomain((CreateDomainStmt *) parsetree);
1163 * ******************************** ROLE statements ****
1165 case T_CreateRoleStmt:
1166 CreateRole((CreateRoleStmt *) parsetree);
1169 case T_AlterRoleStmt:
1170 AlterRole((AlterRoleStmt *) parsetree);
1173 case T_AlterRoleSetStmt:
1174 AlterRoleSet((AlterRoleSetStmt *) parsetree);
1177 case T_DropRoleStmt:
1178 DropRole((DropRoleStmt *) parsetree);
1181 case T_DropOwnedStmt:
1182 DropOwnedObjects((DropOwnedStmt *) parsetree);
1185 case T_ReassignOwnedStmt:
1186 ReassignOwnedObjects((ReassignOwnedStmt *) parsetree);
1192 * Since the lock would just get dropped immediately, LOCK TABLE
1193 * outside a transaction block is presumed to be user error.
1195 RequireTransactionChain(isTopLevel, "LOCK TABLE");
1196 LockTableCommand((LockStmt *) parsetree);
1199 case T_ConstraintsSetStmt:
1200 AfterTriggerSetState((ConstraintsSetStmt *) parsetree);
1203 case T_CheckPointStmt:
1206 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1207 errmsg("must be superuser to do CHECKPOINT")));
1210 * You might think we should have a PreventCommandDuringRecovery()
1211 * here, but we interpret a CHECKPOINT command during recovery as
1212 * a request for a restartpoint instead. We allow this since it
1213 * can be a useful way of reducing switchover time when using
1214 * various forms of replication.
1216 RequestCheckpoint(CHECKPOINT_IMMEDIATE | CHECKPOINT_WAIT |
1217 (RecoveryInProgress() ? 0 : CHECKPOINT_FORCE));
1222 ReindexStmt *stmt = (ReindexStmt *) parsetree;
1224 /* we choose to allow this during "read only" transactions */
1225 PreventCommandDuringRecovery("REINDEX");
1229 ReindexIndex(stmt->relation);
1232 ReindexTable(stmt->relation);
1234 case OBJECT_DATABASE:
1237 * This cannot run inside a user transaction block; if
1238 * we were inside a transaction, then its commit- and
1239 * start-transaction-command calls would not have the
1242 PreventTransactionChain(isTopLevel,
1243 "REINDEX DATABASE");
1244 ReindexDatabase(stmt->name,
1245 stmt->do_system, stmt->do_user);
1248 elog(ERROR, "unrecognized object type: %d",
1256 case T_CreateConversionStmt:
1257 CreateConversionCommand((CreateConversionStmt *) parsetree);
1260 case T_CreateCastStmt:
1261 CreateCast((CreateCastStmt *) parsetree);
1264 case T_DropCastStmt:
1265 DropCast((DropCastStmt *) parsetree);
1268 case T_CreateOpClassStmt:
1269 DefineOpClass((CreateOpClassStmt *) parsetree);
1272 case T_CreateOpFamilyStmt:
1273 DefineOpFamily((CreateOpFamilyStmt *) parsetree);
1276 case T_AlterOpFamilyStmt:
1277 AlterOpFamily((AlterOpFamilyStmt *) parsetree);
1280 case T_RemoveOpClassStmt:
1281 RemoveOpClass((RemoveOpClassStmt *) parsetree);
1284 case T_RemoveOpFamilyStmt:
1285 RemoveOpFamily((RemoveOpFamilyStmt *) parsetree);
1288 case T_AlterTSDictionaryStmt:
1289 AlterTSDictionary((AlterTSDictionaryStmt *) parsetree);
1292 case T_AlterTSConfigurationStmt:
1293 AlterTSConfiguration((AlterTSConfigurationStmt *) parsetree);
1297 elog(ERROR, "unrecognized node type: %d",
1298 (int) nodeTag(parsetree));
1304 * UtilityReturnsTuples
1305 * Return "true" if this utility statement will send output to the
1308 * Generally, there should be a case here for each case in ProcessUtility
1309 * where "dest" is passed on.
1312 UtilityReturnsTuples(Node *parsetree)
1314 switch (nodeTag(parsetree))
1318 FetchStmt *stmt = (FetchStmt *) parsetree;
1323 portal = GetPortalByName(stmt->portalname);
1324 if (!PortalIsValid(portal))
1325 return false; /* not our business to raise error */
1326 return portal->tupDesc ? true : false;
1331 ExecuteStmt *stmt = (ExecuteStmt *) parsetree;
1332 PreparedStatement *entry;
1336 entry = FetchPreparedStatement(stmt->name, false);
1338 return false; /* not our business to raise error */
1339 if (entry->plansource->resultDesc)
1347 case T_VariableShowStmt:
1356 * UtilityTupleDescriptor
1357 * Fetch the actual output tuple descriptor for a utility statement
1358 * for which UtilityReturnsTuples() previously returned "true".
1360 * The returned descriptor is created in (or copied into) the current memory
1364 UtilityTupleDescriptor(Node *parsetree)
1366 switch (nodeTag(parsetree))
1370 FetchStmt *stmt = (FetchStmt *) parsetree;
1375 portal = GetPortalByName(stmt->portalname);
1376 if (!PortalIsValid(portal))
1377 return NULL; /* not our business to raise error */
1378 return CreateTupleDescCopy(portal->tupDesc);
1383 ExecuteStmt *stmt = (ExecuteStmt *) parsetree;
1384 PreparedStatement *entry;
1388 entry = FetchPreparedStatement(stmt->name, false);
1390 return NULL; /* not our business to raise error */
1391 return FetchPreparedStatementResultDesc(entry);
1395 return ExplainResultDesc((ExplainStmt *) parsetree);
1397 case T_VariableShowStmt:
1399 VariableShowStmt *n = (VariableShowStmt *) parsetree;
1401 return GetPGVariableResultDesc(n->name);
1411 * QueryReturnsTuples
1412 * Return "true" if this Query will send output to the destination.
1416 QueryReturnsTuples(Query *parsetree)
1418 switch (parsetree->commandType)
1421 /* returns tuples ... unless it's DECLARE CURSOR or SELECT INTO */
1422 if (parsetree->utilityStmt == NULL &&
1423 parsetree->intoClause == NULL)
1429 /* the forms with RETURNING return tuples */
1430 if (parsetree->returningList)
1434 return UtilityReturnsTuples(parsetree->utilityStmt);
1437 /* probably shouldn't get here */
1440 return false; /* default */
1446 * AlterObjectTypeCommandTag
1447 * helper function for CreateCommandTag
1449 * This covers most cases where ALTER is used with an ObjectType enum.
1452 AlterObjectTypeCommandTag(ObjectType objtype)
1458 case OBJECT_AGGREGATE:
1459 tag = "ALTER AGGREGATE";
1461 case OBJECT_ATTRIBUTE:
1467 case OBJECT_COLLATION:
1468 tag = "ALTER COLLATION";
1471 tag = "ALTER TABLE";
1473 case OBJECT_CONSTRAINT:
1474 tag = "ALTER TABLE";
1476 case OBJECT_CONVERSION:
1477 tag = "ALTER CONVERSION";
1479 case OBJECT_DATABASE:
1480 tag = "ALTER DATABASE";
1483 tag = "ALTER DOMAIN";
1485 case OBJECT_EXTENSION:
1486 tag = "ALTER EXTENSION";
1489 tag = "ALTER FOREIGN DATA WRAPPER";
1491 case OBJECT_FOREIGN_SERVER:
1492 tag = "ALTER SERVER";
1494 case OBJECT_FOREIGN_TABLE:
1495 tag = "ALTER FOREIGN TABLE";
1497 case OBJECT_FUNCTION:
1498 tag = "ALTER FUNCTION";
1501 tag = "ALTER INDEX";
1503 case OBJECT_LANGUAGE:
1504 tag = "ALTER LANGUAGE";
1506 case OBJECT_LARGEOBJECT:
1507 tag = "ALTER LARGE OBJECT";
1509 case OBJECT_OPCLASS:
1510 tag = "ALTER OPERATOR CLASS";
1512 case OBJECT_OPERATOR:
1513 tag = "ALTER OPERATOR";
1515 case OBJECT_OPFAMILY:
1516 tag = "ALTER OPERATOR FAMILY";
1525 tag = "ALTER SCHEMA";
1527 case OBJECT_SEQUENCE:
1528 tag = "ALTER SEQUENCE";
1531 tag = "ALTER TABLE";
1533 case OBJECT_TABLESPACE:
1534 tag = "ALTER TABLESPACE";
1536 case OBJECT_TRIGGER:
1537 tag = "ALTER TRIGGER";
1539 case OBJECT_TSCONFIGURATION:
1540 tag = "ALTER TEXT SEARCH CONFIGURATION";
1542 case OBJECT_TSDICTIONARY:
1543 tag = "ALTER TEXT SEARCH DICTIONARY";
1545 case OBJECT_TSPARSER:
1546 tag = "ALTER TEXT SEARCH PARSER";
1548 case OBJECT_TSTEMPLATE:
1549 tag = "ALTER TEXT SEARCH TEMPLATE";
1567 * utility to get a string representation of the command operation,
1568 * given either a raw (un-analyzed) parsetree or a planned query.
1570 * This must handle all command types, but since the vast majority
1571 * of 'em are utility commands, it seems sensible to keep it here.
1573 * NB: all result strings must be shorter than COMPLETION_TAG_BUFSIZE.
1574 * Also, the result must point at a true constant (permanent storage).
1577 CreateCommandTag(Node *parsetree)
1581 switch (nodeTag(parsetree))
1583 /* raw plannable queries */
1600 /* utility statements --- same whether raw or cooked */
1601 case T_TransactionStmt:
1603 TransactionStmt *stmt = (TransactionStmt *) parsetree;
1607 case TRANS_STMT_BEGIN:
1611 case TRANS_STMT_START:
1612 tag = "START TRANSACTION";
1615 case TRANS_STMT_COMMIT:
1619 case TRANS_STMT_ROLLBACK:
1620 case TRANS_STMT_ROLLBACK_TO:
1624 case TRANS_STMT_SAVEPOINT:
1628 case TRANS_STMT_RELEASE:
1632 case TRANS_STMT_PREPARE:
1633 tag = "PREPARE TRANSACTION";
1636 case TRANS_STMT_COMMIT_PREPARED:
1637 tag = "COMMIT PREPARED";
1640 case TRANS_STMT_ROLLBACK_PREPARED:
1641 tag = "ROLLBACK PREPARED";
1651 case T_DeclareCursorStmt:
1652 tag = "DECLARE CURSOR";
1655 case T_ClosePortalStmt:
1657 ClosePortalStmt *stmt = (ClosePortalStmt *) parsetree;
1659 if (stmt->portalname == NULL)
1660 tag = "CLOSE CURSOR ALL";
1662 tag = "CLOSE CURSOR";
1668 FetchStmt *stmt = (FetchStmt *) parsetree;
1670 tag = (stmt->ismove) ? "MOVE" : "FETCH";
1674 case T_CreateDomainStmt:
1675 tag = "CREATE DOMAIN";
1678 case T_CreateSchemaStmt:
1679 tag = "CREATE SCHEMA";
1683 tag = "CREATE TABLE";
1686 case T_CreateTableSpaceStmt:
1687 tag = "CREATE TABLESPACE";
1690 case T_DropTableSpaceStmt:
1691 tag = "DROP TABLESPACE";
1694 case T_AlterTableSpaceOptionsStmt:
1695 tag = "ALTER TABLESPACE";
1698 case T_CreateExtensionStmt:
1699 tag = "CREATE EXTENSION";
1702 case T_AlterExtensionStmt:
1703 tag = "ALTER EXTENSION";
1706 case T_AlterExtensionContentsStmt:
1707 tag = "ALTER EXTENSION";
1710 case T_CreateFdwStmt:
1711 tag = "CREATE FOREIGN DATA WRAPPER";
1714 case T_AlterFdwStmt:
1715 tag = "ALTER FOREIGN DATA WRAPPER";
1719 tag = "DROP FOREIGN DATA WRAPPER";
1722 case T_CreateForeignServerStmt:
1723 tag = "CREATE SERVER";
1726 case T_AlterForeignServerStmt:
1727 tag = "ALTER SERVER";
1730 case T_DropForeignServerStmt:
1731 tag = "DROP SERVER";
1734 case T_CreateUserMappingStmt:
1735 tag = "CREATE USER MAPPING";
1738 case T_AlterUserMappingStmt:
1739 tag = "ALTER USER MAPPING";
1742 case T_DropUserMappingStmt:
1743 tag = "DROP USER MAPPING";
1746 case T_CreateForeignTableStmt:
1747 tag = "CREATE FOREIGN TABLE";
1751 switch (((DropStmt *) parsetree)->removeType)
1756 case OBJECT_SEQUENCE:
1757 tag = "DROP SEQUENCE";
1769 tag = "DROP DOMAIN";
1771 case OBJECT_COLLATION:
1772 tag = "DROP COLLATION";
1774 case OBJECT_CONVERSION:
1775 tag = "DROP CONVERSION";
1778 tag = "DROP SCHEMA";
1780 case OBJECT_TSPARSER:
1781 tag = "DROP TEXT SEARCH PARSER";
1783 case OBJECT_TSDICTIONARY:
1784 tag = "DROP TEXT SEARCH DICTIONARY";
1786 case OBJECT_TSTEMPLATE:
1787 tag = "DROP TEXT SEARCH TEMPLATE";
1789 case OBJECT_TSCONFIGURATION:
1790 tag = "DROP TEXT SEARCH CONFIGURATION";
1792 case OBJECT_FOREIGN_TABLE:
1793 tag = "DROP FOREIGN TABLE";
1795 case OBJECT_EXTENSION:
1796 tag = "DROP EXTENSION";
1803 case T_TruncateStmt:
1804 tag = "TRUNCATE TABLE";
1811 case T_SecLabelStmt:
1812 tag = "SECURITY LABEL";
1820 tag = AlterObjectTypeCommandTag(((RenameStmt *) parsetree)->renameType);
1823 case T_AlterObjectSchemaStmt:
1824 tag = AlterObjectTypeCommandTag(((AlterObjectSchemaStmt *) parsetree)->objectType);
1827 case T_AlterOwnerStmt:
1828 tag = AlterObjectTypeCommandTag(((AlterOwnerStmt *) parsetree)->objectType);
1831 case T_AlterTableStmt:
1832 tag = AlterObjectTypeCommandTag(((AlterTableStmt *) parsetree)->relkind);
1835 case T_AlterDomainStmt:
1836 tag = "ALTER DOMAIN";
1839 case T_AlterFunctionStmt:
1840 tag = "ALTER FUNCTION";
1845 GrantStmt *stmt = (GrantStmt *) parsetree;
1847 tag = (stmt->is_grant) ? "GRANT" : "REVOKE";
1851 case T_GrantRoleStmt:
1853 GrantRoleStmt *stmt = (GrantRoleStmt *) parsetree;
1855 tag = (stmt->is_grant) ? "GRANT ROLE" : "REVOKE ROLE";
1859 case T_AlterDefaultPrivilegesStmt:
1860 tag = "ALTER DEFAULT PRIVILEGES";
1864 switch (((DefineStmt *) parsetree)->kind)
1866 case OBJECT_AGGREGATE:
1867 tag = "CREATE AGGREGATE";
1869 case OBJECT_OPERATOR:
1870 tag = "CREATE OPERATOR";
1873 tag = "CREATE TYPE";
1875 case OBJECT_TSPARSER:
1876 tag = "CREATE TEXT SEARCH PARSER";
1878 case OBJECT_TSDICTIONARY:
1879 tag = "CREATE TEXT SEARCH DICTIONARY";
1881 case OBJECT_TSTEMPLATE:
1882 tag = "CREATE TEXT SEARCH TEMPLATE";
1884 case OBJECT_TSCONFIGURATION:
1885 tag = "CREATE TEXT SEARCH CONFIGURATION";
1887 case OBJECT_COLLATION:
1888 tag = "CREATE COLLATION";
1895 case T_CompositeTypeStmt:
1896 tag = "CREATE TYPE";
1899 case T_CreateEnumStmt:
1900 tag = "CREATE TYPE";
1903 case T_AlterEnumStmt:
1908 tag = "CREATE VIEW";
1911 case T_CreateFunctionStmt:
1912 tag = "CREATE FUNCTION";
1916 tag = "CREATE INDEX";
1920 tag = "CREATE RULE";
1923 case T_CreateSeqStmt:
1924 tag = "CREATE SEQUENCE";
1927 case T_AlterSeqStmt:
1928 tag = "ALTER SEQUENCE";
1931 case T_RemoveFuncStmt:
1932 switch (((RemoveFuncStmt *) parsetree)->kind)
1934 case OBJECT_FUNCTION:
1935 tag = "DROP FUNCTION";
1937 case OBJECT_AGGREGATE:
1938 tag = "DROP AGGREGATE";
1940 case OBJECT_OPERATOR:
1941 tag = "DROP OPERATOR";
1952 case T_CreatedbStmt:
1953 tag = "CREATE DATABASE";
1956 case T_AlterDatabaseStmt:
1957 tag = "ALTER DATABASE";
1960 case T_AlterDatabaseSetStmt:
1961 tag = "ALTER DATABASE";
1965 tag = "DROP DATABASE";
1976 case T_UnlistenStmt:
1989 if (((VacuumStmt *) parsetree)->options & VACOPT_VACUUM)
1999 case T_VariableSetStmt:
2000 switch (((VariableSetStmt *) parsetree)->kind)
2003 case VAR_SET_CURRENT:
2004 case VAR_SET_DEFAULT:
2017 case T_VariableShowStmt:
2022 switch (((DiscardStmt *) parsetree)->target)
2025 tag = "DISCARD ALL";
2028 tag = "DISCARD PLANS";
2031 tag = "DISCARD TEMP";
2038 case T_CreateTrigStmt:
2039 tag = "CREATE TRIGGER";
2042 case T_DropPropertyStmt:
2043 switch (((DropPropertyStmt *) parsetree)->removeType)
2045 case OBJECT_TRIGGER:
2046 tag = "DROP TRIGGER";
2056 case T_CreatePLangStmt:
2057 tag = "CREATE LANGUAGE";
2060 case T_DropPLangStmt:
2061 tag = "DROP LANGUAGE";
2064 case T_CreateRoleStmt:
2065 tag = "CREATE ROLE";
2068 case T_AlterRoleStmt:
2072 case T_AlterRoleSetStmt:
2076 case T_DropRoleStmt:
2080 case T_DropOwnedStmt:
2084 case T_ReassignOwnedStmt:
2085 tag = "REASSIGN OWNED";
2092 case T_ConstraintsSetStmt:
2093 tag = "SET CONSTRAINTS";
2096 case T_CheckPointStmt:
2104 case T_CreateConversionStmt:
2105 tag = "CREATE CONVERSION";
2108 case T_CreateCastStmt:
2109 tag = "CREATE CAST";
2112 case T_DropCastStmt:
2116 case T_CreateOpClassStmt:
2117 tag = "CREATE OPERATOR CLASS";
2120 case T_CreateOpFamilyStmt:
2121 tag = "CREATE OPERATOR FAMILY";
2124 case T_AlterOpFamilyStmt:
2125 tag = "ALTER OPERATOR FAMILY";
2128 case T_RemoveOpClassStmt:
2129 tag = "DROP OPERATOR CLASS";
2132 case T_RemoveOpFamilyStmt:
2133 tag = "DROP OPERATOR FAMILY";
2136 case T_AlterTSDictionaryStmt:
2137 tag = "ALTER TEXT SEARCH DICTIONARY";
2140 case T_AlterTSConfigurationStmt:
2141 tag = "ALTER TEXT SEARCH CONFIGURATION";
2152 case T_DeallocateStmt:
2154 DeallocateStmt *stmt = (DeallocateStmt *) parsetree;
2156 if (stmt->name == NULL)
2157 tag = "DEALLOCATE ALL";
2163 /* already-planned queries */
2166 PlannedStmt *stmt = (PlannedStmt *) parsetree;
2168 switch (stmt->commandType)
2173 * We take a little extra care here so that the result
2174 * will be useful for complaints about read-only
2177 if (stmt->utilityStmt != NULL)
2179 Assert(IsA(stmt->utilityStmt, DeclareCursorStmt));
2180 tag = "DECLARE CURSOR";
2182 else if (stmt->intoClause != NULL)
2183 tag = "SELECT INTO";
2184 else if (stmt->rowMarks != NIL)
2186 /* not 100% but probably close enough */
2187 if (((PlanRowMark *) linitial(stmt->rowMarks))->markType == ROW_MARK_EXCLUSIVE)
2188 tag = "SELECT FOR UPDATE";
2190 tag = "SELECT FOR SHARE";
2205 elog(WARNING, "unrecognized commandType: %d",
2206 (int) stmt->commandType);
2213 /* parsed-and-rewritten-but-not-planned queries */
2216 Query *stmt = (Query *) parsetree;
2218 switch (stmt->commandType)
2223 * We take a little extra care here so that the result
2224 * will be useful for complaints about read-only
2227 if (stmt->utilityStmt != NULL)
2229 Assert(IsA(stmt->utilityStmt, DeclareCursorStmt));
2230 tag = "DECLARE CURSOR";
2232 else if (stmt->intoClause != NULL)
2233 tag = "SELECT INTO";
2234 else if (stmt->rowMarks != NIL)
2236 /* not 100% but probably close enough */
2237 if (((RowMarkClause *) linitial(stmt->rowMarks))->forUpdate)
2238 tag = "SELECT FOR UPDATE";
2240 tag = "SELECT FOR SHARE";
2255 tag = CreateCommandTag(stmt->utilityStmt);
2258 elog(WARNING, "unrecognized commandType: %d",
2259 (int) stmt->commandType);
2267 elog(WARNING, "unrecognized node type: %d",
2268 (int) nodeTag(parsetree));
2278 * GetCommandLogLevel
2279 * utility to get the minimum log_statement level for a command,
2280 * given either a raw (un-analyzed) parsetree or a planned query.
2282 * This must handle all command types, but since the vast majority
2283 * of 'em are utility commands, it seems sensible to keep it here.
2286 GetCommandLogLevel(Node *parsetree)
2290 switch (nodeTag(parsetree))
2292 /* raw plannable queries */
2300 if (((SelectStmt *) parsetree)->intoClause)
2301 lev = LOGSTMT_DDL; /* CREATE AS, SELECT INTO */
2306 /* utility statements --- same whether raw or cooked */
2307 case T_TransactionStmt:
2311 case T_DeclareCursorStmt:
2315 case T_ClosePortalStmt:
2323 case T_CreateSchemaStmt:
2328 case T_CreateForeignTableStmt:
2332 case T_CreateTableSpaceStmt:
2333 case T_DropTableSpaceStmt:
2334 case T_AlterTableSpaceOptionsStmt:
2338 case T_CreateExtensionStmt:
2339 case T_AlterExtensionStmt:
2340 case T_AlterExtensionContentsStmt:
2344 case T_CreateFdwStmt:
2345 case T_AlterFdwStmt:
2347 case T_CreateForeignServerStmt:
2348 case T_AlterForeignServerStmt:
2349 case T_DropForeignServerStmt:
2350 case T_CreateUserMappingStmt:
2351 case T_AlterUserMappingStmt:
2352 case T_DropUserMappingStmt:
2360 case T_TruncateStmt:
2368 case T_SecLabelStmt:
2373 if (((CopyStmt *) parsetree)->is_from)
2381 PrepareStmt *stmt = (PrepareStmt *) parsetree;
2383 /* Look through a PREPARE to the contained stmt */
2384 lev = GetCommandLogLevel(stmt->query);
2390 ExecuteStmt *stmt = (ExecuteStmt *) parsetree;
2391 PreparedStatement *ps;
2393 /* Look through an EXECUTE to the referenced stmt */
2394 ps = FetchPreparedStatement(stmt->name, false);
2396 lev = GetCommandLogLevel(ps->plansource->raw_parse_tree);
2402 case T_DeallocateStmt:
2410 case T_AlterObjectSchemaStmt:
2414 case T_AlterOwnerStmt:
2418 case T_AlterTableStmt:
2422 case T_AlterDomainStmt:
2430 case T_GrantRoleStmt:
2434 case T_AlterDefaultPrivilegesStmt:
2442 case T_CompositeTypeStmt:
2446 case T_CreateEnumStmt:
2450 case T_AlterEnumStmt:
2458 case T_CreateFunctionStmt:
2462 case T_AlterFunctionStmt:
2474 case T_CreateSeqStmt:
2478 case T_AlterSeqStmt:
2482 case T_RemoveFuncStmt:
2490 case T_CreatedbStmt:
2494 case T_AlterDatabaseStmt:
2498 case T_AlterDatabaseSetStmt:
2514 case T_UnlistenStmt:
2532 ExplainStmt *stmt = (ExplainStmt *) parsetree;
2533 bool analyze = false;
2536 /* Look through an EXPLAIN ANALYZE to the contained stmt */
2537 foreach(lc, stmt->options)
2539 DefElem *opt = (DefElem *) lfirst(lc);
2541 if (strcmp(opt->defname, "analyze") == 0)
2542 analyze = defGetBoolean(opt);
2543 /* don't "break", as explain.c will use the last value */
2546 return GetCommandLogLevel(stmt->query);
2548 /* Plain EXPLAIN isn't so interesting */
2553 case T_VariableSetStmt:
2557 case T_VariableShowStmt:
2565 case T_CreateTrigStmt:
2569 case T_DropPropertyStmt:
2573 case T_CreatePLangStmt:
2577 case T_DropPLangStmt:
2581 case T_CreateDomainStmt:
2585 case T_CreateRoleStmt:
2589 case T_AlterRoleStmt:
2593 case T_AlterRoleSetStmt:
2597 case T_DropRoleStmt:
2601 case T_DropOwnedStmt:
2605 case T_ReassignOwnedStmt:
2613 case T_ConstraintsSetStmt:
2617 case T_CheckPointStmt:
2622 lev = LOGSTMT_ALL; /* should this be DDL? */
2625 case T_CreateConversionStmt:
2629 case T_CreateCastStmt:
2633 case T_DropCastStmt:
2637 case T_CreateOpClassStmt:
2641 case T_CreateOpFamilyStmt:
2645 case T_AlterOpFamilyStmt:
2649 case T_RemoveOpClassStmt:
2653 case T_RemoveOpFamilyStmt:
2657 case T_AlterTSDictionaryStmt:
2661 case T_AlterTSConfigurationStmt:
2665 /* already-planned queries */
2668 PlannedStmt *stmt = (PlannedStmt *) parsetree;
2670 switch (stmt->commandType)
2673 if (stmt->intoClause != NULL)
2674 lev = LOGSTMT_DDL; /* CREATE AS, SELECT INTO */
2676 lev = LOGSTMT_ALL; /* SELECT or DECLARE CURSOR */
2686 elog(WARNING, "unrecognized commandType: %d",
2687 (int) stmt->commandType);
2694 /* parsed-and-rewritten-but-not-planned queries */
2697 Query *stmt = (Query *) parsetree;
2699 switch (stmt->commandType)
2702 if (stmt->intoClause != NULL)
2703 lev = LOGSTMT_DDL; /* CREATE AS, SELECT INTO */
2705 lev = LOGSTMT_ALL; /* SELECT or DECLARE CURSOR */
2715 lev = GetCommandLogLevel(stmt->utilityStmt);
2719 elog(WARNING, "unrecognized commandType: %d",
2720 (int) stmt->commandType);
2729 elog(WARNING, "unrecognized node type: %d",
2730 (int) nodeTag(parsetree));