github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/pingcap/tidb/ddl/column_test.go (about) 1 // Copyright 2015 PingCAP, 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 ddl 15 16 import ( 17 "time" 18 19 . "github.com/insionng/yougam/libraries/pingcap/check" 20 "github.com/insionng/yougam/libraries/pingcap/tidb/ast" 21 "github.com/insionng/yougam/libraries/pingcap/tidb/column" 22 "github.com/insionng/yougam/libraries/pingcap/tidb/context" 23 "github.com/insionng/yougam/libraries/pingcap/tidb/kv" 24 "github.com/insionng/yougam/libraries/pingcap/tidb/model" 25 "github.com/insionng/yougam/libraries/pingcap/tidb/mysql" 26 "github.com/insionng/yougam/libraries/pingcap/tidb/table" 27 "github.com/insionng/yougam/libraries/pingcap/tidb/table/tables" 28 "github.com/insionng/yougam/libraries/pingcap/tidb/util/mock" 29 "github.com/insionng/yougam/libraries/pingcap/tidb/util/testleak" 30 "github.com/insionng/yougam/libraries/pingcap/tidb/util/types" 31 ) 32 33 var _ = Suite(&testColumnSuite{}) 34 35 type testColumnSuite struct { 36 store kv.Storage 37 dbInfo *model.DBInfo 38 39 d *ddl 40 } 41 42 func (s *testColumnSuite) SetUpSuite(c *C) { 43 trySkipTest(c) 44 45 s.store = testCreateStore(c, "test_column") 46 lease := 50 * time.Millisecond 47 s.d = newDDL(s.store, nil, nil, lease) 48 49 s.dbInfo = testSchemaInfo(c, s.d, "test_column") 50 testCreateSchema(c, mock.NewContext(), s.d, s.dbInfo) 51 } 52 53 func (s *testColumnSuite) TearDownSuite(c *C) { 54 trySkipTest(c) 55 56 testDropSchema(c, mock.NewContext(), s.d, s.dbInfo) 57 s.d.close() 58 59 err := s.store.Close() 60 c.Assert(err, IsNil) 61 } 62 63 func testCreateColumn(c *C, ctx context.Context, d *ddl, dbInfo *model.DBInfo, tblInfo *model.TableInfo, 64 colName string, pos *ast.ColumnPosition, defaultValue interface{}) *model.Job { 65 col := &model.ColumnInfo{ 66 Name: model.NewCIStr(colName), 67 Offset: len(tblInfo.Columns), 68 DefaultValue: defaultValue, 69 } 70 71 var err error 72 col.ID, err = d.genGlobalID() 73 c.Assert(err, IsNil) 74 75 col.FieldType = *types.NewFieldType(mysql.TypeLong) 76 77 job := &model.Job{ 78 SchemaID: dbInfo.ID, 79 TableID: tblInfo.ID, 80 Type: model.ActionAddColumn, 81 Args: []interface{}{col, pos, 0}, 82 } 83 84 err = d.doDDLJob(ctx, job) 85 c.Assert(err, IsNil) 86 return job 87 } 88 89 func testDropColumn(c *C, ctx context.Context, d *ddl, dbInfo *model.DBInfo, tblInfo *model.TableInfo, colName string, isError bool) *model.Job { 90 job := &model.Job{ 91 SchemaID: dbInfo.ID, 92 TableID: tblInfo.ID, 93 Type: model.ActionDropColumn, 94 Args: []interface{}{model.NewCIStr(colName)}, 95 } 96 97 err := d.doDDLJob(ctx, job) 98 if isError { 99 c.Assert(err, NotNil) 100 return nil 101 } 102 103 c.Assert(err, IsNil) 104 return job 105 } 106 107 func (s *testColumnSuite) TestColumn(c *C) { 108 defer testleak.AfterTest(c)() 109 tblInfo := testTableInfo(c, s.d, "t1", 3) 110 ctx := testNewContext(c, s.d) 111 defer ctx.FinishTxn(true) 112 113 testCreateTable(c, ctx, s.d, s.dbInfo, tblInfo) 114 115 t := testGetTable(c, s.d, s.dbInfo.ID, tblInfo.ID) 116 117 num := 10 118 for i := 0; i < num; i++ { 119 _, err := t.AddRecord(ctx, types.MakeDatums(i, 10*i, 100*i)) 120 c.Assert(err, IsNil) 121 } 122 123 err := ctx.FinishTxn(false) 124 c.Assert(err, IsNil) 125 126 i := int64(0) 127 t.IterRecords(ctx, t.FirstKey(), t.Cols(), func(h int64, data []types.Datum, cols []*column.Col) (bool, error) { 128 c.Assert(data, HasLen, 3) 129 c.Assert(data[0].GetInt64(), Equals, i) 130 c.Assert(data[1].GetInt64(), Equals, 10*i) 131 c.Assert(data[2].GetInt64(), Equals, 100*i) 132 i++ 133 return true, nil 134 }) 135 c.Assert(i, Equals, int64(num)) 136 137 c.Assert(column.FindCol(t.Cols(), "c4"), IsNil) 138 139 job := testCreateColumn(c, ctx, s.d, s.dbInfo, tblInfo, "c4", &ast.ColumnPosition{Tp: ast.ColumnPositionAfter, RelativeColumn: &ast.ColumnName{Name: model.NewCIStr("c3")}}, 100) 140 testCheckJobDone(c, s.d, job, true) 141 142 t = testGetTable(c, s.d, s.dbInfo.ID, tblInfo.ID) 143 c.Assert(column.FindCol(t.Cols(), "c4"), NotNil) 144 145 i = int64(0) 146 t.IterRecords(ctx, t.FirstKey(), t.Cols(), func(h int64, data []types.Datum, cols []*column.Col) (bool, error) { 147 c.Assert(data, HasLen, 4) 148 c.Assert(data[0].GetInt64(), Equals, i) 149 c.Assert(data[1].GetInt64(), Equals, 10*i) 150 c.Assert(data[2].GetInt64(), Equals, 100*i) 151 c.Assert(data[3].GetInt64(), Equals, int64(100)) 152 i++ 153 return true, nil 154 }) 155 c.Assert(i, Equals, int64(num)) 156 157 h, err := t.AddRecord(ctx, types.MakeDatums(11, 12, 13, 14)) 158 c.Assert(err, IsNil) 159 err = ctx.FinishTxn(false) 160 c.Assert(err, IsNil) 161 values, err := t.RowWithCols(ctx, h, t.Cols()) 162 c.Assert(err, IsNil) 163 164 c.Assert(values, HasLen, 4) 165 c.Assert(values[3].GetInt64(), Equals, int64(14)) 166 167 job = testDropColumn(c, ctx, s.d, s.dbInfo, tblInfo, "c4", false) 168 testCheckJobDone(c, s.d, job, false) 169 170 t = testGetTable(c, s.d, s.dbInfo.ID, tblInfo.ID) 171 values, err = t.RowWithCols(ctx, h, t.Cols()) 172 c.Assert(err, IsNil) 173 174 c.Assert(values, HasLen, 3) 175 c.Assert(values[2].GetInt64(), Equals, int64(13)) 176 177 job = testCreateColumn(c, ctx, s.d, s.dbInfo, tblInfo, "c4", &ast.ColumnPosition{Tp: ast.ColumnPositionNone}, 111) 178 testCheckJobDone(c, s.d, job, true) 179 180 t = testGetTable(c, s.d, s.dbInfo.ID, tblInfo.ID) 181 values, err = t.RowWithCols(ctx, h, t.Cols()) 182 c.Assert(err, IsNil) 183 184 c.Assert(values, HasLen, 4) 185 c.Assert(values[3].GetInt64(), Equals, int64(111)) 186 187 job = testCreateColumn(c, ctx, s.d, s.dbInfo, tblInfo, "c5", &ast.ColumnPosition{Tp: ast.ColumnPositionNone}, 101) 188 testCheckJobDone(c, s.d, job, true) 189 190 t = testGetTable(c, s.d, s.dbInfo.ID, tblInfo.ID) 191 values, err = t.RowWithCols(ctx, h, t.Cols()) 192 c.Assert(err, IsNil) 193 194 c.Assert(values, HasLen, 5) 195 c.Assert(values[4].GetInt64(), Equals, int64(101)) 196 197 job = testCreateColumn(c, ctx, s.d, s.dbInfo, tblInfo, "c6", &ast.ColumnPosition{Tp: ast.ColumnPositionFirst}, 202) 198 testCheckJobDone(c, s.d, job, true) 199 200 t = testGetTable(c, s.d, s.dbInfo.ID, tblInfo.ID) 201 cols := t.Cols() 202 c.Assert(cols, HasLen, 6) 203 c.Assert(cols[0].Offset, Equals, 0) 204 c.Assert(cols[0].Name.L, Equals, "c6") 205 c.Assert(cols[1].Offset, Equals, 1) 206 c.Assert(cols[1].Name.L, Equals, "c1") 207 c.Assert(cols[2].Offset, Equals, 2) 208 c.Assert(cols[2].Name.L, Equals, "c2") 209 c.Assert(cols[3].Offset, Equals, 3) 210 c.Assert(cols[3].Name.L, Equals, "c3") 211 c.Assert(cols[4].Offset, Equals, 4) 212 c.Assert(cols[4].Name.L, Equals, "c4") 213 c.Assert(cols[5].Offset, Equals, 5) 214 c.Assert(cols[5].Name.L, Equals, "c5") 215 216 values, err = t.RowWithCols(ctx, h, cols) 217 c.Assert(err, IsNil) 218 219 c.Assert(values, HasLen, 6) 220 c.Assert(values[0].GetInt64(), Equals, int64(202)) 221 c.Assert(values[5].GetInt64(), Equals, int64(101)) 222 223 job = testDropColumn(c, ctx, s.d, s.dbInfo, tblInfo, "c2", false) 224 testCheckJobDone(c, s.d, job, false) 225 226 t = testGetTable(c, s.d, s.dbInfo.ID, tblInfo.ID) 227 228 values, err = t.RowWithCols(ctx, h, t.Cols()) 229 c.Assert(err, IsNil) 230 231 c.Assert(values, HasLen, 5) 232 c.Assert(values[0].GetInt64(), Equals, int64(202)) 233 c.Assert(values[4].GetInt64(), Equals, int64(101)) 234 235 job = testDropColumn(c, ctx, s.d, s.dbInfo, tblInfo, "c1", false) 236 testCheckJobDone(c, s.d, job, false) 237 238 job = testDropColumn(c, ctx, s.d, s.dbInfo, tblInfo, "c3", false) 239 testCheckJobDone(c, s.d, job, false) 240 241 job = testDropColumn(c, ctx, s.d, s.dbInfo, tblInfo, "c4", false) 242 testCheckJobDone(c, s.d, job, false) 243 244 job = testCreateIndex(c, ctx, s.d, s.dbInfo, tblInfo, false, "c5_idx", "c5") 245 testCheckJobDone(c, s.d, job, true) 246 247 testDropColumn(c, ctx, s.d, s.dbInfo, tblInfo, "c5", true) 248 249 testDropIndex(c, ctx, s.d, s.dbInfo, tblInfo, "c5_idx") 250 testCheckJobDone(c, s.d, job, true) 251 252 job = testDropColumn(c, ctx, s.d, s.dbInfo, tblInfo, "c5", false) 253 testCheckJobDone(c, s.d, job, false) 254 255 testDropColumn(c, ctx, s.d, s.dbInfo, tblInfo, "c6", true) 256 257 testDropTable(c, ctx, s.d, s.dbInfo, tblInfo) 258 } 259 260 func (s *testColumnSuite) checkColumnKVExist(c *C, ctx context.Context, t table.Table, handle int64, col *column.Col, columnValue interface{}, isExist bool) { 261 txn, err := ctx.GetTxn(true) 262 c.Assert(err, IsNil) 263 264 key := t.RecordKey(handle, col) 265 data, err := txn.Get(key) 266 267 if isExist { 268 c.Assert(err, IsNil) 269 v, err1 := tables.DecodeValue(data, &col.FieldType) 270 c.Assert(err1, IsNil) 271 value, err1 := v.ConvertTo(&col.FieldType) 272 c.Assert(err1, IsNil) 273 c.Assert(value.GetValue(), Equals, columnValue) 274 } else { 275 c.Assert(err, NotNil) 276 } 277 278 err = ctx.FinishTxn(false) 279 c.Assert(err, IsNil) 280 } 281 282 func (s *testColumnSuite) checkNoneColumn(c *C, ctx context.Context, d *ddl, tblInfo *model.TableInfo, handle int64, col *column.Col, columnValue interface{}) { 283 t := testGetTable(c, d, s.dbInfo.ID, tblInfo.ID) 284 s.checkColumnKVExist(c, ctx, t, handle, col, columnValue, false) 285 s.testGetColumn(c, t, col.Name.L, false) 286 } 287 288 func (s *testColumnSuite) checkDeleteOnlyColumn(c *C, ctx context.Context, d *ddl, tblInfo *model.TableInfo, handle int64, col *column.Col, row []types.Datum, columnValue interface{}, isDropped bool) { 289 t := testGetTable(c, d, s.dbInfo.ID, tblInfo.ID) 290 291 _, err := ctx.GetTxn(true) 292 c.Assert(err, IsNil) 293 294 i := int64(0) 295 err = t.IterRecords(ctx, t.FirstKey(), t.Cols(), func(h int64, data []types.Datum, cols []*column.Col) (bool, error) { 296 c.Assert(data, DeepEquals, row) 297 i++ 298 return true, nil 299 }) 300 c.Assert(err, IsNil) 301 c.Assert(i, Equals, int64(1)) 302 303 s.checkColumnKVExist(c, ctx, t, handle, col, columnValue, isDropped) 304 305 // Test add a new row. 306 _, err = ctx.GetTxn(true) 307 c.Assert(err, IsNil) 308 309 newRow := types.MakeDatums(int64(11), int64(22), int64(33)) 310 handle, err = t.AddRecord(ctx, newRow) 311 c.Assert(err, IsNil) 312 313 _, err = ctx.GetTxn(true) 314 c.Assert(err, IsNil) 315 316 rows := [][]types.Datum{row, newRow} 317 318 i = int64(0) 319 t.IterRecords(ctx, t.FirstKey(), t.Cols(), func(h int64, data []types.Datum, cols []*column.Col) (bool, error) { 320 c.Assert(data, DeepEquals, rows[i]) 321 i++ 322 return true, nil 323 }) 324 c.Assert(i, Equals, int64(2)) 325 326 s.checkColumnKVExist(c, ctx, t, handle, col, columnValue, false) 327 328 // Test remove a row. 329 _, err = ctx.GetTxn(true) 330 c.Assert(err, IsNil) 331 332 err = t.RemoveRecord(ctx, handle, newRow) 333 c.Assert(err, IsNil) 334 335 _, err = ctx.GetTxn(true) 336 c.Assert(err, IsNil) 337 338 i = int64(0) 339 t.IterRecords(ctx, t.FirstKey(), t.Cols(), func(h int64, data []types.Datum, cols []*column.Col) (bool, error) { 340 i++ 341 return true, nil 342 }) 343 c.Assert(i, Equals, int64(1)) 344 345 s.checkColumnKVExist(c, ctx, t, handle, col, columnValue, false) 346 s.testGetColumn(c, t, col.Name.L, false) 347 } 348 349 func (s *testColumnSuite) checkWriteOnlyColumn(c *C, ctx context.Context, d *ddl, tblInfo *model.TableInfo, handle int64, col *column.Col, row []types.Datum, columnValue interface{}, isDropped bool) { 350 t := testGetTable(c, d, s.dbInfo.ID, tblInfo.ID) 351 352 _, err := ctx.GetTxn(true) 353 c.Assert(err, IsNil) 354 355 i := int64(0) 356 err = t.IterRecords(ctx, t.FirstKey(), t.Cols(), func(h int64, data []types.Datum, cols []*column.Col) (bool, error) { 357 c.Assert(data, DeepEquals, row) 358 i++ 359 return true, nil 360 }) 361 c.Assert(err, IsNil) 362 c.Assert(i, Equals, int64(1)) 363 364 s.checkColumnKVExist(c, ctx, t, handle, col, columnValue, isDropped) 365 366 // Test add a new row. 367 _, err = ctx.GetTxn(true) 368 c.Assert(err, IsNil) 369 370 newRow := types.MakeDatums(int64(11), int64(22), int64(33)) 371 handle, err = t.AddRecord(ctx, newRow) 372 c.Assert(err, IsNil) 373 374 _, err = ctx.GetTxn(true) 375 c.Assert(err, IsNil) 376 377 rows := [][]types.Datum{row, newRow} 378 379 i = int64(0) 380 t.IterRecords(ctx, t.FirstKey(), t.Cols(), func(h int64, data []types.Datum, cols []*column.Col) (bool, error) { 381 c.Assert(data, DeepEquals, rows[i]) 382 i++ 383 return true, nil 384 }) 385 c.Assert(i, Equals, int64(2)) 386 387 s.checkColumnKVExist(c, ctx, t, handle, col, columnValue, true) 388 389 // Test remove a row. 390 _, err = ctx.GetTxn(true) 391 c.Assert(err, IsNil) 392 393 err = t.RemoveRecord(ctx, handle, newRow) 394 c.Assert(err, IsNil) 395 396 _, err = ctx.GetTxn(true) 397 c.Assert(err, IsNil) 398 399 i = int64(0) 400 t.IterRecords(ctx, t.FirstKey(), t.Cols(), func(h int64, data []types.Datum, cols []*column.Col) (bool, error) { 401 i++ 402 return true, nil 403 }) 404 c.Assert(i, Equals, int64(1)) 405 406 s.checkColumnKVExist(c, ctx, t, handle, col, columnValue, false) 407 s.testGetColumn(c, t, col.Name.L, false) 408 } 409 410 func (s *testColumnSuite) checkReorganizationColumn(c *C, ctx context.Context, d *ddl, tblInfo *model.TableInfo, handle int64, col *column.Col, row []types.Datum, columnValue interface{}, isDropped bool) { 411 t := testGetTable(c, d, s.dbInfo.ID, tblInfo.ID) 412 413 _, err := ctx.GetTxn(true) 414 c.Assert(err, IsNil) 415 416 i := int64(0) 417 err = t.IterRecords(ctx, t.FirstKey(), t.Cols(), func(h int64, data []types.Datum, cols []*column.Col) (bool, error) { 418 c.Assert(data, DeepEquals, row) 419 i++ 420 return true, nil 421 }) 422 c.Assert(err, IsNil) 423 c.Assert(i, Equals, int64(1)) 424 425 // Test add a new row. 426 _, err = ctx.GetTxn(true) 427 c.Assert(err, IsNil) 428 429 newRow := types.MakeDatums(int64(11), int64(22), int64(33)) 430 handle, err = t.AddRecord(ctx, newRow) 431 c.Assert(err, IsNil) 432 433 _, err = ctx.GetTxn(true) 434 c.Assert(err, IsNil) 435 436 rows := [][]types.Datum{row, newRow} 437 438 i = int64(0) 439 t.IterRecords(ctx, t.FirstKey(), t.Cols(), func(h int64, data []types.Datum, cols []*column.Col) (bool, error) { 440 c.Assert(data, DeepEquals, rows[i]) 441 i++ 442 return true, nil 443 }) 444 c.Assert(i, Equals, int64(2)) 445 446 s.checkColumnKVExist(c, ctx, t, handle, col, columnValue, !isDropped) 447 448 // Test remove a row. 449 _, err = ctx.GetTxn(true) 450 c.Assert(err, IsNil) 451 452 err = t.RemoveRecord(ctx, handle, newRow) 453 c.Assert(err, IsNil) 454 455 _, err = ctx.GetTxn(true) 456 c.Assert(err, IsNil) 457 458 i = int64(0) 459 t.IterRecords(ctx, t.FirstKey(), t.Cols(), func(h int64, data []types.Datum, cols []*column.Col) (bool, error) { 460 i++ 461 return true, nil 462 }) 463 c.Assert(i, Equals, int64(1)) 464 465 s.testGetColumn(c, t, col.Name.L, false) 466 } 467 468 func (s *testColumnSuite) checkPublicColumn(c *C, ctx context.Context, d *ddl, tblInfo *model.TableInfo, handle int64, col *column.Col, row []types.Datum, columnValue interface{}) { 469 t := testGetTable(c, d, s.dbInfo.ID, tblInfo.ID) 470 471 _, err := ctx.GetTxn(true) 472 c.Assert(err, IsNil) 473 474 i := int64(0) 475 oldRow := append(row, types.NewDatum(columnValue)) 476 err = t.IterRecords(ctx, t.FirstKey(), t.Cols(), func(h int64, data []types.Datum, cols []*column.Col) (bool, error) { 477 c.Assert(data, DeepEquals, oldRow) 478 i++ 479 return true, nil 480 }) 481 c.Assert(err, IsNil) 482 c.Assert(i, Equals, int64(1)) 483 484 // Test add a new row. 485 _, err = ctx.GetTxn(true) 486 c.Assert(err, IsNil) 487 488 newRow := types.MakeDatums(int64(11), int64(22), int64(33), int64(44)) 489 handle, err = t.AddRecord(ctx, newRow) 490 c.Assert(err, IsNil) 491 492 _, err = ctx.GetTxn(true) 493 c.Assert(err, IsNil) 494 495 rows := [][]types.Datum{oldRow, newRow} 496 497 i = int64(0) 498 t.IterRecords(ctx, t.FirstKey(), t.Cols(), func(h int64, data []types.Datum, cols []*column.Col) (bool, error) { 499 c.Assert(data, DeepEquals, rows[i]) 500 i++ 501 return true, nil 502 }) 503 c.Assert(i, Equals, int64(2)) 504 505 // Test remove a row. 506 _, err = ctx.GetTxn(true) 507 c.Assert(err, IsNil) 508 509 err = t.RemoveRecord(ctx, handle, newRow) 510 c.Assert(err, IsNil) 511 512 _, err = ctx.GetTxn(true) 513 c.Assert(err, IsNil) 514 515 i = int64(0) 516 t.IterRecords(ctx, t.FirstKey(), t.Cols(), func(h int64, data []types.Datum, cols []*column.Col) (bool, error) { 517 c.Assert(data, DeepEquals, oldRow) 518 i++ 519 return true, nil 520 }) 521 c.Assert(i, Equals, int64(1)) 522 523 err = ctx.FinishTxn(false) 524 c.Assert(err, IsNil) 525 s.testGetColumn(c, t, col.Name.L, true) 526 } 527 528 func (s *testColumnSuite) checkAddOrDropColumn(c *C, state model.SchemaState, d *ddl, tblInfo *model.TableInfo, handle int64, col *column.Col, row []types.Datum, columnValue interface{}, isDropped bool) { 529 ctx := testNewContext(c, d) 530 531 switch state { 532 case model.StateNone: 533 s.checkNoneColumn(c, ctx, d, tblInfo, handle, col, columnValue) 534 case model.StateDeleteOnly: 535 s.checkDeleteOnlyColumn(c, ctx, d, tblInfo, handle, col, row, columnValue, isDropped) 536 case model.StateWriteOnly: 537 s.checkWriteOnlyColumn(c, ctx, d, tblInfo, handle, col, row, columnValue, isDropped) 538 case model.StateWriteReorganization, model.StateDeleteReorganization: 539 s.checkReorganizationColumn(c, ctx, d, tblInfo, handle, col, row, columnValue, isDropped) 540 case model.StatePublic: 541 s.checkPublicColumn(c, ctx, d, tblInfo, handle, col, row, columnValue) 542 } 543 } 544 545 func (s *testColumnSuite) testGetColumn(c *C, t table.Table, name string, isExist bool) { 546 col := column.FindCol(t.Cols(), name) 547 if isExist { 548 c.Assert(col, NotNil) 549 } else { 550 c.Assert(col, IsNil) 551 } 552 } 553 554 func (s *testColumnSuite) TestAddColumn(c *C) { 555 defer testleak.AfterTest(c)() 556 d := newDDL(s.store, nil, nil, 100*time.Millisecond) 557 tblInfo := testTableInfo(c, d, "t", 3) 558 ctx := testNewContext(c, d) 559 560 _, err := ctx.GetTxn(true) 561 c.Assert(err, IsNil) 562 563 testCreateTable(c, ctx, d, s.dbInfo, tblInfo) 564 565 t := testGetTable(c, d, s.dbInfo.ID, tblInfo.ID) 566 567 row := types.MakeDatums(int64(1), int64(2), int64(3)) 568 handle, err := t.AddRecord(ctx, row) 569 c.Assert(err, IsNil) 570 571 err = ctx.FinishTxn(false) 572 c.Assert(err, IsNil) 573 574 colName := "c4" 575 defaultColValue := int64(4) 576 checkOK := false 577 578 tc := &testDDLCallback{} 579 tc.onJobUpdated = func(job *model.Job) { 580 if checkOK { 581 return 582 } 583 584 t := testGetTable(c, d, s.dbInfo.ID, tblInfo.ID).(*tables.Table) 585 col := column.FindCol(t.Columns, colName) 586 if col == nil { 587 return 588 } 589 590 s.checkAddOrDropColumn(c, col.State, d, tblInfo, handle, col, row, defaultColValue, false) 591 592 if col.State == model.StatePublic { 593 checkOK = true 594 } 595 } 596 597 d.hook = tc 598 599 // Use local ddl for callback test. 600 s.d.close() 601 602 d.close() 603 d.start() 604 605 job := testCreateColumn(c, ctx, d, s.dbInfo, tblInfo, colName, &ast.ColumnPosition{Tp: ast.ColumnPositionNone}, defaultColValue) 606 testCheckJobDone(c, d, job, true) 607 608 _, err = ctx.GetTxn(true) 609 c.Assert(err, IsNil) 610 611 job = testDropTable(c, ctx, d, s.dbInfo, tblInfo) 612 testCheckJobDone(c, d, job, false) 613 614 err = ctx.FinishTxn(false) 615 c.Assert(err, IsNil) 616 617 d.close() 618 s.d.start() 619 } 620 621 func (s *testColumnSuite) TestDropColumn(c *C) { 622 defer testleak.AfterTest(c)() 623 d := newDDL(s.store, nil, nil, 100*time.Millisecond) 624 tblInfo := testTableInfo(c, d, "t", 4) 625 ctx := testNewContext(c, d) 626 627 _, err := ctx.GetTxn(true) 628 c.Assert(err, IsNil) 629 630 testCreateTable(c, ctx, d, s.dbInfo, tblInfo) 631 632 t := testGetTable(c, d, s.dbInfo.ID, tblInfo.ID) 633 634 colName := "c4" 635 defaultColValue := int64(4) 636 row := types.MakeDatums(int64(1), int64(2), int64(3)) 637 handle, err := t.AddRecord(ctx, append(row, types.NewDatum(defaultColValue))) 638 c.Assert(err, IsNil) 639 640 err = ctx.FinishTxn(false) 641 c.Assert(err, IsNil) 642 643 checkOK := false 644 oldCol := &column.Col{} 645 646 tc := &testDDLCallback{} 647 tc.onJobUpdated = func(job *model.Job) { 648 if checkOK { 649 return 650 } 651 652 t := testGetTable(c, d, s.dbInfo.ID, tblInfo.ID).(*tables.Table) 653 col := column.FindCol(t.Columns, colName) 654 if col == nil { 655 s.checkAddOrDropColumn(c, model.StateNone, d, tblInfo, handle, oldCol, row, defaultColValue, true) 656 checkOK = true 657 return 658 } 659 660 s.checkAddOrDropColumn(c, col.State, d, tblInfo, handle, col, row, defaultColValue, true) 661 oldCol = col 662 } 663 664 d.hook = tc 665 666 // Use local ddl for callback test. 667 s.d.close() 668 669 d.close() 670 d.start() 671 672 job := testDropColumn(c, ctx, s.d, s.dbInfo, tblInfo, colName, false) 673 testCheckJobDone(c, d, job, false) 674 675 _, err = ctx.GetTxn(true) 676 c.Assert(err, IsNil) 677 678 job = testDropTable(c, ctx, d, s.dbInfo, tblInfo) 679 testCheckJobDone(c, d, job, false) 680 681 err = ctx.FinishTxn(false) 682 c.Assert(err, IsNil) 683 684 d.close() 685 s.d.start() 686 }