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

Commit727bc6a

Browse files
author
Richard Guo
committed
Fix freeing a child join's SpecialJoinInfo
In try_partitionwise_join, we try to break down the join between twopartitioned relations into joins between matching partitions. Toachieve this, we iterate through each pair of partitions from the twojoining relations and create child join relations for them. To reducememory accumulation during each iteration, one step we take is freeingthe SpecialJoinInfos created for the child joins.A child join's SpecialJoinInfo is a copy of the parent join'sSpecialJoinInfo, with some members being translated copies of theircounterparts in the parent. However, when freeing the bitmapsetmembers in a child join's SpecialJoinInfo, we failed to check whetherthey were translated copies. As a result, we inadvertently freed themembers that were still in use by the parent SpecialJoinInfo, leadingto crashes when those freed members were accessed.To fix, check if each member of the child join's SpecialJoinInfo is atranslated copy and free it only if that's the case. This requirespassing the parent join's SpecialJoinInfo as a parameter tofree_child_join_sjinfo.Back-patch to v17 where this bug crept in.Bug: #18806Reported-by: 孟令彬 <m_lingbin@126.com>Diagnosed-by: Tender Wang <tndrwang@gmail.com>Author: Richard Guo <guofenglinux@gmail.com>Reviewed-by: Amit Langote <amitlangote09@gmail.com>Reviewed-by: Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>Discussion:https://postgr.es/m/18806-d70b0c9fdf63dcbf@postgresql.orgBackpatch-through: 17
1 parenta68a759 commit727bc6a

File tree

3 files changed

+64
-9
lines changed

3 files changed

+64
-9
lines changed

‎src/backend/optimizer/path/joinrels.c

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ static void try_partitionwise_join(PlannerInfo *root, RelOptInfo *rel1,
4545
staticSpecialJoinInfo*build_child_join_sjinfo(PlannerInfo*root,
4646
SpecialJoinInfo*parent_sjinfo,
4747
Relidsleft_relids,Relidsright_relids);
48-
staticvoidfree_child_join_sjinfo(SpecialJoinInfo*sjinfo);
48+
staticvoidfree_child_join_sjinfo(SpecialJoinInfo*child_sjinfo,
49+
SpecialJoinInfo*parent_sjinfo);
4950
staticvoidcompute_partition_bounds(PlannerInfo*root,RelOptInfo*rel1,
5051
RelOptInfo*rel2,RelOptInfo*joinrel,
5152
SpecialJoinInfo*parent_sjinfo,
@@ -1677,7 +1678,7 @@ try_partitionwise_join(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2,
16771678
child_restrictlist);
16781679

16791680
pfree(appinfos);
1680-
free_child_join_sjinfo(child_sjinfo);
1681+
free_child_join_sjinfo(child_sjinfo,parent_sjinfo);
16811682
}
16821683
}
16831684

@@ -1744,26 +1745,41 @@ build_child_join_sjinfo(PlannerInfo *root, SpecialJoinInfo *parent_sjinfo,
17441745
* SpecialJoinInfo are freed here.
17451746
*/
17461747
staticvoid
1747-
free_child_join_sjinfo(SpecialJoinInfo*sjinfo)
1748+
free_child_join_sjinfo(SpecialJoinInfo*child_sjinfo,
1749+
SpecialJoinInfo*parent_sjinfo)
17481750
{
17491751
/*
17501752
* Dummy SpecialJoinInfos of inner joins do not have any translated fields
17511753
* and hence no fields that to be freed.
17521754
*/
1753-
if (sjinfo->jointype!=JOIN_INNER)
1755+
if (child_sjinfo->jointype!=JOIN_INNER)
17541756
{
1755-
bms_free(sjinfo->min_lefthand);
1756-
bms_free(sjinfo->min_righthand);
1757-
bms_free(sjinfo->syn_lefthand);
1758-
bms_free(sjinfo->syn_righthand);
1757+
if (child_sjinfo->min_lefthand!=parent_sjinfo->min_lefthand)
1758+
bms_free(child_sjinfo->min_lefthand);
1759+
1760+
if (child_sjinfo->min_righthand!=parent_sjinfo->min_righthand)
1761+
bms_free(child_sjinfo->min_righthand);
1762+
1763+
if (child_sjinfo->syn_lefthand!=parent_sjinfo->syn_lefthand)
1764+
bms_free(child_sjinfo->syn_lefthand);
1765+
1766+
if (child_sjinfo->syn_righthand!=parent_sjinfo->syn_righthand)
1767+
bms_free(child_sjinfo->syn_righthand);
1768+
1769+
Assert(child_sjinfo->commute_above_l==parent_sjinfo->commute_above_l);
1770+
Assert(child_sjinfo->commute_above_r==parent_sjinfo->commute_above_r);
1771+
Assert(child_sjinfo->commute_below_l==parent_sjinfo->commute_below_l);
1772+
Assert(child_sjinfo->commute_below_r==parent_sjinfo->commute_below_r);
1773+
1774+
Assert(child_sjinfo->semi_operators==parent_sjinfo->semi_operators);
17591775

17601776
/*
17611777
* semi_rhs_exprs may in principle be freed, but a simple pfree() does
17621778
* not suffice, so we leave it alone.
17631779
*/
17641780
}
17651781

1766-
pfree(sjinfo);
1782+
pfree(child_sjinfo);
17671783
}
17681784

17691785
/*

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

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -674,6 +674,41 @@ SELECT a, b FROM prt1 FULL JOIN prt2 p2(b,a,c) USING(a,b)
674674

675675
RESET enable_partitionwise_aggregate;
676676
RESET enable_hashjoin;
677+
-- bug in freeing the SpecialJoinInfo of a child-join
678+
EXPLAIN (COSTS OFF)
679+
SELECT * FROM prt1 t1 JOIN prt1 t2 ON t1.a = t2.a WHERE t1.a IN (SELECT a FROM prt1 t3);
680+
QUERY PLAN
681+
--------------------------------------------------
682+
Append
683+
-> Hash Semi Join
684+
Hash Cond: (t1_1.a = t3_1.a)
685+
-> Hash Join
686+
Hash Cond: (t1_1.a = t2_1.a)
687+
-> Seq Scan on prt1_p1 t1_1
688+
-> Hash
689+
-> Seq Scan on prt1_p1 t2_1
690+
-> Hash
691+
-> Seq Scan on prt1_p1 t3_1
692+
-> Hash Semi Join
693+
Hash Cond: (t1_2.a = t3_2.a)
694+
-> Hash Join
695+
Hash Cond: (t1_2.a = t2_2.a)
696+
-> Seq Scan on prt1_p2 t1_2
697+
-> Hash
698+
-> Seq Scan on prt1_p2 t2_2
699+
-> Hash
700+
-> Seq Scan on prt1_p2 t3_2
701+
-> Hash Semi Join
702+
Hash Cond: (t1_3.a = t3_3.a)
703+
-> Hash Join
704+
Hash Cond: (t1_3.a = t2_3.a)
705+
-> Seq Scan on prt1_p3 t1_3
706+
-> Hash
707+
-> Seq Scan on prt1_p3 t2_3
708+
-> Hash
709+
-> Seq Scan on prt1_p3 t3_3
710+
(28 rows)
711+
677712
--
678713
-- partitioned by expression
679714
--

‎src/test/regress/sql/partition_join.sql

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,10 @@ SELECT a, b FROM prt1 FULL JOIN prt2 p2(b,a,c) USING(a,b)
138138
RESET enable_partitionwise_aggregate;
139139
RESET enable_hashjoin;
140140

141+
-- bug in freeing the SpecialJoinInfo of a child-join
142+
EXPLAIN (COSTS OFF)
143+
SELECT*FROM prt1 t1JOIN prt1 t2ONt1.a=t2.aWHEREt1.aIN (SELECT aFROM prt1 t3);
144+
141145
--
142146
-- partitioned by expression
143147
--

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp