diff options
author | Etsuro Fujita <efujita@postgresql.org> | 2021-06-07 12:45:00 +0900 |
---|---|---|
committer | Etsuro Fujita <efujita@postgresql.org> | 2021-06-07 12:45:00 +0900 |
commit | f3baaf28a6da588987b94a05a725894805c3eae9 (patch) | |
tree | 75687ca3a9446c0335a3a849ca619e5208cfb5dc /src/backend/executor/nodeAppend.c | |
parent | a65e9f3f1405b786673feec131879843432bf9a6 (diff) | |
download | postgresql-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.c | 27 |
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); } |