From: Tom Lane Date: Wed, 18 Jul 2007 21:41:14 +0000 (+0000) Subject: Fix an old thinko in SS_make_initplan_from_plan, which is used when optimizing X-Git-Url: http://waps.l3s.uni-hannover.de/gitweb/?a=commitdiff_plain;h=5e50b44210f8f499adebad8268758bc59ce00dda;p=users%2Fbernd%2Fpostgres.git Fix an old thinko in SS_make_initplan_from_plan, which is used when optimizing a MIN or MAX aggregate call into an indexscan: the initplan is being made at the current query nesting level and so we shouldn't increment query_level. Though usually harmless, this mistake could lead to bogus "plan should not reference subplan's variable" failures on complex queries. Per bug report from David Sanchez i Gregori. --- diff --git a/src/backend/optimizer/plan/subselect.c b/src/backend/optimizer/plan/subselect.c index 88212d5b76..07fa26909d 100644 --- a/src/backend/optimizer/plan/subselect.c +++ b/src/backend/optimizer/plan/subselect.c @@ -1306,10 +1306,14 @@ SS_make_initplan_from_plan(PlannerInfo *root, Plan *plan, Param *prm; /* - * Set up for a new level of subquery. This is just to keep - * SS_finalize_plan from becoming confused. + * We must run SS_finalize_plan(), since that's normally done before a + * subplan gets put into the initplan list. However it will try to attach + * any pre-existing initplans to this one, which we don't want (they are + * siblings not children of this initplan). So, a quick kluge to hide + * them. (This is something else that could perhaps be cleaner if we did + * extParam/allParam processing in setrefs.c instead of here? See notes + * for materialize_finished_plan.) */ - PlannerQueryLevel++; PlannerInitPlan = NIL; /* @@ -1317,8 +1321,7 @@ SS_make_initplan_from_plan(PlannerInfo *root, Plan *plan, */ SS_finalize_plan(plan, root->parse->rtable); - /* Return to outer subquery context */ - PlannerQueryLevel--; + /* Restore outer initplan list */ PlannerInitPlan = saved_initplan; /* diff --git a/src/test/regress/expected/subselect.out b/src/test/regress/expected/subselect.out index f36b5acfe8..bc0f991ae1 100644 --- a/src/test/regress/expected/subselect.out +++ b/src/test/regress/expected/subselect.out @@ -386,3 +386,25 @@ select f1, ss1 as relabel from -2147483647 | 0 (5 rows) +-- +-- Test cases involving PARAM_EXEC parameters and min/max index optimizations. +-- Per bug report from David Sanchez i Gregori. +-- +select * from ( + select max(unique1) from tenk1 as a + where exists (select 1 from tenk1 as b where b.thousand = a.unique2) +) ss; + max +------ + 9997 +(1 row) + +select * from ( + select min(unique1) from tenk1 as a + where not exists (select 1 from tenk1 as b where b.unique2 = 10000) +) ss; + min +----- + 0 +(1 row) + diff --git a/src/test/regress/sql/subselect.sql b/src/test/regress/sql/subselect.sql index b8cb45c6fc..cb20721b1d 100644 --- a/src/test/regress/sql/subselect.sql +++ b/src/test/regress/sql/subselect.sql @@ -236,3 +236,18 @@ select * from shipped_view; select f1, ss1 as relabel from (select *, (select sum(f1) from int4_tbl b where f1 >= a.f1) as ss1 from int4_tbl a) ss; + +-- +-- Test cases involving PARAM_EXEC parameters and min/max index optimizations. +-- Per bug report from David Sanchez i Gregori. +-- + +select * from ( + select max(unique1) from tenk1 as a + where exists (select 1 from tenk1 as b where b.thousand = a.unique2) +) ss; + +select * from ( + select min(unique1) from tenk1 as a + where not exists (select 1 from tenk1 as b where b.unique2 = 10000) +) ss;