From e98c900993e89ad9278cdfbf0ba5495381a1faac Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Sat, 5 Dec 2020 16:16:13 -0500 Subject: [PATCH] Fix missed step in removal of useless RESULT RTEs in the planner. Commit 4be058fe9 forgot that the append_rel_list would already be populated at the time we remove useless result RTEs, and it might contain PlaceHolderVars that need to be adjusted like the ones in the main parse tree. This could lead to "no relation entry for relid N" failures later on, when the planner tries to do something with an unadjusted PHV. Per report from Tom Ellis. Back-patch to v12 where the bug came in. Discussion: https://postgr.es/m/20201205173056.GF30712@cloudinit-builder --- src/backend/optimizer/prep/prepjointree.c | 1 + src/test/regress/expected/join.out | 36 +++++++++++++++++++++++ src/test/regress/sql/join.sql | 22 ++++++++++++++ 3 files changed, 59 insertions(+) diff --git a/src/backend/optimizer/prep/prepjointree.c b/src/backend/optimizer/prep/prepjointree.c index 14521728c6..ce57dfa7cd 100644 --- a/src/backend/optimizer/prep/prepjointree.c +++ b/src/backend/optimizer/prep/prepjointree.c @@ -3256,6 +3256,7 @@ remove_result_refs(PlannerInfo *root, int varno, Node *newjtloc) subrelids = get_relids_in_jointree(newjtloc, false); Assert(!bms_is_empty(subrelids)); substitute_phv_relids((Node *) root->parse, varno, subrelids); + fix_append_rel_relids(root->append_rel_list, varno, subrelids); } /* diff --git a/src/test/regress/expected/join.out b/src/test/regress/expected/join.out index a118041731..b0533a7195 100644 --- a/src/test/regress/expected/join.out +++ b/src/test/regress/expected/join.out @@ -3333,6 +3333,42 @@ select * from 1 | 2 | 2 (1 row) +-- Test proper handling of appendrel PHVs during useless-RTE removal +explain (costs off) +select * from + (select 0 as z) as t1 + left join + (select true as a) as t2 + on true, + lateral (select true as b + union all + select a as b) as t3 +where b; + QUERY PLAN +--------------------------------------- + Nested Loop + -> Result + -> Append + -> Result + -> Result + One-Time Filter: (true) +(6 rows) + +select * from + (select 0 as z) as t1 + left join + (select true as a) as t2 + on true, + lateral (select true as b + union all + select a as b) as t3 +where b; + z | a | b +---+---+--- + 0 | t | t + 0 | t | t +(2 rows) + -- -- test inlining of immutable functions -- diff --git a/src/test/regress/sql/join.sql b/src/test/regress/sql/join.sql index 4de24c1904..00720b629a 100644 --- a/src/test/regress/sql/join.sql +++ b/src/test/regress/sql/join.sql @@ -1056,6 +1056,28 @@ select * from (select 1 as x) ss1 left join (select 2 as y) ss2 on (true), lateral (select ss2.y as z limit 1) ss3; +-- Test proper handling of appendrel PHVs during useless-RTE removal +explain (costs off) +select * from + (select 0 as z) as t1 + left join + (select true as a) as t2 + on true, + lateral (select true as b + union all + select a as b) as t3 +where b; + +select * from + (select 0 as z) as t1 + left join + (select true as a) as t2 + on true, + lateral (select true as b + union all + select a as b) as t3 +where b; + -- -- test inlining of immutable functions --