]> granicus.if.org Git - postgresql/commitdiff
Simplify API for initially hooking custom-path providers into the planner.
authorTom Lane <tgl@sss.pgh.pa.us>
Fri, 21 Nov 2014 19:05:46 +0000 (14:05 -0500)
committerTom Lane <tgl@sss.pgh.pa.us>
Fri, 21 Nov 2014 19:05:46 +0000 (14:05 -0500)
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.

src/backend/optimizer/path/allpaths.c
src/backend/optimizer/util/pathnode.c
src/include/nodes/relation.h
src/include/optimizer/pathnode.h
src/include/optimizer/paths.h

index 8b42e36b6d40cff9c75fa84d92dd44b8d7aa5f84..c97355e8fda8bacf5245f3e958b04d82e7f5621e 100644 (file)
@@ -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);
 }
 
 /*
index 121b9ff3e450a2d651c996de80929c4c6430e13c..319e8b2c37968882cdc70d465e17f9042a572d40 100644 (file)
@@ -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);
-       }
-}
index 7953bf7ed6c808e4dc574fcbcebd1c1f0e5d5c0f..bd5e8ce5c13e203633e9eadce0a4e543e4a6272f 100644 (file)
@@ -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,
index 0f2882986c0c36d980ccf5833939df9401b8d29d..26b17f5f7afcfcbcaa5c9b9aae4603b37128e2f3 100644 (file)
@@ -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
  */
index 9b22fda1ef49c91fd572bb5322ce8c9e07e6fb1c..afa5f9bcd0ecc8ce6d51854f0f22b3bc2d5d861d 100644 (file)
 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,