github.com/dolthub/go-mysql-server@v0.18.0/enginetest/queries/transaction_queries.go (about) 1 // Copyright 2021 Dolthub, 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 // 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 queries 16 17 import ( 18 "github.com/dolthub/go-mysql-server/sql" 19 "github.com/dolthub/go-mysql-server/sql/types" 20 ) 21 22 // TransactionTest is a script to test transaction correctness. It's similar to ScriptTest, but its assertions name 23 // clients that participate 24 type TransactionTest struct { 25 // Name of the script test 26 Name string 27 // The sql statements to execute as setup, in order. Results are not checked, but statements must not error. 28 // Setup scripts are run as a distinct client separate from the client used in any assertions. 29 SetUpScript []string 30 // The set of assertions to make after setup, in order 31 // The transaction test runner augments the ScriptTest runner by allowing embedding of a client string in a query 32 // comment to name the client running the query, like so: 33 // /* client a */ select * from myTable 34 Assertions []ScriptTestAssertion 35 } 36 37 var TransactionTests = []TransactionTest{ 38 { 39 Name: "Changes from transactions are available before analyzing statements in other sessions (autocommit off)", 40 Assertions: []ScriptTestAssertion{ 41 { 42 Query: "/* client a */ set @@autocommit = 0;", 43 Expected: []sql.Row{{}}, 44 }, 45 { 46 Query: "/* client b */ set @@autocommit = 0;", 47 Expected: []sql.Row{{}}, 48 }, 49 { 50 Query: "/* client a */ select @@autocommit;", 51 Expected: []sql.Row{{0}}, 52 }, 53 { 54 Query: "/* client b */ select @@autocommit;", 55 Expected: []sql.Row{{0}}, 56 }, 57 { 58 Query: "/* client a */ start transaction;", 59 Expected: []sql.Row{}, 60 }, 61 { 62 Query: "/* client a */ select * from t;", 63 ExpectedErr: sql.ErrTableNotFound, 64 }, 65 { 66 Query: "/* client a */ create table t(pk int primary key);", 67 Expected: []sql.Row{{types.OkResult{}}}, 68 }, 69 { 70 // Trigger a query error to make sure explicit transaction is still 71 // correctly configured in the session despite the error 72 Query: "/* client a */ select * from t2;", 73 ExpectedErr: sql.ErrTableNotFound, 74 }, 75 { 76 Query: "/* client a */ commit;", 77 Expected: []sql.Row{}, 78 }, 79 { 80 Query: "/* client b */ start transaction;", 81 Expected: []sql.Row{}, 82 }, 83 { 84 Query: "/* client b */ select count(*) from t;", 85 Expected: []sql.Row{{0}}, 86 }, 87 }, 88 }, 89 { 90 Name: "autocommit on", 91 SetUpScript: []string{ 92 "create table t (x int primary key, y int)", 93 "insert into t values (1, 1)", 94 }, 95 Assertions: []ScriptTestAssertion{ 96 { 97 Query: "/* client a */ insert into t values (2, 2)", 98 Expected: []sql.Row{{types.NewOkResult(1)}}, 99 }, 100 { 101 Query: "/* client b */ select * from t order by x", 102 Expected: []sql.Row{{1, 1}, {2, 2}}, 103 }, 104 { 105 Query: "/* client b */ insert into t values (3, 3)", 106 Expected: []sql.Row{{types.NewOkResult(1)}}, 107 }, 108 { 109 Query: "/* client a */ select * from t order by x", 110 Expected: []sql.Row{{1, 1}, {2, 2}, {3, 3}}, 111 }, 112 }, 113 }, 114 { 115 Name: "autocommit off", 116 SetUpScript: []string{ 117 "create table t (x int primary key, y int)", 118 "insert into t values (1, 1)", 119 }, 120 Assertions: []ScriptTestAssertion{ 121 { 122 Query: "/* client a */ set autocommit = off", 123 Expected: []sql.Row{{}}, 124 }, 125 { 126 Query: "/* client b */ set autocommit = off", 127 Expected: []sql.Row{{}}, 128 }, 129 { 130 Query: "/* client b */ select * from t order by x", 131 Expected: []sql.Row{{1, 1}}, 132 }, 133 { 134 Query: "/* client b */ insert into t values (2, 2)", 135 Expected: []sql.Row{{types.NewOkResult(1)}}, 136 }, 137 { 138 Query: "/* client a */ select * from t order by x", 139 Expected: []sql.Row{ 140 {1, 1}, 141 }, 142 }, 143 { 144 Query: "/* client a */ insert into t values (3,3)", 145 Expected: []sql.Row{{types.NewOkResult(1)}}, 146 }, 147 { 148 Query: "/* client b */ select * from t order by x", 149 Expected: []sql.Row{{1, 1}, {2, 2}}, 150 }, 151 { 152 Query: "/* client b */ commit", 153 Expected: []sql.Row{}, 154 }, 155 { 156 Query: "/* client a */ select * from t order by x", 157 Expected: []sql.Row{{1, 1}, {3, 3}}, 158 }, 159 { 160 Query: "/* client b */ select * from t order by x", 161 Expected: []sql.Row{{1, 1}, {2, 2}}, 162 }, 163 { 164 Query: "/* client a */ commit", 165 Expected: []sql.Row{}, 166 }, 167 { 168 Query: "/* client b */ select * from t order by x", 169 Expected: []sql.Row{{1, 1}, {2, 2}}, 170 }, 171 { 172 Query: "/* client b */ start transaction", 173 Expected: []sql.Row{}, 174 }, 175 { 176 Query: "/* client b */ select * from t order by x", 177 Expected: []sql.Row{{1, 1}, {2, 2}, {3, 3}}, 178 }, 179 { 180 Query: "/* client a */ select * from t order by x", 181 Expected: []sql.Row{{1, 1}, {2, 2}, {3, 3}}, 182 }, 183 }, 184 }, 185 { 186 Name: "toggle autocommit", 187 SetUpScript: []string{ 188 "create table t (x int primary key, y int)", 189 "insert into t values (1, 1)", 190 }, 191 Assertions: []ScriptTestAssertion{ 192 { 193 Query: "/* client a */ set autocommit = off", 194 Expected: []sql.Row{{}}, 195 }, 196 { 197 Query: "/* client b */ set autocommit = off", 198 Expected: []sql.Row{{}}, 199 }, 200 { 201 Query: "/* client b */ insert into t values (2,2)", 202 Expected: []sql.Row{{types.NewOkResult(1)}}, 203 }, 204 { 205 Query: "/* client a */ select * from t order by x", 206 Expected: []sql.Row{{1, 1}}, 207 }, 208 // should commit any pending transaction 209 { 210 Query: "/* client b */ set autocommit = on", 211 Expected: []sql.Row{{}}, 212 }, 213 { 214 Query: "/* client a */ select * from t order by x", 215 Expected: []sql.Row{{1, 1}}, 216 }, 217 // client a sees the committed transaction from client b when it begins a new transaction 218 { 219 Query: "/* client a */ set autocommit = on", 220 Expected: []sql.Row{{}}, 221 }, 222 { 223 Query: "/* client a */ select * from t order by x", 224 Expected: []sql.Row{{1, 1}, {2, 2}}, 225 }, 226 }, 227 }, 228 { 229 Name: "autocommit on with explicit transactions", 230 SetUpScript: []string{ 231 "create table t (x int primary key, y int)", 232 "insert into t values (1, 1)", 233 }, 234 Assertions: []ScriptTestAssertion{ 235 { 236 Query: "/* client a */ start transaction", 237 Expected: []sql.Row{}, 238 }, 239 { 240 // Trigger an analyzer error to make sure transaction state is managed correctly 241 Query: "/* client a */ select * from doesnotexist;", 242 ExpectedErr: sql.ErrTableNotFound, 243 }, 244 { 245 Query: "/* client a */ insert into t values (2, 2)", 246 Expected: []sql.Row{{types.NewOkResult(1)}}, 247 }, 248 { 249 Query: "/* client b */ select * from t order by x", 250 Expected: []sql.Row{{1, 1}}, 251 }, 252 { 253 // Trigger an analyzer error to make sure state for the explicitly started 254 // transaction is managed correctly and not cleared 255 Query: "/* client a */ select * from doesnotexist;", 256 ExpectedErr: sql.ErrTableNotFound, 257 }, 258 { 259 Query: "/* client a */ commit", 260 Expected: []sql.Row{}, 261 }, 262 { 263 Query: "/* client b */ select * from t order by x", 264 Expected: []sql.Row{{1, 1}, {2, 2}}, 265 }, 266 // After commit, autocommit turns back on 267 { 268 Query: "/* client a */ insert into t values (3, 3)", 269 Expected: []sql.Row{{types.NewOkResult(1)}}, 270 }, 271 { 272 Query: "/* client b */ select * from t order by x", 273 Expected: []sql.Row{{1, 1}, {2, 2}, {3, 3}}, 274 }, 275 }, 276 }, 277 { 278 Name: "rollback", 279 SetUpScript: []string{ 280 "create table t (x int primary key, y int)", 281 "insert into t values (1, 1)", 282 }, 283 Assertions: []ScriptTestAssertion{ 284 { 285 Query: "/* client a */ set autocommit = off", 286 Expected: []sql.Row{{}}, 287 }, 288 { 289 Query: "/* client b */ set autocommit = off", 290 Expected: []sql.Row{{}}, 291 }, 292 { 293 Query: "/* client a */ start transaction", 294 Expected: []sql.Row{}, 295 }, 296 { 297 Query: "/* client b */ start transaction", 298 Expected: []sql.Row{}, 299 }, 300 { 301 Query: "/* client a */ insert into t values (2, 2)", 302 Expected: []sql.Row{{types.NewOkResult(1)}}, 303 }, 304 { 305 Query: "/* client b */ insert into t values (3, 3)", 306 Expected: []sql.Row{{types.NewOkResult(1)}}, 307 }, 308 { 309 Query: "/* client a */ select * from t order by x", 310 Expected: []sql.Row{{1, 1}, {2, 2}}, 311 }, 312 { 313 Query: "/* client b */ commit", 314 Expected: []sql.Row{}, 315 }, 316 { 317 Query: "/* client a */ select * from t order by x", 318 Expected: []sql.Row{{1, 1}, {2, 2}}, 319 }, 320 { 321 Query: "/* client a */ rollback", 322 Expected: []sql.Row{}, 323 }, 324 { 325 Query: "/* client a */ select * from t order by x", 326 Expected: []sql.Row{{1, 1}, {3, 3}}, 327 }, 328 { 329 Query: "/* client a */ insert into t values (2, 2)", 330 Expected: []sql.Row{{types.NewOkResult(1)}}, 331 }, 332 { 333 Query: "/* client b */ select * from t order by x", 334 Expected: []sql.Row{{1, 1}, {3, 3}}, 335 }, 336 { 337 Query: "/* client a */ commit", 338 Expected: []sql.Row{}, 339 }, 340 { 341 Query: "/* client b */ select * from t order by x", 342 Expected: []sql.Row{{1, 1}, {3, 3}}, 343 }, 344 { 345 Query: "/* client b */ rollback", 346 Expected: []sql.Row{}, 347 }, 348 { 349 Query: "/* client b */ select * from t order by x", 350 Expected: []sql.Row{{1, 1}, {2, 2}, {3, 3}}, 351 }, 352 }, 353 }, 354 { 355 Name: "rollback to savepoint", 356 SetUpScript: []string{ 357 "create table t (x int primary key, y int)", 358 "insert into t values (1, 1)", 359 }, 360 Assertions: []ScriptTestAssertion{ 361 { 362 Query: "/* client a */ set autocommit = off", 363 Expected: []sql.Row{{}}, 364 }, 365 { 366 Query: "/* client b */ set autocommit = off", 367 Expected: []sql.Row{{}}, 368 }, 369 { 370 Query: "/* client a */ start transaction", 371 Expected: []sql.Row{}, 372 }, 373 { 374 Query: "/* client b */ start transaction", 375 Expected: []sql.Row{}, 376 }, 377 { 378 Query: "/* client a */ insert into t values (2, 2)", 379 Expected: []sql.Row{{types.NewOkResult(1)}}, 380 }, 381 { 382 Query: "/* client b */ insert into t values (3, 3)", 383 Expected: []sql.Row{{types.NewOkResult(1)}}, 384 }, 385 { 386 Query: "/* client a */ savepoint spa1", 387 Expected: []sql.Row{}, 388 }, 389 { 390 Query: "/* client b */ savepoint spb1", 391 Expected: []sql.Row{}, 392 }, 393 { 394 Query: "/* client a */ insert into t values (4, 4)", 395 Expected: []sql.Row{{types.NewOkResult(1)}}, 396 }, 397 { 398 Query: "/* client b */ insert into t values (5, 5)", 399 Expected: []sql.Row{{types.NewOkResult(1)}}, 400 }, 401 { 402 Query: "/* client a */ savepoint spa2", 403 Expected: []sql.Row{}, 404 }, 405 { 406 Query: "/* client b */ savepoint spb2", 407 Expected: []sql.Row{}, 408 }, 409 { 410 Query: "/* client a */ insert into t values (6, 6)", 411 Expected: []sql.Row{{types.NewOkResult(1)}}, 412 }, 413 { 414 Query: "/* client b */ insert into t values (7, 7)", 415 Expected: []sql.Row{{types.NewOkResult(1)}}, 416 }, 417 { 418 Query: "/* client a */ select * from t order by x", 419 Expected: []sql.Row{{1, 1}, {2, 2}, {4, 4}, {6, 6}}, 420 }, 421 { 422 Query: "/* client b */ select * from t order by x", 423 Expected: []sql.Row{{1, 1}, {3, 3}, {5, 5}, {7, 7}}, 424 }, 425 { 426 Query: "/* client a */ rollback to SPA2", 427 Expected: []sql.Row{}, 428 }, 429 { 430 Query: "/* client b */ rollback to spB2", 431 Expected: []sql.Row{}, 432 }, 433 { 434 Query: "/* client a */ select * from t order by x", 435 Expected: []sql.Row{{1, 1}, {2, 2}, {4, 4}}, 436 }, 437 { 438 Query: "/* client b */ select * from t order by x", 439 Expected: []sql.Row{{1, 1}, {3, 3}, {5, 5}}, 440 }, 441 { 442 Query: "/* client a */ rollback to sPa2", 443 Expected: []sql.Row{}, 444 }, 445 { 446 Query: "/* client b */ rollback to Spb2", 447 Expected: []sql.Row{}, 448 }, 449 { 450 Query: "/* client a */ select * from t order by x", 451 Expected: []sql.Row{{1, 1}, {2, 2}, {4, 4}}, 452 }, 453 { 454 Query: "/* client b */ select * from t order by x", 455 Expected: []sql.Row{{1, 1}, {3, 3}, {5, 5}}, 456 }, 457 { 458 Query: "/* client a */ rollback to spA1", 459 Expected: []sql.Row{}, 460 }, 461 { 462 Query: "/* client b */ rollback to SPb1", 463 Expected: []sql.Row{}, 464 }, 465 { 466 Query: "/* client a */ select * from t order by x", 467 Expected: []sql.Row{{1, 1}, {2, 2}}, 468 }, 469 { 470 Query: "/* client b */ select * from t order by x", 471 Expected: []sql.Row{{1, 1}, {3, 3}}, 472 }, 473 { 474 Query: "/* client a */ rollback to spa2", 475 ExpectedErr: sql.ErrSavepointDoesNotExist, 476 }, 477 { 478 Query: "/* client b */ rollback to spb2", 479 ExpectedErr: sql.ErrSavepointDoesNotExist, 480 }, 481 { 482 Query: "/* client a */ rollback to Spa1", 483 Expected: []sql.Row{}, 484 }, 485 { 486 Query: "/* client b */ rollback to spB1", 487 Expected: []sql.Row{}, 488 }, 489 { 490 Query: "/* client a */ select * from t order by x", 491 Expected: []sql.Row{{1, 1}, {2, 2}}, 492 }, 493 { 494 Query: "/* client b */ select * from t order by x", 495 Expected: []sql.Row{{1, 1}, {3, 3}}, 496 }, 497 { 498 Query: "/* client a */ rollback", 499 Expected: []sql.Row{}, 500 }, 501 { 502 Query: "/* client b */ commit", 503 Expected: []sql.Row{}, 504 }, 505 { 506 Query: "/* client a */ select * from t order by x", 507 Expected: []sql.Row{{1, 1}, {3, 3}}, 508 }, 509 { 510 Query: "/* client b */ select * from t order by x", 511 Expected: []sql.Row{{1, 1}, {3, 3}}, 512 }, 513 { 514 Query: "/* client a */ rollback to spa1", 515 ExpectedErr: sql.ErrSavepointDoesNotExist, 516 }, 517 { 518 Query: "/* client b */ rollback to spb1", 519 ExpectedErr: sql.ErrSavepointDoesNotExist, 520 }, 521 }, 522 }, 523 { 524 Name: "release savepoint", 525 SetUpScript: []string{ 526 "create table t (x int primary key, y int)", 527 "insert into t values (1, 1)", 528 }, 529 Assertions: []ScriptTestAssertion{ 530 { 531 Query: "/* client a */ set autocommit = off", 532 Expected: []sql.Row{{}}, 533 }, 534 { 535 Query: "/* client b */ set autocommit = off", 536 Expected: []sql.Row{{}}, 537 }, 538 { 539 Query: "/* client a */ start transaction", 540 Expected: []sql.Row{}, 541 }, 542 { 543 Query: "/* client b */ start transaction", 544 Expected: []sql.Row{}, 545 }, 546 { 547 Query: "/* client a */ insert into t values (2, 2)", 548 Expected: []sql.Row{{types.NewOkResult(1)}}, 549 }, 550 { 551 Query: "/* client b */ insert into t values (3, 3)", 552 Expected: []sql.Row{{types.NewOkResult(1)}}, 553 }, 554 { 555 Query: "/* client a */ savepoint spa1", 556 Expected: []sql.Row{}, 557 }, 558 { 559 Query: "/* client b */ savepoint spb1", 560 Expected: []sql.Row{}, 561 }, 562 { 563 Query: "/* client a */ release savepoint Spa1", 564 Expected: []sql.Row{}, 565 }, 566 { 567 Query: "/* client b */ release savepoint sPb1", 568 Expected: []sql.Row{}, 569 }, 570 { 571 Query: "/* client a */ rollback to spa1", 572 ExpectedErr: sql.ErrSavepointDoesNotExist, 573 }, 574 { 575 Query: "/* client b */ rollback to spb1", 576 ExpectedErr: sql.ErrSavepointDoesNotExist, 577 }, 578 { 579 Query: "/* client a */ select * from t order by x", 580 Expected: []sql.Row{{1, 1}, {2, 2}}, 581 }, 582 { 583 Query: "/* client b */ select * from t order by x", 584 Expected: []sql.Row{{1, 1}, {3, 3}}, 585 }, 586 }, 587 }, 588 { 589 Name: "overwrite savepoint", 590 SetUpScript: []string{ 591 "create table t (x int primary key, y int)", 592 "insert into t values (1, 1)", 593 }, 594 Assertions: []ScriptTestAssertion{ 595 { 596 Query: "/* client a */ start transaction", 597 Expected: []sql.Row{}, 598 }, 599 { 600 Query: "/* client a */ insert into t values (2, 2)", 601 Expected: []sql.Row{{types.NewOkResult(1)}}, 602 }, 603 { 604 Query: "/* client a */ savepoint spa1", 605 Expected: []sql.Row{}, 606 }, 607 { 608 Query: "/* client a */ insert into t values (3, 3)", 609 Expected: []sql.Row{{types.NewOkResult(1)}}, 610 }, 611 { 612 Query: "/* client a */ savepoint spa2", 613 Expected: []sql.Row{}, 614 }, 615 { 616 Query: "/* client a */ insert into t values (4, 4)", 617 Expected: []sql.Row{{types.NewOkResult(1)}}, 618 }, 619 { 620 Query: "/* client a */ savepoint SPA1", 621 Expected: []sql.Row{}, 622 }, 623 { 624 Query: "/* client a */ insert into t values (5, 5)", 625 Expected: []sql.Row{{types.NewOkResult(1)}}, 626 }, 627 { 628 Query: "/* client a */ select * from t order by x", 629 Expected: []sql.Row{{1, 1}, {2, 2}, {3, 3}, {4, 4}, {5, 5}}, 630 }, 631 { 632 Query: "/* client a */ rollback to Spa1", 633 Expected: []sql.Row{}, 634 }, 635 { 636 Query: "/* client a */ select * from t order by x", 637 Expected: []sql.Row{{1, 1}, {2, 2}, {3, 3}, {4, 4}}, 638 }, 639 { 640 Query: "/* client a */ rollback to spa2", 641 Expected: []sql.Row{}, 642 }, 643 { 644 Query: "/* client a */ select * from t order by x", 645 Expected: []sql.Row{{1, 1}, {2, 2}, {3, 3}}, 646 }, 647 { 648 Query: "/* client a */ rollback to spa1", 649 ExpectedErr: sql.ErrSavepointDoesNotExist, 650 }, 651 { 652 Query: "/* client a */ release savepoint spa1", 653 ExpectedErr: sql.ErrSavepointDoesNotExist, 654 }, 655 }, 656 }, 657 { 658 Name: "Test AUTO INCREMENT with no autocommit", 659 SetUpScript: []string{ 660 "CREATE table t (x int PRIMARY KEY AUTO_INCREMENT, y int);", 661 "CREATE table t2 (x int PRIMARY KEY AUTO_INCREMENT, y int);", 662 "CREATE table t3 (x int PRIMARY KEY AUTO_INCREMENT, y int);", 663 "insert into t (y) values (1);", 664 "insert into t2 values (10, 10);", 665 }, 666 Assertions: []ScriptTestAssertion{ 667 { 668 Query: "/* client a */ set autocommit = off", 669 Expected: []sql.Row{{}}, 670 }, 671 { 672 Query: "/* client b */ set autocommit = off", 673 Expected: []sql.Row{{}}, 674 }, 675 { 676 Query: "/* client c */ set autocommit = off", 677 Expected: []sql.Row{{}}, 678 }, 679 // Client a starts by insert into t 680 { 681 Query: "/* client a */ insert into t (y) values (2)", 682 Expected: []sql.Row{{types.OkResult{RowsAffected: 1, InsertID: 2}}}, 683 }, 684 { 685 Query: "/* client b */ select * from t order by x", 686 Expected: []sql.Row{{1, 1}}, 687 }, 688 { 689 Query: "/* client c*/ select * from t order by x", 690 Expected: []sql.Row{{1, 1}}, 691 }, 692 // Client b inserts into t 693 { 694 Query: "/* client b */ insert into t (y) values (3)", 695 Expected: []sql.Row{{types.OkResult{RowsAffected: 1, InsertID: 3}}}, 696 }, 697 { 698 Query: "/* client a */ select * from t order by x", 699 Expected: []sql.Row{ 700 {1, 1}, {2, 2}, 701 }, 702 }, 703 { 704 Query: "/* client c */ select * from t order by x", 705 Expected: []sql.Row{ 706 {1, 1}, 707 }, 708 }, 709 // Client c inserts into t2 710 { 711 Query: "/* client c */ insert into t2 (y) values (11)", 712 Expected: []sql.Row{{types.OkResult{RowsAffected: 1, InsertID: 11}}}, 713 }, 714 { 715 Query: "/* client a */ select * from t2 order by x", 716 Expected: []sql.Row{{10, 10}}, 717 }, 718 { 719 Query: "/* client b */ select * from t2 order by x", 720 Expected: []sql.Row{{10, 10}}, 721 }, 722 { 723 Query: "/* client c */ select * from t2 order by x", 724 Expected: []sql.Row{{10, 10}, {11, 11}}, 725 }, 726 // Client a inserts into t2 727 { 728 Query: "/* client a */ insert into t2 (y) values (12)", 729 Expected: []sql.Row{{types.OkResult{RowsAffected: 1, InsertID: 12}}}, 730 }, 731 { 732 Query: "/* client a */ select * from t2 order by x", 733 Expected: []sql.Row{{10, 10}, {12, 12}}, 734 }, 735 { 736 Query: "/* client b */ select * from t2 order by x", 737 Expected: []sql.Row{{10, 10}}, 738 }, 739 { 740 Query: "/* client c */ select * from t2 order by x", 741 Expected: []sql.Row{{10, 10}, {11, 11}}, 742 }, 743 // Client a commits 744 { 745 Query: "/* client a */ commit", 746 Expected: []sql.Row{}, 747 }, 748 { 749 Query: "/* client b */ select * from t order by x", 750 Expected: []sql.Row{{1, 1}, {3, 3}}, 751 }, 752 { 753 Query: "/* client b */ select * from t2 order by x", 754 Expected: []sql.Row{{10, 10}}, 755 }, 756 { 757 Query: "/* client c */ select * from t2 order by x", 758 Expected: []sql.Row{{10, 10}, {11, 11}}, 759 }, 760 { 761 Query: "/* client c */ select * from t order by x", 762 Expected: []sql.Row{ 763 {1, 1}, 764 }, 765 }, 766 // Client b commits 767 { 768 Query: "/* client b */ commit", 769 Expected: []sql.Row{}, 770 }, 771 { 772 Query: "/* client a */ select * from t order by x", 773 Expected: []sql.Row{{1, 1}, {2, 2}, {3, 3}}, 774 }, 775 { 776 Query: "/* client a */ select * from t2 order by x", 777 Expected: []sql.Row{{10, 10}, {12, 12}}, 778 }, 779 { 780 Query: "/* client c */ select * from t2 order by x", 781 Expected: []sql.Row{{10, 10}, {11, 11}}, 782 }, 783 { 784 Query: "/* client c */ select * from t order by x", 785 Expected: []sql.Row{{1, 1}}, 786 }, 787 // Client c commits 788 { 789 Query: "/* client c */ commit", 790 Expected: []sql.Row{}, 791 }, 792 { 793 Query: "/* client a */ select * from t order by x", 794 Expected: []sql.Row{{1, 1}, {2, 2}, {3, 3}}, 795 }, 796 { 797 Query: "/* client a */ select * from t2 order by x", 798 Expected: []sql.Row{{10, 10}, {12, 12}}, 799 }, 800 { 801 Query: "/* client b */ select * from t order by x", 802 Expected: []sql.Row{{1, 1}, {2, 2}, {3, 3}}, 803 }, 804 { 805 Query: "/* client b */ select * from t2 order by x", 806 Expected: []sql.Row{{10, 10}, {11, 11}, {12, 12}}, 807 }, 808 // Client a starts transactions 809 { 810 Query: "/* client a */ start transaction", 811 Expected: []sql.Row{}, 812 }, 813 { 814 Query: "/* client a */ select * from t order by x", 815 Expected: []sql.Row{{1, 1}, {2, 2}, {3, 3}}, 816 }, 817 { 818 Query: "/* client b */ select * from t order by x", 819 Expected: []sql.Row{{1, 1}, {2, 2}, {3, 3}}, 820 }, 821 { 822 Query: "/* client c */ select * from t order by x", 823 Expected: []sql.Row{{1, 1}, {2, 2}, {3, 3}}, 824 }, 825 { 826 Query: "/* client a */ select * from t2 order by x", 827 Expected: []sql.Row{{10, 10}, {11, 11}, {12, 12}}, 828 }, 829 { 830 Query: "/* client b */ select * from t2 order by x", 831 Expected: []sql.Row{{10, 10}, {11, 11}, {12, 12}}, 832 }, 833 { 834 Query: "/* client c */ select * from t2 order by x", 835 Expected: []sql.Row{{10, 10}, {11, 11}, {12, 12}}, 836 }, 837 // Client a does a skip ahead 838 { 839 Query: "/* client a */ insert into t values (10, 10)", 840 Expected: []sql.Row{{types.OkResult{RowsAffected: 1, InsertID: 10}}}, 841 }, 842 { 843 Query: "/* client b */ insert into t (y) values (11)", 844 Expected: []sql.Row{{types.OkResult{RowsAffected: 1, InsertID: 11}}}, 845 }, 846 // Client c skips ahead 847 { 848 Query: "/* client c */ insert into t values (50, 50)", 849 Expected: []sql.Row{{types.OkResult{RowsAffected: 1, InsertID: 50}}}, 850 }, 851 { 852 Query: "/* client b */ insert into t (y) values (51)", 853 Expected: []sql.Row{{types.OkResult{RowsAffected: 1, InsertID: 51}}}, 854 }, 855 { 856 Query: "/* client a */ select * from t order by x", 857 Expected: []sql.Row{{1, 1}, {2, 2}, {3, 3}, {10, 10}}, 858 }, 859 { 860 Query: "/* client b */ select * from t order by x", 861 Expected: []sql.Row{{1, 1}, {2, 2}, {3, 3}, {11, 11}, {51, 51}}, 862 }, 863 { 864 Query: "/* client c */ select * from t order by x", 865 Expected: []sql.Row{{1, 1}, {2, 2}, {3, 3}, {50, 50}}, 866 }, 867 { 868 Query: "/* client a */ commit", 869 Expected: []sql.Row{}, 870 }, 871 { 872 Query: "/* client b */ commit", 873 Expected: []sql.Row{}, 874 }, 875 { 876 Query: "/* client c */ commit", 877 Expected: []sql.Row{}, 878 }, 879 { 880 Query: "/* client a */ select * from t order by x", 881 Expected: []sql.Row{{1, 1}, {2, 2}, {3, 3}, {10, 10}, {11, 11}, {50, 50}, {51, 51}}, 882 }, 883 { 884 Query: "/* client b */ select * from t order by x", 885 Expected: []sql.Row{{1, 1}, {2, 2}, {3, 3}, {10, 10}, {11, 11}, {50, 50}, {51, 51}}, 886 }, 887 { 888 Query: "/* client c */ select * from t order by x", 889 Expected: []sql.Row{{1, 1}, {2, 2}, {3, 3}, {10, 10}, {11, 11}, {50, 50}, {51, 51}}, 890 }, 891 // Client a does a simple insert to ensure merging worked 892 { 893 Query: "/* client a */ insert into t values (NULL, 52)", 894 Expected: []sql.Row{{types.OkResult{RowsAffected: 1, InsertID: 52}}}, 895 }, 896 { 897 Query: "/* client a */ select * from t order by x", 898 Expected: []sql.Row{{1, 1}, {2, 2}, {3, 3}, {10, 10}, {11, 11}, {50, 50}, {51, 51}, {52, 52}}, 899 }, 900 }, 901 }, 902 { 903 Name: "AUTO_INCREMENT transactions off", 904 SetUpScript: []string{ 905 "CREATE table t2 (x int PRIMARY KEY AUTO_INCREMENT, y int);", 906 "insert into t2 (y) values (1);", 907 }, 908 Assertions: []ScriptTestAssertion{ 909 { 910 Query: "/* client a */ insert into t2 (y) values (2)", 911 Expected: []sql.Row{{types.OkResult{RowsAffected: 1, InsertID: 2}}}, 912 }, 913 { 914 Query: "/* client b */ select * from t2 order by x", 915 Expected: []sql.Row{{1, 1}, {2, 2}}, 916 }, 917 { 918 Query: "/* client b */ insert into t2 (y) values (3)", 919 Expected: []sql.Row{{types.OkResult{RowsAffected: 1, InsertID: 3}}}, 920 }, 921 { 922 Query: "/* client a */ select * from t2 order by x", 923 Expected: []sql.Row{{1, 1}, {2, 2}, {3, 3}}, 924 }, 925 { 926 Query: "/* client a */ alter table t2 modify column x int", 927 Expected: []sql.Row{{types.OkResult{RowsAffected: 0, InsertID: 0}}}, 928 }, 929 { 930 Query: "/* client a */ INSERT INTO t2 values (NULL, 3)", 931 ExpectedErr: sql.ErrInsertIntoNonNullableProvidedNull, 932 }, 933 { 934 Query: "/* client a */ DROP TABLE t2", 935 Expected: []sql.Row{{types.OkResult{RowsAffected: 0, InsertID: 0}}}, 936 }, 937 { 938 Query: "/* client a */ CREATE table t2 (x int PRIMARY KEY AUTO_INCREMENT, y int)", 939 Expected: []sql.Row{{types.OkResult{RowsAffected: 0, InsertID: 0}}}, 940 }, 941 { 942 Query: "/* client a */ insert into t2 (y) values (4)", 943 Expected: []sql.Row{{types.OkResult{RowsAffected: 1, InsertID: 1}}}, 944 }, 945 { 946 Query: "/* client a */ SELECT * FROM t2", 947 Expected: []sql.Row{{1, 4}}, 948 }, 949 }, 950 }, 951 { 952 Name: "READ ONLY Transactions", 953 SetUpScript: []string{ 954 "create table t2 (pk int primary key, val int)", 955 "insert into t2 values (0,0)", 956 "commit", 957 }, 958 Assertions: []ScriptTestAssertion{ 959 { 960 Query: "/* client a */ set autocommit = off", 961 Expected: []sql.Row{{}}, 962 }, 963 { 964 Query: "/* client a */ create temporary table tmp(pk int primary key)", 965 Expected: []sql.Row{{types.NewOkResult(0)}}, 966 }, 967 { 968 Query: "/* client a */ START TRANSACTION READ ONLY", 969 Expected: []sql.Row{}, 970 }, 971 { 972 Query: "/* client a */ INSERT INTO tmp VALUES (1)", 973 Expected: []sql.Row{{types.NewOkResult(1)}}, 974 }, 975 { 976 Query: "/* client a */ insert into t2 values (1, 1)", 977 ExpectedErr: sql.ErrReadOnlyTransaction, 978 }, 979 { 980 Query: "/* client a */ insert into t2 values (2, 2)", 981 ExpectedErr: sql.ErrReadOnlyTransaction, 982 }, 983 { 984 Query: "/* client a */ delete from t2 where pk = 0", 985 ExpectedErr: sql.ErrReadOnlyTransaction, 986 }, 987 { 988 989 Query: "/* client a */ alter table t2 add val2 int", 990 Expected: []sql.Row{{types.NewOkResult(0)}}, 991 }, 992 { 993 Query: "/* client a */ select * from t2", 994 Expected: []sql.Row{{0, 0, nil}}, 995 }, 996 { 997 Query: "/* client a */ create temporary table tmp2(pk int primary key)", 998 ExpectedErr: sql.ErrReadOnlyTransaction, 999 }, 1000 { 1001 Query: "/* client a */ COMMIT", 1002 Expected: []sql.Row{}, 1003 }, 1004 { 1005 Query: "/* client b */ START TRANSACTION READ ONLY", 1006 Expected: []sql.Row{}, 1007 }, 1008 { 1009 Query: "/* client b */ SELECT * FROM t2", 1010 Expected: []sql.Row{{0, 0, nil}}, 1011 }, 1012 }, 1013 }, 1014 { 1015 Name: "Insert error with auto commit off", 1016 SetUpScript: []string{ 1017 "create table t1 (pk int primary key, val int)", 1018 "insert into t1 values (0,0)", 1019 }, 1020 Assertions: []ScriptTestAssertion{ 1021 { 1022 Query: "/* client a */ set autocommit = off", 1023 SkipResultsCheck: true, 1024 }, 1025 { 1026 Query: "/* client b */ set autocommit = off", 1027 SkipResultsCheck: true, 1028 }, 1029 { 1030 Query: "/* client a */ insert into t1 values (1, 1)", 1031 Expected: []sql.Row{{types.NewOkResult(1)}}, 1032 }, 1033 { 1034 Query: "/* client a */ insert into t1 values (1, 2)", 1035 ExpectedErr: sql.ErrPrimaryKeyViolation, 1036 }, 1037 { 1038 Query: "/* client a */ insert into t1 values (2, 2)", 1039 Expected: []sql.Row{{types.NewOkResult(1)}}, 1040 }, 1041 { 1042 Query: "/* client a */ select * from t1 order by pk", 1043 Expected: []sql.Row{{0, 0}, {1, 1}, {2, 2}}, 1044 }, 1045 { 1046 Query: "/* client b */ select * from t1 order by pk", 1047 Expected: []sql.Row{{0, 0}}, 1048 }, 1049 { 1050 Query: "/* client a */ commit", 1051 SkipResultsCheck: true, 1052 }, 1053 { 1054 Query: "/* client b */ start transaction", 1055 SkipResultsCheck: true, 1056 }, 1057 { 1058 Query: "/* client b */ select * from t1 order by pk", 1059 Expected: []sql.Row{{0, 0}, {1, 1}, {2, 2}}, 1060 }, 1061 { 1062 Query: "/* client a */ select * from t1 order by pk", 1063 Expected: []sql.Row{{0, 0}, {1, 1}, {2, 2}}, 1064 }, 1065 }, 1066 }, 1067 }