]> granicus.if.org Git - postgresql/commitdiff
Fix set_subquery_pathlist() to copy the RTE's subquery before it gets mangled
authorTom Lane <tgl@sss.pgh.pa.us>
Tue, 10 Mar 2009 20:58:26 +0000 (20:58 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 10 Mar 2009 20:58:26 +0000 (20:58 +0000)
by the planning process.  This prevents the "failed to locate grouping columns"
error recently reported by Dickson Guedes.  That happens because planning
replaces SubLinks by SubPlans in the subquery's targetlist, and exprTypmod()
is smarter about the former than the latter, causing the apparent type of
the subquery's output columns to change.  This seems to be a deficiency we
should fix in exprTypmod(), but that will be a much more invasive patch
with possible side-effects elsewhere, so I'll do that only in HEAD.

Back-patch to 8.3.  Arguably the lack of a copying step is broken/dangerous
all the way back, but in the absence of known problems I'll refrain from
making the older branches pay the extra cost.  (The reason this particular
symptom didn't appear before is that exprTypmod() wasn't smart about SubLinks
either, until 8.3.)

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

index 4e0d9ca4e574423468d2907fc06f1ee91ea62a18..a172c5de7ab2bb6e6a96fe90669a8bbe893774f1 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/optimizer/path/allpaths.c,v 1.180 2009/02/15 20:16:21 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/optimizer/path/allpaths.c,v 1.181 2009/03/10 20:58:26 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -523,6 +523,13 @@ set_subquery_pathlist(PlannerInfo *root, RelOptInfo *rel,
        PlannerInfo *subroot;
        List       *pathkeys;
 
+       /*
+        * Must copy the Query so that planning doesn't mess up the RTE contents
+        * (really really need to fix the planner to not scribble on its input,
+        * someday).
+        */
+       subquery = copyObject(subquery);
+
        /* We need a workspace for keeping track of set-op type coercions */
        differentTypes = (bool *)
                palloc0((list_length(subquery->targetList) + 1) * sizeof(bool));
index f6dbc0212cd46c983005a3dd53656bf10ca34d44..49ee53741b206686db1dd71095b72ec4c43d2a1c 100644 (file)
@@ -465,3 +465,15 @@ from tc;
          3
 (2 rows)
 
+--
+-- Test case for 8.3 "failed to locate grouping columns" bug
+--
+create temp table t1 (f1 numeric(14,0), f2 varchar(30));
+select * from
+  (select distinct f1, f2, (select f2 from t1 x where x.f1 = up.f1) as fs
+   from t1 up) ss
+group by f1,f2,fs;
+ f1 | f2 | fs 
+----+----+----
+(0 rows)
+
index 3a3f11793dc6e5dd8fbc930dad5aa7aa8dde17a3..fd8d5df3a01c72cc0ee409d33157e23e063bbb95 100644 (file)
@@ -298,3 +298,14 @@ select
   ( select min(tb.id) from tb
     where tb.aval = (select ta.val from ta where ta.id = tc.aid) ) as min_tb_id
 from tc;
+
+--
+-- Test case for 8.3 "failed to locate grouping columns" bug
+--
+
+create temp table t1 (f1 numeric(14,0), f2 varchar(30));
+
+select * from
+  (select distinct f1, f2, (select f2 from t1 x where x.f1 = up.f1) as fs
+   from t1 up) ss
+group by f1,f2,fs;