Skip to content

Commit a8ed9bd

Browse files
author
Etsuro Fujita
committed
Fix oversight in commit 1ec7fca.
I failed to account for the possibility that when ExecAppendAsyncEventWait() notifies multiple async-capable nodes using postgres_fdw, a preceding node might invoke process_pending_request() to process a pending asynchronous request made by a succeeding node. In that case the succeeding node should produce a tuple to return to the parent Append node from tuples fetched by process_pending_request() when notified. Repair. Per buildfarm via Michael Paquier. Back-patch to v14, like the previous commit. Thanks to Tom Lane for testing. Discussion: https://postgr.es/m/YQP0UPT8KmPiHTMs%40paquier.xyz
1 parent eaf5321 commit a8ed9bd

File tree

2 files changed

+30
-14
lines changed

2 files changed

+30
-14
lines changed

contrib/postgres_fdw/postgres_fdw.c

+18-4
Original file line numberDiff line numberDiff line change
@@ -6896,12 +6896,26 @@ postgresForeignAsyncNotify(AsyncRequest *areq)
68966896
ForeignScanState *node = (ForeignScanState *) areq->requestee;
68976897
PgFdwScanState *fsstate = (PgFdwScanState *) node->fdw_state;
68986898

6899-
/* The request should be currently in-process */
6900-
Assert(fsstate->conn_state->pendingAreq == areq);
6901-
69026899
/* The core code would have initialized the callback_pending flag */
69036900
Assert(!areq->callback_pending);
69046901

6902+
/*
6903+
* If process_pending_request() has been invoked on the given request
6904+
* before we get here, we might have some tuples already; in which case
6905+
* produce the next tuple
6906+
*/
6907+
if (fsstate->next_tuple < fsstate->num_tuples)
6908+
{
6909+
produce_tuple_asynchronously(areq, true);
6910+
return;
6911+
}
6912+
6913+
/* We must have run out of tuples */
6914+
Assert(fsstate->next_tuple >= fsstate->num_tuples);
6915+
6916+
/* The request should be currently in-process */
6917+
Assert(fsstate->conn_state->pendingAreq == areq);
6918+
69056919
/* On error, report the original query, not the FETCH. */
69066920
if (!PQconsumeInput(fsstate->conn))
69076921
pgfdw_report_error(ERROR, NULL, fsstate->conn, false, fsstate->query);
@@ -7027,7 +7041,7 @@ process_pending_request(AsyncRequest *areq)
70277041
/*
70287042
* If we didn't get any tuples, must be end of data; complete the request
70297043
* now. Otherwise, we postpone completing the request until we are called
7030-
* from postgresForeignAsyncConfigureWait().
7044+
* from postgresForeignAsyncConfigureWait()/postgresForeignAsyncNotify().
70317045
*/
70327046
if (fsstate->next_tuple >= fsstate->num_tuples)
70337047
{

src/backend/executor/nodeAppend.c

+12-10
Original file line numberDiff line numberDiff line change
@@ -1082,16 +1082,18 @@ ExecAppendAsyncEventWait(AppendState *node)
10821082
{
10831083
AsyncRequest *areq = (AsyncRequest *) w->user_data;
10841084

1085-
/*
1086-
* Mark it as no longer needing a callback. We must do this
1087-
* before dispatching the callback in case the callback resets the
1088-
* flag.
1089-
*/
1090-
Assert(areq->callback_pending);
1091-
areq->callback_pending = false;
1092-
1093-
/* Do the actual work. */
1094-
ExecAsyncNotify(areq);
1085+
if (areq->callback_pending)
1086+
{
1087+
/*
1088+
* Mark it as no longer needing a callback. We must do this
1089+
* before dispatching the callback in case the callback resets
1090+
* the flag.
1091+
*/
1092+
areq->callback_pending = false;
1093+
1094+
/* Do the actual work. */
1095+
ExecAsyncNotify(areq);
1096+
}
10951097
}
10961098
}
10971099
}

0 commit comments

Comments
 (0)