mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-12-21 08:29:39 +08:00
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.
This commit is contained in:
parent
4077fb4d1d
commit
c2ea2285e9
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user