Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit1ca695d

Browse files
committed
Fix another thinko in join_is_legal's handling of semijoins: we have to test
for the case that the semijoin was implemented within either input byunique-ifying its RHS before we test to see if it appears to match the currentjoin situation. The previous coding would select semijoin logic in situationswhere we'd already unique-ified the RHS and joined it to some unrelatedrelation(s), and then came to join it to the semijoin's LHS. That still gavethe right answer as far as the semijoin itself was concerned, but would leadto incorrectly examining only an arbitrary one of the matchable rows from theunrelated relation(s). The cause of this thinko was incorrect unification ofthe pre-8.4 logic for IN joins and OUTER joins --- the comparable case forouter joins can be handled after making the match test, but that's becausethere is nothing like the unique-ification escape hatch for outer joins.Per bug #4934 from Benjamin Reed.
1 parent00f0b47 commit1ca695d

File tree

1 file changed

+17
-10
lines changed

1 file changed

+17
-10
lines changed

‎src/backend/optimizer/path/joinrels.c

Lines changed: 17 additions & 10 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.101 2009/07/19 20:32:48 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/optimizer/path/joinrels.c,v 1.102 2009/07/23 17:42:06 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -399,6 +399,22 @@ join_is_legal(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2,
399399
bms_is_subset(sjinfo->min_righthand,rel2->relids))
400400
continue;
401401

402+
/*
403+
* If it's a semijoin and we already joined the RHS to any other
404+
* rels within either input, then we must have unique-ified the RHS
405+
* at that point (see below). Therefore the semijoin is no longer
406+
* relevant in this join path.
407+
*/
408+
if (sjinfo->jointype==JOIN_SEMI)
409+
{
410+
if (bms_is_subset(sjinfo->syn_righthand,rel1->relids)&&
411+
!bms_equal(sjinfo->syn_righthand,rel1->relids))
412+
continue;
413+
if (bms_is_subset(sjinfo->syn_righthand,rel2->relids)&&
414+
!bms_equal(sjinfo->syn_righthand,rel2->relids))
415+
continue;
416+
}
417+
402418
/*
403419
* If one input contains min_lefthand and the other contains
404420
* min_righthand, then we can perform the SJ at this join.
@@ -491,9 +507,6 @@ join_is_legal(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2,
491507
* We assume that make_outerjoininfo() set things up correctly
492508
* so that we'll only match to some SJ if the join is valid.
493509
* Set flag here to check at bottom of loop.
494-
*
495-
* For a semijoin, assume it's okay if either side fully contains
496-
* the RHS (per the unique-ification case above).
497510
*----------
498511
*/
499512
if (sjinfo->jointype!=JOIN_SEMI&&
@@ -503,12 +516,6 @@ join_is_legal(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2,
503516
/* seems OK */
504517
Assert(!bms_overlap(joinrelids,sjinfo->min_lefthand));
505518
}
506-
elseif (sjinfo->jointype==JOIN_SEMI&&
507-
(bms_is_subset(sjinfo->syn_righthand,rel1->relids)||
508-
bms_is_subset(sjinfo->syn_righthand,rel2->relids)))
509-
{
510-
/* seems OK */
511-
}
512519
else
513520
is_valid_inner= false;
514521
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp