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

Commit 59fc64a

Browse files
committed
Fix a conceptual error in my patch of 2007-10-26 that avoided considering
clauseless joins of relations that have unexploited join clauses. Rather than looking at every other base relation in the query, the correct thing is to examine the other relations in the "initial_rels" list of the current make_rel_from_joinlist() invocation, because those are what we actually have the ability to join against. This might be a subset of the whole query in cases where join_collapse_limit or from_collapse_limit or full joins have prevented merging the whole query into a single join problem. This is a bit untidy because we have to pass those rels down through a new PlannerInfo field, but it's necessary. Per bug #3865 from Oleg Kharin.
1 parent e6a442c commit 59fc64a

File tree

4 files changed

+26
-24
lines changed

4 files changed

+26
-24
lines changed

src/backend/optimizer/path/allpaths.c

+6-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/optimizer/path/allpaths.c,v 1.167 2008/01/01 19:45:50 momjian Exp $
11+
* $PostgreSQL: pgsql/src/backend/optimizer/path/allpaths.c,v 1.168 2008/01/11 04:02:18 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -674,7 +674,12 @@ make_rel_from_joinlist(PlannerInfo *root, List *joinlist)
674674
/*
675675
* Consider the different orders in which we could join the rels,
676676
* using a plugin, GEQO, or the regular join search code.
677+
*
678+
* We put the initial_rels list into a PlannerInfo field because
679+
* has_legal_joinclause() needs to look at it (ugly :-().
677680
*/
681+
root->initial_rels = initial_rels;
682+
678683
if (join_search_hook)
679684
return (*join_search_hook) (root, levels_needed, initial_rels);
680685
else if (enable_geqo && levels_needed >= geqo_threshold)

src/backend/optimizer/path/joinrels.c

+15-21
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/optimizer/path/joinrels.c,v 1.90 2008/01/01 19:45:50 momjian Exp $
11+
* $PostgreSQL: pgsql/src/backend/optimizer/path/joinrels.c,v 1.91 2008/01/11 04:02:18 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -838,33 +838,27 @@ has_join_restriction(PlannerInfo *root, RelOptInfo *rel)
838838
* Detect whether the specified relation can legally be joined
839839
* to any other rels using join clauses.
840840
*
841-
* We consider only joins to single other relations. This is sufficient
842-
* to get a "true" result in most real queries, and an occasional erroneous
843-
* "false" will only cost a bit more planning time. The reason for this
844-
* limitation is that considering joins to other joins would require proving
845-
* that the other join rel can legally be formed, which seems like too much
846-
* trouble for something that's only a heuristic to save planning time.
841+
* We consider only joins to single other relations in the current
842+
* initial_rels list. This is sufficient to get a "true" result in most real
843+
* queries, and an occasional erroneous "false" will only cost a bit more
844+
* planning time. The reason for this limitation is that considering joins to
845+
* other joins would require proving that the other join rel can legally be
846+
* formed, which seems like too much trouble for something that's only a
847+
* heuristic to save planning time. (Note: we must look at initial_rels
848+
* and not all of the query, since when we are planning a sub-joinlist we
849+
* may be forced to make clauseless joins within initial_rels even though
850+
* there are join clauses linking to other parts of the query.)
847851
*/
848852
static bool
849853
has_legal_joinclause(PlannerInfo *root, RelOptInfo *rel)
850854
{
851-
Index rti;
855+
ListCell *lc;
852856

853-
for (rti = 1; rti < root->simple_rel_array_size; rti++)
857+
foreach(lc, root->initial_rels)
854858
{
855-
RelOptInfo *rel2 = root->simple_rel_array[rti];
859+
RelOptInfo *rel2 = (RelOptInfo *) lfirst(lc);
856860

857-
/* there may be empty slots corresponding to non-baserel RTEs */
858-
if (rel2 == NULL)
859-
continue;
860-
861-
Assert(rel2->relid == rti); /* sanity check on array */
862-
863-
/* ignore RTEs that are "other rels" */
864-
if (rel2->reloptkind != RELOPT_BASEREL)
865-
continue;
866-
867-
/* ignore RTEs that are already in "rel" */
861+
/* ignore rels that are already in "rel" */
868862
if (bms_overlap(rel->relids, rel2->relids))
869863
continue;
870864

src/backend/optimizer/plan/planmain.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
*
1515
*
1616
* IDENTIFICATION
17-
* $PostgreSQL: pgsql/src/backend/optimizer/plan/planmain.c,v 1.105 2008/01/01 19:45:50 momjian Exp $
17+
* $PostgreSQL: pgsql/src/backend/optimizer/plan/planmain.c,v 1.106 2008/01/11 04:02:18 tgl Exp $
1818
*
1919
*-------------------------------------------------------------------------
2020
*/
@@ -142,6 +142,7 @@ query_planner(PlannerInfo *root, List *tlist,
142142
root->right_join_clauses = NIL;
143143
root->full_join_clauses = NIL;
144144
root->oj_info_list = NIL;
145+
root->initial_rels = NIL;
145146

146147
/*
147148
* Make a flattened version of the rangetable for faster access (this is

src/include/nodes/relation.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/include/nodes/relation.h,v 1.153 2008/01/09 20:42:28 tgl Exp $
10+
* $PostgreSQL: pgsql/src/include/nodes/relation.h,v 1.154 2008/01/11 04:02:18 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -165,6 +165,8 @@ typedef struct PlannerInfo
165165
List *group_pathkeys; /* groupClause pathkeys, if any */
166166
List *sort_pathkeys; /* sortClause pathkeys, if any */
167167

168+
List *initial_rels; /* RelOptInfos we are now trying to join */
169+
168170
MemoryContext planner_cxt; /* context holding PlannerInfo */
169171

170172
double total_table_pages; /* # of pages in all tables of query */

0 commit comments

Comments
 (0)