1616 *
1717 *
1818 * IDENTIFICATION
19- * $PostgreSQL: pgsql/src/backend/optimizer/prep/prepjointree.c,v 1.51 2008/08/1418:47:59 tgl Exp $
19+ * $PostgreSQL: pgsql/src/backend/optimizer/prep/prepjointree.c,v 1.52 2008/08/1420:31:29 heikki Exp $
2020 *
2121 *-------------------------------------------------------------------------
2222 */
@@ -47,7 +47,8 @@ static Node *pull_up_simple_subquery(PlannerInfo *root, Node *jtnode,
4747static Node * pull_up_simple_union_all (PlannerInfo * root ,Node * jtnode ,
4848RangeTblEntry * rte );
4949static void pull_up_union_leaf_queries (Node * setOp ,PlannerInfo * root ,
50- int parentRTindex ,Query * setOpQuery );
50+ int parentRTindex ,Query * setOpQuery ,
51+ int childRToffset );
5152static void make_setop_translation_lists (Query * query ,
5253Index newvarno ,
5354List * * col_mappings ,List * * translated_vars );
@@ -560,14 +561,34 @@ pull_up_simple_union_all(PlannerInfo *root, Node *jtnode, RangeTblEntry *rte)
560561{
561562int varno = ((RangeTblRef * )jtnode )-> rtindex ;
562563Query * subquery = rte -> subquery ;
564+ int rtoffset ;
565+ List * rtable ;
563566
564567/*
565- * Recursively scan the subquery's setOperations tree and copy the leaf
566- * subqueries into the parent rangetable. Add AppendRelInfo nodes for
567- * them to the parent's append_rel_list, too.
568+ * Append the subquery rtable entries to upper query.
569+ */
570+ rtoffset = list_length (root -> parse -> rtable );
571+
572+ /*
573+ * Append child RTEs to parent rtable.
574+ *
575+ * Upper-level vars in subquery are now one level closer to their
576+ * parent than before.We don't have to worry about offsetting
577+ * varnos, though, because any such vars must refer to stuff above the
578+ * level of the query we are pulling into.
579+ */
580+ rtable = copyObject (subquery -> rtable );
581+ IncrementVarSublevelsUp_rtable (rtable ,-1 ,1 );
582+ root -> parse -> rtable = list_concat (root -> parse -> rtable ,rtable );
583+
584+ /*
585+ * Recursively scan the subquery's setOperations tree and add
586+ * AppendRelInfo nodes for leaf subqueries to the parent's
587+ * append_rel_list.
568588 */
569589Assert (subquery -> setOperations );
570- pull_up_union_leaf_queries (subquery -> setOperations ,root ,varno ,subquery );
590+ pull_up_union_leaf_queries (subquery -> setOperations ,root ,varno ,subquery ,
591+ rtoffset );
571592
572593/*
573594 * Mark the parent as an append relation.
@@ -583,41 +604,26 @@ pull_up_simple_union_all(PlannerInfo *root, Node *jtnode, RangeTblEntry *rte)
583604 * Note that setOpQuery is the Query containing the setOp node, whose rtable
584605 * is where to look up the RTE if setOp is a RangeTblRef. This is *not* the
585606 * same as root->parse, which is the top-level Query we are pulling up into.
607+ *
586608 * parentRTindex is the appendrel parent's index in root->parse->rtable.
609+ *
610+ * The child RTEs have already been copied to the parent. childRToffset
611+ * tells us where in the parent's range table they were copied.
587612 */
588613static void
589614pull_up_union_leaf_queries (Node * setOp ,PlannerInfo * root ,int parentRTindex ,
590- Query * setOpQuery )
615+ Query * setOpQuery , int childRToffset )
591616{
592617if (IsA (setOp ,RangeTblRef ))
593618{
594619RangeTblRef * rtr = (RangeTblRef * )setOp ;
595- RangeTblEntry * rte = rt_fetch (rtr -> rtindex ,setOpQuery -> rtable );
596- Query * subquery ;
597620int childRTindex ;
598621AppendRelInfo * appinfo ;
599- Query * parse = root -> parse ;
600-
601- /*
602- * Make a modifiable copy of the child RTE and contained query.
603- */
604- rte = copyObject (rte );
605- subquery = rte -> subquery ;
606- Assert (subquery != NULL );
607-
608- /*
609- * Upper-level vars in subquery are now one level closer to their
610- * parent than before.We don't have to worry about offsetting
611- * varnos, though, because any such vars must refer to stuff above the
612- * level of the query we are pulling into.
613- */
614- IncrementVarSublevelsUp ((Node * )subquery ,-1 ,1 );
615622
616623/*
617- *Attach child RTE to parent rtable.
624+ *Calculate the index in the parent's range table
618625 */
619- parse -> rtable = lappend (parse -> rtable ,rte );
620- childRTindex = list_length (parse -> rtable );
626+ childRTindex = childRToffset + rtr -> rtindex ;
621627
622628/*
623629 * Build a suitable AppendRelInfo, and attach to parent's list.
@@ -649,8 +655,10 @@ pull_up_union_leaf_queries(Node *setOp, PlannerInfo *root, int parentRTindex,
649655SetOperationStmt * op = (SetOperationStmt * )setOp ;
650656
651657/* Recurse to reach leaf queries */
652- pull_up_union_leaf_queries (op -> larg ,root ,parentRTindex ,setOpQuery );
653- pull_up_union_leaf_queries (op -> rarg ,root ,parentRTindex ,setOpQuery );
658+ pull_up_union_leaf_queries (op -> larg ,root ,parentRTindex ,setOpQuery ,
659+ childRToffset );
660+ pull_up_union_leaf_queries (op -> rarg ,root ,parentRTindex ,setOpQuery ,
661+ childRToffset );
654662}
655663else
656664{