Fix an old thinko in SS_make_initplan_from_plan, which is used when optimizing
authorTom Lane <tgl@sss.pgh.pa.us>
Wed, 18 Jul 2007 21:40:57 +0000 (21:40 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Wed, 18 Jul 2007 21:40:57 +0000 (21:40 +0000)
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.

src/backend/optimizer/plan/subselect.c
src/test/regress/expected/subselect.out
src/test/regress/sql/subselect.sql

index 27db5c0433fa32179a15d5ca3e9fac281657ccdc..6a41138d3b2464d6b30b3c87127b968b876f8fc2 100644 (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.122 2007/02/27 01:11:25 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/optimizer/plan/subselect.c,v 1.123 2007/07/18 21:40:57 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1328,11 +1328,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 don't bother with making
-        * a whole new PlannerInfo struct.
+        * 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.)
         */
-       root->query_level++;
        saved_init_plans = root->init_plans;
        root->init_plans = NIL;
 
@@ -1341,8 +1344,7 @@ SS_make_initplan_from_plan(PlannerInfo *root, Plan *plan,
         */
        SS_finalize_plan(root, plan);
 
-       /* Return to outer subquery context */
-       root->query_level--;
+       /* Restore outer initplan list */
        root->init_plans = saved_init_plans;
 
        /*
index 5f50ba6e00d03dfbefb2bf12776b547b0ae2ee3b..a37489b4956173636639722cf1fdae1c18f61903 100644 (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)
+
index 3c501f1d1bac6e19be11aa3f74fb6351f228d354..4f824c05f76e9f661258d3b455b8e6e123a705a5 100644 (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;