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

Commite047783

Browse files
committed
Make replace_relid() leave argument unmodified
There are a lot of situations when we share the same pointer to a Bitmapsetstructure across different places. In order to evade undesirable side effectsreplace_relid() function should always return a copy.Reported-by: Richard GuoDiscussion:https://postgr.es/m/CAMbWs4_wJthNtYBL%2BSsebpgF-5L2r5zFFk6xYbS0A78GKOTFHw%40mail.gmail.comReviewed-by: Richard Guo, Andres Freund, Ashutosh Bapat, Andrei Lepikhov
1 parent7d58f23 commite047783

File tree

3 files changed

+29
-3
lines changed

3 files changed

+29
-3
lines changed

‎src/backend/optimizer/plan/analyzejoins.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1522,19 +1522,24 @@ replace_varno_walker(Node *node, ReplaceVarnoContext *ctx)
15221522

15231523
/*
15241524
* Substitute newId by oldId in relids.
1525+
*
1526+
* We must make a copy of the original Bitmapset before making any
1527+
* modifications, because the same pointer to it might be shared among
1528+
* different places.
15251529
*/
15261530
staticBitmapset*
15271531
replace_relid(Relidsrelids,intoldId,intnewId)
15281532
{
15291533
if (oldId<0)
15301534
returnrelids;
15311535

1536+
/* Delete relid without substitution. */
15321537
if (newId<0)
1533-
/* Delete relid without substitution. */
1534-
returnbms_del_member(relids,oldId);
1538+
returnbms_del_member(bms_copy(relids),oldId);
15351539

1540+
/* Substitute newId for oldId. */
15361541
if (bms_is_member(oldId,relids))
1537-
returnbms_add_member(bms_del_member(relids,oldId),newId);
1542+
returnbms_add_member(bms_del_member(bms_copy(relids),oldId),newId);
15381543

15391544
returnrelids;
15401545
}

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6853,6 +6853,21 @@ on true;
68536853
Filter: (t3.id IS NOT NULL)
68546854
(8 rows)
68556855

6856+
-- Check that SJE replaces join clauses involving the removed rel correctly
6857+
explain (costs off)
6858+
select * from emp1 t1
6859+
inner join emp1 t2 on t1.id = t2.id
6860+
left join emp1 t3 on t1.id > 1 and t1.id < 2;
6861+
QUERY PLAN
6862+
----------------------------------------------
6863+
Nested Loop Left Join
6864+
Join Filter: ((t2.id > 1) AND (t2.id < 2))
6865+
-> Seq Scan on emp1 t2
6866+
Filter: (id IS NOT NULL)
6867+
-> Materialize
6868+
-> Seq Scan on emp1 t3
6869+
(6 rows)
6870+
68566871
-- We can remove the join even if we find the join can't duplicate rows and
68576872
-- the base quals of each side are different. In the following case we end up
68586873
-- moving quals over to s1 to make it so it can't match any rows.

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2610,6 +2610,12 @@ select * from generate_series(1,10) t1(id) left join
26102610
lateral (selectt1.idas t1id,t2.idfrom emp1 t2join emp1 t3ont2.id=t3.id)
26112611
on true;
26122612

2613+
-- Check that SJE replaces join clauses involving the removed rel correctly
2614+
explain (costs off)
2615+
select*from emp1 t1
2616+
inner join emp1 t2ont1.id=t2.id
2617+
left join emp1 t3ont1.id>1andt1.id<2;
2618+
26132619
-- We can remove the join even if we find the join can't duplicate rows and
26142620
-- the base quals of each side are different. In the following case we end up
26152621
-- moving quals over to s1 to make it so it can't match any rows.

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp