Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commita21049f

Browse files
committed
Fix pull_varnos to cope with translated PlaceHolderVars.
Commit55dc86e changed pull_varnos to use (if possible) the associatedph_eval_at for a PlaceHolderVar. I missed a fine point though: we mightbe looking at a PHV in the quals or tlist of a child appendrel, in whichcase we need to compute a ph_eval_at value that's been translated in thesame way that the PHV itself has been (cf. adjust_appendrel_attrs).Fortunately, enough info is available in the PlaceHolderInfo to makesuch translation possible without additional outside data, so we don'tneed another round of uglification of planner APIs. This is a littlebit complicated, but since it's a hard-to-hit corner case, I'm not muchworried about adding cycles here.Per report from Jaime Casanova. Back-patch to v12, like the previouscommit.Discussion:https://postgr.es/m/20210915230959.GB17635@ahch-to
1 parentcddcf78 commita21049f

File tree

3 files changed

+82
-3
lines changed

3 files changed

+82
-3
lines changed

‎src/backend/optimizer/util/var.c

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,16 @@ pull_varnos_walker(Node *node, pull_varnos_context *context)
188188
* join that forces delay of evaluation of a given qual clause
189189
* will be processed before we examine that clause here, so the
190190
* ph_eval_at value should have been updated to include it.
191+
*
192+
* Another problem is that a PlaceHolderVar can appear in quals or
193+
* tlists that have been translated for use in a child appendrel.
194+
* Typically such a PHV is a parameter expression sourced by some
195+
* other relation, so that the translation from parent appendrel
196+
* to child doesn't change its phrels, and we should still take
197+
* ph_eval_at at face value. But in corner cases, the PHV's
198+
* original phrels can include the parent appendrel itself, in
199+
* which case the translated PHV will have the child appendrel in
200+
* phrels, and we must translate ph_eval_at to match.
191201
*/
192202
PlaceHolderInfo*phinfo=NULL;
193203

@@ -203,12 +213,37 @@ pull_varnos_walker(Node *node, pull_varnos_context *context)
203213
phinfo=NULL;
204214
}
205215
}
206-
if (phinfo!=NULL)
216+
if (phinfo==NULL)
217+
{
218+
/* No PlaceHolderInfo yet, use phrels */
219+
context->varnos=bms_add_members(context->varnos,
220+
phv->phrels);
221+
}
222+
elseif (bms_equal(phv->phrels,phinfo->ph_var->phrels))
223+
{
224+
/* Normal case: use ph_eval_at */
207225
context->varnos=bms_add_members(context->varnos,
208226
phinfo->ph_eval_at);
227+
}
209228
else
210-
context->varnos=bms_add_members(context->varnos,
211-
phv->phrels);
229+
{
230+
/* Translated PlaceHolderVar: translate ph_eval_at to match */
231+
Relidsnewevalat,
232+
delta;
233+
234+
/* remove what was removed from phv->phrels ... */
235+
delta=bms_difference(phinfo->ph_var->phrels,phv->phrels);
236+
newevalat=bms_difference(phinfo->ph_eval_at,delta);
237+
/* ... then if that was in fact part of ph_eval_at ... */
238+
if (!bms_equal(newevalat,phinfo->ph_eval_at))
239+
{
240+
/* ... add what was added */
241+
delta=bms_difference(phv->phrels,phinfo->ph_var->phrels);
242+
newevalat=bms_join(newevalat,delta);
243+
}
244+
context->varnos=bms_join(context->varnos,
245+
newevalat);
246+
}
212247
return false;/* don't recurse into expression */
213248
}
214249
}

‎src/test/regress/expected/join.out

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4870,6 +4870,34 @@ where q2 = 456;
48704870
123 | 456 | |
48714871
(1 row)
48724872

4873+
-- and check a related issue where we miscompute required relids for
4874+
-- a PHV that's been translated to a child rel
4875+
create temp table parttbl (a integer primary key) partition by range (a);
4876+
create temp table parttbl1 partition of parttbl for values from (1) to (100);
4877+
insert into parttbl values (11), (12);
4878+
explain (costs off)
4879+
select * from
4880+
(select *, 12 as phv from parttbl) as ss
4881+
right join int4_tbl on true
4882+
where ss.a = ss.phv and f1 = 0;
4883+
QUERY PLAN
4884+
------------------------------------
4885+
Nested Loop
4886+
-> Seq Scan on int4_tbl
4887+
Filter: (f1 = 0)
4888+
-> Seq Scan on parttbl1 parttbl
4889+
Filter: (a = 12)
4890+
(5 rows)
4891+
4892+
select * from
4893+
(select *, 12 as phv from parttbl) as ss
4894+
right join int4_tbl on true
4895+
where ss.a = ss.phv and f1 = 0;
4896+
a | phv | f1
4897+
----+-----+----
4898+
12 | 12 | 0
4899+
(1 row)
4900+
48734901
-- bug #8444: we've historically allowed duplicate aliases within aliased JOINs
48744902
select * from
48754903
int8_tbl x join (int4_tbl x cross join int4_tbl y) j on q1 = f1; -- error

‎src/test/regress/sql/join.sql

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1728,6 +1728,22 @@ select i8.*, ss.v, t.unique2
17281728
left join tenk1 tont.unique2=ss.v
17291729
where q2=456;
17301730

1731+
-- and check a related issue where we miscompute required relids for
1732+
-- a PHV that's been translated to a child rel
1733+
create temp table parttbl (aintegerprimary key) partition by range (a);
1734+
create temp table parttbl1 partition of parttbl forvaluesfrom (1) to (100);
1735+
insert into parttblvalues (11), (12);
1736+
explain (costs off)
1737+
select*from
1738+
(select*,12as phvfrom parttbl)as ss
1739+
right join int4_tblon true
1740+
wheress.a=ss.phvand f1=0;
1741+
1742+
select*from
1743+
(select*,12as phvfrom parttbl)as ss
1744+
right join int4_tblon true
1745+
wheress.a=ss.phvand f1=0;
1746+
17311747
-- bug #8444: we've historically allowed duplicate aliases within aliased JOINs
17321748

17331749
select*from

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp