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

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

  1. 001_libpq_pipeline.pl: use Test::Differences if available

  2. libpq: Improve idle state handling in pipeline mode