Skip to content

Commit

Permalink
partition: fix exchange partition validition check for null value (#4…
Browse files Browse the repository at this point in the history
  • Loading branch information
jiyfhust authored Feb 28, 2024
1 parent 33d7a2c commit f505eda
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 3 deletions.
16 changes: 14 additions & 2 deletions pkg/ddl/partition.go
Original file line number Diff line number Diff line change
Expand Up @@ -3578,6 +3578,14 @@ func checkExchangePartitionRecordValidation(w *worker, ptbl, ntbl table.Table, p
buf.WriteString(pi.Expr)
buf.WriteString(", %?) != %?")
paramList = append(paramList, pi.Num, index)
if index != 0 {
// TODO: if hash result can't be NULL, we can remove the check part.
// For example hash(id), but id is defined not NULL.
buf.WriteString(" or mod(")
buf.WriteString(pi.Expr)
buf.WriteString(", %?) is null")
paramList = append(paramList, pi.Num, index)
}
}
case model.PartitionTypeRange:
// Table has only one partition and has the maximum value
Expand Down Expand Up @@ -3691,13 +3699,17 @@ func buildCheckSQLConditionForRangeExprPartition(pi *model.PartitionInfo, index
paramList = append(paramList, driver.UnwrapFromSingleQuotes(pi.Definitions[index].LessThan[0]))
} else if index == len(pi.Definitions)-1 && strings.EqualFold(pi.Definitions[index].LessThan[0], partitionMaxValue) {
buf.WriteString(pi.Expr)
buf.WriteString(" < %?")
buf.WriteString(" < %? or ")
buf.WriteString(pi.Expr)
buf.WriteString(" is null")
paramList = append(paramList, driver.UnwrapFromSingleQuotes(pi.Definitions[index-1].LessThan[0]))
} else {
buf.WriteString(pi.Expr)
buf.WriteString(" < %? or ")
buf.WriteString(pi.Expr)
buf.WriteString(" >= %?")
buf.WriteString(" >= %? or ")
buf.WriteString(pi.Expr)
buf.WriteString(" is null")
paramList = append(paramList, driver.UnwrapFromSingleQuotes(pi.Definitions[index-1].LessThan[0]), driver.UnwrapFromSingleQuotes(pi.Definitions[index].LessThan[0]))
}
return buf.String(), paramList
Expand Down
2 changes: 1 addition & 1 deletion pkg/ddl/tests/partition/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ go_test(
"main_test.go",
],
flaky = True,
shard_count = 44,
shard_count = 45,
deps = [
"//pkg/config",
"//pkg/ddl",
Expand Down
39 changes: 39 additions & 0 deletions pkg/ddl/tests/partition/db_partition_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3413,3 +3413,42 @@ func TestAlterLastIntervalPartition(t *testing.T) {
}

// TODO: check EXCHANGE how it handles null (for all types of partitioning!!!)
func TestExchangeValidateHandleNullValue(t *testing.T) {
store := testkit.CreateMockStore(t)

tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")

tk.MustExec(`CREATE TABLE t1 (id int, c varchar(128)) PARTITION BY HASH (id) PARTITIONS 3`)
tk.MustExec(`CREATE TABLE t2 (id int, c varchar(128))`)
tk.MustExec(`insert into t1 values(null, 'a1')`)
tk.MustExec(`insert into t2 values(null, 'b2')`)
tk.MustQuery(`select id, c from t1 partition(p0)`).Check(testkit.Rows("<nil> a1"))
tk.MustContainErrMsg(`alter table t1 EXCHANGE PARTITION p1 WITH TABLE t2`,
"[ddl:1737]Found a row that does not match the partition")
tk.MustExec(`alter table t1 EXCHANGE PARTITION p0 WITH TABLE t2`)

tk.MustExec(`CREATE TABLE t3 (id int, c date) PARTITION BY HASH (year(c)) PARTITIONS 12`)
tk.MustExec(`CREATE TABLE t4 (id int, c date)`)
tk.MustExec(`insert into t3 values(1, null)`)
tk.MustExec(`insert into t4 values(2, null)`)
tk.MustQuery(`select id, c from t3 partition(p0)`).Check(testkit.Rows("1 <nil>"))
tk.MustContainErrMsg(`alter table t3 EXCHANGE PARTITION p1 WITH TABLE t4`,
"[ddl:1737]Found a row that does not match the partition")
tk.MustExec(`alter table t3 EXCHANGE PARTITION p0 WITH TABLE t4`)

tk.MustExec(`CREATE TABLE t5 (id int, c varchar(128)) partition by range (id)(
partition p0 values less than (10),
partition p1 values less than (20),
partition p2 values less than (maxvalue))`)
tk.MustExec(`CREATE TABLE t6 (id int, c varchar(128))`)
tk.MustExec(`insert into t5 values(null, 'a5')`)
tk.MustExec(`insert into t6 values(null, 'b6')`)
tk.MustQuery(`select id, c from t5 partition(p0)`).Check(testkit.Rows("<nil> a5"))
tk.MustContainErrMsg(`alter table t5 EXCHANGE PARTITION p1 WITH TABLE t6`,
"[ddl:1737]Found a row that does not match the partition")
tk.MustContainErrMsg(`alter table t5 EXCHANGE PARTITION p2 WITH TABLE t6`,
"[ddl:1737]Found a row that does not match the partition")
tk.MustExec(`alter table t5 EXCHANGE PARTITION p0 WITH TABLE t6`)
// TODO: add "partition by range columns(a, b, c)" test cases.
}

0 comments on commit f505eda

Please sign in to comment.