summaryrefslogtreecommitdiff
path: root/src/backend/optimizer
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2015-04-25 16:44:27 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2015-04-25 16:44:27 -0400
commit5f3d1909c58aee1911d4b1e7f643bb8db09e8da6 (patch)
treeebca6af166d390dc7fb68485632a7088145fd90a /src/backend/optimizer
parent0a5570e3684adeb50c06e197e59dff9f829e67e6 (diff)
Prevent improper reordering of antijoins vs. outer joins.
An outer join appearing within the RHS of an antijoin can't commute with the antijoin, but somehow I missed teaching make_outerjoininfo() about that. In Teodor Sigaev's recent trouble report, this manifests as a "could not find RelOptInfo for given relids" error within eqjoinsel(); but I think silently wrong query results are possible too, if the planner misorders the joins and doesn't happen to trigger any internal consistency checks. It's broken as far back as we had antijoins, so back-patch to all supported branches.
Diffstat (limited to 'src/backend/optimizer')
-rw-r--r--src/backend/optimizer/plan/initsplan.c7
1 files changed, 4 insertions, 3 deletions
diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c
index f88e493edb8..9fa729666f3 100644
--- a/src/backend/optimizer/plan/initsplan.c
+++ b/src/backend/optimizer/plan/initsplan.c
@@ -1162,9 +1162,9 @@ make_outerjoininfo(PlannerInfo *root,
* For a lower OJ in our RHS, if our join condition does not use the
* lower join's RHS and the lower OJ's join condition is strict, we
* can interchange the ordering of the two OJs; otherwise we must add
- * lower OJ's full syntactic relset to min_righthand. Here, we must
- * preserve ordering anyway if either the current join is a semijoin,
- * or the lower OJ is either a semijoin or an antijoin.
+ * the lower OJ's full syntactic relset to min_righthand. Also, we
+ * must preserve ordering anyway if either the current join or the
+ * lower OJ is either a semijoin or an antijoin.
*
* Here, we have to consider that "our join condition" includes any
* clauses that syntactically appeared above the lower OJ and below
@@ -1181,6 +1181,7 @@ make_outerjoininfo(PlannerInfo *root,
{
if (bms_overlap(clause_relids, otherinfo->syn_righthand) ||
jointype == JOIN_SEMI ||
+ jointype == JOIN_ANTI ||
otherinfo->jointype == JOIN_SEMI ||
otherinfo->jointype == JOIN_ANTI ||
!otherinfo->lhs_strict || otherinfo->delay_upper_joins)