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

Lines changed: 27 additions & 19 deletions
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy