> On Nov 10, 2025, at 12:45, Fujii Masao <[email protected]> wrote:
> 
> On Mon, Nov 10, 2025 at 11:07 AM Chao Li <[email protected]> wrote:
>> I just did a test. In the test, I inserted a tuple with the same primary key 
>> so that the inserts fails by the unique key constraint which breaks the 
>> pipeline, and some random select statements followed. And I added some debug 
>> messages in discardAvailableResults(), which showed me that the function 
>> will discard rest of statements’ results until \endpipeline. As there are 
>> anyway limited number of statements before \endpipeline, my concern is 
>> actually not valid. So, now I am good with this patch.
> 
> Thanks a lot for testing!
> 

Hi Fujii-san,

I just did more tests on both pipeline mode and non-pipeline mode, I think the 
main purpose of discardAvailableResults() is to drain results for pipeline 
mode. In non-pipeline mode, a NULL res indicates no more result to read; while 
in pipeline mode, when a pipeline is aborted, either a valid result or NULL 
could still be returned, thus we need to wait until pipeline state switch to 
PQ_PIPELINE_OK. From this perspective, the current inline comment is correct, 
but I feel it’s not clear enough.

So I am proposing the function comment and inline comment like the following:
```
/*
 * Read and discard all available results from the connection.
 *
 * Non-pipeline mode:
 * ------------------
 * PQgetResult() returns each PGresult in order for the last command sent.
 * When it returns NULL, that definitively means there are no more results
 * for that command. We stop on NULL (or on CONNECTION_BAD).
 *
 * Pipeline mode:
 * --------------
 * If an earlier command in the pipeline errors, libpq enters the
 * PQ_PIPELINE_ABORTED state. In this state, PQgetResult() may return
 * either a valid PGresult or NULL, and a NULL return does NOT mean
 * that the connection is drained. More results for later commands (or
 * protocol housekeeping such as the pipeline sync result) can still
 * arrive afterward. Therefore we must continue calling PQgetResult()
 * while PQpipelineStatus(conn) == PQ_PIPELINE_ABORTED, even if we see
 * intermittent NULLs.
 */
static void
discardAvailableResults(CState *st)
{
        PGresult   *res = NULL;

        for (;;)
        {
                res = PQgetResult(st->con);

                /*
                 * Stop when there are no more results *and* the pipeline is not
                 * in the aborted state, or if the connection has failed.
                 */
                if ((res == NULL && PQpipelineStatus(st->con) != 
PQ_PIPELINE_ABORTED) ||
                        PQstatus(st->con) == CONNECTION_BAD)
                        break;

                PQclear(res);
        }
        PQclear(res);
}
```

What do you think?

Best regards,
--
Chao Li (Evan)
HighGo Software Co., Ltd.
https://www.highgo.com/






Reply via email to