LCOV - code coverage report
Current view: top level - src/backend/tcop - utility.c (source / functions) Coverage Total Hit
Test: Code coverage Lines: 75.4 % 1631 1229
Test Date: 2026-01-26 10:56:24 Functions: 94.1 % 17 16
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
Branches: 64.1 % 857 549

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

Generated by: LCOV version 2.3.2-1