github.com/pingcap/ticdc@v0.0.0-20220526033649-485a10ef2652/cdc/owner/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 owner
    15  
    16  import (
    17  	"sort"
    18  
    19  	"github.com/pingcap/check"
    20  	timodel "github.com/pingcap/parser/model"
    21  	"github.com/pingcap/parser/mysql"
    22  	"github.com/pingcap/ticdc/cdc/entry"
    23  	"github.com/pingcap/ticdc/cdc/model"
    24  	"github.com/pingcap/ticdc/pkg/config"
    25  	"github.com/pingcap/ticdc/pkg/util/testleak"
    26  	"github.com/pingcap/tidb/store/tikv/oracle"
    27  )
    28  
    29  var _ = check.Suite(&schemaSuite{})
    30  
    31  type schemaSuite struct {
    32  }
    33  
    34  func (s *schemaSuite) TestAllPhysicalTables(c *check.C) {
    35  	defer testleak.AfterTest(c)()
    36  	helper := entry.NewSchemaTestHelper(c)
    37  	defer helper.Close()
    38  	ver, err := helper.Storage().CurrentVersion(oracle.GlobalTxnScope)
    39  	c.Assert(err, check.IsNil)
    40  	schema, err := newSchemaWrap4Owner(helper.Storage(), ver.Ver, config.GetDefaultReplicaConfig())
    41  	c.Assert(err, check.IsNil)
    42  	c.Assert(schema.AllPhysicalTables(), check.HasLen, 0)
    43  	// add normal table
    44  	job := helper.DDL2Job("create table test.t1(id int primary key)")
    45  	tableIDT1 := job.BinlogInfo.TableInfo.ID
    46  	c.Assert(schema.HandleDDL(job), check.IsNil)
    47  	c.Assert(schema.AllPhysicalTables(), check.DeepEquals, []model.TableID{tableIDT1})
    48  	// add ineligible table
    49  	c.Assert(schema.HandleDDL(helper.DDL2Job("create table test.t2(id int)")), check.IsNil)
    50  	c.Assert(schema.AllPhysicalTables(), check.DeepEquals, []model.TableID{tableIDT1})
    51  	// add partition table
    52  	job = helper.DDL2Job(`CREATE TABLE test.employees  (
    53  			id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    54  			fname VARCHAR(25) NOT NULL,
    55  			lname VARCHAR(25) NOT NULL,
    56  			store_id INT NOT NULL,
    57  			department_id INT NOT NULL
    58  		)
    59  
    60  		PARTITION BY RANGE(id)  (
    61  			PARTITION p0 VALUES LESS THAN (5),
    62  			PARTITION p1 VALUES LESS THAN (10),
    63  			PARTITION p2 VALUES LESS THAN (15),
    64  			PARTITION p3 VALUES LESS THAN (20)
    65  		)`)
    66  	c.Assert(schema.HandleDDL(job), check.IsNil)
    67  	expectedTableIDs := []model.TableID{tableIDT1}
    68  	for _, p := range job.BinlogInfo.TableInfo.GetPartitionInfo().Definitions {
    69  		expectedTableIDs = append(expectedTableIDs, p.ID)
    70  	}
    71  	sortTableIDs := func(tableIDs []model.TableID) {
    72  		sort.Slice(tableIDs, func(i, j int) bool {
    73  			return tableIDs[i] < tableIDs[j]
    74  		})
    75  	}
    76  	sortTableIDs(expectedTableIDs)
    77  	sortTableIDs(schema.AllPhysicalTables())
    78  	c.Assert(schema.AllPhysicalTables(), check.DeepEquals, expectedTableIDs)
    79  }
    80  
    81  func (s *schemaSuite) TestIsIneligibleTableID(c *check.C) {
    82  	defer testleak.AfterTest(c)()
    83  	helper := entry.NewSchemaTestHelper(c)
    84  	defer helper.Close()
    85  	ver, err := helper.Storage().CurrentVersion(oracle.GlobalTxnScope)
    86  	c.Assert(err, check.IsNil)
    87  	schema, err := newSchemaWrap4Owner(helper.Storage(), ver.Ver, config.GetDefaultReplicaConfig())
    88  	c.Assert(err, check.IsNil)
    89  	// add normal table
    90  	job := helper.DDL2Job("create table test.t1(id int primary key)")
    91  	tableIDT1 := job.BinlogInfo.TableInfo.ID
    92  	c.Assert(schema.HandleDDL(job), check.IsNil)
    93  	// add ineligible table
    94  	job = helper.DDL2Job("create table test.t2(id int)")
    95  	tableIDT2 := job.BinlogInfo.TableInfo.ID
    96  	c.Assert(schema.HandleDDL(job), check.IsNil)
    97  	c.Assert(schema.IsIneligibleTableID(tableIDT1), check.IsFalse)
    98  	c.Assert(schema.IsIneligibleTableID(tableIDT2), check.IsTrue)
    99  }
   100  
   101  func (s *schemaSuite) TestBuildDDLEvent(c *check.C) {
   102  	defer testleak.AfterTest(c)()
   103  	helper := entry.NewSchemaTestHelper(c)
   104  	defer helper.Close()
   105  	ver, err := helper.Storage().CurrentVersion(oracle.GlobalTxnScope)
   106  	c.Assert(err, check.IsNil)
   107  	schema, err := newSchemaWrap4Owner(helper.Storage(), ver.Ver, config.GetDefaultReplicaConfig())
   108  	c.Assert(err, check.IsNil)
   109  	// add normal table
   110  	job := helper.DDL2Job("create table test.t1(id int primary key)")
   111  	event, err := schema.BuildDDLEvent(job)
   112  	c.Assert(err, check.IsNil)
   113  	c.Assert(event, check.DeepEquals, &model.DDLEvent{
   114  		StartTs:  job.StartTS,
   115  		CommitTs: job.BinlogInfo.FinishedTS,
   116  		Query:    "create table test.t1(id int primary key)",
   117  		Type:     timodel.ActionCreateTable,
   118  		TableInfo: &model.SimpleTableInfo{
   119  			Schema:     "test",
   120  			Table:      "t1",
   121  			TableID:    job.TableID,
   122  			ColumnInfo: []*model.ColumnInfo{{Name: "id", Type: mysql.TypeLong}},
   123  		},
   124  		PreTableInfo: nil,
   125  	})
   126  	c.Assert(schema.HandleDDL(job), check.IsNil)
   127  	job = helper.DDL2Job("ALTER TABLE test.t1 ADD COLUMN c1 CHAR(16) NOT NULL")
   128  	event, err = schema.BuildDDLEvent(job)
   129  	c.Assert(err, check.IsNil)
   130  	c.Assert(event, check.DeepEquals, &model.DDLEvent{
   131  		StartTs:  job.StartTS,
   132  		CommitTs: job.BinlogInfo.FinishedTS,
   133  		Query:    "ALTER TABLE test.t1 ADD COLUMN c1 CHAR(16) NOT NULL",
   134  		Type:     timodel.ActionAddColumn,
   135  		TableInfo: &model.SimpleTableInfo{
   136  			Schema:     "test",
   137  			Table:      "t1",
   138  			TableID:    job.TableID,
   139  			ColumnInfo: []*model.ColumnInfo{{Name: "id", Type: mysql.TypeLong}, {Name: "c1", Type: mysql.TypeString}},
   140  		},
   141  		PreTableInfo: &model.SimpleTableInfo{
   142  			Schema:     "test",
   143  			Table:      "t1",
   144  			TableID:    job.TableID,
   145  			ColumnInfo: []*model.ColumnInfo{{Name: "id", Type: mysql.TypeLong}},
   146  		},
   147  	})
   148  }
   149  
   150  func (s *schemaSuite) TestSinkTableInfos(c *check.C) {
   151  	defer testleak.AfterTest(c)()
   152  	helper := entry.NewSchemaTestHelper(c)
   153  	defer helper.Close()
   154  	ver, err := helper.Storage().CurrentVersion(oracle.GlobalTxnScope)
   155  	c.Assert(err, check.IsNil)
   156  	schema, err := newSchemaWrap4Owner(helper.Storage(), ver.Ver, config.GetDefaultReplicaConfig())
   157  	c.Assert(err, check.IsNil)
   158  	// add normal table
   159  	job := helper.DDL2Job("create table test.t1(id int primary key)")
   160  	tableIDT1 := job.BinlogInfo.TableInfo.ID
   161  	c.Assert(schema.HandleDDL(job), check.IsNil)
   162  	// add ineligible table
   163  	job = helper.DDL2Job("create table test.t2(id int)")
   164  	c.Assert(schema.HandleDDL(job), check.IsNil)
   165  	c.Assert(schema.SinkTableInfos(), check.DeepEquals, []*model.SimpleTableInfo{
   166  		{
   167  			Schema:     "test",
   168  			Table:      "t1",
   169  			TableID:    tableIDT1,
   170  			ColumnInfo: []*model.ColumnInfo{{Name: "id", Type: mysql.TypeLong}},
   171  		},
   172  	})
   173  }