Skip to content

Commit 233b8a9

Browse files
committed
Improve comments about semijoin implementation strategy, per a question
from Robert Haas.
1 parent 5717f3a commit 233b8a9

File tree

1 file changed

+24
-4
lines changed

1 file changed

+24
-4
lines changed

src/backend/optimizer/path/joinrels.c

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/optimizer/path/joinrels.c,v 1.97 2009/01/01 17:23:44 momjian Exp $
11+
* $PostgreSQL: pgsql/src/backend/optimizer/path/joinrels.c,v 1.98 2009/02/19 20:32:45 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -424,9 +424,27 @@ join_is_legal(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2,
424424
create_unique_path(root, rel2, rel2->cheapest_total_path,
425425
sjinfo) != NULL)
426426
{
427-
/*
427+
/*----------
428428
* For a semijoin, we can join the RHS to anything else by
429429
* unique-ifying the RHS (if the RHS can be unique-ified).
430+
* We will only get here if we have the full RHS but less
431+
* than min_lefthand on the LHS.
432+
*
433+
* The reason to consider such a join path is exemplified by
434+
* SELECT ... FROM a,b WHERE (a.x,b.y) IN (SELECT c1,c2 FROM c)
435+
* If we insist on doing this as a semijoin we will first have
436+
* to form the cartesian product of A*B. But if we unique-ify
437+
* C then the semijoin becomes a plain innerjoin and we can join
438+
* in any order, eg C to A and then to B. When C is much smaller
439+
* than A and B this can be a huge win. So we allow C to be
440+
* joined to just A or just B here, and then make_join_rel has
441+
* to handle the case properly.
442+
*
443+
* Note that actually we'll allow unique-ified C to be joined to
444+
* some other relation D here, too. That is legal, if usually not
445+
* very sane, and this routine is only concerned with legality not
446+
* with whether the join is good strategy.
447+
*----------
430448
*/
431449
if (match_sjinfo)
432450
return false; /* invalid join path */
@@ -648,8 +666,10 @@ make_join_rel(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2)
648666
break;
649667
case JOIN_SEMI:
650668
/*
651-
* Do these steps only if we actually have a regular semijoin,
652-
* as opposed to a case where we should unique-ify the RHS.
669+
* We might have a normal semijoin, or a case where we don't have
670+
* enough rels to do the semijoin but can unique-ify the RHS and
671+
* then do an innerjoin (see comments in join_is_legal). In the
672+
* latter case we can't apply JOIN_SEMI joining.
653673
*/
654674
if (bms_is_subset(sjinfo->min_lefthand, rel1->relids) &&
655675
bms_is_subset(sjinfo->min_righthand, rel2->relids))

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