Re: Using PQexecQuery in pipeline mode produces unexpected Close messages
Kyotaro Horiguchi <horikyota.ntt@gmail.com>
From: Kyotaro Horiguchi <horikyota.ntt@gmail.com>
To: tgl@sss.pgh.pa.us
Cc: alvherre@alvh.no-ip.org, daniele.varrazzo@gmail.com,
pgsql-hackers@lists.postgresql.org
Date: 2022-06-16T03:07:47Z
Lists: pgsql-bugs, pgsql-hackers
Attachments
- libpqpline-test.diff (text/x-patch) patch
- libpqpline-separte-pipelineidle-state.diff (text/x-patch) patch
At Thu, 16 Jun 2022 10:34:22 +0900 (JST), Kyotaro Horiguchi <horikyota.ntt@gmail.com> wrote in
> PQgetResult() resets the state to IDLE while in pipeline mode.
>
> fe-exec.c:2171
>
> > if (conn->pipelineStatus != PQ_PIPELINE_OFF)
> > {
> > /*
> > * We're about to send the results of the current query. Set
> > * us idle now, and ...
> > */
> > conn->asyncStatus = PGASYNC_IDLE;
>
> And actually that code let the connection state enter to IDLE before
> CloseComplete. In the test case I posted, the following happens.
>
> PQsendQuery(conn, "SELECT 1;");
> PQsendFlushRequest(conn);
> PQgetResult(conn); // state enters IDLE, reads down to <CommandComplete>
> PQgetResult(conn); // reads <CloseComplete comes>
> PQpipelineSync(conn); // sync too late
>
> Pipeline feature seems intending to allow PQgetResult called before
> PQpipelineSync. And also seems allowing to call QPpipelineSync() after
> PQgetResult().
>
> I haven't come up with a valid *fix* of this flow..
The attached is a crude patch to separate the state for PIPELINE-IDLE
from PGASYNC_IDLE. I haven't found a better way..
regards.
--
Kyotaro Horiguchi
NTT Open Source Software Center
Commits
-
001_libpq_pipeline.pl: use Test::Differences if available
- 87e4f24d8293 16.0 landed
-
libpq: Improve idle state handling in pipeline mode
- 93cf9233cd54 15.0 landed
- 7c1f42612384 14.5 landed
- 054325c5eeb3 16.0 landed