summaryrefslogtreecommitdiff
path: root/src/backend/tcop
diff options
context:
space:
mode:
authorAlvaro Herrera2020-03-02 21:19:51 +0000
committerAlvaro Herrera2020-03-02 21:19:51 +0000
commit2f9661311b83dc481fc19f6e3bda015392010a40 (patch)
tree9a1aabe1d15ac894f7badbc886ae33f16bbfc3b6 /src/backend/tcop
parent7b425a5283cb2c8a452c2e79d6218e41373fd641 (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/Makefile1
-rw-r--r--src/backend/tcop/cmdtag.c98
-rw-r--r--src/backend/tcop/dest.c32
-rw-r--r--src/backend/tcop/postgres.c33
-rw-r--r--src/backend/tcop/pquery.c112
-rw-r--r--src/backend/tcop/utility.c561
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;
}