|
8 | 8 | *
|
9 | 9 | *
|
10 | 10 | * IDENTIFICATION
|
11 |
| - * $PostgreSQL: pgsql/src/backend/optimizer/path/joinrels.c,v 1.66 2004/01/24 00:37:28 tgl Exp $ |
| 11 | + * $PostgreSQL: pgsql/src/backend/optimizer/path/joinrels.c,v 1.67 2004/03/08 17:20:17 tgl Exp $ |
12 | 12 | *
|
13 | 13 | *-------------------------------------------------------------------------
|
14 | 14 | */
|
@@ -483,35 +483,45 @@ make_join_rel(Query *root, RelOptInfo *rel1, RelOptInfo *rel2,
|
483 | 483 | InClauseInfo*ininfo= (InClauseInfo*)lfirst(l);
|
484 | 484 |
|
485 | 485 | /*
|
486 |
| - * Cannot join if proposed join contains part, but only part, |
487 |
| - * of the RHS, *and* it contains rels not in the RHS. |
| 486 | + * This IN clause is not relevant unless its RHS overlaps the |
| 487 | + * proposed join. (Check this first as a fast path for dismissing |
| 488 | + * most irrelevant INs quickly.) |
488 | 489 | */
|
489 |
| -if (bms_overlap(ininfo->righthand,joinrelids)&& |
490 |
| -!bms_is_subset(ininfo->righthand,joinrelids)&& |
491 |
| -!bms_is_subset(joinrelids,ininfo->righthand)) |
492 |
| -{ |
493 |
| -bms_free(joinrelids); |
494 |
| -returnNULL; |
495 |
| -} |
| 490 | +if (!bms_overlap(ininfo->righthand,joinrelids)) |
| 491 | +continue; |
496 | 492 |
|
497 | 493 | /*
|
498 |
| - *No issue unlesswe arelooking at a join ofthe IN's RHS to |
499 |
| - *other stuff. |
| 494 | + *Ifwe arestill buildingthe IN clause's RHS, then this IN |
| 495 | + *clause isn't relevant yet. |
500 | 496 | */
|
501 |
| -if (!(bms_is_subset(ininfo->righthand,joinrelids)&& |
502 |
| - !bms_equal(ininfo->righthand,joinrelids))) |
| 497 | +if (bms_is_subset(joinrelids,ininfo->righthand)) |
503 | 498 | continue;
|
504 | 499 |
|
505 | 500 | /*
|
506 |
| - * If we already joined IN's RHS to any part of its LHS in |
507 |
| - * either input path, then this join is not constrained (the |
508 |
| - * necessary work was done at a lower level). |
| 501 | + * Cannot join if proposed join contains rels not in the RHS |
| 502 | + * *and* contains only part of the RHS. We must build the |
| 503 | + * complete RHS (subselect's join) before it can be joined to |
| 504 | + * rels outside the subselect. |
| 505 | + */ |
| 506 | +if (!bms_is_subset(ininfo->righthand,joinrelids)) |
| 507 | +{ |
| 508 | +bms_free(joinrelids); |
| 509 | +returnNULL; |
| 510 | +} |
| 511 | + |
| 512 | +/* |
| 513 | + * At this point we are considering a join of the IN's RHS to |
| 514 | + * some other rel(s). |
| 515 | + * |
| 516 | + * If we already joined IN's RHS to any other rels in either |
| 517 | + * input path, then this join is not constrained (the necessary |
| 518 | + * work was done at the lower level where that join occurred). |
509 | 519 | */
|
510 |
| -if (bms_overlap(ininfo->lefthand,rel1->relids)&& |
511 |
| -bms_is_subset(ininfo->righthand,rel1->relids)) |
| 520 | +if (bms_is_subset(ininfo->righthand,rel1->relids)&& |
| 521 | +!bms_equal(ininfo->righthand,rel1->relids)) |
512 | 522 | continue;
|
513 |
| -if (bms_overlap(ininfo->lefthand,rel2->relids)&& |
514 |
| -bms_is_subset(ininfo->righthand,rel2->relids)) |
| 523 | +if (bms_is_subset(ininfo->righthand,rel2->relids)&& |
| 524 | +!bms_equal(ininfo->righthand,rel2->relids)) |
515 | 525 | continue;
|
516 | 526 |
|
517 | 527 | /*
|
|