mirror of
https://github.com/postgres/postgres.git
synced 2025-04-24 10:47:04 +03:00
Improve ExecFindInitialMatchingSubPlans's subplan renumbering logic.
We don't need two passes if we scan child partitions before parents, as that way the children's present_parts are up to date before they're needed. I (tgl) think there's actually a bug being fixed here, for the case of an intermediate partitioned table with no direct leaf children, but haven't attempted to construct a test case to prove it. David Rowley Discussion: https://postgr.es/m/CAKJS1f-6GODRNgEtdPxCnAPme2h2hTztB6LmtfdmcYAAOE0kQg@mail.gmail.com
This commit is contained in:
parent
4e23236403
commit
69025c5a07
@ -1442,8 +1442,8 @@ ExecSetupPartitionPruneState(PlanState *planstate, List *partitionpruneinfo)
|
|||||||
int n_steps;
|
int n_steps;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We must make a copy of this rather than pointing directly to the
|
* We must copy the subplan_map rather than pointing directly to the
|
||||||
* plan's version as we may end up making modifications to it later.
|
* plan's version, as we may end up making modifications to it later.
|
||||||
*/
|
*/
|
||||||
pprune->subplan_map = palloc(sizeof(int) * pinfo->nparts);
|
pprune->subplan_map = palloc(sizeof(int) * pinfo->nparts);
|
||||||
memcpy(pprune->subplan_map, pinfo->subplan_map,
|
memcpy(pprune->subplan_map, pinfo->subplan_map,
|
||||||
@ -1589,8 +1589,8 @@ ExecFindInitialMatchingSubPlans(PartitionPruneState *prunestate, int nsubplans)
|
|||||||
int newidx;
|
int newidx;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* First we must build an array which we can use to adjust the
|
* First we must build a temporary array which maps old subplan
|
||||||
* existing subplan_map so that it contains the new subplan indexes.
|
* indexes to new ones.
|
||||||
*/
|
*/
|
||||||
new_subplan_indexes = (int *) palloc(sizeof(int) * nsubplans);
|
new_subplan_indexes = (int *) palloc(sizeof(int) * nsubplans);
|
||||||
newidx = 0;
|
newidx = 0;
|
||||||
@ -1603,79 +1603,55 @@ ExecFindInitialMatchingSubPlans(PartitionPruneState *prunestate, int nsubplans)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Now we can re-sequence each PartitionPruneInfo's subplan_map so
|
* Now we can update each PartitionPruneInfo's subplan_map with new
|
||||||
* that they point to the new index of the subplan.
|
* subplan indexes. We must also recompute its present_parts bitmap.
|
||||||
|
* We perform this loop in back-to-front order so that we determine
|
||||||
|
* present_parts for the lowest-level partitioned tables first. This
|
||||||
|
* way we can tell whether a sub-partitioned table's partitions were
|
||||||
|
* entirely pruned so we can exclude that from 'present_parts'.
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < prunestate->num_partprunedata; i++)
|
for (i = prunestate->num_partprunedata - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
int nparts;
|
int nparts;
|
||||||
int j;
|
int j;
|
||||||
|
|
||||||
pprune = &prunestate->partprunedata[i];
|
pprune = &prunestate->partprunedata[i];
|
||||||
nparts = pprune->context.nparts;
|
nparts = pprune->context.nparts;
|
||||||
|
/* We just rebuild present_parts from scratch */
|
||||||
/*
|
|
||||||
* We also need to reset the present_parts field so that it only
|
|
||||||
* contains partition indexes that we actually still have subplans
|
|
||||||
* for. It seems easier to build a fresh one, rather than trying
|
|
||||||
* to update the existing one.
|
|
||||||
*/
|
|
||||||
bms_free(pprune->present_parts);
|
bms_free(pprune->present_parts);
|
||||||
pprune->present_parts = NULL;
|
pprune->present_parts = NULL;
|
||||||
|
|
||||||
for (j = 0; j < nparts; j++)
|
for (j = 0; j < nparts; j++)
|
||||||
{
|
{
|
||||||
int oldidx = pprune->subplan_map[j];
|
int oldidx = pprune->subplan_map[j];
|
||||||
|
int subidx;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If this partition existed as a subplan then change the old
|
* If this partition existed as a subplan then change the old
|
||||||
* subplan index to the new subplan index. The new index may
|
* subplan index to the new subplan index. The new index may
|
||||||
* become -1 if the partition was pruned above, or it may just
|
* become -1 if the partition was pruned above, or it may just
|
||||||
* come earlier in the subplan list due to some subplans being
|
* come earlier in the subplan list due to some subplans being
|
||||||
* removed earlier in the list.
|
* removed earlier in the list. If it's a subpartition, add
|
||||||
|
* it to present_parts unless it's entirely pruned.
|
||||||
*/
|
*/
|
||||||
if (oldidx >= 0)
|
if (oldidx >= 0)
|
||||||
{
|
{
|
||||||
|
Assert(oldidx < nsubplans);
|
||||||
pprune->subplan_map[j] = new_subplan_indexes[oldidx];
|
pprune->subplan_map[j] = new_subplan_indexes[oldidx];
|
||||||
|
|
||||||
if (new_subplan_indexes[oldidx] >= 0)
|
if (new_subplan_indexes[oldidx] >= 0)
|
||||||
pprune->present_parts =
|
pprune->present_parts =
|
||||||
bms_add_member(pprune->present_parts, j);
|
bms_add_member(pprune->present_parts, j);
|
||||||
}
|
}
|
||||||
}
|
else if ((subidx = pprune->subpart_map[j]) >= 0)
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Now we must determine which sub-partitioned tables still have
|
|
||||||
* unpruned partitions. The easiest way to do this is to simply loop
|
|
||||||
* over each PartitionPruningData again checking if there are any
|
|
||||||
* 'present_parts' in the sub-partitioned table. We needn't bother
|
|
||||||
* doing this if there are no sub-partitioned tables.
|
|
||||||
*/
|
|
||||||
if (prunestate->num_partprunedata > 1)
|
|
||||||
{
|
|
||||||
for (i = 0; i < prunestate->num_partprunedata; i++)
|
|
||||||
{
|
|
||||||
int nparts;
|
|
||||||
int j;
|
|
||||||
|
|
||||||
pprune = &prunestate->partprunedata[i];
|
|
||||||
nparts = pprune->context.nparts;
|
|
||||||
|
|
||||||
for (j = 0; j < nparts; j++)
|
|
||||||
{
|
{
|
||||||
int subidx = pprune->subpart_map[j];
|
PartitionPruningData *subprune;
|
||||||
|
|
||||||
if (subidx >= 0)
|
subprune = &prunestate->partprunedata[subidx];
|
||||||
{
|
|
||||||
PartitionPruningData *subprune;
|
|
||||||
|
|
||||||
subprune = &prunestate->partprunedata[subidx];
|
if (!bms_is_empty(subprune->present_parts))
|
||||||
|
pprune->present_parts =
|
||||||
if (!bms_is_empty(subprune->present_parts))
|
bms_add_member(pprune->present_parts, j);
|
||||||
pprune->present_parts =
|
|
||||||
bms_add_member(pprune->present_parts, j);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user