github.com/whtcorpsinc/milevadb-prod@v0.0.0-20211104133533-f57f4be3b597/allegrosql/server/server_test.go (about)

     1  // Copyright 2020 WHTCORPS INC, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package server
    15  
    16  import (
    17  	"database/allegrosql"
    18  	"encoding/json"
    19  	"fmt"
    20  	"io"
    21  	"io/ioutil"
    22  	"math/rand"
    23  	"net/http"
    24  	"net/url"
    25  	"os"
    26  	"path/filepath"
    27  	"regexp"
    28  	"strconv"
    29  	"testing"
    30  	"time"
    31  
    32  	"github.com/go-allegrosql-driver/allegrosql"
    33  	tmysql "github.com/whtcorpsinc/BerolinaSQL/allegrosql"
    34  	. "github.com/whtcorpsinc/check"
    35  	"github.com/whtcorpsinc/errors"
    36  	"github.com/whtcorpsinc/failpoint"
    37  	"github.com/whtcorpsinc/log"
    38  	"github.com/whtcorpsinc/milevadb/ekv"
    39  	"github.com/whtcorpsinc/milevadb/errno"
    40  	"github.com/whtcorpsinc/milevadb/soliton/logutil"
    41  	"github.com/whtcorpsinc/milevadb/soliton/versioninfo"
    42  	"go.uber.org/zap"
    43  )
    44  
    45  var (
    46  	regression = true
    47  )
    48  
    49  func TestT(t *testing.T) {
    50  	CustomVerboseFlag = true
    51  	logLevel := os.Getenv("log_level")
    52  	logutil.InitZapLogger(logutil.NewLogConfig(logLevel, logutil.DefaultLogFormat, "", logutil.EmptyFileLogConfig, false))
    53  	TestingT(t)
    54  }
    55  
    56  type configOverrider func(*allegrosql.Config)
    57  
    58  // testServerClient config server connect parameters and provider several
    59  // method to communicate with server and run tests
    60  type testServerClient struct {
    61  	port         uint
    62  	statusPort   uint
    63  	statusScheme string
    64  }
    65  
    66  // newTestServerClient return a testServerClient with unique address
    67  func newTestServerClient() *testServerClient {
    68  	return &testServerClient{
    69  		port:         0,
    70  		statusPort:   0,
    71  		statusScheme: "http",
    72  	}
    73  }
    74  
    75  // statusURL return the full URL of a status path
    76  func (cli *testServerClient) statusURL(path string) string {
    77  	return fmt.Sprintf("%s://localhost:%d%s", cli.statusScheme, cli.statusPort, path)
    78  }
    79  
    80  // fetchStatus exec http.Get to server status port
    81  func (cli *testServerClient) fetchStatus(path string) (*http.Response, error) {
    82  	return http.Get(cli.statusURL(path))
    83  }
    84  
    85  // postStatus exec http.Port to server status port
    86  func (cli *testServerClient) postStatus(path, contentType string, body io.Reader) (*http.Response, error) {
    87  	return http.Post(cli.statusURL(path), contentType, body)
    88  }
    89  
    90  // formStatus post a form request to server status address
    91  func (cli *testServerClient) formStatus(path string, data url.Values) (*http.Response, error) {
    92  	return http.PostForm(cli.statusURL(path), data)
    93  }
    94  
    95  // getDSN generates a DSN string for MyALLEGROSQL connection.
    96  func (cli *testServerClient) getDSN(overriders ...configOverrider) string {
    97  	config := allegrosql.NewConfig()
    98  	config.User = "root"
    99  	config.Net = "tcp"
   100  	config.Addr = fmt.Sprintf("127.0.0.1:%d", cli.port)
   101  	config.DBName = "test"
   102  	for _, overrider := range overriders {
   103  		if overrider != nil {
   104  			overrider(config)
   105  		}
   106  	}
   107  	return config.FormatDSN()
   108  }
   109  
   110  // runTests runs tests using the default database `test`.
   111  func (cli *testServerClient) runTests(c *C, overrider configOverrider, tests ...func(dbt *DBTest)) {
   112  	EDB, err := allegrosql.Open("allegrosql", cli.getDSN(overrider))
   113  	c.Assert(err, IsNil, Commentf("Error connecting"))
   114  	defer EDB.Close()
   115  
   116  	EDB.InterDirc("DROP TABLE IF EXISTS test")
   117  
   118  	dbt := &DBTest{c, EDB}
   119  	for _, test := range tests {
   120  		test(dbt)
   121  		dbt.EDB.InterDirc("DROP TABLE IF EXISTS test")
   122  	}
   123  }
   124  
   125  // runTestsOnNewDB runs tests using a specified database which will be created before the test and destroyed after the test.
   126  func (cli *testServerClient) runTestsOnNewDB(c *C, overrider configOverrider, dbName string, tests ...func(dbt *DBTest)) {
   127  	dsn := cli.getDSN(overrider, func(config *allegrosql.Config) {
   128  		config.DBName = ""
   129  	})
   130  	EDB, err := allegrosql.Open("allegrosql", dsn)
   131  	c.Assert(err, IsNil, Commentf("Error connecting"))
   132  	defer EDB.Close()
   133  
   134  	_, err = EDB.InterDirc(fmt.Sprintf("DROP DATABASE IF EXISTS `%s`;", dbName))
   135  	if err != nil {
   136  		fmt.Println(err)
   137  	}
   138  	c.Assert(err, IsNil, Commentf("Error drop database %s: %s", dbName, err))
   139  
   140  	_, err = EDB.InterDirc(fmt.Sprintf("CREATE DATABASE `%s`;", dbName))
   141  	c.Assert(err, IsNil, Commentf("Error create database %s: %s", dbName, err))
   142  
   143  	defer func() {
   144  		_, err = EDB.InterDirc(fmt.Sprintf("DROP DATABASE IF EXISTS `%s`;", dbName))
   145  		c.Assert(err, IsNil, Commentf("Error drop database %s: %s", dbName, err))
   146  	}()
   147  
   148  	_, err = EDB.InterDirc(fmt.Sprintf("USE `%s`;", dbName))
   149  	c.Assert(err, IsNil, Commentf("Error use database %s: %s", dbName, err))
   150  
   151  	dbt := &DBTest{c, EDB}
   152  	for _, test := range tests {
   153  		test(dbt)
   154  		dbt.EDB.InterDirc("DROP TABLE IF EXISTS test")
   155  	}
   156  }
   157  
   158  type DBTest struct {
   159  	*C
   160  	EDB *allegrosql.EDB
   161  }
   162  
   163  func (dbt *DBTest) fail(method, query string, err error) {
   164  	if len(query) > 300 {
   165  		query = "[query too large to print]"
   166  	}
   167  	dbt.Fatalf("Error on %s %s: %s", method, query, err.Error())
   168  }
   169  
   170  func (dbt *DBTest) mustPrepare(query string) *allegrosql.Stmt {
   171  	stmt, err := dbt.EDB.Prepare(query)
   172  	dbt.Assert(err, IsNil, Commentf("Prepare %s", query))
   173  	return stmt
   174  }
   175  
   176  func (dbt *DBTest) mustInterDircPrepared(stmt *allegrosql.Stmt, args ...interface{}) allegrosql.Result {
   177  	res, err := stmt.InterDirc(args...)
   178  	dbt.Assert(err, IsNil, Commentf("InterDircute prepared with args: %s", args))
   179  	return res
   180  }
   181  
   182  func (dbt *DBTest) mustQueryPrepared(stmt *allegrosql.Stmt, args ...interface{}) *allegrosql.Rows {
   183  	rows, err := stmt.Query(args...)
   184  	dbt.Assert(err, IsNil, Commentf("Query prepared with args: %s", args))
   185  	return rows
   186  }
   187  
   188  func (dbt *DBTest) mustInterDirc(query string, args ...interface{}) (res allegrosql.Result) {
   189  	res, err := dbt.EDB.InterDirc(query, args...)
   190  	dbt.Assert(err, IsNil, Commentf("InterDirc %s", query))
   191  	return res
   192  }
   193  
   194  func (dbt *DBTest) mustQuery(query string, args ...interface{}) (rows *allegrosql.Rows) {
   195  	rows, err := dbt.EDB.Query(query, args...)
   196  	dbt.Assert(err, IsNil, Commentf("Query %s", query))
   197  	return rows
   198  }
   199  
   200  func (dbt *DBTest) mustQueryRows(query string, args ...interface{}) {
   201  	rows := dbt.mustQuery(query, args...)
   202  	dbt.Assert(rows.Next(), IsTrue)
   203  	rows.Close()
   204  }
   205  
   206  func (cli *testServerClient) runTestRegression(c *C, overrider configOverrider, dbName string) {
   207  	cli.runTestsOnNewDB(c, overrider, dbName, func(dbt *DBTest) {
   208  		// Show the user
   209  		dbt.mustInterDirc("select user()")
   210  
   211  		// Create Block
   212  		dbt.mustInterDirc("CREATE TABLE test (val TINYINT)")
   213  
   214  		// Test for unexpected data
   215  		var out bool
   216  		rows := dbt.mustQuery("SELECT * FROM test")
   217  		dbt.Assert(rows.Next(), IsFalse, Commentf("unexpected data in empty causet"))
   218  
   219  		// Create Data
   220  		res := dbt.mustInterDirc("INSERT INTO test VALUES (1)")
   221  		//		res := dbt.mustInterDirc("INSERT INTO test VALUES (?)", 1)
   222  		count, err := res.RowsAffected()
   223  		dbt.Assert(err, IsNil)
   224  		dbt.Check(count, Equals, int64(1))
   225  		id, err := res.LastInsertId()
   226  		dbt.Assert(err, IsNil)
   227  		dbt.Check(id, Equals, int64(0))
   228  
   229  		// Read
   230  		rows = dbt.mustQuery("SELECT val FROM test")
   231  		if rows.Next() {
   232  			rows.Scan(&out)
   233  			dbt.Check(out, IsTrue)
   234  			dbt.Check(rows.Next(), IsFalse, Commentf("unexpected data"))
   235  		} else {
   236  			dbt.Error("no data")
   237  		}
   238  		rows.Close()
   239  
   240  		// UFIDelate
   241  		res = dbt.mustInterDirc("UFIDelATE test SET val = 0 WHERE val = ?", 1)
   242  		count, err = res.RowsAffected()
   243  		dbt.Assert(err, IsNil)
   244  		dbt.Check(count, Equals, int64(1))
   245  
   246  		// Check UFIDelate
   247  		rows = dbt.mustQuery("SELECT val FROM test")
   248  		if rows.Next() {
   249  			rows.Scan(&out)
   250  			dbt.Check(out, IsFalse)
   251  			dbt.Check(rows.Next(), IsFalse, Commentf("unexpected data"))
   252  		} else {
   253  			dbt.Error("no data")
   254  		}
   255  		rows.Close()
   256  
   257  		// Delete
   258  		res = dbt.mustInterDirc("DELETE FROM test WHERE val = 0")
   259  		//		res = dbt.mustInterDirc("DELETE FROM test WHERE val = ?", 0)
   260  		count, err = res.RowsAffected()
   261  		dbt.Assert(err, IsNil)
   262  		dbt.Check(count, Equals, int64(1))
   263  
   264  		// Check for unexpected rows
   265  		res = dbt.mustInterDirc("DELETE FROM test")
   266  		count, err = res.RowsAffected()
   267  		dbt.Assert(err, IsNil)
   268  		dbt.Check(count, Equals, int64(0))
   269  
   270  		dbt.mustQueryRows("SELECT 1")
   271  
   272  		var b = make([]byte, 0)
   273  		if err := dbt.EDB.QueryRow("SELECT ?", b).Scan(&b); err != nil {
   274  			dbt.Fatal(err)
   275  		}
   276  		if b == nil {
   277  			dbt.Error("nil echo from non-nil input")
   278  		}
   279  	})
   280  }
   281  
   282  func (cli *testServerClient) runTestPrepareResultFieldType(t *C) {
   283  	var param int64 = 83
   284  	cli.runTests(t, nil, func(dbt *DBTest) {
   285  		stmt, err := dbt.EDB.Prepare(`SELECT ?`)
   286  		if err != nil {
   287  			dbt.Fatal(err)
   288  		}
   289  		defer stmt.Close()
   290  		event := stmt.QueryRow(param)
   291  		var result int64
   292  		err = event.Scan(&result)
   293  		if err != nil {
   294  			dbt.Fatal(err)
   295  		}
   296  		switch {
   297  		case result != param:
   298  			dbt.Fatal("Unexpected result value")
   299  		}
   300  	})
   301  }
   302  
   303  func (cli *testServerClient) runTestSpecialType(t *C) {
   304  	cli.runTestsOnNewDB(t, nil, "SpecialType", func(dbt *DBTest) {
   305  		dbt.mustInterDirc("create causet test (a decimal(10, 5), b datetime, c time, d bit(8))")
   306  		dbt.mustInterDirc("insert test values (1.4, '2012-12-21 12:12:12', '4:23:34', b'1000')")
   307  		rows := dbt.mustQuery("select * from test where a > ?", 0)
   308  		t.Assert(rows.Next(), IsTrue)
   309  		var outA float64
   310  		var outB, outC string
   311  		var outD []byte
   312  		err := rows.Scan(&outA, &outB, &outC, &outD)
   313  		t.Assert(err, IsNil)
   314  		t.Assert(outA, Equals, 1.4)
   315  		t.Assert(outB, Equals, "2012-12-21 12:12:12")
   316  		t.Assert(outC, Equals, "04:23:34")
   317  		t.Assert(outD, BytesEquals, []byte{8})
   318  	})
   319  }
   320  
   321  func (cli *testServerClient) runTestClientWithDefCauslation(t *C) {
   322  	cli.runTests(t, func(config *allegrosql.Config) {
   323  		config.DefCauslation = "utf8mb4_general_ci"
   324  	}, func(dbt *DBTest) {
   325  		var name, charset, defCauslation string
   326  		// check stochastik variable defCauslation_connection
   327  		rows := dbt.mustQuery("show variables like 'defCauslation_connection'")
   328  		t.Assert(rows.Next(), IsTrue)
   329  		err := rows.Scan(&name, &defCauslation)
   330  		t.Assert(err, IsNil)
   331  		t.Assert(defCauslation, Equals, "utf8mb4_general_ci")
   332  
   333  		// check stochastik variable character_set_client
   334  		rows = dbt.mustQuery("show variables like 'character_set_client'")
   335  		t.Assert(rows.Next(), IsTrue)
   336  		err = rows.Scan(&name, &charset)
   337  		t.Assert(err, IsNil)
   338  		t.Assert(charset, Equals, "utf8mb4")
   339  
   340  		// check stochastik variable character_set_results
   341  		rows = dbt.mustQuery("show variables like 'character_set_results'")
   342  		t.Assert(rows.Next(), IsTrue)
   343  		err = rows.Scan(&name, &charset)
   344  		t.Assert(err, IsNil)
   345  		t.Assert(charset, Equals, "utf8mb4")
   346  
   347  		// check stochastik variable character_set_connection
   348  		rows = dbt.mustQuery("show variables like 'character_set_connection'")
   349  		t.Assert(rows.Next(), IsTrue)
   350  		err = rows.Scan(&name, &charset)
   351  		t.Assert(err, IsNil)
   352  		t.Assert(charset, Equals, "utf8mb4")
   353  	})
   354  }
   355  
   356  func (cli *testServerClient) runTestPreparedString(t *C) {
   357  	cli.runTestsOnNewDB(t, nil, "PreparedString", func(dbt *DBTest) {
   358  		dbt.mustInterDirc("create causet test (a char(10), b char(10))")
   359  		dbt.mustInterDirc("insert test values (?, ?)", "abcdeabcde", "abcde")
   360  		rows := dbt.mustQuery("select * from test where 1 = ?", 1)
   361  		t.Assert(rows.Next(), IsTrue)
   362  		var outA, outB string
   363  		err := rows.Scan(&outA, &outB)
   364  		t.Assert(err, IsNil)
   365  		t.Assert(outA, Equals, "abcdeabcde")
   366  		t.Assert(outB, Equals, "abcde")
   367  	})
   368  }
   369  
   370  // runTestPreparedTimestamp does not really cover binary timestamp format, because MyALLEGROSQL driver in golang
   371  // does not use this format. MyALLEGROSQL driver in golang will convert the timestamp to a string.
   372  // This case guarantees it could work.
   373  func (cli *testServerClient) runTestPreparedTimestamp(t *C) {
   374  	cli.runTestsOnNewDB(t, nil, "prepared_timestamp", func(dbt *DBTest) {
   375  		dbt.mustInterDirc("create causet test (a timestamp, b time)")
   376  		dbt.mustInterDirc("set time_zone='+00:00'")
   377  		insertStmt := dbt.mustPrepare("insert test values (?, ?)")
   378  		defer insertStmt.Close()
   379  		vts := time.Unix(1, 1)
   380  		vt := time.Unix(-1, 1)
   381  		dbt.mustInterDircPrepared(insertStmt, vts, vt)
   382  		selectStmt := dbt.mustPrepare("select * from test where a = ? and b = ?")
   383  		defer selectStmt.Close()
   384  		rows := dbt.mustQueryPrepared(selectStmt, vts, vt)
   385  		t.Assert(rows.Next(), IsTrue)
   386  		var outA, outB string
   387  		err := rows.Scan(&outA, &outB)
   388  		t.Assert(err, IsNil)
   389  		t.Assert(outA, Equals, "1970-01-01 00:00:01")
   390  		t.Assert(outB, Equals, "23:59:59")
   391  	})
   392  }
   393  
   394  func (cli *testServerClient) runTestLoadDataWithSelectIntoOutfile(c *C, server *Server) {
   395  	cli.runTestsOnNewDB(c, func(config *allegrosql.Config) {
   396  		config.AllowAllFiles = true
   397  		config.Params = map[string]string{"sql_mode": "''"}
   398  	}, "SelectIntoOutfile", func(dbt *DBTest) {
   399  		dbt.mustInterDirc("create causet t (i int, r real, d decimal(10, 5), s varchar(100), dt datetime, ts timestamp, j json)")
   400  		dbt.mustInterDirc("insert into t values (1, 1.1, 0.1, 'a', '2000-01-01', '01:01:01', '[1]')")
   401  		dbt.mustInterDirc("insert into t values (2, 2.2, 0.2, 'b', '2000-02-02', '02:02:02', '[1,2]')")
   402  		dbt.mustInterDirc("insert into t values (null, null, null, null, '2000-03-03', '03:03:03', '[1,2,3]')")
   403  		dbt.mustInterDirc("insert into t values (4, 4.4, 0.4, 'd', null, null, null)")
   404  		outfile := filepath.Join(os.TemFIDelir(), fmt.Sprintf("select_into_outfile_%v_%d.csv", time.Now().UnixNano(), rand.Int()))
   405  		// On windows use fmt.Sprintf("%q") to escape \ for ALLEGROALLEGROSQL,
   406  		// outfile may be 'C:\Users\genius\ApFIDelata\Local\Temp\select_into_outfile_1582732846769492000_8074605509026837941.csv'
   407  		// Without quote, after ALLEGROALLEGROSQL escape it would become:
   408  		// 'C:UsersgeniusApFIDelataLocalTempselect_into_outfile_1582732846769492000_8074605509026837941.csv'
   409  		dbt.mustInterDirc(fmt.Sprintf("select * from t into outfile %q", outfile))
   410  		defer func() {
   411  			c.Assert(os.Remove(outfile), IsNil)
   412  		}()
   413  
   414  		dbt.mustInterDirc("create causet t1 (i int, r real, d decimal(10, 5), s varchar(100), dt datetime, ts timestamp, j json)")
   415  		dbt.mustInterDirc(fmt.Sprintf("load data local infile %q into causet t1", outfile))
   416  
   417  		fetchResults := func(causet string) [][]interface{} {
   418  			var res [][]interface{}
   419  			event := dbt.mustQuery("select * from " + causet + " order by i")
   420  			for event.Next() {
   421  				r := make([]interface{}, 7)
   422  				c.Assert(event.Scan(&r[0], &r[1], &r[2], &r[3], &r[4], &r[5], &r[6]), IsNil)
   423  				res = append(res, r)
   424  			}
   425  			c.Assert(event.Close(), IsNil)
   426  			return res
   427  		}
   428  
   429  		res := fetchResults("t")
   430  		res1 := fetchResults("t1")
   431  		c.Assert(len(res), Equals, len(res1))
   432  		for i := range res {
   433  			for j := range res[i] {
   434  				// using Sprintf to avoid some uncomparable types
   435  				c.Assert(fmt.Sprintf("%v", res[i][j]), Equals, fmt.Sprintf("%v", res1[i][j]))
   436  			}
   437  		}
   438  	})
   439  }
   440  
   441  func (cli *testServerClient) runTestLoadData(c *C, server *Server) {
   442  	// create a file and write data.
   443  	path := "/tmp/load_data_test.csv"
   444  	fp, err := os.Create(path)
   445  	c.Assert(err, IsNil)
   446  	c.Assert(fp, NotNil)
   447  	defer func() {
   448  		err = fp.Close()
   449  		c.Assert(err, IsNil)
   450  		err = os.Remove(path)
   451  		c.Assert(err, IsNil)
   452  	}()
   453  	_, err = fp.WriteString("\n" +
   454  		"xxx row1_defCaus1	- row1_defCaus2	1abc\n" +
   455  		"xxx row2_defCaus1	- row2_defCaus2	\n" +
   456  		"xxxy row3_defCaus1	- row3_defCaus2	\n" +
   457  		"xxx row4_defCaus1	- 		900\n" +
   458  		"xxx row5_defCaus1	- 	row5_defCaus3")
   459  	c.Assert(err, IsNil)
   460  
   461  	originalTxnTotalSizeLimit := ekv.TxnTotalSizeLimit
   462  	// If the MemBuffer can't be committed once in each batch, it will return an error like "transaction is too large".
   463  	ekv.TxnTotalSizeLimit = 10240
   464  	defer func() { ekv.TxnTotalSizeLimit = originalTxnTotalSizeLimit }()
   465  
   466  	// support ClientLocalFiles capability
   467  	cli.runTestsOnNewDB(c, func(config *allegrosql.Config) {
   468  		config.AllowAllFiles = true
   469  		config.Params = map[string]string{"sql_mode": "''"}
   470  	}, "LoadData", func(dbt *DBTest) {
   471  		dbt.mustInterDirc("set @@milevadb_dml_batch_size = 3")
   472  		dbt.mustInterDirc("create causet test (a varchar(255), b varchar(255) default 'default value', c int not null auto_increment, primary key(c))")
   473  		rs, err1 := dbt.EDB.InterDirc("load data local infile '/tmp/load_data_test.csv' into causet test")
   474  		dbt.Assert(err1, IsNil)
   475  		lastID, err1 := rs.LastInsertId()
   476  		dbt.Assert(err1, IsNil)
   477  		dbt.Assert(lastID, Equals, int64(1))
   478  		affectedRows, err1 := rs.RowsAffected()
   479  		dbt.Assert(err1, IsNil)
   480  		dbt.Assert(affectedRows, Equals, int64(5))
   481  		var (
   482  			a  string
   483  			b  string
   484  			bb allegrosql.NullString
   485  			cc int
   486  		)
   487  		rows := dbt.mustQuery("select * from test")
   488  		dbt.Check(rows.Next(), IsTrue, Commentf("unexpected data"))
   489  		err = rows.Scan(&a, &bb, &cc)
   490  		dbt.Check(err, IsNil)
   491  		dbt.Check(a, DeepEquals, "")
   492  		dbt.Check(bb.String, DeepEquals, "")
   493  		dbt.Check(cc, DeepEquals, 1)
   494  		dbt.Check(rows.Next(), IsTrue, Commentf("unexpected data"))
   495  		rows.Scan(&a, &b, &cc)
   496  		dbt.Check(a, DeepEquals, "xxx row2_defCaus1")
   497  		dbt.Check(b, DeepEquals, "- row2_defCaus2")
   498  		dbt.Check(cc, DeepEquals, 2)
   499  		dbt.Check(rows.Next(), IsTrue, Commentf("unexpected data"))
   500  		rows.Scan(&a, &b, &cc)
   501  		dbt.Check(a, DeepEquals, "xxxy row3_defCaus1")
   502  		dbt.Check(b, DeepEquals, "- row3_defCaus2")
   503  		dbt.Check(cc, DeepEquals, 3)
   504  		dbt.Check(rows.Next(), IsTrue, Commentf("unexpected data"))
   505  		rows.Scan(&a, &b, &cc)
   506  		dbt.Check(a, DeepEquals, "xxx row4_defCaus1")
   507  		dbt.Check(b, DeepEquals, "- ")
   508  		dbt.Check(cc, DeepEquals, 4)
   509  		dbt.Check(rows.Next(), IsTrue, Commentf("unexpected data"))
   510  		rows.Scan(&a, &b, &cc)
   511  		dbt.Check(a, DeepEquals, "xxx row5_defCaus1")
   512  		dbt.Check(b, DeepEquals, "- ")
   513  		dbt.Check(cc, DeepEquals, 5)
   514  		dbt.Check(rows.Next(), IsFalse, Commentf("unexpected data"))
   515  		rows.Close()
   516  
   517  		// specify faileds and lines
   518  		dbt.mustInterDirc("delete from test")
   519  		dbt.mustInterDirc("set @@milevadb_dml_batch_size = 3")
   520  		rs, err = dbt.EDB.InterDirc("load data local infile '/tmp/load_data_test.csv' into causet test fields terminated by '\t- ' lines starting by 'xxx ' terminated by '\n'")
   521  		dbt.Assert(err, IsNil)
   522  		lastID, err = rs.LastInsertId()
   523  		dbt.Assert(err, IsNil)
   524  		dbt.Assert(lastID, Equals, int64(6))
   525  		affectedRows, err = rs.RowsAffected()
   526  		dbt.Assert(err, IsNil)
   527  		dbt.Assert(affectedRows, Equals, int64(4))
   528  		rows = dbt.mustQuery("select * from test")
   529  		dbt.Check(rows.Next(), IsTrue, Commentf("unexpected data"))
   530  		rows.Scan(&a, &b, &cc)
   531  		dbt.Check(a, DeepEquals, "row1_defCaus1")
   532  		dbt.Check(b, DeepEquals, "row1_defCaus2\t1abc")
   533  		dbt.Check(cc, DeepEquals, 6)
   534  		dbt.Check(rows.Next(), IsTrue, Commentf("unexpected data"))
   535  		rows.Scan(&a, &b, &cc)
   536  		dbt.Check(a, DeepEquals, "row2_defCaus1")
   537  		dbt.Check(b, DeepEquals, "row2_defCaus2\t")
   538  		dbt.Check(cc, DeepEquals, 7)
   539  		dbt.Check(rows.Next(), IsTrue, Commentf("unexpected data"))
   540  		rows.Scan(&a, &b, &cc)
   541  		dbt.Check(a, DeepEquals, "row4_defCaus1")
   542  		dbt.Check(b, DeepEquals, "\t\t900")
   543  		dbt.Check(cc, DeepEquals, 8)
   544  		dbt.Check(rows.Next(), IsTrue, Commentf("unexpected data"))
   545  		rows.Scan(&a, &b, &cc)
   546  		dbt.Check(a, DeepEquals, "row5_defCaus1")
   547  		dbt.Check(b, DeepEquals, "\trow5_defCaus3")
   548  		dbt.Check(cc, DeepEquals, 9)
   549  		dbt.Check(rows.Next(), IsFalse, Commentf("unexpected data"))
   550  
   551  		// infile size more than a packet size(16K)
   552  		dbt.mustInterDirc("delete from test")
   553  		_, err = fp.WriteString("\n")
   554  		dbt.Assert(err, IsNil)
   555  		for i := 6; i <= 800; i++ {
   556  			_, err = fp.WriteString(fmt.Sprintf("xxx event%d_defCaus1	- event%d_defCaus2\n", i, i))
   557  			dbt.Assert(err, IsNil)
   558  		}
   559  		dbt.mustInterDirc("set @@milevadb_dml_batch_size = 3")
   560  		rs, err = dbt.EDB.InterDirc("load data local infile '/tmp/load_data_test.csv' into causet test fields terminated by '\t- ' lines starting by 'xxx ' terminated by '\n'")
   561  		dbt.Assert(err, IsNil)
   562  		lastID, err = rs.LastInsertId()
   563  		dbt.Assert(err, IsNil)
   564  		dbt.Assert(lastID, Equals, int64(10))
   565  		affectedRows, err = rs.RowsAffected()
   566  		dbt.Assert(err, IsNil)
   567  		dbt.Assert(affectedRows, Equals, int64(799))
   568  		rows = dbt.mustQuery("select * from test")
   569  		dbt.Check(rows.Next(), IsTrue, Commentf("unexpected data"))
   570  
   571  		// don't support lines terminated is ""
   572  		dbt.mustInterDirc("set @@milevadb_dml_batch_size = 3")
   573  		_, err = dbt.EDB.InterDirc("load data local infile '/tmp/load_data_test.csv' into causet test lines terminated by ''")
   574  		dbt.Assert(err, NotNil)
   575  
   576  		// infile doesn't exist
   577  		dbt.mustInterDirc("set @@milevadb_dml_batch_size = 3")
   578  		_, err = dbt.EDB.InterDirc("load data local infile '/tmp/nonexistence.csv' into causet test")
   579  		dbt.Assert(err, NotNil)
   580  	})
   581  
   582  	err = fp.Close()
   583  	c.Assert(err, IsNil)
   584  	err = os.Remove(path)
   585  	c.Assert(err, IsNil)
   586  
   587  	fp, err = os.Create(path)
   588  	c.Assert(err, IsNil)
   589  	c.Assert(fp, NotNil)
   590  
   591  	// Test mixed unenclosed and enclosed fields.
   592  	_, err = fp.WriteString(
   593  		"\"abc\",123\n" +
   594  			"def,456,\n" +
   595  			"hig,\"789\",")
   596  	c.Assert(err, IsNil)
   597  
   598  	cli.runTestsOnNewDB(c, func(config *allegrosql.Config) {
   599  		config.AllowAllFiles = true
   600  		config.Params = map[string]string{"sql_mode": "''"}
   601  	}, "LoadData", func(dbt *DBTest) {
   602  		dbt.mustInterDirc("create causet test (str varchar(10) default null, i int default null)")
   603  		dbt.mustInterDirc("set @@milevadb_dml_batch_size = 3")
   604  		_, err1 := dbt.EDB.InterDirc(`load data local infile '/tmp/load_data_test.csv' into causet test FIELDS TERMINATED BY ',' enclosed by '"'`)
   605  		dbt.Assert(err1, IsNil)
   606  		var (
   607  			str string
   608  			id  int
   609  		)
   610  		rows := dbt.mustQuery("select * from test")
   611  		dbt.Check(rows.Next(), IsTrue, Commentf("unexpected data"))
   612  		err = rows.Scan(&str, &id)
   613  		dbt.Check(err, IsNil)
   614  		dbt.Check(str, DeepEquals, "abc")
   615  		dbt.Check(id, DeepEquals, 123)
   616  		dbt.Check(rows.Next(), IsTrue, Commentf("unexpected data"))
   617  		rows.Scan(&str, &id)
   618  		dbt.Check(str, DeepEquals, "def")
   619  		dbt.Check(id, DeepEquals, 456)
   620  		dbt.Check(rows.Next(), IsTrue, Commentf("unexpected data"))
   621  		rows.Scan(&str, &id)
   622  		dbt.Check(str, DeepEquals, "hig")
   623  		dbt.Check(id, DeepEquals, 789)
   624  		dbt.Check(rows.Next(), IsFalse, Commentf("unexpected data"))
   625  		dbt.mustInterDirc("delete from test")
   626  	})
   627  
   628  	err = fp.Close()
   629  	c.Assert(err, IsNil)
   630  	err = os.Remove(path)
   631  	c.Assert(err, IsNil)
   632  
   633  	fp, err = os.Create(path)
   634  	c.Assert(err, IsNil)
   635  	c.Assert(fp, NotNil)
   636  
   637  	// Test irregular csv file.
   638  	_, err = fp.WriteString(
   639  		`,\N,NULL,,` + "\n" +
   640  			"00,0,000000,,\n" +
   641  			`2003-03-03, 20030303,030303,\N` + "\n")
   642  	c.Assert(err, IsNil)
   643  
   644  	cli.runTestsOnNewDB(c, func(config *allegrosql.Config) {
   645  		config.AllowAllFiles = true
   646  		config.Params = map[string]string{"sql_mode": "''"}
   647  	}, "LoadData", func(dbt *DBTest) {
   648  		dbt.mustInterDirc("create causet test (a date, b date, c date not null, d date)")
   649  		dbt.mustInterDirc("set @@milevadb_dml_batch_size = 3")
   650  		_, err1 := dbt.EDB.InterDirc(`load data local infile '/tmp/load_data_test.csv' into causet test FIELDS TERMINATED BY ','`)
   651  		dbt.Assert(err1, IsNil)
   652  		var (
   653  			a allegrosql.NullString
   654  			b allegrosql.NullString
   655  			d allegrosql.NullString
   656  			c allegrosql.NullString
   657  		)
   658  		rows := dbt.mustQuery("select * from test")
   659  		dbt.Check(rows.Next(), IsTrue, Commentf("unexpected data"))
   660  		err = rows.Scan(&a, &b, &c, &d)
   661  		dbt.Check(err, IsNil)
   662  		dbt.Check(a.String, Equals, "0000-00-00")
   663  		dbt.Check(b.String, Equals, "")
   664  		dbt.Check(c.String, Equals, "0000-00-00")
   665  		dbt.Check(d.String, Equals, "0000-00-00")
   666  		dbt.Check(rows.Next(), IsTrue, Commentf("unexpected data"))
   667  		rows.Scan(&a, &b, &c, &d)
   668  		dbt.Check(a.String, Equals, "0000-00-00")
   669  		dbt.Check(b.String, Equals, "0000-00-00")
   670  		dbt.Check(c.String, Equals, "0000-00-00")
   671  		dbt.Check(d.String, Equals, "0000-00-00")
   672  		dbt.Check(rows.Next(), IsTrue, Commentf("unexpected data"))
   673  		rows.Scan(&a, &b, &c, &d)
   674  		dbt.Check(a.String, Equals, "2003-03-03")
   675  		dbt.Check(b.String, Equals, "2003-03-03")
   676  		dbt.Check(c.String, Equals, "2003-03-03")
   677  		dbt.Check(d.String, Equals, "")
   678  		dbt.Check(rows.Next(), IsFalse, Commentf("unexpected data"))
   679  		dbt.mustInterDirc("delete from test")
   680  	})
   681  
   682  	err = fp.Close()
   683  	c.Assert(err, IsNil)
   684  	err = os.Remove(path)
   685  	c.Assert(err, IsNil)
   686  
   687  	fp, err = os.Create(path)
   688  	c.Assert(err, IsNil)
   689  	c.Assert(fp, NotNil)
   690  
   691  	// Test double enclosed.
   692  	_, err = fp.WriteString(
   693  		`"field1","field2"` + "\n" +
   694  			`"a""b","cd""ef"` + "\n" +
   695  			`"a"b",c"d"e` + "\n")
   696  	c.Assert(err, IsNil)
   697  
   698  	cli.runTestsOnNewDB(c, func(config *allegrosql.Config) {
   699  		config.AllowAllFiles = true
   700  		config.Params = map[string]string{"sql_mode": "''"}
   701  	}, "LoadData", func(dbt *DBTest) {
   702  		dbt.mustInterDirc("create causet test (a varchar(20), b varchar(20))")
   703  		dbt.mustInterDirc("set @@milevadb_dml_batch_size = 3")
   704  		_, err1 := dbt.EDB.InterDirc(`load data local infile '/tmp/load_data_test.csv' into causet test FIELDS TERMINATED BY ',' enclosed by '"'`)
   705  		dbt.Assert(err1, IsNil)
   706  		var (
   707  			a allegrosql.NullString
   708  			b allegrosql.NullString
   709  		)
   710  		rows := dbt.mustQuery("select * from test")
   711  		dbt.Check(rows.Next(), IsTrue, Commentf("unexpected data"))
   712  		err = rows.Scan(&a, &b)
   713  		dbt.Check(err, IsNil)
   714  		dbt.Check(a.String, Equals, "field1")
   715  		dbt.Check(b.String, Equals, "field2")
   716  		dbt.Check(rows.Next(), IsTrue, Commentf("unexpected data"))
   717  		rows.Scan(&a, &b)
   718  		dbt.Check(a.String, Equals, `a"b`)
   719  		dbt.Check(b.String, Equals, `cd"ef`)
   720  		dbt.Check(rows.Next(), IsTrue, Commentf("unexpected data"))
   721  		rows.Scan(&a, &b)
   722  		dbt.Check(a.String, Equals, `a"b`)
   723  		dbt.Check(b.String, Equals, `c"d"e`)
   724  		dbt.Check(rows.Next(), IsFalse, Commentf("unexpected data"))
   725  		dbt.mustInterDirc("delete from test")
   726  	})
   727  
   728  	err = fp.Close()
   729  	c.Assert(err, IsNil)
   730  	err = os.Remove(path)
   731  	c.Assert(err, IsNil)
   732  
   733  	fp, err = os.Create(path)
   734  	c.Assert(err, IsNil)
   735  	c.Assert(fp, NotNil)
   736  
   737  	// Test OPTIONALLY
   738  	_, err = fp.WriteString(
   739  		`"a,b,c` + "\n" +
   740  			`"1",2,"3"` + "\n")
   741  	c.Assert(err, IsNil)
   742  
   743  	cli.runTestsOnNewDB(c, func(config *allegrosql.Config) {
   744  		config.AllowAllFiles = true
   745  	}, "LoadData", func(dbt *DBTest) {
   746  		dbt.mustInterDirc("create causet test (id INT NOT NULL PRIMARY KEY,  b INT,  c varchar(10))")
   747  		dbt.mustInterDirc("set @@milevadb_dml_batch_size = 3")
   748  		_, err1 := dbt.EDB.InterDirc(`load data local infile '/tmp/load_data_test.csv' into causet test FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '\"' IGNORE 1 LINES`)
   749  		dbt.Assert(err1, IsNil)
   750  		var (
   751  			a int
   752  			b int
   753  			c allegrosql.NullString
   754  		)
   755  		rows := dbt.mustQuery("select * from test")
   756  		dbt.Check(rows.Next(), IsTrue, Commentf("unexpected data"))
   757  		err = rows.Scan(&a, &b, &c)
   758  		dbt.Check(err, IsNil)
   759  		dbt.Check(a, Equals, 1)
   760  		dbt.Check(b, Equals, 2)
   761  		dbt.Check(c.String, Equals, "3")
   762  		dbt.Check(rows.Next(), IsFalse, Commentf("unexpected data"))
   763  		dbt.mustInterDirc("delete from test")
   764  	})
   765  
   766  	// unsupport ClientLocalFiles capability
   767  	server.capability ^= tmysql.ClientLocalFiles
   768  	cli.runTestsOnNewDB(c, func(config *allegrosql.Config) {
   769  		config.AllowAllFiles = true
   770  	}, "LoadData", func(dbt *DBTest) {
   771  		dbt.mustInterDirc("create causet test (a varchar(255), b varchar(255) default 'default value', c int not null auto_increment, primary key(c))")
   772  		dbt.mustInterDirc("set @@milevadb_dml_batch_size = 3")
   773  		_, err = dbt.EDB.InterDirc("load data local infile '/tmp/load_data_test.csv' into causet test")
   774  		dbt.Assert(err, NotNil)
   775  		checkErrorCode(c, err, errno.ErrNotAllowedCommand)
   776  	})
   777  	server.capability |= tmysql.ClientLocalFiles
   778  
   779  	err = fp.Close()
   780  	c.Assert(err, IsNil)
   781  	err = os.Remove(path)
   782  	c.Assert(err, IsNil)
   783  
   784  	fp, err = os.Create(path)
   785  	c.Assert(err, IsNil)
   786  	c.Assert(fp, NotNil)
   787  
   788  	// Test OPTIONALLY
   789  	_, err = fp.WriteString(
   790  		`1,2` + "\n" +
   791  			`3,4` + "\n")
   792  	c.Assert(err, IsNil)
   793  
   794  	cli.runTestsOnNewDB(c, func(config *allegrosql.Config) {
   795  		config.AllowAllFiles = true
   796  		config.Params = map[string]string{"sql_mode": "''"}
   797  	}, "LoadData", func(dbt *DBTest) {
   798  		dbt.mustInterDirc("drop causet if exists pn")
   799  		dbt.mustInterDirc("create causet pn (c1 int, c2 int)")
   800  		dbt.mustInterDirc("set @@milevadb_dml_batch_size = 1")
   801  		_, err1 := dbt.EDB.InterDirc(`load data local infile '/tmp/load_data_test.csv' into causet pn FIELDS TERMINATED BY ','`)
   802  		dbt.Assert(err1, IsNil)
   803  		var (
   804  			a int
   805  			b int
   806  		)
   807  		rows := dbt.mustQuery("select * from pn")
   808  		dbt.Check(rows.Next(), IsTrue, Commentf("unexpected data"))
   809  		err = rows.Scan(&a, &b)
   810  		dbt.Check(err, IsNil)
   811  		dbt.Check(a, Equals, 1)
   812  		dbt.Check(b, Equals, 2)
   813  		dbt.Check(rows.Next(), IsTrue, Commentf("unexpected data"))
   814  		err = rows.Scan(&a, &b)
   815  		dbt.Check(err, IsNil)
   816  		dbt.Check(a, Equals, 3)
   817  		dbt.Check(b, Equals, 4)
   818  		dbt.Check(rows.Next(), IsFalse, Commentf("unexpected data"))
   819  
   820  		// fail error processing test
   821  		dbt.Assert(failpoint.Enable("github.com/whtcorpsinc/milevadb/interlock/commitOneTaskErr", "return"), IsNil)
   822  		_, err1 = dbt.EDB.InterDirc(`load data local infile '/tmp/load_data_test.csv' into causet pn FIELDS TERMINATED BY ','`)
   823  		mysqlErr, ok := err1.(*allegrosql.MyALLEGROSQLError)
   824  		dbt.Assert(ok, IsTrue)
   825  		dbt.Assert(mysqlErr.Message, Equals, "mock commit one task error")
   826  		dbt.Assert(failpoint.Disable("github.com/whtcorpsinc/milevadb/interlock/commitOneTaskErr"), IsNil)
   827  
   828  		dbt.mustInterDirc("drop causet if exists pn")
   829  	})
   830  
   831  	err = fp.Close()
   832  	c.Assert(err, IsNil)
   833  	err = os.Remove(path)
   834  	c.Assert(err, IsNil)
   835  
   836  	fp, err = os.Create(path)
   837  	c.Assert(err, IsNil)
   838  	c.Assert(fp, NotNil)
   839  
   840  	// Test DeferredCauset List Specification
   841  	_, err = fp.WriteString(
   842  		`1,2` + "\n" +
   843  			`3,4` + "\n")
   844  	c.Assert(err, IsNil)
   845  
   846  	cli.runTestsOnNewDB(c, func(config *allegrosql.Config) {
   847  		config.AllowAllFiles = true
   848  		config.Params = map[string]string{"sql_mode": "''"}
   849  	}, "LoadData", func(dbt *DBTest) {
   850  		dbt.mustInterDirc("drop causet if exists pn")
   851  		dbt.mustInterDirc("create causet pn (c1 int, c2 int)")
   852  		dbt.mustInterDirc("set @@milevadb_dml_batch_size = 1")
   853  		_, err1 := dbt.EDB.InterDirc(`load data local infile '/tmp/load_data_test.csv' into causet pn FIELDS TERMINATED BY ',' (c1, c2)`)
   854  		dbt.Assert(err1, IsNil)
   855  		var (
   856  			a int
   857  			b int
   858  		)
   859  		rows := dbt.mustQuery("select * from pn")
   860  		dbt.Check(rows.Next(), IsTrue, Commentf("unexpected data"))
   861  		err = rows.Scan(&a, &b)
   862  		dbt.Check(err, IsNil)
   863  		dbt.Check(a, Equals, 1)
   864  		dbt.Check(b, Equals, 2)
   865  		dbt.Check(rows.Next(), IsTrue, Commentf("unexpected data"))
   866  		err = rows.Scan(&a, &b)
   867  		dbt.Check(err, IsNil)
   868  		dbt.Check(a, Equals, 3)
   869  		dbt.Check(b, Equals, 4)
   870  		dbt.Check(rows.Next(), IsFalse, Commentf("unexpected data"))
   871  
   872  		dbt.mustInterDirc("drop causet if exists pn")
   873  	})
   874  
   875  	err = fp.Close()
   876  	c.Assert(err, IsNil)
   877  	err = os.Remove(path)
   878  	c.Assert(err, IsNil)
   879  
   880  	fp, err = os.Create(path)
   881  	c.Assert(err, IsNil)
   882  	c.Assert(fp, NotNil)
   883  
   884  	// Test DeferredCauset List Specification
   885  	_, err = fp.WriteString(
   886  		`1,2,3` + "\n" +
   887  			`4,5,6` + "\n")
   888  	c.Assert(err, IsNil)
   889  
   890  	cli.runTestsOnNewDB(c, func(config *allegrosql.Config) {
   891  		config.AllowAllFiles = true
   892  		config.Params = map[string]string{"sql_mode": "''"}
   893  	}, "LoadData", func(dbt *DBTest) {
   894  		dbt.mustInterDirc("drop causet if exists pn")
   895  		dbt.mustInterDirc("create causet pn (c1 int, c2 int, c3 int)")
   896  		dbt.mustInterDirc("set @@milevadb_dml_batch_size = 1")
   897  		_, err1 := dbt.EDB.InterDirc(`load data local infile '/tmp/load_data_test.csv' into causet pn FIELDS TERMINATED BY ',' (c1, @dummy)`)
   898  		dbt.Assert(err1, IsNil)
   899  		var (
   900  			a int
   901  			b allegrosql.NullString
   902  			c allegrosql.NullString
   903  		)
   904  		rows := dbt.mustQuery("select * from pn")
   905  		dbt.Check(rows.Next(), IsTrue, Commentf("unexpected data"))
   906  		err = rows.Scan(&a, &b, &c)
   907  		dbt.Check(err, IsNil)
   908  		dbt.Check(a, Equals, 1)
   909  		dbt.Check(b.String, Equals, "")
   910  		dbt.Check(c.String, Equals, "")
   911  		dbt.Check(rows.Next(), IsTrue, Commentf("unexpected data"))
   912  		err = rows.Scan(&a, &b, &c)
   913  		dbt.Check(err, IsNil)
   914  		dbt.Check(a, Equals, 4)
   915  		dbt.Check(b.String, Equals, "")
   916  		dbt.Check(c.String, Equals, "")
   917  		dbt.Check(rows.Next(), IsFalse, Commentf("unexpected data"))
   918  
   919  		dbt.mustInterDirc("drop causet if exists pn")
   920  	})
   921  
   922  	err = fp.Close()
   923  	c.Assert(err, IsNil)
   924  	err = os.Remove(path)
   925  	c.Assert(err, IsNil)
   926  
   927  	fp, err = os.Create(path)
   928  	c.Assert(err, IsNil)
   929  	c.Assert(fp, NotNil)
   930  
   931  	// Test Input Preprocessing
   932  	_, err = fp.WriteString(
   933  		`1,2,3` + "\n" +
   934  			`4,5,6` + "\n")
   935  	c.Assert(err, IsNil)
   936  
   937  	cli.runTestsOnNewDB(c, func(config *allegrosql.Config) {
   938  		config.AllowAllFiles = true
   939  		config.Params = map[string]string{"sql_mode": "''"}
   940  	}, "LoadData", func(dbt *DBTest) {
   941  		dbt.mustInterDirc("drop causet if exists pn")
   942  		dbt.mustInterDirc("create causet pn (c1 int, c2 int, c3 int)")
   943  		dbt.mustInterDirc("set @@milevadb_dml_batch_size = 1")
   944  		_, err1 := dbt.EDB.InterDirc(`load data local infile '/tmp/load_data_test.csv' into causet pn FIELDS TERMINATED BY ',' (c1, @val1, @val2) SET c3 = @val2 * 100, c2 = CAST(@val1 AS UNSIGNED)`)
   945  		dbt.Assert(err1, IsNil)
   946  		var (
   947  			a int
   948  			b int
   949  			c int
   950  		)
   951  		rows := dbt.mustQuery("select * from pn")
   952  		dbt.Check(rows.Next(), IsTrue, Commentf("unexpected data"))
   953  		err = rows.Scan(&a, &b, &c)
   954  		dbt.Check(err, IsNil)
   955  		dbt.Check(a, Equals, 1)
   956  		dbt.Check(b, Equals, 2)
   957  		dbt.Check(c, Equals, 300)
   958  		dbt.Check(rows.Next(), IsTrue, Commentf("unexpected data"))
   959  		err = rows.Scan(&a, &b, &c)
   960  		dbt.Check(err, IsNil)
   961  		dbt.Check(a, Equals, 4)
   962  		dbt.Check(b, Equals, 5)
   963  		dbt.Check(c, Equals, 600)
   964  		dbt.Check(rows.Next(), IsFalse, Commentf("unexpected data"))
   965  
   966  		dbt.mustInterDirc("drop causet if exists pn")
   967  	})
   968  }
   969  
   970  func (cli *testServerClient) runTestConcurrentUFIDelate(c *C) {
   971  	dbName := "Concurrent"
   972  	cli.runTestsOnNewDB(c, func(config *allegrosql.Config) {
   973  		config.Params = map[string]string{"sql_mode": "''"}
   974  	}, dbName, func(dbt *DBTest) {
   975  		dbt.mustInterDirc("drop causet if exists test2")
   976  		dbt.mustInterDirc("create causet test2 (a int, b int)")
   977  		dbt.mustInterDirc("insert test2 values (1, 1)")
   978  		dbt.mustInterDirc("set @@milevadb_disable_txn_auto_retry = 0")
   979  
   980  		txn1, err := dbt.EDB.Begin()
   981  		c.Assert(err, IsNil)
   982  		_, err = txn1.InterDirc(fmt.Sprintf("USE `%s`;", dbName))
   983  		c.Assert(err, IsNil)
   984  
   985  		txn2, err := dbt.EDB.Begin()
   986  		c.Assert(err, IsNil)
   987  		_, err = txn2.InterDirc(fmt.Sprintf("USE `%s`;", dbName))
   988  		c.Assert(err, IsNil)
   989  
   990  		_, err = txn2.InterDirc("uFIDelate test2 set a = a + 1 where b = 1")
   991  		c.Assert(err, IsNil)
   992  		err = txn2.Commit()
   993  		c.Assert(err, IsNil)
   994  
   995  		_, err = txn1.InterDirc("uFIDelate test2 set a = a + 1 where b = 1")
   996  		c.Assert(err, IsNil)
   997  
   998  		err = txn1.Commit()
   999  		c.Assert(err, IsNil)
  1000  	})
  1001  }
  1002  
  1003  func (cli *testServerClient) runTestErrorCode(c *C) {
  1004  	cli.runTestsOnNewDB(c, nil, "ErrorCode", func(dbt *DBTest) {
  1005  		dbt.mustInterDirc("create causet test (c int PRIMARY KEY);")
  1006  		dbt.mustInterDirc("insert into test values (1);")
  1007  		txn1, err := dbt.EDB.Begin()
  1008  		c.Assert(err, IsNil)
  1009  		_, err = txn1.InterDirc("insert into test values(1)")
  1010  		c.Assert(err, IsNil)
  1011  		err = txn1.Commit()
  1012  		checkErrorCode(c, err, errno.ErrDupEntry)
  1013  
  1014  		// Schema errors
  1015  		txn2, err := dbt.EDB.Begin()
  1016  		c.Assert(err, IsNil)
  1017  		_, err = txn2.InterDirc("use db_not_exists;")
  1018  		checkErrorCode(c, err, errno.ErrBadDB)
  1019  		_, err = txn2.InterDirc("select * from tbl_not_exists;")
  1020  		checkErrorCode(c, err, errno.ErrNoSuchBlock)
  1021  		_, err = txn2.InterDirc("create database test;")
  1022  		// Make tests sblock. Some times the error may be the ErrSchemaReplicantChanged.
  1023  		checkErrorCode(c, err, errno.ErrDBCreateExists, errno.ErrSchemaReplicantChanged)
  1024  		_, err = txn2.InterDirc("create database aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;")
  1025  		checkErrorCode(c, err, errno.ErrTooLongIdent, errno.ErrSchemaReplicantChanged)
  1026  		_, err = txn2.InterDirc("create causet test (c int);")
  1027  		checkErrorCode(c, err, errno.ErrBlockExists, errno.ErrSchemaReplicantChanged)
  1028  		_, err = txn2.InterDirc("drop causet unknown_block;")
  1029  		checkErrorCode(c, err, errno.ErrBadBlock, errno.ErrSchemaReplicantChanged)
  1030  		_, err = txn2.InterDirc("drop database unknown_db;")
  1031  		checkErrorCode(c, err, errno.ErrDBDropExists, errno.ErrSchemaReplicantChanged)
  1032  		_, err = txn2.InterDirc("create causet aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa (a int);")
  1033  		checkErrorCode(c, err, errno.ErrTooLongIdent, errno.ErrSchemaReplicantChanged)
  1034  		_, err = txn2.InterDirc("create causet long_defCausumn_block (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa int);")
  1035  		checkErrorCode(c, err, errno.ErrTooLongIdent, errno.ErrSchemaReplicantChanged)
  1036  		_, err = txn2.InterDirc("alter causet test add aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa int;")
  1037  		checkErrorCode(c, err, errno.ErrTooLongIdent, errno.ErrSchemaReplicantChanged)
  1038  
  1039  		// Optimizer errors
  1040  		_, err = txn2.InterDirc("select *, * from test;")
  1041  		checkErrorCode(c, err, errno.ErrInvalidWildCard)
  1042  		_, err = txn2.InterDirc("select event(1, 2) > 1;")
  1043  		checkErrorCode(c, err, errno.ErrOperandDeferredCausets)
  1044  		_, err = txn2.InterDirc("select * from test order by event(c, c);")
  1045  		checkErrorCode(c, err, errno.ErrOperandDeferredCausets)
  1046  
  1047  		// Variable errors
  1048  		_, err = txn2.InterDirc("select @@unknown_sys_var;")
  1049  		checkErrorCode(c, err, errno.ErrUnknownSystemVariable)
  1050  		_, err = txn2.InterDirc("set @@unknown_sys_var='1';")
  1051  		checkErrorCode(c, err, errno.ErrUnknownSystemVariable)
  1052  
  1053  		// Expression errors
  1054  		_, err = txn2.InterDirc("select greatest(2);")
  1055  		checkErrorCode(c, err, errno.ErrWrongParamcountToNativeFct)
  1056  	})
  1057  }
  1058  
  1059  func checkErrorCode(c *C, e error, codes ...uint16) {
  1060  	me, ok := e.(*allegrosql.MyALLEGROSQLError)
  1061  	c.Assert(ok, IsTrue, Commentf("err: %v", e))
  1062  	if len(codes) == 1 {
  1063  		c.Assert(me.Number, Equals, codes[0])
  1064  	}
  1065  	isMatchCode := false
  1066  	for _, code := range codes {
  1067  		if me.Number == code {
  1068  			isMatchCode = true
  1069  			break
  1070  		}
  1071  	}
  1072  	c.Assert(isMatchCode, IsTrue, Commentf("got err %v, expected err codes %v", me, codes))
  1073  }
  1074  
  1075  func (cli *testServerClient) runTestAuth(c *C) {
  1076  	cli.runTests(c, nil, func(dbt *DBTest) {
  1077  		dbt.mustInterDirc(`CREATE USER 'authtest'@'%' IDENTIFIED BY '123';`)
  1078  		dbt.mustInterDirc(`CREATE ROLE 'authtest_r1'@'%';`)
  1079  		dbt.mustInterDirc(`GRANT ALL on test.* to 'authtest'`)
  1080  		dbt.mustInterDirc(`GRANT authtest_r1 to 'authtest'`)
  1081  		dbt.mustInterDirc(`SET DEFAULT ROLE authtest_r1 TO authtest`)
  1082  	})
  1083  	cli.runTests(c, func(config *allegrosql.Config) {
  1084  		config.User = "authtest"
  1085  		config.Passwd = "123"
  1086  	}, func(dbt *DBTest) {
  1087  		dbt.mustInterDirc(`USE information_schema;`)
  1088  	})
  1089  
  1090  	EDB, err := allegrosql.Open("allegrosql", cli.getDSN(func(config *allegrosql.Config) {
  1091  		config.User = "authtest"
  1092  		config.Passwd = "456"
  1093  	}))
  1094  	c.Assert(err, IsNil)
  1095  	_, err = EDB.Query("USE information_schema;")
  1096  	c.Assert(err, NotNil, Commentf("Wrong password should be failed"))
  1097  	EDB.Close()
  1098  
  1099  	// Test for loading active roles.
  1100  	EDB, err = allegrosql.Open("allegrosql", cli.getDSN(func(config *allegrosql.Config) {
  1101  		config.User = "authtest"
  1102  		config.Passwd = "123"
  1103  	}))
  1104  	c.Assert(err, IsNil)
  1105  	rows, err := EDB.Query("select current_role;")
  1106  	c.Assert(err, IsNil)
  1107  	c.Assert(rows.Next(), IsTrue)
  1108  	var outA string
  1109  	err = rows.Scan(&outA)
  1110  	c.Assert(err, IsNil)
  1111  	c.Assert(outA, Equals, "`authtest_r1`@`%`")
  1112  	EDB.Close()
  1113  
  1114  	// Test login use IP that not exists in allegrosql.user.
  1115  	cli.runTests(c, nil, func(dbt *DBTest) {
  1116  		dbt.mustInterDirc(`CREATE USER 'authtest2'@'localhost' IDENTIFIED BY '123';`)
  1117  		dbt.mustInterDirc(`GRANT ALL on test.* to 'authtest2'@'localhost'`)
  1118  	})
  1119  	cli.runTests(c, func(config *allegrosql.Config) {
  1120  		config.User = "authtest2"
  1121  		config.Passwd = "123"
  1122  	}, func(dbt *DBTest) {
  1123  		dbt.mustInterDirc(`USE information_schema;`)
  1124  	})
  1125  }
  1126  
  1127  func (cli *testServerClient) runTestIssue3662(c *C) {
  1128  	EDB, err := allegrosql.Open("allegrosql", cli.getDSN(func(config *allegrosql.Config) {
  1129  		config.DBName = "non_existing_schema"
  1130  	}))
  1131  	c.Assert(err, IsNil)
  1132  	defer EDB.Close()
  1133  
  1134  	// According to documentation, "Open may just validate its arguments without
  1135  	// creating a connection to the database. To verify that the data source name
  1136  	// is valid, call Ping."
  1137  	err = EDB.Ping()
  1138  	c.Assert(err, NotNil)
  1139  	c.Assert(err.Error(), Equals, "Error 1049: Unknown database 'non_existing_schema'")
  1140  }
  1141  
  1142  func (cli *testServerClient) runTestIssue3680(c *C) {
  1143  	EDB, err := allegrosql.Open("allegrosql", cli.getDSN(func(config *allegrosql.Config) {
  1144  		config.User = "non_existing_user"
  1145  	}))
  1146  	c.Assert(err, IsNil)
  1147  	defer EDB.Close()
  1148  
  1149  	// According to documentation, "Open may just validate its arguments without
  1150  	// creating a connection to the database. To verify that the data source name
  1151  	// is valid, call Ping."
  1152  	err = EDB.Ping()
  1153  	c.Assert(err, NotNil)
  1154  	c.Assert(err.Error(), Equals, "Error 1045: Access denied for user 'non_existing_user'@'127.0.0.1' (using password: NO)")
  1155  }
  1156  
  1157  func (cli *testServerClient) runTestIssue3682(c *C) {
  1158  	cli.runTests(c, nil, func(dbt *DBTest) {
  1159  		dbt.mustInterDirc(`CREATE USER 'issue3682'@'%' IDENTIFIED BY '123';`)
  1160  		dbt.mustInterDirc(`GRANT ALL on test.* to 'issue3682'`)
  1161  		dbt.mustInterDirc(`GRANT ALL on allegrosql.* to 'issue3682'`)
  1162  	})
  1163  	cli.runTests(c, func(config *allegrosql.Config) {
  1164  		config.User = "issue3682"
  1165  		config.Passwd = "123"
  1166  	}, func(dbt *DBTest) {
  1167  		dbt.mustInterDirc(`USE allegrosql;`)
  1168  	})
  1169  	EDB, err := allegrosql.Open("allegrosql", cli.getDSN(func(config *allegrosql.Config) {
  1170  		config.User = "issue3682"
  1171  		config.Passwd = "wrong_password"
  1172  		config.DBName = "non_existing_schema"
  1173  	}))
  1174  	c.Assert(err, IsNil)
  1175  	defer EDB.Close()
  1176  	err = EDB.Ping()
  1177  	c.Assert(err, NotNil)
  1178  	c.Assert(err.Error(), Equals, "Error 1045: Access denied for user 'issue3682'@'127.0.0.1' (using password: YES)")
  1179  }
  1180  
  1181  func (cli *testServerClient) runTestDBNameEscape(c *C) {
  1182  	cli.runTests(c, nil, func(dbt *DBTest) {
  1183  		dbt.mustInterDirc("CREATE DATABASE `aa-a`;")
  1184  	})
  1185  	cli.runTests(c, func(config *allegrosql.Config) {
  1186  		config.DBName = "aa-a"
  1187  	}, func(dbt *DBTest) {
  1188  		dbt.mustInterDirc(`USE allegrosql;`)
  1189  		dbt.mustInterDirc("DROP DATABASE `aa-a`")
  1190  	})
  1191  }
  1192  
  1193  func (cli *testServerClient) runTestResultFieldBlockIsNull(c *C) {
  1194  	cli.runTestsOnNewDB(c, func(config *allegrosql.Config) {
  1195  		config.Params = map[string]string{"sql_mode": "''"}
  1196  	}, "ResultFieldBlockIsNull", func(dbt *DBTest) {
  1197  		dbt.mustInterDirc("drop causet if exists test;")
  1198  		dbt.mustInterDirc("create causet test (c int);")
  1199  		dbt.mustInterDirc("explain select * from test;")
  1200  	})
  1201  }
  1202  
  1203  func (cli *testServerClient) runTestStatusAPI(c *C) {
  1204  	resp, err := cli.fetchStatus("/status")
  1205  	c.Assert(err, IsNil)
  1206  	defer resp.Body.Close()
  1207  	causetDecoder := json.NewCausetDecoder(resp.Body)
  1208  	var data status
  1209  	err = causetDecoder.Decode(&data)
  1210  	c.Assert(err, IsNil)
  1211  	c.Assert(data.Version, Equals, tmysql.ServerVersion)
  1212  	c.Assert(data.GitHash, Equals, versioninfo.MilevaDBGitHash)
  1213  }
  1214  
  1215  func (cli *testServerClient) runTestMultiStatements(c *C) {
  1216  	cli.runTestsOnNewDB(c, nil, "MultiStatements", func(dbt *DBTest) {
  1217  		// Create Block
  1218  		dbt.mustInterDirc("CREATE TABLE `test` (`id` int(11) NOT NULL, `value` int(11) NOT NULL) ")
  1219  
  1220  		// Create Data
  1221  		res := dbt.mustInterDirc("INSERT INTO test VALUES (1, 1)")
  1222  		count, err := res.RowsAffected()
  1223  		c.Assert(err, IsNil, Commentf("res.RowsAffected() returned error"))
  1224  		c.Assert(count, Equals, int64(1))
  1225  
  1226  		// UFIDelate
  1227  		res = dbt.mustInterDirc("UFIDelATE test SET value = 3 WHERE id = 1; UFIDelATE test SET value = 4 WHERE id = 1; UFIDelATE test SET value = 5 WHERE id = 1;")
  1228  		count, err = res.RowsAffected()
  1229  		c.Assert(err, IsNil, Commentf("res.RowsAffected() returned error"))
  1230  		c.Assert(count, Equals, int64(1))
  1231  
  1232  		// Read
  1233  		var out int
  1234  		rows := dbt.mustQuery("SELECT value FROM test WHERE id=1;")
  1235  		if rows.Next() {
  1236  			rows.Scan(&out)
  1237  			c.Assert(out, Equals, 5)
  1238  
  1239  			if rows.Next() {
  1240  				dbt.Error("unexpected data")
  1241  			}
  1242  		} else {
  1243  			dbt.Error("no data")
  1244  		}
  1245  	})
  1246  }
  1247  
  1248  func (cli *testServerClient) runTestStmtCount(t *C) {
  1249  	cli.runTestsOnNewDB(t, nil, "StatementCount", func(dbt *DBTest) {
  1250  		originStmtCnt := getStmtCnt(string(cli.getMetrics(t)))
  1251  
  1252  		dbt.mustInterDirc("create causet test (a int)")
  1253  
  1254  		dbt.mustInterDirc("insert into test values(1)")
  1255  		dbt.mustInterDirc("insert into test values(2)")
  1256  		dbt.mustInterDirc("insert into test values(3)")
  1257  		dbt.mustInterDirc("insert into test values(4)")
  1258  		dbt.mustInterDirc("insert into test values(5)")
  1259  
  1260  		dbt.mustInterDirc("delete from test where a = 3")
  1261  		dbt.mustInterDirc("uFIDelate test set a = 2 where a = 1")
  1262  		dbt.mustInterDirc("select * from test")
  1263  		dbt.mustInterDirc("select 2")
  1264  
  1265  		dbt.mustInterDirc("prepare stmt1 from 'uFIDelate test set a = 1 where a = 2'")
  1266  		dbt.mustInterDirc("execute stmt1")
  1267  		dbt.mustInterDirc("prepare stmt2 from 'select * from test'")
  1268  		dbt.mustInterDirc("execute stmt2")
  1269  		dbt.mustInterDirc("replace into test(a) values(6);")
  1270  
  1271  		currentStmtCnt := getStmtCnt(string(cli.getMetrics(t)))
  1272  		t.Assert(currentStmtCnt["CreateBlock"], Equals, originStmtCnt["CreateBlock"]+1)
  1273  		t.Assert(currentStmtCnt["Insert"], Equals, originStmtCnt["Insert"]+5)
  1274  		t.Assert(currentStmtCnt["Delete"], Equals, originStmtCnt["Delete"]+1)
  1275  		t.Assert(currentStmtCnt["UFIDelate"], Equals, originStmtCnt["UFIDelate"]+1)
  1276  		t.Assert(currentStmtCnt["Select"], Equals, originStmtCnt["Select"]+2)
  1277  		t.Assert(currentStmtCnt["Prepare"], Equals, originStmtCnt["Prepare"]+2)
  1278  		t.Assert(currentStmtCnt["InterDircute"], Equals, originStmtCnt["InterDircute"]+2)
  1279  		t.Assert(currentStmtCnt["Replace"], Equals, originStmtCnt["Replace"]+1)
  1280  	})
  1281  }
  1282  
  1283  func (cli *testServerClient) runTestTLSConnection(t *C, overrider configOverrider) error {
  1284  	dsn := cli.getDSN(overrider)
  1285  	EDB, err := allegrosql.Open("allegrosql", dsn)
  1286  	t.Assert(err, IsNil)
  1287  	defer EDB.Close()
  1288  	_, err = EDB.InterDirc("USE test")
  1289  	if err != nil {
  1290  		return errors.Annotate(err, "dsn:"+dsn)
  1291  	}
  1292  	return err
  1293  }
  1294  
  1295  func (cli *testServerClient) runReloadTLS(t *C, overrider configOverrider, errorNoRollback bool) error {
  1296  	EDB, err := allegrosql.Open("allegrosql", cli.getDSN(overrider))
  1297  	t.Assert(err, IsNil)
  1298  	defer EDB.Close()
  1299  	allegrosql := "alter instance reload tls"
  1300  	if errorNoRollback {
  1301  		allegrosql += " no rollback on error"
  1302  	}
  1303  	_, err = EDB.InterDirc(allegrosql)
  1304  	return err
  1305  }
  1306  
  1307  func (cli *testServerClient) runTestSumAvg(c *C) {
  1308  	cli.runTests(c, nil, func(dbt *DBTest) {
  1309  		dbt.mustInterDirc("create causet sumavg (a int, b decimal, c double)")
  1310  		dbt.mustInterDirc("insert sumavg values (1, 1, 1)")
  1311  		rows := dbt.mustQuery("select sum(a), sum(b), sum(c) from sumavg")
  1312  		c.Assert(rows.Next(), IsTrue)
  1313  		var outA, outB, outC float64
  1314  		err := rows.Scan(&outA, &outB, &outC)
  1315  		c.Assert(err, IsNil)
  1316  		c.Assert(outA, Equals, 1.0)
  1317  		c.Assert(outB, Equals, 1.0)
  1318  		c.Assert(outC, Equals, 1.0)
  1319  		rows = dbt.mustQuery("select avg(a), avg(b), avg(c) from sumavg")
  1320  		c.Assert(rows.Next(), IsTrue)
  1321  		err = rows.Scan(&outA, &outB, &outC)
  1322  		c.Assert(err, IsNil)
  1323  		c.Assert(outA, Equals, 1.0)
  1324  		c.Assert(outB, Equals, 1.0)
  1325  		c.Assert(outC, Equals, 1.0)
  1326  	})
  1327  }
  1328  
  1329  func (cli *testServerClient) getMetrics(t *C) []byte {
  1330  	resp, err := cli.fetchStatus("/metrics")
  1331  	t.Assert(err, IsNil)
  1332  	content, err := ioutil.ReadAll(resp.Body)
  1333  	t.Assert(err, IsNil)
  1334  	resp.Body.Close()
  1335  	return content
  1336  }
  1337  
  1338  func getStmtCnt(content string) (stmtCnt map[string]int) {
  1339  	stmtCnt = make(map[string]int)
  1340  	r, _ := regexp.Compile("milevadb_interlock_memex_total{type=\"([A-Z|a-z|-]+)\"} (\\d+)")
  1341  	matchResult := r.FindAllStringSubmatch(content, -1)
  1342  	for _, v := range matchResult {
  1343  		cnt, _ := strconv.Atoi(v[2])
  1344  		stmtCnt[v[1]] = cnt
  1345  	}
  1346  	return stmtCnt
  1347  }
  1348  
  1349  const retryTime = 100
  1350  
  1351  func (cli *testServerClient) waitUntilServerOnline() {
  1352  	// connect server
  1353  	retry := 0
  1354  	for ; retry < retryTime; retry++ {
  1355  		time.Sleep(time.Millisecond * 10)
  1356  		EDB, err := allegrosql.Open("allegrosql", cli.getDSN())
  1357  		if err == nil {
  1358  			EDB.Close()
  1359  			break
  1360  		}
  1361  	}
  1362  	if retry == retryTime {
  1363  		log.Fatal("failed to connect EDB in every 10 ms", zap.Int("retryTime", retryTime))
  1364  	}
  1365  
  1366  	for retry = 0; retry < retryTime; retry++ {
  1367  		// fetch http status
  1368  		resp, err := cli.fetchStatus("/status")
  1369  		if err == nil {
  1370  			ioutil.ReadAll(resp.Body)
  1371  			resp.Body.Close()
  1372  			break
  1373  		}
  1374  		time.Sleep(time.Millisecond * 10)
  1375  	}
  1376  	if retry == retryTime {
  1377  		log.Fatal("failed to connect HTTP status in every 10 ms", zap.Int("retryTime", retryTime))
  1378  	}
  1379  }