|
8 | 8 | *
|
9 | 9 | *
|
10 | 10 | * IDENTIFICATION
|
11 |
| - * $PostgreSQL: pgsql/src/backend/optimizer/path/joinrels.c,v 1.95 2008/11/22 22:47:06 tgl Exp $ |
| 11 | + * $PostgreSQL: pgsql/src/backend/optimizer/path/joinrels.c,v 1.96 2008/11/28 19:29:07 tgl Exp $ |
12 | 12 | *
|
13 | 13 | *-------------------------------------------------------------------------
|
14 | 14 | */
|
@@ -420,19 +420,23 @@ join_is_legal(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2,
|
420 | 420 | reversed = true;
|
421 | 421 | }
|
422 | 422 | else if (sjinfo->jointype == JOIN_SEMI &&
|
423 |
| - bms_equal(sjinfo->syn_righthand, rel2->relids)) |
| 423 | + bms_equal(sjinfo->syn_righthand, rel2->relids) && |
| 424 | + create_unique_path(root, rel2, rel2->cheapest_total_path, |
| 425 | + sjinfo) != NULL) |
424 | 426 | {
|
425 | 427 | /*
|
426 | 428 | * For a semijoin, we can join the RHS to anything else by
|
427 |
| - * unique-ifying the RHS. |
| 429 | + * unique-ifying the RHS (if the RHS can be unique-ified). |
428 | 430 | */
|
429 | 431 | if (match_sjinfo)
|
430 | 432 | return false; /* invalid join path */
|
431 | 433 | match_sjinfo = sjinfo;
|
432 | 434 | reversed = false;
|
433 | 435 | }
|
434 | 436 | else if (sjinfo->jointype == JOIN_SEMI &&
|
435 |
| - bms_equal(sjinfo->syn_righthand, rel1->relids)) |
| 437 | + bms_equal(sjinfo->syn_righthand, rel1->relids) && |
| 438 | + create_unique_path(root, rel1, rel1->cheapest_total_path, |
| 439 | + sjinfo) != NULL) |
436 | 440 | {
|
437 | 441 | /* Reversed semijoin case */
|
438 | 442 | if (match_sjinfo)
|
@@ -664,7 +668,10 @@ make_join_rel(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2)
|
664 | 668 | /*
|
665 | 669 | * If we know how to unique-ify the RHS and one input rel is
|
666 | 670 | * exactly the RHS (not a superset) we can consider unique-ifying
|
667 |
| - * it and then doing a regular join. |
| 671 | + * it and then doing a regular join. (The create_unique_path |
| 672 | + * check here is probably redundant with what join_is_legal did, |
| 673 | + * but if so the check is cheap because it's cached. So test |
| 674 | + * anyway to be sure.) |
668 | 675 | */
|
669 | 676 | if (bms_equal(sjinfo->syn_righthand, rel2->relids) &&
|
670 | 677 | create_unique_path(root, rel2, rel2->cheapest_total_path,
|
|
0 commit comments