diff options
Diffstat (limited to 'src/backend/optimizer/plan/setrefs.c')
-rw-r--r-- | src/backend/optimizer/plan/setrefs.c | 71 |
1 files changed, 50 insertions, 21 deletions
diff --git a/src/backend/optimizer/plan/setrefs.c b/src/backend/optimizer/plan/setrefs.c index 566ee96da8c..f581c5f532c 100644 --- a/src/backend/optimizer/plan/setrefs.c +++ b/src/backend/optimizer/plan/setrefs.c @@ -108,6 +108,7 @@ static Plan *set_mergeappend_references(PlannerInfo *root, MergeAppend *mplan, int rtoffset); static void set_hash_references(PlannerInfo *root, Plan *plan, int rtoffset); +static Relids offset_relid_set(Relids relids, int rtoffset); static Node *fix_scan_expr(PlannerInfo *root, Node *node, int rtoffset); static Node *fix_scan_expr_mutator(Node *node, fix_scan_expr_context *context); static bool fix_scan_expr_walker(Node *node, fix_scan_expr_context *context); @@ -208,7 +209,8 @@ static List *set_returning_clause_references(PlannerInfo *root, * * The flattened rangetable entries are appended to root->glob->finalrtable. * Also, rowmarks entries are appended to root->glob->finalrowmarks, and the - * RT indexes of ModifyTable result relations to root->glob->resultRelations. + * RT indexes of ModifyTable result relations to root->glob->resultRelations, + * and flattened AppendRelInfos are appended to root->glob->appendRelations. * Plan dependencies are appended to root->glob->relationOids (for relations) * and root->glob->invalItems (for everything else). * @@ -250,6 +252,28 @@ set_plan_references(PlannerInfo *root, Plan *plan) glob->finalrowmarks = lappend(glob->finalrowmarks, newrc); } + /* + * Adjust RT indexes of AppendRelInfos and add to final appendrels list. + * We assume the AppendRelInfos were built during planning and don't need + * to be copied. + */ + foreach(lc, root->append_rel_list) + { + AppendRelInfo *appinfo = lfirst_node(AppendRelInfo, lc); + + /* adjust RT indexes */ + appinfo->parent_relid += rtoffset; + appinfo->child_relid += rtoffset; + + /* + * Rather than adjust the translated_vars entries, just drop 'em. + * Neither the executor nor EXPLAIN currently need that data. + */ + appinfo->translated_vars = NIL; + + glob->appendRelations = lappend(glob->appendRelations, appinfo); + } + /* Now fix the Plan tree */ return set_plan_refs(root, plan, rtoffset); } @@ -1215,16 +1239,7 @@ set_foreignscan_references(PlannerInfo *root, fix_scan_list(root, fscan->fdw_recheck_quals, rtoffset); } - /* Adjust fs_relids if needed */ - if (rtoffset > 0) - { - Bitmapset *tempset = NULL; - int x = -1; - - while ((x = bms_next_member(fscan->fs_relids, x)) >= 0) - tempset = bms_add_member(tempset, x + rtoffset); - fscan->fs_relids = tempset; - } + fscan->fs_relids = offset_relid_set(fscan->fs_relids, rtoffset); } /* @@ -1287,16 +1302,7 @@ set_customscan_references(PlannerInfo *root, lfirst(lc) = set_plan_refs(root, (Plan *) lfirst(lc), rtoffset); } - /* Adjust custom_relids if needed */ - if (rtoffset > 0) - { - Bitmapset *tempset = NULL; - int x = -1; - - while ((x = bms_next_member(cscan->custom_relids, x)) >= 0) - tempset = bms_add_member(tempset, x + rtoffset); - cscan->custom_relids = tempset; - } + cscan->custom_relids = offset_relid_set(cscan->custom_relids, rtoffset); } /* @@ -1338,6 +1344,8 @@ set_append_references(PlannerInfo *root, */ set_dummy_tlist_references((Plan *) aplan, rtoffset); + aplan->apprelids = offset_relid_set(aplan->apprelids, rtoffset); + if (aplan->part_prune_info) { foreach(l, aplan->part_prune_info->prune_infos) @@ -1400,6 +1408,8 @@ set_mergeappend_references(PlannerInfo *root, */ set_dummy_tlist_references((Plan *) mplan, rtoffset); + mplan->apprelids = offset_relid_set(mplan->apprelids, rtoffset); + if (mplan->part_prune_info) { foreach(l, mplan->part_prune_info->prune_infos) @@ -1455,6 +1465,25 @@ set_hash_references(PlannerInfo *root, Plan *plan, int rtoffset) } /* + * offset_relid_set + * Apply rtoffset to the members of a Relids set. + */ +static Relids +offset_relid_set(Relids relids, int rtoffset) +{ + Relids result = NULL; + int rtindex; + + /* If there's no offset to apply, we needn't recompute the value */ + if (rtoffset == 0) + return relids; + rtindex = -1; + while ((rtindex = bms_next_member(relids, rtindex)) >= 0) + result = bms_add_member(result, rtindex + rtoffset); + return result; +} + +/* * copyVar * Copy a Var node. * |