aboutsummaryrefslogtreecommitdiff
path: root/src/backend/optimizer/plan/planagg.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/optimizer/plan/planagg.c')
-rw-r--r--src/backend/optimizer/plan/planagg.c43
1 files changed, 30 insertions, 13 deletions
diff --git a/src/backend/optimizer/plan/planagg.c b/src/backend/optimizer/plan/planagg.c
index f0e9c05a452..a761cfdb09b 100644
--- a/src/backend/optimizer/plan/planagg.c
+++ b/src/backend/optimizer/plan/planagg.c
@@ -416,13 +416,23 @@ build_minmax_path(PlannerInfo *root, MinMaxAggInfo *mminfo,
* WHERE col IS NOT NULL AND existing-quals
* ORDER BY col ASC/DESC
* LIMIT 1)
+ *
+ * We cheat a bit here by building what is effectively a subplan query
+ * level without taking the trouble to increment varlevelsup of outer
+ * references. Therefore we don't increment the subroot's query_level nor
+ * repoint its parent_root to the parent level. We can get away with that
+ * because the plan will be an initplan and therefore cannot need any
+ * parameters from the parent level. But see hackery in make_agg_subplan;
+ * we might someday need to do this the hard way.
*----------
*/
subroot = (PlannerInfo *) palloc(sizeof(PlannerInfo));
memcpy(subroot, root, sizeof(PlannerInfo));
subroot->parse = parse = (Query *) copyObject(root->parse);
- /* make sure subroot planning won't change root->init_plans contents */
- subroot->init_plans = list_copy(root->init_plans);
+ /* reset subplan-related stuff */
+ subroot->plan_params = NIL;
+ subroot->outer_params = NULL;
+ subroot->init_plans = NIL;
/* There shouldn't be any OJ or LATERAL info to translate, as yet */
Assert(subroot->join_info_list == NIL);
Assert(subroot->lateral_info_list == NIL);
@@ -578,23 +588,30 @@ make_agg_subplan(PlannerInfo *root, MinMaxAggInfo *mminfo)
0, 1);
/*
+ * We have to do some of the same cleanup that subquery_planner() would
+ * do, namely cope with params and initplans used within this plan tree.
+ *
+ * This is a little bit messy because although we initially created the
+ * subroot by cloning the outer root, it really is a subplan and needs to
+ * consider initplans belonging to the outer root as providing available
+ * parameters. So temporarily change its parent_root pointer.
+ * (Fortunately, SS_identify_outer_params doesn't care whether the depth
+ * of parent_root nesting matches query_level.)
+ */
+ subroot->parent_root = root;
+ SS_identify_outer_params(subroot);
+ subroot->parent_root = root->parent_root;
+
+ SS_attach_initplans(subroot, plan);
+
+ /*
* Convert the plan into an InitPlan, and make a Param for its result.
*/
mminfo->param =
- SS_make_initplan_from_plan(subroot, plan,
+ SS_make_initplan_from_plan(root, subroot, plan,
exprType((Node *) mminfo->target),
-1,
exprCollation((Node *) mminfo->target));
-
- /*
- * Make sure the initplan gets into the outer PlannerInfo, along with any
- * other initplans generated by the sub-planning run. We had to include
- * the outer PlannerInfo's pre-existing initplans into the inner one's
- * init_plans list earlier, so make sure we don't put back any duplicate
- * entries.
- */
- root->init_plans = list_concat_unique_ptr(root->init_plans,
- subroot->init_plans);
}
/*