Skip to content

Commit 15d25e0

Browse files
authored
planner: fix hash partition prune with is null condition (#58383)
close #58374
1 parent c400723 commit 15d25e0

File tree

4 files changed

+47
-13
lines changed

4 files changed

+47
-13
lines changed

pkg/planner/core/casetest/partition/partition_pruner_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ func TestHashPartitionPruner(t *testing.T) {
4949
tk.MustExec("create table t8(a int, b int) partition by hash(a) partitions 6;")
5050
tk.MustExec("create table t9(a bit(1) default null, b int(11) default null) partition by hash(a) partitions 3;") //issue #22619
5151
tk.MustExec("create table t10(a bigint unsigned) partition BY hash (a);")
52+
tk.MustExec("create table t11(a int, b int) partition by hash(a + a + a + b) partitions 5")
5253

5354
var input []string
5455
var output []struct {

pkg/planner/core/casetest/partition/testdata/partition_pruner_in.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,10 @@
3030
"explain format = 'brief' select * from t8 where (a <= 10 and a >= 8) or (a <= 13 and a >= 11) or (a <= 16 and a >= 14)",
3131
"explain format = 'brief' select * from t8 where a < 12 and a > 9",
3232
"explain format = 'brief' select * from t9",
33-
"explain format = 'brief' select * from t10 where a between 0 AND 15218001646226433652"
33+
"explain format = 'brief' select * from t10 where a between 0 AND 15218001646226433652",
34+
"explain format = 'brief' select * from t11 where a is null",
35+
"explain format = 'brief' select * from t11 where a is null and b = 2",
36+
"explain format = 'brief' select * from t11 where a = 1 and b = 2"
3437
]
3538
},
3639
{

pkg/planner/core/casetest/partition/testdata/partition_pruner_out.json

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,30 @@
215215
"└─Selection 250.00 cop[tikv] ge(test_partition.t10.a, 0), le(test_partition.t10.a, 15218001646226433652)",
216216
" └─TableFullScan 10000.00 cop[tikv] table:t10 keep order:false, stats:pseudo"
217217
]
218+
},
219+
{
220+
"SQL": "explain format = 'brief' select * from t11 where a is null",
221+
"Result": [
222+
"TableReader 10.00 root partition:all data:Selection",
223+
"└─Selection 10.00 cop[tikv] isnull(test_partition.t11.a)",
224+
" └─TableFullScan 10000.00 cop[tikv] table:t11 keep order:false, stats:pseudo"
225+
]
226+
},
227+
{
228+
"SQL": "explain format = 'brief' select * from t11 where a is null and b = 2",
229+
"Result": [
230+
"TableReader 0.01 root partition:p0 data:Selection",
231+
"└─Selection 0.01 cop[tikv] eq(test_partition.t11.b, 2), isnull(test_partition.t11.a)",
232+
" └─TableFullScan 10000.00 cop[tikv] table:t11 keep order:false, stats:pseudo"
233+
]
234+
},
235+
{
236+
"SQL": "explain format = 'brief' select * from t11 where a = 1 and b = 2",
237+
"Result": [
238+
"TableReader 0.01 root partition:p0 data:Selection",
239+
"└─Selection 0.01 cop[tikv] eq(test_partition.t11.a, 1), eq(test_partition.t11.b, 2)",
240+
" └─TableFullScan 10000.00 cop[tikv] table:t11 keep order:false, stats:pseudo"
241+
]
218242
}
219243
]
220244
},

pkg/planner/core/rule_partition_processor.go

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -148,11 +148,18 @@ func generateHashPartitionExpr(ctx base.PlanContext, pi *model.PartitionInfo, co
148148
func getPartColumnsForHashPartition(hashExpr expression.Expression) ([]*expression.Column, []int) {
149149
partCols := expression.ExtractColumns(hashExpr)
150150
colLen := make([]int, 0, len(partCols))
151+
retCols := make([]*expression.Column, 0, len(partCols))
152+
filled := make(map[int64]struct{})
151153
for i := 0; i < len(partCols); i++ {
152-
partCols[i].Index = i
153-
colLen = append(colLen, types.UnspecifiedLength)
154+
// Deal with same columns.
155+
if _, done := filled[partCols[i].UniqueID]; !done {
156+
partCols[i].Index = len(filled)
157+
filled[partCols[i].UniqueID] = struct{}{}
158+
colLen = append(colLen, types.UnspecifiedLength)
159+
retCols = append(retCols, partCols[i])
160+
}
154161
}
155-
return partCols, colLen
162+
return retCols, colLen
156163
}
157164

158165
func (s *PartitionProcessor) getUsedHashPartitions(ctx base.PlanContext,
@@ -247,16 +254,15 @@ func (s *PartitionProcessor) getUsedHashPartitions(ctx base.PlanContext,
247254
used = []int{FullRange}
248255
break
249256
}
250-
if !r.HighVal[0].IsNull() {
251-
if len(r.HighVal) != len(partCols) {
252-
used = []int{-1}
253-
break
254-
}
257+
258+
// The code below is for the range `r` is a point.
259+
if len(r.HighVal) != len(partCols) {
260+
used = []int{FullRange}
261+
break
255262
}
256-
highLowVals := make([]types.Datum, 0, len(r.HighVal)+len(r.LowVal))
257-
highLowVals = append(highLowVals, r.HighVal...)
258-
highLowVals = append(highLowVals, r.LowVal...)
259-
pos, isNull, err := hashExpr.EvalInt(ctx.GetExprCtx().GetEvalCtx(), chunk.MutRowFromDatums(highLowVals).ToRow())
263+
vals := make([]types.Datum, 0, len(partCols))
264+
vals = append(vals, r.HighVal...)
265+
pos, isNull, err := hashExpr.EvalInt(ctx.GetExprCtx().GetEvalCtx(), chunk.MutRowFromDatums(vals).ToRow())
260266
if err != nil {
261267
// If we failed to get the point position, we can just skip and ignore it.
262268
continue

0 commit comments

Comments
 (0)