github.com/pingcap/tiflow@v0.0.0-20240520035814-5bf52d54e205/cdc/entry/schema_test.go (about) 1 // Copyright 2021 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 entry 15 16 import ( 17 "context" 18 "encoding/json" 19 "fmt" 20 "sort" 21 "testing" 22 23 timodel "github.com/pingcap/tidb/pkg/parser/model" 24 "github.com/pingcap/tidb/pkg/parser/mysql" 25 "github.com/pingcap/tidb/pkg/parser/types" 26 "github.com/pingcap/tiflow/cdc/model" 27 "github.com/pingcap/tiflow/pkg/config" 28 "github.com/pingcap/tiflow/pkg/filter" 29 "github.com/pingcap/tiflow/pkg/util" 30 "github.com/stretchr/testify/require" 31 "github.com/tikv/client-go/v2/oracle" 32 ) 33 34 func TestAllPhysicalTables(t *testing.T) { 35 helper := NewSchemaTestHelper(t) 36 defer helper.Close() 37 ver, err := helper.Storage().CurrentVersion(oracle.GlobalTxnScope) 38 require.Nil(t, err) 39 f, err := filter.NewFilter(config.GetDefaultReplicaConfig(), "") 40 require.Nil(t, err) 41 schema, err := NewSchemaStorage(helper.Storage(), ver.Ver, 42 false, dummyChangeFeedID, util.RoleTester, f) 43 require.Nil(t, err) 44 tableIDs, err := schema.AllPhysicalTables(context.Background(), ver.Ver) 45 require.Nil(t, err) 46 require.Len(t, tableIDs, 0) 47 // add normal table 48 job := helper.DDL2Job("create table test.t1(id int primary key)") 49 tableIDT1 := job.BinlogInfo.TableInfo.ID 50 require.Nil(t, schema.HandleDDLJob(job)) 51 tableIDs, err = schema.AllPhysicalTables(context.Background(), job.BinlogInfo.FinishedTS) 52 require.Nil(t, err) 53 require.Equal(t, tableIDs, []model.TableID{tableIDT1}) 54 // add ineligible table 55 job = helper.DDL2Job("create table test.t2(id int)") 56 require.Nil(t, schema.HandleDDLJob(job)) 57 tableIDs, err = schema.AllPhysicalTables(context.Background(), job.BinlogInfo.FinishedTS) 58 require.Nil(t, err) 59 require.Equal(t, tableIDs, []model.TableID{tableIDT1}) 60 // add partition table 61 job = helper.DDL2Job(`CREATE TABLE test.employees ( 62 id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, 63 fname VARCHAR(25) NOT NULL, 64 lname VARCHAR(25) NOT NULL, 65 store_id INT NOT NULL, 66 department_id INT NOT NULL 67 ) 68 69 PARTITION BY RANGE(id) ( 70 PARTITION p0 VALUES LESS THAN (5), 71 PARTITION p1 VALUES LESS THAN (10), 72 PARTITION p2 VALUES LESS THAN (15), 73 PARTITION p3 VALUES LESS THAN (20) 74 )`) 75 require.Nil(t, schema.HandleDDLJob(job)) 76 expectedTableIDs := []model.TableID{tableIDT1} 77 for _, p := range job.BinlogInfo.TableInfo.GetPartitionInfo().Definitions { 78 expectedTableIDs = append(expectedTableIDs, p.ID) 79 } 80 sortTableIDs := func(tableIDs []model.TableID) { 81 sort.Slice(tableIDs, func(i, j int) bool { 82 return tableIDs[i] < tableIDs[j] 83 }) 84 } 85 sortTableIDs(expectedTableIDs) 86 tableIDs, err = schema.AllPhysicalTables(context.Background(), job.BinlogInfo.FinishedTS) 87 require.Nil(t, err) 88 sortTableIDs(tableIDs) 89 require.Equal(t, tableIDs, expectedTableIDs) 90 } 91 92 func TestAllTables(t *testing.T) { 93 helper := NewSchemaTestHelper(t) 94 defer helper.Close() 95 ver, err := helper.Storage().CurrentVersion(oracle.GlobalTxnScope) 96 require.Nil(t, err) 97 f, err := filter.NewFilter(config.GetDefaultReplicaConfig(), "") 98 require.Nil(t, err) 99 schema, err := NewSchemaStorage(helper.Storage(), ver.Ver, 100 false, dummyChangeFeedID, util.RoleTester, f) 101 require.Nil(t, err) 102 tableInfos, err := schema.AllTables(context.Background(), ver.Ver) 103 require.Nil(t, err) 104 require.Len(t, tableInfos, 0) 105 // add normal table 106 job := helper.DDL2Job("create table test.t1(id int primary key)") 107 require.Nil(t, schema.HandleDDLJob(job)) 108 tableInfos, err = schema.AllTables(context.Background(), job.BinlogInfo.FinishedTS) 109 require.Nil(t, err) 110 require.Len(t, tableInfos, 1) 111 tableName := tableInfos[0].TableName 112 require.Equal(t, model.TableName{ 113 Schema: "test", 114 Table: "t1", 115 TableID: 104, 116 }, tableName) 117 // add ineligible table 118 job = helper.DDL2Job("create table test.t2(id int)") 119 require.Nil(t, schema.HandleDDLJob(job)) 120 tableInfos, err = schema.AllTables(context.Background(), job.BinlogInfo.FinishedTS) 121 require.Nil(t, err) 122 require.Len(t, tableInfos, 1) 123 tableName = tableInfos[0].TableName 124 require.Equal(t, model.TableName{ 125 Schema: "test", 126 Table: "t1", 127 TableID: 104, 128 }, tableName) 129 } 130 131 func TestIsIneligibleTableID(t *testing.T) { 132 helper := NewSchemaTestHelper(t) 133 defer helper.Close() 134 ver, err := helper.Storage().CurrentVersion(oracle.GlobalTxnScope) 135 require.Nil(t, err) 136 f, err := filter.NewFilter(config.GetDefaultReplicaConfig(), "") 137 require.Nil(t, err) 138 schema, err := NewSchemaStorage(helper.Storage(), ver.Ver, 139 false, dummyChangeFeedID, util.RoleTester, f) 140 require.Nil(t, err) 141 // add normal table 142 job := helper.DDL2Job("create table test.t1(id int primary key)") 143 tableIDT1 := job.BinlogInfo.TableInfo.ID 144 require.Nil(t, schema.HandleDDLJob(job)) 145 // add ineligible table 146 job = helper.DDL2Job("create table test.t2(id int)") 147 tableIDT2 := job.BinlogInfo.TableInfo.ID 148 149 require.Nil(t, schema.HandleDDLJob(job)) 150 ctx := context.Background() 151 ignore, err := schema.IsIneligibleTable(ctx, tableIDT1, job.BinlogInfo.FinishedTS) 152 require.Nil(t, err) 153 require.False(t, ignore) 154 155 ignore, err = schema.IsIneligibleTable(ctx, tableIDT2, job.BinlogInfo.FinishedTS) 156 require.Nil(t, err) 157 require.True(t, ignore) 158 159 // test we get the right snapshot to check ineligible table 160 job = helper.DDL2Job("create table test.t3(id int)") 161 tableIDT3 := job.BinlogInfo.TableInfo.ID 162 snapshotTsWithoutPK := job.BinlogInfo.FinishedTS 163 require.Nil(t, schema.HandleDDLJob(job)) 164 job = helper.DDL2Job("alter table test.t3 add primary key(id)") 165 snapshotTsWithPK := job.BinlogInfo.FinishedTS 166 require.Nil(t, schema.HandleDDLJob(job)) 167 // tableIDT3 is ineligible at snapshotTsWithoutPK 168 ignore, err = schema.IsIneligibleTable(ctx, tableIDT3, snapshotTsWithoutPK) 169 require.Nil(t, err) 170 require.True(t, ignore) 171 // tableIDT3 is eligible at snapshotTsWithPK 172 ignore, err = schema.IsIneligibleTable(ctx, tableIDT3, snapshotTsWithPK) 173 require.Nil(t, err) 174 require.False(t, ignore) 175 } 176 177 func compareEvents(t *testing.T, e1, e2 *model.DDLEvent) { 178 require.Equal(t, e1.StartTs, e2.StartTs) 179 require.Equal(t, e1.CommitTs, e2.CommitTs) 180 require.Equal(t, e1.Query, e2.Query) 181 require.Equal(t, e1.TableInfo.TableName, e2.TableInfo.TableName) 182 require.Equal(t, len(e1.TableInfo.TableInfo.Columns), len(e2.TableInfo.TableInfo.Columns)) 183 for idx, col := range e1.TableInfo.TableInfo.Columns { 184 require.Equal(t, col.Name, e2.TableInfo.Columns[idx].Name) 185 require.Equal(t, col.FieldType.GetType(), e2.TableInfo.Columns[idx].FieldType.GetType()) 186 } 187 } 188 189 func TestBuildDDLEventsFromSingleTableDDL(t *testing.T) { 190 helper := NewSchemaTestHelper(t) 191 defer helper.Close() 192 ver, err := helper.Storage().CurrentVersion(oracle.GlobalTxnScope) 193 require.Nil(t, err) 194 f, err := filter.NewFilter(config.GetDefaultReplicaConfig(), "") 195 require.Nil(t, err) 196 schema, err := NewSchemaStorage(helper.Storage(), ver.Ver, 197 false, dummyChangeFeedID, util.RoleTester, f) 198 require.Nil(t, err) 199 // add normal table 200 ctx := context.Background() 201 job := helper.DDL2Job("create table test.t1(id int primary key)") 202 schema.AdvanceResolvedTs(job.BinlogInfo.FinishedTS - 1) 203 events, err := schema.BuildDDLEvents(ctx, job) 204 require.Nil(t, err) 205 require.Len(t, events, 1) 206 compareEvents(t, events[0], &model.DDLEvent{ 207 StartTs: job.StartTS, 208 CommitTs: job.BinlogInfo.FinishedTS, 209 Query: "create table test.t1(id int primary key)", 210 Type: timodel.ActionCreateTable, 211 TableInfo: &model.TableInfo{ 212 TableName: model.TableName{ 213 Schema: "test", 214 Table: "t1", 215 TableID: job.TableID, 216 }, 217 TableInfo: &timodel.TableInfo{ 218 Columns: []*timodel.ColumnInfo{ 219 {Name: timodel.NewCIStr("id"), FieldType: *types.NewFieldType(mysql.TypeLong)}, 220 }, 221 }, 222 }, 223 PreTableInfo: nil, 224 }) 225 require.Nil(t, schema.HandleDDLJob(job)) 226 job = helper.DDL2Job("ALTER TABLE test.t1 ADD COLUMN c1 CHAR(16) NOT NULL") 227 schema.AdvanceResolvedTs(job.BinlogInfo.FinishedTS - 1) 228 events, err = schema.BuildDDLEvents(ctx, job) 229 require.Nil(t, err) 230 require.Len(t, events, 1) 231 compareEvents(t, events[0], &model.DDLEvent{ 232 StartTs: job.StartTS, 233 CommitTs: job.BinlogInfo.FinishedTS, 234 Query: "ALTER TABLE test.t1 ADD COLUMN c1 CHAR(16) NOT NULL", 235 Type: timodel.ActionAddColumn, 236 TableInfo: &model.TableInfo{ 237 TableName: model.TableName{ 238 Schema: "test", 239 Table: "t1", 240 TableID: job.TableID, 241 }, 242 TableInfo: &timodel.TableInfo{ 243 Columns: []*timodel.ColumnInfo{ 244 {Name: timodel.NewCIStr("id"), FieldType: *types.NewFieldType(mysql.TypeLong)}, 245 {Name: timodel.NewCIStr("c1"), FieldType: *types.NewFieldType(mysql.TypeString)}, 246 }, 247 }, 248 }, 249 PreTableInfo: &model.TableInfo{ 250 TableName: model.TableName{ 251 Schema: "test", 252 Table: "t1", 253 TableID: job.TableID, 254 }, 255 TableInfo: &timodel.TableInfo{ 256 Columns: []*timodel.ColumnInfo{ 257 {Name: timodel.NewCIStr("id"), FieldType: *types.NewFieldType(mysql.TypeLong)}, 258 }, 259 }, 260 }, 261 }) 262 } 263 264 func TestBuildDDLEventsFromRenameTablesDDL(t *testing.T) { 265 helper := NewSchemaTestHelper(t) 266 defer helper.Close() 267 268 ver, err := helper.Storage().CurrentVersion(oracle.GlobalTxnScope) 269 require.Nil(t, err) 270 f, err := filter.NewFilter(config.GetDefaultReplicaConfig(), "") 271 require.Nil(t, err) 272 schema, err := NewSchemaStorage(helper.Storage(), ver.Ver, 273 false, dummyChangeFeedID, util.RoleTester, f) 274 require.Nil(t, err) 275 ctx := context.Background() 276 job := helper.DDL2Job("create database test1") 277 schema.AdvanceResolvedTs(job.BinlogInfo.FinishedTS - 1) 278 events, err := schema.BuildDDLEvents(ctx, job) 279 require.Nil(t, err) 280 require.Len(t, events, 1) 281 require.Nil(t, schema.HandleDDLJob(job)) 282 schemaID := job.SchemaID 283 // add test.t1 284 job = helper.DDL2Job("create table test1.t1(id int primary key)") 285 schema.AdvanceResolvedTs(job.BinlogInfo.FinishedTS - 1) 286 events, err = schema.BuildDDLEvents(ctx, job) 287 require.Nil(t, err) 288 require.Len(t, events, 1) 289 require.Nil(t, schema.HandleDDLJob(job)) 290 t1TableID := job.TableID 291 292 // add test.t2 293 job = helper.DDL2Job("create table test1.t2(id int primary key)") 294 schema.AdvanceResolvedTs(job.BinlogInfo.FinishedTS - 1) 295 events, err = schema.BuildDDLEvents(ctx, job) 296 require.Nil(t, err) 297 require.Len(t, events, 1) 298 require.Nil(t, schema.HandleDDLJob(job)) 299 t2TableID := job.TableID 300 301 // rename test.t1 and test.t2 302 job = helper.DDL2Job( 303 "rename table test1.t1 to test1.t10, test1.t2 to test1.t20") 304 oldSchemaIDs := []int64{schemaID, schemaID} 305 oldTableIDs := []int64{t1TableID, t2TableID} 306 newSchemaIDs := oldSchemaIDs 307 oldSchemaNames := []timodel.CIStr{ 308 timodel.NewCIStr("test1"), 309 timodel.NewCIStr("test1"), 310 } 311 newTableNames := []timodel.CIStr{ 312 timodel.NewCIStr("t10"), 313 timodel.NewCIStr("t20"), 314 } 315 args := []interface{}{ 316 oldSchemaIDs, newSchemaIDs, 317 newTableNames, oldTableIDs, oldSchemaNames, 318 } 319 rawArgs, err := json.Marshal(args) 320 require.Nil(t, err) 321 // the RawArgs field in job fetched from tidb snapshot meta is incorrent, 322 // so we manually construct `job.RawArgs` to do the workaround. 323 job.RawArgs = rawArgs 324 schema.AdvanceResolvedTs(job.BinlogInfo.FinishedTS - 1) 325 events, err = schema.BuildDDLEvents(ctx, job) 326 require.Nil(t, err) 327 require.Len(t, events, 2) 328 fmt.Printf("events[0]:%+v\n", events[0]) 329 fmt.Printf("events[1]:%+v\n", events[1]) 330 compareEvents(t, events[0], &model.DDLEvent{ 331 StartTs: job.StartTS, 332 CommitTs: job.BinlogInfo.FinishedTS, 333 Query: "RENAME TABLE `test1`.`t1` TO `test1`.`t10`", 334 Type: timodel.ActionRenameTable, 335 TableInfo: &model.TableInfo{ 336 TableName: model.TableName{ 337 Schema: "test1", 338 Table: "t10", 339 TableID: t1TableID, 340 }, 341 TableInfo: &timodel.TableInfo{ 342 Columns: []*timodel.ColumnInfo{ 343 {Name: timodel.NewCIStr("id"), FieldType: *types.NewFieldType(mysql.TypeLong)}, 344 }, 345 }, 346 }, 347 PreTableInfo: &model.TableInfo{ 348 TableName: model.TableName{ 349 Schema: "test1", 350 Table: "t1", 351 TableID: t1TableID, 352 }, 353 TableInfo: &timodel.TableInfo{ 354 Columns: []*timodel.ColumnInfo{ 355 {Name: timodel.NewCIStr("id"), FieldType: *types.NewFieldType(mysql.TypeLong)}, 356 }, 357 }, 358 }, 359 }) 360 compareEvents(t, events[1], &model.DDLEvent{ 361 StartTs: job.StartTS, 362 CommitTs: job.BinlogInfo.FinishedTS, 363 Query: "RENAME TABLE `test1`.`t2` TO `test1`.`t20`", 364 Type: timodel.ActionRenameTable, 365 TableInfo: &model.TableInfo{ 366 TableName: model.TableName{ 367 Schema: "test1", 368 Table: "t20", 369 TableID: t2TableID, 370 }, 371 TableInfo: &timodel.TableInfo{ 372 Columns: []*timodel.ColumnInfo{ 373 {Name: timodel.NewCIStr("id"), FieldType: *types.NewFieldType(mysql.TypeLong)}, 374 }, 375 }, 376 }, 377 PreTableInfo: &model.TableInfo{ 378 TableName: model.TableName{ 379 Schema: "test1", 380 Table: "t2", 381 TableID: t2TableID, 382 }, 383 TableInfo: &timodel.TableInfo{ 384 Columns: []*timodel.ColumnInfo{ 385 {Name: timodel.NewCIStr("id"), FieldType: *types.NewFieldType(mysql.TypeLong)}, 386 }, 387 }, 388 }, 389 }) 390 } 391 392 func TestBuildDDLEventsFromDropTablesDDL(t *testing.T) { 393 helper := NewSchemaTestHelper(t) 394 defer helper.Close() 395 396 ver, err := helper.Storage().CurrentVersion(oracle.GlobalTxnScope) 397 require.Nil(t, err) 398 f, err := filter.NewFilter(config.GetDefaultReplicaConfig(), "") 399 require.Nil(t, err) 400 schema, err := NewSchemaStorage(helper.Storage(), ver.Ver, 401 false, dummyChangeFeedID, util.RoleTester, f) 402 require.Nil(t, err) 403 // add test.t1 404 ctx := context.Background() 405 job := helper.DDL2Job("create table test.t1(id int primary key)") 406 schema.AdvanceResolvedTs(job.BinlogInfo.FinishedTS - 1) 407 events, err := schema.BuildDDLEvents(ctx, job) 408 require.Nil(t, err) 409 require.Len(t, events, 1) 410 require.Nil(t, schema.HandleDDLJob(job)) 411 412 // add test.t2 413 job = helper.DDL2Job("create table test.t2(id int primary key)") 414 schema.AdvanceResolvedTs(job.BinlogInfo.FinishedTS - 1) 415 events, err = schema.BuildDDLEvents(ctx, job) 416 require.Nil(t, err) 417 require.Len(t, events, 1) 418 require.Nil(t, schema.HandleDDLJob(job)) 419 420 jobs := helper.DDL2Jobs("drop table test.t1, test.t2", 2) 421 t1DropJob := jobs[1] 422 t2DropJob := jobs[0] 423 schema.AdvanceResolvedTs(t1DropJob.BinlogInfo.FinishedTS - 1) 424 events, err = schema.BuildDDLEvents(ctx, t1DropJob) 425 require.Nil(t, err) 426 require.Len(t, events, 1) 427 require.Nil(t, schema.HandleDDLJob(t1DropJob)) 428 compareEvents(t, events[0], &model.DDLEvent{ 429 StartTs: t1DropJob.StartTS, 430 CommitTs: t1DropJob.BinlogInfo.FinishedTS, 431 Query: "DROP TABLE `test`.`t1`", 432 Type: timodel.ActionDropTable, 433 PreTableInfo: &model.TableInfo{ 434 TableName: model.TableName{ 435 Schema: "test", 436 Table: "t1", 437 TableID: t1DropJob.TableID, 438 }, 439 TableInfo: &timodel.TableInfo{ 440 Columns: []*timodel.ColumnInfo{ 441 {Name: timodel.NewCIStr("id"), FieldType: *types.NewFieldType(mysql.TypeLong)}, 442 }, 443 }, 444 }, 445 TableInfo: &model.TableInfo{ 446 TableName: model.TableName{ 447 Schema: "test", 448 Table: "t1", 449 TableID: t1DropJob.TableID, 450 }, 451 TableInfo: &timodel.TableInfo{ 452 Columns: []*timodel.ColumnInfo{ 453 {Name: timodel.NewCIStr("id"), FieldType: *types.NewFieldType(mysql.TypeLong)}, 454 }, 455 }, 456 }, 457 }) 458 schema.AdvanceResolvedTs(t2DropJob.BinlogInfo.FinishedTS - 1) 459 events, err = schema.BuildDDLEvents(ctx, t2DropJob) 460 require.Nil(t, err) 461 require.Len(t, events, 1) 462 require.Nil(t, schema.HandleDDLJob(t2DropJob)) 463 compareEvents(t, events[0], &model.DDLEvent{ 464 StartTs: t2DropJob.StartTS, 465 CommitTs: t2DropJob.BinlogInfo.FinishedTS, 466 Query: "DROP TABLE `test`.`t2`", 467 Type: timodel.ActionDropTable, 468 PreTableInfo: &model.TableInfo{ 469 TableName: model.TableName{ 470 Schema: "test", 471 Table: "t2", 472 TableID: t2DropJob.TableID, 473 }, 474 TableInfo: &timodel.TableInfo{ 475 Columns: []*timodel.ColumnInfo{ 476 {Name: timodel.NewCIStr("id"), FieldType: *types.NewFieldType(mysql.TypeLong)}, 477 }, 478 }, 479 }, 480 TableInfo: &model.TableInfo{ 481 TableName: model.TableName{ 482 Schema: "test", 483 Table: "t2", 484 TableID: t2DropJob.TableID, 485 }, 486 TableInfo: &timodel.TableInfo{ 487 Columns: []*timodel.ColumnInfo{ 488 {Name: timodel.NewCIStr("id"), FieldType: *types.NewFieldType(mysql.TypeLong)}, 489 }, 490 }, 491 }, 492 }) 493 } 494 495 func TestBuildDDLEventsFromDropViewsDDL(t *testing.T) { 496 helper := NewSchemaTestHelper(t) 497 defer helper.Close() 498 499 ver, err := helper.Storage().CurrentVersion(oracle.GlobalTxnScope) 500 require.Nil(t, err) 501 f, err := filter.NewFilter(config.GetDefaultReplicaConfig(), "") 502 require.Nil(t, err) 503 schema, err := NewSchemaStorage(helper.Storage(), ver.Ver, 504 false, dummyChangeFeedID, util.RoleTester, f) 505 require.Nil(t, err) 506 ctx := context.Background() 507 // add test.tb1 508 job := helper.DDL2Job("create table test.tb1(id int primary key)") 509 schema.AdvanceResolvedTs(job.BinlogInfo.FinishedTS - 1) 510 events, err := schema.BuildDDLEvents(ctx, job) 511 require.Nil(t, err) 512 require.Len(t, events, 1) 513 require.Nil(t, schema.HandleDDLJob(job)) 514 515 // add test.tb2 516 job = helper.DDL2Job("create table test.tb2(id int primary key)") 517 schema.AdvanceResolvedTs(job.BinlogInfo.FinishedTS - 1) 518 events, err = schema.BuildDDLEvents(ctx, job) 519 require.Nil(t, err) 520 require.Len(t, events, 1) 521 require.Nil(t, schema.HandleDDLJob(job)) 522 523 // add test.view1 524 job = helper.DDL2Job( 525 "create view test.view1 as select * from test.tb1 where id > 100") 526 schema.AdvanceResolvedTs(job.BinlogInfo.FinishedTS - 1) 527 events, err = schema.BuildDDLEvents(ctx, job) 528 require.Nil(t, err) 529 require.Len(t, events, 1) 530 require.Nil(t, schema.HandleDDLJob(job)) 531 532 // add test.view2 533 job = helper.DDL2Job( 534 "create view test.view2 as select * from test.tb2 where id > 100") 535 schema.AdvanceResolvedTs(job.BinlogInfo.FinishedTS - 1) 536 events, err = schema.BuildDDLEvents(ctx, job) 537 require.Nil(t, err) 538 require.Len(t, events, 1) 539 require.Nil(t, schema.HandleDDLJob(job)) 540 541 jobs := helper.DDL2Jobs("drop view test.view1, test.view2", 2) 542 view1DropJob := jobs[1] 543 view2DropJob := jobs[0] 544 schema.AdvanceResolvedTs(view1DropJob.BinlogInfo.FinishedTS - 1) 545 events, err = schema.BuildDDLEvents(ctx, view1DropJob) 546 require.Nil(t, err) 547 require.Len(t, events, 1) 548 require.Nil(t, schema.HandleDDLJob(view1DropJob)) 549 compareEvents(t, events[0], &model.DDLEvent{ 550 StartTs: view1DropJob.StartTS, 551 CommitTs: view1DropJob.BinlogInfo.FinishedTS, 552 Query: "DROP VIEW `test`.`view1`", 553 Type: timodel.ActionDropView, 554 PreTableInfo: &model.TableInfo{ 555 TableName: model.TableName{ 556 Schema: "test", 557 Table: "view1", 558 TableID: view1DropJob.TableID, 559 }, 560 TableInfo: &timodel.TableInfo{ 561 Columns: []*timodel.ColumnInfo{ 562 {Name: timodel.NewCIStr("id"), FieldType: *types.NewFieldType(mysql.TypeUnspecified)}, 563 }, 564 }, 565 }, 566 TableInfo: &model.TableInfo{ 567 TableName: model.TableName{ 568 Schema: "test", 569 Table: "view1", 570 TableID: view1DropJob.TableID, 571 }, 572 TableInfo: &timodel.TableInfo{ 573 Columns: []*timodel.ColumnInfo{ 574 {Name: timodel.NewCIStr("id"), FieldType: *types.NewFieldType(mysql.TypeUnspecified)}, 575 }, 576 }, 577 }, 578 }) 579 schema.AdvanceResolvedTs(view2DropJob.BinlogInfo.FinishedTS - 1) 580 events, err = schema.BuildDDLEvents(ctx, view2DropJob) 581 require.Nil(t, err) 582 require.Len(t, events, 1) 583 require.Nil(t, schema.HandleDDLJob(view2DropJob)) 584 compareEvents(t, events[0], &model.DDLEvent{ 585 StartTs: view2DropJob.StartTS, 586 CommitTs: view2DropJob.BinlogInfo.FinishedTS, 587 Query: "DROP VIEW `test`.`view2`", 588 Type: timodel.ActionDropView, 589 PreTableInfo: &model.TableInfo{ 590 TableName: model.TableName{ 591 Schema: "test", 592 Table: "view2", 593 TableID: view2DropJob.TableID, 594 }, 595 TableInfo: &timodel.TableInfo{ 596 Columns: []*timodel.ColumnInfo{ 597 {Name: timodel.NewCIStr("id"), FieldType: *types.NewFieldType(mysql.TypeUnspecified)}, 598 }, 599 }, 600 }, 601 TableInfo: &model.TableInfo{ 602 TableName: model.TableName{ 603 Schema: "test", 604 Table: "view2", 605 TableID: view2DropJob.TableID, 606 }, 607 TableInfo: &timodel.TableInfo{ 608 Columns: []*timodel.ColumnInfo{ 609 {Name: timodel.NewCIStr("id"), FieldType: *types.NewFieldType(mysql.TypeUnspecified)}, 610 }, 611 }, 612 }, 613 }) 614 }