summaryrefslogtreecommitdiff
path: root/src/backend/optimizer/prep/prepjointree.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/optimizer/prep/prepjointree.c')
-rw-r--r--src/backend/optimizer/prep/prepjointree.c36
1 files changed, 13 insertions, 23 deletions
diff --git a/src/backend/optimizer/prep/prepjointree.c b/src/backend/optimizer/prep/prepjointree.c
index 59a52687f9d..2fd795b4592 100644
--- a/src/backend/optimizer/prep/prepjointree.c
+++ b/src/backend/optimizer/prep/prepjointree.c
@@ -866,15 +866,22 @@ pull_up_simple_subquery(PlannerInfo *root, Node *jtnode, RangeTblEntry *rte,
parse->havingQual = pullup_replace_vars(parse->havingQual, &rvcontext);
/*
- * Replace references in the translated_vars lists of appendrels, too.
- * We do it this way because we must preserve the AppendRelInfo structs.
+ * Replace references in the translated_vars lists of appendrels. When
+ * pulling up an appendrel member, we do not need PHVs in the list of the
+ * parent appendrel --- there isn't any outer join between. Elsewhere, use
+ * PHVs for safety. (This analysis could be made tighter but it seems
+ * unlikely to be worth much trouble.)
*/
foreach(lc, root->append_rel_list)
{
AppendRelInfo *appinfo = (AppendRelInfo *) lfirst(lc);
+ bool save_need_phvs = rvcontext.need_phvs;
+ if (appinfo == containing_appendrel)
+ rvcontext.need_phvs = false;
appinfo->translated_vars = (List *)
pullup_replace_vars((Node *) appinfo->translated_vars, &rvcontext);
+ rvcontext.need_phvs = save_need_phvs;
}
/*
@@ -1482,31 +1489,14 @@ pullup_replace_vars_callback(Var *var,
if (newnode && IsA(newnode, Var) &&
((Var *) newnode)->varlevelsup == 0)
{
- /*
- * Simple Vars normally escape being wrapped. However, in
- * wrap_non_vars mode (ie, we are dealing with an appendrel
- * member), we must ensure that each tlist entry expands to a
- * distinct expression, else we may have problems with
- * improperly placing identical entries into different
- * EquivalenceClasses. Therefore, we wrap a Var in a
- * PlaceHolderVar if it duplicates any earlier entry in the
- * tlist (ie, we've got "SELECT x, x, ..."). Since each PHV
- * is distinct, this fixes the ambiguity. We can use
- * tlist_member to detect whether there's an earlier
- * duplicate.
- */
- wrap = (rcon->wrap_non_vars &&
- tlist_member(newnode, rcon->targetlist) != tle);
+ /* Simple Vars always escape being wrapped */
+ wrap = false;
}
else if (newnode && IsA(newnode, PlaceHolderVar) &&
((PlaceHolderVar *) newnode)->phlevelsup == 0)
{
- /*
- * No need to directly wrap a PlaceHolderVar with another one,
- * either, unless we need to prevent duplication.
- */
- wrap = (rcon->wrap_non_vars &&
- tlist_member(newnode, rcon->targetlist) != tle);
+ /* No need to wrap a PlaceHolderVar with another one, either */
+ wrap = false;
}
else if (rcon->wrap_non_vars)
{