]> granicus.if.org Git - postgresql/commitdiff
Redefine create_upper_paths_hook as being invoked once per upper relation.
authorTom Lane <tgl@sss.pgh.pa.us>
Tue, 12 Apr 2016 19:23:14 +0000 (15:23 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 12 Apr 2016 19:23:14 +0000 (15:23 -0400)
Per discussion, this gives potential users of the hook more flexibility,
because they can build custom Paths that implement only one stage of
upper processing atop core-provided Paths for earlier stages.

src/backend/optimizer/plan/planner.c
src/backend/optimizer/prep/prepunion.c
src/include/optimizer/planner.h

index b2a9a8088f61d855945e5ec57eb7298a056a091d..7c1e3d6bbfd29ae9c2f8bc916262d7c7c5776381 100644 (file)
@@ -62,7 +62,7 @@ int                   force_parallel_mode = FORCE_PARALLEL_OFF;
 /* Hook for plugins to get control in planner() */
 planner_hook_type planner_hook = NULL;
 
-/* Hook for plugins to get control before grouping_planner plans upper rels */
+/* Hook for plugins to get control when grouping_planner() plans upper rels */
 create_upper_paths_hook_type create_upper_paths_hook = NULL;
 
 
@@ -1772,20 +1772,20 @@ grouping_planner(PlannerInfo *root, bool inheritance_update,
                root->upper_targets[UPPERREL_GROUP_AGG] = grouping_target;
 
                /*
-                * Let extensions, particularly FDWs and CustomScan providers,
-                * consider injecting extension Paths into the query's upperrels,
-                * where they will compete with the Paths we create below.  We pass
-                * the final scan/join rel because that's not so easily findable from
-                * the PlannerInfo struct; anything else the hooks want to know should
-                * be obtainable via "root".
+                * If there is an FDW that's responsible for the final scan/join rel,
+                * let it consider injecting extension Paths into the query's
+                * upperrels, where they will compete with the Paths we create below.
+                * We pass the final scan/join rel because that's not so easily
+                * findable from the PlannerInfo struct; anything else the FDW wants
+                * to know should be obtainable via "root".
+                *
+                * Note: CustomScan providers, as well as FDWs that don't want to
+                * use this hook, can use the create_upper_paths_hook; see below.
                 */
                if (current_rel->fdwroutine &&
                        current_rel->fdwroutine->GetForeignUpperPaths)
                        current_rel->fdwroutine->GetForeignUpperPaths(root, current_rel);
 
-               if (create_upper_paths_hook)
-                       (*create_upper_paths_hook) (root, current_rel);
-
                /*
                 * If we have grouping and/or aggregation, consider ways to implement
                 * that.  We build a new upperrel representing the output of this
@@ -1962,6 +1962,11 @@ grouping_planner(PlannerInfo *root, bool inheritance_update,
                add_path(final_rel, path);
        }
 
+       /* Let extensions possibly add some more paths */
+       if (create_upper_paths_hook)
+               (*create_upper_paths_hook) (root, UPPERREL_FINAL,
+                                                                       current_rel, final_rel);
+
        /* Note: currently, we leave it to callers to do set_cheapest() */
 }
 
@@ -3724,6 +3729,11 @@ create_grouping_paths(PlannerInfo *root,
                                 errmsg("could not implement GROUP BY"),
                                 errdetail("Some of the datatypes only support hashing, while others only support sorting.")));
 
+       /* Let extensions possibly add some more paths */
+       if (create_upper_paths_hook)
+               (*create_upper_paths_hook) (root, UPPERREL_GROUP_AGG,
+                                                                       input_rel, grouped_rel);
+
        /* Now choose the best path(s) */
        set_cheapest(grouped_rel);
 
@@ -3780,6 +3790,11 @@ create_window_paths(PlannerInfo *root,
                                                                   activeWindows);
        }
 
+       /* Let extensions possibly add some more paths */
+       if (create_upper_paths_hook)
+               (*create_upper_paths_hook) (root, UPPERREL_WINDOW,
+                                                                       input_rel, window_rel);
+
        /* Now choose the best path(s) */
        set_cheapest(window_rel);
 
@@ -4056,6 +4071,11 @@ create_distinct_paths(PlannerInfo *root,
                                 errmsg("could not implement DISTINCT"),
                                 errdetail("Some of the datatypes only support hashing, while others only support sorting.")));
 
+       /* Let extensions possibly add some more paths */
+       if (create_upper_paths_hook)
+               (*create_upper_paths_hook) (root, UPPERREL_DISTINCT,
+                                                                       input_rel, distinct_rel);
+
        /* Now choose the best path(s) */
        set_cheapest(distinct_rel);
 
@@ -4117,6 +4137,11 @@ create_ordered_paths(PlannerInfo *root,
                }
        }
 
+       /* Let extensions possibly add some more paths */
+       if (create_upper_paths_hook)
+               (*create_upper_paths_hook) (root, UPPERREL_ORDERED,
+                                                                       input_rel, ordered_rel);
+
        /*
         * No need to bother with set_cheapest here; grouping_planner does not
         * need us to do it.
index a1ab4daf11a7d8e3361467d8837f6e0831ccbf5a..552b756b8b1b5da51445c02183a304889b439ee1 100644 (file)
@@ -206,7 +206,12 @@ plan_set_operations(PlannerInfo *root)
        /* Add only the final path to the SETOP upperrel. */
        add_path(setop_rel, path);
 
-       /* Select cheapest path (pretty easy at the moment) */
+       /* Let extensions possibly add some more paths */
+       if (create_upper_paths_hook)
+               (*create_upper_paths_hook) (root, UPPERREL_SETOP,
+                                                                       NULL, setop_rel);
+
+       /* Select cheapest path */
        set_cheapest(setop_rel);
 
        return setop_rel;
index a95e73fa93b4e36f83dd0c79b8b3b2160ec87729..4161bcf8d745221a6acec7f0f721b96ef07984c1 100644 (file)
@@ -24,9 +24,11 @@ typedef PlannedStmt *(*planner_hook_type) (Query *parse,
                                                                                                  ParamListInfo boundParams);
 extern PGDLLIMPORT planner_hook_type planner_hook;
 
-/* Hook for plugins to get control before grouping_planner plans upper rels */
+/* Hook for plugins to get control when grouping_planner() plans upper rels */
 typedef void (*create_upper_paths_hook_type) (PlannerInfo *root,
-                                                                                                 RelOptInfo *scan_join_rel);
+                                                                                                        UpperRelationKind stage,
+                                                                                                          RelOptInfo *input_rel,
+                                                                                                        RelOptInfo *output_rel);
 extern PGDLLIMPORT create_upper_paths_hook_type create_upper_paths_hook;