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-2017, 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 "access/xlog.h"
24 #include "catalog/catalog.h"
25 #include "catalog/namespace.h"
26 #include "catalog/toasting.h"
27 #include "commands/alter.h"
28 #include "commands/async.h"
29 #include "commands/cluster.h"
30 #include "commands/comment.h"
31 #include "commands/collationcmds.h"
32 #include "commands/conversioncmds.h"
33 #include "commands/copy.h"
34 #include "commands/createas.h"
35 #include "commands/dbcommands.h"
36 #include "commands/defrem.h"
37 #include "commands/discard.h"
38 #include "commands/event_trigger.h"
39 #include "commands/explain.h"
40 #include "commands/extension.h"
41 #include "commands/matview.h"
42 #include "commands/lockcmds.h"
43 #include "commands/policy.h"
44 #include "commands/portalcmds.h"
45 #include "commands/prepare.h"
46 #include "commands/proclang.h"
47 #include "commands/publicationcmds.h"
48 #include "commands/schemacmds.h"
49 #include "commands/seclabel.h"
50 #include "commands/sequence.h"
51 #include "commands/subscriptioncmds.h"
52 #include "commands/tablecmds.h"
53 #include "commands/tablespace.h"
54 #include "commands/trigger.h"
55 #include "commands/typecmds.h"
56 #include "commands/user.h"
57 #include "commands/vacuum.h"
58 #include "commands/view.h"
59 #include "miscadmin.h"
60 #include "parser/parse_utilcmd.h"
61 #include "postmaster/bgwriter.h"
62 #include "rewrite/rewriteDefine.h"
63 #include "rewrite/rewriteRemove.h"
64 #include "storage/fd.h"
65 #include "tcop/pquery.h"
66 #include "tcop/utility.h"
67 #include "utils/acl.h"
68 #include "utils/guc.h"
69 #include "utils/syscache.h"
72 /* Hook for plugins to get control in ProcessUtility() */
73 ProcessUtility_hook_type ProcessUtility_hook = NULL;
75 /* local function declarations */
76 static void ProcessUtilitySlow(ParseState *pstate,
78 const char *queryString,
79 ProcessUtilityContext context,
81 QueryEnvironment *queryEnv,
84 static void ExecDropStmt(DropStmt *stmt, bool isTopLevel);
88 * CommandIsReadOnly: is an executable query read-only?
90 * This is a much stricter test than we apply for XactReadOnly mode;
91 * the query must be *in truth* read-only, because the caller wishes
92 * not to do CommandCounterIncrement for it.
94 * Note: currently no need to support raw or analyzed queries here
97 CommandIsReadOnly(PlannedStmt *pstmt)
99 Assert(IsA(pstmt, PlannedStmt));
100 switch (pstmt->commandType)
103 if (pstmt->rowMarks != NIL)
104 return false; /* SELECT FOR [KEY] UPDATE/SHARE */
105 else if (pstmt->hasModifyingCTE)
106 return false; /* data-modifying CTE */
114 /* For now, treat all utility commands as read/write */
117 elog(WARNING, "unrecognized commandType: %d",
118 (int) pstmt->commandType);
125 * check_xact_readonly: is a utility command read-only?
127 * Here we use the loose rules of XactReadOnly mode: no permanent effects
128 * on the database are allowed.
131 check_xact_readonly(Node *parsetree)
133 /* Only perform the check if we have a reason to do so. */
134 if (!XactReadOnly && !IsInParallelMode())
138 * Note: Commands that need to do more complicated checking are handled
139 * elsewhere, in particular COPY and plannable statements do their own
140 * checking. However they should all call PreventCommandIfReadOnly or
141 * PreventCommandIfParallelMode to actually throw the error.
144 switch (nodeTag(parsetree))
146 case T_AlterDatabaseStmt:
147 case T_AlterDatabaseSetStmt:
148 case T_AlterDomainStmt:
149 case T_AlterFunctionStmt:
150 case T_AlterRoleStmt:
151 case T_AlterRoleSetStmt:
152 case T_AlterObjectDependsStmt:
153 case T_AlterObjectSchemaStmt:
154 case T_AlterOwnerStmt:
155 case T_AlterOperatorStmt:
157 case T_AlterTableMoveAllStmt:
158 case T_AlterTableStmt:
162 case T_CreateCastStmt:
163 case T_CreateEventTrigStmt:
164 case T_AlterEventTrigStmt:
165 case T_CreateConversionStmt:
167 case T_CreateDomainStmt:
168 case T_CreateFunctionStmt:
169 case T_CreateRoleStmt:
171 case T_CreatePLangStmt:
172 case T_CreateOpClassStmt:
173 case T_CreateOpFamilyStmt:
174 case T_AlterOpFamilyStmt:
176 case T_CreateSchemaStmt:
177 case T_CreateSeqStmt:
179 case T_CreateTableAsStmt:
180 case T_RefreshMatViewStmt:
181 case T_CreateTableSpaceStmt:
182 case T_CreateTransformStmt:
183 case T_CreateTrigStmt:
184 case T_CompositeTypeStmt:
185 case T_CreateEnumStmt:
186 case T_CreateRangeStmt:
187 case T_AlterEnumStmt:
191 case T_DropTableSpaceStmt:
194 case T_GrantRoleStmt:
195 case T_AlterDefaultPrivilegesStmt:
197 case T_DropOwnedStmt:
198 case T_ReassignOwnedStmt:
199 case T_AlterTSDictionaryStmt:
200 case T_AlterTSConfigurationStmt:
201 case T_CreateExtensionStmt:
202 case T_AlterExtensionStmt:
203 case T_AlterExtensionContentsStmt:
204 case T_CreateFdwStmt:
206 case T_CreateForeignServerStmt:
207 case T_AlterForeignServerStmt:
208 case T_CreateUserMappingStmt:
209 case T_AlterUserMappingStmt:
210 case T_DropUserMappingStmt:
211 case T_AlterTableSpaceOptionsStmt:
212 case T_CreateForeignTableStmt:
213 case T_ImportForeignSchemaStmt:
215 case T_CreatePublicationStmt:
216 case T_AlterPublicationStmt:
217 case T_CreateSubscriptionStmt:
218 case T_AlterSubscriptionStmt:
219 case T_DropSubscriptionStmt:
220 PreventCommandIfReadOnly(CreateCommandTag(parsetree));
221 PreventCommandIfParallelMode(CreateCommandTag(parsetree));
230 * PreventCommandIfReadOnly: throw error if XactReadOnly
232 * This is useful mainly to ensure consistency of the error message wording;
233 * most callers have checked XactReadOnly for themselves.
236 PreventCommandIfReadOnly(const char *cmdname)
240 (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
241 /* translator: %s is name of a SQL command, eg CREATE */
242 errmsg("cannot execute %s in a read-only transaction",
247 * PreventCommandIfParallelMode: throw error if current (sub)transaction is
250 * This is useful mainly to ensure consistency of the error message wording;
251 * most callers have checked IsInParallelMode() for themselves.
254 PreventCommandIfParallelMode(const char *cmdname)
256 if (IsInParallelMode())
258 (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
259 /* translator: %s is name of a SQL command, eg CREATE */
260 errmsg("cannot execute %s during a parallel operation",
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 * pstmt: PlannedStmt wrapper for the utility statement
307 * queryString: original source text of command
308 * context: identifies source of statement (toplevel client command,
309 * non-toplevel client command, subcommand of a larger utility command)
310 * params: parameters to use during execution
311 * queryEnv: environment for parse through execution (e.g., ephemeral named
312 * tables like trigger transition tables). May be NULL.
313 * dest: where to send results
314 * completionTag: points to a buffer of size COMPLETION_TAG_BUFSIZE
315 * in which to store a command completion status string.
317 * Caller MUST supply a queryString; it is not allowed (anymore) to pass NULL.
318 * If you really don't have source text, you can pass a constant string,
319 * perhaps "(query not available)".
321 * completionTag is only set nonempty if we want to return a nondefault status.
323 * completionTag may be NULL if caller doesn't want a status string.
325 * Note for users of ProcessUtility_hook: the same queryString may be passed
326 * to multiple invocations of ProcessUtility when processing a query string
327 * containing multiple semicolon-separated statements. One should use
328 * pstmt->stmt_location and pstmt->stmt_len to identify the substring
329 * containing the current statement. Keep in mind also that some utility
330 * statements (e.g., CREATE SCHEMA) will recurse to ProcessUtility to process
331 * sub-statements, often passing down the same queryString, stmt_location,
332 * and stmt_len that were given for the whole statement.
335 ProcessUtility(PlannedStmt *pstmt,
336 const char *queryString,
337 ProcessUtilityContext context,
338 ParamListInfo params,
339 QueryEnvironment *queryEnv,
343 Assert(IsA(pstmt, PlannedStmt));
344 Assert(pstmt->commandType == CMD_UTILITY);
345 Assert(queryString != NULL); /* required as of 8.4 */
348 * We provide a function hook variable that lets loadable plugins get
349 * control when ProcessUtility is called. Such a plugin would normally
350 * call standard_ProcessUtility().
352 if (ProcessUtility_hook)
353 (*ProcessUtility_hook) (pstmt, queryString,
354 context, params, queryEnv,
355 dest, completionTag);
357 standard_ProcessUtility(pstmt, queryString,
358 context, params, queryEnv,
359 dest, completionTag);
363 * standard_ProcessUtility itself deals only with utility commands for
364 * which we do not provide event trigger support. Commands that do have
365 * such support are passed down to ProcessUtilitySlow, which contains the
366 * necessary infrastructure for such triggers.
368 * This division is not just for performance: it's critical that the
369 * event trigger code not be invoked when doing START TRANSACTION for
370 * example, because we might need to refresh the event trigger cache,
371 * which requires being in a valid transaction.
374 standard_ProcessUtility(PlannedStmt *pstmt,
375 const char *queryString,
376 ProcessUtilityContext context,
377 ParamListInfo params,
378 QueryEnvironment *queryEnv,
382 Node *parsetree = pstmt->utilityStmt;
383 bool isTopLevel = (context == PROCESS_UTILITY_TOPLEVEL);
386 check_xact_readonly(parsetree);
389 completionTag[0] = '\0';
391 pstate = make_parsestate(NULL);
392 pstate->p_sourcetext = queryString;
394 switch (nodeTag(parsetree))
397 * ******************** transactions ********************
399 case T_TransactionStmt:
401 TransactionStmt *stmt = (TransactionStmt *) parsetree;
406 * START TRANSACTION, as defined by SQL99: Identical
407 * to BEGIN. Same code for both.
409 case TRANS_STMT_BEGIN:
410 case TRANS_STMT_START:
414 BeginTransactionBlock();
415 foreach(lc, stmt->options)
417 DefElem *item = (DefElem *) lfirst(lc);
419 if (strcmp(item->defname, "transaction_isolation") == 0)
420 SetPGVariable("transaction_isolation",
421 list_make1(item->arg),
423 else if (strcmp(item->defname, "transaction_read_only") == 0)
424 SetPGVariable("transaction_read_only",
425 list_make1(item->arg),
427 else if (strcmp(item->defname, "transaction_deferrable") == 0)
428 SetPGVariable("transaction_deferrable",
429 list_make1(item->arg),
435 case TRANS_STMT_COMMIT:
436 if (!EndTransactionBlock())
438 /* report unsuccessful commit in completionTag */
440 strcpy(completionTag, "ROLLBACK");
444 case TRANS_STMT_PREPARE:
445 PreventCommandDuringRecovery("PREPARE TRANSACTION");
446 if (!PrepareTransactionBlock(stmt->gid))
448 /* report unsuccessful commit in completionTag */
450 strcpy(completionTag, "ROLLBACK");
454 case TRANS_STMT_COMMIT_PREPARED:
455 PreventTransactionChain(isTopLevel, "COMMIT PREPARED");
456 PreventCommandDuringRecovery("COMMIT PREPARED");
457 FinishPreparedTransaction(stmt->gid, true);
460 case TRANS_STMT_ROLLBACK_PREPARED:
461 PreventTransactionChain(isTopLevel, "ROLLBACK PREPARED");
462 PreventCommandDuringRecovery("ROLLBACK PREPARED");
463 FinishPreparedTransaction(stmt->gid, false);
466 case TRANS_STMT_ROLLBACK:
467 UserAbortTransactionBlock();
470 case TRANS_STMT_SAVEPOINT:
475 RequireTransactionChain(isTopLevel, "SAVEPOINT");
477 foreach(cell, stmt->options)
479 DefElem *elem = lfirst(cell);
481 if (strcmp(elem->defname, "savepoint_name") == 0)
482 name = strVal(elem->arg);
485 Assert(PointerIsValid(name));
487 DefineSavepoint(name);
491 case TRANS_STMT_RELEASE:
492 RequireTransactionChain(isTopLevel, "RELEASE SAVEPOINT");
493 ReleaseSavepoint(stmt->options);
496 case TRANS_STMT_ROLLBACK_TO:
497 RequireTransactionChain(isTopLevel, "ROLLBACK TO SAVEPOINT");
498 RollbackToSavepoint(stmt->options);
501 * CommitTransactionCommand is in charge of
502 * re-defining the savepoint again
510 * Portal (cursor) manipulation
512 case T_DeclareCursorStmt:
513 PerformCursorOpen((DeclareCursorStmt *) parsetree, params,
514 queryString, isTopLevel);
517 case T_ClosePortalStmt:
519 ClosePortalStmt *stmt = (ClosePortalStmt *) parsetree;
521 CheckRestrictedOperation("CLOSE");
522 PerformPortalClose(stmt->portalname);
527 PerformPortalFetch((FetchStmt *) parsetree, dest,
532 ExecuteDoStmt((DoStmt *) parsetree);
535 case T_CreateTableSpaceStmt:
536 /* no event triggers for global objects */
537 PreventTransactionChain(isTopLevel, "CREATE TABLESPACE");
538 CreateTableSpace((CreateTableSpaceStmt *) parsetree);
541 case T_DropTableSpaceStmt:
542 /* no event triggers for global objects */
543 PreventTransactionChain(isTopLevel, "DROP TABLESPACE");
544 DropTableSpace((DropTableSpaceStmt *) parsetree);
547 case T_AlterTableSpaceOptionsStmt:
548 /* no event triggers for global objects */
549 AlterTableSpaceOptions((AlterTableSpaceOptionsStmt *) parsetree);
553 ExecuteTruncate((TruncateStmt *) parsetree);
560 DoCopy(pstate, (CopyStmt *) parsetree,
561 pstmt->stmt_location, pstmt->stmt_len,
564 snprintf(completionTag, COMPLETION_TAG_BUFSIZE,
565 "COPY " UINT64_FORMAT, processed);
570 CheckRestrictedOperation("PREPARE");
571 PrepareQuery((PrepareStmt *) parsetree, queryString,
572 pstmt->stmt_location, pstmt->stmt_len);
576 ExecuteQuery((ExecuteStmt *) parsetree, NULL,
578 dest, completionTag);
581 case T_DeallocateStmt:
582 CheckRestrictedOperation("DEALLOCATE");
583 DeallocateQuery((DeallocateStmt *) parsetree);
586 case T_GrantRoleStmt:
587 /* no event triggers for global objects */
588 GrantRole((GrantRoleStmt *) parsetree);
592 /* no event triggers for global objects */
593 PreventTransactionChain(isTopLevel, "CREATE DATABASE");
594 createdb(pstate, (CreatedbStmt *) parsetree);
597 case T_AlterDatabaseStmt:
598 /* no event triggers for global objects */
599 AlterDatabase(pstate, (AlterDatabaseStmt *) parsetree, isTopLevel);
602 case T_AlterDatabaseSetStmt:
603 /* no event triggers for global objects */
604 AlterDatabaseSet((AlterDatabaseSetStmt *) parsetree);
609 DropdbStmt *stmt = (DropdbStmt *) parsetree;
611 /* no event triggers for global objects */
612 PreventTransactionChain(isTopLevel, "DROP DATABASE");
613 dropdb(stmt->dbname, stmt->missing_ok);
617 /* Query-level asynchronous notification */
620 NotifyStmt *stmt = (NotifyStmt *) parsetree;
622 PreventCommandDuringRecovery("NOTIFY");
623 Async_Notify(stmt->conditionname, stmt->payload);
629 ListenStmt *stmt = (ListenStmt *) parsetree;
631 PreventCommandDuringRecovery("LISTEN");
632 CheckRestrictedOperation("LISTEN");
633 Async_Listen(stmt->conditionname);
639 UnlistenStmt *stmt = (UnlistenStmt *) parsetree;
641 PreventCommandDuringRecovery("UNLISTEN");
642 CheckRestrictedOperation("UNLISTEN");
643 if (stmt->conditionname)
644 Async_Unlisten(stmt->conditionname);
652 LoadStmt *stmt = (LoadStmt *) parsetree;
654 closeAllVfds(); /* probably not necessary... */
655 /* Allowed names are restricted if you're not superuser */
656 load_file(stmt->filename, !superuser());
661 /* we choose to allow this during "read only" transactions */
662 PreventCommandDuringRecovery("CLUSTER");
663 /* forbidden in parallel mode due to CommandIsReadOnly */
664 cluster((ClusterStmt *) parsetree, isTopLevel);
669 VacuumStmt *stmt = (VacuumStmt *) parsetree;
671 /* we choose to allow this during "read only" transactions */
672 PreventCommandDuringRecovery((stmt->options & VACOPT_VACUUM) ?
673 "VACUUM" : "ANALYZE");
674 /* forbidden in parallel mode due to CommandIsReadOnly */
675 ExecVacuum(stmt, isTopLevel);
680 ExplainQuery(pstate, (ExplainStmt *) parsetree, queryString, params,
684 case T_AlterSystemStmt:
685 PreventTransactionChain(isTopLevel, "ALTER SYSTEM");
686 AlterSystemSetConfigFile((AlterSystemStmt *) parsetree);
689 case T_VariableSetStmt:
690 ExecSetVariableStmt((VariableSetStmt *) parsetree, isTopLevel);
693 case T_VariableShowStmt:
695 VariableShowStmt *n = (VariableShowStmt *) parsetree;
697 GetPGVariable(n->name, dest);
702 /* should we allow DISCARD PLANS? */
703 CheckRestrictedOperation("DISCARD");
704 DiscardCommand((DiscardStmt *) parsetree, isTopLevel);
707 case T_CreateEventTrigStmt:
708 /* no event triggers on event triggers */
709 CreateEventTrigger((CreateEventTrigStmt *) parsetree);
712 case T_AlterEventTrigStmt:
713 /* no event triggers on event triggers */
714 AlterEventTrigger((AlterEventTrigStmt *) parsetree);
718 * ******************************** ROLE statements ****
720 case T_CreateRoleStmt:
721 /* no event triggers for global objects */
722 CreateRole(pstate, (CreateRoleStmt *) parsetree);
725 case T_AlterRoleStmt:
726 /* no event triggers for global objects */
727 AlterRole((AlterRoleStmt *) parsetree);
730 case T_AlterRoleSetStmt:
731 /* no event triggers for global objects */
732 AlterRoleSet((AlterRoleSetStmt *) parsetree);
736 /* no event triggers for global objects */
737 DropRole((DropRoleStmt *) parsetree);
740 case T_ReassignOwnedStmt:
741 /* no event triggers for global objects */
742 ReassignOwnedObjects((ReassignOwnedStmt *) parsetree);
748 * Since the lock would just get dropped immediately, LOCK TABLE
749 * outside a transaction block is presumed to be user error.
751 RequireTransactionChain(isTopLevel, "LOCK TABLE");
752 /* forbidden in parallel mode due to CommandIsReadOnly */
753 LockTableCommand((LockStmt *) parsetree);
756 case T_ConstraintsSetStmt:
757 WarnNoTransactionChain(isTopLevel, "SET CONSTRAINTS");
758 AfterTriggerSetState((ConstraintsSetStmt *) parsetree);
761 case T_CheckPointStmt:
764 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
765 errmsg("must be superuser to do CHECKPOINT")));
768 * You might think we should have a PreventCommandDuringRecovery()
769 * here, but we interpret a CHECKPOINT command during recovery as
770 * a request for a restartpoint instead. We allow this since it
771 * can be a useful way of reducing switchover time when using
772 * various forms of replication.
774 RequestCheckpoint(CHECKPOINT_IMMEDIATE | CHECKPOINT_WAIT |
775 (RecoveryInProgress() ? 0 : CHECKPOINT_FORCE));
780 ReindexStmt *stmt = (ReindexStmt *) parsetree;
782 /* we choose to allow this during "read only" transactions */
783 PreventCommandDuringRecovery("REINDEX");
784 /* forbidden in parallel mode due to CommandIsReadOnly */
787 case REINDEX_OBJECT_INDEX:
788 ReindexIndex(stmt->relation, stmt->options);
790 case REINDEX_OBJECT_TABLE:
791 ReindexTable(stmt->relation, stmt->options);
793 case REINDEX_OBJECT_SCHEMA:
794 case REINDEX_OBJECT_SYSTEM:
795 case REINDEX_OBJECT_DATABASE:
798 * This cannot run inside a user transaction block; if
799 * we were inside a transaction, then its commit- and
800 * start-transaction-command calls would not have the
803 PreventTransactionChain(isTopLevel,
804 (stmt->kind == REINDEX_OBJECT_SCHEMA) ? "REINDEX SCHEMA" :
805 (stmt->kind == REINDEX_OBJECT_SYSTEM) ? "REINDEX SYSTEM" :
807 ReindexMultipleTables(stmt->name, stmt->kind, stmt->options);
810 elog(ERROR, "unrecognized object type: %d",
818 * The following statements are supported by Event Triggers only
819 * in some cases, so we "fast path" them in the other cases.
824 GrantStmt *stmt = (GrantStmt *) parsetree;
826 if (EventTriggerSupportsGrantObjectType(stmt->objtype))
827 ProcessUtilitySlow(pstate, pstmt, queryString,
828 context, params, queryEnv,
829 dest, completionTag);
831 ExecuteGrantStmt(stmt);
837 DropStmt *stmt = (DropStmt *) parsetree;
839 if (EventTriggerSupportsObjectType(stmt->removeType))
840 ProcessUtilitySlow(pstate, pstmt, queryString,
841 context, params, queryEnv,
842 dest, completionTag);
844 ExecDropStmt(stmt, isTopLevel);
850 RenameStmt *stmt = (RenameStmt *) parsetree;
852 if (EventTriggerSupportsObjectType(stmt->renameType))
853 ProcessUtilitySlow(pstate, pstmt, queryString,
854 context, params, queryEnv,
855 dest, completionTag);
857 ExecRenameStmt(stmt);
861 case T_AlterObjectDependsStmt:
863 AlterObjectDependsStmt *stmt = (AlterObjectDependsStmt *) parsetree;
865 if (EventTriggerSupportsObjectType(stmt->objectType))
866 ProcessUtilitySlow(pstate, pstmt, queryString,
867 context, params, queryEnv,
868 dest, completionTag);
870 ExecAlterObjectDependsStmt(stmt, NULL);
874 case T_AlterObjectSchemaStmt:
876 AlterObjectSchemaStmt *stmt = (AlterObjectSchemaStmt *) parsetree;
878 if (EventTriggerSupportsObjectType(stmt->objectType))
879 ProcessUtilitySlow(pstate, pstmt, queryString,
880 context, params, queryEnv,
881 dest, completionTag);
883 ExecAlterObjectSchemaStmt(stmt, NULL);
887 case T_AlterOwnerStmt:
889 AlterOwnerStmt *stmt = (AlterOwnerStmt *) parsetree;
891 if (EventTriggerSupportsObjectType(stmt->objectType))
892 ProcessUtilitySlow(pstate, pstmt, queryString,
893 context, params, queryEnv,
894 dest, completionTag);
896 ExecAlterOwnerStmt(stmt);
902 CommentStmt *stmt = (CommentStmt *) parsetree;
904 if (EventTriggerSupportsObjectType(stmt->objtype))
905 ProcessUtilitySlow(pstate, pstmt, queryString,
906 context, params, queryEnv,
907 dest, completionTag);
915 SecLabelStmt *stmt = (SecLabelStmt *) parsetree;
917 if (EventTriggerSupportsObjectType(stmt->objtype))
918 ProcessUtilitySlow(pstate, pstmt, queryString,
919 context, params, queryEnv,
920 dest, completionTag);
922 ExecSecLabelStmt(stmt);
927 /* All other statement types have event trigger support */
928 ProcessUtilitySlow(pstate, pstmt, queryString,
929 context, params, queryEnv,
930 dest, completionTag);
934 free_parsestate(pstate);
938 * The "Slow" variant of ProcessUtility should only receive statements
939 * supported by the event triggers facility. Therefore, we always
940 * perform the trigger support calls if the context allows it.
943 ProcessUtilitySlow(ParseState *pstate,
945 const char *queryString,
946 ProcessUtilityContext context,
947 ParamListInfo params,
948 QueryEnvironment *queryEnv,
952 Node *parsetree = pstmt->utilityStmt;
953 bool isTopLevel = (context == PROCESS_UTILITY_TOPLEVEL);
954 bool isCompleteQuery = (context <= PROCESS_UTILITY_QUERY);
956 bool commandCollected = false;
957 ObjectAddress address;
958 ObjectAddress secondaryObject = InvalidObjectAddress;
960 /* All event trigger calls are done only when isCompleteQuery is true */
961 needCleanup = isCompleteQuery && EventTriggerBeginCompleteQuery();
963 /* PG_TRY block is to ensure we call EventTriggerEndCompleteQuery */
967 EventTriggerDDLCommandStart(parsetree);
969 switch (nodeTag(parsetree))
972 * relation and attribute manipulation
974 case T_CreateSchemaStmt:
975 CreateSchemaCommand((CreateSchemaStmt *) parsetree,
977 pstmt->stmt_location,
981 * EventTriggerCollectSimpleCommand called by
982 * CreateSchemaCommand
984 commandCollected = true;
988 case T_CreateForeignTableStmt:
993 /* Run parse analysis ... */
994 stmts = transformCreateStmt((CreateStmt *) parsetree,
1000 Node *stmt = (Node *) lfirst(l);
1002 if (IsA(stmt, CreateStmt))
1004 Datum toast_options;
1005 static char *validnsps[] = HEAP_RELOPT_NAMESPACES;
1007 /* Create the table itself */
1008 address = DefineRelation((CreateStmt *) stmt,
1012 EventTriggerCollectSimpleCommand(address,
1017 * Let NewRelationCreateToastTable decide if this
1018 * one needs a secondary relation too.
1020 CommandCounterIncrement();
1023 * parse and validate reloptions for the toast
1026 toast_options = transformRelOptions((Datum) 0,
1027 ((CreateStmt *) stmt)->options,
1032 (void) heap_reloptions(RELKIND_TOASTVALUE,
1036 NewRelationCreateToastTable(address.objectId,
1039 else if (IsA(stmt, CreateForeignTableStmt))
1041 /* Create the table itself */
1042 address = DefineRelation((CreateStmt *) stmt,
1043 RELKIND_FOREIGN_TABLE,
1046 CreateForeignTable((CreateForeignTableStmt *) stmt,
1048 EventTriggerCollectSimpleCommand(address,
1055 * Recurse for anything else. Note the recursive
1056 * call will stash the objects so created into our
1057 * event trigger context.
1059 PlannedStmt *wrapper;
1061 wrapper = makeNode(PlannedStmt);
1062 wrapper->commandType = CMD_UTILITY;
1063 wrapper->canSetTag = false;
1064 wrapper->utilityStmt = stmt;
1065 wrapper->stmt_location = pstmt->stmt_location;
1066 wrapper->stmt_len = pstmt->stmt_len;
1068 ProcessUtility(wrapper,
1070 PROCESS_UTILITY_SUBCOMMAND,
1077 /* Need CCI between commands */
1078 if (lnext(l) != NULL)
1079 CommandCounterIncrement();
1083 * The multiple commands generated here are stashed
1084 * individually, so disable collection below.
1086 commandCollected = true;
1090 case T_AlterTableStmt:
1092 AlterTableStmt *atstmt = (AlterTableStmt *) parsetree;
1099 * Figure out lock mode, and acquire lock. This also does
1100 * basic permissions checks, so that we won't wait for a
1101 * lock on (for example) a relation on which we have no
1104 lockmode = AlterTableGetLockLevel(atstmt->cmds);
1105 relid = AlterTableLookupRelation(atstmt, lockmode);
1107 if (OidIsValid(relid))
1109 /* Run parse analysis ... */
1110 stmts = transformAlterTableStmt(relid, atstmt,
1113 /* ... ensure we have an event trigger context ... */
1114 EventTriggerAlterTableStart(parsetree);
1115 EventTriggerAlterTableRelid(relid);
1120 Node *stmt = (Node *) lfirst(l);
1122 if (IsA(stmt, AlterTableStmt))
1124 /* Do the table alteration proper */
1125 AlterTable(relid, lockmode,
1126 (AlterTableStmt *) stmt);
1131 * Recurse for anything else. If we need to
1132 * do so, "close" the current complex-command
1133 * set, and start a new one at the bottom;
1134 * this is needed to ensure the ordering of
1135 * queued commands is consistent with the way
1136 * they are executed here.
1138 PlannedStmt *wrapper;
1140 EventTriggerAlterTableEnd();
1141 wrapper = makeNode(PlannedStmt);
1142 wrapper->commandType = CMD_UTILITY;
1143 wrapper->canSetTag = false;
1144 wrapper->utilityStmt = stmt;
1145 wrapper->stmt_location = pstmt->stmt_location;
1146 wrapper->stmt_len = pstmt->stmt_len;
1147 ProcessUtility(wrapper,
1149 PROCESS_UTILITY_SUBCOMMAND,
1154 EventTriggerAlterTableStart(parsetree);
1155 EventTriggerAlterTableRelid(relid);
1158 /* Need CCI between commands */
1159 if (lnext(l) != NULL)
1160 CommandCounterIncrement();
1164 EventTriggerAlterTableEnd();
1168 (errmsg("relation \"%s\" does not exist, skipping",
1169 atstmt->relation->relname)));
1172 /* ALTER TABLE stashes commands internally */
1173 commandCollected = true;
1176 case T_AlterDomainStmt:
1178 AlterDomainStmt *stmt = (AlterDomainStmt *) parsetree;
1181 * Some or all of these functions are recursive to cover
1182 * inherited things, so permission checks are done there.
1184 switch (stmt->subtype)
1186 case 'T': /* ALTER DOMAIN DEFAULT */
1189 * Recursively alter column default for table and,
1190 * if requested, for descendants
1193 AlterDomainDefault(stmt->typeName,
1196 case 'N': /* ALTER DOMAIN DROP NOT NULL */
1198 AlterDomainNotNull(stmt->typeName,
1201 case 'O': /* ALTER DOMAIN SET NOT NULL */
1203 AlterDomainNotNull(stmt->typeName,
1206 case 'C': /* ADD CONSTRAINT */
1208 AlterDomainAddConstraint(stmt->typeName,
1212 case 'X': /* DROP CONSTRAINT */
1214 AlterDomainDropConstraint(stmt->typeName,
1219 case 'V': /* VALIDATE CONSTRAINT */
1221 AlterDomainValidateConstraint(stmt->typeName,
1225 elog(ERROR, "unrecognized alter domain type: %d",
1226 (int) stmt->subtype);
1233 * ************* object creation / destruction **************
1237 DefineStmt *stmt = (DefineStmt *) parsetree;
1241 case OBJECT_AGGREGATE:
1243 DefineAggregate(pstate, stmt->defnames, stmt->args,
1247 case OBJECT_OPERATOR:
1248 Assert(stmt->args == NIL);
1249 address = DefineOperator(stmt->defnames,
1253 Assert(stmt->args == NIL);
1254 address = DefineType(pstate,
1258 case OBJECT_TSPARSER:
1259 Assert(stmt->args == NIL);
1260 address = DefineTSParser(stmt->defnames,
1263 case OBJECT_TSDICTIONARY:
1264 Assert(stmt->args == NIL);
1265 address = DefineTSDictionary(stmt->defnames,
1268 case OBJECT_TSTEMPLATE:
1269 Assert(stmt->args == NIL);
1270 address = DefineTSTemplate(stmt->defnames,
1273 case OBJECT_TSCONFIGURATION:
1274 Assert(stmt->args == NIL);
1275 address = DefineTSConfiguration(stmt->defnames,
1279 case OBJECT_COLLATION:
1280 Assert(stmt->args == NIL);
1281 address = DefineCollation(pstate,
1284 stmt->if_not_exists);
1287 elog(ERROR, "unrecognized define stmt type: %d",
1294 case T_IndexStmt: /* CREATE INDEX */
1296 IndexStmt *stmt = (IndexStmt *) parsetree;
1300 if (stmt->concurrent)
1301 PreventTransactionChain(isTopLevel,
1302 "CREATE INDEX CONCURRENTLY");
1305 * Look up the relation OID just once, right here at the
1306 * beginning, so that we don't end up repeating the name
1307 * lookup later and latching onto a different relation
1308 * partway through. To avoid lock upgrade hazards, it's
1309 * important that we take the strongest lock that will
1310 * eventually be needed here, so the lockmode calculation
1311 * needs to match what DefineIndex() does.
1313 lockmode = stmt->concurrent ? ShareUpdateExclusiveLock
1316 RangeVarGetRelidExtended(stmt->relation, lockmode,
1318 RangeVarCallbackOwnsRelation,
1321 /* Run parse analysis ... */
1322 stmt = transformIndexStmt(relid, stmt, queryString);
1325 EventTriggerAlterTableStart(parsetree);
1327 DefineIndex(relid, /* OID of heap relation */
1329 InvalidOid, /* no predefined OID */
1330 false, /* is_alter_table */
1331 true, /* check_rights */
1332 false, /* skip_build */
1336 * Add the CREATE INDEX node itself to stash right away;
1337 * if there were any commands stashed in the ALTER TABLE
1338 * code, we need them to appear after this one.
1340 EventTriggerCollectSimpleCommand(address, secondaryObject,
1342 commandCollected = true;
1343 EventTriggerAlterTableEnd();
1347 case T_CreateExtensionStmt:
1348 address = CreateExtension(pstate, (CreateExtensionStmt *) parsetree);
1351 case T_AlterExtensionStmt:
1352 address = ExecAlterExtensionStmt(pstate, (AlterExtensionStmt *) parsetree);
1355 case T_AlterExtensionContentsStmt:
1356 address = ExecAlterExtensionContentsStmt((AlterExtensionContentsStmt *) parsetree,
1360 case T_CreateFdwStmt:
1361 address = CreateForeignDataWrapper((CreateFdwStmt *) parsetree);
1364 case T_AlterFdwStmt:
1365 address = AlterForeignDataWrapper((AlterFdwStmt *) parsetree);
1368 case T_CreateForeignServerStmt:
1369 address = CreateForeignServer((CreateForeignServerStmt *) parsetree);
1372 case T_AlterForeignServerStmt:
1373 address = AlterForeignServer((AlterForeignServerStmt *) parsetree);
1376 case T_CreateUserMappingStmt:
1377 address = CreateUserMapping((CreateUserMappingStmt *) parsetree);
1380 case T_AlterUserMappingStmt:
1381 address = AlterUserMapping((AlterUserMappingStmt *) parsetree);
1384 case T_DropUserMappingStmt:
1385 RemoveUserMapping((DropUserMappingStmt *) parsetree);
1386 /* no commands stashed for DROP */
1387 commandCollected = true;
1390 case T_ImportForeignSchemaStmt:
1391 ImportForeignSchema((ImportForeignSchemaStmt *) parsetree);
1392 /* commands are stashed inside ImportForeignSchema */
1393 commandCollected = true;
1396 case T_CompositeTypeStmt: /* CREATE TYPE (composite) */
1398 CompositeTypeStmt *stmt = (CompositeTypeStmt *) parsetree;
1400 address = DefineCompositeType(stmt->typevar,
1405 case T_CreateEnumStmt: /* CREATE TYPE AS ENUM */
1406 address = DefineEnum((CreateEnumStmt *) parsetree);
1409 case T_CreateRangeStmt: /* CREATE TYPE AS RANGE */
1410 address = DefineRange((CreateRangeStmt *) parsetree);
1413 case T_AlterEnumStmt: /* ALTER TYPE (enum) */
1414 address = AlterEnum((AlterEnumStmt *) parsetree);
1417 case T_ViewStmt: /* CREATE VIEW */
1418 EventTriggerAlterTableStart(parsetree);
1419 address = DefineView((ViewStmt *) parsetree, queryString,
1420 pstmt->stmt_location, pstmt->stmt_len);
1421 EventTriggerCollectSimpleCommand(address, secondaryObject,
1423 /* stashed internally */
1424 commandCollected = true;
1425 EventTriggerAlterTableEnd();
1428 case T_CreateFunctionStmt: /* CREATE FUNCTION */
1429 address = CreateFunction(pstate, (CreateFunctionStmt *) parsetree);
1432 case T_AlterFunctionStmt: /* ALTER FUNCTION */
1433 address = AlterFunction(pstate, (AlterFunctionStmt *) parsetree);
1436 case T_RuleStmt: /* CREATE RULE */
1437 address = DefineRule((RuleStmt *) parsetree, queryString);
1440 case T_CreateSeqStmt:
1441 address = DefineSequence(pstate, (CreateSeqStmt *) parsetree);
1444 case T_AlterSeqStmt:
1445 address = AlterSequence(pstate, (AlterSeqStmt *) parsetree);
1448 case T_CreateTableAsStmt:
1449 address = ExecCreateTableAs((CreateTableAsStmt *) parsetree,
1450 queryString, params, queryEnv,
1454 case T_RefreshMatViewStmt:
1456 * REFRESH CONCURRENTLY executes some DDL commands internally.
1457 * Inhibit DDL command collection here to avoid those commands
1458 * from showing up in the deparsed command queue. The refresh
1459 * command itself is queued, which is enough.
1461 EventTriggerInhibitCommandCollection();
1464 address = ExecRefreshMatView((RefreshMatViewStmt *) parsetree,
1465 queryString, params, completionTag);
1469 EventTriggerUndoInhibitCommandCollection();
1473 EventTriggerUndoInhibitCommandCollection();
1476 case T_CreateTrigStmt:
1477 address = CreateTrigger((CreateTrigStmt *) parsetree,
1478 queryString, InvalidOid, InvalidOid,
1479 InvalidOid, InvalidOid, false);
1482 case T_CreatePLangStmt:
1483 address = CreateProceduralLanguage((CreatePLangStmt *) parsetree);
1486 case T_CreateDomainStmt:
1487 address = DefineDomain((CreateDomainStmt *) parsetree);
1490 case T_CreateConversionStmt:
1491 address = CreateConversionCommand((CreateConversionStmt *) parsetree);
1494 case T_CreateCastStmt:
1495 address = CreateCast((CreateCastStmt *) parsetree);
1498 case T_CreateOpClassStmt:
1499 DefineOpClass((CreateOpClassStmt *) parsetree);
1500 /* command is stashed in DefineOpClass */
1501 commandCollected = true;
1504 case T_CreateOpFamilyStmt:
1505 address = DefineOpFamily((CreateOpFamilyStmt *) parsetree);
1508 case T_CreateTransformStmt:
1509 address = CreateTransform((CreateTransformStmt *) parsetree);
1512 case T_AlterOpFamilyStmt:
1513 AlterOpFamily((AlterOpFamilyStmt *) parsetree);
1514 /* commands are stashed in AlterOpFamily */
1515 commandCollected = true;
1518 case T_AlterTSDictionaryStmt:
1519 address = AlterTSDictionary((AlterTSDictionaryStmt *) parsetree);
1522 case T_AlterTSConfigurationStmt:
1523 AlterTSConfiguration((AlterTSConfigurationStmt *) parsetree);
1526 * Commands are stashed in MakeConfigurationMapping and
1527 * DropConfigurationMapping, which are called from
1528 * AlterTSConfiguration
1530 commandCollected = true;
1533 case T_AlterTableMoveAllStmt:
1534 AlterTableMoveAll((AlterTableMoveAllStmt *) parsetree);
1535 /* commands are stashed in AlterTableMoveAll */
1536 commandCollected = true;
1540 ExecDropStmt((DropStmt *) parsetree, isTopLevel);
1541 /* no commands stashed for DROP */
1542 commandCollected = true;
1546 address = ExecRenameStmt((RenameStmt *) parsetree);
1549 case T_AlterObjectDependsStmt:
1551 ExecAlterObjectDependsStmt((AlterObjectDependsStmt *) parsetree,
1555 case T_AlterObjectSchemaStmt:
1557 ExecAlterObjectSchemaStmt((AlterObjectSchemaStmt *) parsetree,
1561 case T_AlterOwnerStmt:
1562 address = ExecAlterOwnerStmt((AlterOwnerStmt *) parsetree);
1565 case T_AlterOperatorStmt:
1566 address = AlterOperator((AlterOperatorStmt *) parsetree);
1570 address = CommentObject((CommentStmt *) parsetree);
1574 ExecuteGrantStmt((GrantStmt *) parsetree);
1575 /* commands are stashed in ExecGrantStmt_oids */
1576 commandCollected = true;
1579 case T_DropOwnedStmt:
1580 DropOwnedObjects((DropOwnedStmt *) parsetree);
1581 /* no commands stashed for DROP */
1582 commandCollected = true;
1585 case T_AlterDefaultPrivilegesStmt:
1586 ExecAlterDefaultPrivilegesStmt(pstate, (AlterDefaultPrivilegesStmt *) parsetree);
1587 EventTriggerCollectAlterDefPrivs((AlterDefaultPrivilegesStmt *) parsetree);
1588 commandCollected = true;
1591 case T_CreatePolicyStmt: /* CREATE POLICY */
1592 address = CreatePolicy((CreatePolicyStmt *) parsetree);
1595 case T_AlterPolicyStmt: /* ALTER POLICY */
1596 address = AlterPolicy((AlterPolicyStmt *) parsetree);
1599 case T_SecLabelStmt:
1600 address = ExecSecLabelStmt((SecLabelStmt *) parsetree);
1603 case T_CreateAmStmt:
1604 address = CreateAccessMethod((CreateAmStmt *) parsetree);
1607 case T_CreatePublicationStmt:
1608 address = CreatePublication((CreatePublicationStmt *) parsetree);
1611 case T_AlterPublicationStmt:
1612 AlterPublication((AlterPublicationStmt *) parsetree);
1614 * AlterPublication calls EventTriggerCollectSimpleCommand
1617 commandCollected = true;
1620 case T_CreateSubscriptionStmt:
1621 address = CreateSubscription((CreateSubscriptionStmt *) parsetree,
1625 case T_AlterSubscriptionStmt:
1626 address = AlterSubscription((AlterSubscriptionStmt *) parsetree);
1629 case T_DropSubscriptionStmt:
1630 DropSubscription((DropSubscriptionStmt *) parsetree, isTopLevel);
1631 /* no commands stashed for DROP */
1632 commandCollected = true;
1635 case T_CreateStatsStmt:
1636 address = CreateStatistics((CreateStatsStmt *) parsetree);
1639 case T_AlterCollationStmt:
1640 address = AlterCollation((AlterCollationStmt *) parsetree);
1644 elog(ERROR, "unrecognized node type: %d",
1645 (int) nodeTag(parsetree));
1650 * Remember the object so that ddl_command_end event triggers have
1653 if (!commandCollected)
1654 EventTriggerCollectSimpleCommand(address, secondaryObject,
1657 if (isCompleteQuery)
1659 EventTriggerSQLDrop(parsetree);
1660 EventTriggerDDLCommandEnd(parsetree);
1666 EventTriggerEndCompleteQuery();
1672 EventTriggerEndCompleteQuery();
1676 * Dispatch function for DropStmt
1679 ExecDropStmt(DropStmt *stmt, bool isTopLevel)
1681 switch (stmt->removeType)
1684 if (stmt->concurrent)
1685 PreventTransactionChain(isTopLevel,
1686 "DROP INDEX CONCURRENTLY");
1690 case OBJECT_SEQUENCE:
1692 case OBJECT_MATVIEW:
1693 case OBJECT_FOREIGN_TABLE:
1694 RemoveRelations(stmt);
1697 RemoveObjects(stmt);
1704 * UtilityReturnsTuples
1705 * Return "true" if this utility statement will send output to the
1708 * Generally, there should be a case here for each case in ProcessUtility
1709 * where "dest" is passed on.
1712 UtilityReturnsTuples(Node *parsetree)
1714 switch (nodeTag(parsetree))
1718 FetchStmt *stmt = (FetchStmt *) parsetree;
1723 portal = GetPortalByName(stmt->portalname);
1724 if (!PortalIsValid(portal))
1725 return false; /* not our business to raise error */
1726 return portal->tupDesc ? true : false;
1731 ExecuteStmt *stmt = (ExecuteStmt *) parsetree;
1732 PreparedStatement *entry;
1734 entry = FetchPreparedStatement(stmt->name, false);
1736 return false; /* not our business to raise error */
1737 if (entry->plansource->resultDesc)
1745 case T_VariableShowStmt:
1754 * UtilityTupleDescriptor
1755 * Fetch the actual output tuple descriptor for a utility statement
1756 * for which UtilityReturnsTuples() previously returned "true".
1758 * The returned descriptor is created in (or copied into) the current memory
1762 UtilityTupleDescriptor(Node *parsetree)
1764 switch (nodeTag(parsetree))
1768 FetchStmt *stmt = (FetchStmt *) parsetree;
1773 portal = GetPortalByName(stmt->portalname);
1774 if (!PortalIsValid(portal))
1775 return NULL; /* not our business to raise error */
1776 return CreateTupleDescCopy(portal->tupDesc);
1781 ExecuteStmt *stmt = (ExecuteStmt *) parsetree;
1782 PreparedStatement *entry;
1784 entry = FetchPreparedStatement(stmt->name, false);
1786 return NULL; /* not our business to raise error */
1787 return FetchPreparedStatementResultDesc(entry);
1791 return ExplainResultDesc((ExplainStmt *) parsetree);
1793 case T_VariableShowStmt:
1795 VariableShowStmt *n = (VariableShowStmt *) parsetree;
1797 return GetPGVariableResultDesc(n->name);
1807 * QueryReturnsTuples
1808 * Return "true" if this Query will send output to the destination.
1812 QueryReturnsTuples(Query *parsetree)
1814 switch (parsetree->commandType)
1817 /* returns tuples */
1822 /* the forms with RETURNING return tuples */
1823 if (parsetree->returningList)
1827 return UtilityReturnsTuples(parsetree->utilityStmt);
1830 /* probably shouldn't get here */
1833 return false; /* default */
1839 * UtilityContainsQuery
1840 * Return the contained Query, or NULL if there is none
1842 * Certain utility statements, such as EXPLAIN, contain a plannable Query.
1843 * This function encapsulates knowledge of exactly which ones do.
1844 * We assume it is invoked only on already-parse-analyzed statements
1845 * (else the contained parsetree isn't a Query yet).
1847 * In some cases (currently, only EXPLAIN of CREATE TABLE AS/SELECT INTO and
1848 * CREATE MATERIALIZED VIEW), potentially Query-containing utility statements
1849 * can be nested. This function will drill down to a non-utility Query, or
1850 * return NULL if none.
1853 UtilityContainsQuery(Node *parsetree)
1857 switch (nodeTag(parsetree))
1859 case T_DeclareCursorStmt:
1860 qry = castNode(Query, ((DeclareCursorStmt *) parsetree)->query);
1861 if (qry->commandType == CMD_UTILITY)
1862 return UtilityContainsQuery(qry->utilityStmt);
1866 qry = castNode(Query, ((ExplainStmt *) parsetree)->query);
1867 if (qry->commandType == CMD_UTILITY)
1868 return UtilityContainsQuery(qry->utilityStmt);
1871 case T_CreateTableAsStmt:
1872 qry = castNode(Query, ((CreateTableAsStmt *) parsetree)->query);
1873 if (qry->commandType == CMD_UTILITY)
1874 return UtilityContainsQuery(qry->utilityStmt);
1884 * AlterObjectTypeCommandTag
1885 * helper function for CreateCommandTag
1887 * This covers most cases where ALTER is used with an ObjectType enum.
1890 AlterObjectTypeCommandTag(ObjectType objtype)
1896 case OBJECT_AGGREGATE:
1897 tag = "ALTER AGGREGATE";
1899 case OBJECT_ATTRIBUTE:
1905 case OBJECT_COLLATION:
1906 tag = "ALTER COLLATION";
1909 tag = "ALTER TABLE";
1911 case OBJECT_CONVERSION:
1912 tag = "ALTER CONVERSION";
1914 case OBJECT_DATABASE:
1915 tag = "ALTER DATABASE";
1918 case OBJECT_DOMCONSTRAINT:
1919 tag = "ALTER DOMAIN";
1921 case OBJECT_EXTENSION:
1922 tag = "ALTER EXTENSION";
1925 tag = "ALTER FOREIGN DATA WRAPPER";
1927 case OBJECT_FOREIGN_SERVER:
1928 tag = "ALTER SERVER";
1930 case OBJECT_FOREIGN_TABLE:
1931 tag = "ALTER FOREIGN TABLE";
1933 case OBJECT_FUNCTION:
1934 tag = "ALTER FUNCTION";
1937 tag = "ALTER INDEX";
1939 case OBJECT_LANGUAGE:
1940 tag = "ALTER LANGUAGE";
1942 case OBJECT_LARGEOBJECT:
1943 tag = "ALTER LARGE OBJECT";
1945 case OBJECT_OPCLASS:
1946 tag = "ALTER OPERATOR CLASS";
1948 case OBJECT_OPERATOR:
1949 tag = "ALTER OPERATOR";
1951 case OBJECT_OPFAMILY:
1952 tag = "ALTER OPERATOR FAMILY";
1955 tag = "ALTER POLICY";
1964 tag = "ALTER SCHEMA";
1966 case OBJECT_SEQUENCE:
1967 tag = "ALTER SEQUENCE";
1970 case OBJECT_TABCONSTRAINT:
1971 tag = "ALTER TABLE";
1973 case OBJECT_TABLESPACE:
1974 tag = "ALTER TABLESPACE";
1976 case OBJECT_TRIGGER:
1977 tag = "ALTER TRIGGER";
1979 case OBJECT_EVENT_TRIGGER:
1980 tag = "ALTER EVENT TRIGGER";
1982 case OBJECT_TSCONFIGURATION:
1983 tag = "ALTER TEXT SEARCH CONFIGURATION";
1985 case OBJECT_TSDICTIONARY:
1986 tag = "ALTER TEXT SEARCH DICTIONARY";
1988 case OBJECT_TSPARSER:
1989 tag = "ALTER TEXT SEARCH PARSER";
1991 case OBJECT_TSTEMPLATE:
1992 tag = "ALTER TEXT SEARCH TEMPLATE";
2000 case OBJECT_MATVIEW:
2001 tag = "ALTER MATERIALIZED VIEW";
2003 case OBJECT_PUBLICATION:
2004 tag = "ALTER PUBLICATION";
2006 case OBJECT_SUBSCRIPTION:
2007 tag = "ALTER SUBSCRIPTION";
2009 case OBJECT_STATISTIC_EXT:
2010 tag = "ALTER STATISTICS";
2022 * utility to get a string representation of the command operation,
2023 * given either a raw (un-analyzed) parsetree, an analyzed Query,
2026 * This must handle all command types, but since the vast majority
2027 * of 'em are utility commands, it seems sensible to keep it here.
2029 * NB: all result strings must be shorter than COMPLETION_TAG_BUFSIZE.
2030 * Also, the result must point at a true constant (permanent storage).
2033 CreateCommandTag(Node *parsetree)
2037 switch (nodeTag(parsetree))
2039 /* recurse if we're given a RawStmt */
2041 tag = CreateCommandTag(((RawStmt *) parsetree)->stmt);
2044 /* raw plannable queries */
2061 /* utility statements --- same whether raw or cooked */
2062 case T_TransactionStmt:
2064 TransactionStmt *stmt = (TransactionStmt *) parsetree;
2068 case TRANS_STMT_BEGIN:
2072 case TRANS_STMT_START:
2073 tag = "START TRANSACTION";
2076 case TRANS_STMT_COMMIT:
2080 case TRANS_STMT_ROLLBACK:
2081 case TRANS_STMT_ROLLBACK_TO:
2085 case TRANS_STMT_SAVEPOINT:
2089 case TRANS_STMT_RELEASE:
2093 case TRANS_STMT_PREPARE:
2094 tag = "PREPARE TRANSACTION";
2097 case TRANS_STMT_COMMIT_PREPARED:
2098 tag = "COMMIT PREPARED";
2101 case TRANS_STMT_ROLLBACK_PREPARED:
2102 tag = "ROLLBACK PREPARED";
2112 case T_DeclareCursorStmt:
2113 tag = "DECLARE CURSOR";
2116 case T_ClosePortalStmt:
2118 ClosePortalStmt *stmt = (ClosePortalStmt *) parsetree;
2120 if (stmt->portalname == NULL)
2121 tag = "CLOSE CURSOR ALL";
2123 tag = "CLOSE CURSOR";
2129 FetchStmt *stmt = (FetchStmt *) parsetree;
2131 tag = (stmt->ismove) ? "MOVE" : "FETCH";
2135 case T_CreateDomainStmt:
2136 tag = "CREATE DOMAIN";
2139 case T_CreateSchemaStmt:
2140 tag = "CREATE SCHEMA";
2144 tag = "CREATE TABLE";
2147 case T_CreateTableSpaceStmt:
2148 tag = "CREATE TABLESPACE";
2151 case T_DropTableSpaceStmt:
2152 tag = "DROP TABLESPACE";
2155 case T_AlterTableSpaceOptionsStmt:
2156 tag = "ALTER TABLESPACE";
2159 case T_CreateExtensionStmt:
2160 tag = "CREATE EXTENSION";
2163 case T_AlterExtensionStmt:
2164 tag = "ALTER EXTENSION";
2167 case T_AlterExtensionContentsStmt:
2168 tag = "ALTER EXTENSION";
2171 case T_CreateFdwStmt:
2172 tag = "CREATE FOREIGN DATA WRAPPER";
2175 case T_AlterFdwStmt:
2176 tag = "ALTER FOREIGN DATA WRAPPER";
2179 case T_CreateForeignServerStmt:
2180 tag = "CREATE SERVER";
2183 case T_AlterForeignServerStmt:
2184 tag = "ALTER SERVER";
2187 case T_CreateUserMappingStmt:
2188 tag = "CREATE USER MAPPING";
2191 case T_AlterUserMappingStmt:
2192 tag = "ALTER USER MAPPING";
2195 case T_DropUserMappingStmt:
2196 tag = "DROP USER MAPPING";
2199 case T_CreateForeignTableStmt:
2200 tag = "CREATE FOREIGN TABLE";
2203 case T_ImportForeignSchemaStmt:
2204 tag = "IMPORT FOREIGN SCHEMA";
2208 switch (((DropStmt *) parsetree)->removeType)
2213 case OBJECT_SEQUENCE:
2214 tag = "DROP SEQUENCE";
2219 case OBJECT_MATVIEW:
2220 tag = "DROP MATERIALIZED VIEW";
2229 tag = "DROP DOMAIN";
2231 case OBJECT_COLLATION:
2232 tag = "DROP COLLATION";
2234 case OBJECT_CONVERSION:
2235 tag = "DROP CONVERSION";
2238 tag = "DROP SCHEMA";
2240 case OBJECT_TSPARSER:
2241 tag = "DROP TEXT SEARCH PARSER";
2243 case OBJECT_TSDICTIONARY:
2244 tag = "DROP TEXT SEARCH DICTIONARY";
2246 case OBJECT_TSTEMPLATE:
2247 tag = "DROP TEXT SEARCH TEMPLATE";
2249 case OBJECT_TSCONFIGURATION:
2250 tag = "DROP TEXT SEARCH CONFIGURATION";
2252 case OBJECT_FOREIGN_TABLE:
2253 tag = "DROP FOREIGN TABLE";
2255 case OBJECT_EXTENSION:
2256 tag = "DROP EXTENSION";
2258 case OBJECT_FUNCTION:
2259 tag = "DROP FUNCTION";
2261 case OBJECT_AGGREGATE:
2262 tag = "DROP AGGREGATE";
2264 case OBJECT_OPERATOR:
2265 tag = "DROP OPERATOR";
2267 case OBJECT_LANGUAGE:
2268 tag = "DROP LANGUAGE";
2273 case OBJECT_TRIGGER:
2274 tag = "DROP TRIGGER";
2276 case OBJECT_EVENT_TRIGGER:
2277 tag = "DROP EVENT TRIGGER";
2283 tag = "DROP FOREIGN DATA WRAPPER";
2285 case OBJECT_FOREIGN_SERVER:
2286 tag = "DROP SERVER";
2288 case OBJECT_OPCLASS:
2289 tag = "DROP OPERATOR CLASS";
2291 case OBJECT_OPFAMILY:
2292 tag = "DROP OPERATOR FAMILY";
2295 tag = "DROP POLICY";
2297 case OBJECT_TRANSFORM:
2298 tag = "DROP TRANSFORM";
2300 case OBJECT_ACCESS_METHOD:
2301 tag = "DROP ACCESS METHOD";
2303 case OBJECT_PUBLICATION:
2304 tag = "DROP PUBLICATION";
2306 case OBJECT_STATISTIC_EXT:
2307 tag = "DROP STATISTICS";
2314 case T_TruncateStmt:
2315 tag = "TRUNCATE TABLE";
2322 case T_SecLabelStmt:
2323 tag = "SECURITY LABEL";
2331 tag = AlterObjectTypeCommandTag(((RenameStmt *) parsetree)->renameType);
2334 case T_AlterObjectDependsStmt:
2335 tag = AlterObjectTypeCommandTag(((AlterObjectDependsStmt *) parsetree)->objectType);
2338 case T_AlterObjectSchemaStmt:
2339 tag = AlterObjectTypeCommandTag(((AlterObjectSchemaStmt *) parsetree)->objectType);
2342 case T_AlterOwnerStmt:
2343 tag = AlterObjectTypeCommandTag(((AlterOwnerStmt *) parsetree)->objectType);
2346 case T_AlterTableMoveAllStmt:
2347 tag = AlterObjectTypeCommandTag(((AlterTableMoveAllStmt *) parsetree)->objtype);
2350 case T_AlterTableStmt:
2351 tag = AlterObjectTypeCommandTag(((AlterTableStmt *) parsetree)->relkind);
2354 case T_AlterDomainStmt:
2355 tag = "ALTER DOMAIN";
2358 case T_AlterFunctionStmt:
2359 tag = "ALTER FUNCTION";
2364 GrantStmt *stmt = (GrantStmt *) parsetree;
2366 tag = (stmt->is_grant) ? "GRANT" : "REVOKE";
2370 case T_GrantRoleStmt:
2372 GrantRoleStmt *stmt = (GrantRoleStmt *) parsetree;
2374 tag = (stmt->is_grant) ? "GRANT ROLE" : "REVOKE ROLE";
2378 case T_AlterDefaultPrivilegesStmt:
2379 tag = "ALTER DEFAULT PRIVILEGES";
2383 switch (((DefineStmt *) parsetree)->kind)
2385 case OBJECT_AGGREGATE:
2386 tag = "CREATE AGGREGATE";
2388 case OBJECT_OPERATOR:
2389 tag = "CREATE OPERATOR";
2392 tag = "CREATE TYPE";
2394 case OBJECT_TSPARSER:
2395 tag = "CREATE TEXT SEARCH PARSER";
2397 case OBJECT_TSDICTIONARY:
2398 tag = "CREATE TEXT SEARCH DICTIONARY";
2400 case OBJECT_TSTEMPLATE:
2401 tag = "CREATE TEXT SEARCH TEMPLATE";
2403 case OBJECT_TSCONFIGURATION:
2404 tag = "CREATE TEXT SEARCH CONFIGURATION";
2406 case OBJECT_COLLATION:
2407 tag = "CREATE COLLATION";
2409 case OBJECT_ACCESS_METHOD:
2410 tag = "CREATE ACCESS METHOD";
2417 case T_CompositeTypeStmt:
2418 tag = "CREATE TYPE";
2421 case T_CreateEnumStmt:
2422 tag = "CREATE TYPE";
2425 case T_CreateRangeStmt:
2426 tag = "CREATE TYPE";
2429 case T_AlterEnumStmt:
2434 tag = "CREATE VIEW";
2437 case T_CreateFunctionStmt:
2438 tag = "CREATE FUNCTION";
2442 tag = "CREATE INDEX";
2446 tag = "CREATE RULE";
2449 case T_CreateSeqStmt:
2450 tag = "CREATE SEQUENCE";
2453 case T_AlterSeqStmt:
2454 tag = "ALTER SEQUENCE";
2461 case T_CreatedbStmt:
2462 tag = "CREATE DATABASE";
2465 case T_AlterDatabaseStmt:
2466 tag = "ALTER DATABASE";
2469 case T_AlterDatabaseSetStmt:
2470 tag = "ALTER DATABASE";
2474 tag = "DROP DATABASE";
2485 case T_UnlistenStmt:
2498 if (((VacuumStmt *) parsetree)->options & VACOPT_VACUUM)
2508 case T_CreateTableAsStmt:
2509 switch (((CreateTableAsStmt *) parsetree)->relkind)
2512 if (((CreateTableAsStmt *) parsetree)->is_select_into)
2513 tag = "SELECT INTO";
2515 tag = "CREATE TABLE AS";
2517 case OBJECT_MATVIEW:
2518 tag = "CREATE MATERIALIZED VIEW";
2525 case T_RefreshMatViewStmt:
2526 tag = "REFRESH MATERIALIZED VIEW";
2529 case T_AlterSystemStmt:
2530 tag = "ALTER SYSTEM";
2533 case T_VariableSetStmt:
2534 switch (((VariableSetStmt *) parsetree)->kind)
2537 case VAR_SET_CURRENT:
2538 case VAR_SET_DEFAULT:
2551 case T_VariableShowStmt:
2556 switch (((DiscardStmt *) parsetree)->target)
2559 tag = "DISCARD ALL";
2562 tag = "DISCARD PLANS";
2565 tag = "DISCARD TEMP";
2567 case DISCARD_SEQUENCES:
2568 tag = "DISCARD SEQUENCES";
2575 case T_CreateTransformStmt:
2576 tag = "CREATE TRANSFORM";
2579 case T_CreateTrigStmt:
2580 tag = "CREATE TRIGGER";
2583 case T_CreateEventTrigStmt:
2584 tag = "CREATE EVENT TRIGGER";
2587 case T_AlterEventTrigStmt:
2588 tag = "ALTER EVENT TRIGGER";
2591 case T_CreatePLangStmt:
2592 tag = "CREATE LANGUAGE";
2595 case T_CreateRoleStmt:
2596 tag = "CREATE ROLE";
2599 case T_AlterRoleStmt:
2603 case T_AlterRoleSetStmt:
2607 case T_DropRoleStmt:
2611 case T_DropOwnedStmt:
2615 case T_ReassignOwnedStmt:
2616 tag = "REASSIGN OWNED";
2623 case T_ConstraintsSetStmt:
2624 tag = "SET CONSTRAINTS";
2627 case T_CheckPointStmt:
2635 case T_CreateConversionStmt:
2636 tag = "CREATE CONVERSION";
2639 case T_CreateCastStmt:
2640 tag = "CREATE CAST";
2643 case T_CreateOpClassStmt:
2644 tag = "CREATE OPERATOR CLASS";
2647 case T_CreateOpFamilyStmt:
2648 tag = "CREATE OPERATOR FAMILY";
2651 case T_AlterOpFamilyStmt:
2652 tag = "ALTER OPERATOR FAMILY";
2655 case T_AlterOperatorStmt:
2656 tag = "ALTER OPERATOR";
2659 case T_AlterTSDictionaryStmt:
2660 tag = "ALTER TEXT SEARCH DICTIONARY";
2663 case T_AlterTSConfigurationStmt:
2664 tag = "ALTER TEXT SEARCH CONFIGURATION";
2667 case T_CreatePolicyStmt:
2668 tag = "CREATE POLICY";
2671 case T_AlterPolicyStmt:
2672 tag = "ALTER POLICY";
2675 case T_CreateAmStmt:
2676 tag = "CREATE ACCESS METHOD";
2679 case T_CreatePublicationStmt:
2680 tag = "CREATE PUBLICATION";
2683 case T_AlterPublicationStmt:
2684 tag = "ALTER PUBLICATION";
2687 case T_CreateSubscriptionStmt:
2688 tag = "CREATE SUBSCRIPTION";
2691 case T_AlterSubscriptionStmt:
2692 tag = "ALTER SUBSCRIPTION";
2695 case T_DropSubscriptionStmt:
2696 tag = "DROP SUBSCRIPTION";
2699 case T_AlterCollationStmt:
2700 tag = "ALTER COLLATION";
2711 case T_CreateStatsStmt:
2712 tag = "CREATE STATISTICS";
2715 case T_DeallocateStmt:
2717 DeallocateStmt *stmt = (DeallocateStmt *) parsetree;
2719 if (stmt->name == NULL)
2720 tag = "DEALLOCATE ALL";
2726 /* already-planned queries */
2729 PlannedStmt *stmt = (PlannedStmt *) parsetree;
2731 switch (stmt->commandType)
2736 * We take a little extra care here so that the result
2737 * will be useful for complaints about read-only
2740 if (stmt->rowMarks != NIL)
2742 /* not 100% but probably close enough */
2743 switch (((PlanRowMark *) linitial(stmt->rowMarks))->strength)
2745 case LCS_FORKEYSHARE:
2746 tag = "SELECT FOR KEY SHARE";
2749 tag = "SELECT FOR SHARE";
2751 case LCS_FORNOKEYUPDATE:
2752 tag = "SELECT FOR NO KEY UPDATE";
2755 tag = "SELECT FOR UPDATE";
2775 tag = CreateCommandTag(stmt->utilityStmt);
2778 elog(WARNING, "unrecognized commandType: %d",
2779 (int) stmt->commandType);
2786 /* parsed-and-rewritten-but-not-planned queries */
2789 Query *stmt = (Query *) parsetree;
2791 switch (stmt->commandType)
2796 * We take a little extra care here so that the result
2797 * will be useful for complaints about read-only
2800 if (stmt->rowMarks != NIL)
2802 /* not 100% but probably close enough */
2803 switch (((RowMarkClause *) linitial(stmt->rowMarks))->strength)
2805 case LCS_FORKEYSHARE:
2806 tag = "SELECT FOR KEY SHARE";
2809 tag = "SELECT FOR SHARE";
2811 case LCS_FORNOKEYUPDATE:
2812 tag = "SELECT FOR NO KEY UPDATE";
2815 tag = "SELECT FOR UPDATE";
2835 tag = CreateCommandTag(stmt->utilityStmt);
2838 elog(WARNING, "unrecognized commandType: %d",
2839 (int) stmt->commandType);
2847 elog(WARNING, "unrecognized node type: %d",
2848 (int) nodeTag(parsetree));
2858 * GetCommandLogLevel
2859 * utility to get the minimum log_statement level for a command,
2860 * given either a raw (un-analyzed) parsetree, an analyzed Query,
2863 * This must handle all command types, but since the vast majority
2864 * of 'em are utility commands, it seems sensible to keep it here.
2867 GetCommandLogLevel(Node *parsetree)
2871 switch (nodeTag(parsetree))
2873 /* recurse if we're given a RawStmt */
2875 lev = GetCommandLogLevel(((RawStmt *) parsetree)->stmt);
2878 /* raw plannable queries */
2886 if (((SelectStmt *) parsetree)->intoClause)
2887 lev = LOGSTMT_DDL; /* SELECT INTO */
2892 /* utility statements --- same whether raw or cooked */
2893 case T_TransactionStmt:
2897 case T_DeclareCursorStmt:
2901 case T_ClosePortalStmt:
2909 case T_CreateSchemaStmt:
2914 case T_CreateForeignTableStmt:
2918 case T_CreateTableSpaceStmt:
2919 case T_DropTableSpaceStmt:
2920 case T_AlterTableSpaceOptionsStmt:
2924 case T_CreateExtensionStmt:
2925 case T_AlterExtensionStmt:
2926 case T_AlterExtensionContentsStmt:
2930 case T_CreateFdwStmt:
2931 case T_AlterFdwStmt:
2932 case T_CreateForeignServerStmt:
2933 case T_AlterForeignServerStmt:
2934 case T_CreateUserMappingStmt:
2935 case T_AlterUserMappingStmt:
2936 case T_DropUserMappingStmt:
2937 case T_ImportForeignSchemaStmt:
2945 case T_TruncateStmt:
2953 case T_SecLabelStmt:
2958 if (((CopyStmt *) parsetree)->is_from)
2966 PrepareStmt *stmt = (PrepareStmt *) parsetree;
2968 /* Look through a PREPARE to the contained stmt */
2969 lev = GetCommandLogLevel(stmt->query);
2975 ExecuteStmt *stmt = (ExecuteStmt *) parsetree;
2976 PreparedStatement *ps;
2978 /* Look through an EXECUTE to the referenced stmt */
2979 ps = FetchPreparedStatement(stmt->name, false);
2980 if (ps && ps->plansource->raw_parse_tree)
2981 lev = GetCommandLogLevel(ps->plansource->raw_parse_tree->stmt);
2987 case T_DeallocateStmt:
2995 case T_AlterObjectDependsStmt:
2999 case T_AlterObjectSchemaStmt:
3003 case T_AlterOwnerStmt:
3007 case T_AlterTableMoveAllStmt:
3008 case T_AlterTableStmt:
3012 case T_AlterDomainStmt:
3020 case T_GrantRoleStmt:
3024 case T_AlterDefaultPrivilegesStmt:
3032 case T_CompositeTypeStmt:
3036 case T_CreateEnumStmt:
3040 case T_CreateRangeStmt:
3044 case T_AlterEnumStmt:
3052 case T_CreateFunctionStmt:
3056 case T_AlterFunctionStmt:
3068 case T_CreateSeqStmt:
3072 case T_AlterSeqStmt:
3080 case T_CreatedbStmt:
3084 case T_AlterDatabaseStmt:
3088 case T_AlterDatabaseSetStmt:
3104 case T_UnlistenStmt:
3122 ExplainStmt *stmt = (ExplainStmt *) parsetree;
3123 bool analyze = false;
3126 /* Look through an EXPLAIN ANALYZE to the contained stmt */
3127 foreach(lc, stmt->options)
3129 DefElem *opt = (DefElem *) lfirst(lc);
3131 if (strcmp(opt->defname, "analyze") == 0)
3132 analyze = defGetBoolean(opt);
3133 /* don't "break", as explain.c will use the last value */
3136 return GetCommandLogLevel(stmt->query);
3138 /* Plain EXPLAIN isn't so interesting */
3143 case T_CreateTableAsStmt:
3147 case T_RefreshMatViewStmt:
3151 case T_AlterSystemStmt:
3155 case T_VariableSetStmt:
3159 case T_VariableShowStmt:
3167 case T_CreateTrigStmt:
3171 case T_CreateEventTrigStmt:
3175 case T_AlterEventTrigStmt:
3179 case T_CreatePLangStmt:
3183 case T_CreateDomainStmt:
3187 case T_CreateRoleStmt:
3191 case T_AlterRoleStmt:
3195 case T_AlterRoleSetStmt:
3199 case T_DropRoleStmt:
3203 case T_DropOwnedStmt:
3207 case T_ReassignOwnedStmt:
3215 case T_ConstraintsSetStmt:
3219 case T_CheckPointStmt:
3224 lev = LOGSTMT_ALL; /* should this be DDL? */
3227 case T_CreateConversionStmt:
3231 case T_CreateCastStmt:
3235 case T_CreateOpClassStmt:
3239 case T_CreateOpFamilyStmt:
3243 case T_CreateTransformStmt:
3247 case T_AlterOpFamilyStmt:
3251 case T_CreatePolicyStmt:
3255 case T_AlterPolicyStmt:
3259 case T_AlterTSDictionaryStmt:
3263 case T_AlterTSConfigurationStmt:
3267 case T_CreateAmStmt:
3271 case T_CreatePublicationStmt:
3275 case T_AlterPublicationStmt:
3279 case T_CreateSubscriptionStmt:
3283 case T_AlterSubscriptionStmt:
3287 case T_DropSubscriptionStmt:
3291 /* already-planned queries */
3294 PlannedStmt *stmt = (PlannedStmt *) parsetree;
3296 switch (stmt->commandType)
3309 lev = GetCommandLogLevel(stmt->utilityStmt);
3313 elog(WARNING, "unrecognized commandType: %d",
3314 (int) stmt->commandType);
3321 /* parsed-and-rewritten-but-not-planned queries */
3324 Query *stmt = (Query *) parsetree;
3326 switch (stmt->commandType)
3339 lev = GetCommandLogLevel(stmt->utilityStmt);
3343 elog(WARNING, "unrecognized commandType: %d",
3344 (int) stmt->commandType);
3353 elog(WARNING, "unrecognized node type: %d",
3354 (int) nodeTag(parsetree));