github.com/matrixorigin/matrixone@v1.2.0/pkg/frontend/mysql_protocol_test.go (about)

     1  // Copyright 2021 Matrix Origin
     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 frontend
    16  
    17  import (
    18  	"bytes"
    19  	"context"
    20  	"database/sql"
    21  	"encoding/binary"
    22  	"fmt"
    23  	"math"
    24  	"sync"
    25  	"testing"
    26  	"time"
    27  
    28  	"github.com/stretchr/testify/assert"
    29  	"go.uber.org/zap"
    30  
    31  	// mysqlDriver "github.com/go-sql-driver/mysql"
    32  	"github.com/BurntSushi/toml"
    33  	"github.com/fagongzi/goetty/v2"
    34  	goetty_buf "github.com/fagongzi/goetty/v2/buf"
    35  	"github.com/golang/mock/gomock"
    36  	fuzz "github.com/google/gofuzz"
    37  	"github.com/prashantv/gostub"
    38  	"github.com/smartystreets/goconvey/convey"
    39  	"github.com/stretchr/testify/require"
    40  
    41  	"github.com/matrixorigin/matrixone/pkg/common/moerr"
    42  	"github.com/matrixorigin/matrixone/pkg/config"
    43  	"github.com/matrixorigin/matrixone/pkg/container/types"
    44  	"github.com/matrixorigin/matrixone/pkg/container/vector"
    45  	"github.com/matrixorigin/matrixone/pkg/defines"
    46  	mock_frontend "github.com/matrixorigin/matrixone/pkg/frontend/test"
    47  	"github.com/matrixorigin/matrixone/pkg/logutil"
    48  	"github.com/matrixorigin/matrixone/pkg/pb/txn"
    49  	"github.com/matrixorigin/matrixone/pkg/sql/parsers"
    50  	"github.com/matrixorigin/matrixone/pkg/sql/parsers/dialect"
    51  	"github.com/matrixorigin/matrixone/pkg/sql/parsers/dialect/mysql"
    52  	"github.com/matrixorigin/matrixone/pkg/sql/parsers/tree"
    53  	"github.com/matrixorigin/matrixone/pkg/sql/plan"
    54  	"github.com/matrixorigin/matrixone/pkg/testutil"
    55  	"github.com/matrixorigin/matrixone/pkg/vm/engine"
    56  	"github.com/matrixorigin/matrixone/pkg/vm/process"
    57  )
    58  
    59  type TestRoutineManager struct {
    60  	rwlock  sync.Mutex
    61  	clients map[goetty.IOSession]*Routine
    62  
    63  	pu *config.ParameterUnit
    64  }
    65  
    66  func (tRM *TestRoutineManager) Created(rs goetty.IOSession) {
    67  	pro := NewMysqlClientProtocol(nextConnectionID(), rs, 1024, tRM.pu.SV)
    68  	routine := NewRoutine(context.TODO(), pro, tRM.pu.SV, rs)
    69  
    70  	hsV10pkt := pro.makeHandshakeV10Payload()
    71  	err := pro.writePackets(hsV10pkt, true)
    72  	if err != nil {
    73  		panic(err)
    74  	}
    75  
    76  	tRM.rwlock.Lock()
    77  	defer tRM.rwlock.Unlock()
    78  	tRM.clients[rs] = routine
    79  }
    80  
    81  func (tRM *TestRoutineManager) Closed(rs goetty.IOSession) {
    82  	tRM.rwlock.Lock()
    83  	defer tRM.rwlock.Unlock()
    84  	delete(tRM.clients, rs)
    85  }
    86  
    87  func NewTestRoutineManager(pu *config.ParameterUnit) *TestRoutineManager {
    88  	rm := &TestRoutineManager{
    89  		clients: make(map[goetty.IOSession]*Routine),
    90  		pu:      pu,
    91  	}
    92  	return rm
    93  }
    94  
    95  func TestMysqlClientProtocol_Handshake(t *testing.T) {
    96  	//client connection method: mysql -h 127.0.0.1 -P 6001 --default-auth=mysql_native_password -uroot -p
    97  	//client connect
    98  	//ion method: mysql -h 127.0.0.1 -P 6001 -udump -p
    99  
   100  	var db *sql.DB
   101  	var err error
   102  	//before anything using the configuration
   103  	pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
   104  	_, err = toml.DecodeFile("test/system_vars_config.toml", pu.SV)
   105  	require.NoError(t, err)
   106  	pu.SV.SkipCheckUser = true
   107  	setGlobalPu(pu)
   108  
   109  	ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
   110  
   111  	// A mock autoincrcache manager.
   112  	setGlobalAicm(&defines.AutoIncrCacheManager{})
   113  	rm, _ := NewRoutineManager(ctx)
   114  	setGlobalRtMgr(rm)
   115  
   116  	wg := sync.WaitGroup{}
   117  	wg.Add(1)
   118  
   119  	//running server
   120  	go func() {
   121  		defer wg.Done()
   122  		echoServer(getGlobalRtMgr().Handler, getGlobalRtMgr(), NewSqlCodec())
   123  	}()
   124  
   125  	time.Sleep(time.Second * 2)
   126  	db, err = openDbConn(t, 6001)
   127  	require.NoError(t, err)
   128  
   129  	time.Sleep(time.Millisecond * 10)
   130  	//close server
   131  	setServer(1)
   132  	wg.Wait()
   133  
   134  	closeDbConn(t, db)
   135  }
   136  
   137  func newMrsForConnectionId(rows [][]interface{}) *MysqlResultSet {
   138  	mrs := &MysqlResultSet{}
   139  
   140  	col1 := &MysqlColumn{}
   141  	col1.SetName("connection_id")
   142  	col1.SetColumnType(defines.MYSQL_TYPE_LONGLONG)
   143  
   144  	mrs.AddColumn(col1)
   145  
   146  	for _, row := range rows {
   147  		mrs.AddRow(row)
   148  	}
   149  
   150  	return mrs
   151  }
   152  
   153  func newMrsForSleep(rows [][]interface{}) *MysqlResultSet {
   154  	mrs := &MysqlResultSet{}
   155  
   156  	col1 := &MysqlColumn{}
   157  	col1.SetName("sleep")
   158  	col1.SetColumnType(defines.MYSQL_TYPE_TINY)
   159  
   160  	mrs.AddColumn(col1)
   161  
   162  	for _, row := range rows {
   163  		mrs.AddRow(row)
   164  	}
   165  
   166  	return mrs
   167  }
   168  
   169  func TestKill(t *testing.T) {
   170  	//client connection method: mysql -h 127.0.0.1 -P 6001 --default-auth=mysql_native_password -uroot -p
   171  	//client connect
   172  	//ion method: mysql -h 127.0.0.1 -P 6001 -udump -p
   173  	ctrl := gomock.NewController(t)
   174  	defer ctrl.Finish()
   175  	var conn1, conn2 *sql.DB
   176  	var err error
   177  	var connIdRow *sql.Row
   178  
   179  	//before anything using the configuration
   180  	eng := mock_frontend.NewMockEngine(ctrl)
   181  	eng.EXPECT().New(gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
   182  	eng.EXPECT().Hints().Return(engine.Hints{CommitOrRollbackTimeout: time.Second * 10}).AnyTimes()
   183  	wp := newTestWorkspace()
   184  
   185  	txnOp := mock_frontend.NewMockTxnOperator(ctrl)
   186  	txnOp.EXPECT().Txn().Return(txn.TxnMeta{}).AnyTimes()
   187  	txnOp.EXPECT().GetWorkspace().Return(wp).AnyTimes()
   188  	txnOp.EXPECT().Commit(gomock.Any()).Return(nil).AnyTimes()
   189  	txnOp.EXPECT().Rollback(gomock.Any()).Return(nil).AnyTimes()
   190  	txnClient := mock_frontend.NewMockTxnClient(ctrl)
   191  	txnClient.EXPECT().New(gomock.Any(), gomock.Any(), gomock.Any()).Return(txnOp, nil).AnyTimes()
   192  	pu, err := getParameterUnit("test/system_vars_config.toml", eng, txnClient)
   193  	require.NoError(t, err)
   194  	pu.SV.SkipCheckUser = true
   195  	setGlobalPu(pu)
   196  	sql1 := "select connection_id();"
   197  	var sql2, sql3, sql4 string
   198  
   199  	noResultSet := make(map[string]bool)
   200  	resultSet := make(map[string]*result)
   201  	resultSet[sql1] = &result{
   202  		gen: func(ses *Session) *MysqlResultSet {
   203  			mrs := newMrsForConnectionId([][]interface{}{
   204  				{ses.GetConnectionID()},
   205  			})
   206  			return mrs
   207  		},
   208  		isSleepSql: false,
   209  	}
   210  
   211  	sql5 := "select sleep(30);"
   212  	resultSet[sql5] = &result{
   213  		gen: func(ses *Session) *MysqlResultSet {
   214  			return newMrsForSleep([][]interface{}{
   215  				{uint8(0)},
   216  			})
   217  		},
   218  		isSleepSql: true,
   219  		seconds:    30,
   220  	}
   221  
   222  	sql6 := "select sleep(30);"
   223  	resultSet[sql6] = &result{
   224  		gen: func(ses *Session) *MysqlResultSet {
   225  			return newMrsForSleep([][]interface{}{
   226  				{uint8(0)},
   227  			})
   228  		},
   229  		isSleepSql: true,
   230  		seconds:    30,
   231  	}
   232  
   233  	var wrapperStubFunc = func(execCtx *ExecCtx, db string, user string, eng engine.Engine, proc *process.Process, ses *Session) ([]ComputationWrapper, error) {
   234  		var cw []ComputationWrapper = nil
   235  		var stmts []tree.Statement = nil
   236  		var cmdFieldStmt *InternalCmdFieldList
   237  		var err error
   238  		if isCmdFieldListSql(execCtx.input.getSql()) {
   239  			cmdFieldStmt, err = parseCmdFieldList(execCtx.reqCtx, execCtx.input.getSql())
   240  			if err != nil {
   241  				return nil, err
   242  			}
   243  			stmts = append(stmts, cmdFieldStmt)
   244  		} else {
   245  			stmts, err = parsers.Parse(execCtx.reqCtx, dialect.MYSQL, execCtx.input.getSql(), 1, 0)
   246  			if err != nil {
   247  				return nil, err
   248  			}
   249  		}
   250  
   251  		for _, stmt := range stmts {
   252  			cw = append(cw, newMockWrapper(ctrl, ses, resultSet, noResultSet, execCtx.input.getSql(), stmt, proc))
   253  		}
   254  		return cw, nil
   255  	}
   256  
   257  	bhStub := gostub.Stub(&GetComputationWrapper, wrapperStubFunc)
   258  	defer bhStub.Reset()
   259  
   260  	ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
   261  	// A mock autoincrcache manager.
   262  	setGlobalAicm(&defines.AutoIncrCacheManager{})
   263  	temp, _ := NewRoutineManager(ctx)
   264  	setGlobalRtMgr(temp)
   265  
   266  	wg := sync.WaitGroup{}
   267  	wg.Add(1)
   268  
   269  	//running server
   270  	go func() {
   271  		defer wg.Done()
   272  		echoServer(getGlobalRtMgr().Handler, getGlobalRtMgr(), NewSqlCodec())
   273  	}()
   274  
   275  	logutil.Infof("open conn1")
   276  	time.Sleep(time.Second * 2)
   277  	conn1, err = openDbConn(t, 6001)
   278  	require.NoError(t, err)
   279  	logutil.Infof("open conn1 done")
   280  
   281  	logutil.Infof("open conn2")
   282  	time.Sleep(time.Second * 2)
   283  	conn2, err = openDbConn(t, 6001)
   284  	require.NoError(t, err)
   285  	logutil.Infof("open conn2 done")
   286  
   287  	logutil.Infof("get the connection id of conn1")
   288  	//get the connection id of conn1
   289  	var conn1Id uint64
   290  	connIdRow = conn1.QueryRow(sql1)
   291  	err = connIdRow.Scan(&conn1Id)
   292  	require.NoError(t, err)
   293  	logutil.Infof("get the connection id of conn1 done")
   294  
   295  	logutil.Infof("get the connection id of conn2")
   296  	//get the connection id of conn2
   297  	var conn2Id uint64
   298  	connIdRow = conn2.QueryRow(sql1)
   299  	err = connIdRow.Scan(&conn2Id)
   300  	require.NoError(t, err)
   301  	logutil.Infof("get the connection id of conn2 done")
   302  	logutil.Infof("conn==>%v %v", conn1Id, conn2Id)
   303  
   304  	wgSleep := sync.WaitGroup{}
   305  	wgSleep.Add(1)
   306  
   307  	//===================================
   308  	//connection 1 exec : select sleep(30);
   309  	go func() {
   310  		defer wgSleep.Done()
   311  		var resultId int
   312  		logutil.Infof("conn1 sleep(30)")
   313  		connIdRow = conn1.QueryRow(sql5)
   314  		//find race on err here
   315  		err := connIdRow.Scan(&resultId)
   316  		require.NoError(t, err)
   317  		logutil.Infof("conn1 sleep(30) done")
   318  	}()
   319  
   320  	//sleep before cancel
   321  	time.Sleep(time.Second * 2)
   322  
   323  	logutil.Infof("conn2 kill query on conn1")
   324  	//conn2 kills the query
   325  	sql3 = fmt.Sprintf("kill query %d;", conn1Id)
   326  	noResultSet[sql3] = true
   327  	_, err = conn2.Exec(sql3)
   328  	require.NoError(t, err)
   329  	logutil.Infof("conn2 kill query on conn1: KILL query done")
   330  
   331  	//check killed result
   332  	wgSleep.Wait()
   333  	res := resultSet[sql5]
   334  	require.Equal(t, res.resultX.Load(), contextCancel)
   335  	logutil.Infof("conn2 kill query on conn1 done")
   336  
   337  	//================================
   338  
   339  	//connection 1 exec : select sleep(30);
   340  	wgSleep2 := sync.WaitGroup{}
   341  	wgSleep2.Add(1)
   342  	go func() {
   343  		defer wgSleep2.Done()
   344  		var resultId int
   345  		logutil.Infof("conn1 sleep(30) 2")
   346  		connIdRow = conn1.QueryRow(sql6)
   347  		err = connIdRow.Scan(&resultId)
   348  		require.NoError(t, err)
   349  		logutil.Infof("conn1 sleep(30) 2 done")
   350  	}()
   351  
   352  	//sleep before cancel
   353  	time.Sleep(time.Second * 2)
   354  
   355  	logutil.Infof("conn2 kill conn1")
   356  	//conn2 kills the connection 1
   357  	sql2 = fmt.Sprintf("kill %d;", conn1Id)
   358  	noResultSet[sql2] = true
   359  	_, err = conn2.Exec(sql2)
   360  	require.NoError(t, err)
   361  	logutil.Infof("conn2 kill conn1 : KILL connection done")
   362  
   363  	//check killed result
   364  	wgSleep2.Wait()
   365  	res = resultSet[sql6]
   366  	require.Equal(t, res.resultX.Load(), contextCancel)
   367  	logutil.Infof("conn2 kill conn1 done")
   368  
   369  	logutil.Infof("conn1 test itself after being killed")
   370  	//==============================
   371  	//conn 1 is killed by conn2
   372  	//check conn1 is disconnected or not
   373  	err = conn1.Ping()
   374  	require.Error(t, err)
   375  	logutil.Infof("conn1 test itself after being killed done")
   376  
   377  	//==============================
   378  
   379  	logutil.Infof("conn2 kill itself")
   380  	//conn2 kills itself
   381  	sql4 = fmt.Sprintf("kill %d;", conn2Id)
   382  	noResultSet[sql4] = true
   383  	_, err = conn2.Exec(sql4)
   384  	require.NoError(t, err)
   385  	logutil.Infof("conn2 kill itself done")
   386  
   387  	time.Sleep(time.Millisecond * 10)
   388  	//close server
   389  	setServer(1)
   390  	wg.Wait()
   391  
   392  	logutil.Infof("close conn1,conn2")
   393  	//close the connection
   394  	closeDbConn(t, conn1)
   395  	closeDbConn(t, conn2)
   396  	logutil.Infof("close conn1,conn2 done")
   397  }
   398  
   399  func TestReadIntLenEnc(t *testing.T) {
   400  	var intEnc MysqlProtocolImpl
   401  	var data = make([]byte, 24)
   402  	var cases = [][]uint64{
   403  		{0, 123, 250},
   404  		{251, 10000, 1<<16 - 1},
   405  		{1 << 16, 1<<16 + 10000, 1<<24 - 1},
   406  		{1 << 24, 1<<24 + 10000, 1<<64 - 1},
   407  	}
   408  	var caseLens = []int{1, 3, 4, 9}
   409  	for j := 0; j < len(cases); j++ {
   410  		for i := 0; i < len(cases[j]); i++ {
   411  			value := cases[j][i]
   412  			p1 := intEnc.writeIntLenEnc(data, 0, value)
   413  			val, p2, ok := intEnc.readIntLenEnc(data, 0)
   414  			if !ok || p1 != caseLens[j] || p1 != p2 || val != value {
   415  				t.Errorf("IntLenEnc %d failed.", value)
   416  				break
   417  			}
   418  			_, _, ok = intEnc.readIntLenEnc(data[0:caseLens[j]-1], 0)
   419  			if ok {
   420  				t.Errorf("read IntLenEnc failed.")
   421  				break
   422  			}
   423  		}
   424  	}
   425  }
   426  
   427  func TestReadCountOfBytes(t *testing.T) {
   428  	var client MysqlProtocolImpl
   429  	var data = make([]byte, 24)
   430  	var length = 10
   431  	for i := 0; i < length; i++ {
   432  		data[i] = byte(length - i)
   433  	}
   434  
   435  	r, pos, ok := client.readCountOfBytes(data, 0, length)
   436  	if !ok || pos != length {
   437  		t.Error("read bytes failed.")
   438  		return
   439  	}
   440  
   441  	for i := 0; i < length; i++ {
   442  		if r[i] != data[i] {
   443  			t.Error("read != write")
   444  			break
   445  		}
   446  	}
   447  
   448  	_, _, ok = client.readCountOfBytes(data, 0, 100)
   449  	if ok {
   450  		t.Error("read bytes failed.")
   451  		return
   452  	}
   453  
   454  	_, pos, ok = client.readCountOfBytes(data, 0, 0)
   455  	if !ok || pos != 0 {
   456  		t.Error("read bytes failed.")
   457  		return
   458  	}
   459  }
   460  
   461  func TestReadStringFix(t *testing.T) {
   462  	var client MysqlProtocolImpl
   463  	var data = make([]byte, 24)
   464  	var length = 10
   465  	var s = "haha, test read string fix function"
   466  	pos := client.writeStringFix(data, 0, s, length)
   467  	if pos != length {
   468  		t.Error("write string fix failed.")
   469  		return
   470  	}
   471  	var x string
   472  	var ok bool
   473  
   474  	x, pos, ok = client.readStringFix(data, 0, length)
   475  	if !ok || pos != length || x != s[0:length] {
   476  		t.Error("read string fix failed.")
   477  		return
   478  	}
   479  	var sLen = []int{
   480  		length + 10,
   481  		length + 20,
   482  		length + 30,
   483  	}
   484  	for i := 0; i < len(sLen); i++ {
   485  		x, pos, ok = client.readStringFix(data, 0, sLen[i])
   486  		if ok && pos == sLen[i] && x == s[0:sLen[i]] {
   487  			t.Error("read string fix failed.")
   488  			return
   489  		}
   490  	}
   491  
   492  	//empty string
   493  	pos = client.writeStringFix(data, 0, s, 0)
   494  	if pos != 0 {
   495  		t.Error("write string fix failed.")
   496  		return
   497  	}
   498  
   499  	x, pos, ok = client.readStringFix(data, 0, 0)
   500  	if !ok || pos != 0 || x != "" {
   501  		t.Error("read string fix failed.")
   502  		return
   503  	}
   504  }
   505  
   506  func TestReadStringNUL(t *testing.T) {
   507  	var client MysqlProtocolImpl
   508  	var data = make([]byte, 24)
   509  	var length = 10
   510  	var s = "haha, test read string fix function"
   511  	pos := client.writeStringNUL(data, 0, s[0:length])
   512  	if pos != length+1 {
   513  		t.Error("write string NUL failed.")
   514  		return
   515  	}
   516  	var x string
   517  	var ok bool
   518  
   519  	x, pos, ok = client.readStringNUL(data, 0)
   520  	if !ok || pos != length+1 || x != s[0:length] {
   521  		t.Error("read string NUL failed.")
   522  		return
   523  	}
   524  	var sLen = []int{
   525  		length + 10,
   526  		length + 20,
   527  		length + 30,
   528  	}
   529  	for i := 0; i < len(sLen); i++ {
   530  		x, pos, ok = client.readStringNUL(data, 0)
   531  		if ok && pos == sLen[i]+1 && x == s[0:sLen[i]] {
   532  			t.Error("read string NUL failed.")
   533  			return
   534  		}
   535  	}
   536  }
   537  
   538  func TestReadStringLenEnc(t *testing.T) {
   539  	var client MysqlProtocolImpl
   540  	var data = make([]byte, 24)
   541  	var length = 10
   542  	var s = "haha, test read string fix function"
   543  	pos := client.writeStringLenEnc(data, 0, s[0:length])
   544  	if pos != length+1 {
   545  		t.Error("write string lenenc failed.")
   546  		return
   547  	}
   548  	var x string
   549  	var ok bool
   550  
   551  	x, pos, ok = client.readStringLenEnc(data, 0)
   552  	if !ok || pos != length+1 || x != s[0:length] {
   553  		t.Error("read string lenenc failed.")
   554  		return
   555  	}
   556  
   557  	//empty string
   558  	pos = client.writeStringLenEnc(data, 0, s[0:0])
   559  	if pos != 1 {
   560  		t.Error("write string lenenc failed.")
   561  		return
   562  	}
   563  
   564  	x, pos, ok = client.readStringLenEnc(data, 0)
   565  	if !ok || pos != 1 || x != s[0:0] {
   566  		t.Error("read string lenenc failed.")
   567  		return
   568  	}
   569  }
   570  
   571  // can not run this test case in ubuntu+golang1.9, let's add an issue(#4656) for that, I will fixed in someday.
   572  // func TestMysqlClientProtocol_TlsHandshake(t *testing.T) {
   573  // 	//before anything using the configuration
   574  // 	pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
   575  // 	_, err := toml.DecodeFile("test/system_vars_config.toml", pu.SV)
   576  // 	if err != nil {
   577  // 		panic(err)
   578  // 	}
   579  // 	pu.SV.EnableTls = true
   580  // 	ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu)
   581  // 	rm, _ := NewRoutineManager(ctx, pu)
   582  // 	rm.SetSkipCheckUser(true)
   583  
   584  // 	wg := sync.WaitGroup{}
   585  // 	wg.Add(1)
   586  
   587  // 	// //running server
   588  // 	go func() {
   589  // 		defer wg.Done()
   590  // 		echoServer(rm.Handler, rm, NewSqlCodec())
   591  // 	}()
   592  
   593  // 	// to := NewTimeout(1*time.Minute, false)
   594  // 	// for isClosed() && !to.isTimeout() {
   595  // 	// }
   596  
   597  // 	time.Sleep(time.Second * 2)
   598  // 	db := open_tls_db(t, 6001)
   599  // 	closeDbConn(t, db)
   600  
   601  // 	time.Sleep(time.Millisecond * 10)
   602  // 	//close server
   603  // 	setServer(1)
   604  // 	wg.Wait()
   605  // }
   606  
   607  //	func makeMysqlTinyIntResultSet(unsigned bool) *MysqlResultSet {
   608  //		var rs = &MysqlResultSet{}
   609  //
   610  //		name := "Tiny"
   611  //		if unsigned {
   612  //			name = name + "Uint"
   613  //		} else {
   614  //			name = name + "Int"
   615  //		}
   616  //
   617  //		mysqlCol := new(MysqlColumn)
   618  //		mysqlCol.SetName(name)
   619  //		mysqlCol.SetOrgName(name + "OrgName")
   620  //		mysqlCol.SetColumnType(defines.MYSQL_TYPE_TINY)
   621  //		mysqlCol.SetSchema(name + "Schema")
   622  //		mysqlCol.SetTable(name + "Table")
   623  //		mysqlCol.SetOrgTable(name + "Table")
   624  //		mysqlCol.SetCharset(uint16(Utf8mb4CollationID))
   625  //		mysqlCol.SetSigned(!unsigned)
   626  //
   627  //		rs.AddColumn(mysqlCol)
   628  //		if unsigned {
   629  //			var cases = []uint8{0, 1, 254, 255}
   630  //			for _, v := range cases {
   631  //				var data = make([]interface{}, 1)
   632  //				data[0] = v
   633  //				rs.AddRow(data)
   634  //			}
   635  //		} else {
   636  //			var cases = []int8{-128, -127, 127}
   637  //			for _, v := range cases {
   638  //				var data = make([]interface{}, 1)
   639  //				data[0] = v
   640  //				rs.AddRow(data)
   641  //			}
   642  //		}
   643  //
   644  //		return rs
   645  //	}
   646  //
   647  //	func makeMysqlTinyResult(unsigned bool) *MysqlExecutionResult {
   648  //		return NewMysqlExecutionResult(0, 0, 0, 0, makeMysqlTinyIntResultSet(unsigned))
   649  //	}
   650  //
   651  //	func makeMysqlShortResultSet(unsigned bool) *MysqlResultSet {
   652  //		var rs = &MysqlResultSet{}
   653  //
   654  //		name := "Short"
   655  //		if unsigned {
   656  //			name = name + "Uint"
   657  //		} else {
   658  //			name = name + "Int"
   659  //		}
   660  //		mysqlCol := new(MysqlColumn)
   661  //		mysqlCol.SetName(name)
   662  //		mysqlCol.SetOrgName(name + "OrgName")
   663  //		mysqlCol.SetColumnType(defines.MYSQL_TYPE_SHORT)
   664  //		mysqlCol.SetSchema(name + "Schema")
   665  //		mysqlCol.SetTable(name + "Table")
   666  //		mysqlCol.SetOrgTable(name + "Table")
   667  //		mysqlCol.SetCharset(uint16(Utf8mb4CollationID))
   668  //		mysqlCol.SetSigned(!unsigned)
   669  //
   670  //		rs.AddColumn(mysqlCol)
   671  //		if unsigned {
   672  //			var cases = []uint16{0, 1, 254, 255, 65535}
   673  //			for _, v := range cases {
   674  //				var data = make([]interface{}, 1)
   675  //				data[0] = v
   676  //				rs.AddRow(data)
   677  //			}
   678  //		} else {
   679  //			var cases = []int16{-32768, 0, 32767}
   680  //			for _, v := range cases {
   681  //				var data = make([]interface{}, 1)
   682  //				data[0] = v
   683  //				rs.AddRow(data)
   684  //			}
   685  //		}
   686  //
   687  //		return rs
   688  //	}
   689  //
   690  //	func makeMysqlShortResult(unsigned bool) *MysqlExecutionResult {
   691  //		return NewMysqlExecutionResult(0, 0, 0, 0, makeMysqlShortResultSet(unsigned))
   692  //	}
   693  //
   694  //	func makeMysqlLongResultSet(unsigned bool) *MysqlResultSet {
   695  //		var rs = &MysqlResultSet{}
   696  //
   697  //		name := "Long"
   698  //		if unsigned {
   699  //			name = name + "Uint"
   700  //		} else {
   701  //			name = name + "Int"
   702  //		}
   703  //		mysqlCol := new(MysqlColumn)
   704  //		mysqlCol.SetName(name)
   705  //		mysqlCol.SetOrgName(name + "OrgName")
   706  //		mysqlCol.SetColumnType(defines.MYSQL_TYPE_LONG)
   707  //		mysqlCol.SetSchema(name + "Schema")
   708  //		mysqlCol.SetTable(name + "Table")
   709  //		mysqlCol.SetOrgTable(name + "Table")
   710  //		mysqlCol.SetCharset(uint16(Utf8mb4CollationID))
   711  //		mysqlCol.SetSigned(!unsigned)
   712  //
   713  //		rs.AddColumn(mysqlCol)
   714  //		if unsigned {
   715  //			var cases = []uint32{0, 4294967295}
   716  //			for _, v := range cases {
   717  //				var data = make([]interface{}, 1)
   718  //				data[0] = v
   719  //				rs.AddRow(data)
   720  //			}
   721  //		} else {
   722  //			var cases = []int32{-2147483648, 0, 2147483647}
   723  //			for _, v := range cases {
   724  //				var data = make([]interface{}, 1)
   725  //				data[0] = v
   726  //				rs.AddRow(data)
   727  //			}
   728  //		}
   729  //
   730  //		return rs
   731  //	}
   732  //
   733  //	func makeMysqlLongResult(unsigned bool) *MysqlExecutionResult {
   734  //		return NewMysqlExecutionResult(0, 0, 0, 0, makeMysqlLongResultSet(unsigned))
   735  //	}
   736  //
   737  //	func makeMysqlLongLongResultSet(unsigned bool) *MysqlResultSet {
   738  //		var rs = &MysqlResultSet{}
   739  //
   740  //		name := "LongLong"
   741  //		if unsigned {
   742  //			name = name + "Uint"
   743  //		} else {
   744  //			name = name + "Int"
   745  //		}
   746  //		mysqlCol := new(MysqlColumn)
   747  //		mysqlCol.SetName(name)
   748  //		mysqlCol.SetOrgName(name + "OrgName")
   749  //		mysqlCol.SetColumnType(defines.MYSQL_TYPE_LONGLONG)
   750  //		mysqlCol.SetSchema(name + "Schema")
   751  //		mysqlCol.SetTable(name + "Table")
   752  //		mysqlCol.SetOrgTable(name + "Table")
   753  //		mysqlCol.SetCharset(uint16(Utf8mb4CollationID))
   754  //		mysqlCol.SetSigned(!unsigned)
   755  //
   756  //		rs.AddColumn(mysqlCol)
   757  //		if unsigned {
   758  //			var cases = []uint64{0, 4294967295, 18446744073709551615}
   759  //			for _, v := range cases {
   760  //				var data = make([]interface{}, 1)
   761  //				data[0] = v
   762  //				rs.AddRow(data)
   763  //			}
   764  //		} else {
   765  //			var cases = []int64{-9223372036854775808, 0, 9223372036854775807}
   766  //			for _, v := range cases {
   767  //				var data = make([]interface{}, 1)
   768  //				data[0] = v
   769  //				rs.AddRow(data)
   770  //			}
   771  //		}
   772  //
   773  //		return rs
   774  //	}
   775  //
   776  //	func makeMysqlLongLongResult(unsigned bool) *MysqlExecutionResult {
   777  //		return NewMysqlExecutionResult(0, 0, 0, 0, makeMysqlLongLongResultSet(unsigned))
   778  //	}
   779  //
   780  //	func makeMysqlInt24ResultSet(unsigned bool) *MysqlResultSet {
   781  //		var rs = &MysqlResultSet{}
   782  //
   783  //		name := "Int24"
   784  //		if unsigned {
   785  //			name = name + "Uint"
   786  //		} else {
   787  //			name = name + "Int"
   788  //		}
   789  //		mysqlCol := new(MysqlColumn)
   790  //		mysqlCol.SetName(name)
   791  //		mysqlCol.SetOrgName(name + "OrgName")
   792  //		mysqlCol.SetColumnType(defines.MYSQL_TYPE_INT24)
   793  //		mysqlCol.SetSchema(name + "Schema")
   794  //		mysqlCol.SetTable(name + "Table")
   795  //		mysqlCol.SetOrgTable(name + "Table")
   796  //		mysqlCol.SetCharset(uint16(Utf8mb4CollationID))
   797  //		mysqlCol.SetSigned(!unsigned)
   798  //
   799  //		rs.AddColumn(mysqlCol)
   800  //		if unsigned {
   801  //			//[0,16777215]
   802  //			var cases = []uint32{0, 16777215, 4294967295}
   803  //			for _, v := range cases {
   804  //				var data = make([]interface{}, 1)
   805  //				data[0] = v
   806  //				rs.AddRow(data)
   807  //			}
   808  //		} else {
   809  //			//[-8388608,8388607]
   810  //			var cases = []int32{-2147483648, -8388608, 0, 8388607, 2147483647}
   811  //			for _, v := range cases {
   812  //				var data = make([]interface{}, 1)
   813  //				data[0] = v
   814  //				rs.AddRow(data)
   815  //			}
   816  //		}
   817  //
   818  //		return rs
   819  //	}
   820  //
   821  //	func makeMysqlInt24Result(unsigned bool) *MysqlExecutionResult {
   822  //		return NewMysqlExecutionResult(0, 0, 0, 0, makeMysqlInt24ResultSet(unsigned))
   823  //	}
   824  //
   825  //	func makeMysqlYearResultSet(unsigned bool) *MysqlResultSet {
   826  //		var rs = &MysqlResultSet{}
   827  //
   828  //		name := "Year"
   829  //		if unsigned {
   830  //			name = name + "Uint"
   831  //		} else {
   832  //			name = name + "Int"
   833  //		}
   834  //		mysqlCol := new(MysqlColumn)
   835  //		mysqlCol.SetName(name)
   836  //		mysqlCol.SetOrgName(name + "OrgName")
   837  //		mysqlCol.SetColumnType(defines.MYSQL_TYPE_YEAR)
   838  //		mysqlCol.SetSchema(name + "Schema")
   839  //		mysqlCol.SetTable(name + "Table")
   840  //		mysqlCol.SetOrgTable(name + "Table")
   841  //		mysqlCol.SetCharset(uint16(Utf8mb4CollationID))
   842  //		mysqlCol.SetSigned(!unsigned)
   843  //
   844  //		rs.AddColumn(mysqlCol)
   845  //		if unsigned {
   846  //			var cases = []uint16{0, 1, 254, 255, 65535}
   847  //			for _, v := range cases {
   848  //				var data = make([]interface{}, 1)
   849  //				data[0] = v
   850  //				rs.AddRow(data)
   851  //			}
   852  //		} else {
   853  //			var cases = []int16{-32768, 0, 32767}
   854  //			for _, v := range cases {
   855  //				var data = make([]interface{}, 1)
   856  //				data[0] = v
   857  //				rs.AddRow(data)
   858  //			}
   859  //		}
   860  //
   861  //		return rs
   862  //	}
   863  //
   864  //	func makeMysqlYearResult(unsigned bool) *MysqlExecutionResult {
   865  //		return NewMysqlExecutionResult(0, 0, 0, 0, makeMysqlYearResultSet(unsigned))
   866  //	}
   867  //
   868  //	func makeMysqlVarcharResultSet() *MysqlResultSet {
   869  //		var rs = &MysqlResultSet{}
   870  //
   871  //		name := "Varchar"
   872  //
   873  //		mysqlCol := new(MysqlColumn)
   874  //		mysqlCol.SetName(name)
   875  //		mysqlCol.SetOrgName(name + "OrgName")
   876  //		mysqlCol.SetColumnType(defines.MYSQL_TYPE_VARCHAR)
   877  //		mysqlCol.SetSchema(name + "Schema")
   878  //		mysqlCol.SetTable(name + "Table")
   879  //		mysqlCol.SetOrgTable(name + "Table")
   880  //		mysqlCol.SetCharset(uint16(Utf8mb4CollationID))
   881  //
   882  //		rs.AddColumn(mysqlCol)
   883  //
   884  //		var cases = []string{"abc", "abcde", "", "x-", "xx"}
   885  //		for _, v := range cases {
   886  //			var data = make([]interface{}, 1)
   887  //			data[0] = v
   888  //			rs.AddRow(data)
   889  //		}
   890  //
   891  //		return rs
   892  //	}
   893  //
   894  //	func makeMysqlVarcharResult() *MysqlExecutionResult {
   895  //		return NewMysqlExecutionResult(0, 0, 0, 0, makeMysqlVarcharResultSet())
   896  //	}
   897  //
   898  //	func makeMysqlVarStringResultSet() *MysqlResultSet {
   899  //		var rs = &MysqlResultSet{}
   900  //
   901  //		name := "Varstring"
   902  //
   903  //		mysqlCol := new(MysqlColumn)
   904  //		mysqlCol.SetName(name)
   905  //		mysqlCol.SetOrgName(name + "OrgName")
   906  //		mysqlCol.SetColumnType(defines.MYSQL_TYPE_VAR_STRING)
   907  //		mysqlCol.SetSchema(name + "Schema")
   908  //		mysqlCol.SetTable(name + "Table")
   909  //		mysqlCol.SetOrgTable(name + "Table")
   910  //		mysqlCol.SetCharset(uint16(Utf8mb4CollationID))
   911  //
   912  //		rs.AddColumn(mysqlCol)
   913  //
   914  //		var cases = []string{"abc", "abcde", "", "x-", "xx"}
   915  //		for _, v := range cases {
   916  //			var data = make([]interface{}, 1)
   917  //			data[0] = v
   918  //			rs.AddRow(data)
   919  //		}
   920  //
   921  //		return rs
   922  //	}
   923  //
   924  //	func makeMysqlVarStringResult() *MysqlExecutionResult {
   925  //		return NewMysqlExecutionResult(0, 0, 0, 0, makeMysqlVarStringResultSet())
   926  //	}
   927  //
   928  //	func makeMysqlStringResultSet() *MysqlResultSet {
   929  //		var rs = &MysqlResultSet{}
   930  //
   931  //		name := "String"
   932  //
   933  //		mysqlCol := new(MysqlColumn)
   934  //		mysqlCol.SetName(name)
   935  //		mysqlCol.SetOrgName(name + "OrgName")
   936  //		mysqlCol.SetColumnType(defines.MYSQL_TYPE_STRING)
   937  //		mysqlCol.SetSchema(name + "Schema")
   938  //		mysqlCol.SetTable(name + "Table")
   939  //		mysqlCol.SetOrgTable(name + "Table")
   940  //		mysqlCol.SetCharset(uint16(Utf8mb4CollationID))
   941  //
   942  //		rs.AddColumn(mysqlCol)
   943  //
   944  //		var cases = []string{"abc", "abcde", "", "x-", "xx"}
   945  //		for _, v := range cases {
   946  //			var data = make([]interface{}, 1)
   947  //			data[0] = v
   948  //			rs.AddRow(data)
   949  //		}
   950  //
   951  //		return rs
   952  //	}
   953  //
   954  //	func makeMysqlStringResult() *MysqlExecutionResult {
   955  //		return NewMysqlExecutionResult(0, 0, 0, 0, makeMysqlStringResultSet())
   956  //	}
   957  //
   958  //	func makeMysqlFloatResultSet() *MysqlResultSet {
   959  //		var rs = &MysqlResultSet{}
   960  //
   961  //		name := "Float"
   962  //
   963  //		mysqlCol := new(MysqlColumn)
   964  //		mysqlCol.SetName(name)
   965  //		mysqlCol.SetOrgName(name + "OrgName")
   966  //		mysqlCol.SetColumnType(defines.MYSQL_TYPE_FLOAT)
   967  //		mysqlCol.SetSchema(name + "Schema")
   968  //		mysqlCol.SetTable(name + "Table")
   969  //		mysqlCol.SetOrgTable(name + "Table")
   970  //		mysqlCol.SetCharset(uint16(Utf8mb4CollationID))
   971  //
   972  //		rs.AddColumn(mysqlCol)
   973  //
   974  //		var cases = []float32{math.MaxFloat32, math.SmallestNonzeroFloat32, -math.MaxFloat32, -math.SmallestNonzeroFloat32}
   975  //		for _, v := range cases {
   976  //			var data = make([]interface{}, 1)
   977  //			data[0] = v
   978  //			rs.AddRow(data)
   979  //		}
   980  //
   981  //		return rs
   982  //	}
   983  //
   984  //	func makeMysqlFloatResult() *MysqlExecutionResult {
   985  //		return NewMysqlExecutionResult(0, 0, 0, 0, makeMysqlFloatResultSet())
   986  //	}
   987  //
   988  //	func makeMysqlDoubleResultSet() *MysqlResultSet {
   989  //		var rs = &MysqlResultSet{}
   990  //
   991  //		name := "Double"
   992  //
   993  //		mysqlCol := new(MysqlColumn)
   994  //		mysqlCol.SetName(name)
   995  //		mysqlCol.SetOrgName(name + "OrgName")
   996  //		mysqlCol.SetColumnType(defines.MYSQL_TYPE_DOUBLE)
   997  //		mysqlCol.SetSchema(name + "Schema")
   998  //		mysqlCol.SetTable(name + "Table")
   999  //		mysqlCol.SetOrgTable(name + "Table")
  1000  //		mysqlCol.SetCharset(uint16(Utf8mb4CollationID))
  1001  //
  1002  //		rs.AddColumn(mysqlCol)
  1003  //
  1004  //		var cases = []float64{math.MaxFloat64, math.SmallestNonzeroFloat64, -math.MaxFloat64, -math.SmallestNonzeroFloat64}
  1005  //		for _, v := range cases {
  1006  //			var data = make([]interface{}, 1)
  1007  //			data[0] = v
  1008  //			rs.AddRow(data)
  1009  //		}
  1010  //
  1011  //		return rs
  1012  //	}
  1013  //
  1014  //	func makeMysqlDoubleResult() *MysqlExecutionResult {
  1015  //		return NewMysqlExecutionResult(0, 0, 0, 0, makeMysqlDoubleResultSet())
  1016  //	}
  1017  //
  1018  //	func makeMysqlDateResultSet() *MysqlResultSet {
  1019  //		var rs = &MysqlResultSet{}
  1020  //
  1021  //		name := "Date"
  1022  //
  1023  //		mysqlCol := new(MysqlColumn)
  1024  //		mysqlCol.SetName(name)
  1025  //		mysqlCol.SetOrgName(name + "OrgName")
  1026  //		mysqlCol.SetColumnType(defines.MYSQL_TYPE_DATE)
  1027  //		mysqlCol.SetSchema(name + "Schema")
  1028  //		mysqlCol.SetTable(name + "Table")
  1029  //		mysqlCol.SetOrgTable(name + "Table")
  1030  //		mysqlCol.SetCharset(uint16(Utf8mb4CollationID))
  1031  //
  1032  //		rs.AddColumn(mysqlCol)
  1033  //
  1034  //		d1, _ := types.ParseDateCast("1997-01-01")
  1035  //		d2, _ := types.ParseDateCast("2008-02-02")
  1036  //		var cases = []types.Date{
  1037  //			d1,
  1038  //			d2,
  1039  //		}
  1040  //		for _, v := range cases {
  1041  //			var data = make([]interface{}, 1)
  1042  //			data[0] = v
  1043  //			rs.AddRow(data)
  1044  //		}
  1045  //
  1046  //		return rs
  1047  //	}
  1048  //
  1049  //	func makeMysqlDateResult() *MysqlExecutionResult {
  1050  //		return NewMysqlExecutionResult(0, 0, 0, 0, makeMysqlDateResultSet())
  1051  //	}
  1052  //
  1053  //	func makeMysqlTimeResultSet() *MysqlResultSet {
  1054  //		var rs = &MysqlResultSet{}
  1055  //
  1056  //		name := "Time"
  1057  //
  1058  //		mysqlCol := new(MysqlColumn)
  1059  //		mysqlCol.SetName(name)
  1060  //		mysqlCol.SetOrgName(name + "OrgName")
  1061  //		mysqlCol.SetColumnType(defines.MYSQL_TYPE_TIME)
  1062  //		mysqlCol.SetSchema(name + "Schema")
  1063  //		mysqlCol.SetTable(name + "Table")
  1064  //		mysqlCol.SetOrgTable(name + "Table")
  1065  //		mysqlCol.SetCharset(uint16(Utf8mb4CollationID))
  1066  //
  1067  //		rs.AddColumn(mysqlCol)
  1068  //
  1069  //		t1, _ := types.ParseTime("110:21:15", 0)
  1070  //		t2, _ := types.ParseTime("2018-04-28 10:21:15.123", 0)
  1071  //		t3, _ := types.ParseTime("-112:12:12", 0)
  1072  //		var cases = []types.Time{
  1073  //			t1,
  1074  //			t2,
  1075  //			t3,
  1076  //		}
  1077  //		for _, v := range cases {
  1078  //			var data = make([]interface{}, 1)
  1079  //			data[0] = v
  1080  //			rs.AddRow(data)
  1081  //		}
  1082  //
  1083  //		return rs
  1084  //	}
  1085  //
  1086  //	func makeMysqlTimeResult() *MysqlExecutionResult {
  1087  //		return NewMysqlExecutionResult(0, 0, 0, 0, makeMysqlTimeResultSet())
  1088  //	}
  1089  //
  1090  //	func makeMysqlDatetimeResultSet() *MysqlResultSet {
  1091  //		var rs = &MysqlResultSet{}
  1092  //
  1093  //		name := "Date"
  1094  //
  1095  //		mysqlCol := new(MysqlColumn)
  1096  //		mysqlCol.SetName(name)
  1097  //		mysqlCol.SetOrgName(name + "OrgName")
  1098  //		mysqlCol.SetColumnType(defines.MYSQL_TYPE_DATETIME)
  1099  //		mysqlCol.SetSchema(name + "Schema")
  1100  //		mysqlCol.SetTable(name + "Table")
  1101  //		mysqlCol.SetOrgTable(name + "Table")
  1102  //		mysqlCol.SetCharset(uint16(Utf8mb4CollationID))
  1103  //
  1104  //		rs.AddColumn(mysqlCol)
  1105  //
  1106  //		d1, _ := types.ParseDatetime("2018-04-28 10:21:15", 0)
  1107  //		d2, _ := types.ParseDatetime("2018-04-28 10:21:15.123", 0)
  1108  //		d3, _ := types.ParseDatetime("2015-03-03 12:12:12", 0)
  1109  //		var cases = []types.Datetime{
  1110  //			d1,
  1111  //			d2,
  1112  //			d3,
  1113  //		}
  1114  //		for _, v := range cases {
  1115  //			var data = make([]interface{}, 1)
  1116  //			data[0] = v
  1117  //			rs.AddRow(data)
  1118  //		}
  1119  //
  1120  //		return rs
  1121  //	}
  1122  //
  1123  //	func makeMysqlDatetimeResult() *MysqlExecutionResult {
  1124  //		return NewMysqlExecutionResult(0, 0, 0, 0, makeMysqlDatetimeResultSet())
  1125  //	}
  1126  func make9ColumnsResultSet() *MysqlResultSet {
  1127  	var rs = &MysqlResultSet{}
  1128  
  1129  	var columnTypes = []defines.MysqlType{
  1130  		defines.MYSQL_TYPE_TINY,
  1131  		defines.MYSQL_TYPE_SHORT,
  1132  		defines.MYSQL_TYPE_LONG,
  1133  		defines.MYSQL_TYPE_LONGLONG,
  1134  		defines.MYSQL_TYPE_VARCHAR,
  1135  		defines.MYSQL_TYPE_FLOAT,
  1136  		defines.MYSQL_TYPE_DATE,
  1137  		defines.MYSQL_TYPE_TIME,
  1138  		defines.MYSQL_TYPE_DATETIME,
  1139  		defines.MYSQL_TYPE_DOUBLE,
  1140  	}
  1141  
  1142  	var names = []string{
  1143  		"Tiny",
  1144  		"Short",
  1145  		"Long",
  1146  		"Longlong",
  1147  		"Varchar",
  1148  		"Float",
  1149  		"Date",
  1150  		"Time",
  1151  		"Datetime",
  1152  		"Double",
  1153  	}
  1154  
  1155  	d1, _ := types.ParseDateCast("1997-01-01")
  1156  	d2, _ := types.ParseDateCast("2008-02-02")
  1157  
  1158  	dt1, _ := types.ParseDatetime("2018-04-28 10:21:15", 0)
  1159  	dt2, _ := types.ParseDatetime("2018-04-28 10:21:15.123", 0)
  1160  	dt3, _ := types.ParseDatetime("2015-03-03 12:12:12", 0)
  1161  
  1162  	t1, _ := types.ParseTime("2018-04-28 10:21:15", 0)
  1163  	t2, _ := types.ParseTime("2018-04-28 10:21:15.123", 0)
  1164  	t3, _ := types.ParseTime("2015-03-03 12:12:12", 0)
  1165  
  1166  	var cases = [][]interface{}{
  1167  		{int8(-128), int16(-32768), int32(-2147483648), int64(-9223372036854775808), "abc", float32(math.MaxFloat32), d1, t1, dt1, float64(0.01)},
  1168  		{int8(-127), int16(0), int32(0), int64(0), "abcde", float32(math.SmallestNonzeroFloat32), d2, t2, dt2, float64(0.01)},
  1169  		{int8(127), int16(32767), int32(2147483647), int64(9223372036854775807), "", float32(-math.MaxFloat32), d1, t3, dt3, float64(0.01)},
  1170  		{int8(126), int16(32766), int32(2147483646), int64(9223372036854775806), "x-", float32(-math.SmallestNonzeroFloat32), d2, t1, dt1, float64(0.01)},
  1171  	}
  1172  
  1173  	for i, ct := range columnTypes {
  1174  		name := names[i]
  1175  		mysqlCol := new(MysqlColumn)
  1176  		mysqlCol.SetName(name)
  1177  		mysqlCol.SetOrgName(name + "OrgName")
  1178  		mysqlCol.SetColumnType(ct)
  1179  		mysqlCol.SetSchema(name + "Schema")
  1180  		mysqlCol.SetTable(name + "Table")
  1181  		mysqlCol.SetOrgTable(name + "Table")
  1182  		mysqlCol.SetCharset(uint16(Utf8mb4CollationID))
  1183  
  1184  		rs.AddColumn(mysqlCol)
  1185  	}
  1186  
  1187  	for _, v := range cases {
  1188  		rs.AddRow(v)
  1189  	}
  1190  
  1191  	return rs
  1192  }
  1193  
  1194  //func makeMysql9ColumnsResult() *MysqlExecutionResult {
  1195  //	return NewMysqlExecutionResult(0, 0, 0, 0, make9ColumnsResultSet())
  1196  //}
  1197  
  1198  //func makeMoreThan16MBResultSet() *MysqlResultSet {
  1199  //	var rs = &MysqlResultSet{}
  1200  //
  1201  //	var columnTypes = []defines.MysqlType{
  1202  //		defines.MYSQL_TYPE_LONGLONG,
  1203  //		defines.MYSQL_TYPE_DOUBLE,
  1204  //		defines.MYSQL_TYPE_VARCHAR,
  1205  //	}
  1206  //
  1207  //	var names = []string{
  1208  //		"Longlong",
  1209  //		"Double",
  1210  //		"Varchar",
  1211  //	}
  1212  //
  1213  //	var rowCase = []interface{}{int64(9223372036854775807), math.MaxFloat64, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}
  1214  //
  1215  //	for i, ct := range columnTypes {
  1216  //		name := names[i]
  1217  //		mysqlCol := new(MysqlColumn)
  1218  //		mysqlCol.SetName(name)
  1219  //		mysqlCol.SetOrgName(name + "OrgName")
  1220  //		mysqlCol.SetColumnType(ct)
  1221  //		mysqlCol.SetSchema(name + "Schema")
  1222  //		mysqlCol.SetTable(name + "Table")
  1223  //		mysqlCol.SetOrgTable(name + "Table")
  1224  //		mysqlCol.SetCharset(uint16(Utf8mb4CollationID))
  1225  //
  1226  //		rs.AddColumn(mysqlCol)
  1227  //	}
  1228  //
  1229  //	//the size of the total result set will be more than 16MB
  1230  //	for i := 0; i < 40000; i++ {
  1231  //		rs.AddRow(rowCase)
  1232  //	}
  1233  //
  1234  //	return rs
  1235  //}
  1236  //
  1237  //// the size of resultset will be morethan 16MB
  1238  //func makeMoreThan16MBResult() *MysqlExecutionResult {
  1239  //	return NewMysqlExecutionResult(0, 0, 0, 0, makeMoreThan16MBResultSet())
  1240  //}
  1241  //
  1242  //func make16MBRowResultSet() *MysqlResultSet {
  1243  //	var rs = &MysqlResultSet{}
  1244  //
  1245  //	name := "Varstring"
  1246  //
  1247  //	mysqlCol := new(MysqlColumn)
  1248  //	mysqlCol.SetName(name)
  1249  //	mysqlCol.SetOrgName(name + "OrgName")
  1250  //	mysqlCol.SetColumnType(defines.MYSQL_TYPE_VAR_STRING)
  1251  //	mysqlCol.SetSchema(name + "Schema")
  1252  //	mysqlCol.SetTable(name + "Table")
  1253  //	mysqlCol.SetOrgTable(name + "Table")
  1254  //	mysqlCol.SetCharset(uint16(Utf8mb4CollationID))
  1255  //
  1256  //	rs.AddColumn(mysqlCol)
  1257  //
  1258  //	/*
  1259  //		How to test the max size of the data in one packet that the client can received ?
  1260  //		Environment: Mysql Version 8.0.23
  1261  //		1. shell: mysql --help | grep allowed-packet
  1262  //			something like:
  1263  //			"
  1264  //			  --max-allowed-packet=#
  1265  //			max-allowed-packet                16777216
  1266  //			"
  1267  //			so, we get:
  1268  //				max-allowed-packet means : The maximum packet length to send to or receive from server.
  1269  //				default value : 16777216 (16MB)
  1270  //		2. shell execution: mysql -uroot -e "select repeat('a',16*1024*1024-4);" > 16MB-mysql.txt
  1271  //			we get: ERROR 2020 (HY000) at line 1: Got packet bigger than 'max_allowed_packet' bytes
  1272  //		3. shell execution: mysql -uroot -e "select repeat('a',16*1024*1024-5);" > 16MB-mysql.txt
  1273  //			execution succeeded
  1274  //		4. so, the max size of the data in one packet is (max-allowed-packet - 5).
  1275  //		5. To change max-allowed-packet.
  1276  //			shell execution: mysql max-allowed-packet=xxxxx ....
  1277  //	*/
  1278  //
  1279  //	//test in shell : mysql -h 127.0.0.1 -P 6001 -udump -p111 -e "16mbrow" > 16mbrow.txt
  1280  //	//max data size : 16 * 1024 * 1024 - 5
  1281  //	var stuff = make([]byte, 16*1024*1024-5)
  1282  //	for i := range stuff {
  1283  //		stuff[i] = 'a'
  1284  //	}
  1285  //
  1286  //	var rowCase = []interface{}{string(stuff)}
  1287  //	for i := 0; i < 1; i++ {
  1288  //		rs.AddRow(rowCase)
  1289  //	}
  1290  //
  1291  //	return rs
  1292  //}
  1293  //
  1294  //// the size of resultset row will be more than 16MB
  1295  //func make16MBRowResult() *MysqlExecutionResult {
  1296  //	return NewMysqlExecutionResult(0, 0, 0, 0, make16MBRowResultSet())
  1297  //}
  1298  //
  1299  //func (tRM *TestRoutineManager) resultsetHandler(rs goetty.IOSession, msg interface{}, _ uint64) error {
  1300  //	tRM.rwlock.Lock()
  1301  //	routine := tRM.clients[rs]
  1302  //	tRM.rwlock.Unlock()
  1303  //	ctx := context.TODO()
  1304  //
  1305  //	pu, err := getParameterUnit("test/system_vars_config.toml", nil, nil)
  1306  //	if err != nil {
  1307  //		return err
  1308  //	}
  1309  //	pu.SV.SkipCheckUser = true
  1310  //	pro := routine.getProtocol().(*MysqlProtocolImpl)
  1311  //	packet, ok := msg.(*Packet)
  1312  //	pro.SetSequenceID(uint8(packet.SequenceID + 1))
  1313  //	if !ok {
  1314  //		return moerr.NewInternalError(ctx, "message is not Packet")
  1315  //	}
  1316  //	setGlobalPu(pu)
  1317  //	ses := NewSession(pro, nil, nil, false, nil)
  1318  //	ses.SetRequestContext(ctx)
  1319  //	pro.SetSession(ses)
  1320  //
  1321  //	length := packet.Length
  1322  //	payload := packet.Payload
  1323  //	for uint32(length) == MaxPayloadSize {
  1324  //		var err error
  1325  //		msg, err = pro.GetTcpConnection().Read(goetty.ReadOptions{})
  1326  //		if err != nil {
  1327  //			return moerr.NewInternalError(ctx, "read msg error")
  1328  //		}
  1329  //
  1330  //		packet, ok = msg.(*Packet)
  1331  //		if !ok {
  1332  //			return moerr.NewInternalError(ctx, "message is not Packet")
  1333  //		}
  1334  //
  1335  //		pro.SetSequenceID(uint8(packet.SequenceID + 1))
  1336  //		payload = append(payload, packet.Payload...)
  1337  //		length = packet.Length
  1338  //	}
  1339  //
  1340  //	// finish handshake process
  1341  //	if !pro.IsEstablished() {
  1342  //		_, err := pro.HandleHandshake(ctx, payload)
  1343  //		if err != nil {
  1344  //			return err
  1345  //		}
  1346  //		if err = pro.Authenticate(ctx); err != nil {
  1347  //			return err
  1348  //		}
  1349  //		pro.SetEstablished()
  1350  //		return nil
  1351  //	}
  1352  //
  1353  //	var req *Request
  1354  //	var resp *Response
  1355  //	req = pro.GetRequest(payload)
  1356  //	switch req.GetCmd() {
  1357  //	case COM_QUIT:
  1358  //		resp = &Response{
  1359  //			category: OkResponse,
  1360  //			status:   0,
  1361  //			data:     nil,
  1362  //		}
  1363  //		if err := pro.SendResponse(ctx, resp); err != nil {
  1364  //			fmt.Printf("send response failed. error:%v", err)
  1365  //			break
  1366  //		}
  1367  //	case COM_QUERY:
  1368  //		var query = string(req.GetData().([]byte))
  1369  //
  1370  //		switch query {
  1371  //		case "tiny":
  1372  //			resp = &Response{
  1373  //				category: ResultResponse,
  1374  //				status:   0,
  1375  //				cmd:      0,
  1376  //				data:     makeMysqlTinyResult(false),
  1377  //			}
  1378  //		case "tinyu":
  1379  //			resp = &Response{
  1380  //				category: ResultResponse,
  1381  //				status:   0,
  1382  //				data:     makeMysqlTinyResult(true),
  1383  //			}
  1384  //		case "short":
  1385  //			resp = &Response{
  1386  //				category: ResultResponse,
  1387  //				status:   0,
  1388  //				data:     makeMysqlShortResult(false),
  1389  //			}
  1390  //		case "shortu":
  1391  //			resp = &Response{
  1392  //				category: ResultResponse,
  1393  //				status:   0,
  1394  //				data:     makeMysqlShortResult(true),
  1395  //			}
  1396  //		case "long":
  1397  //			resp = &Response{
  1398  //				category: ResultResponse,
  1399  //				status:   0,
  1400  //				data:     makeMysqlLongResult(false),
  1401  //			}
  1402  //		case "longu":
  1403  //			resp = &Response{
  1404  //				category: ResultResponse,
  1405  //				status:   0,
  1406  //				data:     makeMysqlLongResult(true),
  1407  //			}
  1408  //		case "longlong":
  1409  //			resp = &Response{
  1410  //				category: ResultResponse,
  1411  //				status:   0,
  1412  //				data:     makeMysqlLongLongResult(false),
  1413  //			}
  1414  //		case "longlongu":
  1415  //			resp = &Response{
  1416  //				category: ResultResponse,
  1417  //				status:   0,
  1418  //				data:     makeMysqlLongLongResult(true),
  1419  //			}
  1420  //		case "int24":
  1421  //			resp = &Response{
  1422  //				category: ResultResponse,
  1423  //				status:   0,
  1424  //				data:     makeMysqlInt24Result(false),
  1425  //			}
  1426  //		case "int24u":
  1427  //			resp = &Response{
  1428  //				category: ResultResponse,
  1429  //				status:   0,
  1430  //				data:     makeMysqlInt24Result(true),
  1431  //			}
  1432  //		case "year":
  1433  //			resp = &Response{
  1434  //				category: ResultResponse,
  1435  //				status:   0,
  1436  //				data:     makeMysqlYearResult(false),
  1437  //			}
  1438  //		case "yearu":
  1439  //			resp = &Response{
  1440  //				category: ResultResponse,
  1441  //				status:   0,
  1442  //				data:     makeMysqlYearResult(true),
  1443  //			}
  1444  //		case "varchar":
  1445  //			resp = &Response{
  1446  //				category: ResultResponse,
  1447  //				status:   0,
  1448  //				data:     makeMysqlVarcharResult(),
  1449  //			}
  1450  //		case "varstring":
  1451  //			resp = &Response{
  1452  //				category: ResultResponse,
  1453  //				status:   0,
  1454  //				data:     makeMysqlVarStringResult(),
  1455  //			}
  1456  //		case "string":
  1457  //			resp = &Response{
  1458  //				category: ResultResponse,
  1459  //				status:   0,
  1460  //				data:     makeMysqlStringResult(),
  1461  //			}
  1462  //		case "float":
  1463  //			resp = &Response{
  1464  //				category: ResultResponse,
  1465  //				status:   0,
  1466  //				data:     makeMysqlFloatResult(),
  1467  //			}
  1468  //		case "double":
  1469  //			resp = &Response{
  1470  //				category: ResultResponse,
  1471  //				status:   0,
  1472  //				data:     makeMysqlDoubleResult(),
  1473  //			}
  1474  //		case "date":
  1475  //			resp = &Response{
  1476  //				category: ResultResponse,
  1477  //				status:   0,
  1478  //				data:     makeMysqlDateResult(),
  1479  //			}
  1480  //		case "time":
  1481  //			resp = &Response{
  1482  //				category: ResultResponse,
  1483  //				status:   0,
  1484  //				data:     makeMysqlTimeResult(),
  1485  //			}
  1486  //		case "datetime":
  1487  //			resp = &Response{
  1488  //				category: ResultResponse,
  1489  //				status:   0,
  1490  //				data:     makeMysqlDatetimeResult(),
  1491  //			}
  1492  //		case "9columns":
  1493  //			resp = &Response{
  1494  //				category: ResultResponse,
  1495  //				status:   0,
  1496  //				data:     makeMysql9ColumnsResult(),
  1497  //			}
  1498  //		case "16mb":
  1499  //			resp = &Response{
  1500  //				category: ResultResponse,
  1501  //				status:   0,
  1502  //				data:     makeMoreThan16MBResult(),
  1503  //			}
  1504  //		case "16mbrow":
  1505  //			resp = &Response{
  1506  //				category: ResultResponse,
  1507  //				status:   0,
  1508  //				data:     make16MBRowResult(),
  1509  //			}
  1510  //		default:
  1511  //			resp = &Response{
  1512  //				category: OkResponse,
  1513  //				status:   0,
  1514  //				data:     nil,
  1515  //			}
  1516  //		}
  1517  //
  1518  //		if err := pro.SendResponse(ctx, resp); err != nil {
  1519  //			fmt.Printf("send response failed. error:%v", err)
  1520  //			break
  1521  //		}
  1522  //	case COM_PING:
  1523  //		resp = NewResponse(
  1524  //			OkResponse,
  1525  //			0, 0, 0,
  1526  //			0,
  1527  //			int(COM_PING),
  1528  //			nil,
  1529  //		)
  1530  //		if err := pro.SendResponse(ctx, resp); err != nil {
  1531  //			fmt.Printf("send response failed. error:%v", err)
  1532  //			break
  1533  //		}
  1534  //
  1535  //	default:
  1536  //		fmt.Printf("unsupported command. 0x%x \n", req.cmd)
  1537  //	}
  1538  //	if req.cmd == COM_QUIT {
  1539  //		return nil
  1540  //	}
  1541  //	return nil
  1542  //}
  1543  
  1544  //TODO:replace by the dedicated table functions.
  1545  //func TestMysqlResultSet(t *testing.T) {
  1546  //	//client connection method: mysql -h 127.0.0.1 -P 6001 -udump -p
  1547  //	//pwd: mysql-server-mysql-8.0.23/mysql-test
  1548  //	//with mysqltest: mysqltest --test-file=t/1st.test --result-file=r/1st.result --user=dump -p111 -P 6001 --host=127.0.0.1
  1549  //
  1550  //	//test:
  1551  //	//./mysql-test-run 1st --extern user=root --extern port=3306 --extern host=127.0.0.1
  1552  //	//  mysql5.7 failed
  1553  //	//	mysql-8.0.23 success
  1554  //	//./mysql-test-run 1st --extern user=root --extern port=6001 --extern host=127.0.0.1
  1555  //	//	matrixone failed: mysql-test-run: *** ERROR: Could not connect to extern server using command: '/Users/pengzhen/Documents/mysql-server-mysql-8.0.23/bld/runtime_output_directory//mysql --no-defaults --user=root --user=root --port=6001 --host=127.0.0.1 --silent --database=mysql --execute="SHOW GLOBAL VARIABLES"'
  1556  //	pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil)
  1557  //	_, err := toml.DecodeFile("test/system_vars_config.toml", pu.SV)
  1558  //	if err != nil {
  1559  //		panic(err)
  1560  //	}
  1561  //	pu.SV.SkipCheckUser = true
  1562  //
  1563  //	trm := NewTestRoutineManager(pu)
  1564  //	var atomTrm atomic.Value
  1565  //	atomTrm.Store(trm)
  1566  //
  1567  //	wg := sync.WaitGroup{}
  1568  //	wg.Add(1)
  1569  //
  1570  //	go func() {
  1571  //		defer wg.Done()
  1572  //
  1573  //		temTrm := atomTrm.Load().(*TestRoutineManager)
  1574  //		echoServer(temTrm.resultsetHandler, temTrm, NewSqlCodec())
  1575  //	}()
  1576  //
  1577  //	// to := NewTimeout(1*time.Minute, false)
  1578  //	// for isClosed() && !to.isTimeout() {
  1579  //	// }
  1580  //
  1581  //	time.Sleep(time.Second * 2)
  1582  //	db, err := openDbConn(t, 6001)
  1583  //	require.NoError(t, err)
  1584  //
  1585  //	do_query_resp_resultset(t, db, false, false, "tiny", makeMysqlTinyIntResultSet(false))
  1586  //	do_query_resp_resultset(t, db, false, false, "tinyu", makeMysqlTinyIntResultSet(true))
  1587  //	do_query_resp_resultset(t, db, false, false, "short", makeMysqlShortResultSet(false))
  1588  //	do_query_resp_resultset(t, db, false, false, "shortu", makeMysqlShortResultSet(true))
  1589  //	do_query_resp_resultset(t, db, false, false, "long", makeMysqlLongResultSet(false))
  1590  //	do_query_resp_resultset(t, db, false, false, "longu", makeMysqlLongResultSet(true))
  1591  //	do_query_resp_resultset(t, db, false, false, "longlong", makeMysqlLongLongResultSet(false))
  1592  //	do_query_resp_resultset(t, db, false, false, "longlongu", makeMysqlLongLongResultSet(true))
  1593  //	do_query_resp_resultset(t, db, false, false, "int24", makeMysqlInt24ResultSet(false))
  1594  //	do_query_resp_resultset(t, db, false, false, "int24u", makeMysqlInt24ResultSet(true))
  1595  //	do_query_resp_resultset(t, db, false, false, "year", makeMysqlYearResultSet(false))
  1596  //	do_query_resp_resultset(t, db, false, false, "yearu", makeMysqlYearResultSet(true))
  1597  //	do_query_resp_resultset(t, db, false, false, "varchar", makeMysqlVarcharResultSet())
  1598  //	do_query_resp_resultset(t, db, false, false, "varstring", makeMysqlVarStringResultSet())
  1599  //	do_query_resp_resultset(t, db, false, false, "string", makeMysqlStringResultSet())
  1600  //	do_query_resp_resultset(t, db, false, false, "float", makeMysqlFloatResultSet())
  1601  //	do_query_resp_resultset(t, db, false, false, "double", makeMysqlDoubleResultSet())
  1602  //	do_query_resp_resultset(t, db, false, false, "date", makeMysqlDateResultSet())
  1603  //	do_query_resp_resultset(t, db, false, false, "time", makeMysqlTimeResultSet())
  1604  //	do_query_resp_resultset(t, db, false, false, "datetime", makeMysqlDatetimeResultSet())
  1605  //	do_query_resp_resultset(t, db, false, false, "9columns", make9ColumnsResultSet())
  1606  //	do_query_resp_resultset(t, db, false, false, "16mbrow", make16MBRowResultSet())
  1607  //	do_query_resp_resultset(t, db, false, false, "16mb", makeMoreThan16MBResultSet())
  1608  //
  1609  //	time.Sleep(time.Millisecond * 10)
  1610  //	//close server
  1611  //	setServer(1)
  1612  //	wg.Wait()
  1613  //
  1614  //	closeDbConn(t, db)
  1615  //}
  1616  
  1617  // func open_tls_db(t *testing.T, port int) *sql.DB {
  1618  // 	tlsName := "custom"
  1619  // 	rootCertPool := x509.NewCertPool()
  1620  // 	pem, err := os.ReadFile("test/ca.pem")
  1621  // 	if err != nil {
  1622  // 		setServer(1)
  1623  // 		require.NoError(t, err)
  1624  // 	}
  1625  // 	if ok := rootCertPool.AppendCertsFromPEM(pem); !ok {
  1626  // 		log.Fatal("Failed to append PEM.")
  1627  // 	}
  1628  // 	clientCert := make([]tls.Certificate, 0, 1)
  1629  // 	certs, err := tls.LoadX509KeyPair("test/client-cert2.pem", "test/client-key2.pem")
  1630  // 	if err != nil {
  1631  // 		setServer(1)
  1632  // 		require.NoError(t, err)
  1633  // 	}
  1634  // 	clientCert = append(clientCert, certs)
  1635  // 	err = mysqlDriver.RegisterTLSConfig(tlsName, &tls.Config{
  1636  // 		RootCAs:            rootCertPool,
  1637  // 		Certificates:       clientCert,
  1638  // 		MinVersion:         tls.VersionTLS12,
  1639  // 		InsecureSkipVerify: true,
  1640  // 	})
  1641  // 	if err != nil {
  1642  // 		setServer(1)
  1643  // 		require.NoError(t, err)
  1644  // 	}
  1645  
  1646  // 	dsn := fmt.Sprintf("dump:111@tcp(127.0.0.1:%d)/?readTimeout=5s&timeout=5s&writeTimeout=5s&tls=%s", port, tlsName)
  1647  // 	db, err := sql.Open("mysql", dsn)
  1648  // 	if err != nil {
  1649  // 		require.NoError(t, err)
  1650  // 	} else {
  1651  // 		db.SetConnMaxLifetime(time.Minute * 3)
  1652  // 		db.SetMaxOpenConns(1)
  1653  // 		db.SetMaxIdleConns(1)
  1654  // 		time.Sleep(time.Millisecond * 100)
  1655  
  1656  // 		// ping opens the connection
  1657  // 		logutil.Info("start ping")
  1658  // 		err = db.Ping()
  1659  // 		if err != nil {
  1660  // 			setServer(1)
  1661  // 			require.NoError(t, err)
  1662  // 		}
  1663  // 	}
  1664  // 	return db
  1665  // }
  1666  
  1667  func openDbConn(t *testing.T, port int) (db *sql.DB, err error) {
  1668  	dsn := fmt.Sprintf("dump:111@tcp(127.0.0.1:%d)/?readTimeout=30s&timeout=30s&writeTimeout=30s", port)
  1669  	for i := 0; i < 3; i++ {
  1670  		db, err = tryConn(dsn)
  1671  		if err != nil {
  1672  			logger.Error("open conn failed.", zap.Error(err))
  1673  			time.Sleep(time.Second)
  1674  			continue
  1675  		}
  1676  		break
  1677  	}
  1678  	return
  1679  }
  1680  
  1681  func tryConn(dsn string) (*sql.DB, error) {
  1682  	db, err := sql.Open("mysql", dsn)
  1683  	if err != nil {
  1684  		return nil, err
  1685  	} else {
  1686  		db.SetConnMaxLifetime(time.Minute * 3)
  1687  		db.SetMaxOpenConns(1)
  1688  		db.SetMaxIdleConns(1)
  1689  		time.Sleep(time.Millisecond * 100)
  1690  
  1691  		//ping opens the connection
  1692  		err = db.Ping()
  1693  		if err != nil {
  1694  			return nil, err
  1695  		}
  1696  	}
  1697  	return db, err
  1698  }
  1699  
  1700  func closeDbConn(t *testing.T, db *sql.DB) {
  1701  	err := db.Close()
  1702  	assert.NoError(t, err)
  1703  }
  1704  
  1705  //func do_query_resp_resultset(t *testing.T, db *sql.DB, wantErr bool, skipResultsetCheck bool, query string, mrs *MysqlResultSet) {
  1706  //	logutil.Infof("query: %v", query)
  1707  //	rows, err := db.Query(query)
  1708  //	if wantErr {
  1709  //		require.Error(t, err)
  1710  //		require.True(t, rows == nil)
  1711  //		return
  1712  //	}
  1713  //	require.NoError(t, err)
  1714  //	defer func() {
  1715  //		err = rows.Close()
  1716  //		require.NoError(t, err)
  1717  //		err = rows.Err()
  1718  //		require.NoError(t, err)
  1719  //	}()
  1720  //
  1721  //	//column check
  1722  //	columns, err := rows.Columns()
  1723  //	require.NoError(t, err)
  1724  //	require.True(t, len(columns) == len(mrs.Columns))
  1725  //
  1726  //	//colType, err := rows.ColumnTypes()
  1727  //	//require.NoError(t, err)
  1728  //	//for i, ct := range colType {
  1729  //	//	fmt.Printf("column %d\n",i)
  1730  //	//	fmt.Printf("name %v \n",ct.Name())
  1731  //	//	l,o := ct.RowCount()
  1732  //	//	fmt.Printf("length %v %v \n",l,o)
  1733  //	//	p,s,o := ct.DecimalSize()
  1734  //	//	fmt.Printf("decimalsize %v %v %v \n",p,s,o)
  1735  //	//	fmt.Printf("scantype %v \n",ct.ScanType())
  1736  //	//	n,o := ct.Nullable()
  1737  //	//	fmt.Printf("nullable %v %v \n",n,o)
  1738  //	//	fmt.Printf("databaseTypeName %s \n",ct.DatabaseTypeName())
  1739  //	//}
  1740  //
  1741  //	values := make([][]byte, len(columns))
  1742  //
  1743  //	// rows.Scan wants '[]interface{}' as an argument, so we must copy the
  1744  //	// references into such a slice
  1745  //	// See http://code.google.com/p/go-wiki/wiki/InterfaceSlice for details
  1746  //	scanArgs := make([]interface{}, len(columns))
  1747  //	for i := uint64(0); i < mrs.GetColumnCount(); i++ {
  1748  //		scanArgs[i] = &values[i]
  1749  //	}
  1750  //
  1751  //	rowIdx := uint64(0)
  1752  //	for rows.Next() {
  1753  //		err = rows.Scan(scanArgs...)
  1754  //		require.NoError(t, err)
  1755  //
  1756  //		//fmt.Println(rowIdx)
  1757  //		//fmt.Println(mrs.GetRow(rowIdx))
  1758  //		//
  1759  //		//for i := uint64(0); i < mrs.GetColumnCount(); i++ {
  1760  //		//	arg := scanArgs[i]
  1761  //		//	val := *(arg.(*[]byte))
  1762  //		//	fmt.Printf("%v ",val)
  1763  //		//}
  1764  //		//fmt.Println()
  1765  //
  1766  //		if !skipResultsetCheck {
  1767  //			for i := uint64(0); i < mrs.GetColumnCount(); i++ {
  1768  //				arg := scanArgs[i]
  1769  //				val := *(arg.(*[]byte))
  1770  //
  1771  //				column, err := mrs.GetColumn(context.TODO(), i)
  1772  //				require.NoError(t, err)
  1773  //
  1774  //				col, ok := column.(*MysqlColumn)
  1775  //				require.True(t, ok)
  1776  //
  1777  //				isNUll, err := mrs.ColumnIsNull(context.TODO(), rowIdx, i)
  1778  //				require.NoError(t, err)
  1779  //
  1780  //				if isNUll {
  1781  //					require.True(t, val == nil)
  1782  //				} else {
  1783  //					var data []byte = nil
  1784  //					switch col.ColumnType() {
  1785  //					case defines.MYSQL_TYPE_TINY, defines.MYSQL_TYPE_SHORT, defines.MYSQL_TYPE_INT24, defines.MYSQL_TYPE_LONG, defines.MYSQL_TYPE_YEAR:
  1786  //						value, err := mrs.GetInt64(context.TODO(), rowIdx, i)
  1787  //						require.NoError(t, err)
  1788  //						if col.ColumnType() == defines.MYSQL_TYPE_YEAR {
  1789  //							if value == 0 {
  1790  //								data = append(data, []byte("0000")...)
  1791  //							} else {
  1792  //								data = strconv.AppendInt(data, value, 10)
  1793  //							}
  1794  //						} else {
  1795  //							data = strconv.AppendInt(data, value, 10)
  1796  //						}
  1797  //
  1798  //					case defines.MYSQL_TYPE_LONGLONG:
  1799  //						if uint32(col.Flag())&defines.UNSIGNED_FLAG != 0 {
  1800  //							value, err := mrs.GetUint64(context.TODO(), rowIdx, i)
  1801  //							require.NoError(t, err)
  1802  //							data = strconv.AppendUint(data, value, 10)
  1803  //						} else {
  1804  //							value, err := mrs.GetInt64(context.TODO(), rowIdx, i)
  1805  //							require.NoError(t, err)
  1806  //							data = strconv.AppendInt(data, value, 10)
  1807  //						}
  1808  //					case defines.MYSQL_TYPE_VARCHAR, defines.MYSQL_TYPE_VAR_STRING, defines.MYSQL_TYPE_STRING:
  1809  //						value, err := mrs.GetString(context.TODO(), rowIdx, i)
  1810  //						require.NoError(t, err)
  1811  //						data = []byte(value)
  1812  //					case defines.MYSQL_TYPE_FLOAT:
  1813  //						value, err := mrs.GetFloat64(context.TODO(), rowIdx, i)
  1814  //						require.NoError(t, err)
  1815  //						data = strconv.AppendFloat(data, value, 'f', -1, 32)
  1816  //					case defines.MYSQL_TYPE_DOUBLE:
  1817  //						value, err := mrs.GetFloat64(context.TODO(), rowIdx, i)
  1818  //						require.NoError(t, err)
  1819  //						data = strconv.AppendFloat(data, value, 'f', -1, 64)
  1820  //					case defines.MYSQL_TYPE_DATE:
  1821  //						value, err := mrs.GetValue(context.TODO(), rowIdx, i)
  1822  //						require.NoError(t, err)
  1823  //						x := value.(types.Date).String()
  1824  //						data = []byte(x)
  1825  //					case defines.MYSQL_TYPE_TIME:
  1826  //						value, err := mrs.GetValue(context.TODO(), rowIdx, i)
  1827  //						require.NoError(t, err)
  1828  //						x := value.(types.Time).String()
  1829  //						data = []byte(x)
  1830  //					case defines.MYSQL_TYPE_DATETIME:
  1831  //						value, err := mrs.GetValue(context.TODO(), rowIdx, i)
  1832  //						require.NoError(t, err)
  1833  //						x := value.(types.Datetime).String()
  1834  //						data = []byte(x)
  1835  //					default:
  1836  //						require.NoError(t, moerr.NewInternalError(context.TODO(), "unsupported type %v", col.ColumnType()))
  1837  //					}
  1838  //					//check
  1839  //					ret := reflect.DeepEqual(data, val)
  1840  //					//fmt.Println(i)
  1841  //					//fmt.Println(data)
  1842  //					//fmt.Println(val)
  1843  //					require.True(t, ret)
  1844  //				}
  1845  //			}
  1846  //		}
  1847  //
  1848  //		rowIdx++
  1849  //	}
  1850  //
  1851  //	require.True(t, rowIdx == mrs.GetRowCount())
  1852  //
  1853  //}
  1854  
  1855  func Test_writePackets(t *testing.T) {
  1856  	ctx := context.TODO()
  1857  	convey.Convey("writepackets 16MB succ", t, func() {
  1858  		ctrl := gomock.NewController(t)
  1859  		defer ctrl.Finish()
  1860  		ioses := mock_frontend.NewMockIOSession(ctrl)
  1861  		ioses.EXPECT().Write(gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
  1862  		ioses.EXPECT().RemoteAddress().Return("").AnyTimes()
  1863  		ioses.EXPECT().Ref().AnyTimes()
  1864  		ioses.EXPECT().Flush(gomock.Any()).AnyTimes()
  1865  		sv, err := getSystemVariables("test/system_vars_config.toml")
  1866  		if err != nil {
  1867  			t.Error(err)
  1868  		}
  1869  
  1870  		proto := NewMysqlClientProtocol(0, ioses, 1024, sv)
  1871  		err = proto.writePackets(make([]byte, MaxPayloadSize), true)
  1872  		convey.So(err, convey.ShouldBeNil)
  1873  	})
  1874  	convey.Convey("writepackets 16MB failed", t, func() {
  1875  		ctrl := gomock.NewController(t)
  1876  		defer ctrl.Finish()
  1877  		ioses := mock_frontend.NewMockIOSession(ctrl)
  1878  
  1879  		cnt := 0
  1880  		ioses.EXPECT().Write(gomock.Any(), gomock.Any()).DoAndReturn(func(msg interface{}, opts goetty.WriteOptions) error {
  1881  			if cnt == 0 {
  1882  				cnt++
  1883  				return nil
  1884  			} else {
  1885  				cnt++
  1886  				return moerr.NewInternalError(ctx, "write and flush failed.")
  1887  			}
  1888  		}).AnyTimes()
  1889  		ioses.EXPECT().RemoteAddress().Return("").AnyTimes()
  1890  		ioses.EXPECT().Ref().AnyTimes()
  1891  		ioses.EXPECT().Flush(gomock.Any()).AnyTimes()
  1892  		sv, err := getSystemVariables("test/system_vars_config.toml")
  1893  		if err != nil {
  1894  			t.Error(err)
  1895  		}
  1896  
  1897  		proto := NewMysqlClientProtocol(0, ioses, 1024, sv)
  1898  		err = proto.writePackets(make([]byte, MaxPayloadSize), true)
  1899  		convey.So(err, convey.ShouldBeError)
  1900  	})
  1901  
  1902  	convey.Convey("writepackets 16MB failed 2", t, func() {
  1903  		ctrl := gomock.NewController(t)
  1904  		defer ctrl.Finish()
  1905  		ioses := mock_frontend.NewMockIOSession(ctrl)
  1906  
  1907  		ioses.EXPECT().Write(gomock.Any(), gomock.Any()).DoAndReturn(func(msg interface{}, opts goetty.WriteOptions) error {
  1908  			return moerr.NewInternalError(ctx, "write and flush failed.")
  1909  		}).AnyTimes()
  1910  		ioses.EXPECT().RemoteAddress().Return("").AnyTimes()
  1911  		ioses.EXPECT().Ref().AnyTimes()
  1912  		ioses.EXPECT().Flush(gomock.Any()).AnyTimes()
  1913  		sv, err := getSystemVariables("test/system_vars_config.toml")
  1914  		if err != nil {
  1915  			t.Error(err)
  1916  		}
  1917  
  1918  		proto := NewMysqlClientProtocol(0, ioses, 1024, sv)
  1919  		err = proto.writePackets(make([]byte, MaxPayloadSize), true)
  1920  		convey.So(err, convey.ShouldBeError)
  1921  	})
  1922  }
  1923  
  1924  func Test_openpacket(t *testing.T) {
  1925  	convey.Convey("openpacket succ", t, func() {
  1926  		ctrl := gomock.NewController(t)
  1927  		defer ctrl.Finish()
  1928  		ioses := mock_frontend.NewMockIOSession(ctrl)
  1929  
  1930  		ioses.EXPECT().OutBuf().Return(goetty_buf.NewByteBuf(1024)).AnyTimes()
  1931  		ioses.EXPECT().RemoteAddress().Return("").AnyTimes()
  1932  		ioses.EXPECT().Ref().AnyTimes()
  1933  		ioses.EXPECT().Flush(gomock.Any()).AnyTimes()
  1934  		sv, err := getSystemVariables("test/system_vars_config.toml")
  1935  		if err != nil {
  1936  			t.Error(err)
  1937  		}
  1938  
  1939  		proto := NewMysqlClientProtocol(0, ioses, 1024, sv)
  1940  
  1941  		err = proto.openPacket()
  1942  		convey.So(err, convey.ShouldBeNil)
  1943  		outBuf := proto.tcpConn.OutBuf()
  1944  		headLen := outBuf.GetWriteIndex() - beginWriteIndex(outBuf, proto.beginOffset)
  1945  		convey.So(headLen, convey.ShouldEqual, HeaderLengthOfTheProtocol)
  1946  	})
  1947  
  1948  	convey.Convey("fillpacket succ", t, func() {
  1949  		ctrl := gomock.NewController(t)
  1950  		defer ctrl.Finish()
  1951  		ioses := mock_frontend.NewMockIOSession(ctrl)
  1952  
  1953  		ioses.EXPECT().OutBuf().Return(goetty_buf.NewByteBuf(1024)).AnyTimes()
  1954  		ioses.EXPECT().Flush(gomock.Any()).Return(nil).AnyTimes()
  1955  		ioses.EXPECT().RemoteAddress().Return("").AnyTimes()
  1956  		ioses.EXPECT().Ref().AnyTimes()
  1957  		ioses.EXPECT().Flush(gomock.Any()).AnyTimes()
  1958  		pu, err := getParameterUnit("test/system_vars_config.toml", nil, nil)
  1959  		if err != nil {
  1960  			t.Error(err)
  1961  		}
  1962  		setGlobalPu(pu)
  1963  
  1964  		proto := NewMysqlClientProtocol(0, ioses, 1024, pu.SV)
  1965  		// fill proto.ses
  1966  		ses := NewSession(context.TODO(), proto, nil, nil, false, nil)
  1967  		proto.ses = ses
  1968  
  1969  		err = proto.fillPacket(make([]byte, MaxPayloadSize)...)
  1970  		convey.So(err, convey.ShouldBeNil)
  1971  
  1972  		err = proto.closePacket(true)
  1973  		convey.So(err, convey.ShouldBeNil)
  1974  
  1975  		proto.append(nil, make([]byte, 1024)...)
  1976  	})
  1977  
  1978  	convey.Convey("closepacket falied.", t, func() {
  1979  		ctrl := gomock.NewController(t)
  1980  		defer ctrl.Finish()
  1981  		ioses := mock_frontend.NewMockIOSession(ctrl)
  1982  
  1983  		ioses.EXPECT().OutBuf().Return(goetty_buf.NewByteBuf(1024)).AnyTimes()
  1984  		ioses.EXPECT().RemoteAddress().Return("").AnyTimes()
  1985  		ioses.EXPECT().Ref().AnyTimes()
  1986  		ioses.EXPECT().Flush(gomock.Any()).AnyTimes()
  1987  		pu, err := getParameterUnit("test/system_vars_config.toml", nil, nil)
  1988  		if err != nil {
  1989  			t.Error(err)
  1990  		}
  1991  		setGlobalPu(pu)
  1992  
  1993  		proto := NewMysqlClientProtocol(0, ioses, 1024, pu.SV)
  1994  		// fill proto.ses
  1995  		ses := NewSession(context.TODO(), proto, nil, nil, false, nil)
  1996  		proto.ses = ses
  1997  
  1998  		err = proto.openPacket()
  1999  		convey.So(err, convey.ShouldBeNil)
  2000  
  2001  		proto.beginOffset = proto.tcpConn.OutBuf().GetWriteIndex() - proto.tcpConn.OutBuf().GetReadIndex()
  2002  		err = proto.closePacket(true)
  2003  		convey.So(err, convey.ShouldBeError)
  2004  	})
  2005  
  2006  	convey.Convey("append -- data checks", t, func() {
  2007  		ctrl := gomock.NewController(t)
  2008  		defer ctrl.Finish()
  2009  		ioses := mock_frontend.NewMockIOSession(ctrl)
  2010  
  2011  		ioses.EXPECT().OutBuf().Return(goetty_buf.NewByteBuf(1024)).AnyTimes()
  2012  		ioses.EXPECT().Flush(gomock.Any()).Return(nil).AnyTimes()
  2013  		ioses.EXPECT().RemoteAddress().Return("").AnyTimes()
  2014  		ioses.EXPECT().Ref().AnyTimes()
  2015  		ioses.EXPECT().Flush(gomock.Any()).AnyTimes()
  2016  		sv, err := getSystemVariables("test/system_vars_config.toml")
  2017  		if err != nil {
  2018  			t.Error(err)
  2019  		}
  2020  
  2021  		proto := NewMysqlClientProtocol(0, ioses, 1024, sv)
  2022  
  2023  		mysqlPack := func(payload []byte) []byte {
  2024  			n := len(payload)
  2025  			var curLen int
  2026  			var header [4]byte
  2027  			var data []byte = nil
  2028  			var sequenceId byte = 0
  2029  			for i := 0; i < n; i += curLen {
  2030  				curLen = Min(int(MaxPayloadSize), n-i)
  2031  				binary.LittleEndian.PutUint32(header[:], uint32(curLen))
  2032  				header[3] = sequenceId
  2033  				sequenceId++
  2034  				data = append(data, header[:]...)
  2035  				data = append(data, payload[i:i+curLen]...)
  2036  				if i+curLen == n && curLen == int(MaxPayloadSize) {
  2037  					binary.LittleEndian.PutUint32(header[:], uint32(0))
  2038  					header[3] = sequenceId
  2039  					sequenceId++
  2040  					data = append(data, header[:]...)
  2041  				}
  2042  			}
  2043  			return data
  2044  		}
  2045  
  2046  		data16MB := func(cnt int) []byte {
  2047  			data := make([]byte, cnt*int(MaxPayloadSize))
  2048  			return data
  2049  		}
  2050  
  2051  		type kase struct {
  2052  			data []byte
  2053  			len  int
  2054  		}
  2055  
  2056  		kases := []kase{
  2057  			{
  2058  				data: []byte{1, 2, 3, 4},
  2059  				len:  HeaderLengthOfTheProtocol + 4,
  2060  			},
  2061  			{
  2062  				data: data16MB(1),
  2063  				len:  HeaderLengthOfTheProtocol + int(MaxPayloadSize) + HeaderLengthOfTheProtocol,
  2064  			},
  2065  			{
  2066  				data: data16MB(2),
  2067  				len:  HeaderLengthOfTheProtocol + int(MaxPayloadSize) + HeaderLengthOfTheProtocol + int(MaxPayloadSize) + HeaderLengthOfTheProtocol,
  2068  			},
  2069  			{
  2070  				data: data16MB(3),
  2071  				len: HeaderLengthOfTheProtocol + int(MaxPayloadSize) +
  2072  					HeaderLengthOfTheProtocol + int(MaxPayloadSize) +
  2073  					HeaderLengthOfTheProtocol + int(MaxPayloadSize) +
  2074  					HeaderLengthOfTheProtocol,
  2075  			},
  2076  			{
  2077  				data: data16MB(4),
  2078  				len: HeaderLengthOfTheProtocol + int(MaxPayloadSize) +
  2079  					HeaderLengthOfTheProtocol + int(MaxPayloadSize) +
  2080  					HeaderLengthOfTheProtocol + int(MaxPayloadSize) +
  2081  					HeaderLengthOfTheProtocol + int(MaxPayloadSize) +
  2082  					HeaderLengthOfTheProtocol,
  2083  			},
  2084  		}
  2085  
  2086  		for _, c := range kases {
  2087  			proto.SetSequenceID(0)
  2088  
  2089  			err = proto.openRow(nil)
  2090  			convey.So(err, convey.ShouldBeNil)
  2091  
  2092  			outBuf := proto.tcpConn.OutBuf()
  2093  			beginOffset := proto.beginOffset
  2094  
  2095  			rawBuf := proto.append(nil, c.data...)
  2096  
  2097  			err = proto.closeRow(nil)
  2098  			convey.So(err, convey.ShouldBeNil)
  2099  
  2100  			want := mysqlPack(c.data)
  2101  
  2102  			convey.So(c.len, convey.ShouldEqual, len(want))
  2103  
  2104  			widx := outBuf.GetWriteIndex()
  2105  			beginIdx := beginWriteIndex(outBuf, beginOffset)
  2106  			res := rawBuf[beginIdx:widx]
  2107  
  2108  			convey.So(bytes.Equal(res, want), convey.ShouldBeTrue)
  2109  		}
  2110  	})
  2111  
  2112  }
  2113  
  2114  func TestSendPrepareResponse(t *testing.T) {
  2115  	ctx := context.TODO()
  2116  	convey.Convey("send Prepare response succ", t, func() {
  2117  		ctrl := gomock.NewController(t)
  2118  		defer ctrl.Finish()
  2119  		ioses := mock_frontend.NewMockIOSession(ctrl)
  2120  
  2121  		ioses.EXPECT().OutBuf().Return(goetty_buf.NewByteBuf(1024)).AnyTimes()
  2122  		ioses.EXPECT().Write(gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
  2123  		ioses.EXPECT().RemoteAddress().Return("").AnyTimes()
  2124  		ioses.EXPECT().Ref().AnyTimes()
  2125  		ioses.EXPECT().Flush(gomock.Any()).AnyTimes()
  2126  		sv, err := getSystemVariables("test/system_vars_config.toml")
  2127  		if err != nil {
  2128  			t.Error(err)
  2129  		}
  2130  
  2131  		proto := NewMysqlClientProtocol(0, ioses, 1024, sv)
  2132  		proto.SetSession(&Session{
  2133  			feSessionImpl: feSessionImpl{
  2134  				txnHandler: &TxnHandler{},
  2135  			},
  2136  		})
  2137  
  2138  		st := tree.NewPrepareString(tree.Identifier(getPrepareStmtName(1)), "select ?, 1")
  2139  		stmts, err := mysql.Parse(ctx, st.Sql, 1, 0)
  2140  		if err != nil {
  2141  			t.Error(err)
  2142  		}
  2143  		compCtx := plan.NewEmptyCompilerContext()
  2144  		preparePlan, err := buildPlan(context.TODO(), nil, compCtx, st)
  2145  		if err != nil {
  2146  			t.Error(err)
  2147  		}
  2148  		prepareStmt := &PrepareStmt{
  2149  			Name:        preparePlan.GetDcl().GetPrepare().GetName(),
  2150  			PreparePlan: preparePlan,
  2151  			PrepareStmt: stmts[0],
  2152  		}
  2153  		err = proto.SendPrepareResponse(ctx, prepareStmt)
  2154  
  2155  		convey.So(err, convey.ShouldBeNil)
  2156  	})
  2157  
  2158  	convey.Convey("send Prepare response error", t, func() {
  2159  		ctrl := gomock.NewController(t)
  2160  		defer ctrl.Finish()
  2161  		ioses := mock_frontend.NewMockIOSession(ctrl)
  2162  
  2163  		ioses.EXPECT().OutBuf().Return(goetty_buf.NewByteBuf(1024)).AnyTimes()
  2164  		ioses.EXPECT().Write(gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
  2165  		ioses.EXPECT().RemoteAddress().Return("").AnyTimes()
  2166  		ioses.EXPECT().Ref().AnyTimes()
  2167  		ioses.EXPECT().Flush(gomock.Any()).AnyTimes()
  2168  		sv, err := getSystemVariables("test/system_vars_config.toml")
  2169  		if err != nil {
  2170  			t.Error(err)
  2171  		}
  2172  
  2173  		proto := NewMysqlClientProtocol(0, ioses, 1024, sv)
  2174  
  2175  		st := tree.NewPrepareString("stmt1", "select ?, 1")
  2176  		stmts, err := mysql.Parse(ctx, st.Sql, 1, 0)
  2177  		if err != nil {
  2178  			t.Error(err)
  2179  		}
  2180  		compCtx := plan.NewEmptyCompilerContext()
  2181  		preparePlan, err := buildPlan(context.TODO(), nil, compCtx, st)
  2182  		if err != nil {
  2183  			t.Error(err)
  2184  		}
  2185  		prepareStmt := &PrepareStmt{
  2186  			Name:        preparePlan.GetDcl().GetPrepare().GetName(),
  2187  			PreparePlan: preparePlan,
  2188  			PrepareStmt: stmts[0],
  2189  		}
  2190  		err = proto.SendPrepareResponse(ctx, prepareStmt)
  2191  
  2192  		convey.So(err, convey.ShouldBeError)
  2193  	})
  2194  }
  2195  
  2196  func FuzzParseExecuteData(f *testing.F) {
  2197  	ctx := context.TODO()
  2198  
  2199  	ctrl := gomock.NewController(f)
  2200  	defer ctrl.Finish()
  2201  	ioses := mock_frontend.NewMockIOSession(ctrl)
  2202  	proc := testutil.NewProcess()
  2203  
  2204  	ioses.EXPECT().OutBuf().Return(goetty_buf.NewByteBuf(1024)).AnyTimes()
  2205  	ioses.EXPECT().Write(gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
  2206  	ioses.EXPECT().RemoteAddress().Return("").AnyTimes()
  2207  	ioses.EXPECT().Ref().AnyTimes()
  2208  	ioses.EXPECT().Flush(gomock.Any()).AnyTimes()
  2209  	sv, err := getSystemVariables("test/system_vars_config.toml")
  2210  	if err != nil {
  2211  		f.Error(err)
  2212  	}
  2213  
  2214  	proto := NewMysqlClientProtocol(0, ioses, 1024, sv)
  2215  
  2216  	st := tree.NewPrepareString(tree.Identifier(getPrepareStmtName(1)), "select ?, 1")
  2217  	stmts, err := mysql.Parse(ctx, st.Sql, 1, 0)
  2218  	if err != nil {
  2219  		f.Error(err)
  2220  	}
  2221  	compCtx := plan.NewEmptyCompilerContext()
  2222  	preparePlan, err := buildPlan(context.TODO(), nil, compCtx, st)
  2223  	if err != nil {
  2224  		f.Error(err)
  2225  	}
  2226  	prepareStmt := &PrepareStmt{
  2227  		Name:        preparePlan.GetDcl().GetPrepare().GetName(),
  2228  		PreparePlan: preparePlan,
  2229  		PrepareStmt: stmts[0],
  2230  		params:      vector.NewVec(types.T_varchar.ToType()),
  2231  	}
  2232  
  2233  	var testData []byte
  2234  	testData = append(testData, 0)          //flag
  2235  	testData = append(testData, 0, 0, 0, 0) // skip iteration-count
  2236  	nullBitmapLen := (1 + 7) >> 3
  2237  	//nullBitmapLen
  2238  	for i := 0; i < nullBitmapLen; i++ {
  2239  		testData = append(testData, 0)
  2240  	}
  2241  	testData = append(testData, 1)                              // new param bound flag
  2242  	testData = append(testData, uint8(defines.MYSQL_TYPE_TINY)) // type
  2243  	testData = append(testData, 0)                              //is unsigned
  2244  	testData = append(testData, 10)                             //tiny value
  2245  
  2246  	f.Add(testData)
  2247  
  2248  	testData = []byte{}
  2249  	testData = append(testData, 0)          //flag
  2250  	testData = append(testData, 0, 0, 0, 0) // skip iteration-count
  2251  	nullBitmapLen = (1 + 7) >> 3
  2252  	//nullBitmapLen
  2253  	for i := 0; i < nullBitmapLen; i++ {
  2254  		testData = append(testData, 0)
  2255  	}
  2256  	testData = append(testData, 1)                              // new param bound flag
  2257  	testData = append(testData, uint8(defines.MYSQL_TYPE_TINY)) // type
  2258  	testData = append(testData, 0)                              //is unsigned
  2259  	testData = append(testData, 4)                              //tiny value
  2260  	f.Add(testData)
  2261  
  2262  	f.Fuzz(func(t *testing.T, data []byte) {
  2263  		proto.ParseExecuteData(ctx, proc, prepareStmt, data, 0)
  2264  	})
  2265  }
  2266  
  2267  /* FIXME The prepare process has undergone some modifications,
  2268    	so the unit tests for prepare need to be refactored, and the subsequent pr I will resubmit a reasonable ut
  2269  func TestParseExecuteData(t *testing.T) {
  2270  	ctx := context.TODO()
  2271  	convey.Convey("parseExecuteData succ", t, func() {
  2272  		ctrl := gomock.NewController(t)
  2273  		defer ctrl.Finish()
  2274  		ioses := mock_frontend.NewMockIOSession(ctrl)
  2275  
  2276  		ioses.EXPECT().OutBuf().Return(goetty_buf.NewByteBuf(1024)).AnyTimes()
  2277  		ioses.EXPECT().Write(gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
  2278  		ioses.EXPECT().RemoteAddress().Return("").AnyTimes()
  2279  		ioses.EXPECT().Ref().AnyTimes()
  2280  		ioses.EXPECT().Flush(gomock.Any()).AnyTimes()
  2281  		sv, err := getSystemVariables("test/system_vars_config.toml")
  2282  		if err != nil {
  2283  			t.Error(err)
  2284  		}
  2285  
  2286  		proto := NewMysqlClientProtocol(0, ioses, 1024, sv)
  2287  		proc := testutil.NewProcess()
  2288  
  2289  		st := tree.NewPrepareString(tree.Identifier(getPrepareStmtName(1)), "select ?, 1")
  2290  		stmts, err := mysql.Parse(ctx, st.Sql, 1)
  2291  		if err != nil {
  2292  			t.Error(err)
  2293  		}
  2294  		compCtx := plan.NewEmptyCompilerContext()
  2295  		preparePlan, err := buildPlan(context.TODO(), nil, compCtx, st)
  2296  		if err != nil {
  2297  			t.Error(err)
  2298  		}
  2299  		prepareStmt := &PrepareStmt{
  2300  			Name:        preparePlan.GetDcl().GetPrepare().GetName(),
  2301  			PreparePlan: preparePlan,
  2302  			PrepareStmt: stmts[0],
  2303  			params:      vector.NewVec(types.T_varchar.ToType()),
  2304  		}
  2305  
  2306  		var testData []byte
  2307  		testData = append(testData, 0)          //flag
  2308  		testData = append(testData, 0, 0, 0, 0) // skip iteration-count
  2309  		nullBitmapLen := (1 + 7) >> 3
  2310  		//nullBitmapLen
  2311  		for i := 0; i < nullBitmapLen; i++ {
  2312  			testData = append(testData, 0)
  2313  		}
  2314  		testData = append(testData, 1)                              // new param bound flag
  2315  		testData = append(testData, uint8(defines.MYSQL_TYPE_TINY)) // type
  2316  		testData = append(testData, 0)                              //is unsigned
  2317  		testData = append(testData, 10)                             //tiny value
  2318  
  2319  		err = proto.ParseExecuteData(ctx, proc, prepareStmt, testData, 0)
  2320  		convey.So(err, convey.ShouldBeNil)
  2321  	})
  2322  
  2323  }
  2324  */
  2325  
  2326  func Test_resultset(t *testing.T) {
  2327  	ctx := context.TODO()
  2328  	convey.Convey("send result set batch row succ", t, func() {
  2329  		ctrl := gomock.NewController(t)
  2330  		defer ctrl.Finish()
  2331  		ioses := mock_frontend.NewMockIOSession(ctrl)
  2332  
  2333  		ioses.EXPECT().OutBuf().Return(goetty_buf.NewByteBuf(1024)).AnyTimes()
  2334  		ioses.EXPECT().Write(gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
  2335  		ioses.EXPECT().RemoteAddress().Return("").AnyTimes()
  2336  		ioses.EXPECT().Ref().AnyTimes()
  2337  		ioses.EXPECT().Flush(gomock.Any()).AnyTimes()
  2338  		sv, err := getSystemVariables("test/system_vars_config.toml")
  2339  		if err != nil {
  2340  			t.Error(err)
  2341  		}
  2342  
  2343  		proto := NewMysqlClientProtocol(0, ioses, 1024, sv)
  2344  		eng := mock_frontend.NewMockEngine(ctrl)
  2345  		txnClient := mock_frontend.NewMockTxnClient(ctrl)
  2346  		pu, err := getParameterUnit("test/system_vars_config.toml", eng, txnClient)
  2347  		if err != nil {
  2348  			t.Error(err)
  2349  		}
  2350  		setGlobalPu(pu)
  2351  		var gSys GlobalSystemVariables
  2352  		InitGlobalSystemVariables(&gSys)
  2353  		ses := NewSession(ctx, proto, nil, &gSys, true, nil)
  2354  		proto.ses = ses
  2355  
  2356  		res := make9ColumnsResultSet()
  2357  
  2358  		err = proto.SendResultSetTextBatchRow(res, uint64(len(res.Data)))
  2359  		convey.So(err, convey.ShouldBeNil)
  2360  	})
  2361  
  2362  	convey.Convey("send result set batch row speedup succ", t, func() {
  2363  		ctrl := gomock.NewController(t)
  2364  		defer ctrl.Finish()
  2365  		ioses := mock_frontend.NewMockIOSession(ctrl)
  2366  
  2367  		ioses.EXPECT().OutBuf().Return(goetty_buf.NewByteBuf(1024)).AnyTimes()
  2368  		ioses.EXPECT().Write(gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
  2369  		ioses.EXPECT().RemoteAddress().Return("").AnyTimes()
  2370  		ioses.EXPECT().Ref().AnyTimes()
  2371  		ioses.EXPECT().Flush(gomock.Any()).AnyTimes()
  2372  		sv, err := getSystemVariables("test/system_vars_config.toml")
  2373  		if err != nil {
  2374  			t.Error(err)
  2375  		}
  2376  
  2377  		proto := NewMysqlClientProtocol(0, ioses, 1024, sv)
  2378  		eng := mock_frontend.NewMockEngine(ctrl)
  2379  		txnClient := mock_frontend.NewMockTxnClient(ctrl)
  2380  		pu, err := getParameterUnit("test/system_vars_config.toml", eng, txnClient)
  2381  		if err != nil {
  2382  			t.Error(err)
  2383  		}
  2384  		setGlobalPu(pu)
  2385  		var gSys GlobalSystemVariables
  2386  		InitGlobalSystemVariables(&gSys)
  2387  		ses := NewSession(ctx, proto, nil, &gSys, true, nil)
  2388  		proto.ses = ses
  2389  
  2390  		res := make9ColumnsResultSet()
  2391  
  2392  		err = proto.SendResultSetTextBatchRowSpeedup(res, uint64(len(res.Data)))
  2393  		convey.So(err, convey.ShouldBeNil)
  2394  	})
  2395  
  2396  	convey.Convey("send result set succ", t, func() {
  2397  		ctrl := gomock.NewController(t)
  2398  		defer ctrl.Finish()
  2399  		ioses := mock_frontend.NewMockIOSession(ctrl)
  2400  
  2401  		ioses.EXPECT().OutBuf().Return(goetty_buf.NewByteBuf(1024)).AnyTimes()
  2402  		ioses.EXPECT().Write(gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
  2403  		ioses.EXPECT().RemoteAddress().Return("").AnyTimes()
  2404  		ioses.EXPECT().Ref().AnyTimes()
  2405  		ioses.EXPECT().Flush(gomock.Any()).AnyTimes()
  2406  		sv, err := getSystemVariables("test/system_vars_config.toml")
  2407  		if err != nil {
  2408  			t.Error(err)
  2409  		}
  2410  
  2411  		proto := NewMysqlClientProtocol(0, ioses, 1024, sv)
  2412  		eng := mock_frontend.NewMockEngine(ctrl)
  2413  		txnClient := mock_frontend.NewMockTxnClient(ctrl)
  2414  		pu, err := getParameterUnit("test/system_vars_config.toml", eng, txnClient)
  2415  		if err != nil {
  2416  			t.Error(err)
  2417  		}
  2418  		setGlobalPu(pu)
  2419  		var gSys GlobalSystemVariables
  2420  		InitGlobalSystemVariables(&gSys)
  2421  		ses := NewSession(ctx, proto, nil, &gSys, true, nil)
  2422  		proto.ses = ses
  2423  
  2424  		res := make9ColumnsResultSet()
  2425  
  2426  		err = proto.sendResultSet(ctx, res, int(COM_QUERY), 0, 0)
  2427  		convey.So(err, convey.ShouldBeNil)
  2428  
  2429  		err = proto.SendResultSetTextRow(res, 0)
  2430  		convey.So(err, convey.ShouldBeNil)
  2431  	})
  2432  
  2433  	convey.Convey("send binary result set succ", t, func() {
  2434  		ctrl := gomock.NewController(t)
  2435  		defer ctrl.Finish()
  2436  		ioses := mock_frontend.NewMockIOSession(ctrl)
  2437  
  2438  		ioses.EXPECT().OutBuf().Return(goetty_buf.NewByteBuf(1024)).AnyTimes()
  2439  		ioses.EXPECT().Write(gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
  2440  		ioses.EXPECT().RemoteAddress().Return("").AnyTimes()
  2441  		ioses.EXPECT().Ref().AnyTimes()
  2442  		ioses.EXPECT().Flush(gomock.Any()).AnyTimes()
  2443  		sv, err := getSystemVariables("test/system_vars_config.toml")
  2444  		if err != nil {
  2445  			t.Error(err)
  2446  		}
  2447  
  2448  		proto := NewMysqlClientProtocol(0, ioses, 1024, sv)
  2449  		eng := mock_frontend.NewMockEngine(ctrl)
  2450  		txnClient := mock_frontend.NewMockTxnClient(ctrl)
  2451  		pu, err := getParameterUnit("test/system_vars_config.toml", eng, txnClient)
  2452  		if err != nil {
  2453  			t.Error(err)
  2454  		}
  2455  		setGlobalPu(pu)
  2456  		var gSys GlobalSystemVariables
  2457  		InitGlobalSystemVariables(&gSys)
  2458  		ses := NewSession(ctx, proto, nil, &gSys, true, nil)
  2459  		ses.cmd = COM_STMT_EXECUTE
  2460  		proto.ses = ses
  2461  
  2462  		res := make9ColumnsResultSet()
  2463  
  2464  		err = proto.SendResultSetTextBatchRowSpeedup(res, 0)
  2465  		convey.So(err, convey.ShouldBeNil)
  2466  	})
  2467  }
  2468  
  2469  func Test_send_packet(t *testing.T) {
  2470  	convey.Convey("send err packet", t, func() {
  2471  		ctrl := gomock.NewController(t)
  2472  		defer ctrl.Finish()
  2473  		ioses := mock_frontend.NewMockIOSession(ctrl)
  2474  
  2475  		ioses.EXPECT().OutBuf().Return(goetty_buf.NewByteBuf(1024)).AnyTimes()
  2476  		ioses.EXPECT().Write(gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
  2477  		ioses.EXPECT().RemoteAddress().Return("").AnyTimes()
  2478  		ioses.EXPECT().Ref().AnyTimes()
  2479  		ioses.EXPECT().Flush(gomock.Any()).AnyTimes()
  2480  		sv, err := getSystemVariables("test/system_vars_config.toml")
  2481  		if err != nil {
  2482  			t.Error(err)
  2483  		}
  2484  
  2485  		proto := NewMysqlClientProtocol(0, ioses, 1024, sv)
  2486  
  2487  		err = proto.sendErrPacket(1, "fake state", "fake error")
  2488  		convey.So(err, convey.ShouldBeNil)
  2489  	})
  2490  	convey.Convey("send eof packet", t, func() {
  2491  		ctrl := gomock.NewController(t)
  2492  		defer ctrl.Finish()
  2493  		ioses := mock_frontend.NewMockIOSession(ctrl)
  2494  
  2495  		ioses.EXPECT().OutBuf().Return(goetty_buf.NewByteBuf(1024)).AnyTimes()
  2496  		ioses.EXPECT().Write(gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
  2497  		ioses.EXPECT().RemoteAddress().Return("").AnyTimes()
  2498  		ioses.EXPECT().Ref().AnyTimes()
  2499  		ioses.EXPECT().Flush(gomock.Any()).AnyTimes()
  2500  		sv, err := getSystemVariables("test/system_vars_config.toml")
  2501  		if err != nil {
  2502  			t.Error(err)
  2503  		}
  2504  
  2505  		proto := NewMysqlClientProtocol(0, ioses, 1024, sv)
  2506  
  2507  		err = proto.sendEOFPacket(1, 0)
  2508  		convey.So(err, convey.ShouldBeNil)
  2509  
  2510  		err = proto.SendEOFPacketIf(1, 0)
  2511  		convey.So(err, convey.ShouldBeNil)
  2512  
  2513  		err = proto.sendEOFOrOkPacket(1, 0)
  2514  		convey.So(err, convey.ShouldBeNil)
  2515  	})
  2516  }
  2517  
  2518  func Test_analyse320resp(t *testing.T) {
  2519  	convey.Convey("analyse 320 resp succ", t, func() {
  2520  		ctrl := gomock.NewController(t)
  2521  		defer ctrl.Finish()
  2522  		ioses := mock_frontend.NewMockIOSession(ctrl)
  2523  		ioses.EXPECT().RemoteAddress().Return("").AnyTimes()
  2524  		ioses.EXPECT().Ref().AnyTimes()
  2525  		ioses.EXPECT().Flush(gomock.Any()).AnyTimes()
  2526  		sv, err := getSystemVariables("test/system_vars_config.toml")
  2527  		if err != nil {
  2528  			t.Error(err)
  2529  		}
  2530  
  2531  		proto := NewMysqlClientProtocol(0, ioses, 1024, sv)
  2532  
  2533  		var data []byte = nil
  2534  		var cap uint16 = 0
  2535  		cap |= uint16(CLIENT_CONNECT_WITH_DB)
  2536  		var header [2]byte
  2537  		proto.io.WriteUint16(header[:], 0, cap)
  2538  		//int<2>             capabilities flags, CLIENT_PROTOCOL_41 never set
  2539  		data = append(data, header[:]...)
  2540  		//int<3>             max-packet size
  2541  		data = append(data, 0xff, 0xff, 0xff)
  2542  		//string[NUL]        username
  2543  		username := "abc"
  2544  		data = append(data, []byte(username)...)
  2545  		data = append(data, 0x0)
  2546  		//auth response
  2547  		authResp := []byte{0x1, 0x2, 0x3, 0x4}
  2548  		data = append(data, authResp...)
  2549  		data = append(data, 0x0)
  2550  		//database
  2551  		dbName := "T"
  2552  		data = append(data, []byte(dbName)...)
  2553  		data = append(data, 0x0)
  2554  
  2555  		ok, resp320, err := proto.analyseHandshakeResponse320(context.TODO(), data)
  2556  		convey.So(err, convey.ShouldBeNil)
  2557  		convey.So(ok, convey.ShouldBeTrue)
  2558  
  2559  		convey.So(resp320.username, convey.ShouldEqual, username)
  2560  		convey.So(bytes.Equal(resp320.authResponse, authResp), convey.ShouldBeTrue)
  2561  		convey.So(resp320.database, convey.ShouldEqual, dbName)
  2562  	})
  2563  
  2564  	convey.Convey("analyse 320 resp failed", t, func() {
  2565  		ctrl := gomock.NewController(t)
  2566  		defer ctrl.Finish()
  2567  		ioses := mock_frontend.NewMockIOSession(ctrl)
  2568  		ioses.EXPECT().RemoteAddress().Return("").AnyTimes()
  2569  		ioses.EXPECT().Ref().AnyTimes()
  2570  		ioses.EXPECT().Flush(gomock.Any()).AnyTimes()
  2571  		sv, err := getSystemVariables("test/system_vars_config.toml")
  2572  		if err != nil {
  2573  			t.Error(err)
  2574  		}
  2575  
  2576  		proto := NewMysqlClientProtocol(0, ioses, 1024, sv)
  2577  
  2578  		type kase struct {
  2579  			data []byte
  2580  			res  bool
  2581  		}
  2582  
  2583  		kases := []kase{
  2584  			{data: []byte{0}, res: false},
  2585  			{data: []byte{0, 0, 0, 0}, res: false},
  2586  			{data: []byte{0, 0, 1, 2, 3}, res: false},
  2587  			{data: []byte{0, 0, 1, 2, 3, 'a', 0}, res: true},
  2588  			{data: []byte{0, 0, 1, 2, 3, 'a', 0, 1, 2, 3}, res: true},
  2589  			{data: []byte{uint8(CLIENT_CONNECT_WITH_DB), 0, 1, 2, 3, 'a', 0}, res: false},
  2590  			{data: []byte{uint8(CLIENT_CONNECT_WITH_DB), 0, 1, 2, 3, 'a', 0, 'b', 'c'}, res: false},
  2591  			{data: []byte{uint8(CLIENT_CONNECT_WITH_DB), 0, 1, 2, 3, 'a', 0, 'b', 'c', 0}, res: false},
  2592  			{data: []byte{uint8(CLIENT_CONNECT_WITH_DB), 0, 1, 2, 3, 'a', 0, 'b', 'c', 0, 'd', 'e'}, res: false},
  2593  			{data: []byte{uint8(CLIENT_CONNECT_WITH_DB), 0, 1, 2, 3, 'a', 0, 'b', 'c', 0, 'd', 'e', 0}, res: true},
  2594  		}
  2595  
  2596  		for _, c := range kases {
  2597  			ok, _, _ := proto.analyseHandshakeResponse320(context.TODO(), c.data)
  2598  			convey.So(ok, convey.ShouldEqual, c.res)
  2599  		}
  2600  	})
  2601  }
  2602  
  2603  func Test_analyse41resp(t *testing.T) {
  2604  	convey.Convey("analyse 41 resp succ", t, func() {
  2605  		ctrl := gomock.NewController(t)
  2606  		defer ctrl.Finish()
  2607  		ioses := mock_frontend.NewMockIOSession(ctrl)
  2608  		ioses.EXPECT().RemoteAddress().Return("").AnyTimes()
  2609  		ioses.EXPECT().Ref().AnyTimes()
  2610  		ioses.EXPECT().Flush(gomock.Any()).AnyTimes()
  2611  		sv, err := getSystemVariables("test/system_vars_config.toml")
  2612  		if err != nil {
  2613  			t.Error(err)
  2614  		}
  2615  
  2616  		proto := NewMysqlClientProtocol(0, ioses, 1024, sv)
  2617  
  2618  		var data []byte = nil
  2619  		var cap uint32 = 0
  2620  		cap |= CLIENT_PROTOCOL_41 | CLIENT_CONNECT_WITH_DB
  2621  		var header [4]byte
  2622  		proto.io.WriteUint32(header[:], 0, cap)
  2623  		//int<4>             capabilities flags of the client, CLIENT_PROTOCOL_41 always set
  2624  		data = append(data, header[:]...)
  2625  		//int<4>             max-packet size
  2626  		data = append(data, 0xff, 0xff, 0xff, 0xff)
  2627  		//int<1>             character set
  2628  		data = append(data, 0x1)
  2629  		//string[23]         reserved (all [0])
  2630  		data = append(data, make([]byte, 23)...)
  2631  		//string[NUL]        username
  2632  		username := "abc"
  2633  		data = append(data, []byte(username)...)
  2634  		data = append(data, 0x0)
  2635  		//auth response
  2636  		authResp := []byte{0x1, 0x2, 0x3, 0x4}
  2637  		data = append(data, authResp...)
  2638  		data = append(data, 0x0)
  2639  		//database
  2640  		dbName := "T"
  2641  		data = append(data, []byte(dbName)...)
  2642  		data = append(data, 0x0)
  2643  
  2644  		ok, resp41, err := proto.analyseHandshakeResponse41(context.TODO(), data)
  2645  		convey.So(err, convey.ShouldBeNil)
  2646  		convey.So(ok, convey.ShouldBeTrue)
  2647  
  2648  		convey.So(resp41.username, convey.ShouldEqual, username)
  2649  		convey.So(bytes.Equal(resp41.authResponse, authResp), convey.ShouldBeTrue)
  2650  		convey.So(resp41.database, convey.ShouldEqual, dbName)
  2651  	})
  2652  
  2653  	convey.Convey("analyse 41 resp failed", t, func() {
  2654  		ctrl := gomock.NewController(t)
  2655  		defer ctrl.Finish()
  2656  		ioses := mock_frontend.NewMockIOSession(ctrl)
  2657  		ioses.EXPECT().Write(gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
  2658  		ioses.EXPECT().Read(gomock.Any()).Return(new(Packet), nil).AnyTimes()
  2659  		ioses.EXPECT().RemoteAddress().Return("").AnyTimes()
  2660  		ioses.EXPECT().Ref().AnyTimes()
  2661  		ioses.EXPECT().Flush(gomock.Any()).AnyTimes()
  2662  		sv, err := getSystemVariables("test/system_vars_config.toml")
  2663  		if err != nil {
  2664  			t.Error(err)
  2665  		}
  2666  
  2667  		proto := NewMysqlClientProtocol(0, ioses, 1024, sv)
  2668  
  2669  		type kase struct {
  2670  			data []byte
  2671  			res  bool
  2672  		}
  2673  
  2674  		var cap uint32 = 0
  2675  		cap |= CLIENT_PROTOCOL_41 | CLIENT_CONNECT_WITH_DB | CLIENT_PLUGIN_AUTH
  2676  		var header [4]byte
  2677  		proto.io.WriteUint32(header[:], 0, cap)
  2678  
  2679  		kases := []kase{
  2680  			{data: []byte{0}, res: false},
  2681  			{data: []byte{0, 0, 0, 0}, res: false},
  2682  			{data: append(header[:], []byte{
  2683  				0, 0, 0,
  2684  			}...), res: false},
  2685  			{data: append(header[:], []byte{
  2686  				0, 0, 0, 0,
  2687  			}...), res: false},
  2688  			{data: append(header[:], []byte{
  2689  				0, 0, 0, 0,
  2690  				0,
  2691  				0, 0, 0,
  2692  			}...), res: false},
  2693  			{data: append(header[:], []byte{
  2694  				0, 0, 0, 0,
  2695  				0,
  2696  				0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  2697  			}...), res: false},
  2698  			{data: append(header[:], []byte{
  2699  				0, 0, 0, 0,
  2700  				0,
  2701  				0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  2702  				'a', 'b', 'c',
  2703  			}...), res: false},
  2704  			{data: append(header[:], []byte{
  2705  				0, 0, 0, 0,
  2706  				0,
  2707  				0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  2708  				'a', 'b', 'c', 0,
  2709  				'd', 'e', 'f',
  2710  			}...), res: false},
  2711  			{data: append(header[:], []byte{
  2712  				0, 0, 0, 0,
  2713  				0,
  2714  				0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  2715  				'a', 'b', 'c', 0,
  2716  				'd', 'e', 'f', 0,
  2717  				'T',
  2718  			}...), res: false},
  2719  			{data: append(header[:], []byte{
  2720  				0, 0, 0, 0,
  2721  				0,
  2722  				0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  2723  				'a', 'b', 'c', 0,
  2724  				'd', 'e', 'f', 0,
  2725  				'T', 0,
  2726  				'm', 'y', 's',
  2727  			}...), res: false},
  2728  			{data: append(header[:], []byte{
  2729  				0, 0, 0, 0,
  2730  				0,
  2731  				0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  2732  				'a', 'b', 'c', 0,
  2733  				'd', 'e', 'f', 0,
  2734  				'T', 0,
  2735  				'm', 'y', 's', 'q', 'l', '_', 'n', 'a', 't', 'i', 'v', 'e', '_', 'p', 'a', 's', 's', 'w', 'o', 'r', 'x', 0,
  2736  			}...), res: true},
  2737  			{data: append(header[:], []byte{
  2738  				0, 0, 0, 0,
  2739  				0,
  2740  				0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  2741  				'a', 'b', 'c', 0,
  2742  				'd', 'e', 'f', 0,
  2743  				'T', 0,
  2744  				'm', 'y', 's', 'q', 'l', '_', 'n', 'a', 't', 'i', 'v', 'e', '_', 'p', 'a', 's', 's', 'w', 'o', 'r', 'd', 0,
  2745  			}...), res: true},
  2746  		}
  2747  
  2748  		for _, c := range kases {
  2749  			ok, _, _ := proto.analyseHandshakeResponse41(context.TODO(), c.data)
  2750  			convey.So(ok, convey.ShouldEqual, c.res)
  2751  		}
  2752  	})
  2753  }
  2754  
  2755  func Test_handleHandshake(t *testing.T) {
  2756  	ctx := context.TODO()
  2757  	convey.Convey("handleHandshake succ", t, func() {
  2758  		ctrl := gomock.NewController(t)
  2759  		defer ctrl.Finish()
  2760  		ioses := mock_frontend.NewMockIOSession(ctrl)
  2761  		ioses.EXPECT().Write(gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
  2762  		ioses.EXPECT().RemoteAddress().Return("").AnyTimes()
  2763  		ioses.EXPECT().Ref().AnyTimes()
  2764  		ioses.EXPECT().Flush(gomock.Any()).AnyTimes()
  2765  		var IO IOPackageImpl
  2766  		var SV = &config.FrontendParameters{}
  2767  		SV.SkipCheckUser = true
  2768  		mp := &MysqlProtocolImpl{SV: SV}
  2769  		mp.io = &IO
  2770  		mp.tcpConn = ioses
  2771  		payload := []byte{'a'}
  2772  		_, err := mp.HandleHandshake(ctx, payload)
  2773  		convey.So(err, convey.ShouldNotBeNil)
  2774  
  2775  		payload = append(payload, []byte{'b', 'c'}...)
  2776  		_, err = mp.HandleHandshake(ctx, payload)
  2777  		convey.So(err, convey.ShouldNotBeNil)
  2778  
  2779  		payload = append(payload, []byte{'c', 'd', 0}...)
  2780  		_, err = mp.HandleHandshake(ctx, payload)
  2781  		convey.So(err, convey.ShouldBeNil)
  2782  	})
  2783  }
  2784  
  2785  func Test_handleHandshake_Recover(t *testing.T) {
  2786  	f := fuzz.New()
  2787  	count := 10000
  2788  	maxLen := 0
  2789  
  2790  	ctx := context.TODO()
  2791  	ctrl := gomock.NewController(t)
  2792  	defer ctrl.Finish()
  2793  	ioses := mock_frontend.NewMockIOSession(ctrl)
  2794  	ioses.EXPECT().Write(gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
  2795  	ioses.EXPECT().RemoteAddress().Return("").AnyTimes()
  2796  	ioses.EXPECT().Ref().AnyTimes()
  2797  	ioses.EXPECT().Flush(gomock.Any()).AnyTimes()
  2798  	convey.Convey("handleHandshake succ", t, func() {
  2799  		var IO IOPackageImpl
  2800  		var SV = &config.FrontendParameters{}
  2801  		SV.SkipCheckUser = true
  2802  		mp := &MysqlProtocolImpl{SV: SV}
  2803  		mp.io = &IO
  2804  		mp.tcpConn = ioses
  2805  		var payload []byte
  2806  		for i := 0; i < count; i++ {
  2807  			f.Fuzz(&payload)
  2808  			_, _ = mp.HandleHandshake(ctx, payload)
  2809  			maxLen = Max(maxLen, len(payload))
  2810  		}
  2811  		maxLen = 0
  2812  		var payload2 string
  2813  		for i := 0; i < count; i++ {
  2814  			f.Fuzz(&payload2)
  2815  			_, _ = mp.HandleHandshake(ctx, []byte(payload2))
  2816  			maxLen = Max(maxLen, len(payload2))
  2817  		}
  2818  	})
  2819  }
  2820  
  2821  func TestMysqlProtocolImpl_Close(t *testing.T) {
  2822  	ctrl := gomock.NewController(t)
  2823  	defer ctrl.Finish()
  2824  	ioses := mock_frontend.NewMockIOSession(ctrl)
  2825  	ioses.EXPECT().Write(gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
  2826  	ioses.EXPECT().Read(gomock.Any()).Return(new(Packet), nil).AnyTimes()
  2827  	ioses.EXPECT().RemoteAddress().Return("").AnyTimes()
  2828  	ioses.EXPECT().Ref().AnyTimes()
  2829  	ioses.EXPECT().Flush(gomock.Any()).AnyTimes()
  2830  	ioses.EXPECT().Disconnect().AnyTimes()
  2831  	sv, err := getSystemVariables("test/system_vars_config.toml")
  2832  	if err != nil {
  2833  		t.Error(err)
  2834  	}
  2835  
  2836  	proto := NewMysqlClientProtocol(0, ioses, 1024, sv)
  2837  	proto.Quit()
  2838  	assert.Nil(t, proto.GetSalt())
  2839  	assert.Nil(t, proto.strconvBuffer)
  2840  	assert.Nil(t, proto.lenEncBuffer)
  2841  	assert.Nil(t, proto.binaryNullBuffer)
  2842  }