diff --git a/src/backend/optimizer/README b/src/backend/optimizer/README index a3ce21b690..f406e642db 100644 --- a/src/backend/optimizer/README +++ b/src/backend/optimizer/README @@ -1,4 +1,4 @@ -$PostgreSQL: pgsql/src/backend/optimizer/README,v 1.49 2009/02/27 22:41:37 tgl Exp $ +$PostgreSQL: pgsql/src/backend/optimizer/README,v 1.50 2009/07/21 02:02:44 tgl Exp $ Optimizer ========= @@ -214,10 +214,10 @@ out of the nullable side of an outer join: != (A leftjoin B on (Pab)) join C on (Pbc) SEMI joins work a little bit differently. A semijoin can be reassociated -into or out of the lefthand side of another semijoin, but not into or out -of the righthand side. Likewise, an inner join, left join, or antijoin -can be reassociated into or out of the lefthand side of a semijoin, but -not into or out of the righthand side. +into or out of the lefthand side of another semijoin, left join, or +antijoin, but not into or out of the righthand side. Likewise, an inner +join, left join, or antijoin can be reassociated into or out of the +lefthand side of a semijoin, but not into or out of the righthand side. ANTI joins work approximately like LEFT joins, except that identity 3 fails if the join to C is an antijoin (even if Pbc is strict, and in diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c index 8a189d4443..9ea928ed9d 100644 --- a/src/backend/optimizer/plan/initsplan.c +++ b/src/backend/optimizer/plan/initsplan.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/optimizer/plan/initsplan.c,v 1.154 2009/06/11 14:48:59 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/optimizer/plan/initsplan.c,v 1.155 2009/07/21 02:02:44 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -630,8 +630,8 @@ make_outerjoininfo(PlannerInfo *root, * min_lefthand + min_righthand. This is because there might be other * OJs below this one that this one can commute with, but we cannot * commute with them if we don't with this one.) Also, if the current - * join is an antijoin, we must preserve ordering regardless of - * strictness. + * join is a semijoin or antijoin, we must preserve ordering + * regardless of strictness. * * Note: I believe we have to insist on being strict for at least one * rel in the lower OJ's min_righthand, not its whole syn_righthand. @@ -639,7 +639,7 @@ make_outerjoininfo(PlannerInfo *root, if (bms_overlap(left_rels, otherinfo->syn_righthand)) { if (bms_overlap(clause_relids, otherinfo->syn_righthand) && - (jointype == JOIN_ANTI || + (jointype == JOIN_SEMI || jointype == JOIN_ANTI || !bms_overlap(strict_relids, otherinfo->min_righthand))) { min_lefthand = bms_add_members(min_lefthand, @@ -655,7 +655,7 @@ make_outerjoininfo(PlannerInfo *root, * 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 an antijoin. + * 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 @@ -672,6 +672,7 @@ make_outerjoininfo(PlannerInfo *root, { if (bms_overlap(clause_relids, otherinfo->syn_righthand) || jointype == JOIN_SEMI || + otherinfo->jointype == JOIN_SEMI || otherinfo->jointype == JOIN_ANTI || !otherinfo->lhs_strict || otherinfo->delay_upper_joins) {