aboutsummaryrefslogtreecommitdiff
path: root/src/backend/optimizer/plan/setrefs.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2019-12-11 17:05:18 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2019-12-11 17:05:18 -0500
commit6ef77cf46e81f45716ec981cb08781d426181378 (patch)
tree39e28a070288a373431e396c3f92d3e9ebcf14a2 /src/backend/optimizer/plan/setrefs.c
parentba79cb5dc841104cf4810b5c23af4f881079dbb5 (diff)
downloadpostgresql-6ef77cf46e81f45716ec981cb08781d426181378.tar.gz
postgresql-6ef77cf46e81f45716ec981cb08781d426181378.zip
Further adjust EXPLAIN's choices of table alias names.
This patch causes EXPLAIN to always assign a separate table alias to the parent RTE of an append relation (inheritance set); before, such RTEs were ignored if not actually scanned by the plan. Since the child RTEs now always have that same alias to start with (cf. commit 55a1954da), the net effect is that the parent RTE usually gets the alias used or implied by the query text, and the children all get that alias with "_N" appended. (The exception to "usually" is if there are duplicate aliases in different subtrees of the original query; then some of those original RTEs will also have "_N" appended.) This results in more uniform output for partitioned-table plans than we had before: the partitioned table itself gets the original alias, and all child tables have aliases with "_N", rather than the previous behavior where one of the children would get an alias without "_N". The reason for giving the parent RTE an alias, even if it isn't scanned by the plan, is that we now use the parent's alias to qualify Vars that refer to an appendrel output column and appear above the Append or MergeAppend that computes the appendrel. But below the append, Vars refer to some one of the child relations, and are displayed that way. This seems clearer than the old behavior where a Var that could carry values from any child relation was displayed as if it referred to only one of them. While at it, change ruleutils.c so that the code paths used by EXPLAIN deal in Plan trees not PlanState trees. This effectively reverts a decision made in commit 1cc29fe7c, which seemed like a good idea at the time to make ruleutils.c consistent with explain.c. However, it's problematic because we'd really like to allow executor startup pruning to remove all the children of an append node when possible, leaving no child PlanState to resolve Vars against. (That's not done here, but will be in the next patch.) This requires different handling of subplans and initplans than before, but is otherwise a pretty straightforward change. Discussion: https://postgr.es/m/001001d4f44b$2a2cca50$7e865ef0$@lab.ntt.co.jp
Diffstat (limited to 'src/backend/optimizer/plan/setrefs.c')
-rw-r--r--src/backend/optimizer/plan/setrefs.c71
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.
*