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)