diff --git a/src/backend/optimizer/path/joinrels.c b/src/backend/optimizer/path/joinrels.c index 2ad0b969d25..ea297db907d 100644 --- a/src/backend/optimizer/path/joinrels.c +++ b/src/backend/optimizer/path/joinrels.c @@ -169,61 +169,26 @@ join_search_one_level(PlannerInfo *root, int level) } } - /* - * Last-ditch effort: if we failed to find any usable joins so far, force - * a set of cartesian-product joins to be generated. This handles the - * special case where all the available rels have join clauses but we - * cannot use any of those clauses yet. An example is + /*---------- + * Normally, we should always have made at least one join of the current + * level. However, when special joins are involved, there may be no legal + * way to make an N-way join for some values of N. For example consider * - * SELECT * FROM a,b,c WHERE (a.f1 + b.f2 + c.f3) = 0; + * SELECT ... FROM t1 WHERE + * x IN (SELECT ... FROM t2,t3 WHERE ...) AND + * y IN (SELECT ... FROM t4,t5 WHERE ...) * - * The join clause will be usable at level 3, but at level 2 we have no - * choice but to make cartesian joins. We consider only left-sided and - * right-sided cartesian joins in this case (no bushy). + * We will flatten this query to a 5-way join problem, but there are + * no 4-way joins that join_is_legal() will consider legal. We have + * to accept failure at level 4 and go on to discover a workable + * bushy plan at level 5. + * + * However, if there are no special joins then join_is_legal() should + * never fail, and so the following sanity check is useful. + *---------- */ - if (joinrels[level] == NIL) - { - /* - * This loop is just like the first one, except we always call - * make_rels_by_clauseless_joins(). - */ - foreach(r, joinrels[level - 1]) - { - RelOptInfo *old_rel = (RelOptInfo *) lfirst(r); - ListCell *other_rels; - - if (level == 2) - other_rels = lnext(r); /* only consider remaining initial - * rels */ - else - other_rels = list_head(joinrels[1]); /* consider all initial - * rels */ - - make_rels_by_clauseless_joins(root, - old_rel, - other_rels); - } - - /*---------- - * When special joins are involved, there may be no legal way - * to make an N-way join for some values of N. For example consider - * - * SELECT ... FROM t1 WHERE - * x IN (SELECT ... FROM t2,t3 WHERE ...) AND - * y IN (SELECT ... FROM t4,t5 WHERE ...) - * - * We will flatten this query to a 5-way join problem, but there are - * no 4-way joins that join_is_legal() will consider legal. We have - * to accept failure at level 4 and go on to discover a workable - * bushy plan at level 5. - * - * However, if there are no special joins then join_is_legal() should - * never fail, and so the following sanity check is useful. - *---------- - */ - if (joinrels[level] == NIL && root->join_info_list == NIL) - elog(ERROR, "failed to build any %d-way joins", level); - } + if (joinrels[level] == NIL && root->join_info_list == NIL) + elog(ERROR, "failed to build any %d-way joins", level); } /* @@ -751,13 +716,6 @@ make_join_rel(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2) * could be merged with that function, but it seems clearer to separate the * two concerns. We need this test because there are degenerate cases where * a clauseless join must be performed to satisfy join-order restrictions. - * - * Note: this is only a problem if one side of a degenerate outer join - * contains multiple rels, or a clauseless join is required within an - * IN/EXISTS RHS; else we will find a join path via the "last ditch" case in - * join_search_one_level(). We could dispense with this test if we were - * willing to try bushy plans in the "last ditch" case, but that seems much - * less efficient. */ bool have_join_order_restriction(PlannerInfo *root,