]> granicus.if.org Git - postgresql/commitdiff
Remove the restriction originally coded into optimize_minmax_aggregates() that
authorTom Lane <tgl@sss.pgh.pa.us>
Fri, 28 Apr 2006 20:57:59 +0000 (20:57 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Fri, 28 Apr 2006 20:57:59 +0000 (20:57 +0000)
MIN/MAX not be converted to use an index if the query WHERE clause contains
any volatile functions or subplans.

I had originally feared that the conversion might alter the behavior of such a
query with respect to a volatile function.  Well, so it might, but only in the
sense that the function would get evaluated at a subset of the table rows
rather than all of them --- and we have never made any such guarantee anyway.
(For instance, we don't refuse to use an index for an ordinary non-aggregate
query when one of the non-indexable filter conditions contains a volatile
function.)

The prohibition against subplans was because of worry that that case wasn't
adequately tested, which it wasn't, but it turns out to be possible to make
8.1 fail anyway:

regression=# select o.ten, (select max(unique2) from tenk1 i where ten = o.ten
or ten = (select f1 from int4_tbl limit 1)) from tenk1 o;
ERROR:  direct correlated subquery unsupported as initplan

This is due to bogus code in SS_make_initplan_from_plan (it's an initplan,
ergo it can't have any parParams).  Having fixed that, we might as well allow
subplans as well as initplans.

src/backend/optimizer/plan/planagg.c
src/backend/optimizer/plan/subselect.c

index a63f85ba51159e81d9b3c6b2563209dde608c1de..eb43da06e1925f674f2ae696ea4727390605615b 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/optimizer/plan/planagg.c,v 1.10.2.1 2005/11/22 18:23:11 momjian Exp $
+ *       $PostgreSQL: pgsql/src/backend/optimizer/plan/planagg.c,v 1.10.2.2 2006/04/28 20:57:59 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -117,15 +117,6 @@ optimize_minmax_aggregates(PlannerInfo *root, List *tlist, Path *best_path)
                return NULL;
        rel = find_base_rel(root, rtr->rtindex);
 
-       /*
-        * Also reject cases with subplans or volatile functions in WHERE. This
-        * may be overly paranoid, but it's not entirely clear if the
-        * transformation is safe then.
-        */
-       if (contain_subplans(parse->jointree->quals) ||
-               contain_volatile_functions(parse->jointree->quals))
-               return NULL;
-
        /*
         * Since this optimization is not applicable all that often, we want to
         * fall out before doing very much work if possible.  Therefore we do the
@@ -508,7 +499,7 @@ make_agg_subplan(PlannerInfo *root, MinMaxAggInfo *info, List *constant_quals)
        ntest->nulltesttype = IS_NOT_NULL;
        ntest->arg = copyObject(info->target);
 
-       plan->qual = lappend(plan->qual, ntest);
+       plan->qual = lcons(ntest, plan->qual);
 
        if (constant_quals)
                plan = (Plan *) make_result(copyObject(plan->targetlist),
index e621e710f5b5a97bb99d05bd789f7fec514fc2a5..60071ca9cc30f34a13f1b8fd2aa8346cff247bd9 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.100.2.1 2005/11/22 18:23:11 momjian Exp $
+ *       $PostgreSQL: pgsql/src/backend/optimizer/plan/subselect.c,v 1.100.2.2 2006/04/28 20:57:59 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1230,8 +1230,6 @@ SS_make_initplan_from_plan(PlannerInfo *root, Plan *plan,
        List       *saved_initplan = PlannerInitPlan;
        SubPlan    *node;
        Param      *prm;
-       Bitmapset  *tmpset;
-       int                     paramid;
 
        /*
         * Set up for a new level of subquery.  This is just to keep
@@ -1262,18 +1260,9 @@ SS_make_initplan_from_plan(PlannerInfo *root, Plan *plan,
        PlannerInitPlan = lappend(PlannerInitPlan, node);
 
        /*
-        * Make parParam list of params that current query level will pass to this
-        * child plan.  (In current usage there probably aren't any.)
+        * The node can't have any inputs (since it's an initplan), so the
+        * parParam and args lists remain empty.
         */
-       tmpset = bms_copy(plan->extParam);
-       while ((paramid = bms_first_member(tmpset)) >= 0)
-       {
-               PlannerParamItem *pitem = list_nth(PlannerParamList, paramid);
-
-               if (pitem->abslevel == PlannerQueryLevel)
-                       node->parParam = lappend_int(node->parParam, paramid);
-       }
-       bms_free(tmpset);
 
        /*
         * Make a Param that will be the subplan's output.