|
8 | 8 | *
|
9 | 9 | *
|
10 | 10 | * IDENTIFICATION
|
11 |
| - * $Header: /cvsroot/pgsql/src/backend/optimizer/path/joinrels.c,v 1.44 2000/04/12 17:15:20 momjian Exp $ |
| 11 | + * $Header: /cvsroot/pgsql/src/backend/optimizer/path/joinrels.c,v 1.45 2000/04/27 18:35:04 tgl Exp $ |
12 | 12 | *
|
13 | 13 | *-------------------------------------------------------------------------
|
14 | 14 | */
|
@@ -39,6 +39,7 @@ static RelOptInfo *make_join_rel(Query *root, RelOptInfo *rel1,
|
39 | 39 | void
|
40 | 40 | make_rels_by_joins(Query*root,intlevel)
|
41 | 41 | {
|
| 42 | +List*first_old_rel=root->join_rel_list; |
42 | 43 | List*r;
|
43 | 44 |
|
44 | 45 | /*
|
@@ -85,7 +86,9 @@ make_rels_by_joins(Query *root, int level)
|
85 | 86 | * Note that if all available join clauses for this rel
|
86 | 87 | * require more than one other rel, we will fail to make any
|
87 | 88 | * joins against it here. That's OK; it'll be considered by
|
88 |
| - * "bushy plan" join code in a higher-level pass. |
| 89 | + * "bushy plan" join code in a higher-level pass where we |
| 90 | + * have those other rels collected into a join rel. See also |
| 91 | + * the last-ditch case below. |
89 | 92 | */
|
90 | 93 | make_rels_by_clause_joins(root,
|
91 | 94 | old_rel,
|
@@ -161,6 +164,52 @@ make_rels_by_joins(Query *root, int level)
|
161 | 164 | }
|
162 | 165 | }
|
163 | 166 | }
|
| 167 | + |
| 168 | +/* |
| 169 | + * Last-ditch effort: if we failed to find any usable joins so far, |
| 170 | + * force a set of cartesian-product joins to be generated. This |
| 171 | + * handles the special case where all the available rels have join |
| 172 | + * clauses but we cannot use any of the joins yet. An example is |
| 173 | + * |
| 174 | + * SELECT * FROM a,b,c WHERE (a.f1 + b.f2 + c.f3) = 0; |
| 175 | + * |
| 176 | + * The join clause will be usable at level 3, but at level 2 we have |
| 177 | + * no choice but to make cartesian joins. We consider only left-sided |
| 178 | + * and right-sided cartesian joins in this case (no bushy). |
| 179 | + */ |
| 180 | +if (root->join_rel_list==first_old_rel) |
| 181 | +{ |
| 182 | +/* This loop is just like the first one, except we always call |
| 183 | + * make_rels_by_clauseless_joins(). |
| 184 | + */ |
| 185 | +if (level==2) |
| 186 | +r=root->base_rel_list;/* level-1 is base rels */ |
| 187 | +else |
| 188 | +r=root->join_rel_list; |
| 189 | +for (;r!=NIL;r=lnext(r)) |
| 190 | +{ |
| 191 | +RelOptInfo*old_rel= (RelOptInfo*)lfirst(r); |
| 192 | +intold_level=length(old_rel->relids); |
| 193 | +List*other_rels; |
| 194 | + |
| 195 | +if (old_level!=level-1) |
| 196 | +break; |
| 197 | + |
| 198 | +if (level==2) |
| 199 | +other_rels=lnext(r);/* only consider remaining base |
| 200 | +* rels */ |
| 201 | +else |
| 202 | +other_rels=root->base_rel_list;/* consider all base rels */ |
| 203 | + |
| 204 | +make_rels_by_clauseless_joins(root, |
| 205 | +old_rel, |
| 206 | +other_rels); |
| 207 | +} |
| 208 | + |
| 209 | +if (root->join_rel_list==first_old_rel) |
| 210 | +elog(ERROR,"make_rels_by_joins: failed to build any %d-way joins", |
| 211 | +level); |
| 212 | +} |
164 | 213 | }
|
165 | 214 |
|
166 | 215 | /*
|
|