diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index 8b42e36b6d4..c97355e8fda 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -54,6 +54,9 @@ typedef struct pushdown_safety_info bool enable_geqo = false; /* just in case GUC doesn't set it */ int geqo_threshold; +/* Hook for plugins to get control in set_rel_pathlist() */ +set_rel_pathlist_hook_type set_rel_pathlist_hook = NULL; + /* Hook for plugins to replace standard_join_search() */ join_search_hook_type join_search_hook = NULL; @@ -355,6 +358,17 @@ set_rel_pathlist(PlannerInfo *root, RelOptInfo *rel, } } + /* + * Allow a plugin to editorialize on the set of Paths for this base + * relation. It could add new paths (such as CustomPaths) by calling + * add_path(), or delete or modify paths added by the core code. + */ + if (set_rel_pathlist_hook) + (*set_rel_pathlist_hook) (root, rel, rti, rte); + + /* Now find the cheapest of the paths for this rel */ + set_cheapest(rel); + #ifdef OPTIMIZER_DEBUG debug_print_rel(root, rel); #endif @@ -401,12 +415,6 @@ set_plain_rel_pathlist(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte) /* Consider TID scans */ create_tidscan_paths(root, rel); - - /* Consider custom scans, if any */ - create_customscan_paths(root, rel, rte); - - /* Now find the cheapest of the paths for this rel */ - set_cheapest(rel); } /* @@ -432,9 +440,6 @@ set_foreign_pathlist(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte) { /* Call the FDW's GetForeignPaths function to generate path(s) */ rel->fdwroutine->GetForeignPaths(root, rel, rte->relid); - - /* Select cheapest path */ - set_cheapest(rel); } /* @@ -857,9 +862,6 @@ set_append_rel_pathlist(PlannerInfo *root, RelOptInfo *rel, add_path(rel, (Path *) create_append_path(rel, subpaths, required_outer)); } - - /* Select cheapest paths */ - set_cheapest(rel); } /* @@ -1087,7 +1089,12 @@ set_dummy_rel_pathlist(RelOptInfo *rel) add_path(rel, (Path *) create_append_path(rel, NIL, NULL)); - /* Select cheapest path (pretty easy in this case...) */ + /* + * We set the cheapest path immediately, to ensure that IS_DUMMY_REL() + * will recognize the relation as dummy if anyone asks. This is redundant + * when we're called from set_rel_size(), but not when called from + * elsewhere, and doing it twice is harmless anyway. + */ set_cheapest(rel); } @@ -1275,9 +1282,6 @@ set_subquery_pathlist(PlannerInfo *root, RelOptInfo *rel, /* Generate appropriate path */ add_path(rel, create_subqueryscan_path(root, rel, pathkeys, required_outer)); - - /* Select cheapest path (pretty easy in this case...) */ - set_cheapest(rel); } /* @@ -1346,9 +1350,6 @@ set_function_pathlist(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte) /* Generate appropriate path */ add_path(rel, create_functionscan_path(root, rel, pathkeys, required_outer)); - - /* Select cheapest path (pretty easy in this case...) */ - set_cheapest(rel); } /* @@ -1369,9 +1370,6 @@ set_values_pathlist(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte) /* Generate appropriate path */ add_path(rel, create_valuesscan_path(root, rel, required_outer)); - - /* Select cheapest path (pretty easy in this case...) */ - set_cheapest(rel); } /* @@ -1438,9 +1436,6 @@ set_cte_pathlist(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte) /* Generate appropriate path */ add_path(rel, create_ctescan_path(root, rel, required_outer)); - - /* Select cheapest path (pretty easy in this case...) */ - set_cheapest(rel); } /* @@ -1491,9 +1486,6 @@ set_worktable_pathlist(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte) /* Generate appropriate path */ add_path(rel, create_worktablescan_path(root, rel, required_outer)); - - /* Select cheapest path (pretty easy in this case...) */ - set_cheapest(rel); } /* diff --git a/src/backend/optimizer/util/pathnode.c b/src/backend/optimizer/util/pathnode.c index 121b9ff3e45..319e8b2c379 100644 --- a/src/backend/optimizer/util/pathnode.c +++ b/src/backend/optimizer/util/pathnode.c @@ -27,7 +27,6 @@ #include "optimizer/var.h" #include "parser/parsetree.h" #include "utils/lsyscache.h" -#include "utils/memutils.h" #include "utils/selfuncs.h" @@ -1927,50 +1926,3 @@ reparameterize_path(PlannerInfo *root, Path *path, } return NULL; } - -/***************************************************************************** - * creation of custom-plan paths - *****************************************************************************/ - -static List *custom_path_providers = NIL; - -/* - * register_custom_path_provider - * - * Register a table of callback functions which implements a custom-path - * provider. This allows extension to provide additional (hopefully faster) - * methods of scanning a relation. - */ -void -register_custom_path_provider(const CustomPathMethods *cpp_methods) -{ - MemoryContext oldcxt; - - oldcxt = MemoryContextSwitchTo(TopMemoryContext); - custom_path_providers = lappend(custom_path_providers, - (void *) cpp_methods); - MemoryContextSwitchTo(oldcxt); -} - -/* - * create_customscan_paths - * - * Invoke custom path provider callbacks. If the callback determines that - * the custom-path provider can handle this relation, it can add one or more - * paths using add_path(). - */ -void -create_customscan_paths(PlannerInfo *root, - RelOptInfo *baserel, - RangeTblEntry *rte) -{ - ListCell *cell; - - foreach(cell, custom_path_providers) - { - const CustomPathMethods *cpp_methods = lfirst(cell); - - if (cpp_methods->CreateCustomScanPath) - cpp_methods->CreateCustomScanPath(root, baserel, rte); - } -} diff --git a/src/include/nodes/relation.h b/src/include/nodes/relation.h index 7953bf7ed6c..bd5e8ce5c13 100644 --- a/src/include/nodes/relation.h +++ b/src/include/nodes/relation.h @@ -906,9 +906,6 @@ typedef struct CustomPathMethods { const char *CustomName; - void (*CreateCustomScanPath) (PlannerInfo *root, - RelOptInfo *baserel, - RangeTblEntry *rte); struct Plan *(*PlanCustomPath) (PlannerInfo *root, RelOptInfo *rel, struct CustomPath *best_path, diff --git a/src/include/optimizer/pathnode.h b/src/include/optimizer/pathnode.h index 0f2882986c0..26b17f5f7af 100644 --- a/src/include/optimizer/pathnode.h +++ b/src/include/optimizer/pathnode.h @@ -128,15 +128,6 @@ extern Path *reparameterize_path(PlannerInfo *root, Path *path, Relids required_outer, double loop_count); -/* - * Interface definition of custom-scan providers - */ -extern void register_custom_path_provider(const CustomPathMethods *cpp_methods); - -extern void create_customscan_paths(PlannerInfo *root, - RelOptInfo *baserel, - RangeTblEntry *rte); - /* * prototypes for relnode.c */ diff --git a/src/include/optimizer/paths.h b/src/include/optimizer/paths.h index 9b22fda1ef4..afa5f9bcd0e 100644 --- a/src/include/optimizer/paths.h +++ b/src/include/optimizer/paths.h @@ -23,6 +23,13 @@ extern bool enable_geqo; extern int geqo_threshold; +/* Hook for plugins to get control in set_rel_pathlist() */ +typedef void (*set_rel_pathlist_hook_type) (PlannerInfo *root, + RelOptInfo *rel, + Index rti, + RangeTblEntry *rte); +extern PGDLLIMPORT set_rel_pathlist_hook_type set_rel_pathlist_hook; + /* Hook for plugins to replace standard_join_search() */ typedef RelOptInfo *(*join_search_hook_type) (PlannerInfo *root, int levels_needed,