Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 1f03630

Browse files
committed
Adjust join_search_one_level's handling of clauseless joins.
For an initial relation that lacks any join clauses (that is, it has to be cartesian-product-joined to the rest of the query), we considered only cartesian joins with initial rels appearing later in the initial-relations list. This creates an undesirable dependency on FROM-list order. We would never fail to find a plan, but perhaps we might not find the best available plan. Noted while discussing the logic with Amit Kapila. Improve the comments a bit in this area, too. Arguably this is a bug fix, but given the lack of complaints from the field I'll refrain from back-patching.
1 parent 5b7b551 commit 1f03630

File tree

1 file changed

+27
-19
lines changed

1 file changed

+27
-19
lines changed

src/backend/optimizer/path/joinrels.c

+27-19
Original file line numberDiff line numberDiff line change
@@ -65,33 +65,34 @@ join_search_one_level(PlannerInfo *root, int level)
6565
* We prefer to join using join clauses, but if we find a rel of level-1
6666
* members that has no join clauses, we will generate Cartesian-product
6767
* joins against all initial rels not already contained in it.
68-
*
69-
* In the first pass (level == 2), we try to join each initial rel to each
70-
* initial rel that appears later in joinrels[1]. (The mirror-image joins
71-
* are handled automatically by make_join_rel.) In later passes, we try
72-
* to join rels of size level-1 from joinrels[level-1] to each initial rel
73-
* in joinrels[1].
7468
*/
7569
foreach(r, joinrels[level - 1])
7670
{
7771
RelOptInfo *old_rel = (RelOptInfo *) lfirst(r);
78-
ListCell *other_rels;
79-
80-
if (level == 2)
81-
other_rels = lnext(r); /* only consider remaining initial
82-
* rels */
83-
else
84-
other_rels = list_head(joinrels[1]); /* consider all initial
85-
* rels */
8672

8773
if (old_rel->joininfo != NIL || old_rel->has_eclass_joins ||
8874
has_join_restriction(root, old_rel))
8975
{
9076
/*
91-
* There are relevant join clauses or join order restrictions,
92-
* so consider joins between this rel and (only) those rels it is
93-
* linked to by a clause or restriction.
77+
* There are join clauses or join order restrictions relevant to
78+
* this rel, so consider joins between this rel and (only) those
79+
* initial rels it is linked to by a clause or restriction.
80+
*
81+
* At level 2 this condition is symmetric, so there is no need to
82+
* look at initial rels before this one in the list; we already
83+
* considered such joins when we were at the earlier rel. (The
84+
* mirror-image joins are handled automatically by make_join_rel.)
85+
* In later passes (level > 2), we join rels of the previous level
86+
* to each initial rel they don't already include but have a join
87+
* clause or restriction with.
9488
*/
89+
ListCell *other_rels;
90+
91+
if (level == 2) /* consider remaining initial rels */
92+
other_rels = lnext(r);
93+
else /* consider all initial rels */
94+
other_rels = list_head(joinrels[1]);
95+
9596
make_rels_by_clause_joins(root,
9697
old_rel,
9798
other_rels);
@@ -102,10 +103,17 @@ join_search_one_level(PlannerInfo *root, int level)
102103
* Oops, we have a relation that is not joined to any other
103104
* relation, either directly or by join-order restrictions.
104105
* Cartesian product time.
106+
*
107+
* We consider a cartesian product with each not-already-included
108+
* initial rel, whether it has other join clauses or not. At
109+
* level 2, if there are two or more clauseless initial rels, we
110+
* will redundantly consider joining them in both directions; but
111+
* such cases aren't common enough to justify adding complexity to
112+
* avoid the duplicated effort.
105113
*/
106114
make_rels_by_clauseless_joins(root,
107115
old_rel,
108-
other_rels);
116+
list_head(joinrels[1]));
109117
}
110118
}
111119

@@ -135,7 +143,7 @@ join_search_one_level(PlannerInfo *root, int level)
135143
ListCell *r2;
136144

137145
/*
138-
* We can ignore clauseless joins here, *except* when they
146+
* We can ignore relations without join clauses here, unless they
139147
* participate in join-order restrictions --- then we might have
140148
* to force a bushy join plan.
141149
*/

0 commit comments

Comments
 (0)