Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit b028327

Browse files
committed
Avoid unnecessary copying of parameter values in BIND. This allows
efficient insertion of large bytea values through the BIND interface.
1 parent d97c9b3 commit b028327

File tree

1 file changed

+27
-19
lines changed

1 file changed

+27
-19
lines changed

src/backend/tcop/postgres.c

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.342 2003/05/09 18:08:48 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.343 2003/05/12 16:48:17 tgl Exp $
1212
*
1313
* NOTES
1414
* this is the "main" module of the postgres backend and
@@ -1265,13 +1265,9 @@ exec_bind_message(StringInfo input_message)
12651265
if (numParams > 0)
12661266
{
12671267
bool isaborted = IsAbortedTransactionBlockState();
1268-
StringInfoData pbuf;
12691268
List *l;
12701269
MemoryContext oldContext;
12711270

1272-
/* Note that the string buffer lives in MessageContext */
1273-
initStringInfo(&pbuf);
1274-
12751271
oldContext = MemoryContextSwitchTo(PortalGetHeapMemory(portal));
12761272

12771273
params = (ParamListInfo)
@@ -1289,14 +1285,7 @@ exec_bind_message(StringInfo input_message)
12891285

12901286
if (!isNull)
12911287
{
1292-
/* Reset pbuf to empty, and insert raw data into it */
1293-
pbuf.len = 0;
1294-
pbuf.data[0] = '\0';
1295-
pbuf.cursor = 0;
1296-
1297-
appendBinaryStringInfo(&pbuf,
1298-
pq_getmsgbytes(input_message, plength),
1299-
plength);
1288+
const char *pvalue = pq_getmsgbytes(input_message, plength);
13001289

13011290
if (isaborted)
13021291
{
@@ -1306,6 +1295,8 @@ exec_bind_message(StringInfo input_message)
13061295
else
13071296
{
13081297
int16 pformat;
1298+
StringInfoData pbuf;
1299+
char csave;
13091300

13101301
if (numPFormats > 1)
13111302
pformat = pformats[i];
@@ -1314,6 +1305,23 @@ exec_bind_message(StringInfo input_message)
13141305
else
13151306
pformat = 0; /* default = text */
13161307

1308+
/*
1309+
* Rather than copying data around, we just set up a phony
1310+
* StringInfo pointing to the correct portion of the
1311+
* message buffer. We assume we can scribble on the
1312+
* message buffer so as to maintain the convention that
1313+
* StringInfos have a trailing null. This is grotty but
1314+
* is a big win when dealing with very large parameter
1315+
* strings.
1316+
*/
1317+
pbuf.data = (char *) pvalue;
1318+
pbuf.maxlen = plength + 1;
1319+
pbuf.len = plength;
1320+
pbuf.cursor = 0;
1321+
1322+
csave = pbuf.data[plength];
1323+
pbuf.data[plength] = '\0';
1324+
13171325
if (pformat == 0)
13181326
{
13191327
Oid typInput;
@@ -1322,11 +1330,8 @@ exec_bind_message(StringInfo input_message)
13221330

13231331
getTypeInputInfo(ptype, &typInput, &typElem);
13241332
/*
1325-
* Since stringinfo.c keeps a trailing null in
1326-
* place even for binary data, the contents of
1327-
* pbuf are a valid C string. We have to do
1328-
* encoding conversion before calling the typinput
1329-
* routine, though.
1333+
* We have to do encoding conversion before calling
1334+
* the typinput routine.
13301335
*/
13311336
pstring = (char *)
13321337
pg_client_to_server((unsigned char *) pbuf.data,
@@ -1362,6 +1367,9 @@ exec_bind_message(StringInfo input_message)
13621367
{
13631368
elog(ERROR, "Invalid format code %d", pformat);
13641369
}
1370+
1371+
/* Restore message buffer contents */
1372+
pbuf.data[plength] = csave;
13651373
}
13661374
}
13671375

@@ -2524,7 +2532,7 @@ PostgresMain(int argc, char *argv[], const char *username)
25242532
if (!IsUnderPostmaster)
25252533
{
25262534
puts("\nPOSTGRES backend interactive interface ");
2527-
puts("$Revision: 1.342 $ $Date: 2003/05/09 18:08:48 $\n");
2535+
puts("$Revision: 1.343 $ $Date: 2003/05/12 16:48:17 $\n");
25282536
}
25292537

25302538
/*

0 commit comments

Comments
 (0)