aboutsummaryrefslogtreecommitdiff
path: root/src/backend/tcop/postgres.c
diff options
context:
space:
mode:
authorAlvaro Herrera <alvherre@alvh.no-ip.org>2020-03-02 18:19:51 -0300
committerAlvaro Herrera <alvherre@alvh.no-ip.org>2020-03-02 18:19:51 -0300
commit2f9661311b83dc481fc19f6e3bda015392010a40 (patch)
tree9a1aabe1d15ac894f7badbc886ae33f16bbfc3b6 /src/backend/tcop/postgres.c
parent7b425a5283cb2c8a452c2e79d6218e41373fd641 (diff)
downloadpostgresql-2f9661311b83dc481fc19f6e3bda015392010a40.tar.gz
postgresql-2f9661311b83dc481fc19f6e3bda015392010a40.zip
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/postgres.c')
-rw-r--r--src/backend/tcop/postgres.c33
1 files changed, 14 insertions, 19 deletions
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
{