Hi Alexander,

On Sat, Jul 4, 2026 at 7:00 AM Alexander Korotkov <[email protected]> wrote:
> ExecReScanAppend() unconditionally resets callback_pending for all 
> AsyncRequests.  The problem is that postgres_fdw keeps its own knowledge for 
> the same fact: PgFdwConnState.pendingAreq – a pointer to "pending async 
> request" for a given connection.  That connection can be shared by several 
> partitions/foreign tables (postgres_fdw caches one connection per 
> server+usermapping pair). The blind reset in nodeAppend.c only touches the 
> local AsyncRequest.callback_pending; it never touches 
> PgFdwConnState.pendingAreq, which correctly points to the still-dangling 
> request.
>
> Later, when another partition sharing that same connection gets its own 
> ReScan (for instance, its chgParam changed because of the LATERAL parameter, 
> and it already has a cursor open), it sends "CLOSE cursor" via 
> pgfdw_exec_query().  Before sending any new command on the connection, that 
> function first drains whatever request is still outstanding on it:
>
> if (state && state->pendingAreq)
>     process_pending_request(state->pendingAreq);
>
> And process_pending_request() starts with:
>
> Assert(areq->callback_pending);
>
> – which fails, because the flag was corrupted some rounds earlier.
>
> The attached patch contains both the reproduction case and the fix.  The fix 
> postpones the reset of the callback_pending flag to ExecAppendAsyncBegin().  
> ExecAppendAsyncBegin() performs this cleanup along with ExecReScan(), which 
> completes the async fetch.

Interesting!  Thanks for the report and patch!  Will review.

Best regards,
Etsuro Fujita


Reply via email to