8
8
*
9
9
*
10
10
* 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 $
12
12
*
13
13
*-------------------------------------------------------------------------
14
14
*/
37
37
bool enable_geqo = false; /* just in case GUC doesn't set it */
38
38
int geqo_threshold ;
39
39
40
+ /* Hook for plugins to replace standard_join_search() */
41
+ join_search_hook_type join_search_hook = NULL ;
42
+
40
43
41
44
static void set_base_rel_pathlists (PlannerInfo * root );
42
45
static void set_rel_pathlist (PlannerInfo * root , RelOptInfo * rel ,
@@ -53,8 +56,6 @@ static void set_function_pathlist(PlannerInfo *root, RelOptInfo *rel,
53
56
static void set_values_pathlist (PlannerInfo * root , RelOptInfo * rel ,
54
57
RangeTblEntry * rte );
55
58
static RelOptInfo * make_rel_from_joinlist (PlannerInfo * root , List * joinlist );
56
- static RelOptInfo * make_one_rel_by_joins (PlannerInfo * root , int levels_needed ,
57
- List * initial_rels );
58
59
static bool subquery_is_pushdown_safe (Query * subquery , Query * topquery ,
59
60
bool * differentTypes );
60
61
static bool recurse_pushdown_safe (Node * setOp , Query * topquery ,
@@ -672,31 +673,48 @@ make_rel_from_joinlist(PlannerInfo *root, List *joinlist)
672
673
{
673
674
/*
674
675
* Consider the different orders in which we could join the rels,
675
- * using either GEQO or regular optimizer .
676
+ * using a plugin, GEQO, or the regular join search code .
676
677
*/
677
- if (enable_geqo && levels_needed >= geqo_threshold )
678
+ if (join_search_hook )
679
+ return (* join_search_hook ) (root , levels_needed , initial_rels );
680
+ else if (enable_geqo && levels_needed >= geqo_threshold )
678
681
return geqo (root , levels_needed , initial_rels );
679
682
else
680
- return make_one_rel_by_joins (root , levels_needed , initial_rels );
683
+ return standard_join_search (root , levels_needed , initial_rels );
681
684
}
682
685
}
683
686
684
687
/*
685
- * make_one_rel_by_joins
686
- * Find all possible joinpaths for a query by successively finding ways
688
+ * standard_join_search
689
+ * Find possible joinpaths for a query by successively finding ways
687
690
* to join component relations into join relations.
688
691
*
689
692
* 'levels_needed' is the number of iterations needed, ie, the number of
690
693
* independent jointree items in the query. This is > 1.
691
694
*
692
695
* 'initial_rels' is a list of RelOptInfo nodes for each independent
693
696
* jointree item. These are the components to be joined together.
697
+ * Note that levels_needed == list_length(initial_rels).
694
698
*
695
699
* Returns the final level of join relations, i.e., the relation that is
696
700
* 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.
697
715
*/
698
- static RelOptInfo *
699
- make_one_rel_by_joins (PlannerInfo * root , int levels_needed , List * initial_rels )
716
+ RelOptInfo *
717
+ standard_join_search (PlannerInfo * root , int levels_needed , List * initial_rels )
700
718
{
701
719
List * * joinitems ;
702
720
int lev ;
@@ -725,7 +743,7 @@ make_one_rel_by_joins(PlannerInfo *root, int levels_needed, List *initial_rels)
725
743
* level, and build paths for making each one from every available
726
744
* pair of lower-level relations.
727
745
*/
728
- joinitems [lev ] = make_rels_by_joins (root , lev , joinitems );
746
+ joinitems [lev ] = join_search_one_level (root , lev , joinitems );
729
747
730
748
/*
731
749
* Do cleanup work on each just-processed rel.
0 commit comments