1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-06 07:49:08 +03:00

Speed up creation of command completion tags

The building of command completion tags could often be seen showing up in
profiles when running high tps workloads.

The query completion tags were being built with snprintf, which is slow at
the best of times when compared with more manual ways of formatting
strings.  Here we introduce BuildQueryCompletionString() to do this job
for us.  We also now store the completion tag's strlen in the
CommandTagBehavior struct so that we can quickly memcpy this number of
bytes into the completion tag string.  Appending the rows affected is done
via pg_ulltoa_n.  BuildQueryCompletionString returns the length of the
built string.  This saves us having to call strlen to figure out how many
bytes to pass to pq_putmessage().

Author: David Rowley, Andres Freund
Reviewed-by: Andres Freund
Discussion: https://postgr.es/m/CAHoyFK-Xwqc-iY52shj0G+8K9FJpse+FuZ36XBKy78wDVnd=Qg@mail.gmail.com
This commit is contained in:
David Rowley
2022-12-16 10:31:25 +13:00
parent d35a1af468
commit ac99802080
4 changed files with 78 additions and 30 deletions

View File

@@ -166,8 +166,7 @@ void
EndCommand(const QueryCompletion *qc, CommandDest dest, bool force_undecorated_output)
{
char completionTag[COMPLETION_TAG_BUFSIZE];
CommandTag tag;
const char *tagname;
Size len;
switch (dest)
{
@@ -175,29 +174,9 @@ EndCommand(const QueryCompletion *qc, CommandDest dest, bool force_undecorated_o
case DestRemoteExecute:
case DestRemoteSimple:
/*
* We assume the tagname is plain ASCII and therefore requires no
* encoding conversion.
*/
tag = qc->commandTag;
tagname = GetCommandTagName(tag);
/*
* In PostgreSQL versions 11 and earlier, it was possible to
* create a table WITH OIDS. When inserting into such a table,
* INSERT used to include the Oid of the inserted record in the
* completion tag. To maintain compatibility in the wire
* protocol, we now write a "0" (for InvalidOid) in the location
* where we once wrote the new record's Oid.
*/
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);
len = BuildQueryCompletionString(completionTag, qc,
force_undecorated_output);
pq_putmessage('C', completionTag, len + 1);
case DestNone:
case DestDebug: