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 }