aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/optimizer/path/joinrels.c76
1 files changed, 17 insertions, 59 deletions
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 t1 WHERE
+ * x IN (SELECT ... FROM t2,t3 WHERE ...) AND
+ * y IN (SELECT ... FROM t4,t5 WHERE ...)
*
- * SELECT * FROM a,b,c WHERE (a.f1 + b.f2 + c.f3) = 0;
+ * 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.
*
- * 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).
+ * 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,