Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit b2c51e6

Browse files
committed
Fix another semijoin-ordering bug. We already knew that we couldn't
reorder a semijoin into or out of the righthand side of another semijoin, but actually it doesn't work to reorder it into or out of the righthand side of a left or antijoin, either. Per bug #4906 from Mathieu Fenniak. This was sloppy thinking on my part. This identity does work: ( A left join B on (Pab) ) semijoin C on (Pac) == ( A semijoin C on (Pac) ) left join B on (Pab) but I failed to see that that doesn't mean this does: ( A left join B on (Pab) ) semijoin C on (Pbc) != A left join ( B semijoin C on (Pbc) ) on (Pab)
1 parent 4e03b82 commit b2c51e6

File tree

2 files changed

+11
-10
lines changed

2 files changed

+11
-10
lines changed

src/backend/optimizer/README

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
$PostgreSQL: pgsql/src/backend/optimizer/README,v 1.49 2009/02/27 22:41:37 tgl Exp $
1+
$PostgreSQL: pgsql/src/backend/optimizer/README,v 1.50 2009/07/21 02:02:44 tgl Exp $
22

33
Optimizer
44
=========
@@ -214,10 +214,10 @@ out of the nullable side of an outer join:
214214
!= (A leftjoin B on (Pab)) join C on (Pbc)
215215

216216
SEMI joins work a little bit differently. A semijoin can be reassociated
217-
into or out of the lefthand side of another semijoin, but not into or out
218-
of the righthand side. Likewise, an inner join, left join, or antijoin
219-
can be reassociated into or out of the lefthand side of a semijoin, but
220-
not into or out of the righthand side.
217+
into or out of the lefthand side of another semijoin, left join, or
218+
antijoin, but not into or out of the righthand side. Likewise, an inner
219+
join, left join, or antijoin can be reassociated into or out of the
220+
lefthand side of a semijoin, but not into or out of the righthand side.
221221

222222
ANTI joins work approximately like LEFT joins, except that identity 3
223223
fails if the join to C is an antijoin (even if Pbc is strict, and in

src/backend/optimizer/plan/initsplan.c

+6-5
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/optimizer/plan/initsplan.c,v 1.154 2009/06/11 14:48:59 momjian Exp $
11+
* $PostgreSQL: pgsql/src/backend/optimizer/plan/initsplan.c,v 1.155 2009/07/21 02:02:44 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -630,16 +630,16 @@ make_outerjoininfo(PlannerInfo *root,
630630
* min_lefthand + min_righthand. This is because there might be other
631631
* OJs below this one that this one can commute with, but we cannot
632632
* commute with them if we don't with this one.) Also, if the current
633-
* join is an antijoin, we must preserve ordering regardless of
634-
* strictness.
633+
* join is a semijoin or antijoin, we must preserve ordering
634+
* regardless of strictness.
635635
*
636636
* Note: I believe we have to insist on being strict for at least one
637637
* rel in the lower OJ's min_righthand, not its whole syn_righthand.
638638
*/
639639
if (bms_overlap(left_rels, otherinfo->syn_righthand))
640640
{
641641
if (bms_overlap(clause_relids, otherinfo->syn_righthand) &&
642-
(jointype == JOIN_ANTI ||
642+
(jointype == JOIN_SEMI || jointype == JOIN_ANTI ||
643643
!bms_overlap(strict_relids, otherinfo->min_righthand)))
644644
{
645645
min_lefthand = bms_add_members(min_lefthand,
@@ -655,7 +655,7 @@ make_outerjoininfo(PlannerInfo *root,
655655
* can interchange the ordering of the two OJs; otherwise we must add
656656
* lower OJ's full syntactic relset to min_righthand. Here, we must
657657
* preserve ordering anyway if either the current join is a semijoin,
658-
* or the lower OJ is an antijoin.
658+
* or the lower OJ is either a semijoin or an antijoin.
659659
*
660660
* Here, we have to consider that "our join condition" includes any
661661
* clauses that syntactically appeared above the lower OJ and below
@@ -672,6 +672,7 @@ make_outerjoininfo(PlannerInfo *root,
672672
{
673673
if (bms_overlap(clause_relids, otherinfo->syn_righthand) ||
674674
jointype == JOIN_SEMI ||
675+
otherinfo->jointype == JOIN_SEMI ||
675676
otherinfo->jointype == JOIN_ANTI ||
676677
!otherinfo->lhs_strict || otherinfo->delay_upper_joins)
677678
{

0 commit comments

Comments
 (0)