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

Lines changed: 5 additions & 5 deletions
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

Lines changed: 6 additions & 5 deletions
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy