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.
This commit is contained in:
Tom Lane 2007-07-18 21:41:22 +00:00
parent b1def736b0
commit 429870e33e
3 changed files with 46 additions and 6 deletions

View File

@ -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.100.2.3 2006/05/03 00:25:07 tgl Exp $
* $PostgreSQL: pgsql/src/backend/optimizer/plan/subselect.c,v 1.100.2.4 2007/07/18 21:41:22 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -1251,10 +1251,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;
/*
@ -1262,8 +1266,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;
/*

View File

@ -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)

View File

@ -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;