Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitcdf0231

Browse files
committed
Create a function variable "join_search_hook" to let plugins override the
join search order portion of the planner; this is specifically intended tosimplify developing a replacement for GEQO planning. Patch by JuliusStroffek, editorialized on by me. I renamed make_one_rel_by_joins tostandard_join_search and make_rels_by_joins to join_search_one_level to betterreflect their place within this scheme.
1 parent149af06 commitcdf0231

File tree

4 files changed

+55
-26
lines changed

4 files changed

+55
-26
lines changed

‎src/backend/optimizer/README

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -292,16 +292,17 @@ planner()
292292
find qual clauses that enable merge and hash joins
293293
----make_one_rel()
294294
set_base_rel_pathlist()
295-
findscan and all index paths for each base relation
295+
findseqscan and all index paths for each base relation
296296
find selectivity of columns used in joins
297-
-----make_one_rel_by_joins()
298-
jump to geqo if needed
299-
else call make_rels_by_joins() for each level of join tree needed
300-
make_rels_by_joins():
297+
make_rel_from_joinlist()
298+
hand off join subproblems to a plugin, GEQO, or standard_join_search()
299+
-----standard_join_search()
300+
call join_search_one_level() for each level of join tree needed
301+
join_search_one_level():
301302
For each joinrel of the prior level, do make_rels_by_clause_joins()
302303
if it has join clauses, or make_rels_by_clauseless_joins() if not.
303304
Also generate "bushy plan" joins between joinrels of lower levels.
304-
Back atmake_one_rel_by_joins(), apply set_cheapest() to extract the
305+
Back atstandard_join_search(), apply set_cheapest() to extract the
305306
cheapest path for each newly constructed joinrel.
306307
Loop back if this wasn't the top join level.
307308
Back at query_planner:

‎src/backend/optimizer/path/allpaths.c

Lines changed: 29 additions & 11 deletions
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.164 2007/05/26 18:23:01 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/optimizer/path/allpaths.c,v 1.165 2007/09/26 18:51:50 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -37,6 +37,9 @@
3737
boolenable_geqo= false;/* just in case GUC doesn't set it */
3838
intgeqo_threshold;
3939

40+
/* Hook for plugins to replace standard_join_search() */
41+
join_search_hook_typejoin_search_hook=NULL;
42+
4043

4144
staticvoidset_base_rel_pathlists(PlannerInfo*root);
4245
staticvoidset_rel_pathlist(PlannerInfo*root,RelOptInfo*rel,
@@ -53,8 +56,6 @@ static void set_function_pathlist(PlannerInfo *root, RelOptInfo *rel,
5356
staticvoidset_values_pathlist(PlannerInfo*root,RelOptInfo*rel,
5457
RangeTblEntry*rte);
5558
staticRelOptInfo*make_rel_from_joinlist(PlannerInfo*root,List*joinlist);
56-
staticRelOptInfo*make_one_rel_by_joins(PlannerInfo*root,intlevels_needed,
57-
List*initial_rels);
5859
staticboolsubquery_is_pushdown_safe(Query*subquery,Query*topquery,
5960
bool*differentTypes);
6061
staticboolrecurse_pushdown_safe(Node*setOp,Query*topquery,
@@ -672,31 +673,48 @@ make_rel_from_joinlist(PlannerInfo *root, List *joinlist)
672673
{
673674
/*
674675
* Consider the different orders in which we could join the rels,
675-
* usingeitherGEQO or regularoptimizer.
676+
* usinga plugin,GEQO, ortheregularjoin search code.
676677
*/
677-
if (enable_geqo&&levels_needed >=geqo_threshold)
678+
if (join_search_hook)
679+
return (*join_search_hook) (root,levels_needed,initial_rels);
680+
elseif (enable_geqo&&levels_needed >=geqo_threshold)
678681
returngeqo(root,levels_needed,initial_rels);
679682
else
680-
returnmake_one_rel_by_joins(root,levels_needed,initial_rels);
683+
returnstandard_join_search(root,levels_needed,initial_rels);
681684
}
682685
}
683686

684687
/*
685-
*make_one_rel_by_joins
686-
* Findallpossible joinpaths for a query by successively finding ways
688+
*standard_join_search
689+
* Find possible joinpaths for a query by successively finding ways
687690
* to join component relations into join relations.
688691
*
689692
* 'levels_needed' is the number of iterations needed, ie, the number of
690693
*independent jointree items in the query. This is > 1.
691694
*
692695
* 'initial_rels' is a list of RelOptInfo nodes for each independent
693696
*jointree item.These are the components to be joined together.
697+
*Note that levels_needed == list_length(initial_rels).
694698
*
695699
* Returns the final level of join relations, i.e., the relation that is
696700
* the result of joining all the original relations together.
701+
* At least one implementation path must be provided for this relation and
702+
* all required sub-relations.
703+
*
704+
* To support loadable plugins that modify planner behavior by changing the
705+
* join searching algorithm, we provide a hook variable that lets a plugin
706+
* replace or supplement this function. Any such hook must return the same
707+
* final join relation as the standard code would, but it might have a
708+
* different set of implementation paths attached, and only the sub-joinrels
709+
* needed for these paths need have been instantiated.
710+
*
711+
* Note to plugin authors: the functions invoked during standard_join_search()
712+
* modify root->join_rel_list and root->join_rel_hash. If you want to do more
713+
* than one join-order search, you'll probably need to save and restore the
714+
* original states of those data structures. See geqo_eval() for an example.
697715
*/
698-
staticRelOptInfo*
699-
make_one_rel_by_joins(PlannerInfo*root,intlevels_needed,List*initial_rels)
716+
RelOptInfo*
717+
standard_join_search(PlannerInfo*root,intlevels_needed,List*initial_rels)
700718
{
701719
List**joinitems;
702720
intlev;
@@ -725,7 +743,7 @@ make_one_rel_by_joins(PlannerInfo *root, int levels_needed, List *initial_rels)
725743
* level, and build paths for making each one from every available
726744
* pair of lower-level relations.
727745
*/
728-
joinitems[lev]=make_rels_by_joins(root,lev,joinitems);
746+
joinitems[lev]=join_search_one_level(root,lev,joinitems);
729747

730748
/*
731749
* Do cleanup work on each just-processed rel.

‎src/backend/optimizer/path/joinrels.c

Lines changed: 7 additions & 7 deletions
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.86 2007/02/16 00:14:01 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/optimizer/path/joinrels.c,v 1.87 2007/09/26 18:51:50 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -29,18 +29,18 @@ static bool has_join_restriction(PlannerInfo *root, RelOptInfo *rel);
2929

3030

3131
/*
32-
*make_rels_by_joins
32+
*join_search_one_level
3333
* Consider ways to produce join relations containing exactly 'level'
3434
* jointree items. (This is one step of the dynamic-programming method
35-
* embodied inmake_one_rel_by_joins.) Join rel nodes for each feasible
35+
* embodied instandard_join_search.) Join rel nodes for each feasible
3636
* combination of lower-level rels are created and returned in a list.
3737
* Implementation paths are created for each such joinrel, too.
3838
*
3939
* level: level of rels we want to make this time.
4040
* joinrels[j], 1 <= j < level, is a list of rels containing j items.
4141
*/
4242
List*
43-
make_rels_by_joins(PlannerInfo*root,intlevel,List**joinrels)
43+
join_search_one_level(PlannerInfo*root,intlevel,List**joinrels)
4444
{
4545
List*result_rels=NIL;
4646
List*new_rels;
@@ -638,9 +638,9 @@ make_join_rel(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2)
638638
* Note: this is only a problem if one side of a degenerate outer join
639639
* contains multiple rels, or a clauseless join is required within an IN's
640640
* RHS; else we will find a join path via the "last ditch" case in
641-
*make_rels_by_joins(). We could dispense with this test if we were willing
642-
* to try bushy plans in the "last ditch" case, but that seems much less
643-
* efficient.
641+
*join_search_one_level(). We could dispense with this test if we were
642+
*willingto try bushy plans in the "last ditch" case, but that seems much
643+
*lessefficient.
644644
*/
645645
bool
646646
have_join_order_restriction(PlannerInfo*root,

‎src/include/optimizer/paths.h

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/include/optimizer/paths.h,v 1.98 2007/05/22 01:40:33 tgl Exp $
10+
* $PostgreSQL: pgsql/src/include/optimizer/paths.h,v 1.99 2007/09/26 18:51:51 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -23,7 +23,16 @@
2323
externboolenable_geqo;
2424
externintgeqo_threshold;
2525

26+
/* Hook for plugins to replace standard_join_search() */
27+
typedefRelOptInfo* (*join_search_hook_type) (PlannerInfo*root,
28+
intlevels_needed,
29+
List*initial_rels);
30+
externPGDLLIMPORTjoin_search_hook_typejoin_search_hook;
31+
32+
2633
externRelOptInfo*make_one_rel(PlannerInfo*root,List*joinlist);
34+
externRelOptInfo*standard_join_search(PlannerInfo*root,intlevels_needed,
35+
List*initial_rels);
2736

2837
#ifdefOPTIMIZER_DEBUG
2938
externvoiddebug_print_rel(PlannerInfo*root,RelOptInfo*rel);
@@ -89,7 +98,8 @@ extern void add_paths_to_joinrel(PlannerInfo *root, RelOptInfo *joinrel,
8998
* joinrels.c
9099
* routines to determine which relations to join
91100
*/
92-
externList*make_rels_by_joins(PlannerInfo*root,intlevel,List**joinrels);
101+
externList*join_search_one_level(PlannerInfo*root,intlevel,
102+
List**joinrels);
93103
externRelOptInfo*make_join_rel(PlannerInfo*root,
94104
RelOptInfo*rel1,RelOptInfo*rel2);
95105
externboolhave_join_order_restriction(PlannerInfo*root,

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp