• Alvaro Herrera's avatar
    libpq: Improve idle state handling in pipeline mode · 7c1f4261
    Alvaro Herrera authored
    We were going into IDLE state too soon when executing queries via
    PQsendQuery in pipeline mode, causing several scenarios to misbehave in
    different ways -- most notably, as reported by Daniele Varrazzo, that a
    warning message is produced by libpq:
      message type 0x33 arrived from server while idle
    But it is also possible, if queries are sent and results consumed not in
    lockstep, for the expected mediating NULL result values from PQgetResult
    to be lost (a problem which has not been reported, but which is more
    serious).
    
    Fix this by introducing two new concepts: one is a command queue element
    PGQUERY_CLOSE to tell libpq to wait for the CloseComplete server
    response to the Close message that is sent by PQsendQuery.  Because the
    application is not expecting any PGresult from this, the mechanism to
    consume it is a bit hackish.
    
    The other concept, authored by Horiguchi-san, is a PGASYNC_PIPELINE_IDLE
    state for libpq's state machine to differentiate "really idle" from
    merely "the idle state that occurs in between reading results from the
    server for elements in the pipeline".  This makes libpq not go fully
    IDLE when the libpq command queue contains entries; in normal cases, we
    only go IDLE once at the end of the pipeline, when the server response
    to the final SYNC message is received.  (However, there are corner cases
    it doesn't fix, such as terminating the query sequence by
    PQsendFlushRequest instead of PQpipelineSync; this sort of scenario is
    what requires PGQUERY_CLOSE bit above.)
    
    This last bit helps make the libpq state machine clearer; in particular
    we can get rid of an ugly hack in pqParseInput3 to avoid considering
    IDLE as such when the command queue contains entries.
    
    A new test mode is added to libpq_pipeline.c to tickle some related
    problematic cases.
    Reported-by: default avatarDaniele Varrazzo <daniele.varrazzo@gmail.com>
    Co-authored-by: default avatarKyotaro Horiguchi <horikyota.ntt@gmail.com>
    Discussion: https://postgr.es/m/CA+mi_8bvD0_CW3sumgwPvWdNzXY32itoG_16tDYRu_1S2gV2iw@mail.gmail.com
    7c1f4261
libpq_pipeline.c 53.6 KB