aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor/nodeAppend.c
diff options
context:
space:
mode:
authorEtsuro Fujita <efujita@postgresql.org>2021-06-07 12:45:00 +0900
committerEtsuro Fujita <efujita@postgresql.org>2021-06-07 12:45:00 +0900
commitf3baaf28a6da588987b94a05a725894805c3eae9 (patch)
tree75687ca3a9446c0335a3a849ca619e5208cfb5dc /src/backend/executor/nodeAppend.c
parenta65e9f3f1405b786673feec131879843432bf9a6 (diff)
downloadpostgresql-f3baaf28a6da588987b94a05a725894805c3eae9.tar.gz
postgresql-f3baaf28a6da588987b94a05a725894805c3eae9.zip
Fix rescanning of async-aware Append nodes.
In cases where run-time pruning isn't required, the synchronous and asynchronous subplans for an async-aware Append node determined using classify_matching_subplans() should be re-used when rescanning the node, but the previous code re-determined them using that function repeatedly each time when rescanning the node, leading to incorrect results in a normal build and an Assert failure in an Assert-enabled build as that function doesn't assume that it's called repeatedly in such cases. Fix the code as mentioned above. My oversight in commit 27e1f1456. While at it, initialize async-related pointers/variables to NULL/zero explicitly in ExecInitAppend() and ExecReScanAppend(), just to be sure. (The variables would have been set to zero before we get to the latter function, but let's do so.) Reviewed-by: Kyotaro Horiguchi Discussion: https://postgr.es/m/CAPmGK16Q4B2_KY%2BJH7rb7wQbw54AUprp7TMekGTd2T1B62yysQ%40mail.gmail.com
Diffstat (limited to 'src/backend/executor/nodeAppend.c')
-rw-r--r--src/backend/executor/nodeAppend.c27
1 files changed, 22 insertions, 5 deletions
diff --git a/src/backend/executor/nodeAppend.c b/src/backend/executor/nodeAppend.c
index 62335ed4c47..755c1392f09 100644
--- a/src/backend/executor/nodeAppend.c
+++ b/src/backend/executor/nodeAppend.c
@@ -240,10 +240,12 @@ ExecInitAppend(Append *node, EState *estate, int eflags)
appendstate->as_asyncplans = asyncplans;
appendstate->as_nasyncplans = nasyncplans;
appendstate->as_asyncrequests = NULL;
- appendstate->as_asyncresults = (TupleTableSlot **)
- palloc0(nasyncplans * sizeof(TupleTableSlot *));
+ appendstate->as_asyncresults = NULL;
+ appendstate->as_nasyncresults = 0;
+ appendstate->as_nasyncremain = 0;
appendstate->as_needrequest = NULL;
appendstate->as_eventset = NULL;
+ appendstate->as_valid_asyncplans = NULL;
if (nasyncplans > 0)
{
@@ -265,6 +267,12 @@ ExecInitAppend(Append *node, EState *estate, int eflags)
appendstate->as_asyncrequests[i] = areq;
}
+
+ appendstate->as_asyncresults = (TupleTableSlot **)
+ palloc0(nasyncplans * sizeof(TupleTableSlot *));
+
+ if (appendstate->as_valid_subplans != NULL)
+ classify_matching_subplans(appendstate);
}
/*
@@ -459,6 +467,8 @@ ExecReScanAppend(AppendState *node)
areq->result = NULL;
}
+ node->as_nasyncresults = 0;
+ node->as_nasyncremain = 0;
bms_free(node->as_needrequest);
node->as_needrequest = NULL;
}
@@ -861,15 +871,24 @@ ExecAppendAsyncBegin(AppendState *node)
/* Backward scan is not supported by async-aware Appends. */
Assert(ScanDirectionIsForward(node->ps.state->es_direction));
+ /* We should never be called when there are no subplans */
+ Assert(node->as_nplans > 0);
+
/* We should never be called when there are no async subplans. */
Assert(node->as_nasyncplans > 0);
/* If we've yet to determine the valid subplans then do so now. */
if (node->as_valid_subplans == NULL)
+ {
node->as_valid_subplans =
ExecFindMatchingSubPlans(node->as_prune_state);
- classify_matching_subplans(node);
+ classify_matching_subplans(node);
+ }
+
+ /* Initialize state variables. */
+ node->as_syncdone = bms_is_empty(node->as_valid_subplans);
+ node->as_nasyncremain = bms_num_members(node->as_valid_asyncplans);
/* Nothing to do if there are no valid async subplans. */
if (node->as_nasyncremain == 0)
@@ -1148,9 +1167,7 @@ classify_matching_subplans(AppendState *node)
/* Adjust the valid subplans to contain sync subplans only. */
node->as_valid_subplans = bms_del_members(node->as_valid_subplans,
valid_asyncplans);
- node->as_syncdone = bms_is_empty(node->as_valid_subplans);
/* Save valid async subplans. */
node->as_valid_asyncplans = valid_asyncplans;
- node->as_nasyncremain = bms_num_members(valid_asyncplans);
}