mirror of
https://github.com/postgres/postgres.git
synced 2025-06-13 07:41:39 +03:00
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
This commit is contained in:
@ -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);
|
||||
}
|
||||
|
Reference in New Issue
Block a user