Skip to content

Commit f24f233

Browse files
committed
Fix pull_up_simple_union_all to copy all rtable entries from child subquery to
parent, not only those with RangeTblRefs. We need them in ExecCheckRTPerms. Report by Brendan O'Shea. Back-patch to 8.2, where pull_up_simple_union_all was introduced.
1 parent e006a24 commit f24f233

File tree

3 files changed

+61
-32
lines changed

3 files changed

+61
-32
lines changed

src/backend/optimizer/prep/prepjointree.c

Lines changed: 38 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
*
1717
*
1818
* 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 $
2020
*
2121
*-------------------------------------------------------------------------
2222
*/
@@ -47,7 +47,8 @@ static Node *pull_up_simple_subquery(PlannerInfo *root, Node *jtnode,
4747
static Node *pull_up_simple_union_all(PlannerInfo *root, Node *jtnode,
4848
RangeTblEntry *rte);
4949
static void pull_up_union_leaf_queries(Node *setOp, PlannerInfo *root,
50-
int parentRTindex, Query *setOpQuery);
50+
int parentRTindex, Query *setOpQuery,
51+
int childRToffset);
5152
static void make_setop_translation_lists(Query *query,
5253
Index newvarno,
5354
List **col_mappings, List **translated_vars);
@@ -560,14 +561,34 @@ pull_up_simple_union_all(PlannerInfo *root, Node *jtnode, RangeTblEntry *rte)
560561
{
561562
int varno = ((RangeTblRef *) jtnode)->rtindex;
562563
Query *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
*/
569589
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);
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
*/
588613
static void
589614
pull_up_union_leaf_queries(Node *setOp, PlannerInfo *root, int parentRTindex,
590-
Query *setOpQuery)
615+
Query *setOpQuery, int childRToffset)
591616
{
592617
if (IsA(setOp, RangeTblRef))
593618
{
594619
RangeTblRef *rtr = (RangeTblRef *) setOp;
595-
RangeTblEntry *rte = rt_fetch(rtr->rtindex, setOpQuery->rtable);
596-
Query *subquery;
597620
int childRTindex;
598621
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);
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,
649655
SetOperationStmt *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
}
655663
else
656664
{

src/backend/rewrite/rewriteManip.c

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $PostgreSQL: pgsql/src/backend/rewrite/rewriteManip.c,v 1.108 2008/08/14 18:47:59 tgl Exp $
10+
* $PostgreSQL: pgsql/src/backend/rewrite/rewriteManip.c,v 1.109 2008/08/14 20:31:29 heikki Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -533,6 +533,25 @@ IncrementVarSublevelsUp(Node *node, int delta_sublevels_up,
533533
0);
534534
}
535535

536+
/*
537+
* IncrementVarSublevelsUp_rtable -
538+
* Same as IncrementVarSublevelsUp, but to be invoked on a range table.
539+
*/
540+
void
541+
IncrementVarSublevelsUp_rtable(List *rtable, int delta_sublevels_up,
542+
int min_sublevels_up)
543+
{
544+
IncrementVarSublevelsUp_context context;
545+
546+
context.delta_sublevels_up = delta_sublevels_up;
547+
context.min_sublevels_up = min_sublevels_up;
548+
549+
range_table_walker(rtable,
550+
IncrementVarSublevelsUp_walker,
551+
(void *) &context,
552+
0);
553+
}
554+
536555

537556
/*
538557
* rangeTableEntry_used - detect whether an RTE is referenced somewhere

src/include/rewrite/rewriteManip.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/include/rewrite/rewriteManip.h,v 1.44 2008/01/01 19:45:58 momjian Exp $
10+
* $PostgreSQL: pgsql/src/include/rewrite/rewriteManip.h,v 1.45 2008/08/14 20:31:29 heikki Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -22,6 +22,8 @@ extern void ChangeVarNodes(Node *node, int old_varno, int new_varno,
2222
int sublevels_up);
2323
extern void IncrementVarSublevelsUp(Node *node, int delta_sublevels_up,
2424
int min_sublevels_up);
25+
extern void IncrementVarSublevelsUp_rtable(List *rtable,
26+
int delta_sublevels_up, int min_sublevels_up);
2527

2628
extern bool rangeTableEntry_used(Node *node, int rt_index,
2729
int sublevels_up);

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy