Fix LATERAL references to join alias variables.
I had thought this case worked already, but perhaps I didn't re-test it after adding extract_lateral_references() ...
This commit is contained in:
parent
f789909b59
commit
da3df99870
@ -49,13 +49,15 @@ planner_hook_type planner_hook = NULL;
|
|||||||
|
|
||||||
|
|
||||||
/* Expression kind codes for preprocess_expression */
|
/* Expression kind codes for preprocess_expression */
|
||||||
#define EXPRKIND_QUAL 0
|
#define EXPRKIND_QUAL 0
|
||||||
#define EXPRKIND_TARGET 1
|
#define EXPRKIND_TARGET 1
|
||||||
#define EXPRKIND_RTFUNC 2
|
#define EXPRKIND_RTFUNC 2
|
||||||
#define EXPRKIND_VALUES 3
|
#define EXPRKIND_RTFUNC_LATERAL 3
|
||||||
#define EXPRKIND_LIMIT 4
|
#define EXPRKIND_VALUES 4
|
||||||
#define EXPRKIND_APPINFO 5
|
#define EXPRKIND_VALUES_LATERAL 5
|
||||||
#define EXPRKIND_PHV 6
|
#define EXPRKIND_LIMIT 6
|
||||||
|
#define EXPRKIND_APPINFO 7
|
||||||
|
#define EXPRKIND_PHV 8
|
||||||
|
|
||||||
|
|
||||||
static Node *preprocess_expression(PlannerInfo *root, Node *expr, int kind);
|
static Node *preprocess_expression(PlannerInfo *root, Node *expr, int kind);
|
||||||
@ -438,18 +440,38 @@ subquery_planner(PlannerGlobal *glob, Query *parse,
|
|||||||
preprocess_expression(root, (Node *) root->append_rel_list,
|
preprocess_expression(root, (Node *) root->append_rel_list,
|
||||||
EXPRKIND_APPINFO);
|
EXPRKIND_APPINFO);
|
||||||
|
|
||||||
/* Also need to preprocess expressions for function and values RTEs */
|
/* Also need to preprocess expressions within RTEs */
|
||||||
foreach(l, parse->rtable)
|
foreach(l, parse->rtable)
|
||||||
{
|
{
|
||||||
RangeTblEntry *rte = (RangeTblEntry *) lfirst(l);
|
RangeTblEntry *rte = (RangeTblEntry *) lfirst(l);
|
||||||
|
int kind;
|
||||||
|
|
||||||
if (rte->rtekind == RTE_FUNCTION)
|
if (rte->rtekind == RTE_SUBQUERY)
|
||||||
rte->funcexpr = preprocess_expression(root, rte->funcexpr,
|
{
|
||||||
EXPRKIND_RTFUNC);
|
/*
|
||||||
|
* We don't want to do all preprocessing yet on the subquery's
|
||||||
|
* expressions, since that will happen when we plan it. But if it
|
||||||
|
* contains any join aliases of our level, those have to get
|
||||||
|
* expanded now, because planning of the subquery won't do it.
|
||||||
|
* That's only possible if the subquery is LATERAL.
|
||||||
|
*/
|
||||||
|
if (rte->lateral && root->hasJoinRTEs)
|
||||||
|
rte->subquery = (Query *)
|
||||||
|
flatten_join_alias_vars(root, (Node *) rte->subquery);
|
||||||
|
}
|
||||||
|
else if (rte->rtekind == RTE_FUNCTION)
|
||||||
|
{
|
||||||
|
/* Preprocess the function expression fully */
|
||||||
|
kind = rte->lateral ? EXPRKIND_RTFUNC_LATERAL : EXPRKIND_RTFUNC;
|
||||||
|
rte->funcexpr = preprocess_expression(root, rte->funcexpr, kind);
|
||||||
|
}
|
||||||
else if (rte->rtekind == RTE_VALUES)
|
else if (rte->rtekind == RTE_VALUES)
|
||||||
|
{
|
||||||
|
/* Preprocess the values lists fully */
|
||||||
|
kind = rte->lateral ? EXPRKIND_VALUES_LATERAL : EXPRKIND_VALUES;
|
||||||
rte->values_lists = (List *)
|
rte->values_lists = (List *)
|
||||||
preprocess_expression(root, (Node *) rte->values_lists,
|
preprocess_expression(root, (Node *) rte->values_lists, kind);
|
||||||
EXPRKIND_VALUES);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -593,12 +615,13 @@ preprocess_expression(PlannerInfo *root, Node *expr, int kind)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* If the query has any join RTEs, replace join alias variables with
|
* If the query has any join RTEs, replace join alias variables with
|
||||||
* base-relation variables. We must do this before sublink processing,
|
* base-relation variables. We must do this before sublink processing,
|
||||||
* else sublinks expanded out from join aliases wouldn't get processed. We
|
* else sublinks expanded out from join aliases would not get processed.
|
||||||
* can skip it in VALUES lists, however, since they can't contain any Vars
|
* We can skip it in non-lateral RTE functions and VALUES lists, however,
|
||||||
* at all.
|
* since they can't contain any Vars of the current query level.
|
||||||
*/
|
*/
|
||||||
if (root->hasJoinRTEs && kind != EXPRKIND_VALUES)
|
if (root->hasJoinRTEs &&
|
||||||
|
!(kind == EXPRKIND_RTFUNC || kind == EXPRKIND_VALUES))
|
||||||
expr = flatten_join_alias_vars(root, expr);
|
expr = flatten_join_alias_vars(root, expr);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -600,7 +600,9 @@ pull_var_clause_walker(Node *node, pull_var_clause_context *context)
|
|||||||
* hasSubLinks = TRUE, so this is only relevant to un-flattened subqueries.
|
* hasSubLinks = TRUE, so this is only relevant to un-flattened subqueries.
|
||||||
*
|
*
|
||||||
* NOTE: this is used on not-yet-planned expressions. We do not expect it
|
* NOTE: this is used on not-yet-planned expressions. We do not expect it
|
||||||
* to be applied directly to a Query node.
|
* to be applied directly to the whole Query, so if we see a Query to start
|
||||||
|
* with, we do want to increment sublevels_up (this occurs for LATERAL
|
||||||
|
* subqueries).
|
||||||
*/
|
*/
|
||||||
Node *
|
Node *
|
||||||
flatten_join_alias_vars(PlannerInfo *root, Node *node)
|
flatten_join_alias_vars(PlannerInfo *root, Node *node)
|
||||||
|
@ -3242,6 +3242,32 @@ select * from int8_tbl a,
|
|||||||
4567890123456789 | -4567890123456789 | 4567890123456789 | -4567890123456789 |
|
4567890123456789 | -4567890123456789 | 4567890123456789 | -4567890123456789 |
|
||||||
(57 rows)
|
(57 rows)
|
||||||
|
|
||||||
|
-- lateral reference to a join alias variable
|
||||||
|
select * from (select f1/2 as x from int4_tbl) ss1 join int4_tbl i4 on x = f1,
|
||||||
|
lateral (select x) ss2(y);
|
||||||
|
x | f1 | y
|
||||||
|
---+----+---
|
||||||
|
0 | 0 | 0
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
select * from (select f1 as x from int4_tbl) ss1 join int4_tbl i4 on x = f1,
|
||||||
|
lateral (values(x)) ss2(y);
|
||||||
|
x | f1 | y
|
||||||
|
-------------+-------------+-------------
|
||||||
|
0 | 0 | 0
|
||||||
|
123456 | 123456 | 123456
|
||||||
|
-123456 | -123456 | -123456
|
||||||
|
2147483647 | 2147483647 | 2147483647
|
||||||
|
-2147483647 | -2147483647 | -2147483647
|
||||||
|
(5 rows)
|
||||||
|
|
||||||
|
select * from ((select f1/2 as x from int4_tbl) ss1 join int4_tbl i4 on x = f1) j,
|
||||||
|
lateral (select x) ss2(y);
|
||||||
|
x | f1 | y
|
||||||
|
---+----+---
|
||||||
|
0 | 0 | 0
|
||||||
|
(1 row)
|
||||||
|
|
||||||
-- lateral references requiring pullup
|
-- lateral references requiring pullup
|
||||||
select * from (values(1)) x(lb),
|
select * from (values(1)) x(lb),
|
||||||
lateral generate_series(lb,4) x4;
|
lateral generate_series(lb,4) x4;
|
||||||
|
@ -901,6 +901,14 @@ select * from int8_tbl a,
|
|||||||
int8_tbl x left join lateral (select a.q1 from int4_tbl y) ss(z)
|
int8_tbl x left join lateral (select a.q1 from int4_tbl y) ss(z)
|
||||||
on x.q2 = ss.z;
|
on x.q2 = ss.z;
|
||||||
|
|
||||||
|
-- lateral reference to a join alias variable
|
||||||
|
select * from (select f1/2 as x from int4_tbl) ss1 join int4_tbl i4 on x = f1,
|
||||||
|
lateral (select x) ss2(y);
|
||||||
|
select * from (select f1 as x from int4_tbl) ss1 join int4_tbl i4 on x = f1,
|
||||||
|
lateral (values(x)) ss2(y);
|
||||||
|
select * from ((select f1/2 as x from int4_tbl) ss1 join int4_tbl i4 on x = f1) j,
|
||||||
|
lateral (select x) ss2(y);
|
||||||
|
|
||||||
-- lateral references requiring pullup
|
-- lateral references requiring pullup
|
||||||
select * from (values(1)) x(lb),
|
select * from (values(1)) x(lb),
|
||||||
lateral generate_series(lb,4) x4;
|
lateral generate_series(lb,4) x4;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user