mirror of
https://github.com/postgres/postgres.git
synced 2025-06-16 06:01:02 +03:00
Fix libpq state machine in pipeline mode
The original coding required that PQpipelineSync had been called before
the first call to PQgetResult, and failure to do that would result in an
unexpected NULL result being returned. Fix by setting the right state
when a query is sent, rather than leaving it unchanged and having
PQpipelineSync apply the necessary state change.
A new test case to verify the behavior is added, which relies on the new
PQsendFlushRequest() function added by commit a7192326c7
.
Backpatch to 14, where pipeline mode was added.
Reported-by: Boris Kolpackov <boris@codesynthesis.com>
Author: Álvaro Herrera <alvherre@alvh.no-ip.org>
Discussion: https://postgr.es/m/boris.20210616110321@codesynthesis.com
This commit is contained in:
@ -1375,8 +1375,7 @@ PQsendQueryInternal(PGconn *conn, const char *query, bool newQuery)
|
||||
|
||||
/* OK, it's launched! */
|
||||
pqAppendCmdQueueEntry(conn, entry);
|
||||
if (conn->pipelineStatus == PQ_PIPELINE_OFF)
|
||||
conn->asyncStatus = PGASYNC_BUSY;
|
||||
conn->asyncStatus = PGASYNC_BUSY;
|
||||
return 1;
|
||||
|
||||
sendFailed:
|
||||
@ -1513,8 +1512,7 @@ PQsendPrepare(PGconn *conn,
|
||||
|
||||
pqAppendCmdQueueEntry(conn, entry);
|
||||
|
||||
if (conn->pipelineStatus == PQ_PIPELINE_OFF)
|
||||
conn->asyncStatus = PGASYNC_BUSY;
|
||||
conn->asyncStatus = PGASYNC_BUSY;
|
||||
|
||||
/*
|
||||
* Give the data a push (in pipeline mode, only if we're past the size
|
||||
@ -1817,8 +1815,7 @@ PQsendQueryGuts(PGconn *conn,
|
||||
|
||||
/* OK, it's launched! */
|
||||
pqAppendCmdQueueEntry(conn, entry);
|
||||
if (conn->pipelineStatus == PQ_PIPELINE_OFF)
|
||||
conn->asyncStatus = PGASYNC_BUSY;
|
||||
conn->asyncStatus = PGASYNC_BUSY;
|
||||
return 1;
|
||||
|
||||
sendFailed:
|
||||
@ -2448,8 +2445,7 @@ PQsendDescribe(PGconn *conn, char desc_type, const char *desc_target)
|
||||
|
||||
/* OK, it's launched! */
|
||||
pqAppendCmdQueueEntry(conn, entry);
|
||||
if (conn->pipelineStatus == PQ_PIPELINE_OFF)
|
||||
conn->asyncStatus = PGASYNC_BUSY;
|
||||
conn->asyncStatus = PGASYNC_BUSY;
|
||||
return 1;
|
||||
|
||||
sendFailed:
|
||||
@ -3084,12 +3080,7 @@ PQpipelineSync(PGconn *conn)
|
||||
*/
|
||||
if (PQflush(conn) < 0)
|
||||
goto sendFailed;
|
||||
|
||||
/*
|
||||
* Call pqPipelineProcessQueue so the user can call start calling
|
||||
* PQgetResult.
|
||||
*/
|
||||
pqPipelineProcessQueue(conn);
|
||||
conn->asyncStatus = PGASYNC_BUSY;
|
||||
|
||||
return 1;
|
||||
|
||||
|
Reference in New Issue
Block a user