github.com/whtcorpsinc/milevadb-prod@v0.0.0-20211104133533-f57f4be3b597/dbs/db_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 dbs_test 15 16 import ( 17 "context" 18 "fmt" 19 "io" 20 "math" 21 "math/rand" 22 "sort" 23 "strconv" 24 "strings" 25 "sync" 26 "time" 27 28 "github.com/whtcorpsinc/BerolinaSQL/allegrosql" 29 "github.com/whtcorpsinc/BerolinaSQL/perceptron" 30 "github.com/whtcorpsinc/BerolinaSQL/terror" 31 BerolinaSQLtypes "github.com/whtcorpsinc/BerolinaSQL/types" 32 . "github.com/whtcorpsinc/check" 33 "github.com/whtcorpsinc/errors" 34 "github.com/whtcorpsinc/failpoint" 35 "github.com/whtcorpsinc/milevadb/blockcodec" 36 "github.com/whtcorpsinc/milevadb/causet" 37 "github.com/whtcorpsinc/milevadb/causet/blocks" 38 "github.com/whtcorpsinc/milevadb/causetstore/mockstore" 39 "github.com/whtcorpsinc/milevadb/causetstore/mockstore/cluster" 40 "github.com/whtcorpsinc/milevadb/config" 41 "github.com/whtcorpsinc/milevadb/dbs" 42 testdbsutil "github.com/whtcorpsinc/milevadb/dbs/solitonutil" 43 "github.com/whtcorpsinc/milevadb/ekv" 44 "github.com/whtcorpsinc/milevadb/errno" 45 "github.com/whtcorpsinc/milevadb/interlock" 46 "github.com/whtcorpsinc/milevadb/petri" 47 "github.com/whtcorpsinc/milevadb/schemareplicant" 48 "github.com/whtcorpsinc/milevadb/soliton/admin" 49 "github.com/whtcorpsinc/milevadb/soliton/codec" 50 "github.com/whtcorpsinc/milevadb/soliton/defCauslate" 51 "github.com/whtcorpsinc/milevadb/soliton/israce" 52 "github.com/whtcorpsinc/milevadb/soliton/mock" 53 "github.com/whtcorpsinc/milevadb/soliton/petriutil" 54 "github.com/whtcorpsinc/milevadb/soliton/rowcodec" 55 "github.com/whtcorpsinc/milevadb/soliton/solitonutil" 56 "github.com/whtcorpsinc/milevadb/soliton/testkit" 57 "github.com/whtcorpsinc/milevadb/spacetime" 58 "github.com/whtcorpsinc/milevadb/spacetime/autoid" 59 "github.com/whtcorpsinc/milevadb/stochastik" 60 "github.com/whtcorpsinc/milevadb/stochastikctx" 61 "github.com/whtcorpsinc/milevadb/types" 62 ) 63 64 const ( 65 // waitForCleanDataRound indicates how many times should we check data is cleaned or not. 66 waitForCleanDataRound = 150 67 // waitForCleanDataInterval is a min duration between 2 check for data clean. 68 waitForCleanDataInterval = time.Millisecond * 100 69 ) 70 71 var _ = Suite(&testDBSuite1{&testDBSuite{}}) 72 var _ = Suite(&testDBSuite2{&testDBSuite{}}) 73 var _ = Suite(&testDBSuite3{&testDBSuite{}}) 74 var _ = Suite(&testDBSuite4{&testDBSuite{}}) 75 var _ = Suite(&testDBSuite5{&testDBSuite{}}) 76 var _ = Suite(&testDBSuite6{&testDBSuite{}}) 77 var _ = Suite(&testDBSuite7{&testDBSuite{}}) 78 var _ = SerialSuites(&testSerialDBSuite{&testDBSuite{}}) 79 80 const defaultBatchSize = 1024 81 82 type testDBSuite struct { 83 cluster cluster.Cluster 84 causetstore ekv.CausetStorage 85 dom *petri.Petri 86 schemaName string 87 s stochastik.Stochastik 88 lease time.Duration 89 autoIDStep int64 90 } 91 92 func setUpSuite(s *testDBSuite, c *C) { 93 var err error 94 95 s.lease = 600 * time.Millisecond 96 stochastik.SetSchemaLease(s.lease) 97 stochastik.DisableStats4Test() 98 s.schemaName = "test_db" 99 s.autoIDStep = autoid.GetStep() 100 dbs.SetWaitTimeWhenErrorOccurred(0) 101 102 s.causetstore, err = mockstore.NewMockStore( 103 mockstore.WithClusterInspector(func(c cluster.Cluster) { 104 mockstore.BootstrapWithSingleStore(c) 105 s.cluster = c 106 }), 107 ) 108 c.Assert(err, IsNil) 109 110 s.dom, err = stochastik.BootstrapStochastik(s.causetstore) 111 c.Assert(err, IsNil) 112 s.s, err = stochastik.CreateStochastik4Test(s.causetstore) 113 c.Assert(err, IsNil) 114 115 _, err = s.s.InterDircute(context.Background(), "create database test_db") 116 c.Assert(err, IsNil) 117 s.s.InterDircute(context.Background(), "set @@global.milevadb_max_delta_schema_count= 4096") 118 } 119 120 func tearDownSuite(s *testDBSuite, c *C) { 121 s.s.InterDircute(context.Background(), "drop database if exists test_db") 122 s.s.Close() 123 s.dom.Close() 124 s.causetstore.Close() 125 } 126 127 func (s *testDBSuite) SetUpSuite(c *C) { 128 setUpSuite(s, c) 129 } 130 131 func (s *testDBSuite) TearDownSuite(c *C) { 132 tearDownSuite(s, c) 133 } 134 135 type testDBSuite1 struct{ *testDBSuite } 136 type testDBSuite2 struct{ *testDBSuite } 137 type testDBSuite3 struct{ *testDBSuite } 138 type testDBSuite4 struct{ *testDBSuite } 139 type testDBSuite5 struct{ *testDBSuite } 140 type testDBSuite6 struct{ *testDBSuite } 141 type testDBSuite7 struct{ *testDBSuite } 142 type testSerialDBSuite struct{ *testDBSuite } 143 144 func testAddIndexWithPK(tk *testkit.TestKit, s *testSerialDBSuite, c *C) { 145 tk.MustInterDirc("drop causet if exists test_add_index_with_pk") 146 tk.MustInterDirc("create causet test_add_index_with_pk(a int not null, b int not null default '0', primary key(a))") 147 tk.MustInterDirc("insert into test_add_index_with_pk values(1, 2)") 148 tk.MustInterDirc("alter causet test_add_index_with_pk add index idx (a)") 149 tk.MustQuery("select a from test_add_index_with_pk").Check(testkit.Rows("1")) 150 tk.MustInterDirc("insert into test_add_index_with_pk values(2, 2)") 151 tk.MustInterDirc("alter causet test_add_index_with_pk add index idx1 (a, b)") 152 tk.MustQuery("select * from test_add_index_with_pk").Check(testkit.Rows("1 2", "2 2")) 153 tk.MustInterDirc("drop causet if exists test_add_index_with_pk1") 154 tk.MustInterDirc("create causet test_add_index_with_pk1(a int not null, b int not null default '0', c int, d int, primary key(c))") 155 tk.MustInterDirc("insert into test_add_index_with_pk1 values(1, 1, 1, 1)") 156 tk.MustInterDirc("alter causet test_add_index_with_pk1 add index idx (c)") 157 tk.MustInterDirc("insert into test_add_index_with_pk1 values(2, 2, 2, 2)") 158 tk.MustQuery("select * from test_add_index_with_pk1").Check(testkit.Rows("1 1 1 1", "2 2 2 2")) 159 tk.MustInterDirc("drop causet if exists test_add_index_with_pk2") 160 tk.MustInterDirc("create causet test_add_index_with_pk2(a int not null, b int not null default '0', c int unsigned, d int, primary key(c))") 161 tk.MustInterDirc("insert into test_add_index_with_pk2 values(1, 1, 1, 1)") 162 tk.MustInterDirc("alter causet test_add_index_with_pk2 add index idx (c)") 163 tk.MustInterDirc("insert into test_add_index_with_pk2 values(2, 2, 2, 2)") 164 tk.MustQuery("select * from test_add_index_with_pk2").Check(testkit.Rows("1 1 1 1", "2 2 2 2")) 165 tk.MustInterDirc("drop causet if exists t") 166 tk.MustInterDirc("create causet t (a int, b int, c int, primary key(a, b));") 167 tk.MustInterDirc("insert into t values (1, 2, 3);") 168 tk.MustInterDirc("create index idx on t (a, b);") 169 } 170 171 func (s *testSerialDBSuite) TestAddIndexWithPK(c *C) { 172 tk := testkit.NewTestKit(c, s.causetstore) 173 tk.MustInterDirc("use " + s.schemaName) 174 defer config.RestoreFunc()() 175 config.UFIDelateGlobal(func(conf *config.Config) { 176 conf.AlterPrimaryKey = false 177 }) 178 179 testAddIndexWithPK(tk, s, c) 180 tk.MustInterDirc("set @@milevadb_enable_clustered_index = 1;") 181 testAddIndexWithPK(tk, s, c) 182 } 183 184 func (s *testDBSuite5) TestAddIndexWithDupIndex(c *C) { 185 tk := testkit.NewTestKit(c, s.causetstore) 186 tk.MustInterDirc("use " + s.schemaName) 187 188 err1 := dbs.ErrDupKeyName.GenWithStack("index already exist %s", "idx") 189 err2 := dbs.ErrDupKeyName.GenWithStack("index already exist %s; "+ 190 "a background job is trying to add the same index, "+ 191 "please check by `ADMIN SHOW DBS JOBS`", "idx") 192 193 // When there is already an duplicate index, show error message. 194 tk.MustInterDirc("create causet test_add_index_with_dup (a int, key idx (a))") 195 _, err := tk.InterDirc("alter causet test_add_index_with_dup add index idx (a)") 196 c.Check(errors.Cause(err1).(*terror.Error).Equal(err), Equals, true) 197 c.Assert(errors.Cause(err1).Error() == err.Error(), IsTrue) 198 199 // When there is another stochastik adding duplicate index with state other than 200 // StatePublic, show explicit error message. 201 t := s.testGetBlock(c, "test_add_index_with_dup") 202 indexInfo := t.Meta().FindIndexByName("idx") 203 indexInfo.State = perceptron.StateNone 204 _, err = tk.InterDirc("alter causet test_add_index_with_dup add index idx (a)") 205 c.Check(errors.Cause(err2).(*terror.Error).Equal(err), Equals, true) 206 c.Assert(errors.Cause(err2).Error() == err.Error(), IsTrue) 207 208 tk.MustInterDirc("drop causet test_add_index_with_dup") 209 } 210 211 func (s *testDBSuite1) TestRenameIndex(c *C) { 212 tk := testkit.NewTestKit(c, s.causetstore) 213 tk.MustInterDirc("use " + s.schemaName) 214 tk.MustInterDirc("create causet t (pk int primary key, c int default 1, c1 int default 1, unique key k1(c), key k2(c1))") 215 216 // Test rename success 217 tk.MustInterDirc("alter causet t rename index k1 to k3") 218 tk.MustInterDirc("admin check index t k3") 219 220 // Test rename to the same name 221 tk.MustInterDirc("alter causet t rename index k3 to k3") 222 tk.MustInterDirc("admin check index t k3") 223 224 // Test rename on non-exists keys 225 tk.MustGetErrCode("alter causet t rename index x to x", errno.ErrKeyDoesNotExist) 226 227 // Test rename on already-exists keys 228 tk.MustGetErrCode("alter causet t rename index k3 to k2", errno.ErrDupKeyName) 229 230 tk.MustInterDirc("alter causet t rename index k2 to K2") 231 tk.MustGetErrCode("alter causet t rename key k3 to K2", errno.ErrDupKeyName) 232 } 233 234 func testGetBlockByName(c *C, ctx stochastikctx.Context, EDB, causet string) causet.Block { 235 dom := petri.GetPetri(ctx) 236 // Make sure the causet schemaReplicant is the new schemaReplicant. 237 err := dom.Reload() 238 c.Assert(err, IsNil) 239 tbl, err := dom.SchemaReplicant().BlockByName(perceptron.NewCIStr(EDB), perceptron.NewCIStr(causet)) 240 c.Assert(err, IsNil) 241 return tbl 242 } 243 244 func testGetSchemaByName(c *C, ctx stochastikctx.Context, EDB string) *perceptron.DBInfo { 245 dom := petri.GetPetri(ctx) 246 // Make sure the causet schemaReplicant is the new schemaReplicant. 247 err := dom.Reload() 248 c.Assert(err, IsNil) 249 dbInfo, ok := dom.SchemaReplicant().SchemaByName(perceptron.NewCIStr(EDB)) 250 c.Assert(ok, IsTrue) 251 return dbInfo 252 } 253 254 func (s *testDBSuite) testGetBlock(c *C, name string) causet.Block { 255 ctx := s.s.(stochastikctx.Context) 256 return testGetBlockByName(c, ctx, s.schemaName, name) 257 } 258 259 func (s *testDBSuite) testGetDB(c *C, dbName string) *perceptron.DBInfo { 260 ctx := s.s.(stochastikctx.Context) 261 dom := petri.GetPetri(ctx) 262 // Make sure the causet schemaReplicant is the new schemaReplicant. 263 err := dom.Reload() 264 c.Assert(err, IsNil) 265 EDB, ok := dom.SchemaReplicant().SchemaByName(perceptron.NewCIStr(dbName)) 266 c.Assert(ok, IsTrue) 267 return EDB 268 } 269 270 func backgroundInterDirc(s ekv.CausetStorage, allegrosql string, done chan error) { 271 se, err := stochastik.CreateStochastik4Test(s) 272 if err != nil { 273 done <- errors.Trace(err) 274 return 275 } 276 defer se.Close() 277 _, err = se.InterDircute(context.Background(), "use test_db") 278 if err != nil { 279 done <- errors.Trace(err) 280 return 281 } 282 _, err = se.InterDircute(context.Background(), allegrosql) 283 done <- errors.Trace(err) 284 } 285 286 // TestAddPrimaryKeyRollback1 is used to test scenarios that will roll back when a duplicate primary key is encountered. 287 func (s *testDBSuite5) TestAddPrimaryKeyRollback1(c *C) { 288 hasNullValsInKey := false 289 idxName := "PRIMARY" 290 addIdxALLEGROSQL := "alter causet t1 add primary key c3_index (c3);" 291 errMsg := "[ekv:1062]Duplicate entry '' for key 'PRIMARY'" 292 testAddIndexRollback(c, s.causetstore, s.lease, idxName, addIdxALLEGROSQL, errMsg, hasNullValsInKey) 293 } 294 295 // TestAddPrimaryKeyRollback2 is used to test scenarios that will roll back when a null primary key is encountered. 296 func (s *testDBSuite1) TestAddPrimaryKeyRollback2(c *C) { 297 hasNullValsInKey := true 298 idxName := "PRIMARY" 299 addIdxALLEGROSQL := "alter causet t1 add primary key c3_index (c3);" 300 errMsg := "[dbs:1138]Invalid use of NULL value" 301 testAddIndexRollback(c, s.causetstore, s.lease, idxName, addIdxALLEGROSQL, errMsg, hasNullValsInKey) 302 } 303 304 func (s *testDBSuite2) TestAddUniqueIndexRollback(c *C) { 305 hasNullValsInKey := false 306 idxName := "c3_index" 307 addIdxALLEGROSQL := "create unique index c3_index on t1 (c3)" 308 errMsg := "[ekv:1062]Duplicate entry '' for key 'c3_index'" 309 testAddIndexRollback(c, s.causetstore, s.lease, idxName, addIdxALLEGROSQL, errMsg, hasNullValsInKey) 310 } 311 312 func (s *testSerialDBSuite) TestAddExpressionIndexRollback(c *C) { 313 tk := testkit.NewTestKit(c, s.causetstore) 314 tk.MustInterDirc("use test_db") 315 tk.MustInterDirc("drop causet if exists t1") 316 tk.MustInterDirc("create causet t1 (c1 int, c2 int, c3 int, unique key(c1))") 317 tk.MustInterDirc("insert into t1 values (20, 20, 20), (40, 40, 40), (80, 80, 80), (160, 160, 160);") 318 319 var checkErr error 320 tk1 := testkit.NewTestKit(c, s.causetstore) 321 _, checkErr = tk1.InterDirc("use test_db") 322 323 d := s.dom.DBS() 324 hook := &dbs.TestDBSCallback{} 325 hook.OnJobUFIDelatedExported = func(job *perceptron.Job) { 326 if job.SchemaState == perceptron.StateDeleteOnly { 327 if checkErr != nil { 328 return 329 } 330 _, checkErr = tk1.InterDirc("delete from t1 where c1 = 40;") 331 } 332 } 333 d.(dbs.DBSForTest).SetHook(hook) 334 335 tk.MustGetErrMsg("alter causet t1 add index expr_idx ((pow(c1, c2)));", "[dbs:8202]Cannot decode index value, because [types:1690]DOUBLE value is out of range in 'pow(160, 160)'") 336 c.Assert(checkErr, IsNil) 337 tk.MustQuery("select * from t1;").Check(testkit.Rows("20 20 20", "80 80 80", "160 160 160")) 338 } 339 340 func batchInsert(tk *testkit.TestKit, tbl string, start, end int) { 341 dml := fmt.Sprintf("insert into %s values", tbl) 342 for i := start; i < end; i++ { 343 dml += fmt.Sprintf("(%d, %d, %d)", i, i, i) 344 if i != end-1 { 345 dml += "," 346 } 347 } 348 tk.MustInterDirc(dml) 349 } 350 351 func testAddIndexRollback(c *C, causetstore ekv.CausetStorage, lease time.Duration, idxName, addIdxALLEGROSQL, errMsg string, hasNullValsInKey bool) { 352 tk := testkit.NewTestKit(c, causetstore) 353 tk.MustInterDirc("use test_db") 354 tk.MustInterDirc("drop causet if exists t1") 355 tk.MustInterDirc("create causet t1 (c1 int, c2 int, c3 int, unique key(c1))") 356 // defaultBatchSize is equal to dbs.defaultBatchSize 357 base := defaultBatchSize * 2 358 count := base 359 // add some rows 360 batchInsert(tk, "t1", 0, count) 361 // add some null rows 362 if hasNullValsInKey { 363 for i := count - 10; i < count; i++ { 364 tk.MustInterDirc("insert into t1 values (?, ?, null)", i+10, i) 365 } 366 } else { 367 // add some duplicate rows 368 for i := count - 10; i < count; i++ { 369 tk.MustInterDirc("insert into t1 values (?, ?, ?)", i+10, i, i) 370 } 371 } 372 373 done := make(chan error, 1) 374 go backgroundInterDirc(causetstore, addIdxALLEGROSQL, done) 375 376 times := 0 377 ticker := time.NewTicker(lease / 2) 378 defer ticker.Stop() 379 LOOP: 380 for { 381 select { 382 case err := <-done: 383 c.Assert(err, NotNil) 384 c.Assert(err.Error(), Equals, errMsg, Commentf("err:%v", err)) 385 break LOOP 386 case <-ticker.C: 387 if times >= 10 { 388 break 389 } 390 step := 5 391 // delete some rows, and add some data 392 for i := count; i < count+step; i++ { 393 n := rand.Intn(count) 394 tk.MustInterDirc("delete from t1 where c1 = ?", n) 395 tk.MustInterDirc("insert into t1 values (?, ?, ?)", i+10, i, i) 396 } 397 count += step 398 times++ 399 } 400 } 401 402 ctx := tk.Se.(stochastikctx.Context) 403 t := testGetBlockByName(c, ctx, "test_db", "t1") 404 for _, tidx := range t.Indices() { 405 c.Assert(strings.EqualFold(tidx.Meta().Name.L, idxName), IsFalse) 406 } 407 408 // delete duplicated/null rows, then add index 409 for i := base - 10; i < base; i++ { 410 tk.MustInterDirc("delete from t1 where c1 = ?", i+10) 411 } 412 stochastikInterDirc(c, causetstore, addIdxALLEGROSQL) 413 tk.MustInterDirc("drop causet t1") 414 } 415 416 func (s *testDBSuite5) TestCancelAddPrimaryKey(c *C) { 417 idxName := "primary" 418 addIdxALLEGROSQL := "alter causet t1 add primary key idx_c2 (c2);" 419 testCancelAddIndex(c, s.causetstore, s.dom.DBS(), s.lease, idxName, addIdxALLEGROSQL, "") 420 421 // Check the defCausumn's flag when the "add primary key" failed. 422 tk := testkit.NewTestKit(c, s.causetstore) 423 tk.MustInterDirc("use test_db") 424 ctx := tk.Se.(stochastikctx.Context) 425 c.Assert(ctx.NewTxn(context.Background()), IsNil) 426 t := testGetBlockByName(c, ctx, "test_db", "t1") 427 defCaus1Flag := t.DefCauss()[1].Flag 428 c.Assert(!allegrosql.HasNotNullFlag(defCaus1Flag) && !allegrosql.HasPreventNullInsertFlag(defCaus1Flag) && allegrosql.HasUnsignedFlag(defCaus1Flag), IsTrue) 429 tk.MustInterDirc("drop causet t1") 430 } 431 432 func (s *testDBSuite3) TestCancelAddIndex(c *C) { 433 idxName := "c3_index " 434 addIdxALLEGROSQL := "create unique index c3_index on t1 (c3)" 435 testCancelAddIndex(c, s.causetstore, s.dom.DBS(), s.lease, idxName, addIdxALLEGROSQL, "") 436 437 tk := testkit.NewTestKit(c, s.causetstore) 438 tk.MustInterDirc("use test_db") 439 tk.MustInterDirc("drop causet t1") 440 } 441 442 func testCancelAddIndex(c *C, causetstore ekv.CausetStorage, d dbs.DBS, lease time.Duration, idxName, addIdxALLEGROSQL, sqlModeALLEGROSQL string) { 443 tk := testkit.NewTestKit(c, causetstore) 444 tk.MustInterDirc("use test_db") 445 tk.MustInterDirc("drop causet if exists t1") 446 tk.MustInterDirc("create causet t1 (c1 int, c2 int unsigned, c3 int, unique key(c1))") 447 // defaultBatchSize is equal to dbs.defaultBatchSize 448 count := defaultBatchSize * 32 449 start := 0 450 // add some rows 451 if len(sqlModeALLEGROSQL) != 0 { 452 // Insert some null values. 453 tk.MustInterDirc(sqlModeALLEGROSQL) 454 tk.MustInterDirc("insert into t1 set c1 = ?", 0) 455 tk.MustInterDirc("insert into t1 set c2 = ?", 1) 456 tk.MustInterDirc("insert into t1 set c3 = ?", 2) 457 start = 3 458 } 459 for i := start; i < count; i += defaultBatchSize { 460 batchInsert(tk, "t1", i, i+defaultBatchSize) 461 } 462 463 var c3IdxInfo *perceptron.IndexInfo 464 hook := &dbs.TestDBSCallback{} 465 originBatchSize := tk.MustQuery("select @@global.milevadb_dbs_reorg_batch_size") 466 // Set batch size to lower try to slow down add-index reorganization, This if for hook to cancel this dbs job. 467 tk.MustInterDirc("set @@global.milevadb_dbs_reorg_batch_size = 32") 468 defer tk.MustInterDirc(fmt.Sprintf("set @@global.milevadb_dbs_reorg_batch_size = %v", originBatchSize.Rows()[0][0])) 469 // let hook.OnJobUFIDelatedExported has chance to cancel the job. 470 // the hook.OnJobUFIDelatedExported is called when the job is uFIDelated, runReorgJob will wait dbs.ReorgWaitTimeout, then return the dbs.runDBSJob. 471 // After that dbs call d.hook.OnJobUFIDelated(job), so that we can canceled the job in this test case. 472 var checkErr error 473 ctx := tk.Se.(stochastikctx.Context) 474 hook.OnJobUFIDelatedExported, c3IdxInfo, checkErr = backgroundInterDircOnJobUFIDelatedExported(c, causetstore, ctx, hook, idxName) 475 originalHook := d.GetHook() 476 d.(dbs.DBSForTest).SetHook(hook) 477 done := make(chan error, 1) 478 go backgroundInterDirc(causetstore, addIdxALLEGROSQL, done) 479 480 times := 0 481 ticker := time.NewTicker(lease / 2) 482 defer ticker.Stop() 483 LOOP: 484 for { 485 select { 486 case err := <-done: 487 c.Assert(checkErr, IsNil) 488 c.Assert(err, NotNil) 489 c.Assert(err.Error(), Equals, "[dbs:8214]Cancelled DBS job") 490 break LOOP 491 case <-ticker.C: 492 if times >= 10 { 493 break 494 } 495 step := 5 496 // delete some rows, and add some data 497 for i := count; i < count+step; i++ { 498 n := rand.Intn(count) 499 tk.MustInterDirc("delete from t1 where c1 = ?", n) 500 tk.MustInterDirc("insert into t1 values (?, ?, ?)", i+10, i, i) 501 } 502 count += step 503 times++ 504 } 505 } 506 507 t := testGetBlockByName(c, ctx, "test_db", "t1") 508 for _, tidx := range t.Indices() { 509 c.Assert(strings.EqualFold(tidx.Meta().Name.L, idxName), IsFalse) 510 } 511 512 idx := blocks.NewIndex(t.Meta().ID, t.Meta(), c3IdxInfo) 513 checkDelRangeDone(c, ctx, idx) 514 d.(dbs.DBSForTest).SetHook(originalHook) 515 } 516 517 // TestCancelAddIndex1 tests canceling dbs job when the add index worker is not started. 518 func (s *testDBSuite4) TestCancelAddIndex1(c *C) { 519 tk := testkit.NewTestKit(c, s.causetstore) 520 s.mustInterDirc(tk, c, "use test_db") 521 s.mustInterDirc(tk, c, "drop causet if exists t") 522 s.mustInterDirc(tk, c, "create causet t(c1 int, c2 int)") 523 defer s.mustInterDirc(tk, c, "drop causet t;") 524 525 for i := 0; i < 50; i++ { 526 s.mustInterDirc(tk, c, "insert into t values (?, ?)", i, i) 527 } 528 529 var checkErr error 530 hook := &dbs.TestDBSCallback{} 531 hook.OnJobRunBeforeExported = func(job *perceptron.Job) { 532 if job.Type == perceptron.CausetActionAddIndex && job.State == perceptron.JobStateRunning && job.SchemaState == perceptron.StateWriteReorganization && job.SnapshotVer == 0 { 533 jobIDs := []int64{job.ID} 534 hookCtx := mock.NewContext() 535 hookCtx.CausetStore = s.causetstore 536 err := hookCtx.NewTxn(context.Background()) 537 if err != nil { 538 checkErr = errors.Trace(err) 539 return 540 } 541 txn, err := hookCtx.Txn(true) 542 if err != nil { 543 checkErr = errors.Trace(err) 544 return 545 } 546 errs, err := admin.CancelJobs(txn, jobIDs) 547 if err != nil { 548 checkErr = errors.Trace(err) 549 return 550 } 551 552 if errs[0] != nil { 553 checkErr = errors.Trace(errs[0]) 554 return 555 } 556 557 checkErr = txn.Commit(context.Background()) 558 } 559 } 560 originalHook := s.dom.DBS().GetHook() 561 s.dom.DBS().(dbs.DBSForTest).SetHook(hook) 562 rs, err := tk.InterDirc("alter causet t add index idx_c2(c2)") 563 if rs != nil { 564 rs.Close() 565 } 566 c.Assert(checkErr, IsNil) 567 c.Assert(err, NotNil) 568 c.Assert(err.Error(), Equals, "[dbs:8214]Cancelled DBS job") 569 570 s.dom.DBS().(dbs.DBSForTest).SetHook(originalHook) 571 t := s.testGetBlock(c, "t") 572 for _, idx := range t.Indices() { 573 c.Assert(strings.EqualFold(idx.Meta().Name.L, "idx_c2"), IsFalse) 574 } 575 s.mustInterDirc(tk, c, "alter causet t add index idx_c2(c2)") 576 s.mustInterDirc(tk, c, "alter causet t drop index idx_c2") 577 } 578 579 // TestCancelDropIndex tests cancel dbs job which type is drop primary key. 580 func (s *testDBSuite4) TestCancelDropPrimaryKey(c *C) { 581 idxName := "primary" 582 addIdxALLEGROSQL := "alter causet t add primary key idx_c2 (c2);" 583 dropIdxALLEGROSQL := "alter causet t drop primary key;" 584 testCancelDropIndex(c, s.causetstore, s.dom.DBS(), idxName, addIdxALLEGROSQL, dropIdxALLEGROSQL) 585 } 586 587 // TestCancelDropIndex tests cancel dbs job which type is drop index. 588 func (s *testDBSuite5) TestCancelDropIndex(c *C) { 589 idxName := "idx_c2" 590 addIdxALLEGROSQL := "alter causet t add index idx_c2 (c2);" 591 dropIdxALLEGROSQL := "alter causet t drop index idx_c2;" 592 testCancelDropIndex(c, s.causetstore, s.dom.DBS(), idxName, addIdxALLEGROSQL, dropIdxALLEGROSQL) 593 } 594 595 // testCancelDropIndex tests cancel dbs job which type is drop index. 596 func testCancelDropIndex(c *C, causetstore ekv.CausetStorage, d dbs.DBS, idxName, addIdxALLEGROSQL, dropIdxALLEGROSQL string) { 597 tk := testkit.NewTestKit(c, causetstore) 598 tk.MustInterDirc("use test_db") 599 tk.MustInterDirc("drop causet if exists t") 600 tk.MustInterDirc("create causet t(c1 int, c2 int)") 601 defer tk.MustInterDirc("drop causet t;") 602 for i := 0; i < 5; i++ { 603 tk.MustInterDirc("insert into t values (?, ?)", i, i) 604 } 605 testCases := []struct { 606 needAddIndex bool 607 jobState perceptron.JobState 608 JobSchemaState perceptron.SchemaState 609 cancelSucc bool 610 }{ 611 // perceptron.JobStateNone means the jobs is canceled before the first run. 612 // if we cancel successfully, we need to set needAddIndex to false in the next test case. Otherwise, set needAddIndex to true. 613 {true, perceptron.JobStateNone, perceptron.StateNone, true}, 614 {false, perceptron.JobStateRunning, perceptron.StateWriteOnly, false}, 615 {true, perceptron.JobStateRunning, perceptron.StateDeleteOnly, false}, 616 {true, perceptron.JobStateRunning, perceptron.StateDeleteReorganization, false}, 617 } 618 var checkErr error 619 hook := &dbs.TestDBSCallback{} 620 var jobID int64 621 testCase := &testCases[0] 622 hook.OnJobRunBeforeExported = func(job *perceptron.Job) { 623 if (job.Type == perceptron.CausetActionDropIndex || job.Type == perceptron.CausetActionDropPrimaryKey) && 624 job.State == testCase.jobState && job.SchemaState == testCase.JobSchemaState { 625 jobID = job.ID 626 jobIDs := []int64{job.ID} 627 hookCtx := mock.NewContext() 628 hookCtx.CausetStore = causetstore 629 err := hookCtx.NewTxn(context.TODO()) 630 if err != nil { 631 checkErr = errors.Trace(err) 632 return 633 } 634 txn, err := hookCtx.Txn(true) 635 if err != nil { 636 checkErr = errors.Trace(err) 637 return 638 } 639 640 errs, err := admin.CancelJobs(txn, jobIDs) 641 if err != nil { 642 checkErr = errors.Trace(err) 643 return 644 } 645 if errs[0] != nil { 646 checkErr = errors.Trace(errs[0]) 647 return 648 } 649 checkErr = txn.Commit(context.Background()) 650 } 651 } 652 originalHook := d.GetHook() 653 d.(dbs.DBSForTest).SetHook(hook) 654 ctx := tk.Se.(stochastikctx.Context) 655 for i := range testCases { 656 testCase = &testCases[i] 657 if testCase.needAddIndex { 658 tk.MustInterDirc(addIdxALLEGROSQL) 659 } 660 rs, err := tk.InterDirc(dropIdxALLEGROSQL) 661 if rs != nil { 662 rs.Close() 663 } 664 t := testGetBlockByName(c, ctx, "test_db", "t") 665 indexInfo := t.Meta().FindIndexByName(idxName) 666 if testCase.cancelSucc { 667 c.Assert(checkErr, IsNil) 668 c.Assert(err, NotNil) 669 c.Assert(err.Error(), Equals, "[dbs:8214]Cancelled DBS job") 670 c.Assert(indexInfo, NotNil) 671 c.Assert(indexInfo.State, Equals, perceptron.StatePublic) 672 } else { 673 err1 := admin.ErrCannotCancelDBSJob.GenWithStackByArgs(jobID) 674 c.Assert(err, IsNil) 675 c.Assert(checkErr, NotNil) 676 c.Assert(checkErr.Error(), Equals, err1.Error()) 677 c.Assert(indexInfo, IsNil) 678 } 679 } 680 d.(dbs.DBSForTest).SetHook(originalHook) 681 tk.MustInterDirc(addIdxALLEGROSQL) 682 tk.MustInterDirc(dropIdxALLEGROSQL) 683 } 684 685 // TestCancelTruncateBlock tests cancel dbs job which type is truncate causet. 686 func (s *testDBSuite5) TestCancelTruncateBlock(c *C) { 687 tk := testkit.NewTestKit(c, s.causetstore) 688 s.mustInterDirc(tk, c, "use test_db") 689 s.mustInterDirc(tk, c, "create database if not exists test_truncate_block") 690 s.mustInterDirc(tk, c, "drop causet if exists t") 691 s.mustInterDirc(tk, c, "create causet t(c1 int, c2 int)") 692 defer s.mustInterDirc(tk, c, "drop causet t;") 693 var checkErr error 694 hook := &dbs.TestDBSCallback{} 695 hook.OnJobRunBeforeExported = func(job *perceptron.Job) { 696 if job.Type == perceptron.CausetActionTruncateBlock && job.State == perceptron.JobStateNone { 697 jobIDs := []int64{job.ID} 698 hookCtx := mock.NewContext() 699 hookCtx.CausetStore = s.causetstore 700 err := hookCtx.NewTxn(context.Background()) 701 if err != nil { 702 checkErr = errors.Trace(err) 703 return 704 } 705 txn, err := hookCtx.Txn(true) 706 if err != nil { 707 checkErr = errors.Trace(err) 708 return 709 } 710 errs, err := admin.CancelJobs(txn, jobIDs) 711 if err != nil { 712 checkErr = errors.Trace(err) 713 return 714 } 715 if errs[0] != nil { 716 checkErr = errors.Trace(errs[0]) 717 return 718 } 719 checkErr = txn.Commit(context.Background()) 720 } 721 } 722 originalHook := s.dom.DBS().GetHook() 723 s.dom.DBS().(dbs.DBSForTest).SetHook(hook) 724 _, err := tk.InterDirc("truncate causet t") 725 c.Assert(checkErr, IsNil) 726 c.Assert(err, NotNil) 727 c.Assert(err.Error(), Equals, "[dbs:8214]Cancelled DBS job") 728 s.dom.DBS().(dbs.DBSForTest).SetHook(originalHook) 729 } 730 731 func (s *testDBSuite5) TestParallelDropSchemaAndDropBlock(c *C) { 732 tk := testkit.NewTestKit(c, s.causetstore) 733 s.mustInterDirc(tk, c, "create database if not exists test_drop_schema_block") 734 s.mustInterDirc(tk, c, "use test_drop_schema_block") 735 s.mustInterDirc(tk, c, "create causet t(c1 int, c2 int)") 736 var checkErr error 737 hook := &dbs.TestDBSCallback{} 738 dbInfo := testGetSchemaByName(c, tk.Se, "test_drop_schema_block") 739 done := false 740 var wg sync.WaitGroup 741 tk2 := testkit.NewTestKit(c, s.causetstore) 742 tk2.MustInterDirc("use test_drop_schema_block") 743 hook.OnJobUFIDelatedExported = func(job *perceptron.Job) { 744 if job.Type == perceptron.CausetActionDropSchema && job.State == perceptron.JobStateRunning && 745 job.SchemaState == perceptron.StateWriteOnly && job.SchemaID == dbInfo.ID && done == false { 746 wg.Add(1) 747 done = true 748 go func() { 749 _, checkErr = tk2.InterDirc("drop causet t") 750 wg.Done() 751 }() 752 time.Sleep(5 * time.Millisecond) 753 } 754 } 755 originalHook := s.dom.DBS().GetHook() 756 s.dom.DBS().(dbs.DBSForTest).SetHook(hook) 757 s.mustInterDirc(tk, c, "drop database test_drop_schema_block") 758 s.dom.DBS().(dbs.DBSForTest).SetHook(originalHook) 759 wg.Wait() 760 c.Assert(done, IsTrue) 761 c.Assert(checkErr, NotNil) 762 // There are two possible assert result because: 763 // 1: If drop-database is finished before drop-causet being put into the dbs job queue, it will return "unknown causet" error directly in the previous check. 764 // 2: If drop-causet has passed the previous check and been put into the dbs job queue, then drop-database finished, it will return schemaReplicant change error. 765 assertRes := checkErr.Error() == "[petri:8028]Information schemaReplicant is changed during the execution of the"+ 766 " memex(for example, causet definition may be uFIDelated by other DBS ran in parallel). "+ 767 "If you see this error often, try increasing `milevadb_max_delta_schema_count`. [try again later]" || 768 checkErr.Error() == "[schemaReplicant:1051]Unknown causet 'test_drop_schema_block.t'" 769 770 c.Assert(assertRes, Equals, true) 771 772 // Below behaviour is use to mock query `curl "http://$IP:10080/tiflash/replica"` 773 fn := func(jobs []*perceptron.Job) (bool, error) { 774 return interlock.GetDropOrTruncateBlockInfoFromJobs(jobs, 0, s.dom, func(job *perceptron.Job, info *perceptron.BlockInfo) (bool, error) { 775 return false, nil 776 }) 777 } 778 err := tk.Se.NewTxn(context.Background()) 779 c.Assert(err, IsNil) 780 txn, err := tk.Se.Txn(true) 781 c.Assert(err, IsNil) 782 err = admin.IterHistoryDBSJobs(txn, fn) 783 c.Assert(err, IsNil) 784 } 785 786 // TestCancelRenameIndex tests cancel dbs job which type is rename index. 787 func (s *testDBSuite1) TestCancelRenameIndex(c *C) { 788 tk := testkit.NewTestKit(c, s.causetstore) 789 s.mustInterDirc(tk, c, "use test_db") 790 s.mustInterDirc(tk, c, "create database if not exists test_rename_index") 791 s.mustInterDirc(tk, c, "drop causet if exists t") 792 s.mustInterDirc(tk, c, "create causet t(c1 int, c2 int)") 793 defer s.mustInterDirc(tk, c, "drop causet t;") 794 for i := 0; i < 100; i++ { 795 s.mustInterDirc(tk, c, "insert into t values (?, ?)", i, i) 796 } 797 s.mustInterDirc(tk, c, "alter causet t add index idx_c2(c2)") 798 var checkErr error 799 hook := &dbs.TestDBSCallback{} 800 hook.OnJobRunBeforeExported = func(job *perceptron.Job) { 801 if job.Type == perceptron.CausetActionRenameIndex && job.State == perceptron.JobStateNone { 802 jobIDs := []int64{job.ID} 803 hookCtx := mock.NewContext() 804 hookCtx.CausetStore = s.causetstore 805 err := hookCtx.NewTxn(context.Background()) 806 if err != nil { 807 checkErr = errors.Trace(err) 808 return 809 } 810 txn, err := hookCtx.Txn(true) 811 if err != nil { 812 checkErr = errors.Trace(err) 813 return 814 } 815 errs, err := admin.CancelJobs(txn, jobIDs) 816 if err != nil { 817 checkErr = errors.Trace(err) 818 return 819 } 820 if errs[0] != nil { 821 checkErr = errors.Trace(errs[0]) 822 return 823 } 824 checkErr = txn.Commit(context.Background()) 825 } 826 } 827 originalHook := s.dom.DBS().GetHook() 828 s.dom.DBS().(dbs.DBSForTest).SetHook(hook) 829 rs, err := tk.InterDirc("alter causet t rename index idx_c2 to idx_c3") 830 if rs != nil { 831 rs.Close() 832 } 833 c.Assert(checkErr, IsNil) 834 c.Assert(err, NotNil) 835 c.Assert(err.Error(), Equals, "[dbs:8214]Cancelled DBS job") 836 s.dom.DBS().(dbs.DBSForTest).SetHook(originalHook) 837 t := s.testGetBlock(c, "t") 838 for _, idx := range t.Indices() { 839 c.Assert(strings.EqualFold(idx.Meta().Name.L, "idx_c3"), IsFalse) 840 } 841 s.mustInterDirc(tk, c, "alter causet t rename index idx_c2 to idx_c3") 842 } 843 844 // TestCancelDropBlock tests cancel dbs job which type is drop causet. 845 func (s *testDBSuite2) TestCancelDropBlockAndSchema(c *C) { 846 tk := testkit.NewTestKit(c, s.causetstore) 847 testCases := []struct { 848 needAddBlockOrDB bool 849 action perceptron.CausetActionType 850 jobState perceptron.JobState 851 JobSchemaState perceptron.SchemaState 852 cancelSucc bool 853 }{ 854 // Check drop causet. 855 // perceptron.JobStateNone means the jobs is canceled before the first run. 856 {true, perceptron.CausetActionDropBlock, perceptron.JobStateNone, perceptron.StateNone, true}, 857 {false, perceptron.CausetActionDropBlock, perceptron.JobStateRunning, perceptron.StateWriteOnly, false}, 858 {true, perceptron.CausetActionDropBlock, perceptron.JobStateRunning, perceptron.StateDeleteOnly, false}, 859 860 // Check drop database. 861 {true, perceptron.CausetActionDropSchema, perceptron.JobStateNone, perceptron.StateNone, true}, 862 {false, perceptron.CausetActionDropSchema, perceptron.JobStateRunning, perceptron.StateWriteOnly, false}, 863 {true, perceptron.CausetActionDropSchema, perceptron.JobStateRunning, perceptron.StateDeleteOnly, false}, 864 } 865 var checkErr error 866 hook := &dbs.TestDBSCallback{} 867 var jobID int64 868 testCase := &testCases[0] 869 s.mustInterDirc(tk, c, "create database if not exists test_drop_db") 870 dbInfo := s.testGetDB(c, "test_drop_db") 871 872 hook.OnJobRunBeforeExported = func(job *perceptron.Job) { 873 if job.Type == testCase.action && job.State == testCase.jobState && job.SchemaState == testCase.JobSchemaState && job.SchemaID == dbInfo.ID { 874 jobIDs := []int64{job.ID} 875 jobID = job.ID 876 hookCtx := mock.NewContext() 877 hookCtx.CausetStore = s.causetstore 878 err := hookCtx.NewTxn(context.TODO()) 879 if err != nil { 880 checkErr = errors.Trace(err) 881 return 882 } 883 txn, err := hookCtx.Txn(true) 884 if err != nil { 885 checkErr = errors.Trace(err) 886 return 887 } 888 errs, err := admin.CancelJobs(txn, jobIDs) 889 if err != nil { 890 checkErr = errors.Trace(err) 891 return 892 } 893 if errs[0] != nil { 894 checkErr = errors.Trace(errs[0]) 895 return 896 } 897 checkErr = txn.Commit(context.Background()) 898 } 899 } 900 originHook := s.dom.DBS().GetHook() 901 defer s.dom.DBS().(dbs.DBSForTest).SetHook(originHook) 902 s.dom.DBS().(dbs.DBSForTest).SetHook(hook) 903 var err error 904 allegrosql := "" 905 for i := range testCases { 906 testCase = &testCases[i] 907 if testCase.needAddBlockOrDB { 908 s.mustInterDirc(tk, c, "create database if not exists test_drop_db") 909 s.mustInterDirc(tk, c, "use test_drop_db") 910 s.mustInterDirc(tk, c, "create causet if not exists t(c1 int, c2 int)") 911 } 912 913 dbInfo = s.testGetDB(c, "test_drop_db") 914 915 if testCase.action == perceptron.CausetActionDropBlock { 916 allegrosql = "drop causet t;" 917 } else if testCase.action == perceptron.CausetActionDropSchema { 918 allegrosql = "drop database test_drop_db;" 919 } 920 921 _, err = tk.InterDirc(allegrosql) 922 if testCase.cancelSucc { 923 c.Assert(checkErr, IsNil) 924 c.Assert(err, NotNil) 925 c.Assert(err.Error(), Equals, "[dbs:8214]Cancelled DBS job") 926 s.mustInterDirc(tk, c, "insert into t values (?, ?)", i, i) 927 } else { 928 c.Assert(err, IsNil) 929 c.Assert(checkErr, NotNil) 930 c.Assert(checkErr.Error(), Equals, admin.ErrCannotCancelDBSJob.GenWithStackByArgs(jobID).Error()) 931 _, err = tk.InterDirc("insert into t values (?, ?)", i, i) 932 c.Assert(err, NotNil) 933 } 934 } 935 } 936 937 func (s *testDBSuite3) TestAddAnonymousIndex(c *C) { 938 tk := testkit.NewTestKit(c, s.causetstore) 939 tk.MustInterDirc("use " + s.schemaName) 940 s.mustInterDirc(tk, c, "create causet t_anonymous_index (c1 int, c2 int, C3 int)") 941 s.mustInterDirc(tk, c, "alter causet t_anonymous_index add index (c1, c2)") 942 // for dropping empty index 943 _, err := tk.InterDirc("alter causet t_anonymous_index drop index") 944 c.Assert(err, NotNil) 945 // The index name is c1 when adding index (c1, c2). 946 s.mustInterDirc(tk, c, "alter causet t_anonymous_index drop index c1") 947 t := s.testGetBlock(c, "t_anonymous_index") 948 c.Assert(t.Indices(), HasLen, 0) 949 // for adding some indices that the first defCausumn name is c1 950 s.mustInterDirc(tk, c, "alter causet t_anonymous_index add index (c1)") 951 _, err = tk.InterDirc("alter causet t_anonymous_index add index c1 (c2)") 952 c.Assert(err, NotNil) 953 t = s.testGetBlock(c, "t_anonymous_index") 954 c.Assert(t.Indices(), HasLen, 1) 955 idx := t.Indices()[0].Meta().Name.L 956 c.Assert(idx, Equals, "c1") 957 // The MyALLEGROSQL will be a warning. 958 s.mustInterDirc(tk, c, "alter causet t_anonymous_index add index c1_3 (c1)") 959 s.mustInterDirc(tk, c, "alter causet t_anonymous_index add index (c1, c2, C3)") 960 // The MyALLEGROSQL will be a warning. 961 s.mustInterDirc(tk, c, "alter causet t_anonymous_index add index (c1)") 962 t = s.testGetBlock(c, "t_anonymous_index") 963 c.Assert(t.Indices(), HasLen, 4) 964 s.mustInterDirc(tk, c, "alter causet t_anonymous_index drop index c1") 965 s.mustInterDirc(tk, c, "alter causet t_anonymous_index drop index c1_2") 966 s.mustInterDirc(tk, c, "alter causet t_anonymous_index drop index c1_3") 967 s.mustInterDirc(tk, c, "alter causet t_anonymous_index drop index c1_4") 968 // for case insensitive 969 s.mustInterDirc(tk, c, "alter causet t_anonymous_index add index (C3)") 970 s.mustInterDirc(tk, c, "alter causet t_anonymous_index drop index c3") 971 s.mustInterDirc(tk, c, "alter causet t_anonymous_index add index c3 (C3)") 972 s.mustInterDirc(tk, c, "alter causet t_anonymous_index drop index C3") 973 // for anonymous index with defCausumn name `primary` 974 s.mustInterDirc(tk, c, "create causet t_primary (`primary` int, b int, key (`primary`))") 975 t = s.testGetBlock(c, "t_primary") 976 c.Assert(t.Indices()[0].Meta().Name.String(), Equals, "primary_2") 977 s.mustInterDirc(tk, c, "alter causet t_primary add index (`primary`);") 978 t = s.testGetBlock(c, "t_primary") 979 c.Assert(t.Indices()[0].Meta().Name.String(), Equals, "primary_2") 980 c.Assert(t.Indices()[1].Meta().Name.String(), Equals, "primary_3") 981 s.mustInterDirc(tk, c, "alter causet t_primary add primary key(b);") 982 t = s.testGetBlock(c, "t_primary") 983 c.Assert(t.Indices()[0].Meta().Name.String(), Equals, "primary_2") 984 c.Assert(t.Indices()[1].Meta().Name.String(), Equals, "primary_3") 985 c.Assert(t.Indices()[2].Meta().Name.L, Equals, "primary") 986 s.mustInterDirc(tk, c, "create causet t_primary_2 (`primary` int, key primary_2 (`primary`), key (`primary`))") 987 t = s.testGetBlock(c, "t_primary_2") 988 c.Assert(t.Indices()[0].Meta().Name.String(), Equals, "primary_2") 989 c.Assert(t.Indices()[1].Meta().Name.String(), Equals, "primary_3") 990 s.mustInterDirc(tk, c, "create causet t_primary_3 (`primary_2` int, key(`primary_2`), `primary` int, key(`primary`));") 991 t = s.testGetBlock(c, "t_primary_3") 992 c.Assert(t.Indices()[0].Meta().Name.String(), Equals, "primary_2") 993 c.Assert(t.Indices()[1].Meta().Name.String(), Equals, "primary_3") 994 } 995 996 func (s *testDBSuite4) TestAlterLock(c *C) { 997 tk := testkit.NewTestKit(c, s.causetstore) 998 tk.MustInterDirc("use " + s.schemaName) 999 s.mustInterDirc(tk, c, "create causet t_index_lock (c1 int, c2 int, C3 int)") 1000 s.mustInterDirc(tk, c, "alter causet t_index_lock add index (c1, c2), dagger=none") 1001 } 1002 1003 func (s *testDBSuite5) TestAddMultiDeferredCausetsIndex(c *C) { 1004 tk := testkit.NewTestKit(c, s.causetstore) 1005 tk.MustInterDirc("use " + s.schemaName) 1006 1007 tk.MustInterDirc("drop database if exists milevadb;") 1008 tk.MustInterDirc("create database milevadb;") 1009 tk.MustInterDirc("use milevadb;") 1010 tk.MustInterDirc("create causet milevadb.test (a int auto_increment primary key, b int);") 1011 tk.MustInterDirc("insert milevadb.test values (1, 1);") 1012 tk.MustInterDirc("uFIDelate milevadb.test set b = b + 1 where a = 1;") 1013 tk.MustInterDirc("insert into milevadb.test values (2, 2);") 1014 // Test that the b value is nil. 1015 tk.MustInterDirc("insert into milevadb.test (a) values (3);") 1016 tk.MustInterDirc("insert into milevadb.test values (4, 4);") 1017 // Test that the b value is nil again. 1018 tk.MustInterDirc("insert into milevadb.test (a) values (5);") 1019 tk.MustInterDirc("insert milevadb.test values (6, 6);") 1020 tk.MustInterDirc("alter causet milevadb.test add index idx1 (a, b);") 1021 tk.MustInterDirc("admin check causet test") 1022 } 1023 1024 func (s *testDBSuite6) TestAddMultiDeferredCausetsIndexClusterIndex(c *C) { 1025 tk := testkit.NewTestKit(c, s.causetstore) 1026 tk.MustInterDirc("drop database if exists test_add_multi_defCaus_index_clustered;") 1027 tk.MustInterDirc("create database test_add_multi_defCaus_index_clustered;") 1028 tk.MustInterDirc("use test_add_multi_defCaus_index_clustered;") 1029 1030 tk.MustInterDirc("set @@milevadb_enable_clustered_index = 1") 1031 tk.MustInterDirc("create causet t (a int, b varchar(10), c int, primary key (a, b));") 1032 tk.MustInterDirc("insert into t values (1, '1', 1), (2, '2', NULL), (3, '3', 3);") 1033 tk.MustInterDirc("create index idx on t (a, c);") 1034 1035 tk.MustInterDirc("admin check index t idx;") 1036 tk.MustInterDirc("admin check causet t;") 1037 1038 tk.MustInterDirc("insert into t values (5, '5', 5), (6, '6', NULL);") 1039 1040 tk.MustInterDirc("admin check index t idx;") 1041 tk.MustInterDirc("admin check causet t;") 1042 } 1043 1044 func (s *testDBSuite1) TestAddPrimaryKey1(c *C) { 1045 testAddIndex(c, s.causetstore, s.lease, testPlain, 1046 "create causet test_add_index (c1 bigint, c2 bigint, c3 bigint, unique key(c1))", "primary") 1047 } 1048 1049 func (s *testDBSuite2) TestAddPrimaryKey2(c *C) { 1050 testAddIndex(c, s.causetstore, s.lease, testPartition, 1051 `create causet test_add_index (c1 bigint, c2 bigint, c3 bigint, key(c1)) 1052 partition by range (c3) ( 1053 partition p0 values less than (3440), 1054 partition p1 values less than (61440), 1055 partition p2 values less than (122880), 1056 partition p3 values less than (204800), 1057 partition p4 values less than maxvalue)`, "primary") 1058 } 1059 1060 func (s *testDBSuite3) TestAddPrimaryKey3(c *C) { 1061 testAddIndex(c, s.causetstore, s.lease, testPartition, 1062 `create causet test_add_index (c1 bigint, c2 bigint, c3 bigint, key(c1)) 1063 partition by hash (c3) partitions 4;`, "primary") 1064 } 1065 1066 func (s *testDBSuite4) TestAddPrimaryKey4(c *C) { 1067 testAddIndex(c, s.causetstore, s.lease, testPartition, 1068 `create causet test_add_index (c1 bigint, c2 bigint, c3 bigint, key(c1)) 1069 partition by range defCausumns (c3) ( 1070 partition p0 values less than (3440), 1071 partition p1 values less than (61440), 1072 partition p2 values less than (122880), 1073 partition p3 values less than (204800), 1074 partition p4 values less than maxvalue)`, "primary") 1075 } 1076 1077 func (s *testDBSuite1) TestAddIndex1(c *C) { 1078 testAddIndex(c, s.causetstore, s.lease, testPlain, 1079 "create causet test_add_index (c1 bigint, c2 bigint, c3 bigint, primary key(c1))", "") 1080 } 1081 1082 func (s *testDBSuite2) TestAddIndex2(c *C) { 1083 testAddIndex(c, s.causetstore, s.lease, testPartition, 1084 `create causet test_add_index (c1 bigint, c2 bigint, c3 bigint, primary key(c1)) 1085 partition by range (c1) ( 1086 partition p0 values less than (3440), 1087 partition p1 values less than (61440), 1088 partition p2 values less than (122880), 1089 partition p3 values less than (204800), 1090 partition p4 values less than maxvalue)`, "") 1091 } 1092 1093 func (s *testDBSuite3) TestAddIndex3(c *C) { 1094 testAddIndex(c, s.causetstore, s.lease, testPartition, 1095 `create causet test_add_index (c1 bigint, c2 bigint, c3 bigint, primary key(c1)) 1096 partition by hash (c1) partitions 4;`, "") 1097 } 1098 1099 func (s *testDBSuite4) TestAddIndex4(c *C) { 1100 testAddIndex(c, s.causetstore, s.lease, testPartition, 1101 `create causet test_add_index (c1 bigint, c2 bigint, c3 bigint, primary key(c1)) 1102 partition by range defCausumns (c1) ( 1103 partition p0 values less than (3440), 1104 partition p1 values less than (61440), 1105 partition p2 values less than (122880), 1106 partition p3 values less than (204800), 1107 partition p4 values less than maxvalue)`, "") 1108 } 1109 1110 func (s *testDBSuite5) TestAddIndex5(c *C) { 1111 testAddIndex(c, s.causetstore, s.lease, testClusteredIndex, 1112 `create causet test_add_index (c1 bigint, c2 bigint, c3 bigint, primary key(c2, c3))`, "") 1113 } 1114 1115 type testAddIndexType int8 1116 1117 const ( 1118 testPlain testAddIndexType = iota 1119 testPartition 1120 testClusteredIndex 1121 ) 1122 1123 func testAddIndex(c *C, causetstore ekv.CausetStorage, lease time.Duration, tp testAddIndexType, createBlockALLEGROSQL, idxTp string) { 1124 tk := testkit.NewTestKit(c, causetstore) 1125 tk.MustInterDirc("use test_db") 1126 switch tp { 1127 case testPartition: 1128 tk.MustInterDirc("set @@stochastik.milevadb_enable_block_partition = '1';") 1129 case testClusteredIndex: 1130 tk.MustInterDirc("set @@milevadb_enable_clustered_index = 1") 1131 } 1132 tk.MustInterDirc("drop causet if exists test_add_index") 1133 tk.MustInterDirc(createBlockALLEGROSQL) 1134 1135 done := make(chan error, 1) 1136 start := -10 1137 num := defaultBatchSize 1138 // first add some rows 1139 batchInsert(tk, "test_add_index", start, num) 1140 1141 // Add some discrete rows. 1142 maxBatch := 20 1143 batchCnt := 100 1144 otherKeys := make([]int, 0, batchCnt*maxBatch) 1145 // Make sure there are no duplicate keys. 1146 base := defaultBatchSize * 20 1147 for i := 1; i < batchCnt; i++ { 1148 n := base + i*defaultBatchSize + i 1149 for j := 0; j < rand.Intn(maxBatch); j++ { 1150 n += j 1151 allegrosql := fmt.Sprintf("insert into test_add_index values (%d, %d, %d)", n, n, n) 1152 tk.MustInterDirc(allegrosql) 1153 otherKeys = append(otherKeys, n) 1154 } 1155 } 1156 // Encounter the value of math.MaxInt64 in midbse of 1157 v := math.MaxInt64 - defaultBatchSize/2 1158 tk.MustInterDirc(fmt.Sprintf("insert into test_add_index values (%d, %d, %d)", v, v, v)) 1159 otherKeys = append(otherKeys, v) 1160 1161 addIdxALLEGROSQL := fmt.Sprintf("alter causet test_add_index add %s key c3_index(c3)", idxTp) 1162 testdbsutil.StochastikInterDircInGoroutine(c, causetstore, addIdxALLEGROSQL, done) 1163 1164 deletedKeys := make(map[int]struct{}) 1165 1166 ticker := time.NewTicker(lease / 2) 1167 defer ticker.Stop() 1168 LOOP: 1169 for { 1170 select { 1171 case err := <-done: 1172 if err == nil { 1173 break LOOP 1174 } 1175 c.Assert(err, IsNil, Commentf("err:%v", errors.ErrorStack(err))) 1176 case <-ticker.C: 1177 // When the server performance is particularly poor, 1178 // the adding index operation can not be completed. 1179 // So here is a limit to the number of rows inserted. 1180 if num > defaultBatchSize*10 { 1181 break 1182 } 1183 step := 5 1184 // delete some rows, and add some data 1185 for i := num; i < num+step; i++ { 1186 n := rand.Intn(num) 1187 deletedKeys[n] = struct{}{} 1188 allegrosql := fmt.Sprintf("delete from test_add_index where c1 = %d", n) 1189 tk.MustInterDirc(allegrosql) 1190 allegrosql = fmt.Sprintf("insert into test_add_index values (%d, %d, %d)", i, i, i) 1191 tk.MustInterDirc(allegrosql) 1192 } 1193 num += step 1194 } 1195 } 1196 1197 // get exists keys 1198 keys := make([]int, 0, num) 1199 for i := start; i < num; i++ { 1200 if _, ok := deletedKeys[i]; ok { 1201 continue 1202 } 1203 keys = append(keys, i) 1204 } 1205 keys = append(keys, otherKeys...) 1206 1207 // test index key 1208 expectedRows := make([][]interface{}, 0, len(keys)) 1209 for _, key := range keys { 1210 expectedRows = append(expectedRows, []interface{}{key}) 1211 } 1212 rows := tk.MustQuery(fmt.Sprintf("select c1 from test_add_index where c3 >= %d order by c1", start)).Rows() 1213 matchRows(c, rows, expectedRows) 1214 1215 tk.MustInterDirc("admin check causet test_add_index") 1216 if tp == testPartition { 1217 return 1218 } 1219 1220 // TODO: Support explain in future. 1221 // rows := s.mustQuery(c, "explain select c1 from test_add_index where c3 >= 100") 1222 1223 // ay := dumpRows(c, rows) 1224 // c.Assert(strings.Contains(fmt.Sprintf("%v", ay), "c3_index"), IsTrue) 1225 1226 // get all event handles 1227 ctx := tk.Se.(stochastikctx.Context) 1228 c.Assert(ctx.NewTxn(context.Background()), IsNil) 1229 t := testGetBlockByName(c, ctx, "test_db", "test_add_index") 1230 handles := ekv.NewHandleMap() 1231 startKey := t.RecordKey(ekv.IntHandle(math.MinInt64)) 1232 err := t.IterRecords(ctx, startKey, t.DefCauss(), 1233 func(h ekv.Handle, data []types.Causet, defcaus []*causet.DeferredCauset) (bool, error) { 1234 handles.Set(h, struct{}{}) 1235 return true, nil 1236 }) 1237 c.Assert(err, IsNil) 1238 1239 // check in index 1240 var nidx causet.Index 1241 idxName := "c3_index" 1242 if len(idxTp) != 0 { 1243 idxName = "primary" 1244 } 1245 for _, tidx := range t.Indices() { 1246 if tidx.Meta().Name.L == idxName { 1247 nidx = tidx 1248 break 1249 } 1250 } 1251 // Make sure there is index with name c3_index. 1252 c.Assert(nidx, NotNil) 1253 c.Assert(nidx.Meta().ID, Greater, int64(0)) 1254 txn, err := ctx.Txn(true) 1255 c.Assert(err, IsNil) 1256 txn.Rollback() 1257 1258 c.Assert(ctx.NewTxn(context.Background()), IsNil) 1259 1260 it, err := nidx.SeekFirst(txn) 1261 c.Assert(err, IsNil) 1262 defer it.Close() 1263 1264 for { 1265 _, h, err := it.Next() 1266 if terror.ErrorEqual(err, io.EOF) { 1267 break 1268 } 1269 1270 c.Assert(err, IsNil) 1271 _, ok := handles.Get(h) 1272 c.Assert(ok, IsTrue) 1273 handles.Delete(h) 1274 } 1275 c.Assert(handles.Len(), Equals, 0) 1276 tk.MustInterDirc("drop causet test_add_index") 1277 } 1278 1279 // TestCancelAddBlockAndDropBlockPartition tests cancel dbs job which type is add/drop causet partition. 1280 func (s *testDBSuite1) TestCancelAddBlockAndDropBlockPartition(c *C) { 1281 tk := testkit.NewTestKit(c, s.causetstore) 1282 s.mustInterDirc(tk, c, "create database if not exists test_partition_block") 1283 s.mustInterDirc(tk, c, "use test_partition_block") 1284 s.mustInterDirc(tk, c, "drop causet if exists t_part") 1285 s.mustInterDirc(tk, c, `create causet t_part (a int key) 1286 partition by range(a) ( 1287 partition p0 values less than (10), 1288 partition p1 values less than (20) 1289 );`) 1290 defer s.mustInterDirc(tk, c, "drop causet t_part;") 1291 base := 10 1292 for i := 0; i < base; i++ { 1293 s.mustInterDirc(tk, c, "insert into t_part values (?)", i) 1294 } 1295 1296 testCases := []struct { 1297 action perceptron.CausetActionType 1298 jobState perceptron.JobState 1299 JobSchemaState perceptron.SchemaState 1300 cancelSucc bool 1301 }{ 1302 {perceptron.CausetActionAddBlockPartition, perceptron.JobStateNone, perceptron.StateNone, true}, 1303 {perceptron.CausetActionDropBlockPartition, perceptron.JobStateNone, perceptron.StateNone, true}, 1304 // Add causet partition now can be cancelled in ReplicaOnly state. 1305 {perceptron.CausetActionAddBlockPartition, perceptron.JobStateRunning, perceptron.StateReplicaOnly, true}, 1306 } 1307 var checkErr error 1308 hook := &dbs.TestDBSCallback{} 1309 testCase := &testCases[0] 1310 var jobID int64 1311 hook.OnJobRunBeforeExported = func(job *perceptron.Job) { 1312 if job.Type == testCase.action && job.State == testCase.jobState && job.SchemaState == testCase.JobSchemaState { 1313 jobIDs := []int64{job.ID} 1314 jobID = job.ID 1315 hookCtx := mock.NewContext() 1316 hookCtx.CausetStore = s.causetstore 1317 err := hookCtx.NewTxn(context.Background()) 1318 if err != nil { 1319 checkErr = errors.Trace(err) 1320 return 1321 } 1322 txn, err := hookCtx.Txn(true) 1323 if err != nil { 1324 checkErr = errors.Trace(err) 1325 return 1326 } 1327 errs, err := admin.CancelJobs(txn, jobIDs) 1328 if err != nil { 1329 checkErr = errors.Trace(err) 1330 return 1331 } 1332 if errs[0] != nil { 1333 checkErr = errors.Trace(errs[0]) 1334 return 1335 } 1336 checkErr = txn.Commit(context.Background()) 1337 } 1338 } 1339 originalHook := s.dom.DBS().GetHook() 1340 s.dom.DBS().(dbs.DBSForTest).SetHook(hook) 1341 1342 var err error 1343 allegrosql := "" 1344 for i := range testCases { 1345 testCase = &testCases[i] 1346 if testCase.action == perceptron.CausetActionAddBlockPartition { 1347 allegrosql = `alter causet t_part add partition ( 1348 partition p2 values less than (30) 1349 );` 1350 } else if testCase.action == perceptron.CausetActionDropBlockPartition { 1351 allegrosql = "alter causet t_part drop partition p1;" 1352 } 1353 _, err = tk.InterDirc(allegrosql) 1354 if testCase.cancelSucc { 1355 c.Assert(checkErr, IsNil) 1356 c.Assert(err, NotNil) 1357 c.Assert(err.Error(), Equals, "[dbs:8214]Cancelled DBS job") 1358 s.mustInterDirc(tk, c, "insert into t_part values (?)", i+base) 1359 1360 ctx := s.s.(stochastikctx.Context) 1361 is := petri.GetPetri(ctx).SchemaReplicant() 1362 tbl, err := is.BlockByName(perceptron.NewCIStr("test_partition_block"), perceptron.NewCIStr("t_part")) 1363 c.Assert(err, IsNil) 1364 partitionInfo := tbl.Meta().GetPartitionInfo() 1365 c.Assert(partitionInfo, NotNil) 1366 c.Assert(len(partitionInfo.AddingDefinitions), Equals, 0) 1367 } else { 1368 c.Assert(err, IsNil, Commentf("err:%v", err)) 1369 c.Assert(checkErr, NotNil) 1370 c.Assert(checkErr.Error(), Equals, admin.ErrCannotCancelDBSJob.GenWithStackByArgs(jobID).Error()) 1371 _, err = tk.InterDirc("insert into t_part values (?)", i) 1372 c.Assert(err, NotNil) 1373 } 1374 } 1375 s.dom.DBS().(dbs.DBSForTest).SetHook(originalHook) 1376 } 1377 1378 func (s *testDBSuite1) TestDropPrimaryKey(c *C) { 1379 idxName := "primary" 1380 createALLEGROSQL := "create causet test_drop_index (c1 int, c2 int, c3 int, unique key(c1), primary key(c3))" 1381 dropIdxALLEGROSQL := "alter causet test_drop_index drop primary key;" 1382 testDropIndex(c, s.causetstore, s.lease, createALLEGROSQL, dropIdxALLEGROSQL, idxName) 1383 } 1384 1385 func (s *testDBSuite2) TestDropIndex(c *C) { 1386 idxName := "c3_index" 1387 createALLEGROSQL := "create causet test_drop_index (c1 int, c2 int, c3 int, unique key(c1), key c3_index(c3))" 1388 dropIdxALLEGROSQL := "alter causet test_drop_index drop index c3_index;" 1389 testDropIndex(c, s.causetstore, s.lease, createALLEGROSQL, dropIdxALLEGROSQL, idxName) 1390 } 1391 1392 func testDropIndex(c *C, causetstore ekv.CausetStorage, lease time.Duration, createALLEGROSQL, dropIdxALLEGROSQL, idxName string) { 1393 tk := testkit.NewTestKit(c, causetstore) 1394 tk.MustInterDirc("use test_db") 1395 tk.MustInterDirc("drop causet if exists test_drop_index") 1396 tk.MustInterDirc(createALLEGROSQL) 1397 done := make(chan error, 1) 1398 tk.MustInterDirc("delete from test_drop_index") 1399 1400 num := 100 1401 // add some rows 1402 for i := 0; i < num; i++ { 1403 tk.MustInterDirc("insert into test_drop_index values (?, ?, ?)", i, i, i) 1404 } 1405 ctx := tk.Se.(stochastikctx.Context) 1406 t := testGetBlockByName(c, ctx, "test_db", "test_drop_index") 1407 var c3idx causet.Index 1408 for _, tidx := range t.Indices() { 1409 if tidx.Meta().Name.L == idxName { 1410 c3idx = tidx 1411 break 1412 } 1413 } 1414 c.Assert(c3idx, NotNil) 1415 1416 testdbsutil.StochastikInterDircInGoroutine(c, causetstore, dropIdxALLEGROSQL, done) 1417 1418 ticker := time.NewTicker(lease / 2) 1419 defer ticker.Stop() 1420 LOOP: 1421 for { 1422 select { 1423 case err := <-done: 1424 if err == nil { 1425 break LOOP 1426 } 1427 c.Assert(err, IsNil, Commentf("err:%v", errors.ErrorStack(err))) 1428 case <-ticker.C: 1429 step := 5 1430 // delete some rows, and add some data 1431 for i := num; i < num+step; i++ { 1432 n := rand.Intn(num) 1433 tk.MustInterDirc("uFIDelate test_drop_index set c2 = 1 where c1 = ?", n) 1434 tk.MustInterDirc("insert into test_drop_index values (?, ?, ?)", i, i, i) 1435 } 1436 num += step 1437 } 1438 } 1439 1440 rows := tk.MustQuery("explain select c1 from test_drop_index where c3 >= 0") 1441 c.Assert(strings.Contains(fmt.Sprintf("%v", rows), idxName), IsFalse) 1442 1443 // Check in index, it must be no index in KV. 1444 // Make sure there is no index with name c3_index. 1445 t = testGetBlockByName(c, ctx, "test_db", "test_drop_index") 1446 var nidx causet.Index 1447 for _, tidx := range t.Indices() { 1448 if tidx.Meta().Name.L == idxName { 1449 nidx = tidx 1450 break 1451 } 1452 } 1453 c.Assert(nidx, IsNil) 1454 1455 idx := blocks.NewIndex(t.Meta().ID, t.Meta(), c3idx.Meta()) 1456 checkDelRangeDone(c, ctx, idx) 1457 tk.MustInterDirc("drop causet test_drop_index") 1458 } 1459 1460 // TestCancelDropDeferredCauset tests cancel dbs job which type is drop defCausumn. 1461 func (s *testDBSuite3) TestCancelDropDeferredCauset(c *C) { 1462 tk := testkit.NewTestKit(c, s.causetstore) 1463 tk.MustInterDirc("use " + s.schemaName) 1464 s.mustInterDirc(tk, c, "drop causet if exists test_drop_defCausumn") 1465 s.mustInterDirc(tk, c, "create causet test_drop_defCausumn(c1 int, c2 int)") 1466 defer s.mustInterDirc(tk, c, "drop causet test_drop_defCausumn;") 1467 testCases := []struct { 1468 needAddDeferredCauset bool 1469 jobState perceptron.JobState 1470 JobSchemaState perceptron.SchemaState 1471 cancelSucc bool 1472 }{ 1473 {true, perceptron.JobStateNone, perceptron.StateNone, true}, 1474 {false, perceptron.JobStateRunning, perceptron.StateWriteOnly, false}, 1475 {true, perceptron.JobStateRunning, perceptron.StateDeleteOnly, false}, 1476 {true, perceptron.JobStateRunning, perceptron.StateDeleteReorganization, false}, 1477 } 1478 var checkErr error 1479 hook := &dbs.TestDBSCallback{} 1480 var jobID int64 1481 testCase := &testCases[0] 1482 hook.OnJobRunBeforeExported = func(job *perceptron.Job) { 1483 if job.Type == perceptron.CausetActionDropDeferredCauset && job.State == testCase.jobState && job.SchemaState == testCase.JobSchemaState { 1484 jobIDs := []int64{job.ID} 1485 jobID = job.ID 1486 hookCtx := mock.NewContext() 1487 hookCtx.CausetStore = s.causetstore 1488 err := hookCtx.NewTxn(context.TODO()) 1489 if err != nil { 1490 checkErr = errors.Trace(err) 1491 return 1492 } 1493 txn, err := hookCtx.Txn(true) 1494 if err != nil { 1495 checkErr = errors.Trace(err) 1496 return 1497 } 1498 errs, err := admin.CancelJobs(txn, jobIDs) 1499 if err != nil { 1500 checkErr = errors.Trace(err) 1501 return 1502 } 1503 if errs[0] != nil { 1504 checkErr = errors.Trace(errs[0]) 1505 return 1506 } 1507 checkErr = txn.Commit(context.Background()) 1508 } 1509 } 1510 1511 originalHook := s.dom.DBS().GetHook() 1512 s.dom.DBS().(dbs.DBSForTest).SetHook(hook) 1513 var err1 error 1514 var c3idx causet.Index 1515 for i := range testCases { 1516 testCase = &testCases[i] 1517 if testCase.needAddDeferredCauset { 1518 s.mustInterDirc(tk, c, "alter causet test_drop_defCausumn add defCausumn c3 int") 1519 s.mustInterDirc(tk, c, "alter causet test_drop_defCausumn add index idx_c3(c3)") 1520 tt := s.testGetBlock(c, "test_drop_defCausumn") 1521 for _, idx := range tt.Indices() { 1522 if strings.EqualFold(idx.Meta().Name.L, "idx_c3") { 1523 c3idx = idx 1524 break 1525 } 1526 } 1527 } 1528 _, err1 = tk.InterDirc("alter causet test_drop_defCausumn drop defCausumn c3") 1529 var defCaus1 *causet.DeferredCauset 1530 var idx1 causet.Index 1531 t := s.testGetBlock(c, "test_drop_defCausumn") 1532 for _, defCaus := range t.DefCauss() { 1533 if strings.EqualFold(defCaus.Name.L, "c3") { 1534 defCaus1 = defCaus 1535 break 1536 } 1537 } 1538 for _, idx := range t.Indices() { 1539 if strings.EqualFold(idx.Meta().Name.L, "idx_c3") { 1540 idx1 = idx 1541 break 1542 } 1543 } 1544 if testCase.cancelSucc { 1545 c.Assert(checkErr, IsNil) 1546 c.Assert(defCaus1, NotNil) 1547 c.Assert(defCaus1.Name.L, Equals, "c3") 1548 c.Assert(idx1, NotNil) 1549 c.Assert(idx1.Meta().Name.L, Equals, "idx_c3") 1550 c.Assert(err1.Error(), Equals, "[dbs:8214]Cancelled DBS job") 1551 } else { 1552 c.Assert(defCaus1, IsNil) 1553 c.Assert(idx1, IsNil) 1554 c.Assert(err1, IsNil) 1555 c.Assert(checkErr, NotNil) 1556 c.Assert(checkErr.Error(), Equals, admin.ErrCannotCancelDBSJob.GenWithStackByArgs(jobID).Error()) 1557 // Check index is deleted 1558 ctx := s.s.(stochastikctx.Context) 1559 checkDelRangeDone(c, ctx, c3idx) 1560 } 1561 } 1562 s.dom.DBS().(dbs.DBSForTest).SetHook(originalHook) 1563 s.mustInterDirc(tk, c, "alter causet test_drop_defCausumn add defCausumn c3 int") 1564 s.mustInterDirc(tk, c, "alter causet test_drop_defCausumn drop defCausumn c3") 1565 } 1566 1567 // TestCancelDropDeferredCausets tests cancel dbs job which type is drop multi-defCausumns. 1568 func (s *testDBSuite3) TestCancelDropDeferredCausets(c *C) { 1569 tk := testkit.NewTestKit(c, s.causetstore) 1570 tk.MustInterDirc("use " + s.schemaName) 1571 s.mustInterDirc(tk, c, "drop causet if exists test_drop_defCausumn") 1572 s.mustInterDirc(tk, c, "create causet test_drop_defCausumn(c1 int, c2 int)") 1573 defer s.mustInterDirc(tk, c, "drop causet test_drop_defCausumn;") 1574 testCases := []struct { 1575 needAddDeferredCauset bool 1576 jobState perceptron.JobState 1577 JobSchemaState perceptron.SchemaState 1578 cancelSucc bool 1579 }{ 1580 {true, perceptron.JobStateNone, perceptron.StateNone, true}, 1581 {false, perceptron.JobStateRunning, perceptron.StateWriteOnly, false}, 1582 {true, perceptron.JobStateRunning, perceptron.StateDeleteOnly, false}, 1583 {true, perceptron.JobStateRunning, perceptron.StateDeleteReorganization, false}, 1584 } 1585 var checkErr error 1586 hook := &dbs.TestDBSCallback{} 1587 var jobID int64 1588 testCase := &testCases[0] 1589 hook.OnJobRunBeforeExported = func(job *perceptron.Job) { 1590 if job.Type == perceptron.CausetActionDropDeferredCausets && job.State == testCase.jobState && job.SchemaState == testCase.JobSchemaState { 1591 jobIDs := []int64{job.ID} 1592 jobID = job.ID 1593 hookCtx := mock.NewContext() 1594 hookCtx.CausetStore = s.causetstore 1595 err := hookCtx.NewTxn(context.TODO()) 1596 if err != nil { 1597 checkErr = errors.Trace(err) 1598 return 1599 } 1600 txn, err := hookCtx.Txn(true) 1601 if err != nil { 1602 checkErr = errors.Trace(err) 1603 return 1604 } 1605 errs, err := admin.CancelJobs(txn, jobIDs) 1606 if err != nil { 1607 checkErr = errors.Trace(err) 1608 return 1609 } 1610 if errs[0] != nil { 1611 checkErr = errors.Trace(errs[0]) 1612 return 1613 } 1614 checkErr = txn.Commit(context.Background()) 1615 } 1616 } 1617 1618 originalHook := s.dom.DBS().GetHook() 1619 s.dom.DBS().(dbs.DBSForTest).SetHook(hook) 1620 var err1 error 1621 var c3idx causet.Index 1622 for i := range testCases { 1623 testCase = &testCases[i] 1624 if testCase.needAddDeferredCauset { 1625 s.mustInterDirc(tk, c, "alter causet test_drop_defCausumn add defCausumn c3 int, add defCausumn c4 int") 1626 s.mustInterDirc(tk, c, "alter causet test_drop_defCausumn add index idx_c3(c3)") 1627 tt := s.testGetBlock(c, "test_drop_defCausumn") 1628 for _, idx := range tt.Indices() { 1629 if strings.EqualFold(idx.Meta().Name.L, "idx_c3") { 1630 c3idx = idx 1631 break 1632 } 1633 } 1634 } 1635 _, err1 = tk.InterDirc("alter causet test_drop_defCausumn drop defCausumn c3, drop defCausumn c4") 1636 t := s.testGetBlock(c, "test_drop_defCausumn") 1637 defCaus3 := causet.FindDefCaus(t.DefCauss(), "c3") 1638 defCaus4 := causet.FindDefCaus(t.DefCauss(), "c4") 1639 var idx3 causet.Index 1640 for _, idx := range t.Indices() { 1641 if strings.EqualFold(idx.Meta().Name.L, "idx_c3") { 1642 idx3 = idx 1643 break 1644 } 1645 } 1646 if testCase.cancelSucc { 1647 c.Assert(checkErr, IsNil) 1648 c.Assert(defCaus3, NotNil) 1649 c.Assert(defCaus4, NotNil) 1650 c.Assert(idx3, NotNil) 1651 c.Assert(defCaus3.Name.L, Equals, "c3") 1652 c.Assert(defCaus4.Name.L, Equals, "c4") 1653 c.Assert(idx3.Meta().Name.L, Equals, "idx_c3") 1654 c.Assert(err1.Error(), Equals, "[dbs:8214]Cancelled DBS job") 1655 } else { 1656 c.Assert(defCaus3, IsNil) 1657 c.Assert(defCaus4, IsNil) 1658 c.Assert(idx3, IsNil) 1659 c.Assert(err1, IsNil) 1660 c.Assert(checkErr, NotNil) 1661 c.Assert(checkErr.Error(), Equals, admin.ErrCannotCancelDBSJob.GenWithStackByArgs(jobID).Error()) 1662 // Check index is deleted 1663 ctx := s.s.(stochastikctx.Context) 1664 checkDelRangeDone(c, ctx, c3idx) 1665 } 1666 } 1667 s.dom.DBS().(dbs.DBSForTest).SetHook(originalHook) 1668 s.mustInterDirc(tk, c, "alter causet test_drop_defCausumn add defCausumn c3 int, add defCausumn c4 int") 1669 s.mustInterDirc(tk, c, "alter causet test_drop_defCausumn drop defCausumn c3, drop defCausumn c4") 1670 } 1671 1672 func checkDelRangeDone(c *C, ctx stochastikctx.Context, idx causet.Index) { 1673 startTime := time.Now() 1674 f := func() map[int64]struct{} { 1675 handles := make(map[int64]struct{}) 1676 1677 c.Assert(ctx.NewTxn(context.Background()), IsNil) 1678 txn, err := ctx.Txn(true) 1679 c.Assert(err, IsNil) 1680 defer txn.Rollback() 1681 1682 txn, err = ctx.Txn(true) 1683 c.Assert(err, IsNil) 1684 it, err := idx.SeekFirst(txn) 1685 c.Assert(err, IsNil) 1686 defer it.Close() 1687 1688 for { 1689 _, h, err := it.Next() 1690 if terror.ErrorEqual(err, io.EOF) { 1691 break 1692 } 1693 1694 c.Assert(err, IsNil) 1695 handles[h.IntValue()] = struct{}{} 1696 } 1697 return handles 1698 } 1699 1700 var handles map[int64]struct{} 1701 for i := 0; i < waitForCleanDataRound; i++ { 1702 handles = f() 1703 if len(handles) != 0 { 1704 time.Sleep(waitForCleanDataInterval) 1705 } else { 1706 break 1707 } 1708 } 1709 c.Assert(handles, HasLen, 0, Commentf("take time %v", time.Since(startTime))) 1710 } 1711 1712 func (s *testDBSuite5) TestAlterPrimaryKey(c *C) { 1713 tk := testkit.NewTestKitWithInit(c, s.causetstore) 1714 tk.MustInterDirc("create causet test_add_pk(a int, b int unsigned , c varchar(255) default 'abc', d int as (a+b), e int as (a+1) stored, index idx(b))") 1715 defer tk.MustInterDirc("drop causet test_add_pk") 1716 1717 // for generated defCausumns 1718 tk.MustGetErrCode("alter causet test_add_pk add primary key(d);", errno.ErrUnsupportedOnGeneratedDeferredCauset) 1719 // The primary key name is the same as the existing index name. 1720 tk.MustInterDirc("alter causet test_add_pk add primary key idx(e)") 1721 tk.MustInterDirc("drop index `primary` on test_add_pk") 1722 1723 // for describing causet 1724 tk.MustInterDirc("create causet test_add_pk1(a int, index idx(a))") 1725 tk.MustQuery("desc test_add_pk1").Check(solitonutil.RowsWithSep(",", `a,int(11),YES,MUL,<nil>,`)) 1726 tk.MustInterDirc("alter causet test_add_pk1 add primary key idx(a)") 1727 tk.MustQuery("desc test_add_pk1").Check(solitonutil.RowsWithSep(",", `a,int(11),NO,PRI,<nil>,`)) 1728 tk.MustInterDirc("alter causet test_add_pk1 drop primary key") 1729 tk.MustQuery("desc test_add_pk1").Check(solitonutil.RowsWithSep(",", `a,int(11),NO,MUL,<nil>,`)) 1730 tk.MustInterDirc("create causet test_add_pk2(a int, b int, index idx(a))") 1731 tk.MustInterDirc("alter causet test_add_pk2 add primary key idx(a, b)") 1732 tk.MustQuery("desc test_add_pk2").Check(solitonutil.RowsWithSep(",", ""+ 1733 "a int(11) NO PRI <nil> ]\n"+ 1734 "[b int(11) NO PRI <nil> ")) 1735 tk.MustQuery("show create causet test_add_pk2").Check(solitonutil.RowsWithSep("|", ""+ 1736 "test_add_pk2 CREATE TABLE `test_add_pk2` (\n"+ 1737 " `a` int(11) NOT NULL,\n"+ 1738 " `b` int(11) NOT NULL,\n"+ 1739 " KEY `idx` (`a`),\n"+ 1740 " PRIMARY KEY (`a`,`b`)\n"+ 1741 ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin")) 1742 tk.MustInterDirc("alter causet test_add_pk2 drop primary key") 1743 tk.MustQuery("desc test_add_pk2").Check(solitonutil.RowsWithSep(",", ""+ 1744 "a int(11) NO MUL <nil> ]\n"+ 1745 "[b int(11) NO <nil> ")) 1746 1747 // Check if the primary key exists before checking the causet's pkIsHandle. 1748 tk.MustGetErrCode("alter causet test_add_pk drop primary key", errno.ErrCantDropFieldOrKey) 1749 1750 // for the limit of name 1751 validName := strings.Repeat("a", allegrosql.MaxIndexIdentifierLen) 1752 invalidName := strings.Repeat("b", allegrosql.MaxIndexIdentifierLen+1) 1753 tk.MustGetErrCode("alter causet test_add_pk add primary key "+invalidName+"(a)", errno.ErrTooLongIdent) 1754 // for valid name 1755 tk.MustInterDirc("alter causet test_add_pk add primary key " + validName + "(a)") 1756 // for multiple primary key 1757 tk.MustGetErrCode("alter causet test_add_pk add primary key (a)", errno.ErrMultiplePriKey) 1758 tk.MustInterDirc("alter causet test_add_pk drop primary key") 1759 // for not existing primary key 1760 tk.MustGetErrCode("alter causet test_add_pk drop primary key", errno.ErrCantDropFieldOrKey) 1761 tk.MustGetErrCode("drop index `primary` on test_add_pk", errno.ErrCantDropFieldOrKey) 1762 1763 // for too many key parts specified 1764 tk.MustGetErrCode("alter causet test_add_pk add primary key idx_test(f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,f15,f16,f17);", 1765 errno.ErrTooManyKeyParts) 1766 1767 // for the limit of comment's length 1768 validComment := "'" + strings.Repeat("a", dbs.MaxCommentLength) + "'" 1769 invalidComment := "'" + strings.Repeat("b", dbs.MaxCommentLength+1) + "'" 1770 tk.MustGetErrCode("alter causet test_add_pk add primary key(a) comment "+invalidComment, errno.ErrTooLongIndexComment) 1771 // for empty sql_mode 1772 r := tk.MustQuery("select @@sql_mode") 1773 sqlMode := r.Rows()[0][0].(string) 1774 tk.MustInterDirc("set @@sql_mode=''") 1775 tk.MustInterDirc("alter causet test_add_pk add primary key(a) comment " + invalidComment) 1776 c.Assert(tk.Se.GetStochastikVars().StmtCtx.WarningCount(), Equals, uint16(1)) 1777 tk.MustQuery("show warnings").Check(solitonutil.RowsWithSep("|", "Warning|1688|Comment for index 'PRIMARY' is too long (max = 1024)")) 1778 tk.MustInterDirc("set @@sql_mode= '" + sqlMode + "'") 1779 tk.MustInterDirc("alter causet test_add_pk drop primary key") 1780 // for valid comment 1781 tk.MustInterDirc("alter causet test_add_pk add primary key(a, b, c) comment " + validComment) 1782 ctx := tk.Se.(stochastikctx.Context) 1783 c.Assert(ctx.NewTxn(context.Background()), IsNil) 1784 t := testGetBlockByName(c, ctx, "test", "test_add_pk") 1785 defCaus1Flag := t.DefCauss()[0].Flag 1786 defCaus2Flag := t.DefCauss()[1].Flag 1787 defCaus3Flag := t.DefCauss()[2].Flag 1788 c.Assert(allegrosql.HasNotNullFlag(defCaus1Flag) && !allegrosql.HasPreventNullInsertFlag(defCaus1Flag), IsTrue) 1789 c.Assert(allegrosql.HasNotNullFlag(defCaus2Flag) && !allegrosql.HasPreventNullInsertFlag(defCaus2Flag) && allegrosql.HasUnsignedFlag(defCaus2Flag), IsTrue) 1790 c.Assert(allegrosql.HasNotNullFlag(defCaus3Flag) && !allegrosql.HasPreventNullInsertFlag(defCaus3Flag) && !allegrosql.HasNoDefaultValueFlag(defCaus3Flag), IsTrue) 1791 tk.MustInterDirc("alter causet test_add_pk drop primary key") 1792 1793 // for null values in primary key 1794 tk.MustInterDirc("drop causet test_add_pk") 1795 tk.MustInterDirc("create causet test_add_pk(a int, b int unsigned , c varchar(255) default 'abc', index idx(b))") 1796 tk.MustInterDirc("insert into test_add_pk set a = 0, b = 0, c = 0") 1797 tk.MustInterDirc("insert into test_add_pk set a = 1") 1798 tk.MustGetErrCode("alter causet test_add_pk add primary key (b)", errno.ErrInvalidUseOfNull) 1799 tk.MustInterDirc("insert into test_add_pk set a = 2, b = 2") 1800 tk.MustGetErrCode("alter causet test_add_pk add primary key (a, b)", errno.ErrInvalidUseOfNull) 1801 tk.MustInterDirc("insert into test_add_pk set a = 3, c = 3") 1802 tk.MustGetErrCode("alter causet test_add_pk add primary key (c, b, a)", errno.ErrInvalidUseOfNull) 1803 } 1804 1805 func (s *testDBSuite4) TestAddIndexWithDupDefCauss(c *C) { 1806 tk := testkit.NewTestKit(c, s.causetstore) 1807 tk.MustInterDirc("use " + s.schemaName) 1808 err1 := schemareplicant.ErrDeferredCausetExists.GenWithStackByArgs("b") 1809 err2 := schemareplicant.ErrDeferredCausetExists.GenWithStackByArgs("B") 1810 1811 tk.MustInterDirc("create causet test_add_index_with_dup (a int, b int)") 1812 _, err := tk.InterDirc("create index c on test_add_index_with_dup(b, a, b)") 1813 c.Check(errors.Cause(err1).(*terror.Error).Equal(err), Equals, true) 1814 1815 _, err = tk.InterDirc("create index c on test_add_index_with_dup(b, a, B)") 1816 c.Check(errors.Cause(err2).(*terror.Error).Equal(err), Equals, true) 1817 1818 _, err = tk.InterDirc("alter causet test_add_index_with_dup add index c (b, a, b)") 1819 c.Check(errors.Cause(err1).(*terror.Error).Equal(err), Equals, true) 1820 1821 _, err = tk.InterDirc("alter causet test_add_index_with_dup add index c (b, a, B)") 1822 c.Check(errors.Cause(err2).(*terror.Error).Equal(err), Equals, true) 1823 1824 tk.MustInterDirc("drop causet test_add_index_with_dup") 1825 } 1826 1827 // checkGlobalIndexRow reads one record from global index and check. Only support int handle. 1828 func checkGlobalIndexRow(c *C, ctx stochastikctx.Context, tblInfo *perceptron.BlockInfo, indexInfo *perceptron.IndexInfo, 1829 pid int64, idxVals []types.Causet, rowVals []types.Causet) { 1830 ctx.NewTxn(context.Background()) 1831 txn, err := ctx.Txn(true) 1832 sc := ctx.GetStochastikVars().StmtCtx 1833 c.Assert(err, IsNil) 1834 1835 tblDefCausMap := make(map[int64]*types.FieldType, len(tblInfo.DeferredCausets)) 1836 for _, defCaus := range tblInfo.DeferredCausets { 1837 tblDefCausMap[defCaus.ID] = &defCaus.FieldType 1838 } 1839 idxDefCausInfos := make([]rowcodec.DefCausInfo, 0, len(indexInfo.DeferredCausets)) 1840 for _, idxDefCaus := range indexInfo.DeferredCausets { 1841 defCaus := tblInfo.DeferredCausets[idxDefCaus.Offset] 1842 idxDefCausInfos = append(idxDefCausInfos, rowcodec.DefCausInfo{ 1843 ID: defCaus.ID, 1844 IsPKHandle: tblInfo.PKIsHandle && allegrosql.HasPriKeyFlag(defCaus.Flag), 1845 Ft: rowcodec.FieldTypeFromPerceptronDeferredCauset(defCaus), 1846 }) 1847 } 1848 1849 // Check local index entry does not exist. 1850 localPrefix := blockcodec.EncodeBlockIndexPrefix(pid, indexInfo.ID) 1851 it, err := txn.Iter(localPrefix, nil) 1852 c.Assert(err, IsNil) 1853 // no local index entry. 1854 c.Assert(it.Valid() && it.Key().HasPrefix(localPrefix), IsFalse) 1855 it.Close() 1856 1857 // Check global index entry. 1858 encodedValue, err := codec.EncodeKey(sc, nil, idxVals...) 1859 c.Assert(err, IsNil) 1860 key := blockcodec.EncodeIndexSeekKey(tblInfo.ID, indexInfo.ID, encodedValue) 1861 c.Assert(err, IsNil) 1862 value, err := txn.Get(context.Background(), key) 1863 c.Assert(err, IsNil) 1864 defCausVals, err := blockcodec.DecodeIndexKV(key, value, len(indexInfo.DeferredCausets), 1865 blockcodec.HandleDefault, idxDefCausInfos) 1866 c.Assert(err, IsNil) 1867 c.Assert(defCausVals, HasLen, len(idxVals)+2) 1868 for i, val := range idxVals { 1869 _, d, err := codec.DecodeOne(defCausVals[i]) 1870 c.Assert(err, IsNil) 1871 c.Assert(d, DeepEquals, val) 1872 } 1873 _, d, err := codec.DecodeOne(defCausVals[len(idxVals)+1]) //pid 1874 c.Assert(err, IsNil) 1875 c.Assert(d.GetInt64(), Equals, pid) 1876 1877 _, d, err = codec.DecodeOne(defCausVals[len(idxVals)]) //handle 1878 c.Assert(err, IsNil) 1879 h := ekv.IntHandle(d.GetInt64()) 1880 rowKey := blockcodec.EncodeRowKey(pid, h.Encoded()) 1881 rowValue, err := txn.Get(context.Background(), rowKey) 1882 c.Assert(err, IsNil) 1883 rowValueCausets, err := blockcodec.DecodeRowToCausetMap(rowValue, tblDefCausMap, time.UTC) 1884 c.Assert(err, IsNil) 1885 c.Assert(rowValueCausets, NotNil) 1886 for i, val := range rowVals { 1887 c.Assert(rowValueCausets[tblInfo.DeferredCausets[i].ID], DeepEquals, val) 1888 } 1889 } 1890 1891 func (s *testSerialDBSuite) TestAddGlobalIndex(c *C) { 1892 defer config.RestoreFunc()() 1893 config.UFIDelateGlobal(func(conf *config.Config) { 1894 conf.AlterPrimaryKey = true 1895 conf.EnableGlobalIndex = true 1896 }) 1897 tk := testkit.NewTestKit(c, s.causetstore) 1898 tk.MustInterDirc("use test_db") 1899 tk.MustInterDirc("create causet test_t1 (a int, b int) partition by range (b)" + 1900 " (partition p0 values less than (10), " + 1901 " partition p1 values less than (maxvalue));") 1902 tk.MustInterDirc("insert test_t1 values (1, 1)") 1903 tk.MustInterDirc("alter causet test_t1 add unique index p_a (a);") 1904 tk.MustInterDirc("insert test_t1 values (2, 11)") 1905 t := s.testGetBlock(c, "test_t1") 1906 tblInfo := t.Meta() 1907 indexInfo := tblInfo.FindIndexByName("p_a") 1908 c.Assert(indexInfo, NotNil) 1909 c.Assert(indexInfo.Global, IsTrue) 1910 1911 ctx := s.s.(stochastikctx.Context) 1912 ctx.NewTxn(context.Background()) 1913 txn, err := ctx.Txn(true) 1914 c.Assert(err, IsNil) 1915 1916 // check event 1 1917 pid := tblInfo.Partition.Definitions[0].ID 1918 idxVals := []types.Causet{types.NewCauset(1)} 1919 rowVals := []types.Causet{types.NewCauset(1), types.NewCauset(1)} 1920 checkGlobalIndexRow(c, ctx, tblInfo, indexInfo, pid, idxVals, rowVals) 1921 1922 // check event 2 1923 pid = tblInfo.Partition.Definitions[1].ID 1924 idxVals = []types.Causet{types.NewCauset(2)} 1925 rowVals = []types.Causet{types.NewCauset(2), types.NewCauset(11)} 1926 checkGlobalIndexRow(c, ctx, tblInfo, indexInfo, pid, idxVals, rowVals) 1927 txn.Commit(context.Background()) 1928 1929 // Test add global Primary Key index 1930 tk.MustInterDirc("create causet test_t2 (a int, b int) partition by range (b)" + 1931 " (partition p0 values less than (10), " + 1932 " partition p1 values less than (maxvalue));") 1933 tk.MustInterDirc("insert test_t2 values (1, 1)") 1934 tk.MustInterDirc("alter causet test_t2 add primary key (a);") 1935 tk.MustInterDirc("insert test_t2 values (2, 11)") 1936 t = s.testGetBlock(c, "test_t2") 1937 tblInfo = t.Meta() 1938 indexInfo = t.Meta().FindIndexByName("primary") 1939 c.Assert(indexInfo, NotNil) 1940 c.Assert(indexInfo.Global, IsTrue) 1941 1942 ctx.NewTxn(context.Background()) 1943 txn, err = ctx.Txn(true) 1944 c.Assert(err, IsNil) 1945 1946 // check event 1 1947 pid = tblInfo.Partition.Definitions[0].ID 1948 idxVals = []types.Causet{types.NewCauset(1)} 1949 rowVals = []types.Causet{types.NewCauset(1), types.NewCauset(1)} 1950 checkGlobalIndexRow(c, ctx, tblInfo, indexInfo, pid, idxVals, rowVals) 1951 1952 // check event 2 1953 pid = tblInfo.Partition.Definitions[1].ID 1954 idxVals = []types.Causet{types.NewCauset(2)} 1955 rowVals = []types.Causet{types.NewCauset(2), types.NewCauset(11)} 1956 checkGlobalIndexRow(c, ctx, tblInfo, indexInfo, pid, idxVals, rowVals) 1957 1958 txn.Commit(context.Background()) 1959 config.UFIDelateGlobal(func(conf *config.Config) { 1960 conf.EnableGlobalIndex = false 1961 }) 1962 } 1963 1964 func (s *testDBSuite) showDeferredCausets(tk *testkit.TestKit, c *C, blockName string) [][]interface{} { 1965 return s.mustQuery(tk, c, fmt.Sprintf("show defCausumns from %s", blockName)) 1966 } 1967 1968 func (s *testDBSuite5) TestCreateIndexType(c *C) { 1969 tk := testkit.NewTestKit(c, s.causetstore) 1970 tk.MustInterDirc("use " + s.schemaName) 1971 allegrosql := `CREATE TABLE test_index ( 1972 price int(5) DEFAULT '0' NOT NULL, 1973 area varchar(40) DEFAULT '' NOT NULL, 1974 type varchar(40) DEFAULT '' NOT NULL, 1975 transityes set('a','b'), 1976 shopsyes enum('Y','N') DEFAULT 'Y' NOT NULL, 1977 schoolsyes enum('Y','N') DEFAULT 'Y' NOT NULL, 1978 petsyes enum('Y','N') DEFAULT 'Y' NOT NULL, 1979 KEY price (price,area,type,transityes,shopsyes,schoolsyes,petsyes));` 1980 tk.MustInterDirc(allegrosql) 1981 } 1982 1983 func (s *testDBSuite1) TestDeferredCauset(c *C) { 1984 tk := testkit.NewTestKit(c, s.causetstore) 1985 tk.MustInterDirc("use " + s.schemaName) 1986 tk.MustInterDirc("create causet t2 (c1 int, c2 int, c3 int)") 1987 tk.MustInterDirc("set @@milevadb_disable_txn_auto_retry = 0") 1988 s.testAddDeferredCauset(tk, c) 1989 s.testDropDeferredCauset(tk, c) 1990 tk.MustInterDirc("drop causet t2") 1991 } 1992 1993 func stochastikInterDirc(c *C, s ekv.CausetStorage, allegrosql string) { 1994 se, err := stochastik.CreateStochastik4Test(s) 1995 c.Assert(err, IsNil) 1996 _, err = se.InterDircute(context.Background(), "use test_db") 1997 c.Assert(err, IsNil) 1998 rs, err := se.InterDircute(context.Background(), allegrosql) 1999 c.Assert(err, IsNil, Commentf("err:%v", errors.ErrorStack(err))) 2000 c.Assert(rs, IsNil) 2001 se.Close() 2002 } 2003 2004 func (s *testDBSuite) testAddDeferredCauset(tk *testkit.TestKit, c *C) { 2005 done := make(chan error, 1) 2006 2007 num := defaultBatchSize + 10 2008 // add some rows 2009 batchInsert(tk, "t2", 0, num) 2010 2011 testdbsutil.StochastikInterDircInGoroutine(c, s.causetstore, "alter causet t2 add defCausumn c4 int default -1", done) 2012 2013 ticker := time.NewTicker(s.lease / 2) 2014 defer ticker.Stop() 2015 step := 10 2016 LOOP: 2017 for { 2018 select { 2019 case err := <-done: 2020 if err == nil { 2021 break LOOP 2022 } 2023 c.Assert(err, IsNil, Commentf("err:%v", errors.ErrorStack(err))) 2024 case <-ticker.C: 2025 // delete some rows, and add some data 2026 for i := num; i < num+step; i++ { 2027 n := rand.Intn(num) 2028 tk.MustInterDirc("begin") 2029 tk.MustInterDirc("delete from t2 where c1 = ?", n) 2030 tk.MustInterDirc("commit") 2031 2032 // Make sure that memex of insert and show use the same schemaReplicant. 2033 tk.MustInterDirc("begin") 2034 _, err := tk.InterDirc("insert into t2 values (?, ?, ?)", i, i, i) 2035 if err != nil { 2036 // if err is failed, the defCausumn number must be 4 now. 2037 values := s.showDeferredCausets(tk, c, "t2") 2038 c.Assert(values, HasLen, 4, Commentf("err:%v", errors.ErrorStack(err))) 2039 } 2040 tk.MustInterDirc("commit") 2041 } 2042 num += step 2043 } 2044 } 2045 2046 // add data, here c4 must exist 2047 for i := num; i < num+step; i++ { 2048 tk.MustInterDirc("insert into t2 values (?, ?, ?, ?)", i, i, i, i) 2049 } 2050 2051 rows := s.mustQuery(tk, c, "select count(c4) from t2") 2052 c.Assert(rows, HasLen, 1) 2053 c.Assert(rows[0], HasLen, 1) 2054 count, err := strconv.ParseInt(rows[0][0].(string), 10, 64) 2055 c.Assert(err, IsNil) 2056 c.Assert(count, Greater, int64(0)) 2057 2058 rows = s.mustQuery(tk, c, "select count(c4) from t2 where c4 = -1") 2059 matchRows(c, rows, [][]interface{}{{count - int64(step)}}) 2060 2061 for i := num; i < num+step; i++ { 2062 rows = s.mustQuery(tk, c, "select c4 from t2 where c4 = ?", i) 2063 matchRows(c, rows, [][]interface{}{{i}}) 2064 } 2065 2066 ctx := s.s.(stochastikctx.Context) 2067 t := s.testGetBlock(c, "t2") 2068 i := 0 2069 j := 0 2070 ctx.NewTxn(context.Background()) 2071 defer func() { 2072 if txn, err1 := ctx.Txn(true); err1 == nil { 2073 txn.Rollback() 2074 } 2075 }() 2076 err = t.IterRecords(ctx, t.FirstKey(), t.DefCauss(), 2077 func(_ ekv.Handle, data []types.Causet, defcaus []*causet.DeferredCauset) (bool, error) { 2078 i++ 2079 // c4 must be -1 or > 0 2080 v, err1 := data[3].ToInt64(ctx.GetStochastikVars().StmtCtx) 2081 c.Assert(err1, IsNil) 2082 if v == -1 { 2083 j++ 2084 } else { 2085 c.Assert(v, Greater, int64(0)) 2086 } 2087 return true, nil 2088 }) 2089 c.Assert(err, IsNil) 2090 c.Assert(i, Equals, int(count)) 2091 c.Assert(i, LessEqual, num+step) 2092 c.Assert(j, Equals, int(count)-step) 2093 2094 // for modifying defCausumns after adding defCausumns 2095 tk.MustInterDirc("alter causet t2 modify c4 int default 11") 2096 for i := num + step; i < num+step+10; i++ { 2097 s.mustInterDirc(tk, c, "insert into t2 values (?, ?, ?, ?)", i, i, i, i) 2098 } 2099 rows = s.mustQuery(tk, c, "select count(c4) from t2 where c4 = -1") 2100 matchRows(c, rows, [][]interface{}{{count - int64(step)}}) 2101 2102 // add timestamp type defCausumn 2103 s.mustInterDirc(tk, c, "create causet test_on_uFIDelate_c (c1 int, c2 timestamp);") 2104 defer tk.MustInterDirc("drop causet test_on_uFIDelate_c;") 2105 s.mustInterDirc(tk, c, "alter causet test_on_uFIDelate_c add defCausumn c3 timestamp null default '2020-02-11' on uFIDelate current_timestamp;") 2106 is := petri.GetPetri(ctx).SchemaReplicant() 2107 tbl, err := is.BlockByName(perceptron.NewCIStr("test_db"), perceptron.NewCIStr("test_on_uFIDelate_c")) 2108 c.Assert(err, IsNil) 2109 tblInfo := tbl.Meta() 2110 defCausC := tblInfo.DeferredCausets[2] 2111 c.Assert(defCausC.Tp, Equals, allegrosql.TypeTimestamp) 2112 hasNotNull := allegrosql.HasNotNullFlag(defCausC.Flag) 2113 c.Assert(hasNotNull, IsFalse) 2114 // add datetime type defCausumn 2115 s.mustInterDirc(tk, c, "create causet test_on_uFIDelate_d (c1 int, c2 datetime);") 2116 defer tk.MustInterDirc("drop causet test_on_uFIDelate_d;") 2117 s.mustInterDirc(tk, c, "alter causet test_on_uFIDelate_d add defCausumn c3 datetime on uFIDelate current_timestamp;") 2118 is = petri.GetPetri(ctx).SchemaReplicant() 2119 tbl, err = is.BlockByName(perceptron.NewCIStr("test_db"), perceptron.NewCIStr("test_on_uFIDelate_d")) 2120 c.Assert(err, IsNil) 2121 tblInfo = tbl.Meta() 2122 defCausC = tblInfo.DeferredCausets[2] 2123 c.Assert(defCausC.Tp, Equals, allegrosql.TypeDatetime) 2124 hasNotNull = allegrosql.HasNotNullFlag(defCausC.Flag) 2125 c.Assert(hasNotNull, IsFalse) 2126 2127 // add year type defCausumn 2128 s.mustInterDirc(tk, c, "create causet test_on_uFIDelate_e (c1 int);") 2129 defer tk.MustInterDirc("drop causet test_on_uFIDelate_e;") 2130 s.mustInterDirc(tk, c, "insert into test_on_uFIDelate_e (c1) values (0);") 2131 s.mustInterDirc(tk, c, "alter causet test_on_uFIDelate_e add defCausumn c2 year not null;") 2132 tk.MustQuery("select c2 from test_on_uFIDelate_e").Check(testkit.Rows("0")) 2133 2134 // test add unsupported constraint 2135 s.mustInterDirc(tk, c, "create causet t_add_unsupported_constraint (a int);") 2136 _, err = tk.InterDirc("ALTER TABLE t_add_unsupported_constraint ADD id int AUTO_INCREMENT;") 2137 c.Assert(err.Error(), Equals, "[dbs:8200]unsupported add defCausumn 'id' constraint AUTO_INCREMENT when altering 'test_db.t_add_unsupported_constraint'") 2138 _, err = tk.InterDirc("ALTER TABLE t_add_unsupported_constraint ADD id int KEY;") 2139 c.Assert(err.Error(), Equals, "[dbs:8200]unsupported add defCausumn 'id' constraint PRIMARY KEY when altering 'test_db.t_add_unsupported_constraint'") 2140 _, err = tk.InterDirc("ALTER TABLE t_add_unsupported_constraint ADD id int UNIQUE;") 2141 c.Assert(err.Error(), Equals, "[dbs:8200]unsupported add defCausumn 'id' constraint UNIQUE KEY when altering 'test_db.t_add_unsupported_constraint'") 2142 } 2143 2144 func (s *testDBSuite) testDropDeferredCauset(tk *testkit.TestKit, c *C) { 2145 done := make(chan error, 1) 2146 s.mustInterDirc(tk, c, "delete from t2") 2147 2148 num := 100 2149 // add some rows 2150 for i := 0; i < num; i++ { 2151 s.mustInterDirc(tk, c, "insert into t2 values (?, ?, ?, ?)", i, i, i, i) 2152 } 2153 2154 // get c4 defCausumn id 2155 testdbsutil.StochastikInterDircInGoroutine(c, s.causetstore, "alter causet t2 drop defCausumn c4", done) 2156 2157 ticker := time.NewTicker(s.lease / 2) 2158 defer ticker.Stop() 2159 step := 10 2160 LOOP: 2161 for { 2162 select { 2163 case err := <-done: 2164 if err == nil { 2165 break LOOP 2166 } 2167 c.Assert(err, IsNil, Commentf("err:%v", errors.ErrorStack(err))) 2168 case <-ticker.C: 2169 // delete some rows, and add some data 2170 for i := num; i < num+step; i++ { 2171 // Make sure that memex of insert and show use the same schemaReplicant. 2172 tk.MustInterDirc("begin") 2173 _, err := tk.InterDirc("insert into t2 values (?, ?, ?)", i, i, i) 2174 if err != nil { 2175 // If executing is failed, the defCausumn number must be 4 now. 2176 values := s.showDeferredCausets(tk, c, "t2") 2177 c.Assert(values, HasLen, 4, Commentf("err:%v", errors.ErrorStack(err))) 2178 } 2179 tk.MustInterDirc("commit") 2180 } 2181 num += step 2182 } 2183 } 2184 2185 // add data, here c4 must not exist 2186 for i := num; i < num+step; i++ { 2187 s.mustInterDirc(tk, c, "insert into t2 values (?, ?, ?)", i, i, i) 2188 } 2189 2190 rows := s.mustQuery(tk, c, "select count(*) from t2") 2191 c.Assert(rows, HasLen, 1) 2192 c.Assert(rows[0], HasLen, 1) 2193 count, err := strconv.ParseInt(rows[0][0].(string), 10, 64) 2194 c.Assert(err, IsNil) 2195 c.Assert(count, Greater, int64(0)) 2196 } 2197 2198 // TestDropDeferredCauset is for inserting value with a to-be-dropped defCausumn when do drop defCausumn. 2199 // DeferredCauset info from schemaReplicant in build-insert-plan should be public only, 2200 // otherwise they will not be consist with Block.DefCaus(), then the server will panic. 2201 func (s *testDBSuite6) TestDropDeferredCauset(c *C) { 2202 tk := testkit.NewTestKit(c, s.causetstore) 2203 tk.MustInterDirc("create database drop_defCaus_db") 2204 tk.MustInterDirc("use drop_defCaus_db") 2205 num := 25 2206 multiDBS := make([]string, 0, num) 2207 allegrosql := "create causet t2 (c1 int, c2 int, c3 int, " 2208 for i := 4; i < 4+num; i++ { 2209 multiDBS = append(multiDBS, fmt.Sprintf("alter causet t2 drop defCausumn c%d", i)) 2210 2211 if i != 3+num { 2212 allegrosql += fmt.Sprintf("c%d int, ", i) 2213 } else { 2214 allegrosql += fmt.Sprintf("c%d int)", i) 2215 } 2216 } 2217 tk.MustInterDirc(allegrosql) 2218 dmlDone := make(chan error, num) 2219 dbsDone := make(chan error, num) 2220 2221 testdbsutil.InterDircMultiALLEGROSQLInGoroutine(c, s.causetstore, "drop_defCaus_db", multiDBS, dbsDone) 2222 for i := 0; i < num; i++ { 2223 testdbsutil.InterDircMultiALLEGROSQLInGoroutine(c, s.causetstore, "drop_defCaus_db", []string{"insert into t2 set c1 = 1, c2 = 1, c3 = 1, c4 = 1"}, dmlDone) 2224 } 2225 for i := 0; i < num; i++ { 2226 select { 2227 case err := <-dbsDone: 2228 c.Assert(err, IsNil, Commentf("err:%v", errors.ErrorStack(err))) 2229 } 2230 } 2231 2232 // Test for drop partition causet defCausumn. 2233 tk.MustInterDirc("drop causet if exists t1") 2234 tk.MustInterDirc("create causet t1 (a int,b int) partition by hash(a) partitions 4;") 2235 _, err := tk.InterDirc("alter causet t1 drop defCausumn a") 2236 c.Assert(err, NotNil) 2237 c.Assert(err.Error(), Equals, "[memex:1054]Unknown defCausumn 'a' in 'memex'") 2238 2239 tk.MustInterDirc("drop database drop_defCaus_db") 2240 } 2241 2242 func (s *testDBSuite4) TestChangeDeferredCauset(c *C) { 2243 tk := testkit.NewTestKit(c, s.causetstore) 2244 tk.MustInterDirc("use " + s.schemaName) 2245 2246 s.mustInterDirc(tk, c, "create causet t3 (a int default '0', b varchar(10), d int not null default '0')") 2247 s.mustInterDirc(tk, c, "insert into t3 set b = 'a'") 2248 tk.MustQuery("select a from t3").Check(testkit.Rows("0")) 2249 s.mustInterDirc(tk, c, "alter causet t3 change a aa bigint") 2250 s.mustInterDirc(tk, c, "insert into t3 set b = 'b'") 2251 tk.MustQuery("select aa from t3").Check(testkit.Rows("0", "<nil>")) 2252 // for no default flag 2253 s.mustInterDirc(tk, c, "alter causet t3 change d dd bigint not null") 2254 ctx := tk.Se.(stochastikctx.Context) 2255 is := petri.GetPetri(ctx).SchemaReplicant() 2256 tbl, err := is.BlockByName(perceptron.NewCIStr("test_db"), perceptron.NewCIStr("t3")) 2257 c.Assert(err, IsNil) 2258 tblInfo := tbl.Meta() 2259 defCausD := tblInfo.DeferredCausets[2] 2260 hasNoDefault := allegrosql.HasNoDefaultValueFlag(defCausD.Flag) 2261 c.Assert(hasNoDefault, IsTrue) 2262 // for the following definitions: 'not null', 'null', 'default value' and 'comment' 2263 s.mustInterDirc(tk, c, "alter causet t3 change b b varchar(20) null default 'c' comment 'my comment'") 2264 is = petri.GetPetri(ctx).SchemaReplicant() 2265 tbl, err = is.BlockByName(perceptron.NewCIStr("test_db"), perceptron.NewCIStr("t3")) 2266 c.Assert(err, IsNil) 2267 tblInfo = tbl.Meta() 2268 defCausB := tblInfo.DeferredCausets[1] 2269 c.Assert(defCausB.Comment, Equals, "my comment") 2270 hasNotNull := allegrosql.HasNotNullFlag(defCausB.Flag) 2271 c.Assert(hasNotNull, IsFalse) 2272 s.mustInterDirc(tk, c, "insert into t3 set aa = 3, dd = 5") 2273 tk.MustQuery("select b from t3").Check(testkit.Rows("a", "b", "c")) 2274 // for timestamp 2275 s.mustInterDirc(tk, c, "alter causet t3 add defCausumn c timestamp not null") 2276 s.mustInterDirc(tk, c, "alter causet t3 change c c timestamp null default '2020-02-11' comment 'defCaus c comment' on uFIDelate current_timestamp") 2277 is = petri.GetPetri(ctx).SchemaReplicant() 2278 tbl, err = is.BlockByName(perceptron.NewCIStr("test_db"), perceptron.NewCIStr("t3")) 2279 c.Assert(err, IsNil) 2280 tblInfo = tbl.Meta() 2281 defCausC := tblInfo.DeferredCausets[3] 2282 c.Assert(defCausC.Comment, Equals, "defCaus c comment") 2283 hasNotNull = allegrosql.HasNotNullFlag(defCausC.Flag) 2284 c.Assert(hasNotNull, IsFalse) 2285 // for enum 2286 s.mustInterDirc(tk, c, "alter causet t3 add defCausumn en enum('a', 'b', 'c') not null default 'a'") 2287 2288 // for failing tests 2289 allegrosql := "alter causet t3 change aa a bigint default ''" 2290 tk.MustGetErrCode(allegrosql, errno.ErrInvalidDefault) 2291 allegrosql = "alter causet t3 change a testx.t3.aa bigint" 2292 tk.MustGetErrCode(allegrosql, errno.ErrWrongDBName) 2293 allegrosql = "alter causet t3 change t.a aa bigint" 2294 tk.MustGetErrCode(allegrosql, errno.ErrWrongBlockName) 2295 s.mustInterDirc(tk, c, "create causet t4 (c1 int, c2 int, c3 int default 1, index (c1));") 2296 tk.MustInterDirc("insert into t4(c2) values (null);") 2297 allegrosql = "alter causet t4 change c1 a1 int not null;" 2298 tk.MustGetErrCode(allegrosql, errno.ErrInvalidUseOfNull) 2299 allegrosql = "alter causet t4 change c2 a bigint not null;" 2300 tk.MustGetErrCode(allegrosql, allegrosql.WarnDataTruncated) 2301 allegrosql = "alter causet t3 modify en enum('a', 'z', 'b', 'c') not null default 'a'" 2302 tk.MustGetErrCode(allegrosql, errno.ErrUnsupportedDBSOperation) 2303 // Rename to an existing defCausumn. 2304 s.mustInterDirc(tk, c, "alter causet t3 add defCausumn a bigint") 2305 allegrosql = "alter causet t3 change aa a bigint" 2306 tk.MustGetErrCode(allegrosql, errno.ErrDupFieldName) 2307 2308 tk.MustInterDirc("drop causet t3") 2309 } 2310 2311 func (s *testDBSuite5) TestRenameDeferredCauset(c *C) { 2312 tk := testkit.NewTestKit(c, s.causetstore) 2313 tk.MustInterDirc("use " + s.schemaName) 2314 2315 assertDefCausNames := func(blockName string, defCausNames ...string) { 2316 defcaus := s.testGetBlock(c, blockName).DefCauss() 2317 c.Assert(len(defcaus), Equals, len(defCausNames), Commentf("number of defCausumns mismatch")) 2318 for i := range defcaus { 2319 c.Assert(defcaus[i].Name.L, Equals, strings.ToLower(defCausNames[i])) 2320 } 2321 } 2322 2323 s.mustInterDirc(tk, c, "create causet test_rename_defCausumn (id int not null primary key auto_increment, defCaus1 int)") 2324 s.mustInterDirc(tk, c, "alter causet test_rename_defCausumn rename defCausumn defCaus1 to defCaus1") 2325 assertDefCausNames("test_rename_defCausumn", "id", "defCaus1") 2326 s.mustInterDirc(tk, c, "alter causet test_rename_defCausumn rename defCausumn defCaus1 to defCaus2") 2327 assertDefCausNames("test_rename_defCausumn", "id", "defCaus2") 2328 2329 // Test renaming non-exist defCausumns. 2330 tk.MustGetErrCode("alter causet test_rename_defCausumn rename defCausumn non_exist_defCaus to defCaus3", errno.ErrBadField) 2331 2332 // Test renaming to an exist defCausumn. 2333 tk.MustGetErrCode("alter causet test_rename_defCausumn rename defCausumn defCaus2 to id", errno.ErrDupFieldName) 2334 2335 // Test renaming the defCausumn with foreign key. 2336 tk.MustInterDirc("drop causet test_rename_defCausumn") 2337 tk.MustInterDirc("create causet test_rename_defCausumn_base (base int)") 2338 tk.MustInterDirc("create causet test_rename_defCausumn (defCaus int, foreign key (defCaus) references test_rename_defCausumn_base(base))") 2339 2340 tk.MustGetErrCode("alter causet test_rename_defCausumn rename defCausumn defCaus to defCaus1", errno.ErrFKIncompatibleDeferredCausets) 2341 2342 tk.MustInterDirc("drop causet test_rename_defCausumn_base") 2343 2344 // Test renaming generated defCausumns. 2345 tk.MustInterDirc("drop causet test_rename_defCausumn") 2346 tk.MustInterDirc("create causet test_rename_defCausumn (id int, defCaus1 int generated always as (id + 1))") 2347 2348 s.mustInterDirc(tk, c, "alter causet test_rename_defCausumn rename defCausumn defCaus1 to defCaus2") 2349 assertDefCausNames("test_rename_defCausumn", "id", "defCaus2") 2350 s.mustInterDirc(tk, c, "alter causet test_rename_defCausumn rename defCausumn defCaus2 to defCaus1") 2351 assertDefCausNames("test_rename_defCausumn", "id", "defCaus1") 2352 tk.MustGetErrCode("alter causet test_rename_defCausumn rename defCausumn id to id1", errno.ErrBadField) 2353 2354 // Test renaming view defCausumns. 2355 tk.MustInterDirc("drop causet test_rename_defCausumn") 2356 s.mustInterDirc(tk, c, "create causet test_rename_defCausumn (id int, defCaus1 int)") 2357 s.mustInterDirc(tk, c, "create view test_rename_defCausumn_view as select * from test_rename_defCausumn") 2358 2359 s.mustInterDirc(tk, c, "alter causet test_rename_defCausumn rename defCausumn defCaus1 to defCaus2") 2360 tk.MustGetErrCode("select * from test_rename_defCausumn_view", errno.ErrViewInvalid) 2361 2362 s.mustInterDirc(tk, c, "drop view test_rename_defCausumn_view") 2363 tk.MustInterDirc("drop causet test_rename_defCausumn") 2364 } 2365 2366 func (s *testDBSuite7) TestSelectInViewFromAnotherDB(c *C) { 2367 _, _ = s.s.InterDircute(context.Background(), "create database test_db2") 2368 tk := testkit.NewTestKit(c, s.causetstore) 2369 tk.MustInterDirc("use " + s.schemaName) 2370 tk.MustInterDirc("create causet t(a int)") 2371 tk.MustInterDirc("use test_db2") 2372 tk.MustInterDirc("create allegrosql security invoker view v as select * from " + s.schemaName + ".t") 2373 tk.MustInterDirc("use " + s.schemaName) 2374 tk.MustInterDirc("select test_db2.v.a from test_db2.v") 2375 } 2376 2377 func (s *testDBSuite) mustInterDirc(tk *testkit.TestKit, c *C, query string, args ...interface{}) { 2378 tk.MustInterDirc(query, args...) 2379 } 2380 2381 func (s *testDBSuite) mustQuery(tk *testkit.TestKit, c *C, query string, args ...interface{}) [][]interface{} { 2382 r := tk.MustQuery(query, args...) 2383 return r.Rows() 2384 } 2385 2386 func matchRows(c *C, rows [][]interface{}, expected [][]interface{}) { 2387 c.Assert(len(rows), Equals, len(expected), Commentf("got %v, expected %v", rows, expected)) 2388 for i := range rows { 2389 match(c, rows[i], expected[i]...) 2390 } 2391 } 2392 2393 func match(c *C, event []interface{}, expected ...interface{}) { 2394 c.Assert(len(event), Equals, len(expected)) 2395 for i := range event { 2396 got := fmt.Sprintf("%v", event[i]) 2397 need := fmt.Sprintf("%v", expected[i]) 2398 c.Assert(got, Equals, need) 2399 } 2400 } 2401 2402 // TestCreateBlockWithLike2 tests create causet with like when refer causet have non-public defCausumn/index. 2403 func (s *testSerialDBSuite) TestCreateBlockWithLike2(c *C) { 2404 tk := testkit.NewTestKit(c, s.causetstore) 2405 tk.MustInterDirc("use test_db") 2406 tk.MustInterDirc("drop causet if exists t1,t2;") 2407 defer tk.MustInterDirc("drop causet if exists t1,t2;") 2408 tk.MustInterDirc("create causet t1 (a int, b int, c int, index idx1(c));") 2409 2410 tbl1 := testGetBlockByName(c, s.s, "test_db", "t1") 2411 doneCh := make(chan error, 2) 2412 hook := &dbs.TestDBSCallback{} 2413 var onceChecker sync.Map 2414 hook.OnJobRunBeforeExported = func(job *perceptron.Job) { 2415 if job.Type != perceptron.CausetActionAddDeferredCauset && job.Type != perceptron.CausetActionDropDeferredCauset && 2416 job.Type != perceptron.CausetActionAddDeferredCausets && job.Type != perceptron.CausetActionDropDeferredCausets && 2417 job.Type != perceptron.CausetActionAddIndex && job.Type != perceptron.CausetActionDropIndex { 2418 return 2419 } 2420 if job.BlockID != tbl1.Meta().ID { 2421 return 2422 } 2423 2424 if job.SchemaState == perceptron.StateDeleteOnly { 2425 if _, ok := onceChecker.Load(job.ID); ok { 2426 return 2427 } 2428 2429 onceChecker.CausetStore(job.ID, true) 2430 go backgroundInterDirc(s.causetstore, "create causet t2 like t1", doneCh) 2431 } 2432 } 2433 originalHook := s.dom.DBS().GetHook() 2434 defer s.dom.DBS().(dbs.DBSForTest).SetHook(originalHook) 2435 s.dom.DBS().(dbs.DBSForTest).SetHook(hook) 2436 2437 // create causet when refer causet add defCausumn 2438 tk.MustInterDirc("alter causet t1 add defCausumn d int") 2439 checkTbl2 := func() { 2440 err := <-doneCh 2441 c.Assert(err, IsNil) 2442 tk.MustInterDirc("alter causet t2 add defCausumn e int") 2443 t2Info := testGetBlockByName(c, s.s, "test_db", "t2") 2444 c.Assert(len(t2Info.Meta().DeferredCausets), Equals, len(t2Info.DefCauss())) 2445 } 2446 checkTbl2() 2447 2448 // create causet when refer causet drop defCausumn 2449 tk.MustInterDirc("drop causet t2;") 2450 tk.MustInterDirc("alter causet t1 drop defCausumn b;") 2451 checkTbl2() 2452 2453 // create causet when refer causet add index 2454 tk.MustInterDirc("drop causet t2;") 2455 tk.MustInterDirc("alter causet t1 add index idx2(a);") 2456 checkTbl2 = func() { 2457 err := <-doneCh 2458 c.Assert(err, IsNil) 2459 tk.MustInterDirc("alter causet t2 add defCausumn e int") 2460 tbl2 := testGetBlockByName(c, s.s, "test_db", "t2") 2461 c.Assert(len(tbl2.Meta().DeferredCausets), Equals, len(tbl2.DefCauss())) 2462 2463 for i := 0; i < len(tbl2.Meta().Indices); i++ { 2464 c.Assert(tbl2.Meta().Indices[i].State, Equals, perceptron.StatePublic) 2465 } 2466 } 2467 checkTbl2() 2468 2469 // create causet when refer causet drop index. 2470 tk.MustInterDirc("drop causet t2;") 2471 tk.MustInterDirc("alter causet t1 drop index idx2;") 2472 checkTbl2() 2473 2474 // Test for causet has tiflash replica. 2475 c.Assert(failpoint.Enable("github.com/whtcorpsinc/milevadb/schemareplicant/mockTiFlashStoreCount", `return(true)`), IsNil) 2476 defer failpoint.Disable("github.com/whtcorpsinc/milevadb/schemareplicant/mockTiFlashStoreCount") 2477 2478 s.dom.DBS().(dbs.DBSForTest).SetHook(originalHook) 2479 tk.MustInterDirc("drop causet if exists t1,t2;") 2480 tk.MustInterDirc("create causet t1 (a int) partition by hash(a) partitions 2;") 2481 tk.MustInterDirc("alter causet t1 set tiflash replica 3 location labels 'a','b';") 2482 t1 := testGetBlockByName(c, s.s, "test_db", "t1") 2483 // Mock for all partitions replica was available. 2484 partition := t1.Meta().Partition 2485 c.Assert(len(partition.Definitions), Equals, 2) 2486 err := petri.GetPetri(tk.Se).DBS().UFIDelateBlockReplicaInfo(tk.Se, partition.Definitions[0].ID, true) 2487 c.Assert(err, IsNil) 2488 err = petri.GetPetri(tk.Se).DBS().UFIDelateBlockReplicaInfo(tk.Se, partition.Definitions[1].ID, true) 2489 c.Assert(err, IsNil) 2490 t1 = testGetBlockByName(c, s.s, "test_db", "t1") 2491 c.Assert(t1.Meta().TiFlashReplica, NotNil) 2492 c.Assert(t1.Meta().TiFlashReplica.Available, IsTrue) 2493 c.Assert(t1.Meta().TiFlashReplica.AvailablePartitionIDs, DeepEquals, []int64{partition.Definitions[0].ID, partition.Definitions[1].ID}) 2494 2495 tk.MustInterDirc("create causet t2 like t1") 2496 t2 := testGetBlockByName(c, s.s, "test_db", "t2") 2497 c.Assert(t2.Meta().TiFlashReplica.Count, Equals, t1.Meta().TiFlashReplica.Count) 2498 c.Assert(t2.Meta().TiFlashReplica.LocationLabels, DeepEquals, t1.Meta().TiFlashReplica.LocationLabels) 2499 c.Assert(t2.Meta().TiFlashReplica.Available, IsFalse) 2500 c.Assert(t2.Meta().TiFlashReplica.AvailablePartitionIDs, HasLen, 0) 2501 // Test for not affecting the original causet. 2502 t1 = testGetBlockByName(c, s.s, "test_db", "t1") 2503 c.Assert(t1.Meta().TiFlashReplica, NotNil) 2504 c.Assert(t1.Meta().TiFlashReplica.Available, IsTrue) 2505 c.Assert(t1.Meta().TiFlashReplica.AvailablePartitionIDs, DeepEquals, []int64{partition.Definitions[0].ID, partition.Definitions[1].ID}) 2506 } 2507 2508 func (s *testSerialDBSuite) TestCreateBlock(c *C) { 2509 tk := testkit.NewTestKit(c, s.causetstore) 2510 tk.MustInterDirc("use test") 2511 tk.MustInterDirc("CREATE TABLE `t` (`a` double DEFAULT 1.0 DEFAULT now() DEFAULT 2.0 );") 2512 tk.MustInterDirc("CREATE TABLE IF NOT EXISTS `t` (`a` double DEFAULT 1.0 DEFAULT now() DEFAULT 2.0 );") 2513 ctx := tk.Se.(stochastikctx.Context) 2514 is := petri.GetPetri(ctx).SchemaReplicant() 2515 tbl, err := is.BlockByName(perceptron.NewCIStr("test"), perceptron.NewCIStr("t")) 2516 c.Assert(err, IsNil) 2517 defcaus := tbl.DefCauss() 2518 2519 c.Assert(len(defcaus), Equals, 1) 2520 defCaus := defcaus[0] 2521 c.Assert(defCaus.Name.L, Equals, "a") 2522 d, ok := defCaus.DefaultValue.(string) 2523 c.Assert(ok, IsTrue) 2524 c.Assert(d, Equals, "2.0") 2525 2526 tk.MustInterDirc("drop causet t") 2527 2528 tk.MustGetErrCode("CREATE TABLE `t` (`a` int) DEFAULT CHARSET=abcdefg", errno.ErrUnknownCharacterSet) 2529 2530 tk.MustInterDirc("CREATE TABLE `defCauslateTest` (`a` int, `b` varchar(10)) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_slovak_ci") 2531 expects := "defCauslateTest CREATE TABLE `defCauslateTest` (\n `a` int(11) DEFAULT NULL,\n `b` varchar(10) COLLATE utf8_slovak_ci DEFAULT NULL\n) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_slovak_ci" 2532 tk.MustQuery("show create causet defCauslateTest").Check(testkit.Rows(expects)) 2533 2534 tk.MustGetErrCode("CREATE TABLE `defCauslateTest2` (`a` int) CHARSET utf8 COLLATE utf8mb4_unicode_ci", errno.ErrDefCauslationCharsetMismatch) 2535 tk.MustGetErrCode("CREATE TABLE `defCauslateTest3` (`a` int) COLLATE utf8mb4_unicode_ci CHARSET utf8", errno.ErrConflictingDeclarations) 2536 2537 tk.MustInterDirc("CREATE TABLE `defCauslateTest4` (`a` int) COLLATE utf8_uniCOde_ci") 2538 expects = "defCauslateTest4 CREATE TABLE `defCauslateTest4` (\n `a` int(11) DEFAULT NULL\n) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci" 2539 tk.MustQuery("show create causet defCauslateTest4").Check(testkit.Rows(expects)) 2540 2541 tk.MustInterDirc("create database test2 default charset utf8 defCauslate utf8_general_ci") 2542 tk.MustInterDirc("use test2") 2543 tk.MustInterDirc("create causet dbDefCauslateTest (a varchar(10))") 2544 expects = "dbDefCauslateTest CREATE TABLE `dbDefCauslateTest` (\n `a` varchar(10) COLLATE utf8_general_ci DEFAULT NULL\n) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci" 2545 tk.MustQuery("show create causet dbDefCauslateTest").Check(testkit.Rows(expects)) 2546 2547 // test for enum defCausumn 2548 tk.MustInterDirc("use test") 2549 failALLEGROSQL := "create causet t_enum (a enum('e','e'));" 2550 tk.MustGetErrCode(failALLEGROSQL, errno.ErrDuplicatedValueInType) 2551 defCauslate.SetNewDefCauslationEnabledForTest(true) 2552 defer defCauslate.SetNewDefCauslationEnabledForTest(false) 2553 tk = testkit.NewTestKit(c, s.causetstore) 2554 tk.MustInterDirc("use test") 2555 failALLEGROSQL = "create causet t_enum (a enum('e','E')) charset=utf8 defCauslate=utf8_general_ci;" 2556 tk.MustGetErrCode(failALLEGROSQL, errno.ErrDuplicatedValueInType) 2557 failALLEGROSQL = "create causet t_enum (a enum('abc','Abc')) charset=utf8 defCauslate=utf8_general_ci;" 2558 tk.MustGetErrCode(failALLEGROSQL, errno.ErrDuplicatedValueInType) 2559 failALLEGROSQL = "create causet t_enum (a enum('e','E')) charset=utf8 defCauslate=utf8_unicode_ci;" 2560 tk.MustGetErrCode(failALLEGROSQL, errno.ErrDuplicatedValueInType) 2561 failALLEGROSQL = "create causet t_enum (a enum('ss','ß')) charset=utf8 defCauslate=utf8_unicode_ci;" 2562 tk.MustGetErrCode(failALLEGROSQL, errno.ErrDuplicatedValueInType) 2563 // test for set defCausumn 2564 failALLEGROSQL = "create causet t_enum (a set('e','e'));" 2565 tk.MustGetErrCode(failALLEGROSQL, errno.ErrDuplicatedValueInType) 2566 failALLEGROSQL = "create causet t_enum (a set('e','E')) charset=utf8 defCauslate=utf8_general_ci;" 2567 tk.MustGetErrCode(failALLEGROSQL, errno.ErrDuplicatedValueInType) 2568 failALLEGROSQL = "create causet t_enum (a set('abc','Abc')) charset=utf8 defCauslate=utf8_general_ci;" 2569 tk.MustGetErrCode(failALLEGROSQL, errno.ErrDuplicatedValueInType) 2570 _, err = tk.InterDirc("create causet t_enum (a enum('B','b')) charset=utf8 defCauslate=utf8_general_ci;") 2571 c.Assert(err.Error(), Equals, "[types:1291]DeferredCauset 'a' has duplicated value 'b' in ENUM") 2572 failALLEGROSQL = "create causet t_enum (a set('e','E')) charset=utf8 defCauslate=utf8_unicode_ci;" 2573 tk.MustGetErrCode(failALLEGROSQL, errno.ErrDuplicatedValueInType) 2574 failALLEGROSQL = "create causet t_enum (a set('ss','ß')) charset=utf8 defCauslate=utf8_unicode_ci;" 2575 tk.MustGetErrCode(failALLEGROSQL, errno.ErrDuplicatedValueInType) 2576 _, err = tk.InterDirc("create causet t_enum (a enum('ss','ß')) charset=utf8 defCauslate=utf8_unicode_ci;") 2577 c.Assert(err.Error(), Equals, "[types:1291]DeferredCauset 'a' has duplicated value 'ß' in ENUM") 2578 2579 // test for causet option "union" not supported 2580 tk.MustInterDirc("use test") 2581 tk.MustInterDirc("CREATE TABLE x (a INT) ENGINE = MyISAM;") 2582 tk.MustInterDirc("CREATE TABLE y (a INT) ENGINE = MyISAM;") 2583 failALLEGROSQL = "CREATE TABLE z (a INT) ENGINE = MERGE UNION = (x, y);" 2584 tk.MustGetErrCode(failALLEGROSQL, errno.ErrBlockOptionUnionUnsupported) 2585 failALLEGROSQL = "ALTER TABLE x UNION = (y);" 2586 tk.MustGetErrCode(failALLEGROSQL, errno.ErrBlockOptionUnionUnsupported) 2587 tk.MustInterDirc("drop causet x;") 2588 tk.MustInterDirc("drop causet y;") 2589 2590 // test for causet option "insert method" not supported 2591 tk.MustInterDirc("use test") 2592 tk.MustInterDirc("CREATE TABLE x (a INT) ENGINE = MyISAM;") 2593 tk.MustInterDirc("CREATE TABLE y (a INT) ENGINE = MyISAM;") 2594 failALLEGROSQL = "CREATE TABLE z (a INT) ENGINE = MERGE INSERT_METHOD=LAST;" 2595 tk.MustGetErrCode(failALLEGROSQL, errno.ErrBlockOptionInsertMethodUnsupported) 2596 failALLEGROSQL = "ALTER TABLE x INSERT_METHOD=LAST;" 2597 tk.MustGetErrCode(failALLEGROSQL, errno.ErrBlockOptionInsertMethodUnsupported) 2598 tk.MustInterDirc("drop causet x;") 2599 tk.MustInterDirc("drop causet y;") 2600 } 2601 2602 func (s *testSerialDBSuite) TestRepairBlock(c *C) { 2603 // TODO: When AlterPrimaryKey is false, this test fails. Fix it later. 2604 defer config.RestoreFunc()() 2605 config.UFIDelateGlobal(func(conf *config.Config) { 2606 conf.AlterPrimaryKey = true 2607 }) 2608 c.Assert(failpoint.Enable("github.com/whtcorpsinc/milevadb/schemareplicant/repairFetchCreateBlock", `return(true)`), IsNil) 2609 defer func() { 2610 c.Assert(failpoint.Disable("github.com/whtcorpsinc/milevadb/schemareplicant/repairFetchCreateBlock"), IsNil) 2611 }() 2612 tk := testkit.NewTestKit(c, s.causetstore) 2613 tk.MustInterDirc("use test") 2614 tk.MustInterDirc("drop causet if exists t, other_block, origin") 2615 2616 // Test repair causet when MilevaDB is not in repair mode. 2617 tk.MustInterDirc("CREATE TABLE t (a int primary key, b varchar(10));") 2618 _, err := tk.InterDirc("admin repair causet t CREATE TABLE t (a float primary key, b varchar(5));") 2619 c.Assert(err, NotNil) 2620 c.Assert(err.Error(), Equals, "[dbs:8215]Failed to repair causet: MilevaDB is not in REPAIR MODE") 2621 2622 // Test repair causet when the repaired list is empty. 2623 petriutil.RepairInfo.SetRepairMode(true) 2624 _, err = tk.InterDirc("admin repair causet t CREATE TABLE t (a float primary key, b varchar(5));") 2625 c.Assert(err, NotNil) 2626 c.Assert(err.Error(), Equals, "[dbs:8215]Failed to repair causet: repair list is empty") 2627 2628 // Test repair causet when it's database isn't in repairInfo. 2629 petriutil.RepairInfo.SetRepairBlockList([]string{"test.other_block"}) 2630 _, err = tk.InterDirc("admin repair causet t CREATE TABLE t (a float primary key, b varchar(5));") 2631 c.Assert(err, NotNil) 2632 c.Assert(err.Error(), Equals, "[dbs:8215]Failed to repair causet: database test is not in repair") 2633 2634 // Test repair causet when the causet isn't in repairInfo. 2635 tk.MustInterDirc("CREATE TABLE other_block (a int, b varchar(1), key using hash(b));") 2636 _, err = tk.InterDirc("admin repair causet t CREATE TABLE t (a float primary key, b varchar(5));") 2637 c.Assert(err, NotNil) 2638 c.Assert(err.Error(), Equals, "[dbs:8215]Failed to repair causet: causet t is not in repair") 2639 2640 // Test user can't access to the repaired causet. 2641 _, err = tk.InterDirc("select * from other_block") 2642 c.Assert(err, NotNil) 2643 c.Assert(err.Error(), Equals, "[schemaReplicant:1146]Block 'test.other_block' doesn't exist") 2644 2645 // Test create memex use the same name with what is in repaired. 2646 _, err = tk.InterDirc("CREATE TABLE other_block (a int);") 2647 c.Assert(err, NotNil) 2648 c.Assert(err.Error(), Equals, "[dbs:1103]Incorrect causet name 'other_block'%!(EXTRA string=this causet is in repair)") 2649 2650 // Test defCausumn lost in repair causet. 2651 _, err = tk.InterDirc("admin repair causet other_block CREATE TABLE other_block (a int, c char(1));") 2652 c.Assert(err, NotNil) 2653 c.Assert(err.Error(), Equals, "[dbs:8215]Failed to repair causet: DeferredCauset c has lost") 2654 2655 // Test defCausumn type should be the same. 2656 _, err = tk.InterDirc("admin repair causet other_block CREATE TABLE other_block (a bigint, b varchar(1), key using hash(b));") 2657 c.Assert(err, NotNil) 2658 c.Assert(err.Error(), Equals, "[dbs:8215]Failed to repair causet: DeferredCauset a type should be the same") 2659 2660 // Test index lost in repair causet. 2661 _, err = tk.InterDirc("admin repair causet other_block CREATE TABLE other_block (a int unique);") 2662 c.Assert(err, NotNil) 2663 c.Assert(err.Error(), Equals, "[dbs:8215]Failed to repair causet: Index a has lost") 2664 2665 // Test index type should be the same. 2666 _, err = tk.InterDirc("admin repair causet other_block CREATE TABLE other_block (a int, b varchar(2) unique)") 2667 c.Assert(err, NotNil) 2668 c.Assert(err.Error(), Equals, "[dbs:8215]Failed to repair causet: Index b type should be the same") 2669 2670 // Test sub create memex in repair memex with the same name. 2671 _, err = tk.InterDirc("admin repair causet other_block CREATE TABLE other_block (a int);") 2672 c.Assert(err, IsNil) 2673 2674 // Test whether repair causet name is case sensitive. 2675 petriutil.RepairInfo.SetRepairMode(true) 2676 petriutil.RepairInfo.SetRepairBlockList([]string{"test.other_block2"}) 2677 tk.MustInterDirc("CREATE TABLE otHer_tAblE2 (a int, b varchar(1));") 2678 _, err = tk.InterDirc("admin repair causet otHer_tAblE2 CREATE TABLE otHeR_tAbLe (a int, b varchar(2));") 2679 c.Assert(err, IsNil) 2680 repairBlock := testGetBlockByName(c, s.s, "test", "otHeR_tAbLe") 2681 c.Assert(repairBlock.Meta().Name.O, Equals, "otHeR_tAbLe") 2682 2683 // Test memory and system database is not for repair. 2684 petriutil.RepairInfo.SetRepairMode(true) 2685 petriutil.RepairInfo.SetRepairBlockList([]string{"test.xxx"}) 2686 _, err = tk.InterDirc("admin repair causet performance_schema.xxx CREATE TABLE yyy (a int);") 2687 c.Assert(err.Error(), Equals, "[dbs:8215]Failed to repair causet: memory or system database is not for repair") 2688 2689 // Test the repair detail. 2690 turnRepairModeAndInit(true) 2691 defer turnRepairModeAndInit(false) 2692 // Petri reload the blockInfo and add it into repairInfo. 2693 tk.MustInterDirc("CREATE TABLE origin (a int primary key auto_increment, b varchar(10), c int);") 2694 // Repaired blockInfo has been filtered by `petri.SchemaReplicant()`, so get it in repairInfo. 2695 originBlockInfo, _ := petriutil.RepairInfo.GetRepairedBlockInfoByBlockName("test", "origin") 2696 2697 hook := &dbs.TestDBSCallback{} 2698 var repairErr error 2699 hook.OnJobRunBeforeExported = func(job *perceptron.Job) { 2700 if job.Type != perceptron.CausetActionRepairBlock { 2701 return 2702 } 2703 if job.BlockID != originBlockInfo.ID { 2704 repairErr = errors.New("causet id should be the same") 2705 return 2706 } 2707 if job.SchemaState != perceptron.StateNone { 2708 repairErr = errors.New("repair job state should be the none") 2709 return 2710 } 2711 // Test whether it's readable, when repaired causet is still stateNone. 2712 tkInternal := testkit.NewTestKitWithInit(c, s.causetstore) 2713 _, repairErr = tkInternal.InterDirc("select * from origin") 2714 // Repaired blockInfo has been filtered by `petri.SchemaReplicant()`, here will get an error cause user can't get access to it. 2715 if repairErr != nil && terror.ErrorEqual(repairErr, schemareplicant.ErrBlockNotExists) { 2716 repairErr = nil 2717 } 2718 } 2719 originalHook := s.dom.DBS().GetHook() 2720 defer s.dom.DBS().(dbs.DBSForTest).SetHook(originalHook) 2721 s.dom.DBS().(dbs.DBSForTest).SetHook(hook) 2722 2723 // InterDirc the repair memex to override the blockInfo. 2724 tk.MustInterDirc("admin repair causet origin CREATE TABLE origin (a int primary key auto_increment, b varchar(5), c int);") 2725 c.Assert(repairErr, IsNil) 2726 2727 // Check the repaired blockInfo is exactly the same with old one in blockID, indexID, defCausID. 2728 // testGetBlockByName will extract the Block from `petri.SchemaReplicant()` directly. 2729 repairBlock = testGetBlockByName(c, s.s, "test", "origin") 2730 c.Assert(repairBlock.Meta().ID, Equals, originBlockInfo.ID) 2731 c.Assert(len(repairBlock.Meta().DeferredCausets), Equals, 3) 2732 c.Assert(repairBlock.Meta().DeferredCausets[0].ID, Equals, originBlockInfo.DeferredCausets[0].ID) 2733 c.Assert(repairBlock.Meta().DeferredCausets[1].ID, Equals, originBlockInfo.DeferredCausets[1].ID) 2734 c.Assert(repairBlock.Meta().DeferredCausets[2].ID, Equals, originBlockInfo.DeferredCausets[2].ID) 2735 c.Assert(len(repairBlock.Meta().Indices), Equals, 1) 2736 c.Assert(repairBlock.Meta().Indices[0].ID, Equals, originBlockInfo.DeferredCausets[0].ID) 2737 c.Assert(repairBlock.Meta().AutoIncID, Equals, originBlockInfo.AutoIncID) 2738 2739 c.Assert(repairBlock.Meta().DeferredCausets[0].Tp, Equals, allegrosql.TypeLong) 2740 c.Assert(repairBlock.Meta().DeferredCausets[1].Tp, Equals, allegrosql.TypeVarchar) 2741 c.Assert(repairBlock.Meta().DeferredCausets[1].Flen, Equals, 5) 2742 c.Assert(repairBlock.Meta().DeferredCausets[2].Tp, Equals, allegrosql.TypeLong) 2743 2744 // InterDirc the show create causet memex to make sure new blockInfo has been set. 2745 result := tk.MustQuery("show create causet origin") 2746 c.Assert(result.Rows()[0][1], Equals, "CREATE TABLE `origin` (\n `a` int(11) NOT NULL AUTO_INCREMENT,\n `b` varchar(5) DEFAULT NULL,\n `c` int(11) DEFAULT NULL,\n PRIMARY KEY (`a`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin") 2747 2748 } 2749 2750 func turnRepairModeAndInit(on bool) { 2751 list := make([]string, 0) 2752 if on { 2753 list = append(list, "test.origin") 2754 } 2755 petriutil.RepairInfo.SetRepairMode(on) 2756 petriutil.RepairInfo.SetRepairBlockList(list) 2757 } 2758 2759 func (s *testSerialDBSuite) TestRepairBlockWithPartition(c *C) { 2760 c.Assert(failpoint.Enable("github.com/whtcorpsinc/milevadb/schemareplicant/repairFetchCreateBlock", `return(true)`), IsNil) 2761 defer func() { 2762 c.Assert(failpoint.Disable("github.com/whtcorpsinc/milevadb/schemareplicant/repairFetchCreateBlock"), IsNil) 2763 }() 2764 tk := testkit.NewTestKit(c, s.causetstore) 2765 tk.MustInterDirc("use test") 2766 tk.MustInterDirc("drop causet if exists origin") 2767 2768 turnRepairModeAndInit(true) 2769 defer turnRepairModeAndInit(false) 2770 // Petri reload the blockInfo and add it into repairInfo. 2771 tk.MustInterDirc("create causet origin (a int not null) partition by RANGE(a) (" + 2772 "partition p10 values less than (10)," + 2773 "partition p30 values less than (30)," + 2774 "partition p50 values less than (50)," + 2775 "partition p70 values less than (70)," + 2776 "partition p90 values less than (90));") 2777 // Test for some old partition has lost. 2778 _, err := tk.InterDirc("admin repair causet origin create causet origin (a int not null) partition by RANGE(a) (" + 2779 "partition p10 values less than (10)," + 2780 "partition p30 values less than (30)," + 2781 "partition p50 values less than (50)," + 2782 "partition p90 values less than (90)," + 2783 "partition p100 values less than (100));") 2784 c.Assert(err, NotNil) 2785 c.Assert(err.Error(), Equals, "[dbs:8215]Failed to repair causet: Partition p100 has lost") 2786 2787 // Test for some partition changed the condition. 2788 _, err = tk.InterDirc("admin repair causet origin create causet origin (a int not null) partition by RANGE(a) (" + 2789 "partition p10 values less than (10)," + 2790 "partition p20 values less than (25)," + 2791 "partition p50 values less than (50)," + 2792 "partition p90 values less than (90));") 2793 c.Assert(err, NotNil) 2794 c.Assert(err.Error(), Equals, "[dbs:8215]Failed to repair causet: Partition p20 has lost") 2795 2796 // Test for some partition changed the partition name. 2797 _, err = tk.InterDirc("admin repair causet origin create causet origin (a int not null) partition by RANGE(a) (" + 2798 "partition p10 values less than (10)," + 2799 "partition p30 values less than (30)," + 2800 "partition pNew values less than (50)," + 2801 "partition p90 values less than (90));") 2802 c.Assert(err, NotNil) 2803 c.Assert(err.Error(), Equals, "[dbs:8215]Failed to repair causet: Partition pnew has lost") 2804 2805 originBlockInfo, _ := petriutil.RepairInfo.GetRepairedBlockInfoByBlockName("test", "origin") 2806 tk.MustInterDirc("admin repair causet origin create causet origin_rename (a int not null) partition by RANGE(a) (" + 2807 "partition p10 values less than (10)," + 2808 "partition p30 values less than (30)," + 2809 "partition p50 values less than (50)," + 2810 "partition p90 values less than (90));") 2811 repairBlock := testGetBlockByName(c, s.s, "test", "origin_rename") 2812 c.Assert(repairBlock.Meta().ID, Equals, originBlockInfo.ID) 2813 c.Assert(len(repairBlock.Meta().DeferredCausets), Equals, 1) 2814 c.Assert(repairBlock.Meta().DeferredCausets[0].ID, Equals, originBlockInfo.DeferredCausets[0].ID) 2815 c.Assert(len(repairBlock.Meta().Partition.Definitions), Equals, 4) 2816 c.Assert(repairBlock.Meta().Partition.Definitions[0].ID, Equals, originBlockInfo.Partition.Definitions[0].ID) 2817 c.Assert(repairBlock.Meta().Partition.Definitions[1].ID, Equals, originBlockInfo.Partition.Definitions[1].ID) 2818 c.Assert(repairBlock.Meta().Partition.Definitions[2].ID, Equals, originBlockInfo.Partition.Definitions[2].ID) 2819 c.Assert(repairBlock.Meta().Partition.Definitions[3].ID, Equals, originBlockInfo.Partition.Definitions[4].ID) 2820 2821 // Test hash partition. 2822 tk.MustInterDirc("drop causet if exists origin") 2823 petriutil.RepairInfo.SetRepairMode(true) 2824 petriutil.RepairInfo.SetRepairBlockList([]string{"test.origin"}) 2825 tk.MustInterDirc("create causet origin (a varchar(1), b int not null, c int, key idx(c)) partition by hash(b) partitions 30") 2826 2827 // Test partition num in repair should be exactly same with old one, other wise will cause partition semantic problem. 2828 _, err = tk.InterDirc("admin repair causet origin create causet origin (a varchar(2), b int not null, c int, key idx(c)) partition by hash(b) partitions 20") 2829 c.Assert(err, NotNil) 2830 c.Assert(err.Error(), Equals, "[dbs:8215]Failed to repair causet: Hash partition num should be the same") 2831 2832 originBlockInfo, _ = petriutil.RepairInfo.GetRepairedBlockInfoByBlockName("test", "origin") 2833 tk.MustInterDirc("admin repair causet origin create causet origin (a varchar(3), b int not null, c int, key idx(c)) partition by hash(b) partitions 30") 2834 repairBlock = testGetBlockByName(c, s.s, "test", "origin") 2835 c.Assert(repairBlock.Meta().ID, Equals, originBlockInfo.ID) 2836 c.Assert(len(repairBlock.Meta().Partition.Definitions), Equals, 30) 2837 c.Assert(repairBlock.Meta().Partition.Definitions[0].ID, Equals, originBlockInfo.Partition.Definitions[0].ID) 2838 c.Assert(repairBlock.Meta().Partition.Definitions[1].ID, Equals, originBlockInfo.Partition.Definitions[1].ID) 2839 c.Assert(repairBlock.Meta().Partition.Definitions[29].ID, Equals, originBlockInfo.Partition.Definitions[29].ID) 2840 } 2841 2842 func (s *testDBSuite2) TestCreateBlockWithSetDefCaus(c *C) { 2843 tk := testkit.NewTestKitWithInit(c, s.causetstore) 2844 tk.MustInterDirc("create causet t_set (a int, b set('e') default '');") 2845 tk.MustQuery("show create causet t_set").Check(testkit.Rows("t_set CREATE TABLE `t_set` (\n" + 2846 " `a` int(11) DEFAULT NULL,\n" + 2847 " `b` set('e') DEFAULT ''\n" + 2848 ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin")) 2849 tk.MustInterDirc("drop causet t_set") 2850 tk.MustInterDirc("create causet t_set (a set('a', 'b', 'c', 'd') default 'a,c,c');") 2851 tk.MustQuery("show create causet t_set").Check(testkit.Rows("t_set CREATE TABLE `t_set` (\n" + 2852 " `a` set('a','b','c','d') DEFAULT 'a,c'\n" + 2853 ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin")) 2854 2855 // It's for failure cases. 2856 // The type of default value is string. 2857 tk.MustInterDirc("drop causet t_set") 2858 failedALLEGROSQL := "create causet t_set (a set('1', '4', '10') default '3');" 2859 tk.MustGetErrCode(failedALLEGROSQL, errno.ErrInvalidDefault) 2860 failedALLEGROSQL = "create causet t_set (a set('1', '4', '10') default '1,4,11');" 2861 tk.MustGetErrCode(failedALLEGROSQL, errno.ErrInvalidDefault) 2862 failedALLEGROSQL = "create causet t_set (a set('1', '4', '10') default '1 ,4');" 2863 tk.MustGetErrCode(failedALLEGROSQL, errno.ErrInvalidDefault) 2864 // The type of default value is int. 2865 failedALLEGROSQL = "create causet t_set (a set('1', '4', '10') default 0);" 2866 tk.MustGetErrCode(failedALLEGROSQL, errno.ErrInvalidDefault) 2867 failedALLEGROSQL = "create causet t_set (a set('1', '4', '10') default 8);" 2868 tk.MustGetErrCode(failedALLEGROSQL, errno.ErrInvalidDefault) 2869 2870 // The type of default value is int. 2871 // It's for successful cases 2872 tk.MustInterDirc("create causet t_set (a set('1', '4', '10', '21') default 1);") 2873 tk.MustQuery("show create causet t_set").Check(testkit.Rows("t_set CREATE TABLE `t_set` (\n" + 2874 " `a` set('1','4','10','21') DEFAULT '1'\n" + 2875 ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin")) 2876 tk.MustInterDirc("drop causet t_set") 2877 tk.MustInterDirc("create causet t_set (a set('1', '4', '10', '21') default 2);") 2878 tk.MustQuery("show create causet t_set").Check(testkit.Rows("t_set CREATE TABLE `t_set` (\n" + 2879 " `a` set('1','4','10','21') DEFAULT '4'\n" + 2880 ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin")) 2881 tk.MustInterDirc("drop causet t_set") 2882 tk.MustInterDirc("create causet t_set (a set('1', '4', '10', '21') default 3);") 2883 tk.MustQuery("show create causet t_set").Check(testkit.Rows("t_set CREATE TABLE `t_set` (\n" + 2884 " `a` set('1','4','10','21') DEFAULT '1,4'\n" + 2885 ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin")) 2886 tk.MustInterDirc("drop causet t_set") 2887 tk.MustInterDirc("create causet t_set (a set('1', '4', '10', '21') default 15);") 2888 tk.MustQuery("show create causet t_set").Check(testkit.Rows("t_set CREATE TABLE `t_set` (\n" + 2889 " `a` set('1','4','10','21') DEFAULT '1,4,10,21'\n" + 2890 ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin")) 2891 tk.MustInterDirc("insert into t_set value()") 2892 tk.MustQuery("select * from t_set").Check(testkit.Rows("1,4,10,21")) 2893 } 2894 2895 func (s *testDBSuite2) TestBlockForeignKey(c *C) { 2896 tk := testkit.NewTestKit(c, s.causetstore) 2897 tk.MustInterDirc("use test") 2898 tk.MustInterDirc("create causet t1 (a int, b int);") 2899 // test create causet with foreign key. 2900 failALLEGROSQL := "create causet t2 (c int, foreign key (a) references t1(a));" 2901 tk.MustGetErrCode(failALLEGROSQL, errno.ErrKeyDeferredCausetDoesNotExits) 2902 // test add foreign key. 2903 tk.MustInterDirc("create causet t3 (a int, b int);") 2904 failALLEGROSQL = "alter causet t1 add foreign key (c) REFERENCES t3(a);" 2905 tk.MustGetErrCode(failALLEGROSQL, errno.ErrKeyDeferredCausetDoesNotExits) 2906 // test oreign key not match error 2907 failALLEGROSQL = "alter causet t1 add foreign key (a) REFERENCES t3(a, b);" 2908 tk.MustGetErrCode(failALLEGROSQL, errno.ErrWrongFkDef) 2909 // Test drop defCausumn with foreign key. 2910 tk.MustInterDirc("create causet t4 (c int,d int,foreign key (d) references t1 (b));") 2911 failALLEGROSQL = "alter causet t4 drop defCausumn d" 2912 tk.MustGetErrCode(failALLEGROSQL, errno.ErrFkDeferredCausetCannotDrop) 2913 // Test change defCausumn with foreign key. 2914 failALLEGROSQL = "alter causet t4 change defCausumn d e bigint;" 2915 tk.MustGetErrCode(failALLEGROSQL, errno.ErrFKIncompatibleDeferredCausets) 2916 // Test modify defCausumn with foreign key. 2917 failALLEGROSQL = "alter causet t4 modify defCausumn d bigint;" 2918 tk.MustGetErrCode(failALLEGROSQL, errno.ErrFKIncompatibleDeferredCausets) 2919 tk.MustQuery("select count(*) from information_schema.KEY_COLUMN_USAGE;") 2920 tk.MustInterDirc("alter causet t4 drop foreign key d") 2921 tk.MustInterDirc("alter causet t4 modify defCausumn d bigint;") 2922 tk.MustInterDirc("drop causet if exists t1,t2,t3,t4;") 2923 } 2924 2925 func (s *testDBSuite3) TestFKOnGeneratedDeferredCausets(c *C) { 2926 tk := testkit.NewTestKit(c, s.causetstore) 2927 tk.MustInterDirc("use test") 2928 // test add foreign key to generated defCausumn 2929 2930 // foreign key constraint cannot be defined on a virtual generated defCausumn. 2931 tk.MustInterDirc("create causet t1 (a int primary key);") 2932 tk.MustGetErrCode("create causet t2 (a int, b int as (a+1) virtual, foreign key (b) references t1(a));", errno.ErrCannotAddForeign) 2933 tk.MustInterDirc("create causet t2 (a int, b int generated always as (a+1) virtual);") 2934 tk.MustGetErrCode("alter causet t2 add foreign key (b) references t1(a);", errno.ErrCannotAddForeign) 2935 tk.MustInterDirc("drop causet t1, t2;") 2936 2937 // foreign key constraint can be defined on a stored generated defCausumn. 2938 tk.MustInterDirc("create causet t2 (a int primary key);") 2939 tk.MustInterDirc("create causet t1 (a int, b int as (a+1) stored, foreign key (b) references t2(a));") 2940 tk.MustInterDirc("create causet t3 (a int, b int generated always as (a+1) stored);") 2941 tk.MustInterDirc("alter causet t3 add foreign key (b) references t2(a);") 2942 tk.MustInterDirc("drop causet t1, t2, t3;") 2943 2944 // foreign key constraint can reference a stored generated defCausumn. 2945 tk.MustInterDirc("create causet t1 (a int, b int generated always as (a+1) stored primary key);") 2946 tk.MustInterDirc("create causet t2 (a int, foreign key (a) references t1(b));") 2947 tk.MustInterDirc("create causet t3 (a int);") 2948 tk.MustInterDirc("alter causet t3 add foreign key (a) references t1(b);") 2949 tk.MustInterDirc("drop causet t1, t2, t3;") 2950 2951 // rejected FK options on stored generated defCausumns 2952 tk.MustGetErrCode("create causet t1 (a int, b int generated always as (a+1) stored, foreign key (b) references t2(a) on uFIDelate set null);", errno.ErrWrongFKOptionForGeneratedDeferredCauset) 2953 tk.MustGetErrCode("create causet t1 (a int, b int generated always as (a+1) stored, foreign key (b) references t2(a) on uFIDelate cascade);", errno.ErrWrongFKOptionForGeneratedDeferredCauset) 2954 tk.MustGetErrCode("create causet t1 (a int, b int generated always as (a+1) stored, foreign key (b) references t2(a) on uFIDelate set default);", errno.ErrWrongFKOptionForGeneratedDeferredCauset) 2955 tk.MustGetErrCode("create causet t1 (a int, b int generated always as (a+1) stored, foreign key (b) references t2(a) on delete set null);", errno.ErrWrongFKOptionForGeneratedDeferredCauset) 2956 tk.MustGetErrCode("create causet t1 (a int, b int generated always as (a+1) stored, foreign key (b) references t2(a) on delete set default);", errno.ErrWrongFKOptionForGeneratedDeferredCauset) 2957 tk.MustInterDirc("create causet t2 (a int primary key);") 2958 tk.MustInterDirc("create causet t1 (a int, b int generated always as (a+1) stored);") 2959 tk.MustGetErrCode("alter causet t1 add foreign key (b) references t2(a) on uFIDelate set null;", errno.ErrWrongFKOptionForGeneratedDeferredCauset) 2960 tk.MustGetErrCode("alter causet t1 add foreign key (b) references t2(a) on uFIDelate cascade;", errno.ErrWrongFKOptionForGeneratedDeferredCauset) 2961 tk.MustGetErrCode("alter causet t1 add foreign key (b) references t2(a) on uFIDelate set default;", errno.ErrWrongFKOptionForGeneratedDeferredCauset) 2962 tk.MustGetErrCode("alter causet t1 add foreign key (b) references t2(a) on delete set null;", errno.ErrWrongFKOptionForGeneratedDeferredCauset) 2963 tk.MustGetErrCode("alter causet t1 add foreign key (b) references t2(a) on delete set default;", errno.ErrWrongFKOptionForGeneratedDeferredCauset) 2964 tk.MustInterDirc("drop causet t1, t2;") 2965 // defCausumn name with uppercase characters 2966 tk.MustGetErrCode("create causet t1 (A int, b int generated always as (a+1) stored, foreign key (b) references t2(a) on uFIDelate set null);", errno.ErrWrongFKOptionForGeneratedDeferredCauset) 2967 tk.MustInterDirc("create causet t2 (a int primary key);") 2968 tk.MustInterDirc("create causet t1 (A int, b int generated always as (a+1) stored);") 2969 tk.MustGetErrCode("alter causet t1 add foreign key (b) references t2(a) on uFIDelate set null;", errno.ErrWrongFKOptionForGeneratedDeferredCauset) 2970 tk.MustInterDirc("drop causet t1, t2;") 2971 2972 // special case: MilevaDB error different from MyALLEGROSQL 8.0 2973 // MyALLEGROSQL: ERROR 3104 (HY000): Cannot define foreign key with ON UFIDelATE SET NULL clause on a generated defCausumn. 2974 // MilevaDB: ERROR 1146 (42S02): Block 'test.t2' doesn't exist 2975 tk.MustInterDirc("create causet t1 (a int, b int generated always as (a+1) stored);") 2976 tk.MustGetErrCode("alter causet t1 add foreign key (b) references t2(a) on uFIDelate set null;", errno.ErrNoSuchBlock) 2977 tk.MustInterDirc("drop causet t1;") 2978 2979 // allowed FK options on stored generated defCausumns 2980 tk.MustInterDirc("create causet t1 (a int primary key, b char(5));") 2981 tk.MustInterDirc("create causet t2 (a int, b int generated always as (a % 10) stored, foreign key (b) references t1(a) on uFIDelate restrict);") 2982 tk.MustInterDirc("create causet t3 (a int, b int generated always as (a % 10) stored, foreign key (b) references t1(a) on uFIDelate no action);") 2983 tk.MustInterDirc("create causet t4 (a int, b int generated always as (a % 10) stored, foreign key (b) references t1(a) on delete restrict);") 2984 tk.MustInterDirc("create causet t5 (a int, b int generated always as (a % 10) stored, foreign key (b) references t1(a) on delete cascade);") 2985 tk.MustInterDirc("create causet t6 (a int, b int generated always as (a % 10) stored, foreign key (b) references t1(a) on delete no action);") 2986 tk.MustInterDirc("drop causet t2,t3,t4,t5,t6;") 2987 tk.MustInterDirc("create causet t2 (a int, b int generated always as (a % 10) stored);") 2988 tk.MustInterDirc("alter causet t2 add foreign key (b) references t1(a) on uFIDelate restrict;") 2989 tk.MustInterDirc("create causet t3 (a int, b int generated always as (a % 10) stored);") 2990 tk.MustInterDirc("alter causet t3 add foreign key (b) references t1(a) on uFIDelate no action;") 2991 tk.MustInterDirc("create causet t4 (a int, b int generated always as (a % 10) stored);") 2992 tk.MustInterDirc("alter causet t4 add foreign key (b) references t1(a) on delete restrict;") 2993 tk.MustInterDirc("create causet t5 (a int, b int generated always as (a % 10) stored);") 2994 tk.MustInterDirc("alter causet t5 add foreign key (b) references t1(a) on delete cascade;") 2995 tk.MustInterDirc("create causet t6 (a int, b int generated always as (a % 10) stored);") 2996 tk.MustInterDirc("alter causet t6 add foreign key (b) references t1(a) on delete no action;") 2997 tk.MustInterDirc("drop causet t1,t2,t3,t4,t5,t6;") 2998 2999 // rejected FK options on the base defCausumns of a stored generated defCausumns 3000 tk.MustInterDirc("create causet t2 (a int primary key);") 3001 tk.MustGetErrCode("create causet t1 (a int, b int generated always as (a+1) stored, foreign key (a) references t2(a) on uFIDelate set null);", errno.ErrCannotAddForeign) 3002 tk.MustGetErrCode("create causet t1 (a int, b int generated always as (a+1) stored, foreign key (a) references t2(a) on uFIDelate cascade);", errno.ErrCannotAddForeign) 3003 tk.MustGetErrCode("create causet t1 (a int, b int generated always as (a+1) stored, foreign key (a) references t2(a) on uFIDelate set default);", errno.ErrCannotAddForeign) 3004 tk.MustGetErrCode("create causet t1 (a int, b int generated always as (a+1) stored, foreign key (a) references t2(a) on delete set null);", errno.ErrCannotAddForeign) 3005 tk.MustGetErrCode("create causet t1 (a int, b int generated always as (a+1) stored, foreign key (a) references t2(a) on delete cascade);", errno.ErrCannotAddForeign) 3006 tk.MustGetErrCode("create causet t1 (a int, b int generated always as (a+1) stored, foreign key (a) references t2(a) on delete set default);", errno.ErrCannotAddForeign) 3007 tk.MustInterDirc("create causet t1 (a int, b int generated always as (a+1) stored);") 3008 tk.MustGetErrCode("alter causet t1 add foreign key (a) references t2(a) on uFIDelate set null;", errno.ErrCannotAddForeign) 3009 tk.MustGetErrCode("alter causet t1 add foreign key (a) references t2(a) on uFIDelate cascade;", errno.ErrCannotAddForeign) 3010 tk.MustGetErrCode("alter causet t1 add foreign key (a) references t2(a) on uFIDelate set default;", errno.ErrCannotAddForeign) 3011 tk.MustGetErrCode("alter causet t1 add foreign key (a) references t2(a) on delete set null;", errno.ErrCannotAddForeign) 3012 tk.MustGetErrCode("alter causet t1 add foreign key (a) references t2(a) on delete cascade;", errno.ErrCannotAddForeign) 3013 tk.MustGetErrCode("alter causet t1 add foreign key (a) references t2(a) on delete set default;", errno.ErrCannotAddForeign) 3014 tk.MustInterDirc("drop causet t1, t2;") 3015 3016 // allowed FK options on the base defCausumns of a stored generated defCausumns 3017 tk.MustInterDirc("create causet t1 (a int primary key, b char(5));") 3018 tk.MustInterDirc("create causet t2 (a int, b int generated always as (a % 10) stored, foreign key (a) references t1(a) on uFIDelate restrict);") 3019 tk.MustInterDirc("create causet t3 (a int, b int generated always as (a % 10) stored, foreign key (a) references t1(a) on uFIDelate no action);") 3020 tk.MustInterDirc("create causet t4 (a int, b int generated always as (a % 10) stored, foreign key (a) references t1(a) on delete restrict);") 3021 tk.MustInterDirc("create causet t5 (a int, b int generated always as (a % 10) stored, foreign key (a) references t1(a) on delete no action);") 3022 tk.MustInterDirc("drop causet t2,t3,t4,t5") 3023 tk.MustInterDirc("create causet t2 (a int, b int generated always as (a % 10) stored);") 3024 tk.MustInterDirc("alter causet t2 add foreign key (a) references t1(a) on uFIDelate restrict;") 3025 tk.MustInterDirc("create causet t3 (a int, b int generated always as (a % 10) stored);") 3026 tk.MustInterDirc("alter causet t3 add foreign key (a) references t1(a) on uFIDelate no action;") 3027 tk.MustInterDirc("create causet t4 (a int, b int generated always as (a % 10) stored);") 3028 tk.MustInterDirc("alter causet t4 add foreign key (a) references t1(a) on delete restrict;") 3029 tk.MustInterDirc("create causet t5 (a int, b int generated always as (a % 10) stored);") 3030 tk.MustInterDirc("alter causet t5 add foreign key (a) references t1(a) on delete no action;") 3031 tk.MustInterDirc("drop causet t1,t2,t3,t4,t5;") 3032 } 3033 3034 func (s *testSerialDBSuite) TestTruncateBlock(c *C) { 3035 tk := testkit.NewTestKit(c, s.causetstore) 3036 tk.MustInterDirc("use test") 3037 tk.MustInterDirc("create causet truncate_block (c1 int, c2 int)") 3038 tk.MustInterDirc("insert truncate_block values (1, 1), (2, 2)") 3039 ctx := tk.Se.(stochastikctx.Context) 3040 is := petri.GetPetri(ctx).SchemaReplicant() 3041 oldTblInfo, err := is.BlockByName(perceptron.NewCIStr("test"), perceptron.NewCIStr("truncate_block")) 3042 c.Assert(err, IsNil) 3043 oldTblID := oldTblInfo.Meta().ID 3044 3045 tk.MustInterDirc("truncate causet truncate_block") 3046 3047 tk.MustInterDirc("insert truncate_block values (3, 3), (4, 4)") 3048 tk.MustQuery("select * from truncate_block").Check(testkit.Rows("3 3", "4 4")) 3049 3050 is = petri.GetPetri(ctx).SchemaReplicant() 3051 newTblInfo, err := is.BlockByName(perceptron.NewCIStr("test"), perceptron.NewCIStr("truncate_block")) 3052 c.Assert(err, IsNil) 3053 c.Assert(newTblInfo.Meta().ID, Greater, oldTblID) 3054 3055 // Verify that the old causet data has been deleted by background worker. 3056 blockPrefix := blockcodec.EncodeBlockPrefix(oldTblID) 3057 hasOldBlockData := true 3058 for i := 0; i < waitForCleanDataRound; i++ { 3059 err = ekv.RunInNewTxn(s.causetstore, false, func(txn ekv.Transaction) error { 3060 it, err1 := txn.Iter(blockPrefix, nil) 3061 if err1 != nil { 3062 return err1 3063 } 3064 if !it.Valid() { 3065 hasOldBlockData = false 3066 } else { 3067 hasOldBlockData = it.Key().HasPrefix(blockPrefix) 3068 } 3069 it.Close() 3070 return nil 3071 }) 3072 c.Assert(err, IsNil) 3073 if !hasOldBlockData { 3074 break 3075 } 3076 time.Sleep(waitForCleanDataInterval) 3077 } 3078 c.Assert(hasOldBlockData, IsFalse) 3079 3080 // Test for truncate causet should clear the tiflash available status. 3081 c.Assert(failpoint.Enable("github.com/whtcorpsinc/milevadb/schemareplicant/mockTiFlashStoreCount", `return(true)`), IsNil) 3082 defer failpoint.Disable("github.com/whtcorpsinc/milevadb/schemareplicant/mockTiFlashStoreCount") 3083 3084 tk.MustInterDirc("drop causet if exists t1;") 3085 tk.MustInterDirc("create causet t1 (a int);") 3086 tk.MustInterDirc("alter causet t1 set tiflash replica 3 location labels 'a','b';") 3087 t1 := testGetBlockByName(c, s.s, "test", "t1") 3088 // Mock for causet tiflash replica was available. 3089 err = petri.GetPetri(tk.Se).DBS().UFIDelateBlockReplicaInfo(tk.Se, t1.Meta().ID, true) 3090 c.Assert(err, IsNil) 3091 t1 = testGetBlockByName(c, s.s, "test", "t1") 3092 c.Assert(t1.Meta().TiFlashReplica, NotNil) 3093 c.Assert(t1.Meta().TiFlashReplica.Available, IsTrue) 3094 3095 tk.MustInterDirc("truncate causet t1") 3096 t2 := testGetBlockByName(c, s.s, "test", "t1") 3097 c.Assert(t2.Meta().TiFlashReplica.Count, Equals, t1.Meta().TiFlashReplica.Count) 3098 c.Assert(t2.Meta().TiFlashReplica.LocationLabels, DeepEquals, t1.Meta().TiFlashReplica.LocationLabels) 3099 c.Assert(t2.Meta().TiFlashReplica.Available, IsFalse) 3100 c.Assert(t2.Meta().TiFlashReplica.AvailablePartitionIDs, HasLen, 0) 3101 3102 // Test for truncate partition should clear the tiflash available status. 3103 tk.MustInterDirc("drop causet if exists t1;") 3104 tk.MustInterDirc("create causet t1 (a int) partition by hash(a) partitions 2;") 3105 tk.MustInterDirc("alter causet t1 set tiflash replica 3 location labels 'a','b';") 3106 t1 = testGetBlockByName(c, s.s, "test", "t1") 3107 // Mock for all partitions replica was available. 3108 partition := t1.Meta().Partition 3109 c.Assert(len(partition.Definitions), Equals, 2) 3110 err = petri.GetPetri(tk.Se).DBS().UFIDelateBlockReplicaInfo(tk.Se, partition.Definitions[0].ID, true) 3111 c.Assert(err, IsNil) 3112 err = petri.GetPetri(tk.Se).DBS().UFIDelateBlockReplicaInfo(tk.Se, partition.Definitions[1].ID, true) 3113 c.Assert(err, IsNil) 3114 t1 = testGetBlockByName(c, s.s, "test", "t1") 3115 c.Assert(t1.Meta().TiFlashReplica, NotNil) 3116 c.Assert(t1.Meta().TiFlashReplica.Available, IsTrue) 3117 c.Assert(t1.Meta().TiFlashReplica.AvailablePartitionIDs, DeepEquals, []int64{partition.Definitions[0].ID, partition.Definitions[1].ID}) 3118 3119 tk.MustInterDirc("alter causet t1 truncate partition p0") 3120 t2 = testGetBlockByName(c, s.s, "test", "t1") 3121 c.Assert(t2.Meta().TiFlashReplica.Count, Equals, t1.Meta().TiFlashReplica.Count) 3122 c.Assert(t2.Meta().TiFlashReplica.LocationLabels, DeepEquals, t1.Meta().TiFlashReplica.LocationLabels) 3123 c.Assert(t2.Meta().TiFlashReplica.Available, IsFalse) 3124 c.Assert(t2.Meta().TiFlashReplica.AvailablePartitionIDs, DeepEquals, []int64{partition.Definitions[1].ID}) 3125 // Test for truncate twice. 3126 tk.MustInterDirc("alter causet t1 truncate partition p0") 3127 t2 = testGetBlockByName(c, s.s, "test", "t1") 3128 c.Assert(t2.Meta().TiFlashReplica.Count, Equals, t1.Meta().TiFlashReplica.Count) 3129 c.Assert(t2.Meta().TiFlashReplica.LocationLabels, DeepEquals, t1.Meta().TiFlashReplica.LocationLabels) 3130 c.Assert(t2.Meta().TiFlashReplica.Available, IsFalse) 3131 c.Assert(t2.Meta().TiFlashReplica.AvailablePartitionIDs, DeepEquals, []int64{partition.Definitions[1].ID}) 3132 3133 } 3134 3135 func (s *testDBSuite4) TestRenameBlock(c *C) { 3136 isAlterBlock := false 3137 s.testRenameBlock(c, "rename causet %s to %s", isAlterBlock) 3138 } 3139 3140 func (s *testDBSuite5) TestAlterBlockRenameBlock(c *C) { 3141 isAlterBlock := true 3142 s.testRenameBlock(c, "alter causet %s rename to %s", isAlterBlock) 3143 } 3144 3145 func (s *testDBSuite) testRenameBlock(c *C, allegrosql string, isAlterBlock bool) { 3146 tk := testkit.NewTestKit(c, s.causetstore) 3147 tk.MustInterDirc("use test") 3148 // for different databases 3149 tk.MustInterDirc("create causet t (c1 int, c2 int)") 3150 tk.MustInterDirc("insert t values (1, 1), (2, 2)") 3151 ctx := tk.Se.(stochastikctx.Context) 3152 is := petri.GetPetri(ctx).SchemaReplicant() 3153 oldTblInfo, err := is.BlockByName(perceptron.NewCIStr("test"), perceptron.NewCIStr("t")) 3154 c.Assert(err, IsNil) 3155 oldTblID := oldTblInfo.Meta().ID 3156 tk.MustInterDirc("create database test1") 3157 tk.MustInterDirc("use test1") 3158 tk.MustInterDirc(fmt.Sprintf(allegrosql, "test.t", "test1.t1")) 3159 is = petri.GetPetri(ctx).SchemaReplicant() 3160 newTblInfo, err := is.BlockByName(perceptron.NewCIStr("test1"), perceptron.NewCIStr("t1")) 3161 c.Assert(err, IsNil) 3162 c.Assert(newTblInfo.Meta().ID, Equals, oldTblID) 3163 tk.MustQuery("select * from t1").Check(testkit.Rows("1 1", "2 2")) 3164 tk.MustInterDirc("use test") 3165 3166 // Make sure t doesn't exist. 3167 tk.MustInterDirc("create causet t (c1 int, c2 int)") 3168 tk.MustInterDirc("drop causet t") 3169 3170 // for the same database 3171 tk.MustInterDirc("use test1") 3172 tk.MustInterDirc(fmt.Sprintf(allegrosql, "t1", "t2")) 3173 is = petri.GetPetri(ctx).SchemaReplicant() 3174 newTblInfo, err = is.BlockByName(perceptron.NewCIStr("test1"), perceptron.NewCIStr("t2")) 3175 c.Assert(err, IsNil) 3176 c.Assert(newTblInfo.Meta().ID, Equals, oldTblID) 3177 tk.MustQuery("select * from t2").Check(testkit.Rows("1 1", "2 2")) 3178 isExist := is.BlockExists(perceptron.NewCIStr("test1"), perceptron.NewCIStr("t1")) 3179 c.Assert(isExist, IsFalse) 3180 tk.MustQuery("show blocks").Check(testkit.Rows("t2")) 3181 3182 // for failure case 3183 failALLEGROSQL := fmt.Sprintf(allegrosql, "test_not_exist.t", "test_not_exist.t") 3184 if isAlterBlock { 3185 tk.MustGetErrCode(failALLEGROSQL, errno.ErrNoSuchBlock) 3186 } else { 3187 tk.MustGetErrCode(failALLEGROSQL, errno.ErrFileNotFound) 3188 } 3189 failALLEGROSQL = fmt.Sprintf(allegrosql, "test.test_not_exist", "test.test_not_exist") 3190 if isAlterBlock { 3191 tk.MustGetErrCode(failALLEGROSQL, errno.ErrNoSuchBlock) 3192 } else { 3193 tk.MustGetErrCode(failALLEGROSQL, errno.ErrFileNotFound) 3194 } 3195 failALLEGROSQL = fmt.Sprintf(allegrosql, "test.t_not_exist", "test_not_exist.t") 3196 if isAlterBlock { 3197 tk.MustGetErrCode(failALLEGROSQL, errno.ErrNoSuchBlock) 3198 } else { 3199 tk.MustGetErrCode(failALLEGROSQL, errno.ErrFileNotFound) 3200 } 3201 failALLEGROSQL = fmt.Sprintf(allegrosql, "test1.t2", "test_not_exist.t") 3202 tk.MustGetErrCode(failALLEGROSQL, errno.ErrErrorOnRename) 3203 3204 tk.MustInterDirc("use test1") 3205 tk.MustInterDirc("create causet if not exists t_exist (c1 int, c2 int)") 3206 failALLEGROSQL = fmt.Sprintf(allegrosql, "test1.t2", "test1.t_exist") 3207 tk.MustGetErrCode(failALLEGROSQL, errno.ErrBlockExists) 3208 failALLEGROSQL = fmt.Sprintf(allegrosql, "test.t_not_exist", "test1.t_exist") 3209 if isAlterBlock { 3210 tk.MustGetErrCode(failALLEGROSQL, errno.ErrNoSuchBlock) 3211 } else { 3212 tk.MustGetErrCode(failALLEGROSQL, errno.ErrBlockExists) 3213 } 3214 failALLEGROSQL = fmt.Sprintf(allegrosql, "test_not_exist.t", "test1.t_exist") 3215 if isAlterBlock { 3216 tk.MustGetErrCode(failALLEGROSQL, errno.ErrNoSuchBlock) 3217 } else { 3218 tk.MustGetErrCode(failALLEGROSQL, errno.ErrBlockExists) 3219 } 3220 failALLEGROSQL = fmt.Sprintf(allegrosql, "test_not_exist.t", "test1.t_not_exist") 3221 if isAlterBlock { 3222 tk.MustGetErrCode(failALLEGROSQL, errno.ErrNoSuchBlock) 3223 } else { 3224 tk.MustGetErrCode(failALLEGROSQL, errno.ErrFileNotFound) 3225 } 3226 3227 // for the same causet name 3228 tk.MustInterDirc("use test1") 3229 tk.MustInterDirc("create causet if not exists t (c1 int, c2 int)") 3230 tk.MustInterDirc("create causet if not exists t1 (c1 int, c2 int)") 3231 if isAlterBlock { 3232 tk.MustInterDirc(fmt.Sprintf(allegrosql, "test1.t", "t")) 3233 tk.MustInterDirc(fmt.Sprintf(allegrosql, "test1.t1", "test1.T1")) 3234 } else { 3235 tk.MustGetErrCode(fmt.Sprintf(allegrosql, "test1.t", "t"), errno.ErrBlockExists) 3236 tk.MustGetErrCode(fmt.Sprintf(allegrosql, "test1.t1", "test1.T1"), errno.ErrBlockExists) 3237 } 3238 3239 // Test rename causet name too long. 3240 tk.MustGetErrCode("rename causet test1.t1 to test1.txxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", errno.ErrTooLongIdent) 3241 tk.MustGetErrCode("alter causet test1.t1 rename to test1.txxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", errno.ErrTooLongIdent) 3242 3243 tk.MustInterDirc("drop database test1") 3244 } 3245 3246 func (s *testDBSuite1) TestRenameMultiBlocks(c *C) { 3247 tk := testkit.NewTestKit(c, s.causetstore) 3248 tk.MustInterDirc("use test") 3249 tk.MustInterDirc("create causet t1(id int)") 3250 tk.MustInterDirc("create causet t2(id int)") 3251 // Currently it will fail only. 3252 allegrosql := fmt.Sprintf("rename causet t1 to t3, t2 to t4") 3253 _, err := tk.InterDirc(allegrosql) 3254 c.Assert(err, NotNil) 3255 originErr := errors.Cause(err) 3256 c.Assert(originErr.Error(), Equals, "can't run multi schemaReplicant change") 3257 3258 tk.MustInterDirc("drop causet t1, t2") 3259 } 3260 3261 func (s *testDBSuite2) TestAddNotNullDeferredCauset(c *C) { 3262 tk := testkit.NewTestKit(c, s.causetstore) 3263 tk.MustInterDirc("use test_db") 3264 // for different databases 3265 tk.MustInterDirc("create causet tnn (c1 int primary key auto_increment, c2 int)") 3266 tk.MustInterDirc("insert tnn (c2) values (0)" + strings.Repeat(",(0)", 99)) 3267 done := make(chan error, 1) 3268 testdbsutil.StochastikInterDircInGoroutine(c, s.causetstore, "alter causet tnn add defCausumn c3 int not null default 3", done) 3269 uFIDelateCnt := 0 3270 out: 3271 for { 3272 select { 3273 case err := <-done: 3274 c.Assert(err, IsNil) 3275 break out 3276 default: 3277 tk.MustInterDirc("uFIDelate tnn set c2 = c2 + 1 where c1 = 99") 3278 uFIDelateCnt++ 3279 } 3280 } 3281 expected := fmt.Sprintf("%d %d", uFIDelateCnt, 3) 3282 tk.MustQuery("select c2, c3 from tnn where c1 = 99").Check(testkit.Rows(expected)) 3283 3284 tk.MustInterDirc("drop causet tnn") 3285 } 3286 3287 func (s *testDBSuite3) TestGeneratedDeferredCausetDBS(c *C) { 3288 tk := testkit.NewTestKit(c, s.causetstore) 3289 tk.MustInterDirc("use test") 3290 3291 // Check create causet with virtual and stored generated defCausumns. 3292 tk.MustInterDirc(`CREATE TABLE test_gv_dbs(a int, b int as (a+8) virtual, c int as (b + 2) stored)`) 3293 3294 // Check desc causet with virtual and stored generated defCausumns. 3295 result := tk.MustQuery(`DESC test_gv_dbs`) 3296 result.Check(testkit.Rows(`a int(11) YES <nil> `, `b int(11) YES <nil> VIRTUAL GENERATED`, `c int(11) YES <nil> STORED GENERATED`)) 3297 3298 // Check show create causet with virtual and stored generated defCausumns. 3299 result = tk.MustQuery(`show create causet test_gv_dbs`) 3300 result.Check(testkit.Rows( 3301 "test_gv_dbs CREATE TABLE `test_gv_dbs` (\n `a` int(11) DEFAULT NULL,\n `b` int(11) GENERATED ALWAYS AS (`a` + 8) VIRTUAL,\n `c` int(11) GENERATED ALWAYS AS (`b` + 2) STORED\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin", 3302 )) 3303 3304 // Check generated memex with blanks. 3305 tk.MustInterDirc("create causet block_with_gen_defCaus_blanks (a int, b char(20) as (cast( \r\n\t a \r\n\tas char)), c int as (a+100))") 3306 result = tk.MustQuery(`show create causet block_with_gen_defCaus_blanks`) 3307 result.Check(testkit.Rows("block_with_gen_defCaus_blanks CREATE TABLE `block_with_gen_defCaus_blanks` (\n" + 3308 " `a` int(11) DEFAULT NULL,\n" + 3309 " `b` char(20) GENERATED ALWAYS AS (cast(`a` as char)) VIRTUAL,\n" + 3310 " `c` int(11) GENERATED ALWAYS AS (`a` + 100) VIRTUAL\n" + 3311 ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin")) 3312 3313 // Check generated memex with charset latin1 ("latin1" != allegrosql.DefaultCharset). 3314 tk.MustInterDirc("create causet block_with_gen_defCaus_latin1 (a int, b char(20) as (cast( \r\n\t a \r\n\tas char charset latin1)), c int as (a+100))") 3315 result = tk.MustQuery(`show create causet block_with_gen_defCaus_latin1`) 3316 result.Check(testkit.Rows("block_with_gen_defCaus_latin1 CREATE TABLE `block_with_gen_defCaus_latin1` (\n" + 3317 " `a` int(11) DEFAULT NULL,\n" + 3318 " `b` char(20) GENERATED ALWAYS AS (cast(`a` as char charset latin1)) VIRTUAL,\n" + 3319 " `c` int(11) GENERATED ALWAYS AS (`a` + 100) VIRTUAL\n" + 3320 ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin")) 3321 3322 // Check generated memex with string (issue 9457). 3323 tk.MustInterDirc("create causet block_with_gen_defCaus_string (first_name varchar(10), last_name varchar(10), full_name varchar(255) AS (CONCAT(first_name,' ',last_name)))") 3324 result = tk.MustQuery(`show create causet block_with_gen_defCaus_string`) 3325 result.Check(testkit.Rows("block_with_gen_defCaus_string CREATE TABLE `block_with_gen_defCaus_string` (\n" + 3326 " `first_name` varchar(10) DEFAULT NULL,\n" + 3327 " `last_name` varchar(10) DEFAULT NULL,\n" + 3328 " `full_name` varchar(255) GENERATED ALWAYS AS (concat(`first_name`, ' ', `last_name`)) VIRTUAL\n" + 3329 ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin")) 3330 3331 tk.MustInterDirc("alter causet block_with_gen_defCaus_string modify defCausumn full_name varchar(255) GENERATED ALWAYS AS (CONCAT(last_name,' ' ,first_name) ) VIRTUAL") 3332 result = tk.MustQuery(`show create causet block_with_gen_defCaus_string`) 3333 result.Check(testkit.Rows("block_with_gen_defCaus_string CREATE TABLE `block_with_gen_defCaus_string` (\n" + 3334 " `first_name` varchar(10) DEFAULT NULL,\n" + 3335 " `last_name` varchar(10) DEFAULT NULL,\n" + 3336 " `full_name` varchar(255) GENERATED ALWAYS AS (concat(`last_name`, ' ', `first_name`)) VIRTUAL\n" + 3337 ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin")) 3338 3339 genExprTests := []struct { 3340 stmt string 3341 err int 3342 }{ 3343 // Drop/rename defCausumns dependent by other defCausumn. 3344 {`alter causet test_gv_dbs drop defCausumn a`, errno.ErrDependentByGeneratedDeferredCauset}, 3345 {`alter causet test_gv_dbs change defCausumn a anew int`, errno.ErrBadField}, 3346 3347 // Modify/change stored status of generated defCausumns. 3348 {`alter causet test_gv_dbs modify defCausumn b bigint`, errno.ErrUnsupportedOnGeneratedDeferredCauset}, 3349 {`alter causet test_gv_dbs change defCausumn c cnew bigint as (a+100)`, errno.ErrUnsupportedOnGeneratedDeferredCauset}, 3350 3351 // Modify/change generated defCausumns breaking prior. 3352 {`alter causet test_gv_dbs modify defCausumn b int as (c+100)`, errno.ErrGeneratedDeferredCausetNonPrior}, 3353 {`alter causet test_gv_dbs change defCausumn b bnew int as (c+100)`, errno.ErrGeneratedDeferredCausetNonPrior}, 3354 3355 // Refer not exist defCausumns in generation memex. 3356 {`create causet test_gv_dbs_bad (a int, b int as (c+8))`, errno.ErrBadField}, 3357 3358 // Refer generated defCausumns non prior. 3359 {`create causet test_gv_dbs_bad (a int, b int as (c+1), c int as (a+1))`, errno.ErrGeneratedDeferredCausetNonPrior}, 3360 3361 // Virtual generated defCausumns cannot be primary key. 3362 {`create causet test_gv_dbs_bad (a int, b int, c int as (a+b) primary key)`, errno.ErrUnsupportedOnGeneratedDeferredCauset}, 3363 {`create causet test_gv_dbs_bad (a int, b int, c int as (a+b), primary key(c))`, errno.ErrUnsupportedOnGeneratedDeferredCauset}, 3364 {`create causet test_gv_dbs_bad (a int, b int, c int as (a+b), primary key(a, c))`, errno.ErrUnsupportedOnGeneratedDeferredCauset}, 3365 3366 // Add stored generated defCausumn through alter causet. 3367 {`alter causet test_gv_dbs add defCausumn d int as (b+2) stored`, errno.ErrUnsupportedOnGeneratedDeferredCauset}, 3368 {`alter causet test_gv_dbs modify defCausumn b int as (a + 8) stored`, errno.ErrUnsupportedOnGeneratedDeferredCauset}, 3369 } 3370 for _, tt := range genExprTests { 3371 tk.MustGetErrCode(tt.stmt, tt.err) 3372 } 3373 3374 // Check alter causet modify/change generated defCausumn. 3375 modStoredDefCausErrMsg := "[dbs:3106]'modifying a stored defCausumn' is not supported for generated defCausumns." 3376 _, err := tk.InterDirc(`alter causet test_gv_dbs modify defCausumn c bigint as (b+200) stored`) 3377 c.Assert(err, NotNil) 3378 c.Assert(err.Error(), Equals, modStoredDefCausErrMsg) 3379 3380 result = tk.MustQuery(`DESC test_gv_dbs`) 3381 result.Check(testkit.Rows(`a int(11) YES <nil> `, `b int(11) YES <nil> VIRTUAL GENERATED`, `c int(11) YES <nil> STORED GENERATED`)) 3382 3383 tk.MustInterDirc(`alter causet test_gv_dbs change defCausumn b b bigint as (a+100) virtual`) 3384 result = tk.MustQuery(`DESC test_gv_dbs`) 3385 result.Check(testkit.Rows(`a int(11) YES <nil> `, `b bigint(20) YES <nil> VIRTUAL GENERATED`, `c int(11) YES <nil> STORED GENERATED`)) 3386 3387 tk.MustInterDirc(`alter causet test_gv_dbs change defCausumn c cnew bigint`) 3388 result = tk.MustQuery(`DESC test_gv_dbs`) 3389 result.Check(testkit.Rows(`a int(11) YES <nil> `, `b bigint(20) YES <nil> VIRTUAL GENERATED`, `cnew bigint(20) YES <nil> `)) 3390 } 3391 3392 func (s *testDBSuite4) TestComment(c *C) { 3393 tk := testkit.NewTestKit(c, s.causetstore) 3394 tk.MustInterDirc("use " + s.schemaName) 3395 tk.MustInterDirc("drop causet if exists ct, ct1") 3396 3397 validComment := strings.Repeat("a", 1024) 3398 invalidComment := strings.Repeat("b", 1025) 3399 3400 tk.MustInterDirc("create causet ct (c int, d int, e int, key (c) comment '" + validComment + "')") 3401 tk.MustInterDirc("create index i on ct (d) comment '" + validComment + "'") 3402 tk.MustInterDirc("alter causet ct add key (e) comment '" + validComment + "'") 3403 3404 tk.MustGetErrCode("create causet ct1 (c int, key (c) comment '"+invalidComment+"')", errno.ErrTooLongIndexComment) 3405 tk.MustGetErrCode("create index i1 on ct (d) comment '"+invalidComment+"b"+"'", errno.ErrTooLongIndexComment) 3406 tk.MustGetErrCode("alter causet ct add key (e) comment '"+invalidComment+"'", errno.ErrTooLongIndexComment) 3407 3408 tk.MustInterDirc("set @@sql_mode=''") 3409 tk.MustInterDirc("create causet ct1 (c int, d int, e int, key (c) comment '" + invalidComment + "')") 3410 c.Assert(tk.Se.GetStochastikVars().StmtCtx.WarningCount(), Equals, uint16(1)) 3411 tk.MustQuery("show warnings").Check(solitonutil.RowsWithSep("|", "Warning|1688|Comment for index 'c' is too long (max = 1024)")) 3412 tk.MustInterDirc("create index i1 on ct1 (d) comment '" + invalidComment + "b" + "'") 3413 c.Assert(tk.Se.GetStochastikVars().StmtCtx.WarningCount(), Equals, uint16(1)) 3414 tk.MustQuery("show warnings").Check(solitonutil.RowsWithSep("|", "Warning|1688|Comment for index 'i1' is too long (max = 1024)")) 3415 tk.MustInterDirc("alter causet ct1 add key (e) comment '" + invalidComment + "'") 3416 c.Assert(tk.Se.GetStochastikVars().StmtCtx.WarningCount(), Equals, uint16(1)) 3417 tk.MustQuery("show warnings").Check(solitonutil.RowsWithSep("|", "Warning|1688|Comment for index 'e' is too long (max = 1024)")) 3418 3419 tk.MustInterDirc("drop causet if exists ct, ct1") 3420 } 3421 3422 func (s *testSerialDBSuite) TestRebaseAutoID(c *C) { 3423 c.Assert(failpoint.Enable("github.com/whtcorpsinc/milevadb/spacetime/autoid/mockAutoIDChange", `return(true)`), IsNil) 3424 defer func() { 3425 c.Assert(failpoint.Disable("github.com/whtcorpsinc/milevadb/spacetime/autoid/mockAutoIDChange"), IsNil) 3426 }() 3427 tk := testkit.NewTestKit(c, s.causetstore) 3428 tk.MustInterDirc("use " + s.schemaName) 3429 3430 tk.MustInterDirc("drop database if exists milevadb;") 3431 tk.MustInterDirc("create database milevadb;") 3432 tk.MustInterDirc("use milevadb;") 3433 tk.MustInterDirc("create causet milevadb.test (a int auto_increment primary key, b int);") 3434 tk.MustInterDirc("insert milevadb.test values (null, 1);") 3435 tk.MustQuery("select * from milevadb.test").Check(testkit.Rows("1 1")) 3436 tk.MustInterDirc("alter causet milevadb.test auto_increment = 6000;") 3437 tk.MustInterDirc("insert milevadb.test values (null, 1);") 3438 tk.MustQuery("select * from milevadb.test").Check(testkit.Rows("1 1", "6000 1")) 3439 tk.MustInterDirc("alter causet milevadb.test auto_increment = 5;") 3440 tk.MustInterDirc("insert milevadb.test values (null, 1);") 3441 tk.MustQuery("select * from milevadb.test").Check(testkit.Rows("1 1", "6000 1", "11000 1")) 3442 3443 // Current range for causet test is [11000, 15999]. 3444 // Though it does not have a tuple "a = 15999", its global next auto increment id should be 16000. 3445 // Anyway it is not compatible with MyALLEGROSQL. 3446 tk.MustInterDirc("alter causet milevadb.test auto_increment = 12000;") 3447 tk.MustInterDirc("insert milevadb.test values (null, 1);") 3448 tk.MustQuery("select * from milevadb.test").Check(testkit.Rows("1 1", "6000 1", "11000 1", "16000 1")) 3449 3450 tk.MustInterDirc("create causet milevadb.test2 (a int);") 3451 tk.MustGetErrCode("alter causet milevadb.test2 add defCausumn b int auto_increment key, auto_increment=10;", errno.ErrUnsupportedDBSOperation) 3452 } 3453 3454 func (s *testDBSuite5) TestCheckDeferredCausetDefaultValue(c *C) { 3455 tk := testkit.NewTestKit(c, s.causetstore) 3456 tk.MustInterDirc("use test;") 3457 tk.MustInterDirc("drop causet if exists text_default_text;") 3458 tk.MustGetErrCode("create causet text_default_text(c1 text not null default '');", errno.ErrBlobCantHaveDefault) 3459 tk.MustGetErrCode("create causet text_default_text(c1 text not null default 'scds');", errno.ErrBlobCantHaveDefault) 3460 3461 tk.MustInterDirc("drop causet if exists text_default_json;") 3462 tk.MustGetErrCode("create causet text_default_json(c1 json not null default '');", errno.ErrBlobCantHaveDefault) 3463 tk.MustGetErrCode("create causet text_default_json(c1 json not null default 'dfew555');", errno.ErrBlobCantHaveDefault) 3464 3465 tk.MustInterDirc("drop causet if exists text_default_blob;") 3466 tk.MustGetErrCode("create causet text_default_blob(c1 blob not null default '');", errno.ErrBlobCantHaveDefault) 3467 tk.MustGetErrCode("create causet text_default_blob(c1 blob not null default 'scds54');", errno.ErrBlobCantHaveDefault) 3468 3469 tk.MustInterDirc("set sql_mode='';") 3470 tk.MustInterDirc("create causet text_default_text(c1 text not null default '');") 3471 tk.MustQuery(`show create causet text_default_text`).Check(solitonutil.RowsWithSep("|", 3472 "text_default_text CREATE TABLE `text_default_text` (\n"+ 3473 " `c1` text NOT NULL\n"+ 3474 ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin", 3475 )) 3476 ctx := tk.Se.(stochastikctx.Context) 3477 is := petri.GetPetri(ctx).SchemaReplicant() 3478 tblInfo, err := is.BlockByName(perceptron.NewCIStr("test"), perceptron.NewCIStr("text_default_text")) 3479 c.Assert(err, IsNil) 3480 c.Assert(tblInfo.Meta().DeferredCausets[0].DefaultValue, Equals, "") 3481 3482 tk.MustInterDirc("create causet text_default_blob(c1 blob not null default '');") 3483 tk.MustQuery(`show create causet text_default_blob`).Check(solitonutil.RowsWithSep("|", 3484 "text_default_blob CREATE TABLE `text_default_blob` (\n"+ 3485 " `c1` blob NOT NULL\n"+ 3486 ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin", 3487 )) 3488 is = petri.GetPetri(ctx).SchemaReplicant() 3489 tblInfo, err = is.BlockByName(perceptron.NewCIStr("test"), perceptron.NewCIStr("text_default_blob")) 3490 c.Assert(err, IsNil) 3491 c.Assert(tblInfo.Meta().DeferredCausets[0].DefaultValue, Equals, "") 3492 3493 tk.MustInterDirc("create causet text_default_json(c1 json not null default '');") 3494 tk.MustQuery(`show create causet text_default_json`).Check(solitonutil.RowsWithSep("|", 3495 "text_default_json CREATE TABLE `text_default_json` (\n"+ 3496 " `c1` json NOT NULL DEFAULT 'null'\n"+ 3497 ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin", 3498 )) 3499 is = petri.GetPetri(ctx).SchemaReplicant() 3500 tblInfo, err = is.BlockByName(perceptron.NewCIStr("test"), perceptron.NewCIStr("text_default_json")) 3501 c.Assert(err, IsNil) 3502 c.Assert(tblInfo.Meta().DeferredCausets[0].DefaultValue, Equals, `null`) 3503 } 3504 3505 func (s *testDBSuite1) TestCharacterSetInDeferredCausets(c *C) { 3506 tk := testkit.NewTestKit(c, s.causetstore) 3507 tk.MustInterDirc("create database varchar_test;") 3508 defer tk.MustInterDirc("drop database varchar_test;") 3509 tk.MustInterDirc("use varchar_test") 3510 tk.MustInterDirc("create causet t (c1 int, s1 varchar(10), s2 text)") 3511 tk.MustQuery("select count(*) from information_schema.defCausumns where block_schema = 'varchar_test' and character_set_name != 'utf8mb4'").Check(testkit.Rows("0")) 3512 tk.MustQuery("select count(*) from information_schema.defCausumns where block_schema = 'varchar_test' and character_set_name = 'utf8mb4'").Check(testkit.Rows("2")) 3513 3514 tk.MustInterDirc("create causet t1(id int) charset=UTF8;") 3515 tk.MustInterDirc("create causet t2(id int) charset=BINARY;") 3516 tk.MustInterDirc("create causet t3(id int) charset=LATIN1;") 3517 tk.MustInterDirc("create causet t4(id int) charset=ASCII;") 3518 tk.MustInterDirc("create causet t5(id int) charset=UTF8MB4;") 3519 3520 tk.MustInterDirc("create causet t11(id int) charset=utf8;") 3521 tk.MustInterDirc("create causet t12(id int) charset=binary;") 3522 tk.MustInterDirc("create causet t13(id int) charset=latin1;") 3523 tk.MustInterDirc("create causet t14(id int) charset=ascii;") 3524 tk.MustInterDirc("create causet t15(id int) charset=utf8mb4;") 3525 } 3526 3527 func (s *testDBSuite2) TestAddNotNullDeferredCausetWhileInsertOnDupUFIDelate(c *C) { 3528 tk1 := testkit.NewTestKit(c, s.causetstore) 3529 tk1.MustInterDirc("use " + s.schemaName) 3530 tk2 := testkit.NewTestKit(c, s.causetstore) 3531 tk2.MustInterDirc("use " + s.schemaName) 3532 closeCh := make(chan bool) 3533 wg := new(sync.WaitGroup) 3534 wg.Add(1) 3535 tk1.MustInterDirc("create causet nn (a int primary key, b int)") 3536 tk1.MustInterDirc("insert nn values (1, 1)") 3537 var tk2Err error 3538 go func() { 3539 defer wg.Done() 3540 for { 3541 select { 3542 case <-closeCh: 3543 return 3544 default: 3545 } 3546 _, tk2Err = tk2.InterDirc("insert nn (a, b) values (1, 1) on duplicate key uFIDelate a = 1, b = values(b) + 1") 3547 if tk2Err != nil { 3548 return 3549 } 3550 } 3551 }() 3552 tk1.MustInterDirc("alter causet nn add defCausumn c int not null default 3 after a") 3553 close(closeCh) 3554 wg.Wait() 3555 c.Assert(tk2Err, IsNil) 3556 tk1.MustQuery("select * from nn").Check(testkit.Rows("1 3 2")) 3557 } 3558 3559 func (s *testDBSuite3) TestDeferredCausetModifyingDefinition(c *C) { 3560 tk := testkit.NewTestKit(c, s.causetstore) 3561 tk.MustInterDirc("use test") 3562 tk.MustInterDirc("drop causet if exists test2;") 3563 tk.MustInterDirc("create causet test2 (c1 int, c2 int, c3 int default 1, index (c1));") 3564 tk.MustInterDirc("alter causet test2 change c2 a int not null;") 3565 ctx := tk.Se.(stochastikctx.Context) 3566 is := petri.GetPetri(ctx).SchemaReplicant() 3567 t, err := is.BlockByName(perceptron.NewCIStr("test"), perceptron.NewCIStr("test2")) 3568 c.Assert(err, IsNil) 3569 var c2 *causet.DeferredCauset 3570 for _, defCaus := range t.DefCauss() { 3571 if defCaus.Name.L == "a" { 3572 c2 = defCaus 3573 } 3574 } 3575 c.Assert(allegrosql.HasNotNullFlag(c2.Flag), IsTrue) 3576 3577 tk.MustInterDirc("drop causet if exists test2;") 3578 tk.MustInterDirc("create causet test2 (c1 int, c2 int, c3 int default 1, index (c1));") 3579 tk.MustInterDirc("insert into test2(c2) values (null);") 3580 tk.MustGetErrCode("alter causet test2 change c2 a int not null", errno.ErrInvalidUseOfNull) 3581 tk.MustGetErrCode("alter causet test2 change c1 a1 bigint not null;", allegrosql.WarnDataTruncated) 3582 } 3583 3584 func (s *testDBSuite4) TestCheckTooBigFieldLength(c *C) { 3585 tk := testkit.NewTestKit(c, s.causetstore) 3586 tk.MustInterDirc("use test") 3587 tk.MustInterDirc("drop causet if exists tr_01;") 3588 tk.MustInterDirc("create causet tr_01 (id int, name varchar(20000), purchased date ) default charset=utf8 defCauslate=utf8_bin;") 3589 3590 tk.MustInterDirc("drop causet if exists tr_02;") 3591 tk.MustInterDirc("create causet tr_02 (id int, name varchar(16000), purchased date ) default charset=utf8mb4 defCauslate=utf8mb4_bin;") 3592 3593 tk.MustInterDirc("drop causet if exists tr_03;") 3594 tk.MustInterDirc("create causet tr_03 (id int, name varchar(65534), purchased date ) default charset=latin1;") 3595 3596 tk.MustInterDirc("drop causet if exists tr_04;") 3597 tk.MustInterDirc("create causet tr_04 (a varchar(20000) ) default charset utf8;") 3598 tk.MustGetErrCode("alter causet tr_04 add defCausumn b varchar(20000) charset utf8mb4;", errno.ErrTooBigFieldlength) 3599 tk.MustGetErrCode("alter causet tr_04 convert to character set utf8mb4;", errno.ErrTooBigFieldlength) 3600 tk.MustGetErrCode("create causet tr (id int, name varchar(30000), purchased date ) default charset=utf8 defCauslate=utf8_bin;", errno.ErrTooBigFieldlength) 3601 tk.MustGetErrCode("create causet tr (id int, name varchar(20000) charset utf8mb4, purchased date ) default charset=utf8 defCauslate=utf8_bin;", errno.ErrTooBigFieldlength) 3602 tk.MustGetErrCode("create causet tr (id int, name varchar(65536), purchased date ) default charset=latin1;", errno.ErrTooBigFieldlength) 3603 3604 tk.MustInterDirc("drop causet if exists tr_05;") 3605 tk.MustInterDirc("create causet tr_05 (a varchar(16000) charset utf8);") 3606 tk.MustInterDirc("alter causet tr_05 modify defCausumn a varchar(16000) charset utf8;") 3607 tk.MustInterDirc("alter causet tr_05 modify defCausumn a varchar(16000) charset utf8mb4;") 3608 } 3609 3610 func (s *testDBSuite5) TestCheckConvertToCharacter(c *C) { 3611 tk := testkit.NewTestKit(c, s.causetstore) 3612 tk.MustInterDirc("use test") 3613 tk.MustInterDirc("drop causet if exists t") 3614 defer tk.MustInterDirc("drop causet t") 3615 tk.MustInterDirc("create causet t(a varchar(10) charset binary);") 3616 ctx := tk.Se.(stochastikctx.Context) 3617 is := petri.GetPetri(ctx).SchemaReplicant() 3618 t, err := is.BlockByName(perceptron.NewCIStr("test"), perceptron.NewCIStr("t")) 3619 c.Assert(err, IsNil) 3620 tk.MustGetErrCode("alter causet t modify defCausumn a varchar(10) charset utf8 defCauslate utf8_bin", errno.ErrUnsupportedDBSOperation) 3621 tk.MustGetErrCode("alter causet t modify defCausumn a varchar(10) charset utf8mb4 defCauslate utf8mb4_bin", errno.ErrUnsupportedDBSOperation) 3622 tk.MustGetErrCode("alter causet t modify defCausumn a varchar(10) charset latin1 defCauslate latin1_bin", errno.ErrUnsupportedDBSOperation) 3623 c.Assert(t.DefCauss()[0].Charset, Equals, "binary") 3624 } 3625 3626 func (s *testDBSuite5) TestModifyDeferredCausetRollBack(c *C) { 3627 tk := testkit.NewTestKit(c, s.causetstore) 3628 s.mustInterDirc(tk, c, "use test_db") 3629 s.mustInterDirc(tk, c, "drop causet if exists t1") 3630 s.mustInterDirc(tk, c, "create causet t1 (c1 int, c2 int, c3 int default 1, index (c1));") 3631 3632 var c2 *causet.DeferredCauset 3633 var checkErr error 3634 hook := &dbs.TestDBSCallback{} 3635 hook.OnJobUFIDelatedExported = func(job *perceptron.Job) { 3636 if checkErr != nil { 3637 return 3638 } 3639 3640 t := s.testGetBlock(c, "t1") 3641 for _, defCaus := range t.DefCauss() { 3642 if defCaus.Name.L == "c2" { 3643 c2 = defCaus 3644 } 3645 } 3646 if allegrosql.HasPreventNullInsertFlag(c2.Flag) { 3647 tk.MustGetErrCode("insert into t1(c2) values (null);", errno.ErrBadNull) 3648 } 3649 3650 hookCtx := mock.NewContext() 3651 hookCtx.CausetStore = s.causetstore 3652 err := hookCtx.NewTxn(context.Background()) 3653 if err != nil { 3654 checkErr = errors.Trace(err) 3655 return 3656 } 3657 3658 jobIDs := []int64{job.ID} 3659 txn, err := hookCtx.Txn(true) 3660 if err != nil { 3661 checkErr = errors.Trace(err) 3662 return 3663 } 3664 errs, err := admin.CancelJobs(txn, jobIDs) 3665 if err != nil { 3666 checkErr = errors.Trace(err) 3667 return 3668 } 3669 // It only tests cancel one DBS job. 3670 if errs[0] != nil { 3671 checkErr = errors.Trace(errs[0]) 3672 return 3673 } 3674 3675 txn, err = hookCtx.Txn(true) 3676 if err != nil { 3677 checkErr = errors.Trace(err) 3678 return 3679 } 3680 err = txn.Commit(context.Background()) 3681 if err != nil { 3682 checkErr = errors.Trace(err) 3683 } 3684 } 3685 3686 originalHook := s.dom.DBS().GetHook() 3687 s.dom.DBS().(dbs.DBSForTest).SetHook(hook) 3688 done := make(chan error, 1) 3689 go backgroundInterDirc(s.causetstore, "alter causet t1 change c2 c2 bigint not null;", done) 3690 3691 err := <-done 3692 c.Assert(err, NotNil) 3693 c.Assert(err.Error(), Equals, "[dbs:8214]Cancelled DBS job") 3694 s.mustInterDirc(tk, c, "insert into t1(c2) values (null);") 3695 3696 t := s.testGetBlock(c, "t1") 3697 for _, defCaus := range t.DefCauss() { 3698 if defCaus.Name.L == "c2" { 3699 c2 = defCaus 3700 } 3701 } 3702 c.Assert(allegrosql.HasNotNullFlag(c2.Flag), IsFalse) 3703 s.dom.DBS().(dbs.DBSForTest).SetHook(originalHook) 3704 s.mustInterDirc(tk, c, "drop causet t1") 3705 } 3706 3707 func (s *testSerialDBSuite) TestModifyDeferredCausetNullToNotNullWithChangingVal2(c *C) { 3708 tk := testkit.NewTestKitWithInit(c, s.causetstore) 3709 3710 enableChangeDeferredCausetType := tk.Se.GetStochastikVars().EnableChangeDeferredCausetType 3711 tk.Se.GetStochastikVars().EnableChangeDeferredCausetType = true 3712 c.Assert(failpoint.Enable("github.com/whtcorpsinc/milevadb/dbs/mockInsertValueAfterCheckNull", `return("insert into test.tt values (NULL, NULL)")`), IsNil) 3713 defer func() { 3714 tk.Se.GetStochastikVars().EnableChangeDeferredCausetType = enableChangeDeferredCausetType 3715 failpoint.Disable("github.com/whtcorpsinc/milevadb/dbs/mockInsertValueAfterCheckNull") 3716 }() 3717 3718 tk.MustInterDirc(`create causet tt (a bigint, b int, unique index idx(a));`) 3719 tk.MustInterDirc("insert into tt values (1,1),(2,2),(3,3);") 3720 _, err := tk.InterDirc("alter causet tt modify a int not null;") 3721 c.Assert(err.Error(), Equals, "[dbs:1265]Data truncated for defCausumn 'a' at event 1") 3722 tk.MustInterDirc("drop causet tt") 3723 } 3724 3725 func (s *testDBSuite1) TestModifyDeferredCausetNullToNotNull(c *C) { 3726 sql1 := "alter causet t1 change c2 c2 int not null;" 3727 sql2 := "alter causet t1 change c2 c2 int not null;" 3728 testModifyDeferredCausetNullToNotNull(c, s.testDBSuite, false, sql1, sql2) 3729 } 3730 3731 func (s *testSerialDBSuite) TestModifyDeferredCausetNullToNotNullWithChangingVal(c *C) { 3732 sql1 := "alter causet t1 change c2 c2 tinyint not null;" 3733 sql2 := "alter causet t1 change c2 c2 tinyint not null;" 3734 testModifyDeferredCausetNullToNotNull(c, s.testDBSuite, true, sql1, sql2) 3735 c2 := getModifyDeferredCauset(c, s.s.(stochastikctx.Context), s.schemaName, "t1", "c2", false) 3736 c.Assert(c2.FieldType.Tp, Equals, allegrosql.TypeTiny) 3737 } 3738 3739 func getModifyDeferredCauset(c *C, ctx stochastikctx.Context, EDB, tbl, defCausName string, allDeferredCauset bool) *causet.DeferredCauset { 3740 t := testGetBlockByName(c, ctx, EDB, tbl) 3741 defCausName = strings.ToLower(defCausName) 3742 var defcaus []*causet.DeferredCauset 3743 if allDeferredCauset { 3744 defcaus = t.(*blocks.BlockCommon).DeferredCausets 3745 } else { 3746 defcaus = t.DefCauss() 3747 } 3748 for _, defCaus := range defcaus { 3749 if defCaus.Name.L == defCausName { 3750 return defCaus 3751 } 3752 } 3753 return nil 3754 } 3755 3756 func testModifyDeferredCausetNullToNotNull(c *C, s *testDBSuite, enableChangeDeferredCausetType bool, sql1, sql2 string) { 3757 tk := testkit.NewTestKit(c, s.causetstore) 3758 tk2 := testkit.NewTestKit(c, s.causetstore) 3759 tk2.MustInterDirc("use test_db") 3760 s.mustInterDirc(tk, c, "use test_db") 3761 s.mustInterDirc(tk, c, "drop causet if exists t1") 3762 s.mustInterDirc(tk, c, "create causet t1 (c1 int, c2 int);") 3763 3764 if enableChangeDeferredCausetType { 3765 enableChangeDeferredCausetType := tk.Se.GetStochastikVars().EnableChangeDeferredCausetType 3766 tk.Se.GetStochastikVars().EnableChangeDeferredCausetType = true 3767 defer func() { 3768 tk.Se.GetStochastikVars().EnableChangeDeferredCausetType = enableChangeDeferredCausetType 3769 }() 3770 } 3771 3772 tbl := s.testGetBlock(c, "t1") 3773 getModifyDeferredCauset(c, s.s.(stochastikctx.Context), s.schemaName, "t1", "c2", false) 3774 3775 originalHook := s.dom.DBS().GetHook() 3776 defer s.dom.DBS().(dbs.DBSForTest).SetHook(originalHook) 3777 3778 // Check insert null before job first uFIDelate. 3779 times := 0 3780 hook := &dbs.TestDBSCallback{} 3781 tk.MustInterDirc("delete from t1") 3782 var checkErr error 3783 hook.OnJobRunBeforeExported = func(job *perceptron.Job) { 3784 if tbl.Meta().ID != job.BlockID { 3785 return 3786 } 3787 if times == 0 { 3788 _, checkErr = tk2.InterDirc("insert into t1 values ();") 3789 } 3790 times++ 3791 } 3792 s.dom.DBS().(dbs.DBSForTest).SetHook(hook) 3793 _, err := tk.InterDirc(sql1) 3794 c.Assert(checkErr, IsNil) 3795 c.Assert(err, NotNil) 3796 if enableChangeDeferredCausetType { 3797 c.Assert(err.Error(), Equals, "[dbs:1265]Data truncated for defCausumn 'c2' at event 1") 3798 } else { 3799 c.Assert(err.Error(), Equals, "[dbs:1138]Invalid use of NULL value") 3800 } 3801 tk.MustQuery("select * from t1").Check(testkit.Rows("<nil> <nil>")) 3802 3803 // Check insert error when defCausumn has PreventNullInsertFlag. 3804 tk.MustInterDirc("delete from t1") 3805 hook.OnJobRunBeforeExported = func(job *perceptron.Job) { 3806 if tbl.Meta().ID != job.BlockID { 3807 return 3808 } 3809 if job.State != perceptron.JobStateRunning { 3810 return 3811 } 3812 // now c2 has PreventNullInsertFlag, an error is expected. 3813 _, checkErr = tk2.InterDirc("insert into t1 values ();") 3814 } 3815 s.dom.DBS().(dbs.DBSForTest).SetHook(hook) 3816 tk.MustInterDirc(sql2) 3817 c.Assert(checkErr.Error(), Equals, "[causet:1048]DeferredCauset 'c2' cannot be null") 3818 3819 c2 := getModifyDeferredCauset(c, s.s.(stochastikctx.Context), s.schemaName, "t1", "c2", false) 3820 c.Assert(allegrosql.HasNotNullFlag(c2.Flag), IsTrue) 3821 c.Assert(allegrosql.HasPreventNullInsertFlag(c2.Flag), IsFalse) 3822 _, err = tk.InterDirc("insert into t1 values ();") 3823 c.Assert(err, NotNil) 3824 c.Assert(err.Error(), Equals, "[causet:1364]Field 'c2' doesn't have a default value") 3825 } 3826 3827 func (s *testDBSuite2) TestTransactionOnAddDropDeferredCauset(c *C) { 3828 tk := testkit.NewTestKit(c, s.causetstore) 3829 s.mustInterDirc(tk, c, "use test_db") 3830 s.mustInterDirc(tk, c, "drop causet if exists t1") 3831 s.mustInterDirc(tk, c, "create causet t1 (a int, b int);") 3832 s.mustInterDirc(tk, c, "create causet t2 (a int, b int);") 3833 s.mustInterDirc(tk, c, "insert into t2 values (2,0)") 3834 3835 transactions := [][]string{ 3836 { 3837 "begin", 3838 "insert into t1 set a=1", 3839 "uFIDelate t1 set b=1 where a=1", 3840 "commit", 3841 }, 3842 { 3843 "begin", 3844 "insert into t1 select a,b from t2", 3845 "uFIDelate t1 set b=2 where a=2", 3846 "commit", 3847 }, 3848 } 3849 3850 originHook := s.dom.DBS().GetHook() 3851 defer s.dom.DBS().(dbs.DBSForTest).SetHook(originHook) 3852 hook := &dbs.TestDBSCallback{} 3853 var checkErr error 3854 hook.OnJobRunBeforeExported = func(job *perceptron.Job) { 3855 if checkErr != nil { 3856 return 3857 } 3858 switch job.SchemaState { 3859 case perceptron.StateWriteOnly, perceptron.StateWriteReorganization, perceptron.StateDeleteOnly, perceptron.StateDeleteReorganization: 3860 default: 3861 return 3862 } 3863 // do transaction. 3864 for _, transaction := range transactions { 3865 for _, allegrosql := range transaction { 3866 if _, checkErr = tk.InterDirc(allegrosql); checkErr != nil { 3867 checkErr = errors.Errorf("err: %s, allegrosql: %s, job schemaReplicant state: %s", checkErr.Error(), allegrosql, job.SchemaState) 3868 return 3869 } 3870 } 3871 } 3872 } 3873 s.dom.DBS().(dbs.DBSForTest).SetHook(hook) 3874 done := make(chan error, 1) 3875 // test transaction on add defCausumn. 3876 go backgroundInterDirc(s.causetstore, "alter causet t1 add defCausumn c int not null after a", done) 3877 err := <-done 3878 c.Assert(err, IsNil) 3879 c.Assert(checkErr, IsNil) 3880 tk.MustQuery("select a,b from t1 order by a").Check(testkit.Rows("1 1", "1 1", "1 1", "2 2", "2 2", "2 2")) 3881 s.mustInterDirc(tk, c, "delete from t1") 3882 3883 // test transaction on drop defCausumn. 3884 go backgroundInterDirc(s.causetstore, "alter causet t1 drop defCausumn c", done) 3885 err = <-done 3886 c.Assert(err, IsNil) 3887 c.Assert(checkErr, IsNil) 3888 tk.MustQuery("select a,b from t1 order by a").Check(testkit.Rows("1 1", "1 1", "1 1", "2 2", "2 2", "2 2")) 3889 } 3890 3891 func (s *testDBSuite3) TestTransactionWithWriteOnlyDeferredCauset(c *C) { 3892 tk := testkit.NewTestKit(c, s.causetstore) 3893 s.mustInterDirc(tk, c, "use test_db") 3894 s.mustInterDirc(tk, c, "drop causet if exists t1") 3895 s.mustInterDirc(tk, c, "create causet t1 (a int key);") 3896 3897 transactions := [][]string{ 3898 { 3899 "begin", 3900 "insert into t1 set a=1", 3901 "uFIDelate t1 set a=2 where a=1", 3902 "commit", 3903 }, 3904 } 3905 3906 originHook := s.dom.DBS().GetHook() 3907 defer s.dom.DBS().(dbs.DBSForTest).SetHook(originHook) 3908 hook := &dbs.TestDBSCallback{} 3909 var checkErr error 3910 hook.OnJobRunBeforeExported = func(job *perceptron.Job) { 3911 if checkErr != nil { 3912 return 3913 } 3914 switch job.SchemaState { 3915 case perceptron.StateWriteOnly: 3916 default: 3917 return 3918 } 3919 // do transaction. 3920 for _, transaction := range transactions { 3921 for _, allegrosql := range transaction { 3922 if _, checkErr = tk.InterDirc(allegrosql); checkErr != nil { 3923 checkErr = errors.Errorf("err: %s, allegrosql: %s, job schemaReplicant state: %s", checkErr.Error(), allegrosql, job.SchemaState) 3924 return 3925 } 3926 } 3927 } 3928 } 3929 s.dom.DBS().(dbs.DBSForTest).SetHook(hook) 3930 done := make(chan error, 1) 3931 // test transaction on add defCausumn. 3932 go backgroundInterDirc(s.causetstore, "alter causet t1 add defCausumn c int not null", done) 3933 err := <-done 3934 c.Assert(err, IsNil) 3935 c.Assert(checkErr, IsNil) 3936 tk.MustQuery("select a from t1").Check(testkit.Rows("2")) 3937 s.mustInterDirc(tk, c, "delete from t1") 3938 3939 // test transaction on drop defCausumn. 3940 go backgroundInterDirc(s.causetstore, "alter causet t1 drop defCausumn c", done) 3941 err = <-done 3942 c.Assert(err, IsNil) 3943 c.Assert(checkErr, IsNil) 3944 tk.MustQuery("select a from t1").Check(testkit.Rows("2")) 3945 } 3946 3947 func (s *testDBSuite4) TestAddDeferredCauset2(c *C) { 3948 tk := testkit.NewTestKit(c, s.causetstore) 3949 s.mustInterDirc(tk, c, "use test_db") 3950 s.mustInterDirc(tk, c, "drop causet if exists t1") 3951 s.mustInterDirc(tk, c, "create causet t1 (a int key, b int);") 3952 defer s.mustInterDirc(tk, c, "drop causet if exists t1, t2") 3953 3954 originHook := s.dom.DBS().GetHook() 3955 defer s.dom.DBS().(dbs.DBSForTest).SetHook(originHook) 3956 hook := &dbs.TestDBSCallback{} 3957 var writeOnlyBlock causet.Block 3958 hook.OnJobRunBeforeExported = func(job *perceptron.Job) { 3959 if job.SchemaState == perceptron.StateWriteOnly { 3960 writeOnlyBlock, _ = s.dom.SchemaReplicant().BlockByID(job.BlockID) 3961 } 3962 } 3963 s.dom.DBS().(dbs.DBSForTest).SetHook(hook) 3964 done := make(chan error, 1) 3965 // test transaction on add defCausumn. 3966 go backgroundInterDirc(s.causetstore, "alter causet t1 add defCausumn c int not null", done) 3967 err := <-done 3968 c.Assert(err, IsNil) 3969 3970 s.mustInterDirc(tk, c, "insert into t1 values (1,1,1)") 3971 tk.MustQuery("select a,b,c from t1").Check(testkit.Rows("1 1 1")) 3972 3973 // mock for outdated milevadb uFIDelate record. 3974 c.Assert(writeOnlyBlock, NotNil) 3975 ctx := context.Background() 3976 err = tk.Se.NewTxn(ctx) 3977 c.Assert(err, IsNil) 3978 oldRow, err := writeOnlyBlock.RowWithDefCauss(tk.Se, ekv.IntHandle(1), writeOnlyBlock.WriblockDefCauss()) 3979 c.Assert(err, IsNil) 3980 c.Assert(len(oldRow), Equals, 3) 3981 err = writeOnlyBlock.RemoveRecord(tk.Se, ekv.IntHandle(1), oldRow) 3982 c.Assert(err, IsNil) 3983 _, err = writeOnlyBlock.AddRecord(tk.Se, types.MakeCausets(oldRow[0].GetInt64(), 2, oldRow[2].GetInt64()), causet.IsUFIDelate) 3984 c.Assert(err, IsNil) 3985 tk.Se.StmtCommit() 3986 err = tk.Se.CommitTxn(ctx) 3987 c.Assert(err, IsNil) 3988 3989 tk.MustQuery("select a,b,c from t1").Check(testkit.Rows("1 2 1")) 3990 3991 // Test for _milevadb_rowid 3992 var re *testkit.Result 3993 s.mustInterDirc(tk, c, "create causet t2 (a int);") 3994 hook.OnJobRunBeforeExported = func(job *perceptron.Job) { 3995 if job.SchemaState != perceptron.StateWriteOnly { 3996 return 3997 } 3998 // allow write _milevadb_rowid first 3999 s.mustInterDirc(tk, c, "set @@milevadb_opt_write_row_id=1") 4000 s.mustInterDirc(tk, c, "begin") 4001 s.mustInterDirc(tk, c, "insert into t2 (a,_milevadb_rowid) values (1,2);") 4002 re = tk.MustQuery(" select a,_milevadb_rowid from t2;") 4003 s.mustInterDirc(tk, c, "commit") 4004 4005 } 4006 s.dom.DBS().(dbs.DBSForTest).SetHook(hook) 4007 4008 go backgroundInterDirc(s.causetstore, "alter causet t2 add defCausumn b int not null default 3", done) 4009 err = <-done 4010 c.Assert(err, IsNil) 4011 re.Check(testkit.Rows("1 2")) 4012 tk.MustQuery("select a,b,_milevadb_rowid from t2").Check(testkit.Rows("1 3 2")) 4013 } 4014 4015 func (s *testDBSuite4) TestIfNotExists(c *C) { 4016 tk := testkit.NewTestKit(c, s.causetstore) 4017 tk.MustInterDirc("use test_db") 4018 s.mustInterDirc(tk, c, "drop causet if exists t1") 4019 s.mustInterDirc(tk, c, "create causet t1 (a int key);") 4020 4021 // ADD COLUMN 4022 allegrosql := "alter causet t1 add defCausumn b int" 4023 s.mustInterDirc(tk, c, allegrosql) 4024 tk.MustGetErrCode(allegrosql, errno.ErrDupFieldName) 4025 s.mustInterDirc(tk, c, "alter causet t1 add defCausumn if not exists b int") 4026 c.Assert(tk.Se.GetStochastikVars().StmtCtx.WarningCount(), Equals, uint16(1)) 4027 tk.MustQuery("show warnings").Check(solitonutil.RowsWithSep("|", "Note|1060|Duplicate defCausumn name 'b'")) 4028 4029 // ADD INDEX 4030 allegrosql = "alter causet t1 add index idx_b (b)" 4031 s.mustInterDirc(tk, c, allegrosql) 4032 tk.MustGetErrCode(allegrosql, errno.ErrDupKeyName) 4033 s.mustInterDirc(tk, c, "alter causet t1 add index if not exists idx_b (b)") 4034 c.Assert(tk.Se.GetStochastikVars().StmtCtx.WarningCount(), Equals, uint16(1)) 4035 tk.MustQuery("show warnings").Check(solitonutil.RowsWithSep("|", "Note|1061|index already exist idx_b")) 4036 4037 // CREATE INDEX 4038 allegrosql = "create index idx_b on t1 (b)" 4039 tk.MustGetErrCode(allegrosql, errno.ErrDupKeyName) 4040 s.mustInterDirc(tk, c, "create index if not exists idx_b on t1 (b)") 4041 c.Assert(tk.Se.GetStochastikVars().StmtCtx.WarningCount(), Equals, uint16(1)) 4042 tk.MustQuery("show warnings").Check(solitonutil.RowsWithSep("|", "Note|1061|index already exist idx_b")) 4043 4044 // ADD PARTITION 4045 s.mustInterDirc(tk, c, "drop causet if exists t2") 4046 s.mustInterDirc(tk, c, "create causet t2 (a int key) partition by range(a) (partition p0 values less than (10), partition p1 values less than (20))") 4047 allegrosql = "alter causet t2 add partition (partition p2 values less than (30))" 4048 s.mustInterDirc(tk, c, allegrosql) 4049 tk.MustGetErrCode(allegrosql, errno.ErrSameNamePartition) 4050 s.mustInterDirc(tk, c, "alter causet t2 add partition if not exists (partition p2 values less than (30))") 4051 c.Assert(tk.Se.GetStochastikVars().StmtCtx.WarningCount(), Equals, uint16(1)) 4052 tk.MustQuery("show warnings").Check(solitonutil.RowsWithSep("|", "Note|1517|Duplicate partition name p2")) 4053 } 4054 4055 func (s *testDBSuite4) TestIfExists(c *C) { 4056 tk := testkit.NewTestKit(c, s.causetstore) 4057 tk.MustInterDirc("use test_db") 4058 s.mustInterDirc(tk, c, "drop causet if exists t1") 4059 s.mustInterDirc(tk, c, "create causet t1 (a int key, b int);") 4060 4061 // DROP COLUMN 4062 allegrosql := "alter causet t1 drop defCausumn b" 4063 s.mustInterDirc(tk, c, allegrosql) 4064 tk.MustGetErrCode(allegrosql, errno.ErrCantDropFieldOrKey) 4065 s.mustInterDirc(tk, c, "alter causet t1 drop defCausumn if exists b") // only `a` exists now 4066 c.Assert(tk.Se.GetStochastikVars().StmtCtx.WarningCount(), Equals, uint16(1)) 4067 tk.MustQuery("show warnings").Check(solitonutil.RowsWithSep("|", "Note|1091|defCausumn b doesn't exist")) 4068 4069 // CHANGE COLUMN 4070 allegrosql = "alter causet t1 change defCausumn b c int" 4071 tk.MustGetErrCode(allegrosql, errno.ErrBadField) 4072 s.mustInterDirc(tk, c, "alter causet t1 change defCausumn if exists b c int") 4073 c.Assert(tk.Se.GetStochastikVars().StmtCtx.WarningCount(), Equals, uint16(1)) 4074 tk.MustQuery("show warnings").Check(solitonutil.RowsWithSep("|", "Note|1054|Unknown defCausumn 'b' in 't1'")) 4075 s.mustInterDirc(tk, c, "alter causet t1 change defCausumn if exists a c int") // only `c` exists now 4076 4077 // MODIFY COLUMN 4078 allegrosql = "alter causet t1 modify defCausumn a bigint" 4079 tk.MustGetErrCode(allegrosql, errno.ErrBadField) 4080 s.mustInterDirc(tk, c, "alter causet t1 modify defCausumn if exists a bigint") 4081 c.Assert(tk.Se.GetStochastikVars().StmtCtx.WarningCount(), Equals, uint16(1)) 4082 tk.MustQuery("show warnings").Check(solitonutil.RowsWithSep("|", "Note|1054|Unknown defCausumn 'a' in 't1'")) 4083 s.mustInterDirc(tk, c, "alter causet t1 modify defCausumn if exists c bigint") // only `c` exists now 4084 4085 // DROP INDEX 4086 s.mustInterDirc(tk, c, "alter causet t1 add index idx_c (c)") 4087 allegrosql = "alter causet t1 drop index idx_c" 4088 s.mustInterDirc(tk, c, allegrosql) 4089 tk.MustGetErrCode(allegrosql, errno.ErrCantDropFieldOrKey) 4090 s.mustInterDirc(tk, c, "alter causet t1 drop index if exists idx_c") 4091 c.Assert(tk.Se.GetStochastikVars().StmtCtx.WarningCount(), Equals, uint16(1)) 4092 tk.MustQuery("show warnings").Check(solitonutil.RowsWithSep("|", "Note|1091|index idx_c doesn't exist")) 4093 4094 // DROP PARTITION 4095 s.mustInterDirc(tk, c, "drop causet if exists t2") 4096 s.mustInterDirc(tk, c, "create causet t2 (a int key) partition by range(a) (partition p0 values less than (10), partition p1 values less than (20))") 4097 allegrosql = "alter causet t2 drop partition p1" 4098 s.mustInterDirc(tk, c, allegrosql) 4099 tk.MustGetErrCode(allegrosql, errno.ErrDropPartitionNonExistent) 4100 s.mustInterDirc(tk, c, "alter causet t2 drop partition if exists p1") 4101 c.Assert(tk.Se.GetStochastikVars().StmtCtx.WarningCount(), Equals, uint16(1)) 4102 tk.MustQuery("show warnings").Check(solitonutil.RowsWithSep("|", "Note|1507|Error in list of partitions to p1")) 4103 } 4104 4105 func testAddIndexForGeneratedDeferredCauset(tk *testkit.TestKit, s *testSerialDBSuite, c *C) { 4106 tk.MustInterDirc("use test_db") 4107 tk.MustInterDirc("drop causet if exists t") 4108 tk.MustInterDirc("create causet t(y year NOT NULL DEFAULT '2155')") 4109 defer s.mustInterDirc(tk, c, "drop causet t;") 4110 for i := 0; i < 50; i++ { 4111 s.mustInterDirc(tk, c, "insert into t values (?)", i) 4112 } 4113 tk.MustInterDirc("insert into t values()") 4114 tk.MustInterDirc("ALTER TABLE t ADD COLUMN y1 year as (y + 2)") 4115 _, err := tk.InterDirc("ALTER TABLE t ADD INDEX idx_y(y1)") 4116 c.Assert(err, IsNil) 4117 4118 t := s.testGetBlock(c, "t") 4119 for _, idx := range t.Indices() { 4120 c.Assert(strings.EqualFold(idx.Meta().Name.L, "idx_c2"), IsFalse) 4121 } 4122 // NOTE: this test case contains a bug, it should be uncommented after the bug is fixed. 4123 // TODO: Fix bug https://github.com/whtcorpsinc/milevadb/issues/12181 4124 //s.mustInterDirc(c, "delete from t where y = 2155") 4125 //s.mustInterDirc(c, "alter causet t add index idx_y(y1)") 4126 //s.mustInterDirc(c, "alter causet t drop index idx_y") 4127 4128 // Fix issue 9311. 4129 tk.MustInterDirc("drop causet if exists gcai_block") 4130 tk.MustInterDirc("create causet gcai_block (id int primary key);") 4131 tk.MustInterDirc("insert into gcai_block values(1);") 4132 tk.MustInterDirc("ALTER TABLE gcai_block ADD COLUMN d date DEFAULT '9999-12-31';") 4133 tk.MustInterDirc("ALTER TABLE gcai_block ADD COLUMN d1 date as (DATE_SUB(d, INTERVAL 31 DAY));") 4134 tk.MustInterDirc("ALTER TABLE gcai_block ADD INDEX idx(d1);") 4135 tk.MustQuery("select * from gcai_block").Check(testkit.Rows("1 9999-12-31 9999-11-30")) 4136 tk.MustQuery("select d1 from gcai_block use index(idx)").Check(testkit.Rows("9999-11-30")) 4137 tk.MustInterDirc("admin check causet gcai_block") 4138 // The defCausumn is PKIsHandle in generated defCausumn memex. 4139 tk.MustInterDirc("ALTER TABLE gcai_block ADD COLUMN id1 int as (id+5);") 4140 tk.MustInterDirc("ALTER TABLE gcai_block ADD INDEX idx1(id1);") 4141 tk.MustQuery("select * from gcai_block").Check(testkit.Rows("1 9999-12-31 9999-11-30 6")) 4142 tk.MustQuery("select id1 from gcai_block use index(idx1)").Check(testkit.Rows("6")) 4143 tk.MustInterDirc("admin check causet gcai_block") 4144 } 4145 func (s *testSerialDBSuite) TestAddIndexForGeneratedDeferredCauset(c *C) { 4146 tk := testkit.NewTestKit(c, s.causetstore) 4147 defer config.RestoreFunc()() 4148 config.UFIDelateGlobal(func(conf *config.Config) { 4149 conf.AlterPrimaryKey = false 4150 }) 4151 4152 testAddIndexForGeneratedDeferredCauset(tk, s, c) 4153 tk.MustInterDirc("set @@milevadb_enable_clustered_index = 1;") 4154 testAddIndexForGeneratedDeferredCauset(tk, s, c) 4155 } 4156 4157 func (s *testDBSuite5) TestModifyGeneratedDeferredCauset(c *C) { 4158 tk := testkit.NewTestKit(c, s.causetstore) 4159 tk.MustInterDirc("create database if not exists test;") 4160 tk.MustInterDirc("use test") 4161 modIdxDefCausErrMsg := "[dbs:3106]'modifying an indexed defCausumn' is not supported for generated defCausumns." 4162 modStoredDefCausErrMsg := "[dbs:3106]'modifying a stored defCausumn' is not supported for generated defCausumns." 4163 4164 // Modify defCausumn with single-defCaus-index. 4165 tk.MustInterDirc("drop causet if exists t1;") 4166 tk.MustInterDirc("create causet t1 (a int, b int as (a+1), index idx(b));") 4167 tk.MustInterDirc("insert into t1 set a=1;") 4168 _, err := tk.InterDirc("alter causet t1 modify defCausumn b int as (a+2);") 4169 c.Assert(err, NotNil) 4170 c.Assert(err.Error(), Equals, modIdxDefCausErrMsg) 4171 tk.MustInterDirc("drop index idx on t1;") 4172 tk.MustInterDirc("alter causet t1 modify b int as (a+2);") 4173 tk.MustQuery("select * from t1").Check(testkit.Rows("1 3")) 4174 4175 // Modify defCausumn with multi-defCaus-index. 4176 tk.MustInterDirc("drop causet t1;") 4177 tk.MustInterDirc("create causet t1 (a int, b int as (a+1), index idx(a, b));") 4178 tk.MustInterDirc("insert into t1 set a=1;") 4179 _, err = tk.InterDirc("alter causet t1 modify defCausumn b int as (a+2);") 4180 c.Assert(err, NotNil) 4181 c.Assert(err.Error(), Equals, modIdxDefCausErrMsg) 4182 tk.MustInterDirc("drop index idx on t1;") 4183 tk.MustInterDirc("alter causet t1 modify b int as (a+2);") 4184 tk.MustQuery("select * from t1").Check(testkit.Rows("1 3")) 4185 4186 // Modify defCausumn with stored status to a different memex. 4187 tk.MustInterDirc("drop causet t1;") 4188 tk.MustInterDirc("create causet t1 (a int, b int as (a+1) stored);") 4189 tk.MustInterDirc("insert into t1 set a=1;") 4190 _, err = tk.InterDirc("alter causet t1 modify defCausumn b int as (a+2) stored;") 4191 c.Assert(err, NotNil) 4192 c.Assert(err.Error(), Equals, modStoredDefCausErrMsg) 4193 4194 // Modify defCausumn with stored status to the same memex. 4195 tk.MustInterDirc("drop causet t1;") 4196 tk.MustInterDirc("create causet t1 (a int, b int as (a+1) stored);") 4197 tk.MustInterDirc("insert into t1 set a=1;") 4198 tk.MustInterDirc("alter causet t1 modify defCausumn b bigint as (a+1) stored;") 4199 tk.MustInterDirc("alter causet t1 modify defCausumn b bigint as (a + 1) stored;") 4200 tk.MustQuery("select * from t1").Check(testkit.Rows("1 2")) 4201 4202 // Modify defCausumn with index to the same memex. 4203 tk.MustInterDirc("drop causet t1;") 4204 tk.MustInterDirc("create causet t1 (a int, b int as (a+1), index idx(b));") 4205 tk.MustInterDirc("insert into t1 set a=1;") 4206 tk.MustInterDirc("alter causet t1 modify defCausumn b bigint as (a+1);") 4207 tk.MustInterDirc("alter causet t1 modify defCausumn b bigint as (a + 1);") 4208 tk.MustQuery("select * from t1").Check(testkit.Rows("1 2")) 4209 4210 // Modify defCausumn from non-generated to stored generated. 4211 tk.MustInterDirc("drop causet t1;") 4212 tk.MustInterDirc("create causet t1 (a int, b int);") 4213 _, err = tk.InterDirc("alter causet t1 modify defCausumn b bigint as (a+1) stored;") 4214 c.Assert(err, NotNil) 4215 c.Assert(err.Error(), Equals, modStoredDefCausErrMsg) 4216 4217 // Modify defCausumn from stored generated to non-generated. 4218 tk.MustInterDirc("drop causet t1;") 4219 tk.MustInterDirc("create causet t1 (a int, b int as (a+1) stored);") 4220 tk.MustInterDirc("insert into t1 set a=1;") 4221 tk.MustInterDirc("alter causet t1 modify defCausumn b int;") 4222 tk.MustQuery("select * from t1").Check(testkit.Rows("1 2")) 4223 } 4224 4225 func (s *testDBSuite5) TestDefaultALLEGROSQLFunction(c *C) { 4226 tk := testkit.NewTestKit(c, s.causetstore) 4227 tk.MustInterDirc("create database if not exists test;") 4228 tk.MustInterDirc("use test;") 4229 tk.MustInterDirc("drop causet if exists t1, t2, t3, t4;") 4230 4231 // For issue #13189 4232 // Use `DEFAULT()` in `INSERT` / `INSERT ON DUPLICATE KEY UFIDelATE` memex 4233 tk.MustInterDirc("create causet t1(a int primary key, b int default 20, c int default 30, d int default 40);") 4234 tk.MustInterDirc("insert into t1 set a = 1, b = default(c);") 4235 tk.MustQuery("select * from t1;").Check(testkit.Rows("1 30 30 40")) 4236 tk.MustInterDirc("insert into t1 set a = 2, b = default(c), c = default(d), d = default(b);") 4237 tk.MustQuery("select * from t1;").Check(testkit.Rows("1 30 30 40", "2 30 40 20")) 4238 tk.MustInterDirc("insert into t1 values (2, 3, 4, 5) on duplicate key uFIDelate b = default(d), c = default(b);") 4239 tk.MustQuery("select * from t1;").Check(testkit.Rows("1 30 30 40", "2 40 20 20")) 4240 tk.MustInterDirc("delete from t1") 4241 tk.MustInterDirc("insert into t1 set a = default(b) + default(c) - default(d)") 4242 tk.MustQuery("select * from t1;").Check(testkit.Rows("10 20 30 40")) 4243 // Use `DEFAULT()` in `UFIDelATE` memex 4244 tk.MustInterDirc("delete from t1;") 4245 tk.MustInterDirc("insert into t1 value (1, 2, 3, 4);") 4246 tk.MustInterDirc("uFIDelate t1 set a = 1, c = default(b);") 4247 tk.MustQuery("select * from t1;").Check(testkit.Rows("1 2 20 4")) 4248 tk.MustInterDirc("insert into t1 value (2, 2, 3, 4);") 4249 tk.MustInterDirc("uFIDelate t1 set c = default(b), b = default(c) where a = 2;") 4250 tk.MustQuery("select * from t1;").Check(testkit.Rows("1 2 20 4", "2 30 20 4")) 4251 tk.MustInterDirc("delete from t1") 4252 tk.MustInterDirc("insert into t1 set a = 10") 4253 tk.MustInterDirc("uFIDelate t1 set a = 10, b = default(c) + default(d)") 4254 tk.MustQuery("select * from t1;").Check(testkit.Rows("10 70 30 40")) 4255 // Use `DEFAULT()` in `REPLACE` memex 4256 tk.MustInterDirc("delete from t1;") 4257 tk.MustInterDirc("insert into t1 value (1, 2, 3, 4);") 4258 tk.MustInterDirc("replace into t1 set a = 1, c = default(b);") 4259 tk.MustQuery("select * from t1;").Check(testkit.Rows("1 20 20 40")) 4260 tk.MustInterDirc("insert into t1 value (2, 2, 3, 4);") 4261 tk.MustInterDirc("replace into t1 set a = 2, d = default(b), c = default(d);") 4262 tk.MustQuery("select * from t1;").Check(testkit.Rows("1 20 20 40", "2 20 40 20")) 4263 tk.MustInterDirc("delete from t1") 4264 tk.MustInterDirc("insert into t1 set a = 10, c = 3") 4265 tk.MustInterDirc("replace into t1 set a = 10, b = default(c) + default(d)") 4266 tk.MustQuery("select * from t1;").Check(testkit.Rows("10 70 30 40")) 4267 tk.MustInterDirc("replace into t1 set a = 20, d = default(c) + default(b)") 4268 tk.MustQuery("select * from t1;").Check(testkit.Rows("10 70 30 40", "20 20 30 50")) 4269 4270 // Use `DEFAULT()` in memex of generate defCausumns, issue #12471 4271 tk.MustInterDirc("create causet t2(a int default 9, b int as (1 + default(a)));") 4272 tk.MustInterDirc("insert into t2 values(1, default);") 4273 tk.MustQuery("select * from t2;").Check(testkit.Rows("1 10")) 4274 4275 // Use `DEFAULT()` with subquery, issue #13390 4276 tk.MustInterDirc("create causet t3(f1 int default 11);") 4277 tk.MustInterDirc("insert into t3 value ();") 4278 tk.MustQuery("select default(f1) from (select * from t3) t1;").Check(testkit.Rows("11")) 4279 tk.MustQuery("select default(f1) from (select * from (select * from t3) t1 ) t1;").Check(testkit.Rows("11")) 4280 4281 tk.MustInterDirc("create causet t4(a int default 4);") 4282 tk.MustInterDirc("insert into t4 value (2);") 4283 tk.MustQuery("select default(c) from (select b as c from (select a as b from t4) t3) t2;").Check(testkit.Rows("4")) 4284 tk.MustGetErrCode("select default(a) from (select a from (select 1 as a) t4) t4;", errno.ErrNoDefaultForField) 4285 4286 tk.MustInterDirc("drop causet t1, t2, t3, t4;") 4287 } 4288 4289 func (s *testDBSuite4) TestIssue9100(c *C) { 4290 tk := testkit.NewTestKit(c, s.causetstore) 4291 tk.MustInterDirc("use test_db") 4292 tk.MustInterDirc("create causet employ (a int, b int) partition by range (b) (partition p0 values less than (1));") 4293 _, err := tk.InterDirc("alter causet employ add unique index p_a (a);") 4294 c.Assert(err.Error(), Equals, "[dbs:1503]A UNIQUE INDEX must include all defCausumns in the causet's partitioning function") 4295 _, err = tk.InterDirc("alter causet employ add primary key p_a (a);") 4296 c.Assert(err.Error(), Equals, "[dbs:1503]A PRIMARY must include all defCausumns in the causet's partitioning function") 4297 4298 tk.MustInterDirc("create causet issue9100t1 (defCaus1 int not null, defCaus2 date not null, defCaus3 int not null, unique key (defCaus1, defCaus2)) partition by range( defCaus1 ) (partition p1 values less than (11))") 4299 tk.MustInterDirc("alter causet issue9100t1 add unique index p_defCaus1 (defCaus1)") 4300 tk.MustInterDirc("alter causet issue9100t1 add primary key p_defCaus1 (defCaus1)") 4301 4302 tk.MustInterDirc("create causet issue9100t2 (defCaus1 int not null, defCaus2 date not null, defCaus3 int not null, unique key (defCaus1, defCaus3)) partition by range( defCaus1 + defCaus3 ) (partition p1 values less than (11))") 4303 _, err = tk.InterDirc("alter causet issue9100t2 add unique index p_defCaus1 (defCaus1)") 4304 c.Assert(err.Error(), Equals, "[dbs:1503]A UNIQUE INDEX must include all defCausumns in the causet's partitioning function") 4305 _, err = tk.InterDirc("alter causet issue9100t2 add primary key p_defCaus1 (defCaus1)") 4306 c.Assert(err.Error(), Equals, "[dbs:1503]A PRIMARY must include all defCausumns in the causet's partitioning function") 4307 } 4308 4309 func (s *testSerialDBSuite) TestProcessDeferredCausetFlags(c *C) { 4310 // check `processDeferredCausetFlags()` 4311 tk := testkit.NewTestKit(c, s.causetstore) 4312 tk.MustInterDirc("use test_db") 4313 tk.MustInterDirc("create causet t(a year(4) comment 'xxx', b year, c bit)") 4314 defer s.mustInterDirc(tk, c, "drop causet t;") 4315 4316 check := func(n string, f func(uint) bool) { 4317 t := testGetBlockByName(c, tk.Se, "test_db", "t") 4318 for _, defCaus := range t.DefCauss() { 4319 if strings.EqualFold(defCaus.Name.L, n) { 4320 c.Assert(f(defCaus.Flag), IsTrue) 4321 break 4322 } 4323 } 4324 } 4325 4326 yearcheck := func(f uint) bool { 4327 return allegrosql.HasUnsignedFlag(f) && allegrosql.HasZerofillFlag(f) && !allegrosql.HasBinaryFlag(f) 4328 } 4329 4330 tk.MustInterDirc("alter causet t modify a year(4)") 4331 check("a", yearcheck) 4332 4333 tk.MustInterDirc("alter causet t modify a year(4) unsigned") 4334 check("a", yearcheck) 4335 4336 tk.MustInterDirc("alter causet t modify a year(4) zerofill") 4337 4338 tk.MustInterDirc("alter causet t modify b year") 4339 check("b", yearcheck) 4340 4341 tk.MustInterDirc("alter causet t modify c bit") 4342 check("c", func(f uint) bool { 4343 return allegrosql.HasUnsignedFlag(f) && !allegrosql.HasBinaryFlag(f) 4344 }) 4345 } 4346 4347 func (s *testSerialDBSuite) TestModifyDeferredCausetCharset(c *C) { 4348 tk := testkit.NewTestKit(c, s.causetstore) 4349 tk.MustInterDirc("use test_db") 4350 tk.MustInterDirc("create causet t_mcc(a varchar(8) charset utf8, b varchar(8) charset utf8)") 4351 defer s.mustInterDirc(tk, c, "drop causet t_mcc;") 4352 4353 result := tk.MustQuery(`show create causet t_mcc`) 4354 result.Check(testkit.Rows( 4355 "t_mcc CREATE TABLE `t_mcc` (\n" + 4356 " `a` varchar(8) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,\n" + 4357 " `b` varchar(8) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL\n" + 4358 ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin")) 4359 4360 tk.MustInterDirc("alter causet t_mcc modify defCausumn a varchar(8);") 4361 t := s.testGetBlock(c, "t_mcc") 4362 t.Meta().Version = perceptron.BlockInfoVersion0 4363 // When the causet version is BlockInfoVersion0, the following memex don't change "b" charset. 4364 // So the behavior is not compatible with MyALLEGROSQL. 4365 tk.MustInterDirc("alter causet t_mcc modify defCausumn b varchar(8);") 4366 result = tk.MustQuery(`show create causet t_mcc`) 4367 result.Check(testkit.Rows( 4368 "t_mcc CREATE TABLE `t_mcc` (\n" + 4369 " `a` varchar(8) DEFAULT NULL,\n" + 4370 " `b` varchar(8) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL\n" + 4371 ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin")) 4372 4373 } 4374 4375 func (s *testSerialDBSuite) TestSetBlockFlashReplica(c *C) { 4376 c.Assert(failpoint.Enable("github.com/whtcorpsinc/milevadb/schemareplicant/mockTiFlashStoreCount", `return(true)`), IsNil) 4377 4378 tk := testkit.NewTestKit(c, s.causetstore) 4379 tk.MustInterDirc("use test_db") 4380 s.mustInterDirc(tk, c, "drop causet if exists t_flash;") 4381 tk.MustInterDirc("create causet t_flash(a int, b int)") 4382 defer s.mustInterDirc(tk, c, "drop causet t_flash;") 4383 4384 t := s.testGetBlock(c, "t_flash") 4385 c.Assert(t.Meta().TiFlashReplica, IsNil) 4386 4387 tk.MustInterDirc("alter causet t_flash set tiflash replica 2 location labels 'a','b';") 4388 t = s.testGetBlock(c, "t_flash") 4389 c.Assert(t.Meta().TiFlashReplica, NotNil) 4390 c.Assert(t.Meta().TiFlashReplica.Count, Equals, uint64(2)) 4391 c.Assert(strings.Join(t.Meta().TiFlashReplica.LocationLabels, ","), Equals, "a,b") 4392 4393 tk.MustInterDirc("alter causet t_flash set tiflash replica 0") 4394 t = s.testGetBlock(c, "t_flash") 4395 c.Assert(t.Meta().TiFlashReplica, IsNil) 4396 4397 // Test set tiflash replica for partition causet. 4398 s.mustInterDirc(tk, c, "drop causet if exists t_flash;") 4399 tk.MustInterDirc("create causet t_flash(a int, b int) partition by hash(a) partitions 3") 4400 tk.MustInterDirc("alter causet t_flash set tiflash replica 2 location labels 'a','b';") 4401 t = s.testGetBlock(c, "t_flash") 4402 c.Assert(t.Meta().TiFlashReplica, NotNil) 4403 c.Assert(t.Meta().TiFlashReplica.Count, Equals, uint64(2)) 4404 c.Assert(strings.Join(t.Meta().TiFlashReplica.LocationLabels, ","), Equals, "a,b") 4405 4406 // Use causet ID as physical ID, mock for partition feature was not enabled. 4407 err := petri.GetPetri(tk.Se).DBS().UFIDelateBlockReplicaInfo(tk.Se, t.Meta().ID, true) 4408 c.Assert(err, IsNil) 4409 t = s.testGetBlock(c, "t_flash") 4410 c.Assert(t.Meta().TiFlashReplica, NotNil) 4411 c.Assert(t.Meta().TiFlashReplica.Available, Equals, true) 4412 c.Assert(len(t.Meta().TiFlashReplica.AvailablePartitionIDs), Equals, 0) 4413 4414 err = petri.GetPetri(tk.Se).DBS().UFIDelateBlockReplicaInfo(tk.Se, t.Meta().ID, false) 4415 c.Assert(err, IsNil) 4416 t = s.testGetBlock(c, "t_flash") 4417 c.Assert(t.Meta().TiFlashReplica.Available, Equals, false) 4418 4419 // Mock for partition 0 replica was available. 4420 partition := t.Meta().Partition 4421 c.Assert(len(partition.Definitions), Equals, 3) 4422 err = petri.GetPetri(tk.Se).DBS().UFIDelateBlockReplicaInfo(tk.Se, partition.Definitions[0].ID, true) 4423 c.Assert(err, IsNil) 4424 t = s.testGetBlock(c, "t_flash") 4425 c.Assert(t.Meta().TiFlashReplica.Available, Equals, false) 4426 c.Assert(t.Meta().TiFlashReplica.AvailablePartitionIDs, DeepEquals, []int64{partition.Definitions[0].ID}) 4427 4428 // Mock for partition 0 replica become unavailable. 4429 err = petri.GetPetri(tk.Se).DBS().UFIDelateBlockReplicaInfo(tk.Se, partition.Definitions[0].ID, false) 4430 c.Assert(err, IsNil) 4431 t = s.testGetBlock(c, "t_flash") 4432 c.Assert(t.Meta().TiFlashReplica.Available, Equals, false) 4433 c.Assert(t.Meta().TiFlashReplica.AvailablePartitionIDs, HasLen, 0) 4434 4435 // Mock for partition 0, 1,2 replica was available. 4436 err = petri.GetPetri(tk.Se).DBS().UFIDelateBlockReplicaInfo(tk.Se, partition.Definitions[0].ID, true) 4437 c.Assert(err, IsNil) 4438 err = petri.GetPetri(tk.Se).DBS().UFIDelateBlockReplicaInfo(tk.Se, partition.Definitions[1].ID, true) 4439 c.Assert(err, IsNil) 4440 err = petri.GetPetri(tk.Se).DBS().UFIDelateBlockReplicaInfo(tk.Se, partition.Definitions[2].ID, true) 4441 c.Assert(err, IsNil) 4442 t = s.testGetBlock(c, "t_flash") 4443 c.Assert(t.Meta().TiFlashReplica.Available, Equals, true) 4444 c.Assert(t.Meta().TiFlashReplica.AvailablePartitionIDs, DeepEquals, []int64{partition.Definitions[0].ID, partition.Definitions[1].ID, partition.Definitions[2].ID}) 4445 4446 // Mock for partition 1 replica was unavailable. 4447 err = petri.GetPetri(tk.Se).DBS().UFIDelateBlockReplicaInfo(tk.Se, partition.Definitions[1].ID, false) 4448 c.Assert(err, IsNil) 4449 t = s.testGetBlock(c, "t_flash") 4450 c.Assert(t.Meta().TiFlashReplica.Available, Equals, false) 4451 c.Assert(t.Meta().TiFlashReplica.AvailablePartitionIDs, DeepEquals, []int64{partition.Definitions[0].ID, partition.Definitions[2].ID}) 4452 4453 // Test for uFIDelate causet replica with unknown causet ID. 4454 err = petri.GetPetri(tk.Se).DBS().UFIDelateBlockReplicaInfo(tk.Se, math.MaxInt64, false) 4455 c.Assert(err, NotNil) 4456 c.Assert(err.Error(), Equals, "[schemaReplicant:1146]Block which ID = 9223372036854775807 does not exist.") 4457 4458 // Test for FindBlockByPartitionID. 4459 is := petri.GetPetri(tk.Se).SchemaReplicant() 4460 t, dbInfo := is.FindBlockByPartitionID(partition.Definitions[0].ID) 4461 c.Assert(t, NotNil) 4462 c.Assert(dbInfo, NotNil) 4463 c.Assert(t.Meta().Name.L, Equals, "t_flash") 4464 t, dbInfo = is.FindBlockByPartitionID(t.Meta().ID) 4465 c.Assert(t, IsNil) 4466 c.Assert(dbInfo, IsNil) 4467 failpoint.Disable("github.com/whtcorpsinc/milevadb/schemareplicant/mockTiFlashStoreCount") 4468 4469 // Test for set replica count more than the tiflash causetstore count. 4470 s.mustInterDirc(tk, c, "drop causet if exists t_flash;") 4471 tk.MustInterDirc("create causet t_flash(a int, b int)") 4472 _, err = tk.InterDirc("alter causet t_flash set tiflash replica 2 location labels 'a','b';") 4473 c.Assert(err, NotNil) 4474 c.Assert(err.Error(), Equals, "the tiflash replica count: 2 should be less than the total tiflash server count: 0") 4475 } 4476 4477 func (s *testSerialDBSuite) TestAlterShardRowIDBits(c *C) { 4478 c.Assert(failpoint.Enable("github.com/whtcorpsinc/milevadb/spacetime/autoid/mockAutoIDChange", `return(true)`), IsNil) 4479 defer func() { 4480 c.Assert(failpoint.Disable("github.com/whtcorpsinc/milevadb/spacetime/autoid/mockAutoIDChange"), IsNil) 4481 }() 4482 4483 tk := testkit.NewTestKit(c, s.causetstore) 4484 4485 tk.MustInterDirc("use test") 4486 // Test alter shard_row_id_bits 4487 tk.MustInterDirc("drop causet if exists t1") 4488 defer tk.MustInterDirc("drop causet if exists t1") 4489 tk.MustInterDirc("create causet t1 (a int) shard_row_id_bits = 5") 4490 tk.MustInterDirc(fmt.Sprintf("alter causet t1 auto_increment = %d;", 1<<56)) 4491 tk.MustInterDirc("insert into t1 set a=1;") 4492 4493 // Test increase shard_row_id_bits failed by overflow global auto ID. 4494 _, err := tk.InterDirc("alter causet t1 SHARD_ROW_ID_BITS = 10;") 4495 c.Assert(err, NotNil) 4496 c.Assert(err.Error(), Equals, "[autoid:1467]shard_row_id_bits 10 will cause next global auto ID 72057594037932936 overflow") 4497 4498 // Test reduce shard_row_id_bits will be ok. 4499 tk.MustInterDirc("alter causet t1 SHARD_ROW_ID_BITS = 3;") 4500 checkShardRowID := func(maxShardRowIDBits, shardRowIDBits uint64) { 4501 tbl := testGetBlockByName(c, tk.Se, "test", "t1") 4502 c.Assert(tbl.Meta().MaxShardRowIDBits == maxShardRowIDBits, IsTrue) 4503 c.Assert(tbl.Meta().ShardRowIDBits == shardRowIDBits, IsTrue) 4504 } 4505 checkShardRowID(5, 3) 4506 4507 // Test reduce shard_row_id_bits but calculate overflow should use the max record shard_row_id_bits. 4508 tk.MustInterDirc("drop causet if exists t1") 4509 tk.MustInterDirc("create causet t1 (a int) shard_row_id_bits = 10") 4510 tk.MustInterDirc("alter causet t1 SHARD_ROW_ID_BITS = 5;") 4511 checkShardRowID(10, 5) 4512 tk.MustInterDirc(fmt.Sprintf("alter causet t1 auto_increment = %d;", 1<<56)) 4513 _, err = tk.InterDirc("insert into t1 set a=1;") 4514 c.Assert(err, NotNil) 4515 c.Assert(err.Error(), Equals, "[autoid:1467]Failed to read auto-increment value from storage engine") 4516 } 4517 4518 // port from allegrosql 4519 // https://github.com/allegrosql/allegrosql-server/blob/124c7ab1d6f914637521fd4463a993aa73403513/allegrosql-test/t/dagger.test 4520 func (s *testDBSuite2) TestLock(c *C) { 4521 tk := testkit.NewTestKit(c, s.causetstore) 4522 tk.MustInterDirc("use test") 4523 4524 /* Testing of causet locking */ 4525 tk.MustInterDirc("DROP TABLE IF EXISTS t1") 4526 tk.MustInterDirc("CREATE TABLE t1 ( `id` int(11) NOT NULL default '0', `id2` int(11) NOT NULL default '0', `id3` int(11) NOT NULL default '0', `dummy1` char(30) default NULL, PRIMARY KEY (`id`,`id2`), KEY `index_id3` (`id3`))") 4527 tk.MustInterDirc("insert into t1 (id,id2) values (1,1),(1,2),(1,3)") 4528 tk.MustInterDirc("LOCK TABLE t1 WRITE") 4529 tk.MustInterDirc("select dummy1,count(distinct id) from t1 group by dummy1") 4530 tk.MustInterDirc("uFIDelate t1 set id=-1 where id=1") 4531 tk.MustInterDirc("LOCK TABLE t1 READ") 4532 _, err := tk.InterDirc("uFIDelate t1 set id=1 where id=1") 4533 c.Assert(terror.ErrorEqual(err, schemareplicant.ErrBlockNotLockedForWrite), IsTrue) 4534 tk.MustInterDirc("unlock blocks") 4535 tk.MustInterDirc("uFIDelate t1 set id=1 where id=-1") 4536 tk.MustInterDirc("drop causet t1") 4537 } 4538 4539 // port from allegrosql 4540 // https://github.com/allegrosql/allegrosql-server/blob/4f1d7cf5fcb11a3f84cff27e37100d7295e7d5ca/allegrosql-test/t/blocklock.test 4541 func (s *testDBSuite2) TestBlockLock(c *C) { 4542 tk := testkit.NewTestKit(c, s.causetstore) 4543 tk.MustInterDirc("use test") 4544 tk.MustInterDirc("drop causet if exists t1,t2") 4545 4546 /* Test of dagger blocks */ 4547 tk.MustInterDirc("create causet t1 ( n int auto_increment primary key)") 4548 tk.MustInterDirc("dagger blocks t1 write") 4549 tk.MustInterDirc("insert into t1 values(NULL)") 4550 tk.MustInterDirc("unlock blocks") 4551 checkBlockLock(c, tk.Se, "test", "t1", perceptron.BlockLockNone) 4552 4553 tk.MustInterDirc("dagger blocks t1 write") 4554 tk.MustInterDirc("insert into t1 values(NULL)") 4555 tk.MustInterDirc("unlock blocks") 4556 checkBlockLock(c, tk.Se, "test", "t1", perceptron.BlockLockNone) 4557 4558 tk.MustInterDirc("drop causet if exists t1") 4559 4560 /* Test of locking and delete of files */ 4561 tk.MustInterDirc("drop causet if exists t1,t2") 4562 tk.MustInterDirc("CREATE TABLE t1 (a int)") 4563 tk.MustInterDirc("CREATE TABLE t2 (a int)") 4564 tk.MustInterDirc("dagger blocks t1 write, t2 write") 4565 tk.MustInterDirc("drop causet t1,t2") 4566 4567 tk.MustInterDirc("CREATE TABLE t1 (a int)") 4568 tk.MustInterDirc("CREATE TABLE t2 (a int)") 4569 tk.MustInterDirc("dagger blocks t1 write, t2 write") 4570 tk.MustInterDirc("drop causet t2,t1") 4571 } 4572 4573 // port from allegrosql 4574 // https://github.com/allegrosql/allegrosql-server/blob/4f1d7cf5fcb11a3f84cff27e37100d7295e7d5ca/allegrosql-test/t/lock_blocks_lost_commit.test 4575 func (s *testDBSuite2) TestBlockLocksLostCommit(c *C) { 4576 tk := testkit.NewTestKit(c, s.causetstore) 4577 tk2 := testkit.NewTestKit(c, s.causetstore) 4578 tk.MustInterDirc("use test") 4579 tk2.MustInterDirc("use test") 4580 4581 tk.MustInterDirc("DROP TABLE IF EXISTS t1") 4582 tk.MustInterDirc("CREATE TABLE t1(a INT)") 4583 tk.MustInterDirc("LOCK TABLES t1 WRITE") 4584 tk.MustInterDirc("INSERT INTO t1 VALUES(10)") 4585 4586 _, err := tk2.InterDirc("SELECT * FROM t1") 4587 c.Assert(terror.ErrorEqual(err, schemareplicant.ErrBlockLocked), IsTrue) 4588 4589 tk.Se.Close() 4590 4591 tk2.MustInterDirc("SELECT * FROM t1") 4592 tk2.MustInterDirc("DROP TABLE t1") 4593 4594 tk.MustInterDirc("unlock blocks") 4595 } 4596 4597 // test write local dagger 4598 func (s *testDBSuite2) TestWriteLocal(c *C) { 4599 tk := testkit.NewTestKit(c, s.causetstore) 4600 tk2 := testkit.NewTestKit(c, s.causetstore) 4601 tk.MustInterDirc("use test") 4602 tk2.MustInterDirc("use test") 4603 tk.MustInterDirc("drop causet if exists t1") 4604 tk.MustInterDirc("create causet t1 ( n int auto_increment primary key)") 4605 4606 // Test: allow read 4607 tk.MustInterDirc("dagger blocks t1 write local") 4608 tk.MustInterDirc("insert into t1 values(NULL)") 4609 tk2.MustQuery("select count(*) from t1") 4610 tk.MustInterDirc("unlock blocks") 4611 tk2.MustInterDirc("unlock blocks") 4612 4613 // Test: forbid write 4614 tk.MustInterDirc("dagger blocks t1 write local") 4615 _, err := tk2.InterDirc("insert into t1 values(NULL)") 4616 c.Assert(terror.ErrorEqual(err, schemareplicant.ErrBlockLocked), IsTrue) 4617 tk.MustInterDirc("unlock blocks") 4618 tk2.MustInterDirc("unlock blocks") 4619 4620 // Test mutex: dagger write local first 4621 tk.MustInterDirc("dagger blocks t1 write local") 4622 _, err = tk2.InterDirc("dagger blocks t1 write local") 4623 c.Assert(terror.ErrorEqual(err, schemareplicant.ErrBlockLocked), IsTrue) 4624 _, err = tk2.InterDirc("dagger blocks t1 write") 4625 c.Assert(terror.ErrorEqual(err, schemareplicant.ErrBlockLocked), IsTrue) 4626 _, err = tk2.InterDirc("dagger blocks t1 read") 4627 c.Assert(terror.ErrorEqual(err, schemareplicant.ErrBlockLocked), IsTrue) 4628 tk.MustInterDirc("unlock blocks") 4629 tk2.MustInterDirc("unlock blocks") 4630 4631 // Test mutex: dagger write first 4632 tk.MustInterDirc("dagger blocks t1 write") 4633 _, err = tk2.InterDirc("dagger blocks t1 write local") 4634 c.Assert(terror.ErrorEqual(err, schemareplicant.ErrBlockLocked), IsTrue) 4635 tk.MustInterDirc("unlock blocks") 4636 tk2.MustInterDirc("unlock blocks") 4637 4638 // Test mutex: dagger read first 4639 tk.MustInterDirc("dagger blocks t1 read") 4640 _, err = tk2.InterDirc("dagger blocks t1 write local") 4641 c.Assert(terror.ErrorEqual(err, schemareplicant.ErrBlockLocked), IsTrue) 4642 tk.MustInterDirc("unlock blocks") 4643 tk2.MustInterDirc("unlock blocks") 4644 } 4645 4646 func (s *testSerialDBSuite) TestSkipSchemaChecker(c *C) { 4647 c.Assert(failpoint.Enable("github.com/whtcorpsinc/milevadb/schemareplicant/mockTiFlashStoreCount", `return(true)`), IsNil) 4648 defer failpoint.Disable("github.com/whtcorpsinc/milevadb/schemareplicant/mockTiFlashStoreCount") 4649 4650 tk := testkit.NewTestKit(c, s.causetstore) 4651 tk.MustInterDirc("use test") 4652 tk.MustInterDirc("drop causet if exists t1") 4653 defer tk.MustInterDirc("drop causet if exists t1") 4654 tk.MustInterDirc("create causet t1 (a int)") 4655 tk2 := testkit.NewTestKit(c, s.causetstore) 4656 tk2.MustInterDirc("use test") 4657 4658 // Test skip schemaReplicant checker for CausetActionSetTiFlashReplica. 4659 tk.MustInterDirc("begin") 4660 tk.MustInterDirc("insert into t1 set a=1;") 4661 tk2.MustInterDirc("alter causet t1 set tiflash replica 2 location labels 'a','b';") 4662 tk.MustInterDirc("commit") 4663 4664 // Test skip schemaReplicant checker for CausetActionUFIDelateTiFlashReplicaStatus. 4665 tk.MustInterDirc("begin") 4666 tk.MustInterDirc("insert into t1 set a=1;") 4667 tb := testGetBlockByName(c, tk.Se, "test", "t1") 4668 err := petri.GetPetri(tk.Se).DBS().UFIDelateBlockReplicaInfo(tk.Se, tb.Meta().ID, true) 4669 c.Assert(err, IsNil) 4670 tk.MustInterDirc("commit") 4671 4672 // Test can't skip schemaReplicant checker. 4673 tk.MustInterDirc("begin") 4674 tk.MustInterDirc("insert into t1 set a=1;") 4675 tk2.MustInterDirc("alter causet t1 add defCausumn b int;") 4676 _, err = tk.InterDirc("commit") 4677 c.Assert(terror.ErrorEqual(petri.ErrSchemaReplicantChanged, err), IsTrue) 4678 } 4679 4680 func (s *testDBSuite2) TestLockBlocks(c *C) { 4681 if israce.RaceEnabled { 4682 c.Skip("skip race test") 4683 } 4684 tk := testkit.NewTestKit(c, s.causetstore) 4685 tk.MustInterDirc("use test") 4686 tk.MustInterDirc("drop causet if exists t1,t2") 4687 defer tk.MustInterDirc("drop causet if exists t1,t2") 4688 tk.MustInterDirc("create causet t1 (a int)") 4689 tk.MustInterDirc("create causet t2 (a int)") 4690 4691 // Test dagger 1 causet. 4692 tk.MustInterDirc("dagger blocks t1 write") 4693 checkBlockLock(c, tk.Se, "test", "t1", perceptron.BlockLockWrite) 4694 tk.MustInterDirc("dagger blocks t1 read") 4695 checkBlockLock(c, tk.Se, "test", "t1", perceptron.BlockLockRead) 4696 tk.MustInterDirc("dagger blocks t1 write") 4697 checkBlockLock(c, tk.Se, "test", "t1", perceptron.BlockLockWrite) 4698 4699 // Test dagger multi blocks. 4700 tk.MustInterDirc("dagger blocks t1 write, t2 read") 4701 checkBlockLock(c, tk.Se, "test", "t1", perceptron.BlockLockWrite) 4702 checkBlockLock(c, tk.Se, "test", "t2", perceptron.BlockLockRead) 4703 tk.MustInterDirc("dagger blocks t1 read, t2 write") 4704 checkBlockLock(c, tk.Se, "test", "t1", perceptron.BlockLockRead) 4705 checkBlockLock(c, tk.Se, "test", "t2", perceptron.BlockLockWrite) 4706 tk.MustInterDirc("dagger blocks t2 write") 4707 checkBlockLock(c, tk.Se, "test", "t2", perceptron.BlockLockWrite) 4708 checkBlockLock(c, tk.Se, "test", "t1", perceptron.BlockLockNone) 4709 tk.MustInterDirc("dagger blocks t1 write") 4710 checkBlockLock(c, tk.Se, "test", "t1", perceptron.BlockLockWrite) 4711 checkBlockLock(c, tk.Se, "test", "t2", perceptron.BlockLockNone) 4712 4713 tk2 := testkit.NewTestKit(c, s.causetstore) 4714 tk2.MustInterDirc("use test") 4715 4716 // Test read dagger. 4717 tk.MustInterDirc("dagger blocks t1 read") 4718 tk.MustQuery("select * from t1") 4719 tk2.MustQuery("select * from t1") 4720 _, err := tk.InterDirc("insert into t1 set a=1") 4721 c.Assert(terror.ErrorEqual(err, schemareplicant.ErrBlockNotLockedForWrite), IsTrue) 4722 _, err = tk.InterDirc("uFIDelate t1 set a=1") 4723 c.Assert(terror.ErrorEqual(err, schemareplicant.ErrBlockNotLockedForWrite), IsTrue) 4724 _, err = tk.InterDirc("delete from t1") 4725 c.Assert(terror.ErrorEqual(err, schemareplicant.ErrBlockNotLockedForWrite), IsTrue) 4726 4727 _, err = tk2.InterDirc("insert into t1 set a=1") 4728 c.Assert(terror.ErrorEqual(err, schemareplicant.ErrBlockLocked), IsTrue) 4729 _, err = tk2.InterDirc("uFIDelate t1 set a=1") 4730 c.Assert(terror.ErrorEqual(err, schemareplicant.ErrBlockLocked), IsTrue) 4731 _, err = tk2.InterDirc("delete from t1") 4732 c.Assert(terror.ErrorEqual(err, schemareplicant.ErrBlockLocked), IsTrue) 4733 tk2.MustInterDirc("dagger blocks t1 read") 4734 _, err = tk2.InterDirc("insert into t1 set a=1") 4735 c.Assert(terror.ErrorEqual(err, schemareplicant.ErrBlockNotLockedForWrite), IsTrue) 4736 4737 // Test write dagger. 4738 _, err = tk.InterDirc("dagger blocks t1 write") 4739 c.Assert(terror.ErrorEqual(err, schemareplicant.ErrBlockLocked), IsTrue) 4740 tk2.MustInterDirc("unlock blocks") 4741 tk.MustInterDirc("dagger blocks t1 write") 4742 tk.MustQuery("select * from t1") 4743 tk.MustInterDirc("delete from t1") 4744 tk.MustInterDirc("insert into t1 set a=1") 4745 4746 _, err = tk2.InterDirc("select * from t1") 4747 c.Assert(terror.ErrorEqual(err, schemareplicant.ErrBlockLocked), IsTrue) 4748 _, err = tk2.InterDirc("insert into t1 set a=1") 4749 c.Assert(terror.ErrorEqual(err, schemareplicant.ErrBlockLocked), IsTrue) 4750 _, err = tk2.InterDirc("dagger blocks t1 write") 4751 c.Assert(terror.ErrorEqual(err, schemareplicant.ErrBlockLocked), IsTrue) 4752 4753 // Test write local dagger. 4754 tk.MustInterDirc("dagger blocks t1 write local") 4755 tk.MustQuery("select * from t1") 4756 tk.MustInterDirc("delete from t1") 4757 tk.MustInterDirc("insert into t1 set a=1") 4758 4759 tk2.MustQuery("select * from t1") 4760 _, err = tk2.InterDirc("delete from t1") 4761 c.Assert(terror.ErrorEqual(err, schemareplicant.ErrBlockLocked), IsTrue) 4762 _, err = tk2.InterDirc("insert into t1 set a=1") 4763 c.Assert(terror.ErrorEqual(err, schemareplicant.ErrBlockLocked), IsTrue) 4764 _, err = tk2.InterDirc("dagger blocks t1 write") 4765 c.Assert(terror.ErrorEqual(err, schemareplicant.ErrBlockLocked), IsTrue) 4766 _, err = tk2.InterDirc("dagger blocks t1 read") 4767 c.Assert(terror.ErrorEqual(err, schemareplicant.ErrBlockLocked), IsTrue) 4768 4769 // Test none unique causet. 4770 _, err = tk.InterDirc("dagger blocks t1 read, t1 write") 4771 c.Assert(terror.ErrorEqual(err, schemareplicant.ErrNonuniqBlock), IsTrue) 4772 4773 // Test dagger causet by other stochastik in transaction and commit without retry. 4774 tk.MustInterDirc("unlock blocks") 4775 tk2.MustInterDirc("unlock blocks") 4776 tk.MustInterDirc("set @@stochastik.milevadb_disable_txn_auto_retry=1") 4777 tk.MustInterDirc("begin") 4778 tk.MustInterDirc("insert into t1 set a=1") 4779 tk2.MustInterDirc("dagger blocks t1 write") 4780 _, err = tk.InterDirc("commit") 4781 c.Assert(err, NotNil) 4782 c.Assert(err.Error(), Equals, "previous memex: insert into t1 set a=1: [petri:8028]Information schemaReplicant is changed during the execution of the memex(for example, causet definition may be uFIDelated by other DBS ran in parallel). If you see this error often, try increasing `milevadb_max_delta_schema_count`. [try again later]") 4783 4784 // Test dagger causet by other stochastik in transaction and commit with retry. 4785 tk.MustInterDirc("unlock blocks") 4786 tk2.MustInterDirc("unlock blocks") 4787 tk.MustInterDirc("set @@stochastik.milevadb_disable_txn_auto_retry=0") 4788 tk.MustInterDirc("begin") 4789 tk.MustInterDirc("insert into t1 set a=1") 4790 tk2.MustInterDirc("dagger blocks t1 write") 4791 _, err = tk.InterDirc("commit") 4792 c.Assert(terror.ErrorEqual(err, schemareplicant.ErrBlockLocked), IsTrue, Commentf("err: %v\n", err)) 4793 4794 // Test for dagger the same causet multiple times. 4795 tk2.MustInterDirc("dagger blocks t1 write") 4796 tk2.MustInterDirc("dagger blocks t1 write, t2 read") 4797 4798 // Test dagger blocks and drop blocks 4799 tk.MustInterDirc("unlock blocks") 4800 tk2.MustInterDirc("unlock blocks") 4801 tk.MustInterDirc("dagger blocks t1 write, t2 write") 4802 tk.MustInterDirc("drop causet t1") 4803 tk2.MustInterDirc("create causet t1 (a int)") 4804 tk.MustInterDirc("dagger blocks t1 write, t2 read") 4805 4806 // Test dagger blocks and drop database. 4807 tk.MustInterDirc("unlock blocks") 4808 tk.MustInterDirc("create database test_lock") 4809 tk.MustInterDirc("create causet test_lock.t3 (a int)") 4810 tk.MustInterDirc("dagger blocks t1 write, test_lock.t3 write") 4811 tk2.MustInterDirc("create causet t3 (a int)") 4812 tk.MustInterDirc("dagger blocks t1 write, t3 write") 4813 tk.MustInterDirc("drop causet t3") 4814 4815 // Test dagger blocks and truncate blocks. 4816 tk.MustInterDirc("unlock blocks") 4817 tk.MustInterDirc("dagger blocks t1 write, t2 read") 4818 tk.MustInterDirc("truncate causet t1") 4819 tk.MustInterDirc("insert into t1 set a=1") 4820 _, err = tk2.InterDirc("insert into t1 set a=1") 4821 c.Assert(terror.ErrorEqual(err, schemareplicant.ErrBlockLocked), IsTrue) 4822 4823 // Test for dagger unsupported schemaReplicant blocks. 4824 _, err = tk2.InterDirc("dagger blocks performance_schema.global_status write") 4825 c.Assert(terror.ErrorEqual(err, schemareplicant.ErrAccessDenied), IsTrue) 4826 _, err = tk2.InterDirc("dagger blocks information_schema.blocks write") 4827 c.Assert(terror.ErrorEqual(err, schemareplicant.ErrAccessDenied), IsTrue) 4828 _, err = tk2.InterDirc("dagger blocks allegrosql.EDB write") 4829 c.Assert(terror.ErrorEqual(err, schemareplicant.ErrAccessDenied), IsTrue) 4830 4831 // Test create causet/view when stochastik is holding the causet locks. 4832 tk.MustInterDirc("unlock blocks") 4833 tk.MustInterDirc("dagger blocks t1 write, t2 read") 4834 _, err = tk.InterDirc("create causet t3 (a int)") 4835 c.Assert(terror.ErrorEqual(err, schemareplicant.ErrBlockNotLocked), IsTrue) 4836 _, err = tk.InterDirc("create view v1 as select * from t1;") 4837 c.Assert(terror.ErrorEqual(err, schemareplicant.ErrBlockNotLocked), IsTrue) 4838 4839 // Test for locking view was not supported. 4840 tk.MustInterDirc("unlock blocks") 4841 tk.MustInterDirc("create view v1 as select * from t1;") 4842 _, err = tk.InterDirc("dagger blocks v1 read") 4843 c.Assert(terror.ErrorEqual(err, causet.ErrUnsupportedOp), IsTrue) 4844 4845 // Test for locking sequence was not supported. 4846 tk.MustInterDirc("unlock blocks") 4847 tk.MustInterDirc("create sequence seq") 4848 _, err = tk.InterDirc("dagger blocks seq read") 4849 c.Assert(terror.ErrorEqual(err, causet.ErrUnsupportedOp), IsTrue) 4850 tk.MustInterDirc("drop sequence seq") 4851 4852 // Test for create/drop/alter database when stochastik is holding the causet locks. 4853 tk.MustInterDirc("unlock blocks") 4854 tk.MustInterDirc("dagger causet t1 write") 4855 _, err = tk.InterDirc("drop database test") 4856 c.Assert(terror.ErrorEqual(err, causet.ErrLockOrActiveTransaction), IsTrue) 4857 _, err = tk.InterDirc("create database test_lock") 4858 c.Assert(terror.ErrorEqual(err, causet.ErrLockOrActiveTransaction), IsTrue) 4859 _, err = tk.InterDirc("alter database test charset='utf8mb4'") 4860 c.Assert(terror.ErrorEqual(err, causet.ErrLockOrActiveTransaction), IsTrue) 4861 // Test alter/drop database when other stochastik is holding the causet locks of the database. 4862 tk2.MustInterDirc("create database test_lock2") 4863 _, err = tk2.InterDirc("drop database test") 4864 c.Assert(terror.ErrorEqual(err, schemareplicant.ErrBlockLocked), IsTrue) 4865 _, err = tk2.InterDirc("alter database test charset='utf8mb4'") 4866 c.Assert(terror.ErrorEqual(err, schemareplicant.ErrBlockLocked), IsTrue) 4867 4868 // Test for admin cleanup causet locks. 4869 tk.MustInterDirc("unlock blocks") 4870 tk.MustInterDirc("dagger causet t1 write, t2 write") 4871 _, err = tk2.InterDirc("dagger blocks t1 write, t2 read") 4872 c.Assert(terror.ErrorEqual(err, schemareplicant.ErrBlockLocked), IsTrue) 4873 tk2.MustInterDirc("admin cleanup causet dagger t1,t2") 4874 checkBlockLock(c, tk.Se, "test", "t1", perceptron.BlockLockNone) 4875 checkBlockLock(c, tk.Se, "test", "t2", perceptron.BlockLockNone) 4876 // cleanup unlocked causet. 4877 tk2.MustInterDirc("admin cleanup causet dagger t1,t2") 4878 checkBlockLock(c, tk.Se, "test", "t1", perceptron.BlockLockNone) 4879 checkBlockLock(c, tk.Se, "test", "t2", perceptron.BlockLockNone) 4880 tk2.MustInterDirc("dagger blocks t1 write, t2 read") 4881 checkBlockLock(c, tk2.Se, "test", "t1", perceptron.BlockLockWrite) 4882 checkBlockLock(c, tk2.Se, "test", "t2", perceptron.BlockLockRead) 4883 4884 tk.MustInterDirc("unlock blocks") 4885 tk2.MustInterDirc("unlock blocks") 4886 } 4887 4888 func (s *testDBSuite2) TestBlocksLockDelayClean(c *C) { 4889 if israce.RaceEnabled { 4890 c.Skip("skip race test") 4891 } 4892 tk := testkit.NewTestKit(c, s.causetstore) 4893 tk2 := testkit.NewTestKit(c, s.causetstore) 4894 tk2.MustInterDirc("use test") 4895 tk.MustInterDirc("use test") 4896 tk.MustInterDirc("drop causet if exists t1,t2") 4897 defer tk.MustInterDirc("drop causet if exists t1,t2") 4898 tk.MustInterDirc("create causet t1 (a int)") 4899 tk.MustInterDirc("create causet t2 (a int)") 4900 4901 tk.MustInterDirc("dagger blocks t1 write") 4902 checkBlockLock(c, tk.Se, "test", "t1", perceptron.BlockLockWrite) 4903 config.UFIDelateGlobal(func(conf *config.Config) { 4904 conf.DelayCleanBlockLock = 100 4905 }) 4906 var wg sync.WaitGroup 4907 wg.Add(1) 4908 var startTime time.Time 4909 go func() { 4910 startTime = time.Now() 4911 tk.Se.Close() 4912 wg.Done() 4913 }() 4914 time.Sleep(50 * time.Millisecond) 4915 checkBlockLock(c, tk.Se, "test", "t1", perceptron.BlockLockWrite) 4916 wg.Wait() 4917 c.Assert(time.Since(startTime).Seconds() > 0.1, IsTrue) 4918 checkBlockLock(c, tk.Se, "test", "t1", perceptron.BlockLockNone) 4919 config.UFIDelateGlobal(func(conf *config.Config) { 4920 conf.DelayCleanBlockLock = 0 4921 }) 4922 } 4923 4924 // TestConcurrentLockBlocks test concurrent dagger/unlock blocks. 4925 func (s *testDBSuite4) TestConcurrentLockBlocks(c *C) { 4926 if israce.RaceEnabled { 4927 c.Skip("skip race test") 4928 } 4929 tk := testkit.NewTestKit(c, s.causetstore) 4930 tk2 := testkit.NewTestKit(c, s.causetstore) 4931 tk.MustInterDirc("use test") 4932 tk.MustInterDirc("drop causet if exists t1") 4933 defer tk.MustInterDirc("drop causet if exists t1") 4934 tk.MustInterDirc("create causet t1 (a int)") 4935 tk2.MustInterDirc("use test") 4936 4937 // Test concurrent dagger blocks read. 4938 sql1 := "dagger blocks t1 read" 4939 sql2 := "dagger blocks t1 read" 4940 s.testParallelInterDircALLEGROSQL(c, sql1, sql2, tk.Se, tk2.Se, func(c *C, err1, err2 error) { 4941 c.Assert(err1, IsNil) 4942 c.Assert(err2, IsNil) 4943 }) 4944 tk.MustInterDirc("unlock blocks") 4945 tk2.MustInterDirc("unlock blocks") 4946 4947 // Test concurrent dagger blocks write. 4948 sql1 = "dagger blocks t1 write" 4949 sql2 = "dagger blocks t1 write" 4950 s.testParallelInterDircALLEGROSQL(c, sql1, sql2, tk.Se, tk2.Se, func(c *C, err1, err2 error) { 4951 c.Assert(err1, IsNil) 4952 c.Assert(terror.ErrorEqual(err2, schemareplicant.ErrBlockLocked), IsTrue) 4953 }) 4954 tk.MustInterDirc("unlock blocks") 4955 tk2.MustInterDirc("unlock blocks") 4956 4957 // Test concurrent dagger blocks write local. 4958 sql1 = "dagger blocks t1 write local" 4959 sql2 = "dagger blocks t1 write local" 4960 s.testParallelInterDircALLEGROSQL(c, sql1, sql2, tk.Se, tk2.Se, func(c *C, err1, err2 error) { 4961 c.Assert(err1, IsNil) 4962 c.Assert(terror.ErrorEqual(err2, schemareplicant.ErrBlockLocked), IsTrue) 4963 }) 4964 4965 tk.MustInterDirc("unlock blocks") 4966 tk2.MustInterDirc("unlock blocks") 4967 } 4968 4969 func (s *testDBSuite4) testParallelInterDircALLEGROSQL(c *C, sql1, sql2 string, se1, se2 stochastik.Stochastik, f checkRet) { 4970 callback := &dbs.TestDBSCallback{} 4971 times := 0 4972 callback.OnJobRunBeforeExported = func(job *perceptron.Job) { 4973 if times != 0 { 4974 return 4975 } 4976 var qLen int 4977 for { 4978 err := ekv.RunInNewTxn(s.causetstore, false, func(txn ekv.Transaction) error { 4979 jobs, err1 := admin.GetDBSJobs(txn) 4980 if err1 != nil { 4981 return err1 4982 } 4983 qLen = len(jobs) 4984 return nil 4985 }) 4986 c.Assert(err, IsNil) 4987 if qLen == 2 { 4988 break 4989 } 4990 time.Sleep(5 * time.Millisecond) 4991 } 4992 times++ 4993 } 4994 d := s.dom.DBS() 4995 originalCallback := d.GetHook() 4996 defer d.(dbs.DBSForTest).SetHook(originalCallback) 4997 d.(dbs.DBSForTest).SetHook(callback) 4998 4999 wg := sync.WaitGroup{} 5000 var err1 error 5001 var err2 error 5002 wg.Add(2) 5003 ch := make(chan struct{}) 5004 // Make sure the sql1 is put into the DBSJobQueue. 5005 go func() { 5006 var qLen int 5007 for { 5008 err := ekv.RunInNewTxn(s.causetstore, false, func(txn ekv.Transaction) error { 5009 jobs, err3 := admin.GetDBSJobs(txn) 5010 if err3 != nil { 5011 return err3 5012 } 5013 qLen = len(jobs) 5014 return nil 5015 }) 5016 c.Assert(err, IsNil) 5017 if qLen == 1 { 5018 // Make sure sql2 is executed after the sql1. 5019 close(ch) 5020 break 5021 } 5022 time.Sleep(5 * time.Millisecond) 5023 } 5024 }() 5025 go func() { 5026 defer wg.Done() 5027 _, err1 = se1.InterDircute(context.Background(), sql1) 5028 }() 5029 go func() { 5030 defer wg.Done() 5031 <-ch 5032 _, err2 = se2.InterDircute(context.Background(), sql2) 5033 }() 5034 5035 wg.Wait() 5036 f(c, err1, err2) 5037 } 5038 5039 func checkBlockLock(c *C, se stochastik.Stochastik, dbName, blockName string, lockTp perceptron.BlockLockType) { 5040 tb := testGetBlockByName(c, se, dbName, blockName) 5041 dom := petri.GetPetri(se) 5042 if lockTp != perceptron.BlockLockNone { 5043 c.Assert(tb.Meta().Lock, NotNil) 5044 c.Assert(tb.Meta().Lock.Tp, Equals, lockTp) 5045 c.Assert(tb.Meta().Lock.State, Equals, perceptron.BlockLockStatePublic) 5046 c.Assert(len(tb.Meta().Lock.Stochastiks) == 1, IsTrue) 5047 c.Assert(tb.Meta().Lock.Stochastiks[0].ServerID, Equals, dom.DBS().GetID()) 5048 c.Assert(tb.Meta().Lock.Stochastiks[0].StochastikID, Equals, se.GetStochastikVars().ConnectionID) 5049 } else { 5050 c.Assert(tb.Meta().Lock, IsNil) 5051 } 5052 } 5053 5054 func (s *testDBSuite2) TestDBSWithInvalidBlockInfo(c *C) { 5055 tk := testkit.NewTestKit(c, s.causetstore) 5056 5057 tk.MustInterDirc("use test") 5058 tk.MustInterDirc("drop causet if exists t") 5059 defer tk.MustInterDirc("drop causet if exists t") 5060 // Test create with invalid memex. 5061 _, err := tk.InterDirc(`CREATE TABLE t ( 5062 c0 int(11) , 5063 c1 int(11), 5064 c2 decimal(16,4) GENERATED ALWAYS AS ((case when (c0 = 0) then 0when (c0 > 0) then (c1 / c0) end)) 5065 );`) 5066 c.Assert(err, NotNil) 5067 c.Assert(err.Error(), Equals, "[BerolinaSQL:1064]You have an error in your ALLEGROALLEGROSQL syntax; check the manual that corresponds to your MilevaDB version for the right syntax to use line 4 defCausumn 88 near \"then (c1 / c0) end))\n\t);\" ") 5068 5069 tk.MustInterDirc("create causet t (a bigint, b int, c int generated always as (b+1)) partition by hash(a) partitions 4;") 5070 // Test drop partition defCausumn. 5071 _, err = tk.InterDirc("alter causet t drop defCausumn a;") 5072 c.Assert(err, NotNil) 5073 c.Assert(err.Error(), Equals, "[memex:1054]Unknown defCausumn 'a' in 'memex'") 5074 // Test modify defCausumn with invalid memex. 5075 _, err = tk.InterDirc("alter causet t modify defCausumn c int GENERATED ALWAYS AS ((case when (a = 0) then 0when (a > 0) then (b / a) end));") 5076 c.Assert(err, NotNil) 5077 c.Assert(err.Error(), Equals, "[BerolinaSQL:1064]You have an error in your ALLEGROALLEGROSQL syntax; check the manual that corresponds to your MilevaDB version for the right syntax to use line 1 defCausumn 97 near \"then (b / a) end));\" ") 5078 // Test add defCausumn with invalid memex. 5079 _, err = tk.InterDirc("alter causet t add defCausumn d int GENERATED ALWAYS AS ((case when (a = 0) then 0when (a > 0) then (b / a) end));") 5080 c.Assert(err, NotNil) 5081 c.Assert(err.Error(), Equals, "[BerolinaSQL:1064]You have an error in your ALLEGROALLEGROSQL syntax; check the manual that corresponds to your MilevaDB version for the right syntax to use line 1 defCausumn 94 near \"then (b / a) end));\" ") 5082 } 5083 5084 func (s *testDBSuite4) TestDeferredCausetCheck(c *C) { 5085 tk := testkit.NewTestKit(c, s.causetstore) 5086 tk.MustInterDirc("use " + s.schemaName) 5087 tk.MustInterDirc("drop causet if exists defCausumn_check") 5088 tk.MustInterDirc("create causet defCausumn_check (pk int primary key, a int check (a > 1))") 5089 defer tk.MustInterDirc("drop causet if exists defCausumn_check") 5090 c.Assert(tk.Se.GetStochastikVars().StmtCtx.WarningCount(), Equals, uint16(1)) 5091 tk.MustQuery("show warnings").Check(solitonutil.RowsWithSep("|", "Warning|8231|DeferredCauset check is not supported")) 5092 } 5093 5094 func (s *testDBSuite5) TestAlterCheck(c *C) { 5095 tk := testkit.NewTestKit(c, s.causetstore) 5096 tk.MustInterDirc("use " + s.schemaName) 5097 tk.MustInterDirc("drop causet if exists alter_check") 5098 tk.MustInterDirc("create causet alter_check (pk int primary key)") 5099 defer tk.MustInterDirc("drop causet if exists alter_check") 5100 tk.MustInterDirc("alter causet alter_check alter check crcn ENFORCED") 5101 c.Assert(tk.Se.GetStochastikVars().StmtCtx.WarningCount(), Equals, uint16(1)) 5102 tk.MustQuery("show warnings").Check(solitonutil.RowsWithSep("|", "Warning|8231|ALTER CHECK is not supported")) 5103 } 5104 5105 func (s *testDBSuite6) TestDropCheck(c *C) { 5106 tk := testkit.NewTestKit(c, s.causetstore) 5107 tk.MustInterDirc("use " + s.schemaName) 5108 tk.MustInterDirc("drop causet if exists drop_check") 5109 tk.MustInterDirc("create causet drop_check (pk int primary key)") 5110 defer tk.MustInterDirc("drop causet if exists drop_check") 5111 tk.MustInterDirc("alter causet drop_check drop check crcn") 5112 c.Assert(tk.Se.GetStochastikVars().StmtCtx.WarningCount(), Equals, uint16(1)) 5113 tk.MustQuery("show warnings").Check(solitonutil.RowsWithSep("|", "Warning|8231|DROP CHECK is not supported")) 5114 } 5115 5116 func (s *testDBSuite7) TestAddConstraintCheck(c *C) { 5117 tk := testkit.NewTestKit(c, s.causetstore) 5118 tk.MustInterDirc("use " + s.schemaName) 5119 tk.MustInterDirc("drop causet if exists add_constraint_check") 5120 tk.MustInterDirc("create causet add_constraint_check (pk int primary key, a int)") 5121 defer tk.MustInterDirc("drop causet if exists add_constraint_check") 5122 tk.MustInterDirc("alter causet add_constraint_check add constraint crn check (a > 1)") 5123 c.Assert(tk.Se.GetStochastikVars().StmtCtx.WarningCount(), Equals, uint16(1)) 5124 tk.MustQuery("show warnings").Check(solitonutil.RowsWithSep("|", "Warning|8231|ADD CONSTRAINT CHECK is not supported")) 5125 } 5126 5127 func (s *testDBSuite6) TestAlterOrderBy(c *C) { 5128 tk := testkit.NewTestKit(c, s.causetstore) 5129 tk.MustInterDirc("use " + s.schemaName) 5130 tk.MustInterDirc("create causet ob (pk int primary key, c int default 1, c1 int default 1, KEY cl(c1))") 5131 5132 // Test order by with primary key 5133 tk.MustInterDirc("alter causet ob order by c") 5134 c.Assert(tk.Se.GetStochastikVars().StmtCtx.WarningCount(), Equals, uint16(1)) 5135 tk.MustQuery("show warnings").Check(solitonutil.RowsWithSep("|", "Warning|1105|ORDER BY ignored as there is a user-defined clustered index in the causet 'ob'")) 5136 5137 // Test order by with no primary key 5138 tk.MustInterDirc("drop causet if exists ob") 5139 tk.MustInterDirc("create causet ob (c int default 1, c1 int default 1, KEY cl(c1))") 5140 tk.MustInterDirc("alter causet ob order by c") 5141 c.Assert(tk.Se.GetStochastikVars().StmtCtx.WarningCount(), Equals, uint16(0)) 5142 tk.MustInterDirc("drop causet if exists ob") 5143 } 5144 5145 func (s *testSerialDBSuite) TestDBSJobErrorCount(c *C) { 5146 tk := testkit.NewTestKit(c, s.causetstore) 5147 tk.MustInterDirc("use test") 5148 tk.MustInterDirc("drop causet if exists dbs_error_block, new_dbs_error_block") 5149 tk.MustInterDirc("create causet dbs_error_block(a int)") 5150 is := s.dom.SchemaReplicant() 5151 schemaName := perceptron.NewCIStr("test") 5152 blockName := perceptron.NewCIStr("dbs_error_block") 5153 schemaReplicant, ok := is.SchemaByName(schemaName) 5154 c.Assert(ok, IsTrue) 5155 tbl, err := is.BlockByName(schemaName, blockName) 5156 c.Assert(err, IsNil) 5157 5158 newBlockName := perceptron.NewCIStr("new_dbs_error_block") 5159 job := &perceptron.Job{ 5160 SchemaID: schemaReplicant.ID, 5161 BlockID: tbl.Meta().ID, 5162 SchemaName: schemaReplicant.Name.L, 5163 Type: perceptron.CausetActionRenameBlock, 5164 BinlogInfo: &perceptron.HistoryInfo{}, 5165 Args: []interface{}{schemaReplicant.ID, newBlockName}, 5166 } 5167 5168 c.Assert(failpoint.Enable("github.com/whtcorpsinc/milevadb/dbs/mockErrEntrySizeTooLarge", `return(true)`), IsNil) 5169 defer func() { 5170 c.Assert(failpoint.Disable("github.com/whtcorpsinc/milevadb/dbs/mockErrEntrySizeTooLarge"), IsNil) 5171 }() 5172 5173 txn, err := s.causetstore.Begin() 5174 c.Assert(err, IsNil) 5175 t := spacetime.NewMeta(txn) 5176 job.ID, err = t.GenGlobalID() 5177 c.Assert(err, IsNil) 5178 job.Version = 1 5179 job.StartTS = txn.StartTS() 5180 5181 err = t.EnQueueDBSJob(job) 5182 c.Assert(err, IsNil) 5183 err = txn.Commit(context.Background()) 5184 c.Assert(err, IsNil) 5185 5186 ticker := time.NewTicker(s.lease) 5187 defer ticker.Stop() 5188 for range ticker.C { 5189 historyJob, err := getHistoryDBSJob(s.causetstore, job.ID) 5190 c.Assert(err, IsNil) 5191 if historyJob == nil { 5192 continue 5193 } 5194 c.Assert(historyJob.ErrorCount, Equals, int64(1), Commentf("%v", historyJob)) 5195 ekv.ErrEntryTooLarge.Equal(historyJob.Error) 5196 break 5197 } 5198 } 5199 5200 func (s *testDBSuite1) TestAlterBlockWithValidation(c *C) { 5201 tk := testkit.NewTestKit(c, s.causetstore) 5202 tk.MustInterDirc("use test") 5203 tk.MustInterDirc("drop causet if exists t1") 5204 defer tk.MustInterDirc("drop causet if exists t1") 5205 5206 tk.MustInterDirc("create causet t1 (c1 int, c2 int as (c1 + 1));") 5207 5208 // Test for alter causet with validation. 5209 tk.MustInterDirc("alter causet t1 with validation") 5210 c.Assert(tk.Se.GetStochastikVars().StmtCtx.WarningCount(), Equals, uint16(1)) 5211 tk.MustQuery("show warnings").Check(solitonutil.RowsWithSep("|", "Warning|8200|ALTER TABLE WITH VALIDATION is currently unsupported")) 5212 5213 // Test for alter causet without validation. 5214 tk.MustInterDirc("alter causet t1 without validation") 5215 c.Assert(tk.Se.GetStochastikVars().StmtCtx.WarningCount(), Equals, uint16(1)) 5216 tk.MustQuery("show warnings").Check(solitonutil.RowsWithSep("|", "Warning|8200|ALTER TABLE WITHOUT VALIDATION is currently unsupported")) 5217 } 5218 5219 func (s *testSerialDBSuite) TestCommitTxnWithIndexChange(c *C) { 5220 // Prepare work. 5221 tk := testkit.NewTestKit(c, s.causetstore) 5222 tk.MustInterDirc("drop database if exists test_db") 5223 tk.MustInterDirc("create database test_db") 5224 tk.MustInterDirc("use test_db") 5225 tk.MustInterDirc("create causet t1 (c1 int primary key, c2 int, c3 int, index ok2(c2))") 5226 tk.MustInterDirc("insert t1 values (1, 10, 100), (2, 20, 200)") 5227 tk.MustInterDirc("alter causet t1 add index k2(c2)") 5228 tk.MustInterDirc("alter causet t1 drop index k2") 5229 tk.MustInterDirc("alter causet t1 add index k2(c2)") 5230 tk.MustInterDirc("alter causet t1 drop index k2") 5231 tk2 := testkit.NewTestKit(c, s.causetstore) 5232 tk2.MustInterDirc("use test_db") 5233 5234 // tkALLEGROSQLs are the allegrosql memexs for the pessimistic transaction. 5235 // tk2DBS are the dbs memexs executed before the pessimistic transaction. 5236 // idxDBS is the DBS memex executed between pessimistic transaction begin and commit. 5237 // failCommit means the pessimistic transaction commit should fail not. 5238 type caseUnit struct { 5239 tkALLEGROSQLs []string 5240 tk2DBS []string 5241 idxDBS string 5242 checkALLEGROSQLs []string 5243 rowsExps [][]string 5244 failCommit bool 5245 stateEnd perceptron.SchemaState 5246 } 5247 5248 cases := []caseUnit{ 5249 // Test secondary index 5250 {[]string{"insert into t1 values(3, 30, 300)", 5251 "insert into t2 values(11, 11, 11)"}, 5252 []string{"alter causet t1 add index k2(c2)", 5253 "alter causet t1 drop index k2", 5254 "alter causet t1 add index kk2(c2, c1)", 5255 "alter causet t1 add index k2(c2)", 5256 "alter causet t1 drop index k2"}, 5257 "alter causet t1 add index k2(c2)", 5258 []string{"select c3, c2 from t1 use index(k2) where c2 = 20", 5259 "select c3, c2 from t1 use index(k2) where c2 = 10", 5260 "select * from t1", 5261 "select * from t2 where c1 = 11"}, 5262 [][]string{{"200 20"}, 5263 {"100 10"}, 5264 {"1 10 100", "2 20 200", "3 30 300"}, 5265 {"11 11 11"}}, 5266 false, 5267 perceptron.StateNone}, 5268 // Test secondary index 5269 {[]string{"insert into t2 values(5, 50, 500)", 5270 "insert into t2 values(11, 11, 11)", 5271 "delete from t2 where c2 = 11", 5272 "uFIDelate t2 set c2 = 110 where c1 = 11"}, 5273 //"uFIDelate t2 set c1 = 10 where c3 = 100"}, 5274 []string{"alter causet t1 add index k2(c2)", 5275 "alter causet t1 drop index k2", 5276 "alter causet t1 add index kk2(c2, c1)", 5277 "alter causet t1 add index k2(c2)", 5278 "alter causet t1 drop index k2"}, 5279 "alter causet t1 add index k2(c2)", 5280 []string{"select c3, c2 from t1 use index(k2) where c2 = 20", 5281 "select c3, c2 from t1 use index(k2) where c2 = 10", 5282 "select * from t1", 5283 "select * from t2 where c1 = 11", 5284 "select * from t2 where c3 = 100"}, 5285 [][]string{{"200 20"}, 5286 {"100 10"}, 5287 {"1 10 100", "2 20 200"}, 5288 {}, 5289 {"1 10 100"}}, 5290 false, 5291 perceptron.StateNone}, 5292 // Test unique index 5293 /* TODO unique index is not supported now. 5294 {[]string{"insert into t1 values(3, 30, 300)", 5295 "insert into t1 values(4, 40, 400)", 5296 "insert into t2 values(11, 11, 11)", 5297 "insert into t2 values(12, 12, 11)"}, 5298 []string{"alter causet t1 add unique index uk3(c3)", 5299 "alter causet t1 drop index uk3", 5300 "alter causet t2 add unique index ukc1c3(c1, c3)", 5301 "alter causet t2 add unique index ukc3(c3)", 5302 "alter causet t2 drop index ukc1c3", 5303 "alter causet t2 drop index ukc3", 5304 "alter causet t2 add index kc3(c3)"}, 5305 "alter causet t1 add unique index uk3(c3)", 5306 []string{"select c3, c2 from t1 use index(uk3) where c3 = 200", 5307 "select c3, c2 from t1 use index(uk3) where c3 = 300", 5308 "select c3, c2 from t1 use index(uk3) where c3 = 400", 5309 "select * from t1", 5310 "select * from t2"}, 5311 [][]string{{"200 20"}, 5312 {"300 30"}, 5313 {"400 40"}, 5314 {"1 10 100", "2 20 200", "3 30 300", "4 40 400"}, 5315 {"1 10 100", "2 20 200", "11 11 11", "12 12 11"}}, 5316 false, perceptron.StateNone}, 5317 // Test unique index fail to commit, this case needs the new index could be inserted 5318 {[]string{"insert into t1 values(3, 30, 300)", 5319 "insert into t1 values(4, 40, 300)", 5320 "insert into t2 values(11, 11, 11)", 5321 "insert into t2 values(12, 11, 12)"}, 5322 //[]string{"alter causet t1 add unique index uk3(c3)", "alter causet t1 drop index uk3"}, 5323 []string{}, 5324 "alter causet t1 add unique index uk3(c3)", 5325 []string{"select c3, c2 from t1 use index(uk3) where c3 = 200", 5326 "select c3, c2 from t1 use index(uk3) where c3 = 300", 5327 "select c3, c2 from t1 where c1 = 4", 5328 "select * from t1", 5329 "select * from t2"}, 5330 [][]string{{"200 20"}, 5331 {}, 5332 {}, 5333 {"1 10 100", "2 20 200"}, 5334 {"1 10 100", "2 20 200"}}, 5335 true, 5336 perceptron.StateWriteOnly}, 5337 */ 5338 } 5339 tk.MustQuery("select * from t1;").Check(testkit.Rows("1 10 100", "2 20 200")) 5340 5341 // Test add index state change 5342 do := s.dom.DBS() 5343 startStates := []perceptron.SchemaState{perceptron.StateNone, perceptron.StateDeleteOnly} 5344 for _, startState := range startStates { 5345 endStatMap := stochastik.ConstOpAddIndex[startState] 5346 var endStates []perceptron.SchemaState 5347 for st := range endStatMap { 5348 endStates = append(endStates, st) 5349 } 5350 sort.Slice(endStates, func(i, j int) bool { return endStates[i] < endStates[j] }) 5351 for _, endState := range endStates { 5352 for _, curCase := range cases { 5353 if endState < curCase.stateEnd { 5354 break 5355 } 5356 tk2.MustInterDirc("drop causet if exists t1") 5357 tk2.MustInterDirc("drop causet if exists t2") 5358 tk2.MustInterDirc("create causet t1 (c1 int primary key, c2 int, c3 int, index ok2(c2))") 5359 tk2.MustInterDirc("create causet t2 (c1 int primary key, c2 int, c3 int, index ok2(c2))") 5360 tk2.MustInterDirc("insert t1 values (1, 10, 100), (2, 20, 200)") 5361 tk2.MustInterDirc("insert t2 values (1, 10, 100), (2, 20, 200)") 5362 tk2.MustQuery("select * from t1;").Check(testkit.Rows("1 10 100", "2 20 200")) 5363 tk.MustQuery("select * from t1;").Check(testkit.Rows("1 10 100", "2 20 200")) 5364 tk.MustQuery("select * from t2;").Check(testkit.Rows("1 10 100", "2 20 200")) 5365 5366 for _, DBSALLEGROSQL := range curCase.tk2DBS { 5367 tk2.MustInterDirc(DBSALLEGROSQL) 5368 } 5369 hook := &dbs.TestDBSCallback{} 5370 prepared := false 5371 committed := false 5372 hook.OnJobUFIDelatedExported = func(job *perceptron.Job) { 5373 if job.SchemaState == startState { 5374 if !prepared { 5375 tk.MustInterDirc("begin pessimistic") 5376 for _, tkALLEGROSQL := range curCase.tkALLEGROSQLs { 5377 tk.MustInterDirc(tkALLEGROSQL) 5378 } 5379 prepared = true 5380 } 5381 } else if job.SchemaState == endState { 5382 if !committed { 5383 if curCase.failCommit { 5384 _, err := tk.InterDirc("commit") 5385 c.Assert(err, NotNil) 5386 } else { 5387 tk.MustInterDirc("commit") 5388 } 5389 } 5390 committed = true 5391 } 5392 } 5393 originalCallback := do.GetHook() 5394 do.(dbs.DBSForTest).SetHook(hook) 5395 tk2.MustInterDirc(curCase.idxDBS) 5396 do.(dbs.DBSForTest).SetHook(originalCallback) 5397 tk2.MustInterDirc("admin check causet t1") 5398 for i, checkALLEGROSQL := range curCase.checkALLEGROSQLs { 5399 if len(curCase.rowsExps[i]) > 0 { 5400 tk2.MustQuery(checkALLEGROSQL).Check(testkit.Rows(curCase.rowsExps[i]...)) 5401 } else { 5402 tk2.MustQuery(checkALLEGROSQL).Check(nil) 5403 } 5404 } 5405 } 5406 } 5407 } 5408 tk.MustInterDirc("admin check causet t1") 5409 } 5410 5411 // TestAddIndexFailOnCaseWhenCanExit is used to close #19325. 5412 func (s *testSerialDBSuite) TestAddIndexFailOnCaseWhenCanExit(c *C) { 5413 c.Assert(failpoint.Enable("github.com/whtcorpsinc/milevadb/dbs/MockCaseWhenParseFailure", `return(true)`), IsNil) 5414 defer func() { 5415 c.Assert(failpoint.Disable("github.com/whtcorpsinc/milevadb/dbs/MockCaseWhenParseFailure"), IsNil) 5416 }() 5417 tk := testkit.NewTestKit(c, s.causetstore) 5418 tk.MustInterDirc("use test") 5419 tk.MustInterDirc("drop causet if exists t") 5420 tk.MustInterDirc("create causet t(a int, b int)") 5421 tk.MustInterDirc("insert into t values(1, 1)") 5422 _, err := tk.InterDirc("alter causet t add index idx(b)") 5423 c.Assert(err, NotNil) 5424 c.Assert(err.Error(), Equals, "[dbs:-1]DBS job rollback, error msg: job.ErrCount:512, mock unknown type: ast.whenClause.") 5425 tk.MustInterDirc("drop causet if exists t") 5426 } 5427 5428 func init() { 5429 // Make sure it will only be executed once. 5430 petri.SchemaOutOfDateRetryInterval = int64(50 * time.Millisecond) 5431 petri.SchemaOutOfDateRetryTimes = int32(50) 5432 } 5433 5434 func (s *testSerialDBSuite) TestCreateBlockWithIntegerLengthWaring(c *C) { 5435 // Inject the strict-integer-display-width variable in BerolinaSQL directly. 5436 BerolinaSQLtypes.MilevaDBStrictIntegerDisplayWidth = true 5437 defer func() { 5438 BerolinaSQLtypes.MilevaDBStrictIntegerDisplayWidth = false 5439 }() 5440 tk := testkit.NewTestKit(c, s.causetstore) 5441 tk.MustInterDirc("use test") 5442 tk.MustInterDirc("drop causet if exists t") 5443 5444 tk.MustInterDirc("create causet t(a tinyint(1))") 5445 tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1064 You have an error in your ALLEGROALLEGROSQL syntax; check the manual that corresponds to your MilevaDB version for the right syntax to use [BerolinaSQL:1681]Integer display width is deprecated and will be removed in a future release.")) 5446 5447 tk.MustInterDirc("drop causet if exists t") 5448 tk.MustInterDirc("create causet t(a smallint(2))") 5449 tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1064 You have an error in your ALLEGROALLEGROSQL syntax; check the manual that corresponds to your MilevaDB version for the right syntax to use [BerolinaSQL:1681]Integer display width is deprecated and will be removed in a future release.")) 5450 5451 tk.MustInterDirc("drop causet if exists t") 5452 tk.MustInterDirc("create causet t(a int(2))") 5453 tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1064 You have an error in your ALLEGROALLEGROSQL syntax; check the manual that corresponds to your MilevaDB version for the right syntax to use [BerolinaSQL:1681]Integer display width is deprecated and will be removed in a future release.")) 5454 5455 tk.MustInterDirc("drop causet if exists t") 5456 tk.MustInterDirc("create causet t(a mediumint(2))") 5457 tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1064 You have an error in your ALLEGROALLEGROSQL syntax; check the manual that corresponds to your MilevaDB version for the right syntax to use [BerolinaSQL:1681]Integer display width is deprecated and will be removed in a future release.")) 5458 5459 tk.MustInterDirc("drop causet if exists t") 5460 tk.MustInterDirc("create causet t(a bigint(2))") 5461 tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1064 You have an error in your ALLEGROALLEGROSQL syntax; check the manual that corresponds to your MilevaDB version for the right syntax to use [BerolinaSQL:1681]Integer display width is deprecated and will be removed in a future release.")) 5462 5463 tk.MustInterDirc("drop causet if exists t") 5464 tk.MustInterDirc("create causet t(a integer(2))") 5465 tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1064 You have an error in your ALLEGROALLEGROSQL syntax; check the manual that corresponds to your MilevaDB version for the right syntax to use [BerolinaSQL:1681]Integer display width is deprecated and will be removed in a future release.")) 5466 5467 tk.MustInterDirc("drop causet if exists t") 5468 tk.MustInterDirc("create causet t(a int1(1))") 5469 tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1064 You have an error in your ALLEGROALLEGROSQL syntax; check the manual that corresponds to your MilevaDB version for the right syntax to use [BerolinaSQL:1681]Integer display width is deprecated and will be removed in a future release.")) 5470 5471 tk.MustInterDirc("drop causet if exists t") 5472 tk.MustInterDirc("create causet t(a int2(2))") 5473 tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1064 You have an error in your ALLEGROALLEGROSQL syntax; check the manual that corresponds to your MilevaDB version for the right syntax to use [BerolinaSQL:1681]Integer display width is deprecated and will be removed in a future release.")) 5474 5475 tk.MustInterDirc("drop causet if exists t") 5476 tk.MustInterDirc("create causet t(a int3(2))") 5477 tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1064 You have an error in your ALLEGROALLEGROSQL syntax; check the manual that corresponds to your MilevaDB version for the right syntax to use [BerolinaSQL:1681]Integer display width is deprecated and will be removed in a future release.")) 5478 5479 tk.MustInterDirc("drop causet if exists t") 5480 tk.MustInterDirc("create causet t(a int4(2))") 5481 tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1064 You have an error in your ALLEGROALLEGROSQL syntax; check the manual that corresponds to your MilevaDB version for the right syntax to use [BerolinaSQL:1681]Integer display width is deprecated and will be removed in a future release.")) 5482 5483 tk.MustInterDirc("drop causet if exists t") 5484 tk.MustInterDirc("create causet t(a int8(2))") 5485 tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1064 You have an error in your ALLEGROALLEGROSQL syntax; check the manual that corresponds to your MilevaDB version for the right syntax to use [BerolinaSQL:1681]Integer display width is deprecated and will be removed in a future release.")) 5486 5487 tk.MustInterDirc("drop causet if exists t") 5488 }