aboutsummaryrefslogtreecommitdiff
path: root/src/backend/optimizer/plan/planner.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2004-10-02 22:39:49 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2004-10-02 22:39:49 +0000
commit47aa95e951c8291239f15e400d767ea32b5be9b3 (patch)
tree978f2668fce7bd379efc85a4ce2ca4ff79086acf /src/backend/optimizer/plan/planner.c
parent19241421f250ce3041c55a0508530820d938c667 (diff)
downloadpostgresql-47aa95e951c8291239f15e400d767ea32b5be9b3.tar.gz
postgresql-47aa95e951c8291239f15e400d767ea32b5be9b3.zip
Clean up handling of inherited-table update queries, per bug report
from Sebastian Böck. The fix involves being more consistent about when rangetable entries are copied or modified. Someday we really need to fix this stuff to not scribble on its input data structures in the first place...
Diffstat (limited to 'src/backend/optimizer/plan/planner.c')
-rw-r--r--src/backend/optimizer/plan/planner.c46
1 files changed, 31 insertions, 15 deletions
diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c
index d8f228f2b94..1831c1bb9ca 100644
--- a/src/backend/optimizer/plan/planner.c
+++ b/src/backend/optimizer/plan/planner.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/optimizer/plan/planner.c,v 1.175 2004/08/30 02:54:38 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/optimizer/plan/planner.c,v 1.176 2004/10/02 22:39:46 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -320,8 +320,7 @@ subquery_planner(Query *parse, double tuple_fraction)
* grouping_planner.
*/
if (parse->resultRelation &&
- (lst = expand_inherited_rtentry(parse, parse->resultRelation,
- false)) != NIL)
+ (lst = expand_inherited_rtentry(parse, parse->resultRelation)) != NIL)
plan = inheritance_planner(parse, lst);
else
plan = grouping_planner(parse, tuple_fraction);
@@ -513,7 +512,6 @@ inheritance_planner(Query *parse, List *inheritlist)
{
int childRTindex = lfirst_int(l);
Oid childOID = getrelid(childRTindex, parse->rtable);
- int subrtlength;
Query *subquery;
Plan *subplan;
@@ -526,22 +524,40 @@ inheritance_planner(Query *parse, List *inheritlist)
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 next bit is ugly. Really need to think about
+ * ways to rein in planner's habit of scribbling on its input.
*
- * XXX my goodness this is ugly. Really need to think about ways to
- * rein in planner's habit of scribbling on its input.
+ * Planning of the subquery might have modified the rangetable,
+ * either by addition of RTEs due to expansion of inherited source
+ * tables, or by changes of the Query structures inside subquery
+ * RTEs. We have to ensure that this gets propagated back to the
+ * master copy. However, if we aren't done planning yet, we also
+ * need to ensure that subsequent calls to grouping_planner have
+ * virgin sub-Queries to work from. So, if we are at the last
+ * list entry, just copy the subquery rangetable back to the master
+ * copy; if we are not, then extend the master copy by adding
+ * whatever the subquery added. (We assume these added entries
+ * will go untouched by the future grouping_planner calls. We are
+ * also effectively assuming that sub-Queries will get planned
+ * identically each time, or at least that the impacts on their
+ * rangetables will be the same each time. Did I say this is ugly?)
*/
- subrtlength = list_length(subquery->rtable);
- if (subrtlength > mainrtlength)
+ if (lnext(l) == NULL)
+ parse->rtable = subquery->rtable;
+ else
{
- List *subrt;
+ int subrtlength = list_length(subquery->rtable);
+
+ if (subrtlength > mainrtlength)
+ {
+ List *subrt;
- subrt = list_copy_tail(subquery->rtable, mainrtlength);
- parse->rtable = list_concat(parse->rtable, subrt);
- mainrtlength = subrtlength;
+ subrt = list_copy_tail(subquery->rtable, mainrtlength);
+ parse->rtable = list_concat(parse->rtable, subrt);
+ mainrtlength = subrtlength;
+ }
}
+
/* Save preprocessed tlist from first rel for use in Append */
if (tlist == NIL)
tlist = subplan->targetlist;