diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2003-03-05 18:38:14 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2003-03-05 18:38:14 +0000 |
commit | 147fbf9c6eba1a494c7fcd34227c5809ab39d491 (patch) | |
tree | 5ce4212e2ade04e29007df95ff3d65b75b97dafa /src | |
parent | 391eb5e5b6a78fce5179808379cdae20baedd9c3 (diff) | |
download | postgresql-147fbf9c6eba1a494c7fcd34227c5809ab39d491.tar.gz postgresql-147fbf9c6eba1a494c7fcd34227c5809ab39d491.zip |
Repair bug reported by Laurent Perez: bad plan generated when UPDATE or
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).
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/optimizer/plan/planner.c | 22 |
1 files changed, 21 insertions, 1 deletions
diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c index 76862c769cb..c597e44f1d4 100644 --- a/src/backend/optimizer/plan/planner.c +++ b/src/backend/optimizer/plan/planner.c @@ -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; |