vitess.io/vitess@v0.16.2/go/vt/vttablet/endtoend/reserve_test.go (about)

     1  /*
     2  Copyright 2020 The Vitess Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package endtoend
    18  
    19  import (
    20  	"fmt"
    21  	"sync"
    22  	"testing"
    23  
    24  	"github.com/stretchr/testify/assert"
    25  
    26  	"github.com/stretchr/testify/require"
    27  
    28  	"vitess.io/vitess/go/vt/vttablet/endtoend/framework"
    29  )
    30  
    31  //TODO: Add Counter checks in all the tests.
    32  
    33  func TestMultipleReserveHaveDifferentConnection(t *testing.T) {
    34  	client1 := framework.NewClient()
    35  	client2 := framework.NewClient()
    36  
    37  	query := "select connection_id()"
    38  
    39  	qrc1_1, err := client1.ReserveExecute(query, nil, nil)
    40  	require.NoError(t, err)
    41  	defer client1.Release()
    42  	qrc2_1, err := client2.ReserveExecute(query, nil, nil)
    43  	require.NoError(t, err)
    44  	defer client2.Release()
    45  	require.NotEqual(t, qrc1_1.Rows, qrc2_1.Rows)
    46  
    47  	qrc1_2, err := client1.Execute(query, nil)
    48  	require.NoError(t, err)
    49  	qrc2_2, err := client2.Execute(query, nil)
    50  	require.NoError(t, err)
    51  	require.Equal(t, qrc1_1.Rows, qrc1_2.Rows)
    52  	require.Equal(t, qrc2_1.Rows, qrc2_2.Rows)
    53  }
    54  
    55  func TestReserveBeginRelease(t *testing.T) {
    56  	client := framework.NewClient()
    57  
    58  	query := "select connection_id()"
    59  
    60  	qr1, err := client.ReserveExecute(query, nil, nil)
    61  	require.NoError(t, err)
    62  	defer client.Release()
    63  
    64  	qr2, err := client.BeginExecute(query, nil, nil)
    65  	require.NoError(t, err)
    66  	assert.Equal(t, qr1.Rows, qr2.Rows)
    67  	assert.Equal(t, client.ReservedID(), client.TransactionID())
    68  
    69  	require.NoError(t, client.Release())
    70  }
    71  
    72  func TestBeginReserveRelease(t *testing.T) {
    73  	client := framework.NewClient()
    74  
    75  	query := "select connection_id()"
    76  
    77  	qr1, err := client.BeginExecute(query, nil, nil)
    78  	require.NoError(t, err)
    79  	defer client.Release()
    80  
    81  	qr2, err := client.ReserveExecute(query, nil, nil)
    82  	require.NoError(t, err)
    83  	assert.Equal(t, qr1.Rows, qr2.Rows)
    84  	assert.Equal(t, client.ReservedID(), client.TransactionID())
    85  
    86  	require.NoError(t, client.Release())
    87  }
    88  
    89  func TestReserveBeginExecuteRelease(t *testing.T) {
    90  	client := framework.NewClient()
    91  
    92  	insQuery := "insert into vitess_test (intval, floatval, charval, binval) values (4, null, null, null)"
    93  	selQuery := "select intval from vitess_test where intval = 4"
    94  	_, err := client.ReserveBeginExecute(insQuery, nil, nil, nil)
    95  	require.NoError(t, err)
    96  
    97  	qr, err := client.Execute(selQuery, nil)
    98  	require.NoError(t, err)
    99  	assert.Equal(t, `[[INT32(4)]]`, fmt.Sprintf("%v", qr.Rows))
   100  
   101  	err = client.Release()
   102  	require.NoError(t, err)
   103  
   104  	qr, err = client.Execute(selQuery, nil)
   105  	require.NoError(t, err)
   106  	assert.Equal(t, `[]`, fmt.Sprintf("%v", qr.Rows))
   107  }
   108  
   109  func TestMultipleReserveBeginHaveDifferentConnection(t *testing.T) {
   110  	client1 := framework.NewClient()
   111  	client2 := framework.NewClient()
   112  
   113  	query := "select connection_id()"
   114  
   115  	qrc1_1, err := client1.ReserveBeginExecute(query, nil, nil, nil)
   116  	require.NoError(t, err)
   117  	defer client1.Release()
   118  	qrc2_1, err := client2.ReserveBeginExecute(query, nil, nil, nil)
   119  	require.NoError(t, err)
   120  	defer client2.Release()
   121  	require.NotEqual(t, qrc1_1.Rows, qrc2_1.Rows)
   122  
   123  	qrc1_2, err := client1.Execute(query, nil)
   124  	require.NoError(t, err)
   125  	qrc2_2, err := client2.Execute(query, nil)
   126  	require.NoError(t, err)
   127  	require.Equal(t, qrc1_1.Rows, qrc1_2.Rows)
   128  	require.Equal(t, qrc2_1.Rows, qrc2_2.Rows)
   129  }
   130  
   131  func TestCommitOnReserveBeginConn(t *testing.T) {
   132  	client := framework.NewClient()
   133  
   134  	query := "select connection_id()"
   135  
   136  	qr1, err := client.ReserveBeginExecute(query, nil, nil, nil)
   137  	require.NoError(t, err)
   138  	defer client.Release()
   139  
   140  	oldRID := client.ReservedID()
   141  	err = client.Commit()
   142  	require.NoError(t, err)
   143  	assert.NotEqual(t, client.ReservedID(), oldRID, "reservedID must change after commit")
   144  	assert.EqualValues(t, 0, client.TransactionID(), "transactionID should be 0 after commit")
   145  
   146  	qr2, err := client.Execute(query, nil)
   147  	require.NoError(t, err)
   148  	assert.Equal(t, qr1.Rows, qr2.Rows)
   149  }
   150  
   151  func TestRollbackOnReserveBeginConn(t *testing.T) {
   152  	client := framework.NewClient()
   153  
   154  	query := "select connection_id()"
   155  
   156  	qr1, err := client.ReserveBeginExecute(query, nil, nil, nil)
   157  	require.NoError(t, err)
   158  	defer client.Release()
   159  
   160  	oldRID := client.ReservedID()
   161  	err = client.Rollback()
   162  	require.NoError(t, err)
   163  	assert.NotEqual(t, client.ReservedID(), oldRID, "reservedID must change after rollback")
   164  	assert.EqualValues(t, 0, client.TransactionID(), "transactionID should be 0 after commit")
   165  
   166  	qr2, err := client.Execute(query, nil)
   167  	require.NoError(t, err)
   168  	assert.Equal(t, qr1.Rows, qr2.Rows)
   169  }
   170  
   171  func TestReserveBeginRollbackAndBeginCommitAgain(t *testing.T) {
   172  	client := framework.NewClient()
   173  
   174  	query := "select connection_id()"
   175  
   176  	qr1, err := client.ReserveBeginExecute(query, nil, nil, nil)
   177  	require.NoError(t, err)
   178  	defer client.Release()
   179  
   180  	oldRID := client.ReservedID()
   181  	err = client.Rollback()
   182  	require.NoError(t, err)
   183  	assert.EqualValues(t, 0, client.TransactionID(), "transactionID should be 0 after rollback")
   184  	assert.NotEqual(t, client.ReservedID(), oldRID, "reservedID must change after rollback")
   185  
   186  	oldRID = client.ReservedID()
   187  
   188  	qr2, err := client.BeginExecute(query, nil, nil)
   189  	require.NoError(t, err)
   190  
   191  	err = client.Commit()
   192  	require.NoError(t, err)
   193  	assert.EqualValues(t, 0, client.TransactionID(), "transactionID should be 0 after commit")
   194  	assert.NotEqual(t, client.ReservedID(), oldRID, "reservedID must change after rollback")
   195  
   196  	qr3, err := client.Execute(query, nil)
   197  	require.NoError(t, err)
   198  	assert.Equal(t, qr1.Rows, qr2.Rows)
   199  	assert.Equal(t, qr2.Rows, qr3.Rows)
   200  
   201  	require.NoError(t,
   202  		client.Release())
   203  }
   204  
   205  func TestReserveBeginCommitFailToReuseTxID(t *testing.T) {
   206  	client := framework.NewClient()
   207  
   208  	query := "select connection_id()"
   209  
   210  	_, err := client.ReserveBeginExecute(query, nil, nil, nil)
   211  	require.NoError(t, err)
   212  	defer client.Release()
   213  
   214  	oldTxID := client.TransactionID()
   215  
   216  	err = client.Commit()
   217  	require.NoError(t, err)
   218  
   219  	client.SetTransactionID(oldTxID)
   220  
   221  	_, err = client.Execute(query, nil)
   222  	require.Error(t, err)
   223  	require.NoError(t,
   224  		client.Release())
   225  }
   226  
   227  func TestReserveBeginRollbackFailToReuseTxID(t *testing.T) {
   228  	client := framework.NewClient()
   229  
   230  	query := "select connection_id()"
   231  
   232  	_, err := client.ReserveBeginExecute(query, nil, nil, nil)
   233  	require.NoError(t, err)
   234  	defer client.Release()
   235  
   236  	oldTxID := client.TransactionID()
   237  
   238  	err = client.Rollback()
   239  	require.NoError(t, err)
   240  
   241  	client.SetTransactionID(oldTxID)
   242  
   243  	_, err = client.Execute(query, nil)
   244  	require.Error(t, err)
   245  	require.NoError(t,
   246  		client.Release())
   247  }
   248  
   249  func TestReserveBeginCommitFailToReuseOldReservedID(t *testing.T) {
   250  	client := framework.NewClient()
   251  
   252  	query := "select connection_id()"
   253  
   254  	_, err := client.ReserveBeginExecute(query, nil, nil, nil)
   255  	require.NoError(t, err)
   256  
   257  	oldRID := client.ReservedID()
   258  
   259  	err = client.Commit()
   260  	require.NoError(t, err)
   261  	newRID := client.ReservedID()
   262  
   263  	client.SetReservedID(oldRID)
   264  
   265  	_, err = client.Execute(query, nil)
   266  	require.Error(t, err)
   267  
   268  	client.SetReservedID(newRID)
   269  	require.NoError(t,
   270  		client.Release())
   271  }
   272  
   273  func TestReserveBeginRollbackFailToReuseOldReservedID(t *testing.T) {
   274  	client := framework.NewClient()
   275  
   276  	query := "select connection_id()"
   277  
   278  	_, err := client.ReserveBeginExecute(query, nil, nil, nil)
   279  	require.NoError(t, err)
   280  
   281  	oldRID := client.ReservedID()
   282  
   283  	err = client.Rollback()
   284  	require.NoError(t, err)
   285  	newRID := client.ReservedID()
   286  
   287  	client.SetReservedID(oldRID)
   288  	_, err = client.Execute(query, nil)
   289  	require.Error(t, err)
   290  
   291  	client.SetReservedID(newRID)
   292  	require.NoError(t,
   293  		client.Release())
   294  }
   295  
   296  func TestReserveReleaseAndFailToUseReservedIDAgain(t *testing.T) {
   297  	client := framework.NewClient()
   298  
   299  	query := "select 42"
   300  
   301  	_, err := client.ReserveExecute(query, nil, nil)
   302  	require.NoError(t, err)
   303  
   304  	rID := client.ReservedID()
   305  	require.NoError(t,
   306  		client.Release())
   307  
   308  	client.SetReservedID(rID)
   309  
   310  	_, err = client.Execute(query, nil)
   311  	require.Error(t, err)
   312  }
   313  
   314  func TestReserveAndFailToRunTwiceConcurrently(t *testing.T) {
   315  	client := framework.NewClient()
   316  
   317  	query := "select 42"
   318  
   319  	_, err := client.ReserveExecute(query, nil, nil)
   320  	require.NoError(t, err)
   321  	defer client.Release()
   322  
   323  	// WaitGroup will make defer call to wait for go func to complete.
   324  	wg := &sync.WaitGroup{}
   325  	wg.Add(1)
   326  	go func() {
   327  		_, err = client.Execute("select sleep(1)", nil)
   328  		wg.Done()
   329  	}()
   330  	_, err2 := client.Execute("select sleep(1)", nil)
   331  	wg.Wait()
   332  
   333  	if err == nil && err2 == nil {
   334  		assert.Fail(t, "at least one execution should fail")
   335  	}
   336  }
   337  
   338  func TestBeginReserveCommitAndNewTransactionsOnSameReservedID(t *testing.T) {
   339  	client := framework.NewClient()
   340  
   341  	query := "select connection_id()"
   342  
   343  	qrTx, err := client.BeginExecute(query, nil, nil)
   344  	require.NoError(t, err)
   345  
   346  	qrRID, err := client.ReserveExecute(query, nil, nil)
   347  	require.NoError(t, err)
   348  	require.Equal(t, qrTx.Rows, qrRID.Rows)
   349  
   350  	err = client.Commit()
   351  	require.NoError(t, err)
   352  
   353  	qrTx, err = client.BeginExecute(query, nil, nil)
   354  	require.NoError(t, err)
   355  	require.Equal(t, qrTx.Rows, qrRID.Rows)
   356  
   357  	err = client.Commit()
   358  	require.NoError(t, err)
   359  
   360  	qrTx, err = client.BeginExecute(query, nil, nil)
   361  	require.NoError(t, err)
   362  	require.Equal(t, qrTx.Rows, qrRID.Rows)
   363  
   364  	err = client.Rollback()
   365  	require.NoError(t, err)
   366  
   367  	require.NoError(t,
   368  		client.Release())
   369  }
   370  
   371  func TestBeginReserveRollbackAndNewTransactionsOnSameReservedID(t *testing.T) {
   372  	client := framework.NewClient()
   373  
   374  	query := "select connection_id()"
   375  
   376  	qrTx, err := client.BeginExecute(query, nil, nil)
   377  	require.NoError(t, err)
   378  
   379  	qrRID, err := client.ReserveExecute(query, nil, nil)
   380  	require.NoError(t, err)
   381  	require.Equal(t, qrTx.Rows, qrRID.Rows)
   382  
   383  	err = client.Rollback()
   384  	require.NoError(t, err)
   385  
   386  	qrTx, err = client.BeginExecute(query, nil, nil)
   387  	require.NoError(t, err)
   388  	require.Equal(t, qrTx.Rows, qrRID.Rows)
   389  
   390  	err = client.Commit()
   391  	require.NoError(t, err)
   392  
   393  	qrTx, err = client.BeginExecute(query, nil, nil)
   394  	require.NoError(t, err)
   395  	require.Equal(t, qrTx.Rows, qrRID.Rows)
   396  
   397  	err = client.Rollback()
   398  	require.NoError(t, err)
   399  
   400  	require.NoError(t,
   401  		client.Release())
   402  }
   403  
   404  func TestBeginReserveReleaseAndFailToUseReservedIDAndTxIDAgain(t *testing.T) {
   405  	client := framework.NewClient()
   406  
   407  	query := "select 42"
   408  
   409  	_, err := client.BeginExecute(query, nil, nil)
   410  	require.NoError(t, err)
   411  
   412  	_, err = client.ReserveExecute(query, nil, nil)
   413  	require.NoError(t, err)
   414  
   415  	rID := client.ReservedID()
   416  	txID := client.TransactionID()
   417  
   418  	require.NoError(t,
   419  		client.Release())
   420  
   421  	client.SetReservedID(rID)
   422  	_, err = client.Execute(query, nil)
   423  	require.Error(t, err)
   424  
   425  	client.SetReservedID(0)
   426  	client.SetTransactionID(txID)
   427  	_, err = client.Execute(query, nil)
   428  	require.Error(t, err)
   429  }
   430  
   431  func TestReserveBeginReleaseAndFailToUseReservedIDAndTxIDAgain(t *testing.T) {
   432  	client := framework.NewClient()
   433  
   434  	query := "select 42"
   435  
   436  	_, err := client.ReserveExecute(query, nil, nil)
   437  	require.NoError(t, err)
   438  
   439  	_, err = client.BeginExecute(query, nil, nil)
   440  	require.NoError(t, err)
   441  
   442  	rID := client.ReservedID()
   443  	txID := client.TransactionID()
   444  
   445  	require.NoError(t,
   446  		client.Release())
   447  
   448  	client.SetReservedID(rID)
   449  	_, err = client.Execute(query, nil)
   450  	require.Error(t, err)
   451  
   452  	client.SetReservedID(0)
   453  	client.SetTransactionID(txID)
   454  	_, err = client.Execute(query, nil)
   455  	require.Error(t, err)
   456  }
   457  
   458  func TestReserveExecuteWithFailingQueryAndReserveConnectionRemainsOpen(t *testing.T) {
   459  	client := framework.NewClient()
   460  
   461  	_, err := client.ReserveExecute("select foo", nil, nil)
   462  	require.Error(t, err)
   463  	defer client.Release()
   464  	require.NotEqual(t, int64(0), client.ReservedID())
   465  
   466  	_, err = client.Execute("select 42", nil)
   467  	require.NoError(t, err)
   468  	require.NoError(t, client.Release())
   469  }
   470  
   471  func TestReserveAndExecuteWithFailingQueryAndReserveConnectionRemainsOpen(t *testing.T) {
   472  	client := framework.NewClient()
   473  
   474  	qr1, err := client.ReserveExecute("select connection_id()", nil, nil)
   475  	require.NoError(t, err)
   476  	defer client.Release()
   477  
   478  	_, err = client.Execute("select foo", nil)
   479  	require.Error(t, err)
   480  
   481  	qr2, err := client.Execute("select connection_id()", nil)
   482  	require.NoError(t, err)
   483  	require.Equal(t, qr1.Rows, qr2.Rows)
   484  	require.NoError(t, client.Release())
   485  }
   486  
   487  func TestReserveBeginExecuteWithFailingQueryAndReserveConnAndTxRemainsOpen(t *testing.T) {
   488  	client := framework.NewClient()
   489  
   490  	_, err := client.ReserveBeginExecute("select foo", nil, nil, nil)
   491  	require.Error(t, err)
   492  
   493  	// Save the connection id to check in the end that everything got executed on same connection.
   494  	qr1, err := client.Execute("select connection_id()", nil)
   495  	require.NoError(t, err)
   496  
   497  	_, err = client.Execute("insert into vitess_test (intval, floatval, charval, binval) values (4, null, null, null)", nil)
   498  	require.NoError(t, err)
   499  
   500  	qr, err := client.Execute("select intval from vitess_test", nil)
   501  	require.NoError(t, err)
   502  	assert.Equal(t, "[[INT32(1)] [INT32(2)] [INT32(3)] [INT32(4)]]", fmt.Sprintf("%v", qr.Rows))
   503  
   504  	err = client.Rollback()
   505  	require.NoError(t, err)
   506  
   507  	qr, err = client.Execute("select intval from vitess_test", nil)
   508  	require.NoError(t, err)
   509  	assert.Equal(t, "[[INT32(1)] [INT32(2)] [INT32(3)]]", fmt.Sprintf("%v", qr.Rows))
   510  
   511  	qr2, err := client.Execute("select connection_id()", nil)
   512  	require.NoError(t, err)
   513  	require.Equal(t, qr1.Rows, qr2.Rows)
   514  
   515  	require.NoError(t, client.Release())
   516  }
   517  
   518  func TestReserveAndBeginExecuteWithFailingQueryAndReserveConnAndTxRemainsOpen(t *testing.T) {
   519  	client := framework.NewClient()
   520  
   521  	// Save the connection id to check in the end that everything got executed on same connection.
   522  	qr1, err := client.ReserveExecute("select connection_id()", nil, nil)
   523  	require.NoError(t, err)
   524  
   525  	_, err = client.BeginExecute("select foo", nil, nil)
   526  	require.Error(t, err)
   527  
   528  	_, err = client.Execute("insert into vitess_test (intval, floatval, charval, binval) values (4, null, null, null)", nil)
   529  	require.NoError(t, err)
   530  
   531  	qr, err := client.Execute("select intval from vitess_test", nil)
   532  	require.NoError(t, err)
   533  	assert.Equal(t, "[[INT32(1)] [INT32(2)] [INT32(3)] [INT32(4)]]", fmt.Sprintf("%v", qr.Rows))
   534  
   535  	err = client.Rollback()
   536  	require.NoError(t, err)
   537  
   538  	qr, err = client.Execute("select intval from vitess_test", nil)
   539  	require.NoError(t, err)
   540  	assert.Equal(t, "[[INT32(1)] [INT32(2)] [INT32(3)]]", fmt.Sprintf("%v", qr.Rows))
   541  
   542  	qr2, err := client.Execute("select connection_id()", nil)
   543  	require.NoError(t, err)
   544  	require.Equal(t, qr1.Rows, qr2.Rows)
   545  
   546  	require.NoError(t, client.Release())
   547  }
   548  
   549  func TestReserveExecuteWithPreQueriesAndCheckConnectionState(t *testing.T) {
   550  	client1 := framework.NewClient()
   551  	client2 := framework.NewClient()
   552  
   553  	selQuery := "select str_to_date('00/00/0000', '%m/%d/%Y')"
   554  	warnQuery := "show warnings"
   555  	preQueries1 := []string{
   556  		"set sql_mode = ''",
   557  	}
   558  	preQueries2 := []string{
   559  		"set sql_mode = 'NO_ZERO_DATE'",
   560  	}
   561  
   562  	qr1, err := client1.ReserveExecute(selQuery, preQueries1, nil)
   563  	require.NoError(t, err)
   564  	defer client1.Release()
   565  
   566  	qr2, err := client2.ReserveExecute(selQuery, preQueries2, nil)
   567  	require.NoError(t, err)
   568  	defer client2.Release()
   569  
   570  	assert.NotEqual(t, qr1.Rows, qr2.Rows)
   571  	assert.Equal(t, `[[DATE("0000-00-00")]]`, fmt.Sprintf("%v", qr1.Rows))
   572  	assert.Equal(t, `[[NULL]]`, fmt.Sprintf("%v", qr2.Rows))
   573  
   574  	qr1, err = client1.Execute(warnQuery, nil)
   575  	require.NoError(t, err)
   576  
   577  	qr2, err = client2.Execute(warnQuery, nil)
   578  	require.NoError(t, err)
   579  
   580  	assert.NotEqual(t, qr1.Rows, qr2.Rows)
   581  	assert.Equal(t, `[]`, fmt.Sprintf("%v", qr1.Rows))
   582  	assert.Equal(t, `[[VARCHAR("Warning") UINT32(1411) VARCHAR("Incorrect datetime value: '00/00/0000' for function str_to_date")]]`, fmt.Sprintf("%v", qr2.Rows))
   583  }
   584  
   585  func TestReserveExecuteWithPreQueriesAndSavepoint(t *testing.T) {
   586  	client := framework.NewClient()
   587  	defer client.Release()
   588  
   589  	insQuery := "insert into vitess_test (intval) values (5)"
   590  	selQuery := "select intval from vitess_test where intval = 5"
   591  	preQueries := []string{
   592  		"set sql_mode = ''",
   593  	}
   594  
   595  	postBeginQueries1 := []string{
   596  		"savepoint a",
   597  	}
   598  	// savepoint there after begin.
   599  	_, err := client.ReserveBeginExecute(insQuery, preQueries, postBeginQueries1, nil)
   600  	require.NoError(t, err)
   601  
   602  	qr, err := client.Execute(selQuery, nil)
   603  	require.NoError(t, err)
   604  	assert.Equal(t, `[[INT32(5)]]`, fmt.Sprintf("%v", qr.Rows))
   605  
   606  	_, err = client.Execute("rollback to a", nil)
   607  	require.NoError(t, err)
   608  
   609  	qr, err = client.Execute(selQuery, nil)
   610  	require.NoError(t, err)
   611  	assert.Equal(t, `[]`, fmt.Sprintf("%v", qr.Rows))
   612  
   613  	err = client.Release()
   614  	require.NoError(t, err)
   615  
   616  	postBeginQueries2 := []string{
   617  		"savepoint a",
   618  		"release savepoint a",
   619  		"savepoint b",
   620  	}
   621  	// no savepoint after begin
   622  	_, err = client.ReserveBeginExecute(insQuery, preQueries, postBeginQueries2, nil)
   623  	require.NoError(t, err)
   624  
   625  	qr, err = client.Execute(selQuery, nil)
   626  	require.NoError(t, err)
   627  	assert.Equal(t, `[[INT32(5)]]`, fmt.Sprintf("%v", qr.Rows))
   628  
   629  	// no savepoint a
   630  	_, err = client.Execute("rollback to a", nil)
   631  	require.Error(t, err)
   632  
   633  	// no savepoint a.
   634  	_, err = client.Execute("release a", nil)
   635  	require.Error(t, err)
   636  
   637  	// record still exists.
   638  	qr, err = client.Execute(selQuery, nil)
   639  	require.NoError(t, err)
   640  	assert.Equal(t, `[[INT32(5)]]`, fmt.Sprintf("%v", qr.Rows))
   641  
   642  	_, err = client.Execute("rollback to b", nil)
   643  	require.NoError(t, err)
   644  
   645  	qr, err = client.Execute(selQuery, nil)
   646  	require.NoError(t, err)
   647  	assert.Equal(t, `[]`, fmt.Sprintf("%v", qr.Rows))
   648  }
   649  
   650  func TestReserveBeginExecuteWithPreQueriesAndCheckConnectionState(t *testing.T) {
   651  	rcClient := framework.NewClient()
   652  	rucClient := framework.NewClient()
   653  
   654  	insRcQuery := "insert into vitess_test (intval, floatval, charval, binval) values (4, null, null, null)"
   655  	insRucQuery := "insert into vitess_test (intval, floatval, charval, binval) values (5, null, null, null)"
   656  	selQuery := "select intval from vitess_test"
   657  	delQuery := "delete from vitess_test where intval = 5"
   658  	rcQuery := []string{
   659  		"set session transaction isolation level read committed",
   660  	}
   661  	rucQuery := []string{
   662  		"set session transaction isolation level read uncommitted",
   663  	}
   664  
   665  	_, err := rcClient.ReserveBeginExecute(insRcQuery, rcQuery, nil, nil)
   666  	require.NoError(t, err)
   667  	defer rcClient.Release()
   668  
   669  	_, err = rucClient.ReserveBeginExecute(insRucQuery, rucQuery, nil, nil)
   670  	require.NoError(t, err)
   671  	defer rucClient.Release()
   672  
   673  	qr1, err := rcClient.Execute(selQuery, nil)
   674  	require.NoError(t, err)
   675  
   676  	qr2, err := rucClient.Execute(selQuery, nil)
   677  	require.NoError(t, err)
   678  
   679  	assert.NotEqual(t, qr1.Rows, qr2.Rows)
   680  	// As the transaction is read commited it is not able to see #5.
   681  	assert.Equal(t, `[[INT32(1)] [INT32(2)] [INT32(3)] [INT32(4)]]`, fmt.Sprintf("%v", qr1.Rows))
   682  	// As the transaction is read uncommited it is able to see #4.
   683  	assert.Equal(t, `[[INT32(1)] [INT32(2)] [INT32(3)] [INT32(4)] [INT32(5)]]`, fmt.Sprintf("%v", qr2.Rows))
   684  
   685  	err = rucClient.Commit()
   686  	require.NoError(t, err)
   687  
   688  	qr1, err = rcClient.Execute(selQuery, nil)
   689  	require.NoError(t, err)
   690  
   691  	qr2, err = rucClient.Execute(selQuery, nil)
   692  	require.NoError(t, err)
   693  
   694  	// As the transaction on read uncommitted client got committed, transaction with read committed will be able to see #5.
   695  	assert.Equal(t, qr1.Rows, qr2.Rows)
   696  	assert.Equal(t, `[[INT32(1)] [INT32(2)] [INT32(3)] [INT32(4)] [INT32(5)]]`, fmt.Sprintf("%v", qr1.Rows))
   697  
   698  	err = rcClient.Rollback()
   699  	require.NoError(t, err)
   700  
   701  	qr1, err = rcClient.Execute(selQuery, nil)
   702  	require.NoError(t, err)
   703  
   704  	qr2, err = rucClient.Execute(selQuery, nil)
   705  	require.NoError(t, err)
   706  
   707  	// As the transaction on read committed client got rollbacked back, table will forget #4.
   708  	assert.Equal(t, qr1.Rows, qr2.Rows)
   709  	assert.Equal(t, `[[INT32(1)] [INT32(2)] [INT32(3)] [INT32(5)]]`, fmt.Sprintf("%v", qr2.Rows))
   710  
   711  	// This is executed on reserved connection without transaction as the transaction was committed.
   712  	_, err = rucClient.Execute(delQuery, nil)
   713  	require.NoError(t, err)
   714  }
   715  
   716  func TestReserveExecuteWithFailingPreQueriesAndCheckConnectionState(t *testing.T) {
   717  	client := framework.NewClient()
   718  
   719  	selQuery := "select 42"
   720  	preQueries := []string{
   721  		"set @@no_sys_var = 42",
   722  	}
   723  
   724  	_, err := client.ReserveExecute(selQuery, preQueries, nil)
   725  	require.Error(t, err)
   726  
   727  	err = client.Release()
   728  	require.Error(t, err)
   729  }
   730  
   731  func TestReserveBeginExecuteWithFailingPreQueriesAndCheckConnectionState(t *testing.T) {
   732  	client := framework.NewClient()
   733  
   734  	selQuery := "select 42"
   735  	preQueries := []string{
   736  		"set @@no_sys_var = 42",
   737  	}
   738  
   739  	_, err := client.ReserveBeginExecute(selQuery, preQueries, nil, nil)
   740  	require.Error(t, err)
   741  
   742  	err = client.Commit()
   743  	require.Error(t, err)
   744  
   745  	err = client.Release()
   746  	require.Error(t, err)
   747  }
   748  
   749  func TestBeginReserveExecuteWithFailingPreQueriesAndCheckConnectionState(t *testing.T) {
   750  	client := framework.NewClient()
   751  
   752  	selQuery := "select 42"
   753  	preQueries := []string{
   754  		"set @@no_sys_var = 42",
   755  	}
   756  
   757  	_, err := client.BeginExecute(selQuery, nil, nil)
   758  	require.NoError(t, err)
   759  
   760  	_, err = client.ReserveExecute(selQuery, preQueries, nil)
   761  	require.Error(t, err)
   762  
   763  	err = client.Commit()
   764  	require.Error(t, err)
   765  
   766  	err = client.Release()
   767  	require.Error(t, err)
   768  }
   769  
   770  func TestReserveBeginExecuteWithCommitFailureAndCheckConnectionAndDBState(t *testing.T) {
   771  	client := framework.NewClient()
   772  
   773  	connQuery := "select connection_id()"
   774  	insQuery := "insert into vitess_test (intval, floatval, charval, binval) values (4, null, null, null)"
   775  	selQuery := "select intval from vitess_test where intval = 4"
   776  
   777  	connQr, err := client.ReserveBeginExecute(connQuery, nil, nil, nil)
   778  	require.NoError(t, err)
   779  
   780  	_, err = client.Execute(insQuery, nil)
   781  	require.NoError(t, err)
   782  
   783  	killConnection(t, connQr.Rows[0][0].ToString())
   784  
   785  	err = client.Commit()
   786  	require.Error(t, err)
   787  	require.Zero(t, client.ReservedID())
   788  
   789  	qr, err := client.Execute(selQuery, nil)
   790  	require.NoError(t, err)
   791  	require.Empty(t, qr.Rows)
   792  
   793  	qr, err = client.Execute(connQuery, nil)
   794  	require.NoError(t, err)
   795  	require.NotEqual(t, connQr.Rows, qr.Rows)
   796  
   797  	require.Error(t, client.Release())
   798  }
   799  
   800  func TestReserveBeginExecuteWithRollbackFailureAndCheckConnectionAndDBState(t *testing.T) {
   801  	client := framework.NewClient()
   802  
   803  	connQuery := "select connection_id()"
   804  	insQuery := "insert into vitess_test (intval, floatval, charval, binval) values (4, null, null, null)"
   805  	selQuery := "select intval from vitess_test where intval = 4"
   806  
   807  	connQr, err := client.ReserveBeginExecute(connQuery, nil, nil, nil)
   808  	require.NoError(t, err)
   809  
   810  	_, err = client.Execute(insQuery, nil)
   811  	require.NoError(t, err)
   812  
   813  	killConnection(t, connQr.Rows[0][0].ToString())
   814  
   815  	err = client.Rollback()
   816  	require.Error(t, err)
   817  	require.Zero(t, client.ReservedID())
   818  
   819  	qr, err := client.Execute(selQuery, nil)
   820  	require.NoError(t, err)
   821  	require.Empty(t, qr.Rows)
   822  
   823  	qr, err = client.Execute(connQuery, nil)
   824  	require.NoError(t, err)
   825  	require.NotEqual(t, connQr.Rows, qr.Rows)
   826  
   827  	require.Error(t, client.Release())
   828  }
   829  
   830  func TestReserveExecuteWithExecuteFailureAndCheckConnectionAndDBState(t *testing.T) {
   831  	client := framework.NewClient()
   832  
   833  	connQuery := "select connection_id()"
   834  	insQuery := "insert into vitess_test (intval, floatval, charval, binval) values (4, null, null, null)"
   835  	selQuery := "select intval from vitess_test where intval = 4"
   836  
   837  	connQr, err := client.ReserveExecute(connQuery, nil, nil)
   838  	require.NoError(t, err)
   839  
   840  	killConnection(t, connQr.Rows[0][0].ToString())
   841  
   842  	_, err = client.Execute(insQuery, nil)
   843  	require.Error(t, err)
   844  	// Expectation  - require.Zero(t, client.ReservedID())
   845  	// Reality
   846  	require.NotZero(t, client.ReservedID())
   847  
   848  	// Client still has transaction id and client id as non-zero.
   849  	_, err = client.Execute(selQuery, nil)
   850  	require.Error(t, err)
   851  	client.SetTransactionID(0)
   852  
   853  	_, err = client.Execute(selQuery, nil)
   854  	require.Error(t, err)
   855  	client.SetReservedID(0)
   856  
   857  	qr, err := client.Execute(selQuery, nil)
   858  	require.NoError(t, err)
   859  	require.Empty(t, qr.Rows)
   860  
   861  	qr, err = client.Execute(connQuery, nil)
   862  	require.NoError(t, err)
   863  	require.NotEqual(t, connQr.Rows, qr.Rows)
   864  
   865  	require.Error(t, client.Release())
   866  }
   867  
   868  func TestReserveExecuteDDLWithoutTx(t *testing.T) {
   869  	client := framework.NewClient()
   870  	defer client.Release()
   871  
   872  	connQuery := "select connection_id()"
   873  	createQuery := "create table vitess_test_ddl(id bigint primary key)"
   874  	dropQuery := "drop table vitess_test_ddl"
   875  	descQuery := "describe vitess_test_ddl"
   876  
   877  	qr1, err := client.ReserveExecute(connQuery, nil, nil)
   878  	require.NoError(t, err)
   879  
   880  	_, err = client.Execute(createQuery, nil)
   881  	require.NoError(t, err)
   882  	require.Zero(t, client.TransactionID())
   883  	defer client.Execute(dropQuery, nil)
   884  
   885  	qr2, err := client.Execute(connQuery, nil)
   886  	require.NoError(t, err)
   887  	assert.Equal(t, qr1.Rows, qr2.Rows)
   888  
   889  	qr3, err := client.Execute(descQuery, nil)
   890  	require.NoError(t, err)
   891  	require.NotZero(t, qr3.Rows)
   892  }
   893  
   894  func TestReserveExecuteDDLWithTx(t *testing.T) {
   895  	client := framework.NewClient()
   896  	defer client.Release()
   897  
   898  	connQuery := "select connection_id()"
   899  	createQuery := "create table vitess_test_ddl(id bigint primary key)"
   900  	dropQuery := "drop table vitess_test_ddl"
   901  	descQuery := "describe vitess_test_ddl"
   902  
   903  	qr1, err := client.ReserveBeginExecute(connQuery, nil, nil, nil)
   904  	require.NoError(t, err)
   905  
   906  	_, err = client.Execute(createQuery, nil)
   907  	require.NoError(t, err)
   908  	require.NotZero(t, client.TransactionID())
   909  	defer client.Execute(dropQuery, nil)
   910  
   911  	qr2, err := client.Execute(connQuery, nil)
   912  	require.NoError(t, err)
   913  	assert.Equal(t, qr1.Rows, qr2.Rows)
   914  
   915  	qr3, err := client.Execute(descQuery, nil)
   916  	require.NoError(t, err)
   917  	require.NotZero(t, qr3.Rows)
   918  }
   919  
   920  func killConnection(t *testing.T, connID string) {
   921  	client := framework.NewClient()
   922  	_, err := client.ReserveExecute("select 1", []string{fmt.Sprintf("kill %s", connID)}, nil)
   923  	require.NoError(t, err)
   924  	defer client.Release()
   925  }
   926  
   927  func BenchmarkPreQueries(b *testing.B) {
   928  	client := framework.NewClient()
   929  
   930  	tcases := []struct {
   931  		name     string
   932  		settings []string
   933  	}{{
   934  		name: "split_1",
   935  		settings: []string{
   936  			"set @@sql_mode = 'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'"},
   937  	}, {
   938  		name: "split_2",
   939  		settings: []string{
   940  			"set @@sql_mode = 'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'",
   941  			"set @@sql_safe_updates = false"},
   942  	}, {
   943  		name: "split_3",
   944  		settings: []string{
   945  			"set @@sql_mode = 'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'",
   946  			"set @@sql_safe_updates = false",
   947  			"set @@read_buffer_size = 9191181919"},
   948  	}, {
   949  		name: "split_4",
   950  		settings: []string{
   951  			"set @@sql_mode = 'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'",
   952  			"set @@sql_safe_updates = false", "set @@read_buffer_size = 9191181919",
   953  			"set @@max_heap_table_size = 10204023"},
   954  	}, {
   955  		name:     "combined_2",
   956  		settings: []string{"set @@sql_mode = 'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION', @@sql_safe_updates = false"},
   957  	}, {
   958  		name:     "combined_3",
   959  		settings: []string{"set @@sql_mode = 'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION', @@sql_safe_updates = false, @@read_buffer_size = 9191181919"},
   960  	}, {
   961  		name:     "combined_4",
   962  		settings: []string{"set @@sql_mode = 'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION', @@sql_safe_updates = false, @@read_buffer_size = 9191181919, @@max_heap_table_size = 10204023"},
   963  	}}
   964  	query := "select connection_id()"
   965  
   966  	for _, tcase := range tcases {
   967  		b.Run(tcase.name, func(b *testing.B) {
   968  			for i := 0; i < b.N; i++ {
   969  				if _, err := client.ReserveExecute(query, tcase.settings, nil); err != nil {
   970  					b.Error(err)
   971  				}
   972  				if err := client.Release(); err != nil {
   973  					b.Error(err)
   974  				}
   975  			}
   976  		})
   977  	}
   978  }
   979  
   980  func TestFailInfiniteSessions(t *testing.T) {
   981  	client := framework.NewClient()
   982  	qr, err := client.Execute("select @@max_connections", nil)
   983  	require.NoError(t, err)
   984  	maxConn, err := qr.Rows[0][0].ToInt64()
   985  	require.NoError(t, err)
   986  
   987  	// twice the number of sessions than the pool size.
   988  	numOfSessions := int(maxConn * 2)
   989  
   990  	var clients []*framework.QueryClient
   991  
   992  	// read session
   993  	var failed bool
   994  	for i := 0; i < numOfSessions; i++ {
   995  		client := framework.NewClient()
   996  		_, err := client.ReserveExecute("select 1", []string{"set sql_mode = ''"}, nil)
   997  		if err != nil {
   998  			failed = true
   999  			require.Contains(t, err.Error(), "immediate error from server errorCode=1040 errorMsg=Too many connections")
  1000  			break
  1001  		}
  1002  		clients = append(clients, client)
  1003  	}
  1004  	require.True(t, failed, "should have failed to create more sessions than the max mysql connection")
  1005  
  1006  	// Release all the sessions.
  1007  	for _, client := range clients {
  1008  		require.NoError(t,
  1009  			client.Release())
  1010  	}
  1011  	clients = nil
  1012  
  1013  	// write session
  1014  	failed = false
  1015  	for i := 0; i < numOfSessions; i++ {
  1016  		client := framework.NewClient()
  1017  		_, err := client.ReserveBeginExecute("select 1", []string{"set sql_mode = ''"}, nil, nil)
  1018  		if err != nil {
  1019  			failed = true
  1020  			require.Contains(t, err.Error(), "immediate error from server errorCode=1040 errorMsg=Too many connections")
  1021  			break
  1022  		}
  1023  		require.NoError(t,
  1024  			client.Commit())
  1025  		clients = append(clients, client)
  1026  	}
  1027  	require.True(t, failed, "should have failed to create more sessions than the max mysql connection")
  1028  
  1029  	// Release all the sessions.
  1030  	for _, client := range clients {
  1031  		require.NoError(t,
  1032  			client.Release())
  1033  	}
  1034  }
  1035  
  1036  func TestReserveQueryTimeout(t *testing.T) {
  1037  	client := framework.NewClient()
  1038  
  1039  	_, err := client.ReserveExecute("select sleep(19)", []string{"set sql_mode = ''"}, nil)
  1040  	assert.NoError(t, err)
  1041  	assert.NoError(t,
  1042  		client.Release())
  1043  
  1044  	_, err = client.ReserveStreamExecute("select sleep(19)", []string{"set sql_mode = ''"}, nil)
  1045  	assert.NoError(t, err)
  1046  	assert.NoError(t,
  1047  		client.Release())
  1048  }