Skip to content

Commit 99e922a

Browse files
committed
Repair planner failure when there are multiple IN clauses, each with
a join in its subselect. In this situation we *must* build a bushy plan because there are no valid left-sided or right-sided join trees. Accordingly, hoary sanity check needs an update. Per report from Alessandro Depase.
1 parent 9dddd24 commit 99e922a

File tree

2 files changed

+22
-3
lines changed

2 files changed

+22
-3
lines changed

src/backend/optimizer/path/allpaths.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/optimizer/path/allpaths.c,v 1.109 2003/11/29 19:51:50 pgsql Exp $
11+
* $PostgreSQL: pgsql/src/backend/optimizer/path/allpaths.c,v 1.110 2003/12/17 17:07:48 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -545,6 +545,8 @@ make_one_rel_by_joins(Query *root, int levels_needed, List *initial_rels)
545545
/*
546546
* We should have a single rel at the final level.
547547
*/
548+
if (joinitems[levels_needed] == NIL)
549+
elog(ERROR, "failed to build any %d-way joins", levels_needed);
548550
Assert(length(joinitems[levels_needed]) == 1);
549551

550552
rel = (RelOptInfo *) lfirst(joinitems[levels_needed]);

src/backend/optimizer/path/joinrels.c

Lines changed: 19 additions & 2 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.64 2003/11/29 19:51:50 pgsql Exp $
11+
* $PostgreSQL: pgsql/src/backend/optimizer/path/joinrels.c,v 1.65 2003/12/17 17:07:48 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -226,7 +226,24 @@ make_rels_by_joins(Query *root, int level, List **joinrels)
226226
}
227227
}
228228

229-
if (result_rels == NIL)
229+
/*----------
230+
* When IN clauses are involved, there may be no legal way to make
231+
* an N-way join for some values of N. For example consider
232+
*
233+
* SELECT ... FROM t1 WHERE
234+
* x IN (SELECT ... FROM t2,t3 WHERE ...) AND
235+
* y IN (SELECT ... FROM t4,t5 WHERE ...)
236+
*
237+
* We will flatten this query to a 5-way join problem, but there are
238+
* no 4-way joins that make_join_rel() will consider legal. We have
239+
* to accept failure at level 4 and go on to discover a workable
240+
* bushy plan at level 5.
241+
*
242+
* However, if there are no IN clauses then make_join_rel() should
243+
* never fail, and so the following sanity check is useful.
244+
*----------
245+
*/
246+
if (result_rels == NIL && root->in_info_list == NIL)
230247
elog(ERROR, "failed to build any %d-way joins", level);
231248
}
232249

0 commit comments

Comments
 (0)