Thread

  1. Re: BUG #18944: Assertion Failure in psql with idle_session_timeout Set

    Anthonin Bonnefoy <anthonin.bonnefoy@datadoghq.com> — 2025-06-11T14:11:14Z

    On Wed, Jun 11, 2025 at 5:58 AM Никита Калинин <n.kalinin@postgrespro.ru> wrote:
    >
    > I do not believe it is necessary to create a new bug report, as, in my opinion, this issue remains a continuation of BUG #18944. Upon executing the following request:
    >
    > psql <<EOF
    > CREATE TABLE psql_pipeline(a INTEGER PRIMARY KEY, s TEXT);
    > \startpipeline
    > COPY psql_pipeline FROM STDIN;
    > \flushrequest
    > \getresults
    > \endpipeline
    > \.
    > COPY psql_pipeline FROM STDIN;
    > \syncpipeline
    > \getresults
    > EOF
    >
    > we encounter yet another assertion failure:
    >
    > ERROR:  invalid input syntax for type integer: "endpipeline"
    > CONTEXT:  COPY psql_pipeline, line 1, column a: "endpipeline"
    > message type 0x5a arrived from server while idle
    > Pipeline aborted, command did not run
    > psql: common.c:1527: discardAbortedPipelineResults: Assertion `res == ((void *)0) || result_status == PGRES_PIPELINE_ABORTED' failed.
    
    I've managed to reproduce, thanks for the report.
    
    The issue seems to come from COPY automatically sending a Sync
    message. During the first COPY failure, the sync is used as a
    synchronisation point, aborts the transaction and is ready to process
    new commands from the client.
    However, from the client's point of view, the pipeline is in an
    aborted state and all commands should be ignored as ignore_till_sync
    should be true.However, that's not the case due to the Sync message
    automatically added by COPY.
    Thus, when the second COPY is sent (something else than COPY can
    trigger this), we go through discardAbortedPipelineResults while the
    server answers to the commands, triggering the assertion failure.
    
    Libpq's fe-exec doesn't seem to handle a possible pipeline state in
    PQputCopyEnd. Naively, I've tried to only send a Sync message if
    'conn->pipelineStatus == PQ_PIPELINE_OFF' but this will block the
    client in Copy mode and the Sync message is needed to exit it.
    I didn't have time to look into this further today but a possible fix
    could be to send the Sync message and add it to the command queue if
    we're in a pipeline. This should allow libpq's state to get out of the
    aborted pipeline state and match the backend's state.