Replace relids in lateral subquery parse tree during SJE
Reported-by: Alexander Lakhin Discussion: https://postgr.es/m/56ee4520-e9d1-d519-54fe-c8bff880ce9b%40gmail.com Author: Alexander Korotkov, Andrei Lepikhov
This commit is contained in:
parent
74563f6b90
commit
489072ab7a
|
@ -395,7 +395,34 @@ remove_rel_from_query(PlannerInfo *root, RelOptInfo *rel,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update lateral references. */
|
/* Update lateral references. */
|
||||||
replace_varno((Node *) otherrel->lateral_vars, relid, subst);
|
if (root->hasLateralRTEs)
|
||||||
|
{
|
||||||
|
RangeTblEntry *rte = root->simple_rte_array[rti];
|
||||||
|
ReplaceVarnoContext ctx = {.from = relid,.to = subst};
|
||||||
|
|
||||||
|
if (rte->lateral)
|
||||||
|
{
|
||||||
|
replace_varno((Node *) otherrel->lateral_vars, relid, subst);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Although we pass root->parse through cleanup procedure,
|
||||||
|
* but parse->rtable and rte contains refs to different copies
|
||||||
|
* of the subquery.
|
||||||
|
*/
|
||||||
|
if (otherrel->rtekind == RTE_SUBQUERY)
|
||||||
|
query_tree_walker(rte->subquery, replace_varno_walker, &ctx,
|
||||||
|
QTW_EXAMINE_SORTGROUP);
|
||||||
|
#ifdef USE_ASSERT_CHECKING
|
||||||
|
/* Just check possibly hidden non-replaced relids */
|
||||||
|
Assert(!bms_is_member(relid, pull_varnos(root, (Node *) rte->tablesample)));
|
||||||
|
Assert(!bms_is_member(relid, pull_varnos(root, (Node *) rte->functions)));
|
||||||
|
Assert(!bms_is_member(relid, pull_varnos(root, (Node *) rte->tablefunc)));
|
||||||
|
Assert(!bms_is_member(relid, pull_varnos(root, (Node *) rte->values_lists)));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -6349,6 +6349,50 @@ on true;
|
||||||
-> Seq Scan on int8_tbl y
|
-> Seq Scan on int8_tbl y
|
||||||
(7 rows)
|
(7 rows)
|
||||||
|
|
||||||
|
-- Test processing target lists in lateral subqueries
|
||||||
|
explain (verbose, costs off)
|
||||||
|
SELECT t3.a FROM sj t1, sj t2,
|
||||||
|
LATERAL (SELECT t1.a WHERE t1.a <> 1
|
||||||
|
GROUP BY (t1.a) HAVING t1.a > 0 ORDER BY t1.a LIMIT 1) t3,
|
||||||
|
LATERAL (SELECT t1.a,t3.a WHERE t1.a <> t3.a+t2.a
|
||||||
|
GROUP BY (t3.a) HAVING t1.a > t3.a*t3.a+t2.a/t1.a LIMIT 2) t4,
|
||||||
|
LATERAL (SELECT * FROM sj TABLESAMPLE bernoulli(t1.a/t2.a)
|
||||||
|
REPEATABLE (t1.a+t2.a)) t5,
|
||||||
|
LATERAL generate_series(1, t1.a + t2.a) AS t6
|
||||||
|
WHERE t1.a = t2.a;
|
||||||
|
QUERY PLAN
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
Nested Loop
|
||||||
|
Output: (t2.a)
|
||||||
|
-> Nested Loop
|
||||||
|
Output: t2.a, (t2.a)
|
||||||
|
-> Nested Loop
|
||||||
|
Output: t2.a, (t2.a)
|
||||||
|
-> Nested Loop
|
||||||
|
Output: t2.a, (t2.a)
|
||||||
|
-> Seq Scan on public.sj t2
|
||||||
|
Output: t2.a, t2.b, t2.c
|
||||||
|
Filter: (t2.a IS NOT NULL)
|
||||||
|
-> Limit
|
||||||
|
Output: (t2.a)
|
||||||
|
-> Group
|
||||||
|
Output: t2.a
|
||||||
|
-> Result
|
||||||
|
One-Time Filter: ((t2.a <> 1) AND (t2.a > 0))
|
||||||
|
-> Limit
|
||||||
|
Output: NULL::integer, ((t2.a))
|
||||||
|
-> Group
|
||||||
|
Output: NULL::integer, (t2.a)
|
||||||
|
-> Result
|
||||||
|
One-Time Filter: ((t2.a <> ((t2.a) + t2.a)) AND (t2.a > (((t2.a) * (t2.a)) + (t2.a / t2.a))))
|
||||||
|
-> Sample Scan on public.sj
|
||||||
|
Output: sj.a, sj.b, sj.c
|
||||||
|
Sampling: bernoulli ((t2.a / t2.a)) REPEATABLE ((t2.a + t2.a))
|
||||||
|
-> Function Scan on pg_catalog.generate_series t6
|
||||||
|
Output: t6.t6
|
||||||
|
Function Call: generate_series(1, (t2.a + t2.a))
|
||||||
|
(29 rows)
|
||||||
|
|
||||||
-- Check updating of Lateral links from top-level query to the removing relation
|
-- Check updating of Lateral links from top-level query to the removing relation
|
||||||
explain (COSTS OFF)
|
explain (COSTS OFF)
|
||||||
SELECT * FROM pg_am am WHERE am.amname IN (
|
SELECT * FROM pg_am am WHERE am.amname IN (
|
||||||
|
|
|
@ -2406,6 +2406,18 @@ left join (select coalesce(y.q1, 1) from int8_tbl y
|
||||||
on true) z
|
on true) z
|
||||||
on true;
|
on true;
|
||||||
|
|
||||||
|
-- Test processing target lists in lateral subqueries
|
||||||
|
explain (verbose, costs off)
|
||||||
|
SELECT t3.a FROM sj t1, sj t2,
|
||||||
|
LATERAL (SELECT t1.a WHERE t1.a <> 1
|
||||||
|
GROUP BY (t1.a) HAVING t1.a > 0 ORDER BY t1.a LIMIT 1) t3,
|
||||||
|
LATERAL (SELECT t1.a,t3.a WHERE t1.a <> t3.a+t2.a
|
||||||
|
GROUP BY (t3.a) HAVING t1.a > t3.a*t3.a+t2.a/t1.a LIMIT 2) t4,
|
||||||
|
LATERAL (SELECT * FROM sj TABLESAMPLE bernoulli(t1.a/t2.a)
|
||||||
|
REPEATABLE (t1.a+t2.a)) t5,
|
||||||
|
LATERAL generate_series(1, t1.a + t2.a) AS t6
|
||||||
|
WHERE t1.a = t2.a;
|
||||||
|
|
||||||
-- Check updating of Lateral links from top-level query to the removing relation
|
-- Check updating of Lateral links from top-level query to the removing relation
|
||||||
explain (COSTS OFF)
|
explain (COSTS OFF)
|
||||||
SELECT * FROM pg_am am WHERE am.amname IN (
|
SELECT * FROM pg_am am WHERE am.amname IN (
|
||||||
|
|
Loading…
Reference in New Issue