github.com/hasnat/dolt/go@v0.0.0-20210628190320-9eb5d843fbb7/libraries/doltcore/sqle/enginetest/dolt_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 enginetest 16 17 import ( 18 "github.com/dolthub/go-mysql-server/enginetest" 19 "github.com/dolthub/go-mysql-server/sql" 20 "github.com/dolthub/go-mysql-server/sql/plan" 21 ) 22 23 var DoltTransactionTests = []enginetest.TransactionTest{ 24 { 25 Name: "duplicate inserts, autocommit on", 26 SetUpScript: []string{ 27 "create table t (x int primary key, y int)", 28 "insert into t values (1, 1)", 29 }, 30 Assertions: []enginetest.ScriptTestAssertion{ 31 { 32 Query: "/* client a */ insert into t values (2, 2)", 33 Expected: []sql.Row{{sql.NewOkResult(1)}}, 34 }, 35 { 36 Query: "/* client b */ insert into t values (2, 2)", 37 ExpectedErr: sql.ErrPrimaryKeyViolation, 38 }, 39 }, 40 }, 41 { 42 Name: "duplicate inserts, autocommit off", 43 SetUpScript: []string{ 44 "create table t (x int primary key, y int)", 45 "insert into t values (1, 1)", 46 }, 47 Assertions: []enginetest.ScriptTestAssertion{ 48 { 49 Query: "/* client a */ start transaction", 50 Expected: []sql.Row{}, 51 }, 52 { 53 Query: "/* client b */ start transaction", 54 Expected: []sql.Row{}, 55 }, 56 { 57 Query: "/* client a */ insert into t values (2, 2)", 58 Expected: []sql.Row{{sql.NewOkResult(1)}}, 59 }, 60 { 61 Query: "/* client b */ insert into t values (2, 2)", 62 Expected: []sql.Row{{sql.NewOkResult(1)}}, 63 }, 64 { 65 Query: "/* client a */ commit", 66 Expected: []sql.Row{}, 67 }, 68 { 69 Query: "/* client b */ commit", 70 Expected: []sql.Row{}, 71 }, 72 { 73 Query: "/* client a */ select * from t order by x", 74 Expected: []sql.Row{{1, 1}, {2, 2}}, 75 }, 76 { 77 Query: "/* client b */ select * from t order by x", 78 Expected: []sql.Row{{1, 1}, {2, 2}}, 79 }, 80 }, 81 }, 82 { 83 Name: "conflicting inserts", 84 SetUpScript: []string{ 85 "create table t (x int primary key, y int)", 86 "insert into t values (1, 1)", 87 }, 88 Assertions: []enginetest.ScriptTestAssertion{ 89 { 90 Query: "/* client a */ start transaction", 91 Expected: []sql.Row{}, 92 }, 93 { 94 Query: "/* client b */ start transaction", 95 Expected: []sql.Row{}, 96 }, 97 { 98 Query: "/* client a */ insert into t values (2, 2)", 99 Expected: []sql.Row{{sql.NewOkResult(1)}}, 100 }, 101 { 102 Query: "/* client b */ insert into t values (2, 3)", 103 Expected: []sql.Row{{sql.NewOkResult(1)}}, 104 }, 105 { 106 Query: "/* client a */ commit", 107 Expected: []sql.Row{}, 108 }, 109 { 110 Query: "/* client b */ commit", 111 ExpectedErrStr: "conflict in table t", 112 }, 113 { 114 Query: "/* client a */ select * from t order by x", 115 Expected: []sql.Row{{1, 1}, {2, 2}}, 116 }, 117 // TODO: behavior right now is to leave the session state dirty on an unsuccessful commit, letting the 118 // client choose whether to rollback or not. Not clear if this is the right behavior for a failed commit. 119 { 120 Query: "/* client b */ select * from t order by x", 121 Expected: []sql.Row{{1, 1}, {2, 3}}, 122 }, 123 { 124 Query: "/* client b */ rollback", 125 Expected: []sql.Row{}, 126 }, 127 { 128 Query: "/* client b */ select * from t order by x", 129 Expected: []sql.Row{{1, 1}, {2, 2}}, 130 }, 131 }, 132 }, 133 { 134 Name: "duplicate updates, autocommit on", 135 SetUpScript: []string{ 136 "create table t (x int primary key, y int)", 137 "insert into t values (1, 1), (2, 2)", 138 }, 139 Assertions: []enginetest.ScriptTestAssertion{ 140 { 141 Query: "/* client a */ update t set y = 2", 142 Expected: []sql.Row{{sql.OkResult{ 143 RowsAffected: uint64(1), 144 Info: plan.UpdateInfo{ 145 Matched: 2, 146 Updated: 1, 147 }, 148 }}}, 149 }, 150 { 151 Query: "/* client b */ update t set y = 2", 152 Expected: []sql.Row{{sql.OkResult{ 153 RowsAffected: uint64(0), 154 Info: plan.UpdateInfo{ 155 Matched: 2, 156 Updated: 0, 157 }, 158 }}}, 159 }, 160 { 161 Query: "/* client a */ select * from t order by x", 162 Expected: []sql.Row{{1, 2}, {2, 2}}, 163 }, 164 { 165 Query: "/* client b */ select * from t order by x", 166 Expected: []sql.Row{{1, 2}, {2, 2}}, 167 }, 168 }, 169 }, 170 { 171 Name: "duplicate updates, autocommit off", 172 SetUpScript: []string{ 173 "create table t (x int primary key, y int)", 174 "insert into t values (1, 1), (2, 2)", 175 }, 176 Assertions: []enginetest.ScriptTestAssertion{ 177 { 178 Query: "/* client a */ start transaction", 179 Expected: []sql.Row{}, 180 }, 181 { 182 Query: "/* client b */ start transaction", 183 Expected: []sql.Row{}, 184 }, 185 { 186 Query: "/* client a */ update t set y = 2", 187 Expected: []sql.Row{{sql.OkResult{ 188 RowsAffected: uint64(1), 189 Info: plan.UpdateInfo{ 190 Matched: 2, 191 Updated: 1, 192 }, 193 }}}, 194 }, 195 { 196 Query: "/* client b */ update t set y = 2", 197 Expected: []sql.Row{{sql.OkResult{ 198 RowsAffected: uint64(1), 199 Info: plan.UpdateInfo{ 200 Matched: 2, 201 Updated: 1, 202 }, 203 }}}, 204 }, 205 { 206 Query: "/* client a */ commit", 207 Expected: []sql.Row{}, 208 }, 209 { 210 Query: "/* client b */ commit", 211 Expected: []sql.Row{}, 212 }, 213 { 214 Query: "/* client a */ select * from t order by x", 215 Expected: []sql.Row{{1, 2}, {2, 2}}, 216 }, 217 { 218 Query: "/* client b */ select * from t order by x", 219 Expected: []sql.Row{{1, 2}, {2, 2}}, 220 }, 221 }, 222 }, 223 { 224 Name: "conflicting updates", 225 SetUpScript: []string{ 226 "create table t (x int primary key, y int)", 227 "insert into t values (1, 1), (2, 2)", 228 }, 229 Assertions: []enginetest.ScriptTestAssertion{ 230 { 231 Query: "/* client a */ start transaction", 232 Expected: []sql.Row{}, 233 }, 234 { 235 Query: "/* client b */ start transaction", 236 Expected: []sql.Row{}, 237 }, 238 { 239 Query: "/* client a */ update t set y = 3", 240 Expected: []sql.Row{{sql.OkResult{ 241 RowsAffected: uint64(2), 242 Info: plan.UpdateInfo{ 243 Matched: 2, 244 Updated: 2, 245 }, 246 }}}, 247 }, 248 { 249 Query: "/* client b */ update t set y = 4", 250 Expected: []sql.Row{{sql.OkResult{ 251 RowsAffected: uint64(2), 252 Info: plan.UpdateInfo{ 253 Matched: 2, 254 Updated: 2, 255 }, 256 }}}, 257 }, 258 { 259 Query: "/* client a */ commit", 260 Expected: []sql.Row{}, 261 }, 262 { 263 Query: "/* client b */ commit", 264 ExpectedErrStr: "conflict in table t", 265 }, 266 { 267 Query: "/* client a */ select * from t order by x", 268 Expected: []sql.Row{{1, 3}, {2, 3}}, 269 }, 270 { 271 Query: "/* client b */ select * from t order by x", 272 Expected: []sql.Row{{1, 4}, {2, 4}}, 273 }, 274 { 275 Query: "/* client b */ rollback", 276 Expected: []sql.Row{}, 277 }, 278 { 279 Query: "/* client b */ select * from t order by x", 280 Expected: []sql.Row{{1, 3}, {2, 3}}, 281 }, 282 }, 283 }, 284 { 285 Name: "conflicting updates, resolved with more updates", 286 SetUpScript: []string{ 287 "create table t (x int primary key, y int)", 288 "insert into t values (1, 1), (2, 2)", 289 }, 290 Assertions: []enginetest.ScriptTestAssertion{ 291 { 292 Query: "/* client a */ start transaction", 293 Expected: []sql.Row{}, 294 }, 295 { 296 Query: "/* client b */ start transaction", 297 Expected: []sql.Row{}, 298 }, 299 { 300 Query: "/* client a */ update t set y = 3", 301 Expected: []sql.Row{{sql.OkResult{ 302 RowsAffected: uint64(2), 303 Info: plan.UpdateInfo{ 304 Matched: 2, 305 Updated: 2, 306 }, 307 }}}, 308 }, 309 { 310 Query: "/* client b */ update t set y = 4", 311 Expected: []sql.Row{{sql.OkResult{ 312 RowsAffected: uint64(2), 313 Info: plan.UpdateInfo{ 314 Matched: 2, 315 Updated: 2, 316 }, 317 }}}, 318 }, 319 { 320 Query: "/* client a */ commit", 321 Expected: []sql.Row{}, 322 }, 323 { 324 Query: "/* client b */ commit", 325 ExpectedErrStr: "conflict in table t", 326 }, 327 { 328 Query: "/* client b */ update t set y = 3", 329 Expected: []sql.Row{{sql.OkResult{ 330 RowsAffected: uint64(2), 331 Info: plan.UpdateInfo{ 332 Matched: 2, 333 Updated: 2, 334 }, 335 }}}, 336 }, 337 { 338 Query: "/* client b */ commit", 339 Expected: []sql.Row{}, 340 }, 341 { 342 Query: "/* client a */ select * from t order by x", 343 Expected: []sql.Row{{1, 3}, {2, 3}}, 344 }, 345 { 346 Query: "/* client b */ select * from t order by x", 347 Expected: []sql.Row{{1, 3}, {2, 3}}, 348 }, 349 }, 350 }, 351 { 352 Name: "non overlapping updates (diff rows)", 353 SetUpScript: []string{ 354 "create table t (x int primary key, y int)", 355 "insert into t values (1, 1), (2, 2)", 356 }, 357 Assertions: []enginetest.ScriptTestAssertion{ 358 { 359 Query: "/* client a */ start transaction", 360 Expected: []sql.Row{}, 361 }, 362 { 363 Query: "/* client b */ start transaction", 364 Expected: []sql.Row{}, 365 }, 366 { 367 Query: "/* client a */ update t set y = 3 where x = 1", 368 Expected: []sql.Row{{sql.OkResult{ 369 RowsAffected: uint64(1), 370 Info: plan.UpdateInfo{ 371 Matched: 1, 372 Updated: 1, 373 }, 374 }}}, 375 }, 376 { 377 Query: "/* client b */ update t set y = 4 where x = 2", 378 Expected: []sql.Row{{sql.OkResult{ 379 RowsAffected: uint64(1), 380 Info: plan.UpdateInfo{ 381 Matched: 1, 382 Updated: 1, 383 }, 384 }}}, 385 }, 386 { 387 Query: "/* client a */ commit", 388 Expected: []sql.Row{}, 389 }, 390 { 391 Query: "/* client b */ commit", 392 Expected: []sql.Row{}, 393 }, 394 { 395 Query: "/* client a */ select * from t order by x", 396 Expected: []sql.Row{{1, 3}, {2, 4}}, 397 }, 398 { 399 Query: "/* client b */ select * from t order by x", 400 Expected: []sql.Row{{1, 3}, {2, 4}}, 401 }, 402 }, 403 }, 404 { 405 Name: "non overlapping updates (diff cols)", 406 SetUpScript: []string{ 407 "create table t (x int primary key, y int, z int)", 408 "insert into t values (1, 1, 1), (2, 2, 2)", 409 }, 410 Assertions: []enginetest.ScriptTestAssertion{ 411 { 412 Query: "/* client a */ start transaction", 413 Expected: []sql.Row{}, 414 }, 415 { 416 Query: "/* client b */ start transaction", 417 Expected: []sql.Row{}, 418 }, 419 { 420 Query: "/* client a */ update t set y = 2", 421 Expected: []sql.Row{{sql.OkResult{ 422 RowsAffected: uint64(1), 423 Info: plan.UpdateInfo{ 424 Matched: 2, 425 Updated: 1, 426 }, 427 }}}, 428 }, 429 { 430 Query: "/* client b */ update t set z = 3", 431 Expected: []sql.Row{{sql.OkResult{ 432 RowsAffected: uint64(2), 433 Info: plan.UpdateInfo{ 434 Matched: 2, 435 Updated: 2, 436 }, 437 }}}, 438 }, 439 { 440 Query: "/* client a */ commit", 441 Expected: []sql.Row{}, 442 }, 443 { 444 Query: "/* client b */ commit", 445 Expected: []sql.Row{}, 446 }, 447 { 448 Query: "/* client a */ select * from t order by x", 449 Expected: []sql.Row{{1, 2, 3}, {2, 2, 3}}, 450 }, 451 { 452 Query: "/* client b */ select * from t order by x", 453 Expected: []sql.Row{{1, 2, 3}, {2, 2, 3}}, 454 }, 455 }, 456 }, 457 { 458 Name: "duplicate deletes, autocommit on", 459 SetUpScript: []string{ 460 "create table t (x int primary key, y int)", 461 "insert into t values (1, 1), (2, 2)", 462 }, 463 Assertions: []enginetest.ScriptTestAssertion{ 464 { 465 Query: "/* client a */ delete from t where y = 2", 466 Expected: []sql.Row{{sql.NewOkResult(1)}}, 467 }, 468 { 469 Query: "/* client b */ delete from t where y = 2", 470 Expected: []sql.Row{{sql.NewOkResult(0)}}, 471 }, 472 { 473 Query: "/* client a */ select * from t order by x", 474 Expected: []sql.Row{{1, 1}}, 475 }, 476 { 477 Query: "/* client b */ select * from t order by x", 478 Expected: []sql.Row{{1, 1}}, 479 }, 480 }, 481 }, 482 { 483 Name: "duplicate deletes, autocommit off", 484 SetUpScript: []string{ 485 "create table t (x int primary key, y int)", 486 "insert into t values (1, 1), (2, 2)", 487 }, 488 Assertions: []enginetest.ScriptTestAssertion{ 489 { 490 Query: "/* client a */ start transaction", 491 Expected: []sql.Row{}, 492 }, 493 { 494 Query: "/* client b */ start transaction", 495 Expected: []sql.Row{}, 496 }, 497 { 498 Query: "/* client a */ delete from t where y = 2", 499 Expected: []sql.Row{{sql.NewOkResult(1)}}, 500 }, 501 { 502 Query: "/* client b */ delete from t where y = 2", 503 Expected: []sql.Row{{sql.NewOkResult(1)}}, 504 }, 505 { 506 Query: "/* client a */ commit", 507 Expected: []sql.Row{}, 508 }, 509 { 510 Query: "/* client b */ commit", 511 Expected: []sql.Row{}, 512 }, 513 { 514 Query: "/* client a */ select * from t order by x", 515 Expected: []sql.Row{{1, 1}}, 516 }, 517 { 518 Query: "/* client b */ select * from t order by x", 519 Expected: []sql.Row{{1, 1}}, 520 }, 521 }, 522 }, 523 { 524 Name: "non overlapping deletes", 525 SetUpScript: []string{ 526 "create table t (x int primary key, y int)", 527 "insert into t values (1, 1), (2, 2), (3, 3)", 528 }, 529 Assertions: []enginetest.ScriptTestAssertion{ 530 { 531 Query: "/* client a */ start transaction", 532 Expected: []sql.Row{}, 533 }, 534 { 535 Query: "/* client b */ start transaction", 536 Expected: []sql.Row{}, 537 }, 538 { 539 Query: "/* client a */ delete from t where y = 2", 540 Expected: []sql.Row{{sql.NewOkResult(1)}}, 541 }, 542 { 543 Query: "/* client b */ delete from t where y = 3", 544 Expected: []sql.Row{{sql.NewOkResult(1)}}, 545 }, 546 { 547 Query: "/* client a */ commit", 548 Expected: []sql.Row{}, 549 }, 550 { 551 Query: "/* client b */ commit", 552 Expected: []sql.Row{}, 553 }, 554 { 555 Query: "/* client a */ select * from t order by x", 556 Expected: []sql.Row{{1, 1}}, 557 }, 558 { 559 Query: "/* client b */ select * from t order by x", 560 Expected: []sql.Row{{1, 1}}, 561 }, 562 }, 563 }, 564 { 565 Name: "conflicting delete and update", 566 SetUpScript: []string{ 567 "create table t (x int primary key, y int)", 568 "insert into t values (1, 1), (2, 2)", 569 }, 570 Assertions: []enginetest.ScriptTestAssertion{ 571 { 572 Query: "/* client a */ start transaction", 573 Expected: []sql.Row{}, 574 }, 575 { 576 Query: "/* client b */ start transaction", 577 Expected: []sql.Row{}, 578 }, 579 { 580 Query: "/* client a */ update t set y = 3 where y = 2", 581 Expected: []sql.Row{{sql.OkResult{ 582 RowsAffected: uint64(1), 583 Info: plan.UpdateInfo{ 584 Matched: 1, 585 Updated: 1, 586 }, 587 }}}, 588 }, 589 { 590 Query: "/* client b */ delete from t where y = 2", 591 Expected: []sql.Row{{sql.NewOkResult(1)}}, 592 }, 593 { 594 Query: "/* client a */ commit", 595 Expected: []sql.Row{}, 596 }, 597 { 598 Query: "/* client b */ commit", 599 ExpectedErrStr: "conflict in table t", 600 }, 601 { 602 Query: "/* client b */ rollback", 603 Expected: []sql.Row{}, 604 }, 605 { 606 Query: "/* client a */ select * from t order by x", 607 Expected: []sql.Row{{1, 1}, {2, 3}}, 608 }, 609 { 610 Query: "/* client b */ select * from t order by x", 611 Expected: []sql.Row{{1, 1}, {2, 3}}, 612 }, 613 }, 614 }, 615 { 616 Name: "delete in one client, insert into another", 617 SetUpScript: []string{ 618 "create table t (x int primary key, y int)", 619 "insert into t values (1, 1), (2, 2)", 620 }, 621 Assertions: []enginetest.ScriptTestAssertion{ 622 { 623 Query: "/* client a */ start transaction", 624 Expected: []sql.Row{}, 625 }, 626 { 627 Query: "/* client b */ start transaction", 628 Expected: []sql.Row{}, 629 }, 630 { 631 Query: "/* client a */ delete from t where y = 1", 632 Expected: []sql.Row{{sql.NewOkResult(1)}}, 633 }, 634 { 635 Query: "/* client b */ delete from t", 636 Expected: []sql.Row{{sql.NewOkResult(2)}}, 637 }, 638 { 639 Query: "/* client b */ insert into t values (1,1)", 640 Expected: []sql.Row{{sql.NewOkResult(1)}}, 641 }, 642 { 643 Query: "/* client a */ commit", 644 Expected: []sql.Row{}, 645 }, 646 { 647 Query: "/* client b */ commit", 648 Expected: []sql.Row{}, 649 }, 650 { 651 Query: "/* client a */ select * from t order by x", 652 Expected: []sql.Row{}, 653 }, 654 { 655 Query: "/* client b */ select * from t order by x", 656 Expected: []sql.Row{}, 657 }, 658 }, 659 }, 660 { 661 Name: "multiple client edit session", 662 SetUpScript: []string{ 663 "create table t (x int primary key, y int, z int)", 664 "insert into t values (1, 1, 1), (2, 2, 2)", 665 }, 666 Assertions: []enginetest.ScriptTestAssertion{ 667 { 668 Query: "/* client a */ start transaction", 669 Expected: []sql.Row{}, 670 }, 671 { 672 Query: "/* client b */ start transaction", 673 Expected: []sql.Row{}, 674 }, 675 { 676 Query: "/* client c */ start transaction", 677 Expected: []sql.Row{}, 678 }, 679 { 680 Query: "/* client a */ update t set y = 3 where y = 2", 681 Expected: []sql.Row{{sql.OkResult{ 682 RowsAffected: uint64(1), 683 Info: plan.UpdateInfo{ 684 Matched: 1, 685 Updated: 1, 686 }, 687 }}}, 688 }, 689 { 690 Query: "/* client b */ delete from t where y = 1", 691 Expected: []sql.Row{{sql.NewOkResult(1)}}, 692 }, 693 { 694 Query: "/* client c */ update t set z = 4 where y = 2", 695 Expected: []sql.Row{{sql.OkResult{ 696 RowsAffected: uint64(1), 697 Info: plan.UpdateInfo{ 698 Matched: 1, 699 Updated: 1, 700 }, 701 }}}, 702 }, 703 { 704 Query: "/* client a */ commit", 705 Expected: []sql.Row{}, 706 }, 707 { 708 Query: "/* client b */ commit", 709 Expected: []sql.Row{}, 710 }, 711 { 712 Query: "/* client a */ select * from t order by x", 713 Expected: []sql.Row{{2, 3, 2}}, 714 }, 715 { 716 Query: "/* client b */ select * from t order by x", 717 Expected: []sql.Row{{2, 3, 2}}, 718 }, 719 { 720 Query: "/* client c */ select * from t order by x", 721 Expected: []sql.Row{{1, 1, 1}, {2, 2, 4}}, 722 }, 723 { 724 Query: "/* client c */ commit", 725 Expected: []sql.Row{}, 726 }, 727 { 728 Query: "/* client a */ select * from t order by x", 729 Expected: []sql.Row{{2, 3, 4}}, 730 }, 731 { 732 Query: "/* client b */ select * from t order by x", 733 Expected: []sql.Row{{2, 3, 4}}, 734 }, 735 { 736 Query: "/* client c */ select * from t order by x", 737 Expected: []sql.Row{{2, 3, 4}}, 738 }, 739 }, 740 }, 741 }