Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitac99802

Browse files
committed
Speed up creation of command completion tags
The building of command completion tags could often be seen showing up inprofiles when running high tps workloads.The query completion tags were being built with snprintf, which is slow atthe best of times when compared with more manual ways of formattingstrings. Here we introduce BuildQueryCompletionString() to do this jobfor us. We also now store the completion tag's strlen in theCommandTagBehavior struct so that we can quickly memcpy this number ofbytes into the completion tag string. Appending the rows affected is donevia pg_ulltoa_n. BuildQueryCompletionString returns the length of thebuilt string. This saves us having to call strlen to figure out how manybytes to pass to pq_putmessage().Author: David Rowley, Andres FreundReviewed-by: Andres FreundDiscussion:https://postgr.es/m/CAHoyFK-Xwqc-iY52shj0G+8K9FJpse+FuZ36XBKy78wDVnd=Qg@mail.gmail.com
1 parentd35a1af commitac99802

File tree

4 files changed

+78
-30
lines changed

4 files changed

+78
-30
lines changed

‎src/backend/tcop/cmdtag.c

Lines changed: 69 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,21 @@
1515

1616
#include"miscadmin.h"
1717
#include"tcop/cmdtag.h"
18+
#include"utils/builtins.h"
1819

1920

2021
typedefstructCommandTagBehavior
2122
{
22-
constchar*name;
23+
constchar*name;/* tag name, e.g. "SELECT" */
24+
constuint8namelen;/* set to strlen(name) */
2325
constboolevent_trigger_ok;
2426
constbooltable_rewrite_ok;
25-
constbooldisplay_rowcount;
27+
constbooldisplay_rowcount;/* should the number of rows affected be
28+
* shown in the command completion string */
2629
}CommandTagBehavior;
2730

2831
#definePG_CMDTAG(tag,name,evtrgok,rwrok,rowcnt) \
29-
{ name, evtrgok, rwrok, rowcnt },
32+
{ name,(uint8) (sizeof(name) - 1),evtrgok, rwrok, rowcnt },
3033

3134
staticconstCommandTagBehaviortag_behavior[COMMAND_TAG_NEXTTAG]= {
3235
#include"tcop/cmdtaglist.h"
@@ -47,6 +50,13 @@ GetCommandTagName(CommandTag commandTag)
4750
returntag_behavior[commandTag].name;
4851
}
4952

53+
constchar*
54+
GetCommandTagNameAndLen(CommandTagcommandTag,Size*len)
55+
{
56+
*len= (Size)tag_behavior[commandTag].namelen;
57+
returntag_behavior[commandTag].name;
58+
}
59+
5060
bool
5161
command_tag_display_rowcount(CommandTagcommandTag)
5262
{
@@ -96,3 +106,59 @@ GetCommandTagEnum(const char *commandname)
96106
}
97107
returnCMDTAG_UNKNOWN;
98108
}
109+
110+
/*
111+
* BuildQueryCompletionString
112+
*Build a string containing the command tag name with the
113+
*QueryCompletion's nprocessed for command tags with display_rowcount
114+
*set. Returns the strlen of the constructed string.
115+
*
116+
* The caller must ensure that buff is at least COMPLETION_TAG_BUFSIZE bytes.
117+
*
118+
* If nameonly is true, then the constructed string will contain only the tag
119+
* name.
120+
*/
121+
Size
122+
BuildQueryCompletionString(char*buff,constQueryCompletion*qc,
123+
boolnameonly)
124+
{
125+
CommandTagtag=qc->commandTag;
126+
Sizetaglen;
127+
constchar*tagname=GetCommandTagNameAndLen(tag,&taglen);
128+
char*bufp;
129+
130+
/*
131+
* We assume the tagname is plain ASCII and therefore requires no encoding
132+
* conversion.
133+
*/
134+
memcpy(buff,tagname,taglen);
135+
bufp=buff+taglen;
136+
137+
/* ensure that the tagname isn't long enough to overrun the buffer */
138+
Assert(taglen <=COMPLETION_TAG_BUFSIZE-MAXINT8LEN-4);
139+
140+
/*
141+
* In PostgreSQL versions 11 and earlier, it was possible to create a
142+
* table WITH OIDS. When inserting into such a table, INSERT used to
143+
* include the Oid of the inserted record in the completion tag. To
144+
* maintain compatibility in the wire protocol, we now write a "0" (for
145+
* InvalidOid) in the location where we once wrote the new record's Oid.
146+
*/
147+
if (command_tag_display_rowcount(tag)&& !nameonly)
148+
{
149+
if (tag==CMDTAG_INSERT)
150+
{
151+
*bufp++=' ';
152+
*bufp++='0';
153+
}
154+
*bufp++=' ';
155+
bufp+=pg_ulltoa_n(qc->nprocessed,bufp);
156+
}
157+
158+
/* and finally, NUL terminate the string */
159+
*bufp='\0';
160+
161+
Assert((bufp-buff)==strlen(buff));
162+
163+
returnbufp-buff;
164+
}

‎src/backend/tcop/dest.c

Lines changed: 4 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -166,38 +166,17 @@ void
166166
EndCommand(constQueryCompletion*qc,CommandDestdest,boolforce_undecorated_output)
167167
{
168168
charcompletionTag[COMPLETION_TAG_BUFSIZE];
169-
CommandTagtag;
170-
constchar*tagname;
169+
Sizelen;
171170

172171
switch (dest)
173172
{
174173
caseDestRemote:
175174
caseDestRemoteExecute:
176175
caseDestRemoteSimple:
177176

178-
/*
179-
* We assume the tagname is plain ASCII and therefore requires no
180-
* encoding conversion.
181-
*/
182-
tag=qc->commandTag;
183-
tagname=GetCommandTagName(tag);
184-
185-
/*
186-
* In PostgreSQL versions 11 and earlier, it was possible to
187-
* create a table WITH OIDS. When inserting into such a table,
188-
* INSERT used to include the Oid of the inserted record in the
189-
* completion tag. To maintain compatibility in the wire
190-
* protocol, we now write a "0" (for InvalidOid) in the location
191-
* where we once wrote the new record's Oid.
192-
*/
193-
if (command_tag_display_rowcount(tag)&& !force_undecorated_output)
194-
snprintf(completionTag,COMPLETION_TAG_BUFSIZE,
195-
tag==CMDTAG_INSERT ?
196-
"%s 0 "UINT64_FORMAT :"%s "UINT64_FORMAT,
197-
tagname,qc->nprocessed);
198-
else
199-
snprintf(completionTag,COMPLETION_TAG_BUFSIZE,"%s",tagname);
200-
pq_putmessage('C',completionTag,strlen(completionTag)+1);
177+
len=BuildQueryCompletionString(completionTag,qc,
178+
force_undecorated_output);
179+
pq_putmessage('C',completionTag,len+1);
201180

202181
caseDestNone:
203182
caseDestDebug:

‎src/include/tcop/cmdtag.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
#ifndefCMDTAG_H
1414
#defineCMDTAG_H
1515

16+
/* buffer size required for command completion tags */
17+
#defineCOMPLETION_TAG_BUFSIZE64
1618

1719
#definePG_CMDTAG(tag,name,evtrgok,rwrok,rowcnt) \
1820
tag,
@@ -50,9 +52,12 @@ CopyQueryCompletion(QueryCompletion *dst, const QueryCompletion *src)
5052

5153
externvoidInitializeQueryCompletion(QueryCompletion*qc);
5254
externconstchar*GetCommandTagName(CommandTagcommandTag);
55+
externconstchar*GetCommandTagNameAndLen(CommandTagcommandTag,Size*len);
5356
externboolcommand_tag_display_rowcount(CommandTagcommandTag);
5457
externboolcommand_tag_event_trigger_ok(CommandTagcommandTag);
5558
externboolcommand_tag_table_rewrite_ok(CommandTagcommandTag);
5659
externCommandTagGetCommandTagEnum(constchar*commandname);
60+
externSizeBuildQueryCompletionString(char*buff,constQueryCompletion*qc,
61+
boolnameonly);
5762

5863
#endif/* CMDTAG_H */

‎src/include/tcop/dest.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,6 @@
7171
#include"tcop/cmdtag.h"
7272

7373

74-
/* buffer size to use for command completion tags */
75-
#defineCOMPLETION_TAG_BUFSIZE64
7674

7775

7876
/* ----------------

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp