summaryrefslogtreecommitdiff
path: root/src/backend/optimizer/plan/planmain.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2010-09-28 12:08:56 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2010-09-28 14:19:00 -0400
commiteb229505103eb5494c33832d422584bfdee03fc6 (patch)
treeca7c12732d170cb5abef8f108b2d95f508444b7c /src/backend/optimizer/plan/planmain.c
parent9c5f4f6cb50dd22028acc0b6f20291a5edcac62b (diff)
Fix PlaceHolderVar mechanism's interaction with outer joins.
The point of a PlaceHolderVar is to allow a non-strict expression to be evaluated below an outer join, after which its value bubbles up like a Var and can be forced to NULL when the outer join's semantics require that. However, there was a serious design oversight in that, namely that we didn't ensure that there was actually a correct place in the plan tree to evaluate the placeholder :-(. It may be necessary to delay evaluation of an outer join to ensure that a placeholder that should be evaluated below the join can be evaluated there. Per recent bug report from Kirill Simonov. Back-patch to 8.4 where the PlaceHolderVar mechanism was introduced.
Diffstat (limited to 'src/backend/optimizer/plan/planmain.c')
-rw-r--r--src/backend/optimizer/plan/planmain.c23
1 files changed, 15 insertions, 8 deletions
diff --git a/src/backend/optimizer/plan/planmain.c b/src/backend/optimizer/plan/planmain.c
index e82c3404b53..9e884cbb3cb 100644
--- a/src/backend/optimizer/plan/planmain.c
+++ b/src/backend/optimizer/plan/planmain.c
@@ -180,14 +180,19 @@ query_planner(PlannerInfo *root, List *tlist,
add_base_rels_to_query(root, (Node *) parse->jointree);
/*
- * Examine the targetlist and qualifications, adding entries to baserel
- * targetlists for all referenced Vars. Restrict and join clauses are
- * added to appropriate lists belonging to the mentioned relations. We
- * also build EquivalenceClasses for provably equivalent expressions, and
- * form a target joinlist for make_one_rel() to work from.
+ * Examine the targetlist and join tree, adding entries to baserel
+ * targetlists for all referenced Vars, and generating PlaceHolderInfo
+ * entries for all referenced PlaceHolderVars. Restrict and join clauses
+ * are added to appropriate lists belonging to the mentioned relations.
+ * We also build EquivalenceClasses for provably equivalent expressions.
+ * The SpecialJoinInfo list is also built to hold information about join
+ * order restrictions. Finally, we form a target joinlist for
+ * make_one_rel() to work from.
*/
build_base_rel_tlists(root, tlist);
+ find_placeholders_in_jointree(root);
+
joinlist = deconstruct_jointree(root);
/*
@@ -218,10 +223,12 @@ query_planner(PlannerInfo *root, List *tlist,
/*
* Examine any "placeholder" expressions generated during subquery pullup.
- * Make sure that we know what level to evaluate them at, and that the
- * Vars they need are marked as needed.
+ * Make sure that the Vars they need are marked as needed at the relevant
+ * join level. This must be done before join removal because it might
+ * cause Vars or placeholders to be needed above a join when they weren't
+ * so marked before.
*/
- fix_placeholder_eval_levels(root);
+ fix_placeholder_input_needed_levels(root);
/*
* Remove any useless outer joins. Ideally this would be done during