mirror of
https://github.com/postgres/postgres.git
synced 2025-06-17 17:02:08 +03:00
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
This commit is contained in:
@ -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;
|
||||
@ -1438,11 +1437,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
|
||||
@ -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
|
||||
{
|
||||
|
Reference in New Issue
Block a user