From 147b5cc81537fc646e6908268f0a5ba1b658fc7f Mon Sep 17 00:00:00 2001 From: Richard Guo Date: Tue, 20 Jan 2026 19:32:08 +0900 Subject: [PATCH v3 2/2] Fixing test cases This optimization improves plans for many queries in the regression tests. However, it also reduces coverage in tests specifically designed to verify the planner's handling of PlaceHolderVars. To maintain this coverage, this patch modifies the affected queries to force the preservation of PHVs by changing target expressions into forms that the new logic considers unsafe to strip. --- .../postgres_fdw/expected/postgres_fdw.out | 14 +- contrib/postgres_fdw/sql/postgres_fdw.sql | 4 +- src/test/regress/expected/groupingsets.out | 19 +- src/test/regress/expected/join.out | 225 +++++++++--------- src/test/regress/expected/memoize.out | 16 +- src/test/regress/expected/partition_join.out | 50 ++-- src/test/regress/sql/join.sql | 73 +++--- src/test/regress/sql/memoize.sql | 8 +- src/test/regress/sql/partition_join.sql | 24 +- 9 files changed, 227 insertions(+), 206 deletions(-) diff --git a/contrib/postgres_fdw/expected/postgres_fdw.out b/contrib/postgres_fdw/expected/postgres_fdw.out index 6066510c7c0..017f20939f9 100644 --- a/contrib/postgres_fdw/expected/postgres_fdw.out +++ b/contrib/postgres_fdw/expected/postgres_fdw.out @@ -3841,7 +3841,7 @@ FROM "S 1"."T 1" AS ref_0, LATERAL ( SELECT ref_0."C 1" c1, subq_0.* - FROM (SELECT ref_0.c2, ref_1.c3 + FROM (SELECT ref_0.c2::bigint, ref_1.c3 FROM ft1 AS ref_1) AS subq_0 RIGHT JOIN ft2 AS ref_3 ON (subq_0.c3 = ref_3.c3) ) AS subq_1 @@ -3850,18 +3850,18 @@ ORDER BY ref_0."C 1"; QUERY PLAN --------------------------------------------------------------------------------------------------------- Nested Loop - Output: ref_0.c2, ref_0."C 1", (ref_0.c2), ref_1.c3, ref_0."C 1" + Output: ref_0.c2, ref_0."C 1", ((ref_0.c2)::bigint), ref_1.c3, ref_0."C 1" -> Nested Loop - Output: ref_0.c2, ref_0."C 1", ref_1.c3, (ref_0.c2) + Output: ref_0.c2, ref_0."C 1", ref_1.c3, ((ref_0.c2)::bigint) -> Index Scan using t1_pkey on "S 1"."T 1" ref_0 Output: ref_0."C 1", ref_0.c2, ref_0.c3, ref_0.c4, ref_0.c5, ref_0.c6, ref_0.c7, ref_0.c8 Index Cond: (ref_0."C 1" < 10) -> Memoize - Output: ref_1.c3, (ref_0.c2) - Cache Key: ref_0.c2 + Output: ref_1.c3, ((ref_0.c2)::bigint) + Cache Key: (ref_0.c2)::bigint Cache Mode: binary -> Foreign Scan on public.ft1 ref_1 - Output: ref_1.c3, ref_0.c2 + Output: ref_1.c3, (ref_0.c2)::bigint Remote SQL: SELECT c3 FROM "S 1"."T 1" WHERE ((c3 = '00001')) -> Materialize Output: ref_3.c3 @@ -3875,7 +3875,7 @@ FROM "S 1"."T 1" AS ref_0, LATERAL ( SELECT ref_0."C 1" c1, subq_0.* - FROM (SELECT ref_0.c2, ref_1.c3 + FROM (SELECT ref_0.c2::bigint, ref_1.c3 FROM ft1 AS ref_1) AS subq_0 RIGHT JOIN ft2 AS ref_3 ON (subq_0.c3 = ref_3.c3) ) AS subq_1 diff --git a/contrib/postgres_fdw/sql/postgres_fdw.sql b/contrib/postgres_fdw/sql/postgres_fdw.sql index 4f7ab2ed0ac..929959e8b85 100644 --- a/contrib/postgres_fdw/sql/postgres_fdw.sql +++ b/contrib/postgres_fdw/sql/postgres_fdw.sql @@ -1100,7 +1100,7 @@ FROM "S 1"."T 1" AS ref_0, LATERAL ( SELECT ref_0."C 1" c1, subq_0.* - FROM (SELECT ref_0.c2, ref_1.c3 + FROM (SELECT ref_0.c2::bigint, ref_1.c3 FROM ft1 AS ref_1) AS subq_0 RIGHT JOIN ft2 AS ref_3 ON (subq_0.c3 = ref_3.c3) ) AS subq_1 @@ -1112,7 +1112,7 @@ FROM "S 1"."T 1" AS ref_0, LATERAL ( SELECT ref_0."C 1" c1, subq_0.* - FROM (SELECT ref_0.c2, ref_1.c3 + FROM (SELECT ref_0.c2::bigint, ref_1.c3 FROM ft1 AS ref_1) AS subq_0 RIGHT JOIN ft2 AS ref_3 ON (subq_0.c3 = ref_3.c3) ) AS subq_1 diff --git a/src/test/regress/expected/groupingsets.out b/src/test/regress/expected/groupingsets.out index 921017489c0..68d44f12925 100644 --- a/src/test/regress/expected/groupingsets.out +++ b/src/test/regress/expected/groupingsets.out @@ -566,22 +566,19 @@ select * from ( group by grouping sets(1, 2) ) ss where x = 1 and q1 = 123; - QUERY PLAN --------------------------------------------------- + QUERY PLAN +-------------------------------------------- Subquery Scan on ss Output: ss.x, ss.q1, ss.sum Filter: ((ss.x = 1) AND (ss.q1 = 123)) -> GroupAggregate Output: (1), i1.q1, sum(i1.q2) - Group Key: (1) + Group Key: 1 Sort Key: i1.q1 Group Key: i1.q1 - -> Sort - Output: (1), i1.q1, i1.q2 - Sort Key: (1) - -> Seq Scan on public.int8_tbl i1 - Output: 1, i1.q1, i1.q2 -(13 rows) + -> Seq Scan on public.int8_tbl i1 + Output: 1, i1.q1, i1.q2 +(10 rows) select * from ( select 1 as x, q1, sum(q2) @@ -2617,8 +2614,8 @@ select 1 as one group by rollup(one) order by one nulls first; ----------------------------- Sort Sort Key: (1) NULLS FIRST - -> MixedAggregate - Hash Key: 1 + -> GroupAggregate + Group Key: 1 Group Key: () -> Result (6 rows) diff --git a/src/test/regress/expected/join.out b/src/test/regress/expected/join.out index d05a0ca0373..22756ed0364 100644 --- a/src/test/regress/expected/join.out +++ b/src/test/regress/expected/join.out @@ -36,6 +36,16 @@ create temp table onerow(); insert into onerow default values; analyze onerow; -- +-- A STABLE, non-inlinable identity function used to +-- prevent the planner from stripping no-op PHVs in some tests. +-- +CREATE OR REPLACE FUNCTION phv(anyelement) +RETURNS anyelement AS $$ +BEGIN + RETURN $1; +END; +$$ LANGUAGE plpgsql STABLE COST 0.00001; +-- -- CORRELATION NAMES -- Make sure that table/column aliases are supported -- before diving into more complex join syntax. @@ -3687,13 +3697,13 @@ from nt3 as nt3 (select nt2.*, (nt2.b1 and ss1.a3) AS b3 from nt2 as nt2 left join - (select nt1.*, (nt1.id is not null) as a3 from nt1) as ss1 + (select nt1.*, (nt1.id > 0 and nt1.id < 5) as a3 from nt1) as ss1 on ss1.id = nt2.nt1_id ) as ss2 on ss2.id = nt3.nt2_id where nt3.id = 1 and ss2.b3; - QUERY PLAN ----------------------------------------------- + QUERY PLAN +------------------------------------------------------ Nested Loop -> Nested Loop -> Index Scan using nt3_pkey on nt3 @@ -3702,7 +3712,7 @@ where nt3.id = 1 and ss2.b3; Index Cond: (id = nt3.nt2_id) -> Index Only Scan using nt1_pkey on nt1 Index Cond: (id = nt2.nt1_id) - Filter: (nt2.b1 AND true) + Filter: (nt2.b1 AND ((id > 0) AND (id < 5))) (9 rows) select nt3.id @@ -3711,7 +3721,7 @@ from nt3 as nt3 (select nt2.*, (nt2.b1 and ss1.a3) AS b3 from nt2 as nt2 left join - (select nt1.*, (nt1.id is not null) as a3 from nt1) as ss1 + (select nt1.*, (nt1.id > 0 and nt1.id < 5) as a3 from nt1) as ss1 on ss1.id = nt2.nt1_id ) as ss2 on ss2.id = nt3.nt2_id @@ -3776,20 +3786,20 @@ select * from int4_tbl as i41, lateral (select 1 as x from - (select i41.f1 as lat, + (select phv(i41.f1) as lat, i42.f1 as loc from int8_tbl as i81, int4_tbl as i42) as ss1 right join int4_tbl as i43 on (i43.f1 > 1) where ss1.loc = ss1.lat) as ss2 where i41.f1 > 0; - QUERY PLAN --------------------------------------------------- + QUERY PLAN +--------------------------------------------------- Nested Loop -> Nested Loop -> Seq Scan on int4_tbl i41 Filter: (f1 > 0) -> Nested Loop - Join Filter: (i42.f1 = i41.f1) + Join Filter: (i42.f1 = phv(i41.f1)) -> Seq Scan on int8_tbl i81 -> Materialize -> Seq Scan on int4_tbl i42 @@ -3802,7 +3812,7 @@ select * from int4_tbl as i41, lateral (select 1 as x from - (select i41.f1 as lat, + (select phv(i41.f1) as lat, i42.f1 as loc from int8_tbl as i81, int4_tbl as i42) as ss1 right join int4_tbl as i43 on (i43.f1 > 1) @@ -3955,28 +3965,28 @@ explain (costs off) select t1.unique2, t1.stringu1, t2.unique1, t2.stringu2 from tenk1 t1 inner join int4_tbl i1 - left join (select v1.x2, v2.y1, 11 AS d1 + left join (select v1.x2, v2.y1, phv(11) AS d1 from (select 1,0 from onerow) v1(x1,x2) - left join (select 3,1 from onerow) v2(y1,y2) + left join (select phv(3),1 from onerow) v2(y1,y2) on v1.x1 = v2.y2) subq1 on (i1.f1 = subq1.x2) on (t1.unique2 = subq1.d1) left join tenk1 t2 on (subq1.y1 = t2.unique1) where t1.unique2 < 42 and t1.stringu1 > t2.stringu2; - QUERY PLAN ------------------------------------------------------------------------ + QUERY PLAN +---------------------------------------------------------------------- Nested Loop -> Nested Loop Join Filter: (t1.stringu1 > t2.stringu2) -> Nested Loop -> Nested Loop - -> Seq Scan on onerow -> Seq Scan on onerow onerow_1 - -> Index Scan using tenk1_unique2 on tenk1 t1 - Index Cond: ((unique2 = (11)) AND (unique2 < 42)) - -> Index Scan using tenk1_unique1 on tenk1 t2 - Index Cond: (unique1 = (3)) + -> Index Scan using tenk1_unique1 on tenk1 t2 + Index Cond: (unique1 = (phv(3))) + -> Seq Scan on onerow + -> Index Scan using tenk1_unique2 on tenk1 t1 + Index Cond: ((unique2 = (phv(11))) AND (unique2 < 42)) -> Seq Scan on int4_tbl i1 Filter: (f1 = 0) (13 rows) @@ -3984,9 +3994,9 @@ where t1.unique2 < 42 and t1.stringu1 > t2.stringu2; select t1.unique2, t1.stringu1, t2.unique1, t2.stringu2 from tenk1 t1 inner join int4_tbl i1 - left join (select v1.x2, v2.y1, 11 AS d1 + left join (select v1.x2, v2.y1, phv(11) AS d1 from (select 1,0 from onerow) v1(x1,x2) - left join (select 3,1 from onerow) v2(y1,y2) + left join (select phv(3),1 from onerow) v2(y1,y2) on v1.x1 = v2.y2) subq1 on (i1.f1 = subq1.x2) on (t1.unique2 = subq1.d1) @@ -4076,34 +4086,34 @@ explain (costs off) select t1.unique2, t1.stringu1, t2.unique1, t2.stringu2 from tenk1 t1 inner join int4_tbl i1 - left join (select v1.x2, v2.y1, 11 AS d1 + left join (select v1.x2, v2.y1, phv(11) AS d1 from (values(1,0)) v1(x1,x2) - left join (values(3,1)) v2(y1,y2) + left join (values(phv(3),1)) v2(y1,y2) on v1.x1 = v2.y2) subq1 on (i1.f1 = subq1.x2) on (t1.unique2 = subq1.d1) left join tenk1 t2 on (subq1.y1 = t2.unique1) where t1.unique2 < 42 and t1.stringu1 > t2.stringu2; - QUERY PLAN ------------------------------------------------------------------ + QUERY PLAN +---------------------------------------------------------------------- Nested Loop Join Filter: (t1.stringu1 > t2.stringu2) -> Nested Loop -> Seq Scan on int4_tbl i1 Filter: (f1 = 0) -> Index Scan using tenk1_unique2 on tenk1 t1 - Index Cond: ((unique2 = (11)) AND (unique2 < 42)) + Index Cond: ((unique2 = (phv(11))) AND (unique2 < 42)) -> Index Scan using tenk1_unique1 on tenk1 t2 - Index Cond: (unique1 = (3)) + Index Cond: (unique1 = (phv(3))) (9 rows) select t1.unique2, t1.stringu1, t2.unique1, t2.stringu2 from tenk1 t1 inner join int4_tbl i1 - left join (select v1.x2, v2.y1, 11 AS d1 + left join (select v1.x2, v2.y1, phv(11) AS d1 from (values(1,0)) v1(x1,x2) - left join (values(3,1)) v2(y1,y2) + left join (values(phv(3),1)) v2(y1,y2) on v1.x1 = v2.y2) subq1 on (i1.f1 = subq1.x2) on (t1.unique2 = subq1.d1) @@ -4119,22 +4129,22 @@ where t1.unique2 < 42 and t1.stringu1 > t2.stringu2; -- or we end up with noplace to evaluate the lateral PHV explain (verbose, costs off) select * from - (select 1 as x) ss1 left join (select 2 as y) ss2 on (true), + (select 1 as x) ss1 left join (select phv(2) as y) ss2 on (true), lateral (select ss2.y as z limit 1) ss3; - QUERY PLAN ---------------------------- + QUERY PLAN +----------------------------------- Nested Loop - Output: 1, (2), ((2)) + Output: 1, (phv(2)), ((phv(2))) -> Result - Output: 2 + Output: phv(2) -> Limit - Output: ((2)) + Output: ((phv(2))) -> Result - Output: (2) + Output: (phv(2)) (8 rows) select * from - (select 1 as x) ss1 left join (select 2 as y) ss2 on (true), + (select 1 as x) ss1 left join (select phv(2) as y) ss2 on (true), lateral (select ss2.y as z limit 1) ss3; x | y | z ---+---+--- @@ -4213,25 +4223,25 @@ select * from t t1 explain (verbose, costs off) select * from (select k from - (select i, coalesce(i, j) as k from + (select i, (i > 0 and j > 0) as k from (select i from t union all select 0) join (select 1 as j limit 1) on i = j) right join (select 2 as x) on true join (select 3 as y) on i is not null ), lateral (select k as kl limit 1); - QUERY PLAN -------------------------------------------------------------------- + QUERY PLAN +-------------------------------------------------------------------- Nested Loop - Output: COALESCE(t.i, (1)), ((COALESCE(t.i, (1)))) + Output: ((t.i > 0) AND ((1) > 0)), ((((t.i > 0) AND ((1) > 0)))) -> Limit Output: 1 -> Result Output: 1 -> Nested Loop - Output: t.i, ((COALESCE(t.i, (1)))) + Output: t.i, ((((t.i > 0) AND ((1) > 0)))) -> Result - Output: t.i, COALESCE(t.i, (1)) + Output: t.i, ((t.i > 0) AND ((1) > 0)) -> Append -> Index Only Scan using t_pkey on pg_temp.t Output: t.i @@ -4240,9 +4250,9 @@ select * from Output: 0 One-Time Filter: ((1) = 0) -> Limit - Output: ((COALESCE(t.i, (1)))) + Output: ((((t.i > 0) AND ((1) > 0)))) -> Result - Output: (COALESCE(t.i, (1))) + Output: (((t.i > 0) AND ((1) > 0))) (21 rows) rollback; @@ -4336,26 +4346,26 @@ explain (costs off) select * from (select 0 as z) as t1 left join - (select true as a) as t2 + (select phv(true) as a) as t2 on true, lateral (select true as b union all select a as b) as t3 where b; - QUERY PLAN ---------------------------------------- + QUERY PLAN +-------------------------------------------- Nested Loop -> Result -> Append -> Result -> Result - One-Time Filter: (true) + One-Time Filter: (phv(true)) (6 rows) select * from (select 0 as z) as t1 left join - (select true as a) as t2 + (select phv(true) as a) as t2 on true, lateral (select true as b union all @@ -5138,8 +5148,8 @@ select t1.* from on (t1.f1 = b1.d1) left join int4_tbl i4 on (i8.q2 = i4.f1); - QUERY PLAN ----------------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------------------- Hash Left Join Output: t1.f1 Hash Cond: (i8.q2 = i4.f1) @@ -5150,22 +5160,22 @@ select t1.* from Output: t1.f1 -> Materialize Output: i8.q2 - -> Hash Right Join + -> Nested Loop Left Join Output: i8.q2 - Hash Cond: ((NULL::integer) = i8b1.q2) - -> Hash Join - Output: i8.q2, (NULL::integer) - Hash Cond: (i8.q1 = i8b2.q1) - -> Seq Scan on public.int8_tbl i8 - Output: i8.q1, i8.q2 - -> Hash - Output: i8b2.q1, (NULL::integer) - -> Seq Scan on public.int8_tbl i8b2 - Output: i8b2.q1, NULL::integer - -> Hash - Output: i8b1.q2 - -> Seq Scan on public.int8_tbl i8b1 - Output: i8b1.q2 + Join Filter: (NULL::integer = i8b1.q2) + -> Seq Scan on public.int8_tbl i8b1 + Output: i8b1.q1, i8b1.q2 + -> Materialize + Output: i8.q2 + -> Hash Join + Output: i8.q2 + Hash Cond: (i8.q1 = i8b2.q1) + -> Seq Scan on public.int8_tbl i8 + Output: i8.q1, i8.q2 + -> Hash + Output: i8b2.q1 + -> Seq Scan on public.int8_tbl i8b2 + Output: i8b2.q1 -> Hash Output: i4.f1 -> Seq Scan on public.int4_tbl i4 @@ -5630,18 +5640,18 @@ explain (verbose, costs off) select ss2.* from int4_tbl i41 left join int8_tbl i8 - join (select i42.f1 as c1, i43.f1 as c2, 42 as c3 + join (select i42.f1 as c1, i43.f1 as c2, phv(42) as c3 from int4_tbl i42, int4_tbl i43) ss1 on i8.q1 = ss1.c2 on i41.f1 = ss1.c1, lateral (select i41.*, i8.*, ss1.* from text_tbl limit 1) ss2 where ss1.c2 = 0; - QUERY PLAN ------------------------------------------------------------------------- + QUERY PLAN +----------------------------------------------------------------------------- Nested Loop - Output: (i41.f1), (i8.q1), (i8.q2), (i42.f1), (i43.f1), ((42)) + Output: (i41.f1), (i8.q1), (i8.q2), (i42.f1), (i43.f1), ((phv(42))) -> Hash Join - Output: i41.f1, i42.f1, i8.q1, i8.q2, i43.f1, 42 + Output: i41.f1, i42.f1, i8.q1, i8.q2, i43.f1, phv(42) Hash Cond: (i41.f1 = i42.f1) -> Nested Loop Output: i8.q1, i8.q2, i43.f1, i41.f1 @@ -5660,15 +5670,15 @@ where ss1.c2 = 0; -> Seq Scan on public.int4_tbl i42 Output: i42.f1 -> Limit - Output: (i41.f1), (i8.q1), (i8.q2), (i42.f1), (i43.f1), ((42)) + Output: (i41.f1), (i8.q1), (i8.q2), (i42.f1), (i43.f1), ((phv(42))) -> Seq Scan on public.text_tbl - Output: i41.f1, i8.q1, i8.q2, i42.f1, i43.f1, (42) + Output: i41.f1, i8.q1, i8.q2, i42.f1, i43.f1, (phv(42)) (25 rows) select ss2.* from int4_tbl i41 left join int8_tbl i8 - join (select i42.f1 as c1, i43.f1 as c2, 42 as c3 + join (select i42.f1 as c1, i43.f1 as c2, phv(42) as c3 from int4_tbl i42, int4_tbl i43) ss1 on i8.q1 = ss1.c2 on i41.f1 = ss1.c1, @@ -6237,8 +6247,8 @@ select d.* from d left join (select 1 as x from b group by rollup(x)) s Hash Cond: (d.a = (1)) -> Seq Scan on d -> Hash - -> MixedAggregate - Hash Key: 1 + -> GroupAggregate + Group Key: 1 Group Key: () -> Seq Scan on b (8 rows) @@ -6781,19 +6791,19 @@ insert into t values (1,1), (2,2); explain (costs off) select 1 from t t1 - left join (select t2.a, 1 as c + left join (select t2.a, phv(1) as c from t t2 left join t t3 on t2.a = t3.a) s on true left join t t4 on true where s.a < s.c; - QUERY PLAN -------------------------------------- + QUERY PLAN +------------------------------------------ Nested Loop Left Join -> Nested Loop -> Seq Scan on t t1 -> Materialize -> Seq Scan on t t2 - Filter: (a < 1) + Filter: (a < phv(1)) -> Materialize -> Seq Scan on t t4 (8 rows) @@ -6806,13 +6816,13 @@ from t t1 on true left join t t4 on true where s.a < s.c; - QUERY PLAN ------------------------------------------------ + QUERY PLAN +--------------------------------------------------- Nested Loop Left Join -> Nested Loop -> Seq Scan on t t1 - -> Seq Scan on t t2 - Filter: (a < COALESCE(t1.a, 1)) + -> Index Only Scan using t_a_key on t t2 + Index Cond: (a < COALESCE(t1.a, 1)) -> Materialize -> Seq Scan on t t4 (7 rows) @@ -6836,15 +6846,15 @@ explain (verbose, costs off) select i8.*, ss.v, t.unique2 from int8_tbl i8 left join int4_tbl i4 on i4.f1 = 1 - left join lateral (select i4.f1 + 1 as v) as ss on true + left join lateral (select phv(i4.f1 + 1) as v) as ss on true left join tenk1 t on t.unique2 = ss.v where q2 = 456; QUERY PLAN ------------------------------------------------------------- Nested Loop Left Join - Output: i8.q1, i8.q2, ((i4.f1 + 1)), t.unique2 + Output: i8.q1, i8.q2, (phv((i4.f1 + 1))), t.unique2 -> Nested Loop Left Join - Output: i8.q1, i8.q2, (i4.f1 + 1) + Output: i8.q1, i8.q2, phv((i4.f1 + 1)) -> Seq Scan on public.int8_tbl i8 Output: i8.q1, i8.q2 Filter: (i8.q2 = 456) @@ -6853,13 +6863,13 @@ where q2 = 456; Filter: (i4.f1 = 1) -> Index Only Scan using tenk1_unique2 on public.tenk1 t Output: t.unique2 - Index Cond: (t.unique2 = ((i4.f1 + 1))) + Index Cond: (t.unique2 = (phv((i4.f1 + 1)))) (13 rows) select i8.*, ss.v, t.unique2 from int8_tbl i8 left join int4_tbl i4 on i4.f1 = 1 - left join lateral (select i4.f1 + 1 as v) as ss on true + left join lateral (select phv(i4.f1 + 1) as v) as ss on true left join tenk1 t on t.unique2 = ss.v where q2 = 456; q1 | q2 | v | unique2 @@ -6874,20 +6884,20 @@ create temp table parttbl1 partition of parttbl for values from (1) to (100); insert into parttbl values (11), (12); explain (costs off) select * from - (select *, 12 as phv from parttbl) as ss + (select *, phv(12) as phv from parttbl) as ss right join int4_tbl on true where ss.a = ss.phv and f1 = 0; QUERY PLAN ------------------------------------ Nested Loop -> Seq Scan on parttbl1 parttbl - Filter: (a = 12) + Filter: (a = phv(12)) -> Seq Scan on int4_tbl Filter: (f1 = 0) (5 rows) select * from - (select *, 12 as phv from parttbl) as ss + (select *, phv(12) as phv from parttbl) as ss right join int4_tbl on true where ss.a = ss.phv and f1 = 0; a | phv | f1 @@ -7670,7 +7680,7 @@ on true; -- not implemented yet. explain (verbose, costs off) select 1 from emp1 t1 left join - ((select 1 as x, * from emp1 t2) s1 inner join + ((select phv(1) as x, * from emp1 t2) s1 inner join (select * from emp1 t3) s2 on s1.id = s2.id) on true where s1.x = 1; @@ -7684,7 +7694,7 @@ where s1.x = 1; Output: t3.id -> Seq Scan on public.emp1 t3 Output: t3.id - Filter: (1 = 1) + Filter: (phv(1) = 1) (9 rows) -- Check that PHVs do not impose any constraints on removing self joins @@ -7731,7 +7741,7 @@ INSERT INTO tbl_phv (x, y) VACUUM ANALYZE tbl_phv; EXPLAIN (COSTS OFF, VERBOSE) SELECT 1 FROM tbl_phv t1 LEFT JOIN - (SELECT 1 extra, x, y FROM tbl_phv tl) t3 JOIN + (SELECT phv(1) extra, x, y FROM tbl_phv tl) t3 JOIN (SELECT y FROM tbl_phv tr) t4 ON t4.y = t3.y ON true WHERE t3.extra IS NOT NULL AND t3.x = t1.x % 2; @@ -7744,7 +7754,7 @@ ON true WHERE t3.extra IS NOT NULL AND t3.x = t1.x % 2; -> Index Scan using tbl_phv_idx on public.tbl_phv tr Output: tr.x, tr.y Index Cond: (tr.x = (t1.x % 2)) - Filter: (1 IS NOT NULL) + Filter: (phv(1) IS NOT NULL) (8 rows) DROP TABLE IF EXISTS tbl_phv; @@ -8881,23 +8891,23 @@ select * from explain (verbose, costs off) select * from (select 0 as val0) as ss0 - left join (select 1 as val) as ss1 on true + left join (select phv(1) as val) as ss1 on true left join lateral (select ss1.val as val_filtered where false) as ss2 on true; - QUERY PLAN --------------------------------- + QUERY PLAN +----------------------------------- Nested Loop Left Join - Output: 0, (1), ((1)) + Output: 0, (phv(1)), ((phv(1))) Join Filter: false -> Result - Output: 1 + Output: phv(1) -> Result - Output: (1) + Output: (phv(1)) One-Time Filter: false (8 rows) select * from (select 0 as val0) as ss0 - left join (select 1 as val) as ss1 on true + left join (select phv(1) as val) as ss1 on true left join lateral (select ss1.val as val_filtered where false) as ss2 on true; val0 | val | val_filtered ------+-----+-------------- @@ -9885,20 +9895,20 @@ DROP TABLE group_tbl; -- Test that we ignore PlaceHolderVars when looking up statistics EXPLAIN (COSTS OFF) SELECT t1.unique1 FROM tenk1 t1 LEFT JOIN - (SELECT *, 42 AS phv FROM tenk1 t2) ss ON t1.unique2 = ss.unique2 + (SELECT *, phv(42) AS phv FROM tenk1 t2) ss ON t1.unique2 = ss.unique2 WHERE ss.unique1 = ss.phv AND t1.unique1 < 100; QUERY PLAN -------------------------------------------------- Nested Loop -> Seq Scan on tenk1 t2 - Filter: (unique1 = 42) + Filter: (unique1 = phv(42)) -> Index Scan using tenk1_unique2 on tenk1 t1 Index Cond: (unique2 = t2.unique2) Filter: (unique1 < 100) (6 rows) SELECT t1.unique1 FROM tenk1 t1 LEFT JOIN - (SELECT *, 42 AS phv FROM tenk1 t2) ss ON t1.unique2 = ss.unique2 + (SELECT *, phv(42) AS phv FROM tenk1 t2) ss ON t1.unique2 = ss.unique2 WHERE ss.unique1 = ss.phv AND t1.unique1 < 100; unique1 --------- @@ -9947,3 +9957,4 @@ SELECT COUNT(*) FROM onek t1 LEFT JOIN tenk1 t2 19000 (1 row) +DROP FUNCTION phv(anyelement); diff --git a/src/test/regress/expected/memoize.out b/src/test/regress/expected/memoize.out index 00c30b91459..708cea644d9 100644 --- a/src/test/regress/expected/memoize.out +++ b/src/test/regress/expected/memoize.out @@ -138,7 +138,7 @@ WHERE t1.unique1 < 10; -- Try with LATERAL references within PlaceHolderVars SELECT explain_memoize(' SELECT COUNT(*), AVG(t1.twenty) FROM tenk1 t1 LEFT JOIN -LATERAL (SELECT t1.two+1 AS c1, t2.unique1 AS c2 FROM tenk1 t2) s ON TRUE +LATERAL (SELECT (t1.two+1)::bigint AS c1, t2.unique1 AS c2 FROM tenk1 t2) s ON TRUE WHERE s.c1 = s.c2 AND t1.unique1 < 1000;', false); explain_memoize ---------------------------------------------------------------------------------------------- @@ -148,11 +148,11 @@ WHERE s.c1 = s.c2 AND t1.unique1 < 1000;', false); Filter: (unique1 < 1000) Rows Removed by Filter: 9000 -> Memoize (actual rows=1.00 loops=N) - Cache Key: (t1.two + 1) + Cache Key: ((t1.two + 1))::bigint Cache Mode: binary Hits: 998 Misses: 2 Evictions: Zero Overflows: 0 Memory Usage: NkB -> Index Only Scan using tenk1_unique1 on tenk1 t2 (actual rows=1.00 loops=N) - Filter: ((t1.two + 1) = unique1) + Filter: (((t1.two + 1))::bigint = unique1) Rows Removed by Filter: 9999 Heap Fetches: N Index Searches: N @@ -160,7 +160,7 @@ WHERE s.c1 = s.c2 AND t1.unique1 < 1000;', false); -- And check we get the expected results. SELECT COUNT(*), AVG(t1.twenty) FROM tenk1 t1 LEFT JOIN -LATERAL (SELECT t1.two+1 AS c1, t2.unique1 AS c2 FROM tenk1 t2) s ON TRUE +LATERAL (SELECT (t1.two+1)::bigint AS c1, t2.unique1 AS c2 FROM tenk1 t2) s ON TRUE WHERE s.c1 = s.c2 AND t1.unique1 < 1000; count | avg -------+-------------------- @@ -170,7 +170,7 @@ WHERE s.c1 = s.c2 AND t1.unique1 < 1000; -- Ensure we do not omit the cache keys from PlaceHolderVars SELECT explain_memoize(' SELECT COUNT(*), AVG(t1.twenty) FROM tenk1 t1 LEFT JOIN -LATERAL (SELECT t1.twenty AS c1, t2.unique1 AS c2, t2.two FROM tenk1 t2) s +LATERAL (SELECT t1.twenty::bigint AS c1, t2.unique1 AS c2, t2.two FROM tenk1 t2) s ON t1.two = s.two WHERE s.c1 = s.c2 AND t1.unique1 < 1000;', false); explain_memoize @@ -181,17 +181,17 @@ WHERE s.c1 = s.c2 AND t1.unique1 < 1000;', false); Filter: (unique1 < 1000) Rows Removed by Filter: 9000 -> Memoize (actual rows=1.00 loops=N) - Cache Key: t1.two, t1.twenty + Cache Key: t1.two, (t1.twenty)::bigint Cache Mode: binary Hits: 980 Misses: 20 Evictions: Zero Overflows: 0 Memory Usage: NkB -> Seq Scan on tenk1 t2 (actual rows=1.00 loops=N) - Filter: ((t1.twenty = unique1) AND (t1.two = two)) + Filter: (((t1.twenty)::bigint = unique1) AND (t1.two = two)) Rows Removed by Filter: 9999 (12 rows) -- And check we get the expected results. SELECT COUNT(*), AVG(t1.twenty) FROM tenk1 t1 LEFT JOIN -LATERAL (SELECT t1.twenty AS c1, t2.unique1 AS c2, t2.two FROM tenk1 t2) s +LATERAL (SELECT t1.twenty::bigint AS c1, t2.unique1 AS c2, t2.two FROM tenk1 t2) s ON t1.two = s.two WHERE s.c1 = s.c2 AND t1.unique1 < 1000; count | avg diff --git a/src/test/regress/expected/partition_join.out b/src/test/regress/expected/partition_join.out index f6d3ade368a..e9f9515ea3d 100644 --- a/src/test/regress/expected/partition_join.out +++ b/src/test/regress/expected/partition_join.out @@ -576,8 +576,8 @@ SELECT * FROM prt1 t1 JOIN LATERAL -- lateral reference in scan's restriction clauses EXPLAIN (COSTS OFF) SELECT count(*) FROM prt1 t1 LEFT JOIN LATERAL - (SELECT t1.b AS t1b, t2.* FROM prt2 t2) s - ON t1.a = s.b WHERE s.t1b = s.a; + (SELECT (t1.b >= 0 AND t1.b = a) AS t1b, t2.* FROM prt2 t2) s + ON t1.a = s.b WHERE s.t1b; QUERY PLAN --------------------------------------------------------------- Aggregate @@ -586,22 +586,22 @@ SELECT count(*) FROM prt1 t1 LEFT JOIN LATERAL -> Seq Scan on prt1_p1 t1_1 -> Index Scan using iprt2_p1_b on prt2_p1 t2_1 Index Cond: (b = t1_1.a) - Filter: (t1_1.b = a) + Filter: ((t1_1.b >= 0) AND (t1_1.b = a)) -> Nested Loop -> Seq Scan on prt1_p2 t1_2 -> Index Scan using iprt2_p2_b on prt2_p2 t2_2 Index Cond: (b = t1_2.a) - Filter: (t1_2.b = a) + Filter: ((t1_2.b >= 0) AND (t1_2.b = a)) -> Nested Loop -> Seq Scan on prt1_p3 t1_3 -> Index Scan using iprt2_p3_b on prt2_p3 t2_3 Index Cond: (b = t1_3.a) - Filter: (t1_3.b = a) + Filter: ((t1_3.b >= 0) AND (t1_3.b = a)) (17 rows) SELECT count(*) FROM prt1 t1 LEFT JOIN LATERAL - (SELECT t1.b AS t1b, t2.* FROM prt2 t2) s - ON t1.a = s.b WHERE s.t1b = s.a; + (SELECT (t1.b >= 0 AND t1.b = a) AS t1b, t2.* FROM prt2 t2) s + ON t1.a = s.b WHERE s.t1b; count ------- 100 @@ -609,8 +609,8 @@ SELECT count(*) FROM prt1 t1 LEFT JOIN LATERAL EXPLAIN (COSTS OFF) SELECT count(*) FROM prt1 t1 LEFT JOIN LATERAL - (SELECT t1.b AS t1b, t2.* FROM prt2 t2) s - ON t1.a = s.b WHERE s.t1b = s.b; + (SELECT (t1.b >= 0 AND t1.b = b) AS t1b, t2.* FROM prt2 t2) s + ON t1.a = s.b WHERE s.t1b; QUERY PLAN -------------------------------------------------------------------- Aggregate @@ -619,22 +619,22 @@ SELECT count(*) FROM prt1 t1 LEFT JOIN LATERAL -> Seq Scan on prt1_p1 t1_1 -> Index Only Scan using iprt2_p1_b on prt2_p1 t2_1 Index Cond: (b = t1_1.a) - Filter: (b = t1_1.b) + Filter: ((t1_1.b >= 0) AND (t1_1.b = b)) -> Nested Loop -> Seq Scan on prt1_p2 t1_2 -> Index Only Scan using iprt2_p2_b on prt2_p2 t2_2 Index Cond: (b = t1_2.a) - Filter: (b = t1_2.b) + Filter: ((t1_2.b >= 0) AND (t1_2.b = b)) -> Nested Loop -> Seq Scan on prt1_p3 t1_3 -> Index Only Scan using iprt2_p3_b on prt2_p3 t2_3 Index Cond: (b = t1_3.a) - Filter: (b = t1_3.b) + Filter: ((t1_3.b >= 0) AND (t1_3.b = b)) (17 rows) SELECT count(*) FROM prt1 t1 LEFT JOIN LATERAL - (SELECT t1.b AS t1b, t2.* FROM prt2 t2) s - ON t1.a = s.b WHERE s.t1b = s.b; + (SELECT (t1.b >= 0 AND t1.b = b) AS t1b, t2.* FROM prt2 t2) s + ON t1.a = s.b WHERE s.t1b; count ------- 5 @@ -2200,39 +2200,39 @@ SELECT * FROM prt1_l t1 JOIN LATERAL -- partitionwise join with lateral reference in scan's restriction clauses EXPLAIN (COSTS OFF) SELECT COUNT(*) FROM prt1_l t1 LEFT JOIN LATERAL - (SELECT t1.b AS t1b, t2.* FROM prt2_l t2) s + (SELECT (t1.b >= 0 AND t1.b = a) AS t1b, t2.* FROM prt2_l t2) s ON t1.a = s.b AND t1.b = s.a AND t1.c = s.c - WHERE s.t1b = s.a; - QUERY PLAN ---------------------------------------------------------------------------------------------------------------- + WHERE s.t1b; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------- Aggregate -> Append -> Nested Loop -> Seq Scan on prt1_l_p1 t1_1 -> Seq Scan on prt2_l_p1 t2_1 - Filter: ((a = t1_1.b) AND (t1_1.a = b) AND (t1_1.b = a) AND ((t1_1.c)::text = (c)::text)) + Filter: (((t1_1.b >= 0) AND (t1_1.b = a)) AND (t1_1.a = b) AND (t1_1.b = a) AND ((t1_1.c)::text = (c)::text)) -> Nested Loop -> Seq Scan on prt1_l_p2_p1 t1_2 -> Seq Scan on prt2_l_p2_p1 t2_2 - Filter: ((a = t1_2.b) AND (t1_2.a = b) AND (t1_2.b = a) AND ((t1_2.c)::text = (c)::text)) + Filter: (((t1_2.b >= 0) AND (t1_2.b = a)) AND (t1_2.a = b) AND (t1_2.b = a) AND ((t1_2.c)::text = (c)::text)) -> Nested Loop -> Seq Scan on prt1_l_p2_p2 t1_3 -> Seq Scan on prt2_l_p2_p2 t2_3 - Filter: ((a = t1_3.b) AND (t1_3.a = b) AND (t1_3.b = a) AND ((t1_3.c)::text = (c)::text)) + Filter: (((t1_3.b >= 0) AND (t1_3.b = a)) AND (t1_3.a = b) AND (t1_3.b = a) AND ((t1_3.c)::text = (c)::text)) -> Nested Loop -> Seq Scan on prt1_l_p3_p1 t1_4 -> Seq Scan on prt2_l_p3_p1 t2_4 - Filter: ((a = t1_4.b) AND (t1_4.a = b) AND (t1_4.b = a) AND ((t1_4.c)::text = (c)::text)) + Filter: (((t1_4.b >= 0) AND (t1_4.b = a)) AND (t1_4.a = b) AND (t1_4.b = a) AND ((t1_4.c)::text = (c)::text)) -> Nested Loop -> Seq Scan on prt1_l_p3_p2 t1_5 -> Seq Scan on prt2_l_p3_p2 t2_5 - Filter: ((a = t1_5.b) AND (t1_5.a = b) AND (t1_5.b = a) AND ((t1_5.c)::text = (c)::text)) + Filter: (((t1_5.b >= 0) AND (t1_5.b = a)) AND (t1_5.a = b) AND (t1_5.b = a) AND ((t1_5.c)::text = (c)::text)) (22 rows) SELECT COUNT(*) FROM prt1_l t1 LEFT JOIN LATERAL - (SELECT t1.b AS t1b, t2.* FROM prt2_l t2) s + (SELECT (t1.b >= 0 AND t1.b = a) AS t1b, t2.* FROM prt2_l t2) s ON t1.a = s.b AND t1.b = s.a AND t1.c = s.c - WHERE s.t1b = s.a; + WHERE s.t1b; count ------- 100 diff --git a/src/test/regress/sql/join.sql b/src/test/regress/sql/join.sql index b91fb7574df..8adaedb63ad 100644 --- a/src/test/regress/sql/join.sql +++ b/src/test/regress/sql/join.sql @@ -42,6 +42,17 @@ create temp table onerow(); insert into onerow default values; analyze onerow; +-- +-- A STABLE, non-inlinable identity function used to +-- prevent the planner from stripping no-op PHVs in some tests. +-- +CREATE OR REPLACE FUNCTION phv(anyelement) +RETURNS anyelement AS $$ +BEGIN + RETURN $1; +END; +$$ LANGUAGE plpgsql STABLE COST 0.00001; + -- -- CORRELATION NAMES @@ -1169,7 +1180,7 @@ from nt3 as nt3 (select nt2.*, (nt2.b1 and ss1.a3) AS b3 from nt2 as nt2 left join - (select nt1.*, (nt1.id is not null) as a3 from nt1) as ss1 + (select nt1.*, (nt1.id > 0 and nt1.id < 5) as a3 from nt1) as ss1 on ss1.id = nt2.nt1_id ) as ss2 on ss2.id = nt3.nt2_id @@ -1181,7 +1192,7 @@ from nt3 as nt3 (select nt2.*, (nt2.b1 and ss1.a3) AS b3 from nt2 as nt2 left join - (select nt1.*, (nt1.id is not null) as a3 from nt1) as ss1 + (select nt1.*, (nt1.id > 0 and nt1.id < 5) as a3 from nt1) as ss1 on ss1.id = nt2.nt1_id ) as ss2 on ss2.id = nt3.nt2_id @@ -1217,7 +1228,7 @@ select * from int4_tbl as i41, lateral (select 1 as x from - (select i41.f1 as lat, + (select phv(i41.f1) as lat, i42.f1 as loc from int8_tbl as i81, int4_tbl as i42) as ss1 right join int4_tbl as i43 on (i43.f1 > 1) @@ -1228,7 +1239,7 @@ select * from int4_tbl as i41, lateral (select 1 as x from - (select i41.f1 as lat, + (select phv(i41.f1) as lat, i42.f1 as loc from int8_tbl as i81, int4_tbl as i42) as ss1 right join int4_tbl as i43 on (i43.f1 > 1) @@ -1279,9 +1290,9 @@ explain (costs off) select t1.unique2, t1.stringu1, t2.unique1, t2.stringu2 from tenk1 t1 inner join int4_tbl i1 - left join (select v1.x2, v2.y1, 11 AS d1 + left join (select v1.x2, v2.y1, phv(11) AS d1 from (select 1,0 from onerow) v1(x1,x2) - left join (select 3,1 from onerow) v2(y1,y2) + left join (select phv(3),1 from onerow) v2(y1,y2) on v1.x1 = v2.y2) subq1 on (i1.f1 = subq1.x2) on (t1.unique2 = subq1.d1) @@ -1292,9 +1303,9 @@ where t1.unique2 < 42 and t1.stringu1 > t2.stringu2; select t1.unique2, t1.stringu1, t2.unique1, t2.stringu2 from tenk1 t1 inner join int4_tbl i1 - left join (select v1.x2, v2.y1, 11 AS d1 + left join (select v1.x2, v2.y1, phv(11) AS d1 from (select 1,0 from onerow) v1(x1,x2) - left join (select 3,1 from onerow) v2(y1,y2) + left join (select phv(3),1 from onerow) v2(y1,y2) on v1.x1 = v2.y2) subq1 on (i1.f1 = subq1.x2) on (t1.unique2 = subq1.d1) @@ -1343,9 +1354,9 @@ explain (costs off) select t1.unique2, t1.stringu1, t2.unique1, t2.stringu2 from tenk1 t1 inner join int4_tbl i1 - left join (select v1.x2, v2.y1, 11 AS d1 + left join (select v1.x2, v2.y1, phv(11) AS d1 from (values(1,0)) v1(x1,x2) - left join (values(3,1)) v2(y1,y2) + left join (values(phv(3),1)) v2(y1,y2) on v1.x1 = v2.y2) subq1 on (i1.f1 = subq1.x2) on (t1.unique2 = subq1.d1) @@ -1356,9 +1367,9 @@ where t1.unique2 < 42 and t1.stringu1 > t2.stringu2; select t1.unique2, t1.stringu1, t2.unique1, t2.stringu2 from tenk1 t1 inner join int4_tbl i1 - left join (select v1.x2, v2.y1, 11 AS d1 + left join (select v1.x2, v2.y1, phv(11) AS d1 from (values(1,0)) v1(x1,x2) - left join (values(3,1)) v2(y1,y2) + left join (values(phv(3),1)) v2(y1,y2) on v1.x1 = v2.y2) subq1 on (i1.f1 = subq1.x2) on (t1.unique2 = subq1.d1) @@ -1370,10 +1381,10 @@ where t1.unique2 < 42 and t1.stringu1 > t2.stringu2; -- or we end up with noplace to evaluate the lateral PHV explain (verbose, costs off) select * from - (select 1 as x) ss1 left join (select 2 as y) ss2 on (true), + (select 1 as x) ss1 left join (select phv(2) as y) ss2 on (true), lateral (select ss2.y as z limit 1) ss3; select * from - (select 1 as x) ss1 left join (select 2 as y) ss2 on (true), + (select 1 as x) ss1 left join (select phv(2) as y) ss2 on (true), lateral (select ss2.y as z limit 1) ss3; -- This example demonstrates the folly of our old "have_dangerous_phv" logic @@ -1401,7 +1412,7 @@ select * from t t1 explain (verbose, costs off) select * from (select k from - (select i, coalesce(i, j) as k from + (select i, (i > 0 and j > 0) as k from (select i from t union all select 0) join (select 1 as j limit 1) on i = j) right join (select 2 as x) on true @@ -1439,7 +1450,7 @@ explain (costs off) select * from (select 0 as z) as t1 left join - (select true as a) as t2 + (select phv(true) as a) as t2 on true, lateral (select true as b union all @@ -1449,7 +1460,7 @@ where b; select * from (select 0 as z) as t1 left join - (select true as a) as t2 + (select phv(true) as a) as t2 on true, lateral (select true as b union all @@ -1978,7 +1989,7 @@ explain (verbose, costs off) select ss2.* from int4_tbl i41 left join int8_tbl i8 - join (select i42.f1 as c1, i43.f1 as c2, 42 as c3 + join (select i42.f1 as c1, i43.f1 as c2, phv(42) as c3 from int4_tbl i42, int4_tbl i43) ss1 on i8.q1 = ss1.c2 on i41.f1 = ss1.c1, @@ -1988,7 +1999,7 @@ where ss1.c2 = 0; select ss2.* from int4_tbl i41 left join int8_tbl i8 - join (select i42.f1 as c1, i43.f1 as c2, 42 as c3 + join (select i42.f1 as c1, i43.f1 as c2, phv(42) as c3 from int4_tbl i42, int4_tbl i43) ss1 on i8.q1 = ss1.c2 on i41.f1 = ss1.c1, @@ -2551,7 +2562,7 @@ insert into t values (1,1), (2,2); explain (costs off) select 1 from t t1 - left join (select t2.a, 1 as c + left join (select t2.a, phv(1) as c from t t2 left join t t3 on t2.a = t3.a) s on true left join t t4 on true @@ -2581,14 +2592,14 @@ explain (verbose, costs off) select i8.*, ss.v, t.unique2 from int8_tbl i8 left join int4_tbl i4 on i4.f1 = 1 - left join lateral (select i4.f1 + 1 as v) as ss on true + left join lateral (select phv(i4.f1 + 1) as v) as ss on true left join tenk1 t on t.unique2 = ss.v where q2 = 456; select i8.*, ss.v, t.unique2 from int8_tbl i8 left join int4_tbl i4 on i4.f1 = 1 - left join lateral (select i4.f1 + 1 as v) as ss on true + left join lateral (select phv(i4.f1 + 1) as v) as ss on true left join tenk1 t on t.unique2 = ss.v where q2 = 456; @@ -2599,12 +2610,12 @@ create temp table parttbl1 partition of parttbl for values from (1) to (100); insert into parttbl values (11), (12); explain (costs off) select * from - (select *, 12 as phv from parttbl) as ss + (select *, phv(12) as phv from parttbl) as ss right join int4_tbl on true where ss.a = ss.phv and f1 = 0; select * from - (select *, 12 as phv from parttbl) as ss + (select *, phv(12) as phv from parttbl) as ss right join int4_tbl on true where ss.a = ss.phv and f1 = 0; @@ -2957,7 +2968,7 @@ on true; -- not implemented yet. explain (verbose, costs off) select 1 from emp1 t1 left join - ((select 1 as x, * from emp1 t2) s1 inner join + ((select phv(1) as x, * from emp1 t2) s1 inner join (select * from emp1 t3) s2 on s1.id = s2.id) on true where s1.x = 1; @@ -2986,7 +2997,7 @@ INSERT INTO tbl_phv (x, y) VACUUM ANALYZE tbl_phv; EXPLAIN (COSTS OFF, VERBOSE) SELECT 1 FROM tbl_phv t1 LEFT JOIN - (SELECT 1 extra, x, y FROM tbl_phv tl) t3 JOIN + (SELECT phv(1) extra, x, y FROM tbl_phv tl) t3 JOIN (SELECT y FROM tbl_phv tr) t4 ON t4.y = t3.y ON true WHERE t3.extra IS NOT NULL AND t3.x = t1.x % 2; @@ -3332,12 +3343,12 @@ select * from explain (verbose, costs off) select * from (select 0 as val0) as ss0 - left join (select 1 as val) as ss1 on true + left join (select phv(1) as val) as ss1 on true left join lateral (select ss1.val as val_filtered where false) as ss2 on true; select * from (select 0 as val0) as ss0 - left join (select 1 as val) as ss1 on true + left join (select phv(1) as val) as ss1 on true left join lateral (select ss1.val as val_filtered where false) as ss2 on true; -- case that breaks the old ph_may_need optimization @@ -3767,11 +3778,11 @@ DROP TABLE group_tbl; -- Test that we ignore PlaceHolderVars when looking up statistics EXPLAIN (COSTS OFF) SELECT t1.unique1 FROM tenk1 t1 LEFT JOIN - (SELECT *, 42 AS phv FROM tenk1 t2) ss ON t1.unique2 = ss.unique2 + (SELECT *, phv(42) AS phv FROM tenk1 t2) ss ON t1.unique2 = ss.unique2 WHERE ss.unique1 = ss.phv AND t1.unique1 < 100; SELECT t1.unique1 FROM tenk1 t1 LEFT JOIN - (SELECT *, 42 AS phv FROM tenk1 t2) ss ON t1.unique2 = ss.unique2 + (SELECT *, phv(42) AS phv FROM tenk1 t2) ss ON t1.unique2 = ss.unique2 WHERE ss.unique1 = ss.phv AND t1.unique1 < 100; -- @@ -3790,3 +3801,5 @@ SELECT COUNT(*) FROM onek t1 LEFT JOIN tenk1 t2 ON (t2.thousand = t1.tenthous OR t2.thousand = t1.thousand); SELECT COUNT(*) FROM onek t1 LEFT JOIN tenk1 t2 ON (t2.thousand = t1.tenthous OR t2.thousand = t1.thousand); + +DROP FUNCTION phv(anyelement); diff --git a/src/test/regress/sql/memoize.sql b/src/test/regress/sql/memoize.sql index 8d1cdd6990c..014ce8274c1 100644 --- a/src/test/regress/sql/memoize.sql +++ b/src/test/regress/sql/memoize.sql @@ -79,24 +79,24 @@ WHERE t1.unique1 < 10; -- Try with LATERAL references within PlaceHolderVars SELECT explain_memoize(' SELECT COUNT(*), AVG(t1.twenty) FROM tenk1 t1 LEFT JOIN -LATERAL (SELECT t1.two+1 AS c1, t2.unique1 AS c2 FROM tenk1 t2) s ON TRUE +LATERAL (SELECT (t1.two+1)::bigint AS c1, t2.unique1 AS c2 FROM tenk1 t2) s ON TRUE WHERE s.c1 = s.c2 AND t1.unique1 < 1000;', false); -- And check we get the expected results. SELECT COUNT(*), AVG(t1.twenty) FROM tenk1 t1 LEFT JOIN -LATERAL (SELECT t1.two+1 AS c1, t2.unique1 AS c2 FROM tenk1 t2) s ON TRUE +LATERAL (SELECT (t1.two+1)::bigint AS c1, t2.unique1 AS c2 FROM tenk1 t2) s ON TRUE WHERE s.c1 = s.c2 AND t1.unique1 < 1000; -- Ensure we do not omit the cache keys from PlaceHolderVars SELECT explain_memoize(' SELECT COUNT(*), AVG(t1.twenty) FROM tenk1 t1 LEFT JOIN -LATERAL (SELECT t1.twenty AS c1, t2.unique1 AS c2, t2.two FROM tenk1 t2) s +LATERAL (SELECT t1.twenty::bigint AS c1, t2.unique1 AS c2, t2.two FROM tenk1 t2) s ON t1.two = s.two WHERE s.c1 = s.c2 AND t1.unique1 < 1000;', false); -- And check we get the expected results. SELECT COUNT(*), AVG(t1.twenty) FROM tenk1 t1 LEFT JOIN -LATERAL (SELECT t1.twenty AS c1, t2.unique1 AS c2, t2.two FROM tenk1 t2) s +LATERAL (SELECT t1.twenty::bigint AS c1, t2.unique1 AS c2, t2.two FROM tenk1 t2) s ON t1.two = s.two WHERE s.c1 = s.c2 AND t1.unique1 < 1000; diff --git a/src/test/regress/sql/partition_join.sql b/src/test/regress/sql/partition_join.sql index c4549fc1ad8..ad1735e5c5e 100644 --- a/src/test/regress/sql/partition_join.sql +++ b/src/test/regress/sql/partition_join.sql @@ -119,19 +119,19 @@ SELECT * FROM prt1 t1 JOIN LATERAL -- lateral reference in scan's restriction clauses EXPLAIN (COSTS OFF) SELECT count(*) FROM prt1 t1 LEFT JOIN LATERAL - (SELECT t1.b AS t1b, t2.* FROM prt2 t2) s - ON t1.a = s.b WHERE s.t1b = s.a; + (SELECT (t1.b >= 0 AND t1.b = a) AS t1b, t2.* FROM prt2 t2) s + ON t1.a = s.b WHERE s.t1b; SELECT count(*) FROM prt1 t1 LEFT JOIN LATERAL - (SELECT t1.b AS t1b, t2.* FROM prt2 t2) s - ON t1.a = s.b WHERE s.t1b = s.a; + (SELECT (t1.b >= 0 AND t1.b = a) AS t1b, t2.* FROM prt2 t2) s + ON t1.a = s.b WHERE s.t1b; EXPLAIN (COSTS OFF) SELECT count(*) FROM prt1 t1 LEFT JOIN LATERAL - (SELECT t1.b AS t1b, t2.* FROM prt2 t2) s - ON t1.a = s.b WHERE s.t1b = s.b; + (SELECT (t1.b >= 0 AND t1.b = b) AS t1b, t2.* FROM prt2 t2) s + ON t1.a = s.b WHERE s.t1b; SELECT count(*) FROM prt1 t1 LEFT JOIN LATERAL - (SELECT t1.b AS t1b, t2.* FROM prt2 t2) s - ON t1.a = s.b WHERE s.t1b = s.b; + (SELECT (t1.b >= 0 AND t1.b = b) AS t1b, t2.* FROM prt2 t2) s + ON t1.a = s.b WHERE s.t1b; -- bug with inadequate sort key representation SET enable_partitionwise_aggregate TO true; @@ -439,13 +439,13 @@ SELECT * FROM prt1_l t1 JOIN LATERAL -- partitionwise join with lateral reference in scan's restriction clauses EXPLAIN (COSTS OFF) SELECT COUNT(*) FROM prt1_l t1 LEFT JOIN LATERAL - (SELECT t1.b AS t1b, t2.* FROM prt2_l t2) s + (SELECT (t1.b >= 0 AND t1.b = a) AS t1b, t2.* FROM prt2_l t2) s ON t1.a = s.b AND t1.b = s.a AND t1.c = s.c - WHERE s.t1b = s.a; + WHERE s.t1b; SELECT COUNT(*) FROM prt1_l t1 LEFT JOIN LATERAL - (SELECT t1.b AS t1b, t2.* FROM prt2_l t2) s + (SELECT (t1.b >= 0 AND t1.b = a) AS t1b, t2.* FROM prt2_l t2) s ON t1.a = s.b AND t1.b = s.a AND t1.c = s.c - WHERE s.t1b = s.a; + WHERE s.t1b; -- join with one side empty EXPLAIN (COSTS OFF) -- 2.39.5 (Apple Git-154)