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

Commit3cc0c25

Browse files
committed
Fix runtime partition pruning for HASH partitioned tables
This could only affect HASH partitioned tables with at least 2 partitionkey columns.If partition pruning was delayed until execution and the query containedan IS NULL qual on one of the partitioned keys, and some subsequentpartitioned key was being compared to a non-Const, then this could resultin a crash due to the incorrect keyno being used to calculate thestateidx for the expression evaluation code.Here we fix this by properly skipping partitioned keys which have anullkey set. Effectively, this must be the same as what's going oninside perform_pruning_base_step().Sergei Glukhov also provided a patch, but that's not what's being usedhere.Reported-by: Sergei GlukhovReviewed-by: tender wang, Sergei GlukhovDiscussion:https://postgr.es/m/d05b26fa-af54-27e1-f693-6c31590802fa@postgrespro.ruBackpatch-through: 11, where runtime partition pruning was added.
1 parent7f1b5a6 commit3cc0c25

File tree

3 files changed

+62
-15
lines changed

3 files changed

+62
-15
lines changed

‎src/backend/executor/execPartition.c

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1888,7 +1888,7 @@ ExecInitPruningContext(PartitionPruneContext *context,
18881888
foreach(lc,pruning_steps)
18891889
{
18901890
PartitionPruneStepOp*step= (PartitionPruneStepOp*)lfirst(lc);
1891-
ListCell*lc2;
1891+
ListCell*lc2=list_head(step->exprs);
18921892
intkeyno;
18931893

18941894
/* not needed for other step kinds */
@@ -1897,22 +1897,27 @@ ExecInitPruningContext(PartitionPruneContext *context,
18971897

18981898
Assert(list_length(step->exprs) <=partnatts);
18991899

1900-
keyno=0;
1901-
foreach(lc2,step->exprs)
1900+
for (keyno=0;keyno<partnatts;keyno++)
19021901
{
1903-
Expr*expr= (Expr*)lfirst(lc2);
1902+
if (bms_is_member(keyno,step->nullkeys))
1903+
continue;
19041904

1905-
/* not needed for Consts */
1906-
if (!IsA(expr,Const))
1905+
if (lc2!=NULL)
19071906
{
1908-
intstateidx=PruneCxtStateIdx(partnatts,
1909-
step->step.step_id,
1910-
keyno);
1907+
Expr*expr=lfirst(lc2);
19111908

1912-
context->exprstates[stateidx]=
1913-
ExecInitExpr(expr,context->planstate);
1909+
/* not needed for Consts */
1910+
if (!IsA(expr,Const))
1911+
{
1912+
intstateidx=PruneCxtStateIdx(partnatts,
1913+
step->step.step_id,
1914+
keyno);
1915+
1916+
context->exprstates[stateidx]=
1917+
ExecInitExpr(expr,context->planstate);
1918+
}
1919+
lc2=lnext(lc2);
19141920
}
1915-
keyno++;
19161921
}
19171922
}
19181923
}

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

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1907,7 +1907,6 @@ explain (costs off) select * from hp where a = 1 and b = 'abcde' and
19071907
One-Time Filter: false
19081908
(2 rows)
19091909

1910-
drop table hp;
19111910
--
19121911
-- Test runtime partition pruning
19131912
--
@@ -2133,6 +2132,29 @@ explain (analyze, costs off, summary off, timing off) execute ab_q3 (2, 2);
21332132
Filter: ((b >= $1) AND (b <= $2) AND (a < $0))
21342133
(10 rows)
21352134

2135+
--
2136+
-- Test runtime pruning with hash partitioned tables
2137+
--
2138+
-- recreate partitions dropped above
2139+
create table hp1 partition of hp for values with (modulus 4, remainder 1);
2140+
create table hp2 partition of hp for values with (modulus 4, remainder 2);
2141+
create table hp3 partition of hp for values with (modulus 4, remainder 3);
2142+
-- Ensure we correctly prune unneeded partitions when there is an IS NULL qual
2143+
prepare hp_q1 (text) as
2144+
select * from hp where a is null and b = $1;
2145+
set plan_cache_mode = force_generic_plan;
2146+
explain (costs off) execute hp_q1('xxx');
2147+
QUERY PLAN
2148+
--------------------------------------------
2149+
Append
2150+
Subplans Removed: 3
2151+
-> Seq Scan on hp2
2152+
Filter: ((a IS NULL) AND (b = $1))
2153+
(4 rows)
2154+
2155+
reset plan_cache_mode;
2156+
deallocate hp_q1;
2157+
drop table hp;
21362158
-- Test a backwards Append scan
21372159
create table list_part (a int) partition by list (a);
21382160
create table list_part1 partition of list_part for values in (1);

‎src/test/regress/sql/partition_prune.sql

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -371,8 +371,6 @@ drop table hp2;
371371
explain (costs off)select*from hpwhere a=1and b='abcde'and
372372
(c=2or c=3);
373373

374-
droptable hp;
375-
376374
--
377375
-- Test runtime partition pruning
378376
--
@@ -451,6 +449,28 @@ execute ab_q3 (1, 8);
451449

452450
explain (analyze, costs off, summary off, timing off) execute ab_q3 (2,2);
453451

452+
--
453+
-- Test runtime pruning with hash partitioned tables
454+
--
455+
456+
-- recreate partitions dropped above
457+
createtablehp1 partition of hp forvalues with (modulus4, remainder1);
458+
createtablehp2 partition of hp forvalues with (modulus4, remainder2);
459+
createtablehp3 partition of hp forvalues with (modulus4, remainder3);
460+
461+
-- Ensure we correctly prune unneeded partitions when there is an IS NULL qual
462+
prepare hp_q1 (text)as
463+
select*from hpwhere a isnulland b= $1;
464+
465+
set plan_cache_mode= force_generic_plan;
466+
467+
explain (costs off) execute hp_q1('xxx');
468+
469+
reset plan_cache_mode;
470+
deallocate hp_q1;
471+
472+
droptable hp;
473+
454474
-- Test a backwards Append scan
455475
createtablelist_part (aint) partition by list (a);
456476
createtablelist_part1 partition of list_part forvaluesin (1);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp