0001-Handle-interrupts-while-waiting-on-Append-s-async-su.patch
text/x-patch
Filename: 0001-Handle-interrupts-while-waiting-on-Append-s-async-su.patch
Type: text/x-patch
Part: 0
Patch
Format: format-patch
Series: patch 0001
Subject: Handle interrupts while waiting on Append's async subplans
| File | + | − |
|---|---|---|
| src/backend/executor/nodeAppend.c | 19 | 3 |
From 89b183622d4efbacce8027e8dd29336a7d3182b1 Mon Sep 17 00:00:00 2001
From: Heikki Linnakangas <heikki.linnakangas@iki.fi>
Date: Mon, 3 Mar 2025 17:11:06 +0200
Subject: [PATCH 1/1] Handle interrupts while waiting on Append's async
subplans
We did not wake up on interrupts while waiting on async events on an
async-capable append node. For example, if you tried to cancel the
query, nothing would happen until one of the async subplans becomes
readable. To fix, add WL_LATCH_SET to the WaitEventSet.
---
src/backend/executor/nodeAppend.c | 22 +++++++++++++++++++---
1 file changed, 19 insertions(+), 3 deletions(-)
diff --git a/src/backend/executor/nodeAppend.c b/src/backend/executor/nodeAppend.c
index ca0f54d676f..a03a23c18e4 100644
--- a/src/backend/executor/nodeAppend.c
+++ b/src/backend/executor/nodeAppend.c
@@ -326,6 +326,8 @@ ExecAppend(PlanState *pstate)
{
PlanState *subnode;
+ ResetLatch(MyLatch);
+
CHECK_FOR_INTERRUPTS();
/*
@@ -1016,7 +1018,7 @@ ExecAppendAsyncRequest(AppendState *node, TupleTableSlot **result)
static void
ExecAppendAsyncEventWait(AppendState *node)
{
- int nevents = node->as_nasyncplans + 1;
+ int nevents = node->as_nasyncplans + 2;
long timeout = node->as_syncdone ? -1 : 0;
WaitEvent occurred_event[EVENT_BUFFER_SIZE];
int noccurred;
@@ -1041,8 +1043,7 @@ ExecAppendAsyncEventWait(AppendState *node)
}
/*
- * No need for further processing if there are no configured events other
- * than the postmaster death event.
+ * No need for further processing if none of the subplans configured any events.
*/
if (GetNumRegisteredWaitEvents(node->as_eventset) == 1)
{
@@ -1051,6 +1052,21 @@ ExecAppendAsyncEventWait(AppendState *node)
return;
}
+ /*
+ * Add the latch to the set, so that we wake up to process the standard
+ * interrupts with CHECK_FOR_INTERRUPTS().
+ *
+ * NOTE: For historical reasons, it's important that this is added to the
+ * WaitEventSet after the ExecAsyncConfigureWait() calls. Namely,
+ * postgres_fdw calls "GetNumRegisteredWaitEvents(set) == 1" to check if
+ * any other events are in the set. That's a bad design, it's
+ * questionable for postgres_fdw to be doing that in the first place, but
+ * we cannot change it now. The pattern has possibly been copied to other
+ * extensions too.
+ */
+ AddWaitEventToSet(node->as_eventset, WL_LATCH_SET, PGINVALID_SOCKET,
+ MyLatch, NULL);
+
/* Return at most EVENT_BUFFER_SIZE events in one call. */
if (nevents > EVENT_BUFFER_SIZE)
nevents = EVENT_BUFFER_SIZE;
--
2.39.5