aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/optimizer/plan/planner.c26
-rw-r--r--src/backend/optimizer/prep/prepjointree.c1
-rw-r--r--src/include/nodes/relation.h3
-rw-r--r--src/include/optimizer/planner.h5
4 files changed, 35 insertions, 0 deletions
diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c
index f3a0a44fd88..d11f44e64d5 100644
--- a/src/backend/optimizer/plan/planner.c
+++ b/src/backend/optimizer/plan/planner.c
@@ -62,6 +62,9 @@ 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 */
+create_upper_paths_hook_type create_upper_paths_hook = NULL;
+
/* Expression kind codes for preprocess_expression */
#define EXPRKIND_QUAL 0
@@ -459,6 +462,7 @@ subquery_planner(PlannerGlobal *glob, Query *parse,
root->append_rel_list = NIL;
root->rowMarks = NIL;
memset(root->upper_rels, 0, sizeof(root->upper_rels));
+ memset(root->upper_targets, 0, sizeof(root->upper_targets));
root->processed_tlist = NIL;
root->grouping_map = NULL;
root->minmax_aggs = NIL;
@@ -1737,6 +1741,28 @@ grouping_planner(PlannerInfo *root, bool inheritance_update,
}
/*
+ * Save the various upper-rel PathTargets we just computed into
+ * root->upper_targets[]. The core code doesn't use this, but it
+ * provides a convenient place for extensions to get at the info. For
+ * consistency, we save all the intermediate targets, even though some
+ * of the corresponding upperrels might not be needed for this query.
+ */
+ root->upper_targets[UPPERREL_FINAL] = final_target;
+ root->upper_targets[UPPERREL_WINDOW] = sort_input_target;
+ root->upper_targets[UPPERREL_GROUP_AGG] = grouping_target;
+
+ /*
+ * Let extensions, particularly 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 hook wants to know should be
+ * obtainable via "root".
+ */
+ 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
* phase.
diff --git a/src/backend/optimizer/prep/prepjointree.c b/src/backend/optimizer/prep/prepjointree.c
index c8d5c66b396..75577bce2ca 100644
--- a/src/backend/optimizer/prep/prepjointree.c
+++ b/src/backend/optimizer/prep/prepjointree.c
@@ -909,6 +909,7 @@ pull_up_simple_subquery(PlannerInfo *root, Node *jtnode, RangeTblEntry *rte,
subroot->append_rel_list = NIL;
subroot->rowMarks = NIL;
memset(subroot->upper_rels, 0, sizeof(subroot->upper_rels));
+ memset(subroot->upper_targets, 0, sizeof(subroot->upper_targets));
subroot->processed_tlist = NIL;
subroot->grouping_map = NULL;
subroot->minmax_aggs = NIL;
diff --git a/src/include/nodes/relation.h b/src/include/nodes/relation.h
index b48a6183dc2..503269693ba 100644
--- a/src/include/nodes/relation.h
+++ b/src/include/nodes/relation.h
@@ -263,6 +263,9 @@ typedef struct PlannerInfo
/* Use fetch_upper_rel() to get any particular upper rel */
List *upper_rels[UPPERREL_FINAL + 1]; /* upper-rel RelOptInfos */
+ /* Result tlists chosen by grouping_planner for upper-stage processing */
+ struct PathTarget *upper_targets[UPPERREL_FINAL + 1];
+
/*
* grouping_planner passes back its final processed targetlist here, for
* use in relabeling the topmost tlist of the finished Plan.
diff --git a/src/include/optimizer/planner.h b/src/include/optimizer/planner.h
index 3fb7cb58cbd..a95e73fa93b 100644
--- a/src/include/optimizer/planner.h
+++ b/src/include/optimizer/planner.h
@@ -24,6 +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 */
+typedef void (*create_upper_paths_hook_type) (PlannerInfo *root,
+ RelOptInfo *scan_join_rel);
+extern PGDLLIMPORT create_upper_paths_hook_type create_upper_paths_hook;
+
extern PlannedStmt *planner(Query *parse, int cursorOptions,
ParamListInfo boundParams);