16
16
*
17
17
*
18
18
* IDENTIFICATION
19
- * $PostgreSQL: pgsql/src/backend/optimizer/prep/prepjointree.c,v 1.51 2008/08/14 18:47:59 tgl Exp $
19
+ * $PostgreSQL: pgsql/src/backend/optimizer/prep/prepjointree.c,v 1.52 2008/08/14 20:31:29 heikki Exp $
20
20
*
21
21
*-------------------------------------------------------------------------
22
22
*/
@@ -47,7 +47,8 @@ static Node *pull_up_simple_subquery(PlannerInfo *root, Node *jtnode,
47
47
static Node * pull_up_simple_union_all (PlannerInfo * root , Node * jtnode ,
48
48
RangeTblEntry * rte );
49
49
static void pull_up_union_leaf_queries (Node * setOp , PlannerInfo * root ,
50
- int parentRTindex , Query * setOpQuery );
50
+ int parentRTindex , Query * setOpQuery ,
51
+ int childRToffset );
51
52
static void make_setop_translation_lists (Query * query ,
52
53
Index newvarno ,
53
54
List * * col_mappings , List * * translated_vars );
@@ -560,14 +561,34 @@ pull_up_simple_union_all(PlannerInfo *root, Node *jtnode, RangeTblEntry *rte)
560
561
{
561
562
int varno = ((RangeTblRef * ) jtnode )-> rtindex ;
562
563
Query * subquery = rte -> subquery ;
564
+ int rtoffset ;
565
+ List * rtable ;
563
566
564
567
/*
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.
568
588
*/
569
589
Assert (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 );
571
592
572
593
/*
573
594
* Mark the parent as an append relation.
@@ -583,41 +604,26 @@ pull_up_simple_union_all(PlannerInfo *root, Node *jtnode, RangeTblEntry *rte)
583
604
* Note that setOpQuery is the Query containing the setOp node, whose rtable
584
605
* is where to look up the RTE if setOp is a RangeTblRef. This is *not* the
585
606
* same as root->parse, which is the top-level Query we are pulling up into.
607
+ *
586
608
* 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.
587
612
*/
588
613
static void
589
614
pull_up_union_leaf_queries (Node * setOp , PlannerInfo * root , int parentRTindex ,
590
- Query * setOpQuery )
615
+ Query * setOpQuery , int childRToffset )
591
616
{
592
617
if (IsA (setOp , RangeTblRef ))
593
618
{
594
619
RangeTblRef * rtr = (RangeTblRef * ) setOp ;
595
- RangeTblEntry * rte = rt_fetch (rtr -> rtindex , setOpQuery -> rtable );
596
- Query * subquery ;
597
620
int childRTindex ;
598
621
AppendRelInfo * 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 );
615
622
616
623
/*
617
- * Attach child RTE to parent rtable.
624
+ * Calculate the index in the parent's range table
618
625
*/
619
- parse -> rtable = lappend (parse -> rtable , rte );
620
- childRTindex = list_length (parse -> rtable );
626
+ childRTindex = childRToffset + rtr -> rtindex ;
621
627
622
628
/*
623
629
* 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,
649
655
SetOperationStmt * op = (SetOperationStmt * ) setOp ;
650
656
651
657
/* 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 );
654
662
}
655
663
else
656
664
{
0 commit comments