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-2013, 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/htup_details.h"
20 #include "access/reloptions.h"
21 #include "access/twophase.h"
22 #include "access/xact.h"
23 #include "catalog/catalog.h"
24 #include "catalog/namespace.h"
25 #include "catalog/toasting.h"
26 #include "commands/alter.h"
27 #include "commands/async.h"
28 #include "commands/cluster.h"
29 #include "commands/comment.h"
30 #include "commands/collationcmds.h"
31 #include "commands/conversioncmds.h"
32 #include "commands/copy.h"
33 #include "commands/createas.h"
34 #include "commands/dbcommands.h"
35 #include "commands/defrem.h"
36 #include "commands/discard.h"
37 #include "commands/event_trigger.h"
38 #include "commands/explain.h"
39 #include "commands/extension.h"
40 #include "commands/matview.h"
41 #include "commands/lockcmds.h"
42 #include "commands/portalcmds.h"
43 #include "commands/prepare.h"
44 #include "commands/proclang.h"
45 #include "commands/schemacmds.h"
46 #include "commands/seclabel.h"
47 #include "commands/sequence.h"
48 #include "commands/tablecmds.h"
49 #include "commands/tablespace.h"
50 #include "commands/trigger.h"
51 #include "commands/typecmds.h"
52 #include "commands/user.h"
53 #include "commands/vacuum.h"
54 #include "commands/view.h"
55 #include "miscadmin.h"
56 #include "parser/parse_utilcmd.h"
57 #include "postmaster/bgwriter.h"
58 #include "rewrite/rewriteDefine.h"
59 #include "rewrite/rewriteRemove.h"
60 #include "storage/fd.h"
61 #include "tcop/pquery.h"
62 #include "tcop/utility.h"
63 #include "utils/acl.h"
64 #include "utils/guc.h"
65 #include "utils/syscache.h"
68 /* Hook for plugins to get control in ProcessUtility() */
69 ProcessUtility_hook_type ProcessUtility_hook = NULL;
73 * Verify user has ownership of specified relation, else ereport.
75 * If noCatalogs is true then we also deny access to system catalogs,
76 * except when allowSystemTableMods is true.
79 CheckRelationOwnership(RangeVar *rel, bool noCatalogs)
85 * XXX: This is unsafe in the presence of concurrent DDL, since it is
86 * called before acquiring any lock on the target relation. However,
87 * locking the target relation (especially using something like
88 * AccessExclusiveLock) before verifying that the user has permissions is
89 * not appealing either.
91 relOid = RangeVarGetRelid(rel, NoLock, false);
93 tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relOid));
94 if (!HeapTupleIsValid(tuple)) /* should not happen */
95 elog(ERROR, "cache lookup failed for relation %u", relOid);
97 if (!pg_class_ownercheck(relOid, GetUserId()))
98 aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
103 if (!allowSystemTableMods &&
104 IsSystemClass((Form_pg_class) GETSTRUCT(tuple)))
106 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
107 errmsg("permission denied: \"%s\" is a system catalog",
111 ReleaseSysCache(tuple);
116 * CommandIsReadOnly: is an executable query read-only?
118 * This is a much stricter test than we apply for XactReadOnly mode;
119 * the query must be *in truth* read-only, because the caller wishes
120 * not to do CommandCounterIncrement for it.
122 * Note: currently no need to support Query nodes here
125 CommandIsReadOnly(Node *parsetree)
127 if (IsA(parsetree, PlannedStmt))
129 PlannedStmt *stmt = (PlannedStmt *) parsetree;
131 switch (stmt->commandType)
134 if (stmt->rowMarks != NIL)
135 return false; /* SELECT FOR [KEY] UPDATE/SHARE */
136 else if (stmt->hasModifyingCTE)
137 return false; /* data-modifying CTE */
145 elog(WARNING, "unrecognized commandType: %d",
146 (int) stmt->commandType);
150 /* For now, treat all utility commands as read/write */
155 * check_xact_readonly: is a utility command read-only?
157 * Here we use the loose rules of XactReadOnly mode: no permanent effects
158 * on the database are allowed.
161 check_xact_readonly(Node *parsetree)
167 * Note: Commands that need to do more complicated checking are handled
168 * elsewhere, in particular COPY and plannable statements do their own
169 * checking. However they should all call PreventCommandIfReadOnly to
170 * actually throw the error.
173 switch (nodeTag(parsetree))
175 case T_AlterDatabaseStmt:
176 case T_AlterDatabaseSetStmt:
177 case T_AlterDomainStmt:
178 case T_AlterFunctionStmt:
179 case T_AlterRoleStmt:
180 case T_AlterRoleSetStmt:
181 case T_AlterObjectSchemaStmt:
182 case T_AlterOwnerStmt:
184 case T_AlterTableStmt:
188 case T_CreateCastStmt:
189 case T_CreateEventTrigStmt:
190 case T_AlterEventTrigStmt:
191 case T_CreateConversionStmt:
193 case T_CreateDomainStmt:
194 case T_CreateFunctionStmt:
195 case T_CreateRoleStmt:
197 case T_CreatePLangStmt:
198 case T_CreateOpClassStmt:
199 case T_CreateOpFamilyStmt:
200 case T_AlterOpFamilyStmt:
202 case T_CreateSchemaStmt:
203 case T_CreateSeqStmt:
205 case T_CreateTableAsStmt:
206 case T_RefreshMatViewStmt:
207 case T_CreateTableSpaceStmt:
208 case T_CreateTrigStmt:
209 case T_CompositeTypeStmt:
210 case T_CreateEnumStmt:
211 case T_CreateRangeStmt:
212 case T_AlterEnumStmt:
216 case T_DropTableSpaceStmt:
219 case T_GrantRoleStmt:
220 case T_AlterDefaultPrivilegesStmt:
222 case T_DropOwnedStmt:
223 case T_ReassignOwnedStmt:
224 case T_AlterTSDictionaryStmt:
225 case T_AlterTSConfigurationStmt:
226 case T_CreateExtensionStmt:
227 case T_AlterExtensionStmt:
228 case T_AlterExtensionContentsStmt:
229 case T_CreateFdwStmt:
231 case T_CreateForeignServerStmt:
232 case T_AlterForeignServerStmt:
233 case T_CreateUserMappingStmt:
234 case T_AlterUserMappingStmt:
235 case T_DropUserMappingStmt:
236 case T_AlterTableSpaceOptionsStmt:
237 case T_CreateForeignTableStmt:
239 PreventCommandIfReadOnly(CreateCommandTag(parsetree));
248 * PreventCommandIfReadOnly: throw error if XactReadOnly
250 * This is useful mainly to ensure consistency of the error message wording;
251 * most callers have checked XactReadOnly for themselves.
254 PreventCommandIfReadOnly(const char *cmdname)
258 (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
259 /* translator: %s is name of a SQL command, eg CREATE */
260 errmsg("cannot execute %s in a read-only transaction",
265 * PreventCommandDuringRecovery: throw error if RecoveryInProgress
267 * The majority of operations that are unsafe in a Hot Standby slave
268 * will be rejected by XactReadOnly tests. However there are a few
269 * commands that are allowed in "read-only" xacts but cannot be allowed
270 * in Hot Standby mode. Those commands should call this function.
273 PreventCommandDuringRecovery(const char *cmdname)
275 if (RecoveryInProgress())
277 (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
278 /* translator: %s is name of a SQL command, eg CREATE */
279 errmsg("cannot execute %s during recovery",
284 * CheckRestrictedOperation: throw error for hazardous command if we're
285 * inside a security restriction context.
287 * This is needed to protect session-local state for which there is not any
288 * better-defined protection mechanism, such as ownership.
291 CheckRestrictedOperation(const char *cmdname)
293 if (InSecurityRestrictedOperation())
295 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
296 /* translator: %s is name of a SQL command, eg PREPARE */
297 errmsg("cannot execute %s within security-restricted operation",
304 * general utility function invoker
306 * parsetree: the parse tree for the utility statement
307 * queryString: original source text of command
308 * params: parameters to use during execution
309 * isTopLevel: true if executing a "top level" (interactively issued) command
310 * dest: where to send results
311 * completionTag: points to a buffer of size COMPLETION_TAG_BUFSIZE
312 * in which to store a command completion status string.
314 * Notes: as of PG 8.4, caller MUST supply a queryString; it is not
315 * allowed anymore to pass NULL. (If you really don't have source text,
316 * you can pass a constant string, perhaps "(query not available)".)
318 * completionTag is only set nonempty if we want to return a nondefault status.
320 * completionTag may be NULL if caller doesn't want a status string.
323 ProcessUtility(Node *parsetree,
324 const char *queryString,
325 ParamListInfo params,
328 ProcessUtilityContext context)
330 Assert(queryString != NULL); /* required as of 8.4 */
333 * We provide a function hook variable that lets loadable plugins get
334 * control when ProcessUtility is called. Such a plugin would normally
335 * call standard_ProcessUtility().
337 if (ProcessUtility_hook)
338 (*ProcessUtility_hook) (parsetree, queryString, params,
339 dest, completionTag, context);
341 standard_ProcessUtility(parsetree, queryString, params,
342 dest, completionTag, context);
345 #define InvokeDDLCommandEventTriggers(parsetree, fncall) \
347 if (isCompleteQuery) \
349 EventTriggerDDLCommandStart(parsetree); \
352 if (isCompleteQuery) \
354 EventTriggerDDLCommandEnd(parsetree); \
358 #define InvokeDDLCommandEventTriggersIfSupported(parsetree, fncall, objtype) \
360 bool _supported = EventTriggerSupportsObjectType(objtype); \
364 EventTriggerDDLCommandStart(parsetree); \
369 EventTriggerDDLCommandEnd(parsetree); \
374 standard_ProcessUtility(Node *parsetree,
375 const char *queryString,
376 ParamListInfo params,
379 ProcessUtilityContext context)
381 bool isTopLevel = (context == PROCESS_UTILITY_TOPLEVEL);
382 bool isCompleteQuery = (context <= PROCESS_UTILITY_QUERY);
384 check_xact_readonly(parsetree);
387 completionTag[0] = '\0';
389 switch (nodeTag(parsetree))
392 * ******************** transactions ********************
394 case T_TransactionStmt:
396 TransactionStmt *stmt = (TransactionStmt *) parsetree;
401 * START TRANSACTION, as defined by SQL99: Identical
402 * to BEGIN. Same code for both.
404 case TRANS_STMT_BEGIN:
405 case TRANS_STMT_START:
409 BeginTransactionBlock();
410 foreach(lc, stmt->options)
412 DefElem *item = (DefElem *) lfirst(lc);
414 if (strcmp(item->defname, "transaction_isolation") == 0)
415 SetPGVariable("transaction_isolation",
416 list_make1(item->arg),
418 else if (strcmp(item->defname, "transaction_read_only") == 0)
419 SetPGVariable("transaction_read_only",
420 list_make1(item->arg),
422 else if (strcmp(item->defname, "transaction_deferrable") == 0)
423 SetPGVariable("transaction_deferrable",
424 list_make1(item->arg),
430 case TRANS_STMT_COMMIT:
431 if (!EndTransactionBlock())
433 /* report unsuccessful commit in completionTag */
435 strcpy(completionTag, "ROLLBACK");
439 case TRANS_STMT_PREPARE:
440 PreventCommandDuringRecovery("PREPARE TRANSACTION");
441 if (!PrepareTransactionBlock(stmt->gid))
443 /* report unsuccessful commit in completionTag */
445 strcpy(completionTag, "ROLLBACK");
449 case TRANS_STMT_COMMIT_PREPARED:
450 PreventTransactionChain(isTopLevel, "COMMIT PREPARED");
451 PreventCommandDuringRecovery("COMMIT PREPARED");
452 FinishPreparedTransaction(stmt->gid, true);
455 case TRANS_STMT_ROLLBACK_PREPARED:
456 PreventTransactionChain(isTopLevel, "ROLLBACK PREPARED");
457 PreventCommandDuringRecovery("ROLLBACK PREPARED");
458 FinishPreparedTransaction(stmt->gid, false);
461 case TRANS_STMT_ROLLBACK:
462 UserAbortTransactionBlock();
465 case TRANS_STMT_SAVEPOINT:
470 RequireTransactionChain(isTopLevel, "SAVEPOINT");
472 foreach(cell, stmt->options)
474 DefElem *elem = lfirst(cell);
476 if (strcmp(elem->defname, "savepoint_name") == 0)
477 name = strVal(elem->arg);
480 Assert(PointerIsValid(name));
482 DefineSavepoint(name);
486 case TRANS_STMT_RELEASE:
487 RequireTransactionChain(isTopLevel, "RELEASE SAVEPOINT");
488 ReleaseSavepoint(stmt->options);
491 case TRANS_STMT_ROLLBACK_TO:
492 RequireTransactionChain(isTopLevel, "ROLLBACK TO SAVEPOINT");
493 RollbackToSavepoint(stmt->options);
496 * CommitTransactionCommand is in charge of
497 * re-defining the savepoint again
505 * Portal (cursor) manipulation
507 * Note: DECLARE CURSOR is processed mostly as a SELECT, and
508 * therefore what we will get here is a PlannedStmt not a bare
513 PlannedStmt *stmt = (PlannedStmt *) parsetree;
515 if (stmt->utilityStmt == NULL ||
516 !IsA(stmt->utilityStmt, DeclareCursorStmt))
517 elog(ERROR, "non-DECLARE CURSOR PlannedStmt passed to ProcessUtility");
518 PerformCursorOpen(stmt, params, queryString, isTopLevel);
522 case T_ClosePortalStmt:
524 ClosePortalStmt *stmt = (ClosePortalStmt *) parsetree;
526 CheckRestrictedOperation("CLOSE");
527 PerformPortalClose(stmt->portalname);
532 PerformPortalFetch((FetchStmt *) parsetree, dest,
537 * relation and attribute manipulation
539 case T_CreateSchemaStmt:
540 InvokeDDLCommandEventTriggers(
542 CreateSchemaCommand((CreateSchemaStmt *) parsetree,
547 case T_CreateForeignTableStmt:
554 EventTriggerDDLCommandStart(parsetree);
556 /* Run parse analysis ... */
557 stmts = transformCreateStmt((CreateStmt *) parsetree,
563 Node *stmt = (Node *) lfirst(l);
565 if (IsA(stmt, CreateStmt))
568 static char *validnsps[] = HEAP_RELOPT_NAMESPACES;
570 /* Create the table itself */
571 relOid = DefineRelation((CreateStmt *) stmt,
576 * Let AlterTableCreateToastTable decide if this one
577 * needs a secondary relation too.
579 CommandCounterIncrement();
581 /* parse and validate reloptions for the toast table */
582 toast_options = transformRelOptions((Datum) 0,
583 ((CreateStmt *) stmt)->options,
587 (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options,
590 AlterTableCreateToastTable(relOid, toast_options);
592 else if (IsA(stmt, CreateForeignTableStmt))
594 /* Create the table itself */
595 relOid = DefineRelation((CreateStmt *) stmt,
596 RELKIND_FOREIGN_TABLE,
598 CreateForeignTable((CreateForeignTableStmt *) stmt,
603 /* Recurse for anything else */
609 PROCESS_UTILITY_GENERATED);
612 /* Need CCI between commands */
613 if (lnext(l) != NULL)
614 CommandCounterIncrement();
618 EventTriggerDDLCommandEnd(parsetree);
622 case T_CreateTableSpaceStmt:
623 /* no event triggers for global objects */
624 PreventTransactionChain(isTopLevel, "CREATE TABLESPACE");
625 CreateTableSpace((CreateTableSpaceStmt *) parsetree);
628 case T_DropTableSpaceStmt:
629 /* no event triggers for global objects */
630 PreventTransactionChain(isTopLevel, "DROP TABLESPACE");
631 DropTableSpace((DropTableSpaceStmt *) parsetree);
634 case T_AlterTableSpaceOptionsStmt:
635 /* no event triggers for global objects */
636 AlterTableSpaceOptions((AlterTableSpaceOptionsStmt *) parsetree);
639 case T_CreateExtensionStmt:
640 InvokeDDLCommandEventTriggers(
642 CreateExtension((CreateExtensionStmt *) parsetree));
645 case T_AlterExtensionStmt:
646 InvokeDDLCommandEventTriggers(
648 ExecAlterExtensionStmt((AlterExtensionStmt *) parsetree));
651 case T_AlterExtensionContentsStmt:
652 InvokeDDLCommandEventTriggers(
654 ExecAlterExtensionContentsStmt((AlterExtensionContentsStmt *) parsetree));
657 case T_CreateFdwStmt:
658 InvokeDDLCommandEventTriggers(
660 CreateForeignDataWrapper((CreateFdwStmt *) parsetree));
664 InvokeDDLCommandEventTriggers(
666 AlterForeignDataWrapper((AlterFdwStmt *) parsetree));
669 case T_CreateForeignServerStmt:
670 InvokeDDLCommandEventTriggers(
672 CreateForeignServer((CreateForeignServerStmt *) parsetree));
675 case T_AlterForeignServerStmt:
676 InvokeDDLCommandEventTriggers(
678 AlterForeignServer((AlterForeignServerStmt *) parsetree));
681 case T_CreateUserMappingStmt:
682 InvokeDDLCommandEventTriggers(
684 CreateUserMapping((CreateUserMappingStmt *) parsetree));
687 case T_AlterUserMappingStmt:
688 InvokeDDLCommandEventTriggers(
690 AlterUserMapping((AlterUserMappingStmt *) parsetree));
693 case T_DropUserMappingStmt:
694 InvokeDDLCommandEventTriggers(
696 RemoveUserMapping((DropUserMappingStmt *) parsetree));
701 DropStmt *stmt = (DropStmt *) parsetree;
704 && EventTriggerSupportsObjectType(stmt->removeType))
705 EventTriggerDDLCommandStart(parsetree);
707 switch (stmt->removeType)
710 if (stmt->concurrent)
711 PreventTransactionChain(isTopLevel,
712 "DROP INDEX CONCURRENTLY");
716 case OBJECT_SEQUENCE:
719 case OBJECT_FOREIGN_TABLE:
720 RemoveRelations((DropStmt *) parsetree);
723 RemoveObjects((DropStmt *) parsetree);
728 && EventTriggerSupportsObjectType(stmt->removeType))
729 EventTriggerDDLCommandEnd(parsetree);
735 ExecuteTruncate((TruncateStmt *) parsetree);
739 CommentObject((CommentStmt *) parsetree);
743 ExecSecLabelStmt((SecLabelStmt *) parsetree);
750 DoCopy((CopyStmt *) parsetree, queryString, &processed);
752 snprintf(completionTag, COMPLETION_TAG_BUFSIZE,
753 "COPY " UINT64_FORMAT, processed);
758 CheckRestrictedOperation("PREPARE");
759 PrepareQuery((PrepareStmt *) parsetree, queryString);
763 ExecuteQuery((ExecuteStmt *) parsetree, NULL,
765 dest, completionTag);
768 case T_DeallocateStmt:
769 CheckRestrictedOperation("DEALLOCATE");
770 DeallocateQuery((DeallocateStmt *) parsetree);
778 RenameStmt *stmt = (RenameStmt *) parsetree;
780 InvokeDDLCommandEventTriggersIfSupported(parsetree,
781 ExecRenameStmt(stmt),
786 case T_AlterObjectSchemaStmt:
788 AlterObjectSchemaStmt *stmt = (AlterObjectSchemaStmt *) parsetree;
789 InvokeDDLCommandEventTriggersIfSupported(parsetree,
790 ExecAlterObjectSchemaStmt(stmt),
795 case T_AlterOwnerStmt:
797 AlterOwnerStmt *stmt = (AlterOwnerStmt *) parsetree;
798 InvokeDDLCommandEventTriggersIfSupported(parsetree,
799 ExecAlterOwnerStmt(stmt),
804 case T_AlterTableStmt:
806 AlterTableStmt *atstmt = (AlterTableStmt *) parsetree;
813 EventTriggerDDLCommandStart(parsetree);
816 * Figure out lock mode, and acquire lock. This also does
817 * basic permissions checks, so that we won't wait for a lock
818 * on (for example) a relation on which we have no
821 lockmode = AlterTableGetLockLevel(atstmt->cmds);
822 relid = AlterTableLookupRelation(atstmt, lockmode);
824 if (OidIsValid(relid))
826 /* Run parse analysis ... */
827 stmts = transformAlterTableStmt(atstmt, queryString);
832 Node *stmt = (Node *) lfirst(l);
834 if (IsA(stmt, AlterTableStmt))
836 /* Do the table alteration proper */
837 AlterTable(relid, lockmode, (AlterTableStmt *) stmt);
841 /* Recurse for anything else */
847 PROCESS_UTILITY_GENERATED);
850 /* Need CCI between commands */
851 if (lnext(l) != NULL)
852 CommandCounterIncrement();
857 (errmsg("relation \"%s\" does not exist, skipping",
858 atstmt->relation->relname)));
862 case T_AlterDomainStmt:
864 AlterDomainStmt *stmt = (AlterDomainStmt *) parsetree;
867 EventTriggerDDLCommandStart(parsetree);
870 * Some or all of these functions are recursive to cover
871 * inherited things, so permission checks are done there.
873 switch (stmt->subtype)
875 case 'T': /* ALTER DOMAIN DEFAULT */
878 * Recursively alter column default for table and, if
879 * requested, for descendants
881 AlterDomainDefault(stmt->typeName,
884 case 'N': /* ALTER DOMAIN DROP NOT NULL */
885 AlterDomainNotNull(stmt->typeName,
888 case 'O': /* ALTER DOMAIN SET NOT NULL */
889 AlterDomainNotNull(stmt->typeName,
892 case 'C': /* ADD CONSTRAINT */
893 AlterDomainAddConstraint(stmt->typeName,
896 case 'X': /* DROP CONSTRAINT */
897 AlterDomainDropConstraint(stmt->typeName,
902 case 'V': /* VALIDATE CONSTRAINT */
903 AlterDomainValidateConstraint(stmt->typeName,
907 elog(ERROR, "unrecognized alter domain type: %d",
908 (int) stmt->subtype);
915 ExecuteGrantStmt((GrantStmt *) parsetree);
918 case T_GrantRoleStmt:
919 GrantRole((GrantRoleStmt *) parsetree);
922 case T_AlterDefaultPrivilegesStmt:
923 InvokeDDLCommandEventTriggers(
925 ExecAlterDefaultPrivilegesStmt((AlterDefaultPrivilegesStmt *) parsetree));
929 * **************** object creation / destruction *****************
933 DefineStmt *stmt = (DefineStmt *) parsetree;
936 EventTriggerDDLCommandStart(parsetree);
940 case OBJECT_AGGREGATE:
941 DefineAggregate(stmt->defnames, stmt->args,
942 stmt->oldstyle, stmt->definition);
944 case OBJECT_OPERATOR:
945 Assert(stmt->args == NIL);
946 DefineOperator(stmt->defnames, stmt->definition);
949 Assert(stmt->args == NIL);
950 DefineType(stmt->defnames, stmt->definition);
952 case OBJECT_TSPARSER:
953 Assert(stmt->args == NIL);
954 DefineTSParser(stmt->defnames, stmt->definition);
956 case OBJECT_TSDICTIONARY:
957 Assert(stmt->args == NIL);
958 DefineTSDictionary(stmt->defnames, stmt->definition);
960 case OBJECT_TSTEMPLATE:
961 Assert(stmt->args == NIL);
962 DefineTSTemplate(stmt->defnames, stmt->definition);
964 case OBJECT_TSCONFIGURATION:
965 Assert(stmt->args == NIL);
966 DefineTSConfiguration(stmt->defnames, stmt->definition);
968 case OBJECT_COLLATION:
969 Assert(stmt->args == NIL);
970 DefineCollation(stmt->defnames, stmt->definition);
973 elog(ERROR, "unrecognized define stmt type: %d",
980 case T_CompositeTypeStmt: /* CREATE TYPE (composite) */
982 CompositeTypeStmt *stmt = (CompositeTypeStmt *) parsetree;
984 InvokeDDLCommandEventTriggers(
986 DefineCompositeType(stmt->typevar, stmt->coldeflist));
990 case T_CreateEnumStmt: /* CREATE TYPE AS ENUM */
991 InvokeDDLCommandEventTriggers(
993 DefineEnum((CreateEnumStmt *) parsetree));
996 case T_CreateRangeStmt: /* CREATE TYPE AS RANGE */
997 InvokeDDLCommandEventTriggers(
999 DefineRange((CreateRangeStmt *) parsetree));
1002 case T_AlterEnumStmt: /* ALTER TYPE (enum) */
1003 InvokeDDLCommandEventTriggers(
1005 AlterEnum((AlterEnumStmt *) parsetree, isTopLevel));
1008 case T_ViewStmt: /* CREATE VIEW */
1009 InvokeDDLCommandEventTriggers(
1011 DefineView((ViewStmt *) parsetree, queryString));
1014 case T_CreateFunctionStmt: /* CREATE FUNCTION */
1015 InvokeDDLCommandEventTriggers(
1017 CreateFunction((CreateFunctionStmt *) parsetree, queryString));
1020 case T_AlterFunctionStmt: /* ALTER FUNCTION */
1021 InvokeDDLCommandEventTriggers(
1023 AlterFunction((AlterFunctionStmt *) parsetree));
1026 case T_IndexStmt: /* CREATE INDEX */
1028 IndexStmt *stmt = (IndexStmt *) parsetree;
1030 if (isCompleteQuery)
1031 EventTriggerDDLCommandStart(parsetree);
1032 if (stmt->concurrent)
1033 PreventTransactionChain(isTopLevel,
1034 "CREATE INDEX CONCURRENTLY");
1036 CheckRelationOwnership(stmt->relation, true);
1038 /* Run parse analysis ... */
1039 stmt = transformIndexStmt(stmt, queryString);
1043 InvalidOid, /* no predefined OID */
1044 false, /* is_alter_table */
1045 true, /* check_rights */
1046 false, /* skip_build */
1051 case T_RuleStmt: /* CREATE RULE */
1052 InvokeDDLCommandEventTriggers(
1054 DefineRule((RuleStmt *) parsetree, queryString));
1057 case T_CreateSeqStmt:
1058 InvokeDDLCommandEventTriggers(
1060 DefineSequence((CreateSeqStmt *) parsetree));
1063 case T_AlterSeqStmt:
1064 InvokeDDLCommandEventTriggers(
1066 AlterSequence((AlterSeqStmt *) parsetree));
1070 ExecuteDoStmt((DoStmt *) parsetree);
1073 case T_CreatedbStmt:
1074 /* no event triggers for global objects */
1075 PreventTransactionChain(isTopLevel, "CREATE DATABASE");
1076 createdb((CreatedbStmt *) parsetree);
1079 case T_AlterDatabaseStmt:
1080 /* no event triggers for global objects */
1081 AlterDatabase((AlterDatabaseStmt *) parsetree, isTopLevel);
1084 case T_AlterDatabaseSetStmt:
1085 /* no event triggers for global objects */
1086 AlterDatabaseSet((AlterDatabaseSetStmt *) parsetree);
1091 DropdbStmt *stmt = (DropdbStmt *) parsetree;
1093 /* no event triggers for global objects */
1094 PreventTransactionChain(isTopLevel, "DROP DATABASE");
1095 dropdb(stmt->dbname, stmt->missing_ok);
1099 /* Query-level asynchronous notification */
1102 NotifyStmt *stmt = (NotifyStmt *) parsetree;
1104 PreventCommandDuringRecovery("NOTIFY");
1105 Async_Notify(stmt->conditionname, stmt->payload);
1111 ListenStmt *stmt = (ListenStmt *) parsetree;
1113 PreventCommandDuringRecovery("LISTEN");
1114 CheckRestrictedOperation("LISTEN");
1115 Async_Listen(stmt->conditionname);
1119 case T_UnlistenStmt:
1121 UnlistenStmt *stmt = (UnlistenStmt *) parsetree;
1123 PreventCommandDuringRecovery("UNLISTEN");
1124 CheckRestrictedOperation("UNLISTEN");
1125 if (stmt->conditionname)
1126 Async_Unlisten(stmt->conditionname);
1128 Async_UnlistenAll();
1134 LoadStmt *stmt = (LoadStmt *) parsetree;
1136 closeAllVfds(); /* probably not necessary... */
1137 /* Allowed names are restricted if you're not superuser */
1138 load_file(stmt->filename, !superuser());
1143 /* we choose to allow this during "read only" transactions */
1144 PreventCommandDuringRecovery("CLUSTER");
1145 cluster((ClusterStmt *) parsetree, isTopLevel);
1150 VacuumStmt *stmt = (VacuumStmt *) parsetree;
1152 /* we choose to allow this during "read only" transactions */
1153 PreventCommandDuringRecovery((stmt->options & VACOPT_VACUUM) ?
1154 "VACUUM" : "ANALYZE");
1155 vacuum(stmt, InvalidOid, true, NULL, false, isTopLevel);
1160 ExplainQuery((ExplainStmt *) parsetree, queryString, params, dest);
1163 case T_CreateTableAsStmt:
1164 InvokeDDLCommandEventTriggers(
1166 ExecCreateTableAs((CreateTableAsStmt *) parsetree,
1167 queryString, params, completionTag));
1170 case T_RefreshMatViewStmt:
1171 if (isCompleteQuery)
1172 EventTriggerDDLCommandStart(parsetree);
1173 ExecRefreshMatView((RefreshMatViewStmt *) parsetree,
1174 queryString, params, completionTag);
1177 case T_VariableSetStmt:
1178 ExecSetVariableStmt((VariableSetStmt *) parsetree);
1181 case T_VariableShowStmt:
1183 VariableShowStmt *n = (VariableShowStmt *) parsetree;
1185 GetPGVariable(n->name, dest);
1190 /* should we allow DISCARD PLANS? */
1191 CheckRestrictedOperation("DISCARD");
1192 DiscardCommand((DiscardStmt *) parsetree, isTopLevel);
1195 case T_CreateTrigStmt:
1196 InvokeDDLCommandEventTriggers(
1198 (void) CreateTrigger((CreateTrigStmt *) parsetree, queryString,
1199 InvalidOid, InvalidOid, false));
1202 case T_CreateEventTrigStmt:
1203 /* no event triggers on event triggers */
1204 CreateEventTrigger((CreateEventTrigStmt *) parsetree);
1207 case T_AlterEventTrigStmt:
1208 /* no event triggers on event triggers */
1209 AlterEventTrigger((AlterEventTrigStmt *) parsetree);
1212 case T_CreatePLangStmt:
1213 InvokeDDLCommandEventTriggers(
1215 CreateProceduralLanguage((CreatePLangStmt *) parsetree));
1219 * ******************************** DOMAIN statements ****
1221 case T_CreateDomainStmt:
1222 InvokeDDLCommandEventTriggers(
1224 DefineDomain((CreateDomainStmt *) parsetree));
1228 * ******************************** ROLE statements ****
1230 case T_CreateRoleStmt:
1231 /* no event triggers for global objects */
1232 CreateRole((CreateRoleStmt *) parsetree);
1235 case T_AlterRoleStmt:
1236 /* no event triggers for global objects */
1237 AlterRole((AlterRoleStmt *) parsetree);
1240 case T_AlterRoleSetStmt:
1241 /* no event triggers for global objects */
1242 AlterRoleSet((AlterRoleSetStmt *) parsetree);
1245 case T_DropRoleStmt:
1246 /* no event triggers for global objects */
1247 DropRole((DropRoleStmt *) parsetree);
1250 case T_DropOwnedStmt:
1251 /* no event triggers for global objects */
1252 DropOwnedObjects((DropOwnedStmt *) parsetree);
1255 case T_ReassignOwnedStmt:
1256 /* no event triggers for global objects */
1257 ReassignOwnedObjects((ReassignOwnedStmt *) parsetree);
1263 * Since the lock would just get dropped immediately, LOCK TABLE
1264 * outside a transaction block is presumed to be user error.
1266 RequireTransactionChain(isTopLevel, "LOCK TABLE");
1267 LockTableCommand((LockStmt *) parsetree);
1270 case T_ConstraintsSetStmt:
1271 AfterTriggerSetState((ConstraintsSetStmt *) parsetree);
1274 case T_CheckPointStmt:
1277 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1278 errmsg("must be superuser to do CHECKPOINT")));
1281 * You might think we should have a PreventCommandDuringRecovery()
1282 * here, but we interpret a CHECKPOINT command during recovery as
1283 * a request for a restartpoint instead. We allow this since it
1284 * can be a useful way of reducing switchover time when using
1285 * various forms of replication.
1287 RequestCheckpoint(CHECKPOINT_IMMEDIATE | CHECKPOINT_WAIT |
1288 (RecoveryInProgress() ? 0 : CHECKPOINT_FORCE));
1293 ReindexStmt *stmt = (ReindexStmt *) parsetree;
1295 /* we choose to allow this during "read only" transactions */
1296 PreventCommandDuringRecovery("REINDEX");
1300 ReindexIndex(stmt->relation);
1303 case OBJECT_MATVIEW:
1304 ReindexTable(stmt->relation);
1306 case OBJECT_DATABASE:
1309 * This cannot run inside a user transaction block; if
1310 * we were inside a transaction, then its commit- and
1311 * start-transaction-command calls would not have the
1314 PreventTransactionChain(isTopLevel,
1315 "REINDEX DATABASE");
1316 ReindexDatabase(stmt->name,
1317 stmt->do_system, stmt->do_user);
1320 elog(ERROR, "unrecognized object type: %d",
1328 case T_CreateConversionStmt:
1329 InvokeDDLCommandEventTriggers(
1331 CreateConversionCommand((CreateConversionStmt *) parsetree));
1334 case T_CreateCastStmt:
1335 InvokeDDLCommandEventTriggers(
1337 CreateCast((CreateCastStmt *) parsetree));
1340 case T_CreateOpClassStmt:
1341 InvokeDDLCommandEventTriggers(
1343 DefineOpClass((CreateOpClassStmt *) parsetree));
1346 case T_CreateOpFamilyStmt:
1347 InvokeDDLCommandEventTriggers(
1349 DefineOpFamily((CreateOpFamilyStmt *) parsetree));
1352 case T_AlterOpFamilyStmt:
1353 InvokeDDLCommandEventTriggers(
1355 AlterOpFamily((AlterOpFamilyStmt *) parsetree));
1358 case T_AlterTSDictionaryStmt:
1359 InvokeDDLCommandEventTriggers(
1361 AlterTSDictionary((AlterTSDictionaryStmt *) parsetree));
1364 case T_AlterTSConfigurationStmt:
1365 InvokeDDLCommandEventTriggers(
1367 AlterTSConfiguration((AlterTSConfigurationStmt *) parsetree));
1371 elog(ERROR, "unrecognized node type: %d",
1372 (int) nodeTag(parsetree));
1378 * UtilityReturnsTuples
1379 * Return "true" if this utility statement will send output to the
1382 * Generally, there should be a case here for each case in ProcessUtility
1383 * where "dest" is passed on.
1386 UtilityReturnsTuples(Node *parsetree)
1388 switch (nodeTag(parsetree))
1392 FetchStmt *stmt = (FetchStmt *) parsetree;
1397 portal = GetPortalByName(stmt->portalname);
1398 if (!PortalIsValid(portal))
1399 return false; /* not our business to raise error */
1400 return portal->tupDesc ? true : false;
1405 ExecuteStmt *stmt = (ExecuteStmt *) parsetree;
1406 PreparedStatement *entry;
1408 entry = FetchPreparedStatement(stmt->name, false);
1410 return false; /* not our business to raise error */
1411 if (entry->plansource->resultDesc)
1419 case T_VariableShowStmt:
1428 * UtilityTupleDescriptor
1429 * Fetch the actual output tuple descriptor for a utility statement
1430 * for which UtilityReturnsTuples() previously returned "true".
1432 * The returned descriptor is created in (or copied into) the current memory
1436 UtilityTupleDescriptor(Node *parsetree)
1438 switch (nodeTag(parsetree))
1442 FetchStmt *stmt = (FetchStmt *) parsetree;
1447 portal = GetPortalByName(stmt->portalname);
1448 if (!PortalIsValid(portal))
1449 return NULL; /* not our business to raise error */
1450 return CreateTupleDescCopy(portal->tupDesc);
1455 ExecuteStmt *stmt = (ExecuteStmt *) parsetree;
1456 PreparedStatement *entry;
1458 entry = FetchPreparedStatement(stmt->name, false);
1460 return NULL; /* not our business to raise error */
1461 return FetchPreparedStatementResultDesc(entry);
1465 return ExplainResultDesc((ExplainStmt *) parsetree);
1467 case T_VariableShowStmt:
1469 VariableShowStmt *n = (VariableShowStmt *) parsetree;
1471 return GetPGVariableResultDesc(n->name);
1481 * QueryReturnsTuples
1482 * Return "true" if this Query will send output to the destination.
1486 QueryReturnsTuples(Query *parsetree)
1488 switch (parsetree->commandType)
1491 /* returns tuples ... unless it's DECLARE CURSOR */
1492 if (parsetree->utilityStmt == NULL)
1498 /* the forms with RETURNING return tuples */
1499 if (parsetree->returningList)
1503 return UtilityReturnsTuples(parsetree->utilityStmt);
1506 /* probably shouldn't get here */
1509 return false; /* default */
1515 * UtilityContainsQuery
1516 * Return the contained Query, or NULL if there is none
1518 * Certain utility statements, such as EXPLAIN, contain a plannable Query.
1519 * This function encapsulates knowledge of exactly which ones do.
1520 * We assume it is invoked only on already-parse-analyzed statements
1521 * (else the contained parsetree isn't a Query yet).
1523 * In some cases (currently, only EXPLAIN of CREATE TABLE AS/SELECT INTO and
1524 * CREATE MATERIALIZED VIEW), potentially Query-containing utility statements
1525 * can be nested. This function will drill down to a non-utility Query, or
1526 * return NULL if none.
1529 UtilityContainsQuery(Node *parsetree)
1533 switch (nodeTag(parsetree))
1536 qry = (Query *) ((ExplainStmt *) parsetree)->query;
1537 Assert(IsA(qry, Query));
1538 if (qry->commandType == CMD_UTILITY)
1539 return UtilityContainsQuery(qry->utilityStmt);
1542 case T_CreateTableAsStmt:
1543 qry = (Query *) ((CreateTableAsStmt *) parsetree)->query;
1544 Assert(IsA(qry, Query));
1545 if (qry->commandType == CMD_UTILITY)
1546 return UtilityContainsQuery(qry->utilityStmt);
1556 * AlterObjectTypeCommandTag
1557 * helper function for CreateCommandTag
1559 * This covers most cases where ALTER is used with an ObjectType enum.
1562 AlterObjectTypeCommandTag(ObjectType objtype)
1568 case OBJECT_AGGREGATE:
1569 tag = "ALTER AGGREGATE";
1571 case OBJECT_ATTRIBUTE:
1577 case OBJECT_COLLATION:
1578 tag = "ALTER COLLATION";
1581 tag = "ALTER TABLE";
1583 case OBJECT_CONSTRAINT:
1584 tag = "ALTER TABLE";
1586 case OBJECT_CONVERSION:
1587 tag = "ALTER CONVERSION";
1589 case OBJECT_DATABASE:
1590 tag = "ALTER DATABASE";
1593 tag = "ALTER DOMAIN";
1595 case OBJECT_EXTENSION:
1596 tag = "ALTER EXTENSION";
1599 tag = "ALTER FOREIGN DATA WRAPPER";
1601 case OBJECT_FOREIGN_SERVER:
1602 tag = "ALTER SERVER";
1604 case OBJECT_FOREIGN_TABLE:
1605 tag = "ALTER FOREIGN TABLE";
1607 case OBJECT_FUNCTION:
1608 tag = "ALTER FUNCTION";
1611 tag = "ALTER INDEX";
1613 case OBJECT_LANGUAGE:
1614 tag = "ALTER LANGUAGE";
1616 case OBJECT_LARGEOBJECT:
1617 tag = "ALTER LARGE OBJECT";
1619 case OBJECT_OPCLASS:
1620 tag = "ALTER OPERATOR CLASS";
1622 case OBJECT_OPERATOR:
1623 tag = "ALTER OPERATOR";
1625 case OBJECT_OPFAMILY:
1626 tag = "ALTER OPERATOR FAMILY";
1635 tag = "ALTER SCHEMA";
1637 case OBJECT_SEQUENCE:
1638 tag = "ALTER SEQUENCE";
1641 tag = "ALTER TABLE";
1643 case OBJECT_TABLESPACE:
1644 tag = "ALTER TABLESPACE";
1646 case OBJECT_TRIGGER:
1647 tag = "ALTER TRIGGER";
1649 case OBJECT_EVENT_TRIGGER:
1650 tag = "ALTER EVENT TRIGGER";
1652 case OBJECT_TSCONFIGURATION:
1653 tag = "ALTER TEXT SEARCH CONFIGURATION";
1655 case OBJECT_TSDICTIONARY:
1656 tag = "ALTER TEXT SEARCH DICTIONARY";
1658 case OBJECT_TSPARSER:
1659 tag = "ALTER TEXT SEARCH PARSER";
1661 case OBJECT_TSTEMPLATE:
1662 tag = "ALTER TEXT SEARCH TEMPLATE";
1670 case OBJECT_MATVIEW:
1671 tag = "ALTER MATERIALIZED VIEW";
1683 * utility to get a string representation of the command operation,
1684 * given either a raw (un-analyzed) parsetree or a planned query.
1686 * This must handle all command types, but since the vast majority
1687 * of 'em are utility commands, it seems sensible to keep it here.
1689 * NB: all result strings must be shorter than COMPLETION_TAG_BUFSIZE.
1690 * Also, the result must point at a true constant (permanent storage).
1693 CreateCommandTag(Node *parsetree)
1697 switch (nodeTag(parsetree))
1699 /* raw plannable queries */
1716 /* utility statements --- same whether raw or cooked */
1717 case T_TransactionStmt:
1719 TransactionStmt *stmt = (TransactionStmt *) parsetree;
1723 case TRANS_STMT_BEGIN:
1727 case TRANS_STMT_START:
1728 tag = "START TRANSACTION";
1731 case TRANS_STMT_COMMIT:
1735 case TRANS_STMT_ROLLBACK:
1736 case TRANS_STMT_ROLLBACK_TO:
1740 case TRANS_STMT_SAVEPOINT:
1744 case TRANS_STMT_RELEASE:
1748 case TRANS_STMT_PREPARE:
1749 tag = "PREPARE TRANSACTION";
1752 case TRANS_STMT_COMMIT_PREPARED:
1753 tag = "COMMIT PREPARED";
1756 case TRANS_STMT_ROLLBACK_PREPARED:
1757 tag = "ROLLBACK PREPARED";
1767 case T_DeclareCursorStmt:
1768 tag = "DECLARE CURSOR";
1771 case T_ClosePortalStmt:
1773 ClosePortalStmt *stmt = (ClosePortalStmt *) parsetree;
1775 if (stmt->portalname == NULL)
1776 tag = "CLOSE CURSOR ALL";
1778 tag = "CLOSE CURSOR";
1784 FetchStmt *stmt = (FetchStmt *) parsetree;
1786 tag = (stmt->ismove) ? "MOVE" : "FETCH";
1790 case T_CreateDomainStmt:
1791 tag = "CREATE DOMAIN";
1794 case T_CreateSchemaStmt:
1795 tag = "CREATE SCHEMA";
1799 tag = "CREATE TABLE";
1802 case T_CreateTableSpaceStmt:
1803 tag = "CREATE TABLESPACE";
1806 case T_DropTableSpaceStmt:
1807 tag = "DROP TABLESPACE";
1810 case T_AlterTableSpaceOptionsStmt:
1811 tag = "ALTER TABLESPACE";
1814 case T_CreateExtensionStmt:
1815 tag = "CREATE EXTENSION";
1818 case T_AlterExtensionStmt:
1819 tag = "ALTER EXTENSION";
1822 case T_AlterExtensionContentsStmt:
1823 tag = "ALTER EXTENSION";
1826 case T_CreateFdwStmt:
1827 tag = "CREATE FOREIGN DATA WRAPPER";
1830 case T_AlterFdwStmt:
1831 tag = "ALTER FOREIGN DATA WRAPPER";
1834 case T_CreateForeignServerStmt:
1835 tag = "CREATE SERVER";
1838 case T_AlterForeignServerStmt:
1839 tag = "ALTER SERVER";
1842 case T_CreateUserMappingStmt:
1843 tag = "CREATE USER MAPPING";
1846 case T_AlterUserMappingStmt:
1847 tag = "ALTER USER MAPPING";
1850 case T_DropUserMappingStmt:
1851 tag = "DROP USER MAPPING";
1854 case T_CreateForeignTableStmt:
1855 tag = "CREATE FOREIGN TABLE";
1859 switch (((DropStmt *) parsetree)->removeType)
1864 case OBJECT_SEQUENCE:
1865 tag = "DROP SEQUENCE";
1870 case OBJECT_MATVIEW:
1871 tag = "DROP MATERIALIZED VIEW";
1880 tag = "DROP DOMAIN";
1882 case OBJECT_COLLATION:
1883 tag = "DROP COLLATION";
1885 case OBJECT_CONVERSION:
1886 tag = "DROP CONVERSION";
1889 tag = "DROP SCHEMA";
1891 case OBJECT_TSPARSER:
1892 tag = "DROP TEXT SEARCH PARSER";
1894 case OBJECT_TSDICTIONARY:
1895 tag = "DROP TEXT SEARCH DICTIONARY";
1897 case OBJECT_TSTEMPLATE:
1898 tag = "DROP TEXT SEARCH TEMPLATE";
1900 case OBJECT_TSCONFIGURATION:
1901 tag = "DROP TEXT SEARCH CONFIGURATION";
1903 case OBJECT_FOREIGN_TABLE:
1904 tag = "DROP FOREIGN TABLE";
1906 case OBJECT_EXTENSION:
1907 tag = "DROP EXTENSION";
1909 case OBJECT_FUNCTION:
1910 tag = "DROP FUNCTION";
1912 case OBJECT_AGGREGATE:
1913 tag = "DROP AGGREGATE";
1915 case OBJECT_OPERATOR:
1916 tag = "DROP OPERATOR";
1918 case OBJECT_LANGUAGE:
1919 tag = "DROP LANGUAGE";
1924 case OBJECT_TRIGGER:
1925 tag = "DROP TRIGGER";
1927 case OBJECT_EVENT_TRIGGER:
1928 tag = "DROP EVENT TRIGGER";
1934 tag = "DROP FOREIGN DATA WRAPPER";
1936 case OBJECT_FOREIGN_SERVER:
1937 tag = "DROP SERVER";
1939 case OBJECT_OPCLASS:
1940 tag = "DROP OPERATOR CLASS";
1942 case OBJECT_OPFAMILY:
1943 tag = "DROP OPERATOR FAMILY";
1950 case T_TruncateStmt:
1951 tag = "TRUNCATE TABLE";
1958 case T_SecLabelStmt:
1959 tag = "SECURITY LABEL";
1967 tag = AlterObjectTypeCommandTag(((RenameStmt *) parsetree)->renameType);
1970 case T_AlterObjectSchemaStmt:
1971 tag = AlterObjectTypeCommandTag(((AlterObjectSchemaStmt *) parsetree)->objectType);
1974 case T_AlterOwnerStmt:
1975 tag = AlterObjectTypeCommandTag(((AlterOwnerStmt *) parsetree)->objectType);
1978 case T_AlterTableStmt:
1979 tag = AlterObjectTypeCommandTag(((AlterTableStmt *) parsetree)->relkind);
1982 case T_AlterDomainStmt:
1983 tag = "ALTER DOMAIN";
1986 case T_AlterFunctionStmt:
1987 tag = "ALTER FUNCTION";
1992 GrantStmt *stmt = (GrantStmt *) parsetree;
1994 tag = (stmt->is_grant) ? "GRANT" : "REVOKE";
1998 case T_GrantRoleStmt:
2000 GrantRoleStmt *stmt = (GrantRoleStmt *) parsetree;
2002 tag = (stmt->is_grant) ? "GRANT ROLE" : "REVOKE ROLE";
2006 case T_AlterDefaultPrivilegesStmt:
2007 tag = "ALTER DEFAULT PRIVILEGES";
2011 switch (((DefineStmt *) parsetree)->kind)
2013 case OBJECT_AGGREGATE:
2014 tag = "CREATE AGGREGATE";
2016 case OBJECT_OPERATOR:
2017 tag = "CREATE OPERATOR";
2020 tag = "CREATE TYPE";
2022 case OBJECT_TSPARSER:
2023 tag = "CREATE TEXT SEARCH PARSER";
2025 case OBJECT_TSDICTIONARY:
2026 tag = "CREATE TEXT SEARCH DICTIONARY";
2028 case OBJECT_TSTEMPLATE:
2029 tag = "CREATE TEXT SEARCH TEMPLATE";
2031 case OBJECT_TSCONFIGURATION:
2032 tag = "CREATE TEXT SEARCH CONFIGURATION";
2034 case OBJECT_COLLATION:
2035 tag = "CREATE COLLATION";
2042 case T_CompositeTypeStmt:
2043 tag = "CREATE TYPE";
2046 case T_CreateEnumStmt:
2047 tag = "CREATE TYPE";
2050 case T_CreateRangeStmt:
2051 tag = "CREATE TYPE";
2054 case T_AlterEnumStmt:
2059 tag = "CREATE VIEW";
2062 case T_CreateFunctionStmt:
2063 tag = "CREATE FUNCTION";
2067 tag = "CREATE INDEX";
2071 tag = "CREATE RULE";
2074 case T_CreateSeqStmt:
2075 tag = "CREATE SEQUENCE";
2078 case T_AlterSeqStmt:
2079 tag = "ALTER SEQUENCE";
2086 case T_CreatedbStmt:
2087 tag = "CREATE DATABASE";
2090 case T_AlterDatabaseStmt:
2091 tag = "ALTER DATABASE";
2094 case T_AlterDatabaseSetStmt:
2095 tag = "ALTER DATABASE";
2099 tag = "DROP DATABASE";
2110 case T_UnlistenStmt:
2123 if (((VacuumStmt *) parsetree)->options & VACOPT_VACUUM)
2133 case T_CreateTableAsStmt:
2134 switch (((CreateTableAsStmt *) parsetree)->relkind)
2137 if (((CreateTableAsStmt *) parsetree)->is_select_into)
2138 tag = "SELECT INTO";
2140 tag = "CREATE TABLE AS";
2142 case OBJECT_MATVIEW:
2143 tag = "CREATE MATERIALIZED VIEW";
2150 case T_RefreshMatViewStmt:
2151 tag = "REFRESH MATERIALIZED VIEW";
2154 case T_VariableSetStmt:
2155 switch (((VariableSetStmt *) parsetree)->kind)
2158 case VAR_SET_CURRENT:
2159 case VAR_SET_DEFAULT:
2172 case T_VariableShowStmt:
2177 switch (((DiscardStmt *) parsetree)->target)
2180 tag = "DISCARD ALL";
2183 tag = "DISCARD PLANS";
2186 tag = "DISCARD TEMP";
2193 case T_CreateTrigStmt:
2194 tag = "CREATE TRIGGER";
2197 case T_CreateEventTrigStmt:
2198 tag = "CREATE EVENT TRIGGER";
2201 case T_AlterEventTrigStmt:
2202 tag = "ALTER EVENT TRIGGER";
2205 case T_CreatePLangStmt:
2206 tag = "CREATE LANGUAGE";
2209 case T_CreateRoleStmt:
2210 tag = "CREATE ROLE";
2213 case T_AlterRoleStmt:
2217 case T_AlterRoleSetStmt:
2221 case T_DropRoleStmt:
2225 case T_DropOwnedStmt:
2229 case T_ReassignOwnedStmt:
2230 tag = "REASSIGN OWNED";
2237 case T_ConstraintsSetStmt:
2238 tag = "SET CONSTRAINTS";
2241 case T_CheckPointStmt:
2249 case T_CreateConversionStmt:
2250 tag = "CREATE CONVERSION";
2253 case T_CreateCastStmt:
2254 tag = "CREATE CAST";
2257 case T_CreateOpClassStmt:
2258 tag = "CREATE OPERATOR CLASS";
2261 case T_CreateOpFamilyStmt:
2262 tag = "CREATE OPERATOR FAMILY";
2265 case T_AlterOpFamilyStmt:
2266 tag = "ALTER OPERATOR FAMILY";
2269 case T_AlterTSDictionaryStmt:
2270 tag = "ALTER TEXT SEARCH DICTIONARY";
2273 case T_AlterTSConfigurationStmt:
2274 tag = "ALTER TEXT SEARCH CONFIGURATION";
2285 case T_DeallocateStmt:
2287 DeallocateStmt *stmt = (DeallocateStmt *) parsetree;
2289 if (stmt->name == NULL)
2290 tag = "DEALLOCATE ALL";
2296 /* already-planned queries */
2299 PlannedStmt *stmt = (PlannedStmt *) parsetree;
2301 switch (stmt->commandType)
2306 * We take a little extra care here so that the result
2307 * will be useful for complaints about read-only
2310 if (stmt->utilityStmt != NULL)
2312 Assert(IsA(stmt->utilityStmt, DeclareCursorStmt));
2313 tag = "DECLARE CURSOR";
2315 else if (stmt->rowMarks != NIL)
2317 /* not 100% but probably close enough */
2318 switch (((PlanRowMark *) linitial(stmt->rowMarks))->markType)
2320 case ROW_MARK_EXCLUSIVE:
2321 tag = "SELECT FOR UPDATE";
2323 case ROW_MARK_NOKEYEXCLUSIVE:
2324 tag = "SELECT FOR NO KEY UPDATE";
2326 case ROW_MARK_SHARE:
2327 tag = "SELECT FOR SHARE";
2329 case ROW_MARK_KEYSHARE:
2330 tag = "SELECT FOR KEY SHARE";
2332 case ROW_MARK_REFERENCE:
2354 elog(WARNING, "unrecognized commandType: %d",
2355 (int) stmt->commandType);
2362 /* parsed-and-rewritten-but-not-planned queries */
2365 Query *stmt = (Query *) parsetree;
2367 switch (stmt->commandType)
2372 * We take a little extra care here so that the result
2373 * will be useful for complaints about read-only
2376 if (stmt->utilityStmt != NULL)
2378 Assert(IsA(stmt->utilityStmt, DeclareCursorStmt));
2379 tag = "DECLARE CURSOR";
2381 else if (stmt->rowMarks != NIL)
2383 /* not 100% but probably close enough */
2384 switch (((RowMarkClause *) linitial(stmt->rowMarks))->strength)
2386 case LCS_FORKEYSHARE:
2387 tag = "SELECT FOR KEY SHARE";
2390 tag = "SELECT FOR SHARE";
2392 case LCS_FORNOKEYUPDATE:
2393 tag = "SELECT FOR NO KEY UPDATE";
2396 tag = "SELECT FOR UPDATE";
2416 tag = CreateCommandTag(stmt->utilityStmt);
2419 elog(WARNING, "unrecognized commandType: %d",
2420 (int) stmt->commandType);
2428 elog(WARNING, "unrecognized node type: %d",
2429 (int) nodeTag(parsetree));
2439 * GetCommandLogLevel
2440 * utility to get the minimum log_statement level for a command,
2441 * given either a raw (un-analyzed) parsetree or a planned query.
2443 * This must handle all command types, but since the vast majority
2444 * of 'em are utility commands, it seems sensible to keep it here.
2447 GetCommandLogLevel(Node *parsetree)
2451 switch (nodeTag(parsetree))
2453 /* raw plannable queries */
2461 if (((SelectStmt *) parsetree)->intoClause)
2462 lev = LOGSTMT_DDL; /* SELECT INTO */
2467 /* utility statements --- same whether raw or cooked */
2468 case T_TransactionStmt:
2472 case T_DeclareCursorStmt:
2476 case T_ClosePortalStmt:
2484 case T_CreateSchemaStmt:
2489 case T_CreateForeignTableStmt:
2493 case T_CreateTableSpaceStmt:
2494 case T_DropTableSpaceStmt:
2495 case T_AlterTableSpaceOptionsStmt:
2499 case T_CreateExtensionStmt:
2500 case T_AlterExtensionStmt:
2501 case T_AlterExtensionContentsStmt:
2505 case T_CreateFdwStmt:
2506 case T_AlterFdwStmt:
2507 case T_CreateForeignServerStmt:
2508 case T_AlterForeignServerStmt:
2509 case T_CreateUserMappingStmt:
2510 case T_AlterUserMappingStmt:
2511 case T_DropUserMappingStmt:
2519 case T_TruncateStmt:
2527 case T_SecLabelStmt:
2532 if (((CopyStmt *) parsetree)->is_from)
2540 PrepareStmt *stmt = (PrepareStmt *) parsetree;
2542 /* Look through a PREPARE to the contained stmt */
2543 lev = GetCommandLogLevel(stmt->query);
2549 ExecuteStmt *stmt = (ExecuteStmt *) parsetree;
2550 PreparedStatement *ps;
2552 /* Look through an EXECUTE to the referenced stmt */
2553 ps = FetchPreparedStatement(stmt->name, false);
2555 lev = GetCommandLogLevel(ps->plansource->raw_parse_tree);
2561 case T_DeallocateStmt:
2569 case T_AlterObjectSchemaStmt:
2573 case T_AlterOwnerStmt:
2577 case T_AlterTableStmt:
2581 case T_AlterDomainStmt:
2589 case T_GrantRoleStmt:
2593 case T_AlterDefaultPrivilegesStmt:
2601 case T_CompositeTypeStmt:
2605 case T_CreateEnumStmt:
2609 case T_CreateRangeStmt:
2613 case T_AlterEnumStmt:
2621 case T_CreateFunctionStmt:
2625 case T_AlterFunctionStmt:
2637 case T_CreateSeqStmt:
2641 case T_AlterSeqStmt:
2649 case T_CreatedbStmt:
2653 case T_AlterDatabaseStmt:
2657 case T_AlterDatabaseSetStmt:
2673 case T_UnlistenStmt:
2691 ExplainStmt *stmt = (ExplainStmt *) parsetree;
2692 bool analyze = false;
2695 /* Look through an EXPLAIN ANALYZE to the contained stmt */
2696 foreach(lc, stmt->options)
2698 DefElem *opt = (DefElem *) lfirst(lc);
2700 if (strcmp(opt->defname, "analyze") == 0)
2701 analyze = defGetBoolean(opt);
2702 /* don't "break", as explain.c will use the last value */
2705 return GetCommandLogLevel(stmt->query);
2707 /* Plain EXPLAIN isn't so interesting */
2712 case T_CreateTableAsStmt:
2716 case T_RefreshMatViewStmt:
2720 case T_VariableSetStmt:
2724 case T_VariableShowStmt:
2732 case T_CreateTrigStmt:
2736 case T_CreateEventTrigStmt:
2740 case T_AlterEventTrigStmt:
2744 case T_CreatePLangStmt:
2748 case T_CreateDomainStmt:
2752 case T_CreateRoleStmt:
2756 case T_AlterRoleStmt:
2760 case T_AlterRoleSetStmt:
2764 case T_DropRoleStmt:
2768 case T_DropOwnedStmt:
2772 case T_ReassignOwnedStmt:
2780 case T_ConstraintsSetStmt:
2784 case T_CheckPointStmt:
2789 lev = LOGSTMT_ALL; /* should this be DDL? */
2792 case T_CreateConversionStmt:
2796 case T_CreateCastStmt:
2800 case T_CreateOpClassStmt:
2804 case T_CreateOpFamilyStmt:
2808 case T_AlterOpFamilyStmt:
2812 case T_AlterTSDictionaryStmt:
2816 case T_AlterTSConfigurationStmt:
2820 /* already-planned queries */
2823 PlannedStmt *stmt = (PlannedStmt *) parsetree;
2825 switch (stmt->commandType)
2838 elog(WARNING, "unrecognized commandType: %d",
2839 (int) stmt->commandType);
2846 /* parsed-and-rewritten-but-not-planned queries */
2849 Query *stmt = (Query *) parsetree;
2851 switch (stmt->commandType)
2864 lev = GetCommandLogLevel(stmt->utilityStmt);
2868 elog(WARNING, "unrecognized commandType: %d",
2869 (int) stmt->commandType);
2878 elog(WARNING, "unrecognized node type: %d",
2879 (int) nodeTag(parsetree));