]> granicus.if.org Git - postgresql/commitdiff
Repair bug reported by Laurent Perez: bad plan generated when UPDATE or
authorTom Lane <tgl@sss.pgh.pa.us>
Wed, 5 Mar 2003 18:38:14 +0000 (18:38 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Wed, 5 Mar 2003 18:38:14 +0000 (18:38 +0000)
DELETE of an inheritance tree references another inherited relation.
This bug has been latent since 7.1; I'm still not quite sure why 7.1 and
7.2 don't manifest it (at least, they don't crash on a simple test case).

src/backend/optimizer/plan/planner.c

index 76862c769cb78eb9f84b6deb036f6714cbccd395..c597e44f1d46b7b8ec0322dead4122c0d23dae17 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.148 2003/02/15 21:39:58 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.149 2003/03/05 18:38:14 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -443,6 +443,7 @@ inheritance_planner(Query *parse, List *inheritlist)
 {
        int                     parentRTindex = parse->resultRelation;
        Oid                     parentOID = getrelid(parentRTindex, parse->rtable);
+       int                     mainrtlength = length(parse->rtable);
        List       *subplans = NIL;
        List       *tlist = NIL;
        List       *l;
@@ -451,6 +452,7 @@ inheritance_planner(Query *parse, List *inheritlist)
        {
                int                     childRTindex = lfirsti(l);
                Oid                     childOID = getrelid(childRTindex, parse->rtable);
+               int                     subrtlength;
                Query      *subquery;
                Plan       *subplan;
 
@@ -461,6 +463,24 @@ inheritance_planner(Query *parse, List *inheritlist)
                /* Generate plan */
                subplan = grouping_planner(subquery, 0.0 /* retrieve all tuples */ );
                subplans = lappend(subplans, subplan);
+               /*
+                * It's possible that additional RTEs got added to the rangetable
+                * due to expansion of inherited source tables (see allpaths.c).
+                * If so, we must copy 'em back to the main parse tree's rtable.
+                *
+                * XXX my goodness this is ugly.  Really need to think about ways
+                * to rein in planner's habit of scribbling on its input.
+                */
+               subrtlength = length(subquery->rtable);
+               if (subrtlength > mainrtlength)
+               {
+                       List   *subrt = subquery->rtable;
+
+                       while (mainrtlength-- > 0) /* wish we had nthcdr() */
+                               subrt = lnext(subrt);
+                       parse->rtable = nconc(parse->rtable, subrt);
+                       mainrtlength = subrtlength;
+               }
                /* Save preprocessed tlist from first rel for use in Append */
                if (tlist == NIL)
                        tlist = subplan->targetlist;