1
0
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:
Tom Lane
2007-09-26 18:51:51 +00:00
parent 149af068ff
commit cdf0231c88
4 changed files with 55 additions and 26 deletions

View File

@ -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.