github.com/dolthub/dolt/go@v0.40.5-0.20240520175717-68db7794bea6/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/queries" 19 "github.com/dolthub/go-mysql-server/sql" 20 "github.com/dolthub/go-mysql-server/sql/plan" 21 "github.com/dolthub/go-mysql-server/sql/types" 22 23 "github.com/dolthub/dolt/go/libraries/doltcore/sqle/dsess" 24 ) 25 26 var DoltTransactionTests = []queries.TransactionTest{ 27 { 28 // Repro for https://github.com/dolthub/dolt/issues/3402 29 Name: "DDL changes from transactions are available before analyzing statements in other sessions (autocommit on)", 30 Assertions: []queries.ScriptTestAssertion{ 31 { 32 Query: "/* client a */ select @@autocommit;", 33 Expected: []sql.Row{{1}}, 34 }, 35 { 36 Query: "/* client b */ select @@autocommit;", 37 Expected: []sql.Row{{1}}, 38 }, 39 { 40 Query: "/* client a */ select * from t;", 41 ExpectedErr: sql.ErrTableNotFound, 42 }, 43 { 44 Query: "/* client b */ select * from t;", 45 ExpectedErr: sql.ErrTableNotFound, 46 }, 47 { 48 Query: "/* client a */ create table t(pk int primary key);", 49 Expected: []sql.Row{{types.OkResult{}}}, 50 }, 51 { 52 Query: "/* client b */ select count(*) from t;", 53 Expected: []sql.Row{{0}}, 54 }, 55 }, 56 }, 57 { 58 Name: "duplicate inserts, autocommit on", 59 SetUpScript: []string{ 60 "create table t (x int primary key, y int)", 61 "insert into t values (1, 1)", 62 }, 63 Assertions: []queries.ScriptTestAssertion{ 64 { 65 Query: "/* client a */ insert into t values (2, 2)", 66 Expected: []sql.Row{{types.NewOkResult(1)}}, 67 }, 68 { 69 Query: "/* client b */ insert into t values (2, 2)", 70 ExpectedErr: sql.ErrPrimaryKeyViolation, 71 }, 72 }, 73 }, 74 { 75 Name: "duplicate inserts, autocommit off", 76 SetUpScript: []string{ 77 "create table t (x int primary key, y int)", 78 "insert into t values (1, 1)", 79 }, 80 Assertions: []queries.ScriptTestAssertion{ 81 { 82 Query: "/* client a */ start transaction", 83 Expected: []sql.Row{}, 84 }, 85 { 86 Query: "/* client b */ start transaction", 87 Expected: []sql.Row{}, 88 }, 89 { 90 Query: "/* client a */ insert into t values (2, 2)", 91 Expected: []sql.Row{{types.NewOkResult(1)}}, 92 }, 93 { 94 Query: "/* client b */ insert into t values (2, 2)", 95 Expected: []sql.Row{{types.NewOkResult(1)}}, 96 }, 97 { 98 Query: "/* client a */ commit", 99 Expected: []sql.Row{}, 100 }, 101 { 102 Query: "/* client b */ commit", 103 Expected: []sql.Row{}, 104 }, 105 { 106 Query: "/* client a */ select * from t order by x", 107 Expected: []sql.Row{{1, 1}, {2, 2}}, 108 }, 109 { 110 Query: "/* client b */ select * from t order by x", 111 Expected: []sql.Row{{1, 1}, {2, 2}}, 112 }, 113 }, 114 }, 115 { 116 Name: "conflicting inserts", 117 SetUpScript: []string{ 118 "create table t (x int primary key, y int)", 119 "insert into t values (1, 1)", 120 }, 121 Assertions: []queries.ScriptTestAssertion{ 122 { 123 Query: "/* client a */ start transaction", 124 Expected: []sql.Row{}, 125 }, 126 { 127 Query: "/* client b */ start transaction", 128 Expected: []sql.Row{}, 129 }, 130 { 131 Query: "/* client a */ insert into t values (2, 2)", 132 Expected: []sql.Row{{types.NewOkResult(1)}}, 133 }, 134 { 135 Query: "/* client b */ insert into t values (2, 3)", 136 Expected: []sql.Row{{types.NewOkResult(1)}}, 137 }, 138 { 139 Query: "/* client a */ commit", 140 Expected: []sql.Row{}, 141 }, 142 { 143 Query: "/* client b */ commit", 144 ExpectedErrStr: sql.ErrLockDeadlock.New(dsess.ErrRetryTransaction.Error()).Error(), 145 }, 146 { 147 Query: "/* client a */ select * from t order by x", 148 Expected: []sql.Row{{1, 1}, {2, 2}}, 149 }, 150 { // client b gets a rollback after failed commit, so gets a new tx 151 Query: "/* client b */ select * from t order by x", 152 Expected: []sql.Row{{1, 1}, {2, 2}}, 153 }, 154 { 155 Query: "/* client b */ select * from t order by x", 156 Expected: []sql.Row{{1, 1}, {2, 2}}, 157 }, 158 { 159 Query: "/* client b */ insert into t values (2, 3)", 160 ExpectedErrStr: "duplicate primary key given: [2]", 161 }, 162 }, 163 }, 164 { 165 Name: "duplicate updates, autocommit on", 166 SetUpScript: []string{ 167 "create table t (x int primary key, y int)", 168 "insert into t values (1, 1), (2, 2)", 169 }, 170 Assertions: []queries.ScriptTestAssertion{ 171 { 172 Query: "/* client a */ update t set y = 2", 173 Expected: []sql.Row{{types.OkResult{ 174 RowsAffected: uint64(1), 175 Info: plan.UpdateInfo{ 176 Matched: 2, 177 Updated: 1, 178 }, 179 }}}, 180 }, 181 { 182 Query: "/* client b */ update t set y = 2", 183 Expected: []sql.Row{{types.OkResult{ 184 RowsAffected: uint64(0), 185 Info: plan.UpdateInfo{ 186 Matched: 2, 187 Updated: 0, 188 }, 189 }}}, 190 }, 191 { 192 Query: "/* client a */ select * from t order by x", 193 Expected: []sql.Row{{1, 2}, {2, 2}}, 194 }, 195 { 196 Query: "/* client b */ select * from t order by x", 197 Expected: []sql.Row{{1, 2}, {2, 2}}, 198 }, 199 }, 200 }, 201 { 202 Name: "duplicate updates, autocommit off", 203 SetUpScript: []string{ 204 "create table t (x int primary key, y int)", 205 "insert into t values (1, 1), (2, 2)", 206 }, 207 Assertions: []queries.ScriptTestAssertion{ 208 { 209 Query: "/* client a */ start transaction", 210 Expected: []sql.Row{}, 211 }, 212 { 213 Query: "/* client b */ start transaction", 214 Expected: []sql.Row{}, 215 }, 216 { 217 Query: "/* client a */ update t set y = 2", 218 Expected: []sql.Row{{types.OkResult{ 219 RowsAffected: uint64(1), 220 Info: plan.UpdateInfo{ 221 Matched: 2, 222 Updated: 1, 223 }, 224 }}}, 225 }, 226 { 227 Query: "/* client b */ update t set y = 2", 228 Expected: []sql.Row{{types.OkResult{ 229 RowsAffected: uint64(1), 230 Info: plan.UpdateInfo{ 231 Matched: 2, 232 Updated: 1, 233 }, 234 }}}, 235 }, 236 { 237 Query: "/* client a */ commit", 238 Expected: []sql.Row{}, 239 }, 240 { 241 Query: "/* client b */ commit", 242 Expected: []sql.Row{}, 243 }, 244 { 245 Query: "/* client a */ select * from t order by x", 246 Expected: []sql.Row{{1, 2}, {2, 2}}, 247 }, 248 { 249 Query: "/* client b */ select * from t order by x", 250 Expected: []sql.Row{{1, 2}, {2, 2}}, 251 }, 252 }, 253 }, 254 { 255 Name: "conflicting updates", 256 SetUpScript: []string{ 257 "create table t (x int primary key, y int)", 258 "insert into t values (1, 1), (2, 2)", 259 }, 260 Assertions: []queries.ScriptTestAssertion{ 261 { 262 Query: "/* client a */ start transaction", 263 Expected: []sql.Row{}, 264 }, 265 { 266 Query: "/* client b */ start transaction", 267 Expected: []sql.Row{}, 268 }, 269 { 270 Query: "/* client a */ update t set y = 3", 271 Expected: []sql.Row{{types.OkResult{ 272 RowsAffected: uint64(2), 273 Info: plan.UpdateInfo{ 274 Matched: 2, 275 Updated: 2, 276 }, 277 }}}, 278 }, 279 { 280 Query: "/* client b */ update t set y = 4", 281 Expected: []sql.Row{{types.OkResult{ 282 RowsAffected: uint64(2), 283 Info: plan.UpdateInfo{ 284 Matched: 2, 285 Updated: 2, 286 }, 287 }}}, 288 }, 289 { 290 Query: "/* client a */ commit", 291 Expected: []sql.Row{}, 292 }, 293 { 294 Query: "/* client b */ commit", 295 ExpectedErrStr: sql.ErrLockDeadlock.New(dsess.ErrRetryTransaction.Error()).Error(), 296 }, 297 { 298 Query: "/* client a */ select * from t order by x", 299 Expected: []sql.Row{{1, 3}, {2, 3}}, 300 }, 301 { // client b got rolled back when its commit failed, so it sees the same values as client a 302 Query: "/* client b */ select * from t order by x", 303 Expected: []sql.Row{{1, 3}, {2, 3}}, 304 }, 305 { 306 Query: "/* client b */ rollback", 307 Expected: []sql.Row{}, 308 }, 309 { 310 Query: "/* client b */ select * from t order by x", 311 Expected: []sql.Row{{1, 3}, {2, 3}}, 312 }, 313 }, 314 }, 315 { 316 Name: "non overlapping updates (diff rows)", 317 SetUpScript: []string{ 318 "create table t (x int primary key, y int)", 319 "insert into t values (1, 1), (2, 2)", 320 }, 321 Assertions: []queries.ScriptTestAssertion{ 322 { 323 Query: "/* client a */ start transaction", 324 Expected: []sql.Row{}, 325 }, 326 { 327 Query: "/* client b */ start transaction", 328 Expected: []sql.Row{}, 329 }, 330 { 331 Query: "/* client a */ update t set y = 3 where x = 1", 332 Expected: []sql.Row{{types.OkResult{ 333 RowsAffected: uint64(1), 334 Info: plan.UpdateInfo{ 335 Matched: 1, 336 Updated: 1, 337 }, 338 }}}, 339 }, 340 { 341 Query: "/* client b */ update t set y = 4 where x = 2", 342 Expected: []sql.Row{{types.OkResult{ 343 RowsAffected: uint64(1), 344 Info: plan.UpdateInfo{ 345 Matched: 1, 346 Updated: 1, 347 }, 348 }}}, 349 }, 350 { 351 Query: "/* client a */ commit", 352 Expected: []sql.Row{}, 353 }, 354 { 355 Query: "/* client b */ commit", 356 Expected: []sql.Row{}, 357 }, 358 { 359 Query: "/* client a */ select * from t order by x", 360 Expected: []sql.Row{{1, 3}, {2, 4}}, 361 }, 362 { 363 Query: "/* client b */ select * from t order by x", 364 Expected: []sql.Row{{1, 3}, {2, 4}}, 365 }, 366 }, 367 }, 368 { 369 Name: "non overlapping updates (diff cols)", 370 SetUpScript: []string{ 371 "create table t (x int primary key, y int, z int)", 372 "insert into t values (1, 1, 1), (2, 2, 2)", 373 }, 374 Assertions: []queries.ScriptTestAssertion{ 375 { 376 Query: "/* client a */ start transaction", 377 Expected: []sql.Row{}, 378 }, 379 { 380 Query: "/* client b */ start transaction", 381 Expected: []sql.Row{}, 382 }, 383 { 384 Query: "/* client a */ update t set y = 2", 385 Expected: []sql.Row{{types.OkResult{ 386 RowsAffected: uint64(1), 387 Info: plan.UpdateInfo{ 388 Matched: 2, 389 Updated: 1, 390 }, 391 }}}, 392 }, 393 { 394 Query: "/* client b */ update t set z = 3", 395 Expected: []sql.Row{{types.OkResult{ 396 RowsAffected: uint64(2), 397 Info: plan.UpdateInfo{ 398 Matched: 2, 399 Updated: 2, 400 }, 401 }}}, 402 }, 403 { 404 Query: "/* client a */ commit", 405 Expected: []sql.Row{}, 406 }, 407 { 408 Query: "/* client b */ commit", 409 Expected: []sql.Row{}, 410 }, 411 { 412 Query: "/* client a */ select * from t order by x", 413 Expected: []sql.Row{{1, 2, 3}, {2, 2, 3}}, 414 }, 415 { 416 Query: "/* client b */ select * from t order by x", 417 Expected: []sql.Row{{1, 2, 3}, {2, 2, 3}}, 418 }, 419 }, 420 }, 421 { 422 Name: "duplicate deletes, autocommit on", 423 SetUpScript: []string{ 424 "create table t (x int primary key, y int)", 425 "insert into t values (1, 1), (2, 2)", 426 }, 427 Assertions: []queries.ScriptTestAssertion{ 428 { 429 Query: "/* client a */ delete from t where y = 2", 430 Expected: []sql.Row{{types.NewOkResult(1)}}, 431 }, 432 { 433 Query: "/* client b */ delete from t where y = 2", 434 Expected: []sql.Row{{types.NewOkResult(0)}}, 435 }, 436 { 437 Query: "/* client a */ select * from t order by x", 438 Expected: []sql.Row{{1, 1}}, 439 }, 440 { 441 Query: "/* client b */ select * from t order by x", 442 Expected: []sql.Row{{1, 1}}, 443 }, 444 }, 445 }, 446 { 447 Name: "duplicate deletes, autocommit off", 448 SetUpScript: []string{ 449 "create table t (x int primary key, y int)", 450 "insert into t values (1, 1), (2, 2)", 451 }, 452 Assertions: []queries.ScriptTestAssertion{ 453 { 454 Query: "/* client a */ start transaction", 455 Expected: []sql.Row{}, 456 }, 457 { 458 Query: "/* client b */ start transaction", 459 Expected: []sql.Row{}, 460 }, 461 { 462 Query: "/* client a */ delete from t where y = 2", 463 Expected: []sql.Row{{types.NewOkResult(1)}}, 464 }, 465 { 466 Query: "/* client b */ delete from t where y = 2", 467 Expected: []sql.Row{{types.NewOkResult(1)}}, 468 }, 469 { 470 Query: "/* client a */ commit", 471 Expected: []sql.Row{}, 472 }, 473 { 474 Query: "/* client b */ commit", 475 Expected: []sql.Row{}, 476 }, 477 { 478 Query: "/* client a */ select * from t order by x", 479 Expected: []sql.Row{{1, 1}}, 480 }, 481 { 482 Query: "/* client b */ select * from t order by x", 483 Expected: []sql.Row{{1, 1}}, 484 }, 485 }, 486 }, 487 { 488 Name: "non overlapping deletes", 489 SetUpScript: []string{ 490 "create table t (x int primary key, y int)", 491 "insert into t values (1, 1), (2, 2), (3, 3)", 492 }, 493 Assertions: []queries.ScriptTestAssertion{ 494 { 495 Query: "/* client a */ start transaction", 496 Expected: []sql.Row{}, 497 }, 498 { 499 Query: "/* client b */ start transaction", 500 Expected: []sql.Row{}, 501 }, 502 { 503 Query: "/* client a */ delete from t where y = 2", 504 Expected: []sql.Row{{types.NewOkResult(1)}}, 505 }, 506 { 507 Query: "/* client b */ delete from t where y = 3", 508 Expected: []sql.Row{{types.NewOkResult(1)}}, 509 }, 510 { 511 Query: "/* client a */ commit", 512 Expected: []sql.Row{}, 513 }, 514 { 515 Query: "/* client b */ commit", 516 Expected: []sql.Row{}, 517 }, 518 { 519 Query: "/* client a */ select * from t order by x", 520 Expected: []sql.Row{{1, 1}}, 521 }, 522 { 523 Query: "/* client b */ select * from t order by x", 524 Expected: []sql.Row{{1, 1}}, 525 }, 526 }, 527 }, 528 { 529 Name: "conflicting delete and update", 530 SetUpScript: []string{ 531 "create table t (x int primary key, y int)", 532 "insert into t values (1, 1), (2, 2)", 533 }, 534 Assertions: []queries.ScriptTestAssertion{ 535 { 536 Query: "/* client a */ start transaction", 537 Expected: []sql.Row{}, 538 }, 539 { 540 Query: "/* client b */ start transaction", 541 Expected: []sql.Row{}, 542 }, 543 { 544 Query: "/* client a */ update t set y = 3 where y = 2", 545 Expected: []sql.Row{{types.OkResult{ 546 RowsAffected: uint64(1), 547 Info: plan.UpdateInfo{ 548 Matched: 1, 549 Updated: 1, 550 }, 551 }}}, 552 }, 553 { 554 Query: "/* client b */ delete from t where y = 2", 555 Expected: []sql.Row{{types.NewOkResult(1)}}, 556 }, 557 { 558 Query: "/* client a */ commit", 559 Expected: []sql.Row{}, 560 }, 561 { 562 Query: "/* client b */ commit", 563 ExpectedErrStr: sql.ErrLockDeadlock.New(dsess.ErrRetryTransaction.Error()).Error(), 564 }, 565 { 566 Query: "/* client b */ rollback", 567 Expected: []sql.Row{}, 568 }, 569 { 570 Query: "/* client a */ select * from t order by x", 571 Expected: []sql.Row{{1, 1}, {2, 3}}, 572 }, 573 { 574 Query: "/* client b */ select * from t order by x", 575 Expected: []sql.Row{{1, 1}, {2, 3}}, 576 }, 577 }, 578 }, 579 { 580 Name: "delete in one client, insert into another", 581 SetUpScript: []string{ 582 "create table t (x int primary key, y int)", 583 "insert into t values (1, 1), (2, 2)", 584 }, 585 Assertions: []queries.ScriptTestAssertion{ 586 { 587 Query: "/* client a */ start transaction", 588 Expected: []sql.Row{}, 589 }, 590 { 591 Query: "/* client b */ start transaction", 592 Expected: []sql.Row{}, 593 }, 594 { 595 Query: "/* client a */ delete from t where y = 1", 596 Expected: []sql.Row{{types.NewOkResult(1)}}, 597 }, 598 { 599 Query: "/* client b */ delete from t", 600 Expected: []sql.Row{{types.NewOkResult(2)}}, 601 }, 602 { 603 Query: "/* client b */ insert into t values (1,1)", 604 Expected: []sql.Row{{types.NewOkResult(1)}}, 605 }, 606 { 607 Query: "/* client a */ commit", 608 Expected: []sql.Row{}, 609 }, 610 { 611 Query: "/* client b */ commit", 612 Expected: []sql.Row{}, 613 }, 614 { 615 Query: "/* client a */ select * from t order by x", 616 Expected: []sql.Row{}, 617 }, 618 { 619 Query: "/* client b */ select * from t order by x", 620 Expected: []sql.Row{}, 621 }, 622 }, 623 }, 624 { 625 Name: "multiple client edit session", 626 SetUpScript: []string{ 627 "create table t (x int primary key, y int, z int)", 628 "insert into t values (1, 1, 1), (2, 2, 2)", 629 }, 630 Assertions: []queries.ScriptTestAssertion{ 631 { 632 Query: "/* client a */ start transaction", 633 Expected: []sql.Row{}, 634 }, 635 { 636 Query: "/* client b */ start transaction", 637 Expected: []sql.Row{}, 638 }, 639 { 640 Query: "/* client c */ start transaction", 641 Expected: []sql.Row{}, 642 }, 643 { 644 Query: "/* client a */ update t set y = 3 where y = 2", 645 Expected: []sql.Row{{types.OkResult{ 646 RowsAffected: uint64(1), 647 Info: plan.UpdateInfo{ 648 Matched: 1, 649 Updated: 1, 650 }, 651 }}}, 652 }, 653 { 654 Query: "/* client b */ delete from t where y = 1", 655 Expected: []sql.Row{{types.NewOkResult(1)}}, 656 }, 657 { 658 Query: "/* client c */ update t set z = 4 where y = 2", 659 Expected: []sql.Row{{types.OkResult{ 660 RowsAffected: uint64(1), 661 Info: plan.UpdateInfo{ 662 Matched: 1, 663 Updated: 1, 664 }, 665 }}}, 666 }, 667 { 668 Query: "/* client a */ commit", 669 Expected: []sql.Row{}, 670 }, 671 { 672 Query: "/* client b */ commit", 673 Expected: []sql.Row{}, 674 }, 675 { 676 Query: "/* client a */ select * from t order by x", 677 Expected: []sql.Row{{2, 3, 2}}, 678 }, 679 { 680 Query: "/* client b */ select * from t order by x", 681 Expected: []sql.Row{{2, 3, 2}}, 682 }, 683 { 684 Query: "/* client c */ select * from t order by x", 685 Expected: []sql.Row{{1, 1, 1}, {2, 2, 4}}, 686 }, 687 { 688 Query: "/* client c */ commit", 689 Expected: []sql.Row{}, 690 }, 691 { 692 Query: "/* client a */ select * from t order by x", 693 Expected: []sql.Row{{2, 3, 4}}, 694 }, 695 { 696 Query: "/* client b */ select * from t order by x", 697 Expected: []sql.Row{{2, 3, 4}}, 698 }, 699 { 700 Query: "/* client c */ select * from t order by x", 701 Expected: []sql.Row{{2, 3, 4}}, 702 }, 703 }, 704 }, 705 { 706 Name: "edits from different clients to table with out of order primary key set", 707 SetUpScript: []string{ 708 "create table test (x int, y int, z int, primary key(z, y))", 709 "insert into test values (1, 1, 1), (2, 2, 2)", 710 }, 711 Assertions: []queries.ScriptTestAssertion{ 712 { 713 Query: "/* client b */ start transaction", 714 Expected: []sql.Row{}, 715 }, 716 { 717 Query: "/* client a */ update test set y = 3 where y = 2", 718 Expected: []sql.Row{{types.OkResult{ 719 RowsAffected: uint64(1), 720 Info: plan.UpdateInfo{ 721 Matched: 1, 722 Updated: 1, 723 }, 724 }}}, 725 }, 726 { 727 Query: "/* client b */ update test set y = 5 where y = 2", 728 Expected: []sql.Row{{types.OkResult{ 729 RowsAffected: uint64(1), 730 Info: plan.UpdateInfo{ 731 Matched: 1, 732 Updated: 1, 733 }, 734 }}}, 735 }, 736 { 737 Query: "/* client a */ commit", 738 Expected: []sql.Row{}, 739 }, 740 { 741 Query: "/* client b */ commit", 742 Expected: []sql.Row{}, 743 }, 744 { 745 Query: "/* client a */ select * from test order by x", 746 Expected: []sql.Row{{1, 1, 1}, {2, 3, 2}, {2, 5, 2}}, 747 }, 748 { 749 Query: "/* client b */ select * from test order by x", 750 Expected: []sql.Row{{1, 1, 1}, {2, 3, 2}, {2, 5, 2}}, 751 }, 752 { 753 Query: "/* client b */ insert into test values (4,3,2)", 754 ExpectedErr: sql.ErrPrimaryKeyViolation, 755 }, 756 }, 757 }, 758 } 759 760 var DoltConflictHandlingTests = []queries.TransactionTest{ 761 { 762 Name: "default behavior (rollback on commit conflict)", 763 SetUpScript: []string{ 764 "CREATE TABLE test (pk int primary key, val int)", 765 "CALL DOLT_ADD('.')", 766 "INSERT INTO test VALUES (0, 0)", 767 "CALL DOLT_COMMIT('-a', '-m', 'initial table');", 768 }, 769 Assertions: []queries.ScriptTestAssertion{ 770 { 771 Query: "/* client a */ set autocommit = off", 772 Expected: []sql.Row{{}}, 773 }, 774 { 775 Query: "/* client a */ start transaction", 776 Expected: []sql.Row{}, 777 }, 778 { 779 Query: "/* client b */ set autocommit = off", 780 Expected: []sql.Row{{}}, 781 }, 782 { 783 Query: "/* client b */ start transaction", 784 Expected: []sql.Row{}, 785 }, 786 { 787 Query: "/* client a */ insert into test values (1, 1)", 788 Expected: []sql.Row{{types.NewOkResult(1)}}, 789 }, 790 { 791 Query: "/* client b */ insert into test values (1, 2)", 792 Expected: []sql.Row{{types.NewOkResult(1)}}, 793 }, 794 { 795 Query: "/* client a */ commit", 796 Expected: []sql.Row{}, 797 }, 798 { 799 Query: "/* client b */ commit", 800 ExpectedErrStr: sql.ErrLockDeadlock.New(dsess.ErrRetryTransaction.Error()).Error(), 801 }, 802 { // no conflicts, transaction got rolled back 803 Query: "/* client b */ select count(*) from dolt_conflicts", 804 Expected: []sql.Row{{0}}, 805 }, 806 { 807 Query: "/* client b */ select * from test order by 1", 808 Expected: []sql.Row{{0, 0}, {1, 1}}, 809 }, 810 }, 811 }, 812 { 813 Name: "allow commit conflicts on, conflict on transaction commit", 814 SetUpScript: []string{ 815 "CREATE TABLE test (pk int primary key, val int)", 816 "CALL DOLT_ADD('.')", 817 "INSERT INTO test VALUES (0, 0)", 818 "CALL DOLT_COMMIT('-a', '-m', 'initial table');", 819 }, 820 Assertions: []queries.ScriptTestAssertion{ 821 { 822 Query: "/* client a */ set autocommit = off, dolt_allow_commit_conflicts = on", 823 Expected: []sql.Row{{}}, 824 }, 825 { 826 Query: "/* client a */ start transaction", 827 Expected: []sql.Row{}, 828 }, 829 { 830 Query: "/* client b */ set autocommit = off, dolt_allow_commit_conflicts = on", 831 Expected: []sql.Row{{}}, 832 }, 833 { 834 Query: "/* client b */ start transaction", 835 Expected: []sql.Row{}, 836 }, 837 { 838 Query: "/* client a */ insert into test values (1, 1)", 839 Expected: []sql.Row{{types.NewOkResult(1)}}, 840 }, 841 { 842 Query: "/* client b */ insert into test values (1, 2)", 843 Expected: []sql.Row{{types.NewOkResult(1)}}, 844 }, 845 { 846 Query: "/* client a */ commit", 847 Expected: []sql.Row{}, 848 }, 849 { 850 Query: "/* client b */ commit", 851 ExpectedErrStr: sql.ErrLockDeadlock.New(dsess.ErrRetryTransaction.Error()).Error(), 852 }, 853 { // We see the merge value from a's commit here because we were rolled back and a new transaction begun 854 Query: "/* client b */ select * from test order by 1", 855 Expected: []sql.Row{{0, 0}, {1, 1}}, 856 }, 857 { // no conflicts, transaction got rolled back 858 Query: "/* client b */ select count(*) from dolt_conflicts", 859 Expected: []sql.Row{{0}}, 860 }, 861 }, 862 }, 863 { 864 Name: "force commit on, conflict on transaction commit (same as dolt_allow_commit_conflicts)", 865 SetUpScript: []string{ 866 "CREATE TABLE test (pk int primary key, val int)", 867 "CALL DOLT_ADD('.')", 868 "INSERT INTO test VALUES (0, 0)", 869 "CALL DOLT_COMMIT('-a', '-m', 'initial table');", 870 }, 871 Assertions: []queries.ScriptTestAssertion{ 872 { 873 Query: "/* client a */ set autocommit = off, dolt_force_transaction_commit = on", 874 Expected: []sql.Row{{}}, 875 }, 876 { 877 Query: "/* client a */ start transaction", 878 Expected: []sql.Row{}, 879 }, 880 { 881 Query: "/* client b */ set autocommit = off, dolt_force_transaction_commit = on", 882 Expected: []sql.Row{{}}, 883 }, 884 { 885 Query: "/* client b */ start transaction", 886 Expected: []sql.Row{}, 887 }, 888 { 889 Query: "/* client a */ insert into test values (1, 1)", 890 Expected: []sql.Row{{types.NewOkResult(1)}}, 891 }, 892 { 893 Query: "/* client b */ insert into test values (1, 2)", 894 Expected: []sql.Row{{types.NewOkResult(1)}}, 895 }, 896 { 897 Query: "/* client a */ commit", 898 Expected: []sql.Row{}, 899 }, 900 { 901 Query: "/* client b */ commit", 902 ExpectedErrStr: sql.ErrLockDeadlock.New(dsess.ErrRetryTransaction.Error()).Error(), 903 }, 904 { // We see the merge value from a's commit here because we were rolled back and a new transaction begun 905 Query: "/* client b */ select * from test order by 1", 906 Expected: []sql.Row{{0, 0}, {1, 1}}, 907 }, 908 { // no conflicts, transaction got rolled back 909 Query: "/* client b */ select count(*) from dolt_conflicts", 910 Expected: []sql.Row{{0}}, 911 }, 912 }, 913 }, 914 { 915 Name: "allow commit conflicts on, conflict on dolt_merge", 916 SetUpScript: []string{ 917 "CREATE TABLE test (pk int primary key, val int)", 918 "CALL DOLT_ADD('.')", 919 "INSERT INTO test VALUES (0, 0)", 920 "CALL DOLT_COMMIT('-a', '-m', 'initial table');", 921 }, 922 Assertions: []queries.ScriptTestAssertion{ 923 { 924 Query: "/* client a */ set autocommit = off, dolt_allow_commit_conflicts = on", 925 Expected: []sql.Row{{}}, 926 }, 927 { 928 Query: "/* client a */ start transaction", 929 Expected: []sql.Row{}, 930 }, 931 { 932 Query: "/* client b */ set autocommit = off, dolt_allow_commit_conflicts = on", 933 Expected: []sql.Row{{}}, 934 }, 935 { 936 Query: "/* client b */ start transaction", 937 Expected: []sql.Row{}, 938 }, 939 { 940 Query: "/* client a */ insert into test values (1, 1)", 941 Expected: []sql.Row{{types.NewOkResult(1)}}, 942 }, 943 { 944 Query: "/* client b */ call dolt_checkout('-b', 'new-branch')", 945 SkipResultsCheck: true, 946 }, 947 { 948 Query: "/* client a */ call dolt_commit('-am', 'commit on main')", 949 SkipResultsCheck: true, 950 }, 951 { 952 Query: "/* client b */ insert into test values (1, 2)", 953 Expected: []sql.Row{{types.NewOkResult(1)}}, 954 }, 955 { 956 Query: "/* client b */ call dolt_commit('-am', 'commit on new-branch')", 957 SkipResultsCheck: true, 958 }, 959 { 960 Query: "/* client b */ call dolt_merge('main')", 961 Expected: []sql.Row{{"", 0, 1, "conflicts found"}}, 962 }, 963 { 964 Query: "/* client b */ select count(*) from dolt_conflicts", 965 Expected: []sql.Row{{1}}, 966 }, 967 { 968 Query: "/* client b */ select * from test order by 1", 969 Expected: []sql.Row{{0, 0}, {1, 2}}, 970 }, 971 { // no error because of our session settings 972 // TODO: we should also be able to commit this if the other client made a compatible change 973 // (has the same merge conflicts we do), but that's an error right now 974 Query: "/* client b */ commit", 975 Expected: []sql.Row{}, 976 }, 977 { // TODO: it should be possible to do this without specifying a literal in the subselect, but it's not working 978 Query: "/* client b */ update test t set val = (select their_val from dolt_conflicts_test where our_pk = 1) where pk = 1", 979 Expected: []sql.Row{{types.OkResult{ 980 RowsAffected: 1, 981 Info: plan.UpdateInfo{ 982 Matched: 1, 983 Updated: 1, 984 }, 985 }}}, 986 }, 987 { 988 Query: "/* client b */ delete from dolt_conflicts_test", 989 Expected: []sql.Row{{types.NewOkResult(1)}}, 990 }, 991 { 992 Query: "/* client b */ commit", 993 Expected: []sql.Row{}, 994 }, 995 { 996 Query: "/* client b */ select * from test order by 1", 997 Expected: []sql.Row{{0, 0}, {1, 1}}, 998 }, 999 { 1000 Query: "/* client b */ select count(*) from dolt_conflicts", 1001 Expected: []sql.Row{{0}}, 1002 }, 1003 }, 1004 }, 1005 { 1006 Name: "force commit on, conflict on dolt_merge (same as dolt_allow_commit_conflicts)", 1007 SetUpScript: []string{ 1008 "CREATE TABLE test (pk int primary key, val int)", 1009 "CALL DOLT_ADD('.')", 1010 "INSERT INTO test VALUES (0, 0)", 1011 "CALL DOLT_COMMIT('-a', '-m', 'initial table');", 1012 }, 1013 Assertions: []queries.ScriptTestAssertion{ 1014 { 1015 Query: "/* client a */ set autocommit = off, dolt_force_transaction_commit = on", 1016 Expected: []sql.Row{{}}, 1017 }, 1018 { 1019 Query: "/* client a */ start transaction", 1020 Expected: []sql.Row{}, 1021 }, 1022 { 1023 Query: "/* client b */ set autocommit = off, dolt_force_transaction_commit = on", 1024 Expected: []sql.Row{{}}, 1025 }, 1026 { 1027 Query: "/* client b */ start transaction", 1028 Expected: []sql.Row{}, 1029 }, 1030 { 1031 Query: "/* client a */ insert into test values (1, 1)", 1032 Expected: []sql.Row{{types.NewOkResult(1)}}, 1033 }, 1034 { 1035 Query: "/* client b */ call dolt_checkout('-b', 'new-branch')", 1036 SkipResultsCheck: true, 1037 }, 1038 { 1039 Query: "/* client a */ call dolt_commit('-am', 'commit on main')", 1040 SkipResultsCheck: true, 1041 }, 1042 { 1043 Query: "/* client b */ insert into test values (1, 2)", 1044 Expected: []sql.Row{{types.NewOkResult(1)}}, 1045 }, 1046 { 1047 Query: "/* client b */ call dolt_commit('-am', 'commit on new-branch')", 1048 SkipResultsCheck: true, 1049 }, 1050 { 1051 Query: "/* client b */ call dolt_merge('main')", 1052 Expected: []sql.Row{{"", 0, 1, "conflicts found"}}, 1053 }, 1054 { 1055 Query: "/* client b */ select count(*) from dolt_conflicts", 1056 Expected: []sql.Row{{1}}, 1057 }, 1058 { 1059 Query: "/* client b */ select * from test order by 1", 1060 Expected: []sql.Row{{0, 0}, {1, 2}}, 1061 }, 1062 { // no error because of our session settings 1063 Query: "/* client b */ commit", 1064 Expected: []sql.Row{}, 1065 }, 1066 { // TODO: it should be possible to do this without specifying a literal in the subselect, but it's not working 1067 Query: "/* client b */ update test t set val = (select their_val from dolt_conflicts_test where our_pk = 1) where pk = 1", 1068 Expected: []sql.Row{{types.OkResult{ 1069 RowsAffected: 1, 1070 Info: plan.UpdateInfo{ 1071 Matched: 1, 1072 Updated: 1, 1073 }, 1074 }}}, 1075 }, 1076 { 1077 Query: "/* client b */ delete from dolt_conflicts_test", 1078 Expected: []sql.Row{{types.NewOkResult(1)}}, 1079 }, 1080 { 1081 Query: "/* client b */ commit", 1082 Expected: []sql.Row{}, 1083 }, 1084 { 1085 Query: "/* client b */ select * from test order by 1", 1086 Expected: []sql.Row{{0, 0}, {1, 1}}, 1087 }, 1088 { 1089 Query: "/* client b */ select count(*) from dolt_conflicts", 1090 Expected: []sql.Row{{0}}, 1091 }, 1092 }, 1093 }, 1094 { 1095 Name: "allow commit conflicts off, conflict on dolt_merge", 1096 SetUpScript: []string{ 1097 "CREATE TABLE test (pk int primary key, val int)", 1098 "CALL DOLT_ADD('.')", 1099 "INSERT INTO test VALUES (0, 0)", 1100 "CALL DOLT_COMMIT('-a', '-m', 'initial table');", 1101 }, 1102 Assertions: []queries.ScriptTestAssertion{ 1103 { 1104 Query: "/* client a */ set autocommit = off", 1105 Expected: []sql.Row{{}}, 1106 }, 1107 { 1108 Query: "/* client a */ start transaction", 1109 Expected: []sql.Row{}, 1110 }, 1111 { 1112 Query: "/* client b */ set autocommit = off", 1113 Expected: []sql.Row{{}}, 1114 }, 1115 { 1116 Query: "/* client b */ start transaction", 1117 Expected: []sql.Row{}, 1118 }, 1119 { 1120 Query: "/* client a */ insert into test values (1, 1)", 1121 Expected: []sql.Row{{types.NewOkResult(1)}}, 1122 }, 1123 { 1124 Query: "/* client b */ call dolt_checkout('-b', 'new-branch')", 1125 SkipResultsCheck: true, 1126 }, 1127 { 1128 Query: "/* client a */ call dolt_commit('-am', 'commit on main')", 1129 SkipResultsCheck: true, 1130 }, 1131 { 1132 Query: "/* client b */ insert into test values (1, 2)", 1133 Expected: []sql.Row{{types.NewOkResult(1)}}, 1134 }, 1135 { 1136 Query: "/* client b */ call dolt_commit('-am', 'commit on new-branch')", 1137 SkipResultsCheck: true, 1138 }, 1139 { 1140 Query: "/* client b */ call dolt_merge('main')", 1141 Expected: []sql.Row{{"", 0, 1, "conflicts found"}}, 1142 }, 1143 { 1144 Query: "/* client b */ select count(*) from dolt_conflicts", 1145 Expected: []sql.Row{{1}}, 1146 }, 1147 { 1148 Query: "/* client b */ select * from test order by 1", 1149 Expected: []sql.Row{{0, 0}, {1, 2}}, 1150 }, 1151 { 1152 Query: "/* client b */ insert into test values (2, 2)", 1153 Expected: []sql.Row{{types.NewOkResult(1)}}, 1154 }, 1155 { 1156 Query: "/* client b */ commit", 1157 ExpectedErrStr: dsess.ErrUnresolvedConflictsCommit.Error(), 1158 }, 1159 { // our transaction got rolled back, so we lose the above insert 1160 Query: "/* client b */ select * from test order by 1", 1161 Expected: []sql.Row{{0, 0}, {1, 2}}, 1162 }, 1163 }, 1164 }, 1165 { 1166 Name: "conflicts from a DOLT_MERGE return an initially unhelpful error in a concurrent write scenario", 1167 SetUpScript: []string{ 1168 "CREATE TABLE t (pk int PRIMARY KEY, col1 int);", 1169 "CALL DOLT_ADD('.')", 1170 "CALL DOLT_COMMIT('-am', 'create table');", 1171 1172 "CALL DOLT_CHECKOUT('-b', 'right');", 1173 "INSERT INTO t values (1, 100);", 1174 "CALL DOLT_COMMIT('-am', 'right edit');", 1175 1176 "CALL DOLT_CHECKOUT('main');", 1177 "INSERT INTO t VALUES (1, 200);", 1178 "CALL DOLT_COMMIT('-am', 'left edit');", 1179 1180 "SET dolt_allow_commit_conflicts = on;", 1181 "CALL DOLT_MERGE('right');", 1182 "SET dolt_allow_commit_conflicts = off;", 1183 }, 1184 Assertions: []queries.ScriptTestAssertion{ 1185 { 1186 Query: "/* client a */ SET @@autocommit=0;", 1187 Expected: []sql.Row{{}}, 1188 }, 1189 { 1190 Query: "/* client b */ SET @@autocommit=0;", 1191 Expected: []sql.Row{{}}, 1192 }, 1193 { 1194 Query: "/* client a */ SELECT base_pk, base_col1, our_pk, our_col1, their_pk, their_col1 from dolt_conflicts_t;", 1195 Expected: []sql.Row{{nil, nil, 1, 200, 1, 100}}, 1196 }, 1197 { 1198 Query: "/* client b */ SELECT base_pk, base_col1, our_pk, our_col1, their_pk, their_col1 from dolt_conflicts_t;", 1199 Expected: []sql.Row{{nil, nil, 1, 200, 1, 100}}, 1200 }, 1201 // nominal inserts that will not result in a conflict or constraint violation 1202 // They are needed to trigger a three-way transaction merge 1203 { 1204 Query: "/* client a */ INSERT into t VALUES (2, 2);", 1205 Expected: []sql.Row{{types.NewOkResult(1)}}, 1206 }, 1207 { 1208 Query: "/* client b */ INSERT into t VALUES (3, 3);", 1209 Expected: []sql.Row{{types.NewOkResult(1)}}, 1210 }, 1211 { 1212 Query: "/* client a */ SET dolt_allow_commit_conflicts = on;", 1213 Expected: []sql.Row{{}}, 1214 }, 1215 { 1216 Query: "/* client a */ COMMIT;", 1217 Expected: []sql.Row{}, 1218 }, 1219 { 1220 Query: "/* client b */ COMMIT;", 1221 // TODO: No it didn't! Client b contains conflicts from an internal merge! Retrying will not help. 1222 ExpectedErrStr: sql.ErrLockDeadlock.New(dsess.ErrRetryTransaction.Error()).Error(), 1223 }, 1224 { 1225 Query: "/* client b */ INSERT into t VALUES (3, 3);", 1226 Expected: []sql.Row{{types.NewOkResult(1)}}, 1227 }, 1228 { 1229 Query: "/* client b */ COMMIT;", 1230 // Retrying did not help. But at-least the error makes sense. 1231 ExpectedErrStr: dsess.ErrUnresolvedConflictsCommit.Error(), 1232 }, 1233 }, 1234 }, 1235 { 1236 Name: "transaction conflicts follows first-write-wins (a commits first)", 1237 SetUpScript: []string{ 1238 "CREATE table t (pk int PRIMARY KEY, col1 int, INDEX col1_idx (col1));", 1239 "CREATE table keyless (col1 int);", 1240 "INSERT INTO t VALUES (1, 1);", 1241 "INSERT INTO keyless VALUES (1);", 1242 }, 1243 Assertions: []queries.ScriptTestAssertion{ 1244 { 1245 Query: "/* client a */ START TRANSACTION", 1246 Expected: []sql.Row{}, 1247 }, 1248 { 1249 Query: "/* client b */ START TRANSACTION", 1250 Expected: []sql.Row{}, 1251 }, 1252 { 1253 Query: "/* client a */ UPDATE t SET col1 = -100 where pk = 1;", 1254 Expected: []sql.Row{{types.OkResult{RowsAffected: 1, Info: plan.UpdateInfo{Matched: 1, Updated: 1}}}}, 1255 }, 1256 { 1257 Query: "/* client b */ UPDATE t SET col1 = 100 where pk = 1;", 1258 Expected: []sql.Row{{types.OkResult{RowsAffected: 1, Info: plan.UpdateInfo{Matched: 1, Updated: 1}}}}, 1259 }, 1260 { 1261 Query: "/* client a */ INSERT into KEYLESS VALUES (1);", 1262 Expected: []sql.Row{{types.NewOkResult(1)}}, 1263 }, 1264 { 1265 Query: "/* client b */ INSERT into KEYLESS VALUES (1), (1);", 1266 Expected: []sql.Row{{types.NewOkResult(2)}}, 1267 }, 1268 { 1269 Query: "/* client a */ COMMIT;", 1270 Expected: []sql.Row{}, 1271 }, 1272 { 1273 Query: "/* client b */ COMMIT;", 1274 ExpectedErr: sql.ErrLockDeadlock, 1275 }, 1276 { 1277 Query: "/* client b */ SELECT * from t;", 1278 Expected: []sql.Row{{1, -100}}, 1279 }, 1280 { 1281 Query: "/* client b */ SELECT * from keyless;", 1282 Expected: []sql.Row{{1}, {1}}, 1283 }, 1284 { 1285 Query: "/* client b */ SELECT * from t where col1 = -100;", 1286 Expected: []sql.Row{{1, -100}}, 1287 }, 1288 }, 1289 }, 1290 { 1291 Name: "transaction conflicts follows first-write-wins (b commits first)", 1292 SetUpScript: []string{ 1293 "CREATE table t (pk int PRIMARY KEY, col1 int, INDEX col1_idx (col1));", 1294 "CREATE table keyless (col1 int);", 1295 "INSERT INTO t VALUES (1, 1);", 1296 "INSERT INTO keyless VALUES (1);", 1297 }, 1298 Assertions: []queries.ScriptTestAssertion{ 1299 { 1300 Query: "/* client a */ START TRANSACTION", 1301 Expected: []sql.Row{}, 1302 }, 1303 { 1304 Query: "/* client b */ START TRANSACTION", 1305 Expected: []sql.Row{}, 1306 }, 1307 { 1308 Query: "/* client a */ UPDATE t SET col1 = -100 where pk = 1;", 1309 Expected: []sql.Row{{types.OkResult{RowsAffected: 1, Info: plan.UpdateInfo{Matched: 1, Updated: 1}}}}, 1310 }, 1311 { 1312 Query: "/* client b */ UPDATE t SET col1 = 100 where pk = 1;", 1313 Expected: []sql.Row{{types.OkResult{RowsAffected: 1, Info: plan.UpdateInfo{Matched: 1, Updated: 1}}}}, 1314 }, 1315 { 1316 Query: "/* client a */ INSERT into KEYLESS VALUES (1);", 1317 Expected: []sql.Row{{types.NewOkResult(1)}}, 1318 }, 1319 { 1320 Query: "/* client b */ INSERT into KEYLESS VALUES (1), (1);", 1321 Expected: []sql.Row{{types.NewOkResult(2)}}, 1322 }, 1323 { 1324 Query: "/* client b */ COMMIT;", 1325 Expected: []sql.Row{}, 1326 }, 1327 { 1328 Query: "/* client a */ COMMIT;", 1329 ExpectedErr: sql.ErrLockDeadlock, 1330 }, 1331 { 1332 Query: "/* client b */ SELECT * from t;", 1333 Expected: []sql.Row{{1, 100}}, 1334 }, 1335 { 1336 Query: "/* client b */ SELECT * from keyless;", 1337 Expected: []sql.Row{{1}, {1}, {1}}, 1338 }, 1339 { 1340 Query: "/* client b */ SELECT * from t where col1 = 100;", 1341 Expected: []sql.Row{{1, 100}}, 1342 }, 1343 }, 1344 }, 1345 } 1346 1347 var DoltStoredProcedureTransactionTests = []queries.TransactionTest{ 1348 { 1349 Name: "committed conflicts are seen by other sessions", 1350 SetUpScript: []string{ 1351 "CREATE TABLE test (pk int primary key, val int)", 1352 "CALL DOLT_ADD('.')", 1353 "INSERT INTO test VALUES (0, 0)", 1354 "CALL DOLT_COMMIT('-a', '-m', 'Step 1');", 1355 "CALL DOLT_CHECKOUT('-b', 'feature-branch')", 1356 "INSERT INTO test VALUES (1, 1);", 1357 "UPDATE test SET val=1000 WHERE pk=0;", 1358 "CALL DOLT_COMMIT('-a', '-m', 'this is a normal commit');", 1359 "CALL DOLT_CHECKOUT('main');", 1360 "UPDATE test SET val=1001 WHERE pk=0;", 1361 "CALL DOLT_COMMIT('-a', '-m', 'update a value');", 1362 }, 1363 Assertions: []queries.ScriptTestAssertion{ 1364 { 1365 Query: "/* client a */ start transaction", 1366 Expected: []sql.Row{}, 1367 }, 1368 { 1369 Query: "/* client b */ start transaction", 1370 Expected: []sql.Row{}, 1371 }, 1372 { 1373 Query: "/* client a */ CALL DOLT_MERGE('feature-branch')", 1374 Expected: []sql.Row{{"", 0, 1, "conflicts found"}}, 1375 }, 1376 { 1377 Query: "/* client a */ SELECT count(*) from dolt_conflicts_test", 1378 Expected: []sql.Row{{1}}, 1379 }, 1380 { 1381 Query: "/* client b */ SELECT count(*) from dolt_conflicts_test", 1382 Expected: []sql.Row{{0}}, 1383 }, 1384 { 1385 Query: "/* client a */ set dolt_allow_commit_conflicts = 1", 1386 Expected: []sql.Row{{}}, 1387 }, 1388 { 1389 Query: "/* client a */ commit", 1390 Expected: []sql.Row{}, 1391 }, 1392 { 1393 Query: "/* client b */ start transaction", 1394 Expected: []sql.Row{}, 1395 }, 1396 { 1397 Query: "/* client b */ SELECT count(*) from dolt_conflicts_test", 1398 Expected: []sql.Row{{1}}, 1399 }, 1400 { 1401 Query: "/* client a */ start transaction", 1402 Expected: []sql.Row{}, 1403 }, 1404 { 1405 Query: "/* client a */ CALL DOLT_MERGE('--abort')", 1406 Expected: []sql.Row{{"", 0, 0, "merge aborted"}}, 1407 }, 1408 { 1409 Query: "/* client a */ commit", 1410 Expected: []sql.Row{}, 1411 }, 1412 { 1413 Query: "/* client b */ start transaction", 1414 Expected: []sql.Row{}, 1415 }, 1416 { 1417 Query: "/* client a */ SET @@dolt_allow_commit_conflicts = 0", 1418 Expected: []sql.Row{{}}, 1419 }, 1420 { 1421 Query: "/* client a */ CALL DOLT_MERGE('feature-branch')", 1422 ExpectedErrStr: dsess.ErrUnresolvedConflictsAutoCommit.Error(), 1423 }, 1424 { // client rolled back on merge with conflicts 1425 Query: "/* client a */ SELECT count(*) from dolt_conflicts_test", 1426 Expected: []sql.Row{{0}}, 1427 }, 1428 { 1429 Query: "/* client a */ commit", 1430 Expected: []sql.Row{}, 1431 }, 1432 { 1433 Query: "/* client b */ SELECT count(*) from dolt_conflicts_test", 1434 Expected: []sql.Row{{0}}, 1435 }, 1436 }, 1437 }, 1438 { 1439 Name: "dolt_commit with one table, no merge conflict, no unstaged changes", 1440 SetUpScript: []string{ 1441 "create table users (id int primary key, name varchar(32))", 1442 "insert into users values (1, 'tim'), (2, 'jim')", 1443 "call dolt_commit('-A', '-m', 'initial commit')", 1444 }, 1445 Assertions: []queries.ScriptTestAssertion{ 1446 { 1447 Query: "/* client a */ start transaction", 1448 SkipResultsCheck: true, 1449 }, 1450 { 1451 Query: "/* client b */ start transaction", 1452 SkipResultsCheck: true, 1453 }, 1454 { 1455 Query: "/* client a */ update users set name = 'tim2' where name = 'tim'", 1456 SkipResultsCheck: true, 1457 }, 1458 { 1459 Query: "/* client b */ update users set name = 'jim2' where name = 'jim'", 1460 SkipResultsCheck: true, 1461 }, 1462 { 1463 Query: "/* client a */ call dolt_commit('-A', '-m', 'update tim')", 1464 SkipResultsCheck: true, 1465 }, 1466 { 1467 Query: "/* client b */ call dolt_commit('-A', '-m', 'update jim')", 1468 SkipResultsCheck: true, 1469 }, 1470 { 1471 Query: "/* client a */ select count(*) from dolt_status", // clean working set 1472 Expected: []sql.Row{{0}}, 1473 }, 1474 { 1475 Query: "/* client b */ select count(*) from dolt_status", // clean working set 1476 Expected: []sql.Row{{0}}, 1477 }, 1478 { 1479 Query: "/* client a */ select * from users order by id", 1480 Expected: []sql.Row{{1, "tim2"}, {2, "jim2"}}, 1481 }, 1482 { 1483 Query: "/* client b */ select * from users order by id", 1484 Expected: []sql.Row{{1, "tim2"}, {2, "jim2"}}, 1485 }, 1486 }, 1487 }, 1488 { 1489 Name: "mix of dolt_commit and normal commit", 1490 SetUpScript: []string{ 1491 "create table users (id int primary key, name varchar(32))", 1492 "insert into users values (1, 'tim'), (2, 'jim')", 1493 "call dolt_commit('-A', '-m', 'initial commit')", 1494 }, 1495 Assertions: []queries.ScriptTestAssertion{ 1496 { 1497 Query: "/* client a */ start transaction", 1498 SkipResultsCheck: true, 1499 }, 1500 { 1501 Query: "/* client b */ start transaction", 1502 SkipResultsCheck: true, 1503 }, 1504 { 1505 Query: "/* client a */ update users set name = 'tim2' where name = 'tim'", 1506 SkipResultsCheck: true, 1507 }, 1508 { 1509 Query: "/* client b */ update users set name = 'jim2' where name = 'jim'", 1510 SkipResultsCheck: true, 1511 }, 1512 { 1513 Query: "/* client a */ commit", 1514 SkipResultsCheck: true, 1515 }, 1516 { 1517 Query: "/* client b */ call dolt_commit('-A', '-m', 'update jim')", 1518 SkipResultsCheck: true, 1519 }, 1520 { 1521 // dirty working set: client a's changes were not committed to head 1522 Query: "/* client a */ select * from dolt_status", 1523 Expected: []sql.Row{{"users", false, "modified"}}, 1524 }, 1525 { 1526 // dirty working set: client a's changes were not committed to head, but are visible to client b 1527 Query: "/* client b */ select * from dolt_status", 1528 Expected: []sql.Row{{"users", false, "modified"}}, 1529 }, 1530 { 1531 Query: "/* client a */ select * from users order by id", 1532 Expected: []sql.Row{{1, "tim2"}, {2, "jim2"}}, 1533 }, 1534 { 1535 Query: "/* client b */ select * from users order by id", 1536 Expected: []sql.Row{{1, "tim2"}, {2, "jim2"}}, 1537 }, 1538 { 1539 // changes from client a are in the working set, but not in HEAD 1540 Query: "/* client a */ select from_id, to_id, from_name, to_name from dolt_diff('HEAD', 'WORKING', 'users') order by from_id, to_id", 1541 Expected: []sql.Row{ 1542 {1, 1, "tim", "tim2"}, 1543 }, 1544 }, 1545 { 1546 Query: "/* client b */ select from_id, to_id, from_name, to_name from dolt_diff('HEAD', 'WORKING', 'users') order by from_id, to_id", 1547 Expected: []sql.Row{ 1548 {1, 1, "tim", "tim2"}, 1549 }, 1550 }, 1551 }, 1552 }, 1553 { 1554 Name: "staged change in working set", 1555 SetUpScript: []string{ 1556 "create table users (id int primary key, name varchar(32))", 1557 "insert into users values (1, 'tim'), (2, 'jim')", 1558 "call dolt_commit('-A', '-m', 'initial commit')", 1559 }, 1560 Assertions: []queries.ScriptTestAssertion{ 1561 { 1562 Query: "/* client a */ start transaction", 1563 SkipResultsCheck: true, 1564 }, 1565 { 1566 Query: "/* client b */ start transaction", 1567 SkipResultsCheck: true, 1568 }, 1569 { 1570 Query: "/* client a */ update users set name = 'tim2' where name = 'tim'", 1571 SkipResultsCheck: true, 1572 }, 1573 { 1574 Query: "/* client b */ update users set name = 'jim2' where name = 'jim'", 1575 SkipResultsCheck: true, 1576 }, 1577 { 1578 Query: "/* client a */ call dolt_add('users')", 1579 SkipResultsCheck: true, 1580 }, 1581 { 1582 Query: "/* client b */ call dolt_add('users')", 1583 SkipResultsCheck: true, 1584 }, 1585 { 1586 Query: "/* client a */ commit", 1587 SkipResultsCheck: true, 1588 }, 1589 { 1590 Query: "/* client b */ commit", 1591 SkipResultsCheck: true, 1592 }, 1593 { 1594 Query: "/* client a */ select * from users order by id", 1595 Expected: []sql.Row{{1, "tim2"}, {2, "jim2"}}, 1596 }, 1597 { 1598 Query: "/* client b */ select * from users order by id", 1599 Expected: []sql.Row{{1, "tim2"}, {2, "jim2"}}, 1600 }, 1601 { 1602 // dirty working set: modifications are staged 1603 Query: "/* client a */ select * from dolt_status", 1604 Expected: []sql.Row{ 1605 {"users", true, "modified"}, 1606 }, 1607 }, 1608 { 1609 // dirty working set: modifications are staged 1610 Query: "/* client b */ select * from dolt_status", 1611 Expected: []sql.Row{ 1612 {"users", true, "modified"}, 1613 }, 1614 }, 1615 { 1616 // staged changes include changes from both A and B 1617 Query: "/* client a */ select from_id, to_id, from_name, to_name from dolt_diff('HEAD', 'STAGED', 'users') order by from_id, to_id", 1618 Expected: []sql.Row{ 1619 {1, 1, "tim", "tim2"}, 1620 {2, 2, "jim", "jim2"}, 1621 }, 1622 }, 1623 { 1624 // staged changes include changes from both A and B 1625 Query: "/* client a */ select from_id, to_id, from_name, to_name from dolt_diff('HEAD', 'STAGED', 'users') order by from_id, to_id", 1626 Expected: []sql.Row{ 1627 {1, 1, "tim", "tim2"}, 1628 {2, 2, "jim", "jim2"}, 1629 }, 1630 }, 1631 }, 1632 }, 1633 { 1634 Name: "staged and unstaged changes in working set", 1635 SetUpScript: []string{ 1636 "create table users (id int primary key, name varchar(32))", 1637 "insert into users values (1, 'tim'), (2, 'jim')", 1638 "call dolt_commit('-A', '-m', 'initial commit')", 1639 }, 1640 Assertions: []queries.ScriptTestAssertion{ 1641 { 1642 Query: "/* client a */ start transaction", 1643 SkipResultsCheck: true, 1644 }, 1645 { 1646 Query: "/* client b */ start transaction", 1647 SkipResultsCheck: true, 1648 }, 1649 { 1650 Query: "/* client a */ update users set name = 'tim2' where name = 'tim'", 1651 SkipResultsCheck: true, 1652 }, 1653 { 1654 Query: "/* client b */ update users set name = 'jim2' where name = 'jim'", 1655 SkipResultsCheck: true, 1656 }, 1657 { 1658 Query: "/* client a */ call dolt_add('users')", 1659 SkipResultsCheck: true, 1660 }, 1661 { 1662 Query: "/* client b */ call dolt_add('users')", 1663 SkipResultsCheck: true, 1664 }, 1665 { 1666 Query: "/* client a */ update users set name = 'tim3' where name = 'tim2'", 1667 SkipResultsCheck: true, 1668 }, 1669 { 1670 Query: "/* client b */ update users set name = 'jim3' where name = 'jim2'", 1671 SkipResultsCheck: true, 1672 }, 1673 { 1674 Query: "/* client a */ commit", 1675 SkipResultsCheck: true, 1676 }, 1677 { 1678 Query: "/* client b */ commit", 1679 SkipResultsCheck: true, 1680 }, 1681 { 1682 Query: "/* client a */ select * from users order by id", 1683 Expected: []sql.Row{{1, "tim3"}, {2, "jim3"}}, 1684 }, 1685 { 1686 Query: "/* client b */ select * from users order by id", 1687 Expected: []sql.Row{{1, "tim3"}, {2, "jim3"}}, 1688 }, 1689 { 1690 // dirty working set: modifications are staged and unstaged 1691 Query: "/* client a */ select * from dolt_status", 1692 Expected: []sql.Row{ 1693 {"users", true, "modified"}, 1694 {"users", false, "modified"}, 1695 }, 1696 }, 1697 { 1698 // dirty working set: modifications are staged and unstaged 1699 Query: "/* client b */ select * from dolt_status", 1700 Expected: []sql.Row{ 1701 {"users", true, "modified"}, 1702 {"users", false, "modified"}, 1703 }, 1704 }, 1705 { 1706 // staged changes include changes from both A and B at staged revision of data 1707 Query: "/* client a */ select from_id, to_id, from_name, to_name from dolt_diff('HEAD', 'STAGED', 'users') order by from_id, to_id", 1708 Expected: []sql.Row{ 1709 {1, 1, "tim", "tim2"}, 1710 {2, 2, "jim", "jim2"}, 1711 }, 1712 }, 1713 { 1714 // staged changes include changes from both A and B at staged revision of data 1715 Query: "/* client a */ select from_id, to_id, from_name, to_name from dolt_diff('HEAD', 'STAGED', 'users') order by from_id, to_id", 1716 Expected: []sql.Row{ 1717 {1, 1, "tim", "tim2"}, 1718 {2, 2, "jim", "jim2"}, 1719 }, 1720 }, 1721 { 1722 // working changes include changes from both A and B at working revision of data 1723 Query: "/* client a */ select from_id, to_id, from_name, to_name from dolt_diff('HEAD', 'WORKING', 'users') order by from_id, to_id", 1724 Expected: []sql.Row{ 1725 {1, 1, "tim", "tim3"}, 1726 {2, 2, "jim", "jim3"}, 1727 }, 1728 }, 1729 { 1730 // working changes include changes from both A and B at working revision of data 1731 Query: "/* client a */ select from_id, to_id, from_name, to_name from dolt_diff('HEAD', 'WORKING', 'users') order by from_id, to_id", 1732 Expected: []sql.Row{ 1733 {1, 1, "tim", "tim3"}, 1734 {2, 2, "jim", "jim3"}, 1735 }, 1736 }, 1737 { 1738 Query: "/* client a */ select from_id, to_id, from_name, to_name from dolt_diff('STAGED', 'WORKING', 'users') order by from_id, to_id", 1739 Expected: []sql.Row{ 1740 {1, 1, "tim2", "tim3"}, 1741 {2, 2, "jim2", "jim3"}, 1742 }, 1743 }, 1744 { 1745 Query: "/* client a */ select from_id, to_id, from_name, to_name from dolt_diff('STAGED', 'WORKING', 'users') order by from_id, to_id", 1746 Expected: []sql.Row{ 1747 {1, 1, "tim2", "tim3"}, 1748 {2, 2, "jim2", "jim3"}, 1749 }, 1750 }, 1751 }, 1752 }, 1753 { 1754 Name: "staged changes in working set, dolt_add and dolt_commit on top of it", 1755 SetUpScript: []string{ 1756 "create table users (id int primary key, name varchar(32))", 1757 "insert into users values (1, 'tim'), (2, 'jim')", 1758 "call dolt_commit('-A', '-m', 'initial commit')", 1759 }, 1760 Assertions: []queries.ScriptTestAssertion{ 1761 { 1762 Query: "/* client a */ start transaction", 1763 SkipResultsCheck: true, 1764 }, 1765 { 1766 Query: "/* client b */ start transaction", 1767 SkipResultsCheck: true, 1768 }, 1769 { 1770 Query: "/* client a */ update users set name = 'tim2' where name = 'tim'", 1771 SkipResultsCheck: true, 1772 }, 1773 { 1774 Query: "/* client b */ update users set name = 'jim2' where name = 'jim'", 1775 SkipResultsCheck: true, 1776 }, 1777 { 1778 Query: "/* client a */ call dolt_add('users')", 1779 SkipResultsCheck: true, 1780 }, 1781 { 1782 Query: "/* client a */ commit", 1783 SkipResultsCheck: true, 1784 }, 1785 { 1786 Query: "/* client b */ call dolt_add('users')", 1787 SkipResultsCheck: true, 1788 }, 1789 { 1790 Query: "/* client b */ select * from users order by id", 1791 Expected: []sql.Row{{1, "tim"}, {2, "jim2"}}, 1792 }, 1793 { 1794 Query: "/* client b */ call dolt_commit('-m', 'jim2 commit')", 1795 SkipResultsCheck: true, 1796 }, 1797 { 1798 Query: "/* client b */ select * from users order by id", 1799 Expected: []sql.Row{{1, "tim2"}, {2, "jim2"}}, 1800 }, 1801 { 1802 Query: "/* client b */ select * from users as of 'HEAD' order by id", 1803 Expected: []sql.Row{{1, "tim2"}, {2, "jim2"}}, 1804 }, 1805 { 1806 Query: "/* client b */ select * from dolt_status", 1807 Expected: []sql.Row{}, 1808 }, 1809 { 1810 Query: "/* client b */ select from_id, to_id, from_name, to_name from dolt_diff('HEAD', 'STAGED', 'users') order by from_id, to_id", 1811 Expected: []sql.Row{}, 1812 }, 1813 { 1814 // staged changes include changes from both A and B at staged revision of data 1815 Query: "/* client b */ select from_id, to_id, from_name, to_name from dolt_diff('HEAD', 'WORKING', 'users') order by from_id, to_id", 1816 Expected: []sql.Row{}, 1817 }, 1818 }, 1819 }, 1820 { 1821 Name: "call dolt_commit commits staged stuff, merges with working set and branch head", 1822 SetUpScript: []string{ 1823 "create table t1 (id int primary key, val int)", 1824 "create table t2 (id int primary key, val int)", 1825 "insert into t1 values (1, 1), (2, 2)", 1826 "insert into t2 values (1, 1), (2, 2)", 1827 }, 1828 Assertions: []queries.ScriptTestAssertion{ 1829 { 1830 Query: "/* client a */ set autocommit = off", 1831 Expected: []sql.Row{{}}, 1832 }, 1833 { 1834 Query: "/* client a */ call dolt_add('t1')", 1835 Expected: []sql.Row{{0}}, 1836 }, 1837 { 1838 Query: "/* client a */ call dolt_commit('-m', 'initial commit of t1')", 1839 SkipResultsCheck: true, 1840 }, 1841 { 1842 Query: "/* client b */ set autocommit = off", 1843 Expected: []sql.Row{{}}, 1844 }, 1845 { 1846 Query: "/* client a */ start transaction", 1847 Expected: []sql.Row{}, 1848 }, 1849 { 1850 Query: "/* client b */ start transaction", 1851 Expected: []sql.Row{}, 1852 }, 1853 { 1854 Query: "/* client a */ insert into t1 values (3, 3)", 1855 Expected: []sql.Row{{types.NewOkResult(1)}}, 1856 }, 1857 { 1858 Query: "/* client b */ insert into t1 values (4, 4)", 1859 Expected: []sql.Row{{types.NewOkResult(1)}}, 1860 }, 1861 { 1862 Query: "/* client a */ insert into t2 values (3, 3)", 1863 Expected: []sql.Row{{types.NewOkResult(1)}}, 1864 }, 1865 { 1866 Query: "/* client b */ insert into t2 values (4, 4)", 1867 Expected: []sql.Row{{types.NewOkResult(1)}}, 1868 }, 1869 { 1870 Query: "/* client a */ call dolt_add('t1')", 1871 Expected: []sql.Row{{0}}, 1872 }, 1873 { 1874 Query: "/* client b */ call dolt_add('t1')", 1875 Expected: []sql.Row{{0}}, 1876 }, 1877 { 1878 Query: "/* client a */ insert into t1 values (5, 5)", 1879 Expected: []sql.Row{{types.NewOkResult(1)}}, 1880 }, 1881 { 1882 Query: "/* client b */ insert into t1 values (6, 6)", 1883 Expected: []sql.Row{{types.NewOkResult(1)}}, 1884 }, 1885 { 1886 Query: "/* client c */ insert into t2 values (6, 6)", 1887 Expected: []sql.Row{{types.NewOkResult(1)}}, 1888 }, 1889 { 1890 Query: "/* client a */ call dolt_commit('-m', 'add 3 to t1')", 1891 SkipResultsCheck: true, 1892 }, 1893 { 1894 Query: "/* client a */ select * from t2 order by id asc", 1895 Expected: []sql.Row{{1, 1}, {2, 2}, {3, 3}, {6, 6}}, 1896 }, 1897 { 1898 Query: "/* client a */ select * from t1 order by id asc", 1899 Expected: []sql.Row{{1, 1}, {2, 2}, {3, 3}, {5, 5}}, 1900 }, 1901 { 1902 Query: "/* client a */ select * from t1 as of 'HEAD' order by id asc", 1903 Expected: []sql.Row{{1, 1}, {2, 2}, {3, 3}}, 1904 }, 1905 { 1906 Query: "/* client b */ call dolt_commit('-m', 'add 4 to t1')", 1907 SkipResultsCheck: true, 1908 }, 1909 { 1910 Query: "/* client b */ select * from t2 order by id asc", 1911 Expected: []sql.Row{{1, 1}, {2, 2}, {3, 3}, {4, 4}, {6, 6}}, 1912 }, 1913 { 1914 Query: "/* client b */ select * from t1 order by id asc", 1915 Expected: []sql.Row{{1, 1}, {2, 2}, {3, 3}, {4, 4}, {5, 5}, {6, 6}}, 1916 }, 1917 { 1918 Query: "/* client b */ select * from t1 as of 'HEAD' order by id asc", 1919 Expected: []sql.Row{{1, 1}, {2, 2}, {3, 3}, {4, 4}}, 1920 }, 1921 { 1922 // working set has t2 new, t1 modified, nothing staged 1923 Query: "/* client a */ select * from dolt_status", 1924 Expected: []sql.Row{ 1925 {"t2", false, "new table"}, 1926 {"t1", false, "modified"}, 1927 }, 1928 }, 1929 { 1930 // working set has t2 new, t1 modified, nothing staged 1931 Query: "/* client b */ select * from dolt_status", 1932 Expected: []sql.Row{ 1933 {"t2", false, "new table"}, 1934 {"t1", false, "modified"}, 1935 }, 1936 }, 1937 { 1938 // client a has a stale view of t1 from before the commit, so it's missing the row with 4 in its session's working set 1939 Query: "/* client a */ select from_id, to_id, from_val, to_val from dolt_diff('HEAD', 'WORKING', 't1') order by from_id", 1940 Expected: []sql.Row{ 1941 {nil, 5, nil, 5}, 1942 {4, nil, 4, nil}, 1943 }, 1944 }, 1945 { 1946 Query: "/* client b */ select from_id, to_id, from_val, to_val from dolt_diff('HEAD', 'WORKING', 't1') order by from_id", 1947 Expected: []sql.Row{ 1948 {nil, 5, nil, 5}, 1949 {nil, 6, nil, 6}, 1950 }, 1951 }, 1952 }, 1953 }, 1954 } 1955 1956 var DoltConstraintViolationTransactionTests = []queries.TransactionTest{ 1957 { 1958 Name: "Constraint violations created by concurrent writes should cause a rollback", 1959 SetUpScript: []string{ 1960 "CREATE table parent (pk int PRIMARY KEY);", 1961 "CREATE table child (pk int PRIMARY KEY, parent_fk int, FOREIGN KEY (parent_fk) REFERENCES parent (pk));", 1962 "INSERT into parent VALUES (1);", 1963 }, 1964 Assertions: []queries.ScriptTestAssertion{ 1965 { 1966 Query: "/* client a */ SET @@autocommit=0;", 1967 Expected: []sql.Row{{}}, 1968 }, 1969 { 1970 Query: "/* client b */ SET @@autocommit=0;", 1971 Expected: []sql.Row{{}}, 1972 }, 1973 { 1974 Query: "/* client a */ START TRANSACTION;", 1975 Expected: []sql.Row{}, 1976 }, 1977 { 1978 Query: "/* client b */ START TRANSACTION;", 1979 Expected: []sql.Row{}, 1980 }, 1981 { 1982 Query: "/* client a */ DELETE FROM parent where pk = 1;", 1983 Expected: []sql.Row{{types.NewOkResult(1)}}, 1984 }, 1985 { 1986 Query: "/* client b */ INSERT INTO child VALUES (1, 1);", 1987 Expected: []sql.Row{{types.NewOkResult(1)}}, 1988 }, 1989 { 1990 Query: "/* client a */ COMMIT;", 1991 Expected: []sql.Row{}, 1992 }, 1993 { 1994 Query: "/* client b */ COMMIT;", 1995 ExpectedErrStr: "Committing this transaction resulted in a working set with constraint violations, transaction rolled back. " + 1996 "This constraint violation may be the result of a previous merge or the result of transaction sequencing. " + 1997 "Constraint violations from a merge can be resolved using the dolt_constraint_violations table before committing the transaction. " + 1998 "To allow transactions to be committed with constraint violations from a merge or transaction sequencing set @@dolt_force_transaction_commit=1.\n" + 1999 "Constraint violations: \n" + 2000 "Type: Foreign Key Constraint Violation\n" + 2001 "\tForeignKey: child_ibfk_1,\n" + 2002 "\tTable: child,\n" + 2003 "\tReferencedTable: ,\n" + 2004 "\tIndex: parent_fk,\n" + 2005 "\tReferencedIndex: ", 2006 }, 2007 { 2008 Query: "/* client b */ INSERT INTO child VALUES (1, 1);", 2009 ExpectedErrStr: "cannot add or update a child row - Foreign key violation on fk: `child_ibfk_1`, table: `child`, referenced table: `parent`, key: `[1]`", 2010 }, 2011 }, 2012 }, 2013 { 2014 Name: "Constraint violations created by DOLT_MERGE should cause a roll back", 2015 SetUpScript: []string{ 2016 "CREATE TABLE t (pk int PRIMARY KEY, col1 int UNIQUE);", 2017 "CALL DOLT_ADD('.')", 2018 "CALL DOLT_COMMIT('-am', 'create table');", 2019 2020 "CALL DOLT_CHECKOUT('-b', 'right');", 2021 "INSERT INTO t values (2, 1);", 2022 "CALL DOLT_COMMIT('-am', 'right edit');", 2023 2024 "CALL DOLT_CHECKOUT('main');", 2025 "INSERT INTO t VALUES (1, 1);", 2026 "CALL DOLT_COMMIT('-am', 'left edit');", 2027 }, 2028 Assertions: []queries.ScriptTestAssertion{ 2029 { 2030 Query: "/* client a */ CALL DOLT_MERGE('right');", 2031 ExpectedErrStr: "Committing this transaction resulted in a working set with constraint violations, transaction rolled back. " + 2032 "This constraint violation may be the result of a previous merge or the result of transaction sequencing. " + 2033 "Constraint violations from a merge can be resolved using the dolt_constraint_violations table before committing the transaction. " + 2034 "To allow transactions to be committed with constraint violations from a merge or transaction sequencing set @@dolt_force_transaction_commit=1.\n" + 2035 "Constraint violations: \n" + 2036 "Type: Unique Key Constraint Violation,\n" + 2037 "\tName: col1,\n" + 2038 "\tColumns: [col1]", 2039 }, 2040 { 2041 Query: "/* client a */ SELECT * from DOLT_CONSTRAINT_VIOLATIONS;", 2042 Expected: []sql.Row{}, 2043 }, 2044 { 2045 Query: "/* client a */ CALL DOLT_MERGE('--abort');", 2046 ExpectedErrStr: "fatal: There is no merge to abort", 2047 }, 2048 }, 2049 }, 2050 { 2051 Name: "a transaction commit that is a fast-forward produces no constraint violations", 2052 SetUpScript: []string{ 2053 "CREATE TABLE parent (pk BIGINT PRIMARY KEY, v1 BIGINT, INDEX(v1));", 2054 "CREATE TABLE child (pk BIGINT PRIMARY KEY, v1 BIGINT);", 2055 "CALL DOLT_ADD('.')", 2056 "INSERT INTO parent VALUES (10, 1), (20, 2);", 2057 "INSERT INTO child VALUES (1, 1), (2, 2);", 2058 "ALTER TABLE child ADD CONSTRAINT fk_name FOREIGN KEY (v1) REFERENCES parent (v1);", 2059 "CALL DOLT_COMMIT('-am', 'MC1');", 2060 }, 2061 Assertions: []queries.ScriptTestAssertion{ 2062 { 2063 Query: "/* client a */ SET FOREIGN_KEY_CHECKS = 0;", 2064 Expected: []sql.Row{{}}, 2065 }, 2066 { 2067 Query: "/* client a */ START TRANSACTION;", 2068 Expected: []sql.Row{}, 2069 }, 2070 { 2071 Query: "/* client a */ DELETE FROM PARENT where v1 = 2;", 2072 Expected: []sql.Row{{types.NewOkResult(1)}}, 2073 }, 2074 { 2075 Query: "/* client a */ COMMIT;", 2076 Expected: []sql.Row{}, 2077 }, 2078 }, 2079 }, 2080 { 2081 Name: "a transaction commit that is a three-way merge produces constraint violations", 2082 SetUpScript: []string{ 2083 "CREATE TABLE parent (pk BIGINT PRIMARY KEY, v1 BIGINT, INDEX(v1));", 2084 "CREATE TABLE child (pk BIGINT PRIMARY KEY, v1 BIGINT);", 2085 "CALL DOLT_ADD('.')", 2086 "INSERT INTO parent VALUES (10, 1), (20, 2);", 2087 "INSERT INTO child VALUES (1, 1), (2, 2);", 2088 "ALTER TABLE child ADD CONSTRAINT fk_name FOREIGN KEY (v1) REFERENCES parent (v1);", 2089 "CALL DOLT_COMMIT('-am', 'MC1');", 2090 }, 2091 Assertions: []queries.ScriptTestAssertion{ 2092 { 2093 Query: "/* client a */ SET FOREIGN_KEY_CHECKS = 0;", 2094 Expected: []sql.Row{{}}, 2095 }, 2096 { 2097 Query: "/* client a */ START TRANSACTION;", 2098 Expected: []sql.Row{}, 2099 }, 2100 { 2101 Query: "/* client b */ START TRANSACTION;", 2102 Expected: []sql.Row{}, 2103 }, 2104 { 2105 Query: "/* client a */ DELETE FROM PARENT where v1 = 2;", 2106 Expected: []sql.Row{{types.NewOkResult(1)}}, 2107 }, 2108 { 2109 Query: "/* client b */ INSERT INTO parent VALUES (30, 3);", 2110 Expected: []sql.Row{{types.NewOkResult(1)}}, 2111 }, 2112 { 2113 Query: "/* client a */ COMMIT;", 2114 Expected: []sql.Row{}, 2115 }, 2116 { 2117 Query: "/* client b */ COMMIT;", 2118 ExpectedErrStr: "Committing this transaction resulted in a working set with constraint violations, transaction rolled back. " + 2119 "This constraint violation may be the result of a previous merge or the result of transaction sequencing. " + 2120 "Constraint violations from a merge can be resolved using the dolt_constraint_violations table before committing the transaction. " + 2121 "To allow transactions to be committed with constraint violations from a merge or transaction sequencing set @@dolt_force_transaction_commit=1.\n" + 2122 "Constraint violations: \n" + 2123 "Type: Foreign Key Constraint Violation\n" + 2124 "\tForeignKey: fk_name,\n" + 2125 "\tTable: child,\n" + 2126 "\tReferencedTable: v1,\n" + 2127 "\tIndex: v1,\n" + 2128 "\tReferencedIndex: v1", 2129 }, 2130 }, 2131 }, 2132 // { 2133 // Name: "Run GC concurrently with other transactions", 2134 // SetUpScript: gcSetup(), 2135 // Assertions: []queries.ScriptTestAssertion{ 2136 // { 2137 // Query: "/* client a */ SELECT count(*) FROM t;", 2138 // Expected: []sql.Row{{250}}, 2139 // }, 2140 // { 2141 // Query: "/* client a */ START TRANSACTION", 2142 // Expected: []sql.Row{}, 2143 // }, 2144 // { 2145 // Query: "/* client b */ START TRANSACTION", 2146 // Expected: []sql.Row{}, 2147 // }, 2148 // { 2149 // Query: "/* client a */ CALL DOLT_GC();", 2150 // Expected: []sql.Row{{1}}, 2151 // }, 2152 // { 2153 // Query: "/* client b */ INSERT into t VALUES (300);", 2154 // Expected: []sql.Row{{types.NewOkResult(1)}}, 2155 // }, 2156 // { 2157 // Query: "/* client a */ COMMIT;", 2158 // Expected: []sql.Row{}, 2159 // }, 2160 // { 2161 // Query: "/* client b */ COMMIT;", 2162 // Expected: []sql.Row{}, 2163 // }, 2164 // { 2165 // Query: "/* client a */ SELECT count(*) FROM t;", 2166 // Expected: []sql.Row{{251}}, 2167 // }, 2168 // { 2169 // Query: "/* client b */ SELECT count(*) FROM t;", 2170 // Expected: []sql.Row{{251}}, 2171 // }, 2172 // }, 2173 // }, 2174 } 2175 2176 var BranchIsolationTests = []queries.TransactionTest{ 2177 { 2178 Name: "clients can't see changes on other branch working sets made since transaction start", 2179 SetUpScript: []string{ 2180 "create table t1 (a int)", 2181 "insert into t1 values (1)", 2182 "call dolt_add('.')", 2183 "call dolt_commit('-am', 'new table')", 2184 "call dolt_branch('b1')", 2185 "set autocommit = 0", 2186 }, 2187 Assertions: []queries.ScriptTestAssertion{ 2188 { 2189 Query: "/* client a */ start transaction", 2190 SkipResultsCheck: true, 2191 }, 2192 { 2193 Query: "/* client b */ start transaction", 2194 SkipResultsCheck: true, 2195 }, 2196 { 2197 Query: "/* client b */ call dolt_checkout('b1')", 2198 SkipResultsCheck: true, 2199 }, 2200 { 2201 Query: "/* client b */ insert into t1 values (2)", 2202 SkipResultsCheck: true, 2203 }, 2204 { 2205 Query: "/* client b */ commit", 2206 SkipResultsCheck: true, 2207 }, 2208 { 2209 Query: "/* client a */ select * from t1 order by a", 2210 Expected: []sql.Row{{1}}, 2211 }, 2212 { 2213 Query: "/* client a */ select * from t1 as of 'b1' order by a", 2214 Expected: []sql.Row{{1}}, 2215 }, 2216 { 2217 Query: "/* client a */ select * from `mydb/b1`.t1 order by a", 2218 Expected: []sql.Row{{1}}, 2219 }, 2220 { 2221 Query: "/* client a */ start transaction", 2222 SkipResultsCheck: true, 2223 }, 2224 { 2225 Query: "/* client a */ select * from t1 order by a", 2226 Expected: []sql.Row{{1}}, 2227 }, 2228 { 2229 // This query specifies the branch HEAD commit, which hasn't changed 2230 Query: "/* client a */ select * from t1 as of 'b1' order by a", 2231 Expected: []sql.Row{{1}}, 2232 }, 2233 { 2234 // This query specifies the working set of that branch, which has changed 2235 Query: "/* client a */ select * from `mydb/b1`.t1 order by a", 2236 Expected: []sql.Row{{1}, {2}}, 2237 }, 2238 }, 2239 }, 2240 { 2241 Name: "clients can't see changes on other branch heads made since transaction start", 2242 SetUpScript: []string{ 2243 "create table t1 (a int)", 2244 "insert into t1 values (1)", 2245 "call dolt_add('.')", 2246 "call dolt_commit('-am', 'new table')", 2247 "call dolt_branch('b1')", 2248 "set autocommit = 0", 2249 }, 2250 Assertions: []queries.ScriptTestAssertion{ 2251 { 2252 Query: "/* client a */ start transaction", 2253 SkipResultsCheck: true, 2254 }, 2255 { 2256 Query: "/* client b */ start transaction", 2257 SkipResultsCheck: true, 2258 }, 2259 { 2260 Query: "/* client b */ call dolt_checkout('b1')", 2261 SkipResultsCheck: true, 2262 }, 2263 { 2264 Query: "/* client b */ insert into t1 values (2)", 2265 SkipResultsCheck: true, 2266 }, 2267 { 2268 Query: "/* client b */ call dolt_commit('-am', 'new row')", 2269 SkipResultsCheck: true, 2270 }, 2271 { 2272 Query: "/* client a */ select * from t1 order by a", 2273 Expected: []sql.Row{{1}}, 2274 }, 2275 { 2276 Query: "/* client a */ select * from t1 as of 'b1' order by a", 2277 Expected: []sql.Row{{1}}, 2278 }, 2279 { 2280 Query: "/* client a */ select * from `mydb/b1`.t1 order by a", 2281 Expected: []sql.Row{{1}}, 2282 }, 2283 { 2284 Query: "/* client a */ start transaction", 2285 SkipResultsCheck: true, 2286 }, 2287 { 2288 Query: "/* client a */ select * from t1 order by a", 2289 Expected: []sql.Row{{1}}, 2290 }, 2291 { 2292 Query: "/* client a */ select * from t1 as of 'b1' order by a", 2293 Expected: []sql.Row{{1}, {2}}, 2294 }, 2295 { 2296 Query: "/* client a */ select * from `mydb/b1`.t1 order by a", 2297 Expected: []sql.Row{{1}, {2}}, 2298 }, 2299 }, 2300 }, 2301 { 2302 Name: "dolt_branches table has consistent view", 2303 SetUpScript: []string{ 2304 "create table t1 (a int)", 2305 "insert into t1 values (1)", 2306 "call dolt_add('.')", 2307 "call dolt_commit('-am', 'new table')", 2308 "call dolt_branch('b1')", 2309 "set autocommit = 0", 2310 }, 2311 Assertions: []queries.ScriptTestAssertion{ 2312 { 2313 Query: "/* client a */ start transaction", 2314 SkipResultsCheck: true, 2315 }, 2316 { 2317 Query: "/* client b */ call dolt_branch('-d', 'b1')", 2318 SkipResultsCheck: true, 2319 }, 2320 { 2321 Query: "/* client b */ call dolt_branch('b2')", 2322 SkipResultsCheck: true, 2323 }, 2324 { 2325 Query: "/* client b */ select name from dolt_branches order by 1", 2326 Expected: []sql.Row{{"b2"}, {"main"}}, 2327 }, 2328 { 2329 Query: "/* client b */ commit", 2330 SkipResultsCheck: true, 2331 }, 2332 { 2333 Query: "/* client a */ select name from dolt_branches order by 1", 2334 Expected: []sql.Row{{"b1"}, {"main"}}, 2335 }, 2336 { 2337 Query: "/* client a */ start transaction", 2338 SkipResultsCheck: true, 2339 }, 2340 { 2341 Query: "/* client a */ select name from dolt_branches order by 1", 2342 Expected: []sql.Row{{"b2"}, {"main"}}, 2343 }, 2344 }, 2345 }, 2346 } 2347 2348 var MultiDbTransactionTests = []queries.ScriptTest{ 2349 { 2350 Name: "committing to another branch", 2351 SetUpScript: []string{ 2352 "create table t1 (a int)", 2353 "call dolt_add('.')", 2354 "call dolt_commit('-am', 'new table')", 2355 "call dolt_branch('b1')", 2356 "set autocommit = 0", 2357 }, 2358 Assertions: []queries.ScriptTestAssertion{ 2359 { 2360 Query: "insert into `mydb/b1`.t1 values (1)", 2361 Expected: []sql.Row{ 2362 {types.OkResult{RowsAffected: 1}}, 2363 }, 2364 }, 2365 { 2366 Query: "insert into `mydb/b1`.t1 values (2)", 2367 Expected: []sql.Row{ 2368 {types.OkResult{RowsAffected: 1}}, 2369 }, 2370 }, 2371 { 2372 Query: "select * from t1 order by a", 2373 Expected: []sql.Row{}, 2374 }, 2375 { 2376 Query: "select * from `mydb/b1`.t1 order by a", 2377 Expected: []sql.Row{ 2378 {1}, {2}, 2379 }, 2380 }, 2381 { 2382 Query: "commit", 2383 Expected: []sql.Row{}, 2384 }, 2385 { 2386 Query: "select * from t1 order by a", 2387 Expected: []sql.Row{}, 2388 }, 2389 { 2390 Query: "call dolt_checkout('b1')", 2391 SkipResultsCheck: true, 2392 }, 2393 { 2394 Query: "select * from t1 order by a", 2395 Expected: []sql.Row{ 2396 {1}, {2}, 2397 }, 2398 }, 2399 }, 2400 }, 2401 { 2402 Name: "committing to another branch with autocommit", 2403 SetUpScript: []string{ 2404 "create table t1 (a int)", 2405 "call dolt_add('.')", 2406 "call dolt_commit('-am', 'new table')", 2407 "call dolt_branch('b1')", 2408 "set autocommit = on", // unnecessary but make it explicit 2409 }, 2410 Assertions: []queries.ScriptTestAssertion{ 2411 { 2412 Query: "insert into `mydb/b1`.t1 values (1)", 2413 Expected: []sql.Row{ 2414 {types.OkResult{RowsAffected: 1}}, 2415 }, 2416 }, 2417 { 2418 Query: "select * from t1 order by a", 2419 Expected: []sql.Row{}, 2420 }, 2421 { 2422 Query: "call dolt_checkout('b1')", 2423 SkipResultsCheck: true, 2424 }, 2425 { 2426 Query: "select * from t1 order by a", 2427 Expected: []sql.Row{{1}}, 2428 }, 2429 }, 2430 }, 2431 { 2432 Name: "committing to another branch with dolt_transaction_commit", 2433 SetUpScript: []string{ 2434 "create table t1 (a int)", 2435 "call dolt_add('.')", 2436 "call dolt_commit('-am', 'new table')", 2437 "call dolt_branch('b1')", 2438 "set autocommit = 0", 2439 "set dolt_transaction_commit = on", 2440 }, 2441 Assertions: []queries.ScriptTestAssertion{ 2442 { 2443 Query: "insert into `mydb/b1`.t1 values (1)", 2444 Expected: []sql.Row{ 2445 {types.OkResult{RowsAffected: 1}}, 2446 }, 2447 }, 2448 { 2449 Query: "insert into `mydb/b1`.t1 values (2)", 2450 Expected: []sql.Row{ 2451 {types.OkResult{RowsAffected: 1}}, 2452 }, 2453 }, 2454 { 2455 Query: "select * from t1 order by a", 2456 Expected: []sql.Row{}, 2457 }, 2458 { 2459 Query: "select * from `mydb/b1`.t1 order by a", 2460 Expected: []sql.Row{ 2461 {1}, {2}, 2462 }, 2463 }, 2464 { 2465 Query: "commit", 2466 ExpectedErrStr: "no changes to dolt_commit on branch main", 2467 }, 2468 { 2469 Query: "select * from `mydb/main`.t1 order by a", 2470 Expected: []sql.Row{}, 2471 }, 2472 { 2473 Query: "use mydb/b1", 2474 Expected: []sql.Row{}, 2475 }, 2476 { 2477 Query: "commit", 2478 Expected: []sql.Row{}, 2479 }, 2480 { 2481 Query: "select * from `mydb/b1`.t1 order by a", 2482 Expected: []sql.Row{ 2483 {1}, {2}, 2484 }, 2485 }, 2486 { 2487 Query: "select * from `mydb/main`.t1 order by a", 2488 Expected: []sql.Row{}, 2489 }, 2490 { 2491 Query: "select * from t1 order by a", 2492 Expected: []sql.Row{ 2493 {1}, {2}, 2494 }, 2495 }, 2496 }, 2497 }, 2498 { 2499 Name: "committing to another branch with dolt_commit", 2500 SetUpScript: []string{ 2501 "create table t1 (a int)", 2502 "call dolt_add('.')", 2503 "call dolt_commit('-am', 'new table')", 2504 "call dolt_branch('b1')", 2505 "set autocommit = off", 2506 }, 2507 Assertions: []queries.ScriptTestAssertion{ 2508 { 2509 Query: "insert into `mydb/b1`.t1 values (1)", 2510 Expected: []sql.Row{ 2511 {types.OkResult{RowsAffected: 1}}, 2512 }, 2513 }, 2514 { 2515 Query: "select * from t1 order by a", 2516 Expected: []sql.Row{}, 2517 }, 2518 { 2519 Query: "call dolt_commit('-am', 'changes on b1')", 2520 ExpectedErrStr: "nothing to commit", // this error is different from what you get with @@dolt_transaction_commit 2521 }, 2522 { 2523 Query: "use mydb/b1", 2524 Expected: []sql.Row{}, 2525 }, 2526 { 2527 Query: "call dolt_commit('-am', 'other changes on b1')", 2528 SkipResultsCheck: true, 2529 }, 2530 { 2531 Query: "select * from t1 order by a", 2532 Expected: []sql.Row{{1}}, 2533 }, 2534 { 2535 Query: "select message from dolt_log order by date desc limit 1", 2536 Expected: []sql.Row{{"other changes on b1"}}, 2537 }, 2538 }, 2539 }, 2540 { 2541 Name: "committing to another branch with autocommit and dolt_transaction_commit", 2542 SetUpScript: []string{ 2543 "create table t1 (a int)", 2544 "call dolt_add('.')", 2545 "call dolt_commit('-am', 'new table')", 2546 "call dolt_branch('b1')", 2547 "set autocommit = on", // unnecessary but make it explicit 2548 "set dolt_transaction_commit = on", 2549 }, 2550 Assertions: []queries.ScriptTestAssertion{ 2551 { 2552 Query: "insert into `mydb/b1`.t1 values (1)", 2553 ExpectedErrStr: "no changes to dolt_commit on branch main", 2554 }, 2555 { 2556 Query: "use mydb/b1", 2557 Expected: []sql.Row{}, 2558 }, 2559 { 2560 Query: "select * from t1 order by a", 2561 Expected: []sql.Row{ 2562 {1}, 2563 }, 2564 }, 2565 { 2566 Query: "commit", 2567 Expected: []sql.Row{}, 2568 }, 2569 { 2570 Query: "select * from t1 order by a", 2571 Expected: []sql.Row{ 2572 {1}, 2573 }, 2574 }, 2575 }, 2576 }, 2577 { 2578 Name: "active_branch with dolt_checkout and use", 2579 SetUpScript: []string{ 2580 "create table t1 (a int)", 2581 "call dolt_add('.')", 2582 "call dolt_commit('-am', 'new table')", 2583 "call dolt_branch('b1')", 2584 "set autocommit = 0", 2585 }, 2586 Assertions: []queries.ScriptTestAssertion{ 2587 { 2588 Query: "insert into `mydb/b1`.t1 values (1)", 2589 Expected: []sql.Row{ 2590 {types.OkResult{RowsAffected: 1}}, 2591 }, 2592 }, 2593 { 2594 Query: "insert into `mydb/b1`.t1 values (2)", 2595 Expected: []sql.Row{ 2596 {types.OkResult{RowsAffected: 1}}, 2597 }, 2598 }, 2599 { 2600 Query: "select * from t1 order by a", 2601 Expected: []sql.Row{}, 2602 }, 2603 { 2604 Query: "call dolt_checkout('b1')", 2605 SkipResultsCheck: true, 2606 }, 2607 { 2608 Query: "select active_branch()", 2609 Expected: []sql.Row{{"b1"}}, 2610 }, 2611 { 2612 Query: "select * from t1 order by a", 2613 Expected: []sql.Row{ 2614 {1}, {2}, 2615 }, 2616 }, 2617 { 2618 Query: "call dolt_checkout('main')", 2619 SkipResultsCheck: true, 2620 }, 2621 { 2622 Query: "select active_branch()", 2623 Expected: []sql.Row{{"main"}}, 2624 }, 2625 { 2626 Query: "select * from t1 order by a", 2627 Expected: []sql.Row{}, 2628 }, 2629 { 2630 Query: "use `mydb/b1`", 2631 Expected: []sql.Row{}, 2632 }, 2633 { 2634 Query: "select active_branch()", 2635 Expected: []sql.Row{{"b1"}}, 2636 }, 2637 { 2638 Query: "select * from t1 order by a", 2639 Expected: []sql.Row{{1}, {2}}, 2640 }, 2641 { 2642 Query: "use mydb", 2643 Expected: []sql.Row{}, 2644 }, 2645 { 2646 Query: "select active_branch()", 2647 Expected: []sql.Row{{"main"}}, 2648 }, 2649 { 2650 Query: "commit", 2651 Expected: []sql.Row{}, 2652 }, 2653 { 2654 Query: "select * from t1 order by a", 2655 Expected: []sql.Row{}, 2656 }, 2657 { 2658 Query: "call dolt_checkout('b1')", 2659 SkipResultsCheck: true, 2660 }, 2661 { 2662 Query: "select * from t1 order by a", 2663 Expected: []sql.Row{ 2664 {1}, {2}, 2665 }, 2666 }, 2667 }, 2668 }, 2669 { 2670 Name: "committing to another database", 2671 SetUpScript: []string{ 2672 "create table t1 (a int)", 2673 "call dolt_add('.')", 2674 "call dolt_commit('-am', 'new table')", 2675 "create database db1", 2676 "use db1", 2677 "create table t1 (a int)", 2678 "use mydb", 2679 "set autocommit = 0", 2680 }, 2681 Assertions: []queries.ScriptTestAssertion{ 2682 { 2683 Query: "insert into db1.t1 values (1)", 2684 Expected: []sql.Row{ 2685 {types.OkResult{RowsAffected: 1}}, 2686 }, 2687 }, 2688 { 2689 Query: "insert into db1.t1 values (2)", 2690 Expected: []sql.Row{ 2691 {types.OkResult{RowsAffected: 1}}, 2692 }, 2693 }, 2694 { 2695 Query: "select * from t1 order by a", 2696 Expected: []sql.Row{}, 2697 }, 2698 { 2699 Query: "select * from db1.t1 order by a", 2700 Expected: []sql.Row{{1}, {2}}, 2701 }, 2702 { 2703 Query: "commit", 2704 Expected: []sql.Row{}, 2705 }, 2706 { 2707 Query: "select * from t1 order by a", 2708 Expected: []sql.Row{}, 2709 }, 2710 { 2711 Query: "select * from db1.t1 order by a", 2712 Expected: []sql.Row{{1}, {2}}, 2713 }, 2714 }, 2715 }, 2716 { 2717 Name: "committing to another database with dolt_commit", 2718 SetUpScript: []string{ 2719 "create table t1 (a int)", 2720 "call dolt_add('.')", 2721 "call dolt_commit('-am', 'new table')", 2722 "call dolt_branch('b1')", 2723 "create database db1", 2724 "use db1", 2725 "create table t1 (a int)", 2726 "call dolt_add('.')", 2727 "call dolt_commit('-am', 'new table')", 2728 "call dolt_branch('b1')", 2729 "use mydb/b1", 2730 "set autocommit = off", 2731 }, 2732 Assertions: []queries.ScriptTestAssertion{ 2733 { 2734 Query: "insert into `db1/b1`.t1 values (1)", 2735 Expected: []sql.Row{{types.OkResult{RowsAffected: 1}}}, 2736 }, 2737 { 2738 Query: "call dolt_commit('-am', 'changes on b1')", 2739 ExpectedErrStr: "nothing to commit", // this error is different from what you get with @@dolt_transaction_commit 2740 }, 2741 { 2742 Query: "use db1/b1", 2743 Expected: []sql.Row{}, 2744 }, 2745 { 2746 Query: "call dolt_commit('-am', 'other changes on b1')", 2747 SkipResultsCheck: true, 2748 }, 2749 { 2750 Query: "select * from t1 order by a", 2751 Expected: []sql.Row{{1}}, 2752 }, 2753 { 2754 Query: "select message from dolt_log order by date desc limit 1", 2755 Expected: []sql.Row{{"other changes on b1"}}, 2756 }, 2757 }, 2758 }, 2759 { 2760 Name: "committing to another branch on another database", 2761 SetUpScript: []string{ 2762 "create table t1 (a int)", 2763 "call dolt_add('.')", 2764 "call dolt_commit('-am', 'new table')", 2765 "create database db1", 2766 "use db1", 2767 "create table t1 (a int)", 2768 "call dolt_add('.')", 2769 "call dolt_commit('-am', 'new table')", 2770 "call dolt_branch('b1')", 2771 "use mydb", 2772 "set autocommit = 0", 2773 }, 2774 Assertions: []queries.ScriptTestAssertion{ 2775 { 2776 Query: "insert into `db1/b1`.t1 values (1)", 2777 Expected: []sql.Row{ 2778 {types.OkResult{RowsAffected: 1}}, 2779 }, 2780 }, 2781 { 2782 Query: "insert into `db1/b1`.t1 values (2)", 2783 Expected: []sql.Row{ 2784 {types.OkResult{RowsAffected: 1}}, 2785 }, 2786 }, 2787 { 2788 Query: "select * from t1 order by a", 2789 Expected: []sql.Row{}, 2790 }, 2791 { 2792 Query: "select * from db1.t1 order by a", 2793 Expected: []sql.Row{}, 2794 }, 2795 { 2796 Query: "select * from `db1/b1`.t1 order by a", 2797 Expected: []sql.Row{{1}, {2}}, 2798 }, 2799 { 2800 Query: "commit", 2801 Expected: []sql.Row{}, 2802 }, 2803 { 2804 Query: "select * from t1 order by a", 2805 Expected: []sql.Row{}, 2806 }, 2807 { 2808 Query: "select * from db1.t1 order by a", 2809 Expected: []sql.Row{}, 2810 }, 2811 { 2812 Query: "select * from `db1/b1`.t1 order by a", 2813 Expected: []sql.Row{{1}, {2}}, 2814 }, 2815 }, 2816 }, 2817 { 2818 Name: "committing to another branch on another database with dolt_transaction_commit and autocommit", 2819 SetUpScript: []string{ 2820 "create table t1 (a int)", 2821 "call dolt_add('.')", 2822 "call dolt_commit('-am', 'new table')", 2823 "call dolt_branch('b1')", 2824 "create database db1", 2825 "use db1", 2826 "create table t1 (a int)", 2827 "call dolt_add('.')", 2828 "call dolt_commit('-am', 'new table')", 2829 "call dolt_branch('b1')", 2830 "use mydb/b1", 2831 "set autocommit = 1", 2832 "set dolt_transaction_commit = 1", 2833 }, 2834 Assertions: []queries.ScriptTestAssertion{ 2835 { 2836 Query: "insert into `db1/b1`.t1 values (1)", 2837 ExpectedErrStr: "no changes to dolt_commit on database mydb", 2838 }, 2839 }, 2840 }, 2841 { 2842 Name: "committing to another branch on another database with dolt_transaction_commit, no autocommit", 2843 SetUpScript: []string{ 2844 "create table t1 (a int)", 2845 "call dolt_add('.')", 2846 "call dolt_commit('-am', 'new table')", 2847 "call dolt_branch('b1')", 2848 "create database db1", 2849 "use db1", 2850 "create table t1 (a int)", 2851 "call dolt_add('.')", 2852 "call dolt_commit('-am', 'new table')", 2853 "call dolt_branch('b1')", 2854 "commit", 2855 "use mydb/b1", 2856 "set autocommit = off", 2857 "set dolt_transaction_commit = 1", 2858 }, 2859 Assertions: []queries.ScriptTestAssertion{ 2860 { 2861 Query: "insert into `db1/b1`.t1 values (1)", 2862 Expected: []sql.Row{ 2863 {types.OkResult{RowsAffected: 1}}, 2864 }, 2865 }, 2866 { 2867 Query: "commit", 2868 ExpectedErrStr: "no changes to dolt_commit on database mydb", 2869 }, 2870 }, 2871 }, 2872 { 2873 Name: "committing to more than one branch at a time", 2874 SetUpScript: []string{ 2875 "create table t1 (a int)", 2876 "call dolt_add('.')", 2877 "call dolt_commit('-am', 'new table')", 2878 "call dolt_branch('b1')", 2879 "set autocommit = 0", 2880 }, 2881 Assertions: []queries.ScriptTestAssertion{ 2882 { 2883 Query: "insert into t1 values (1)", 2884 Expected: []sql.Row{ 2885 {types.OkResult{RowsAffected: 1}}, 2886 }, 2887 }, 2888 { 2889 Query: "insert into `mydb/b1`.t1 values (2)", 2890 Expected: []sql.Row{ 2891 {types.OkResult{RowsAffected: 1}}, 2892 }, 2893 }, 2894 { 2895 Query: "commit", 2896 ExpectedErrStr: "Cannot commit changes on more than one branch / database", 2897 }, 2898 }, 2899 }, 2900 { 2901 Name: "committing to more than one branch at a time with checkout", 2902 SetUpScript: []string{ 2903 "create table t1 (a int)", 2904 "call dolt_add('.')", 2905 "call dolt_commit('-am', 'new table')", 2906 "call dolt_branch('b1')", 2907 "set autocommit = 0", 2908 }, 2909 Assertions: []queries.ScriptTestAssertion{ 2910 { 2911 Query: "insert into t1 values (1)", 2912 Expected: []sql.Row{ 2913 {types.OkResult{RowsAffected: 1}}, 2914 }, 2915 }, 2916 { 2917 Query: "call dolt_checkout('b1')", 2918 SkipResultsCheck: true, 2919 }, 2920 { 2921 Query: "insert into t1 values (2)", 2922 Expected: []sql.Row{ 2923 {types.OkResult{RowsAffected: 1}}, 2924 }, 2925 }, 2926 { 2927 Query: "commit", 2928 ExpectedErrStr: "Cannot commit changes on more than one branch / database", 2929 }, 2930 }, 2931 }, 2932 { 2933 Name: "committing to more than one database at a time", 2934 SetUpScript: []string{ 2935 "create table t1 (a int)", 2936 "call dolt_add('.')", 2937 "call dolt_commit('-am', 'new table')", 2938 "create database db2", 2939 "set autocommit = 0", 2940 "create table db2.t1 (a int)", 2941 }, 2942 Assertions: []queries.ScriptTestAssertion{ 2943 { 2944 Query: "insert into t1 values (1)", 2945 Expected: []sql.Row{ 2946 {types.OkResult{RowsAffected: 1}}, 2947 }, 2948 }, 2949 { 2950 Query: "insert into db2.t1 values (2)", 2951 Expected: []sql.Row{ 2952 {types.OkResult{RowsAffected: 1}}, 2953 }, 2954 }, 2955 { 2956 Query: "commit", 2957 ExpectedErrStr: "Cannot commit changes on more than one branch / database", 2958 }, 2959 }, 2960 }, 2961 } 2962 2963 var MultiDbSavepointTests = []queries.TransactionTest{ 2964 { 2965 Name: "rollback to savepoint with multiple databases edited", 2966 SetUpScript: []string{ 2967 "create database db1", 2968 "create database db2", 2969 "create table db1.t (x int primary key, y int)", 2970 "insert into db1.t values (1, 1)", 2971 "create table db2.t (x int primary key, y int)", 2972 "insert into db2.t values (2, 2)", 2973 }, 2974 Assertions: []queries.ScriptTestAssertion{ 2975 { 2976 Query: "/* client a */ set autocommit = off", 2977 Expected: []sql.Row{{}}, 2978 }, 2979 { 2980 Query: "/* client b */ set autocommit = off", 2981 Expected: []sql.Row{{}}, 2982 }, 2983 { 2984 Query: "/* client a */ start transaction", 2985 Expected: []sql.Row{}, 2986 }, 2987 { 2988 Query: "/* client b */ start transaction", 2989 Expected: []sql.Row{}, 2990 }, 2991 { 2992 Query: "/* client a */ insert into db1.t values (3, 3)", 2993 Expected: []sql.Row{{types.NewOkResult(1)}}, 2994 }, 2995 { 2996 Query: "/* client a */ insert into db2.t values (4, 4)", 2997 Expected: []sql.Row{{types.NewOkResult(1)}}, 2998 }, 2999 { 3000 Query: "/* client b */ insert into db1.t values (5, 5)", 3001 Expected: []sql.Row{{types.NewOkResult(1)}}, 3002 }, 3003 { 3004 Query: "/* client b */ insert into db2.t values (6, 6)", 3005 Expected: []sql.Row{{types.NewOkResult(1)}}, 3006 }, 3007 { 3008 Query: "/* client a */ savepoint spa1", 3009 Expected: []sql.Row{}, 3010 }, 3011 { 3012 Query: "/* client b */ savepoint spb1", 3013 Expected: []sql.Row{}, 3014 }, 3015 { 3016 Query: "/* client a */ insert into db1.t values (5, 5)", 3017 Expected: []sql.Row{{types.NewOkResult(1)}}, 3018 }, 3019 { 3020 Query: "/* client a */ insert into db2.t values (6, 6)", 3021 Expected: []sql.Row{{types.NewOkResult(1)}}, 3022 }, 3023 { 3024 Query: "/* client b */ insert into db1.t values (7, 7)", 3025 Expected: []sql.Row{{types.NewOkResult(1)}}, 3026 }, 3027 { 3028 Query: "/* client b */ insert into db2.t values (8, 8)", 3029 Expected: []sql.Row{{types.NewOkResult(1)}}, 3030 }, 3031 { 3032 Query: "/* client a */ savepoint spa2", 3033 Expected: []sql.Row{}, 3034 }, 3035 { 3036 Query: "/* client b */ savepoint spb2", 3037 Expected: []sql.Row{}, 3038 }, 3039 { 3040 Query: "/* client a */ insert into db1.t values (7, 7)", 3041 Expected: []sql.Row{{types.NewOkResult(1)}}, 3042 }, 3043 { 3044 Query: "/* client a */ insert into db2.t values (8, 8)", 3045 Expected: []sql.Row{{types.NewOkResult(1)}}, 3046 }, 3047 { 3048 Query: "/* client b */ insert into db1.t values (9, 9)", 3049 Expected: []sql.Row{{types.NewOkResult(1)}}, 3050 }, 3051 { 3052 Query: "/* client b */ insert into db2.t values (10, 10)", 3053 Expected: []sql.Row{{types.NewOkResult(1)}}, 3054 }, 3055 { 3056 Query: "/* client a */ select * from db1.t order by x", 3057 Expected: []sql.Row{{1, 1}, {3, 3}, {5, 5}, {7, 7}}, 3058 }, 3059 { 3060 Query: "/* client a */ select * from db2.t order by x", 3061 Expected: []sql.Row{{2, 2}, {4, 4}, {6, 6}, {8, 8}}, 3062 }, 3063 { 3064 Query: "/* client b */ select * from db1.t order by x", 3065 Expected: []sql.Row{{1, 1}, {5, 5}, {7, 7}, {9, 9}}, 3066 }, 3067 { 3068 Query: "/* client b */ select * from db2.t order by x", 3069 Expected: []sql.Row{{2, 2}, {6, 6}, {8, 8}, {10, 10}}, 3070 }, 3071 { 3072 Query: "/* client a */ rollback to SPA2", 3073 Expected: []sql.Row{}, 3074 }, 3075 { 3076 Query: "/* client b */ rollback to spB2", 3077 Expected: []sql.Row{}, 3078 }, 3079 { 3080 Query: "/* client a */ select * from db1.t order by x", 3081 Expected: []sql.Row{{1, 1}, {3, 3}, {5, 5}}, 3082 }, 3083 { 3084 Query: "/* client a */ select * from db2.t order by x", 3085 Expected: []sql.Row{{2, 2}, {4, 4}, {6, 6}}, 3086 }, 3087 { 3088 Query: "/* client b */ select * from db1.t order by x", 3089 Expected: []sql.Row{{1, 1}, {5, 5}, {7, 7}}, 3090 }, 3091 { 3092 Query: "/* client b */ select * from db2.t order by x", 3093 Expected: []sql.Row{{2, 2}, {6, 6}, {8, 8}}, 3094 }, 3095 { 3096 Query: "/* client a */ rollback to sPa2", 3097 Expected: []sql.Row{}, 3098 }, 3099 { 3100 Query: "/* client b */ rollback to Spb2", 3101 Expected: []sql.Row{}, 3102 }, 3103 { 3104 Query: "/* client a */ select * from db1.t order by x", 3105 Expected: []sql.Row{{1, 1}, {3, 3}, {5, 5}}, 3106 }, 3107 { 3108 Query: "/* client a */ select * from db2.t order by x", 3109 Expected: []sql.Row{{2, 2}, {4, 4}, {6, 6}}, 3110 }, 3111 { 3112 Query: "/* client b */ select * from db1.t order by x", 3113 Expected: []sql.Row{{1, 1}, {5, 5}, {7, 7}}, 3114 }, 3115 { 3116 Query: "/* client b */ select * from db2.t order by x", 3117 Expected: []sql.Row{{2, 2}, {6, 6}, {8, 8}}, 3118 }, 3119 { 3120 Query: "/* client a */ rollback to spA1", 3121 Expected: []sql.Row{}, 3122 }, 3123 { 3124 Query: "/* client b */ rollback to SPb1", 3125 Expected: []sql.Row{}, 3126 }, 3127 { 3128 Query: "/* client a */ select * from db1.t order by x", 3129 Expected: []sql.Row{{1, 1}, {3, 3}}, 3130 }, 3131 { 3132 Query: "/* client a */ select * from db2.t order by x", 3133 Expected: []sql.Row{{2, 2}, {4, 4}}, 3134 }, 3135 { 3136 Query: "/* client b */ select * from db1.t order by x", 3137 Expected: []sql.Row{{1, 1}, {5, 5}}, 3138 }, 3139 { 3140 Query: "/* client b */ select * from db2.t order by x", 3141 Expected: []sql.Row{{2, 2}, {6, 6}}, 3142 }, 3143 { 3144 Query: "/* client a */ rollback to spa2", 3145 ExpectedErr: sql.ErrSavepointDoesNotExist, 3146 }, 3147 { 3148 Query: "/* client b */ rollback to spb2", 3149 ExpectedErr: sql.ErrSavepointDoesNotExist, 3150 }, 3151 { 3152 Query: "/* client a */ rollback to Spa1", 3153 Expected: []sql.Row{}, 3154 }, 3155 { 3156 Query: "/* client b */ rollback to spB1", 3157 Expected: []sql.Row{}, 3158 }, 3159 { 3160 Query: "/* client a */ select * from db1.t order by x", 3161 Expected: []sql.Row{{1, 1}, {3, 3}}, 3162 }, 3163 { 3164 Query: "/* client a */ select * from db2.t order by x", 3165 Expected: []sql.Row{{2, 2}, {4, 4}}, 3166 }, 3167 { 3168 Query: "/* client b */ select * from db1.t order by x", 3169 Expected: []sql.Row{{1, 1}, {5, 5}}, 3170 }, 3171 { 3172 Query: "/* client b */ select * from db2.t order by x", 3173 Expected: []sql.Row{{2, 2}, {6, 6}}, 3174 }, 3175 { 3176 Query: "/* client a */ rollback", 3177 Expected: []sql.Row{}, 3178 }, 3179 { 3180 Query: "/* client b */ rollback", 3181 Expected: []sql.Row{}, 3182 }, 3183 { 3184 Query: "/* client a */ select * from db1.t order by x", 3185 Expected: []sql.Row{{1, 1}}, 3186 }, 3187 { 3188 Query: "/* client a */ select * from db2.t order by x", 3189 Expected: []sql.Row{{2, 2}}, 3190 }, 3191 { 3192 Query: "/* client b */ select * from db1.t order by x", 3193 Expected: []sql.Row{{1, 1}}, 3194 }, 3195 { 3196 Query: "/* client b */ select * from db2.t order by x", 3197 Expected: []sql.Row{{2, 2}}, 3198 }, 3199 { 3200 Query: "/* client a */ rollback to spa1", 3201 ExpectedErr: sql.ErrSavepointDoesNotExist, 3202 }, 3203 { 3204 Query: "/* client b */ rollback to spb1", 3205 ExpectedErr: sql.ErrSavepointDoesNotExist, 3206 }, 3207 }, 3208 }, 3209 { 3210 Name: "overwrite savepoint with multiple dbs edited", 3211 SetUpScript: []string{ 3212 "create database db1", 3213 "create database db2", 3214 "create table db1.t (x int primary key, y int)", 3215 "insert into db1.t values (1, 1)", 3216 "create table db2.t (x int primary key, y int)", 3217 "insert into db2.t values (2, 2)", 3218 }, 3219 Assertions: []queries.ScriptTestAssertion{ 3220 { 3221 Query: "/* client a */ start transaction", 3222 Expected: []sql.Row{}, 3223 }, 3224 { 3225 Query: "/* client a */ insert into db1.t values (3, 3)", 3226 Expected: []sql.Row{{types.NewOkResult(1)}}, 3227 }, 3228 { 3229 Query: "/* client a */ insert into db2.t values (4, 4)", 3230 Expected: []sql.Row{{types.NewOkResult(1)}}, 3231 }, 3232 { 3233 Query: "/* client a */ savepoint spa1", 3234 Expected: []sql.Row{}, 3235 }, 3236 { 3237 Query: "/* client a */ insert into db1.t values (5, 5)", 3238 Expected: []sql.Row{{types.NewOkResult(1)}}, 3239 }, 3240 { 3241 Query: "/* client a */ insert into db2.t values (6, 6)", 3242 Expected: []sql.Row{{types.NewOkResult(1)}}, 3243 }, 3244 { 3245 Query: "/* client a */ savepoint spa2", 3246 Expected: []sql.Row{}, 3247 }, 3248 { 3249 Query: "/* client a */ insert into db1.t values (7, 7)", 3250 Expected: []sql.Row{{types.NewOkResult(1)}}, 3251 }, 3252 { 3253 Query: "/* client a */ insert into db2.t values (8, 8)", 3254 Expected: []sql.Row{{types.NewOkResult(1)}}, 3255 }, 3256 { 3257 Query: "/* client a */ savepoint SPA1", 3258 Expected: []sql.Row{}, 3259 }, 3260 { 3261 Query: "/* client a */ insert into db1.t values (9, 9)", 3262 Expected: []sql.Row{{types.NewOkResult(1)}}, 3263 }, 3264 { 3265 Query: "/* client a */ insert into db2.t values (10, 10)", 3266 Expected: []sql.Row{{types.NewOkResult(1)}}, 3267 }, 3268 { 3269 Query: "/* client a */ select * from db1.t order by x", 3270 Expected: []sql.Row{{1, 1}, {3, 3}, {5, 5}, {7, 7}, {9, 9}}, 3271 }, 3272 { 3273 Query: "/* client a */ select * from db2.t order by x", 3274 Expected: []sql.Row{{2, 2}, {4, 4}, {6, 6}, {8, 8}, {10, 10}}, 3275 }, 3276 { 3277 Query: "/* client a */ rollback to Spa1", 3278 Expected: []sql.Row{}, 3279 }, 3280 { 3281 Query: "/* client a */ select * from db1.t order by x", 3282 Expected: []sql.Row{{1, 1}, {3, 3}, {5, 5}, {7, 7}}, 3283 }, 3284 { 3285 Query: "/* client a */ select * from db2.t order by x", 3286 Expected: []sql.Row{{2, 2}, {4, 4}, {6, 6}, {8, 8}}, 3287 }, 3288 { 3289 Query: "/* client a */ rollback to spa2", 3290 Expected: []sql.Row{}, 3291 }, 3292 { 3293 Query: "/* client a */ select * from db1.t order by x", 3294 Expected: []sql.Row{{1, 1}, {3, 3}, {5, 5}}, 3295 }, 3296 { 3297 Query: "/* client a */ select * from db2.t order by x", 3298 Expected: []sql.Row{{2, 2}, {4, 4}, {6, 6}}, 3299 }, 3300 { 3301 Query: "/* client a */ rollback to spa1", 3302 ExpectedErr: sql.ErrSavepointDoesNotExist, 3303 }, 3304 { 3305 Query: "/* client a */ release savepoint spa1", 3306 ExpectedErr: sql.ErrSavepointDoesNotExist, 3307 }, 3308 }, 3309 }, 3310 }