88 *
99 *
1010 * IDENTIFICATION
11- * $PostgreSQL: pgsql/src/backend/optimizer/path/joinrels.c,v 1.65 2003/12/17 17:07:48 tgl Exp $
11+ * $PostgreSQL: pgsql/src/backend/optimizer/path/joinrels.c,v 1.66 2004/01/24 00:37:28 tgl Exp $
1212 *
1313 *-------------------------------------------------------------------------
1414 */
@@ -24,6 +24,7 @@ static List *make_rels_by_clause_joins(Query *root,
2424static List * make_rels_by_clauseless_joins (Query * root ,
2525RelOptInfo * old_rel ,
2626List * other_rels );
27+ static bool is_inside_IN (Query * root ,RelOptInfo * rel );
2728
2829
2930/*
@@ -76,14 +77,26 @@ make_rels_by_joins(Query *root, int level, List **joinrels)
7677/*
7778 * Note that if all available join clauses for this rel
7879 * require more than one other rel, we will fail to make any
79- * joins against it here. That's OK; it'll be considered by
80- * "bushy plan" join code in a higher-level pass where we have
81- * those other rels collected into a join rel.See also the
82- * last-ditch case below.
80+ * joins against it here. In most cases that's OK; it'll be
81+ * considered by "bushy plan" join code in a higher-level pass
82+ * where we have those other rels collected into a join rel.
8383 */
8484new_rels = make_rels_by_clause_joins (root ,
8585old_rel ,
8686other_rels );
87+ /*
88+ * An exception occurs when there is a clauseless join inside an
89+ * IN (sub-SELECT) construct. Here, the members of the subselect
90+ * all have join clauses (against the stuff outside the IN), but
91+ * they *must* be joined to each other before we can make use of
92+ * those join clauses. So do the clauseless join bit.
93+ *
94+ * See also the last-ditch case below.
95+ */
96+ if (new_rels == NIL && is_inside_IN (root ,old_rel ))
97+ new_rels = make_rels_by_clauseless_joins (root ,
98+ old_rel ,
99+ other_rels );
87100}
88101else
89102{
@@ -347,6 +360,29 @@ make_rels_by_clauseless_joins(Query *root,
347360}
348361
349362
363+ /*
364+ * is_inside_IN
365+ *Detect whether the specified relation is inside an IN (sub-SELECT).
366+ *
367+ * Note that we are actually only interested in rels that have been pulled up
368+ * out of an IN, so the routine name is a slight misnomer.
369+ */
370+ static bool
371+ is_inside_IN (Query * root ,RelOptInfo * rel )
372+ {
373+ List * i ;
374+
375+ foreach (i ,root -> in_info_list )
376+ {
377+ InClauseInfo * ininfo = (InClauseInfo * )lfirst (i );
378+
379+ if (bms_is_subset (rel -> relids ,ininfo -> righthand ))
380+ return true;
381+ }
382+ return false;
383+ }
384+
385+
350386/*
351387 * make_jointree_rel
352388 *Find or build a RelOptInfo join rel representing a specific