github.com/whtcorpsinc/milevadb-prod@v0.0.0-20211104133533-f57f4be3b597/dbs/defcaus_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 15 16 import ( 17 "context" 18 "reflect" 19 "sync" 20 21 "github.com/whtcorpsinc/BerolinaSQL" 22 "github.com/whtcorpsinc/BerolinaSQL/allegrosql" 23 "github.com/whtcorpsinc/BerolinaSQL/ast" 24 "github.com/whtcorpsinc/BerolinaSQL/charset" 25 "github.com/whtcorpsinc/BerolinaSQL/perceptron" 26 "github.com/whtcorpsinc/BerolinaSQL/terror" 27 . "github.com/whtcorpsinc/check" 28 "github.com/whtcorpsinc/errors" 29 "github.com/whtcorpsinc/milevadb/blockcodec" 30 "github.com/whtcorpsinc/milevadb/causet" 31 "github.com/whtcorpsinc/milevadb/causet/blocks" 32 "github.com/whtcorpsinc/milevadb/ekv" 33 "github.com/whtcorpsinc/milevadb/schemareplicant" 34 "github.com/whtcorpsinc/milevadb/stochastikctx" 35 "github.com/whtcorpsinc/milevadb/types" 36 ) 37 38 var _ = Suite(&testDeferredCausetSuite{}) 39 40 type testDeferredCausetSuite struct { 41 causetstore ekv.CausetStorage 42 dbInfo *perceptron.DBInfo 43 } 44 45 func (s *testDeferredCausetSuite) SetUpSuite(c *C) { 46 s.causetstore = testCreateStore(c, "test_defCausumn") 47 d := testNewDBSAndStart( 48 context.Background(), 49 c, 50 WithStore(s.causetstore), 51 WithLease(testLease), 52 ) 53 54 s.dbInfo = testSchemaInfo(c, d, "test_defCausumn") 55 testCreateSchema(c, testNewContext(d), d, s.dbInfo) 56 d.Stop() 57 } 58 59 func (s *testDeferredCausetSuite) TearDownSuite(c *C) { 60 err := s.causetstore.Close() 61 c.Assert(err, IsNil) 62 } 63 64 func buildCreateDeferredCausetJob(dbInfo *perceptron.DBInfo, tblInfo *perceptron.BlockInfo, defCausName string, 65 pos *ast.DeferredCausetPosition, defaultValue interface{}) *perceptron.Job { 66 defCaus := &perceptron.DeferredCausetInfo{ 67 Name: perceptron.NewCIStr(defCausName), 68 Offset: len(tblInfo.DeferredCausets), 69 DefaultValue: defaultValue, 70 OriginDefaultValue: defaultValue, 71 } 72 defCaus.ID = allocateDeferredCausetID(tblInfo) 73 defCaus.FieldType = *types.NewFieldType(allegrosql.TypeLong) 74 75 job := &perceptron.Job{ 76 SchemaID: dbInfo.ID, 77 BlockID: tblInfo.ID, 78 Type: perceptron.CausetActionAddDeferredCauset, 79 BinlogInfo: &perceptron.HistoryInfo{}, 80 Args: []interface{}{defCaus, pos, 0}, 81 } 82 return job 83 } 84 85 func testCreateDeferredCauset(c *C, ctx stochastikctx.Context, d *dbs, dbInfo *perceptron.DBInfo, tblInfo *perceptron.BlockInfo, 86 defCausName string, pos *ast.DeferredCausetPosition, defaultValue interface{}) *perceptron.Job { 87 job := buildCreateDeferredCausetJob(dbInfo, tblInfo, defCausName, pos, defaultValue) 88 err := d.doDBSJob(ctx, job) 89 c.Assert(err, IsNil) 90 v := getSchemaVer(c, ctx) 91 checkHistoryJobArgs(c, ctx, job.ID, &historyJobArgs{ver: v, tbl: tblInfo}) 92 return job 93 } 94 95 func buildCreateDeferredCausetsJob(dbInfo *perceptron.DBInfo, tblInfo *perceptron.BlockInfo, defCausNames []string, 96 positions []*ast.DeferredCausetPosition, defaultValue interface{}) *perceptron.Job { 97 defCausInfos := make([]*perceptron.DeferredCausetInfo, len(defCausNames)) 98 offsets := make([]int, len(defCausNames)) 99 ifNotExists := make([]bool, len(defCausNames)) 100 for i, defCausName := range defCausNames { 101 defCaus := &perceptron.DeferredCausetInfo{ 102 Name: perceptron.NewCIStr(defCausName), 103 Offset: len(tblInfo.DeferredCausets), 104 DefaultValue: defaultValue, 105 OriginDefaultValue: defaultValue, 106 } 107 defCaus.ID = allocateDeferredCausetID(tblInfo) 108 defCaus.FieldType = *types.NewFieldType(allegrosql.TypeLong) 109 defCausInfos[i] = defCaus 110 } 111 112 job := &perceptron.Job{ 113 SchemaID: dbInfo.ID, 114 BlockID: tblInfo.ID, 115 Type: perceptron.CausetActionAddDeferredCausets, 116 BinlogInfo: &perceptron.HistoryInfo{}, 117 Args: []interface{}{defCausInfos, positions, offsets, ifNotExists}, 118 } 119 return job 120 } 121 122 func testCreateDeferredCausets(c *C, ctx stochastikctx.Context, d *dbs, dbInfo *perceptron.DBInfo, tblInfo *perceptron.BlockInfo, 123 defCausNames []string, positions []*ast.DeferredCausetPosition, defaultValue interface{}) *perceptron.Job { 124 job := buildCreateDeferredCausetsJob(dbInfo, tblInfo, defCausNames, positions, defaultValue) 125 err := d.doDBSJob(ctx, job) 126 c.Assert(err, IsNil) 127 v := getSchemaVer(c, ctx) 128 checkHistoryJobArgs(c, ctx, job.ID, &historyJobArgs{ver: v, tbl: tblInfo}) 129 return job 130 } 131 132 func buildDropDeferredCausetJob(dbInfo *perceptron.DBInfo, tblInfo *perceptron.BlockInfo, defCausName string) *perceptron.Job { 133 return &perceptron.Job{ 134 SchemaID: dbInfo.ID, 135 BlockID: tblInfo.ID, 136 Type: perceptron.CausetActionDropDeferredCauset, 137 BinlogInfo: &perceptron.HistoryInfo{}, 138 Args: []interface{}{perceptron.NewCIStr(defCausName)}, 139 } 140 } 141 142 func testDropDeferredCauset(c *C, ctx stochastikctx.Context, d *dbs, dbInfo *perceptron.DBInfo, tblInfo *perceptron.BlockInfo, defCausName string, isError bool) *perceptron.Job { 143 job := buildDropDeferredCausetJob(dbInfo, tblInfo, defCausName) 144 err := d.doDBSJob(ctx, job) 145 if isError { 146 c.Assert(err, NotNil) 147 return nil 148 } 149 c.Assert(errors.ErrorStack(err), Equals, "") 150 v := getSchemaVer(c, ctx) 151 checkHistoryJobArgs(c, ctx, job.ID, &historyJobArgs{ver: v, tbl: tblInfo}) 152 return job 153 } 154 155 func buildDropDeferredCausetsJob(dbInfo *perceptron.DBInfo, tblInfo *perceptron.BlockInfo, defCausNames []string) *perceptron.Job { 156 defCausumnNames := make([]perceptron.CIStr, len(defCausNames)) 157 ifExists := make([]bool, len(defCausNames)) 158 for i, defCausName := range defCausNames { 159 defCausumnNames[i] = perceptron.NewCIStr(defCausName) 160 } 161 job := &perceptron.Job{ 162 SchemaID: dbInfo.ID, 163 BlockID: tblInfo.ID, 164 Type: perceptron.CausetActionDropDeferredCausets, 165 BinlogInfo: &perceptron.HistoryInfo{}, 166 Args: []interface{}{defCausumnNames, ifExists}, 167 } 168 return job 169 } 170 171 func testDropDeferredCausets(c *C, ctx stochastikctx.Context, d *dbs, dbInfo *perceptron.DBInfo, tblInfo *perceptron.BlockInfo, defCausNames []string, isError bool) *perceptron.Job { 172 job := buildDropDeferredCausetsJob(dbInfo, tblInfo, defCausNames) 173 err := d.doDBSJob(ctx, job) 174 if isError { 175 c.Assert(err, NotNil) 176 return nil 177 } 178 c.Assert(errors.ErrorStack(err), Equals, "") 179 v := getSchemaVer(c, ctx) 180 checkHistoryJobArgs(c, ctx, job.ID, &historyJobArgs{ver: v, tbl: tblInfo}) 181 return job 182 } 183 184 func (s *testDeferredCausetSuite) TestDeferredCauset(c *C) { 185 d := testNewDBSAndStart( 186 context.Background(), 187 c, 188 WithStore(s.causetstore), 189 WithLease(testLease), 190 ) 191 defer d.Stop() 192 193 tblInfo := testBlockInfo(c, d, "t1", 3) 194 ctx := testNewContext(d) 195 196 testCreateBlock(c, ctx, d, s.dbInfo, tblInfo) 197 t := testGetBlock(c, d, s.dbInfo.ID, tblInfo.ID) 198 199 num := 10 200 for i := 0; i < num; i++ { 201 _, err := t.AddRecord(ctx, types.MakeCausets(i, 10*i, 100*i)) 202 c.Assert(err, IsNil) 203 } 204 205 err := ctx.NewTxn(context.Background()) 206 c.Assert(err, IsNil) 207 208 i := int64(0) 209 err = t.IterRecords(ctx, t.FirstKey(), t.DefCauss(), func(_ ekv.Handle, data []types.Causet, defcaus []*causet.DeferredCauset) (bool, error) { 210 c.Assert(data, HasLen, 3) 211 c.Assert(data[0].GetInt64(), Equals, i) 212 c.Assert(data[1].GetInt64(), Equals, 10*i) 213 c.Assert(data[2].GetInt64(), Equals, 100*i) 214 i++ 215 return true, nil 216 }) 217 c.Assert(err, IsNil) 218 c.Assert(i, Equals, int64(num)) 219 220 c.Assert(causet.FindDefCaus(t.DefCauss(), "c4"), IsNil) 221 222 job := testCreateDeferredCauset(c, ctx, d, s.dbInfo, tblInfo, "c4", &ast.DeferredCausetPosition{Tp: ast.DeferredCausetPositionAfter, RelativeDeferredCauset: &ast.DeferredCausetName{Name: perceptron.NewCIStr("c3")}}, 100) 223 testCheckJobDone(c, d, job, true) 224 225 t = testGetBlock(c, d, s.dbInfo.ID, tblInfo.ID) 226 c.Assert(causet.FindDefCaus(t.DefCauss(), "c4"), NotNil) 227 228 i = int64(0) 229 err = t.IterRecords(ctx, t.FirstKey(), t.DefCauss(), 230 func(_ ekv.Handle, data []types.Causet, defcaus []*causet.DeferredCauset) (bool, error) { 231 c.Assert(data, HasLen, 4) 232 c.Assert(data[0].GetInt64(), Equals, i) 233 c.Assert(data[1].GetInt64(), Equals, 10*i) 234 c.Assert(data[2].GetInt64(), Equals, 100*i) 235 c.Assert(data[3].GetInt64(), Equals, int64(100)) 236 i++ 237 return true, nil 238 }) 239 c.Assert(err, IsNil) 240 c.Assert(i, Equals, int64(num)) 241 242 h, err := t.AddRecord(ctx, types.MakeCausets(11, 12, 13, 14)) 243 c.Assert(err, IsNil) 244 err = ctx.NewTxn(context.Background()) 245 c.Assert(err, IsNil) 246 values, err := t.EventWithDefCauss(ctx, h, t.DefCauss()) 247 c.Assert(err, IsNil) 248 249 c.Assert(values, HasLen, 4) 250 c.Assert(values[3].GetInt64(), Equals, int64(14)) 251 252 job = testDropDeferredCauset(c, ctx, d, s.dbInfo, tblInfo, "c4", false) 253 testCheckJobDone(c, d, job, false) 254 255 t = testGetBlock(c, d, s.dbInfo.ID, tblInfo.ID) 256 values, err = t.EventWithDefCauss(ctx, h, t.DefCauss()) 257 c.Assert(err, IsNil) 258 259 c.Assert(values, HasLen, 3) 260 c.Assert(values[2].GetInt64(), Equals, int64(13)) 261 262 job = testCreateDeferredCauset(c, ctx, d, s.dbInfo, tblInfo, "c4", &ast.DeferredCausetPosition{Tp: ast.DeferredCausetPositionNone}, 111) 263 testCheckJobDone(c, d, job, true) 264 265 t = testGetBlock(c, d, s.dbInfo.ID, tblInfo.ID) 266 values, err = t.EventWithDefCauss(ctx, h, t.DefCauss()) 267 c.Assert(err, IsNil) 268 269 c.Assert(values, HasLen, 4) 270 c.Assert(values[3].GetInt64(), Equals, int64(111)) 271 272 job = testCreateDeferredCauset(c, ctx, d, s.dbInfo, tblInfo, "c5", &ast.DeferredCausetPosition{Tp: ast.DeferredCausetPositionNone}, 101) 273 testCheckJobDone(c, d, job, true) 274 275 t = testGetBlock(c, d, s.dbInfo.ID, tblInfo.ID) 276 values, err = t.EventWithDefCauss(ctx, h, t.DefCauss()) 277 c.Assert(err, IsNil) 278 279 c.Assert(values, HasLen, 5) 280 c.Assert(values[4].GetInt64(), Equals, int64(101)) 281 282 job = testCreateDeferredCauset(c, ctx, d, s.dbInfo, tblInfo, "c6", &ast.DeferredCausetPosition{Tp: ast.DeferredCausetPositionFirst}, 202) 283 testCheckJobDone(c, d, job, true) 284 285 t = testGetBlock(c, d, s.dbInfo.ID, tblInfo.ID) 286 defcaus := t.DefCauss() 287 c.Assert(defcaus, HasLen, 6) 288 c.Assert(defcaus[0].Offset, Equals, 0) 289 c.Assert(defcaus[0].Name.L, Equals, "c6") 290 c.Assert(defcaus[1].Offset, Equals, 1) 291 c.Assert(defcaus[1].Name.L, Equals, "c1") 292 c.Assert(defcaus[2].Offset, Equals, 2) 293 c.Assert(defcaus[2].Name.L, Equals, "c2") 294 c.Assert(defcaus[3].Offset, Equals, 3) 295 c.Assert(defcaus[3].Name.L, Equals, "c3") 296 c.Assert(defcaus[4].Offset, Equals, 4) 297 c.Assert(defcaus[4].Name.L, Equals, "c4") 298 c.Assert(defcaus[5].Offset, Equals, 5) 299 c.Assert(defcaus[5].Name.L, Equals, "c5") 300 301 values, err = t.EventWithDefCauss(ctx, h, defcaus) 302 c.Assert(err, IsNil) 303 304 c.Assert(values, HasLen, 6) 305 c.Assert(values[0].GetInt64(), Equals, int64(202)) 306 c.Assert(values[5].GetInt64(), Equals, int64(101)) 307 308 job = testDropDeferredCauset(c, ctx, d, s.dbInfo, tblInfo, "c2", false) 309 testCheckJobDone(c, d, job, false) 310 311 t = testGetBlock(c, d, s.dbInfo.ID, tblInfo.ID) 312 313 values, err = t.EventWithDefCauss(ctx, h, t.DefCauss()) 314 c.Assert(err, IsNil) 315 c.Assert(values, HasLen, 5) 316 c.Assert(values[0].GetInt64(), Equals, int64(202)) 317 c.Assert(values[4].GetInt64(), Equals, int64(101)) 318 319 job = testDropDeferredCauset(c, ctx, d, s.dbInfo, tblInfo, "c1", false) 320 testCheckJobDone(c, d, job, false) 321 322 job = testDropDeferredCauset(c, ctx, d, s.dbInfo, tblInfo, "c3", false) 323 testCheckJobDone(c, d, job, false) 324 325 job = testDropDeferredCauset(c, ctx, d, s.dbInfo, tblInfo, "c4", false) 326 testCheckJobDone(c, d, job, false) 327 328 job = testCreateIndex(c, ctx, d, s.dbInfo, tblInfo, false, "c5_idx", "c5") 329 testCheckJobDone(c, d, job, true) 330 331 job = testDropDeferredCauset(c, ctx, d, s.dbInfo, tblInfo, "c5", false) 332 testCheckJobDone(c, d, job, false) 333 334 testDropDeferredCauset(c, ctx, d, s.dbInfo, tblInfo, "c6", true) 335 336 testDropBlock(c, ctx, d, s.dbInfo, tblInfo) 337 } 338 339 func (s *testDeferredCausetSuite) checkDeferredCausetKVExist(ctx stochastikctx.Context, t causet.Block, handle ekv.Handle, defCaus *causet.DeferredCauset, defCausumnValue interface{}, isExist bool) error { 340 err := ctx.NewTxn(context.Background()) 341 if err != nil { 342 return errors.Trace(err) 343 } 344 defer func() { 345 if txn, err1 := ctx.Txn(true); err1 == nil { 346 txn.Commit(context.Background()) 347 } 348 }() 349 key := t.RecordKey(handle) 350 txn, err := ctx.Txn(true) 351 if err != nil { 352 return errors.Trace(err) 353 } 354 data, err := txn.Get(context.TODO(), key) 355 if !isExist { 356 if terror.ErrorEqual(err, ekv.ErrNotExist) { 357 return nil 358 } 359 } 360 if err != nil { 361 return errors.Trace(err) 362 } 363 defCausMap := make(map[int64]*types.FieldType) 364 defCausMap[defCaus.ID] = &defCaus.FieldType 365 rowMap, err := blockcodec.DecodeEventToCausetMap(data, defCausMap, ctx.GetStochastikVars().Location()) 366 if err != nil { 367 return errors.Trace(err) 368 } 369 val, ok := rowMap[defCaus.ID] 370 if isExist { 371 if !ok || val.GetValue() != defCausumnValue { 372 return errors.Errorf("%v is not equal to %v", val.GetValue(), defCausumnValue) 373 } 374 } else { 375 if ok { 376 return errors.Errorf("defCausumn value should not exists") 377 } 378 } 379 return nil 380 } 381 382 func (s *testDeferredCausetSuite) checkNoneDeferredCauset(ctx stochastikctx.Context, d *dbs, tblInfo *perceptron.BlockInfo, handle ekv.Handle, defCaus *causet.DeferredCauset, defCausumnValue interface{}) error { 383 t, err := testGetBlockWithError(d, s.dbInfo.ID, tblInfo.ID) 384 if err != nil { 385 return errors.Trace(err) 386 } 387 err = s.checkDeferredCausetKVExist(ctx, t, handle, defCaus, defCausumnValue, false) 388 if err != nil { 389 return errors.Trace(err) 390 } 391 err = s.testGetDeferredCauset(t, defCaus.Name.L, false) 392 if err != nil { 393 return errors.Trace(err) 394 } 395 return nil 396 } 397 398 func (s *testDeferredCausetSuite) checkDeleteOnlyDeferredCauset(ctx stochastikctx.Context, d *dbs, tblInfo *perceptron.BlockInfo, handle ekv.Handle, defCaus *causet.DeferredCauset, event []types.Causet, defCausumnValue interface{}) error { 399 t, err := testGetBlockWithError(d, s.dbInfo.ID, tblInfo.ID) 400 if err != nil { 401 return errors.Trace(err) 402 } 403 err = ctx.NewTxn(context.Background()) 404 if err != nil { 405 return errors.Trace(err) 406 } 407 i := int64(0) 408 err = t.IterRecords(ctx, t.FirstKey(), t.DefCauss(), func(_ ekv.Handle, data []types.Causet, defcaus []*causet.DeferredCauset) (bool, error) { 409 if !reflect.DeepEqual(data, event) { 410 return false, errors.Errorf("%v not equal to %v", data, event) 411 } 412 i++ 413 return true, nil 414 }) 415 if err != nil { 416 return errors.Trace(err) 417 } 418 if i != 1 { 419 return errors.Errorf("expect 1, got %v", i) 420 } 421 err = s.checkDeferredCausetKVExist(ctx, t, handle, defCaus, defCausumnValue, false) 422 if err != nil { 423 return errors.Trace(err) 424 } 425 // Test add a new event. 426 err = ctx.NewTxn(context.Background()) 427 if err != nil { 428 return errors.Trace(err) 429 } 430 431 newEvent := types.MakeCausets(int64(11), int64(22), int64(33)) 432 newHandle, err := t.AddRecord(ctx, newEvent) 433 if err != nil { 434 return errors.Trace(err) 435 } 436 err = ctx.NewTxn(context.Background()) 437 if err != nil { 438 return errors.Trace(err) 439 } 440 441 rows := [][]types.Causet{event, newEvent} 442 443 i = int64(0) 444 err = t.IterRecords(ctx, t.FirstKey(), t.DefCauss(), func(_ ekv.Handle, data []types.Causet, defcaus []*causet.DeferredCauset) (bool, error) { 445 if !reflect.DeepEqual(data, rows[i]) { 446 return false, errors.Errorf("%v not equal to %v", data, rows[i]) 447 } 448 i++ 449 return true, nil 450 }) 451 if err != nil { 452 return errors.Trace(err) 453 } 454 if i != 2 { 455 return errors.Errorf("expect 2, got %v", i) 456 } 457 458 err = s.checkDeferredCausetKVExist(ctx, t, handle, defCaus, defCausumnValue, false) 459 if err != nil { 460 return errors.Trace(err) 461 } 462 // Test remove a event. 463 err = ctx.NewTxn(context.Background()) 464 if err != nil { 465 return errors.Trace(err) 466 } 467 468 err = t.RemoveRecord(ctx, newHandle, newEvent) 469 if err != nil { 470 return errors.Trace(err) 471 } 472 err = ctx.NewTxn(context.Background()) 473 if err != nil { 474 return errors.Trace(err) 475 } 476 i = int64(0) 477 err = t.IterRecords(ctx, t.FirstKey(), t.DefCauss(), func(_ ekv.Handle, data []types.Causet, defcaus []*causet.DeferredCauset) (bool, error) { 478 i++ 479 return true, nil 480 }) 481 if err != nil { 482 return errors.Trace(err) 483 } 484 485 if i != 1 { 486 return errors.Errorf("expect 1, got %v", i) 487 } 488 err = s.checkDeferredCausetKVExist(ctx, t, newHandle, defCaus, defCausumnValue, false) 489 if err != nil { 490 return errors.Trace(err) 491 } 492 err = s.testGetDeferredCauset(t, defCaus.Name.L, false) 493 if err != nil { 494 return errors.Trace(err) 495 } 496 return nil 497 } 498 499 func (s *testDeferredCausetSuite) checkWriteOnlyDeferredCauset(ctx stochastikctx.Context, d *dbs, tblInfo *perceptron.BlockInfo, handle ekv.Handle, defCaus *causet.DeferredCauset, event []types.Causet, defCausumnValue interface{}) error { 500 t, err := testGetBlockWithError(d, s.dbInfo.ID, tblInfo.ID) 501 if err != nil { 502 return errors.Trace(err) 503 } 504 err = ctx.NewTxn(context.Background()) 505 if err != nil { 506 return errors.Trace(err) 507 } 508 509 i := int64(0) 510 err = t.IterRecords(ctx, t.FirstKey(), t.DefCauss(), func(_ ekv.Handle, data []types.Causet, defcaus []*causet.DeferredCauset) (bool, error) { 511 if !reflect.DeepEqual(data, event) { 512 return false, errors.Errorf("%v not equal to %v", data, event) 513 } 514 i++ 515 return true, nil 516 }) 517 if err != nil { 518 return errors.Trace(err) 519 } 520 if i != 1 { 521 return errors.Errorf("expect 1, got %v", i) 522 } 523 524 err = s.checkDeferredCausetKVExist(ctx, t, handle, defCaus, defCausumnValue, false) 525 if err != nil { 526 return errors.Trace(err) 527 } 528 529 // Test add a new event. 530 err = ctx.NewTxn(context.Background()) 531 if err != nil { 532 return errors.Trace(err) 533 } 534 535 newEvent := types.MakeCausets(int64(11), int64(22), int64(33)) 536 newHandle, err := t.AddRecord(ctx, newEvent) 537 if err != nil { 538 return errors.Trace(err) 539 } 540 err = ctx.NewTxn(context.Background()) 541 if err != nil { 542 return errors.Trace(err) 543 } 544 545 rows := [][]types.Causet{event, newEvent} 546 547 i = int64(0) 548 err = t.IterRecords(ctx, t.FirstKey(), t.DefCauss(), func(_ ekv.Handle, data []types.Causet, defcaus []*causet.DeferredCauset) (bool, error) { 549 if !reflect.DeepEqual(data, rows[i]) { 550 return false, errors.Errorf("%v not equal to %v", data, rows[i]) 551 } 552 i++ 553 return true, nil 554 }) 555 if err != nil { 556 return errors.Trace(err) 557 } 558 if i != 2 { 559 return errors.Errorf("expect 2, got %v", i) 560 } 561 562 err = s.checkDeferredCausetKVExist(ctx, t, newHandle, defCaus, defCausumnValue, true) 563 if err != nil { 564 return errors.Trace(err) 565 } 566 // Test remove a event. 567 err = ctx.NewTxn(context.Background()) 568 if err != nil { 569 return errors.Trace(err) 570 } 571 572 err = t.RemoveRecord(ctx, newHandle, newEvent) 573 if err != nil { 574 return errors.Trace(err) 575 } 576 err = ctx.NewTxn(context.Background()) 577 if err != nil { 578 return errors.Trace(err) 579 } 580 581 i = int64(0) 582 err = t.IterRecords(ctx, t.FirstKey(), t.DefCauss(), func(_ ekv.Handle, data []types.Causet, defcaus []*causet.DeferredCauset) (bool, error) { 583 i++ 584 return true, nil 585 }) 586 if err != nil { 587 return errors.Trace(err) 588 } 589 if i != 1 { 590 return errors.Errorf("expect 1, got %v", i) 591 } 592 593 err = s.checkDeferredCausetKVExist(ctx, t, newHandle, defCaus, defCausumnValue, false) 594 if err != nil { 595 return errors.Trace(err) 596 } 597 err = s.testGetDeferredCauset(t, defCaus.Name.L, false) 598 if err != nil { 599 return errors.Trace(err) 600 } 601 return nil 602 } 603 604 func (s *testDeferredCausetSuite) checkReorganizationDeferredCauset(ctx stochastikctx.Context, d *dbs, tblInfo *perceptron.BlockInfo, defCaus *causet.DeferredCauset, event []types.Causet, defCausumnValue interface{}) error { 605 t, err := testGetBlockWithError(d, s.dbInfo.ID, tblInfo.ID) 606 if err != nil { 607 return errors.Trace(err) 608 } 609 err = ctx.NewTxn(context.Background()) 610 if err != nil { 611 return errors.Trace(err) 612 } 613 614 i := int64(0) 615 err = t.IterRecords(ctx, t.FirstKey(), t.DefCauss(), func(_ ekv.Handle, data []types.Causet, defcaus []*causet.DeferredCauset) (bool, error) { 616 if !reflect.DeepEqual(data, event) { 617 return false, errors.Errorf("%v not equal to %v", data, event) 618 } 619 i++ 620 return true, nil 621 }) 622 if err != nil { 623 return errors.Trace(err) 624 } 625 if i != 1 { 626 return errors.Errorf("expect 1 got %v", i) 627 } 628 629 // Test add a new event. 630 err = ctx.NewTxn(context.Background()) 631 if err != nil { 632 return errors.Trace(err) 633 } 634 635 newEvent := types.MakeCausets(int64(11), int64(22), int64(33)) 636 newHandle, err := t.AddRecord(ctx, newEvent) 637 if err != nil { 638 return errors.Trace(err) 639 } 640 err = ctx.NewTxn(context.Background()) 641 if err != nil { 642 return errors.Trace(err) 643 } 644 645 rows := [][]types.Causet{event, newEvent} 646 647 i = int64(0) 648 err = t.IterRecords(ctx, t.FirstKey(), t.DefCauss(), func(_ ekv.Handle, data []types.Causet, defcaus []*causet.DeferredCauset) (bool, error) { 649 if !reflect.DeepEqual(data, rows[i]) { 650 return false, errors.Errorf("%v not equal to %v", data, rows[i]) 651 } 652 i++ 653 return true, nil 654 }) 655 if err != nil { 656 return errors.Trace(err) 657 } 658 if i != 2 { 659 return errors.Errorf("expect 2, got %v", i) 660 } 661 662 err = s.checkDeferredCausetKVExist(ctx, t, newHandle, defCaus, defCausumnValue, true) 663 if err != nil { 664 return errors.Trace(err) 665 } 666 667 // Test remove a event. 668 err = ctx.NewTxn(context.Background()) 669 if err != nil { 670 return errors.Trace(err) 671 } 672 673 err = t.RemoveRecord(ctx, newHandle, newEvent) 674 if err != nil { 675 return errors.Trace(err) 676 } 677 err = ctx.NewTxn(context.Background()) 678 if err != nil { 679 return errors.Trace(err) 680 } 681 682 i = int64(0) 683 err = t.IterRecords(ctx, t.FirstKey(), t.DefCauss(), func(_ ekv.Handle, data []types.Causet, defcaus []*causet.DeferredCauset) (bool, error) { 684 i++ 685 return true, nil 686 }) 687 if err != nil { 688 return errors.Trace(err) 689 } 690 if i != 1 { 691 return errors.Errorf("expect 1, got %v", i) 692 } 693 err = s.testGetDeferredCauset(t, defCaus.Name.L, false) 694 if err != nil { 695 return errors.Trace(err) 696 } 697 return nil 698 } 699 700 func (s *testDeferredCausetSuite) checkPublicDeferredCauset(ctx stochastikctx.Context, d *dbs, tblInfo *perceptron.BlockInfo, newDefCaus *causet.DeferredCauset, oldEvent []types.Causet, defCausumnValue interface{}) error { 701 t, err := testGetBlockWithError(d, s.dbInfo.ID, tblInfo.ID) 702 if err != nil { 703 return errors.Trace(err) 704 } 705 err = ctx.NewTxn(context.Background()) 706 if err != nil { 707 return errors.Trace(err) 708 } 709 710 i := int64(0) 711 uFIDelatedEvent := append(oldEvent, types.NewCauset(defCausumnValue)) 712 err = t.IterRecords(ctx, t.FirstKey(), t.DefCauss(), func(_ ekv.Handle, data []types.Causet, defcaus []*causet.DeferredCauset) (bool, error) { 713 if !reflect.DeepEqual(data, uFIDelatedEvent) { 714 return false, errors.Errorf("%v not equal to %v", data, uFIDelatedEvent) 715 } 716 i++ 717 return true, nil 718 }) 719 if err != nil { 720 return errors.Trace(err) 721 } 722 if i != 1 { 723 return errors.Errorf("expect 1, got %v", i) 724 } 725 726 // Test add a new event. 727 err = ctx.NewTxn(context.Background()) 728 if err != nil { 729 return errors.Trace(err) 730 } 731 732 newEvent := types.MakeCausets(int64(11), int64(22), int64(33), int64(44)) 733 handle, err := t.AddRecord(ctx, newEvent) 734 if err != nil { 735 return errors.Trace(err) 736 } 737 err = ctx.NewTxn(context.Background()) 738 if err != nil { 739 return errors.Trace(err) 740 } 741 742 rows := [][]types.Causet{uFIDelatedEvent, newEvent} 743 744 i = int64(0) 745 t.IterRecords(ctx, t.FirstKey(), t.DefCauss(), func(_ ekv.Handle, data []types.Causet, defcaus []*causet.DeferredCauset) (bool, error) { 746 if !reflect.DeepEqual(data, rows[i]) { 747 return false, errors.Errorf("%v not equal to %v", data, rows[i]) 748 } 749 i++ 750 return true, nil 751 }) 752 if i != 2 { 753 return errors.Errorf("expect 2, got %v", i) 754 } 755 756 // Test remove a event. 757 err = ctx.NewTxn(context.Background()) 758 if err != nil { 759 return errors.Trace(err) 760 } 761 762 err = t.RemoveRecord(ctx, handle, newEvent) 763 if err != nil { 764 return errors.Trace(err) 765 } 766 767 err = ctx.NewTxn(context.Background()) 768 if err != nil { 769 return errors.Trace(err) 770 } 771 772 i = int64(0) 773 err = t.IterRecords(ctx, t.FirstKey(), t.DefCauss(), func(_ ekv.Handle, data []types.Causet, defcaus []*causet.DeferredCauset) (bool, error) { 774 if !reflect.DeepEqual(data, uFIDelatedEvent) { 775 return false, errors.Errorf("%v not equal to %v", data, uFIDelatedEvent) 776 } 777 i++ 778 return true, nil 779 }) 780 if err != nil { 781 return errors.Trace(err) 782 } 783 if i != 1 { 784 return errors.Errorf("expect 1, got %v", i) 785 } 786 787 err = s.testGetDeferredCauset(t, newDefCaus.Name.L, true) 788 if err != nil { 789 return errors.Trace(err) 790 } 791 return nil 792 } 793 794 func (s *testDeferredCausetSuite) checkAddDeferredCauset(state perceptron.SchemaState, d *dbs, tblInfo *perceptron.BlockInfo, handle ekv.Handle, newDefCaus *causet.DeferredCauset, oldEvent []types.Causet, defCausumnValue interface{}) error { 795 ctx := testNewContext(d) 796 var err error 797 switch state { 798 case perceptron.StateNone: 799 err = errors.Trace(s.checkNoneDeferredCauset(ctx, d, tblInfo, handle, newDefCaus, defCausumnValue)) 800 case perceptron.StateDeleteOnly: 801 err = errors.Trace(s.checkDeleteOnlyDeferredCauset(ctx, d, tblInfo, handle, newDefCaus, oldEvent, defCausumnValue)) 802 case perceptron.StateWriteOnly: 803 err = errors.Trace(s.checkWriteOnlyDeferredCauset(ctx, d, tblInfo, handle, newDefCaus, oldEvent, defCausumnValue)) 804 case perceptron.StateWriteReorganization, perceptron.StateDeleteReorganization: 805 err = errors.Trace(s.checkReorganizationDeferredCauset(ctx, d, tblInfo, newDefCaus, oldEvent, defCausumnValue)) 806 case perceptron.StatePublic: 807 err = errors.Trace(s.checkPublicDeferredCauset(ctx, d, tblInfo, newDefCaus, oldEvent, defCausumnValue)) 808 } 809 return err 810 } 811 812 func (s *testDeferredCausetSuite) testGetDeferredCauset(t causet.Block, name string, isExist bool) error { 813 defCaus := causet.FindDefCaus(t.DefCauss(), name) 814 if isExist { 815 if defCaus == nil { 816 return errors.Errorf("defCausumn should not be nil") 817 } 818 } else { 819 if defCaus != nil { 820 return errors.Errorf("defCausumn should be nil") 821 } 822 } 823 return nil 824 } 825 826 func (s *testDeferredCausetSuite) TestAddDeferredCauset(c *C) { 827 d := testNewDBSAndStart( 828 context.Background(), 829 c, 830 WithStore(s.causetstore), 831 WithLease(testLease), 832 ) 833 tblInfo := testBlockInfo(c, d, "t", 3) 834 ctx := testNewContext(d) 835 836 err := ctx.NewTxn(context.Background()) 837 c.Assert(err, IsNil) 838 839 testCreateBlock(c, ctx, d, s.dbInfo, tblInfo) 840 t := testGetBlock(c, d, s.dbInfo.ID, tblInfo.ID) 841 842 oldEvent := types.MakeCausets(int64(1), int64(2), int64(3)) 843 handle, err := t.AddRecord(ctx, oldEvent) 844 c.Assert(err, IsNil) 845 846 txn, err := ctx.Txn(true) 847 c.Assert(err, IsNil) 848 err = txn.Commit(context.Background()) 849 c.Assert(err, IsNil) 850 851 newDefCausName := "c4" 852 defaultDefCausValue := int64(4) 853 854 var mu sync.Mutex 855 var hookErr error 856 checkOK := false 857 858 tc := &TestDBSCallback{} 859 tc.onJobUFIDelated = func(job *perceptron.Job) { 860 mu.Lock() 861 defer mu.Unlock() 862 if checkOK { 863 return 864 } 865 866 t, err1 := testGetBlockWithError(d, s.dbInfo.ID, tblInfo.ID) 867 if err1 != nil { 868 hookErr = errors.Trace(err1) 869 return 870 } 871 newDefCaus := causet.FindDefCaus(t.(*blocks.BlockCommon).DeferredCausets, newDefCausName) 872 if newDefCaus == nil { 873 return 874 } 875 876 err1 = s.checkAddDeferredCauset(newDefCaus.State, d, tblInfo, handle, newDefCaus, oldEvent, defaultDefCausValue) 877 if err1 != nil { 878 hookErr = errors.Trace(err1) 879 return 880 } 881 882 if newDefCaus.State == perceptron.StatePublic { 883 checkOK = true 884 } 885 } 886 887 d.SetHook(tc) 888 889 job := testCreateDeferredCauset(c, ctx, d, s.dbInfo, tblInfo, newDefCausName, &ast.DeferredCausetPosition{Tp: ast.DeferredCausetPositionNone}, defaultDefCausValue) 890 891 testCheckJobDone(c, d, job, true) 892 mu.Lock() 893 hErr := hookErr 894 ok := checkOK 895 mu.Unlock() 896 c.Assert(errors.ErrorStack(hErr), Equals, "") 897 c.Assert(ok, IsTrue) 898 899 err = ctx.NewTxn(context.Background()) 900 c.Assert(err, IsNil) 901 902 job = testDropBlock(c, ctx, d, s.dbInfo, tblInfo) 903 testCheckJobDone(c, d, job, false) 904 905 txn, err = ctx.Txn(true) 906 c.Assert(err, IsNil) 907 err = txn.Commit(context.Background()) 908 c.Assert(err, IsNil) 909 910 d.Stop() 911 } 912 913 func (s *testDeferredCausetSuite) TestAddDeferredCausets(c *C) { 914 d := testNewDBSAndStart( 915 context.Background(), 916 c, 917 WithStore(s.causetstore), 918 WithLease(testLease), 919 ) 920 tblInfo := testBlockInfo(c, d, "t", 3) 921 ctx := testNewContext(d) 922 923 err := ctx.NewTxn(context.Background()) 924 c.Assert(err, IsNil) 925 926 testCreateBlock(c, ctx, d, s.dbInfo, tblInfo) 927 t := testGetBlock(c, d, s.dbInfo.ID, tblInfo.ID) 928 929 oldEvent := types.MakeCausets(int64(1), int64(2), int64(3)) 930 handle, err := t.AddRecord(ctx, oldEvent) 931 c.Assert(err, IsNil) 932 933 txn, err := ctx.Txn(true) 934 c.Assert(err, IsNil) 935 err = txn.Commit(context.Background()) 936 c.Assert(err, IsNil) 937 938 newDefCausNames := []string{"c4,c5,c6"} 939 positions := make([]*ast.DeferredCausetPosition, 3) 940 for i := range positions { 941 positions[i] = &ast.DeferredCausetPosition{Tp: ast.DeferredCausetPositionNone} 942 } 943 defaultDefCausValue := int64(4) 944 945 var mu sync.Mutex 946 var hookErr error 947 checkOK := false 948 949 tc := &TestDBSCallback{} 950 tc.onJobUFIDelated = func(job *perceptron.Job) { 951 mu.Lock() 952 defer mu.Unlock() 953 if checkOK { 954 return 955 } 956 957 t, err1 := testGetBlockWithError(d, s.dbInfo.ID, tblInfo.ID) 958 if err1 != nil { 959 hookErr = errors.Trace(err1) 960 return 961 } 962 for _, newDefCausName := range newDefCausNames { 963 newDefCaus := causet.FindDefCaus(t.(*blocks.BlockCommon).DeferredCausets, newDefCausName) 964 if newDefCaus == nil { 965 return 966 } 967 968 err1 = s.checkAddDeferredCauset(newDefCaus.State, d, tblInfo, handle, newDefCaus, oldEvent, defaultDefCausValue) 969 if err1 != nil { 970 hookErr = errors.Trace(err1) 971 return 972 } 973 974 if newDefCaus.State == perceptron.StatePublic { 975 checkOK = true 976 } 977 } 978 } 979 980 d.SetHook(tc) 981 982 job := testCreateDeferredCausets(c, ctx, d, s.dbInfo, tblInfo, newDefCausNames, positions, defaultDefCausValue) 983 984 testCheckJobDone(c, d, job, true) 985 mu.Lock() 986 hErr := hookErr 987 ok := checkOK 988 mu.Unlock() 989 c.Assert(errors.ErrorStack(hErr), Equals, "") 990 c.Assert(ok, IsTrue) 991 992 job = testDropBlock(c, ctx, d, s.dbInfo, tblInfo) 993 testCheckJobDone(c, d, job, false) 994 d.Stop() 995 } 996 997 func (s *testDeferredCausetSuite) TestDropDeferredCauset(c *C) { 998 d := testNewDBSAndStart( 999 context.Background(), 1000 c, 1001 WithStore(s.causetstore), 1002 WithLease(testLease), 1003 ) 1004 tblInfo := testBlockInfo(c, d, "t2", 4) 1005 ctx := testNewContext(d) 1006 1007 err := ctx.NewTxn(context.Background()) 1008 c.Assert(err, IsNil) 1009 1010 testCreateBlock(c, ctx, d, s.dbInfo, tblInfo) 1011 t := testGetBlock(c, d, s.dbInfo.ID, tblInfo.ID) 1012 1013 defCausName := "c4" 1014 defaultDefCausValue := int64(4) 1015 event := types.MakeCausets(int64(1), int64(2), int64(3)) 1016 _, err = t.AddRecord(ctx, append(event, types.NewCauset(defaultDefCausValue))) 1017 c.Assert(err, IsNil) 1018 1019 txn, err := ctx.Txn(true) 1020 c.Assert(err, IsNil) 1021 err = txn.Commit(context.Background()) 1022 c.Assert(err, IsNil) 1023 1024 checkOK := false 1025 var hookErr error 1026 var mu sync.Mutex 1027 1028 tc := &TestDBSCallback{} 1029 tc.onJobUFIDelated = func(job *perceptron.Job) { 1030 mu.Lock() 1031 defer mu.Unlock() 1032 if checkOK { 1033 return 1034 } 1035 t, err1 := testGetBlockWithError(d, s.dbInfo.ID, tblInfo.ID) 1036 if err1 != nil { 1037 hookErr = errors.Trace(err1) 1038 return 1039 } 1040 defCaus := causet.FindDefCaus(t.(*blocks.BlockCommon).DeferredCausets, defCausName) 1041 if defCaus == nil { 1042 checkOK = true 1043 return 1044 } 1045 } 1046 1047 d.SetHook(tc) 1048 1049 job := testDropDeferredCauset(c, ctx, d, s.dbInfo, tblInfo, defCausName, false) 1050 testCheckJobDone(c, d, job, false) 1051 mu.Lock() 1052 hErr := hookErr 1053 ok := checkOK 1054 mu.Unlock() 1055 c.Assert(hErr, IsNil) 1056 c.Assert(ok, IsTrue) 1057 1058 err = ctx.NewTxn(context.Background()) 1059 c.Assert(err, IsNil) 1060 1061 job = testDropBlock(c, ctx, d, s.dbInfo, tblInfo) 1062 testCheckJobDone(c, d, job, false) 1063 1064 txn, err = ctx.Txn(true) 1065 c.Assert(err, IsNil) 1066 err = txn.Commit(context.Background()) 1067 c.Assert(err, IsNil) 1068 1069 d.Stop() 1070 } 1071 1072 func (s *testDeferredCausetSuite) TestDropDeferredCausets(c *C) { 1073 d := testNewDBSAndStart( 1074 context.Background(), 1075 c, 1076 WithStore(s.causetstore), 1077 WithLease(testLease), 1078 ) 1079 tblInfo := testBlockInfo(c, d, "t2", 4) 1080 ctx := testNewContext(d) 1081 1082 err := ctx.NewTxn(context.Background()) 1083 c.Assert(err, IsNil) 1084 1085 testCreateBlock(c, ctx, d, s.dbInfo, tblInfo) 1086 t := testGetBlock(c, d, s.dbInfo.ID, tblInfo.ID) 1087 1088 defCausNames := []string{"c3", "c4"} 1089 defaultDefCausValue := int64(4) 1090 event := types.MakeCausets(int64(1), int64(2), int64(3)) 1091 _, err = t.AddRecord(ctx, append(event, types.NewCauset(defaultDefCausValue))) 1092 c.Assert(err, IsNil) 1093 1094 txn, err := ctx.Txn(true) 1095 c.Assert(err, IsNil) 1096 err = txn.Commit(context.Background()) 1097 c.Assert(err, IsNil) 1098 1099 checkOK := false 1100 var hookErr error 1101 var mu sync.Mutex 1102 1103 tc := &TestDBSCallback{} 1104 tc.onJobUFIDelated = func(job *perceptron.Job) { 1105 mu.Lock() 1106 defer mu.Unlock() 1107 if checkOK { 1108 return 1109 } 1110 t, err1 := testGetBlockWithError(d, s.dbInfo.ID, tblInfo.ID) 1111 if err1 != nil { 1112 hookErr = errors.Trace(err1) 1113 return 1114 } 1115 for _, defCausName := range defCausNames { 1116 defCaus := causet.FindDefCaus(t.(*blocks.BlockCommon).DeferredCausets, defCausName) 1117 if defCaus == nil { 1118 checkOK = true 1119 return 1120 } 1121 } 1122 } 1123 1124 d.SetHook(tc) 1125 1126 job := testDropDeferredCausets(c, ctx, d, s.dbInfo, tblInfo, defCausNames, false) 1127 testCheckJobDone(c, d, job, false) 1128 mu.Lock() 1129 hErr := hookErr 1130 ok := checkOK 1131 mu.Unlock() 1132 c.Assert(hErr, IsNil) 1133 c.Assert(ok, IsTrue) 1134 1135 job = testDropBlock(c, ctx, d, s.dbInfo, tblInfo) 1136 testCheckJobDone(c, d, job, false) 1137 d.Stop() 1138 } 1139 1140 func (s *testDeferredCausetSuite) TestModifyDeferredCauset(c *C) { 1141 d := testNewDBSAndStart( 1142 context.Background(), 1143 c, 1144 WithStore(s.causetstore), 1145 WithLease(testLease), 1146 ) 1147 ctx := testNewContext(d) 1148 defer d.Stop() 1149 tests := []struct { 1150 origin string 1151 to string 1152 err error 1153 }{ 1154 {"int", "bigint", nil}, 1155 {"int", "int unsigned", errUnsupportedModifyDeferredCauset.GenWithStackByArgs("length 10 is less than origin 11, and milevadb_enable_change_defCausumn_type is false")}, 1156 {"varchar(10)", "text", nil}, 1157 {"varbinary(10)", "blob", nil}, 1158 {"text", "blob", errUnsupportedModifyCharset.GenWithStackByArgs("charset from utf8mb4 to binary")}, 1159 {"varchar(10)", "varchar(8)", errUnsupportedModifyDeferredCauset.GenWithStackByArgs("length 8 is less than origin 10")}, 1160 {"varchar(10)", "varchar(11)", nil}, 1161 {"varchar(10) character set utf8 defCauslate utf8_bin", "varchar(10) character set utf8", nil}, 1162 {"decimal(2,1)", "decimal(3,2)", errUnsupportedModifyDeferredCauset.GenWithStackByArgs("can't change decimal defCausumn precision")}, 1163 {"decimal(2,1)", "decimal(2,2)", errUnsupportedModifyDeferredCauset.GenWithStackByArgs("can't change decimal defCausumn precision")}, 1164 {"decimal(2,1)", "decimal(2,1)", nil}, 1165 {"decimal(2,1)", "int", errUnsupportedModifyDeferredCauset.GenWithStackByArgs("type int(11) not match origin decimal(2,1)")}, 1166 {"decimal", "int", errUnsupportedModifyDeferredCauset.GenWithStackByArgs("type int(11) not match origin decimal(11,0)")}, 1167 {"decimal(2,1)", "bigint", errUnsupportedModifyDeferredCauset.GenWithStackByArgs("type bigint(20) not match origin decimal(2,1)")}, 1168 } 1169 for _, tt := range tests { 1170 ftA := s.defCausDefStrToFieldType(c, tt.origin) 1171 ftB := s.defCausDefStrToFieldType(c, tt.to) 1172 err := checkModifyTypes(ctx, ftA, ftB, false) 1173 if err == nil { 1174 c.Assert(tt.err, IsNil, Commentf("origin:%v, to:%v", tt.origin, tt.to)) 1175 } else { 1176 c.Assert(err.Error(), Equals, tt.err.Error()) 1177 } 1178 } 1179 } 1180 1181 func (s *testDeferredCausetSuite) defCausDefStrToFieldType(c *C, str string) *types.FieldType { 1182 sqlA := "alter causet t modify defCausumn a " + str 1183 stmt, err := BerolinaSQL.New().ParseOneStmt(sqlA, "", "") 1184 c.Assert(err, IsNil) 1185 defCausDef := stmt.(*ast.AlterBlockStmt).Specs[0].NewDeferredCausets[0] 1186 chs, defCausl := charset.GetDefaultCharsetAndDefCauslate() 1187 defCaus, _, err := buildDeferredCausetAndConstraint(nil, 0, defCausDef, nil, chs, defCausl) 1188 c.Assert(err, IsNil) 1189 return &defCaus.FieldType 1190 } 1191 1192 func (s *testDeferredCausetSuite) TestFieldCase(c *C) { 1193 var fields = []string{"field", "Field"} 1194 defCausObjects := make([]*perceptron.DeferredCausetInfo, len(fields)) 1195 for i, name := range fields { 1196 defCausObjects[i] = &perceptron.DeferredCausetInfo{ 1197 Name: perceptron.NewCIStr(name), 1198 } 1199 } 1200 err := checkDuplicateDeferredCauset(defCausObjects) 1201 c.Assert(err.Error(), Equals, schemareplicant.ErrDeferredCausetExists.GenWithStackByArgs("Field").Error()) 1202 }