github.com/matrixorigin/matrixone@v0.7.0/pkg/sql/plan/build_partition_test.go (about) 1 // Copyright 2022 Matrix Origin 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 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package plan 16 17 import ( 18 "testing" 19 20 "github.com/matrixorigin/matrixone/pkg/sql/parsers/dialect/mysql" 21 ) 22 23 func TestSingleDDLPartition(t *testing.T) { 24 //sql := `CREATE TABLE k1 ( 25 // id INT NOT NULL PRIMARY KEY, 26 // name VARCHAR(20) 27 // ) 28 // PARTITION BY KEY() 29 // PARTITIONS 2;` 30 31 //sql := `CREATE TABLE k1 ( 32 // id INT NOT NULL, 33 // name VARCHAR(20), 34 // sal DOUBLE, 35 // PRIMARY KEY (id, name) 36 // ) 37 // PARTITION BY KEY() 38 // PARTITIONS 2;` 39 40 sql := `CREATE TABLE k1 ( 41 id INT NOT NULL, 42 name VARCHAR(20), 43 UNIQUE KEY (id) 44 ) 45 PARTITION BY KEY() 46 PARTITIONS 2;` 47 48 //sql := `CREATE TABLE quarterly_report_status ( 49 // report_id INT NOT NULL, 50 // report_status VARCHAR(20) NOT NULL, 51 // report_updated TIMESTAMP NOT NULL 52 // ) 53 // PARTITION BY RANGE ( UNIX_TIMESTAMP(report_updated) ) ( 54 // PARTITION p0 VALUES LESS THAN ( UNIX_TIMESTAMP('2008-01-01 00:00:00') ), 55 // PARTITION p1 VALUES LESS THAN ( UNIX_TIMESTAMP('2008-04-01 00:00:00') ), 56 // PARTITION p2 VALUES LESS THAN ( UNIX_TIMESTAMP('2008-07-01 00:00:00') ), 57 // PARTITION p3 VALUES LESS THAN ( UNIX_TIMESTAMP('2008-10-01 00:00:00') ), 58 // PARTITION p4 VALUES LESS THAN ( UNIX_TIMESTAMP('2009-01-01 00:00:00') ), 59 // PARTITION p5 VALUES LESS THAN ( UNIX_TIMESTAMP('2009-04-01 00:00:00') ), 60 // PARTITION p6 VALUES LESS THAN ( UNIX_TIMESTAMP('2009-07-01 00:00:00') ), 61 // PARTITION p7 VALUES LESS THAN ( UNIX_TIMESTAMP('2009-10-01 00:00:00') ), 62 // PARTITION p8 VALUES LESS THAN ( UNIX_TIMESTAMP('2010-01-01 00:00:00') ), 63 // PARTITION p9 VALUES LESS THAN (MAXVALUE) 64 // );` 65 66 mock := NewMockOptimizer(false) 67 logicPlan, err := buildSingleStmt(mock, t, sql) 68 if err != nil { 69 t.Fatalf("%+v", err) 70 } 71 outPutPlan(logicPlan, true, t) 72 } 73 74 // ---------------------------------- Key Partition ---------------------------------- 75 func TestKeyPartition(t *testing.T) { 76 // KEY(column_list) Partition 77 sqls := []string{ 78 "CREATE TABLE tk (col1 INT, col2 CHAR(5), col3 DATE) PARTITION BY KEY(col3) PARTITIONS 4;", 79 "CREATE TABLE tk (col1 INT, col2 CHAR(5), col3 DATE) PARTITION BY KEY(col3);", 80 "CREATE TABLE tk (col1 INT, col2 CHAR(5), col3 DATE) PARTITION BY LINEAR KEY(col3) PARTITIONS 5;", 81 "CREATE TABLE tk (col1 INT, col2 CHAR(5), col3 DATE) PARTITION BY KEY ALGORITHM = 1 (col3);", 82 "CREATE TABLE tk (col1 INT, col2 CHAR(5), col3 DATE) PARTITION BY LINEAR KEY ALGORITHM = 1 (col3) PARTITIONS 5;", 83 "CREATE TABLE tk (col1 INT, col2 CHAR(5), col3 DATE) PARTITION BY KEY(col1, col2) PARTITIONS 4;", 84 `CREATE TABLE t1 ( 85 col1 INT NOT NULL, 86 col2 DATE NOT NULL, 87 col3 INT NOT NULL, 88 col4 INT NOT NULL, 89 PRIMARY KEY (col1, col2) 90 ) 91 PARTITION BY KEY(col1) 92 PARTITIONS 4;`, 93 `CREATE TABLE k1 ( 94 id INT NOT NULL PRIMARY KEY, 95 name VARCHAR(20) 96 ) 97 PARTITION BY KEY() 98 PARTITIONS 2;`, 99 `CREATE TABLE k1 ( 100 id INT NOT NULL, 101 name VARCHAR(20), 102 sal DOUBLE, 103 PRIMARY KEY (id, name) 104 ) 105 PARTITION BY KEY() 106 PARTITIONS 2;`, 107 `CREATE TABLE k1 ( 108 id INT NOT NULL, 109 name VARCHAR(20), 110 UNIQUE KEY (id) 111 ) 112 PARTITION BY KEY() 113 PARTITIONS 2;`, 114 `CREATE TABLE t1 ( 115 col1 INT NOT NULL, 116 col2 DATE NOT NULL, 117 col3 INT NOT NULL, 118 col4 INT NOT NULL, 119 PRIMARY KEY (col1, col2) 120 ) 121 PARTITION BY KEY() 122 PARTITIONS 4;`, 123 `CREATE TABLE t2 ( 124 col1 INT NOT NULL, 125 col2 DATE NOT NULL, 126 col3 INT NOT NULL, 127 col4 INT NOT NULL, 128 PRIMARY KEY (col1), 129 unique key (col1, col4) 130 ) 131 PARTITION BY KEY() 132 PARTITIONS 4;`, 133 } 134 135 mock := NewMockOptimizer(false) 136 for _, sql := range sqls { 137 t.Log(sql) 138 logicPlan, err := buildSingleStmt(mock, t, sql) 139 if err != nil { 140 t.Fatalf("%+v", err) 141 } 142 outPutPlan(logicPlan, true, t) 143 } 144 } 145 146 func TestKeyPartitionError(t *testing.T) { 147 sqls := []string{ 148 "CREATE TABLE ts (id INT, purchased DATE) PARTITION BY KEY( id ) PARTITIONS 4 SUBPARTITION BY HASH( TO_DAYS(purchased) ) SUBPARTITIONS 2;", 149 "CREATE TABLE tk (col1 INT, col2 CHAR(5), col3 DATE) PARTITION BY KEY(col4) PARTITIONS 4;", 150 "CREATE TABLE tk (col1 INT, col2 CHAR(5), col3 DATE) PARTITION BY KEY ALGORITHM = 3 (col3);", 151 `CREATE TABLE t1 ( 152 col1 INT NOT NULL, 153 col2 DATE NOT NULL, 154 col3 INT NOT NULL, 155 col4 INT NOT NULL, 156 PRIMARY KEY (col1, col2) 157 ) 158 PARTITION BY KEY(col3) 159 PARTITIONS 4;`, 160 `CREATE TABLE k1 ( 161 id INT NOT NULL, 162 name VARCHAR(20) 163 ) 164 PARTITION BY KEY() 165 PARTITIONS 2;`, 166 `CREATE TABLE t4 ( 167 col1 INT NOT NULL, 168 col2 INT NOT NULL, 169 col3 INT NOT NULL, 170 col4 INT NOT NULL, 171 UNIQUE KEY (col1, col3), 172 UNIQUE KEY (col2, col4) 173 ) 174 PARTITION BY KEY() 175 PARTITIONS 2;`, 176 177 `CREATE TABLE t2 ( 178 col1 INT NOT NULL, 179 col2 DATE NOT NULL, 180 col3 INT NOT NULL, 181 col4 INT NOT NULL, 182 PRIMARY KEY (col1), 183 unique key (col3, col4) 184 ) 185 PARTITION BY KEY() 186 PARTITIONS 4;`, 187 188 `CREATE TABLE t3 ( 189 col1 INT NOT NULL, 190 col2 DATE NOT NULL, 191 col3 INT NOT NULL, 192 col4 INT NOT NULL, 193 PRIMARY KEY (col1, col4), 194 unique key (col1) 195 ) 196 PARTITION BY KEY() 197 PARTITIONS 4;`, 198 `CREATE TABLE t1 ( 199 col1 INT NOT NULL, 200 col2 DATE NOT NULL, 201 col3 INT NOT NULL, 202 col4 INT NOT NULL, 203 PRIMARY KEY (col1, col2) 204 ) 205 PARTITION BY KEY(col3) 206 PARTITIONS 4;`, 207 } 208 mock := NewMockOptimizer(false) 209 for _, sql := range sqls { 210 _, err := buildSingleStmt(mock, t, sql) 211 t.Log(sql) 212 t.Log(err) 213 if err == nil { 214 t.Fatalf("%+v", err) 215 } 216 } 217 } 218 219 // -----------------------Hash Partition------------------------------------- 220 func TestHashPartition(t *testing.T) { 221 // HASH(expr) Partition 222 sqls := []string{ 223 "CREATE TABLE t1 (col1 INT, col2 CHAR(5)) PARTITION BY HASH(col1);", 224 "CREATE TABLE t1 (col1 INT, col2 CHAR(5)) PARTITION BY HASH(col1) PARTITIONS 4;", 225 "CREATE TABLE t1 (col1 INT, col2 CHAR(5), col3 DATETIME) PARTITION BY HASH (YEAR(col3));", 226 "CREATE TABLE t1 (col1 INT, col2 CHAR(5), col3 DATE) PARTITION BY LINEAR HASH( YEAR(col3)) PARTITIONS 6;", 227 `CREATE TABLE employees ( 228 id INT NOT NULL, 229 fname VARCHAR(30), 230 lname VARCHAR(30), 231 hired DATE NOT NULL DEFAULT '1970-01-01', 232 separated DATE NOT NULL DEFAULT '9999-12-31', 233 job_code INT, 234 store_id INT 235 ) 236 PARTITION BY HASH(store_id) 237 PARTITIONS 4;`, 238 239 `CREATE TABLE t1 ( 240 col1 INT NOT NULL, 241 col2 DATE NOT NULL, 242 col3 INT NOT NULL, 243 col4 INT NOT NULL, 244 PRIMARY KEY (col1, col2) 245 ) 246 PARTITION BY HASH(col1) 247 PARTITIONS 4;`, 248 249 `CREATE TABLE t1 ( 250 col1 INT NOT NULL, 251 col2 DATE NOT NULL, 252 col3 INT NOT NULL, 253 col4 INT NOT NULL, 254 PRIMARY KEY (col1, col3) 255 ) 256 PARTITION BY HASH(col1 + col3) 257 PARTITIONS 4;`, 258 259 `CREATE TABLE t2 ( 260 col1 INT NOT NULL, 261 col2 DATE NOT NULL, 262 col3 INT NOT NULL, 263 col4 INT NOT NULL, 264 PRIMARY KEY (col1) 265 ) 266 PARTITION BY HASH(col1+10) 267 PARTITIONS 4;`, 268 `CREATE TABLE employees ( 269 id INT NOT NULL, 270 fname VARCHAR(30), 271 lname VARCHAR(30), 272 hired DATE NOT NULL DEFAULT '1970-01-01', 273 separated DATE NOT NULL DEFAULT '9999-12-31', 274 job_code INT, 275 store_id INT 276 ) 277 PARTITION BY LINEAR HASH( YEAR(hired) ) 278 PARTITIONS 4;`, 279 } 280 281 mock := NewMockOptimizer(false) 282 for _, sql := range sqls { 283 t.Log(sql) 284 logicPlan, err := buildSingleStmt(mock, t, sql) 285 if err != nil { 286 t.Fatalf("%+v", err) 287 } 288 outPutPlan(logicPlan, true, t) 289 } 290 } 291 292 func TestHashPartitionError(t *testing.T) { 293 // HASH(expr) Partition 294 sqls := []string{ 295 "CREATE TABLE t1 (col1 INT, col2 CHAR(5)) PARTITION BY HASH(col2);", 296 "CREATE TABLE t1 (col1 INT, col2 DECIMAL) PARTITION BY HASH(col2);", 297 "CREATE TABLE t1 (col1 INT, col2 DECIMAL) PARTITION BY HASH(col1+0.5);", 298 "CREATE TABLE t1 (col1 INT, col2 DECIMAL) PARTITION BY HASH(12);", 299 "CREATE TABLE t1 (col1 INT, col2 CHAR(5), col3 DATETIME) PARTITION BY HASH (YEAR(col3)) PARTITIONS 4 SUBPARTITION BY KEY(col1);", 300 "CREATE TABLE t1 (col1 INT, col2 CHAR(5), col3 DATE) PARTITION BY HASH( YEAR(col3) ) PARTITIONS;", 301 `CREATE TABLE employees ( 302 id INT NOT NULL, 303 fname VARCHAR(30), 304 lname VARCHAR(30), 305 hired DATE NOT NULL DEFAULT '1970-01-01', 306 separated DATE NOT NULL DEFAULT '9999-12-31', 307 job_code INT, 308 store_id INT 309 ) 310 PARTITION BY HASH(4) 311 PARTITIONS 4;`, 312 313 `CREATE TABLE t1 ( 314 col1 INT NOT NULL, 315 col2 DATE NOT NULL, 316 col3 INT NOT NULL, 317 col4 INT NOT NULL, 318 PRIMARY KEY (col1, col2) 319 ) 320 PARTITION BY HASH(col3) 321 PARTITIONS 4;`, 322 323 `CREATE TABLE t2 ( 324 col1 INT NOT NULL, 325 col2 DATE NOT NULL, 326 col3 INT NOT NULL, 327 col4 INT NOT NULL, 328 PRIMARY KEY (col1) 329 ) 330 PARTITION BY HASH(col1 + col3) 331 PARTITIONS 4;`, 332 333 `CREATE TABLE t2 ( 334 col1 INT NOT NULL, 335 col2 DATE NOT NULL, 336 col3 INT NOT NULL, 337 col4 INT NOT NULL, 338 UNIQUE KEY (col1), 339 UNIQUE KEY (col3) 340 ) 341 PARTITION BY HASH(col1,col3) 342 PARTITIONS 4;`, 343 } 344 345 mock := NewMockOptimizer(false) 346 for _, sql := range sqls { 347 _, err := buildSingleStmt(mock, t, sql) 348 t.Log(sql) 349 t.Log(err) 350 if err == nil { 351 t.Fatalf("%+v", err) 352 } 353 } 354 355 } 356 357 // -----------------------Range Partition------------------------------------- 358 func TestRangePartition(t *testing.T) { 359 sqls := []string{ 360 `CREATE TABLE employees ( 361 id INT NOT NULL, 362 fname VARCHAR(30), 363 lname VARCHAR(30), 364 hired DATE NOT NULL DEFAULT '1970-01-01', 365 separated DATE NOT NULL DEFAULT '9999-12-31', 366 job_code INT NOT NULL, 367 store_id INT NOT NULL 368 ) 369 PARTITION BY RANGE (store_id) ( 370 PARTITION p0 VALUES LESS THAN (6), 371 PARTITION p1 VALUES LESS THAN (11), 372 PARTITION p2 VALUES LESS THAN (16), 373 PARTITION p3 VALUES LESS THAN (21) 374 );`, 375 376 `CREATE TABLE t1 ( 377 year_col INT, 378 some_data INT 379 ) 380 PARTITION BY RANGE (year_col) ( 381 PARTITION p0 VALUES LESS THAN (1991), 382 PARTITION p1 VALUES LESS THAN (1995), 383 PARTITION p2 VALUES LESS THAN (1999), 384 PARTITION p3 VALUES LESS THAN (2002), 385 PARTITION p4 VALUES LESS THAN (2006), 386 PARTITION p5 VALUES LESS THAN (2012) 387 );`, 388 389 `CREATE TABLE t1 ( 390 year_col INT, 391 some_data INT 392 ) 393 PARTITION BY RANGE (year_col) ( 394 PARTITION p0 VALUES LESS THAN (1991) COMMENT = 'Data for the years previous to 1991', 395 PARTITION p1 VALUES LESS THAN (1995) COMMENT = 'Data for the years previous to 1995', 396 PARTITION p2 VALUES LESS THAN (1999) COMMENT = 'Data for the years previous to 1999', 397 PARTITION p3 VALUES LESS THAN (2002) COMMENT = 'Data for the years previous to 2002', 398 PARTITION p4 VALUES LESS THAN (2006) COMMENT = 'Data for the years previous to 2006', 399 PARTITION p5 VALUES LESS THAN (2012) COMMENT = 'Data for the years previous to 2012' 400 );`, 401 402 `CREATE TABLE employees ( 403 id INT NOT NULL, 404 fname VARCHAR(30), 405 lname VARCHAR(30), 406 hired DATE NOT NULL DEFAULT '1970-01-01', 407 separated DATE NOT NULL DEFAULT '9999-12-31', 408 job_code INT NOT NULL, 409 store_id INT NOT NULL 410 ) 411 PARTITION BY RANGE (store_id) ( 412 PARTITION p0 VALUES LESS THAN (6), 413 PARTITION p1 VALUES LESS THAN (11), 414 PARTITION p2 VALUES LESS THAN (16), 415 PARTITION p3 VALUES LESS THAN MAXVALUE 416 );`, 417 418 `CREATE TABLE employees ( 419 id INT NOT NULL, 420 fname VARCHAR(30), 421 lname VARCHAR(30), 422 hired DATE NOT NULL DEFAULT '1970-01-01', 423 separated DATE NOT NULL DEFAULT '9999-12-31', 424 job_code INT NOT NULL, 425 store_id INT NOT NULL 426 ) 427 PARTITION BY RANGE (job_code) ( 428 PARTITION p0 VALUES LESS THAN (100), 429 PARTITION p1 VALUES LESS THAN (1000), 430 PARTITION p2 VALUES LESS THAN (10000) 431 );`, 432 433 `CREATE TABLE employees ( 434 id INT NOT NULL, 435 fname VARCHAR(30), 436 lname VARCHAR(30), 437 hired DATE NOT NULL DEFAULT '1970-01-01', 438 separated DATE NOT NULL DEFAULT '9999-12-31', 439 job_code INT, 440 store_id INT 441 ) 442 PARTITION BY RANGE ( YEAR(separated) ) ( 443 PARTITION p0 VALUES LESS THAN (1991), 444 PARTITION p1 VALUES LESS THAN (1996), 445 PARTITION p2 VALUES LESS THAN (2001), 446 PARTITION p3 VALUES LESS THAN MAXVALUE 447 );`, 448 449 `CREATE TABLE employees ( 450 id INT NOT NULL, 451 fname VARCHAR(30), 452 lname VARCHAR(30), 453 hired DATE NOT NULL DEFAULT '1970-01-01', 454 separated DATE NOT NULL DEFAULT '9999-12-31', 455 job_code INT NOT NULL, 456 store_id INT NOT NULL, 457 PRIMARY KEY(id, store_id) 458 ) 459 PARTITION BY RANGE (store_id) ( 460 PARTITION p0 VALUES LESS THAN (6), 461 PARTITION p1 VALUES LESS THAN (11), 462 PARTITION p2 VALUES LESS THAN (16), 463 PARTITION p3 VALUES LESS THAN (21) 464 );`, 465 466 `CREATE TABLE employees ( 467 id INT NOT NULL, 468 fname VARCHAR(30), 469 lname VARCHAR(30), 470 hired DATE NOT NULL DEFAULT '1970-01-01', 471 separated DATE NOT NULL DEFAULT '9999-12-31', 472 job_code INT NOT NULL, 473 store_id INT NOT NULL, 474 PRIMARY KEY(id, store_id) 475 ) 476 PARTITION BY RANGE (store_id + 5) ( 477 PARTITION p0 VALUES LESS THAN (6), 478 PARTITION p1 VALUES LESS THAN (11), 479 PARTITION p2 VALUES LESS THAN (16), 480 PARTITION p3 VALUES LESS THAN (21) 481 );`, 482 483 `CREATE TABLE employees ( 484 id INT NOT NULL, 485 fname VARCHAR(30), 486 lname VARCHAR(30), 487 hired DATE NOT NULL DEFAULT '1970-01-01', 488 separated DATE NOT NULL DEFAULT '9999-12-31', 489 job_code INT NOT NULL, 490 store_id INT NOT NULL, 491 PRIMARY KEY(id, hired) 492 ) 493 PARTITION BY RANGE (year(hired)) ( 494 PARTITION p0 VALUES LESS THAN (6), 495 PARTITION p1 VALUES LESS THAN (11), 496 PARTITION p2 VALUES LESS THAN (16), 497 PARTITION p3 VALUES LESS THAN (21) 498 );`, 499 500 `CREATE TABLE members ( 501 firstname VARCHAR(25) NOT NULL, 502 lastname VARCHAR(25) NOT NULL, 503 username VARCHAR(16) NOT NULL, 504 email VARCHAR(35), 505 joined DATE NOT NULL 506 ) 507 PARTITION BY RANGE( YEAR(joined) ) PARTITIONS 5 ( 508 PARTITION p0 VALUES LESS THAN (1960), 509 PARTITION p1 VALUES LESS THAN (1970), 510 PARTITION p2 VALUES LESS THAN (1980), 511 PARTITION p3 VALUES LESS THAN (1990), 512 PARTITION p4 VALUES LESS THAN MAXVALUE 513 );`, 514 515 //`CREATE TABLE quarterly_report_status ( 516 // report_id INT NOT NULL, 517 // report_status VARCHAR(20) NOT NULL, 518 // report_updated TIMESTAMP NOT NULL 519 //) 520 // PARTITION BY RANGE ( UNIX_TIMESTAMP(report_updated) ) ( 521 // PARTITION p0 VALUES LESS THAN ( UNIX_TIMESTAMP('2008-01-01 00:00:00') ), 522 // PARTITION p1 VALUES LESS THAN ( UNIX_TIMESTAMP('2008-04-01 00:00:00') ), 523 // PARTITION p2 VALUES LESS THAN ( UNIX_TIMESTAMP('2008-07-01 00:00:00') ), 524 // PARTITION p3 VALUES LESS THAN ( UNIX_TIMESTAMP('2008-10-01 00:00:00') ), 525 // PARTITION p4 VALUES LESS THAN ( UNIX_TIMESTAMP('2009-01-01 00:00:00') ), 526 // PARTITION p5 VALUES LESS THAN ( UNIX_TIMESTAMP('2009-04-01 00:00:00') ), 527 // PARTITION p6 VALUES LESS THAN ( UNIX_TIMESTAMP('2009-07-01 00:00:00') ), 528 // PARTITION p7 VALUES LESS THAN ( UNIX_TIMESTAMP('2009-10-01 00:00:00') ), 529 // PARTITION p8 VALUES LESS THAN ( UNIX_TIMESTAMP('2010-01-01 00:00:00') ), 530 // PARTITION p9 VALUES LESS THAN (MAXVALUE) 531 //);`, 532 } 533 534 mock := NewMockOptimizer(false) 535 for _, sql := range sqls { 536 t.Log(sql) 537 logicPlan, err := buildSingleStmt(mock, t, sql) 538 if err != nil { 539 t.Fatalf("%+v", err) 540 } 541 outPutPlan(logicPlan, true, t) 542 } 543 } 544 545 func TestRangePartitionError(t *testing.T) { 546 sqls := []string{ 547 `CREATE TABLE employees ( 548 id INT NOT NULL, 549 fname VARCHAR(30), 550 lname VARCHAR(30), 551 hired DATE NOT NULL DEFAULT '1970-01-01', 552 separated DATE NOT NULL DEFAULT '9999-12-31', 553 job_code INT NOT NULL, 554 store_id INT NOT NULL, 555 PRIMARY KEY(id, store_id) 556 ) 557 PARTITION BY RANGE (job_code) ( 558 PARTITION p0 VALUES LESS THAN (6), 559 PARTITION p1 VALUES LESS THAN (11), 560 PARTITION p2 VALUES LESS THAN (16), 561 PARTITION p3 VALUES LESS THAN (21) 562 );`, 563 564 `CREATE TABLE employees ( 565 id INT NOT NULL, 566 fname VARCHAR(30), 567 lname VARCHAR(30), 568 hired DATE NOT NULL DEFAULT '1970-01-01', 569 separated DATE NOT NULL DEFAULT '9999-12-31', 570 job_code INT NOT NULL, 571 store_id INT NOT NULL, 572 PRIMARY KEY(id, store_id) 573 ) 574 PARTITION BY RANGE (job_code + 5) ( 575 PARTITION p0 VALUES LESS THAN (6), 576 PARTITION p1 VALUES LESS THAN (11), 577 PARTITION p2 VALUES LESS THAN (16), 578 PARTITION p3 VALUES LESS THAN (21) 579 );`, 580 581 `CREATE TABLE employees ( 582 id INT NOT NULL, 583 fname VARCHAR(30), 584 lname VARCHAR(30), 585 hired DATE NOT NULL DEFAULT '1970-01-01', 586 separated DATE NOT NULL DEFAULT '9999-12-31', 587 job_code INT NOT NULL, 588 store_id INT NOT NULL, 589 PRIMARY KEY(id, hired) 590 ) 591 PARTITION BY RANGE (year(separated)) ( 592 PARTITION p0 VALUES LESS THAN (6), 593 PARTITION p1 VALUES LESS THAN (11), 594 PARTITION p2 VALUES LESS THAN (16), 595 PARTITION p3 VALUES LESS THAN (21) 596 );`, 597 598 `CREATE TABLE employees ( 599 id INT NOT NULL, 600 fname VARCHAR(30), 601 lname VARCHAR(30), 602 hired DATE NOT NULL DEFAULT '1970-01-01', 603 separated DATE NOT NULL DEFAULT '9999-12-31', 604 job_code INT NOT NULL, 605 store_id INT NOT NULL, 606 PRIMARY KEY(id, store_id) 607 ) 608 PARTITION BY RANGE (job_code + store_id) ( 609 PARTITION p0 VALUES LESS THAN (6), 610 PARTITION p1 VALUES LESS THAN (11), 611 PARTITION p2 VALUES LESS THAN (16), 612 PARTITION p3 VALUES LESS THAN (21) 613 );`, 614 615 `CREATE TABLE members ( 616 firstname VARCHAR(25) NOT NULL, 617 lastname VARCHAR(25) NOT NULL, 618 username VARCHAR(16) NOT NULL, 619 email VARCHAR(35), 620 joined DATE NOT NULL 621 ) 622 PARTITION BY RANGE( YEAR(joined) ) PARTITIONS 4 ( 623 PARTITION p0 VALUES LESS THAN (1960), 624 PARTITION p1 VALUES LESS THAN (1970), 625 PARTITION p2 VALUES LESS THAN (1980), 626 PARTITION p3 VALUES LESS THAN (1990), 627 PARTITION p4 VALUES LESS THAN MAXVALUE 628 );`, 629 } 630 631 mock := NewMockOptimizer(false) 632 for _, sql := range sqls { 633 _, err := buildSingleStmt(mock, t, sql) 634 t.Log(sql) 635 t.Log(err) 636 if err == nil { 637 t.Fatalf("%+v", err) 638 } 639 } 640 } 641 642 // ---------------------Range Columns Partition-------------------------------- 643 func TestRangeColumnsPartition(t *testing.T) { 644 sqls := []string{ 645 `CREATE TABLE rc ( 646 a INT NOT NULL, 647 b INT NOT NULL 648 ) 649 PARTITION BY RANGE COLUMNS(a,b) ( 650 PARTITION p0 VALUES LESS THAN (10,5), 651 PARTITION p1 VALUES LESS THAN (20,10), 652 PARTITION p2 VALUES LESS THAN (50,20), 653 PARTITION p3 VALUES LESS THAN (65,30) 654 );`, 655 656 `CREATE TABLE rc ( 657 a INT NOT NULL, 658 b INT NOT NULL 659 ) 660 PARTITION BY RANGE COLUMNS(a,b) ( 661 PARTITION p0 VALUES LESS THAN (10,5), 662 PARTITION p1 VALUES LESS THAN (20,10), 663 PARTITION p2 VALUES LESS THAN (50,MAXVALUE), 664 PARTITION p3 VALUES LESS THAN (65,MAXVALUE), 665 PARTITION p4 VALUES LESS THAN (MAXVALUE,MAXVALUE) 666 );`, 667 668 `CREATE TABLE rc ( 669 a INT NOT NULL, 670 b INT NOT NULL 671 ) 672 PARTITION BY RANGE COLUMNS(a,b) ( 673 PARTITION p0 VALUES LESS THAN (10,5) COMMENT = 'Data for LESS THAN (10,5)', 674 PARTITION p1 VALUES LESS THAN (20,10) COMMENT = 'Data for LESS THAN (20,10)', 675 PARTITION p2 VALUES LESS THAN (50,MAXVALUE) COMMENT = 'Data for LESS THAN (50,MAXVALUE)', 676 PARTITION p3 VALUES LESS THAN (65,MAXVALUE) COMMENT = 'Data for LESS THAN (65,MAXVALUE)', 677 PARTITION p4 VALUES LESS THAN (MAXVALUE,MAXVALUE) COMMENT = 'Data for LESS THAN (MAXVALUE,MAXVALUE)' 678 );`, 679 680 `CREATE TABLE rcx ( 681 a INT, 682 b INT, 683 c CHAR(3), 684 d INT 685 ) 686 PARTITION BY RANGE COLUMNS(a,d,c) ( 687 PARTITION p0 VALUES LESS THAN (5,10,'ggg'), 688 PARTITION p1 VALUES LESS THAN (10,20,'mmm'), 689 PARTITION p2 VALUES LESS THAN (15,30,'sss'), 690 PARTITION p3 VALUES LESS THAN (MAXVALUE,MAXVALUE,MAXVALUE) 691 );`, 692 693 `CREATE TABLE t1 ( 694 col1 INT NOT NULL, 695 col2 INT NOT NULL, 696 col3 INT NOT NULL, 697 col4 INT NOT NULL, 698 PRIMARY KEY(col1, col3) 699 ) 700 PARTITION BY RANGE COLUMNS(col1,col3) ( 701 PARTITION p0 VALUES LESS THAN (10,5), 702 PARTITION p1 VALUES LESS THAN (20,10), 703 PARTITION p2 VALUES LESS THAN (50,20), 704 PARTITION p3 VALUES LESS THAN (65,30) 705 );`, 706 707 `CREATE TABLE rc ( 708 a INT NOT NULL, 709 b INT NOT NULL 710 ) 711 PARTITION BY RANGE COLUMNS(a,b) PARTITIONS 4 ( 712 PARTITION p0 VALUES LESS THAN (10,5), 713 PARTITION p1 VALUES LESS THAN (20,10), 714 PARTITION p2 VALUES LESS THAN (50,20), 715 PARTITION p3 VALUES LESS THAN (65,30) 716 );`, 717 } 718 mock := NewMockOptimizer(false) 719 for _, sql := range sqls { 720 t.Log(sql) 721 logicPlan, err := buildSingleStmt(mock, t, sql) 722 if err != nil { 723 t.Fatalf("%+v", err) 724 } 725 outPutPlan(logicPlan, true, t) 726 } 727 } 728 729 func TestRangeColumnsPartitionError(t *testing.T) { 730 sqls := []string{ 731 `CREATE TABLE rc3 ( 732 a INT NOT NULL, 733 b INT NOT NULL 734 ) 735 PARTITION BY RANGE COLUMNS(a,b) ( 736 PARTITION p0 VALUES LESS THAN (a,5), 737 PARTITION p1 VALUES LESS THAN (20,10), 738 PARTITION p2 VALUES LESS THAN (50,20), 739 PARTITION p3 VALUES LESS THAN (65,30) 740 );`, 741 742 `CREATE TABLE rc3 ( 743 a INT NOT NULL, 744 b INT NOT NULL 745 ) 746 PARTITION BY RANGE COLUMNS(a,b) ( 747 PARTITION p0 VALUES LESS THAN (a+7,5), 748 PARTITION p1 VALUES LESS THAN (20,10), 749 PARTITION p2 VALUES LESS THAN (50,20), 750 PARTITION p3 VALUES LESS THAN (65,30) 751 );`, 752 753 `CREATE TABLE t1 ( 754 col1 INT NOT NULL, 755 col2 INT NOT NULL, 756 col3 INT NOT NULL, 757 col4 INT NOT NULL, 758 PRIMARY KEY(col1, col3) 759 ) 760 PARTITION BY RANGE COLUMNS(col1,col2) ( 761 PARTITION p0 VALUES LESS THAN (10,5), 762 PARTITION p1 VALUES LESS THAN (20,10), 763 PARTITION p2 VALUES LESS THAN (50,20), 764 PARTITION p3 VALUES LESS THAN (65,30) 765 );`, 766 767 `CREATE TABLE rc ( 768 a INT NOT NULL, 769 b INT NOT NULL 770 ) 771 PARTITION BY RANGE COLUMNS(a,b) PARTITIONS 5 ( 772 PARTITION p0 VALUES LESS THAN (10,5), 773 PARTITION p1 VALUES LESS THAN (20,10), 774 PARTITION p2 VALUES LESS THAN (50,20), 775 PARTITION p3 VALUES LESS THAN (65,30) 776 );`, 777 778 `CREATE TABLE rc ( 779 a INT NOT NULL, 780 b INT NOT NULL 781 ) 782 PARTITION BY RANGE COLUMNS(a,b) ( 783 PARTITION p0 VALUES LESS THAN (10,5), 784 PARTITION p1 VALUES IN( 1,2 ), 785 PARTITION p2 VALUES LESS THAN (50,20), 786 PARTITION p3 VALUES LESS THAN (65,30) 787 );`, 788 } 789 790 mock := NewMockOptimizer(false) 791 for _, sql := range sqls { 792 _, err := buildSingleStmt(mock, t, sql) 793 t.Log(sql) 794 t.Log(err) 795 if err == nil { 796 t.Fatalf("%+v", err) 797 } 798 } 799 } 800 801 // -----------------------List Partition-------------------------------------- 802 func TestListPartition(t *testing.T) { 803 sqls := []string{ 804 `CREATE TABLE client_firms ( 805 id INT, 806 name VARCHAR(35) 807 ) 808 PARTITION BY LIST (id) ( 809 PARTITION r0 VALUES IN (1, 5, 9, 13, 17, 21), 810 PARTITION r1 VALUES IN (2, 6, 10, 14, 18, 22), 811 PARTITION r2 VALUES IN (3, 7, 11, 15, 19, 23), 812 PARTITION r3 VALUES IN (4, 8, 12, 16, 20, 24) 813 );`, 814 815 `CREATE TABLE employees ( 816 id INT NOT NULL, 817 fname VARCHAR(30), 818 lname VARCHAR(30), 819 hired DATE NOT NULL DEFAULT '1970-01-01', 820 separated DATE NOT NULL DEFAULT '9999-12-31', 821 job_code INT, 822 store_id INT 823 ) 824 PARTITION BY LIST(store_id) ( 825 PARTITION pNorth VALUES IN (3,5,6,9,17), 826 PARTITION pEast VALUES IN (1,2,10,11,19,20), 827 PARTITION pWest VALUES IN (4,12,13,14,18), 828 PARTITION pCentral VALUES IN (7,8,15,16) 829 );`, 830 831 `CREATE TABLE t1 ( 832 id INT PRIMARY KEY, 833 name VARCHAR(35) 834 ) 835 PARTITION BY LIST (id) ( 836 PARTITION r0 VALUES IN (1, 5, 9, 13, 17, 21), 837 PARTITION r1 VALUES IN (2, 6, 10, 14, 18, 22), 838 PARTITION r2 VALUES IN (3, 7, 11, 15, 19, 23), 839 PARTITION r3 VALUES IN (4, 8, 12, 16, 20, 24) 840 );`, 841 842 `CREATE TABLE lc ( 843 a INT NULL, 844 b INT NULL 845 ) 846 PARTITION BY LIST (a) ( 847 PARTITION p0 VALUES IN(0,NULL), 848 PARTITION p1 VALUES IN( 1,2 ), 849 PARTITION p2 VALUES IN( 3,4 ), 850 PARTITION p3 VALUES IN( 5,6 ) 851 );`, 852 } 853 854 mock := NewMockOptimizer(false) 855 for _, sql := range sqls { 856 t.Log(sql) 857 logicPlan, err := buildSingleStmt(mock, t, sql) 858 if err != nil { 859 t.Fatalf("%+v", err) 860 } 861 outPutPlan(logicPlan, true, t) 862 } 863 } 864 865 func TestListPartitionError(t *testing.T) { 866 sqls := []string{ 867 `CREATE TABLE t1 ( 868 id INT, 869 name VARCHAR(35) 870 ) 871 PARTITION BY LIST (id);`, 872 873 `CREATE TABLE t2 ( 874 id INT, 875 name VARCHAR(35) 876 ) 877 PARTITION BY LIST (id) ( 878 PARTITION r0 VALUES IN (1, 5, 9, 13, 17, 21), 879 PARTITION r1 VALUES IN (2, 6, 10, 14, 18, 22), 880 PARTITION r2 VALUES IN (3, 7, 11, 15, 19, 23), 881 PARTITION r2 VALUES IN (4, 8, 12, 16, 20, 24) 882 );`, 883 884 `CREATE TABLE t1 ( 885 id INT PRIMARY KEY, 886 name VARCHAR(35), 887 age INT unsigned 888 ) 889 PARTITION BY LIST (age) ( 890 PARTITION r0 VALUES IN (1, 5, 9, 13, 17, 21), 891 PARTITION r1 VALUES IN (2, 6, 10, 14, 18, 22), 892 PARTITION r2 VALUES IN (3, 7, 11, 15, 19, 23), 893 PARTITION r3 VALUES IN (4, 8, 12, 16, 20, 24) 894 );`, 895 896 `CREATE TABLE lc ( 897 a INT NULL, 898 b INT NULL 899 ) 900 PARTITION BY LIST (a) ( 901 PARTITION p0 VALUES IN(NULL,NULL), 902 PARTITION p1 VALUES IN( 1,2 ), 903 PARTITION p2 VALUES IN( 3,4 ), 904 PARTITION p3 VALUES IN( 5,6 ) 905 );`, 906 907 `CREATE TABLE lc ( 908 a INT NULL, 909 b INT NULL 910 ) 911 PARTITION BY LIST (a) ( 912 PARTITION p0 VALUES IN(NULL,NULL), 913 PARTITION p1 VALUES IN( 1,2 ), 914 PARTITION p2 VALUES IN( 3,1 ), 915 PARTITION p3 VALUES IN( 3,3 ) 916 );`, 917 918 `CREATE TABLE lc ( 919 a INT NULL, 920 b INT NULL 921 ) 922 PARTITION BY LIST (a) ( 923 PARTITION p0 VALUES IN(0,NULL), 924 PARTITION p1 VALUES IN( 1,2 ), 925 PARTITION p2 VALUES IN( 3,4 ), 926 PARTITION p3 VALUES LESS THAN (50,20) 927 );`, 928 929 `create table pt_table_50( 930 col1 tinyint, 931 col2 smallint, 932 col3 int, 933 col4 bigint, 934 col5 tinyint unsigned, 935 col6 smallint unsigned, 936 col7 int unsigned, 937 col8 bigint unsigned, 938 col9 float, 939 col10 double, 940 col11 varchar(255), 941 col12 Date, 942 col13 DateTime, 943 col14 timestamp, 944 col15 bool, 945 col16 decimal(5,2), 946 col17 text, 947 col18 varchar(255), 948 col19 varchar(255), 949 col20 text, 950 primary key(col4,col3,col11) 951 ) partition by list(col3) ( 952 PARTITION r0 VALUES IN (1, 5*2, 9, 13, 17-20, 21), 953 PARTITION r1 VALUES IN (2, 6, 10, 7, 18, 22), 954 PARTITION r2 VALUES IN (3, 7, 11+6, 15, 19, 23), 955 PARTITION r3 VALUES IN (4, 8, 12, 16, 20, 24) 956 );`, 957 958 `create table pt_table_50( 959 col1 tinyint, 960 col2 smallint, 961 col3 int, 962 col4 bigint, 963 col5 tinyint unsigned, 964 col6 smallint unsigned, 965 col7 int unsigned, 966 col8 bigint unsigned, 967 col9 float, 968 col10 double, 969 col11 varchar(255), 970 col12 Date, 971 col13 DateTime, 972 col14 timestamp, 973 col15 bool, 974 col16 decimal(5,2), 975 col17 text, 976 col18 varchar(255), 977 col19 varchar(255), 978 col20 text, 979 primary key(col4,col3,col11) 980 ) partition by list(col3) ( 981 PARTITION r0 VALUES IN (1, 5*2, 9, 13, 17-20, 21), 982 PARTITION r1 VALUES IN (2, 6, 10, 14/2, 18, 22), 983 PARTITION r2 VALUES IN (3, 7, 11+6, 15, 19, 23), 984 PARTITION r3 VALUES IN (4, 8, 12, 16, 20, 24) 985 );`, 986 } 987 988 mock := NewMockOptimizer(false) 989 for _, sql := range sqls { 990 _, err := buildSingleStmt(mock, t, sql) 991 t.Log(sql) 992 t.Log(err) 993 if err == nil { 994 t.Fatalf("%+v", err) 995 } 996 } 997 } 998 999 // -----------------------List Columns Partition-------------------------------------- 1000 func TestListColumnsPartition(t *testing.T) { 1001 sqls := []string{ 1002 `CREATE TABLE lc ( 1003 a INT NULL, 1004 b INT NULL 1005 ) 1006 PARTITION BY LIST COLUMNS(a,b) ( 1007 PARTITION p0 VALUES IN( (0,0), (NULL,NULL) ), 1008 PARTITION p1 VALUES IN( (0,1), (0,2), (0,3), (1,1), (1,2) ), 1009 PARTITION p2 VALUES IN( (1,0), (2,0), (2,1), (3,0), (3,1) ), 1010 PARTITION p3 VALUES IN( (1,3), (2,2), (2,3), (3,2), (3,3) ) 1011 );`, 1012 1013 `CREATE TABLE customers_1 ( 1014 first_name VARCHAR(25), 1015 last_name VARCHAR(25), 1016 street_1 VARCHAR(30), 1017 street_2 VARCHAR(30), 1018 city VARCHAR(15), 1019 renewal DATE 1020 ) 1021 PARTITION BY LIST COLUMNS(city) ( 1022 PARTITION pRegion_1 VALUES IN('Oskarshamn', 'Högsby', 'Mönsterås'), 1023 PARTITION pRegion_2 VALUES IN('Vimmerby', 'Hultsfred', 'Västervik'), 1024 PARTITION pRegion_3 VALUES IN('Nässjö', 'Eksjö', 'Vetlanda'), 1025 PARTITION pRegion_4 VALUES IN('Uppvidinge', 'Alvesta', 'Växjo') 1026 );`, 1027 1028 `CREATE TABLE customers_2 ( 1029 first_name VARCHAR(25), 1030 last_name VARCHAR(25), 1031 street_1 VARCHAR(30), 1032 street_2 VARCHAR(30), 1033 city VARCHAR(15), 1034 renewal DATE 1035 ) 1036 PARTITION BY LIST COLUMNS(renewal) ( 1037 PARTITION pWeek_1 VALUES IN('2010-02-01', '2010-02-02', '2010-02-03', 1038 '2010-02-04', '2010-02-05', '2010-02-06', '2010-02-07'), 1039 PARTITION pWeek_2 VALUES IN('2010-02-08', '2010-02-09', '2010-02-10', 1040 '2010-02-11', '2010-02-12', '2010-02-13', '2010-02-14'), 1041 PARTITION pWeek_3 VALUES IN('2010-02-15', '2010-02-16', '2010-02-17', 1042 '2010-02-18', '2010-02-19', '2010-02-20', '2010-02-21'), 1043 PARTITION pWeek_4 VALUES IN('2010-02-22', '2010-02-23', '2010-02-24', 1044 '2010-02-25', '2010-02-26', '2010-02-27', '2010-02-28') 1045 );`, 1046 1047 `CREATE TABLE lc ( 1048 a INT NULL, 1049 b INT NULL 1050 ) 1051 PARTITION BY LIST COLUMNS(a,b) PARTITIONS 4 ( 1052 PARTITION p0 VALUES IN( (0,0), (NULL,NULL) ), 1053 PARTITION p1 VALUES IN( (0,1), (0,2), (0,3), (1,1), (1,2) ), 1054 PARTITION p2 VALUES IN( (1,0), (2,0), (2,1), (3,0), (3,1) ), 1055 PARTITION p3 VALUES IN( (1,3), (2,2), (2,3), (3,2), (3,3) ) 1056 );`, 1057 1058 `CREATE TABLE lc ( 1059 a INT NULL, 1060 b INT NULL 1061 ) 1062 PARTITION BY LIST COLUMNS(a,b) ( 1063 PARTITION p0 VALUES IN( (0,0), (NULL,NULL) ), 1064 PARTITION p1 VALUES IN( (0,1), (0,2) ), 1065 PARTITION p2 VALUES IN( (1,0), (2,0) ) 1066 );`, 1067 } 1068 1069 mock := NewMockOptimizer(false) 1070 for _, sql := range sqls { 1071 t.Log(sql) 1072 logicPlan, err := buildSingleStmt(mock, t, sql) 1073 if err != nil { 1074 t.Fatalf("%+v", err) 1075 } 1076 outPutPlan(logicPlan, true, t) 1077 } 1078 } 1079 1080 func TestListColumnsPartitionError(t *testing.T) { 1081 sqls := []string{ 1082 `CREATE TABLE t1 ( 1083 a INT NULL, 1084 b INT NULL 1085 ) 1086 PARTITION BY LIST COLUMNS(a,b);`, 1087 1088 `CREATE TABLE t2 ( 1089 a INT NULL, 1090 b INT NULL 1091 ) 1092 PARTITION BY LIST COLUMNS(a,b) ( 1093 PARTITION p0 VALUES IN( (0,0), (NULL,NULL) ), 1094 PARTITION p1 VALUES IN( (0,1), (0,2), (0,3), (1,1), (1,2) ), 1095 PARTITION p2 VALUES IN( (1,0), (2,0), (2,1), (3,0), (3,1) ), 1096 PARTITION p2 VALUES IN( (1,3), (2,2), (2,3), (3,2), (3,3) ) 1097 );`, 1098 1099 `CREATE TABLE lc ( 1100 a INT NULL, 1101 b INT NULL 1102 ) 1103 PARTITION BY LIST COLUMNS(a,b) PARTITIONS 5 ( 1104 PARTITION p0 VALUES IN( (0,0), (NULL,NULL) ), 1105 PARTITION p1 VALUES IN( (0,1), (0,2), (0,3), (1,1), (1,2) ), 1106 PARTITION p2 VALUES IN( (1,0), (2,0), (2,1), (3,0), (3,1) ), 1107 PARTITION p3 VALUES IN( (1,3), (2,2), (2,3), (3,2), (3,3) ) 1108 );`, 1109 } 1110 1111 mock := NewMockOptimizer(false) 1112 for _, sql := range sqls { 1113 _, err := buildSingleStmt(mock, t, sql) 1114 t.Log(sql) 1115 t.Log(err) 1116 if err == nil { 1117 t.Fatalf("%+v", err) 1118 } 1119 } 1120 } 1121 1122 func TestPartitioningKeysUniqueKeys(t *testing.T) { 1123 sqls := []string{ 1124 `CREATE TABLE t1 ( 1125 col1 INT NOT NULL, 1126 col2 DATE NOT NULL, 1127 col3 INT NOT NULL, 1128 col4 INT NOT NULL, 1129 UNIQUE KEY (col1, col2) 1130 ) 1131 PARTITION BY KEY() 1132 PARTITIONS 4;`, 1133 1134 `CREATE TABLE t1 ( 1135 col1 INT NOT NULL, 1136 col2 DATE NOT NULL, 1137 col3 INT NOT NULL, 1138 col4 INT NOT NULL, 1139 UNIQUE KEY (col1, col2, col3) 1140 ) 1141 PARTITION BY HASH(col3) 1142 PARTITIONS 4;`, 1143 1144 `CREATE TABLE t2 ( 1145 col1 INT NOT NULL, 1146 col2 DATE NOT NULL, 1147 col3 INT NOT NULL, 1148 col4 INT NOT NULL, 1149 UNIQUE KEY (col1, col3) 1150 ) 1151 PARTITION BY HASH(col1 + col3) 1152 PARTITIONS 4;`, 1153 1154 `CREATE TABLE t1 ( 1155 col1 INT NOT NULL, 1156 col2 DATE NOT NULL, 1157 col3 INT NOT NULL, 1158 col4 INT NOT NULL, 1159 UNIQUE KEY (col1, col2, col3) 1160 ) 1161 PARTITION BY KEY(col3) 1162 PARTITIONS 4;`, 1163 1164 `CREATE TABLE t2 ( 1165 col1 INT NOT NULL, 1166 col2 DATE NOT NULL, 1167 col3 INT NOT NULL, 1168 col4 INT NOT NULL, 1169 UNIQUE KEY (col1, col3) 1170 ) 1171 PARTITION BY KEY(col1,col3) 1172 PARTITIONS 4;`, 1173 1174 `CREATE TABLE t3 ( 1175 col1 INT NOT NULL, 1176 col2 DATE NOT NULL, 1177 col3 INT NOT NULL, 1178 col4 INT NOT NULL, 1179 UNIQUE KEY (col1, col2, col3), 1180 UNIQUE KEY (col3) 1181 ) 1182 PARTITION BY HASH(col3) 1183 PARTITIONS 4;`, 1184 1185 `CREATE TABLE t3 ( 1186 col1 INT NOT NULL, 1187 col2 DATE NOT NULL, 1188 col3 INT NOT NULL, 1189 col4 INT NOT NULL, 1190 UNIQUE KEY (col1, col2, col3), 1191 UNIQUE KEY (col3) 1192 ) 1193 PARTITION BY KEY(col3) 1194 PARTITIONS 4;`, 1195 1196 `CREATE TABLE t4 ( 1197 col1 INT NOT NULL, 1198 col2 DATE NOT NULL, 1199 col3 INT NOT NULL UNIQUE, 1200 col4 INT NOT NULL 1201 ) 1202 PARTITION BY KEY(col3) 1203 PARTITIONS 4;`, 1204 } 1205 1206 mock := NewMockOptimizer(false) 1207 for _, sql := range sqls { 1208 t.Log(sql) 1209 logicPlan, err := buildSingleStmt(mock, t, sql) 1210 if err != nil { 1211 t.Fatalf("%+v", err) 1212 } 1213 outPutPlan(logicPlan, true, t) 1214 } 1215 } 1216 1217 func TestPartitioningKeysUniqueKeysError(t *testing.T) { 1218 sqls := []string{ 1219 `CREATE TABLE t1 ( 1220 col1 INT NOT NULL, 1221 col2 DATE NOT NULL, 1222 col3 INT NOT NULL, 1223 col4 INT NOT NULL, 1224 UNIQUE KEY (col1, col2) 1225 ) 1226 PARTITION BY HASH(col3) 1227 PARTITIONS 4;`, 1228 1229 `CREATE TABLE t2 ( 1230 col1 INT NOT NULL, 1231 col2 DATE NOT NULL, 1232 col3 INT NOT NULL, 1233 col4 INT NOT NULL, 1234 UNIQUE KEY (col1), 1235 UNIQUE KEY (col3) 1236 ) 1237 PARTITION BY HASH(col1 + col3) 1238 PARTITIONS 4;`, 1239 1240 `CREATE TABLE t1 ( 1241 col1 INT UNIQUE NOT NULL, 1242 col2 DATE NOT NULL, 1243 col3 INT NOT NULL, 1244 col4 INT NOT NULL 1245 ) 1246 PARTITION BY HASH(col3) 1247 PARTITIONS 4;`, 1248 1249 `CREATE TABLE t2 ( 1250 col1 INT NOT NULL, 1251 col2 DATE NOT NULL, 1252 col3 INT NOT NULL, 1253 col4 INT NOT NULL, 1254 UNIQUE KEY (col1), 1255 UNIQUE KEY (col3) 1256 ) 1257 PARTITION BY KEY(col1,col3) 1258 PARTITIONS 4;`, 1259 1260 `CREATE TABLE t3 ( 1261 col1 INT NOT NULL, 1262 col2 DATE NOT NULL, 1263 col3 INT NOT NULL, 1264 col4 INT NOT NULL, 1265 UNIQUE KEY (col1, col2), 1266 UNIQUE KEY (col3) 1267 ) 1268 PARTITION BY HASH(col1 + col3) 1269 PARTITIONS 4;`, 1270 1271 `CREATE TABLE t3 ( 1272 col1 INT NOT NULL, 1273 col2 DATE NOT NULL, 1274 col3 INT NOT NULL, 1275 col4 INT NOT NULL, 1276 UNIQUE KEY (col1, col2), 1277 UNIQUE KEY (col3) 1278 ) 1279 PARTITION BY KEY(col1, col3) 1280 PARTITIONS 4;`, 1281 // should show error:Field in list of fields for partition function not found in table 1282 `CREATE TABLE k1 ( 1283 id INT NOT NULL, 1284 name VARCHAR(20), 1285 sal DOUBLE 1286 ) 1287 PARTITION BY KEY() 1288 PARTITIONS 2;`, 1289 1290 `CREATE TABLE t6 ( 1291 col1 INT NOT NULL, 1292 col2 DATE NOT NULL, 1293 col3 INT NOT NULL UNIQUE, 1294 col4 INT NOT NULL 1295 ) 1296 PARTITION BY KEY(col1) 1297 PARTITIONS 4;`, 1298 1299 `CREATE TABLE t7 ( 1300 col1 INT NOT NULL, 1301 col2 DATE NOT NULL, 1302 col3 INT NOT NULL UNIQUE, 1303 col4 INT NOT NULL 1304 ) 1305 PARTITION BY HASH(col4) 1306 PARTITIONS 4;`, 1307 } 1308 1309 mock := NewMockOptimizer(false) 1310 for _, sql := range sqls { 1311 _, err := buildSingleStmt(mock, t, sql) 1312 t.Log(sql) 1313 t.Log(err) 1314 if err == nil { 1315 t.Fatalf("%+v", err) 1316 } 1317 } 1318 } 1319 1320 func TestPartitioningKeysPrimaryKeys(t *testing.T) { 1321 sqls := []string{ 1322 `CREATE TABLE t7 ( 1323 col1 INT NOT NULL, 1324 col2 DATE NOT NULL, 1325 col3 INT NOT NULL, 1326 col4 INT NOT NULL, 1327 PRIMARY KEY(col1, col2) 1328 ) 1329 PARTITION BY HASH(col1 + YEAR(col2)) 1330 PARTITIONS 4;`, 1331 1332 `CREATE TABLE t8 ( 1333 col1 INT NOT NULL, 1334 col2 DATE NOT NULL, 1335 col3 INT NOT NULL, 1336 col4 INT NOT NULL, 1337 PRIMARY KEY(col1, col2, col4), 1338 UNIQUE KEY(col2, col1) 1339 ) 1340 PARTITION BY HASH(col1 + YEAR(col2)) 1341 PARTITIONS 4;`, 1342 1343 `CREATE TABLE t7 ( 1344 col1 INT NOT NULL, 1345 col2 DATE NOT NULL, 1346 col3 INT NOT NULL, 1347 col4 INT NOT NULL, 1348 PRIMARY KEY(col1, col2) 1349 ) 1350 PARTITION BY KEY(col1,col2) 1351 PARTITIONS 4;`, 1352 1353 `CREATE TABLE t8 ( 1354 col1 INT NOT NULL, 1355 col2 DATE NOT NULL, 1356 col3 INT NOT NULL, 1357 col4 INT NOT NULL, 1358 PRIMARY KEY(col1, col2, col4), 1359 UNIQUE KEY(col2, col1) 1360 ) 1361 PARTITION BY KEY(col1,col2) 1362 PARTITIONS 4;`, 1363 1364 `CREATE TABLE k1 ( 1365 id INT NOT NULL, 1366 name VARCHAR(20), 1367 sal DOUBLE, 1368 PRIMARY KEY (id, name), 1369 unique key (id) 1370 ) 1371 PARTITION BY KEY(id) 1372 PARTITIONS 2;`, 1373 } 1374 1375 mock := NewMockOptimizer(false) 1376 for _, sql := range sqls { 1377 t.Log(sql) 1378 logicPlan, err := buildSingleStmt(mock, t, sql) 1379 if err != nil { 1380 t.Fatalf("%+v", err) 1381 } 1382 outPutPlan(logicPlan, true, t) 1383 } 1384 } 1385 1386 func TestPartitioningKeysPrimaryKeysError(t *testing.T) { 1387 sqls := []string{ 1388 `CREATE TABLE t5 ( 1389 col1 INT NOT NULL, 1390 col2 DATE NOT NULL, 1391 col3 INT NOT NULL, 1392 col4 INT NOT NULL, 1393 PRIMARY KEY(col1, col2) 1394 ) 1395 PARTITION BY HASH(col3) 1396 PARTITIONS 4;`, 1397 1398 `CREATE TABLE t6 ( 1399 col1 INT NOT NULL, 1400 col2 DATE NOT NULL, 1401 col3 INT NOT NULL, 1402 col4 INT NOT NULL, 1403 PRIMARY KEY(col1, col3), 1404 UNIQUE KEY(col2) 1405 ) 1406 PARTITION BY HASH( YEAR(col2) ) 1407 PARTITIONS 4;`, 1408 1409 `CREATE TABLE t5 ( 1410 col1 INT NOT NULL, 1411 col2 DATE NOT NULL, 1412 col3 INT NOT NULL, 1413 col4 INT NOT NULL, 1414 PRIMARY KEY(col1, col2) 1415 ) 1416 PARTITION BY KEY(col3) 1417 PARTITIONS 4;`, 1418 1419 `CREATE TABLE t6 ( 1420 col1 INT NOT NULL, 1421 col2 DATE NOT NULL, 1422 col3 INT NOT NULL, 1423 col4 INT NOT NULL, 1424 PRIMARY KEY(col1, col3), 1425 UNIQUE KEY(col2) 1426 ) 1427 PARTITION BY KEY(col2) 1428 PARTITIONS 4;`, 1429 } 1430 1431 mock := NewMockOptimizer(false) 1432 for _, sql := range sqls { 1433 _, err := buildSingleStmt(mock, t, sql) 1434 t.Log(sql) 1435 t.Log(err) 1436 if err == nil { 1437 t.Fatalf("%+v", err) 1438 } 1439 } 1440 } 1441 1442 // A UNIQUE INDEX must include all columns in the table's partitioning function 1443 func TestPartitionKeysShouldShowError(t *testing.T) { 1444 sqls := []string{ 1445 `CREATE TABLE t4 ( 1446 col1 INT NOT NULL, 1447 col2 INT NOT NULL, 1448 col3 INT NOT NULL, 1449 col4 INT NOT NULL, 1450 UNIQUE KEY (col1, col3), 1451 UNIQUE KEY (col2, col4) 1452 ) 1453 PARTITION BY KEY(col1, col3) 1454 PARTITIONS 2;`, 1455 1456 `CREATE TABLE t4 ( 1457 col1 INT NOT NULL, 1458 col2 INT NOT NULL, 1459 col3 INT NOT NULL, 1460 col4 INT NOT NULL, 1461 UNIQUE KEY (col1, col3), 1462 UNIQUE KEY (col2, col4) 1463 ) 1464 PARTITION BY HASH(col1 + col3) 1465 PARTITIONS 2;`, 1466 1467 `CREATE TABLE t4 ( 1468 col1 INT NOT NULL, 1469 col2 INT NOT NULL, 1470 col3 INT NOT NULL, 1471 col4 INT NOT NULL, 1472 UNIQUE KEY (col1, col3), 1473 UNIQUE KEY (col2, col4) 1474 ) 1475 PARTITION BY RANGE (col1 + col3) ( 1476 PARTITION p0 VALUES LESS THAN (6), 1477 PARTITION p1 VALUES LESS THAN (11), 1478 PARTITION p2 VALUES LESS THAN (16), 1479 PARTITION p3 VALUES LESS THAN (21) 1480 );`, 1481 1482 `CREATE TABLE t4 ( 1483 col1 INT NOT NULL, 1484 col2 INT NOT NULL, 1485 col3 INT NOT NULL, 1486 col4 INT NOT NULL, 1487 UNIQUE KEY (col1, col3), 1488 UNIQUE KEY (col2, col4) 1489 ) 1490 PARTITION BY RANGE COLUMNS(col1, col3) PARTITIONS 4 ( 1491 PARTITION p0 VALUES LESS THAN (10,5), 1492 PARTITION p1 VALUES LESS THAN (20,10), 1493 PARTITION p2 VALUES LESS THAN (50,20), 1494 PARTITION p3 VALUES LESS THAN (65,30) 1495 );`, 1496 1497 `CREATE TABLE t4 ( 1498 col1 INT NOT NULL, 1499 col2 INT NOT NULL, 1500 col3 INT NOT NULL, 1501 col4 INT NOT NULL, 1502 UNIQUE KEY (col1), 1503 UNIQUE KEY (col2, col4) 1504 ) 1505 PARTITION BY LIST (col1) ( 1506 PARTITION r0 VALUES IN (1, 5, 9, 13, 17, 21), 1507 PARTITION r1 VALUES IN (2, 6, 10, 14, 18, 22), 1508 PARTITION r2 VALUES IN (3, 7, 11, 15, 19, 23), 1509 PARTITION r3 VALUES IN (4, 8, 12, 16, 20, 24) 1510 );`, 1511 1512 `CREATE TABLE t4 ( 1513 col1 INT NOT NULL, 1514 col2 INT NOT NULL, 1515 col3 INT NOT NULL, 1516 col4 INT NOT NULL, 1517 UNIQUE KEY (col1, col3), 1518 UNIQUE KEY (col2, col4) 1519 ) 1520 PARTITION BY LIST COLUMNS(col1, col3) ( 1521 PARTITION p0 VALUES IN( (0,0), (NULL,NULL) ), 1522 PARTITION p1 VALUES IN( (0,1), (0,2), (0,3), (1,1), (1,2) ), 1523 PARTITION p2 VALUES IN( (1,0), (2,0), (2,1), (3,0), (3,1) ), 1524 PARTITION p3 VALUES IN( (1,3), (2,2), (2,3), (3,2), (3,3) ) 1525 );`, 1526 } 1527 mock := NewMockOptimizer(false) 1528 for _, sql := range sqls { 1529 _, err := buildSingleStmt(mock, t, sql) 1530 t.Log(sql) 1531 t.Log(err) 1532 if err == nil { 1533 t.Fatalf("%+v", err) 1534 } 1535 } 1536 } 1537 1538 func TestListPartitionFunction(t *testing.T) { 1539 sqls := []string{ 1540 `CREATE TABLE lc ( 1541 a INT NULL, 1542 b INT NULL 1543 ) 1544 PARTITION BY LIST COLUMNS(a,b) ( 1545 PARTITION p0 VALUES IN( (0,0), (NULL,NULL) ), 1546 PARTITION p1 VALUES IN( (0,1), (0,4+2) ), 1547 PARTITION p2 VALUES IN( (1,0), (2,0) ) 1548 );`, 1549 1550 `CREATE TABLE lc ( 1551 a INT NULL, 1552 b INT NULL 1553 ) 1554 PARTITION BY LIST(a) ( 1555 PARTITION p0 VALUES IN(0, NULL ), 1556 PARTITION p1 VALUES IN(1, 2), 1557 PARTITION p2 VALUES IN(3, 4) 1558 );`, 1559 1560 `CREATE TABLE lc ( 1561 a INT NULL, 1562 b INT NULL 1563 ) 1564 PARTITION BY LIST COLUMNS(b) ( 1565 PARTITION p0 VALUES IN( 0,NULL ), 1566 PARTITION p1 VALUES IN( 1,2 ), 1567 PARTITION p2 VALUES IN( 3,4 ) 1568 );`, 1569 1570 `CREATE TABLE lc ( 1571 a INT NULL, 1572 b INT NULL 1573 ) 1574 PARTITION BY LIST COLUMNS(b) ( 1575 PARTITION p0 VALUES IN( 0,NULL ), 1576 PARTITION p1 VALUES IN( 1,1+1 ), 1577 PARTITION p2 VALUES IN( 3,4 ) 1578 );`, 1579 } 1580 1581 mock := NewMockOptimizer(false) 1582 for _, sql := range sqls { 1583 t.Log(sql) 1584 logicPlan, err := buildSingleStmt(mock, t, sql) 1585 if err != nil { 1586 t.Fatalf("%+v", err) 1587 } 1588 outPutPlan(logicPlan, true, t) 1589 } 1590 } 1591 1592 func TestListPartitionFunctionError(t *testing.T) { 1593 sqls := []string{ 1594 `create table pt_table_45( 1595 col1 tinyint, 1596 col2 smallint, 1597 col3 int, 1598 col4 bigint, 1599 col5 tinyint unsigned, 1600 col6 smallint unsigned, 1601 col7 int unsigned, 1602 col8 bigint unsigned, 1603 col9 float, 1604 col10 double, 1605 col11 varchar(255), 1606 col12 Date, 1607 col13 DateTime, 1608 col14 timestamp, 1609 col15 bool, 1610 col16 decimal(5,2), 1611 col17 text, 1612 col18 varchar(255), 1613 col19 varchar(255), 1614 col20 text, 1615 primary key(col4,col3,col11)) 1616 partition by list(col3) ( 1617 PARTITION r0 VALUES IN (1, 5*2, 9, 13, 17-20, 21), 1618 PARTITION r1 VALUES IN (2, 6, 10, 14/2, 18, 22), 1619 PARTITION r2 VALUES IN (3, 7, 11+6, 15, 19, 23), 1620 PARTITION r3 VALUES IN (4, 8, 12, 16, 20, 24) 1621 );`, 1622 1623 `CREATE TABLE lc ( 1624 a INT NULL, 1625 b INT NULL 1626 ) 1627 PARTITION BY LIST COLUMNS(a,b) ( 1628 PARTITION p0 VALUES IN( (0,0), (NULL,NULL) ), 1629 PARTITION p1 VALUES IN( (0,1), (0,4/2) ), 1630 PARTITION p2 VALUES IN( (1,0), (2,0) ) 1631 );`, 1632 1633 `CREATE TABLE lc ( 1634 a INT NULL, 1635 b INT NULL 1636 ) 1637 PARTITION BY LIST COLUMNS(a,b) ( 1638 PARTITION p0 VALUES IN( (0,0), (NULL,NULL) ), 1639 PARTITION p1 VALUES IN( (0,1), (0,4.2) ), 1640 PARTITION p2 VALUES IN( (1,0), (2,0) ) 1641 );`, 1642 1643 `CREATE TABLE lc ( 1644 a INT NULL, 1645 b INT NULL 1646 ) 1647 PARTITION BY LIST COLUMNS(a,b) ( 1648 PARTITION p0 VALUES IN( 0,NULL ), 1649 PARTITION p1 VALUES IN( 0,1 ), 1650 PARTITION p2 VALUES IN( 1,0 ) 1651 );`, 1652 1653 `CREATE TABLE lc ( 1654 a INT NULL, 1655 b INT NULL 1656 ) 1657 PARTITION BY LIST(a) ( 1658 PARTITION p0 VALUES IN(0, NULL ), 1659 PARTITION p1 VALUES IN(1, 4/2), 1660 PARTITION p2 VALUES IN(3, 4) 1661 );`, 1662 1663 `CREATE TABLE lc ( 1664 a INT NULL, 1665 b INT NULL 1666 ) 1667 PARTITION BY LIST COLUMNS(b) ( 1668 PARTITION p0 VALUES IN( 0,NULL ), 1669 PARTITION p1 VALUES IN( 1,4/2 ), 1670 PARTITION p2 VALUES IN( 3,4 ) 1671 );`, 1672 1673 `CREATE TABLE lc ( 1674 a INT NULL, 1675 b INT NULL 1676 ) 1677 PARTITION BY LIST COLUMNS(a,b) ( 1678 PARTITION p0 VALUES IN( (0,0), (NULL,NULL) ), 1679 PARTITION p1 VALUES IN( (0,1,3), (0,4,5) ), 1680 PARTITION p2 VALUES IN( (1,0), (2,0) ) 1681 );`, 1682 } 1683 1684 mock := NewMockOptimizer(false) 1685 for _, sql := range sqls { 1686 _, err := buildSingleStmt(mock, t, sql) 1687 t.Log(sql) 1688 t.Log(err) 1689 if err == nil { 1690 t.Fatalf("%+v", err) 1691 } 1692 } 1693 } 1694 1695 func TestRangePartitionFunctionError(t *testing.T) { 1696 sqls := []string{ 1697 `CREATE TABLE r1 ( 1698 a INT, 1699 b INT 1700 ) 1701 PARTITION BY RANGE (a) ( 1702 PARTITION p0 VALUES LESS THAN (5/2), 1703 PARTITION p1 VALUES LESS THAN (MAXVALUE) 1704 );`, 1705 1706 `CREATE TABLE r1 ( 1707 a INT, 1708 b INT 1709 ) 1710 PARTITION BY RANGE (a) ( 1711 PARTITION p0 VALUES LESS THAN (5.2), 1712 PARTITION p1 VALUES LESS THAN (12) 1713 );`, 1714 1715 `CREATE TABLE r1 ( 1716 a INT, 1717 b FLOAT 1718 ) 1719 PARTITION BY RANGE (b) ( 1720 PARTITION p0 VALUES LESS THAN (12), 1721 PARTITION p1 VALUES LESS THAN (MAXVALUE) 1722 );`, 1723 //`create TABLE t1 ( 1724 // col1 int, 1725 // col2 float 1726 //) 1727 //partition by range( case when col1 > 0 then 10 else 20 end ) ( 1728 // partition p0 values less than (2), 1729 // partition p1 values less than (6) 1730 //);`, 1731 } 1732 mock := NewMockOptimizer(false) 1733 for _, sql := range sqls { 1734 _, err := buildSingleStmt(mock, t, sql) 1735 t.Log(sql) 1736 t.Log(err) 1737 if err == nil { 1738 t.Fatalf("%+v", err) 1739 } 1740 } 1741 } 1742 1743 func buildSingleStmt(opt Optimizer, t *testing.T, sql string) (*Plan, error) { 1744 statements, err := mysql.Parse(opt.CurrentContext().GetContext(), sql) 1745 if err != nil { 1746 return nil, err 1747 } 1748 // this sql always return single statement 1749 context := opt.CurrentContext() 1750 plan, err := BuildPlan(context, statements[0]) 1751 if plan != nil { 1752 testDeepCopy(plan) 1753 } 1754 return plan, err 1755 }