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  }