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

Commitd9e46df

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 parentdab5538 commitd9e46df

File tree

3 files changed

+69
-27
lines changed

3 files changed

+69
-27
lines changed

‎src/backend/executor/execPartition.c

Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2108,7 +2108,7 @@ InitPartitionPruneContext(PartitionPruneContext *context,
21082108
foreach(lc,pruning_steps)
21092109
{
21102110
PartitionPruneStepOp*step= (PartitionPruneStepOp*)lfirst(lc);
2111-
ListCell*lc2;
2111+
ListCell*lc2=list_head(step->exprs);
21122112
intkeyno;
21132113

21142114
/* not needed for other step kinds */
@@ -2117,34 +2117,39 @@ InitPartitionPruneContext(PartitionPruneContext *context,
21172117

21182118
Assert(list_length(step->exprs) <=partnatts);
21192119

2120-
keyno=0;
2121-
foreach(lc2,step->exprs)
2120+
for (keyno=0;keyno<partnatts;keyno++)
21222121
{
2123-
Expr*expr= (Expr*)lfirst(lc2);
2122+
if (bms_is_member(keyno,step->nullkeys))
2123+
continue;
21242124

2125-
/* not needed for Consts */
2126-
if (!IsA(expr,Const))
2125+
if (lc2!=NULL)
21272126
{
2128-
intstateidx=PruneCxtStateIdx(partnatts,
2129-
step->step.step_id,
2130-
keyno);
2127+
Expr*expr=lfirst(lc2);
21312128

2132-
/*
2133-
* When planstate is NULL, pruning_steps is known not to
2134-
* contain any expressions that depend on the parent plan.
2135-
* Information of any available EXTERN parameters must be
2136-
* passed explicitly in that case, which the caller must have
2137-
* made available via econtext.
2138-
*/
2139-
if (planstate==NULL)
2140-
context->exprstates[stateidx]=
2141-
ExecInitExprWithParams(expr,
2142-
econtext->ecxt_param_list_info);
2143-
else
2144-
context->exprstates[stateidx]=
2145-
ExecInitExpr(expr,context->planstate);
2129+
/* not needed for Consts */
2130+
if (!IsA(expr,Const))
2131+
{
2132+
intstateidx=PruneCxtStateIdx(partnatts,
2133+
step->step.step_id,
2134+
keyno);
2135+
2136+
/*
2137+
* When planstate is NULL, pruning_steps is known not to
2138+
* contain any expressions that depend on the parent plan.
2139+
* Information of any available EXTERN parameters must be
2140+
* passed explicitly in that case, which the caller must
2141+
* have made available via econtext.
2142+
*/
2143+
if (planstate==NULL)
2144+
context->exprstates[stateidx]=
2145+
ExecInitExprWithParams(expr,
2146+
econtext->ecxt_param_list_info);
2147+
else
2148+
context->exprstates[stateidx]=
2149+
ExecInitExpr(expr,context->planstate);
2150+
}
2151+
lc2=lnext(step->exprs,lc2);
21462152
}
2147-
keyno++;
21482153
}
21492154
}
21502155
}

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

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

1951-
drop table hp;
19521951
--
19531952
-- Test runtime partition pruning
19541953
--
@@ -2070,6 +2069,27 @@ explain (analyze, costs off, summary off, timing off) execute ab_q3 (2, 2);
20702069
Filter: ((b >= $1) AND (b <= $2) AND (a < $0))
20712070
(10 rows)
20722071

2072+
--
2073+
-- Test runtime pruning with hash partitioned tables
2074+
--
2075+
-- recreate partitions dropped above
2076+
create table hp1 partition of hp for values with (modulus 4, remainder 1);
2077+
create table hp2 partition of hp for values with (modulus 4, remainder 2);
2078+
create table hp3 partition of hp for values with (modulus 4, remainder 3);
2079+
-- Ensure we correctly prune unneeded partitions when there is an IS NULL qual
2080+
prepare hp_q1 (text) as
2081+
select * from hp where a is null and b = $1;
2082+
explain (costs off) execute hp_q1('xxx');
2083+
QUERY PLAN
2084+
--------------------------------------------
2085+
Append
2086+
Subplans Removed: 3
2087+
-> Seq Scan on hp2 hp_1
2088+
Filter: ((a IS NULL) AND (b = $1))
2089+
(4 rows)
2090+
2091+
deallocate hp_q1;
2092+
drop table hp;
20732093
-- Test a backwards Append scan
20742094
create table list_part (a int) partition by list (a);
20752095
create table list_part1 partition of list_part for values in (1);

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

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

387-
droptable hp;
388-
389387
--
390388
-- Test runtime partition pruning
391389
--
@@ -436,6 +434,25 @@ select a from ab where b between $1 and $2 and a < (select 3);
436434

437435
explain (analyze, costs off, summary off, timing off) execute ab_q3 (2,2);
438436

437+
--
438+
-- Test runtime pruning with hash partitioned tables
439+
--
440+
441+
-- recreate partitions dropped above
442+
createtablehp1 partition of hp forvalues with (modulus4, remainder1);
443+
createtablehp2 partition of hp forvalues with (modulus4, remainder2);
444+
createtablehp3 partition of hp forvalues with (modulus4, remainder3);
445+
446+
-- Ensure we correctly prune unneeded partitions when there is an IS NULL qual
447+
prepare hp_q1 (text)as
448+
select*from hpwhere a isnulland b= $1;
449+
450+
explain (costs off) execute hp_q1('xxx');
451+
452+
deallocate hp_q1;
453+
454+
droptable hp;
455+
439456
-- Test a backwards Append scan
440457
createtablelist_part (aint) partition by list (a);
441458
createtablelist_part1 partition of list_part forvaluesin (1);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp