Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ddl: add more functional tests for REORGANIZE PARTITION #42209

Merged
merged 5 commits into from
Mar 15, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
554 changes: 554 additions & 0 deletions ddl/reorg_partition_test.go
Original file line number Diff line number Diff line change
@@ -313,6 +313,276 @@ func TestReorganizeRangePartition(t *testing.T) {
" PARTITION `p2` VALUES LESS THAN (35),\n" +
" PARTITION `p3` VALUES LESS THAN (47),\n" +
" PARTITION `p4` VALUES LESS THAN (90))"))

// Test reorganize range partitions works when a function defined as the key.
tk.MustExec("drop table t")
tk.MustExec(`create table t (a int PRIMARY KEY, b varchar(255), c int, key (b), key (c,b)) partition by range (abs(a)) ` +
`(partition p0 values less than (10),` +
` partition p1 values less than (20),` +
` partition pMax values less than (MAXVALUE))`)
tk.MustExec(`insert into t values (0,"0",0),(1,"1",1),(2,"2",-2),(-12,"12",21),(23,"23",32),(-34,"34",43),(45,"45",54),(56,"56",65)`)
tk.MustExec(`alter table t reorganize partition pMax into (partition p2 values less than (30), partition pMax values less than (MAXVALUE))`)
tk.MustExec(`admin check table t`)
tk.MustQuery(`show create table t`).Check(testkit.Rows("" +
"t CREATE TABLE `t` (\n" +
" `a` int(11) NOT NULL,\n" +
" `b` varchar(255) DEFAULT NULL,\n" +
" `c` int(11) DEFAULT NULL,\n" +
" PRIMARY KEY (`a`) /*T![clustered_index] CLUSTERED */,\n" +
" KEY `b` (`b`),\n" +
" KEY `c` (`c`,`b`)\n" +
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin\n" +
"PARTITION BY RANGE (ABS(`a`))\n" +
"(PARTITION `p0` VALUES LESS THAN (10),\n" +
" PARTITION `p1` VALUES LESS THAN (20),\n" +
" PARTITION `p2` VALUES LESS THAN (30),\n" +
" PARTITION `pMax` VALUES LESS THAN (MAXVALUE))"))
tk.MustQuery(`select * from t partition (p2)`).Sort().Check(testkit.Rows("" +
"23 23 32"))
tk.MustQuery(`select * from t partition (pMax)`).Sort().Check(testkit.Rows(""+
"-34 34 43", "45 45 54", "56 56 65"))
tk.MustExec(`alter table t drop index b`)
tk.MustExec(`alter table t reorganize partition p0,p1,p2,pMax into (partition pAll values less than (maxvalue))`)
tk.MustExec(`admin check table t`)
tk.MustQuery(`show create table t`).Check(testkit.Rows("" +
"t CREATE TABLE `t` (\n" +
" `a` int(11) NOT NULL,\n" +
" `b` varchar(255) DEFAULT NULL,\n" +
" `c` int(11) DEFAULT NULL,\n" +
" PRIMARY KEY (`a`) /*T![clustered_index] CLUSTERED */,\n" +
" KEY `c` (`c`,`b`)\n" +
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin\n" +
"PARTITION BY RANGE (ABS(`a`))\n" +
"(PARTITION `pAll` VALUES LESS THAN (MAXVALUE))"))
tk.MustQuery(`select * from t partition (pAll)`).Sort().Check(testkit.Rows(""+
"-12 12 21", "-34 34 43", "0 0 0", "1 1 1", "2 2 -2", "23 23 32", "45 45 54", "56 56 65"))
}

func TestReorganizeRangeColumnsPartition(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
// Test reorganize range columns partitions works for integer and string defined as the key.
tk.MustExec("CREATE DATABASE ReorgPartition")
tk.MustExec("USE ReorgPartition")
tk.MustExec(`
CREATE TABLE t (
a INT,
b CHAR(3),
c INT,
KEY b(b),
KEY c(c,b)
)
PARTITION BY RANGE COLUMNS(a,b) (
PARTITION p0 VALUES LESS THAN (5,'ggg'),
PARTITION p1 VALUES LESS THAN (10,'mmm'),
PARTITION p2 VALUES LESS THAN (15,'sss'),
PARTITION pMax VALUES LESS THAN (MAXVALUE,MAXVALUE)
);
`)
tk.MustExec(`INSERT INTO t VALUES (1,'abc',1), (3,'ggg',3),(5,'ggg',5), (9,'ggg',9),(10,'mmm',10),(19,'xxx',19);`)
tk.MustQuery(`SELECT * FROM t PARTITION(p0)`).Sort().Check(testkit.Rows(""+
"1 abc 1",
"3 ggg 3"))
tk.MustExec(`ALTER TABLE t DROP INDEX c`)
tk.MustExec(`ALTER TABLE t REORGANIZE PARTITION p0 into (PARTITION p00 VALUES LESS THAN (2,'ggg'), PARTITION p01 VALUES LESS THAN (5,'ggg'));`)
tk.MustExec(`ADMIN CHECK TABLE t`)
tk.MustQuery(`SHOW CREATE TABLE t`).Check(testkit.Rows("" +
"t CREATE TABLE `t` (\n" +
" `a` int(11) DEFAULT NULL,\n" +
" `b` char(3) DEFAULT NULL,\n" +
" `c` int(11) DEFAULT NULL,\n" +
" KEY `b` (`b`)\n" +
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin\n" +
"PARTITION BY RANGE COLUMNS(`a`,`b`)\n" +
"(PARTITION `p00` VALUES LESS THAN (2,'ggg'),\n" +
" PARTITION `p01` VALUES LESS THAN (5,'ggg'),\n" +
" PARTITION `p1` VALUES LESS THAN (10,'mmm'),\n" +
" PARTITION `p2` VALUES LESS THAN (15,'sss'),\n" +
" PARTITION `pMax` VALUES LESS THAN (MAXVALUE,MAXVALUE))"))
tk.MustQuery(`SELECT * FROM t PARTITION(p00)`).Sort().Check(testkit.Rows("1 abc 1"))
tk.MustQuery(`SELECT * FROM t PARTITION(p01)`).Sort().Check(testkit.Rows("3 ggg 3"))

// Test reorganize range columns partitions works for string and integer defined as the key.
tk.MustExec("DROP TABLE t")
tk.MustExec(`
CREATE TABLE t (
a INT,
b CHAR(3),
c INT,
KEY b(b),
KEY c(c,b)
)
PARTITION BY RANGE COLUMNS(b,a) (
PARTITION p0 VALUES LESS THAN ('ggg',5),
PARTITION p1 VALUES LESS THAN ('mmm',10),
PARTITION p2 VALUES LESS THAN ('sss',15),
PARTITION pMax VALUES LESS THAN (MAXVALUE,MAXVALUE)
);
`)
tk.MustExec(`INSERT INTO t VALUES (1,'abc',1), (3,'ccc',3),(5,'ggg',5), (9,'ggg',9),(10,'mmm',10),(19,'xxx',19);`)
tk.MustQuery(`SELECT * FROM t PARTITION(p0)`).Sort().Check(testkit.Rows(""+
"1 abc 1",
"3 ccc 3"))
tk.MustExec("ALTER TABLE t DROP INDEX b")
tk.MustExec(`ALTER TABLE t REORGANIZE PARTITION p0 into (PARTITION p00 VALUES LESS THAN ('ccc',2), PARTITION p01 VALUES LESS THAN ('ggg',5));`)
tk.MustExec(`ADMIN CHECK TABLE t`)
tk.MustQuery(`SHOW CREATE TABLE t`).Check(testkit.Rows("" +
"t CREATE TABLE `t` (\n" +
" `a` int(11) DEFAULT NULL,\n" +
" `b` char(3) DEFAULT NULL,\n" +
" `c` int(11) DEFAULT NULL,\n" +
" KEY `c` (`c`,`b`)\n" +
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin\n" +
"PARTITION BY RANGE COLUMNS(`b`,`a`)\n" +
"(PARTITION `p00` VALUES LESS THAN ('ccc',2),\n" +
" PARTITION `p01` VALUES LESS THAN ('ggg',5),\n" +
" PARTITION `p1` VALUES LESS THAN ('mmm',10),\n" +
" PARTITION `p2` VALUES LESS THAN ('sss',15),\n" +
" PARTITION `pMax` VALUES LESS THAN (MAXVALUE,MAXVALUE))"))
tk.MustQuery(`SELECT * FROM t PARTITION(p00)`).Sort().Check(testkit.Rows("1 abc 1"))
tk.MustQuery(`SELECT * FROM t PARTITION(p01)`).Sort().Check(testkit.Rows("3 ccc 3"))
tk.MustExec(`ALTER TABLE t REORGANIZE PARTITION p00,p01,p1 into (PARTITION p1 VALUES LESS THAN ('mmm',10));`)
tk.MustExec(`ADMIN CHECK TABLE t`)
tk.MustQuery(`SHOW CREATE TABLE t`).Check(testkit.Rows("" +
"t CREATE TABLE `t` (\n" +
" `a` int(11) DEFAULT NULL,\n" +
" `b` char(3) DEFAULT NULL,\n" +
" `c` int(11) DEFAULT NULL,\n" +
" KEY `c` (`c`,`b`)\n" +
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin\n" +
"PARTITION BY RANGE COLUMNS(`b`,`a`)\n" +
"(PARTITION `p1` VALUES LESS THAN ('mmm',10),\n" +
" PARTITION `p2` VALUES LESS THAN ('sss',15),\n" +
" PARTITION `pMax` VALUES LESS THAN (MAXVALUE,MAXVALUE))"))
tk.MustQuery(`SELECT * FROM t PARTITION(p1)`).Sort().Check(testkit.Rows(""+
"1 abc 1",
"3 ccc 3",
"5 ggg 5",
"9 ggg 9"))

// Test reorganize range columns partitions works for DATE and DATETIME defined as the key.
tk.MustExec("DROP TABLE t")
tk.MustExec(`
CREATE TABLE t (
a DATE,
b DATETIME,
c INT,
KEY b(b),
KEY c(c,b)
)
PARTITION BY RANGE COLUMNS(a,b) (
PARTITION p0 VALUES LESS THAN ('2020-05-05','2020-05-05 10:10:10'),
PARTITION p1 VALUES LESS THAN ('2021-05-05','2021-05-05 10:10:10'),
PARTITION p2 VALUES LESS THAN ('2022-05-05','2022-05-05 10:10:10'),
PARTITION pMax VALUES LESS THAN (MAXVALUE,MAXVALUE)
);
`)
tk.MustExec("INSERT INTO t VALUES" +
"('2020-04-10', '2020-04-10 10:10:10', 1), ('2020-05-04', '2020-05-04 10:10:10', 2)," +
"('2020-05-05', '2020-05-05 10:10:10', 3), ('2021-05-04', '2021-05-04 10:10:10', 4)," +
"('2022-05-05', '2022-05-05 10:10:10', 5), ('2023-05-05', '2023-05-05 10:10:10', 6);")
tk.MustExec("ALTER TABLE t REORGANIZE PARTITION p0 into (PARTITION p00 VALUES LESS THAN ('2020-04-10', '2020-04-10 10:10:10'), PARTITION p01 VALUES LESS THAN ('2020-05-05', '2020-05-05 10:10:10'));")
tk.MustExec("ADMIN CHECK TABLE t")
tk.MustQuery(`SHOW CREATE TABLE t`).Check(testkit.Rows("" +
"t CREATE TABLE `t` (\n" +
" `a` date DEFAULT NULL,\n" +
" `b` datetime DEFAULT NULL,\n" +
" `c` int(11) DEFAULT NULL,\n" +
" KEY `b` (`b`),\n" +
" KEY `c` (`c`,`b`)\n" +
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin\n" +
"PARTITION BY RANGE COLUMNS(`a`,`b`)\n" +
"(PARTITION `p00` VALUES LESS THAN ('2020-04-10','2020-04-10 10:10:10'),\n" +
" PARTITION `p01` VALUES LESS THAN ('2020-05-05','2020-05-05 10:10:10'),\n" +
" PARTITION `p1` VALUES LESS THAN ('2021-05-05','2021-05-05 10:10:10'),\n" +
" PARTITION `p2` VALUES LESS THAN ('2022-05-05','2022-05-05 10:10:10'),\n" +
" PARTITION `pMax` VALUES LESS THAN (MAXVALUE,MAXVALUE))"))
tk.MustQuery(`SELECT * FROM t PARTITION(p00)`).Check(testkit.Rows())
tk.MustQuery(`SELECT * FROM t PARTITION(p01)`).Sort().Check(testkit.Rows("2020-04-10 2020-04-10 10:10:10 1", "2020-05-04 2020-05-04 10:10:10 2"))
//TODO(bb7133): different err message with MySQL
tk.MustContainErrMsg(
"ALTER TABLE t REORGANIZE PARTITION p00,p01,p1,p2 into (PARTITION p0 VALUES LESS THAN ('2022-05-05', '2022-05-05 10:10:11'))",
"VALUES LESS THAN value must be strictly increasing for each partition")
tk.MustExec("ALTER TABLE t DROP INDEX c")
tk.MustExec("ALTER TABLE t REORGANIZE PARTITION p00,p01,p1,p2 into (PARTITION p0 VALUES LESS THAN ('2022-05-05', '2022-05-05 10:10:10'))")
tk.MustExec("ADMIN CHECK TABLE t")
tk.MustQuery(`SHOW CREATE TABLE t`).Check(testkit.Rows("" +
"t CREATE TABLE `t` (\n" +
" `a` date DEFAULT NULL,\n" +
" `b` datetime DEFAULT NULL,\n" +
" `c` int(11) DEFAULT NULL,\n" +
" KEY `b` (`b`)\n" +
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin\n" +
"PARTITION BY RANGE COLUMNS(`a`,`b`)\n" +
"(PARTITION `p0` VALUES LESS THAN ('2022-05-05','2022-05-05 10:10:10'),\n" +
" PARTITION `pMax` VALUES LESS THAN (MAXVALUE,MAXVALUE))"))
tk.MustExec("ADMIN CHECK TABLE t")
tk.MustQuery(`SELECT * FROM t PARTITION(p0)`).Sort().Check(testkit.Rows(
"2020-04-10 2020-04-10 10:10:10 1", "2020-05-04 2020-05-04 10:10:10 2",
"2020-05-05 2020-05-05 10:10:10 3", "2021-05-04 2021-05-04 10:10:10 4"))
tk.MustQuery(`SELECT * FROM t PARTITION(pMax)`).Sort().Check(testkit.Rows("2022-05-05 2022-05-05 10:10:10 5", "2023-05-05 2023-05-05 10:10:10 6"))

// Test reorganize range columns partitions works for DATETIME and DATE defined as the key.
tk.MustExec("DROP TABLE t")
tk.MustExec(`
CREATE TABLE t (
a DATE,
b DATETIME,
c INT,
KEY b(b),
KEY c(c,b)
)
PARTITION BY RANGE COLUMNS(b,a) (
PARTITION p0 VALUES LESS THAN ('2020-05-05 10:10:10','2020-05-05'),
PARTITION p1 VALUES LESS THAN ('2021-05-05 10:10:10','2021-05-05'),
PARTITION p2 VALUES LESS THAN ('2022-05-05 10:10:10','2022-05-05'),
PARTITION pMax VALUES LESS THAN (MAXVALUE,MAXVALUE)
);
`)
tk.MustExec("INSERT INTO t VALUES" +
"('2020-04-10', '2020-04-10 10:10:10', 1), ('2020-05-04', '2020-05-04 10:10:10', 2)," +
"('2020-05-05', '2020-05-05 10:10:10', 3), ('2021-05-04', '2021-05-04 10:10:10', 4)," +
"('2022-05-05', '2022-05-05 10:10:10', 5), ('2023-05-05', '2023-05-05 10:10:10', 6);")
tk.MustExec("ALTER TABLE t REORGANIZE PARTITION p0 into (PARTITION p00 VALUES LESS THAN ('2020-04-10 10:10:10', '2020-04-10'), PARTITION p01 VALUES LESS THAN ('2020-05-05 10:10:10', '2020-05-05'));")
tk.MustExec("ADMIN CHECK TABLE t")
tk.MustQuery(`SHOW CREATE TABLE t`).Check(testkit.Rows("" +
"t CREATE TABLE `t` (\n" +
" `a` date DEFAULT NULL,\n" +
" `b` datetime DEFAULT NULL,\n" +
" `c` int(11) DEFAULT NULL,\n" +
" KEY `b` (`b`),\n" +
" KEY `c` (`c`,`b`)\n" +
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin\n" +
"PARTITION BY RANGE COLUMNS(`b`,`a`)\n" +
"(PARTITION `p00` VALUES LESS THAN ('2020-04-10 10:10:10','2020-04-10'),\n" +
" PARTITION `p01` VALUES LESS THAN ('2020-05-05 10:10:10','2020-05-05'),\n" +
" PARTITION `p1` VALUES LESS THAN ('2021-05-05 10:10:10','2021-05-05'),\n" +
" PARTITION `p2` VALUES LESS THAN ('2022-05-05 10:10:10','2022-05-05'),\n" +
" PARTITION `pMax` VALUES LESS THAN (MAXVALUE,MAXVALUE))"))
tk.MustQuery(`SELECT * FROM t PARTITION(p00)`).Check(testkit.Rows())
tk.MustQuery(`SELECT * FROM t PARTITION(p01)`).Sort().Check(testkit.Rows("2020-04-10 2020-04-10 10:10:10 1", "2020-05-04 2020-05-04 10:10:10 2"))
tk.MustExec("ALTER TABLE t DROP INDEX b")
//TODO(bb7133): different err message with MySQL
tk.MustContainErrMsg(
"ALTER TABLE t REORGANIZE PARTITION p00,p01,p1,p2 into (PARTITION p0 VALUES LESS THAN ('2022-05-05 10:10:11', '2022-05-05'))",
"VALUES LESS THAN value must be strictly increasing for each partition")
tk.MustExec("ALTER TABLE t REORGANIZE PARTITION p00,p01,p1,p2 into (PARTITION p0 VALUES LESS THAN ('2022-05-05 10:10:10', '2022-05-05'))")
tk.MustExec("ADMIN CHECK TABLE t")
tk.MustQuery(`SHOW CREATE TABLE t`).Check(testkit.Rows("" +
"t CREATE TABLE `t` (\n" +
" `a` date DEFAULT NULL,\n" +
" `b` datetime DEFAULT NULL,\n" +
" `c` int(11) DEFAULT NULL,\n" +
" KEY `c` (`c`,`b`)\n" +
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin\n" +
"PARTITION BY RANGE COLUMNS(`b`,`a`)\n" +
"(PARTITION `p0` VALUES LESS THAN ('2022-05-05 10:10:10','2022-05-05'),\n" +
" PARTITION `pMax` VALUES LESS THAN (MAXVALUE,MAXVALUE))"))
tk.MustExec("ADMIN CHECK TABLE t")
tk.MustQuery(`SELECT * FROM t PARTITION(p0)`).Sort().Check(testkit.Rows(
"2020-04-10 2020-04-10 10:10:10 1", "2020-05-04 2020-05-04 10:10:10 2",
"2020-05-05 2020-05-05 10:10:10 3", "2021-05-04 2021-05-04 10:10:10 4"))
tk.MustQuery(`SELECT * FROM t PARTITION(pMax)`).Sort().Check(testkit.Rows("2022-05-05 2022-05-05 10:10:10 5", "2023-05-05 2023-05-05 10:10:10 6"))
}

func TestReorganizeListPartition(t *testing.T) {
@@ -358,6 +628,290 @@ func TestReorganizeListPartition(t *testing.T) {
" PARTITION `pa` VALUES IN (45,23,15),\n" +
" PARTITION `p2` VALUES IN (24,63))"))
tk.MustGetErrCode(`alter table t modify a varchar(20)`, errno.ErrUnsupportedDDLOperation)

// Test reorganize list partitions works when a function defined as the key.
tk.MustExec("drop table t")
tk.MustExec(`create table t (a int, b varchar(55), c int) partition by list (abs(a))
(partition p0 values in (-1,0,1),
partition p1 values in (12,23,51,14),
partition p2 values in (24,63),
partition p3 values in (45))`)
tk.MustExec(`insert into t values
(-1,"-1",11),(1,"1",11),(0,"0",0),(-12,"-12",21),
(-24,"-24",42),(51,"-51",15),(23,"23",32),(63,"63",36),(45,"45",54)`)
tk.MustExec(`alter table t reorganize partition p0, p1 into (partition p0 values in (0,1,2,12,51,13), partition p1 values in (23))`)
tk.MustExec(`admin check table t`)
tk.MustQuery(`select * from t partition (p0)`).Sort().Check(testkit.Rows(""+
"-1 -1 11", "-12 -12 21", "0 0 0", "1 1 11", "51 -51 15"))
tk.MustQuery(`show create table t`).Check(testkit.Rows("" +
"t CREATE TABLE `t` (\n" +
" `a` int(11) DEFAULT NULL,\n" +
" `b` varchar(55) DEFAULT NULL,\n" +
" `c` int(11) DEFAULT NULL\n" +
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin\n" +
"PARTITION BY LIST (ABS(`a`))\n" +
"(PARTITION `p0` VALUES IN (0,1,2,12,51,13),\n" +
" PARTITION `p1` VALUES IN (23),\n" +
" PARTITION `p2` VALUES IN (24,63),\n" +
" PARTITION `p3` VALUES IN (45))"))
tk.MustExec(`alter table t add primary key (a), add key (b), add key (c,b)`)

tk.MustExec(`alter table t reorganize partition p0,p1,p2,p3 into (partition paa values in (0,1,2,12,13,23,24,45,51,63,64))`)
tk.MustExec(`admin check table t`)
tk.MustQuery(`select * from t partition (paa)`).Sort().Check(testkit.Rows(""+
"-1 -1 11", "-12 -12 21", "-24 -24 42", "0 0 0", "1 1 11", "23 23 32", "45 45 54", "51 -51 15", "63 63 36"))
tk.MustQuery(`show create table t`).Check(testkit.Rows("" +
"t CREATE TABLE `t` (\n" +
" `a` int(11) NOT NULL,\n" +
" `b` varchar(55) DEFAULT NULL,\n" +
" `c` int(11) DEFAULT NULL,\n" +
" PRIMARY KEY (`a`) /*T![clustered_index] NONCLUSTERED */,\n" +
" KEY `b` (`b`),\n" +
" KEY `c` (`c`,`b`)\n" +
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin\n" +
"PARTITION BY LIST (ABS(`a`))\n" +
"(PARTITION `paa` VALUES IN (0,1,2,12,13,23,24,45,51,63,64))"))
}

func TestReorganizeListColumnsPartition(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("CREATE DATABASE ReorgPartition")
tk.MustExec("USE ReorgPartition")
// Test reorganize list columns partitions works for interger and string defined as the key.
tk.MustExec(`
CREATE TABLE t (
a INT,
b CHAR(3),
c INT,
KEY b(b),
KEY c(c,b)
)
PARTITION BY LIST COLUMNS(a,b) (
PARTITION p0 VALUES IN ((1,'aaa'),(2,'bbb'),(3,'ccc')),
PARTITION p1 VALUES IN ((4,'ddd'),(5,'eee'),(6,'fff')),
PARTITION p2 VALUES IN ((16,'lll'),(17,'mmm'),(18,'lll'))
);
`)
tk.MustExec(`INSERT INTO t VALUES (1,'aaa',1), (3,'ccc',3),(5,'eee',5), (16,'lll',16);`)
tk.MustQuery(`SELECT * FROM t PARTITION(p0)`).Sort().Check(testkit.Rows(""+
"1 aaa 1",
"3 ccc 3"))
//TODO(bb7133) MySQL 8 does not report an error if there's any row does not fit the new partitions, instead the row will be removed.
tk.MustContainErrMsg(`ALTER TABLE t REORGANIZE PARTITION p0 into (PARTITION p00 VALUES IN ((0,'uuu'),(1,'aaa')), PARTITION p01 VALUES IN ((2,'bbb')));`, "Table has no partition for value from column_list")
tk.MustExec(`ALTER TABLE t REORGANIZE PARTITION p0 into (PARTITION p00 VALUES IN ((0,'uuu'),(1,'aaa')), PARTITION p01 VALUES IN ((2,'bbb'),(3,'ccc')));`)
tk.MustExec(`ADMIN CHECK TABLE t`)
tk.MustQuery(`SHOW CREATE TABLE t`).Check(testkit.Rows("" +
"t CREATE TABLE `t` (\n" +
" `a` int(11) DEFAULT NULL,\n" +
" `b` char(3) DEFAULT NULL,\n" +
" `c` int(11) DEFAULT NULL,\n" +
" KEY `b` (`b`),\n" +
" KEY `c` (`c`,`b`)\n" +
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin\n" +
"PARTITION BY LIST COLUMNS(`a`,`b`)\n" +
"(PARTITION `p00` VALUES IN ((0,'uuu'),(1,'aaa')),\n" +
" PARTITION `p01` VALUES IN ((2,'bbb'),(3,'ccc')),\n" +
" PARTITION `p1` VALUES IN ((4,'ddd'),(5,'eee'),(6,'fff')),\n" +
" PARTITION `p2` VALUES IN ((16,'lll'),(17,'mmm'),(18,'lll')))"))
tk.MustQuery(`SELECT * FROM t PARTITION(p00)`).Sort().Check(testkit.Rows("1 aaa 1"))
tk.MustQuery(`SELECT * FROM t PARTITION(p01)`).Sort().Check(testkit.Rows("3 ccc 3"))
tk.MustExec("ALTER TABLE t DROP INDEX b")
tk.MustExec(`ALTER TABLE t REORGANIZE PARTITION p00,p01,p1,p2 into (PARTITION pAll VALUES IN
((0,'uuu'),(1,'aaa'),(2,'bbb'),(3,'ccc'),(4,'ddd'),(5,'eee'),(6,'fff'),(16,'lll'),(17,'mmm'),(18,'lll')));`)
tk.MustExec(`ADMIN CHECK TABLE t`)
tk.MustQuery(`SELECT * FROM t PARTITION(pAll)`).Sort().Check(testkit.Rows("1 aaa 1", "16 lll 16", "3 ccc 3", "5 eee 5"))
tk.MustQuery(`SELECT * FROM t`).Sort().Check(testkit.Rows("1 aaa 1", "16 lll 16", "3 ccc 3", "5 eee 5"))

// Test reorganize list columns partitions works for string and integer defined as the key.
tk.MustExec("DROP TABLE t")
tk.MustExec(`
CREATE TABLE t (
a INT,
b CHAR(3),
c INT,
KEY b(b),
KEY c(c,b)
)
PARTITION BY LIST COLUMNS(b,a) (
PARTITION p0 VALUES IN (('aaa',1),('bbb',2),('ccc',3)),
PARTITION p1 VALUES IN (('ddd',4),('eee',5),('fff',6)),
PARTITION p2 VALUES IN (('lll',16),('mmm',17),('lll',18))
);
`)
tk.MustExec(`INSERT INTO t VALUES (1,'aaa',1), (3,'ccc',3),(5,'eee',5), (16,'lll',16);`)
tk.MustQuery(`SELECT * FROM t PARTITION(p0)`).Sort().Check(testkit.Rows(""+
"1 aaa 1",
"3 ccc 3"))
tk.MustExec(`ALTER TABLE t REORGANIZE PARTITION p0 into (PARTITION p00 VALUES IN (('uuu',-1),('aaa',1)), PARTITION p01 VALUES IN (('bbb',2),('ccc',3),('ccc',4)));`)
tk.MustExec(`ADMIN CHECK TABLE t`)
tk.MustQuery(`SHOW CREATE TABLE t`).Check(testkit.Rows("" +
"t CREATE TABLE `t` (\n" +
" `a` int(11) DEFAULT NULL,\n" +
" `b` char(3) DEFAULT NULL,\n" +
" `c` int(11) DEFAULT NULL,\n" +
" KEY `b` (`b`),\n" +
" KEY `c` (`c`,`b`)\n" +
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin\n" +
"PARTITION BY LIST COLUMNS(`b`,`a`)\n" +
"(PARTITION `p00` VALUES IN (('uuu',-1),('aaa',1)),\n" +
" PARTITION `p01` VALUES IN (('bbb',2),('ccc',3),('ccc',4)),\n" +
" PARTITION `p1` VALUES IN (('ddd',4),('eee',5),('fff',6)),\n" +
" PARTITION `p2` VALUES IN (('lll',16),('mmm',17),('lll',18)))"))
tk.MustQuery(`SELECT * FROM t PARTITION(p00)`).Sort().Check(testkit.Rows("1 aaa 1"))
tk.MustQuery(`SELECT * FROM t PARTITION(p01)`).Sort().Check(testkit.Rows("3 ccc 3"))
tk.MustExec("ALTER TABLE t DROP INDEX c")
tk.MustExec(`ALTER TABLE t REORGANIZE PARTITION p00,p01,p1,p2 into (PARTITION pAll VALUES IN
(('uuu',-1),('aaa',1),('bbb',2),('ccc',3),('ccc',4),('ddd',4),('eee',5),('fff',6),('lll',16),('mmm',17),('lll',18)));`)
tk.MustExec(`ADMIN CHECK TABLE t`)
tk.MustQuery(`SELECT * FROM t PARTITION(pAll)`).Sort().Check(testkit.Rows("1 aaa 1", "16 lll 16", "3 ccc 3", "5 eee 5"))
tk.MustQuery(`SELECT * FROM t`).Sort().Check(testkit.Rows("1 aaa 1", "16 lll 16", "3 ccc 3", "5 eee 5"))

// Test reorganize list columns partitions works for DATE and DATETIME defined as the key.
tk.MustExec("DROP TABLE t")
tk.MustExec(`
CREATE TABLE t (
a DATE,
b DATETIME,
c INT,
KEY b(b),
KEY c(c,b)
)
PARTITION BY LIST COLUMNS(a,b) (
PARTITION p0 VALUES IN (('2020-04-10','2020-04-10 10:10:10'),('2020-05-04','2020-05-04 10:10:10')),
PARTITION p1 VALUES IN (('2021-05-04','2021-05-04 10:10:10'),('2021-05-05','2021-05-05 10:10:10')),
PARTITION p2 VALUES IN (('2022-05-04','2022-05-04 10:10:10'),('2022-05-05','2022-05-06 11:11:11'))
);
`)
tk.MustExec("INSERT INTO t VALUES" +
"('2020-04-10', '2020-04-10 10:10:10', 1), ('2020-05-04', '2020-05-04 10:10:10', 2)," +
"('2020-05-04', '2020-05-04 10:10:10', 3), ('2021-05-04', '2021-05-04 10:10:10', 4)," +
"('2022-05-04', '2022-05-04 10:10:10', 5), ('2022-05-05', '2022-05-06 11:11:11', 6);")
tk.MustExec("ALTER TABLE t REORGANIZE PARTITION p0 into (PARTITION p00 VALUES IN (('2020-04-10', '2020-04-10 10:10:10')), PARTITION p01 VALUES IN (('2020-05-04', '2020-05-04 10:10:10')));")
tk.MustExec("ADMIN CHECK TABLE t")
tk.MustQuery(`SHOW CREATE TABLE t`).Check(testkit.Rows("" +
"t CREATE TABLE `t` (\n" +
" `a` date DEFAULT NULL,\n" +
" `b` datetime DEFAULT NULL,\n" +
" `c` int(11) DEFAULT NULL,\n" +
" KEY `b` (`b`),\n" +
" KEY `c` (`c`,`b`)\n" +
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin\n" +
"PARTITION BY LIST COLUMNS(`a`,`b`)\n" +
"(PARTITION `p00` VALUES IN (('2020-04-10','2020-04-10 10:10:10')),\n" +
" PARTITION `p01` VALUES IN (('2020-05-04','2020-05-04 10:10:10')),\n" +
" PARTITION `p1` VALUES IN (('2021-05-04','2021-05-04 10:10:10'),('2021-05-05','2021-05-05 10:10:10')),\n" +
" PARTITION `p2` VALUES IN (('2022-05-04','2022-05-04 10:10:10'),('2022-05-05','2022-05-06 11:11:11')))"))
tk.MustQuery(`SELECT * FROM t PARTITION(p00)`).Check(testkit.Rows("2020-04-10 2020-04-10 10:10:10 1"))
tk.MustQuery(`SELECT * FROM t PARTITION(p01)`).Sort().Check(testkit.Rows("2020-05-04 2020-05-04 10:10:10 2", "2020-05-04 2020-05-04 10:10:10 3"))
tk.MustExec("ALTER TABLE t DROP INDEX b")
//TODO(bb7133) MySQL 8 does not report an error if there's any row does not fit the new partitions, instead the row will be removed.
tk.MustContainErrMsg(
"ALTER TABLE t REORGANIZE PARTITION p00,p01,p1,p2 into (PARTITION pAll VALUES IN "+
"(('2020-04-10','2020-04-10 10:10:10'),('2020-05-04','2020-05-04 10:10:10'),"+
" ('2021-05-04','2021-05-04 10:10:10'),('2021-05-05','2021-05-05 10:10:10'),"+
" ('2022-05-04','2022-05-04 10:10:10'),('2022-05-05','2023-05-05 11:11:11')))",
"Table has no partition for value from column_list")
tk.MustExec(
"ALTER TABLE t REORGANIZE PARTITION p00,p01,p1,p2 into (PARTITION pAll VALUES IN " +
"(('2020-04-10','2020-04-10 10:10:10'),('2020-05-04','2020-05-04 10:10:10')," +
" ('2021-05-04','2021-05-04 10:10:10'),('2021-05-05','2021-05-05 10:10:10')," +
" ('2022-05-04','2022-05-04 10:10:10'),('2022-05-05','2022-05-06 11:11:11')))")
tk.MustExec("ADMIN CHECK TABLE t")
tk.MustQuery(`SHOW CREATE TABLE t`).Check(testkit.Rows("" +
"t CREATE TABLE `t` (\n" +
" `a` date DEFAULT NULL,\n" +
" `b` datetime DEFAULT NULL,\n" +
" `c` int(11) DEFAULT NULL,\n" +
" KEY `c` (`c`,`b`)\n" +
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin\n" +
"PARTITION BY LIST COLUMNS(`a`,`b`)\n" +
"(PARTITION `pAll` VALUES IN " +
"(('2020-04-10','2020-04-10 10:10:10'),('2020-05-04','2020-05-04 10:10:10')," +
"('2021-05-04','2021-05-04 10:10:10'),('2021-05-05','2021-05-05 10:10:10')," +
"('2022-05-04','2022-05-04 10:10:10'),('2022-05-05','2022-05-06 11:11:11')))"))
tk.MustExec("ADMIN CHECK TABLE t")
tk.MustQuery(`SELECT * FROM t PARTITION(pAll)`).Sort().Check(testkit.Rows(
"2020-04-10 2020-04-10 10:10:10 1", "2020-05-04 2020-05-04 10:10:10 2",
"2020-05-04 2020-05-04 10:10:10 3", "2021-05-04 2021-05-04 10:10:10 4",
"2022-05-04 2022-05-04 10:10:10 5", "2022-05-05 2022-05-06 11:11:11 6"))
tk.MustQuery(`SELECT * FROM t`).Sort().Check(testkit.Rows(
"2020-04-10 2020-04-10 10:10:10 1", "2020-05-04 2020-05-04 10:10:10 2",
"2020-05-04 2020-05-04 10:10:10 3", "2021-05-04 2021-05-04 10:10:10 4",
"2022-05-04 2022-05-04 10:10:10 5", "2022-05-05 2022-05-06 11:11:11 6"))

// Test reorganize list columns partitions works for DATETIME and DATE defined as the key.
tk.MustExec("DROP TABLE t")
tk.MustExec(`
CREATE TABLE t (
a DATE,
b DATETIME,
c INT,
KEY b(b),
KEY c(c,b)
)
PARTITION BY LIST COLUMNS(b,a) (
PARTITION p0 VALUES IN (('2020-04-10 10:10:10','2020-04-10'),('2020-05-04 10:10:10','2020-05-04')),
PARTITION p1 VALUES IN (('2021-05-04 10:10:10','2021-05-04'),('2021-05-05 10:10:10','2021-05-05')),
PARTITION p2 VALUES IN (('2022-05-04 10:10:10','2022-05-04'),('2022-05-06 11:11:11','2022-05-05'))
);
`)
tk.MustExec("INSERT INTO t VALUES" +
"('2020-04-10', '2020-04-10 10:10:10', 1), ('2020-05-04', '2020-05-04 10:10:10', 2)," +
"('2020-05-04', '2020-05-04 10:10:10', 3), ('2021-05-04', '2021-05-04 10:10:10', 4)," +
"('2022-05-04', '2022-05-04 10:10:10', 5), ('2022-05-05', '2022-05-06 11:11:11', 6);")
tk.MustExec("ALTER TABLE t REORGANIZE PARTITION p0 into (PARTITION p00 VALUES IN (('2020-04-10 10:10:10','2020-04-10')), PARTITION p01 VALUES IN (('2020-05-04 10:10:10','2020-05-04')));")
tk.MustExec("ADMIN CHECK TABLE t")
tk.MustQuery(`SHOW CREATE TABLE t`).Check(testkit.Rows("" +
"t CREATE TABLE `t` (\n" +
" `a` date DEFAULT NULL,\n" +
" `b` datetime DEFAULT NULL,\n" +
" `c` int(11) DEFAULT NULL,\n" +
" KEY `b` (`b`),\n" +
" KEY `c` (`c`,`b`)\n" +
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin\n" +
"PARTITION BY LIST COLUMNS(`b`,`a`)\n" +
"(PARTITION `p00` VALUES IN (('2020-04-10 10:10:10','2020-04-10')),\n" +
" PARTITION `p01` VALUES IN (('2020-05-04 10:10:10','2020-05-04')),\n" +
" PARTITION `p1` VALUES IN (('2021-05-04 10:10:10','2021-05-04'),('2021-05-05 10:10:10','2021-05-05')),\n" +
" PARTITION `p2` VALUES IN (('2022-05-04 10:10:10','2022-05-04'),('2022-05-06 11:11:11','2022-05-05')))"))
tk.MustQuery(`SELECT * FROM t PARTITION(p00)`).Check(testkit.Rows("2020-04-10 2020-04-10 10:10:10 1"))
tk.MustQuery(`SELECT * FROM t PARTITION(p01)`).Sort().Check(testkit.Rows("2020-05-04 2020-05-04 10:10:10 2", "2020-05-04 2020-05-04 10:10:10 3"))
tk.MustExec("ALTER TABLE t DROP INDEX b")
//TODO(bb7133) MySQL 8 does not report an error if there's any row does not fit the new partitions, instead the row will be removed.
tk.MustContainErrMsg(
"ALTER TABLE t REORGANIZE PARTITION p00,p01,p1,p2 into (PARTITION pAll VALUES IN "+
"(('2020-04-10 10:10:10','2020-04-10'),('2020-05-04 10:10:10','2020-05-04'),"+
" ('2021-05-04 10:10:10','2021-05-04'),('2021-05-05 10:10:10','2021-05-05'),"+
" ('2022-05-04 10:10:10','2022-05-04'),('2022-05-06 11:11:11','2023-05-05')))",
"Table has no partition for value from column_list")
tk.MustExec(
"ALTER TABLE t REORGANIZE PARTITION p00,p01,p1,p2 into (PARTITION pAll VALUES IN " +
"(('2020-04-10 10:10:10','2020-04-10'),('2020-05-04 10:10:10','2020-05-04')," +
" ('2021-05-04 10:10:10','2021-05-04'),('2021-05-05 10:10:10','2021-05-05')," +
" ('2022-05-04 10:10:10','2022-05-04'),('2022-05-06 11:11:11','2022-05-05')))")
tk.MustExec("ADMIN CHECK TABLE t")
tk.MustQuery(`SHOW CREATE TABLE t`).Check(testkit.Rows("" +
"t CREATE TABLE `t` (\n" +
" `a` date DEFAULT NULL,\n" +
" `b` datetime DEFAULT NULL,\n" +
" `c` int(11) DEFAULT NULL,\n" +
" KEY `c` (`c`,`b`)\n" +
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin\n" +
"PARTITION BY LIST COLUMNS(`b`,`a`)\n" +
"(PARTITION `pAll` VALUES IN " +
"(('2020-04-10 10:10:10','2020-04-10'),('2020-05-04 10:10:10','2020-05-04')," +
"('2021-05-04 10:10:10','2021-05-04'),('2021-05-05 10:10:10','2021-05-05')," +
"('2022-05-04 10:10:10','2022-05-04'),('2022-05-06 11:11:11','2022-05-05')))"))
tk.MustExec("ADMIN CHECK TABLE t")
tk.MustQuery(`SELECT * FROM t PARTITION(pAll)`).Sort().Check(testkit.Rows(
"2020-04-10 2020-04-10 10:10:10 1", "2020-05-04 2020-05-04 10:10:10 2",
"2020-05-04 2020-05-04 10:10:10 3", "2021-05-04 2021-05-04 10:10:10 4",
"2022-05-04 2022-05-04 10:10:10 5", "2022-05-05 2022-05-06 11:11:11 6"))
tk.MustQuery(`SELECT * FROM t`).Sort().Check(testkit.Rows(
"2020-04-10 2020-04-10 10:10:10 1", "2020-05-04 2020-05-04 10:10:10 2",
"2020-05-04 2020-05-04 10:10:10 3", "2021-05-04 2021-05-04 10:10:10 4",
"2022-05-04 2022-05-04 10:10:10 5", "2022-05-05 2022-05-06 11:11:11 6"))
}

type TestReorgDDLCallback struct {