mirror of
https://github.com/postgres/postgres.git
synced 2025-07-14 08:21:07 +03:00
Create a function variable "join_search_hook" to let plugins override the
join search order portion of the planner; this is specifically intended to simplify developing a replacement for GEQO planning. Patch by Julius Stroffek, editorialized on by me. I renamed make_one_rel_by_joins to standard_join_search and make_rels_by_joins to join_search_one_level to better reflect their place within this scheme.
This commit is contained in:
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/path/allpaths.c,v 1.164 2007/05/26 18:23:01 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/path/allpaths.c,v 1.165 2007/09/26 18:51:50 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -37,6 +37,9 @@
|
||||
bool enable_geqo = false; /* just in case GUC doesn't set it */
|
||||
int geqo_threshold;
|
||||
|
||||
/* Hook for plugins to replace standard_join_search() */
|
||||
join_search_hook_type join_search_hook = NULL;
|
||||
|
||||
|
||||
static void set_base_rel_pathlists(PlannerInfo *root);
|
||||
static void set_rel_pathlist(PlannerInfo *root, RelOptInfo *rel,
|
||||
@ -53,8 +56,6 @@ static void set_function_pathlist(PlannerInfo *root, RelOptInfo *rel,
|
||||
static void set_values_pathlist(PlannerInfo *root, RelOptInfo *rel,
|
||||
RangeTblEntry *rte);
|
||||
static RelOptInfo *make_rel_from_joinlist(PlannerInfo *root, List *joinlist);
|
||||
static RelOptInfo *make_one_rel_by_joins(PlannerInfo *root, int levels_needed,
|
||||
List *initial_rels);
|
||||
static bool subquery_is_pushdown_safe(Query *subquery, Query *topquery,
|
||||
bool *differentTypes);
|
||||
static bool recurse_pushdown_safe(Node *setOp, Query *topquery,
|
||||
@ -672,18 +673,20 @@ make_rel_from_joinlist(PlannerInfo *root, List *joinlist)
|
||||
{
|
||||
/*
|
||||
* Consider the different orders in which we could join the rels,
|
||||
* using either GEQO or regular optimizer.
|
||||
* using a plugin, GEQO, or the regular join search code.
|
||||
*/
|
||||
if (enable_geqo && levels_needed >= geqo_threshold)
|
||||
if (join_search_hook)
|
||||
return (*join_search_hook) (root, levels_needed, initial_rels);
|
||||
else if (enable_geqo && levels_needed >= geqo_threshold)
|
||||
return geqo(root, levels_needed, initial_rels);
|
||||
else
|
||||
return make_one_rel_by_joins(root, levels_needed, initial_rels);
|
||||
return standard_join_search(root, levels_needed, initial_rels);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* make_one_rel_by_joins
|
||||
* Find all possible joinpaths for a query by successively finding ways
|
||||
* standard_join_search
|
||||
* Find possible joinpaths for a query by successively finding ways
|
||||
* to join component relations into join relations.
|
||||
*
|
||||
* 'levels_needed' is the number of iterations needed, ie, the number of
|
||||
@ -691,12 +694,27 @@ make_rel_from_joinlist(PlannerInfo *root, List *joinlist)
|
||||
*
|
||||
* 'initial_rels' is a list of RelOptInfo nodes for each independent
|
||||
* jointree item. These are the components to be joined together.
|
||||
* Note that levels_needed == list_length(initial_rels).
|
||||
*
|
||||
* Returns the final level of join relations, i.e., the relation that is
|
||||
* the result of joining all the original relations together.
|
||||
* At least one implementation path must be provided for this relation and
|
||||
* all required sub-relations.
|
||||
*
|
||||
* To support loadable plugins that modify planner behavior by changing the
|
||||
* join searching algorithm, we provide a hook variable that lets a plugin
|
||||
* replace or supplement this function. Any such hook must return the same
|
||||
* final join relation as the standard code would, but it might have a
|
||||
* different set of implementation paths attached, and only the sub-joinrels
|
||||
* needed for these paths need have been instantiated.
|
||||
*
|
||||
* Note to plugin authors: the functions invoked during standard_join_search()
|
||||
* modify root->join_rel_list and root->join_rel_hash. If you want to do more
|
||||
* than one join-order search, you'll probably need to save and restore the
|
||||
* original states of those data structures. See geqo_eval() for an example.
|
||||
*/
|
||||
static RelOptInfo *
|
||||
make_one_rel_by_joins(PlannerInfo *root, int levels_needed, List *initial_rels)
|
||||
RelOptInfo *
|
||||
standard_join_search(PlannerInfo *root, int levels_needed, List *initial_rels)
|
||||
{
|
||||
List **joinitems;
|
||||
int lev;
|
||||
@ -725,7 +743,7 @@ make_one_rel_by_joins(PlannerInfo *root, int levels_needed, List *initial_rels)
|
||||
* level, and build paths for making each one from every available
|
||||
* pair of lower-level relations.
|
||||
*/
|
||||
joinitems[lev] = make_rels_by_joins(root, lev, joinitems);
|
||||
joinitems[lev] = join_search_one_level(root, lev, joinitems);
|
||||
|
||||
/*
|
||||
* Do cleanup work on each just-processed rel.
|
||||
|
Reference in New Issue
Block a user