diff options
| author | Tom Lane <tgl@sss.pgh.pa.us> | 2012-08-11 18:42:20 -0400 |
|---|---|---|
| committer | Tom Lane <tgl@sss.pgh.pa.us> | 2012-08-11 18:42:56 -0400 |
| commit | e76af54137c051cafcb1e39f68383a31d1d55ff6 (patch) | |
| tree | 3aebae04ee3afdbccc059ea941ba8921b5620776 /src/backend/optimizer/prep/prepjointree.c | |
| parent | 83af58f6b5657840f5924332fccecca1e3556abe (diff) | |
Fix some issues with LATERAL(SELECT UNION ALL SELECT).
The LATERAL marking has to be propagated down to the UNION leaf queries
when we pull them up. Also, fix the formerly stubbed-off
set_append_rel_pathlist(). It does already have enough smarts to cope with
making a parameterized Append path at need; it just has to not assume that
there *must* be an unparameterized path.
Diffstat (limited to 'src/backend/optimizer/prep/prepjointree.c')
| -rw-r--r-- | src/backend/optimizer/prep/prepjointree.c | 39 |
1 files changed, 32 insertions, 7 deletions
diff --git a/src/backend/optimizer/prep/prepjointree.c b/src/backend/optimizer/prep/prepjointree.c index 06dbe845404..07b35f98bd1 100644 --- a/src/backend/optimizer/prep/prepjointree.c +++ b/src/backend/optimizer/prep/prepjointree.c @@ -995,20 +995,45 @@ pull_up_simple_union_all(PlannerInfo *root, Node *jtnode, RangeTblEntry *rte) { int varno = ((RangeTblRef *) jtnode)->rtindex; Query *subquery = rte->subquery; - int rtoffset; + int rtoffset = list_length(root->parse->rtable); List *rtable; /* - * Append child RTEs to parent rtable. - * + * Make a modifiable copy of the subquery's rtable, so we can adjust + * upper-level Vars in it. There are no such Vars in the setOperations + * tree proper, so fixing the rtable should be sufficient. + */ + rtable = copyObject(subquery->rtable); + + /* * Upper-level vars in subquery are now one level closer to their parent * than before. We don't have to worry about offsetting varnos, though, - * because any such vars must refer to stuff above the level of the query - * we are pulling into. + * because the UNION leaf queries can't cross-reference each other. */ - rtoffset = list_length(root->parse->rtable); - rtable = copyObject(subquery->rtable); IncrementVarSublevelsUp_rtable(rtable, -1, 1); + + /* + * If the UNION ALL subquery had a LATERAL marker, propagate that to all + * its children. The individual children might or might not contain any + * actual lateral cross-references, but we have to mark the pulled-up + * child RTEs so that later planner stages will check for such. + */ + if (rte->lateral) + { + ListCell *rt; + + foreach(rt, rtable) + { + RangeTblEntry *child_rte = (RangeTblEntry *) lfirst(rt); + + Assert(child_rte->rtekind == RTE_SUBQUERY); + child_rte->lateral = true; + } + } + + /* + * Append child RTEs to parent rtable. + */ root->parse->rtable = list_concat(root->parse->rtable, rtable); /* |
