github.com/whtcorpsinc/milevadb-prod@v0.0.0-20211104133533-f57f4be3b597/dbs/db_partition_test.go (about) 1 // Copyright 2020 WHTCORPS INC, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package dbs_test 15 16 import ( 17 "context" 18 "fmt" 19 "math" 20 "math/rand" 21 "strings" 22 "sync/atomic" 23 "time" 24 25 "github.com/whtcorpsinc/BerolinaSQL/allegrosql" 26 "github.com/whtcorpsinc/BerolinaSQL/ast" 27 "github.com/whtcorpsinc/BerolinaSQL/perceptron" 28 "github.com/whtcorpsinc/BerolinaSQL/terror" 29 . "github.com/whtcorpsinc/check" 30 "github.com/whtcorpsinc/errors" 31 "github.com/whtcorpsinc/failpoint" 32 "github.com/whtcorpsinc/milevadb/blockcodec" 33 "github.com/whtcorpsinc/milevadb/causet" 34 "github.com/whtcorpsinc/milevadb/causet/blocks" 35 "github.com/whtcorpsinc/milevadb/dbs" 36 "github.com/whtcorpsinc/milevadb/dbs/solitonutil" 37 "github.com/whtcorpsinc/milevadb/ekv" 38 tmysql "github.com/whtcorpsinc/milevadb/errno" 39 "github.com/whtcorpsinc/milevadb/petri" 40 "github.com/whtcorpsinc/milevadb/soliton/admin" 41 "github.com/whtcorpsinc/milevadb/soliton/mock" 42 "github.com/whtcorpsinc/milevadb/soliton/testkit" 43 "github.com/whtcorpsinc/milevadb/spacetime" 44 "github.com/whtcorpsinc/milevadb/stochastik" 45 "github.com/whtcorpsinc/milevadb/stochastikctx" 46 "github.com/whtcorpsinc/milevadb/types" 47 ) 48 49 func (s *testIntegrationSuite3) TestCreateBlockWithPartition(c *C) { 50 tk := testkit.NewTestKit(c, s.causetstore) 51 tk.MustInterDirc("use test;") 52 tk.MustInterDirc("drop causet if exists tp;") 53 tk.MustInterDirc(`CREATE TABLE tp (a int) PARTITION BY RANGE(a) ( 54 PARTITION p0 VALUES LESS THAN (10), 55 PARTITION p1 VALUES LESS THAN (20), 56 PARTITION p2 VALUES LESS THAN (MAXVALUE) 57 );`) 58 ctx := tk.Se.(stochastikctx.Context) 59 is := petri.GetPetri(ctx).SchemaReplicant() 60 tbl, err := is.BlockByName(perceptron.NewCIStr("test"), perceptron.NewCIStr("tp")) 61 c.Assert(err, IsNil) 62 c.Assert(tbl.Meta().Partition, NotNil) 63 part := tbl.Meta().Partition 64 c.Assert(part.Type, Equals, perceptron.PartitionTypeRange) 65 c.Assert(part.Expr, Equals, "`a`") 66 for _, FIDelef := range part.Definitions { 67 c.Assert(FIDelef.ID, Greater, int64(0)) 68 } 69 c.Assert(part.Definitions, HasLen, 3) 70 c.Assert(part.Definitions[0].LessThan[0], Equals, "10") 71 c.Assert(part.Definitions[0].Name.L, Equals, "p0") 72 c.Assert(part.Definitions[1].LessThan[0], Equals, "20") 73 c.Assert(part.Definitions[1].Name.L, Equals, "p1") 74 c.Assert(part.Definitions[2].LessThan[0], Equals, "MAXVALUE") 75 c.Assert(part.Definitions[2].Name.L, Equals, "p2") 76 77 tk.MustInterDirc("drop causet if exists employees;") 78 sql1 := `create causet employees ( 79 id int not null, 80 hired int not null 81 ) 82 partition by range( hired ) ( 83 partition p1 values less than (1991), 84 partition p2 values less than (1996), 85 partition p2 values less than (2001) 86 );` 87 tk.MustGetErrCode(sql1, tmysql.ErrSameNamePartition) 88 89 sql2 := `create causet employees ( 90 id int not null, 91 hired int not null 92 ) 93 partition by range( hired ) ( 94 partition p1 values less than (1998), 95 partition p2 values less than (1996), 96 partition p3 values less than (2001) 97 );` 98 tk.MustGetErrCode(sql2, tmysql.ErrRangeNotIncreasing) 99 100 sql3 := `create causet employees ( 101 id int not null, 102 hired int not null 103 ) 104 partition by range( hired ) ( 105 partition p1 values less than (1998), 106 partition p2 values less than maxvalue, 107 partition p3 values less than (2001) 108 );` 109 tk.MustGetErrCode(sql3, tmysql.ErrPartitionMaxvalue) 110 111 sql4 := `create causet t4 ( 112 a int not null, 113 b int not null 114 ) 115 partition by range( a ) ( 116 partition p1 values less than maxvalue, 117 partition p2 values less than (1991), 118 partition p3 values less than (1995) 119 );` 120 tk.MustGetErrCode(sql4, tmysql.ErrPartitionMaxvalue) 121 122 _, err = tk.InterDirc(`CREATE TABLE rc ( 123 a INT NOT NULL, 124 b INT NOT NULL, 125 c INT NOT NULL 126 ) 127 partition by range defCausumns(a,b,c) ( 128 partition p0 values less than (10,5,1), 129 partition p2 values less than (50,maxvalue,10), 130 partition p3 values less than (65,30,13), 131 partition p4 values less than (maxvalue,30,40) 132 );`) 133 c.Assert(err, IsNil) 134 135 sql6 := `create causet employees ( 136 id int not null, 137 hired int not null 138 ) 139 partition by range( hired ) ( 140 partition p0 values less than (6 , 10) 141 );` 142 tk.MustGetErrCode(sql6, tmysql.ErrTooManyValues) 143 144 sql7 := `create causet t7 ( 145 a int not null, 146 b int not null 147 ) 148 partition by range( a ) ( 149 partition p1 values less than (1991), 150 partition p2 values less than maxvalue, 151 partition p3 values less than maxvalue, 152 partition p4 values less than (1995), 153 partition p5 values less than maxvalue 154 );` 155 tk.MustGetErrCode(sql7, tmysql.ErrPartitionMaxvalue) 156 157 sql18 := `create causet t8 ( 158 a int not null, 159 b int not null 160 ) 161 partition by range( a ) ( 162 partition p1 values less than (19xx91), 163 partition p2 values less than maxvalue 164 );` 165 tk.MustGetErrCode(sql18, allegrosql.ErrBadField) 166 167 sql9 := `create TABLE t9 ( 168 defCaus1 int 169 ) 170 partition by range( case when defCaus1 > 0 then 10 else 20 end ) ( 171 partition p0 values less than (2), 172 partition p1 values less than (6) 173 );` 174 tk.MustGetErrCode(sql9, tmysql.ErrPartitionFunctionIsNotAllowed) 175 176 _, err = tk.InterDirc(`CREATE TABLE t9 ( 177 a INT NOT NULL, 178 b INT NOT NULL, 179 c INT NOT NULL 180 ) 181 partition by range defCausumns(a) ( 182 partition p0 values less than (10), 183 partition p2 values less than (20), 184 partition p3 values less than (20) 185 );`) 186 c.Assert(dbs.ErrRangeNotIncreasing.Equal(err), IsTrue) 187 188 tk.MustGetErrCode(`create TABLE t10 (c1 int,c2 int) partition by range(c1 / c2 ) (partition p0 values less than (2));`, tmysql.ErrPartitionFunctionIsNotAllowed) 189 190 tk.MustInterDirc(`create TABLE t11 (c1 int,c2 int) partition by range(c1 div c2 ) (partition p0 values less than (2));`) 191 tk.MustInterDirc(`create TABLE t12 (c1 int,c2 int) partition by range(c1 + c2 ) (partition p0 values less than (2));`) 192 tk.MustInterDirc(`create TABLE t13 (c1 int,c2 int) partition by range(c1 - c2 ) (partition p0 values less than (2));`) 193 tk.MustInterDirc(`create TABLE t14 (c1 int,c2 int) partition by range(c1 * c2 ) (partition p0 values less than (2));`) 194 tk.MustInterDirc(`create TABLE t15 (c1 int,c2 int) partition by range( abs(c1) ) (partition p0 values less than (2));`) 195 tk.MustInterDirc(`create TABLE t16 (c1 int) partition by range( c1) (partition p0 values less than (10));`) 196 197 tk.MustGetErrCode(`create TABLE t17 (c1 int,c2 float) partition by range(c1 + c2 ) (partition p0 values less than (2));`, tmysql.ErrPartitionFuncNotAllowed) 198 tk.MustGetErrCode(`create TABLE t18 (c1 int,c2 float) partition by range( floor(c2) ) (partition p0 values less than (2));`, tmysql.ErrPartitionFuncNotAllowed) 199 tk.MustInterDirc(`create TABLE t19 (c1 int,c2 float) partition by range( floor(c1) ) (partition p0 values less than (2));`) 200 201 tk.MustInterDirc(`create TABLE t20 (c1 int,c2 bit(10)) partition by range(c2) (partition p0 values less than (10));`) 202 tk.MustInterDirc(`create TABLE t21 (c1 int,c2 year) partition by range( c2 ) (partition p0 values less than (2000));`) 203 204 tk.MustGetErrCode(`create TABLE t24 (c1 float) partition by range( c1 ) (partition p0 values less than (2000));`, tmysql.ErrFieldTypeNotAllowedAsPartitionField) 205 206 // test check order. The allegrosql below have 2 problem: 1. ErrFieldTypeNotAllowedAsPartitionField 2. ErrPartitionMaxvalue , allegrosql will return ErrPartitionMaxvalue. 207 tk.MustGetErrCode(`create TABLE t25 (c1 float) partition by range( c1 ) (partition p1 values less than maxvalue,partition p0 values less than (2000));`, tmysql.ErrPartitionMaxvalue) 208 209 // Fix issue 7362. 210 tk.MustInterDirc("create causet test_partition(id bigint, name varchar(255), primary key(id)) ENGINE=InnoDB DEFAULT CHARSET=utf8 PARTITION BY RANGE COLUMNS(id) (PARTITION p1 VALUES LESS THAN (10) ENGINE = InnoDB);") 211 212 // 'Less than' in partition memex could be a constant memex, notice that 213 // the SHOW result changed. 214 tk.MustInterDirc(`create causet t26 (a date) 215 partition by range(to_seconds(a))( 216 partition p0 values less than (to_seconds('2004-01-01')), 217 partition p1 values less than (to_seconds('2005-01-01')));`) 218 tk.MustQuery("show create causet t26").Check( 219 testkit.Rows("t26 CREATE TABLE `t26` (\n `a` date DEFAULT NULL\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin\nPARTITION BY RANGE ( TO_SECONDS(`a`) ) (\n PARTITION `p0` VALUES LESS THAN (63240134400),\n PARTITION `p1` VALUES LESS THAN (63271756800)\n)")) 220 tk.MustInterDirc(`create causet t27 (a bigint unsigned not null) 221 partition by range(a) ( 222 partition p0 values less than (10), 223 partition p1 values less than (100), 224 partition p2 values less than (1000), 225 partition p3 values less than (18446744073709551000), 226 partition p4 values less than (18446744073709551614) 227 );`) 228 tk.MustInterDirc(`create causet t28 (a bigint unsigned not null) 229 partition by range(a) ( 230 partition p0 values less than (10), 231 partition p1 values less than (100), 232 partition p2 values less than (1000), 233 partition p3 values less than (18446744073709551000 + 1), 234 partition p4 values less than (18446744073709551000 + 10) 235 );`) 236 237 tk.MustInterDirc("set @@milevadb_enable_block_partition = 1") 238 tk.MustInterDirc("set @@milevadb_enable_block_partition = 1") 239 tk.MustInterDirc(`create causet t30 ( 240 a int, 241 b float, 242 c varchar(30)) 243 partition by range defCausumns (a, b) 244 (partition p0 values less than (10, 10.0))`) 245 tk.MustQuery("show warnings").Check(testkit.Rows("Warning 8200 Unsupported partition type, treat as normal causet")) 246 247 tk.MustGetErrCode(`create causet t31 (a int not null) partition by range( a );`, tmysql.ErrPartitionsMustBeDefined) 248 tk.MustGetErrCode(`create causet t32 (a int not null) partition by range defCausumns( a );`, tmysql.ErrPartitionsMustBeDefined) 249 tk.MustGetErrCode(`create causet t33 (a int, b int) partition by hash(a) partitions 0;`, tmysql.ErrNoParts) 250 tk.MustGetErrCode(`create causet t33 (a timestamp, b int) partition by hash(a) partitions 30;`, tmysql.ErrFieldTypeNotAllowedAsPartitionField) 251 tk.MustGetErrCode(`CREATE TABLE t34 (c0 INT) PARTITION BY HASH((CASE WHEN 0 THEN 0 ELSE c0 END )) PARTITIONS 1;`, tmysql.ErrPartitionFunctionIsNotAllowed) 252 tk.MustGetErrCode(`CREATE TABLE t0(c0 INT) PARTITION BY HASH((c0<CURRENT_USER())) PARTITIONS 1;`, tmysql.ErrPartitionFunctionIsNotAllowed) 253 // TODO: fix this one 254 // tk.MustGetErrCode(`create causet t33 (a timestamp, b int) partition by hash(unix_timestamp(a)) partitions 30;`, tmysql.ErrPartitionFuncNotAllowed) 255 256 // Fix issue 8647 257 tk.MustGetErrCode(`CREATE TABLE trb8 ( 258 id int(11) DEFAULT NULL, 259 name varchar(50) DEFAULT NULL, 260 purchased date DEFAULT NULL 261 ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin 262 PARTITION BY RANGE ( year(notexist.purchased) - 1 ) ( 263 PARTITION p0 VALUES LESS THAN (1990), 264 PARTITION p1 VALUES LESS THAN (1995), 265 PARTITION p2 VALUES LESS THAN (2000), 266 PARTITION p3 VALUES LESS THAN (2005) 267 );`, tmysql.ErrBadField) 268 269 // Fix a timezone dependent check bug introduced in https://github.com/whtcorpsinc/milevadb/pull/10655 270 tk.MustInterDirc(`create causet t34 (dt timestamp(3)) partition by range (floor(unix_timestamp(dt))) ( 271 partition p0 values less than (unix_timestamp('2020-04-04 00:00:00')), 272 partition p1 values less than (unix_timestamp('2020-04-05 00:00:00')));`) 273 274 tk.MustGetErrCode(`create causet t34 (dt timestamp(3)) partition by range (unix_timestamp(date(dt))) ( 275 partition p0 values less than (unix_timestamp('2020-04-04 00:00:00')), 276 partition p1 values less than (unix_timestamp('2020-04-05 00:00:00')));`, tmysql.ErrWrongExprInPartitionFunc) 277 278 tk.MustGetErrCode(`create causet t34 (dt datetime) partition by range (unix_timestamp(dt)) ( 279 partition p0 values less than (unix_timestamp('2020-04-04 00:00:00')), 280 partition p1 values less than (unix_timestamp('2020-04-05 00:00:00')));`, tmysql.ErrWrongExprInPartitionFunc) 281 282 // Fix https://github.com/whtcorpsinc/milevadb/issues/16333 283 tk.MustInterDirc(`create causet t35 (dt timestamp) partition by range (unix_timestamp(dt)) 284 (partition p0 values less than (unix_timestamp('2020-04-15 00:00:00')));`) 285 286 tk.MustInterDirc(`drop causet if exists too_long_identifier`) 287 tk.MustGetErrCode(`create causet too_long_identifier(a int) 288 partition by range (a) 289 (partition p0pppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppp values less than (10));`, tmysql.ErrTooLongIdent) 290 291 tk.MustInterDirc(`drop causet if exists too_long_identifier`) 292 tk.MustInterDirc("create causet too_long_identifier(a int) partition by range(a) (partition p0 values less than(10))") 293 tk.MustGetErrCode("alter causet too_long_identifier add partition "+ 294 "(partition p0pppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppp values less than(20))", tmysql.ErrTooLongIdent) 295 296 tk.MustInterDirc(`create causet t36 (a date, b datetime) partition by range (EXTRACT(YEAR_MONTH FROM a)) ( 297 partition p0 values less than (200), 298 partition p1 values less than (300), 299 partition p2 values less than maxvalue)`) 300 } 301 302 func (s *testIntegrationSuite2) TestCreateBlockWithHashPartition(c *C) { 303 tk := testkit.NewTestKit(c, s.causetstore) 304 tk.MustInterDirc("use test;") 305 tk.MustInterDirc("drop causet if exists employees;") 306 tk.MustInterDirc("set @@stochastik.milevadb_enable_block_partition = 1") 307 tk.MustInterDirc(` 308 create causet employees ( 309 id int not null, 310 fname varchar(30), 311 lname varchar(30), 312 hired date not null default '1970-01-01', 313 separated date not null default '9999-12-31', 314 job_code int, 315 store_id int 316 ) 317 partition by hash(store_id) partitions 4;`) 318 319 tk.MustInterDirc("drop causet if exists employees;") 320 tk.MustInterDirc(` 321 create causet employees ( 322 id int not null, 323 fname varchar(30), 324 lname varchar(30), 325 hired date not null default '1970-01-01', 326 separated date not null default '9999-12-31', 327 job_code int, 328 store_id int 329 ) 330 partition by hash( year(hired) ) partitions 4;`) 331 332 // This query makes milevadb OOM without partition count check. 333 tk.MustGetErrCode(`CREATE TABLE employees ( 334 id INT NOT NULL, 335 fname VARCHAR(30), 336 lname VARCHAR(30), 337 hired DATE NOT NULL DEFAULT '1970-01-01', 338 separated DATE NOT NULL DEFAULT '9999-12-31', 339 job_code INT, 340 store_id INT 341 ) PARTITION BY HASH(store_id) PARTITIONS 102400000000;`, tmysql.ErrTooManyPartitions) 342 343 tk.MustInterDirc("CREATE TABLE t_linear (a int, b varchar(128)) PARTITION BY LINEAR HASH(a) PARTITIONS 4") 344 tk.MustGetErrCode("select * from t_linear partition (p0)", tmysql.ErrPartitionClauseOnNonpartitioned) 345 346 tk.MustInterDirc(`CREATE TABLE t_sub (a int, b varchar(128)) PARTITION BY RANGE( a ) SUBPARTITION BY HASH( a ) 347 SUBPARTITIONS 2 ( 348 PARTITION p0 VALUES LESS THAN (100), 349 PARTITION p1 VALUES LESS THAN (200), 350 PARTITION p2 VALUES LESS THAN MAXVALUE)`) 351 tk.MustGetErrCode("select * from t_sub partition (p0)", tmysql.ErrPartitionClauseOnNonpartitioned) 352 353 // Fix create partition causet using extract() function as partition key. 354 tk.MustInterDirc("create causet t2 (a date, b datetime) partition by hash (EXTRACT(YEAR_MONTH FROM a)) partitions 7") 355 } 356 357 func (s *testIntegrationSuite1) TestCreateBlockWithRangeDeferredCausetPartition(c *C) { 358 tk := testkit.NewTestKit(c, s.causetstore) 359 tk.MustInterDirc("use test;") 360 tk.MustInterDirc("drop causet if exists log_message_1;") 361 tk.MustInterDirc("set @@stochastik.milevadb_enable_block_partition = 1") 362 tk.MustInterDirc(` 363 create causet log_message_1 ( 364 add_time datetime not null default '2000-01-01 00:00:00', 365 log_level int unsigned not null default '0', 366 log_host varchar(32) not null, 367 service_name varchar(32) not null, 368 message varchar(2000) 369 ) partition by range defCausumns(add_time)( 370 partition p201403 values less than ('2020-04-01'), 371 partition p201404 values less than ('2020-05-01'), 372 partition p201405 values less than ('2020-06-01'), 373 partition p201406 values less than ('2020-07-01'), 374 partition p201407 values less than ('2020-08-01'), 375 partition p201408 values less than ('2020-09-01'), 376 partition p201409 values less than ('2020-10-01'), 377 partition p201410 values less than ('2020-11-01') 378 )`) 379 tk.MustInterDirc("drop causet if exists log_message_1;") 380 tk.MustInterDirc(` 381 create causet log_message_1 ( 382 id int not null, 383 fname varchar(30), 384 lname varchar(30), 385 hired date not null default '1970-01-01', 386 separated date not null default '9999-12-31', 387 job_code int, 388 store_id int 389 ) 390 partition by hash( year(hired) ) partitions 4;`) 391 392 tk.MustInterDirc("drop causet if exists t") 393 394 type testCase struct { 395 allegrosql string 396 err *terror.Error 397 } 398 399 cases := []testCase{ 400 { 401 "create causet t (id int) partition by range defCausumns (id);", 402 ast.ErrPartitionsMustBeDefined, 403 }, 404 { 405 "create causet t (id int) partition by range defCausumns (id) (partition p0 values less than (1, 2));", 406 ast.ErrPartitionDeferredCausetList, 407 }, 408 { 409 "create causet t (a int) partition by range defCausumns (b) (partition p0 values less than (1, 2));", 410 ast.ErrPartitionDeferredCausetList, 411 }, 412 { 413 "create causet t (a int) partition by range defCausumns (b) (partition p0 values less than (1));", 414 dbs.ErrFieldNotFoundPart, 415 }, 416 { 417 "create causet t (id timestamp) partition by range defCausumns (id) (partition p0 values less than ('2020-01-09 11:23:34'));", 418 dbs.ErrNotAllowedTypeInPartition, 419 }, 420 { 421 `create causet t29 ( 422 a decimal 423 ) 424 partition by range defCausumns (a) 425 (partition p0 values less than (0));`, 426 dbs.ErrNotAllowedTypeInPartition, 427 }, 428 { 429 "create causet t (id text) partition by range defCausumns (id) (partition p0 values less than ('abc'));", 430 dbs.ErrNotAllowedTypeInPartition, 431 }, 432 // create as normal causet, warning. 433 // { 434 // "create causet t (a int, b varchar(64)) partition by range defCausumns (a, b) (" + 435 // "partition p0 values less than (1, 'a')," + 436 // "partition p1 values less than (1, 'a'))", 437 // dbs.ErrRangeNotIncreasing, 438 // }, 439 { 440 "create causet t (a int, b varchar(64)) partition by range defCausumns ( b) (" + 441 "partition p0 values less than ( 'a')," + 442 "partition p1 values less than ('a'))", 443 dbs.ErrRangeNotIncreasing, 444 }, 445 // create as normal causet, warning. 446 // { 447 // "create causet t (a int, b varchar(64)) partition by range defCausumns (a, b) (" + 448 // "partition p0 values less than (1, 'b')," + 449 // "partition p1 values less than (1, 'a'))", 450 // dbs.ErrRangeNotIncreasing, 451 // }, 452 { 453 "create causet t (a int, b varchar(64)) partition by range defCausumns (b) (" + 454 "partition p0 values less than ('b')," + 455 "partition p1 values less than ('a'))", 456 dbs.ErrRangeNotIncreasing, 457 }, 458 // create as normal causet, warning. 459 // { 460 // "create causet t (a int, b varchar(64)) partition by range defCausumns (a, b) (" + 461 // "partition p0 values less than (1, maxvalue)," + 462 // "partition p1 values less than (1, 'a'))", 463 // dbs.ErrRangeNotIncreasing, 464 // }, 465 { 466 "create causet t (a int, b varchar(64)) partition by range defCausumns ( b) (" + 467 "partition p0 values less than ( maxvalue)," + 468 "partition p1 values less than ('a'))", 469 dbs.ErrRangeNotIncreasing, 470 }, 471 { 472 "create causet t (defCaus datetime not null default '2000-01-01')" + 473 "partition by range defCausumns (defCaus) (" + 474 "PARTITION p0 VALUES LESS THAN (20190905)," + 475 "PARTITION p1 VALUES LESS THAN (20190906));", 476 dbs.ErrWrongTypeDeferredCausetValue, 477 }, 478 } 479 for i, t := range cases { 480 _, err := tk.InterDirc(t.allegrosql) 481 c.Assert(t.err.Equal(err), IsTrue, Commentf( 482 "case %d fail, allegrosql = `%s`\nexpected error = `%v`\n actual error = `%v`", 483 i, t.allegrosql, t.err, err, 484 )) 485 } 486 487 tk.MustInterDirc("create causet t1 (a int, b char(3)) partition by range defCausumns (a, b) (" + 488 "partition p0 values less than (1, 'a')," + 489 "partition p1 values less than (2, maxvalue))") 490 491 tk.MustInterDirc("create causet t2 (a int, b char(3)) partition by range defCausumns (b) (" + 492 "partition p0 values less than ( 'a')," + 493 "partition p1 values less than (maxvalue))") 494 } 495 496 func (s *testIntegrationSuite3) TestCreateBlockWithKeyPartition(c *C) { 497 tk := testkit.NewTestKit(c, s.causetstore) 498 tk.MustInterDirc("use test;") 499 tk.MustInterDirc("drop causet if exists tm1;") 500 tk.MustInterDirc(`create causet tm1 501 ( 502 s1 char(32) primary key 503 ) 504 partition by key(s1) partitions 10;`) 505 506 tk.MustInterDirc(`drop causet if exists tm2`) 507 tk.MustInterDirc(`create causet tm2 (a char(5), unique key(a(5))) partition by key() partitions 5;`) 508 } 509 510 func (s *testIntegrationSuite5) TestAlterBlockAddPartition(c *C) { 511 tk := testkit.NewTestKit(c, s.causetstore) 512 tk.MustInterDirc("use test;") 513 tk.MustInterDirc("drop causet if exists employees;") 514 tk.MustInterDirc(`create causet employees ( 515 id int not null, 516 hired date not null 517 ) 518 partition by range( year(hired) ) ( 519 partition p1 values less than (1991), 520 partition p2 values less than (1996), 521 partition p3 values less than (2001) 522 );`) 523 tk.MustInterDirc(`alter causet employees add partition ( 524 partition p4 values less than (2010), 525 partition p5 values less than MAXVALUE 526 );`) 527 528 ctx := tk.Se.(stochastikctx.Context) 529 is := petri.GetPetri(ctx).SchemaReplicant() 530 tbl, err := is.BlockByName(perceptron.NewCIStr("test"), perceptron.NewCIStr("employees")) 531 c.Assert(err, IsNil) 532 c.Assert(tbl.Meta().Partition, NotNil) 533 part := tbl.Meta().Partition 534 c.Assert(part.Type, Equals, perceptron.PartitionTypeRange) 535 536 c.Assert(part.Expr, Equals, "YEAR(`hired`)") 537 c.Assert(part.Definitions, HasLen, 5) 538 c.Assert(part.Definitions[0].LessThan[0], Equals, "1991") 539 c.Assert(part.Definitions[0].Name, Equals, perceptron.NewCIStr("p1")) 540 c.Assert(part.Definitions[1].LessThan[0], Equals, "1996") 541 c.Assert(part.Definitions[1].Name, Equals, perceptron.NewCIStr("p2")) 542 c.Assert(part.Definitions[2].LessThan[0], Equals, "2001") 543 c.Assert(part.Definitions[2].Name, Equals, perceptron.NewCIStr("p3")) 544 c.Assert(part.Definitions[3].LessThan[0], Equals, "2010") 545 c.Assert(part.Definitions[3].Name, Equals, perceptron.NewCIStr("p4")) 546 c.Assert(part.Definitions[4].LessThan[0], Equals, "MAXVALUE") 547 c.Assert(part.Definitions[4].Name, Equals, perceptron.NewCIStr("p5")) 548 549 tk.MustInterDirc("drop causet if exists block1;") 550 tk.MustInterDirc("create causet block1(a int)") 551 sql1 := `alter causet block1 add partition ( 552 partition p1 values less than (2010), 553 partition p2 values less than maxvalue 554 );` 555 tk.MustGetErrCode(sql1, tmysql.ErrPartitionMgmtOnNonpartitioned) 556 tk.MustInterDirc(`create causet block_MustBeDefined ( 557 id int not null, 558 hired date not null 559 ) 560 partition by range( year(hired) ) ( 561 partition p1 values less than (1991), 562 partition p2 values less than (1996), 563 partition p3 values less than (2001) 564 );`) 565 sql2 := "alter causet block_MustBeDefined add partition" 566 tk.MustGetErrCode(sql2, tmysql.ErrPartitionsMustBeDefined) 567 tk.MustInterDirc("drop causet if exists block2;") 568 tk.MustInterDirc(`create causet block2 ( 569 570 id int not null, 571 hired date not null 572 ) 573 partition by range( year(hired) ) ( 574 partition p1 values less than (1991), 575 partition p2 values less than maxvalue 576 );`) 577 578 sql3 := `alter causet block2 add partition ( 579 partition p3 values less than (2010) 580 );` 581 tk.MustGetErrCode(sql3, tmysql.ErrPartitionMaxvalue) 582 583 tk.MustInterDirc("drop causet if exists block3;") 584 tk.MustInterDirc(`create causet block3 ( 585 id int not null, 586 hired date not null 587 ) 588 partition by range( year(hired) ) ( 589 partition p1 values less than (1991), 590 partition p2 values less than (2001) 591 );`) 592 593 sql4 := `alter causet block3 add partition ( 594 partition p3 values less than (1993) 595 );` 596 tk.MustGetErrCode(sql4, tmysql.ErrRangeNotIncreasing) 597 598 sql5 := `alter causet block3 add partition ( 599 partition p1 values less than (1993) 600 );` 601 tk.MustGetErrCode(sql5, tmysql.ErrSameNamePartition) 602 603 sql6 := `alter causet block3 add partition ( 604 partition p1 values less than (1993), 605 partition p1 values less than (1995) 606 );` 607 tk.MustGetErrCode(sql6, tmysql.ErrSameNamePartition) 608 609 sql7 := `alter causet block3 add partition ( 610 partition p4 values less than (1993), 611 partition p1 values less than (1995), 612 partition p5 values less than maxvalue 613 );` 614 tk.MustGetErrCode(sql7, tmysql.ErrSameNamePartition) 615 616 sql8 := "alter causet block3 add partition (partition p6);" 617 tk.MustGetErrCode(sql8, tmysql.ErrPartitionRequiresValues) 618 619 sql9 := "alter causet block3 add partition (partition p7 values in (2020));" 620 tk.MustGetErrCode(sql9, tmysql.ErrPartitionWrongValues) 621 622 sql10 := "alter causet block3 add partition partitions 4;" 623 tk.MustGetErrCode(sql10, tmysql.ErrPartitionsMustBeDefined) 624 625 tk.MustInterDirc("alter causet block3 add partition (partition p3 values less than (2001 + 10))") 626 627 // less than value can be negative or memex. 628 tk.MustInterDirc(`CREATE TABLE tt5 ( 629 c3 bigint(20) NOT NULL 630 ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin 631 PARTITION BY RANGE ( c3 ) ( 632 PARTITION p0 VALUES LESS THAN (-3), 633 PARTITION p1 VALUES LESS THAN (-2) 634 );`) 635 tk.MustInterDirc(`ALTER TABLE tt5 add partition ( partition p2 values less than (-1) );`) 636 tk.MustInterDirc(`ALTER TABLE tt5 add partition ( partition p3 values less than (5-1) );`) 637 638 // Test add partition for the causet partition by range defCausumns. 639 tk.MustInterDirc("drop causet if exists t;") 640 tk.MustInterDirc("create causet t (a datetime) partition by range defCausumns (a) (partition p1 values less than ('2020-06-01'), partition p2 values less than ('2020-07-01'));") 641 allegrosql := "alter causet t add partition ( partition p3 values less than ('2020-07-01'));" 642 tk.MustGetErrCode(allegrosql, tmysql.ErrRangeNotIncreasing) 643 tk.MustInterDirc("alter causet t add partition ( partition p3 values less than ('2020-08-01'));") 644 645 // Add partition value's type should be the same with the defCausumn's type. 646 tk.MustInterDirc("drop causet if exists t;") 647 tk.MustInterDirc(`create causet t ( 648 defCaus date not null default '2000-01-01') 649 partition by range defCausumns (defCaus) ( 650 PARTITION p0 VALUES LESS THAN ('20190905'), 651 PARTITION p1 VALUES LESS THAN ('20190906'));`) 652 allegrosql = "alter causet t add partition (partition p2 values less than (20190907));" 653 tk.MustGetErrCode(allegrosql, tmysql.ErrWrongTypeDeferredCausetValue) 654 } 655 656 func (s *testIntegrationSuite5) TestAlterBlockDropPartition(c *C) { 657 tk := testkit.NewTestKit(c, s.causetstore) 658 tk.MustInterDirc("use test") 659 tk.MustInterDirc("drop causet if exists employees") 660 tk.MustInterDirc(`create causet employees ( 661 id int not null, 662 hired int not null 663 ) 664 partition by range( hired ) ( 665 partition p1 values less than (1991), 666 partition p2 values less than (1996), 667 partition p3 values less than (2001) 668 );`) 669 670 tk.MustInterDirc("alter causet employees drop partition p3;") 671 ctx := tk.Se.(stochastikctx.Context) 672 is := petri.GetPetri(ctx).SchemaReplicant() 673 tbl, err := is.BlockByName(perceptron.NewCIStr("test"), perceptron.NewCIStr("employees")) 674 c.Assert(err, IsNil) 675 c.Assert(tbl.Meta().GetPartitionInfo(), NotNil) 676 part := tbl.Meta().Partition 677 c.Assert(part.Type, Equals, perceptron.PartitionTypeRange) 678 c.Assert(part.Expr, Equals, "`hired`") 679 c.Assert(part.Definitions, HasLen, 2) 680 c.Assert(part.Definitions[0].LessThan[0], Equals, "1991") 681 c.Assert(part.Definitions[0].Name, Equals, perceptron.NewCIStr("p1")) 682 c.Assert(part.Definitions[1].LessThan[0], Equals, "1996") 683 c.Assert(part.Definitions[1].Name, Equals, perceptron.NewCIStr("p2")) 684 685 tk.MustInterDirc("drop causet if exists block1;") 686 tk.MustInterDirc("create causet block1 (a int);") 687 sql1 := "alter causet block1 drop partition p10;" 688 tk.MustGetErrCode(sql1, tmysql.ErrPartitionMgmtOnNonpartitioned) 689 690 tk.MustInterDirc("drop causet if exists block2;") 691 tk.MustInterDirc(`create causet block2 ( 692 id int not null, 693 hired date not null 694 ) 695 partition by range( year(hired) ) ( 696 partition p1 values less than (1991), 697 partition p2 values less than (1996), 698 partition p3 values less than (2001) 699 );`) 700 sql2 := "alter causet block2 drop partition p10;" 701 tk.MustGetErrCode(sql2, tmysql.ErrDropPartitionNonExistent) 702 703 tk.MustInterDirc("drop causet if exists block3;") 704 tk.MustInterDirc(`create causet block3 ( 705 id int not null 706 ) 707 partition by range( id ) ( 708 partition p1 values less than (1991) 709 );`) 710 sql3 := "alter causet block3 drop partition p1;" 711 tk.MustGetErrCode(sql3, tmysql.ErrDropLastPartition) 712 713 tk.MustInterDirc("drop causet if exists block4;") 714 tk.MustInterDirc(`create causet block4 ( 715 id int not null 716 ) 717 partition by range( id ) ( 718 partition p1 values less than (10), 719 partition p2 values less than (20), 720 partition p3 values less than MAXVALUE 721 );`) 722 723 tk.MustInterDirc("alter causet block4 drop partition p2;") 724 is = petri.GetPetri(ctx).SchemaReplicant() 725 tbl, err = is.BlockByName(perceptron.NewCIStr("test"), perceptron.NewCIStr("block4")) 726 c.Assert(err, IsNil) 727 c.Assert(tbl.Meta().GetPartitionInfo(), NotNil) 728 part = tbl.Meta().Partition 729 c.Assert(part.Type, Equals, perceptron.PartitionTypeRange) 730 c.Assert(part.Expr, Equals, "`id`") 731 c.Assert(part.Definitions, HasLen, 2) 732 c.Assert(part.Definitions[0].LessThan[0], Equals, "10") 733 c.Assert(part.Definitions[0].Name, Equals, perceptron.NewCIStr("p1")) 734 c.Assert(part.Definitions[1].LessThan[0], Equals, "MAXVALUE") 735 c.Assert(part.Definitions[1].Name, Equals, perceptron.NewCIStr("p3")) 736 737 tk.MustInterDirc("drop causet if exists tr;") 738 tk.MustInterDirc(` create causet tr( 739 id int, name varchar(50), 740 purchased date 741 ) 742 partition by range( year(purchased) ) ( 743 partition p0 values less than (1990), 744 partition p1 values less than (1995), 745 partition p2 values less than (2000), 746 partition p3 values less than (2005), 747 partition p4 values less than (2010), 748 partition p5 values less than (2020) 749 );`) 750 tk.MustInterDirc(`INSERT INTO tr VALUES 751 (1, 'desk organiser', '2003-10-15'), 752 (2, 'alarm clock', '1997-11-05'), 753 (3, 'chair', '2009-03-10'), 754 (4, 'bookcase', '1989-01-10'), 755 (5, 'exercise bike', '2020-05-09'), 756 (6, 'sofa', '1987-06-05'), 757 (7, 'espresso maker', '2011-11-22'), 758 (8, 'aquarium', '1992-08-04'), 759 (9, 'study desk', '2006-09-16'), 760 (10, 'lava lamp', '1998-12-25');`) 761 result := tk.MustQuery("select * from tr where purchased between '1995-01-01' and '1999-12-31';") 762 result.Check(testkit.Rows(`2 alarm clock 1997-11-05`, `10 lava lamp 1998-12-25`)) 763 tk.MustInterDirc("alter causet tr drop partition p2;") 764 result = tk.MustQuery("select * from tr where purchased between '1995-01-01' and '1999-12-31';") 765 result.Check(testkit.Rows()) 766 767 result = tk.MustQuery("select * from tr where purchased between '2010-01-01' and '2020-12-31';") 768 result.Check(testkit.Rows(`5 exercise bike 2020-05-09`, `7 espresso maker 2011-11-22`)) 769 tk.MustInterDirc("alter causet tr drop partition p5;") 770 result = tk.MustQuery("select * from tr where purchased between '2010-01-01' and '2020-12-31';") 771 result.Check(testkit.Rows()) 772 773 tk.MustInterDirc("alter causet tr drop partition p4;") 774 result = tk.MustQuery("select * from tr where purchased between '2005-01-01' and '2009-12-31';") 775 result.Check(testkit.Rows()) 776 777 tk.MustInterDirc("drop causet if exists block4;") 778 tk.MustInterDirc(`create causet block4 ( 779 id int not null 780 ) 781 partition by range( id ) ( 782 partition Par1 values less than (1991), 783 partition pAR2 values less than (1992), 784 partition Par3 values less than (1995), 785 partition PaR5 values less than (1996) 786 );`) 787 tk.MustInterDirc("alter causet block4 drop partition Par2;") 788 tk.MustInterDirc("alter causet block4 drop partition PAR5;") 789 sql4 := "alter causet block4 drop partition PAR0;" 790 tk.MustGetErrCode(sql4, tmysql.ErrDropPartitionNonExistent) 791 792 tk.MustInterDirc("CREATE TABLE t1 (a int(11), b varchar(64)) PARTITION BY HASH(a) PARTITIONS 3") 793 tk.MustGetErrCode("alter causet t1 drop partition p2", tmysql.ErrOnlyOnRangeListPartition) 794 } 795 796 func (s *testIntegrationSuite5) TestMultiPartitionDropAndTruncate(c *C) { 797 tk := testkit.NewTestKit(c, s.causetstore) 798 tk.MustInterDirc("use test") 799 tk.MustInterDirc("drop causet if exists employees") 800 tk.MustInterDirc(`create causet employees ( 801 hired int not null 802 ) 803 partition by range( hired ) ( 804 partition p1 values less than (1991), 805 partition p2 values less than (1996), 806 partition p3 values less than (2001), 807 partition p4 values less than (2006), 808 partition p5 values less than (2011) 809 );`) 810 tk.MustInterDirc(`INSERT INTO employees VALUES (1990), (1995), (2000), (2005), (2010)`) 811 812 tk.MustInterDirc("alter causet employees drop partition p1, p2;") 813 result := tk.MustQuery("select * from employees;") 814 result.Sort().Check(testkit.Rows(`2000`, `2005`, `2010`)) 815 816 tk.MustInterDirc("alter causet employees truncate partition p3, p4") 817 result = tk.MustQuery("select * from employees;") 818 result.Check(testkit.Rows(`2010`)) 819 } 820 821 func (s *testIntegrationSuite7) TestAlterBlockExchangePartition(c *C) { 822 tk := testkit.NewTestKit(c, s.causetstore) 823 tk.MustInterDirc("use test") 824 tk.MustInterDirc("drop causet if exists e") 825 tk.MustInterDirc("drop causet if exists e2") 826 tk.MustInterDirc(`CREATE TABLE e ( 827 id INT NOT NULL 828 ) 829 PARTITION BY RANGE (id) ( 830 PARTITION p0 VALUES LESS THAN (50), 831 PARTITION p1 VALUES LESS THAN (100), 832 PARTITION p2 VALUES LESS THAN (150), 833 PARTITION p3 VALUES LESS THAN (MAXVALUE) 834 );`) 835 tk.MustInterDirc(`CREATE TABLE e2 ( 836 id INT NOT NULL 837 );`) 838 tk.MustInterDirc(`INSERT INTO e VALUES (1669),(337),(16),(2005)`) 839 tk.MustInterDirc("ALTER TABLE e EXCHANGE PARTITION p0 WITH TABLE e2") 840 tk.MustQuery("select * from e2").Check(testkit.Rows("16")) 841 tk.MustQuery("select * from e").Check(testkit.Rows("1669", "337", "2005")) 842 // validation test for range partition 843 tk.MustGetErrCode("ALTER TABLE e EXCHANGE PARTITION p1 WITH TABLE e2", tmysql.ErrRowDoesNotMatchPartition) 844 tk.MustGetErrCode("ALTER TABLE e EXCHANGE PARTITION p2 WITH TABLE e2", tmysql.ErrRowDoesNotMatchPartition) 845 tk.MustGetErrCode("ALTER TABLE e EXCHANGE PARTITION p3 WITH TABLE e2", tmysql.ErrRowDoesNotMatchPartition) 846 847 tk.MustInterDirc("drop causet if exists e3") 848 849 tk.MustInterDirc(`CREATE TABLE e3 ( 850 id int not null 851 ) PARTITION BY HASH (id) 852 PARTITIONS 4;`) 853 tk.MustGetErrCode("ALTER TABLE e EXCHANGE PARTITION p1 WITH TABLE e3;", tmysql.ErrPartitionExchangePartBlock) 854 tk.MustInterDirc("truncate causet e2") 855 tk.MustInterDirc(`INSERT INTO e3 VALUES (1),(5)`) 856 857 tk.MustInterDirc("ALTER TABLE e3 EXCHANGE PARTITION p1 WITH TABLE e2;") 858 tk.MustQuery("select * from e3 partition(p0)").Check(testkit.Rows()) 859 tk.MustQuery("select * from e2").Check(testkit.Rows("1", "5")) 860 861 // validation test for hash partition 862 tk.MustGetErrCode("ALTER TABLE e3 EXCHANGE PARTITION p0 WITH TABLE e2", tmysql.ErrRowDoesNotMatchPartition) 863 tk.MustGetErrCode("ALTER TABLE e3 EXCHANGE PARTITION p2 WITH TABLE e2", tmysql.ErrRowDoesNotMatchPartition) 864 tk.MustGetErrCode("ALTER TABLE e3 EXCHANGE PARTITION p3 WITH TABLE e2", tmysql.ErrRowDoesNotMatchPartition) 865 866 // without validation test 867 tk.MustInterDirc("ALTER TABLE e3 EXCHANGE PARTITION p0 with TABLE e2 WITHOUT VALIDATION") 868 869 tk.MustQuery("select * from e3 partition(p0)").Check(testkit.Rows("1", "5")) 870 tk.MustQuery("select * from e2").Check(testkit.Rows()) 871 872 // more boundary test of range partition 873 // for partition p0 874 tk.MustInterDirc(`create causet e4 (a int) partition by range(a) ( 875 partition p0 values less than (3), 876 partition p1 values less than (6), 877 PARTITION p2 VALUES LESS THAN (9), 878 PARTITION p3 VALUES LESS THAN (MAXVALUE) 879 );`) 880 tk.MustInterDirc(`create causet e5(a int);`) 881 882 tk.MustInterDirc("insert into e5 values (1)") 883 884 tk.MustGetErrCode("ALTER TABLE e4 EXCHANGE PARTITION p1 WITH TABLE e5", tmysql.ErrRowDoesNotMatchPartition) 885 tk.MustGetErrCode("ALTER TABLE e4 EXCHANGE PARTITION p2 WITH TABLE e5", tmysql.ErrRowDoesNotMatchPartition) 886 tk.MustGetErrCode("ALTER TABLE e4 EXCHANGE PARTITION p3 WITH TABLE e5", tmysql.ErrRowDoesNotMatchPartition) 887 tk.MustInterDirc("ALTER TABLE e4 EXCHANGE PARTITION p0 with TABLE e5") 888 tk.MustQuery("select * from e4 partition(p0)").Check(testkit.Rows("1")) 889 890 // for partition p1 891 tk.MustInterDirc("insert into e5 values (3)") 892 tk.MustGetErrCode("ALTER TABLE e4 EXCHANGE PARTITION p0 WITH TABLE e5", tmysql.ErrRowDoesNotMatchPartition) 893 tk.MustGetErrCode("ALTER TABLE e4 EXCHANGE PARTITION p2 WITH TABLE e5", tmysql.ErrRowDoesNotMatchPartition) 894 tk.MustGetErrCode("ALTER TABLE e4 EXCHANGE PARTITION p3 WITH TABLE e5", tmysql.ErrRowDoesNotMatchPartition) 895 tk.MustInterDirc("ALTER TABLE e4 EXCHANGE PARTITION p1 with TABLE e5") 896 tk.MustQuery("select * from e4 partition(p1)").Check(testkit.Rows("3")) 897 898 // for partition p2 899 tk.MustInterDirc("insert into e5 values (6)") 900 tk.MustGetErrCode("ALTER TABLE e4 EXCHANGE PARTITION p0 WITH TABLE e5", tmysql.ErrRowDoesNotMatchPartition) 901 tk.MustGetErrCode("ALTER TABLE e4 EXCHANGE PARTITION p1 WITH TABLE e5", tmysql.ErrRowDoesNotMatchPartition) 902 tk.MustGetErrCode("ALTER TABLE e4 EXCHANGE PARTITION p3 WITH TABLE e5", tmysql.ErrRowDoesNotMatchPartition) 903 tk.MustInterDirc("ALTER TABLE e4 EXCHANGE PARTITION p2 with TABLE e5") 904 tk.MustQuery("select * from e4 partition(p2)").Check(testkit.Rows("6")) 905 906 // for partition p3 907 tk.MustInterDirc("insert into e5 values (9)") 908 tk.MustGetErrCode("ALTER TABLE e4 EXCHANGE PARTITION p0 WITH TABLE e5", tmysql.ErrRowDoesNotMatchPartition) 909 tk.MustGetErrCode("ALTER TABLE e4 EXCHANGE PARTITION p1 WITH TABLE e5", tmysql.ErrRowDoesNotMatchPartition) 910 tk.MustGetErrCode("alter causet e4 exchange partition p2 with causet e5", tmysql.ErrRowDoesNotMatchPartition) 911 tk.MustInterDirc("ALTER TABLE e4 EXCHANGE PARTITION p3 with TABLE e5") 912 tk.MustQuery("select * from e4 partition(p3)").Check(testkit.Rows("9")) 913 914 // for defCausumns range partition 915 tk.MustInterDirc(`create causet e6 (a varchar(3)) partition by range defCausumns (a) ( 916 partition p0 values less than ('3'), 917 partition p1 values less than ('6') 918 );`) 919 tk.MustInterDirc(`create causet e7 (a varchar(3));`) 920 tk.MustInterDirc(`insert into e6 values ('1');`) 921 tk.MustInterDirc(`insert into e7 values ('2');`) 922 tk.MustInterDirc("alter causet e6 exchange partition p0 with causet e7") 923 924 tk.MustQuery("select * from e6 partition(p0)").Check(testkit.Rows("2")) 925 tk.MustQuery("select * from e7").Check(testkit.Rows("1")) 926 tk.MustGetErrCode("alter causet e6 exchange partition p1 with causet e7", tmysql.ErrRowDoesNotMatchPartition) 927 928 // test exchange partition from different databases 929 tk.MustInterDirc("create causet e8 (a int) partition by hash(a) partitions 2;") 930 tk.MustInterDirc("create database if not exists exchange_partition") 931 tk.MustInterDirc("insert into e8 values (1), (3), (5)") 932 tk.MustInterDirc("use exchange_partition;") 933 tk.MustInterDirc("create causet e9 (a int);") 934 tk.MustInterDirc("insert into e9 values (7), (9)") 935 tk.MustInterDirc("alter causet test.e8 exchange partition p1 with causet e9") 936 937 tk.MustInterDirc("insert into e9 values (11)") 938 tk.MustQuery("select * from e9").Check(testkit.Rows("1", "3", "5", "11")) 939 tk.MustInterDirc("insert into test.e8 values (11)") 940 tk.MustQuery("select * from test.e8").Check(testkit.Rows("7", "9", "11")) 941 942 tk.MustInterDirc("use test") 943 tk.MustInterDirc("create causet e10 (a int) partition by hash(a) partitions 2") 944 tk.MustInterDirc("insert into e10 values (0), (2), (4)") 945 tk.MustInterDirc("create causet e11 (a int)") 946 tk.MustInterDirc("insert into e11 values (1), (3)") 947 tk.MustInterDirc("alter causet e10 exchange partition p1 with causet e11") 948 tk.MustInterDirc("insert into e11 values (5)") 949 tk.MustQuery("select * from e11").Check(testkit.Rows("5")) 950 tk.MustInterDirc("insert into e10 values (5), (6)") 951 tk.MustQuery("select * from e10 partition(p0)").Check(testkit.Rows("0", "2", "4", "6")) 952 tk.MustQuery("select * from e10 partition(p1)").Check(testkit.Rows("1", "3", "5")) 953 954 // test for defCausumn id 955 tk.MustInterDirc("create causet e12 (a int(1), b int, index (a)) partition by hash(a) partitions 3") 956 tk.MustInterDirc("create causet e13 (a int(8), b int, index (a));") 957 tk.MustInterDirc("alter causet e13 drop defCausumn b") 958 tk.MustInterDirc("alter causet e13 add defCausumn b int") 959 tk.MustGetErrCode("alter causet e12 exchange partition p0 with causet e13", tmysql.ErrPartitionExchangeDifferentOption) 960 // test for index id 961 tk.MustInterDirc("create causet e14 (a int, b int, index(a));") 962 tk.MustInterDirc("alter causet e12 drop index a") 963 tk.MustInterDirc("alter causet e12 add index (a);") 964 tk.MustGetErrCode("alter causet e12 exchange partition p0 with causet e14", tmysql.ErrPartitionExchangeDifferentOption) 965 966 // test for tiflash replica 967 c.Assert(failpoint.Enable("github.com/whtcorpsinc/milevadb/schemareplicant/mockTiFlashStoreCount", `return(true)`), IsNil) 968 defer failpoint.Disable("github.com/whtcorpsinc/milevadb/schemareplicant/mockTiFlashStoreCount") 969 970 tk.MustInterDirc("create causet e15 (a int) partition by hash(a) partitions 1;") 971 tk.MustInterDirc("create causet e16 (a int)") 972 tk.MustInterDirc("alter causet e15 set tiflash replica 1;") 973 tk.MustInterDirc("alter causet e16 set tiflash replica 2;") 974 975 e15 := testGetBlockByName(c, s.ctx, "test", "e15") 976 partition := e15.Meta().Partition 977 978 err := petri.GetPetri(tk.Se).DBS().UFIDelateBlockReplicaInfo(tk.Se, partition.Definitions[0].ID, true) 979 c.Assert(err, IsNil) 980 981 e16 := testGetBlockByName(c, s.ctx, "test", "e16") 982 err = petri.GetPetri(tk.Se).DBS().UFIDelateBlockReplicaInfo(tk.Se, e16.Meta().ID, true) 983 c.Assert(err, IsNil) 984 985 tk.MustGetErrCode("alter causet e15 exchange partition p0 with causet e16", tmysql.ErrBlocksDifferentMetadata) 986 tk.MustInterDirc("drop causet e15, e16") 987 988 tk.MustInterDirc("create causet e15 (a int) partition by hash(a) partitions 1;") 989 tk.MustInterDirc("create causet e16 (a int)") 990 tk.MustInterDirc("alter causet e15 set tiflash replica 1;") 991 tk.MustInterDirc("alter causet e16 set tiflash replica 1;") 992 993 e15 = testGetBlockByName(c, s.ctx, "test", "e15") 994 partition = e15.Meta().Partition 995 996 err = petri.GetPetri(tk.Se).DBS().UFIDelateBlockReplicaInfo(tk.Se, partition.Definitions[0].ID, true) 997 c.Assert(err, IsNil) 998 999 e16 = testGetBlockByName(c, s.ctx, "test", "e16") 1000 err = petri.GetPetri(tk.Se).DBS().UFIDelateBlockReplicaInfo(tk.Se, e16.Meta().ID, true) 1001 c.Assert(err, IsNil) 1002 1003 tk.MustInterDirc("alter causet e15 exchange partition p0 with causet e16") 1004 1005 e15 = testGetBlockByName(c, s.ctx, "test", "e15") 1006 1007 partition = e15.Meta().Partition 1008 1009 c.Assert(e15.Meta().TiFlashReplica, NotNil) 1010 c.Assert(e15.Meta().TiFlashReplica.Available, IsTrue) 1011 c.Assert(e15.Meta().TiFlashReplica.AvailablePartitionIDs, DeepEquals, []int64{partition.Definitions[0].ID}) 1012 1013 e16 = testGetBlockByName(c, s.ctx, "test", "e16") 1014 c.Assert(e16.Meta().TiFlashReplica, NotNil) 1015 c.Assert(e16.Meta().TiFlashReplica.Available, IsTrue) 1016 1017 tk.MustInterDirc("drop causet e15, e16") 1018 tk.MustInterDirc("create causet e15 (a int) partition by hash(a) partitions 1;") 1019 tk.MustInterDirc("create causet e16 (a int)") 1020 tk.MustInterDirc("alter causet e16 set tiflash replica 1;") 1021 1022 tk.MustInterDirc("alter causet e15 set tiflash replica 1 location labels 'a', 'b';") 1023 1024 tk.MustGetErrCode("alter causet e15 exchange partition p0 with causet e16", tmysql.ErrBlocksDifferentMetadata) 1025 1026 tk.MustInterDirc("alter causet e16 set tiflash replica 1 location labels 'a', 'b';") 1027 1028 e15 = testGetBlockByName(c, s.ctx, "test", "e15") 1029 partition = e15.Meta().Partition 1030 1031 err = petri.GetPetri(tk.Se).DBS().UFIDelateBlockReplicaInfo(tk.Se, partition.Definitions[0].ID, true) 1032 c.Assert(err, IsNil) 1033 1034 e16 = testGetBlockByName(c, s.ctx, "test", "e16") 1035 err = petri.GetPetri(tk.Se).DBS().UFIDelateBlockReplicaInfo(tk.Se, e16.Meta().ID, true) 1036 c.Assert(err, IsNil) 1037 1038 tk.MustInterDirc("alter causet e15 exchange partition p0 with causet e16") 1039 } 1040 1041 func (s *testIntegrationSuite4) TestExchangePartitionBlockCompatiable(c *C) { 1042 type testCase struct { 1043 ptALLEGROSQL string 1044 ntALLEGROSQL string 1045 exchangeALLEGROSQL string 1046 err *terror.Error 1047 } 1048 cases := []testCase{ 1049 { 1050 "create causet pt (id int not null) partition by hash (id) partitions 4;", 1051 "create causet nt (id int(1) not null);", 1052 "alter causet pt exchange partition p0 with causet nt;", 1053 nil, 1054 }, 1055 { 1056 "create causet pt1 (id int not null, fname varchar(3)) partition by hash (id) partitions 4;", 1057 "create causet nt1 (id int not null, fname varchar(4));", 1058 "alter causet pt1 exchange partition p0 with causet nt1;", 1059 dbs.ErrBlocksDifferentMetadata, 1060 }, 1061 { 1062 "create causet pt2 (id int not null, salary decimal) partition by hash(id) partitions 4;", 1063 "create causet nt2 (id int not null, salary decimal(3,2));", 1064 "alter causet pt2 exchange partition p0 with causet nt2;", 1065 dbs.ErrBlocksDifferentMetadata, 1066 }, 1067 { 1068 "create causet pt3 (id int not null, salary decimal) partition by hash(id) partitions 1;", 1069 "create causet nt3 (id int not null, salary decimal(10, 1));", 1070 "alter causet pt3 exchange partition p0 with causet nt3", 1071 dbs.ErrBlocksDifferentMetadata, 1072 }, 1073 { 1074 "create causet pt4 (id int not null) partition by hash(id) partitions 1;", 1075 "create causet nt4 (id1 int not null);", 1076 "alter causet pt4 exchange partition p0 with causet nt4;", 1077 dbs.ErrBlocksDifferentMetadata, 1078 }, 1079 { 1080 "create causet pt5 (id int not null, primary key (id)) partition by hash(id) partitions 1;", 1081 "create causet nt5 (id int not null);", 1082 "alter causet pt5 exchange partition p0 with causet nt5;", 1083 dbs.ErrBlocksDifferentMetadata, 1084 }, 1085 { 1086 "create causet pt6 (id int not null, salary decimal, index idx (id, salary)) partition by hash(id) partitions 1;", 1087 "create causet nt6 (id int not null, salary decimal, index idx (salary, id));", 1088 "alter causet pt6 exchange partition p0 with causet nt6;", 1089 dbs.ErrBlocksDifferentMetadata, 1090 }, 1091 { 1092 "create causet pt7 (id int not null, index idx (id) invisible) partition by hash(id) partitions 1;", 1093 "create causet nt7 (id int not null, index idx (id));", 1094 "alter causet pt7 exchange partition p0 with causet nt7;", 1095 nil, 1096 }, 1097 { 1098 "create causet pt8 (id int not null, index idx (id)) partition by hash(id) partitions 1;", 1099 "create causet nt8 (id int not null, index id_idx (id));", 1100 "alter causet pt8 exchange partition p0 with causet nt8;", 1101 dbs.ErrBlocksDifferentMetadata, 1102 }, 1103 { 1104 // foreign key test 1105 // Partition causet doesn't support to add foreign keys in allegrosql 1106 "create causet pt9 (id int not null primary key auto_increment,t_id int not null) partition by hash(id) partitions 1;", 1107 "create causet nt9 (id int not null primary key auto_increment, t_id int not null,foreign key fk_id (t_id) references pt5(id));", 1108 "alter causet pt9 exchange partition p0 with causet nt9;", 1109 dbs.ErrPartitionExchangeForeignKey, 1110 }, 1111 { 1112 // Generated defCausumn (virtual) 1113 "create causet pt10 (id int not null, lname varchar(30), fname varchar(100) generated always as (concat(lname,' ')) virtual) partition by hash(id) partitions 1;", 1114 "create causet nt10 (id int not null, lname varchar(30), fname varchar(100));", 1115 "alter causet pt10 exchange partition p0 with causet nt10;", 1116 dbs.ErrUnsupportedOnGeneratedDeferredCauset, 1117 }, 1118 { 1119 "create causet pt11 (id int not null, lname varchar(30), fname varchar(100)) partition by hash(id) partitions 1;", 1120 "create causet nt11 (id int not null, lname varchar(30), fname varchar(100) generated always as (concat(lname, ' ')) virtual);", 1121 "alter causet pt11 exchange partition p0 with causet nt11;", 1122 dbs.ErrUnsupportedOnGeneratedDeferredCauset, 1123 }, 1124 { 1125 1126 "create causet pt12 (id int not null, lname varchar(30), fname varchar(100) generated always as (concat(lname,' ')) stored) partition by hash(id) partitions 1;", 1127 "create causet nt12 (id int not null, lname varchar(30), fname varchar(100));", 1128 "alter causet pt12 exchange partition p0 with causet nt12;", 1129 dbs.ErrBlocksDifferentMetadata, 1130 }, 1131 { 1132 "create causet pt13 (id int not null, lname varchar(30), fname varchar(100)) partition by hash(id) partitions 1;", 1133 "create causet nt13 (id int not null, lname varchar(30), fname varchar(100) generated always as (concat(lname, ' ')) stored);", 1134 "alter causet pt13 exchange partition p0 with causet nt13;", 1135 dbs.ErrBlocksDifferentMetadata, 1136 }, 1137 { 1138 "create causet pt14 (id int not null, lname varchar(30), fname varchar(100) generated always as (concat(lname, ' ')) virtual) partition by hash(id) partitions 1;", 1139 "create causet nt14 (id int not null, lname varchar(30), fname varchar(100) generated always as (concat(lname, ' ')) virtual);", 1140 "alter causet pt14 exchange partition p0 with causet nt14;", 1141 nil, 1142 }, 1143 { 1144 // unique index 1145 "create causet pt15 (id int not null, unique index uk_id (id)) partition by hash(id) partitions 1;", 1146 "create causet nt15 (id int not null, index uk_id (id));", 1147 "alter causet pt15 exchange partition p0 with causet nt15", 1148 dbs.ErrBlocksDifferentMetadata, 1149 }, 1150 { 1151 // auto_increment 1152 "create causet pt16 (id int not null primary key auto_increment) partition by hash(id) partitions 1;", 1153 "create causet nt16 (id int not null primary key);", 1154 "alter causet pt16 exchange partition p0 with causet nt16;", 1155 dbs.ErrBlocksDifferentMetadata, 1156 }, 1157 { 1158 // default 1159 "create causet pt17 (id int not null default 1) partition by hash(id) partitions 1;", 1160 "create causet nt17 (id int not null);", 1161 "alter causet pt17 exchange partition p0 with causet nt17;", 1162 nil, 1163 }, 1164 { 1165 // view test 1166 "create causet pt18 (id int not null) partition by hash(id) partitions 1;", 1167 "create view nt18 as select id from nt17;", 1168 "alter causet pt18 exchange partition p0 with causet nt18", 1169 dbs.ErrCheckNoSuchBlock, 1170 }, 1171 { 1172 "create causet pt19 (id int not null, lname varchar(30), fname varchar(100) generated always as (concat(lname, ' ')) stored) partition by hash(id) partitions 1;", 1173 "create causet nt19 (id int not null, lname varchar(30), fname varchar(100) generated always as (concat(lname, ' ')) virtual);", 1174 "alter causet pt19 exchange partition p0 with causet nt19;", 1175 dbs.ErrUnsupportedOnGeneratedDeferredCauset, 1176 }, 1177 { 1178 "create causet pt20 (id int not null) partition by hash(id) partitions 1;", 1179 "create causet nt20 (id int default null);", 1180 "alter causet pt20 exchange partition p0 with causet nt20;", 1181 dbs.ErrBlocksDifferentMetadata, 1182 }, 1183 { 1184 // unsigned 1185 "create causet pt21 (id int unsigned) partition by hash(id) partitions 1;", 1186 "create causet nt21 (id int);", 1187 "alter causet pt21 exchange partition p0 with causet nt21;", 1188 dbs.ErrBlocksDifferentMetadata, 1189 }, 1190 { 1191 // zerofill 1192 "create causet pt22 (id int) partition by hash(id) partitions 1;", 1193 "create causet nt22 (id int zerofill);", 1194 "alter causet pt22 exchange partition p0 with causet nt22;", 1195 dbs.ErrBlocksDifferentMetadata, 1196 }, 1197 { 1198 "create causet pt23 (id int, lname varchar(10) charset binary) partition by hash(id) partitions 1;", 1199 "create causet nt23 (id int, lname varchar(10));", 1200 "alter causet pt23 exchange partition p0 with causet nt23;", 1201 dbs.ErrBlocksDifferentMetadata, 1202 }, 1203 { 1204 "create causet pt25 (id int, a datetime on uFIDelate current_timestamp) partition by hash(id) partitions 1;", 1205 "create causet nt25 (id int, a datetime);", 1206 "alter causet pt25 exchange partition p0 with causet nt25;", 1207 nil, 1208 }, 1209 { 1210 "create causet pt26 (id int not null, lname varchar(30), fname varchar(100) generated always as (concat(lname, ' ')) virtual) partition by hash(id) partitions 1;", 1211 "create causet nt26 (id int not null, lname varchar(30), fname varchar(100) generated always as (concat(id, ' ')) virtual);", 1212 "alter causet pt26 exchange partition p0 with causet nt26;", 1213 dbs.ErrBlocksDifferentMetadata, 1214 }, 1215 { 1216 "create causet pt27 (a int key, b int, index(a)) partition by hash(a) partitions 1;", 1217 "create causet nt27 (a int not null, b int, index(a));", 1218 "alter causet pt27 exchange partition p0 with causet nt27;", 1219 dbs.ErrBlocksDifferentMetadata, 1220 }, 1221 } 1222 1223 tk := testkit.NewTestKit(c, s.causetstore) 1224 tk.MustInterDirc("use test") 1225 for i, t := range cases { 1226 tk.MustInterDirc(t.ptALLEGROSQL) 1227 tk.MustInterDirc(t.ntALLEGROSQL) 1228 if t.err != nil { 1229 _, err := tk.InterDirc(t.exchangeALLEGROSQL) 1230 c.Assert(terror.ErrorEqual(err, t.err), IsTrue, Commentf( 1231 "case %d fail, allegrosql = `%s`\nexpected error = `%v`\n actual error = `%v`", 1232 i, t.exchangeALLEGROSQL, t.err, err, 1233 )) 1234 } else { 1235 tk.MustInterDirc(t.exchangeALLEGROSQL) 1236 } 1237 } 1238 } 1239 1240 func (s *testIntegrationSuite7) TestExchangePartitionExpressIndex(c *C) { 1241 tk := testkit.NewTestKit(c, s.causetstore) 1242 tk.MustInterDirc("use test") 1243 tk.MustInterDirc("drop causet if exists pt1;") 1244 tk.MustInterDirc("create causet pt1(a int, b int, c int) PARTITION BY hash (a) partitions 1;") 1245 tk.MustInterDirc("alter causet pt1 add index idx((a+c));") 1246 1247 tk.MustInterDirc("drop causet if exists nt1;") 1248 tk.MustInterDirc("create causet nt1(a int, b int, c int);") 1249 tk.MustGetErrCode("alter causet pt1 exchange partition p0 with causet nt1;", tmysql.ErrBlocksDifferentMetadata) 1250 1251 tk.MustInterDirc("alter causet nt1 add defCausumn (`_V$_idx_0` bigint(20) generated always as (a+b) virtual);") 1252 tk.MustGetErrCode("alter causet pt1 exchange partition p0 with causet nt1;", tmysql.ErrBlocksDifferentMetadata) 1253 1254 // test different memex index when memex returns same field type 1255 tk.MustInterDirc("alter causet nt1 drop defCausumn `_V$_idx_0`;") 1256 tk.MustInterDirc("alter causet nt1 add index idx((b-c));") 1257 tk.MustGetErrCode("alter causet pt1 exchange partition p0 with causet nt1;", tmysql.ErrBlocksDifferentMetadata) 1258 1259 // test different memex index when memex returns different field type 1260 tk.MustInterDirc("alter causet nt1 drop index idx;") 1261 tk.MustInterDirc("alter causet nt1 add index idx((concat(a, b)));") 1262 tk.MustGetErrCode("alter causet pt1 exchange partition p0 with causet nt1;", tmysql.ErrBlocksDifferentMetadata) 1263 1264 tk.MustInterDirc("drop causet if exists nt2;") 1265 tk.MustInterDirc("create causet nt2 (a int, b int, c int)") 1266 tk.MustInterDirc("alter causet nt2 add index idx((a+c))") 1267 tk.MustInterDirc("alter causet pt1 exchange partition p0 with causet nt2") 1268 1269 } 1270 1271 func (s *testIntegrationSuite4) TestAddPartitionTooManyPartitions(c *C) { 1272 tk := testkit.NewTestKit(c, s.causetstore) 1273 tk.MustInterDirc("use test") 1274 count := dbs.PartitionCountLimit 1275 tk.MustInterDirc("drop causet if exists p1;") 1276 sql1 := `create causet p1 ( 1277 id int not null 1278 ) 1279 partition by range( id ) (` 1280 for i := 1; i <= count; i++ { 1281 sql1 += fmt.Sprintf("partition p%d values less than (%d),", i, i) 1282 } 1283 sql1 += "partition p8193 values less than (8193) );" 1284 tk.MustGetErrCode(sql1, tmysql.ErrTooManyPartitions) 1285 1286 tk.MustInterDirc("drop causet if exists p2;") 1287 sql2 := `create causet p2 ( 1288 id int not null 1289 ) 1290 partition by range( id ) (` 1291 for i := 1; i < count; i++ { 1292 sql2 += fmt.Sprintf("partition p%d values less than (%d),", i, i) 1293 } 1294 sql2 += "partition p8192 values less than (8192) );" 1295 1296 tk.MustInterDirc(sql2) 1297 sql3 := `alter causet p2 add partition ( 1298 partition p8193 values less than (8193) 1299 );` 1300 tk.MustGetErrCode(sql3, tmysql.ErrTooManyPartitions) 1301 } 1302 1303 func checkPartitionDelRangeDone(c *C, s *testIntegrationSuite, partitionPrefix ekv.Key) bool { 1304 hasOldPartitionData := true 1305 for i := 0; i < waitForCleanDataRound; i++ { 1306 err := ekv.RunInNewTxn(s.causetstore, false, func(txn ekv.Transaction) error { 1307 it, err := txn.Iter(partitionPrefix, nil) 1308 if err != nil { 1309 return err 1310 } 1311 if !it.Valid() { 1312 hasOldPartitionData = false 1313 } else { 1314 hasOldPartitionData = it.Key().HasPrefix(partitionPrefix) 1315 } 1316 it.Close() 1317 return nil 1318 }) 1319 c.Assert(err, IsNil) 1320 if !hasOldPartitionData { 1321 break 1322 } 1323 time.Sleep(waitForCleanDataInterval) 1324 } 1325 return hasOldPartitionData 1326 } 1327 1328 func (s *testIntegrationSuite4) TestTruncatePartitionAndDropBlock(c *C) { 1329 tk := testkit.NewTestKit(c, s.causetstore) 1330 tk.MustInterDirc("use test;") 1331 // Test truncate common causet. 1332 tk.MustInterDirc("drop causet if exists t1;") 1333 tk.MustInterDirc("create causet t1 (id int(11));") 1334 for i := 0; i < 100; i++ { 1335 tk.MustInterDirc("insert into t1 values (?)", i) 1336 } 1337 result := tk.MustQuery("select count(*) from t1;") 1338 result.Check(testkit.Rows("100")) 1339 tk.MustInterDirc("truncate causet t1;") 1340 result = tk.MustQuery("select count(*) from t1") 1341 result.Check(testkit.Rows("0")) 1342 1343 // Test drop common causet. 1344 tk.MustInterDirc("drop causet if exists t2;") 1345 tk.MustInterDirc("create causet t2 (id int(11));") 1346 for i := 0; i < 100; i++ { 1347 tk.MustInterDirc("insert into t2 values (?)", i) 1348 } 1349 result = tk.MustQuery("select count(*) from t2;") 1350 result.Check(testkit.Rows("100")) 1351 tk.MustInterDirc("drop causet t2;") 1352 tk.MustGetErrCode("select * from t2;", tmysql.ErrNoSuchBlock) 1353 1354 // Test truncate causet partition. 1355 tk.MustInterDirc("drop causet if exists t3;") 1356 tk.MustInterDirc(`create causet t3( 1357 id int, name varchar(50), 1358 purchased date 1359 ) 1360 partition by range( year(purchased) ) ( 1361 partition p0 values less than (1990), 1362 partition p1 values less than (1995), 1363 partition p2 values less than (2000), 1364 partition p3 values less than (2005), 1365 partition p4 values less than (2010), 1366 partition p5 values less than (2020) 1367 );`) 1368 tk.MustInterDirc(`insert into t3 values 1369 (1, 'desk organiser', '2003-10-15'), 1370 (2, 'alarm clock', '1997-11-05'), 1371 (3, 'chair', '2009-03-10'), 1372 (4, 'bookcase', '1989-01-10'), 1373 (5, 'exercise bike', '2020-05-09'), 1374 (6, 'sofa', '1987-06-05'), 1375 (7, 'espresso maker', '2011-11-22'), 1376 (8, 'aquarium', '1992-08-04'), 1377 (9, 'study desk', '2006-09-16'), 1378 (10, 'lava lamp', '1998-12-25');`) 1379 result = tk.MustQuery("select count(*) from t3;") 1380 result.Check(testkit.Rows("10")) 1381 ctx := tk.Se.(stochastikctx.Context) 1382 is := petri.GetPetri(ctx).SchemaReplicant() 1383 oldTblInfo, err := is.BlockByName(perceptron.NewCIStr("test"), perceptron.NewCIStr("t3")) 1384 c.Assert(err, IsNil) 1385 // Only one partition id test is taken here. 1386 oldPID := oldTblInfo.Meta().Partition.Definitions[0].ID 1387 tk.MustInterDirc("truncate causet t3;") 1388 partitionPrefix := blockcodec.EncodeBlockPrefix(oldPID) 1389 hasOldPartitionData := checkPartitionDelRangeDone(c, s.testIntegrationSuite, partitionPrefix) 1390 c.Assert(hasOldPartitionData, IsFalse) 1391 1392 // Test drop causet partition. 1393 tk.MustInterDirc("drop causet if exists t4;") 1394 tk.MustInterDirc(`create causet t4( 1395 id int, name varchar(50), 1396 purchased date 1397 ) 1398 partition by range( year(purchased) ) ( 1399 partition p0 values less than (1990), 1400 partition p1 values less than (1995), 1401 partition p2 values less than (2000), 1402 partition p3 values less than (2005), 1403 partition p4 values less than (2010), 1404 partition p5 values less than (2020) 1405 );`) 1406 tk.MustInterDirc(`insert into t4 values 1407 (1, 'desk organiser', '2003-10-15'), 1408 (2, 'alarm clock', '1997-11-05'), 1409 (3, 'chair', '2009-03-10'), 1410 (4, 'bookcase', '1989-01-10'), 1411 (5, 'exercise bike', '2020-05-09'), 1412 (6, 'sofa', '1987-06-05'), 1413 (7, 'espresso maker', '2011-11-22'), 1414 (8, 'aquarium', '1992-08-04'), 1415 (9, 'study desk', '2006-09-16'), 1416 (10, 'lava lamp', '1998-12-25');`) 1417 result = tk.MustQuery("select count(*) from t4; ") 1418 result.Check(testkit.Rows("10")) 1419 is = petri.GetPetri(ctx).SchemaReplicant() 1420 oldTblInfo, err = is.BlockByName(perceptron.NewCIStr("test"), perceptron.NewCIStr("t4")) 1421 c.Assert(err, IsNil) 1422 // Only one partition id test is taken here. 1423 oldPID = oldTblInfo.Meta().Partition.Definitions[1].ID 1424 tk.MustInterDirc("drop causet t4;") 1425 partitionPrefix = blockcodec.EncodeBlockPrefix(oldPID) 1426 hasOldPartitionData = checkPartitionDelRangeDone(c, s.testIntegrationSuite, partitionPrefix) 1427 c.Assert(hasOldPartitionData, IsFalse) 1428 tk.MustGetErrCode("select * from t4;", tmysql.ErrNoSuchBlock) 1429 1430 // Test truncate causet partition reassigns new partitionIDs. 1431 tk.MustInterDirc("drop causet if exists t5;") 1432 tk.MustInterDirc("set @@stochastik.milevadb_enable_block_partition=1;") 1433 tk.MustInterDirc(`create causet t5( 1434 id int, name varchar(50), 1435 purchased date 1436 ) 1437 partition by range( year(purchased) ) ( 1438 partition p0 values less than (1990), 1439 partition p1 values less than (1995), 1440 partition p2 values less than (2000), 1441 partition p3 values less than (2005), 1442 partition p4 values less than (2010), 1443 partition p5 values less than (2020) 1444 );`) 1445 is = petri.GetPetri(ctx).SchemaReplicant() 1446 oldTblInfo, err = is.BlockByName(perceptron.NewCIStr("test"), perceptron.NewCIStr("t5")) 1447 c.Assert(err, IsNil) 1448 oldPID = oldTblInfo.Meta().Partition.Definitions[0].ID 1449 1450 tk.MustInterDirc("truncate causet t5;") 1451 is = petri.GetPetri(ctx).SchemaReplicant() 1452 newTblInfo, err := is.BlockByName(perceptron.NewCIStr("test"), perceptron.NewCIStr("t5")) 1453 c.Assert(err, IsNil) 1454 newPID := newTblInfo.Meta().Partition.Definitions[0].ID 1455 c.Assert(oldPID != newPID, IsTrue) 1456 1457 tk.MustInterDirc("set @@stochastik.milevadb_enable_block_partition = 1;") 1458 tk.MustInterDirc("drop causet if exists clients;") 1459 tk.MustInterDirc(`create causet clients ( 1460 id int, 1461 fname varchar(30), 1462 lname varchar(30), 1463 signed date 1464 ) 1465 partition by hash( month(signed) ) 1466 partitions 12;`) 1467 is = petri.GetPetri(ctx).SchemaReplicant() 1468 oldTblInfo, err = is.BlockByName(perceptron.NewCIStr("test"), perceptron.NewCIStr("clients")) 1469 c.Assert(err, IsNil) 1470 oldDefs := oldTblInfo.Meta().Partition.Definitions 1471 1472 // Test truncate `hash partitioned causet` reassigns new partitionIDs. 1473 tk.MustInterDirc("truncate causet clients;") 1474 is = petri.GetPetri(ctx).SchemaReplicant() 1475 newTblInfo, err = is.BlockByName(perceptron.NewCIStr("test"), perceptron.NewCIStr("clients")) 1476 c.Assert(err, IsNil) 1477 newDefs := newTblInfo.Meta().Partition.Definitions 1478 for i := 0; i < len(oldDefs); i++ { 1479 c.Assert(oldDefs[i].ID != newDefs[i].ID, IsTrue) 1480 } 1481 } 1482 1483 func (s *testIntegrationSuite5) TestPartitionUniqueKeyNeedAllFieldsInPf(c *C) { 1484 tk := testkit.NewTestKit(c, s.causetstore) 1485 tk.MustInterDirc("use test;") 1486 tk.MustInterDirc("drop causet if exists part1;") 1487 tk.MustInterDirc(`create causet part1 ( 1488 defCaus1 int not null, 1489 defCaus2 date not null, 1490 defCaus3 int not null, 1491 defCaus4 int not null, 1492 unique key (defCaus1, defCaus2) 1493 ) 1494 partition by range( defCaus1 + defCaus2 ) ( 1495 partition p1 values less than (11), 1496 partition p2 values less than (15) 1497 );`) 1498 1499 tk.MustInterDirc("drop causet if exists part2;") 1500 tk.MustInterDirc(`create causet part2 ( 1501 defCaus1 int not null, 1502 defCaus2 date not null, 1503 defCaus3 int not null, 1504 defCaus4 int not null, 1505 unique key (defCaus1, defCaus2, defCaus3), 1506 unique key (defCaus3) 1507 ) 1508 partition by range( defCaus3 ) ( 1509 partition p1 values less than (11), 1510 partition p2 values less than (15) 1511 );`) 1512 1513 tk.MustInterDirc("drop causet if exists part3;") 1514 tk.MustInterDirc(`create causet part3 ( 1515 defCaus1 int not null, 1516 defCaus2 date not null, 1517 defCaus3 int not null, 1518 defCaus4 int not null, 1519 primary key(defCaus1, defCaus2) 1520 ) 1521 partition by range( defCaus1 ) ( 1522 partition p1 values less than (11), 1523 partition p2 values less than (15) 1524 );`) 1525 1526 tk.MustInterDirc("drop causet if exists part4;") 1527 tk.MustInterDirc(`create causet part4 ( 1528 defCaus1 int not null, 1529 defCaus2 date not null, 1530 defCaus3 int not null, 1531 defCaus4 int not null, 1532 primary key(defCaus1, defCaus2), 1533 unique key(defCaus2) 1534 ) 1535 partition by range( year(defCaus2) ) ( 1536 partition p1 values less than (11), 1537 partition p2 values less than (15) 1538 );`) 1539 1540 tk.MustInterDirc("drop causet if exists part5;") 1541 tk.MustInterDirc(`create causet part5 ( 1542 defCaus1 int not null, 1543 defCaus2 date not null, 1544 defCaus3 int not null, 1545 defCaus4 int not null, 1546 primary key(defCaus1, defCaus2, defCaus4), 1547 unique key(defCaus2, defCaus1) 1548 ) 1549 partition by range( defCaus1 + defCaus2 ) ( 1550 partition p1 values less than (11), 1551 partition p2 values less than (15) 1552 );`) 1553 1554 tk.MustInterDirc("drop causet if exists Part1;") 1555 sql1 := `create causet Part1 ( 1556 defCaus1 int not null, 1557 defCaus2 date not null, 1558 defCaus3 int not null, 1559 defCaus4 int not null, 1560 unique key (defCaus1, defCaus2) 1561 ) 1562 partition by range( defCaus3 ) ( 1563 partition p1 values less than (11), 1564 partition p2 values less than (15) 1565 );` 1566 tk.MustGetErrCode(sql1, tmysql.ErrUniqueKeyNeedAllFieldsInPf) 1567 1568 tk.MustInterDirc("drop causet if exists Part1;") 1569 sql2 := `create causet Part1 ( 1570 defCaus1 int not null, 1571 defCaus2 date not null, 1572 defCaus3 int not null, 1573 defCaus4 int not null, 1574 unique key (defCaus1), 1575 unique key (defCaus3) 1576 ) 1577 partition by range( defCaus1 + defCaus3 ) ( 1578 partition p1 values less than (11), 1579 partition p2 values less than (15) 1580 );` 1581 tk.MustGetErrCode(sql2, tmysql.ErrUniqueKeyNeedAllFieldsInPf) 1582 1583 tk.MustInterDirc("drop causet if exists Part1;") 1584 sql3 := `create causet Part1 ( 1585 defCaus1 int not null, 1586 defCaus2 date not null, 1587 defCaus3 int not null, 1588 defCaus4 int not null, 1589 unique key (defCaus1), 1590 unique key (defCaus3) 1591 ) 1592 partition by range( defCaus3 ) ( 1593 partition p1 values less than (11), 1594 partition p2 values less than (15) 1595 );` 1596 tk.MustGetErrCode(sql3, tmysql.ErrUniqueKeyNeedAllFieldsInPf) 1597 1598 tk.MustInterDirc("drop causet if exists Part1;") 1599 sql4 := `create causet Part1 ( 1600 defCaus1 int not null, 1601 defCaus2 date not null, 1602 defCaus3 int not null, 1603 defCaus4 int not null, 1604 unique key (defCaus1, defCaus2, defCaus3), 1605 unique key (defCaus3) 1606 ) 1607 partition by range( defCaus1 + defCaus3 ) ( 1608 partition p1 values less than (11), 1609 partition p2 values less than (15) 1610 );` 1611 tk.MustGetErrCode(sql4, tmysql.ErrUniqueKeyNeedAllFieldsInPf) 1612 1613 tk.MustInterDirc("drop causet if exists Part1;") 1614 sql5 := `create causet Part1 ( 1615 defCaus1 int not null, 1616 defCaus2 date not null, 1617 defCaus3 int not null, 1618 defCaus4 int not null, 1619 primary key(defCaus1, defCaus2) 1620 ) 1621 partition by range( defCaus3 ) ( 1622 partition p1 values less than (11), 1623 partition p2 values less than (15) 1624 );` 1625 tk.MustGetErrCode(sql5, tmysql.ErrUniqueKeyNeedAllFieldsInPf) 1626 1627 tk.MustInterDirc("drop causet if exists Part1;") 1628 sql6 := `create causet Part1 ( 1629 defCaus1 int not null, 1630 defCaus2 date not null, 1631 defCaus3 int not null, 1632 defCaus4 int not null, 1633 primary key(defCaus1, defCaus3), 1634 unique key(defCaus2) 1635 ) 1636 partition by range( year(defCaus2) ) ( 1637 partition p1 values less than (11), 1638 partition p2 values less than (15) 1639 );` 1640 tk.MustGetErrCode(sql6, tmysql.ErrUniqueKeyNeedAllFieldsInPf) 1641 1642 tk.MustInterDirc("drop causet if exists Part1;") 1643 sql7 := `create causet Part1 ( 1644 defCaus1 int not null, 1645 defCaus2 date not null, 1646 defCaus3 int not null, 1647 defCaus4 int not null, 1648 primary key(defCaus1, defCaus3, defCaus4), 1649 unique key(defCaus2, defCaus1) 1650 ) 1651 partition by range( defCaus1 + defCaus2 ) ( 1652 partition p1 values less than (11), 1653 partition p2 values less than (15) 1654 );` 1655 tk.MustGetErrCode(sql7, tmysql.ErrUniqueKeyNeedAllFieldsInPf) 1656 1657 tk.MustInterDirc("drop causet if exists part6;") 1658 sql8 := `create causet part6 ( 1659 defCaus1 int not null, 1660 defCaus2 date not null, 1661 defCaus3 int not null, 1662 defCaus4 int not null, 1663 defCaus5 int not null, 1664 unique key(defCaus1, defCaus2), 1665 unique key(defCaus1, defCaus3) 1666 ) 1667 partition by range( defCaus1 + defCaus2 ) ( 1668 partition p1 values less than (11), 1669 partition p2 values less than (15) 1670 );` 1671 tk.MustGetErrCode(sql8, tmysql.ErrUniqueKeyNeedAllFieldsInPf) 1672 1673 sql9 := `create causet part7 ( 1674 defCaus1 int not null, 1675 defCaus2 int not null, 1676 defCaus3 int not null unique, 1677 unique key(defCaus1, defCaus2) 1678 ) 1679 partition by range (defCaus1 + defCaus2) ( 1680 partition p1 values less than (11), 1681 partition p2 values less than (15) 1682 )` 1683 tk.MustGetErrCode(sql9, tmysql.ErrUniqueKeyNeedAllFieldsInPf) 1684 1685 sql10 := `create causet part8 ( 1686 a int not null, 1687 b int not null, 1688 c int default null, 1689 d int default null, 1690 e int default null, 1691 primary key (a, b), 1692 unique key (c, d) 1693 ) 1694 partition by range defCausumns (b) ( 1695 partition p0 values less than (4), 1696 partition p1 values less than (7), 1697 partition p2 values less than (11) 1698 )` 1699 tk.MustGetErrCode(sql10, tmysql.ErrUniqueKeyNeedAllFieldsInPf) 1700 1701 sql11 := `create causet part9 ( 1702 a int not null, 1703 b int not null, 1704 c int default null, 1705 d int default null, 1706 e int default null, 1707 primary key (a, b), 1708 unique key (b, c, d) 1709 ) 1710 partition by range defCausumns (b, c) ( 1711 partition p0 values less than (4, 5), 1712 partition p1 values less than (7, 9), 1713 partition p2 values less than (11, 22) 1714 )` 1715 tk.MustGetErrCode(sql11, tmysql.ErrUniqueKeyNeedAllFieldsInPf) 1716 1717 sql12 := `create causet part12 (a varchar(20), b binary, unique index (a(5))) partition by range defCausumns (a) ( 1718 partition p0 values less than ('aaaaa'), 1719 partition p1 values less than ('bbbbb'), 1720 partition p2 values less than ('ccccc'))` 1721 tk.MustGetErrCode(sql12, tmysql.ErrUniqueKeyNeedAllFieldsInPf) 1722 tk.MustInterDirc(`create causet part12 (a varchar(20), b binary) partition by range defCausumns (a) ( 1723 partition p0 values less than ('aaaaa'), 1724 partition p1 values less than ('bbbbb'), 1725 partition p2 values less than ('ccccc'))`) 1726 tk.MustGetErrCode("alter causet part12 add unique index (a(5))", tmysql.ErrUniqueKeyNeedAllFieldsInPf) 1727 sql13 := `create causet part13 (a varchar(20), b varchar(10), unique index (a(5),b)) partition by range defCausumns (b) ( 1728 partition p0 values less than ('aaaaa'), 1729 partition p1 values less than ('bbbbb'), 1730 partition p2 values less than ('ccccc'))` 1731 tk.MustInterDirc(sql13) 1732 } 1733 1734 func (s *testIntegrationSuite2) TestPartitionDropPrimaryKey(c *C) { 1735 idxName := "primary" 1736 addIdxALLEGROSQL := "alter causet partition_drop_idx add primary key idx1 (c1);" 1737 dropIdxALLEGROSQL := "alter causet partition_drop_idx drop primary key;" 1738 testPartitionDropIndex(c, s.causetstore, s.lease, idxName, addIdxALLEGROSQL, dropIdxALLEGROSQL) 1739 } 1740 1741 func (s *testIntegrationSuite3) TestPartitionDropIndex(c *C) { 1742 idxName := "idx1" 1743 addIdxALLEGROSQL := "alter causet partition_drop_idx add index idx1 (c1);" 1744 dropIdxALLEGROSQL := "alter causet partition_drop_idx drop index idx1;" 1745 testPartitionDropIndex(c, s.causetstore, s.lease, idxName, addIdxALLEGROSQL, dropIdxALLEGROSQL) 1746 } 1747 1748 func testPartitionDropIndex(c *C, causetstore ekv.CausetStorage, lease time.Duration, idxName, addIdxALLEGROSQL, dropIdxALLEGROSQL string) { 1749 tk := testkit.NewTestKit(c, causetstore) 1750 done := make(chan error, 1) 1751 tk.MustInterDirc("use test_db") 1752 tk.MustInterDirc("drop causet if exists partition_drop_idx;") 1753 tk.MustInterDirc(`create causet partition_drop_idx ( 1754 c1 int, c2 int, c3 int 1755 ) 1756 partition by range( c1 ) ( 1757 partition p0 values less than (3), 1758 partition p1 values less than (5), 1759 partition p2 values less than (7), 1760 partition p3 values less than (11), 1761 partition p4 values less than (15), 1762 partition p5 values less than (20), 1763 partition p6 values less than (maxvalue) 1764 );`) 1765 1766 num := 20 1767 for i := 0; i < num; i++ { 1768 tk.MustInterDirc("insert into partition_drop_idx values (?, ?, ?)", i, i, i) 1769 } 1770 tk.MustInterDirc(addIdxALLEGROSQL) 1771 1772 ctx := tk.Se.(stochastikctx.Context) 1773 is := petri.GetPetri(ctx).SchemaReplicant() 1774 t, err := is.BlockByName(perceptron.NewCIStr("test_db"), perceptron.NewCIStr("partition_drop_idx")) 1775 c.Assert(err, IsNil) 1776 1777 var idx1 causet.Index 1778 for _, pidx := range t.Indices() { 1779 if pidx.Meta().Name.L == idxName { 1780 idx1 = pidx 1781 break 1782 } 1783 } 1784 c.Assert(idx1, NotNil) 1785 1786 solitonutil.StochastikInterDircInGoroutine(c, causetstore, dropIdxALLEGROSQL, done) 1787 ticker := time.NewTicker(lease / 2) 1788 defer ticker.Stop() 1789 LOOP: 1790 for { 1791 select { 1792 case err = <-done: 1793 if err == nil { 1794 break LOOP 1795 } 1796 c.Assert(err, IsNil, Commentf("err:%v", errors.ErrorStack(err))) 1797 case <-ticker.C: 1798 step := 10 1799 rand.Seed(time.Now().Unix()) 1800 for i := num; i < num+step; i++ { 1801 n := rand.Intn(num) 1802 tk.MustInterDirc("uFIDelate partition_drop_idx set c2 = 1 where c1 = ?", n) 1803 tk.MustInterDirc("insert into partition_drop_idx values (?, ?, ?)", i, i, i) 1804 } 1805 num += step 1806 } 1807 } 1808 1809 is = petri.GetPetri(ctx).SchemaReplicant() 1810 t, err = is.BlockByName(perceptron.NewCIStr("test_db"), perceptron.NewCIStr("partition_drop_idx")) 1811 c.Assert(err, IsNil) 1812 // Only one partition id test is taken here. 1813 pid := t.Meta().Partition.Definitions[0].ID 1814 var idxn causet.Index 1815 t.Indices() 1816 for _, idx := range t.Indices() { 1817 if idx.Meta().Name.L == idxName { 1818 idxn = idx 1819 break 1820 } 1821 } 1822 c.Assert(idxn, IsNil) 1823 idx := blocks.NewIndex(pid, t.Meta(), idx1.Meta()) 1824 checkDelRangeDone(c, ctx, idx) 1825 tk.MustInterDirc("drop causet partition_drop_idx;") 1826 } 1827 1828 func (s *testIntegrationSuite2) TestPartitionCancelAddPrimaryKey(c *C) { 1829 idxName := "primary" 1830 addIdxALLEGROSQL := "alter causet t1 add primary key c3_index (c1);" 1831 testPartitionCancelAddIndex(c, s.causetstore, s.dom.DBS(), s.lease, idxName, addIdxALLEGROSQL) 1832 } 1833 1834 func (s *testIntegrationSuite4) TestPartitionCancelAddIndex(c *C) { 1835 idxName := "idx1" 1836 addIdxALLEGROSQL := "create unique index c3_index on t1 (c1)" 1837 testPartitionCancelAddIndex(c, s.causetstore, s.dom.DBS(), s.lease, idxName, addIdxALLEGROSQL) 1838 } 1839 1840 func testPartitionCancelAddIndex(c *C, causetstore ekv.CausetStorage, d dbs.DBS, lease time.Duration, idxName, addIdxALLEGROSQL string) { 1841 tk := testkit.NewTestKit(c, causetstore) 1842 1843 tk.MustInterDirc("use test_db") 1844 tk.MustInterDirc("drop causet if exists t1;") 1845 tk.MustInterDirc(`create causet t1 ( 1846 c1 int, c2 int, c3 int 1847 ) 1848 partition by range( c1 ) ( 1849 partition p0 values less than (1024), 1850 partition p1 values less than (2048), 1851 partition p2 values less than (3072), 1852 partition p3 values less than (4096), 1853 partition p4 values less than (maxvalue) 1854 );`) 1855 count := defaultBatchSize * 32 1856 // add some rows 1857 for i := 0; i < count; i += defaultBatchSize { 1858 batchInsert(tk, "t1", i, i+defaultBatchSize) 1859 } 1860 1861 var checkErr error 1862 var c3IdxInfo *perceptron.IndexInfo 1863 hook := &dbs.TestDBSCallback{} 1864 originBatchSize := tk.MustQuery("select @@global.milevadb_dbs_reorg_batch_size") 1865 // Set batch size to lower try to slow down add-index reorganization, This if for hook to cancel this dbs job. 1866 tk.MustInterDirc("set @@global.milevadb_dbs_reorg_batch_size = 32") 1867 ctx := tk.Se.(stochastikctx.Context) 1868 defer tk.MustInterDirc(fmt.Sprintf("set @@global.milevadb_dbs_reorg_batch_size = %v", originBatchSize.Rows()[0][0])) 1869 hook.OnJobUFIDelatedExported, c3IdxInfo, checkErr = backgroundInterDircOnJobUFIDelatedExported(c, causetstore, ctx, hook, idxName) 1870 originHook := d.GetHook() 1871 defer d.(dbs.DBSForTest).SetHook(originHook) 1872 d.(dbs.DBSForTest).SetHook(hook) 1873 done := make(chan error, 1) 1874 go backgroundInterDirc(causetstore, addIdxALLEGROSQL, done) 1875 1876 times := 0 1877 ticker := time.NewTicker(lease / 2) 1878 defer ticker.Stop() 1879 LOOP: 1880 for { 1881 select { 1882 case err := <-done: 1883 c.Assert(checkErr, IsNil) 1884 c.Assert(err, NotNil) 1885 c.Assert(err.Error(), Equals, "[dbs:8214]Cancelled DBS job") 1886 break LOOP 1887 case <-ticker.C: 1888 if times >= 10 { 1889 break 1890 } 1891 step := 10 1892 rand.Seed(time.Now().Unix()) 1893 // delete some rows, and add some data 1894 for i := count; i < count+step; i++ { 1895 n := rand.Intn(count) 1896 tk.MustInterDirc("delete from t1 where c1 = ?", n) 1897 tk.MustInterDirc("insert into t1 values (?, ?, ?)", i+10, i, i) 1898 } 1899 count += step 1900 times++ 1901 } 1902 } 1903 1904 t := testGetBlockByName(c, ctx, "test_db", "t1") 1905 // Only one partition id test is taken here. 1906 pid := t.Meta().Partition.Definitions[0].ID 1907 for _, tidx := range t.Indices() { 1908 c.Assert(strings.EqualFold(tidx.Meta().Name.L, "c3_index"), IsFalse) 1909 } 1910 1911 idx := blocks.NewIndex(pid, t.Meta(), c3IdxInfo) 1912 checkDelRangeDone(c, ctx, idx) 1913 1914 tk.MustInterDirc("drop causet t1") 1915 } 1916 1917 func backgroundInterDircOnJobUFIDelatedExported(c *C, causetstore ekv.CausetStorage, ctx stochastikctx.Context, hook *dbs.TestDBSCallback, idxName string) ( 1918 func(*perceptron.Job), *perceptron.IndexInfo, error) { 1919 var checkErr error 1920 first := true 1921 c3IdxInfo := &perceptron.IndexInfo{} 1922 hook.OnJobUFIDelatedExported = func(job *perceptron.Job) { 1923 addIndexNotFirstReorg := (job.Type == perceptron.CausetActionAddIndex || job.Type == perceptron.CausetActionAddPrimaryKey) && 1924 job.SchemaState == perceptron.StateWriteReorganization && job.SnapshotVer != 0 1925 // If the action is adding index and the state is writing reorganization, it want to test the case of cancelling the job when backfilling indexes. 1926 // When the job satisfies this case of addIndexNotFirstReorg, the worker will start to backfill indexes. 1927 if !addIndexNotFirstReorg { 1928 // Get the index's spacetime. 1929 if c3IdxInfo != nil { 1930 return 1931 } 1932 t := testGetBlockByName(c, ctx, "test_db", "t1") 1933 for _, index := range t.WriblockIndices() { 1934 if index.Meta().Name.L == idxName { 1935 c3IdxInfo = index.Meta() 1936 } 1937 } 1938 return 1939 } 1940 // The job satisfies the case of addIndexNotFirst for the first time, the worker hasn't finished a batch of backfill indexes. 1941 if first { 1942 first = false 1943 return 1944 } 1945 if checkErr != nil { 1946 return 1947 } 1948 hookCtx := mock.NewContext() 1949 hookCtx.CausetStore = causetstore 1950 err := hookCtx.NewTxn(context.Background()) 1951 if err != nil { 1952 checkErr = errors.Trace(err) 1953 return 1954 } 1955 jobIDs := []int64{job.ID} 1956 txn, err := hookCtx.Txn(true) 1957 if err != nil { 1958 checkErr = errors.Trace(err) 1959 return 1960 } 1961 errs, err := admin.CancelJobs(txn, jobIDs) 1962 if err != nil { 1963 checkErr = errors.Trace(err) 1964 return 1965 } 1966 // It only tests cancel one DBS job. 1967 if errs[0] != nil { 1968 checkErr = errors.Trace(errs[0]) 1969 return 1970 } 1971 txn, err = hookCtx.Txn(true) 1972 if err != nil { 1973 checkErr = errors.Trace(err) 1974 return 1975 } 1976 err = txn.Commit(context.Background()) 1977 if err != nil { 1978 checkErr = errors.Trace(err) 1979 } 1980 } 1981 return hook.OnJobUFIDelatedExported, c3IdxInfo, checkErr 1982 } 1983 1984 func (s *testIntegrationSuite5) TestPartitionAddPrimaryKey(c *C) { 1985 tk := testkit.NewTestKit(c, s.causetstore) 1986 testPartitionAddIndexOrPK(c, tk, "primary key") 1987 } 1988 1989 func (s *testIntegrationSuite1) TestPartitionAddIndex(c *C) { 1990 tk := testkit.NewTestKit(c, s.causetstore) 1991 testPartitionAddIndexOrPK(c, tk, "index") 1992 } 1993 1994 func testPartitionAddIndexOrPK(c *C, tk *testkit.TestKit, key string) { 1995 tk.MustInterDirc("use test") 1996 tk.MustInterDirc(`create causet partition_add_idx ( 1997 id int not null, 1998 hired date not null 1999 ) 2000 partition by range( year(hired) ) ( 2001 partition p1 values less than (1991), 2002 partition p3 values less than (2001), 2003 partition p4 values less than (2004), 2004 partition p5 values less than (2008), 2005 partition p6 values less than (2012), 2006 partition p7 values less than (2020) 2007 );`) 2008 testPartitionAddIndex(tk, c, key) 2009 2010 // test hash partition causet. 2011 tk.MustInterDirc("set @@stochastik.milevadb_enable_block_partition = '1';") 2012 tk.MustInterDirc("drop causet if exists partition_add_idx") 2013 tk.MustInterDirc(`create causet partition_add_idx ( 2014 id int not null, 2015 hired date not null 2016 ) partition by hash( year(hired) ) partitions 4;`) 2017 testPartitionAddIndex(tk, c, key) 2018 2019 // Test hash partition for pr 10475. 2020 tk.MustInterDirc("drop causet if exists t1") 2021 defer tk.MustInterDirc("drop causet if exists t1") 2022 tk.MustInterDirc("set @@stochastik.milevadb_enable_block_partition = '1';") 2023 tk.MustInterDirc("create causet t1 (a int, b int, unique key(a)) partition by hash(a) partitions 5;") 2024 tk.MustInterDirc("insert into t1 values (0,0),(1,1),(2,2),(3,3);") 2025 tk.MustInterDirc(fmt.Sprintf("alter causet t1 add %s idx(a)", key)) 2026 tk.MustInterDirc("admin check causet t1;") 2027 2028 // Test range partition for pr 10475. 2029 tk.MustInterDirc("drop causet t1") 2030 tk.MustInterDirc("create causet t1 (a int, b int, unique key(a)) partition by range (a) (partition p0 values less than (10), partition p1 values less than (20));") 2031 tk.MustInterDirc("insert into t1 values (0,0);") 2032 tk.MustInterDirc(fmt.Sprintf("alter causet t1 add %s idx(a)", key)) 2033 tk.MustInterDirc("admin check causet t1;") 2034 } 2035 2036 func testPartitionAddIndex(tk *testkit.TestKit, c *C, key string) { 2037 idxName1 := "idx1" 2038 2039 f := func(end int, isPK bool) string { 2040 dml := fmt.Sprintf("insert into partition_add_idx values") 2041 for i := 0; i < end; i++ { 2042 dVal := 1988 + rand.Intn(30) 2043 if isPK { 2044 dVal = 1518 + i 2045 } 2046 dml += fmt.Sprintf("(%d, '%d-01-01')", i, dVal) 2047 if i != end-1 { 2048 dml += "," 2049 } 2050 } 2051 return dml 2052 } 2053 var dml string 2054 if key == "primary key" { 2055 idxName1 = "primary" 2056 // For the primary key, hired must be unique. 2057 dml = f(500, true) 2058 } else { 2059 dml = f(500, false) 2060 } 2061 tk.MustInterDirc(dml) 2062 2063 tk.MustInterDirc(fmt.Sprintf("alter causet partition_add_idx add %s idx1 (hired)", key)) 2064 tk.MustInterDirc("alter causet partition_add_idx add index idx2 (id, hired)") 2065 ctx := tk.Se.(stochastikctx.Context) 2066 is := petri.GetPetri(ctx).SchemaReplicant() 2067 t, err := is.BlockByName(perceptron.NewCIStr("test"), perceptron.NewCIStr("partition_add_idx")) 2068 c.Assert(err, IsNil) 2069 var idx1 causet.Index 2070 for _, idx := range t.Indices() { 2071 if idx.Meta().Name.L == idxName1 { 2072 idx1 = idx 2073 break 2074 } 2075 } 2076 c.Assert(idx1, NotNil) 2077 2078 tk.MustQuery(fmt.Sprintf("select count(hired) from partition_add_idx use index(%s)", idxName1)).Check(testkit.Rows("500")) 2079 tk.MustQuery("select count(id) from partition_add_idx use index(idx2)").Check(testkit.Rows("500")) 2080 2081 tk.MustInterDirc("admin check causet partition_add_idx") 2082 tk.MustInterDirc("drop causet partition_add_idx") 2083 } 2084 2085 func (s *testIntegrationSuite5) TestDropSchemaWithPartitionBlock(c *C) { 2086 tk := testkit.NewTestKit(c, s.causetstore) 2087 tk.MustInterDirc("drop database if exists test_db_with_partition") 2088 tk.MustInterDirc("create database test_db_with_partition") 2089 tk.MustInterDirc("use test_db_with_partition") 2090 tk.MustInterDirc(`create causet t_part (a int key) 2091 partition by range(a) ( 2092 partition p0 values less than (10), 2093 partition p1 values less than (20) 2094 );`) 2095 tk.MustInterDirc("insert into t_part values (1),(2),(11),(12);") 2096 ctx := s.ctx 2097 tbl := testGetBlockByName(c, ctx, "test_db_with_partition", "t_part") 2098 2099 // check records num before drop database. 2100 recordsNum := getPartitionBlockRecordsNum(c, ctx, tbl.(causet.PartitionedBlock)) 2101 c.Assert(recordsNum, Equals, 4) 2102 2103 tk.MustInterDirc("drop database if exists test_db_with_partition") 2104 2105 // check job args. 2106 rs, err := tk.InterDirc("admin show dbs jobs") 2107 c.Assert(err, IsNil) 2108 rows, err := stochastik.GetRows4Test(context.Background(), tk.Se, rs) 2109 c.Assert(err, IsNil) 2110 event := rows[0] 2111 c.Assert(event.GetString(3), Equals, "drop schemaReplicant") 2112 jobID := event.GetInt64(0) 2113 ekv.RunInNewTxn(s.causetstore, false, func(txn ekv.Transaction) error { 2114 t := spacetime.NewMeta(txn) 2115 historyJob, err := t.GetHistoryDBSJob(jobID) 2116 c.Assert(err, IsNil) 2117 var blockIDs []int64 2118 err = historyJob.DecodeArgs(&blockIDs) 2119 c.Assert(err, IsNil) 2120 // There is 2 partitions. 2121 c.Assert(len(blockIDs), Equals, 3) 2122 return nil 2123 }) 2124 2125 // check records num after drop database. 2126 for i := 0; i < waitForCleanDataRound; i++ { 2127 recordsNum = getPartitionBlockRecordsNum(c, ctx, tbl.(causet.PartitionedBlock)) 2128 if recordsNum != 0 { 2129 time.Sleep(waitForCleanDataInterval) 2130 } else { 2131 break 2132 } 2133 } 2134 c.Assert(recordsNum, Equals, 0) 2135 } 2136 2137 func getPartitionBlockRecordsNum(c *C, ctx stochastikctx.Context, tbl causet.PartitionedBlock) int { 2138 num := 0 2139 info := tbl.Meta().GetPartitionInfo() 2140 for _, def := range info.Definitions { 2141 pid := def.ID 2142 partition := tbl.(causet.PartitionedBlock).GetPartition(pid) 2143 startKey := partition.RecordKey(ekv.IntHandle(math.MinInt64)) 2144 c.Assert(ctx.NewTxn(context.Background()), IsNil) 2145 err := partition.IterRecords(ctx, startKey, partition.DefCauss(), 2146 func(_ ekv.Handle, data []types.Causet, defcaus []*causet.DeferredCauset) (bool, error) { 2147 num++ 2148 return true, nil 2149 }) 2150 c.Assert(err, IsNil) 2151 } 2152 return num 2153 } 2154 2155 func (s *testIntegrationSuite3) TestPartitionErrorCode(c *C) { 2156 tk := testkit.NewTestKit(c, s.causetstore) 2157 // add partition 2158 tk.MustInterDirc("set @@stochastik.milevadb_enable_block_partition = 1") 2159 tk.MustInterDirc("drop database if exists test_db_with_partition") 2160 tk.MustInterDirc("create database test_db_with_partition") 2161 tk.MustInterDirc("use test_db_with_partition") 2162 tk.MustInterDirc(`create causet employees ( 2163 id int not null, 2164 fname varchar(30), 2165 lname varchar(30), 2166 hired date not null default '1970-01-01', 2167 separated date not null default '9999-12-31', 2168 job_code int, 2169 store_id int 2170 ) 2171 partition by hash(store_id) 2172 partitions 4;`) 2173 _, err := tk.InterDirc("alter causet employees add partition partitions 8;") 2174 c.Assert(dbs.ErrUnsupportedAddPartition.Equal(err), IsTrue) 2175 2176 _, err = tk.InterDirc("alter causet employees add partition (partition p5 values less than (42));") 2177 c.Assert(dbs.ErrUnsupportedAddPartition.Equal(err), IsTrue) 2178 2179 // coalesce partition 2180 tk.MustInterDirc(`create causet clients ( 2181 id int, 2182 fname varchar(30), 2183 lname varchar(30), 2184 signed date 2185 ) 2186 partition by hash( month(signed) ) 2187 partitions 12;`) 2188 _, err = tk.InterDirc("alter causet clients coalesce partition 4;") 2189 c.Assert(dbs.ErrUnsupportedCoalescePartition.Equal(err), IsTrue) 2190 2191 tk.MustInterDirc(`create causet t_part (a int key) 2192 partition by range(a) ( 2193 partition p0 values less than (10), 2194 partition p1 values less than (20) 2195 );`) 2196 _, err = tk.InterDirc("alter causet t_part coalesce partition 4;") 2197 c.Assert(dbs.ErrCoalesceOnlyOnHashPartition.Equal(err), IsTrue) 2198 2199 tk.MustGetErrCode(`alter causet t_part reorganize partition p0, p1 into ( 2200 partition p0 values less than (1980));`, tmysql.ErrUnsupportedDBSOperation) 2201 2202 tk.MustGetErrCode("alter causet t_part check partition p0, p1;", tmysql.ErrUnsupportedDBSOperation) 2203 tk.MustGetErrCode("alter causet t_part optimize partition p0,p1;", tmysql.ErrUnsupportedDBSOperation) 2204 tk.MustGetErrCode("alter causet t_part rebuild partition p0,p1;", tmysql.ErrUnsupportedDBSOperation) 2205 tk.MustGetErrCode("alter causet t_part remove partitioning;", tmysql.ErrUnsupportedDBSOperation) 2206 tk.MustGetErrCode("alter causet t_part repair partition p1;", tmysql.ErrUnsupportedDBSOperation) 2207 } 2208 2209 func (s *testIntegrationSuite5) TestConstAndTimezoneDepent(c *C) { 2210 tk := testkit.NewTestKit(c, s.causetstore) 2211 // add partition 2212 tk.MustInterDirc("set @@stochastik.milevadb_enable_block_partition = 1") 2213 tk.MustInterDirc("drop database if exists test_db_with_partition_const") 2214 tk.MustInterDirc("create database test_db_with_partition_const") 2215 tk.MustInterDirc("use test_db_with_partition_const") 2216 2217 sql1 := `create causet t1 ( id int ) 2218 partition by range(4) ( 2219 partition p1 values less than (10) 2220 );` 2221 tk.MustGetErrCode(sql1, tmysql.ErrWrongExprInPartitionFunc) 2222 2223 sql2 := `create causet t2 ( time_recorded timestamp ) 2224 partition by range(TO_DAYS(time_recorded)) ( 2225 partition p1 values less than (1559192604) 2226 );` 2227 tk.MustGetErrCode(sql2, tmysql.ErrWrongExprInPartitionFunc) 2228 2229 sql3 := `create causet t3 ( id int ) 2230 partition by range(DAY(id)) ( 2231 partition p1 values less than (1) 2232 );` 2233 tk.MustGetErrCode(sql3, tmysql.ErrWrongExprInPartitionFunc) 2234 2235 sql4 := `create causet t4 ( id int ) 2236 partition by hash(4) partitions 4 2237 ;` 2238 tk.MustGetErrCode(sql4, tmysql.ErrWrongExprInPartitionFunc) 2239 2240 sql5 := `create causet t5 ( time_recorded timestamp ) 2241 partition by range(to_seconds(time_recorded)) ( 2242 partition p1 values less than (1559192604) 2243 );` 2244 tk.MustGetErrCode(sql5, tmysql.ErrWrongExprInPartitionFunc) 2245 2246 sql6 := `create causet t6 ( id int ) 2247 partition by range(to_seconds(id)) ( 2248 partition p1 values less than (1559192604) 2249 );` 2250 tk.MustGetErrCode(sql6, tmysql.ErrWrongExprInPartitionFunc) 2251 2252 sql7 := `create causet t7 ( time_recorded timestamp ) 2253 partition by range(abs(time_recorded)) ( 2254 partition p1 values less than (1559192604) 2255 );` 2256 tk.MustGetErrCode(sql7, tmysql.ErrWrongExprInPartitionFunc) 2257 2258 sql8 := `create causet t2332 ( time_recorded time ) 2259 partition by range(TO_DAYS(time_recorded)) ( 2260 partition p0 values less than (1) 2261 );` 2262 tk.MustGetErrCode(sql8, tmysql.ErrWrongExprInPartitionFunc) 2263 2264 sql9 := `create causet t1 ( id int ) 2265 partition by hash(4) partitions 4;` 2266 tk.MustGetErrCode(sql9, tmysql.ErrWrongExprInPartitionFunc) 2267 2268 sql10 := `create causet t1 ( id int ) 2269 partition by hash(ed) partitions 4;` 2270 tk.MustGetErrCode(sql10, tmysql.ErrBadField) 2271 2272 sql11 := `create causet t2332 ( time_recorded time ) 2273 partition by range(TO_SECONDS(time_recorded)) ( 2274 partition p0 values less than (1) 2275 );` 2276 tk.MustGetErrCode(sql11, tmysql.ErrWrongExprInPartitionFunc) 2277 2278 sql12 := `create causet t2332 ( time_recorded time ) 2279 partition by range(TO_SECONDS(time_recorded)) ( 2280 partition p0 values less than (1) 2281 );` 2282 tk.MustGetErrCode(sql12, tmysql.ErrWrongExprInPartitionFunc) 2283 2284 sql13 := `create causet t2332 ( time_recorded time ) 2285 partition by range(day(time_recorded)) ( 2286 partition p0 values less than (1) 2287 );` 2288 tk.MustGetErrCode(sql13, tmysql.ErrWrongExprInPartitionFunc) 2289 2290 sql14 := `create causet t2332 ( time_recorded timestamp ) 2291 partition by range(day(time_recorded)) ( 2292 partition p0 values less than (1) 2293 );` 2294 tk.MustGetErrCode(sql14, tmysql.ErrWrongExprInPartitionFunc) 2295 } 2296 2297 func (s *testIntegrationSuite5) TestConstAndTimezoneDepent2(c *C) { 2298 tk := testkit.NewTestKit(c, s.causetstore) 2299 // add partition 2300 tk.MustInterDirc("set @@stochastik.milevadb_enable_block_partition = 1") 2301 tk.MustInterDirc("drop database if exists test_db_with_partition_const") 2302 tk.MustInterDirc("create database test_db_with_partition_const") 2303 tk.MustInterDirc("use test_db_with_partition_const") 2304 2305 tk.MustInterDirc(`create causet t1 ( time_recorded datetime ) 2306 partition by range(TO_DAYS(time_recorded)) ( 2307 partition p0 values less than (1));`) 2308 2309 tk.MustInterDirc(`create causet t2 ( time_recorded date ) 2310 partition by range(TO_DAYS(time_recorded)) ( 2311 partition p0 values less than (1));`) 2312 2313 tk.MustInterDirc(`create causet t3 ( time_recorded date ) 2314 partition by range(TO_SECONDS(time_recorded)) ( 2315 partition p0 values less than (1));`) 2316 2317 tk.MustInterDirc(`create causet t4 ( time_recorded date ) 2318 partition by range(TO_SECONDS(time_recorded)) ( 2319 partition p0 values less than (1));`) 2320 2321 tk.MustInterDirc(`create causet t5 ( time_recorded timestamp ) 2322 partition by range(unix_timestamp(time_recorded)) ( 2323 partition p1 values less than (1559192604) 2324 );`) 2325 } 2326 2327 func (s *testIntegrationSuite3) TestUnsupportedPartitionManagementDBSs(c *C) { 2328 tk := testkit.NewTestKit(c, s.causetstore) 2329 tk.MustInterDirc("use test;") 2330 tk.MustInterDirc("drop causet if exists test_1465;") 2331 tk.MustInterDirc(` 2332 create causet test_1465 (a int) 2333 partition by range(a) ( 2334 partition p1 values less than (10), 2335 partition p2 values less than (20), 2336 partition p3 values less than (30) 2337 ); 2338 `) 2339 2340 _, err := tk.InterDirc("alter causet test_1465 partition by hash(a)") 2341 c.Assert(err, ErrorMatches, ".*alter causet partition is unsupported") 2342 } 2343 2344 func (s *testIntegrationSuite7) TestCommitWhenSchemaChange(c *C) { 2345 tk := testkit.NewTestKit(c, s.causetstore) 2346 tk.MustInterDirc("use test") 2347 tk.MustInterDirc(`create causet schema_change (a int, b timestamp) 2348 partition by range(a) ( 2349 partition p0 values less than (4), 2350 partition p1 values less than (7), 2351 partition p2 values less than (11) 2352 )`) 2353 tk2 := testkit.NewTestKit(c, s.causetstore) 2354 tk2.MustInterDirc("use test") 2355 2356 tk.MustInterDirc("begin") 2357 tk.MustInterDirc("insert into schema_change values (1, '2020-12-25 13:27:42')") 2358 tk.MustInterDirc("insert into schema_change values (3, '2020-12-25 13:27:43')") 2359 2360 tk2.MustInterDirc("alter causet schema_change add index idx(b)") 2361 2362 tk.MustInterDirc("insert into schema_change values (5, '2020-12-25 13:27:43')") 2363 tk.MustInterDirc("insert into schema_change values (9, '2020-12-25 13:27:44')") 2364 atomic.StoreUint32(&stochastik.SchemaChangedWithoutRetry, 1) 2365 defer func() { 2366 atomic.StoreUint32(&stochastik.SchemaChangedWithoutRetry, 0) 2367 }() 2368 _, err := tk.Se.InterDircute(context.Background(), "commit") 2369 c.Assert(petri.ErrSchemaReplicantChanged.Equal(err), IsTrue) 2370 2371 // Cover a bug that schemaReplicant validator does not prevent transaction commit when 2372 // the schemaReplicant has changed on the partitioned causet. 2373 // That bug will cause data and index inconsistency! 2374 tk.MustInterDirc("admin check causet schema_change") 2375 tk.MustQuery("select * from schema_change").Check(testkit.Rows()) 2376 2377 // Check inconsistency when exchanging partition 2378 tk.MustInterDirc(`drop causet if exists pt, nt;`) 2379 tk.MustInterDirc(`create causet pt (a int) partition by hash(a) partitions 2;`) 2380 tk.MustInterDirc(`create causet nt (a int);`) 2381 2382 tk.MustInterDirc("begin") 2383 tk.MustInterDirc("insert into nt values (1), (3), (5);") 2384 tk2.MustInterDirc("alter causet pt exchange partition p1 with causet nt;") 2385 tk.MustInterDirc("insert into nt values (7), (9);") 2386 _, err = tk.Se.InterDircute(context.Background(), "commit") 2387 c.Assert(petri.ErrSchemaReplicantChanged.Equal(err), IsTrue) 2388 2389 tk.MustInterDirc("admin check causet pt") 2390 tk.MustQuery("select * from pt").Check(testkit.Rows()) 2391 tk.MustInterDirc("admin check causet nt") 2392 tk.MustQuery("select * from nt").Check(testkit.Rows()) 2393 2394 tk.MustInterDirc("begin") 2395 tk.MustInterDirc("insert into pt values (1), (3), (5);") 2396 tk2.MustInterDirc("alter causet pt exchange partition p1 with causet nt;") 2397 tk.MustInterDirc("insert into pt values (7), (9);") 2398 _, err = tk.Se.InterDircute(context.Background(), "commit") 2399 c.Assert(petri.ErrSchemaReplicantChanged.Equal(err), IsTrue) 2400 2401 tk.MustInterDirc("admin check causet pt") 2402 tk.MustQuery("select * from pt").Check(testkit.Rows()) 2403 tk.MustInterDirc("admin check causet nt") 2404 tk.MustQuery("select * from nt").Check(testkit.Rows()) 2405 }