From f4923880b39ad8f671b3fa172d57e3a0ad1b5b0c Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Wed, 3 May 2006 00:24:56 +0000 Subject: [PATCH] Fix calculation of plan node extParams to account for the possibility that one initPlan sets a parameter for another. This could not (I think) happen before 8.1, but it's possible now because the initPlans generated by MIN/MAX optimization might themselves use initPlans. We attach those initPlans as siblings of the MIN/MAX ones, not children, to avoid duplicate computation when multiple MIN/MAX aggregates are present; so this leads to the case of an initPlan needing the result of a sibling initPlan, which is not possible with ordinary query nesting. Hadn't been noticed because in most contexts having too much stuff listed in extParam is fairly harmless. Fixes "plan should not reference subplan's variable" bug reported by Catalin Pitis. --- src/backend/optimizer/plan/subselect.c | 39 +++++++++++++++++++------- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/src/backend/optimizer/plan/subselect.c b/src/backend/optimizer/plan/subselect.c index b9e123d8e6..1b5533cded 100644 --- a/src/backend/optimizer/plan/subselect.c +++ b/src/backend/optimizer/plan/subselect.c @@ -7,7 +7,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/optimizer/plan/subselect.c,v 1.106 2006/04/28 20:57:49 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/optimizer/plan/subselect.c,v 1.107 2006/05/03 00:24:56 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -912,9 +912,11 @@ process_sublinks_mutator(Node *node, bool *isTopQual) void SS_finalize_plan(Plan *plan, List *rtable) { - Bitmapset *outer_params = NULL; - Bitmapset *valid_params = NULL; - Cost initplan_cost = 0; + Bitmapset *outer_params, + *valid_params, + *initExtParam, + *initSetParam; + Cost initplan_cost; int paramid; ListCell *l; @@ -923,6 +925,7 @@ SS_finalize_plan(Plan *plan, List *rtable) * available from outer query levels and my own query level. We do this * once to save time in the per-plan recursion steps. */ + outer_params = valid_params = NULL; paramid = 0; foreach(l, PlannerParamList) { @@ -954,7 +957,11 @@ SS_finalize_plan(Plan *plan, List *rtable) /* * Finally, attach any initPlans to the topmost plan node, and add their - * extParams to the topmost node's, too. + * extParams to the topmost node's, too. However, any setParams of the + * initPlans should not be present in the topmost node's extParams, only + * in its allParams. (As of PG 8.1, it's possible that some initPlans + * have extParams that are setParams of other initPlans, so we have to + * take care of this situation explicitly.) * * We also add the total_cost of each initPlan to the startup cost of the * top node. This is a conservative overestimate, since in fact each @@ -963,17 +970,29 @@ SS_finalize_plan(Plan *plan, List *rtable) plan->initPlan = PlannerInitPlan; PlannerInitPlan = NIL; /* make sure they're not attached twice */ + initExtParam = initSetParam = NULL; + initplan_cost = 0; foreach(l, plan->initPlan) { SubPlan *initplan = (SubPlan *) lfirst(l); + ListCell *l2; - plan->extParam = bms_add_members(plan->extParam, - initplan->plan->extParam); - /* allParam must include all members of extParam */ - plan->allParam = bms_add_members(plan->allParam, - plan->extParam); + initExtParam = bms_add_members(initExtParam, + initplan->plan->extParam); + foreach(l2, initplan->setParam) + { + initSetParam = bms_add_member(initSetParam, lfirst_int(l2)); + } initplan_cost += initplan->plan->total_cost; } + /* allParam must include all these params */ + plan->allParam = bms_add_members(plan->allParam, initExtParam); + plan->allParam = bms_add_members(plan->allParam, initSetParam); + /* but extParam shouldn't include any setParams */ + initExtParam = bms_del_members(initExtParam, initSetParam); + /* empty test ensures extParam is exactly NULL if it's empty */ + if (!bms_is_empty(initExtParam)) + plan->extParam = bms_join(plan->extParam, initExtParam); plan->startup_cost += initplan_cost; plan->total_cost += initplan_cost; -- 2.40.0