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).
This commit is contained in:
parent
391eb5e5b6
commit
147fbf9c6e
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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;
|
int parentRTindex = parse->resultRelation;
|
||||||
Oid parentOID = getrelid(parentRTindex, parse->rtable);
|
Oid parentOID = getrelid(parentRTindex, parse->rtable);
|
||||||
|
int mainrtlength = length(parse->rtable);
|
||||||
List *subplans = NIL;
|
List *subplans = NIL;
|
||||||
List *tlist = NIL;
|
List *tlist = NIL;
|
||||||
List *l;
|
List *l;
|
||||||
@ -451,6 +452,7 @@ inheritance_planner(Query *parse, List *inheritlist)
|
|||||||
{
|
{
|
||||||
int childRTindex = lfirsti(l);
|
int childRTindex = lfirsti(l);
|
||||||
Oid childOID = getrelid(childRTindex, parse->rtable);
|
Oid childOID = getrelid(childRTindex, parse->rtable);
|
||||||
|
int subrtlength;
|
||||||
Query *subquery;
|
Query *subquery;
|
||||||
Plan *subplan;
|
Plan *subplan;
|
||||||
|
|
||||||
@ -461,6 +463,24 @@ inheritance_planner(Query *parse, List *inheritlist)
|
|||||||
/* Generate plan */
|
/* Generate plan */
|
||||||
subplan = grouping_planner(subquery, 0.0 /* retrieve all tuples */ );
|
subplan = grouping_planner(subquery, 0.0 /* retrieve all tuples */ );
|
||||||
subplans = lappend(subplans, subplan);
|
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 */
|
/* Save preprocessed tlist from first rel for use in Append */
|
||||||
if (tlist == NIL)
|
if (tlist == NIL)
|
||||||
tlist = subplan->targetlist;
|
tlist = subplan->targetlist;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user