diff options
| author | Alvaro Herrera | 2020-03-02 21:19:51 +0000 |
|---|---|---|
| committer | Alvaro Herrera | 2020-03-02 21:19:51 +0000 |
| commit | 2f9661311b83dc481fc19f6e3bda015392010a40 (patch) | |
| tree | 9a1aabe1d15ac894f7badbc886ae33f16bbfc3b6 /src/backend/tcop | |
| parent | 7b425a5283cb2c8a452c2e79d6218e41373fd641 (diff) | |
Represent command completion tags as structs
The backend was using strings to represent command tags and doing string
comparisons in multiple places, but that's slow and unhelpful. Create a
new command list with a supporting structure to use instead; this is
stored in a tag-list-file that can be tailored to specific purposes with
a caller-definable C macro, similar to what we do for WAL resource
managers. The first first such uses are a new CommandTag enum and a
CommandTagBehavior struct.
Replace numerous occurrences of char *completionTag with a
QueryCompletion struct so that the code no longer stores information
about completed queries in a cstring. Only at the last moment, in
EndCommand(), does this get converted to a string.
EventTriggerCacheItem no longer holds an array of palloc’d tag strings
in sorted order, but rather just a Bitmapset over the CommandTags.
Author: Mark Dilger, with unsolicited help from Álvaro Herrera
Reviewed-by: John Naylor, Tom Lane
Discussion: https://postgr.es/m/981A9DB4-3F0C-4DA5-88AD-CB9CFF4D6CAD@enterprisedb.com
Diffstat (limited to 'src/backend/tcop')
| -rw-r--r-- | src/backend/tcop/Makefile | 1 | ||||
| -rw-r--r-- | src/backend/tcop/cmdtag.c | 98 | ||||
| -rw-r--r-- | src/backend/tcop/dest.c | 32 | ||||
| -rw-r--r-- | src/backend/tcop/postgres.c | 33 | ||||
| -rw-r--r-- | src/backend/tcop/pquery.c | 112 | ||||
| -rw-r--r-- | src/backend/tcop/utility.c | 561 |
6 files changed, 457 insertions, 380 deletions
diff --git a/src/backend/tcop/Makefile b/src/backend/tcop/Makefile index c78f1e0a05e..f662a7dd1cf 100644 --- a/src/backend/tcop/Makefile +++ b/src/backend/tcop/Makefile @@ -13,6 +13,7 @@ top_builddir = ../../.. include $(top_builddir)/src/Makefile.global OBJS = \ + cmdtag.o \ dest.o \ fastpath.o \ postgres.o \ diff --git a/src/backend/tcop/cmdtag.c b/src/backend/tcop/cmdtag.c new file mode 100644 index 00000000000..b9fbff612f2 --- /dev/null +++ b/src/backend/tcop/cmdtag.c @@ -0,0 +1,98 @@ +/*------------------------------------------------------------------------- + * + * cmdtag.c + * Data and routines for commandtag names and enumeration. + * + * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * IDENTIFICATION + * src/backend/tcop/cmdtag.c + * + *------------------------------------------------------------------------- + */ +#include "postgres.h" + +#include "miscadmin.h" +#include "tcop/cmdtag.h" + + +typedef struct CommandTagBehavior +{ + const char *name; + const bool event_trigger_ok; + const bool table_rewrite_ok; + const bool display_rowcount; +} CommandTagBehavior; + +#define PG_CMDTAG(tag, name, evtrgok, rwrok, rowcnt) \ + { name, evtrgok, rwrok, rowcnt }, + +const CommandTagBehavior tag_behavior[COMMAND_TAG_NEXTTAG] = { +#include "tcop/cmdtaglist.h" +}; + +#undef PG_CMDTAG + +void +InitializeQueryCompletion(QueryCompletion *qc) +{ + qc->commandTag = CMDTAG_UNKNOWN; + qc->nprocessed = 0; +} + +const char * +GetCommandTagName(CommandTag commandTag) +{ + return tag_behavior[commandTag].name; +} + +bool +command_tag_display_rowcount(CommandTag commandTag) +{ + return tag_behavior[commandTag].display_rowcount; +} + +bool +command_tag_event_trigger_ok(CommandTag commandTag) +{ + return tag_behavior[commandTag].event_trigger_ok; +} + +bool +command_tag_table_rewrite_ok(CommandTag commandTag) +{ + return tag_behavior[commandTag].table_rewrite_ok; +} + +/* + * Search CommandTag by name + * + * Returns CommandTag, or CMDTAG_UNKNOWN if not recognized + */ +CommandTag +GetCommandTagEnum(const char *commandname) +{ + const CommandTagBehavior *base, + *last, + *position; + int result; + + if (commandname == NULL || *commandname == '\0') + return CMDTAG_UNKNOWN; + + base = tag_behavior; + last = tag_behavior + lengthof(tag_behavior) - 1; + while (last >= base) + { + position = base + ((last - base) >> 1); + result = pg_strcasecmp(commandname, position->name); + if (result == 0) + return (CommandTag) (position - tag_behavior); + else if (result < 0) + last = position - 1; + else + base = position + 1; + } + return CMDTAG_UNKNOWN; +} diff --git a/src/backend/tcop/dest.c b/src/backend/tcop/dest.c index 09c1dcbb537..7208751ec78 100644 --- a/src/backend/tcop/dest.c +++ b/src/backend/tcop/dest.c @@ -100,7 +100,7 @@ DestReceiver *None_Receiver = (DestReceiver *) &donothingDR; * ---------------- */ void -BeginCommand(const char *commandTag, CommandDest dest) +BeginCommand(CommandTag commandTag, CommandDest dest) { /* Nothing to do at present */ } @@ -163,8 +163,12 @@ CreateDestReceiver(CommandDest dest) * ---------------- */ void -EndCommand(const char *commandTag, CommandDest dest) +EndCommand(const QueryCompletion *qc, CommandDest dest, bool force_undecorated_output) { + char completionTag[COMPLETION_TAG_BUFSIZE]; + CommandTag tag; + const char *tagname; + switch (dest) { case DestRemote: @@ -172,11 +176,27 @@ EndCommand(const char *commandTag, CommandDest dest) case DestRemoteSimple: /* - * We assume the commandTag is plain ASCII and therefore requires - * no encoding conversion. + * We assume the tagname is plain ASCII and therefore requires no + * encoding conversion. + * + * We no longer display LastOid, but to preserve the wire + * protocol, we write InvalidOid where the LastOid used to be + * written. + * + * All cases where LastOid was written also write nprocessed + * count, so just Assert that rather than having an extra test. */ - pq_putmessage('C', commandTag, strlen(commandTag) + 1); - break; + tag = qc->commandTag; + tagname = GetCommandTagName(tag); + + if (command_tag_display_rowcount(tag) && !force_undecorated_output) + snprintf(completionTag, COMPLETION_TAG_BUFSIZE, + tag == CMDTAG_INSERT ? + "%s 0 " UINT64_FORMAT : "%s " UINT64_FORMAT, + tagname, qc->nprocessed); + else + snprintf(completionTag, COMPLETION_TAG_BUFSIZE, "%s", tagname); + pq_putmessage('C', completionTag, strlen(completionTag) + 1); case DestNone: case DestDebug: diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c index 23661ae15f5..9dba3b0566a 100644 --- a/src/backend/tcop/postgres.c +++ b/src/backend/tcop/postgres.c @@ -1064,8 +1064,8 @@ exec_simple_query(const char *query_string) { RawStmt *parsetree = lfirst_node(RawStmt, parsetree_item); bool snapshot_set = false; - const char *commandTag; - char completionTag[COMPLETION_TAG_BUFSIZE]; + CommandTag commandTag; + QueryCompletion qc; MemoryContext per_parsetree_context = NULL; List *querytree_list, *plantree_list; @@ -1081,7 +1081,7 @@ exec_simple_query(const char *query_string) */ commandTag = CreateCommandTag(parsetree->stmt); - set_ps_display(commandTag, false); + set_ps_display(GetCommandTagName(commandTag), false); BeginCommand(commandTag, dest); @@ -1239,7 +1239,7 @@ exec_simple_query(const char *query_string) true, receiver, receiver, - completionTag); + &qc); receiver->rDestroy(receiver); @@ -1290,7 +1290,7 @@ exec_simple_query(const char *query_string) * command the client sent, regardless of rewriting. (But a command * aborted by error will not send an EndCommand report at all.) */ - EndCommand(completionTag, dest); + EndCommand(&qc, dest, false); /* Now we may drop the per-parsetree context, if one was created. */ if (per_parsetree_context) @@ -1352,7 +1352,6 @@ exec_parse_message(const char *query_string, /* string to execute */ MemoryContext oldcontext; List *parsetree_list; RawStmt *raw_parse_tree; - const char *commandTag; List *querytree_list; CachedPlanSource *psrc; bool is_named; @@ -1439,11 +1438,6 @@ exec_parse_message(const char *query_string, /* string to execute */ raw_parse_tree = linitial_node(RawStmt, parsetree_list); /* - * Get the command name for possible use in status display. - */ - commandTag = CreateCommandTag(raw_parse_tree->stmt); - - /* * If we are in an aborted transaction, reject all commands except * COMMIT/ROLLBACK. It is important that this test occur before we * try to do parse analysis, rewrite, or planning, since all those @@ -1463,7 +1457,8 @@ exec_parse_message(const char *query_string, /* string to execute */ * Create the CachedPlanSource before we do parse analysis, since it * needs to see the unmodified raw parse tree. */ - psrc = CreateCachedPlan(raw_parse_tree, query_string, commandTag); + psrc = CreateCachedPlan(raw_parse_tree, query_string, + CreateCommandTag(raw_parse_tree->stmt)); /* * Set up a snapshot if parse analysis will need one. @@ -1514,8 +1509,8 @@ exec_parse_message(const char *query_string, /* string to execute */ { /* Empty input string. This is legal. */ raw_parse_tree = NULL; - commandTag = NULL; - psrc = CreateCachedPlan(raw_parse_tree, query_string, commandTag); + psrc = CreateCachedPlan(raw_parse_tree, query_string, + CMDTAG_UNKNOWN); querytree_list = NIL; } @@ -2031,7 +2026,7 @@ exec_execute_message(const char *portal_name, long max_rows) DestReceiver *receiver; Portal portal; bool completed; - char completionTag[COMPLETION_TAG_BUFSIZE]; + QueryCompletion qc; const char *sourceText; const char *prepStmtName; ParamListInfo portalParams; @@ -2058,7 +2053,7 @@ exec_execute_message(const char *portal_name, long max_rows) * If the original query was a null string, just return * EmptyQueryResponse. */ - if (portal->commandTag == NULL) + if (portal->commandTag == CMDTAG_UNKNOWN) { Assert(portal->stmts == NIL); NullCommand(dest); @@ -2104,7 +2099,7 @@ exec_execute_message(const char *portal_name, long max_rows) pgstat_report_activity(STATE_RUNNING, sourceText); - set_ps_display(portal->commandTag, false); + set_ps_display(GetCommandTagName(portal->commandTag), false); if (save_log_statement_stats) ResetUsage(); @@ -2185,7 +2180,7 @@ exec_execute_message(const char *portal_name, long max_rows) !execute_is_fetch && max_rows == FETCH_ALL, receiver, receiver, - completionTag); + &qc); receiver->rDestroy(receiver); @@ -2218,7 +2213,7 @@ exec_execute_message(const char *portal_name, long max_rows) } /* Send appropriate CommandComplete to client */ - EndCommand(completionTag, dest); + EndCommand(&qc, dest, false); } else { diff --git a/src/backend/tcop/pquery.c b/src/backend/tcop/pquery.c index 0f5801e0460..5781fb2e55c 100644 --- a/src/backend/tcop/pquery.c +++ b/src/backend/tcop/pquery.c @@ -40,7 +40,7 @@ static void ProcessQuery(PlannedStmt *plan, ParamListInfo params, QueryEnvironment *queryEnv, DestReceiver *dest, - char *completionTag); + QueryCompletion *qc); static void FillPortalStore(Portal portal, bool isTopLevel); static uint64 RunFromStore(Portal portal, ScanDirection direction, uint64 count, DestReceiver *dest); @@ -48,11 +48,11 @@ static uint64 PortalRunSelect(Portal portal, bool forward, long count, DestReceiver *dest); static void PortalRunUtility(Portal portal, PlannedStmt *pstmt, bool isTopLevel, bool setHoldSnapshot, - DestReceiver *dest, char *completionTag); + DestReceiver *dest, QueryCompletion *qc); static void PortalRunMulti(Portal portal, bool isTopLevel, bool setHoldSnapshot, DestReceiver *dest, DestReceiver *altdest, - char *completionTag); + QueryCompletion *qc); static uint64 DoPortalRunFetch(Portal portal, FetchDirection fdirection, long count, @@ -125,10 +125,9 @@ FreeQueryDesc(QueryDesc *qdesc) * sourceText: the source text of the query * params: any parameters needed * dest: where to send results - * completionTag: points to a buffer of size COMPLETION_TAG_BUFSIZE - * in which to store a command completion status string. + * qc: where to store the command completion status data. * - * completionTag may be NULL if caller doesn't want a status string. + * qc may be NULL if caller doesn't want a status string. * * Must be called in a memory context that will be reset or deleted on * error; otherwise the executor's memory usage will be leaked. @@ -139,7 +138,7 @@ ProcessQuery(PlannedStmt *plan, ParamListInfo params, QueryEnvironment *queryEnv, DestReceiver *dest, - char *completionTag) + QueryCompletion *qc) { QueryDesc *queryDesc; @@ -161,38 +160,26 @@ ProcessQuery(PlannedStmt *plan, ExecutorRun(queryDesc, ForwardScanDirection, 0L, true); /* - * Build command completion status string, if caller wants one. + * Build command completion status data, if caller wants one. */ - if (completionTag) + if (qc) { - Oid lastOid; - switch (queryDesc->operation) { case CMD_SELECT: - snprintf(completionTag, COMPLETION_TAG_BUFSIZE, - "SELECT " UINT64_FORMAT, - queryDesc->estate->es_processed); + SetQueryCompletion(qc, CMDTAG_SELECT, queryDesc->estate->es_processed); break; case CMD_INSERT: - /* lastoid doesn't exist anymore */ - lastOid = InvalidOid; - snprintf(completionTag, COMPLETION_TAG_BUFSIZE, - "INSERT %u " UINT64_FORMAT, - lastOid, queryDesc->estate->es_processed); + SetQueryCompletion(qc, CMDTAG_INSERT, queryDesc->estate->es_processed); break; case CMD_UPDATE: - snprintf(completionTag, COMPLETION_TAG_BUFSIZE, - "UPDATE " UINT64_FORMAT, - queryDesc->estate->es_processed); + SetQueryCompletion(qc, CMDTAG_UPDATE, queryDesc->estate->es_processed); break; case CMD_DELETE: - snprintf(completionTag, COMPLETION_TAG_BUFSIZE, - "DELETE " UINT64_FORMAT, - queryDesc->estate->es_processed); + SetQueryCompletion(qc, CMDTAG_DELETE, queryDesc->estate->es_processed); break; default: - strcpy(completionTag, "???"); + SetQueryCompletion(qc, CMDTAG_UNKNOWN, queryDesc->estate->es_processed); break; } } @@ -675,9 +662,8 @@ PortalSetResultFormat(Portal portal, int nFormats, int16 *formats) * * altdest: where to send output of non-primary queries * - * completionTag: points to a buffer of size COMPLETION_TAG_BUFSIZE - * in which to store a command completion status string. - * May be NULL if caller doesn't want a status string. + * qc: where to store command completion status data. + * May be NULL if caller doesn't want status data. * * Returns true if the portal's execution is complete, false if it was * suspended due to exhaustion of the count parameter. @@ -685,7 +671,7 @@ PortalSetResultFormat(Portal portal, int nFormats, int16 *formats) bool PortalRun(Portal portal, long count, bool isTopLevel, bool run_once, DestReceiver *dest, DestReceiver *altdest, - char *completionTag) + QueryCompletion *qc) { bool result; uint64 nprocessed; @@ -700,9 +686,9 @@ PortalRun(Portal portal, long count, bool isTopLevel, bool run_once, TRACE_POSTGRESQL_QUERY_EXECUTE_START(); - /* Initialize completion tag to empty string */ - if (completionTag) - completionTag[0] = '\0'; + /* Initialize empty completion data */ + if (qc) + InitializeQueryCompletion(qc); if (log_executor_stats && portal->strategy != PORTAL_MULTI_QUERY) { @@ -771,16 +757,13 @@ PortalRun(Portal portal, long count, bool isTopLevel, bool run_once, /* * If the portal result contains a command tag and the caller - * gave us a pointer to store it, copy it. Patch the "SELECT" - * tag to also provide the rowcount. + * gave us a pointer to store it, copy it and update the + * rowcount. */ - if (completionTag && portal->commandTag) + if (qc && portal->qc.commandTag != CMDTAG_UNKNOWN) { - if (strcmp(portal->commandTag, "SELECT") == 0) - snprintf(completionTag, COMPLETION_TAG_BUFSIZE, - "SELECT " UINT64_FORMAT, nprocessed); - else - strcpy(completionTag, portal->commandTag); + CopyQueryCompletion(qc, &portal->qc); + qc->nprocessed = nprocessed; } /* Mark portal not active */ @@ -794,7 +777,7 @@ PortalRun(Portal portal, long count, bool isTopLevel, bool run_once, case PORTAL_MULTI_QUERY: PortalRunMulti(portal, isTopLevel, false, - dest, altdest, completionTag); + dest, altdest, qc); /* Prevent portal's commands from being re-executed */ MarkPortalDone(portal); @@ -1005,8 +988,9 @@ static void FillPortalStore(Portal portal, bool isTopLevel) { DestReceiver *treceiver; - char completionTag[COMPLETION_TAG_BUFSIZE]; + QueryCompletion qc; + InitializeQueryCompletion(&qc); PortalCreateHoldStore(portal); treceiver = CreateDestReceiver(DestTuplestore); SetTuplestoreDestReceiverParams(treceiver, @@ -1014,8 +998,6 @@ FillPortalStore(Portal portal, bool isTopLevel) portal->holdContext, false); - completionTag[0] = '\0'; - switch (portal->strategy) { case PORTAL_ONE_RETURNING: @@ -1028,12 +1010,12 @@ FillPortalStore(Portal portal, bool isTopLevel) * portal's holdSnapshot to the snapshot used (or a copy of it). */ PortalRunMulti(portal, isTopLevel, true, - treceiver, None_Receiver, completionTag); + treceiver, None_Receiver, &qc); break; case PORTAL_UTIL_SELECT: PortalRunUtility(portal, linitial_node(PlannedStmt, portal->stmts), - isTopLevel, true, treceiver, completionTag); + isTopLevel, true, treceiver, &qc); break; default: @@ -1042,9 +1024,9 @@ FillPortalStore(Portal portal, bool isTopLevel) break; } - /* Override default completion tag with actual command result */ - if (completionTag[0] != '\0') - portal->commandTag = pstrdup(completionTag); + /* Override portal completion data with actual command results */ + if (qc.commandTag != CMDTAG_UNKNOWN) + CopyQueryCompletion(&portal->qc, &qc); treceiver->rDestroy(treceiver); } @@ -1130,7 +1112,7 @@ RunFromStore(Portal portal, ScanDirection direction, uint64 count, static void PortalRunUtility(Portal portal, PlannedStmt *pstmt, bool isTopLevel, bool setHoldSnapshot, - DestReceiver *dest, char *completionTag) + DestReceiver *dest, QueryCompletion *qc) { Node *utilityStmt = pstmt->utilityStmt; Snapshot snapshot; @@ -1178,7 +1160,7 @@ PortalRunUtility(Portal portal, PlannedStmt *pstmt, portal->portalParams, portal->queryEnv, dest, - completionTag); + qc); /* Some utility statements may change context on us */ MemoryContextSwitchTo(portal->portalContext); @@ -1202,7 +1184,7 @@ static void PortalRunMulti(Portal portal, bool isTopLevel, bool setHoldSnapshot, DestReceiver *dest, DestReceiver *altdest, - char *completionTag) + QueryCompletion *qc) { bool active_snapshot_set = false; ListCell *stmtlist_item; @@ -1284,7 +1266,7 @@ PortalRunMulti(Portal portal, portal->sourceText, portal->portalParams, portal->queryEnv, - dest, completionTag); + dest, qc); } else { @@ -1319,7 +1301,7 @@ PortalRunMulti(Portal portal, Assert(!active_snapshot_set); /* statement can set tag string */ PortalRunUtility(portal, pstmt, isTopLevel, false, - dest, completionTag); + dest, qc); } else { @@ -1350,8 +1332,8 @@ PortalRunMulti(Portal portal, PopActiveSnapshot(); /* - * If a command completion tag was supplied, use it. Otherwise use the - * portal's commandTag as the default completion tag. + * If a query completion data was supplied, use it. Otherwise use the + * portal's query completion data. * * Exception: Clients expect INSERT/UPDATE/DELETE tags to have counts, so * fake them with zeros. This can happen with DO INSTEAD rules if there @@ -1361,18 +1343,12 @@ PortalRunMulti(Portal portal, * e.g. an INSERT that does an UPDATE instead should not print "0 1" if * one row was updated. See QueryRewrite(), step 3, for details. */ - if (completionTag && completionTag[0] == '\0') + if (qc && qc->commandTag == CMDTAG_UNKNOWN) { - if (portal->commandTag) - strcpy(completionTag, portal->commandTag); - if (strcmp(completionTag, "SELECT") == 0) - sprintf(completionTag, "SELECT 0 0"); - else if (strcmp(completionTag, "INSERT") == 0) - strcpy(completionTag, "INSERT 0 0"); - else if (strcmp(completionTag, "UPDATE") == 0) - strcpy(completionTag, "UPDATE 0"); - else if (strcmp(completionTag, "DELETE") == 0) - strcpy(completionTag, "DELETE 0"); + if (portal->qc.commandTag != CMDTAG_UNKNOWN) + CopyQueryCompletion(qc, &portal->qc); + /* If the caller supplied a qc, we should have set it by now. */ + Assert(qc->commandTag != CMDTAG_UNKNOWN); } } diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index bb85b5e52aa..1b460a26126 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -75,7 +75,7 @@ ProcessUtility_hook_type ProcessUtility_hook = NULL; /* local function declarations */ -static int ClassifyUtilityCommandAsReadOnly(Node *parsetree); +static int ClassifyUtilityCommandAsReadOnly(Node *parsetree); static void ProcessUtilitySlow(ParseState *pstate, PlannedStmt *pstmt, const char *queryString, @@ -83,10 +83,9 @@ static void ProcessUtilitySlow(ParseState *pstate, ParamListInfo params, QueryEnvironment *queryEnv, DestReceiver *dest, - char *completionTag); + QueryCompletion *qc); static void ExecDropStmt(DropStmt *stmt, bool isTopLevel); - /* * CommandIsReadOnly: is an executable query read-only? * @@ -467,7 +466,6 @@ CheckRestrictedOperation(const char *cmdname) cmdname))); } - /* * ProcessUtility * general utility function invoker @@ -480,17 +478,13 @@ CheckRestrictedOperation(const char *cmdname) * queryEnv: environment for parse through execution (e.g., ephemeral named * tables like trigger transition tables). May be NULL. * dest: where to send results - * completionTag: points to a buffer of size COMPLETION_TAG_BUFSIZE - * in which to store a command completion status string. + * qc: where to store command completion status data. May be NULL, + * but if not, then caller must have initialized it. * * Caller MUST supply a queryString; it is not allowed (anymore) to pass NULL. * If you really don't have source text, you can pass a constant string, * perhaps "(query not available)". * - * completionTag is only set nonempty if we want to return a nondefault status. - * - * completionTag may be NULL if caller doesn't want a status string. - * * Note for users of ProcessUtility_hook: the same queryString may be passed * to multiple invocations of ProcessUtility when processing a query string * containing multiple semicolon-separated statements. One should use @@ -507,11 +501,12 @@ ProcessUtility(PlannedStmt *pstmt, ParamListInfo params, QueryEnvironment *queryEnv, DestReceiver *dest, - char *completionTag) + QueryCompletion *qc) { Assert(IsA(pstmt, PlannedStmt)); Assert(pstmt->commandType == CMD_UTILITY); Assert(queryString != NULL); /* required as of 8.4 */ + Assert(qc == NULL || qc->commandTag == CMDTAG_UNKNOWN); /* * We provide a function hook variable that lets loadable plugins get @@ -521,11 +516,11 @@ ProcessUtility(PlannedStmt *pstmt, if (ProcessUtility_hook) (*ProcessUtility_hook) (pstmt, queryString, context, params, queryEnv, - dest, completionTag); + dest, qc); else standard_ProcessUtility(pstmt, queryString, context, params, queryEnv, - dest, completionTag); + dest, qc); } /* @@ -546,7 +541,7 @@ standard_ProcessUtility(PlannedStmt *pstmt, ParamListInfo params, QueryEnvironment *queryEnv, DestReceiver *dest, - char *completionTag) + QueryCompletion *qc) { Node *parsetree = pstmt->utilityStmt; bool isTopLevel = (context == PROCESS_UTILITY_TOPLEVEL); @@ -562,19 +557,16 @@ standard_ProcessUtility(PlannedStmt *pstmt, if (readonly_flags != COMMAND_IS_STRICTLY_READ_ONLY && (XactReadOnly || IsInParallelMode())) { - const char *commandtag = CreateCommandTag(parsetree); + CommandTag commandtag = CreateCommandTag(parsetree); if ((readonly_flags & COMMAND_OK_IN_READ_ONLY_TXN) == 0) - PreventCommandIfReadOnly(commandtag); + PreventCommandIfReadOnly(GetCommandTagName(commandtag)); if ((readonly_flags & COMMAND_OK_IN_PARALLEL_MODE) == 0) - PreventCommandIfParallelMode(commandtag); + PreventCommandIfParallelMode(GetCommandTagName(commandtag)); if ((readonly_flags & COMMAND_OK_IN_RECOVERY) == 0) - PreventCommandDuringRecovery(commandtag); + PreventCommandDuringRecovery(GetCommandTagName(commandtag)); } - if (completionTag) - completionTag[0] = '\0'; - pstate = make_parsestate(NULL); pstate->p_sourcetext = queryString; pstate->p_queryEnv = queryEnv; @@ -623,18 +615,18 @@ standard_ProcessUtility(PlannedStmt *pstmt, case TRANS_STMT_COMMIT: if (!EndTransactionBlock(stmt->chain)) { - /* report unsuccessful commit in completionTag */ - if (completionTag) - strcpy(completionTag, "ROLLBACK"); + /* report unsuccessful commit in qc */ + if (qc) + SetQueryCompletion(qc, CMDTAG_ROLLBACK, 0); } break; case TRANS_STMT_PREPARE: if (!PrepareTransactionBlock(stmt->gid)) { - /* report unsuccessful commit in completionTag */ - if (completionTag) - strcpy(completionTag, "ROLLBACK"); + /* report unsuccessful commit in qc */ + if (qc) + SetQueryCompletion(qc, CMDTAG_ROLLBACK, 0); } break; @@ -693,8 +685,7 @@ standard_ProcessUtility(PlannedStmt *pstmt, break; case T_FetchStmt: - PerformPortalFetch((FetchStmt *) parsetree, dest, - completionTag); + PerformPortalFetch((FetchStmt *) parsetree, dest, qc); break; case T_DoStmt: @@ -729,9 +720,8 @@ standard_ProcessUtility(PlannedStmt *pstmt, DoCopy(pstate, (CopyStmt *) parsetree, pstmt->stmt_location, pstmt->stmt_len, &processed); - if (completionTag) - snprintf(completionTag, COMPLETION_TAG_BUFSIZE, - "COPY " UINT64_FORMAT, processed); + if (qc) + SetQueryCompletion(qc, CMDTAG_COPY, processed); } break; @@ -745,7 +735,7 @@ standard_ProcessUtility(PlannedStmt *pstmt, ExecuteQuery(pstate, (ExecuteStmt *) parsetree, NULL, params, - dest, completionTag); + dest, qc); break; case T_DeallocateStmt: @@ -974,7 +964,7 @@ standard_ProcessUtility(PlannedStmt *pstmt, if (EventTriggerSupportsObjectType(stmt->objtype)) ProcessUtilitySlow(pstate, pstmt, queryString, context, params, queryEnv, - dest, completionTag); + dest, qc); else ExecuteGrantStmt(stmt); } @@ -987,7 +977,7 @@ standard_ProcessUtility(PlannedStmt *pstmt, if (EventTriggerSupportsObjectType(stmt->removeType)) ProcessUtilitySlow(pstate, pstmt, queryString, context, params, queryEnv, - dest, completionTag); + dest, qc); else ExecDropStmt(stmt, isTopLevel); } @@ -1000,7 +990,7 @@ standard_ProcessUtility(PlannedStmt *pstmt, if (EventTriggerSupportsObjectType(stmt->renameType)) ProcessUtilitySlow(pstate, pstmt, queryString, context, params, queryEnv, - dest, completionTag); + dest, qc); else ExecRenameStmt(stmt); } @@ -1013,7 +1003,7 @@ standard_ProcessUtility(PlannedStmt *pstmt, if (EventTriggerSupportsObjectType(stmt->objectType)) ProcessUtilitySlow(pstate, pstmt, queryString, context, params, queryEnv, - dest, completionTag); + dest, qc); else ExecAlterObjectDependsStmt(stmt, NULL); } @@ -1026,7 +1016,7 @@ standard_ProcessUtility(PlannedStmt *pstmt, if (EventTriggerSupportsObjectType(stmt->objectType)) ProcessUtilitySlow(pstate, pstmt, queryString, context, params, queryEnv, - dest, completionTag); + dest, qc); else ExecAlterObjectSchemaStmt(stmt, NULL); } @@ -1039,7 +1029,7 @@ standard_ProcessUtility(PlannedStmt *pstmt, if (EventTriggerSupportsObjectType(stmt->objectType)) ProcessUtilitySlow(pstate, pstmt, queryString, context, params, queryEnv, - dest, completionTag); + dest, qc); else ExecAlterOwnerStmt(stmt); } @@ -1052,7 +1042,7 @@ standard_ProcessUtility(PlannedStmt *pstmt, if (EventTriggerSupportsObjectType(stmt->objtype)) ProcessUtilitySlow(pstate, pstmt, queryString, context, params, queryEnv, - dest, completionTag); + dest, qc); else CommentObject(stmt); break; @@ -1065,7 +1055,7 @@ standard_ProcessUtility(PlannedStmt *pstmt, if (EventTriggerSupportsObjectType(stmt->objtype)) ProcessUtilitySlow(pstate, pstmt, queryString, context, params, queryEnv, - dest, completionTag); + dest, qc); else ExecSecLabelStmt(stmt); break; @@ -1075,7 +1065,7 @@ standard_ProcessUtility(PlannedStmt *pstmt, /* All other statement types have event trigger support */ ProcessUtilitySlow(pstate, pstmt, queryString, context, params, queryEnv, - dest, completionTag); + dest, qc); break; } @@ -1102,7 +1092,7 @@ ProcessUtilitySlow(ParseState *pstate, ParamListInfo params, QueryEnvironment *queryEnv, DestReceiver *dest, - char *completionTag) + QueryCompletion *qc) { Node *parsetree = pstmt->utilityStmt; bool isTopLevel = (context == PROCESS_UTILITY_TOPLEVEL); @@ -1605,7 +1595,7 @@ ProcessUtilitySlow(ParseState *pstate, case T_CreateTableAsStmt: address = ExecCreateTableAs(pstate, (CreateTableAsStmt *) parsetree, - params, queryEnv, completionTag); + params, queryEnv, qc); break; case T_RefreshMatViewStmt: @@ -1620,7 +1610,7 @@ ProcessUtilitySlow(ParseState *pstate, PG_TRY(); { address = ExecRefreshMatView((RefreshMatViewStmt *) parsetree, - queryString, params, completionTag); + queryString, params, qc); } PG_FINALLY(); { @@ -2099,137 +2089,137 @@ UtilityContainsQuery(Node *parsetree) * * This covers most cases where ALTER is used with an ObjectType enum. */ -static const char * +static CommandTag AlterObjectTypeCommandTag(ObjectType objtype) { - const char *tag; + CommandTag tag; switch (objtype) { case OBJECT_AGGREGATE: - tag = "ALTER AGGREGATE"; + tag = CMDTAG_ALTER_AGGREGATE; break; case OBJECT_ATTRIBUTE: - tag = "ALTER TYPE"; + tag = CMDTAG_ALTER_TYPE; break; case OBJECT_CAST: - tag = "ALTER CAST"; + tag = CMDTAG_ALTER_CAST; break; case OBJECT_COLLATION: - tag = "ALTER COLLATION"; + tag = CMDTAG_ALTER_COLLATION; break; case OBJECT_COLUMN: - tag = "ALTER TABLE"; + tag = CMDTAG_ALTER_TABLE; break; case OBJECT_CONVERSION: - tag = "ALTER CONVERSION"; + tag = CMDTAG_ALTER_CONVERSION; break; case OBJECT_DATABASE: - tag = "ALTER DATABASE"; + tag = CMDTAG_ALTER_DATABASE; break; case OBJECT_DOMAIN: case OBJECT_DOMCONSTRAINT: - tag = "ALTER DOMAIN"; + tag = CMDTAG_ALTER_DOMAIN; break; case OBJECT_EXTENSION: - tag = "ALTER EXTENSION"; + tag = CMDTAG_ALTER_EXTENSION; break; case OBJECT_FDW: - tag = "ALTER FOREIGN DATA WRAPPER"; + tag = CMDTAG_ALTER_FOREIGN_DATA_WRAPPER; break; case OBJECT_FOREIGN_SERVER: - tag = "ALTER SERVER"; + tag = CMDTAG_ALTER_SERVER; break; case OBJECT_FOREIGN_TABLE: - tag = "ALTER FOREIGN TABLE"; + tag = CMDTAG_ALTER_FOREIGN_TABLE; break; case OBJECT_FUNCTION: - tag = "ALTER FUNCTION"; + tag = CMDTAG_ALTER_FUNCTION; break; case OBJECT_INDEX: - tag = "ALTER INDEX"; + tag = CMDTAG_ALTER_INDEX; break; case OBJECT_LANGUAGE: - tag = "ALTER LANGUAGE"; + tag = CMDTAG_ALTER_LANGUAGE; break; case OBJECT_LARGEOBJECT: - tag = "ALTER LARGE OBJECT"; + tag = CMDTAG_ALTER_LARGE_OBJECT; break; case OBJECT_OPCLASS: - tag = "ALTER OPERATOR CLASS"; + tag = CMDTAG_ALTER_OPERATOR_CLASS; break; case OBJECT_OPERATOR: - tag = "ALTER OPERATOR"; + tag = CMDTAG_ALTER_OPERATOR; break; case OBJECT_OPFAMILY: - tag = "ALTER OPERATOR FAMILY"; + tag = CMDTAG_ALTER_OPERATOR_FAMILY; break; case OBJECT_POLICY: - tag = "ALTER POLICY"; + tag = CMDTAG_ALTER_POLICY; break; case OBJECT_PROCEDURE: - tag = "ALTER PROCEDURE"; + tag = CMDTAG_ALTER_PROCEDURE; break; case OBJECT_ROLE: - tag = "ALTER ROLE"; + tag = CMDTAG_ALTER_ROLE; break; case OBJECT_ROUTINE: - tag = "ALTER ROUTINE"; + tag = CMDTAG_ALTER_ROUTINE; break; case OBJECT_RULE: - tag = "ALTER RULE"; + tag = CMDTAG_ALTER_RULE; break; case OBJECT_SCHEMA: - tag = "ALTER SCHEMA"; + tag = CMDTAG_ALTER_SCHEMA; break; case OBJECT_SEQUENCE: - tag = "ALTER SEQUENCE"; + tag = CMDTAG_ALTER_SEQUENCE; break; case OBJECT_TABLE: case OBJECT_TABCONSTRAINT: - tag = "ALTER TABLE"; + tag = CMDTAG_ALTER_TABLE; break; case OBJECT_TABLESPACE: - tag = "ALTER TABLESPACE"; + tag = CMDTAG_ALTER_TABLESPACE; break; case OBJECT_TRIGGER: - tag = "ALTER TRIGGER"; + tag = CMDTAG_ALTER_TRIGGER; break; case OBJECT_EVENT_TRIGGER: - tag = "ALTER EVENT TRIGGER"; + tag = CMDTAG_ALTER_EVENT_TRIGGER; break; case OBJECT_TSCONFIGURATION: - tag = "ALTER TEXT SEARCH CONFIGURATION"; + tag = CMDTAG_ALTER_TEXT_SEARCH_CONFIGURATION; break; case OBJECT_TSDICTIONARY: - tag = "ALTER TEXT SEARCH DICTIONARY"; + tag = CMDTAG_ALTER_TEXT_SEARCH_DICTIONARY; break; case OBJECT_TSPARSER: - tag = "ALTER TEXT SEARCH PARSER"; + tag = CMDTAG_ALTER_TEXT_SEARCH_PARSER; break; case OBJECT_TSTEMPLATE: - tag = "ALTER TEXT SEARCH TEMPLATE"; + tag = CMDTAG_ALTER_TEXT_SEARCH_TEMPLATE; break; case OBJECT_TYPE: - tag = "ALTER TYPE"; + tag = CMDTAG_ALTER_TYPE; break; case OBJECT_VIEW: - tag = "ALTER VIEW"; + tag = CMDTAG_ALTER_VIEW; break; case OBJECT_MATVIEW: - tag = "ALTER MATERIALIZED VIEW"; + tag = CMDTAG_ALTER_MATERIALIZED_VIEW; break; case OBJECT_PUBLICATION: - tag = "ALTER PUBLICATION"; + tag = CMDTAG_ALTER_PUBLICATION; break; case OBJECT_SUBSCRIPTION: - tag = "ALTER SUBSCRIPTION"; + tag = CMDTAG_ALTER_SUBSCRIPTION; break; case OBJECT_STATISTIC_EXT: - tag = "ALTER STATISTICS"; + tag = CMDTAG_ALTER_STATISTICS; break; default: - tag = "???"; + tag = CMDTAG_UNKNOWN; break; } @@ -2238,20 +2228,17 @@ AlterObjectTypeCommandTag(ObjectType objtype) /* * CreateCommandTag - * utility to get a string representation of the command operation, + * utility to get a CommandTag for the command operation, * given either a raw (un-analyzed) parsetree, an analyzed Query, * or a PlannedStmt. * * This must handle all command types, but since the vast majority * of 'em are utility commands, it seems sensible to keep it here. - * - * NB: all result strings must be shorter than COMPLETION_TAG_BUFSIZE. - * Also, the result must point at a true constant (permanent storage). */ -const char * +CommandTag CreateCommandTag(Node *parsetree) { - const char *tag; + CommandTag tag; switch (nodeTag(parsetree)) { @@ -2262,19 +2249,19 @@ CreateCommandTag(Node *parsetree) /* raw plannable queries */ case T_InsertStmt: - tag = "INSERT"; + tag = CMDTAG_INSERT; break; case T_DeleteStmt: - tag = "DELETE"; + tag = CMDTAG_DELETE; break; case T_UpdateStmt: - tag = "UPDATE"; + tag = CMDTAG_UPDATE; break; case T_SelectStmt: - tag = "SELECT"; + tag = CMDTAG_SELECT; break; /* utility statements --- same whether raw or cooked */ @@ -2285,51 +2272,51 @@ CreateCommandTag(Node *parsetree) switch (stmt->kind) { case TRANS_STMT_BEGIN: - tag = "BEGIN"; + tag = CMDTAG_BEGIN; break; case TRANS_STMT_START: - tag = "START TRANSACTION"; + tag = CMDTAG_START_TRANSACTION; break; case TRANS_STMT_COMMIT: - tag = "COMMIT"; + tag = CMDTAG_COMMIT; break; case TRANS_STMT_ROLLBACK: case TRANS_STMT_ROLLBACK_TO: - tag = "ROLLBACK"; + tag = CMDTAG_ROLLBACK; break; case TRANS_STMT_SAVEPOINT: - tag = "SAVEPOINT"; + tag = CMDTAG_SAVEPOINT; break; case TRANS_STMT_RELEASE: - tag = "RELEASE"; + tag = CMDTAG_RELEASE; break; case TRANS_STMT_PREPARE: - tag = "PREPARE TRANSACTION"; + tag = CMDTAG_PREPARE_TRANSACTION; break; case TRANS_STMT_COMMIT_PREPARED: - tag = "COMMIT PREPARED"; + tag = CMDTAG_COMMIT_PREPARED; break; case TRANS_STMT_ROLLBACK_PREPARED: - tag = "ROLLBACK PREPARED"; + tag = CMDTAG_ROLLBACK_PREPARED; break; default: - tag = "???"; + tag = CMDTAG_UNKNOWN; break; } } break; case T_DeclareCursorStmt: - tag = "DECLARE CURSOR"; + tag = CMDTAG_DECLARE_CURSOR; break; case T_ClosePortalStmt: @@ -2337,9 +2324,9 @@ CreateCommandTag(Node *parsetree) ClosePortalStmt *stmt = (ClosePortalStmt *) parsetree; if (stmt->portalname == NULL) - tag = "CLOSE CURSOR ALL"; + tag = CMDTAG_CLOSE_CURSOR_ALL; else - tag = "CLOSE CURSOR"; + tag = CMDTAG_CLOSE_CURSOR; } break; @@ -2347,209 +2334,209 @@ CreateCommandTag(Node *parsetree) { FetchStmt *stmt = (FetchStmt *) parsetree; - tag = (stmt->ismove) ? "MOVE" : "FETCH"; + tag = (stmt->ismove) ? CMDTAG_MOVE : CMDTAG_FETCH; } break; case T_CreateDomainStmt: - tag = "CREATE DOMAIN"; + tag = CMDTAG_CREATE_DOMAIN; break; case T_CreateSchemaStmt: - tag = "CREATE SCHEMA"; + tag = CMDTAG_CREATE_SCHEMA; break; case T_CreateStmt: - tag = "CREATE TABLE"; + tag = CMDTAG_CREATE_TABLE; break; case T_CreateTableSpaceStmt: - tag = "CREATE TABLESPACE"; + tag = CMDTAG_CREATE_TABLESPACE; break; case T_DropTableSpaceStmt: - tag = "DROP TABLESPACE"; + tag = CMDTAG_DROP_TABLESPACE; break; case T_AlterTableSpaceOptionsStmt: - tag = "ALTER TABLESPACE"; + tag = CMDTAG_ALTER_TABLESPACE; break; case T_CreateExtensionStmt: - tag = "CREATE EXTENSION"; + tag = CMDTAG_CREATE_EXTENSION; break; case T_AlterExtensionStmt: - tag = "ALTER EXTENSION"; + tag = CMDTAG_ALTER_EXTENSION; break; case T_AlterExtensionContentsStmt: - tag = "ALTER EXTENSION"; + tag = CMDTAG_ALTER_EXTENSION; break; case T_CreateFdwStmt: - tag = "CREATE FOREIGN DATA WRAPPER"; + tag = CMDTAG_CREATE_FOREIGN_DATA_WRAPPER; break; case T_AlterFdwStmt: - tag = "ALTER FOREIGN DATA WRAPPER"; + tag = CMDTAG_ALTER_FOREIGN_DATA_WRAPPER; break; case T_CreateForeignServerStmt: - tag = "CREATE SERVER"; + tag = CMDTAG_CREATE_SERVER; break; case T_AlterForeignServerStmt: - tag = "ALTER SERVER"; + tag = CMDTAG_ALTER_SERVER; break; case T_CreateUserMappingStmt: - tag = "CREATE USER MAPPING"; + tag = CMDTAG_CREATE_USER_MAPPING; break; case T_AlterUserMappingStmt: - tag = "ALTER USER MAPPING"; + tag = CMDTAG_ALTER_USER_MAPPING; break; case T_DropUserMappingStmt: - tag = "DROP USER MAPPING"; + tag = CMDTAG_DROP_USER_MAPPING; break; case T_CreateForeignTableStmt: - tag = "CREATE FOREIGN TABLE"; + tag = CMDTAG_CREATE_FOREIGN_TABLE; break; case T_ImportForeignSchemaStmt: - tag = "IMPORT FOREIGN SCHEMA"; + tag = CMDTAG_IMPORT_FOREIGN_SCHEMA; break; case T_DropStmt: switch (((DropStmt *) parsetree)->removeType) { case OBJECT_TABLE: - tag = "DROP TABLE"; + tag = CMDTAG_DROP_TABLE; break; case OBJECT_SEQUENCE: - tag = "DROP SEQUENCE"; + tag = CMDTAG_DROP_SEQUENCE; break; case OBJECT_VIEW: - tag = "DROP VIEW"; + tag = CMDTAG_DROP_VIEW; break; case OBJECT_MATVIEW: - tag = "DROP MATERIALIZED VIEW"; + tag = CMDTAG_DROP_MATERIALIZED_VIEW; break; case OBJECT_INDEX: - tag = "DROP INDEX"; + tag = CMDTAG_DROP_INDEX; break; case OBJECT_TYPE: - tag = "DROP TYPE"; + tag = CMDTAG_DROP_TYPE; break; case OBJECT_DOMAIN: - tag = "DROP DOMAIN"; + tag = CMDTAG_DROP_DOMAIN; break; case OBJECT_COLLATION: - tag = "DROP COLLATION"; + tag = CMDTAG_DROP_COLLATION; break; case OBJECT_CONVERSION: - tag = "DROP CONVERSION"; + tag = CMDTAG_DROP_CONVERSION; break; case OBJECT_SCHEMA: - tag = "DROP SCHEMA"; + tag = CMDTAG_DROP_SCHEMA; break; case OBJECT_TSPARSER: - tag = "DROP TEXT SEARCH PARSER"; + tag = CMDTAG_DROP_TEXT_SEARCH_PARSER; break; case OBJECT_TSDICTIONARY: - tag = "DROP TEXT SEARCH DICTIONARY"; + tag = CMDTAG_DROP_TEXT_SEARCH_DICTIONARY; break; case OBJECT_TSTEMPLATE: - tag = "DROP TEXT SEARCH TEMPLATE"; + tag = CMDTAG_DROP_TEXT_SEARCH_TEMPLATE; break; case OBJECT_TSCONFIGURATION: - tag = "DROP TEXT SEARCH CONFIGURATION"; + tag = CMDTAG_DROP_TEXT_SEARCH_CONFIGURATION; break; case OBJECT_FOREIGN_TABLE: - tag = "DROP FOREIGN TABLE"; + tag = CMDTAG_DROP_FOREIGN_TABLE; break; case OBJECT_EXTENSION: - tag = "DROP EXTENSION"; + tag = CMDTAG_DROP_EXTENSION; break; case OBJECT_FUNCTION: - tag = "DROP FUNCTION"; + tag = CMDTAG_DROP_FUNCTION; break; case OBJECT_PROCEDURE: - tag = "DROP PROCEDURE"; + tag = CMDTAG_DROP_PROCEDURE; break; case OBJECT_ROUTINE: - tag = "DROP ROUTINE"; + tag = CMDTAG_DROP_ROUTINE; break; case OBJECT_AGGREGATE: - tag = "DROP AGGREGATE"; + tag = CMDTAG_DROP_AGGREGATE; break; case OBJECT_OPERATOR: - tag = "DROP OPERATOR"; + tag = CMDTAG_DROP_OPERATOR; break; case OBJECT_LANGUAGE: - tag = "DROP LANGUAGE"; + tag = CMDTAG_DROP_LANGUAGE; break; case OBJECT_CAST: - tag = "DROP CAST"; + tag = CMDTAG_DROP_CAST; break; case OBJECT_TRIGGER: - tag = "DROP TRIGGER"; + tag = CMDTAG_DROP_TRIGGER; break; case OBJECT_EVENT_TRIGGER: - tag = "DROP EVENT TRIGGER"; + tag = CMDTAG_DROP_EVENT_TRIGGER; break; case OBJECT_RULE: - tag = "DROP RULE"; + tag = CMDTAG_DROP_RULE; break; case OBJECT_FDW: - tag = "DROP FOREIGN DATA WRAPPER"; + tag = CMDTAG_DROP_FOREIGN_DATA_WRAPPER; break; case OBJECT_FOREIGN_SERVER: - tag = "DROP SERVER"; + tag = CMDTAG_DROP_SERVER; break; case OBJECT_OPCLASS: - tag = "DROP OPERATOR CLASS"; + tag = CMDTAG_DROP_OPERATOR_CLASS; break; case OBJECT_OPFAMILY: - tag = "DROP OPERATOR FAMILY"; + tag = CMDTAG_DROP_OPERATOR_FAMILY; break; case OBJECT_POLICY: - tag = "DROP POLICY"; + tag = CMDTAG_DROP_POLICY; break; case OBJECT_TRANSFORM: - tag = "DROP TRANSFORM"; + tag = CMDTAG_DROP_TRANSFORM; break; case OBJECT_ACCESS_METHOD: - tag = "DROP ACCESS METHOD"; + tag = CMDTAG_DROP_ACCESS_METHOD; break; case OBJECT_PUBLICATION: - tag = "DROP PUBLICATION"; + tag = CMDTAG_DROP_PUBLICATION; break; case OBJECT_STATISTIC_EXT: - tag = "DROP STATISTICS"; + tag = CMDTAG_DROP_STATISTICS; break; default: - tag = "???"; + tag = CMDTAG_UNKNOWN; } break; case T_TruncateStmt: - tag = "TRUNCATE TABLE"; + tag = CMDTAG_TRUNCATE_TABLE; break; case T_CommentStmt: - tag = "COMMENT"; + tag = CMDTAG_COMMENT; break; case T_SecLabelStmt: - tag = "SECURITY LABEL"; + tag = CMDTAG_SECURITY_LABEL; break; case T_CopyStmt: - tag = "COPY"; + tag = CMDTAG_COPY; break; case T_RenameStmt: @@ -2584,23 +2571,23 @@ CreateCommandTag(Node *parsetree) break; case T_AlterDomainStmt: - tag = "ALTER DOMAIN"; + tag = CMDTAG_ALTER_DOMAIN; break; case T_AlterFunctionStmt: switch (((AlterFunctionStmt *) parsetree)->objtype) { case OBJECT_FUNCTION: - tag = "ALTER FUNCTION"; + tag = CMDTAG_ALTER_FUNCTION; break; case OBJECT_PROCEDURE: - tag = "ALTER PROCEDURE"; + tag = CMDTAG_ALTER_PROCEDURE; break; case OBJECT_ROUTINE: - tag = "ALTER ROUTINE"; + tag = CMDTAG_ALTER_ROUTINE; break; default: - tag = "???"; + tag = CMDTAG_UNKNOWN; } break; @@ -2608,7 +2595,7 @@ CreateCommandTag(Node *parsetree) { GrantStmt *stmt = (GrantStmt *) parsetree; - tag = (stmt->is_grant) ? "GRANT" : "REVOKE"; + tag = (stmt->is_grant) ? CMDTAG_GRANT : CMDTAG_REVOKE; } break; @@ -2616,145 +2603,145 @@ CreateCommandTag(Node *parsetree) { GrantRoleStmt *stmt = (GrantRoleStmt *) parsetree; - tag = (stmt->is_grant) ? "GRANT ROLE" : "REVOKE ROLE"; + tag = (stmt->is_grant) ? CMDTAG_GRANT_ROLE : CMDTAG_REVOKE_ROLE; } break; case T_AlterDefaultPrivilegesStmt: - tag = "ALTER DEFAULT PRIVILEGES"; + tag = CMDTAG_ALTER_DEFAULT_PRIVILEGES; break; case T_DefineStmt: switch (((DefineStmt *) parsetree)->kind) { case OBJECT_AGGREGATE: - tag = "CREATE AGGREGATE"; + tag = CMDTAG_CREATE_AGGREGATE; break; case OBJECT_OPERATOR: - tag = "CREATE OPERATOR"; + tag = CMDTAG_CREATE_OPERATOR; break; case OBJECT_TYPE: - tag = "CREATE TYPE"; + tag = CMDTAG_CREATE_TYPE; break; case OBJECT_TSPARSER: - tag = "CREATE TEXT SEARCH PARSER"; + tag = CMDTAG_CREATE_TEXT_SEARCH_PARSER; break; case OBJECT_TSDICTIONARY: - tag = "CREATE TEXT SEARCH DICTIONARY"; + tag = CMDTAG_CREATE_TEXT_SEARCH_DICTIONARY; break; case OBJECT_TSTEMPLATE: - tag = "CREATE TEXT SEARCH TEMPLATE"; + tag = CMDTAG_CREATE_TEXT_SEARCH_TEMPLATE; break; case OBJECT_TSCONFIGURATION: - tag = "CREATE TEXT SEARCH CONFIGURATION"; + tag = CMDTAG_CREATE_TEXT_SEARCH_CONFIGURATION; break; case OBJECT_COLLATION: - tag = "CREATE COLLATION"; + tag = CMDTAG_CREATE_COLLATION; break; case OBJECT_ACCESS_METHOD: - tag = "CREATE ACCESS METHOD"; + tag = CMDTAG_CREATE_ACCESS_METHOD; break; default: - tag = "???"; + tag = CMDTAG_UNKNOWN; } break; case T_CompositeTypeStmt: - tag = "CREATE TYPE"; + tag = CMDTAG_CREATE_TYPE; break; case T_CreateEnumStmt: - tag = "CREATE TYPE"; + tag = CMDTAG_CREATE_TYPE; break; case T_CreateRangeStmt: - tag = "CREATE TYPE"; + tag = CMDTAG_CREATE_TYPE; break; case T_AlterEnumStmt: - tag = "ALTER TYPE"; + tag = CMDTAG_ALTER_TYPE; break; case T_ViewStmt: - tag = "CREATE VIEW"; + tag = CMDTAG_CREATE_VIEW; break; case T_CreateFunctionStmt: if (((CreateFunctionStmt *) parsetree)->is_procedure) - tag = "CREATE PROCEDURE"; + tag = CMDTAG_CREATE_PROCEDURE; else - tag = "CREATE FUNCTION"; + tag = CMDTAG_CREATE_FUNCTION; break; case T_IndexStmt: - tag = "CREATE INDEX"; + tag = CMDTAG_CREATE_INDEX; break; case T_RuleStmt: - tag = "CREATE RULE"; + tag = CMDTAG_CREATE_RULE; break; case T_CreateSeqStmt: - tag = "CREATE SEQUENCE"; + tag = CMDTAG_CREATE_SEQUENCE; break; case T_AlterSeqStmt: - tag = "ALTER SEQUENCE"; + tag = CMDTAG_ALTER_SEQUENCE; break; case T_DoStmt: - tag = "DO"; + tag = CMDTAG_DO; break; case T_CreatedbStmt: - tag = "CREATE DATABASE"; + tag = CMDTAG_CREATE_DATABASE; break; case T_AlterDatabaseStmt: - tag = "ALTER DATABASE"; + tag = CMDTAG_ALTER_DATABASE; break; case T_AlterDatabaseSetStmt: - tag = "ALTER DATABASE"; + tag = CMDTAG_ALTER_DATABASE; break; case T_DropdbStmt: - tag = "DROP DATABASE"; + tag = CMDTAG_DROP_DATABASE; break; case T_NotifyStmt: - tag = "NOTIFY"; + tag = CMDTAG_NOTIFY; break; case T_ListenStmt: - tag = "LISTEN"; + tag = CMDTAG_LISTEN; break; case T_UnlistenStmt: - tag = "UNLISTEN"; + tag = CMDTAG_UNLISTEN; break; case T_LoadStmt: - tag = "LOAD"; + tag = CMDTAG_LOAD; break; case T_CallStmt: - tag = "CALL"; + tag = CMDTAG_CALL; break; case T_ClusterStmt: - tag = "CLUSTER"; + tag = CMDTAG_CLUSTER; break; case T_VacuumStmt: if (((VacuumStmt *) parsetree)->is_vacuumcmd) - tag = "VACUUM"; + tag = CMDTAG_VACUUM; else - tag = "ANALYZE"; + tag = CMDTAG_ANALYZE; break; case T_ExplainStmt: - tag = "EXPLAIN"; + tag = CMDTAG_EXPLAIN; break; case T_CreateTableAsStmt: @@ -2762,24 +2749,24 @@ CreateCommandTag(Node *parsetree) { case OBJECT_TABLE: if (((CreateTableAsStmt *) parsetree)->is_select_into) - tag = "SELECT INTO"; + tag = CMDTAG_SELECT_INTO; else - tag = "CREATE TABLE AS"; + tag = CMDTAG_CREATE_TABLE_AS; break; case OBJECT_MATVIEW: - tag = "CREATE MATERIALIZED VIEW"; + tag = CMDTAG_CREATE_MATERIALIZED_VIEW; break; default: - tag = "???"; + tag = CMDTAG_UNKNOWN; } break; case T_RefreshMatViewStmt: - tag = "REFRESH MATERIALIZED VIEW"; + tag = CMDTAG_REFRESH_MATERIALIZED_VIEW; break; case T_AlterSystemStmt: - tag = "ALTER SYSTEM"; + tag = CMDTAG_ALTER_SYSTEM; break; case T_VariableSetStmt: @@ -2789,183 +2776,183 @@ CreateCommandTag(Node *parsetree) case VAR_SET_CURRENT: case VAR_SET_DEFAULT: case VAR_SET_MULTI: - tag = "SET"; + tag = CMDTAG_SET; break; case VAR_RESET: case VAR_RESET_ALL: - tag = "RESET"; + tag = CMDTAG_RESET; break; default: - tag = "???"; + tag = CMDTAG_UNKNOWN; } break; case T_VariableShowStmt: - tag = "SHOW"; + tag = CMDTAG_SHOW; break; case T_DiscardStmt: switch (((DiscardStmt *) parsetree)->target) { case DISCARD_ALL: - tag = "DISCARD ALL"; + tag = CMDTAG_DISCARD_ALL; break; case DISCARD_PLANS: - tag = "DISCARD PLANS"; + tag = CMDTAG_DISCARD_PLANS; break; case DISCARD_TEMP: - tag = "DISCARD TEMP"; + tag = CMDTAG_DISCARD_TEMP; break; case DISCARD_SEQUENCES: - tag = "DISCARD SEQUENCES"; + tag = CMDTAG_DISCARD_SEQUENCES; break; default: - tag = "???"; + tag = CMDTAG_UNKNOWN; } break; case T_CreateTransformStmt: - tag = "CREATE TRANSFORM"; + tag = CMDTAG_CREATE_TRANSFORM; break; case T_CreateTrigStmt: - tag = "CREATE TRIGGER"; + tag = CMDTAG_CREATE_TRIGGER; break; case T_CreateEventTrigStmt: - tag = "CREATE EVENT TRIGGER"; + tag = CMDTAG_CREATE_EVENT_TRIGGER; break; case T_AlterEventTrigStmt: - tag = "ALTER EVENT TRIGGER"; + tag = CMDTAG_ALTER_EVENT_TRIGGER; break; case T_CreatePLangStmt: - tag = "CREATE LANGUAGE"; + tag = CMDTAG_CREATE_LANGUAGE; break; case T_CreateRoleStmt: - tag = "CREATE ROLE"; + tag = CMDTAG_CREATE_ROLE; break; case T_AlterRoleStmt: - tag = "ALTER ROLE"; + tag = CMDTAG_ALTER_ROLE; break; case T_AlterRoleSetStmt: - tag = "ALTER ROLE"; + tag = CMDTAG_ALTER_ROLE; break; case T_DropRoleStmt: - tag = "DROP ROLE"; + tag = CMDTAG_DROP_ROLE; break; case T_DropOwnedStmt: - tag = "DROP OWNED"; + tag = CMDTAG_DROP_OWNED; break; case T_ReassignOwnedStmt: - tag = "REASSIGN OWNED"; + tag = CMDTAG_REASSIGN_OWNED; break; case T_LockStmt: - tag = "LOCK TABLE"; + tag = CMDTAG_LOCK_TABLE; break; case T_ConstraintsSetStmt: - tag = "SET CONSTRAINTS"; + tag = CMDTAG_SET_CONSTRAINTS; break; case T_CheckPointStmt: - tag = "CHECKPOINT"; + tag = CMDTAG_CHECKPOINT; break; case T_ReindexStmt: - tag = "REINDEX"; + tag = CMDTAG_REINDEX; break; case T_CreateConversionStmt: - tag = "CREATE CONVERSION"; + tag = CMDTAG_CREATE_CONVERSION; break; case T_CreateCastStmt: - tag = "CREATE CAST"; + tag = CMDTAG_CREATE_CAST; break; case T_CreateOpClassStmt: - tag = "CREATE OPERATOR CLASS"; + tag = CMDTAG_CREATE_OPERATOR_CLASS; break; case T_CreateOpFamilyStmt: - tag = "CREATE OPERATOR FAMILY"; + tag = CMDTAG_CREATE_OPERATOR_FAMILY; break; case T_AlterOpFamilyStmt: - tag = "ALTER OPERATOR FAMILY"; + tag = CMDTAG_ALTER_OPERATOR_FAMILY; break; case T_AlterOperatorStmt: - tag = "ALTER OPERATOR"; + tag = CMDTAG_ALTER_OPERATOR; break; case T_AlterTSDictionaryStmt: - tag = "ALTER TEXT SEARCH DICTIONARY"; + tag = CMDTAG_ALTER_TEXT_SEARCH_DICTIONARY; break; case T_AlterTSConfigurationStmt: - tag = "ALTER TEXT SEARCH CONFIGURATION"; + tag = CMDTAG_ALTER_TEXT_SEARCH_CONFIGURATION; break; case T_CreatePolicyStmt: - tag = "CREATE POLICY"; + tag = CMDTAG_CREATE_POLICY; break; case T_AlterPolicyStmt: - tag = "ALTER POLICY"; + tag = CMDTAG_ALTER_POLICY; break; case T_CreateAmStmt: - tag = "CREATE ACCESS METHOD"; + tag = CMDTAG_CREATE_ACCESS_METHOD; break; case T_CreatePublicationStmt: - tag = "CREATE PUBLICATION"; + tag = CMDTAG_CREATE_PUBLICATION; break; case T_AlterPublicationStmt: - tag = "ALTER PUBLICATION"; + tag = CMDTAG_ALTER_PUBLICATION; break; case T_CreateSubscriptionStmt: - tag = "CREATE SUBSCRIPTION"; + tag = CMDTAG_CREATE_SUBSCRIPTION; break; case T_AlterSubscriptionStmt: - tag = "ALTER SUBSCRIPTION"; + tag = CMDTAG_ALTER_SUBSCRIPTION; break; case T_DropSubscriptionStmt: - tag = "DROP SUBSCRIPTION"; + tag = CMDTAG_DROP_SUBSCRIPTION; break; case T_AlterCollationStmt: - tag = "ALTER COLLATION"; + tag = CMDTAG_ALTER_COLLATION; break; case T_PrepareStmt: - tag = "PREPARE"; + tag = CMDTAG_PREPARE; break; case T_ExecuteStmt: - tag = "EXECUTE"; + tag = CMDTAG_EXECUTE; break; case T_CreateStatsStmt: - tag = "CREATE STATISTICS"; + tag = CMDTAG_CREATE_STATISTICS; break; case T_AlterStatsStmt: - tag = "ALTER STATISTICS"; + tag = CMDTAG_ALTER_STATISTICS; break; case T_DeallocateStmt: @@ -2973,9 +2960,9 @@ CreateCommandTag(Node *parsetree) DeallocateStmt *stmt = (DeallocateStmt *) parsetree; if (stmt->name == NULL) - tag = "DEALLOCATE ALL"; + tag = CMDTAG_DEALLOCATE_ALL; else - tag = "DEALLOCATE"; + tag = CMDTAG_DEALLOCATE; } break; @@ -2999,33 +2986,33 @@ CreateCommandTag(Node *parsetree) switch (((PlanRowMark *) linitial(stmt->rowMarks))->strength) { case LCS_FORKEYSHARE: - tag = "SELECT FOR KEY SHARE"; + tag = CMDTAG_SELECT_FOR_KEY_SHARE; break; case LCS_FORSHARE: - tag = "SELECT FOR SHARE"; + tag = CMDTAG_SELECT_FOR_SHARE; break; case LCS_FORNOKEYUPDATE: - tag = "SELECT FOR NO KEY UPDATE"; + tag = CMDTAG_SELECT_FOR_NO_KEY_UPDATE; break; case LCS_FORUPDATE: - tag = "SELECT FOR UPDATE"; + tag = CMDTAG_SELECT_FOR_UPDATE; break; default: - tag = "SELECT"; + tag = CMDTAG_SELECT; break; } } else - tag = "SELECT"; + tag = CMDTAG_SELECT; break; case CMD_UPDATE: - tag = "UPDATE"; + tag = CMDTAG_UPDATE; break; case CMD_INSERT: - tag = "INSERT"; + tag = CMDTAG_INSERT; break; case CMD_DELETE: - tag = "DELETE"; + tag = CMDTAG_DELETE; break; case CMD_UTILITY: tag = CreateCommandTag(stmt->utilityStmt); @@ -3033,7 +3020,7 @@ CreateCommandTag(Node *parsetree) default: elog(WARNING, "unrecognized commandType: %d", (int) stmt->commandType); - tag = "???"; + tag = CMDTAG_UNKNOWN; break; } } @@ -3059,33 +3046,33 @@ CreateCommandTag(Node *parsetree) switch (((RowMarkClause *) linitial(stmt->rowMarks))->strength) { case LCS_FORKEYSHARE: - tag = "SELECT FOR KEY SHARE"; + tag = CMDTAG_SELECT_FOR_KEY_SHARE; break; case LCS_FORSHARE: - tag = "SELECT FOR SHARE"; + tag = CMDTAG_SELECT_FOR_SHARE; break; case LCS_FORNOKEYUPDATE: - tag = "SELECT FOR NO KEY UPDATE"; + tag = CMDTAG_SELECT_FOR_NO_KEY_UPDATE; break; case LCS_FORUPDATE: - tag = "SELECT FOR UPDATE"; + tag = CMDTAG_SELECT_FOR_UPDATE; break; default: - tag = "???"; + tag = CMDTAG_UNKNOWN; break; } } else - tag = "SELECT"; + tag = CMDTAG_SELECT; break; case CMD_UPDATE: - tag = "UPDATE"; + tag = CMDTAG_UPDATE; break; case CMD_INSERT: - tag = "INSERT"; + tag = CMDTAG_INSERT; break; case CMD_DELETE: - tag = "DELETE"; + tag = CMDTAG_DELETE; break; case CMD_UTILITY: tag = CreateCommandTag(stmt->utilityStmt); @@ -3093,7 +3080,7 @@ CreateCommandTag(Node *parsetree) default: elog(WARNING, "unrecognized commandType: %d", (int) stmt->commandType); - tag = "???"; + tag = CMDTAG_UNKNOWN; break; } } @@ -3102,7 +3089,7 @@ CreateCommandTag(Node *parsetree) default: elog(WARNING, "unrecognized node type: %d", (int) nodeTag(parsetree)); - tag = "???"; + tag = CMDTAG_UNKNOWN; break; } |
