summaryrefslogtreecommitdiff
path: root/src/backend/optimizer/path/joinrels.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2012-04-13 15:32:34 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2012-04-13 16:07:17 -0400
commite3ffd05b02468b1a53de31a322cedf195576a625 (patch)
tree5631a32e6f9275af24b8382f6c776c56b16aa8ad /src/backend/optimizer/path/joinrels.c
parentc0cc526e8b1e821dfced692a68e4c8978c2bdbc1 (diff)
Weaken the planner's tests for relevant joinclauses.
We should be willing to cross-join two small relations if that allows us to use an inner indexscan on a large relation (that is, the potential indexqual for the large table requires both smaller relations). This worked in simple cases but fell apart as soon as there was a join clause to a fourth relation, because the existence of any two-relation join clause caused the planner to not consider clauseless joins between other base relations. The added regression test shows an example case adapted from a recent complaint from Benoit Delbosc. Adjust have_relevant_joinclause, have_relevant_eclass_joinclause, and has_relevant_eclass_joinclause to consider that a join clause mentioning three or more relations is sufficient grounds for joining any subset of those relations, even if we have to do so via a cartesian join. Since such clauses are relatively uncommon, this shouldn't affect planning speed on typical queries; in fact it should help a bit, because the latter two functions in particular get significantly simpler. Although this is arguably a bug fix, I'm not going to risk back-patching it, since it might have currently-unforeseen consequences.
Diffstat (limited to 'src/backend/optimizer/path/joinrels.c')
-rw-r--r--src/backend/optimizer/path/joinrels.c14
1 files changed, 5 insertions, 9 deletions
diff --git a/src/backend/optimizer/path/joinrels.c b/src/backend/optimizer/path/joinrels.c
index 4a35d8d3a48..2ad0b969d25 100644
--- a/src/backend/optimizer/path/joinrels.c
+++ b/src/backend/optimizer/path/joinrels.c
@@ -88,13 +88,9 @@ join_search_one_level(PlannerInfo *root, int level)
has_join_restriction(root, old_rel))
{
/*
- * Note that if all available join clauses for this rel require
- * more than one other rel, we will fail to make any joins against
- * it here. In most cases that's OK; it'll be considered by
- * "bushy plan" join code in a higher-level pass where we have
- * those other rels collected into a join rel.
- *
- * See also the last-ditch case below.
+ * There are relevant join clauses or join order restrictions,
+ * so consider joins between this rel and (only) those rels it is
+ * linked to by a clause or restriction.
*/
make_rels_by_clause_joins(root,
old_rel,
@@ -160,8 +156,8 @@ join_search_one_level(PlannerInfo *root, int level)
{
/*
* OK, we can build a rel of the right level from this
- * pair of rels. Do so if there is at least one usable
- * join clause or a relevant join restriction.
+ * pair of rels. Do so if there is at least one relevant
+ * join clause or join order restriction.
*/
if (have_relevant_joinclause(root, old_rel, new_rel) ||
have_join_order_restriction(root, old_rel, new_rel))