LCOV - code coverage report
Current view: top level - src/backend/tcop - utility.c (source / functions) Hit Total Coverage
Test: PostgreSQL 13beta1 Lines: 1430 1930 74.1 %
Date: 2020-06-01 00:06:26 Functions: 16 17 94.1 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*-------------------------------------------------------------------------
       2             :  *
       3             :  * utility.c
       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
       6             :  *    systems.
       7             :  *
       8             :  * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
       9             :  * Portions Copyright (c) 1994, Regents of the University of California
      10             :  *
      11             :  *
      12             :  * IDENTIFICATION
      13             :  *    src/backend/tcop/utility.c
      14             :  *
      15             :  *-------------------------------------------------------------------------
      16             :  */
      17             : #include "postgres.h"
      18             : 
      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/pg_inherits.h"
      27             : #include "catalog/toasting.h"
      28             : #include "commands/alter.h"
      29             : #include "commands/async.h"
      30             : #include "commands/cluster.h"
      31             : #include "commands/collationcmds.h"
      32             : #include "commands/comment.h"
      33             : #include "commands/conversioncmds.h"
      34             : #include "commands/copy.h"
      35             : #include "commands/createas.h"
      36             : #include "commands/dbcommands.h"
      37             : #include "commands/defrem.h"
      38             : #include "commands/discard.h"
      39             : #include "commands/event_trigger.h"
      40             : #include "commands/explain.h"
      41             : #include "commands/extension.h"
      42             : #include "commands/lockcmds.h"
      43             : #include "commands/matview.h"
      44             : #include "commands/policy.h"
      45             : #include "commands/portalcmds.h"
      46             : #include "commands/prepare.h"
      47             : #include "commands/proclang.h"
      48             : #include "commands/publicationcmds.h"
      49             : #include "commands/schemacmds.h"
      50             : #include "commands/seclabel.h"
      51             : #include "commands/sequence.h"
      52             : #include "commands/subscriptioncmds.h"
      53             : #include "commands/tablecmds.h"
      54             : #include "commands/tablespace.h"
      55             : #include "commands/trigger.h"
      56             : #include "commands/typecmds.h"
      57             : #include "commands/user.h"
      58             : #include "commands/vacuum.h"
      59             : #include "commands/view.h"
      60             : #include "miscadmin.h"
      61             : #include "parser/parse_utilcmd.h"
      62             : #include "postmaster/bgwriter.h"
      63             : #include "rewrite/rewriteDefine.h"
      64             : #include "rewrite/rewriteRemove.h"
      65             : #include "storage/fd.h"
      66             : #include "tcop/pquery.h"
      67             : #include "tcop/utility.h"
      68             : #include "utils/acl.h"
      69             : #include "utils/guc.h"
      70             : #include "utils/lsyscache.h"
      71             : #include "utils/rel.h"
      72             : #include "utils/syscache.h"
      73             : 
      74             : /* Hook for plugins to get control in ProcessUtility() */
      75             : ProcessUtility_hook_type ProcessUtility_hook = NULL;
      76             : 
      77             : /* local function declarations */
      78             : static int  ClassifyUtilityCommandAsReadOnly(Node *parsetree);
      79             : static void ProcessUtilitySlow(ParseState *pstate,
      80             :                                PlannedStmt *pstmt,
      81             :                                const char *queryString,
      82             :                                ProcessUtilityContext context,
      83             :                                ParamListInfo params,
      84             :                                QueryEnvironment *queryEnv,
      85             :                                DestReceiver *dest,
      86             :                                QueryCompletion *qc);
      87             : static void ExecDropStmt(DropStmt *stmt, bool isTopLevel);
      88             : 
      89             : /*
      90             :  * CommandIsReadOnly: is an executable query read-only?
      91             :  *
      92             :  * This is a much stricter test than we apply for XactReadOnly mode;
      93             :  * the query must be *in truth* read-only, because the caller wishes
      94             :  * not to do CommandCounterIncrement for it.
      95             :  *
      96             :  * Note: currently no need to support raw or analyzed queries here
      97             :  */
      98             : bool
      99       10912 : CommandIsReadOnly(PlannedStmt *pstmt)
     100             : {
     101             :     Assert(IsA(pstmt, PlannedStmt));
     102       10912 :     switch (pstmt->commandType)
     103             :     {
     104       10912 :         case CMD_SELECT:
     105       10912 :             if (pstmt->rowMarks != NIL)
     106           0 :                 return false;   /* SELECT FOR [KEY] UPDATE/SHARE */
     107       10912 :             else if (pstmt->hasModifyingCTE)
     108           0 :                 return false;   /* data-modifying CTE */
     109             :             else
     110       10912 :                 return true;
     111           0 :         case CMD_UPDATE:
     112             :         case CMD_INSERT:
     113             :         case CMD_DELETE:
     114           0 :             return false;
     115           0 :         case CMD_UTILITY:
     116             :             /* For now, treat all utility commands as read/write */
     117           0 :             return false;
     118           0 :         default:
     119           0 :             elog(WARNING, "unrecognized commandType: %d",
     120             :                  (int) pstmt->commandType);
     121           0 :             break;
     122             :     }
     123           0 :     return false;
     124             : }
     125             : 
     126             : /*
     127             :  * Determine the degree to which a utility command is read only.
     128             :  *
     129             :  * Note the definitions of the relevant flags in src/include/utility/tcop.h.
     130             :  */
     131             : static int
     132      340458 : ClassifyUtilityCommandAsReadOnly(Node *parsetree)
     133             : {
     134      340458 :     switch (nodeTag(parsetree))
     135             :     {
     136      255820 :         case T_AlterCollationStmt:
     137             :         case T_AlterDatabaseSetStmt:
     138             :         case T_AlterDatabaseStmt:
     139             :         case T_AlterDefaultPrivilegesStmt:
     140             :         case T_AlterDomainStmt:
     141             :         case T_AlterEnumStmt:
     142             :         case T_AlterEventTrigStmt:
     143             :         case T_AlterExtensionContentsStmt:
     144             :         case T_AlterExtensionStmt:
     145             :         case T_AlterFdwStmt:
     146             :         case T_AlterForeignServerStmt:
     147             :         case T_AlterFunctionStmt:
     148             :         case T_AlterObjectDependsStmt:
     149             :         case T_AlterObjectSchemaStmt:
     150             :         case T_AlterOpFamilyStmt:
     151             :         case T_AlterOperatorStmt:
     152             :         case T_AlterOwnerStmt:
     153             :         case T_AlterPolicyStmt:
     154             :         case T_AlterPublicationStmt:
     155             :         case T_AlterRoleSetStmt:
     156             :         case T_AlterRoleStmt:
     157             :         case T_AlterSeqStmt:
     158             :         case T_AlterStatsStmt:
     159             :         case T_AlterSubscriptionStmt:
     160             :         case T_AlterTSConfigurationStmt:
     161             :         case T_AlterTSDictionaryStmt:
     162             :         case T_AlterTableMoveAllStmt:
     163             :         case T_AlterTableSpaceOptionsStmt:
     164             :         case T_AlterTableStmt:
     165             :         case T_AlterTypeStmt:
     166             :         case T_AlterUserMappingStmt:
     167             :         case T_CommentStmt:
     168             :         case T_CompositeTypeStmt:
     169             :         case T_CreateAmStmt:
     170             :         case T_CreateCastStmt:
     171             :         case T_CreateConversionStmt:
     172             :         case T_CreateDomainStmt:
     173             :         case T_CreateEnumStmt:
     174             :         case T_CreateEventTrigStmt:
     175             :         case T_CreateExtensionStmt:
     176             :         case T_CreateFdwStmt:
     177             :         case T_CreateForeignServerStmt:
     178             :         case T_CreateForeignTableStmt:
     179             :         case T_CreateFunctionStmt:
     180             :         case T_CreateOpClassStmt:
     181             :         case T_CreateOpFamilyStmt:
     182             :         case T_CreatePLangStmt:
     183             :         case T_CreatePolicyStmt:
     184             :         case T_CreatePublicationStmt:
     185             :         case T_CreateRangeStmt:
     186             :         case T_CreateRoleStmt:
     187             :         case T_CreateSchemaStmt:
     188             :         case T_CreateSeqStmt:
     189             :         case T_CreateStatsStmt:
     190             :         case T_CreateStmt:
     191             :         case T_CreateSubscriptionStmt:
     192             :         case T_CreateTableAsStmt:
     193             :         case T_CreateTableSpaceStmt:
     194             :         case T_CreateTransformStmt:
     195             :         case T_CreateTrigStmt:
     196             :         case T_CreateUserMappingStmt:
     197             :         case T_CreatedbStmt:
     198             :         case T_DefineStmt:
     199             :         case T_DropOwnedStmt:
     200             :         case T_DropRoleStmt:
     201             :         case T_DropStmt:
     202             :         case T_DropSubscriptionStmt:
     203             :         case T_DropTableSpaceStmt:
     204             :         case T_DropUserMappingStmt:
     205             :         case T_DropdbStmt:
     206             :         case T_GrantRoleStmt:
     207             :         case T_GrantStmt:
     208             :         case T_ImportForeignSchemaStmt:
     209             :         case T_IndexStmt:
     210             :         case T_ReassignOwnedStmt:
     211             :         case T_RefreshMatViewStmt:
     212             :         case T_RenameStmt:
     213             :         case T_RuleStmt:
     214             :         case T_SecLabelStmt:
     215             :         case T_TruncateStmt:
     216             :         case T_ViewStmt:
     217             :             {
     218             :                 /* DDL is not read-only, and neither is TRUNCATE. */
     219      255820 :                 return COMMAND_IS_NOT_READ_ONLY;
     220             :             }
     221             : 
     222          40 :         case T_AlterSystemStmt:
     223             :             {
     224             :                 /*
     225             :                  * Surprisingly, ALTER SYSTEM meets all our definitions of
     226             :                  * read-only: it changes nothing that affects the output of
     227             :                  * pg_dump, it doesn't write WAL or imperil the application of
     228             :                  * future WAL, and it doesn't depend on any state that needs
     229             :                  * to be synchronized with parallel workers.
     230             :                  *
     231             :                  * So, despite the fact that it writes to a file, it's read
     232             :                  * only!
     233             :                  */
     234          40 :                 return COMMAND_IS_STRICTLY_READ_ONLY;
     235             :             }
     236             : 
     237         768 :         case T_CallStmt:
     238             :         case T_DoStmt:
     239             :             {
     240             :                 /*
     241             :                  * Commands inside the DO block or the called procedure might
     242             :                  * not be read only, but they'll be checked separately when we
     243             :                  * try to execute them.  Here we only need to worry about the
     244             :                  * DO or CALL command itself.
     245             :                  */
     246         768 :                 return COMMAND_IS_STRICTLY_READ_ONLY;
     247             :             }
     248             : 
     249         110 :         case T_CheckPointStmt:
     250             :             {
     251             :                 /*
     252             :                  * You might think that this should not be permitted in
     253             :                  * recovery, but we interpret a CHECKPOINT command during
     254             :                  * recovery as a request for a restartpoint instead. We allow
     255             :                  * this since it can be a useful way of reducing switchover
     256             :                  * time when using various forms of replication.
     257             :                  */
     258         110 :                 return COMMAND_IS_STRICTLY_READ_ONLY;
     259             :             }
     260             : 
     261       29512 :         case T_ClosePortalStmt:
     262             :         case T_ConstraintsSetStmt:
     263             :         case T_DeallocateStmt:
     264             :         case T_DeclareCursorStmt:
     265             :         case T_DiscardStmt:
     266             :         case T_ExecuteStmt:
     267             :         case T_FetchStmt:
     268             :         case T_LoadStmt:
     269             :         case T_PrepareStmt:
     270             :         case T_UnlistenStmt:
     271             :         case T_VariableSetStmt:
     272             :             {
     273             :                 /*
     274             :                  * These modify only backend-local state, so they're OK to run
     275             :                  * in a read-only transaction or on a standby. However, they
     276             :                  * are disallowed in parallel mode, because they either rely
     277             :                  * upon or modify backend-local state that might not be
     278             :                  * synchronized among cooperating backends.
     279             :                  */
     280       29512 :                 return COMMAND_OK_IN_RECOVERY | COMMAND_OK_IN_READ_ONLY_TXN;
     281             :             }
     282             : 
     283       13440 :         case T_ClusterStmt:
     284             :         case T_ReindexStmt:
     285             :         case T_VacuumStmt:
     286             :             {
     287             :                 /*
     288             :                  * These commands write WAL, so they're not strictly
     289             :                  * read-only, and running them in parallel workers isn't
     290             :                  * supported.
     291             :                  *
     292             :                  * However, they don't change the database state in a way that
     293             :                  * would affect pg_dump output, so it's fine to run them in a
     294             :                  * read-only transaction. (CLUSTER might change the order of
     295             :                  * rows on disk, which could affect the ordering of pg_dump
     296             :                  * output, but that's not semantically significant.)
     297             :                  */
     298       13440 :                 return COMMAND_OK_IN_READ_ONLY_TXN;
     299             :             }
     300             : 
     301        4146 :         case T_CopyStmt:
     302             :             {
     303        4146 :                 CopyStmt   *stmt = (CopyStmt *) parsetree;
     304             : 
     305             :                 /*
     306             :                  * You might think that COPY FROM is not at all read only, but
     307             :                  * it's OK to copy into a temporary table, because that
     308             :                  * wouldn't change the output of pg_dump.  If the target table
     309             :                  * turns out to be non-temporary, DoCopy itself will call
     310             :                  * PreventCommandIfReadOnly.
     311             :                  */
     312        4146 :                 if (stmt->is_from)
     313        1056 :                     return COMMAND_OK_IN_READ_ONLY_TXN;
     314             :                 else
     315        3090 :                     return COMMAND_IS_STRICTLY_READ_ONLY;
     316             :             }
     317             : 
     318       10852 :         case T_ExplainStmt:
     319             :         case T_VariableShowStmt:
     320             :             {
     321             :                 /*
     322             :                  * These commands don't modify any data and are safe to run in
     323             :                  * a parallel worker.
     324             :                  */
     325       10852 :                 return COMMAND_IS_STRICTLY_READ_ONLY;
     326             :             }
     327             : 
     328         124 :         case T_ListenStmt:
     329             :         case T_NotifyStmt:
     330             :             {
     331             :                 /*
     332             :                  * NOTIFY requires an XID assignment, so it can't be permitted
     333             :                  * on a standby. Perhaps LISTEN could, since without NOTIFY it
     334             :                  * would be OK to just do nothing, at least until promotion,
     335             :                  * but we currently prohibit it lest the user get the wrong
     336             :                  * idea.
     337             :                  *
     338             :                  * (We do allow T_UnlistenStmt on a standby, though, because
     339             :                  * it's a no-op.)
     340             :                  */
     341         124 :                 return COMMAND_OK_IN_READ_ONLY_TXN;
     342             :             }
     343             : 
     344        4184 :         case T_LockStmt:
     345             :             {
     346        4184 :                 LockStmt   *stmt = (LockStmt *) parsetree;
     347             : 
     348             :                 /*
     349             :                  * Only weaker locker modes are allowed during recovery. The
     350             :                  * restrictions here must match those in
     351             :                  * LockAcquireExtended().
     352             :                  */
     353        4184 :                 if (stmt->mode > RowExclusiveLock)
     354         266 :                     return COMMAND_OK_IN_READ_ONLY_TXN;
     355             :                 else
     356        3918 :                     return COMMAND_IS_STRICTLY_READ_ONLY;
     357             :             }
     358             : 
     359       21462 :         case T_TransactionStmt:
     360             :             {
     361       21462 :                 TransactionStmt *stmt = (TransactionStmt *) parsetree;
     362             : 
     363             :                 /*
     364             :                  * PREPARE, COMMIT PREPARED, and ROLLBACK PREPARED all write
     365             :                  * WAL, so they're not read-only in the strict sense; but the
     366             :                  * first and third do not change pg_dump output, so they're OK
     367             :                  * in a read-only transactions.
     368             :                  *
     369             :                  * We also consider COMMIT PREPARED to be OK in a read-only
     370             :                  * transaction environment, by way of exception.
     371             :                  */
     372       21462 :                 switch (stmt->kind)
     373             :                 {
     374       21250 :                     case TRANS_STMT_BEGIN:
     375             :                     case TRANS_STMT_START:
     376             :                     case TRANS_STMT_COMMIT:
     377             :                     case TRANS_STMT_ROLLBACK:
     378             :                     case TRANS_STMT_SAVEPOINT:
     379             :                     case TRANS_STMT_RELEASE:
     380             :                     case TRANS_STMT_ROLLBACK_TO:
     381       21250 :                         return COMMAND_IS_STRICTLY_READ_ONLY;
     382             : 
     383         212 :                     case TRANS_STMT_PREPARE:
     384             :                     case TRANS_STMT_COMMIT_PREPARED:
     385             :                     case TRANS_STMT_ROLLBACK_PREPARED:
     386         212 :                         return COMMAND_OK_IN_READ_ONLY_TXN;
     387             :                 }
     388           0 :                 elog(ERROR, "unrecognized TransactionStmtKind: %d",
     389             :                      (int) stmt->kind);
     390             :                 return 0;       /* silence stupider compilers */
     391             :             }
     392             : 
     393           0 :         default:
     394           0 :             elog(ERROR, "unrecognized node type: %d",
     395             :                  (int) nodeTag(parsetree));
     396             :             return 0;           /* silence stupider compilers */
     397             :     }
     398             : }
     399             : 
     400             : /*
     401             :  * PreventCommandIfReadOnly: throw error if XactReadOnly
     402             :  *
     403             :  * This is useful partly to ensure consistency of the error message wording;
     404             :  * some callers have checked XactReadOnly for themselves.
     405             :  */
     406             : void
     407       59974 : PreventCommandIfReadOnly(const char *cmdname)
     408             : {
     409       59974 :     if (XactReadOnly)
     410          28 :         ereport(ERROR,
     411             :                 (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
     412             :         /* translator: %s is name of a SQL command, eg CREATE */
     413             :                  errmsg("cannot execute %s in a read-only transaction",
     414             :                         cmdname)));
     415       59946 : }
     416             : 
     417             : /*
     418             :  * PreventCommandIfParallelMode: throw error if current (sub)transaction is
     419             :  * in parallel mode.
     420             :  *
     421             :  * This is useful partly to ensure consistency of the error message wording;
     422             :  * some callers have checked IsInParallelMode() for themselves.
     423             :  */
     424             : void
     425      141378 : PreventCommandIfParallelMode(const char *cmdname)
     426             : {
     427      141378 :     if (IsInParallelMode())
     428           0 :         ereport(ERROR,
     429             :                 (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
     430             :         /* translator: %s is name of a SQL command, eg CREATE */
     431             :                  errmsg("cannot execute %s during a parallel operation",
     432             :                         cmdname)));
     433      141378 : }
     434             : 
     435             : /*
     436             :  * PreventCommandDuringRecovery: throw error if RecoveryInProgress
     437             :  *
     438             :  * The majority of operations that are unsafe in a Hot Standby
     439             :  * will be rejected by XactReadOnly tests.  However there are a few
     440             :  * commands that are allowed in "read-only" xacts but cannot be allowed
     441             :  * in Hot Standby mode.  Those commands should call this function.
     442             :  */
     443             : void
     444        7130 : PreventCommandDuringRecovery(const char *cmdname)
     445             : {
     446        7130 :     if (RecoveryInProgress())
     447           0 :         ereport(ERROR,
     448             :                 (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
     449             :         /* translator: %s is name of a SQL command, eg CREATE */
     450             :                  errmsg("cannot execute %s during recovery",
     451             :                         cmdname)));
     452        7130 : }
     453             : 
     454             : /*
     455             :  * CheckRestrictedOperation: throw error for hazardous command if we're
     456             :  * inside a security restriction context.
     457             :  *
     458             :  * This is needed to protect session-local state for which there is not any
     459             :  * better-defined protection mechanism, such as ownership.
     460             :  */
     461             : static void
     462        5810 : CheckRestrictedOperation(const char *cmdname)
     463             : {
     464        5810 :     if (InSecurityRestrictedOperation())
     465           0 :         ereport(ERROR,
     466             :                 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
     467             :         /* translator: %s is name of a SQL command, eg PREPARE */
     468             :                  errmsg("cannot execute %s within security-restricted operation",
     469             :                         cmdname)));
     470        5810 : }
     471             : 
     472             : /*
     473             :  * ProcessUtility
     474             :  *      general utility function invoker
     475             :  *
     476             :  *  pstmt: PlannedStmt wrapper for the utility statement
     477             :  *  queryString: original source text of command
     478             :  *  context: identifies source of statement (toplevel client command,
     479             :  *      non-toplevel client command, subcommand of a larger utility command)
     480             :  *  params: parameters to use during execution
     481             :  *  queryEnv: environment for parse through execution (e.g., ephemeral named
     482             :  *      tables like trigger transition tables).  May be NULL.
     483             :  *  dest: where to send results
     484             :  *  qc: where to store command completion status data.  May be NULL,
     485             :  *      but if not, then caller must have initialized it.
     486             :  *
     487             :  * Caller MUST supply a queryString; it is not allowed (anymore) to pass NULL.
     488             :  * If you really don't have source text, you can pass a constant string,
     489             :  * perhaps "(query not available)".
     490             :  *
     491             :  * Note for users of ProcessUtility_hook: the same queryString may be passed
     492             :  * to multiple invocations of ProcessUtility when processing a query string
     493             :  * containing multiple semicolon-separated statements.  One should use
     494             :  * pstmt->stmt_location and pstmt->stmt_len to identify the substring
     495             :  * containing the current statement.  Keep in mind also that some utility
     496             :  * statements (e.g., CREATE SCHEMA) will recurse to ProcessUtility to process
     497             :  * sub-statements, often passing down the same queryString, stmt_location,
     498             :  * and stmt_len that were given for the whole statement.
     499             :  */
     500             : void
     501      340458 : ProcessUtility(PlannedStmt *pstmt,
     502             :                const char *queryString,
     503             :                ProcessUtilityContext context,
     504             :                ParamListInfo params,
     505             :                QueryEnvironment *queryEnv,
     506             :                DestReceiver *dest,
     507             :                QueryCompletion *qc)
     508             : {
     509             :     Assert(IsA(pstmt, PlannedStmt));
     510             :     Assert(pstmt->commandType == CMD_UTILITY);
     511             :     Assert(queryString != NULL);    /* required as of 8.4 */
     512             :     Assert(qc == NULL || qc->commandTag == CMDTAG_UNKNOWN);
     513             : 
     514             :     /*
     515             :      * We provide a function hook variable that lets loadable plugins get
     516             :      * control when ProcessUtility is called.  Such a plugin would normally
     517             :      * call standard_ProcessUtility().
     518             :      */
     519      340458 :     if (ProcessUtility_hook)
     520         172 :         (*ProcessUtility_hook) (pstmt, queryString,
     521             :                                 context, params, queryEnv,
     522             :                                 dest, qc);
     523             :     else
     524      340286 :         standard_ProcessUtility(pstmt, queryString,
     525             :                                 context, params, queryEnv,
     526             :                                 dest, qc);
     527      333010 : }
     528             : 
     529             : /*
     530             :  * standard_ProcessUtility itself deals only with utility commands for
     531             :  * which we do not provide event trigger support.  Commands that do have
     532             :  * such support are passed down to ProcessUtilitySlow, which contains the
     533             :  * necessary infrastructure for such triggers.
     534             :  *
     535             :  * This division is not just for performance: it's critical that the
     536             :  * event trigger code not be invoked when doing START TRANSACTION for
     537             :  * example, because we might need to refresh the event trigger cache,
     538             :  * which requires being in a valid transaction.
     539             :  */
     540             : void
     541      340458 : standard_ProcessUtility(PlannedStmt *pstmt,
     542             :                         const char *queryString,
     543             :                         ProcessUtilityContext context,
     544             :                         ParamListInfo params,
     545             :                         QueryEnvironment *queryEnv,
     546             :                         DestReceiver *dest,
     547             :                         QueryCompletion *qc)
     548             : {
     549      340458 :     Node       *parsetree = pstmt->utilityStmt;
     550      340458 :     bool        isTopLevel = (context == PROCESS_UTILITY_TOPLEVEL);
     551      340458 :     bool        isAtomicContext = (!(context == PROCESS_UTILITY_TOPLEVEL || context == PROCESS_UTILITY_QUERY_NONATOMIC) || IsTransactionBlock());
     552             :     ParseState *pstate;
     553             :     int         readonly_flags;
     554             : 
     555             :     /* This can recurse, so check for excessive recursion */
     556      340458 :     check_stack_depth();
     557             : 
     558             :     /* Prohibit read/write commands in read-only states. */
     559      340458 :     readonly_flags = ClassifyUtilityCommandAsReadOnly(parsetree);
     560      340458 :     if (readonly_flags != COMMAND_IS_STRICTLY_READ_ONLY &&
     561      300430 :         (XactReadOnly || IsInParallelMode()))
     562             :     {
     563         334 :         CommandTag  commandtag = CreateCommandTag(parsetree);
     564             : 
     565         334 :         if ((readonly_flags & COMMAND_OK_IN_READ_ONLY_TXN) == 0)
     566           8 :             PreventCommandIfReadOnly(GetCommandTagName(commandtag));
     567         326 :         if ((readonly_flags & COMMAND_OK_IN_PARALLEL_MODE) == 0)
     568         326 :             PreventCommandIfParallelMode(GetCommandTagName(commandtag));
     569         326 :         if ((readonly_flags & COMMAND_OK_IN_RECOVERY) == 0)
     570           0 :             PreventCommandDuringRecovery(GetCommandTagName(commandtag));
     571             :     }
     572             : 
     573      340450 :     pstate = make_parsestate(NULL);
     574      340450 :     pstate->p_sourcetext = queryString;
     575      340450 :     pstate->p_queryEnv = queryEnv;
     576             : 
     577      340450 :     switch (nodeTag(parsetree))
     578             :     {
     579             :             /*
     580             :              * ******************** transactions ********************
     581             :              */
     582       21462 :         case T_TransactionStmt:
     583             :             {
     584       21462 :                 TransactionStmt *stmt = (TransactionStmt *) parsetree;
     585             : 
     586       21462 :                 switch (stmt->kind)
     587             :                 {
     588             :                         /*
     589             :                          * START TRANSACTION, as defined by SQL99: Identical
     590             :                          * to BEGIN.  Same code for both.
     591             :                          */
     592       10088 :                     case TRANS_STMT_BEGIN:
     593             :                     case TRANS_STMT_START:
     594       10088 :                         {
     595             :                             ListCell   *lc;
     596             : 
     597       10088 :                             BeginTransactionBlock();
     598       15576 :                             foreach(lc, stmt->options)
     599             :                             {
     600        5488 :                                 DefElem    *item = (DefElem *) lfirst(lc);
     601             : 
     602        5488 :                                 if (strcmp(item->defname, "transaction_isolation") == 0)
     603        4924 :                                     SetPGVariable("transaction_isolation",
     604        4924 :                                                   list_make1(item->arg),
     605             :                                                   true);
     606         564 :                                 else if (strcmp(item->defname, "transaction_read_only") == 0)
     607         550 :                                     SetPGVariable("transaction_read_only",
     608         550 :                                                   list_make1(item->arg),
     609             :                                                   true);
     610          14 :                                 else if (strcmp(item->defname, "transaction_deferrable") == 0)
     611          14 :                                     SetPGVariable("transaction_deferrable",
     612          14 :                                                   list_make1(item->arg),
     613             :                                                   true);
     614             :                             }
     615             :                         }
     616       10088 :                         break;
     617             : 
     618        8654 :                     case TRANS_STMT_COMMIT:
     619        8654 :                         if (!EndTransactionBlock(stmt->chain))
     620             :                         {
     621             :                             /* report unsuccessful commit in qc */
     622         566 :                             if (qc)
     623         566 :                                 SetQueryCompletion(qc, CMDTAG_ROLLBACK, 0);
     624             :                         }
     625        8634 :                         break;
     626             : 
     627         134 :                     case TRANS_STMT_PREPARE:
     628         134 :                         if (!PrepareTransactionBlock(stmt->gid))
     629             :                         {
     630             :                             /* report unsuccessful commit in qc */
     631           2 :                             if (qc)
     632           2 :                                 SetQueryCompletion(qc, CMDTAG_ROLLBACK, 0);
     633             :                         }
     634         134 :                         break;
     635             : 
     636          52 :                     case TRANS_STMT_COMMIT_PREPARED:
     637          52 :                         PreventInTransactionBlock(isTopLevel, "COMMIT PREPARED");
     638          52 :                         FinishPreparedTransaction(stmt->gid, true);
     639          46 :                         break;
     640             : 
     641          26 :                     case TRANS_STMT_ROLLBACK_PREPARED:
     642          26 :                         PreventInTransactionBlock(isTopLevel, "ROLLBACK PREPARED");
     643          26 :                         FinishPreparedTransaction(stmt->gid, false);
     644          20 :                         break;
     645             : 
     646        1138 :                     case TRANS_STMT_ROLLBACK:
     647        1138 :                         UserAbortTransactionBlock(stmt->chain);
     648        1118 :                         break;
     649             : 
     650         816 :                     case TRANS_STMT_SAVEPOINT:
     651         816 :                         RequireTransactionBlock(isTopLevel, "SAVEPOINT");
     652         812 :                         DefineSavepoint(stmt->savepoint_name);
     653         804 :                         break;
     654             : 
     655         148 :                     case TRANS_STMT_RELEASE:
     656         148 :                         RequireTransactionBlock(isTopLevel, "RELEASE SAVEPOINT");
     657         144 :                         ReleaseSavepoint(stmt->savepoint_name);
     658         140 :                         break;
     659             : 
     660         406 :                     case TRANS_STMT_ROLLBACK_TO:
     661         406 :                         RequireTransactionBlock(isTopLevel, "ROLLBACK TO SAVEPOINT");
     662         402 :                         RollbackToSavepoint(stmt->savepoint_name);
     663             : 
     664             :                         /*
     665             :                          * CommitTransactionCommand is in charge of
     666             :                          * re-defining the savepoint again
     667             :                          */
     668         394 :                         break;
     669             :                 }
     670       21378 :             }
     671       21378 :             break;
     672             : 
     673             :             /*
     674             :              * Portal (cursor) manipulation
     675             :              */
     676        1984 :         case T_DeclareCursorStmt:
     677        1984 :             PerformCursorOpen(pstate, (DeclareCursorStmt *) parsetree, params,
     678             :                               isTopLevel);
     679        1982 :             break;
     680             : 
     681        1646 :         case T_ClosePortalStmt:
     682             :             {
     683        1646 :                 ClosePortalStmt *stmt = (ClosePortalStmt *) parsetree;
     684             : 
     685        1646 :                 CheckRestrictedOperation("CLOSE");
     686        1646 :                 PerformPortalClose(stmt->portalname);
     687             :             }
     688        1644 :             break;
     689             : 
     690        4398 :         case T_FetchStmt:
     691        4398 :             PerformPortalFetch((FetchStmt *) parsetree, dest, qc);
     692        4330 :             break;
     693             : 
     694         534 :         case T_DoStmt:
     695         534 :             ExecuteDoStmt((DoStmt *) parsetree, isAtomicContext);
     696         272 :             break;
     697             : 
     698          38 :         case T_CreateTableSpaceStmt:
     699             :             /* no event triggers for global objects */
     700          38 :             PreventInTransactionBlock(isTopLevel, "CREATE TABLESPACE");
     701          38 :             CreateTableSpace((CreateTableSpaceStmt *) parsetree);
     702          26 :             break;
     703             : 
     704          20 :         case T_DropTableSpaceStmt:
     705             :             /* no event triggers for global objects */
     706          20 :             PreventInTransactionBlock(isTopLevel, "DROP TABLESPACE");
     707          20 :             DropTableSpace((DropTableSpaceStmt *) parsetree);
     708          16 :             break;
     709             : 
     710          16 :         case T_AlterTableSpaceOptionsStmt:
     711             :             /* no event triggers for global objects */
     712          16 :             AlterTableSpaceOptions((AlterTableSpaceOptionsStmt *) parsetree);
     713           8 :             break;
     714             : 
     715         790 :         case T_TruncateStmt:
     716         790 :             ExecuteTruncate((TruncateStmt *) parsetree);
     717         692 :             break;
     718             : 
     719        4146 :         case T_CopyStmt:
     720        3848 :             {
     721             :                 uint64      processed;
     722             : 
     723        4146 :                 DoCopy(pstate, (CopyStmt *) parsetree,
     724             :                        pstmt->stmt_location, pstmt->stmt_len,
     725             :                        &processed);
     726        3848 :                 if (qc)
     727        3848 :                     SetQueryCompletion(qc, CMDTAG_COPY, processed);
     728             :             }
     729        3848 :             break;
     730             : 
     731         300 :         case T_PrepareStmt:
     732         300 :             CheckRestrictedOperation("PREPARE");
     733         300 :             PrepareQuery(pstate, (PrepareStmt *) parsetree,
     734             :                          pstmt->stmt_location, pstmt->stmt_len);
     735         292 :             break;
     736             : 
     737         810 :         case T_ExecuteStmt:
     738         810 :             ExecuteQuery(pstate,
     739             :                          (ExecuteStmt *) parsetree, NULL,
     740             :                          params,
     741             :                          dest, qc);
     742         744 :             break;
     743             : 
     744        3768 :         case T_DeallocateStmt:
     745        3768 :             CheckRestrictedOperation("DEALLOCATE");
     746        3768 :             DeallocateQuery((DeallocateStmt *) parsetree);
     747        3768 :             break;
     748             : 
     749        1154 :         case T_GrantRoleStmt:
     750             :             /* no event triggers for global objects */
     751        1154 :             GrantRole((GrantRoleStmt *) parsetree);
     752        1138 :             break;
     753             : 
     754         960 :         case T_CreatedbStmt:
     755             :             /* no event triggers for global objects */
     756         960 :             PreventInTransactionBlock(isTopLevel, "CREATE DATABASE");
     757         960 :             createdb(pstate, (CreatedbStmt *) parsetree);
     758         958 :             break;
     759             : 
     760           6 :         case T_AlterDatabaseStmt:
     761             :             /* no event triggers for global objects */
     762           6 :             AlterDatabase(pstate, (AlterDatabaseStmt *) parsetree, isTopLevel);
     763           6 :             break;
     764             : 
     765         840 :         case T_AlterDatabaseSetStmt:
     766             :             /* no event triggers for global objects */
     767         840 :             AlterDatabaseSet((AlterDatabaseSetStmt *) parsetree);
     768         840 :             break;
     769             : 
     770          40 :         case T_DropdbStmt:
     771             :             /* no event triggers for global objects */
     772          40 :             PreventInTransactionBlock(isTopLevel, "DROP DATABASE");
     773          40 :             DropDatabase(pstate, (DropdbStmt *) parsetree);
     774          28 :             break;
     775             : 
     776             :             /* Query-level asynchronous notification */
     777          82 :         case T_NotifyStmt:
     778             :             {
     779          82 :                 NotifyStmt *stmt = (NotifyStmt *) parsetree;
     780             : 
     781          82 :                 Async_Notify(stmt->conditionname, stmt->payload);
     782             :             }
     783          82 :             break;
     784             : 
     785          42 :         case T_ListenStmt:
     786             :             {
     787          42 :                 ListenStmt *stmt = (ListenStmt *) parsetree;
     788             : 
     789          42 :                 CheckRestrictedOperation("LISTEN");
     790          42 :                 Async_Listen(stmt->conditionname);
     791             :             }
     792          42 :             break;
     793             : 
     794          34 :         case T_UnlistenStmt:
     795             :             {
     796          34 :                 UnlistenStmt *stmt = (UnlistenStmt *) parsetree;
     797             : 
     798          34 :                 CheckRestrictedOperation("UNLISTEN");
     799          34 :                 if (stmt->conditionname)
     800           4 :                     Async_Unlisten(stmt->conditionname);
     801             :                 else
     802          30 :                     Async_UnlistenAll();
     803             :             }
     804          34 :             break;
     805             : 
     806          18 :         case T_LoadStmt:
     807             :             {
     808          18 :                 LoadStmt   *stmt = (LoadStmt *) parsetree;
     809             : 
     810          18 :                 closeAllVfds(); /* probably not necessary... */
     811             :                 /* Allowed names are restricted if you're not superuser */
     812          18 :                 load_file(stmt->filename, !superuser());
     813             :             }
     814          18 :             break;
     815             : 
     816         234 :         case T_CallStmt:
     817         234 :             ExecuteCallStmt(castNode(CallStmt, parsetree), params, isAtomicContext, dest);
     818         198 :             break;
     819             : 
     820         104 :         case T_ClusterStmt:
     821         104 :             cluster((ClusterStmt *) parsetree, isTopLevel);
     822          96 :             break;
     823             : 
     824       13030 :         case T_VacuumStmt:
     825       13030 :             ExecVacuum(pstate, (VacuumStmt *) parsetree, isTopLevel);
     826       12926 :             break;
     827             : 
     828       10398 :         case T_ExplainStmt:
     829       10398 :             ExplainQuery(pstate, (ExplainStmt *) parsetree, params, dest);
     830       10370 :             break;
     831             : 
     832          40 :         case T_AlterSystemStmt:
     833          40 :             PreventInTransactionBlock(isTopLevel, "ALTER SYSTEM");
     834          40 :             AlterSystemSetConfigFile((AlterSystemStmt *) parsetree);
     835          40 :             break;
     836             : 
     837       16468 :         case T_VariableSetStmt:
     838       16468 :             ExecSetVariableStmt((VariableSetStmt *) parsetree, isTopLevel);
     839       16426 :             break;
     840             : 
     841         454 :         case T_VariableShowStmt:
     842             :             {
     843         454 :                 VariableShowStmt *n = (VariableShowStmt *) parsetree;
     844             : 
     845         454 :                 GetPGVariable(n->name, dest);
     846             :             }
     847         454 :             break;
     848             : 
     849          20 :         case T_DiscardStmt:
     850             :             /* should we allow DISCARD PLANS? */
     851          20 :             CheckRestrictedOperation("DISCARD");
     852          20 :             DiscardCommand((DiscardStmt *) parsetree, isTopLevel);
     853          20 :             break;
     854             : 
     855         108 :         case T_CreateEventTrigStmt:
     856             :             /* no event triggers on event triggers */
     857         108 :             CreateEventTrigger((CreateEventTrigStmt *) parsetree);
     858          64 :             break;
     859             : 
     860          20 :         case T_AlterEventTrigStmt:
     861             :             /* no event triggers on event triggers */
     862          20 :             AlterEventTrigger((AlterEventTrigStmt *) parsetree);
     863          20 :             break;
     864             : 
     865             :             /*
     866             :              * ******************************** ROLE statements ****
     867             :              */
     868         740 :         case T_CreateRoleStmt:
     869             :             /* no event triggers for global objects */
     870         740 :             CreateRole(pstate, (CreateRoleStmt *) parsetree);
     871         728 :             break;
     872             : 
     873         218 :         case T_AlterRoleStmt:
     874             :             /* no event triggers for global objects */
     875         218 :             AlterRole((AlterRoleStmt *) parsetree);
     876         194 :             break;
     877             : 
     878          58 :         case T_AlterRoleSetStmt:
     879             :             /* no event triggers for global objects */
     880          58 :             AlterRoleSet((AlterRoleSetStmt *) parsetree);
     881          50 :             break;
     882             : 
     883         752 :         case T_DropRoleStmt:
     884             :             /* no event triggers for global objects */
     885         752 :             DropRole((DropRoleStmt *) parsetree);
     886         666 :             break;
     887             : 
     888          16 :         case T_ReassignOwnedStmt:
     889             :             /* no event triggers for global objects */
     890          16 :             ReassignOwnedObjects((ReassignOwnedStmt *) parsetree);
     891           8 :             break;
     892             : 
     893        4184 :         case T_LockStmt:
     894             : 
     895             :             /*
     896             :              * Since the lock would just get dropped immediately, LOCK TABLE
     897             :              * outside a transaction block is presumed to be user error.
     898             :              */
     899        4184 :             RequireTransactionBlock(isTopLevel, "LOCK TABLE");
     900        4184 :             LockTableCommand((LockStmt *) parsetree);
     901        4118 :             break;
     902             : 
     903          66 :         case T_ConstraintsSetStmt:
     904          66 :             WarnNoTransactionBlock(isTopLevel, "SET CONSTRAINTS");
     905          66 :             AfterTriggerSetState((ConstraintsSetStmt *) parsetree);
     906          54 :             break;
     907             : 
     908         110 :         case T_CheckPointStmt:
     909         110 :             if (!superuser())
     910           0 :                 ereport(ERROR,
     911             :                         (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
     912             :                          errmsg("must be superuser to do CHECKPOINT")));
     913             : 
     914         110 :             RequestCheckpoint(CHECKPOINT_IMMEDIATE | CHECKPOINT_WAIT |
     915         110 :                               (RecoveryInProgress() ? 0 : CHECKPOINT_FORCE));
     916         110 :             break;
     917             : 
     918         306 :         case T_ReindexStmt:
     919             :             {
     920         306 :                 ReindexStmt *stmt = (ReindexStmt *) parsetree;
     921             : 
     922         306 :                 if (stmt->concurrent)
     923         154 :                     PreventInTransactionBlock(isTopLevel,
     924             :                                               "REINDEX CONCURRENTLY");
     925             : 
     926         294 :                 switch (stmt->kind)
     927             :                 {
     928          92 :                     case REINDEX_OBJECT_INDEX:
     929          92 :                         ReindexIndex(stmt->relation, stmt->options, stmt->concurrent);
     930          60 :                         break;
     931         130 :                     case REINDEX_OBJECT_TABLE:
     932         130 :                         ReindexTable(stmt->relation, stmt->options, stmt->concurrent);
     933         114 :                         break;
     934          72 :                     case REINDEX_OBJECT_SCHEMA:
     935             :                     case REINDEX_OBJECT_SYSTEM:
     936             :                     case REINDEX_OBJECT_DATABASE:
     937             : 
     938             :                         /*
     939             :                          * This cannot run inside a user transaction block; if
     940             :                          * we were inside a transaction, then its commit- and
     941             :                          * start-transaction-command calls would not have the
     942             :                          * intended effect!
     943             :                          */
     944          72 :                         PreventInTransactionBlock(isTopLevel,
     945         108 :                                                   (stmt->kind == REINDEX_OBJECT_SCHEMA) ? "REINDEX SCHEMA" :
     946          36 :                                                   (stmt->kind == REINDEX_OBJECT_SYSTEM) ? "REINDEX SYSTEM" :
     947             :                                                   "REINDEX DATABASE");
     948          68 :                         ReindexMultipleTables(stmt->name, stmt->kind, stmt->options, stmt->concurrent);
     949          54 :                         break;
     950           0 :                     default:
     951           0 :                         elog(ERROR, "unrecognized object type: %d",
     952             :                              (int) stmt->kind);
     953             :                         break;
     954             :                 }
     955             :             }
     956         228 :             break;
     957             : 
     958             :             /*
     959             :              * The following statements are supported by Event Triggers only
     960             :              * in some cases, so we "fast path" them in the other cases.
     961             :              */
     962             : 
     963       44926 :         case T_GrantStmt:
     964             :             {
     965       44926 :                 GrantStmt  *stmt = (GrantStmt *) parsetree;
     966             : 
     967       44926 :                 if (EventTriggerSupportsObjectType(stmt->objtype))
     968       44172 :                     ProcessUtilitySlow(pstate, pstmt, queryString,
     969             :                                        context, params, queryEnv,
     970             :                                        dest, qc);
     971             :                 else
     972         754 :                     ExecuteGrantStmt(stmt);
     973             :             }
     974       44850 :             break;
     975             : 
     976       13664 :         case T_DropStmt:
     977             :             {
     978       13664 :                 DropStmt   *stmt = (DropStmt *) parsetree;
     979             : 
     980       13664 :                 if (EventTriggerSupportsObjectType(stmt->removeType))
     981       13602 :                     ProcessUtilitySlow(pstate, pstmt, queryString,
     982             :                                        context, params, queryEnv,
     983             :                                        dest, qc);
     984             :                 else
     985          62 :                     ExecDropStmt(stmt, isTopLevel);
     986             :             }
     987       13050 :             break;
     988             : 
     989         742 :         case T_RenameStmt:
     990             :             {
     991         742 :                 RenameStmt *stmt = (RenameStmt *) parsetree;
     992             : 
     993         742 :                 if (EventTriggerSupportsObjectType(stmt->renameType))
     994         718 :                     ProcessUtilitySlow(pstate, pstmt, queryString,
     995             :                                        context, params, queryEnv,
     996             :                                        dest, qc);
     997             :                 else
     998          24 :                     ExecRenameStmt(stmt);
     999             :             }
    1000         502 :             break;
    1001             : 
    1002          46 :         case T_AlterObjectDependsStmt:
    1003             :             {
    1004          46 :                 AlterObjectDependsStmt *stmt = (AlterObjectDependsStmt *) parsetree;
    1005             : 
    1006          46 :                 if (EventTriggerSupportsObjectType(stmt->objectType))
    1007          46 :                     ProcessUtilitySlow(pstate, pstmt, queryString,
    1008             :                                        context, params, queryEnv,
    1009             :                                        dest, qc);
    1010             :                 else
    1011           0 :                     ExecAlterObjectDependsStmt(stmt, NULL);
    1012             :             }
    1013          46 :             break;
    1014             : 
    1015         244 :         case T_AlterObjectSchemaStmt:
    1016             :             {
    1017         244 :                 AlterObjectSchemaStmt *stmt = (AlterObjectSchemaStmt *) parsetree;
    1018             : 
    1019         244 :                 if (EventTriggerSupportsObjectType(stmt->objectType))
    1020         244 :                     ProcessUtilitySlow(pstate, pstmt, queryString,
    1021             :                                        context, params, queryEnv,
    1022             :                                        dest, qc);
    1023             :                 else
    1024           0 :                     ExecAlterObjectSchemaStmt(stmt, NULL);
    1025             :             }
    1026         162 :             break;
    1027             : 
    1028        1478 :         case T_AlterOwnerStmt:
    1029             :             {
    1030        1478 :                 AlterOwnerStmt *stmt = (AlterOwnerStmt *) parsetree;
    1031             : 
    1032        1478 :                 if (EventTriggerSupportsObjectType(stmt->objectType))
    1033        1436 :                     ProcessUtilitySlow(pstate, pstmt, queryString,
    1034             :                                        context, params, queryEnv,
    1035             :                                        dest, qc);
    1036             :                 else
    1037          42 :                     ExecAlterOwnerStmt(stmt);
    1038             :             }
    1039        1318 :             break;
    1040             : 
    1041       18610 :         case T_CommentStmt:
    1042             :             {
    1043       18610 :                 CommentStmt *stmt = (CommentStmt *) parsetree;
    1044             : 
    1045       18610 :                 if (EventTriggerSupportsObjectType(stmt->objtype))
    1046       17884 :                     ProcessUtilitySlow(pstate, pstmt, queryString,
    1047             :                                        context, params, queryEnv,
    1048             :                                        dest, qc);
    1049             :                 else
    1050         726 :                     CommentObject(stmt);
    1051       18520 :                 break;
    1052             :             }
    1053             : 
    1054          84 :         case T_SecLabelStmt:
    1055             :             {
    1056          84 :                 SecLabelStmt *stmt = (SecLabelStmt *) parsetree;
    1057             : 
    1058          84 :                 if (EventTriggerSupportsObjectType(stmt->objtype))
    1059          54 :                     ProcessUtilitySlow(pstate, pstmt, queryString,
    1060             :                                        context, params, queryEnv,
    1061             :                                        dest, qc);
    1062             :                 else
    1063          30 :                     ExecSecLabelStmt(stmt);
    1064          28 :                 break;
    1065             :             }
    1066             : 
    1067      170242 :         default:
    1068             :             /* All other statement types have event trigger support */
    1069      170242 :             ProcessUtilitySlow(pstate, pstmt, queryString,
    1070             :                                context, params, queryEnv,
    1071             :                                dest, qc);
    1072      165618 :             break;
    1073             :     }
    1074             : 
    1075      333010 :     free_parsestate(pstate);
    1076             : 
    1077             :     /*
    1078             :      * Make effects of commands visible, for instance so that
    1079             :      * PreCommit_on_commit_actions() can see them (see for example bug
    1080             :      * #15631).
    1081             :      */
    1082      333010 :     CommandCounterIncrement();
    1083      333010 : }
    1084             : 
    1085             : /*
    1086             :  * The "Slow" variant of ProcessUtility should only receive statements
    1087             :  * supported by the event triggers facility.  Therefore, we always
    1088             :  * perform the trigger support calls if the context allows it.
    1089             :  */
    1090             : static void
    1091      248398 : ProcessUtilitySlow(ParseState *pstate,
    1092             :                    PlannedStmt *pstmt,
    1093             :                    const char *queryString,
    1094             :                    ProcessUtilityContext context,
    1095             :                    ParamListInfo params,
    1096             :                    QueryEnvironment *queryEnv,
    1097             :                    DestReceiver *dest,
    1098             :                    QueryCompletion *qc)
    1099             : {
    1100      248398 :     Node       *parsetree = pstmt->utilityStmt;
    1101      248398 :     bool        isTopLevel = (context == PROCESS_UTILITY_TOPLEVEL);
    1102      248398 :     bool        isCompleteQuery = (context != PROCESS_UTILITY_SUBCOMMAND);
    1103             :     bool        needCleanup;
    1104      248398 :     bool        commandCollected = false;
    1105             :     ObjectAddress address;
    1106      248398 :     ObjectAddress secondaryObject = InvalidObjectAddress;
    1107             : 
    1108             :     /* All event trigger calls are done only when isCompleteQuery is true */
    1109      248398 :     needCleanup = isCompleteQuery && EventTriggerBeginCompleteQuery();
    1110             : 
    1111             :     /* PG_TRY block is to ensure we call EventTriggerEndCompleteQuery */
    1112      248398 :     PG_TRY();
    1113             :     {
    1114      248398 :         if (isCompleteQuery)
    1115      241566 :             EventTriggerDDLCommandStart(parsetree);
    1116             : 
    1117      248398 :         switch (nodeTag(parsetree))
    1118             :         {
    1119             :                 /*
    1120             :                  * relation and attribute manipulation
    1121             :                  */
    1122         714 :             case T_CreateSchemaStmt:
    1123         714 :                 CreateSchemaCommand((CreateSchemaStmt *) parsetree,
    1124             :                                     queryString,
    1125             :                                     pstmt->stmt_location,
    1126             :                                     pstmt->stmt_len);
    1127             : 
    1128             :                 /*
    1129             :                  * EventTriggerCollectSimpleCommand called by
    1130             :                  * CreateSchemaCommand
    1131             :                  */
    1132         692 :                 commandCollected = true;
    1133         692 :                 break;
    1134             : 
    1135       21366 :             case T_CreateStmt:
    1136             :             case T_CreateForeignTableStmt:
    1137             :                 {
    1138             :                     List       *stmts;
    1139             :                     ListCell   *l;
    1140             : 
    1141             :                     /* Run parse analysis ... */
    1142       21366 :                     stmts = transformCreateStmt((CreateStmt *) parsetree,
    1143             :                                                 queryString);
    1144             : 
    1145             :                     /* ... and do it */
    1146       48018 :                     foreach(l, stmts)
    1147             :                     {
    1148       27606 :                         Node       *stmt = (Node *) lfirst(l);
    1149             : 
    1150       27606 :                         if (IsA(stmt, CreateStmt))
    1151             :                         {
    1152             :                             Datum       toast_options;
    1153             :                             static char *validnsps[] = HEAP_RELOPT_NAMESPACES;
    1154             : 
    1155             :                             /* Create the table itself */
    1156       20976 :                             address = DefineRelation((CreateStmt *) stmt,
    1157             :                                                      RELKIND_RELATION,
    1158             :                                                      InvalidOid, NULL,
    1159             :                                                      queryString);
    1160       20340 :                             EventTriggerCollectSimpleCommand(address,
    1161             :                                                              secondaryObject,
    1162             :                                                              stmt);
    1163             : 
    1164             :                             /*
    1165             :                              * Let NewRelationCreateToastTable decide if this
    1166             :                              * one needs a secondary relation too.
    1167             :                              */
    1168       20340 :                             CommandCounterIncrement();
    1169             : 
    1170             :                             /*
    1171             :                              * parse and validate reloptions for the toast
    1172             :                              * table
    1173             :                              */
    1174       20340 :                             toast_options = transformRelOptions((Datum) 0,
    1175             :                                                                 ((CreateStmt *) stmt)->options,
    1176             :                                                                 "toast",
    1177             :                                                                 validnsps,
    1178             :                                                                 true,
    1179             :                                                                 false);
    1180       20340 :                             (void) heap_reloptions(RELKIND_TOASTVALUE,
    1181             :                                                    toast_options,
    1182             :                                                    true);
    1183             : 
    1184       20336 :                             NewRelationCreateToastTable(address.objectId,
    1185             :                                                         toast_options);
    1186             :                         }
    1187        6630 :                         else if (IsA(stmt, CreateForeignTableStmt))
    1188             :                         {
    1189             :                             /* Create the table itself */
    1190         276 :                             address = DefineRelation((CreateStmt *) stmt,
    1191             :                                                      RELKIND_FOREIGN_TABLE,
    1192             :                                                      InvalidOid, NULL,
    1193             :                                                      queryString);
    1194         262 :                             CreateForeignTable((CreateForeignTableStmt *) stmt,
    1195             :                                                address.objectId);
    1196         210 :                             EventTriggerCollectSimpleCommand(address,
    1197             :                                                              secondaryObject,
    1198             :                                                              stmt);
    1199             :                         }
    1200             :                         else
    1201             :                         {
    1202             :                             /*
    1203             :                              * Recurse for anything else.  Note the recursive
    1204             :                              * call will stash the objects so created into our
    1205             :                              * event trigger context.
    1206             :                              */
    1207             :                             PlannedStmt *wrapper;
    1208             : 
    1209        6354 :                             wrapper = makeNode(PlannedStmt);
    1210        6354 :                             wrapper->commandType = CMD_UTILITY;
    1211        6354 :                             wrapper->canSetTag = false;
    1212        6354 :                             wrapper->utilityStmt = stmt;
    1213        6354 :                             wrapper->stmt_location = pstmt->stmt_location;
    1214        6354 :                             wrapper->stmt_len = pstmt->stmt_len;
    1215             : 
    1216        6354 :                             ProcessUtility(wrapper,
    1217             :                                            queryString,
    1218             :                                            PROCESS_UTILITY_SUBCOMMAND,
    1219             :                                            params,
    1220             :                                            NULL,
    1221             :                                            None_Receiver,
    1222             :                                            NULL);
    1223             :                         }
    1224             : 
    1225             :                         /* Need CCI between commands */
    1226       26754 :                         if (lnext(stmts, l) != NULL)
    1227        6350 :                             CommandCounterIncrement();
    1228             :                     }
    1229             : 
    1230             :                     /*
    1231             :                      * The multiple commands generated here are stashed
    1232             :                      * individually, so disable collection below.
    1233             :                      */
    1234       20412 :                     commandCollected = true;
    1235             :                 }
    1236       20412 :                 break;
    1237             : 
    1238       11124 :             case T_AlterTableStmt:
    1239             :                 {
    1240       11124 :                     AlterTableStmt *atstmt = (AlterTableStmt *) parsetree;
    1241             :                     Oid         relid;
    1242             :                     LOCKMODE    lockmode;
    1243             : 
    1244             :                     /*
    1245             :                      * Figure out lock mode, and acquire lock.  This also does
    1246             :                      * basic permissions checks, so that we won't wait for a
    1247             :                      * lock on (for example) a relation on which we have no
    1248             :                      * permissions.
    1249             :                      */
    1250       11124 :                     lockmode = AlterTableGetLockLevel(atstmt->cmds);
    1251       11124 :                     relid = AlterTableLookupRelation(atstmt, lockmode);
    1252             : 
    1253       11082 :                     if (OidIsValid(relid))
    1254             :                     {
    1255             :                         AlterTableUtilityContext atcontext;
    1256             : 
    1257             :                         /* Set up info needed for recursive callbacks ... */
    1258       10990 :                         atcontext.pstmt = pstmt;
    1259       10990 :                         atcontext.queryString = queryString;
    1260       10990 :                         atcontext.relid = relid;
    1261       10990 :                         atcontext.params = params;
    1262       10990 :                         atcontext.queryEnv = queryEnv;
    1263             : 
    1264             :                         /* ... ensure we have an event trigger context ... */
    1265       10990 :                         EventTriggerAlterTableStart(parsetree);
    1266       10990 :                         EventTriggerAlterTableRelid(relid);
    1267             : 
    1268             :                         /* ... and do it */
    1269       10990 :                         AlterTable(atstmt, lockmode, &atcontext);
    1270             : 
    1271             :                         /* done */
    1272        9416 :                         EventTriggerAlterTableEnd();
    1273             :                     }
    1274             :                     else
    1275          92 :                         ereport(NOTICE,
    1276             :                                 (errmsg("relation \"%s\" does not exist, skipping",
    1277             :                                         atstmt->relation->relname)));
    1278             :                 }
    1279             : 
    1280             :                 /* ALTER TABLE stashes commands internally */
    1281        9508 :                 commandCollected = true;
    1282        9508 :                 break;
    1283             : 
    1284         152 :             case T_AlterDomainStmt:
    1285             :                 {
    1286         152 :                     AlterDomainStmt *stmt = (AlterDomainStmt *) parsetree;
    1287             : 
    1288             :                     /*
    1289             :                      * Some or all of these functions are recursive to cover
    1290             :                      * inherited things, so permission checks are done there.
    1291             :                      */
    1292         152 :                     switch (stmt->subtype)
    1293             :                     {
    1294           8 :                         case 'T':   /* ALTER DOMAIN DEFAULT */
    1295             : 
    1296             :                             /*
    1297             :                              * Recursively alter column default for table and,
    1298             :                              * if requested, for descendants
    1299             :                              */
    1300             :                             address =
    1301           8 :                                 AlterDomainDefault(stmt->typeName,
    1302             :                                                    stmt->def);
    1303           8 :                             break;
    1304           8 :                         case 'N':   /* ALTER DOMAIN DROP NOT NULL */
    1305             :                             address =
    1306           8 :                                 AlterDomainNotNull(stmt->typeName,
    1307             :                                                    false);
    1308           8 :                             break;
    1309          16 :                         case 'O':   /* ALTER DOMAIN SET NOT NULL */
    1310             :                             address =
    1311          16 :                                 AlterDomainNotNull(stmt->typeName,
    1312             :                                                    true);
    1313           8 :                             break;
    1314          84 :                         case 'C':   /* ADD CONSTRAINT */
    1315             :                             address =
    1316          84 :                                 AlterDomainAddConstraint(stmt->typeName,
    1317             :                                                          stmt->def,
    1318             :                                                          &secondaryObject);
    1319          44 :                             break;
    1320          28 :                         case 'X':   /* DROP CONSTRAINT */
    1321             :                             address =
    1322          56 :                                 AlterDomainDropConstraint(stmt->typeName,
    1323          28 :                                                           stmt->name,
    1324             :                                                           stmt->behavior,
    1325          28 :                                                           stmt->missing_ok);
    1326          24 :                             break;
    1327           8 :                         case 'V':   /* VALIDATE CONSTRAINT */
    1328             :                             address =
    1329           8 :                                 AlterDomainValidateConstraint(stmt->typeName,
    1330           8 :                                                               stmt->name);
    1331           4 :                             break;
    1332           0 :                         default:    /* oops */
    1333           0 :                             elog(ERROR, "unrecognized alter domain type: %d",
    1334             :                                  (int) stmt->subtype);
    1335             :                             break;
    1336             :                     }
    1337             :                 }
    1338          96 :                 break;
    1339             : 
    1340             :                 /*
    1341             :                  * ************* object creation / destruction **************
    1342             :                  */
    1343       18590 :             case T_DefineStmt:
    1344             :                 {
    1345       18590 :                     DefineStmt *stmt = (DefineStmt *) parsetree;
    1346             : 
    1347       18590 :                     switch (stmt->kind)
    1348             :                     {
    1349         640 :                         case OBJECT_AGGREGATE:
    1350             :                             address =
    1351        1280 :                                 DefineAggregate(pstate, stmt->defnames, stmt->args,
    1352         640 :                                                 stmt->oldstyle,
    1353             :                                                 stmt->definition,
    1354         640 :                                                 stmt->replace);
    1355         418 :                             break;
    1356        1320 :                         case OBJECT_OPERATOR:
    1357             :                             Assert(stmt->args == NIL);
    1358        1320 :                             address = DefineOperator(stmt->defnames,
    1359             :                                                      stmt->definition);
    1360        1276 :                             break;
    1361         276 :                         case OBJECT_TYPE:
    1362             :                             Assert(stmt->args == NIL);
    1363         276 :                             address = DefineType(pstate,
    1364             :                                                  stmt->defnames,
    1365             :                                                  stmt->definition);
    1366         256 :                             break;
    1367          28 :                         case OBJECT_TSPARSER:
    1368             :                             Assert(stmt->args == NIL);
    1369          28 :                             address = DefineTSParser(stmt->defnames,
    1370             :                                                      stmt->definition);
    1371          24 :                             break;
    1372        7982 :                         case OBJECT_TSDICTIONARY:
    1373             :                             Assert(stmt->args == NIL);
    1374        7982 :                             address = DefineTSDictionary(stmt->defnames,
    1375             :                                                          stmt->definition);
    1376        7966 :                             break;
    1377         390 :                         case OBJECT_TSTEMPLATE:
    1378             :                             Assert(stmt->args == NIL);
    1379         390 :                             address = DefineTSTemplate(stmt->defnames,
    1380             :                                                        stmt->definition);
    1381         386 :                             break;
    1382        7934 :                         case OBJECT_TSCONFIGURATION:
    1383             :                             Assert(stmt->args == NIL);
    1384        7934 :                             address = DefineTSConfiguration(stmt->defnames,
    1385             :                                                             stmt->definition,
    1386             :                                                             &secondaryObject);
    1387        7934 :                             break;
    1388          20 :                         case OBJECT_COLLATION:
    1389             :                             Assert(stmt->args == NIL);
    1390          20 :                             address = DefineCollation(pstate,
    1391             :                                                       stmt->defnames,
    1392             :                                                       stmt->definition,
    1393          20 :                                                       stmt->if_not_exists);
    1394          12 :                             break;
    1395           0 :                         default:
    1396           0 :                             elog(ERROR, "unrecognized define stmt type: %d",
    1397             :                                  (int) stmt->kind);
    1398             :                             break;
    1399             :                     }
    1400             :                 }
    1401       18272 :                 break;
    1402             : 
    1403        7560 :             case T_IndexStmt:   /* CREATE INDEX */
    1404             :                 {
    1405        7560 :                     IndexStmt  *stmt = (IndexStmt *) parsetree;
    1406             :                     Oid         relid;
    1407             :                     LOCKMODE    lockmode;
    1408             : 
    1409        7560 :                     if (stmt->concurrent)
    1410          68 :                         PreventInTransactionBlock(isTopLevel,
    1411             :                                                   "CREATE INDEX CONCURRENTLY");
    1412             : 
    1413             :                     /*
    1414             :                      * Look up the relation OID just once, right here at the
    1415             :                      * beginning, so that we don't end up repeating the name
    1416             :                      * lookup later and latching onto a different relation
    1417             :                      * partway through.  To avoid lock upgrade hazards, it's
    1418             :                      * important that we take the strongest lock that will
    1419             :                      * eventually be needed here, so the lockmode calculation
    1420             :                      * needs to match what DefineIndex() does.
    1421             :                      */
    1422       15104 :                     lockmode = stmt->concurrent ? ShareUpdateExclusiveLock
    1423        7552 :                         : ShareLock;
    1424             :                     relid =
    1425        7552 :                         RangeVarGetRelidExtended(stmt->relation, lockmode,
    1426             :                                                  0,
    1427             :                                                  RangeVarCallbackOwnsRelation,
    1428             :                                                  NULL);
    1429             : 
    1430             :                     /*
    1431             :                      * CREATE INDEX on partitioned tables (but not regular
    1432             :                      * inherited tables) recurses to partitions, so we must
    1433             :                      * acquire locks early to avoid deadlocks.
    1434             :                      *
    1435             :                      * We also take the opportunity to verify that all
    1436             :                      * partitions are something we can put an index on, to
    1437             :                      * avoid building some indexes only to fail later.
    1438             :                      */
    1439        7546 :                     if (stmt->relation->inh &&
    1440        7458 :                         get_rel_relkind(relid) == RELKIND_PARTITIONED_TABLE)
    1441             :                     {
    1442             :                         ListCell   *lc;
    1443         530 :                         List       *inheritors = NIL;
    1444             : 
    1445         530 :                         inheritors = find_all_inheritors(relid, lockmode, NULL);
    1446        1398 :                         foreach(lc, inheritors)
    1447             :                         {
    1448         876 :                             char        relkind = get_rel_relkind(lfirst_oid(lc));
    1449             : 
    1450         876 :                             if (relkind != RELKIND_RELATION &&
    1451         590 :                                 relkind != RELKIND_MATVIEW &&
    1452          12 :                                 relkind != RELKIND_PARTITIONED_TABLE &&
    1453             :                                 relkind != RELKIND_FOREIGN_TABLE)
    1454           0 :                                 elog(ERROR, "unexpected relkind \"%c\" on partition \"%s\"",
    1455             :                                      relkind, stmt->relation->relname);
    1456             : 
    1457         876 :                             if (relkind == RELKIND_FOREIGN_TABLE &&
    1458          12 :                                 (stmt->unique || stmt->primary))
    1459           8 :                                 ereport(ERROR,
    1460             :                                         (errcode(ERRCODE_WRONG_OBJECT_TYPE),
    1461             :                                          errmsg("cannot create unique index on partitioned table \"%s\"",
    1462             :                                                 stmt->relation->relname),
    1463             :                                          errdetail("Table \"%s\" contains partitions that are foreign tables.",
    1464             :                                                    stmt->relation->relname)));
    1465             :                         }
    1466         522 :                         list_free(inheritors);
    1467             :                     }
    1468             : 
    1469             :                     /* Run parse analysis ... */
    1470        7538 :                     stmt = transformIndexStmt(relid, stmt, queryString);
    1471             : 
    1472             :                     /* ... and do it */
    1473        7534 :                     EventTriggerAlterTableStart(parsetree);
    1474             :                     address =
    1475        7534 :                         DefineIndex(relid,  /* OID of heap relation */
    1476             :                                     stmt,
    1477             :                                     InvalidOid, /* no predefined OID */
    1478             :                                     InvalidOid, /* no parent index */
    1479             :                                     InvalidOid, /* no parent constraint */
    1480             :                                     false,  /* is_alter_table */
    1481             :                                     true,   /* check_rights */
    1482             :                                     true,   /* check_not_in_use */
    1483             :                                     false,  /* skip_build */
    1484             :                                     false); /* quiet */
    1485             : 
    1486             :                     /*
    1487             :                      * Add the CREATE INDEX node itself to stash right away;
    1488             :                      * if there were any commands stashed in the ALTER TABLE
    1489             :                      * code, we need them to appear after this one.
    1490             :                      */
    1491        7318 :                     EventTriggerCollectSimpleCommand(address, secondaryObject,
    1492             :                                                      parsetree);
    1493        7318 :                     commandCollected = true;
    1494        7318 :                     EventTriggerAlterTableEnd();
    1495             :                 }
    1496        7318 :                 break;
    1497             : 
    1498         554 :             case T_CreateExtensionStmt:
    1499         554 :                 address = CreateExtension(pstate, (CreateExtensionStmt *) parsetree);
    1500         536 :                 break;
    1501             : 
    1502           2 :             case T_AlterExtensionStmt:
    1503           2 :                 address = ExecAlterExtensionStmt(pstate, (AlterExtensionStmt *) parsetree);
    1504           2 :                 break;
    1505             : 
    1506         126 :             case T_AlterExtensionContentsStmt:
    1507         126 :                 address = ExecAlterExtensionContentsStmt((AlterExtensionContentsStmt *) parsetree,
    1508             :                                                          &secondaryObject);
    1509         126 :                 break;
    1510             : 
    1511         114 :             case T_CreateFdwStmt:
    1512         114 :                 address = CreateForeignDataWrapper((CreateFdwStmt *) parsetree);
    1513          80 :                 break;
    1514             : 
    1515          76 :             case T_AlterFdwStmt:
    1516          76 :                 address = AlterForeignDataWrapper((AlterFdwStmt *) parsetree);
    1517          32 :                 break;
    1518             : 
    1519         170 :             case T_CreateForeignServerStmt:
    1520         170 :                 address = CreateForeignServer((CreateForeignServerStmt *) parsetree);
    1521         140 :                 break;
    1522             : 
    1523          94 :             case T_AlterForeignServerStmt:
    1524          94 :                 address = AlterForeignServer((AlterForeignServerStmt *) parsetree);
    1525          62 :                 break;
    1526             : 
    1527         172 :             case T_CreateUserMappingStmt:
    1528         172 :                 address = CreateUserMapping((CreateUserMappingStmt *) parsetree);
    1529         126 :                 break;
    1530             : 
    1531          86 :             case T_AlterUserMappingStmt:
    1532          86 :                 address = AlterUserMapping((AlterUserMappingStmt *) parsetree);
    1533          48 :                 break;
    1534             : 
    1535          92 :             case T_DropUserMappingStmt:
    1536          92 :                 RemoveUserMapping((DropUserMappingStmt *) parsetree);
    1537             :                 /* no commands stashed for DROP */
    1538          66 :                 commandCollected = true;
    1539          66 :                 break;
    1540             : 
    1541          36 :             case T_ImportForeignSchemaStmt:
    1542          36 :                 ImportForeignSchema((ImportForeignSchemaStmt *) parsetree);
    1543             :                 /* commands are stashed inside ImportForeignSchema */
    1544          10 :                 commandCollected = true;
    1545          10 :                 break;
    1546             : 
    1547         418 :             case T_CompositeTypeStmt:   /* CREATE TYPE (composite) */
    1548             :                 {
    1549         418 :                     CompositeTypeStmt *stmt = (CompositeTypeStmt *) parsetree;
    1550             : 
    1551         418 :                     address = DefineCompositeType(stmt->typevar,
    1552             :                                                   stmt->coldeflist);
    1553             :                 }
    1554         410 :                 break;
    1555             : 
    1556         348 :             case T_CreateEnumStmt:  /* CREATE TYPE AS ENUM */
    1557         348 :                 address = DefineEnum((CreateEnumStmt *) parsetree);
    1558         348 :                 break;
    1559             : 
    1560          58 :             case T_CreateRangeStmt: /* CREATE TYPE AS RANGE */
    1561          58 :                 address = DefineRange((CreateRangeStmt *) parsetree);
    1562          54 :                 break;
    1563             : 
    1564         280 :             case T_AlterEnumStmt:   /* ALTER TYPE (enum) */
    1565         280 :                 address = AlterEnum((AlterEnumStmt *) parsetree);
    1566         260 :                 break;
    1567             : 
    1568       47374 :             case T_ViewStmt:    /* CREATE VIEW */
    1569       47374 :                 EventTriggerAlterTableStart(parsetree);
    1570       47374 :                 address = DefineView((ViewStmt *) parsetree, queryString,
    1571             :                                      pstmt->stmt_location, pstmt->stmt_len);
    1572       47334 :                 EventTriggerCollectSimpleCommand(address, secondaryObject,
    1573             :                                                  parsetree);
    1574             :                 /* stashed internally */
    1575       47334 :                 commandCollected = true;
    1576       47334 :                 EventTriggerAlterTableEnd();
    1577       47334 :                 break;
    1578             : 
    1579       25280 :             case T_CreateFunctionStmt:  /* CREATE FUNCTION */
    1580       25280 :                 address = CreateFunction(pstate, (CreateFunctionStmt *) parsetree);
    1581       25004 :                 break;
    1582             : 
    1583         106 :             case T_AlterFunctionStmt:   /* ALTER FUNCTION */
    1584         106 :                 address = AlterFunction(pstate, (AlterFunctionStmt *) parsetree);
    1585          86 :                 break;
    1586             : 
    1587        1228 :             case T_RuleStmt:    /* CREATE RULE */
    1588        1228 :                 address = DefineRule((RuleStmt *) parsetree, queryString);
    1589        1198 :                 break;
    1590             : 
    1591        1014 :             case T_CreateSeqStmt:
    1592        1014 :                 address = DefineSequence(pstate, (CreateSeqStmt *) parsetree);
    1593         946 :                 break;
    1594             : 
    1595         794 :             case T_AlterSeqStmt:
    1596         794 :                 address = AlterSequence(pstate, (AlterSeqStmt *) parsetree);
    1597         762 :                 break;
    1598             : 
    1599         898 :             case T_CreateTableAsStmt:
    1600         898 :                 address = ExecCreateTableAs(pstate, (CreateTableAsStmt *) parsetree,
    1601             :                                             params, queryEnv, qc);
    1602         838 :                 break;
    1603             : 
    1604          90 :             case T_RefreshMatViewStmt:
    1605             : 
    1606             :                 /*
    1607             :                  * REFRESH CONCURRENTLY executes some DDL commands internally.
    1608             :                  * Inhibit DDL command collection here to avoid those commands
    1609             :                  * from showing up in the deparsed command queue.  The refresh
    1610             :                  * command itself is queued, which is enough.
    1611             :                  */
    1612          90 :                 EventTriggerInhibitCommandCollection();
    1613          90 :                 PG_TRY();
    1614             :                 {
    1615          90 :                     address = ExecRefreshMatView((RefreshMatViewStmt *) parsetree,
    1616             :                                                  queryString, params, qc);
    1617             :                 }
    1618          20 :                 PG_FINALLY();
    1619             :                 {
    1620          90 :                     EventTriggerUndoInhibitCommandCollection();
    1621             :                 }
    1622          90 :                 PG_END_TRY();
    1623          70 :                 break;
    1624             : 
    1625        2008 :             case T_CreateTrigStmt:
    1626        2008 :                 address = CreateTrigger((CreateTrigStmt *) parsetree,
    1627             :                                         queryString, InvalidOid, InvalidOid,
    1628             :                                         InvalidOid, InvalidOid, InvalidOid,
    1629             :                                         InvalidOid, NULL, false, false);
    1630        1878 :                 break;
    1631             : 
    1632         406 :             case T_CreatePLangStmt:
    1633         406 :                 address = CreateProceduralLanguage((CreatePLangStmt *) parsetree);
    1634         406 :                 break;
    1635             : 
    1636        2224 :             case T_CreateDomainStmt:
    1637        2224 :                 address = DefineDomain((CreateDomainStmt *) parsetree);
    1638        2216 :                 break;
    1639             : 
    1640          44 :             case T_CreateConversionStmt:
    1641          44 :                 address = CreateConversionCommand((CreateConversionStmt *) parsetree);
    1642          36 :                 break;
    1643             : 
    1644         198 :             case T_CreateCastStmt:
    1645         198 :                 address = CreateCast((CreateCastStmt *) parsetree);
    1646         194 :                 break;
    1647             : 
    1648         306 :             case T_CreateOpClassStmt:
    1649         306 :                 DefineOpClass((CreateOpClassStmt *) parsetree);
    1650             :                 /* command is stashed in DefineOpClass */
    1651         306 :                 commandCollected = true;
    1652         306 :                 break;
    1653             : 
    1654         102 :             case T_CreateOpFamilyStmt:
    1655         102 :                 address = DefineOpFamily((CreateOpFamilyStmt *) parsetree);
    1656         102 :                 break;
    1657             : 
    1658          54 :             case T_CreateTransformStmt:
    1659          54 :                 address = CreateTransform((CreateTransformStmt *) parsetree);
    1660          44 :                 break;
    1661             : 
    1662         338 :             case T_AlterOpFamilyStmt:
    1663         338 :                 AlterOpFamily((AlterOpFamilyStmt *) parsetree);
    1664             :                 /* commands are stashed in AlterOpFamily */
    1665         234 :                 commandCollected = true;
    1666         234 :                 break;
    1667             : 
    1668          34 :             case T_AlterTSDictionaryStmt:
    1669          34 :                 address = AlterTSDictionary((AlterTSDictionaryStmt *) parsetree);
    1670          28 :                 break;
    1671             : 
    1672       23808 :             case T_AlterTSConfigurationStmt:
    1673       23808 :                 AlterTSConfiguration((AlterTSConfigurationStmt *) parsetree);
    1674             : 
    1675             :                 /*
    1676             :                  * Commands are stashed in MakeConfigurationMapping and
    1677             :                  * DropConfigurationMapping, which are called from
    1678             :                  * AlterTSConfiguration
    1679             :                  */
    1680       23808 :                 commandCollected = true;
    1681       23808 :                 break;
    1682             : 
    1683          12 :             case T_AlterTableMoveAllStmt:
    1684          12 :                 AlterTableMoveAll((AlterTableMoveAllStmt *) parsetree);
    1685             :                 /* commands are stashed in AlterTableMoveAll */
    1686          12 :                 commandCollected = true;
    1687          12 :                 break;
    1688             : 
    1689       13602 :             case T_DropStmt:
    1690       13602 :                 ExecDropStmt((DropStmt *) parsetree, isTopLevel);
    1691             :                 /* no commands stashed for DROP */
    1692       13004 :                 commandCollected = true;
    1693       13004 :                 break;
    1694             : 
    1695         718 :             case T_RenameStmt:
    1696         718 :                 address = ExecRenameStmt((RenameStmt *) parsetree);
    1697         482 :                 break;
    1698             : 
    1699          46 :             case T_AlterObjectDependsStmt:
    1700             :                 address =
    1701          46 :                     ExecAlterObjectDependsStmt((AlterObjectDependsStmt *) parsetree,
    1702             :                                                &secondaryObject);
    1703          46 :                 break;
    1704             : 
    1705         244 :             case T_AlterObjectSchemaStmt:
    1706             :                 address =
    1707         244 :                     ExecAlterObjectSchemaStmt((AlterObjectSchemaStmt *) parsetree,
    1708             :                                               &secondaryObject);
    1709         162 :                 break;
    1710             : 
    1711        1436 :             case T_AlterOwnerStmt:
    1712        1436 :                 address = ExecAlterOwnerStmt((AlterOwnerStmt *) parsetree);
    1713        1280 :                 break;
    1714             : 
    1715         484 :             case T_AlterOperatorStmt:
    1716         484 :                 address = AlterOperator((AlterOperatorStmt *) parsetree);
    1717         452 :                 break;
    1718             : 
    1719          28 :             case T_AlterTypeStmt:
    1720          28 :                 address = AlterType((AlterTypeStmt *) parsetree);
    1721          20 :                 break;
    1722             : 
    1723       17884 :             case T_CommentStmt:
    1724       17884 :                 address = CommentObject((CommentStmt *) parsetree);
    1725       17794 :                 break;
    1726             : 
    1727       44172 :             case T_GrantStmt:
    1728       44172 :                 ExecuteGrantStmt((GrantStmt *) parsetree);
    1729             :                 /* commands are stashed in ExecGrantStmt_oids */
    1730       44096 :                 commandCollected = true;
    1731       44096 :                 break;
    1732             : 
    1733          72 :             case T_DropOwnedStmt:
    1734          72 :                 DropOwnedObjects((DropOwnedStmt *) parsetree);
    1735             :                 /* no commands stashed for DROP */
    1736          60 :                 commandCollected = true;
    1737          60 :                 break;
    1738             : 
    1739          80 :             case T_AlterDefaultPrivilegesStmt:
    1740          80 :                 ExecAlterDefaultPrivilegesStmt(pstate, (AlterDefaultPrivilegesStmt *) parsetree);
    1741          76 :                 EventTriggerCollectAlterDefPrivs((AlterDefaultPrivilegesStmt *) parsetree);
    1742          76 :                 commandCollected = true;
    1743          76 :                 break;
    1744             : 
    1745         394 :             case T_CreatePolicyStmt:    /* CREATE POLICY */
    1746         394 :                 address = CreatePolicy((CreatePolicyStmt *) parsetree);
    1747         384 :                 break;
    1748             : 
    1749          56 :             case T_AlterPolicyStmt: /* ALTER POLICY */
    1750          56 :                 address = AlterPolicy((AlterPolicyStmt *) parsetree);
    1751          48 :                 break;
    1752             : 
    1753          54 :             case T_SecLabelStmt:
    1754          54 :                 address = ExecSecLabelStmt((SecLabelStmt *) parsetree);
    1755          24 :                 break;
    1756             : 
    1757          44 :             case T_CreateAmStmt:
    1758          44 :                 address = CreateAccessMethod((CreateAmStmt *) parsetree);
    1759          28 :                 break;
    1760             : 
    1761         108 :             case T_CreatePublicationStmt:
    1762         108 :                 address = CreatePublication((CreatePublicationStmt *) parsetree);
    1763          84 :                 break;
    1764             : 
    1765          94 :             case T_AlterPublicationStmt:
    1766          94 :                 AlterPublication((AlterPublicationStmt *) parsetree);
    1767             : 
    1768             :                 /*
    1769             :                  * AlterPublication calls EventTriggerCollectSimpleCommand
    1770             :                  * directly
    1771             :                  */
    1772          66 :                 commandCollected = true;
    1773          66 :                 break;
    1774             : 
    1775         108 :             case T_CreateSubscriptionStmt:
    1776         108 :                 address = CreateSubscription((CreateSubscriptionStmt *) parsetree,
    1777             :                                              isTopLevel);
    1778          56 :                 break;
    1779             : 
    1780          68 :             case T_AlterSubscriptionStmt:
    1781          68 :                 address = AlterSubscription((AlterSubscriptionStmt *) parsetree);
    1782          44 :                 break;
    1783             : 
    1784          42 :             case T_DropSubscriptionStmt:
    1785          42 :                 DropSubscription((DropSubscriptionStmt *) parsetree, isTopLevel);
    1786             :                 /* no commands stashed for DROP */
    1787          34 :                 commandCollected = true;
    1788          34 :                 break;
    1789             : 
    1790         196 :             case T_CreateStatsStmt:
    1791         196 :                 address = CreateStatistics((CreateStatsStmt *) parsetree);
    1792         152 :                 break;
    1793             : 
    1794          18 :             case T_AlterStatsStmt:
    1795          18 :                 address = AlterStatistics((AlterStatsStmt *) parsetree);
    1796          14 :                 break;
    1797             : 
    1798           0 :             case T_AlterCollationStmt:
    1799           0 :                 address = AlterCollation((AlterCollationStmt *) parsetree);
    1800           0 :                 break;
    1801             : 
    1802           0 :             default:
    1803           0 :                 elog(ERROR, "unrecognized node type: %d",
    1804             :                      (int) nodeTag(parsetree));
    1805             :                 break;
    1806             :         }
    1807             : 
    1808             :         /*
    1809             :          * Remember the object so that ddl_command_end event triggers have
    1810             :          * access to it.
    1811             :          */
    1812      242506 :         if (!commandCollected)
    1813       75470 :             EventTriggerCollectSimpleCommand(address, secondaryObject,
    1814             :                                              parsetree);
    1815             : 
    1816      242506 :         if (isCompleteQuery)
    1817             :         {
    1818      235836 :             EventTriggerSQLDrop(parsetree);
    1819      235824 :             EventTriggerDDLCommandEnd(parsetree);
    1820             :         }
    1821             :     }
    1822        5904 :     PG_FINALLY();
    1823             :     {
    1824      248398 :         if (needCleanup)
    1825         990 :             EventTriggerEndCompleteQuery();
    1826             :     }
    1827      248398 :     PG_END_TRY();
    1828      242494 : }
    1829             : 
    1830             : /*
    1831             :  * ProcessUtilityForAlterTable
    1832             :  *      Recursive entry from ALTER TABLE
    1833             :  *
    1834             :  * ALTER TABLE sometimes generates subcommands such as CREATE INDEX.
    1835             :  * It calls this, not the main entry point ProcessUtility, to execute
    1836             :  * such subcommands.
    1837             :  *
    1838             :  * stmt: the utility command to execute
    1839             :  * context: opaque passthrough struct with the info we need
    1840             :  *
    1841             :  * It's caller's responsibility to do CommandCounterIncrement after
    1842             :  * calling this, if needed.
    1843             :  */
    1844             : void
    1845         268 : ProcessUtilityForAlterTable(Node *stmt, AlterTableUtilityContext *context)
    1846             : {
    1847             :     PlannedStmt *wrapper;
    1848             : 
    1849             :     /*
    1850             :      * For event triggers, we must "close" the current complex-command set,
    1851             :      * and start a new one afterwards; this is needed to ensure the ordering
    1852             :      * of command events is consistent with the way they were executed.
    1853             :      */
    1854         268 :     EventTriggerAlterTableEnd();
    1855             : 
    1856             :     /* Create a suitable wrapper */
    1857         268 :     wrapper = makeNode(PlannedStmt);
    1858         268 :     wrapper->commandType = CMD_UTILITY;
    1859         268 :     wrapper->canSetTag = false;
    1860         268 :     wrapper->utilityStmt = stmt;
    1861         268 :     wrapper->stmt_location = context->pstmt->stmt_location;
    1862         268 :     wrapper->stmt_len = context->pstmt->stmt_len;
    1863             : 
    1864         268 :     ProcessUtility(wrapper,
    1865             :                    context->queryString,
    1866             :                    PROCESS_UTILITY_SUBCOMMAND,
    1867             :                    context->params,
    1868             :                    context->queryEnv,
    1869             :                    None_Receiver,
    1870             :                    NULL);
    1871             : 
    1872         260 :     EventTriggerAlterTableStart(context->pstmt->utilityStmt);
    1873         260 :     EventTriggerAlterTableRelid(context->relid);
    1874         260 : }
    1875             : 
    1876             : /*
    1877             :  * Dispatch function for DropStmt
    1878             :  */
    1879             : static void
    1880       13664 : ExecDropStmt(DropStmt *stmt, bool isTopLevel)
    1881             : {
    1882       13664 :     switch (stmt->removeType)
    1883             :     {
    1884         380 :         case OBJECT_INDEX:
    1885         380 :             if (stmt->concurrent)
    1886          46 :                 PreventInTransactionBlock(isTopLevel,
    1887             :                                           "DROP INDEX CONCURRENTLY");
    1888             :             /* fall through */
    1889             : 
    1890             :         case OBJECT_TABLE:
    1891             :         case OBJECT_SEQUENCE:
    1892             :         case OBJECT_VIEW:
    1893             :         case OBJECT_MATVIEW:
    1894             :         case OBJECT_FOREIGN_TABLE:
    1895        9286 :             RemoveRelations(stmt);
    1896        9094 :             break;
    1897        4374 :         default:
    1898        4374 :             RemoveObjects(stmt);
    1899        3968 :             break;
    1900             :     }
    1901       13062 : }
    1902             : 
    1903             : 
    1904             : /*
    1905             :  * UtilityReturnsTuples
    1906             :  *      Return "true" if this utility statement will send output to the
    1907             :  *      destination.
    1908             :  *
    1909             :  * Generally, there should be a case here for each case in ProcessUtility
    1910             :  * where "dest" is passed on.
    1911             :  */
    1912             : bool
    1913      325730 : UtilityReturnsTuples(Node *parsetree)
    1914             : {
    1915      325730 :     switch (nodeTag(parsetree))
    1916             :     {
    1917         224 :         case T_CallStmt:
    1918             :             {
    1919         224 :                 CallStmt   *stmt = (CallStmt *) parsetree;
    1920             : 
    1921         224 :                 return (stmt->funcexpr->funcresulttype == RECORDOID);
    1922             :             }
    1923        4398 :         case T_FetchStmt:
    1924             :             {
    1925        4398 :                 FetchStmt  *stmt = (FetchStmt *) parsetree;
    1926             :                 Portal      portal;
    1927             : 
    1928        4398 :                 if (stmt->ismove)
    1929          52 :                     return false;
    1930        4346 :                 portal = GetPortalByName(stmt->portalname);
    1931        4346 :                 if (!PortalIsValid(portal))
    1932          26 :                     return false;   /* not our business to raise error */
    1933        4320 :                 return portal->tupDesc ? true : false;
    1934             :             }
    1935             : 
    1936         814 :         case T_ExecuteStmt:
    1937             :             {
    1938         814 :                 ExecuteStmt *stmt = (ExecuteStmt *) parsetree;
    1939             :                 PreparedStatement *entry;
    1940             : 
    1941         814 :                 entry = FetchPreparedStatement(stmt->name, false);
    1942         814 :                 if (!entry)
    1943           0 :                     return false;   /* not our business to raise error */
    1944         814 :                 if (entry->plansource->resultDesc)
    1945         746 :                     return true;
    1946          68 :                 return false;
    1947             :             }
    1948             : 
    1949       13298 :         case T_ExplainStmt:
    1950       13298 :             return true;
    1951             : 
    1952         456 :         case T_VariableShowStmt:
    1953         456 :             return true;
    1954             : 
    1955      306540 :         default:
    1956      306540 :             return false;
    1957             :     }
    1958             : }
    1959             : 
    1960             : /*
    1961             :  * UtilityTupleDescriptor
    1962             :  *      Fetch the actual output tuple descriptor for a utility statement
    1963             :  *      for which UtilityReturnsTuples() previously returned "true".
    1964             :  *
    1965             :  * The returned descriptor is created in (or copied into) the current memory
    1966             :  * context.
    1967             :  */
    1968             : TupleDesc
    1969       18894 : UtilityTupleDescriptor(Node *parsetree)
    1970             : {
    1971       18894 :     switch (nodeTag(parsetree))
    1972             :     {
    1973          74 :         case T_CallStmt:
    1974          74 :             return CallStmtResultDesc((CallStmt *) parsetree);
    1975             : 
    1976        4320 :         case T_FetchStmt:
    1977             :             {
    1978        4320 :                 FetchStmt  *stmt = (FetchStmt *) parsetree;
    1979             :                 Portal      portal;
    1980             : 
    1981        4320 :                 if (stmt->ismove)
    1982           0 :                     return NULL;
    1983        4320 :                 portal = GetPortalByName(stmt->portalname);
    1984        4320 :                 if (!PortalIsValid(portal))
    1985           0 :                     return NULL;    /* not our business to raise error */
    1986        4320 :                 return CreateTupleDescCopy(portal->tupDesc);
    1987             :             }
    1988             : 
    1989         746 :         case T_ExecuteStmt:
    1990             :             {
    1991         746 :                 ExecuteStmt *stmt = (ExecuteStmt *) parsetree;
    1992             :                 PreparedStatement *entry;
    1993             : 
    1994         746 :                 entry = FetchPreparedStatement(stmt->name, false);
    1995         746 :                 if (!entry)
    1996           0 :                     return NULL;    /* not our business to raise error */
    1997         746 :                 return FetchPreparedStatementResultDesc(entry);
    1998             :             }
    1999             : 
    2000       13298 :         case T_ExplainStmt:
    2001       13298 :             return ExplainResultDesc((ExplainStmt *) parsetree);
    2002             : 
    2003         456 :         case T_VariableShowStmt:
    2004             :             {
    2005         456 :                 VariableShowStmt *n = (VariableShowStmt *) parsetree;
    2006             : 
    2007         456 :                 return GetPGVariableResultDesc(n->name);
    2008             :             }
    2009             : 
    2010           0 :         default:
    2011           0 :             return NULL;
    2012             :     }
    2013             : }
    2014             : 
    2015             : 
    2016             : /*
    2017             :  * QueryReturnsTuples
    2018             :  *      Return "true" if this Query will send output to the destination.
    2019             :  */
    2020             : #ifdef NOT_USED
    2021             : bool
    2022             : QueryReturnsTuples(Query *parsetree)
    2023             : {
    2024             :     switch (parsetree->commandType)
    2025             :     {
    2026             :         case CMD_SELECT:
    2027             :             /* returns tuples */
    2028             :             return true;
    2029             :         case CMD_INSERT:
    2030             :         case CMD_UPDATE:
    2031             :         case CMD_DELETE:
    2032             :             /* the forms with RETURNING return tuples */
    2033             :             if (parsetree->returningList)
    2034             :                 return true;
    2035             :             break;
    2036             :         case CMD_UTILITY:
    2037             :             return UtilityReturnsTuples(parsetree->utilityStmt);
    2038             :         case CMD_UNKNOWN:
    2039             :         case CMD_NOTHING:
    2040             :             /* probably shouldn't get here */
    2041             :             break;
    2042             :     }
    2043             :     return false;               /* default */
    2044             : }
    2045             : #endif
    2046             : 
    2047             : 
    2048             : /*
    2049             :  * UtilityContainsQuery
    2050             :  *      Return the contained Query, or NULL if there is none
    2051             :  *
    2052             :  * Certain utility statements, such as EXPLAIN, contain a plannable Query.
    2053             :  * This function encapsulates knowledge of exactly which ones do.
    2054             :  * We assume it is invoked only on already-parse-analyzed statements
    2055             :  * (else the contained parsetree isn't a Query yet).
    2056             :  *
    2057             :  * In some cases (currently, only EXPLAIN of CREATE TABLE AS/SELECT INTO and
    2058             :  * CREATE MATERIALIZED VIEW), potentially Query-containing utility statements
    2059             :  * can be nested.  This function will drill down to a non-utility Query, or
    2060             :  * return NULL if none.
    2061             :  */
    2062             : Query *
    2063       20770 : UtilityContainsQuery(Node *parsetree)
    2064             : {
    2065             :     Query      *qry;
    2066             : 
    2067       20770 :     switch (nodeTag(parsetree))
    2068             :     {
    2069        2616 :         case T_DeclareCursorStmt:
    2070        2616 :             qry = castNode(Query, ((DeclareCursorStmt *) parsetree)->query);
    2071        2616 :             if (qry->commandType == CMD_UTILITY)
    2072           0 :                 return UtilityContainsQuery(qry->utilityStmt);
    2073        2616 :             return qry;
    2074             : 
    2075        5800 :         case T_ExplainStmt:
    2076        5800 :             qry = castNode(Query, ((ExplainStmt *) parsetree)->query);
    2077        5800 :             if (qry->commandType == CMD_UTILITY)
    2078          40 :                 return UtilityContainsQuery(qry->utilityStmt);
    2079        5760 :             return qry;
    2080             : 
    2081          34 :         case T_CreateTableAsStmt:
    2082          34 :             qry = castNode(Query, ((CreateTableAsStmt *) parsetree)->query);
    2083          34 :             if (qry->commandType == CMD_UTILITY)
    2084           0 :                 return UtilityContainsQuery(qry->utilityStmt);
    2085          34 :             return qry;
    2086             : 
    2087       12320 :         default:
    2088       12320 :             return NULL;
    2089             :     }
    2090             : }
    2091             : 
    2092             : 
    2093             : /*
    2094             :  * AlterObjectTypeCommandTag
    2095             :  *      helper function for CreateCommandTag
    2096             :  *
    2097             :  * This covers most cases where ALTER is used with an ObjectType enum.
    2098             :  */
    2099             : static CommandTag
    2100       12592 : AlterObjectTypeCommandTag(ObjectType objtype)
    2101             : {
    2102             :     CommandTag  tag;
    2103             : 
    2104       12592 :     switch (objtype)
    2105             :     {
    2106         174 :         case OBJECT_AGGREGATE:
    2107         174 :             tag = CMDTAG_ALTER_AGGREGATE;
    2108         174 :             break;
    2109          16 :         case OBJECT_ATTRIBUTE:
    2110          16 :             tag = CMDTAG_ALTER_TYPE;
    2111          16 :             break;
    2112           0 :         case OBJECT_CAST:
    2113           0 :             tag = CMDTAG_ALTER_CAST;
    2114           0 :             break;
    2115           0 :         case OBJECT_COLLATION:
    2116           0 :             tag = CMDTAG_ALTER_COLLATION;
    2117           0 :             break;
    2118           0 :         case OBJECT_COLUMN:
    2119           0 :             tag = CMDTAG_ALTER_TABLE;
    2120           0 :             break;
    2121          48 :         case OBJECT_CONVERSION:
    2122          48 :             tag = CMDTAG_ALTER_CONVERSION;
    2123          48 :             break;
    2124          30 :         case OBJECT_DATABASE:
    2125          30 :             tag = CMDTAG_ALTER_DATABASE;
    2126          30 :             break;
    2127          44 :         case OBJECT_DOMAIN:
    2128             :         case OBJECT_DOMCONSTRAINT:
    2129          44 :             tag = CMDTAG_ALTER_DOMAIN;
    2130          44 :             break;
    2131           0 :         case OBJECT_EXTENSION:
    2132           0 :             tag = CMDTAG_ALTER_EXTENSION;
    2133           0 :             break;
    2134          30 :         case OBJECT_FDW:
    2135          30 :             tag = CMDTAG_ALTER_FOREIGN_DATA_WRAPPER;
    2136          30 :             break;
    2137          62 :         case OBJECT_FOREIGN_SERVER:
    2138          62 :             tag = CMDTAG_ALTER_SERVER;
    2139          62 :             break;
    2140         324 :         case OBJECT_FOREIGN_TABLE:
    2141         324 :             tag = CMDTAG_ALTER_FOREIGN_TABLE;
    2142         324 :             break;
    2143         548 :         case OBJECT_FUNCTION:
    2144         548 :             tag = CMDTAG_ALTER_FUNCTION;
    2145         548 :             break;
    2146         448 :         case OBJECT_INDEX:
    2147         448 :             tag = CMDTAG_ALTER_INDEX;
    2148         448 :             break;
    2149          32 :         case OBJECT_LANGUAGE:
    2150          32 :             tag = CMDTAG_ALTER_LANGUAGE;
    2151          32 :             break;
    2152          10 :         case OBJECT_LARGEOBJECT:
    2153          10 :             tag = CMDTAG_ALTER_LARGE_OBJECT;
    2154          10 :             break;
    2155          68 :         case OBJECT_OPCLASS:
    2156          68 :             tag = CMDTAG_ALTER_OPERATOR_CLASS;
    2157          68 :             break;
    2158          54 :         case OBJECT_OPERATOR:
    2159          54 :             tag = CMDTAG_ALTER_OPERATOR;
    2160          54 :             break;
    2161          74 :         case OBJECT_OPFAMILY:
    2162          74 :             tag = CMDTAG_ALTER_OPERATOR_FAMILY;
    2163          74 :             break;
    2164          20 :         case OBJECT_POLICY:
    2165          20 :             tag = CMDTAG_ALTER_POLICY;
    2166          20 :             break;
    2167           8 :         case OBJECT_PROCEDURE:
    2168           8 :             tag = CMDTAG_ALTER_PROCEDURE;
    2169           8 :             break;
    2170          12 :         case OBJECT_ROLE:
    2171          12 :             tag = CMDTAG_ALTER_ROLE;
    2172          12 :             break;
    2173          16 :         case OBJECT_ROUTINE:
    2174          16 :             tag = CMDTAG_ALTER_ROUTINE;
    2175          16 :             break;
    2176          24 :         case OBJECT_RULE:
    2177          24 :             tag = CMDTAG_ALTER_RULE;
    2178          24 :             break;
    2179          30 :         case OBJECT_SCHEMA:
    2180          30 :             tag = CMDTAG_ALTER_SCHEMA;
    2181          30 :             break;
    2182          16 :         case OBJECT_SEQUENCE:
    2183          16 :             tag = CMDTAG_ALTER_SEQUENCE;
    2184          16 :             break;
    2185        9870 :         case OBJECT_TABLE:
    2186             :         case OBJECT_TABCONSTRAINT:
    2187        9870 :             tag = CMDTAG_ALTER_TABLE;
    2188        9870 :             break;
    2189           8 :         case OBJECT_TABLESPACE:
    2190           8 :             tag = CMDTAG_ALTER_TABLESPACE;
    2191           8 :             break;
    2192          18 :         case OBJECT_TRIGGER:
    2193          18 :             tag = CMDTAG_ALTER_TRIGGER;
    2194          18 :             break;
    2195          16 :         case OBJECT_EVENT_TRIGGER:
    2196          16 :             tag = CMDTAG_ALTER_EVENT_TRIGGER;
    2197          16 :             break;
    2198          56 :         case OBJECT_TSCONFIGURATION:
    2199          56 :             tag = CMDTAG_ALTER_TEXT_SEARCH_CONFIGURATION;
    2200          56 :             break;
    2201          66 :         case OBJECT_TSDICTIONARY:
    2202          66 :             tag = CMDTAG_ALTER_TEXT_SEARCH_DICTIONARY;
    2203          66 :             break;
    2204          20 :         case OBJECT_TSPARSER:
    2205          20 :             tag = CMDTAG_ALTER_TEXT_SEARCH_PARSER;
    2206          20 :             break;
    2207          20 :         case OBJECT_TSTEMPLATE:
    2208          20 :             tag = CMDTAG_ALTER_TEXT_SEARCH_TEMPLATE;
    2209          20 :             break;
    2210         234 :         case OBJECT_TYPE:
    2211         234 :             tag = CMDTAG_ALTER_TYPE;
    2212         234 :             break;
    2213          92 :         case OBJECT_VIEW:
    2214          92 :             tag = CMDTAG_ALTER_VIEW;
    2215          92 :             break;
    2216          14 :         case OBJECT_MATVIEW:
    2217          14 :             tag = CMDTAG_ALTER_MATERIALIZED_VIEW;
    2218          14 :             break;
    2219          16 :         case OBJECT_PUBLICATION:
    2220          16 :             tag = CMDTAG_ALTER_PUBLICATION;
    2221          16 :             break;
    2222          22 :         case OBJECT_SUBSCRIPTION:
    2223          22 :             tag = CMDTAG_ALTER_SUBSCRIPTION;
    2224          22 :             break;
    2225          52 :         case OBJECT_STATISTIC_EXT:
    2226          52 :             tag = CMDTAG_ALTER_STATISTICS;
    2227          52 :             break;
    2228           0 :         default:
    2229           0 :             tag = CMDTAG_UNKNOWN;
    2230           0 :             break;
    2231             :     }
    2232             : 
    2233       12592 :     return tag;
    2234             : }
    2235             : 
    2236             : /*
    2237             :  * CreateCommandTag
    2238             :  *      utility to get a CommandTag for the command operation,
    2239             :  *      given either a raw (un-analyzed) parsetree, an analyzed Query,
    2240             :  *      or a PlannedStmt.
    2241             :  *
    2242             :  * This must handle all command types, but since the vast majority
    2243             :  * of 'em are utility commands, it seems sensible to keep it here.
    2244             :  */
    2245             : CommandTag
    2246      553006 : CreateCommandTag(Node *parsetree)
    2247             : {
    2248             :     CommandTag  tag;
    2249             : 
    2250      553006 :     switch (nodeTag(parsetree))
    2251             :     {
    2252             :             /* recurse if we're given a RawStmt */
    2253           0 :         case T_RawStmt:
    2254           0 :             tag = CreateCommandTag(((RawStmt *) parsetree)->stmt);
    2255           0 :             break;
    2256             : 
    2257             :             /* raw plannable queries */
    2258       60092 :         case T_InsertStmt:
    2259       60092 :             tag = CMDTAG_INSERT;
    2260       60092 :             break;
    2261             : 
    2262        2882 :         case T_DeleteStmt:
    2263        2882 :             tag = CMDTAG_DELETE;
    2264        2882 :             break;
    2265             : 
    2266        9420 :         case T_UpdateStmt:
    2267        9420 :             tag = CMDTAG_UPDATE;
    2268        9420 :             break;
    2269             : 
    2270      158766 :         case T_SelectStmt:
    2271      158766 :             tag = CMDTAG_SELECT;
    2272      158766 :             break;
    2273             : 
    2274             :             /* utility statements --- same whether raw or cooked */
    2275       21256 :         case T_TransactionStmt:
    2276             :             {
    2277       21256 :                 TransactionStmt *stmt = (TransactionStmt *) parsetree;
    2278             : 
    2279       21256 :                 switch (stmt->kind)
    2280             :                 {
    2281        8980 :                     case TRANS_STMT_BEGIN:
    2282        8980 :                         tag = CMDTAG_BEGIN;
    2283        8980 :                         break;
    2284             : 
    2285         996 :                     case TRANS_STMT_START:
    2286         996 :                         tag = CMDTAG_START_TRANSACTION;
    2287         996 :                         break;
    2288             : 
    2289        8542 :                     case TRANS_STMT_COMMIT:
    2290        8542 :                         tag = CMDTAG_COMMIT;
    2291        8542 :                         break;
    2292             : 
    2293        1548 :                     case TRANS_STMT_ROLLBACK:
    2294             :                     case TRANS_STMT_ROLLBACK_TO:
    2295        1548 :                         tag = CMDTAG_ROLLBACK;
    2296        1548 :                         break;
    2297             : 
    2298         826 :                     case TRANS_STMT_SAVEPOINT:
    2299         826 :                         tag = CMDTAG_SAVEPOINT;
    2300         826 :                         break;
    2301             : 
    2302         152 :                     case TRANS_STMT_RELEASE:
    2303         152 :                         tag = CMDTAG_RELEASE;
    2304         152 :                         break;
    2305             : 
    2306         134 :                     case TRANS_STMT_PREPARE:
    2307         134 :                         tag = CMDTAG_PREPARE_TRANSACTION;
    2308         134 :                         break;
    2309             : 
    2310          52 :                     case TRANS_STMT_COMMIT_PREPARED:
    2311          52 :                         tag = CMDTAG_COMMIT_PREPARED;
    2312          52 :                         break;
    2313             : 
    2314          26 :                     case TRANS_STMT_ROLLBACK_PREPARED:
    2315          26 :                         tag = CMDTAG_ROLLBACK_PREPARED;
    2316          26 :                         break;
    2317             : 
    2318           0 :                     default:
    2319           0 :                         tag = CMDTAG_UNKNOWN;
    2320           0 :                         break;
    2321             :                 }
    2322             :             }
    2323       21256 :             break;
    2324             : 
    2325        2068 :         case T_DeclareCursorStmt:
    2326        2068 :             tag = CMDTAG_DECLARE_CURSOR;
    2327        2068 :             break;
    2328             : 
    2329        1684 :         case T_ClosePortalStmt:
    2330             :             {
    2331        1684 :                 ClosePortalStmt *stmt = (ClosePortalStmt *) parsetree;
    2332             : 
    2333        1684 :                 if (stmt->portalname == NULL)
    2334           8 :                     tag = CMDTAG_CLOSE_CURSOR_ALL;
    2335             :                 else
    2336        1676 :                     tag = CMDTAG_CLOSE_CURSOR;
    2337             :             }
    2338        1684 :             break;
    2339             : 
    2340        4532 :         case T_FetchStmt:
    2341             :             {
    2342        4532 :                 FetchStmt  *stmt = (FetchStmt *) parsetree;
    2343             : 
    2344        4532 :                 tag = (stmt->ismove) ? CMDTAG_MOVE : CMDTAG_FETCH;
    2345             :             }
    2346        4532 :             break;
    2347             : 
    2348        2228 :         case T_CreateDomainStmt:
    2349        2228 :             tag = CMDTAG_CREATE_DOMAIN;
    2350        2228 :             break;
    2351             : 
    2352         736 :         case T_CreateSchemaStmt:
    2353         736 :             tag = CMDTAG_CREATE_SCHEMA;
    2354         736 :             break;
    2355             : 
    2356       21104 :         case T_CreateStmt:
    2357       21104 :             tag = CMDTAG_CREATE_TABLE;
    2358       21104 :             break;
    2359             : 
    2360          38 :         case T_CreateTableSpaceStmt:
    2361          38 :             tag = CMDTAG_CREATE_TABLESPACE;
    2362          38 :             break;
    2363             : 
    2364          20 :         case T_DropTableSpaceStmt:
    2365          20 :             tag = CMDTAG_DROP_TABLESPACE;
    2366          20 :             break;
    2367             : 
    2368          16 :         case T_AlterTableSpaceOptionsStmt:
    2369          16 :             tag = CMDTAG_ALTER_TABLESPACE;
    2370          16 :             break;
    2371             : 
    2372         560 :         case T_CreateExtensionStmt:
    2373         560 :             tag = CMDTAG_CREATE_EXTENSION;
    2374         560 :             break;
    2375             : 
    2376           2 :         case T_AlterExtensionStmt:
    2377           2 :             tag = CMDTAG_ALTER_EXTENSION;
    2378           2 :             break;
    2379             : 
    2380         112 :         case T_AlterExtensionContentsStmt:
    2381         112 :             tag = CMDTAG_ALTER_EXTENSION;
    2382         112 :             break;
    2383             : 
    2384         118 :         case T_CreateFdwStmt:
    2385         118 :             tag = CMDTAG_CREATE_FOREIGN_DATA_WRAPPER;
    2386         118 :             break;
    2387             : 
    2388          76 :         case T_AlterFdwStmt:
    2389          76 :             tag = CMDTAG_ALTER_FOREIGN_DATA_WRAPPER;
    2390          76 :             break;
    2391             : 
    2392         180 :         case T_CreateForeignServerStmt:
    2393         180 :             tag = CMDTAG_CREATE_SERVER;
    2394         180 :             break;
    2395             : 
    2396          94 :         case T_AlterForeignServerStmt:
    2397          94 :             tag = CMDTAG_ALTER_SERVER;
    2398          94 :             break;
    2399             : 
    2400         182 :         case T_CreateUserMappingStmt:
    2401         182 :             tag = CMDTAG_CREATE_USER_MAPPING;
    2402         182 :             break;
    2403             : 
    2404          86 :         case T_AlterUserMappingStmt:
    2405          86 :             tag = CMDTAG_ALTER_USER_MAPPING;
    2406          86 :             break;
    2407             : 
    2408          92 :         case T_DropUserMappingStmt:
    2409          92 :             tag = CMDTAG_DROP_USER_MAPPING;
    2410          92 :             break;
    2411             : 
    2412         242 :         case T_CreateForeignTableStmt:
    2413         242 :             tag = CMDTAG_CREATE_FOREIGN_TABLE;
    2414         242 :             break;
    2415             : 
    2416          36 :         case T_ImportForeignSchemaStmt:
    2417          36 :             tag = CMDTAG_IMPORT_FOREIGN_SCHEMA;
    2418          36 :             break;
    2419             : 
    2420       13474 :         case T_DropStmt:
    2421       13474 :             switch (((DropStmt *) parsetree)->removeType)
    2422             :             {
    2423        8284 :                 case OBJECT_TABLE:
    2424        8284 :                     tag = CMDTAG_DROP_TABLE;
    2425        8284 :                     break;
    2426         104 :                 case OBJECT_SEQUENCE:
    2427         104 :                     tag = CMDTAG_DROP_SEQUENCE;
    2428         104 :                     break;
    2429         436 :                 case OBJECT_VIEW:
    2430         436 :                     tag = CMDTAG_DROP_VIEW;
    2431         436 :                     break;
    2432          38 :                 case OBJECT_MATVIEW:
    2433          38 :                     tag = CMDTAG_DROP_MATERIALIZED_VIEW;
    2434          38 :                     break;
    2435         384 :                 case OBJECT_INDEX:
    2436         384 :                     tag = CMDTAG_DROP_INDEX;
    2437         384 :                     break;
    2438         280 :                 case OBJECT_TYPE:
    2439         280 :                     tag = CMDTAG_DROP_TYPE;
    2440         280 :                     break;
    2441         232 :                 case OBJECT_DOMAIN:
    2442         232 :                     tag = CMDTAG_DROP_DOMAIN;
    2443         232 :                     break;
    2444          18 :                 case OBJECT_COLLATION:
    2445          18 :                     tag = CMDTAG_DROP_COLLATION;
    2446          18 :                     break;
    2447          24 :                 case OBJECT_CONVERSION:
    2448          24 :                     tag = CMDTAG_DROP_CONVERSION;
    2449          24 :                     break;
    2450         218 :                 case OBJECT_SCHEMA:
    2451         218 :                     tag = CMDTAG_DROP_SCHEMA;
    2452         218 :                     break;
    2453          12 :                 case OBJECT_TSPARSER:
    2454          12 :                     tag = CMDTAG_DROP_TEXT_SEARCH_PARSER;
    2455          12 :                     break;
    2456          16 :                 case OBJECT_TSDICTIONARY:
    2457          16 :                     tag = CMDTAG_DROP_TEXT_SEARCH_DICTIONARY;
    2458          16 :                     break;
    2459          12 :                 case OBJECT_TSTEMPLATE:
    2460          12 :                     tag = CMDTAG_DROP_TEXT_SEARCH_TEMPLATE;
    2461          12 :                     break;
    2462          16 :                 case OBJECT_TSCONFIGURATION:
    2463          16 :                     tag = CMDTAG_DROP_TEXT_SEARCH_CONFIGURATION;
    2464          16 :                     break;
    2465          78 :                 case OBJECT_FOREIGN_TABLE:
    2466          78 :                     tag = CMDTAG_DROP_FOREIGN_TABLE;
    2467          78 :                     break;
    2468          78 :                 case OBJECT_EXTENSION:
    2469          78 :                     tag = CMDTAG_DROP_EXTENSION;
    2470          78 :                     break;
    2471        1746 :                 case OBJECT_FUNCTION:
    2472        1746 :                     tag = CMDTAG_DROP_FUNCTION;
    2473        1746 :                     break;
    2474          76 :                 case OBJECT_PROCEDURE:
    2475          76 :                     tag = CMDTAG_DROP_PROCEDURE;
    2476          76 :                     break;
    2477          20 :                 case OBJECT_ROUTINE:
    2478          20 :                     tag = CMDTAG_DROP_ROUTINE;
    2479          20 :                     break;
    2480          70 :                 case OBJECT_AGGREGATE:
    2481          70 :                     tag = CMDTAG_DROP_AGGREGATE;
    2482          70 :                     break;
    2483          78 :                 case OBJECT_OPERATOR:
    2484          78 :                     tag = CMDTAG_DROP_OPERATOR;
    2485          78 :                     break;
    2486          18 :                 case OBJECT_LANGUAGE:
    2487          18 :                     tag = CMDTAG_DROP_LANGUAGE;
    2488          18 :                     break;
    2489          36 :                 case OBJECT_CAST:
    2490          36 :                     tag = CMDTAG_DROP_CAST;
    2491          36 :                     break;
    2492         522 :                 case OBJECT_TRIGGER:
    2493         522 :                     tag = CMDTAG_DROP_TRIGGER;
    2494         522 :                     break;
    2495          62 :                 case OBJECT_EVENT_TRIGGER:
    2496          62 :                     tag = CMDTAG_DROP_EVENT_TRIGGER;
    2497          62 :                     break;
    2498         134 :                 case OBJECT_RULE:
    2499         134 :                     tag = CMDTAG_DROP_RULE;
    2500         134 :                     break;
    2501          88 :                 case OBJECT_FDW:
    2502          88 :                     tag = CMDTAG_DROP_FOREIGN_DATA_WRAPPER;
    2503          88 :                     break;
    2504          74 :                 case OBJECT_FOREIGN_SERVER:
    2505          74 :                     tag = CMDTAG_DROP_SERVER;
    2506          74 :                     break;
    2507          34 :                 case OBJECT_OPCLASS:
    2508          34 :                     tag = CMDTAG_DROP_OPERATOR_CLASS;
    2509          34 :                     break;
    2510          86 :                 case OBJECT_OPFAMILY:
    2511          86 :                     tag = CMDTAG_DROP_OPERATOR_FAMILY;
    2512          86 :                     break;
    2513          94 :                 case OBJECT_POLICY:
    2514          94 :                     tag = CMDTAG_DROP_POLICY;
    2515          94 :                     break;
    2516          16 :                 case OBJECT_TRANSFORM:
    2517          16 :                     tag = CMDTAG_DROP_TRANSFORM;
    2518          16 :                     break;
    2519          24 :                 case OBJECT_ACCESS_METHOD:
    2520          24 :                     tag = CMDTAG_DROP_ACCESS_METHOD;
    2521          24 :                     break;
    2522          38 :                 case OBJECT_PUBLICATION:
    2523          38 :                     tag = CMDTAG_DROP_PUBLICATION;
    2524          38 :                     break;
    2525          28 :                 case OBJECT_STATISTIC_EXT:
    2526          28 :                     tag = CMDTAG_DROP_STATISTICS;
    2527          28 :                     break;
    2528           0 :                 default:
    2529           0 :                     tag = CMDTAG_UNKNOWN;
    2530             :             }
    2531       13474 :             break;
    2532             : 
    2533         790 :         case T_TruncateStmt:
    2534         790 :             tag = CMDTAG_TRUNCATE_TABLE;
    2535         790 :             break;
    2536             : 
    2537       18114 :         case T_CommentStmt:
    2538       18114 :             tag = CMDTAG_COMMENT;
    2539       18114 :             break;
    2540             : 
    2541          88 :         case T_SecLabelStmt:
    2542          88 :             tag = CMDTAG_SECURITY_LABEL;
    2543          88 :             break;
    2544             : 
    2545        4154 :         case T_CopyStmt:
    2546        4154 :             tag = CMDTAG_COPY;
    2547        4154 :             break;
    2548             : 
    2549         760 :         case T_RenameStmt:
    2550             : 
    2551             :             /*
    2552             :              * When the column is renamed, the command tag is created from its
    2553             :              * relation type
    2554             :              */
    2555         760 :             tag = AlterObjectTypeCommandTag(((RenameStmt *) parsetree)->renameType == OBJECT_COLUMN ?
    2556             :                                             ((RenameStmt *) parsetree)->relationType :
    2557             :                                             ((RenameStmt *) parsetree)->renameType);
    2558         760 :             break;
    2559             : 
    2560          46 :         case T_AlterObjectDependsStmt:
    2561          46 :             tag = AlterObjectTypeCommandTag(((AlterObjectDependsStmt *) parsetree)->objectType);
    2562          46 :             break;
    2563             : 
    2564         256 :         case T_AlterObjectSchemaStmt:
    2565         256 :             tag = AlterObjectTypeCommandTag(((AlterObjectSchemaStmt *) parsetree)->objectType);
    2566         256 :             break;
    2567             : 
    2568        1106 :         case T_AlterOwnerStmt:
    2569        1106 :             tag = AlterObjectTypeCommandTag(((AlterOwnerStmt *) parsetree)->objectType);
    2570        1106 :             break;
    2571             : 
    2572          12 :         case T_AlterTableMoveAllStmt:
    2573          12 :             tag = AlterObjectTypeCommandTag(((AlterTableMoveAllStmt *) parsetree)->objtype);
    2574          12 :             break;
    2575             : 
    2576       10412 :         case T_AlterTableStmt:
    2577       10412 :             tag = AlterObjectTypeCommandTag(((AlterTableStmt *) parsetree)->relkind);
    2578       10412 :             break;
    2579             : 
    2580         152 :         case T_AlterDomainStmt:
    2581         152 :             tag = CMDTAG_ALTER_DOMAIN;
    2582         152 :             break;
    2583             : 
    2584         120 :         case T_AlterFunctionStmt:
    2585         120 :             switch (((AlterFunctionStmt *) parsetree)->objtype)
    2586             :             {
    2587         108 :                 case OBJECT_FUNCTION:
    2588         108 :                     tag = CMDTAG_ALTER_FUNCTION;
    2589         108 :                     break;
    2590          12 :                 case OBJECT_PROCEDURE:
    2591          12 :                     tag = CMDTAG_ALTER_PROCEDURE;
    2592          12 :                     break;
    2593           0 :                 case OBJECT_ROUTINE:
    2594           0 :                     tag = CMDTAG_ALTER_ROUTINE;
    2595           0 :                     break;
    2596           0 :                 default:
    2597           0 :                     tag = CMDTAG_UNKNOWN;
    2598             :             }
    2599         120 :             break;
    2600             : 
    2601       44816 :         case T_GrantStmt:
    2602             :             {
    2603       44816 :                 GrantStmt  *stmt = (GrantStmt *) parsetree;
    2604             : 
    2605       44816 :                 tag = (stmt->is_grant) ? CMDTAG_GRANT : CMDTAG_REVOKE;
    2606             :             }
    2607       44816 :             break;
    2608             : 
    2609        1146 :         case T_GrantRoleStmt:
    2610             :             {
    2611        1146 :                 GrantRoleStmt *stmt = (GrantRoleStmt *) parsetree;
    2612             : 
    2613        1146 :                 tag = (stmt->is_grant) ? CMDTAG_GRANT_ROLE : CMDTAG_REVOKE_ROLE;
    2614             :             }
    2615        1146 :             break;
    2616             : 
    2617          98 :         case T_AlterDefaultPrivilegesStmt:
    2618          98 :             tag = CMDTAG_ALTER_DEFAULT_PRIVILEGES;
    2619          98 :             break;
    2620             : 
    2621       17416 :         case T_DefineStmt:
    2622       17416 :             switch (((DefineStmt *) parsetree)->kind)
    2623             :             {
    2624         632 :                 case OBJECT_AGGREGATE:
    2625         632 :                     tag = CMDTAG_CREATE_AGGREGATE;
    2626         632 :                     break;
    2627         238 :                 case OBJECT_OPERATOR:
    2628         238 :                     tag = CMDTAG_CREATE_OPERATOR;
    2629         238 :                     break;
    2630         190 :                 case OBJECT_TYPE:
    2631         190 :                     tag = CMDTAG_CREATE_TYPE;
    2632         190 :                     break;
    2633          28 :                 case OBJECT_TSPARSER:
    2634          28 :                     tag = CMDTAG_CREATE_TEXT_SEARCH_PARSER;
    2635          28 :                     break;
    2636        7978 :                 case OBJECT_TSDICTIONARY:
    2637        7978 :                     tag = CMDTAG_CREATE_TEXT_SEARCH_DICTIONARY;
    2638        7978 :                     break;
    2639         386 :                 case OBJECT_TSTEMPLATE:
    2640         386 :                     tag = CMDTAG_CREATE_TEXT_SEARCH_TEMPLATE;
    2641         386 :                     break;
    2642        7942 :                 case OBJECT_TSCONFIGURATION:
    2643        7942 :                     tag = CMDTAG_CREATE_TEXT_SEARCH_CONFIGURATION;
    2644        7942 :                     break;
    2645          22 :                 case OBJECT_COLLATION:
    2646          22 :                     tag = CMDTAG_CREATE_COLLATION;
    2647          22 :                     break;
    2648           0 :                 case OBJECT_ACCESS_METHOD:
    2649           0 :                     tag = CMDTAG_CREATE_ACCESS_METHOD;
    2650           0 :                     break;
    2651           0 :                 default:
    2652           0 :                     tag = CMDTAG_UNKNOWN;
    2653             :             }
    2654       17416 :             break;
    2655             : 
    2656         420 :         case T_CompositeTypeStmt:
    2657         420 :             tag = CMDTAG_CREATE_TYPE;
    2658         420 :             break;
    2659             : 
    2660         116 :         case T_CreateEnumStmt:
    2661         116 :             tag = CMDTAG_CREATE_TYPE;
    2662         116 :             break;
    2663             : 
    2664          68 :         case T_CreateRangeStmt:
    2665          68 :             tag = CMDTAG_CREATE_TYPE;
    2666          68 :             break;
    2667             : 
    2668         292 :         case T_AlterEnumStmt:
    2669         292 :             tag = CMDTAG_ALTER_TYPE;
    2670         292 :             break;
    2671             : 
    2672       47398 :         case T_ViewStmt:
    2673       47398 :             tag = CMDTAG_CREATE_VIEW;
    2674       47398 :             break;
    2675             : 
    2676       20830 :         case T_CreateFunctionStmt:
    2677       20830 :             if (((CreateFunctionStmt *) parsetree)->is_procedure)
    2678         188 :                 tag = CMDTAG_CREATE_PROCEDURE;
    2679             :             else
    2680       20642 :                 tag = CMDTAG_CREATE_FUNCTION;
    2681       20830 :             break;
    2682             : 
    2683        3156 :         case T_IndexStmt:
    2684        3156 :             tag = CMDTAG_CREATE_INDEX;
    2685        3156 :             break;
    2686             : 
    2687        1258 :         case T_RuleStmt:
    2688        1258 :             tag = CMDTAG_CREATE_RULE;
    2689        1258 :             break;
    2690             : 
    2691         370 :         case T_CreateSeqStmt:
    2692         370 :             tag = CMDTAG_CREATE_SEQUENCE;
    2693         370 :             break;
    2694             : 
    2695         150 :         case T_AlterSeqStmt:
    2696         150 :             tag = CMDTAG_ALTER_SEQUENCE;
    2697         150 :             break;
    2698             : 
    2699         534 :         case T_DoStmt:
    2700         534 :             tag = CMDTAG_DO;
    2701         534 :             break;
    2702             : 
    2703         960 :         case T_CreatedbStmt:
    2704         960 :             tag = CMDTAG_CREATE_DATABASE;
    2705         960 :             break;
    2706             : 
    2707           6 :         case T_AlterDatabaseStmt:
    2708           6 :             tag = CMDTAG_ALTER_DATABASE;
    2709           6 :             break;
    2710             : 
    2711         840 :         case T_AlterDatabaseSetStmt:
    2712         840 :             tag = CMDTAG_ALTER_DATABASE;
    2713         840 :             break;
    2714             : 
    2715          40 :         case T_DropdbStmt:
    2716          40 :             tag = CMDTAG_DROP_DATABASE;
    2717          40 :             break;
    2718             : 
    2719          82 :         case T_NotifyStmt:
    2720          82 :             tag = CMDTAG_NOTIFY;
    2721          82 :             break;
    2722             : 
    2723          42 :         case T_ListenStmt:
    2724          42 :             tag = CMDTAG_LISTEN;
    2725          42 :             break;
    2726             : 
    2727          34 :         case T_UnlistenStmt:
    2728          34 :             tag = CMDTAG_UNLISTEN;
    2729          34 :             break;
    2730             : 
    2731          18 :         case T_LoadStmt:
    2732          18 :             tag = CMDTAG_LOAD;
    2733          18 :             break;
    2734             : 
    2735         240 :         case T_CallStmt:
    2736         240 :             tag = CMDTAG_CALL;
    2737         240 :             break;
    2738             : 
    2739         104 :         case T_ClusterStmt:
    2740         104 :             tag = CMDTAG_CLUSTER;
    2741         104 :             break;
    2742             : 
    2743       13014 :         case T_VacuumStmt:
    2744       13014 :             if (((VacuumStmt *) parsetree)->is_vacuumcmd)
    2745        3968 :                 tag = CMDTAG_VACUUM;
    2746             :             else
    2747        9046 :                 tag = CMDTAG_ANALYZE;
    2748       13014 :             break;
    2749             : 
    2750       10406 :         case T_ExplainStmt:
    2751       10406 :             tag = CMDTAG_EXPLAIN;
    2752       10406 :             break;
    2753             : 
    2754         824 :         case T_CreateTableAsStmt:
    2755         824 :             switch (((CreateTableAsStmt *) parsetree)->relkind)
    2756             :             {
    2757         624 :                 case OBJECT_TABLE:
    2758         624 :                     if (((CreateTableAsStmt *) parsetree)->is_select_into)
    2759           0 :                         tag = CMDTAG_SELECT_INTO;
    2760             :                     else
    2761         624 :                         tag = CMDTAG_CREATE_TABLE_AS;
    2762         624 :                     break;
    2763         200 :                 case OBJECT_MATVIEW:
    2764         200 :                     tag = CMDTAG_CREATE_MATERIALIZED_VIEW;
    2765         200 :                     break;
    2766           0 :                 default:
    2767           0 :                     tag = CMDTAG_UNKNOWN;
    2768             :             }
    2769         824 :             break;
    2770             : 
    2771          96 :         case T_RefreshMatViewStmt:
    2772          96 :             tag = CMDTAG_REFRESH_MATERIALIZED_VIEW;
    2773          96 :             break;
    2774             : 
    2775          40 :         case T_AlterSystemStmt:
    2776          40 :             tag = CMDTAG_ALTER_SYSTEM;
    2777          40 :             break;
    2778             : 
    2779       12374 :         case T_VariableSetStmt:
    2780       12374 :             switch (((VariableSetStmt *) parsetree)->kind)
    2781             :             {
    2782       10566 :                 case VAR_SET_VALUE:
    2783             :                 case VAR_SET_CURRENT:
    2784             :                 case VAR_SET_DEFAULT:
    2785             :                 case VAR_SET_MULTI:
    2786       10566 :                     tag = CMDTAG_SET;
    2787       10566 :                     break;
    2788        1808 :                 case VAR_RESET:
    2789             :                 case VAR_RESET_ALL:
    2790        1808 :                     tag = CMDTAG_RESET;
    2791        1808 :                     break;
    2792           0 :                 default:
    2793           0 :                     tag = CMDTAG_UNKNOWN;
    2794             :             }
    2795       12374 :             break;
    2796             : 
    2797         456 :         case T_VariableShowStmt:
    2798         456 :             tag = CMDTAG_SHOW;
    2799         456 :             break;
    2800             : 
    2801          20 :         case T_DiscardStmt:
    2802          20 :             switch (((DiscardStmt *) parsetree)->target)
    2803             :             {
    2804           4 :                 case DISCARD_ALL:
    2805           4 :                     tag = CMDTAG_DISCARD_ALL;
    2806           4 :                     break;
    2807           4 :                 case DISCARD_PLANS:
    2808           4 :                     tag = CMDTAG_DISCARD_PLANS;
    2809           4 :                     break;
    2810           4 :                 case DISCARD_TEMP:
    2811           4 :                     tag = CMDTAG_DISCARD_TEMP;
    2812           4 :                     break;
    2813           8 :                 case DISCARD_SEQUENCES:
    2814           8 :                     tag = CMDTAG_DISCARD_SEQUENCES;
    2815           8 :                     break;
    2816           0 :                 default:
    2817           0 :                     tag = CMDTAG_UNKNOWN;
    2818             :             }
    2819          20 :             break;
    2820             : 
    2821          36 :         case T_CreateTransformStmt:
    2822          36 :             tag = CMDTAG_CREATE_TRANSFORM;
    2823          36 :             break;
    2824             : 
    2825        2016 :         case T_CreateTrigStmt:
    2826        2016 :             tag = CMDTAG_CREATE_TRIGGER;
    2827        2016 :             break;
    2828             : 
    2829         108 :         case T_CreateEventTrigStmt:
    2830         108 :             tag = CMDTAG_CREATE_EVENT_TRIGGER;
    2831         108 :             break;
    2832             : 
    2833          20 :         case T_AlterEventTrigStmt:
    2834          20 :             tag = CMDTAG_ALTER_EVENT_TRIGGER;
    2835          20 :             break;
    2836             : 
    2837          10 :         case T_CreatePLangStmt:
    2838          10 :             tag = CMDTAG_CREATE_LANGUAGE;
    2839          10 :             break;
    2840             : 
    2841         740 :         case T_CreateRoleStmt:
    2842         740 :             tag = CMDTAG_CREATE_ROLE;
    2843         740 :             break;
    2844             : 
    2845         218 :         case T_AlterRoleStmt:
    2846         218 :             tag = CMDTAG_ALTER_ROLE;
    2847         218 :             break;
    2848             : 
    2849          58 :         case T_AlterRoleSetStmt:
    2850          58 :             tag = CMDTAG_ALTER_ROLE;
    2851          58 :             break;
    2852             : 
    2853         752 :         case T_DropRoleStmt:
    2854         752 :             tag = CMDTAG_DROP_ROLE;
    2855         752 :             break;
    2856             : 
    2857          78 :         case T_DropOwnedStmt:
    2858          78 :             tag = CMDTAG_DROP_OWNED;
    2859          78 :             break;
    2860             : 
    2861          16 :         case T_ReassignOwnedStmt:
    2862          16 :             tag = CMDTAG_REASSIGN_OWNED;
    2863          16 :             break;
    2864             : 
    2865        4184 :         case T_LockStmt:
    2866        4184 :             tag = CMDTAG_LOCK_TABLE;
    2867        4184 :             break;
    2868             : 
    2869          66 :         case T_ConstraintsSetStmt:
    2870          66 :             tag = CMDTAG_SET_CONSTRAINTS;
    2871          66 :             break;
    2872             : 
    2873         110 :         case T_CheckPointStmt:
    2874         110 :             tag = CMDTAG_CHECKPOINT;
    2875         110 :             break;
    2876             : 
    2877         306 :         case T_ReindexStmt:
    2878         306 :             tag = CMDTAG_REINDEX;
    2879         306 :             break;
    2880             : 
    2881          52 :         case T_CreateConversionStmt:
    2882          52 :             tag = CMDTAG_CREATE_CONVERSION;
    2883          52 :             break;
    2884             : 
    2885         126 :         case T_CreateCastStmt:
    2886         126 :             tag = CMDTAG_CREATE_CAST;
    2887         126 :             break;
    2888             : 
    2889          72 :         case T_CreateOpClassStmt:
    2890          72 :             tag = CMDTAG_CREATE_OPERATOR_CLASS;
    2891          72 :             break;
    2892             : 
    2893         100 :         case T_CreateOpFamilyStmt:
    2894         100 :             tag = CMDTAG_CREATE_OPERATOR_FAMILY;
    2895         100 :             break;
    2896             : 
    2897         188 :         case T_AlterOpFamilyStmt:
    2898         188 :             tag = CMDTAG_ALTER_OPERATOR_FAMILY;
    2899         188 :             break;
    2900             : 
    2901          56 :         case T_AlterOperatorStmt:
    2902          56 :             tag = CMDTAG_ALTER_OPERATOR;
    2903          56 :             break;
    2904             : 
    2905          16 :         case T_AlterTypeStmt:
    2906          16 :             tag = CMDTAG_ALTER_TYPE;
    2907          16 :             break;
    2908             : 
    2909          34 :         case T_AlterTSDictionaryStmt:
    2910          34 :             tag = CMDTAG_ALTER_TEXT_SEARCH_DICTIONARY;
    2911          34 :             break;
    2912             : 
    2913       23814 :         case T_AlterTSConfigurationStmt:
    2914       23814 :             tag = CMDTAG_ALTER_TEXT_SEARCH_CONFIGURATION;
    2915       23814 :             break;
    2916             : 
    2917         402 :         case T_CreatePolicyStmt:
    2918         402 :             tag = CMDTAG_CREATE_POLICY;
    2919         402 :             break;
    2920             : 
    2921          64 :         case T_AlterPolicyStmt:
    2922          64 :             tag = CMDTAG_ALTER_POLICY;
    2923          64 :             break;
    2924             : 
    2925          38 :         case T_CreateAmStmt:
    2926          38 :             tag = CMDTAG_CREATE_ACCESS_METHOD;
    2927          38 :             break;
    2928             : 
    2929         112 :         case T_CreatePublicationStmt:
    2930         112 :             tag = CMDTAG_CREATE_PUBLICATION;
    2931         112 :             break;
    2932             : 
    2933          98 :         case T_AlterPublicationStmt:
    2934          98 :             tag = CMDTAG_ALTER_PUBLICATION;
    2935          98 :             break;
    2936             : 
    2937         110 :         case T_CreateSubscriptionStmt:
    2938         110 :             tag = CMDTAG_CREATE_SUBSCRIPTION;
    2939         110 :             break;
    2940             : 
    2941          68 :         case T_AlterSubscriptionStmt:
    2942          68 :             tag = CMDTAG_ALTER_SUBSCRIPTION;
    2943          68 :             break;
    2944             : 
    2945          42 :         case T_DropSubscriptionStmt:
    2946          42 :             tag = CMDTAG_DROP_SUBSCRIPTION;
    2947          42 :             break;
    2948             : 
    2949           0 :         case T_AlterCollationStmt:
    2950           0 :             tag = CMDTAG_ALTER_COLLATION;
    2951           0 :             break;
    2952             : 
    2953         304 :         case T_PrepareStmt:
    2954         304 :             tag = CMDTAG_PREPARE;
    2955         304 :             break;
    2956             : 
    2957         818 :         case T_ExecuteStmt:
    2958         818 :             tag = CMDTAG_EXECUTE;
    2959         818 :             break;
    2960             : 
    2961         196 :         case T_CreateStatsStmt:
    2962         196 :             tag = CMDTAG_CREATE_STATISTICS;
    2963         196 :             break;
    2964             : 
    2965          20 :         case T_AlterStatsStmt:
    2966          20 :             tag = CMDTAG_ALTER_STATISTICS;
    2967          20 :             break;
    2968             : 
    2969        3768 :         case T_DeallocateStmt:
    2970             :             {
    2971        3768 :                 DeallocateStmt *stmt = (DeallocateStmt *) parsetree;
    2972             : 
    2973        3768 :                 if (stmt->name == NULL)
    2974          24 :                     tag = CMDTAG_DEALLOCATE_ALL;
    2975             :                 else
    2976        3744 :                     tag = CMDTAG_DEALLOCATE;
    2977             :             }
    2978        3768 :             break;
    2979             : 
    2980             :             /* already-planned queries */
    2981          20 :         case T_PlannedStmt:
    2982             :             {
    2983          20 :                 PlannedStmt *stmt = (PlannedStmt *) parsetree;
    2984             : 
    2985          20 :                 switch (stmt->commandType)
    2986             :                 {
    2987           0 :                     case CMD_SELECT:
    2988             : 
    2989             :                         /*
    2990             :                          * We take a little extra care here so that the result
    2991             :                          * will be useful for complaints about read-only
    2992             :                          * statements
    2993             :                          */
    2994           0 :                         if (stmt->rowMarks != NIL)
    2995             :                         {
    2996             :                             /* not 100% but probably close enough */
    2997           0 :                             switch (((PlanRowMark *) linitial(stmt->rowMarks))->strength)
    2998             :                             {
    2999           0 :                                 case LCS_FORKEYSHARE:
    3000           0 :                                     tag = CMDTAG_SELECT_FOR_KEY_SHARE;
    3001           0 :                                     break;
    3002           0 :                                 case LCS_FORSHARE:
    3003           0 :                                     tag = CMDTAG_SELECT_FOR_SHARE;
    3004           0 :                                     break;
    3005           0 :                                 case LCS_FORNOKEYUPDATE:
    3006           0 :                                     tag = CMDTAG_SELECT_FOR_NO_KEY_UPDATE;
    3007           0 :                                     break;
    3008           0 :                                 case LCS_FORUPDATE:
    3009           0 :                                     tag = CMDTAG_SELECT_FOR_UPDATE;
    3010           0 :                                     break;
    3011           0 :                                 default:
    3012           0 :                                     tag = CMDTAG_SELECT;
    3013           0 :                                     break;
    3014             :                             }
    3015             :                         }
    3016             :                         else
    3017           0 :                             tag = CMDTAG_SELECT;
    3018           0 :                         break;
    3019           8 :                     case CMD_UPDATE:
    3020           8 :                         tag = CMDTAG_UPDATE;
    3021           8 :                         break;
    3022           8 :                     case CMD_INSERT:
    3023           8 :                         tag = CMDTAG_INSERT;
    3024           8 :                         break;
    3025           4 :                     case CMD_DELETE:
    3026           4 :                         tag = CMDTAG_DELETE;
    3027           4 :                         break;
    3028           0 :                     case CMD_UTILITY:
    3029           0 :                         tag = CreateCommandTag(stmt->utilityStmt);
    3030           0 :                         break;
    3031           0 :                     default:
    3032           0 :                         elog(WARNING, "unrecognized commandType: %d",
    3033             :                              (int) stmt->commandType);
    3034           0 :                         tag = CMDTAG_UNKNOWN;
    3035           0 :                         break;
    3036             :                 }
    3037             :             }
    3038          20 :             break;
    3039             : 
    3040             :             /* parsed-and-rewritten-but-not-planned queries */
    3041           0 :         case T_Query:
    3042             :             {
    3043           0 :                 Query      *stmt = (Query *) parsetree;
    3044             : 
    3045           0 :                 switch (stmt->commandType)
    3046             :                 {
    3047           0 :                     case CMD_SELECT:
    3048             : 
    3049             :                         /*
    3050             :                          * We take a little extra care here so that the result
    3051             :                          * will be useful for complaints about read-only
    3052             :                          * statements
    3053             :                          */
    3054           0 :                         if (stmt->rowMarks != NIL)
    3055             :                         {
    3056             :                             /* not 100% but probably close enough */
    3057           0 :                             switch (((RowMarkClause *) linitial(stmt->rowMarks))->strength)
    3058             :                             {
    3059           0 :                                 case LCS_FORKEYSHARE:
    3060           0 :                                     tag = CMDTAG_SELECT_FOR_KEY_SHARE;
    3061           0 :                                     break;
    3062           0 :                                 case LCS_FORSHARE:
    3063           0 :                                     tag = CMDTAG_SELECT_FOR_SHARE;
    3064           0 :                                     break;
    3065           0 :                                 case LCS_FORNOKEYUPDATE:
    3066           0 :                                     tag = CMDTAG_SELECT_FOR_NO_KEY_UPDATE;
    3067           0 :                                     break;
    3068           0 :                                 case LCS_FORUPDATE:
    3069           0 :                                     tag = CMDTAG_SELECT_FOR_UPDATE;
    3070           0 :                                     break;
    3071           0 :                                 default:
    3072           0 :                                     tag = CMDTAG_UNKNOWN;
    3073           0 :                                     break;
    3074             :                             }
    3075             :                         }
    3076             :                         else
    3077           0 :                             tag = CMDTAG_SELECT;
    3078           0 :                         break;
    3079           0 :                     case CMD_UPDATE:
    3080           0 :                         tag = CMDTAG_UPDATE;
    3081           0 :                         break;
    3082           0 :                     case CMD_INSERT:
    3083           0 :                         tag = CMDTAG_INSERT;
    3084           0 :                         break;
    3085           0 :                     case CMD_DELETE:
    3086           0 :                         tag = CMDTAG_DELETE;
    3087           0 :                         break;
    3088           0 :                     case CMD_UTILITY:
    3089           0 :                         tag = CreateCommandTag(stmt->utilityStmt);
    3090           0 :                         break;
    3091           0 :                     default:
    3092           0 :                         elog(WARNING, "unrecognized commandType: %d",
    3093             :                              (int) stmt->commandType);
    3094           0 :                         tag = CMDTAG_UNKNOWN;
    3095           0 :                         break;
    3096             :                 }
    3097             :             }
    3098           0 :             break;
    3099             : 
    3100           0 :         default:
    3101           0 :             elog(WARNING, "unrecognized node type: %d",
    3102             :                  (int) nodeTag(parsetree));
    3103           0 :             tag = CMDTAG_UNKNOWN;
    3104           0 :             break;
    3105             :     }
    3106             : 
    3107      553006 :     return tag;
    3108             : }
    3109             : 
    3110             : 
    3111             : /*
    3112             :  * GetCommandLogLevel
    3113             :  *      utility to get the minimum log_statement level for a command,
    3114             :  *      given either a raw (un-analyzed) parsetree, an analyzed Query,
    3115             :  *      or a PlannedStmt.
    3116             :  *
    3117             :  * This must handle all command types, but since the vast majority
    3118             :  * of 'em are utility commands, it seems sensible to keep it here.
    3119             :  */
    3120             : LogStmtLevel
    3121           0 : GetCommandLogLevel(Node *parsetree)
    3122             : {
    3123             :     LogStmtLevel lev;
    3124             : 
    3125           0 :     switch (nodeTag(parsetree))
    3126             :     {
    3127             :             /* recurse if we're given a RawStmt */
    3128           0 :         case T_RawStmt:
    3129           0 :             lev = GetCommandLogLevel(((RawStmt *) parsetree)->stmt);
    3130           0 :             break;
    3131             : 
    3132             :             /* raw plannable queries */
    3133           0 :         case T_InsertStmt:
    3134             :         case T_DeleteStmt:
    3135             :         case T_UpdateStmt:
    3136           0 :             lev = LOGSTMT_MOD;
    3137           0 :             break;
    3138             : 
    3139           0 :         case T_SelectStmt:
    3140           0 :             if (((SelectStmt *) parsetree)->intoClause)
    3141           0 :                 lev = LOGSTMT_DDL;  /* SELECT INTO */
    3142             :             else
    3143           0 :                 lev = LOGSTMT_ALL;
    3144           0 :             break;
    3145             : 
    3146             :             /* utility statements --- same whether raw or cooked */
    3147           0 :         case T_TransactionStmt:
    3148           0 :             lev = LOGSTMT_ALL;
    3149           0 :             break;
    3150             : 
    3151           0 :         case T_DeclareCursorStmt:
    3152           0 :             lev = LOGSTMT_ALL;
    3153           0 :             break;
    3154             : 
    3155           0 :         case T_ClosePortalStmt:
    3156           0 :             lev = LOGSTMT_ALL;
    3157           0 :             break;
    3158             : 
    3159           0 :         case T_FetchStmt:
    3160           0 :             lev = LOGSTMT_ALL;
    3161           0 :             break;
    3162             : 
    3163           0 :         case T_CreateSchemaStmt:
    3164           0 :             lev = LOGSTMT_DDL;
    3165           0 :             break;
    3166             : 
    3167           0 :         case T_CreateStmt:
    3168             :         case T_CreateForeignTableStmt:
    3169           0 :             lev = LOGSTMT_DDL;
    3170           0 :             break;
    3171             : 
    3172           0 :         case T_CreateTableSpaceStmt:
    3173             :         case T_DropTableSpaceStmt:
    3174             :         case T_AlterTableSpaceOptionsStmt:
    3175           0 :             lev = LOGSTMT_DDL;
    3176           0 :             break;
    3177             : 
    3178           0 :         case T_CreateExtensionStmt:
    3179             :         case T_AlterExtensionStmt:
    3180             :         case T_AlterExtensionContentsStmt:
    3181           0 :             lev = LOGSTMT_DDL;
    3182           0 :             break;
    3183             : 
    3184           0 :         case T_CreateFdwStmt:
    3185             :         case T_AlterFdwStmt:
    3186             :         case T_CreateForeignServerStmt:
    3187             :         case T_AlterForeignServerStmt:
    3188             :         case T_CreateUserMappingStmt:
    3189             :         case T_AlterUserMappingStmt:
    3190             :         case T_DropUserMappingStmt:
    3191             :         case T_ImportForeignSchemaStmt:
    3192           0 :             lev = LOGSTMT_DDL;
    3193           0 :             break;
    3194             : 
    3195           0 :         case T_DropStmt:
    3196           0 :             lev = LOGSTMT_DDL;
    3197           0 :             break;
    3198             : 
    3199           0 :         case T_TruncateStmt:
    3200           0 :             lev = LOGSTMT_MOD;
    3201           0 :             break;
    3202             : 
    3203           0 :         case T_CommentStmt:
    3204           0 :             lev = LOGSTMT_DDL;
    3205           0 :             break;
    3206             : 
    3207           0 :         case T_SecLabelStmt:
    3208           0 :             lev = LOGSTMT_DDL;
    3209           0 :             break;
    3210             : 
    3211           0 :         case T_CopyStmt:
    3212           0 :             if (((CopyStmt *) parsetree)->is_from)
    3213           0 :                 lev = LOGSTMT_MOD;
    3214             :             else
    3215           0 :                 lev = LOGSTMT_ALL;
    3216           0 :             break;
    3217             : 
    3218           0 :         case T_PrepareStmt:
    3219             :             {
    3220           0 :                 PrepareStmt *stmt = (PrepareStmt *) parsetree;
    3221             : 
    3222             :                 /* Look through a PREPARE to the contained stmt */
    3223           0 :                 lev = GetCommandLogLevel(stmt->query);
    3224             :             }
    3225           0 :             break;
    3226             : 
    3227           0 :         case T_ExecuteStmt:
    3228             :             {
    3229           0 :                 ExecuteStmt *stmt = (ExecuteStmt *) parsetree;
    3230             :                 PreparedStatement *ps;
    3231             : 
    3232             :                 /* Look through an EXECUTE to the referenced stmt */
    3233           0 :                 ps = FetchPreparedStatement(stmt->name, false);
    3234           0 :                 if (ps && ps->plansource->raw_parse_tree)
    3235           0 :                     lev = GetCommandLogLevel(ps->plansource->raw_parse_tree->stmt);
    3236             :                 else
    3237           0 :                     lev = LOGSTMT_ALL;
    3238             :             }
    3239           0 :             break;
    3240             : 
    3241           0 :         case T_DeallocateStmt:
    3242           0 :             lev = LOGSTMT_ALL;
    3243           0 :             break;
    3244             : 
    3245           0 :         case T_RenameStmt:
    3246           0 :             lev = LOGSTMT_DDL;
    3247           0 :             break;
    3248             : 
    3249           0 :         case T_AlterObjectDependsStmt:
    3250           0 :             lev = LOGSTMT_DDL;
    3251           0 :             break;
    3252             : 
    3253           0 :         case T_AlterObjectSchemaStmt:
    3254           0 :             lev = LOGSTMT_DDL;
    3255           0 :             break;
    3256             : 
    3257           0 :         case T_AlterOwnerStmt:
    3258           0 :             lev = LOGSTMT_DDL;
    3259           0 :             break;
    3260             : 
    3261           0 :         case T_AlterOperatorStmt:
    3262           0 :             lev = LOGSTMT_DDL;
    3263           0 :             break;
    3264             : 
    3265           0 :         case T_AlterTypeStmt:
    3266           0 :             lev = LOGSTMT_DDL;
    3267           0 :             break;
    3268             : 
    3269           0 :         case T_AlterTableMoveAllStmt:
    3270             :         case T_AlterTableStmt:
    3271           0 :             lev = LOGSTMT_DDL;
    3272           0 :             break;
    3273             : 
    3274           0 :         case T_AlterDomainStmt:
    3275           0 :             lev = LOGSTMT_DDL;
    3276           0 :             break;
    3277             : 
    3278           0 :         case T_GrantStmt:
    3279           0 :             lev = LOGSTMT_DDL;
    3280           0 :             break;
    3281             : 
    3282           0 :         case T_GrantRoleStmt:
    3283           0 :             lev = LOGSTMT_DDL;
    3284           0 :             break;
    3285             : 
    3286           0 :         case T_AlterDefaultPrivilegesStmt:
    3287           0 :             lev = LOGSTMT_DDL;
    3288           0 :             break;
    3289             : 
    3290           0 :         case T_DefineStmt:
    3291           0 :             lev = LOGSTMT_DDL;
    3292           0 :             break;
    3293             : 
    3294           0 :         case T_CompositeTypeStmt:
    3295           0 :             lev = LOGSTMT_DDL;
    3296           0 :             break;
    3297             : 
    3298           0 :         case T_CreateEnumStmt:
    3299           0 :             lev = LOGSTMT_DDL;
    3300           0 :             break;
    3301             : 
    3302           0 :         case T_CreateRangeStmt:
    3303           0 :             lev = LOGSTMT_DDL;
    3304           0 :             break;
    3305             : 
    3306           0 :         case T_AlterEnumStmt:
    3307           0 :             lev = LOGSTMT_DDL;
    3308           0 :             break;
    3309             : 
    3310           0 :         case T_ViewStmt:
    3311           0 :             lev = LOGSTMT_DDL;
    3312           0 :             break;
    3313             : 
    3314           0 :         case T_CreateFunctionStmt:
    3315           0 :             lev = LOGSTMT_DDL;
    3316           0 :             break;
    3317             : 
    3318           0 :         case T_AlterFunctionStmt:
    3319           0 :             lev = LOGSTMT_DDL;
    3320           0 :             break;
    3321             : 
    3322           0 :         case T_IndexStmt:
    3323           0 :             lev = LOGSTMT_DDL;
    3324           0 :             break;
    3325             : 
    3326           0 :         case T_RuleStmt:
    3327           0 :             lev = LOGSTMT_DDL;
    3328           0 :             break;
    3329             : 
    3330           0 :         case T_CreateSeqStmt:
    3331           0 :             lev = LOGSTMT_DDL;
    3332           0 :             break;
    3333             : 
    3334           0 :         case T_AlterSeqStmt:
    3335           0 :             lev = LOGSTMT_DDL;
    3336           0 :             break;
    3337             : 
    3338           0 :         case T_DoStmt:
    3339           0 :             lev = LOGSTMT_ALL;
    3340           0 :             break;
    3341             : 
    3342           0 :         case T_CreatedbStmt:
    3343           0 :             lev = LOGSTMT_DDL;
    3344           0 :             break;
    3345             : 
    3346           0 :         case T_AlterDatabaseStmt:
    3347           0 :             lev = LOGSTMT_DDL;
    3348           0 :             break;
    3349             : 
    3350           0 :         case T_AlterDatabaseSetStmt:
    3351           0 :             lev = LOGSTMT_DDL;
    3352           0 :             break;
    3353             : 
    3354           0 :         case T_DropdbStmt:
    3355           0 :             lev = LOGSTMT_DDL;
    3356           0 :             break;
    3357             : 
    3358           0 :         case T_NotifyStmt:
    3359           0 :             lev = LOGSTMT_ALL;
    3360           0 :             break;
    3361             : 
    3362           0 :         case T_ListenStmt:
    3363           0 :             lev = LOGSTMT_ALL;
    3364           0 :             break;
    3365             : 
    3366           0 :         case T_UnlistenStmt:
    3367           0 :             lev = LOGSTMT_ALL;
    3368           0 :             break;
    3369             : 
    3370           0 :         case T_LoadStmt:
    3371           0 :             lev = LOGSTMT_ALL;
    3372           0 :             break;
    3373             : 
    3374           0 :         case T_CallStmt:
    3375           0 :             lev = LOGSTMT_ALL;
    3376           0 :             break;
    3377             : 
    3378           0 :         case T_ClusterStmt:
    3379           0 :             lev = LOGSTMT_DDL;
    3380           0 :             break;
    3381             : 
    3382           0 :         case T_VacuumStmt:
    3383           0 :             lev = LOGSTMT_ALL;
    3384           0 :             break;
    3385             : 
    3386           0 :         case T_ExplainStmt:
    3387             :             {
    3388           0 :                 ExplainStmt *stmt = (ExplainStmt *) parsetree;
    3389           0 :                 bool        analyze = false;
    3390             :                 ListCell   *lc;
    3391             : 
    3392             :                 /* Look through an EXPLAIN ANALYZE to the contained stmt */
    3393           0 :                 foreach(lc, stmt->options)
    3394             :                 {
    3395           0 :                     DefElem    *opt = (DefElem *) lfirst(lc);
    3396             : 
    3397           0 :                     if (strcmp(opt->defname, "analyze") == 0)
    3398           0 :                         analyze = defGetBoolean(opt);
    3399             :                     /* don't "break", as explain.c will use the last value */
    3400             :                 }
    3401           0 :                 if (analyze)
    3402           0 :                     return GetCommandLogLevel(stmt->query);
    3403             : 
    3404             :                 /* Plain EXPLAIN isn't so interesting */
    3405           0 :                 lev = LOGSTMT_ALL;
    3406             :             }
    3407           0 :             break;
    3408             : 
    3409           0 :         case T_CreateTableAsStmt:
    3410           0 :             lev = LOGSTMT_DDL;
    3411           0 :             break;
    3412             : 
    3413           0 :         case T_RefreshMatViewStmt:
    3414           0 :             lev = LOGSTMT_DDL;
    3415           0 :             break;
    3416             : 
    3417           0 :         case T_AlterSystemStmt:
    3418           0 :             lev = LOGSTMT_DDL;
    3419           0 :             break;
    3420             : 
    3421           0 :         case T_VariableSetStmt:
    3422           0 :             lev = LOGSTMT_ALL;
    3423           0 :             break;
    3424             : 
    3425           0 :         case T_VariableShowStmt:
    3426           0 :             lev = LOGSTMT_ALL;
    3427           0 :             break;
    3428             : 
    3429           0 :         case T_DiscardStmt:
    3430           0 :             lev = LOGSTMT_ALL;
    3431           0 :             break;
    3432             : 
    3433           0 :         case T_CreateTrigStmt:
    3434           0 :             lev = LOGSTMT_DDL;
    3435           0 :             break;
    3436             : 
    3437           0 :         case T_CreateEventTrigStmt:
    3438           0 :             lev = LOGSTMT_DDL;
    3439           0 :             break;
    3440             : 
    3441           0 :         case T_AlterEventTrigStmt:
    3442           0 :             lev = LOGSTMT_DDL;
    3443           0 :             break;
    3444             : 
    3445           0 :         case T_CreatePLangStmt:
    3446           0 :             lev = LOGSTMT_DDL;
    3447           0 :             break;
    3448             : 
    3449           0 :         case T_CreateDomainStmt:
    3450           0 :             lev = LOGSTMT_DDL;
    3451           0 :             break;
    3452             : 
    3453           0 :         case T_CreateRoleStmt:
    3454           0 :             lev = LOGSTMT_DDL;
    3455           0 :             break;
    3456             : 
    3457           0 :         case T_AlterRoleStmt:
    3458           0 :             lev = LOGSTMT_DDL;
    3459           0 :             break;
    3460             : 
    3461           0 :         case T_AlterRoleSetStmt:
    3462           0 :             lev = LOGSTMT_DDL;
    3463           0 :             break;
    3464             : 
    3465           0 :         case T_DropRoleStmt:
    3466           0 :             lev = LOGSTMT_DDL;
    3467           0 :             break;
    3468             : 
    3469           0 :         case T_DropOwnedStmt:
    3470           0 :             lev = LOGSTMT_DDL;
    3471           0 :             break;
    3472             : 
    3473           0 :         case T_ReassignOwnedStmt:
    3474           0 :             lev = LOGSTMT_DDL;
    3475           0 :             break;
    3476             : 
    3477           0 :         case T_LockStmt:
    3478           0 :             lev = LOGSTMT_ALL;
    3479           0 :             break;
    3480             : 
    3481           0 :         case T_ConstraintsSetStmt:
    3482           0 :             lev = LOGSTMT_ALL;
    3483           0 :             break;
    3484             : 
    3485           0 :         case T_CheckPointStmt:
    3486           0 :             lev = LOGSTMT_ALL;
    3487           0 :             break;
    3488             : 
    3489           0 :         case T_ReindexStmt:
    3490           0 :             lev = LOGSTMT_ALL;  /* should this be DDL? */
    3491           0 :             break;
    3492             : 
    3493           0 :         case T_CreateConversionStmt:
    3494           0 :             lev = LOGSTMT_DDL;
    3495           0 :             break;
    3496             : 
    3497           0 :         case T_CreateCastStmt:
    3498           0 :             lev = LOGSTMT_DDL;
    3499           0 :             break;
    3500             : 
    3501           0 :         case T_CreateOpClassStmt:
    3502           0 :             lev = LOGSTMT_DDL;
    3503           0 :             break;
    3504             : 
    3505           0 :         case T_CreateOpFamilyStmt:
    3506           0 :             lev = LOGSTMT_DDL;
    3507           0 :             break;
    3508             : 
    3509           0 :         case T_CreateTransformStmt:
    3510           0 :             lev = LOGSTMT_DDL;
    3511           0 :             break;
    3512             : 
    3513           0 :         case T_AlterOpFamilyStmt:
    3514           0 :             lev = LOGSTMT_DDL;
    3515           0 :             break;
    3516             : 
    3517           0 :         case T_CreatePolicyStmt:
    3518           0 :             lev = LOGSTMT_DDL;
    3519           0 :             break;
    3520             : 
    3521           0 :         case T_AlterPolicyStmt:
    3522           0 :             lev = LOGSTMT_DDL;
    3523           0 :             break;
    3524             : 
    3525           0 :         case T_AlterTSDictionaryStmt:
    3526           0 :             lev = LOGSTMT_DDL;
    3527           0 :             break;
    3528             : 
    3529           0 :         case T_AlterTSConfigurationStmt:
    3530           0 :             lev = LOGSTMT_DDL;
    3531           0 :             break;
    3532             : 
    3533           0 :         case T_CreateAmStmt:
    3534           0 :             lev = LOGSTMT_DDL;
    3535           0 :             break;
    3536             : 
    3537           0 :         case T_CreatePublicationStmt:
    3538           0 :             lev = LOGSTMT_DDL;
    3539           0 :             break;
    3540             : 
    3541           0 :         case T_AlterPublicationStmt:
    3542           0 :             lev = LOGSTMT_DDL;
    3543           0 :             break;
    3544             : 
    3545           0 :         case T_CreateSubscriptionStmt:
    3546           0 :             lev = LOGSTMT_DDL;
    3547           0 :             break;
    3548             : 
    3549           0 :         case T_AlterSubscriptionStmt:
    3550           0 :             lev = LOGSTMT_DDL;
    3551           0 :             break;
    3552             : 
    3553           0 :         case T_DropSubscriptionStmt:
    3554           0 :             lev = LOGSTMT_DDL;
    3555           0 :             break;
    3556             : 
    3557           0 :         case T_CreateStatsStmt:
    3558           0 :             lev = LOGSTMT_DDL;
    3559           0 :             break;
    3560             : 
    3561           0 :         case T_AlterStatsStmt:
    3562           0 :             lev = LOGSTMT_DDL;
    3563           0 :             break;
    3564             : 
    3565           0 :         case T_AlterCollationStmt:
    3566           0 :             lev = LOGSTMT_DDL;
    3567           0 :             break;
    3568             : 
    3569             :             /* already-planned queries */
    3570           0 :         case T_PlannedStmt:
    3571             :             {
    3572           0 :                 PlannedStmt *stmt = (PlannedStmt *) parsetree;
    3573             : 
    3574           0 :                 switch (stmt->commandType)
    3575             :                 {
    3576           0 :                     case CMD_SELECT:
    3577           0 :                         lev = LOGSTMT_ALL;
    3578           0 :                         break;
    3579             : 
    3580           0 :                     case CMD_UPDATE:
    3581             :                     case CMD_INSERT:
    3582             :                     case CMD_DELETE:
    3583           0 :                         lev = LOGSTMT_MOD;
    3584           0 :                         break;
    3585             : 
    3586           0 :                     case CMD_UTILITY:
    3587           0 :                         lev = GetCommandLogLevel(stmt->utilityStmt);
    3588           0 :                         break;
    3589             : 
    3590           0 :                     default:
    3591           0 :                         elog(WARNING, "unrecognized commandType: %d",
    3592             :                              (int) stmt->commandType);
    3593           0 :                         lev = LOGSTMT_ALL;
    3594           0 :                         break;
    3595             :                 }
    3596             :             }
    3597           0 :             break;
    3598             : 
    3599             :             /* parsed-and-rewritten-but-not-planned queries */
    3600           0 :         case T_Query:
    3601             :             {
    3602           0 :                 Query      *stmt = (Query *) parsetree;
    3603             : 
    3604           0 :                 switch (stmt->commandType)
    3605             :                 {
    3606           0 :                     case CMD_SELECT:
    3607           0 :                         lev = LOGSTMT_ALL;
    3608           0 :                         break;
    3609             : 
    3610           0 :                     case CMD_UPDATE:
    3611             :                     case CMD_INSERT:
    3612             :                     case CMD_DELETE:
    3613           0 :                         lev = LOGSTMT_MOD;
    3614           0 :                         break;
    3615             : 
    3616           0 :                     case CMD_UTILITY:
    3617           0 :                         lev = GetCommandLogLevel(stmt->utilityStmt);
    3618           0 :                         break;
    3619             : 
    3620           0 :                     default:
    3621           0 :                         elog(WARNING, "unrecognized commandType: %d",
    3622             :                              (int) stmt->commandType);
    3623           0 :                         lev = LOGSTMT_ALL;
    3624           0 :                         break;
    3625             :                 }
    3626             : 
    3627             :             }
    3628           0 :             break;
    3629             : 
    3630           0 :         default:
    3631           0 :             elog(WARNING, "unrecognized node type: %d",
    3632             :                  (int) nodeTag(parsetree));
    3633           0 :             lev = LOGSTMT_ALL;
    3634           0 :             break;
    3635             :     }
    3636             : 
    3637           0 :     return lev;
    3638             : }

Generated by: LCOV version 1.13