Commit c2ea2285 authored by Tom Lane's avatar Tom Lane

Simplify API for initially hooking custom-path providers into the planner.

Instead of register_custom_path_provider and a CreateCustomScanPath
callback, let's just provide a standard function hook in set_rel_pathlist.
This is more flexible than what was previously committed, is more like the
usual conventions for planner hooks, and requires less support code in the
core.  We had discussed this design (including centralizing the
set_cheapest() calls) back in March or so, so I'm not sure why it wasn't
done like this already.
parent 4077fb4d
...@@ -54,6 +54,9 @@ typedef struct pushdown_safety_info ...@@ -54,6 +54,9 @@ typedef struct pushdown_safety_info
bool enable_geqo = false; /* just in case GUC doesn't set it */ bool enable_geqo = false; /* just in case GUC doesn't set it */
int geqo_threshold; 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() */ /* Hook for plugins to replace standard_join_search() */
join_search_hook_type join_search_hook = NULL; join_search_hook_type join_search_hook = NULL;
...@@ -355,6 +358,17 @@ set_rel_pathlist(PlannerInfo *root, RelOptInfo *rel, ...@@ -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 #ifdef OPTIMIZER_DEBUG
debug_print_rel(root, rel); debug_print_rel(root, rel);
#endif #endif
...@@ -401,12 +415,6 @@ set_plain_rel_pathlist(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte) ...@@ -401,12 +415,6 @@ set_plain_rel_pathlist(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte)
/* Consider TID scans */ /* Consider TID scans */
create_tidscan_paths(root, rel); 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) ...@@ -432,9 +440,6 @@ set_foreign_pathlist(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte)
{ {
/* Call the FDW's GetForeignPaths function to generate path(s) */ /* Call the FDW's GetForeignPaths function to generate path(s) */
rel->fdwroutine->GetForeignPaths(root, rel, rte->relid); 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, ...@@ -857,9 +862,6 @@ set_append_rel_pathlist(PlannerInfo *root, RelOptInfo *rel,
add_path(rel, (Path *) add_path(rel, (Path *)
create_append_path(rel, subpaths, required_outer)); create_append_path(rel, subpaths, required_outer));
} }
/* Select cheapest paths */
set_cheapest(rel);
} }
/* /*
...@@ -1087,7 +1089,12 @@ set_dummy_rel_pathlist(RelOptInfo *rel) ...@@ -1087,7 +1089,12 @@ set_dummy_rel_pathlist(RelOptInfo *rel)
add_path(rel, (Path *) create_append_path(rel, NIL, NULL)); 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); set_cheapest(rel);
} }
...@@ -1275,9 +1282,6 @@ set_subquery_pathlist(PlannerInfo *root, RelOptInfo *rel, ...@@ -1275,9 +1282,6 @@ set_subquery_pathlist(PlannerInfo *root, RelOptInfo *rel,
/* Generate appropriate path */ /* Generate appropriate path */
add_path(rel, create_subqueryscan_path(root, rel, pathkeys, required_outer)); 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) ...@@ -1346,9 +1350,6 @@ set_function_pathlist(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte)
/* Generate appropriate path */ /* Generate appropriate path */
add_path(rel, create_functionscan_path(root, rel, add_path(rel, create_functionscan_path(root, rel,
pathkeys, required_outer)); 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) ...@@ -1369,9 +1370,6 @@ set_values_pathlist(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte)
/* Generate appropriate path */ /* Generate appropriate path */
add_path(rel, create_valuesscan_path(root, rel, required_outer)); 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) ...@@ -1438,9 +1436,6 @@ set_cte_pathlist(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte)
/* Generate appropriate path */ /* Generate appropriate path */
add_path(rel, create_ctescan_path(root, rel, required_outer)); 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) ...@@ -1491,9 +1486,6 @@ set_worktable_pathlist(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte)
/* Generate appropriate path */ /* Generate appropriate path */
add_path(rel, create_worktablescan_path(root, rel, required_outer)); add_path(rel, create_worktablescan_path(root, rel, required_outer));
/* Select cheapest path (pretty easy in this case...) */
set_cheapest(rel);
} }
/* /*
......
...@@ -27,7 +27,6 @@ ...@@ -27,7 +27,6 @@
#include "optimizer/var.h" #include "optimizer/var.h"
#include "parser/parsetree.h" #include "parser/parsetree.h"
#include "utils/lsyscache.h" #include "utils/lsyscache.h"
#include "utils/memutils.h"
#include "utils/selfuncs.h" #include "utils/selfuncs.h"
...@@ -1927,50 +1926,3 @@ reparameterize_path(PlannerInfo *root, Path *path, ...@@ -1927,50 +1926,3 @@ reparameterize_path(PlannerInfo *root, Path *path,
} }
return NULL; 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);
}
}
...@@ -906,9 +906,6 @@ typedef struct CustomPathMethods ...@@ -906,9 +906,6 @@ typedef struct CustomPathMethods
{ {
const char *CustomName; const char *CustomName;
void (*CreateCustomScanPath) (PlannerInfo *root,
RelOptInfo *baserel,
RangeTblEntry *rte);
struct Plan *(*PlanCustomPath) (PlannerInfo *root, struct Plan *(*PlanCustomPath) (PlannerInfo *root,
RelOptInfo *rel, RelOptInfo *rel,
struct CustomPath *best_path, struct CustomPath *best_path,
......
...@@ -128,15 +128,6 @@ extern Path *reparameterize_path(PlannerInfo *root, Path *path, ...@@ -128,15 +128,6 @@ extern Path *reparameterize_path(PlannerInfo *root, Path *path,
Relids required_outer, Relids required_outer,
double loop_count); 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 * prototypes for relnode.c
*/ */
......
...@@ -23,6 +23,13 @@ ...@@ -23,6 +23,13 @@
extern bool enable_geqo; extern bool enable_geqo;
extern int geqo_threshold; 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() */ /* Hook for plugins to replace standard_join_search() */
typedef RelOptInfo *(*join_search_hook_type) (PlannerInfo *root, typedef RelOptInfo *(*join_search_hook_type) (PlannerInfo *root,
int levels_needed, int levels_needed,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment