On Wed, Mar 29, 2023 at 3:39 AM Tom Lane <t...@sss.pgh.pa.us> wrote: > Alvaro Herrera <alvhe...@alvh.no-ip.org> writes: > > So I'm back home and found a couple more weird errors in the log: > > > ERROR: mismatching PartitionPruneInfo found at part_prune_index 0 > > DETALLE: plan node relids (b 1), pruneinfo relids (b 36) > > This one reproduces for me.
I've looked into this one and the attached patch fixes it for me. Turns out set_plan_refs()'s idea of when the entries from PlannerInfo.partPruneInfos are transferred into PlannerGlobal.partPruneInfo was wrong. Though, I wonder if we need to keep ec386948948 that introduced the notion of part_prune_index around if the project that needed it [1] has moved on to an entirely different approach altogether, one that doesn't require hacking up the pruning code. -- Thanks, Amit Langote EDB: http://www.enterprisedb.com [1] https://commitfest.postgresql.org/42/3478/
diff --git a/src/backend/optimizer/plan/setrefs.c b/src/backend/optimizer/plan/setrefs.c index 5cc8366af6..bd82960169 100644 --- a/src/backend/optimizer/plan/setrefs.c +++ b/src/backend/optimizer/plan/setrefs.c @@ -350,6 +350,29 @@ set_plan_references(PlannerInfo *root, Plan *plan) palloc0(list_length(glob->subplans) * sizeof(bool)); } + /* Also fix up the information in PartitionPruneInfos. */ + foreach(lc, root->partPruneInfos) + { + PartitionPruneInfo *pruneinfo = lfirst(lc); + ListCell *l; + + pruneinfo->root_parent_relids = + offset_relid_set(pruneinfo->root_parent_relids, rtoffset); + foreach(l, pruneinfo->prune_infos) + { + List *prune_infos = lfirst(l); + ListCell *l2; + + foreach(l2, prune_infos) + { + PartitionedRelPruneInfo *pinfo = lfirst(l2); + + /* RT index of the table to which the pinfo belongs. */ + pinfo->rtindex += rtoffset; + } + } + } + /* Now fix the Plan tree */ result = set_plan_refs(root, plan, rtoffset); @@ -378,31 +401,6 @@ set_plan_references(PlannerInfo *root, Plan *plan) } } - /* Also fix up the information in PartitionPruneInfos. */ - foreach(lc, root->partPruneInfos) - { - PartitionPruneInfo *pruneinfo = lfirst(lc); - ListCell *l; - - pruneinfo->root_parent_relids = - offset_relid_set(pruneinfo->root_parent_relids, rtoffset); - foreach(l, pruneinfo->prune_infos) - { - List *prune_infos = lfirst(l); - ListCell *l2; - - foreach(l2, prune_infos) - { - PartitionedRelPruneInfo *pinfo = lfirst(l2); - - /* RT index of the table to which the pinfo belongs. */ - pinfo->rtindex += rtoffset; - } - } - - glob->partPruneInfos = lappend(glob->partPruneInfos, pruneinfo); - } - return result; } @@ -1718,6 +1716,28 @@ set_customscan_references(PlannerInfo *root, cscan->custom_relids = offset_relid_set(cscan->custom_relids, rtoffset); } +/* + * fix_part_prune_index + * Adds the PartitionPruneInfo present in root->partPruneIndex at given + * index into the list in PlannerGlobal and returns the index in the new + * list. + */ +static int +fix_part_prune_index(int part_prune_index, PlannerInfo *root) +{ + PlannerGlobal *glob = root->glob; + PartitionPruneInfo *pruneinfo; + + Assert(part_prune_index >= 0 && + part_prune_index < list_length(root->partPruneInfos)); + pruneinfo = list_nth_node(PartitionPruneInfo, root->partPruneInfos, + part_prune_index); + + glob->partPruneInfos = lappend(glob->partPruneInfos, pruneinfo); + + return list_length(glob->partPruneInfos) - 1; +} + /* * set_append_references * Do set_plan_references processing on an Append @@ -1771,11 +1791,11 @@ set_append_references(PlannerInfo *root, aplan->apprelids = offset_relid_set(aplan->apprelids, rtoffset); /* - * PartitionPruneInfos will be added to a list in PlannerGlobal, so update - * the index. + * Add PartitionPruneInfo, if any, to PlannerGlobal and update the index. */ if (aplan->part_prune_index >= 0) - aplan->part_prune_index += list_length(root->glob->partPruneInfos); + aplan->part_prune_index = + fix_part_prune_index(aplan->part_prune_index, root); /* We don't need to recurse to lefttree or righttree ... */ Assert(aplan->plan.lefttree == NULL); @@ -1838,11 +1858,11 @@ set_mergeappend_references(PlannerInfo *root, mplan->apprelids = offset_relid_set(mplan->apprelids, rtoffset); /* - * PartitionPruneInfos will be added to a list in PlannerGlobal, so update - * the index. + * Add PartitionPruneInfo, if any, to PlannerGlobal and update the index. */ if (mplan->part_prune_index >= 0) - mplan->part_prune_index += list_length(root->glob->partPruneInfos); + mplan->part_prune_index = + fix_part_prune_index(mplan->part_prune_index, root); /* We don't need to recurse to lefttree or righttree ... */ Assert(mplan->plan.lefttree == NULL);