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

Commite0b0d1e

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 parent8767a86 commite0b0d1e

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
@@ -200,6 +200,16 @@ pull_varnos_walker(Node *node, pull_varnos_context *context)
200200
* join that forces delay of evaluation of a given qual clause
201201
* will be processed before we examine that clause here, so the
202202
* ph_eval_at value should have been updated to include it.
203+
*
204+
* Another problem is that a PlaceHolderVar can appear in quals or
205+
* tlists that have been translated for use in a child appendrel.
206+
* Typically such a PHV is a parameter expression sourced by some
207+
* other relation, so that the translation from parent appendrel
208+
* to child doesn't change its phrels, and we should still take
209+
* ph_eval_at at face value. But in corner cases, the PHV's
210+
* original phrels can include the parent appendrel itself, in
211+
* which case the translated PHV will have the child appendrel in
212+
* phrels, and we must translate ph_eval_at to match.
203213
*/
204214
PlaceHolderInfo*phinfo=NULL;
205215

@@ -215,12 +225,37 @@ pull_varnos_walker(Node *node, pull_varnos_context *context)
215225
phinfo=NULL;
216226
}
217227
}
218-
if (phinfo!=NULL)
228+
if (phinfo==NULL)
229+
{
230+
/* No PlaceHolderInfo yet, use phrels */
231+
context->varnos=bms_add_members(context->varnos,
232+
phv->phrels);
233+
}
234+
elseif (bms_equal(phv->phrels,phinfo->ph_var->phrels))
235+
{
236+
/* Normal case: use ph_eval_at */
219237
context->varnos=bms_add_members(context->varnos,
220238
phinfo->ph_eval_at);
239+
}
221240
else
222-
context->varnos=bms_add_members(context->varnos,
223-
phv->phrels);
241+
{
242+
/* Translated PlaceHolderVar: translate ph_eval_at to match */
243+
Relidsnewevalat,
244+
delta;
245+
246+
/* remove what was removed from phv->phrels ... */
247+
delta=bms_difference(phinfo->ph_var->phrels,phv->phrels);
248+
newevalat=bms_difference(phinfo->ph_eval_at,delta);
249+
/* ... then if that was in fact part of ph_eval_at ... */
250+
if (!bms_equal(newevalat,phinfo->ph_eval_at))
251+
{
252+
/* ... add what was added */
253+
delta=bms_difference(phv->phrels,phinfo->ph_var->phrels);
254+
newevalat=bms_join(newevalat,delta);
255+
}
256+
context->varnos=bms_join(context->varnos,
257+
newevalat);
258+
}
224259
return false;/* don't recurse into expression */
225260
}
226261
}

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

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4799,6 +4799,34 @@ where q2 = 456;
47994799
123 | 456 | |
48004800
(1 row)
48014801

4802+
-- and check a related issue where we miscompute required relids for
4803+
-- a PHV that's been translated to a child rel
4804+
create temp table parttbl (a integer primary key) partition by range (a);
4805+
create temp table parttbl1 partition of parttbl for values from (1) to (100);
4806+
insert into parttbl values (11), (12);
4807+
explain (costs off)
4808+
select * from
4809+
(select *, 12 as phv from parttbl) as ss
4810+
right join int4_tbl on true
4811+
where ss.a = ss.phv and f1 = 0;
4812+
QUERY PLAN
4813+
------------------------------------
4814+
Nested Loop
4815+
-> Seq Scan on int4_tbl
4816+
Filter: (f1 = 0)
4817+
-> Seq Scan on parttbl1 parttbl
4818+
Filter: (a = 12)
4819+
(5 rows)
4820+
4821+
select * from
4822+
(select *, 12 as phv from parttbl) as ss
4823+
right join int4_tbl on true
4824+
where ss.a = ss.phv and f1 = 0;
4825+
a | phv | f1
4826+
----+-----+----
4827+
12 | 12 | 0
4828+
(1 row)
4829+
48024830
-- bug #8444: we've historically allowed duplicate aliases within aliased JOINs
48034831
select * from
48044832
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
@@ -1714,6 +1714,22 @@ select i8.*, ss.v, t.unique2
17141714
left join tenk1 tont.unique2=ss.v
17151715
where q2=456;
17161716

1717+
-- and check a related issue where we miscompute required relids for
1718+
-- a PHV that's been translated to a child rel
1719+
create temp table parttbl (aintegerprimary key) partition by range (a);
1720+
create temp table parttbl1 partition of parttbl forvaluesfrom (1) to (100);
1721+
insert into parttblvalues (11), (12);
1722+
explain (costs off)
1723+
select*from
1724+
(select*,12as phvfrom parttbl)as ss
1725+
right join int4_tblon true
1726+
wheress.a=ss.phvand f1=0;
1727+
1728+
select*from
1729+
(select*,12as phvfrom parttbl)as ss
1730+
right join int4_tblon true
1731+
wheress.a=ss.phvand f1=0;
1732+
17171733
-- bug #8444: we've historically allowed duplicate aliases within aliased JOINs
17181734

17191735
select*from

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp