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
