github.com/XiaoMi/Gaea@v1.2.5/proxy/plan/plan_insert_test.go (about) 1 // Copyright 2019 The Gaea Authors. All Rights Reserved. 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 "testing" 18 19 func TestMycatShardSimpleInsert(t *testing.T) { 20 ns, err := preparePlanInfo() 21 if err != nil { 22 t.Fatalf("prepare namespace error: %v", err) 23 } 24 25 tests := []SQLTestcase{ 26 { 27 db: "db_mycat", 28 sql: "insert into tbl_mycat (id, a) values (0, 'hi')", 29 sqls: map[string]map[string][]string{ 30 "slice-0": { 31 "db_mycat_0": {"INSERT INTO `tbl_mycat` (`id`,`a`) VALUES (0,'hi')"}, 32 }, 33 }, 34 }, 35 { 36 db: "db_mycat", 37 sql: "insert into tbl_mycat (id, a) values (1, 'hi')", 38 sqls: map[string]map[string][]string{ 39 "slice-0": { 40 "db_mycat_1": {"INSERT INTO `tbl_mycat` (`id`,`a`) VALUES (1,'hi')"}, 41 }, 42 }, 43 }, 44 { 45 db: "db_mycat", 46 sql: "insert into tbl_mycat (id, a) values (2, 'hi')", 47 sqls: map[string]map[string][]string{ 48 "slice-1": { 49 "db_mycat_2": {"INSERT INTO `tbl_mycat` (`id`,`a`) VALUES (2,'hi')"}, 50 }, 51 }, 52 }, 53 { 54 db: "db_mycat", 55 sql: "insert into tbl_mycat (id, a) values (3, 'hi')", 56 sqls: map[string]map[string][]string{ 57 "slice-1": { 58 "db_mycat_3": {"INSERT INTO `tbl_mycat` (`id`,`a`) VALUES (3,'hi')"}, 59 }, 60 }, 61 }, 62 { 63 db: "db_mycat", 64 sql: "insert into tbl_mycat (id, a) values (4, 'hi')", 65 sqls: map[string]map[string][]string{ 66 "slice-0": { 67 "db_mycat_0": {"INSERT INTO `tbl_mycat` (`id`,`a`) VALUES (4,'hi')"}, 68 }, 69 }, 70 }, 71 { 72 db: "db_mycat", 73 sql: "insert into tbl_mycat (id, a) values (6, 'hi')", 74 sqls: map[string]map[string][]string{ 75 "slice-1": { 76 "db_mycat_2": {"INSERT INTO `tbl_mycat` (`id`,`a`) VALUES (6,'hi')"}, 77 }, 78 }, 79 }, 80 { 81 db: "db_mycat", 82 sql: "insert into tbl_mycat (tbl_mycat.id, tbl_mycat.a) values (6, 'hi')", // table name is removed in columns 83 sqls: map[string]map[string][]string{ 84 "slice-1": { 85 "db_mycat_2": {"INSERT INTO `tbl_mycat` (`id`,`a`) VALUES (6,'hi')"}, 86 }, 87 }, 88 }, 89 { 90 db: "db_mycat", 91 sql: "insert into db_mycat.tbl_mycat (db_mycat.tbl_mycat.id, db_mycat.tbl_mycat.a) values (6, 'hi')", // db name is removed in columns, but rewritten in table 92 sqls: map[string]map[string][]string{ 93 "slice-1": { 94 "db_mycat_2": {"INSERT INTO `db_mycat_2`.`tbl_mycat` (`id`,`a`) VALUES (6,'hi')"}, 95 }, 96 }, 97 }, 98 { 99 db: "db_mycat", 100 sql: "insert into tbl_mycat (id,id,a) values (6,6,'hi')", 101 sqls: map[string]map[string][]string{ 102 "slice-1": { 103 "db_mycat_2": {"INSERT INTO `tbl_mycat` (`id`,`id`,`a`) VALUES (6,6,'hi')"}, // invalid syntax, but gaea does not handle 104 }, 105 }, 106 }, 107 { 108 db: "db_mycat", 109 sql: "insert into tbl_mycat (a) values ('hi')", 110 hasErr: true, // sharding column not found 111 }, 112 { 113 db: "db_mycat", 114 sql: "insert into tbl_mycat (id, a) values (6, 'hi') on duplicate key update a = 'hello'", 115 sqls: map[string]map[string][]string{ 116 "slice-1": { 117 "db_mycat_2": {"INSERT INTO `tbl_mycat` (`id`,`a`) VALUES (6,'hi') ON DUPLICATE KEY UPDATE `a`='hello'"}, 118 }, 119 }, 120 }, 121 { 122 db: "db_mycat", 123 sql: "insert into tbl_mycat (id, a) values (6, 'hi') on duplicate key update a = 'hello'+'hi'", 124 sqls: map[string]map[string][]string{ 125 "slice-1": { 126 "db_mycat_2": {"INSERT INTO `tbl_mycat` (`id`,`a`) VALUES (6,'hi') ON DUPLICATE KEY UPDATE `a`='hello'+'hi'"}, 127 }, 128 }, 129 }, 130 { 131 db: "db_mycat", 132 sql: "insert into tbl_mycat (id, a) values (6, 'hi') on duplicate key update a = left('hello',3)", 133 sqls: map[string]map[string][]string{ 134 "slice-1": { 135 "db_mycat_2": {"INSERT INTO `tbl_mycat` (`id`,`a`) VALUES (6,'hi') ON DUPLICATE KEY UPDATE `a`=LEFT('hello', 3)"}, 136 }, 137 }, 138 }, 139 { 140 db: "db_mycat", 141 sql: "insert into tbl_mycat (id, a) values (6, 'hi') on duplicate key update id = 5", 142 hasErr: true, // routing key in update expression 143 }, 144 { 145 db: "db_mycat", 146 sql: "insert into tbl_mycat (id, a) values (6, 'hi') on duplicate key update id = id+3", 147 hasErr: true, // routing key in update expression 148 }, 149 { 150 db: "db_mycat", 151 sql: "insert into tbl_mycat select * from tbl_mycat_child", 152 hasErr: true, // select in insert not allowed 153 }, 154 { 155 db: "db_mycat", 156 sql: "insert into tbl_mycat () values ()", 157 hasErr: true, // insert or replace must specify columns 158 }, 159 { 160 db: "db_mycat", 161 sql: "insert into tbl_mycat values (6, 'hi')", 162 hasErr: true, // insert or replace must specify columns 163 }, 164 { 165 db: "db_mycat", 166 sql: "insert into tbl_mycat (id) values (6, 'hi')", 167 hasErr: true, // column count doesn't match value count 168 }, 169 { 170 db: "db_mycat", 171 sql: "insert into tbl_mycat (id, a) values (6)", 172 hasErr: true, // column count doesn't match value count 173 }, 174 } 175 for _, test := range tests { 176 t.Run(test.sql, getTestFunc(ns, test)) 177 } 178 } 179 180 func TestMycatShardBatchInsert(t *testing.T) { 181 ns, err := preparePlanInfo() 182 if err != nil { 183 t.Fatalf("prepare namespace error: %v", err) 184 } 185 186 tests := []SQLTestcase{ 187 { 188 db: "db_mycat", 189 sql: "insert into tbl_mycat (id, a) values (0, 'hi'), (4, 'hi')", 190 sqls: map[string]map[string][]string{ 191 "slice-0": { 192 "db_mycat_0": {"INSERT INTO `tbl_mycat` (`id`,`a`) VALUES (0,'hi'),(4,'hi')"}, 193 }, 194 }, 195 }, 196 { 197 db: "db_mycat", 198 sql: "insert into tbl_mycat (id, a) values (0, 'hi'), (1, 'hi'), (4, 'hi')", 199 hasErr: true, // batch insert has cross slice values 200 }, 201 { 202 db: "db_mycat", 203 sql: "insert into tbl_mycat (id, a) values (6, 'hi'), (5, 'hello')", 204 hasErr: true, // batch insert has cross slice values 205 }, 206 } 207 for _, test := range tests { 208 t.Run(test.sql, getTestFunc(ns, test)) 209 } 210 } 211 212 func TestMycatShardSimpleInsertSet(t *testing.T) { 213 ns, err := preparePlanInfo() 214 if err != nil { 215 t.Fatalf("prepare namespace error: %v", err) 216 } 217 218 tests := []SQLTestcase{ 219 { 220 db: "db_mycat", 221 sql: "insert into tbl_mycat set id = 0, a = 'hi'", 222 sqls: map[string]map[string][]string{ 223 "slice-0": { 224 "db_mycat_0": {"INSERT INTO `tbl_mycat` SET `id`=0,`a`='hi'"}, 225 }, 226 }, 227 }, 228 } 229 for _, test := range tests { 230 t.Run(test.sql, getTestFunc(ns, test)) 231 } 232 } 233 234 func TestSimpleWriteDMLShardMycatMurmur(t *testing.T) { 235 ns, err := preparePlanInfo() 236 if err != nil { 237 t.Fatalf("prepare namespace error: %v", err) 238 } 239 240 tests := []SQLTestcase{ 241 { 242 db: "db_mycat", 243 sql: "insert into tbl_mycat_murmur (id, a) values (0, 'hi')", 244 sqls: map[string]map[string][]string{ 245 "slice-1": { 246 "db_mycat_2": {"INSERT INTO `tbl_mycat_murmur` (`id`,`a`) VALUES (0,'hi')"}, 247 }, 248 }, 249 }, 250 { 251 db: "db_mycat", 252 sql: "update tbl_mycat_murmur set a = 'h' where id = 0", 253 sqls: map[string]map[string][]string{ 254 "slice-1": { 255 "db_mycat_2": {"UPDATE `tbl_mycat_murmur` SET `a`='h' WHERE `id`=0"}, 256 }, 257 }, 258 }, 259 { 260 db: "db_mycat", 261 sql: "delete from tbl_mycat_murmur where id = 0", 262 sqls: map[string]map[string][]string{ 263 "slice-1": { 264 "db_mycat_2": {"DELETE FROM `tbl_mycat_murmur` WHERE `id`=0"}, 265 }, 266 }, 267 }, 268 { 269 db: "db_mycat", 270 sql: "insert into tbl_mycat_murmur (id, a) values (1, 'hi')", 271 sqls: map[string]map[string][]string{ 272 "slice-0": { 273 "db_mycat_1": {"INSERT INTO `tbl_mycat_murmur` (`id`,`a`) VALUES (1,'hi')"}, 274 }, 275 }, 276 }, 277 { 278 db: "db_mycat", 279 sql: "update tbl_mycat_murmur set a = 'h' where id = 1", 280 sqls: map[string]map[string][]string{ 281 "slice-0": { 282 "db_mycat_1": {"UPDATE `tbl_mycat_murmur` SET `a`='h' WHERE `id`=1"}, 283 }, 284 }, 285 }, 286 { 287 db: "db_mycat", 288 sql: "delete from tbl_mycat_murmur where id = 1", 289 sqls: map[string]map[string][]string{ 290 "slice-0": { 291 "db_mycat_1": {"DELETE FROM `tbl_mycat_murmur` WHERE `id`=1"}, 292 }, 293 }, 294 }, 295 { 296 db: "db_mycat", 297 sql: "insert into tbl_mycat_murmur (id, a) values (2, 'hi')", 298 sqls: map[string]map[string][]string{ 299 "slice-0": { 300 "db_mycat_1": {"INSERT INTO `tbl_mycat_murmur` (`id`,`a`) VALUES (2,'hi')"}, 301 }, 302 }, 303 }, 304 { 305 db: "db_mycat", 306 sql: "update tbl_mycat_murmur set a = 'h' where id = 2", 307 sqls: map[string]map[string][]string{ 308 "slice-0": { 309 "db_mycat_1": {"UPDATE `tbl_mycat_murmur` SET `a`='h' WHERE `id`=2"}, 310 }, 311 }, 312 }, 313 { 314 db: "db_mycat", 315 sql: "delete from tbl_mycat_murmur where id = 2", 316 sqls: map[string]map[string][]string{ 317 "slice-0": { 318 "db_mycat_1": {"DELETE FROM `tbl_mycat_murmur` WHERE `id`=2"}, 319 }, 320 }, 321 }, 322 { 323 db: "db_mycat", 324 sql: "insert into tbl_mycat_murmur (id, a) values (3, 'hi')", 325 sqls: map[string]map[string][]string{ 326 "slice-0": { 327 "db_mycat_1": {"INSERT INTO `tbl_mycat_murmur` (`id`,`a`) VALUES (3,'hi')"}, 328 }, 329 }, 330 }, 331 { 332 db: "db_mycat", 333 sql: "insert into tbl_mycat_murmur (id, a) values (4, 'hi')", 334 sqls: map[string]map[string][]string{ 335 "slice-1": { 336 "db_mycat_2": {"INSERT INTO `tbl_mycat_murmur` (`id`,`a`) VALUES (4,'hi')"}, 337 }, 338 }, 339 }, 340 { 341 db: "db_mycat", 342 sql: "update tbl_mycat_murmur set a = 'h' where id = 4", 343 sqls: map[string]map[string][]string{ 344 "slice-1": { 345 "db_mycat_2": {"UPDATE `tbl_mycat_murmur` SET `a`='h' WHERE `id`=4"}, 346 }, 347 }, 348 }, 349 { 350 db: "db_mycat", 351 sql: "delete from tbl_mycat_murmur where id = 4", 352 sqls: map[string]map[string][]string{ 353 "slice-1": { 354 "db_mycat_2": {"DELETE FROM `tbl_mycat_murmur` WHERE `id`=4"}, 355 }, 356 }, 357 }, 358 } 359 for _, test := range tests { 360 t.Run(test.sql, getTestFunc(ns, test)) 361 } 362 } 363 364 func TestSimpleWriteDMLShardMycatModLong(t *testing.T) { 365 ns, err := preparePlanInfo() 366 if err != nil { 367 t.Fatalf("prepare namespace error: %v", err) 368 } 369 370 tests := []SQLTestcase{ 371 { 372 db: "db_mycat", 373 sql: "insert into tbl_mycat_long (id, a) values (0, 'hi')", 374 sqls: map[string]map[string][]string{ 375 "slice-0": { 376 "db_mycat_0": {"INSERT INTO `tbl_mycat_long` (`id`,`a`) VALUES (0,'hi')"}, 377 }, 378 }, 379 }, 380 { 381 db: "db_mycat", 382 sql: "update tbl_mycat_long set a = 'h' where id = 0", 383 sqls: map[string]map[string][]string{ 384 "slice-0": { 385 "db_mycat_0": {"UPDATE `tbl_mycat_long` SET `a`='h' WHERE `id`=0"}, 386 }, 387 }, 388 }, 389 { 390 db: "db_mycat", 391 sql: "delete from tbl_mycat_long where id = 0", 392 sqls: map[string]map[string][]string{ 393 "slice-0": { 394 "db_mycat_0": {"DELETE FROM `tbl_mycat_long` WHERE `id`=0"}, 395 }, 396 }, 397 }, 398 { 399 db: "db_mycat", 400 sql: "insert into tbl_mycat_long (id, a) values (1, 'hi')", 401 sqls: map[string]map[string][]string{ 402 "slice-0": { 403 "db_mycat_0": {"INSERT INTO `tbl_mycat_long` (`id`,`a`) VALUES (1,'hi')"}, 404 }, 405 }, 406 }, 407 { 408 db: "db_mycat", 409 sql: "update tbl_mycat_long set a = 'h' where id = 1", 410 sqls: map[string]map[string][]string{ 411 "slice-0": { 412 "db_mycat_0": {"UPDATE `tbl_mycat_long` SET `a`='h' WHERE `id`=1"}, 413 }, 414 }, 415 }, 416 { 417 db: "db_mycat", 418 sql: "delete from tbl_mycat_long where id = 1", 419 sqls: map[string]map[string][]string{ 420 "slice-0": { 421 "db_mycat_0": {"DELETE FROM `tbl_mycat_long` WHERE `id`=1"}, 422 }, 423 }, 424 }, 425 { 426 db: "db_mycat", 427 sql: "insert into tbl_mycat_long (id, a) values (256, 'hi')", 428 sqls: map[string]map[string][]string{ 429 "slice-0": { 430 "db_mycat_1": {"INSERT INTO `tbl_mycat_long` (`id`,`a`) VALUES (256,'hi')"}, 431 }, 432 }, 433 }, 434 { 435 db: "db_mycat", 436 sql: "update tbl_mycat_long set a = 'h' where id = 256", 437 sqls: map[string]map[string][]string{ 438 "slice-0": { 439 "db_mycat_1": {"UPDATE `tbl_mycat_long` SET `a`='h' WHERE `id`=256"}, 440 }, 441 }, 442 }, 443 { 444 db: "db_mycat", 445 sql: "delete from tbl_mycat_long where id = 256", 446 sqls: map[string]map[string][]string{ 447 "slice-0": { 448 "db_mycat_1": {"DELETE FROM `tbl_mycat_long` WHERE `id`=256"}, 449 }, 450 }, 451 }, 452 { 453 db: "db_mycat", 454 sql: "insert into tbl_mycat_long (id, a) values (257, 'hi')", 455 sqls: map[string]map[string][]string{ 456 "slice-0": { 457 "db_mycat_1": {"INSERT INTO `tbl_mycat_long` (`id`,`a`) VALUES (257,'hi')"}, 458 }, 459 }, 460 }, 461 { 462 db: "db_mycat", 463 sql: "update tbl_mycat_long set a = 'h' where id = 257", 464 sqls: map[string]map[string][]string{ 465 "slice-0": { 466 "db_mycat_1": {"UPDATE `tbl_mycat_long` SET `a`='h' WHERE `id`=257"}, 467 }, 468 }, 469 }, 470 { 471 db: "db_mycat", 472 sql: "delete from tbl_mycat_long where id = 257", 473 sqls: map[string]map[string][]string{ 474 "slice-0": { 475 "db_mycat_1": {"DELETE FROM `tbl_mycat_long` WHERE `id`=257"}, 476 }, 477 }, 478 }, 479 { 480 db: "db_mycat", 481 sql: "insert into tbl_mycat_long (id, a) values (512, 'hi')", 482 sqls: map[string]map[string][]string{ 483 "slice-1": { 484 "db_mycat_2": {"INSERT INTO `tbl_mycat_long` (`id`,`a`) VALUES (512,'hi')"}, 485 }, 486 }, 487 }, 488 { 489 db: "db_mycat", 490 sql: "update tbl_mycat_long set a = 'h' where id = 512", 491 sqls: map[string]map[string][]string{ 492 "slice-1": { 493 "db_mycat_2": {"UPDATE `tbl_mycat_long` SET `a`='h' WHERE `id`=512"}, 494 }, 495 }, 496 }, 497 { 498 db: "db_mycat", 499 sql: "delete from tbl_mycat_long where id = 512", 500 sqls: map[string]map[string][]string{ 501 "slice-1": { 502 "db_mycat_2": {"DELETE FROM `tbl_mycat_long` WHERE `id`=512"}, 503 }, 504 }, 505 }, 506 { 507 db: "db_mycat", 508 sql: "insert into tbl_mycat_long (id, a) values (513, 'hi')", 509 sqls: map[string]map[string][]string{ 510 "slice-1": { 511 "db_mycat_2": {"INSERT INTO `tbl_mycat_long` (`id`,`a`) VALUES (513,'hi')"}, 512 }, 513 }, 514 }, 515 { 516 db: "db_mycat", 517 sql: "update tbl_mycat_long set a = 'h' where id = 513", 518 sqls: map[string]map[string][]string{ 519 "slice-1": { 520 "db_mycat_2": {"UPDATE `tbl_mycat_long` SET `a`='h' WHERE `id`=513"}, 521 }, 522 }, 523 }, 524 { 525 db: "db_mycat", 526 sql: "delete from tbl_mycat_long where id = 513", 527 sqls: map[string]map[string][]string{ 528 "slice-1": { 529 "db_mycat_2": {"DELETE FROM `tbl_mycat_long` WHERE `id`=513"}, 530 }, 531 }, 532 }, 533 { 534 db: "db_mycat", 535 sql: "insert into tbl_mycat_long (id, a) values (768, 'hi')", 536 sqls: map[string]map[string][]string{ 537 "slice-1": { 538 "db_mycat_3": {"INSERT INTO `tbl_mycat_long` (`id`,`a`) VALUES (768,'hi')"}, 539 }, 540 }, 541 }, 542 { 543 db: "db_mycat", 544 sql: "update tbl_mycat_long set a = 'h' where id = 768", 545 sqls: map[string]map[string][]string{ 546 "slice-1": { 547 "db_mycat_3": {"UPDATE `tbl_mycat_long` SET `a`='h' WHERE `id`=768"}, 548 }, 549 }, 550 }, 551 { 552 db: "db_mycat", 553 sql: "delete from tbl_mycat_long where id = 768", 554 sqls: map[string]map[string][]string{ 555 "slice-1": { 556 "db_mycat_3": {"DELETE FROM `tbl_mycat_long` WHERE `id`=768"}, 557 }, 558 }, 559 }, 560 { 561 db: "db_mycat", 562 sql: "insert into tbl_mycat_long (id, a) values (769, 'hi')", 563 sqls: map[string]map[string][]string{ 564 "slice-1": { 565 "db_mycat_3": {"INSERT INTO `tbl_mycat_long` (`id`,`a`) VALUES (769,'hi')"}, 566 }, 567 }, 568 }, 569 { 570 db: "db_mycat", 571 sql: "update tbl_mycat_long set a = 'h' where id = 769", 572 sqls: map[string]map[string][]string{ 573 "slice-1": { 574 "db_mycat_3": {"UPDATE `tbl_mycat_long` SET `a`='h' WHERE `id`=769"}, 575 }, 576 }, 577 }, 578 { 579 db: "db_mycat", 580 sql: "delete from tbl_mycat_long where id = 769", 581 sqls: map[string]map[string][]string{ 582 "slice-1": { 583 "db_mycat_3": {"DELETE FROM `tbl_mycat_long` WHERE `id`=769"}, 584 }, 585 }, 586 }, 587 } 588 for _, test := range tests { 589 t.Run(test.sql, getTestFunc(ns, test)) 590 } 591 } 592 593 func TestMycatInsertGlobalTable(t *testing.T) { 594 ns, err := preparePlanInfo() 595 if err != nil { 596 t.Fatalf("prepare namespace error: %v", err) 597 } 598 599 tests := []SQLTestcase{ 600 { 601 db: "db_mycat", 602 sql: "insert into tbl_mycat_global_one set id = 0, a = 'hi'", 603 sqls: map[string]map[string][]string{ 604 "slice-0": { 605 "db_mycat_0": {"INSERT INTO `tbl_mycat_global_one` SET `id`=0,`a`='hi'"}, 606 "db_mycat_1": {"INSERT INTO `tbl_mycat_global_one` SET `id`=0,`a`='hi'"}, 607 }, 608 "slice-1": { 609 "db_mycat_2": {"INSERT INTO `tbl_mycat_global_one` SET `id`=0,`a`='hi'"}, 610 "db_mycat_3": {"INSERT INTO `tbl_mycat_global_one` SET `id`=0,`a`='hi'"}, 611 }, 612 }, 613 }, 614 { 615 db: "db_mycat", 616 sql: "insert into db_mycat.tbl_mycat_global_one set id = 0, a = 'hi'", 617 sqls: map[string]map[string][]string{ 618 "slice-0": { 619 "db_mycat_0": {"INSERT INTO `db_mycat_0`.`tbl_mycat_global_one` SET `id`=0,`a`='hi'"}, 620 "db_mycat_1": {"INSERT INTO `db_mycat_1`.`tbl_mycat_global_one` SET `id`=0,`a`='hi'"}, 621 }, 622 "slice-1": { 623 "db_mycat_2": {"INSERT INTO `db_mycat_2`.`tbl_mycat_global_one` SET `id`=0,`a`='hi'"}, 624 "db_mycat_3": {"INSERT INTO `db_mycat_3`.`tbl_mycat_global_one` SET `id`=0,`a`='hi'"}, 625 }, 626 }, 627 }, 628 } 629 for _, test := range tests { 630 t.Run(test.sql, getTestFunc(ns, test)) 631 } 632 } 633 634 // 注意这一组各个测试用例之前有关联, 因为都用到了同一个全局序列号 635 func TestMycatInsertSequenceShardKey(t *testing.T) { 636 ns, err := preparePlanInfo() 637 if err != nil { 638 t.Fatalf("prepare namespace error: %v", err) 639 } 640 641 tests := []SQLTestcase{ 642 { 643 db: "db_mycat", 644 sql: "insert into tbl_mycat set id = nextval(), a = 'hi'", 645 sqls: map[string]map[string][]string{ 646 "slice-0": { 647 "db_mycat_1": {"INSERT INTO `tbl_mycat` SET `id`=1,`a`='hi'"}, 648 }, 649 }, 650 }, 651 { 652 db: "db_mycat", 653 sql: "insert into tbl_mycat set id = nextval(), a = 'hi'", 654 sqls: map[string]map[string][]string{ 655 "slice-1": { 656 "db_mycat_2": {"INSERT INTO `tbl_mycat` SET `id`=2,`a`='hi'"}, // next val 657 }, 658 }, 659 }, 660 { 661 db: "db_mycat", 662 sql: "insert into tbl_mycat (id, a) values (nextval(), 'hi')", 663 sqls: map[string]map[string][]string{ 664 "slice-1": { 665 "db_mycat_3": {"INSERT INTO `tbl_mycat` (`id`,`a`) VALUES (3,'hi')"}, 666 }, 667 }, 668 }, 669 { 670 db: "db_mycat", 671 sql: "insert into tbl_mycat (ID, a) values (nextval(), 'hi')", 672 sqls: map[string]map[string][]string{ 673 "slice-0": { 674 "db_mycat_0": {"INSERT INTO `tbl_mycat` (`ID`,`a`) VALUES (4,'hi')"}, 675 }, 676 }, 677 }, 678 { 679 db: "db_mycat", 680 sql: "insert into tbl_mycat set ID = nextval(), a = 'hi'", 681 sqls: map[string]map[string][]string{ 682 "slice-0": { 683 "db_mycat_1": {"INSERT INTO `tbl_mycat` SET `ID`=5,`a`='hi'"}, 684 }, 685 }, 686 }, 687 } 688 for _, test := range tests { 689 t.Run(test.sql, getTestFunc(ns, test)) 690 } 691 } 692 693 // 注意这一组各个测试用例之前有关联, 因为都用到了同一个全局序列号 694 func TestMycatInsertSequenceUnshardKey(t *testing.T) { 695 ns, err := preparePlanInfo() 696 if err != nil { 697 t.Fatalf("prepare namespace error: %v", err) 698 } 699 700 tests := []SQLTestcase{ 701 { 702 db: "db_ks", 703 sql: "insert into tbl_ks set id = 0, user_id = nextval(), a = 'hi'", 704 sqls: map[string]map[string][]string{ 705 "slice-0": { 706 "db_ks": {"INSERT INTO `tbl_ks_0000` SET `id`=0,`user_id`=1,`a`='hi'"}, 707 }, 708 }, 709 }, 710 { 711 db: "db_ks", 712 sql: "insert into tbl_ks set id = 0, user_id = nextval(), a = 'hi'", 713 sqls: map[string]map[string][]string{ 714 "slice-0": { 715 "db_ks": {"INSERT INTO `tbl_ks_0000` SET `id`=0,`user_id`=2,`a`='hi'"}, 716 }, 717 }, 718 }, 719 { 720 db: "db_ks", 721 sql: "insert into tbl_ks (id, user_id) values (3,nextval()),(3,nextval()),(3, nextval())", 722 sqls: map[string]map[string][]string{ 723 "slice-1": { 724 "db_ks": {"INSERT INTO `tbl_ks_0003` (`id`,`user_id`) VALUES (3,3),(3,4),(3,5)"}, 725 }, 726 }, 727 }, 728 } 729 for _, test := range tests { 730 t.Run(test.sql, getTestFunc(ns, test)) 731 } 732 } 733 734 func TestEscapeBackslashShard(t *testing.T) { 735 ns, err := preparePlanInfo() 736 if err != nil { 737 t.Fatalf("prepare namespace error: %v", err) 738 } 739 740 tests := []SQLTestcase{ 741 { 742 db: "db_ks", 743 sql: `insert into tbl_ks (id,name) values (1,'hello\\"world')`, 744 sqls: map[string]map[string][]string{ 745 "slice-0": { 746 "db_ks": {"INSERT INTO `tbl_ks_0001` (`id`,`name`) VALUES (1,'hello\\\\\"world')"}, 747 }, 748 }, 749 }, 750 } 751 for _, test := range tests { 752 t.Run(test.sql, getTestFunc(ns, test)) 753 } 754 } 755 756 func TestMycatShardSimpleInsertColumnCaseInsensitive(t *testing.T) { 757 ns, err := preparePlanInfo() 758 if err != nil { 759 t.Fatalf("prepare namespace error: %v", err) 760 } 761 762 tests := []SQLTestcase{ 763 { 764 db: "db_mycat", 765 sql: "insert into tbl_mycat (ID, a) values (0, 'hi')", 766 sqls: map[string]map[string][]string{ 767 "slice-0": { 768 "db_mycat_0": {"INSERT INTO `tbl_mycat` (`ID`,`a`) VALUES (0,'hi')"}, 769 }, 770 }, 771 }, 772 { 773 db: "db_mycat", 774 sql: "insert into tbl_mycat set ID = 0, a = 'hi'", 775 sqls: map[string]map[string][]string{ 776 "slice-0": { 777 "db_mycat_0": {"INSERT INTO `tbl_mycat` SET `ID`=0,`a`='hi'"}, 778 }, 779 }, 780 }, 781 { 782 db: "db_mycat", 783 sql: "insert into tbl_mycat (ID, a) values (6, 'hi') on duplicate key update ID = 5", 784 hasErr: true, // routing key in update expression 785 }, 786 } 787 for _, test := range tests { 788 t.Run(test.sql, getTestFunc(ns, test)) 789 } 790 } 791 792 func TestInserTableNameColumnCaseInsensitive(t *testing.T) { 793 ns, err := preparePlanInfo() 794 if err != nil { 795 t.Fatalf("prepare namespace error: %v", err) 796 } 797 798 tests := []SQLTestcase{ 799 { 800 db: "db_mycat", 801 sql: "insert into TBL_MYCAT (ID, a) values (0, 'hi')", 802 sqls: map[string]map[string][]string{ 803 "slice-0": { 804 "db_mycat_0": {"INSERT INTO `TBL_MYCAT` (`ID`,`a`) VALUES (0,'hi')"}, 805 }, 806 }, 807 }, 808 { 809 db: "db_ks", 810 sql: "insert into tbl_ks_uppercase_child (ID, a) values (0, 'hi')", 811 sqls: map[string]map[string][]string{ 812 "slice-0": { 813 "db_ks": {"INSERT INTO `tbl_ks_uppercase_child_0000` (`ID`,`a`) VALUES (0,'hi')"}, 814 }, 815 }, 816 }, 817 } 818 for _, test := range tests { 819 t.Run(test.sql, getTestFunc(ns, test)) 820 } 821 }