Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 27ca0bc

Browse files
committed
libpq: Reset singlerow flag correctly in pipeline mode
When a query whose results were requested in single-row mode is the last in the queue by the time those results are being read, the single-row flag was not being reset, because we were returning early from pqPipelineProcessQueue. Move that stanza up so that the flag is always reset at the end of sending that query's results. Add a test for the situation. Backpatch to 14. Author: Denis Laxalde <denis.laxalde@dalibo.com> Discussion: https://postgr.es/m/01af18c5-dacc-a8c8-07ee-aecc7650c3e8@dalibo.com
1 parent f7eec7f commit 27ca0bc

File tree

3 files changed

+70
-7
lines changed

3 files changed

+70
-7
lines changed

src/interfaces/libpq/fe-exec.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3101,6 +3101,12 @@ pqPipelineProcessQueue(PGconn *conn)
31013101
break;
31023102
}
31033103

3104+
/*
3105+
* Reset single-row processing mode. (Client has to set it up for each
3106+
* query, if desired.)
3107+
*/
3108+
conn->singleRowMode = false;
3109+
31043110
/*
31053111
* If there are no further commands to process in the queue, get us in
31063112
* "real idle" mode now.
@@ -3120,12 +3126,6 @@ pqPipelineProcessQueue(PGconn *conn)
31203126
/* Initialize async result-accumulation state */
31213127
pqClearAsyncResult(conn);
31223128

3123-
/*
3124-
* Reset single-row processing mode. (Client has to set it up for each
3125-
* query, if desired.)
3126-
*/
3127-
conn->singleRowMode = false;
3128-
31293129
if (conn->pipelineStatus == PQ_PIPELINE_ABORTED &&
31303130
conn->cmd_queue_head->queryclass != PGQUERY_SYNC)
31313131
{

src/test/modules/libpq_pipeline/libpq_pipeline.c

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1155,11 +1155,11 @@ test_singlerowmode(PGconn *conn)
11551155
int i;
11561156
bool pipeline_ended = false;
11571157

1158-
/* 1 pipeline, 3 queries in it */
11591158
if (PQenterPipelineMode(conn) != 1)
11601159
pg_fatal("failed to enter pipeline mode: %s",
11611160
PQerrorMessage(conn));
11621161

1162+
/* One series of three commands, using single-row mode for the first two. */
11631163
for (i = 0; i < 3; i++)
11641164
{
11651165
char *param[1];
@@ -1251,6 +1251,49 @@ test_singlerowmode(PGconn *conn)
12511251
pg_fatal("didn't get expected terminating TUPLES_OK");
12521252
}
12531253

1254+
/*
1255+
* Now issue one command, get its results in with single-row mode, then
1256+
* issue another command, and get its results in normal mode; make sure
1257+
* the single-row mode flag is reset as expected.
1258+
*/
1259+
if (PQsendQueryParams(conn, "SELECT generate_series(0, 0)",
1260+
0, NULL, NULL, NULL, NULL, 0) != 1)
1261+
pg_fatal("failed to send query: %s",
1262+
PQerrorMessage(conn));
1263+
if (PQsendFlushRequest(conn) != 1)
1264+
pg_fatal("failed to send flush request");
1265+
if (PQsetSingleRowMode(conn) != 1)
1266+
pg_fatal("PQsetSingleRowMode() failed");
1267+
res = PQgetResult(conn);
1268+
if (res == NULL)
1269+
pg_fatal("unexpected NULL");
1270+
if (PQresultStatus(res) != PGRES_SINGLE_TUPLE)
1271+
pg_fatal("Expected PGRES_SINGLE_TUPLE, got %s",
1272+
PQresStatus(PQresultStatus(res)));
1273+
res = PQgetResult(conn);
1274+
if (res == NULL)
1275+
pg_fatal("unexpected NULL");
1276+
if (PQresultStatus(res) != PGRES_TUPLES_OK)
1277+
pg_fatal("Expected PGRES_TUPLES_OK, got %s",
1278+
PQresStatus(PQresultStatus(res)));
1279+
if (PQgetResult(conn) != NULL)
1280+
pg_fatal("expected NULL result");
1281+
1282+
if (PQsendQueryParams(conn, "SELECT 1",
1283+
0, NULL, NULL, NULL, NULL, 0) != 1)
1284+
pg_fatal("failed to send query: %s",
1285+
PQerrorMessage(conn));
1286+
if (PQsendFlushRequest(conn) != 1)
1287+
pg_fatal("failed to send flush request");
1288+
res = PQgetResult(conn);
1289+
if (res == NULL)
1290+
pg_fatal("unexpected NULL");
1291+
if (PQresultStatus(res) != PGRES_TUPLES_OK)
1292+
pg_fatal("Expected PGRES_TUPLES_OK, got %s",
1293+
PQresStatus(PQresultStatus(res)));
1294+
if (PQgetResult(conn) != NULL)
1295+
pg_fatal("expected NULL result");
1296+
12541297
if (PQexitPipelineMode(conn) != 1)
12551298
pg_fatal("failed to end pipeline mode: %s", PQerrorMessage(conn));
12561299

src/test/modules/libpq_pipeline/traces/singlerow.trace

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,24 @@ B 12 DataRow 1 2 '45'
3636
B 12 DataRow 1 2 '46'
3737
B 13 CommandComplete "SELECT 5"
3838
B 5 ReadyForQuery I
39+
F 36 Parse "" "SELECT generate_series(0, 0)" 0
40+
F 14 Bind "" "" 0 0 1 0
41+
F 6 Describe P ""
42+
F 9 Execute "" 0
43+
F 4 Flush
44+
B 4 ParseComplete
45+
B 4 BindComplete
46+
B 40 RowDescription 1 "generate_series" NNNN 0 NNNN 4 -1 0
47+
B 11 DataRow 1 1 '0'
48+
B 13 CommandComplete "SELECT 1"
49+
F 16 Parse "" "SELECT 1" 0
50+
F 14 Bind "" "" 0 0 1 0
51+
F 6 Describe P ""
52+
F 9 Execute "" 0
53+
F 4 Flush
54+
B 4 ParseComplete
55+
B 4 BindComplete
56+
B 33 RowDescription 1 "?column?" NNNN 0 NNNN 4 -1 0
57+
B 11 DataRow 1 1 '1'
58+
B 13 CommandComplete "SELECT 1"
3959
F 4 Terminate

0 commit comments

Comments
 (0)