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

Commit1e81d3e

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 parent245e0f4 commit1e81d3e

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
@@ -1956,7 +1956,7 @@ InitPartitionPruneContext(PartitionPruneContext *context,
19561956
foreach(lc,pruning_steps)
19571957
{
19581958
PartitionPruneStepOp*step= (PartitionPruneStepOp*)lfirst(lc);
1959-
ListCell*lc2;
1959+
ListCell*lc2=list_head(step->exprs);
19601960
intkeyno;
19611961

19621962
/* not needed for other step kinds */
@@ -1965,34 +1965,39 @@ InitPartitionPruneContext(PartitionPruneContext *context,
19651965

19661966
Assert(list_length(step->exprs) <=partnatts);
19671967

1968-
keyno=0;
1969-
foreach(lc2,step->exprs)
1968+
for (keyno=0;keyno<partnatts;keyno++)
19701969
{
1971-
Expr*expr= (Expr*)lfirst(lc2);
1970+
if (bms_is_member(keyno,step->nullkeys))
1971+
continue;
19721972

1973-
/* not needed for Consts */
1974-
if (!IsA(expr,Const))
1973+
if (lc2!=NULL)
19751974
{
1976-
intstateidx=PruneCxtStateIdx(partnatts,
1977-
step->step.step_id,
1978-
keyno);
1975+
Expr*expr=lfirst(lc2);
19791976

1980-
/*
1981-
* When planstate is NULL, pruning_steps is known not to
1982-
* contain any expressions that depend on the parent plan.
1983-
* Information of any available EXTERN parameters must be
1984-
* passed explicitly in that case, which the caller must have
1985-
* made available via econtext.
1986-
*/
1987-
if (planstate==NULL)
1988-
context->exprstates[stateidx]=
1989-
ExecInitExprWithParams(expr,
1990-
econtext->ecxt_param_list_info);
1991-
else
1992-
context->exprstates[stateidx]=
1993-
ExecInitExpr(expr,context->planstate);
1977+
/* not needed for Consts */
1978+
if (!IsA(expr,Const))
1979+
{
1980+
intstateidx=PruneCxtStateIdx(partnatts,
1981+
step->step.step_id,
1982+
keyno);
1983+
1984+
/*
1985+
* When planstate is NULL, pruning_steps is known not to
1986+
* contain any expressions that depend on the parent plan.
1987+
* Information of any available EXTERN parameters must be
1988+
* passed explicitly in that case, which the caller must
1989+
* have made available via econtext.
1990+
*/
1991+
if (planstate==NULL)
1992+
context->exprstates[stateidx]=
1993+
ExecInitExprWithParams(expr,
1994+
econtext->ecxt_param_list_info);
1995+
else
1996+
context->exprstates[stateidx]=
1997+
ExecInitExpr(expr,context->planstate);
1998+
}
1999+
lc2=lnext(step->exprs,lc2);
19942000
}
1995-
keyno++;
19962001
}
19972002
}
19982003
}

‎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