diff options
Diffstat (limited to 'src/backend/optimizer/prep/prepjointree.c')
-rw-r--r-- | src/backend/optimizer/prep/prepjointree.c | 36 |
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) { |