Skip to content

Commit 489072a

Browse files
committed
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
1 parent 74563f6 commit 489072a

File tree

3 files changed

+84
-1
lines changed

3 files changed

+84
-1
lines changed

src/backend/optimizer/plan/analyzejoins.c

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -395,7 +395,34 @@ remove_rel_from_query(PlannerInfo *root, RelOptInfo *rel,
395395
}
396396

397397
/* Update lateral references. */
398-
replace_varno((Node *) otherrel->lateral_vars, relid, subst);
398+
if (root->hasLateralRTEs)
399+
{
400+
RangeTblEntry *rte = root->simple_rte_array[rti];
401+
ReplaceVarnoContext ctx = {.from = relid,.to = subst};
402+
403+
if (rte->lateral)
404+
{
405+
replace_varno((Node *) otherrel->lateral_vars, relid, subst);
406+
407+
/*
408+
* Although we pass root->parse through cleanup procedure,
409+
* but parse->rtable and rte contains refs to different copies
410+
* of the subquery.
411+
*/
412+
if (otherrel->rtekind == RTE_SUBQUERY)
413+
query_tree_walker(rte->subquery, replace_varno_walker, &ctx,
414+
QTW_EXAMINE_SORTGROUP);
415+
#ifdef USE_ASSERT_CHECKING
416+
/* Just check possibly hidden non-replaced relids */
417+
Assert(!bms_is_member(relid, pull_varnos(root, (Node *) rte->tablesample)));
418+
Assert(!bms_is_member(relid, pull_varnos(root, (Node *) rte->functions)));
419+
Assert(!bms_is_member(relid, pull_varnos(root, (Node *) rte->tablefunc)));
420+
Assert(!bms_is_member(relid, pull_varnos(root, (Node *) rte->values_lists)));
421+
#endif
422+
}
423+
}
424+
425+
399426
}
400427

401428
/*

src/test/regress/expected/join.out

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6349,6 +6349,50 @@ on true;
63496349
-> Seq Scan on int8_tbl y
63506350
(7 rows)
63516351

6352+
-- Test processing target lists in lateral subqueries
6353+
explain (verbose, costs off)
6354+
SELECT t3.a FROM sj t1, sj t2,
6355+
LATERAL (SELECT t1.a WHERE t1.a <> 1
6356+
GROUP BY (t1.a) HAVING t1.a > 0 ORDER BY t1.a LIMIT 1) t3,
6357+
LATERAL (SELECT t1.a,t3.a WHERE t1.a <> t3.a+t2.a
6358+
GROUP BY (t3.a) HAVING t1.a > t3.a*t3.a+t2.a/t1.a LIMIT 2) t4,
6359+
LATERAL (SELECT * FROM sj TABLESAMPLE bernoulli(t1.a/t2.a)
6360+
REPEATABLE (t1.a+t2.a)) t5,
6361+
LATERAL generate_series(1, t1.a + t2.a) AS t6
6362+
WHERE t1.a = t2.a;
6363+
QUERY PLAN
6364+
-------------------------------------------------------------------------------------------------------------------------------
6365+
Nested Loop
6366+
Output: (t2.a)
6367+
-> Nested Loop
6368+
Output: t2.a, (t2.a)
6369+
-> Nested Loop
6370+
Output: t2.a, (t2.a)
6371+
-> Nested Loop
6372+
Output: t2.a, (t2.a)
6373+
-> Seq Scan on public.sj t2
6374+
Output: t2.a, t2.b, t2.c
6375+
Filter: (t2.a IS NOT NULL)
6376+
-> Limit
6377+
Output: (t2.a)
6378+
-> Group
6379+
Output: t2.a
6380+
-> Result
6381+
One-Time Filter: ((t2.a <> 1) AND (t2.a > 0))
6382+
-> Limit
6383+
Output: NULL::integer, ((t2.a))
6384+
-> Group
6385+
Output: NULL::integer, (t2.a)
6386+
-> Result
6387+
One-Time Filter: ((t2.a <> ((t2.a) + t2.a)) AND (t2.a > (((t2.a) * (t2.a)) + (t2.a / t2.a))))
6388+
-> Sample Scan on public.sj
6389+
Output: sj.a, sj.b, sj.c
6390+
Sampling: bernoulli ((t2.a / t2.a)) REPEATABLE ((t2.a + t2.a))
6391+
-> Function Scan on pg_catalog.generate_series t6
6392+
Output: t6.t6
6393+
Function Call: generate_series(1, (t2.a + t2.a))
6394+
(29 rows)
6395+
63526396
-- Check updating of Lateral links from top-level query to the removing relation
63536397
explain (COSTS OFF)
63546398
SELECT * FROM pg_am am WHERE am.amname IN (

src/test/regress/sql/join.sql

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2406,6 +2406,18 @@ left join (select coalesce(y.q1, 1) from int8_tbl y
24062406
on true) z
24072407
on true;
24082408

2409+
-- Test processing target lists in lateral subqueries
2410+
explain (verbose, costs off)
2411+
SELECT t3.a FROM sj t1, sj t2,
2412+
LATERAL (SELECT t1.a WHERE t1.a <> 1
2413+
GROUP BY (t1.a) HAVING t1.a > 0 ORDER BY t1.a LIMIT 1) t3,
2414+
LATERAL (SELECT t1.a,t3.a WHERE t1.a <> t3.a+t2.a
2415+
GROUP BY (t3.a) HAVING t1.a > t3.a*t3.a+t2.a/t1.a LIMIT 2) t4,
2416+
LATERAL (SELECT * FROM sj TABLESAMPLE bernoulli(t1.a/t2.a)
2417+
REPEATABLE (t1.a+t2.a)) t5,
2418+
LATERAL generate_series(1, t1.a + t2.a) AS t6
2419+
WHERE t1.a = t2.a;
2420+
24092421
-- Check updating of Lateral links from top-level query to the removing relation
24102422
explain (COSTS OFF)
24112423
SELECT * FROM pg_am am WHERE am.amname IN (

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