• Etsuro Fujita's avatar
    postgres_fdw: Fix handling of pending asynchronous requests. · 1cf7fb37
    Etsuro Fujita authored
    A pending asynchronous request is handled by process_pending_request(),
    which previously not only processed an in-progress remote query but
    performed ExecForeignScan() to produce a tuple to return to the local
    server asynchronously from the result of the remote query.  But that led
    to a server crash when executing a query or led to an "InstrStartNode
    called twice in a row" or "InstrEndLoop called on running node" failure
    when doing EXPLAIN ANALYZE of it, in cases where the plan tree for it
    contained multiple async-capable nodes accessing the same
    initplan/subplan that contained multiple async-capable nodes scanning
    the same foreign tables as for the parent async-capable nodes, as
    reported by Andrey Lepikhov.  The reason is that the second step in
    process_pending_request() invoked when executing the initplan/subplan
    for one of the parent async-capable nodes caused recursive execution of
    the initplan/subplan for another of the parent async-capable nodes.
    
    To fix, split process_pending_request() into the two steps and postpone
    the second step until ForeignAsyncConfigureWait() is called for each of
    the pending asynchronous requests.  Also, in ExecAppendAsyncEventWait()
    we assumed that FDWs would register at least one wait event in a
    WaitEventSet created there when they were called from
    ForeignAsyncConfigureWait() in that function, but allow FDWs to register
    zero wait events in the WaitEventSet; modify ExecAppendAsyncEventWait()
    to just return in that case.
    
    Oversight in commit 27e1f145.  Back-patch to v14 where that commit went
    in.
    
    Andrey Lepikhov and Etsuro Fujita
    
    Discussion: https://postgr.es/m/fe5eaa19-1704-e4a4-76ee-3b9d37ade399@postgrespro.ru
    1cf7fb37
postgres_fdw.c 222 KB