github.com/pingcap/ticdc@v0.0.0-20220526033649-485a10ef2652/cdc/model/sink_test.go (about)

     1  // Copyright 2020 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 model
    15  
    16  import (
    17  	"github.com/pingcap/check"
    18  	timodel "github.com/pingcap/parser/model"
    19  	"github.com/pingcap/parser/mysql"
    20  	"github.com/pingcap/parser/types"
    21  	"github.com/pingcap/ticdc/pkg/util/testleak"
    22  )
    23  
    24  type columnFlagTypeSuite struct{}
    25  
    26  var _ = check.Suite(&columnFlagTypeSuite{})
    27  
    28  func (s *columnFlagTypeSuite) TestSetFlag(c *check.C) {
    29  	defer testleak.AfterTest(c)()
    30  	var flag ColumnFlagType
    31  	flag.SetIsBinary()
    32  	flag.SetIsGeneratedColumn()
    33  	c.Assert(flag.IsBinary(), check.IsTrue)
    34  	c.Assert(flag.IsHandleKey(), check.IsFalse)
    35  	c.Assert(flag.IsGeneratedColumn(), check.IsTrue)
    36  	flag.UnsetIsBinary()
    37  	c.Assert(flag.IsBinary(), check.IsFalse)
    38  	flag.SetIsMultipleKey()
    39  	flag.SetIsUniqueKey()
    40  	c.Assert(flag.IsMultipleKey() && flag.IsUniqueKey(), check.IsTrue)
    41  	flag.UnsetIsUniqueKey()
    42  	flag.UnsetIsGeneratedColumn()
    43  	flag.UnsetIsMultipleKey()
    44  	c.Assert(flag.IsUniqueKey() || flag.IsGeneratedColumn() || flag.IsMultipleKey(), check.IsFalse)
    45  
    46  	flag = ColumnFlagType(0)
    47  	flag.SetIsHandleKey()
    48  	flag.SetIsPrimaryKey()
    49  	flag.SetIsUnsigned()
    50  	c.Assert(flag.IsHandleKey() && flag.IsPrimaryKey() && flag.IsUnsigned(), check.IsTrue)
    51  	flag.UnsetIsHandleKey()
    52  	flag.UnsetIsPrimaryKey()
    53  	flag.UnsetIsUnsigned()
    54  	c.Assert(flag.IsHandleKey() || flag.IsPrimaryKey() || flag.IsUnsigned(), check.IsFalse)
    55  	flag.SetIsNullable()
    56  	c.Assert(flag.IsNullable(), check.IsTrue)
    57  	flag.UnsetIsNullable()
    58  	c.Assert(flag.IsNullable(), check.IsFalse)
    59  }
    60  
    61  func (s *columnFlagTypeSuite) TestFlagValue(c *check.C) {
    62  	defer testleak.AfterTest(c)()
    63  	c.Assert(BinaryFlag, check.Equals, ColumnFlagType(0b1))
    64  	c.Assert(HandleKeyFlag, check.Equals, ColumnFlagType(0b10))
    65  	c.Assert(GeneratedColumnFlag, check.Equals, ColumnFlagType(0b100))
    66  	c.Assert(PrimaryKeyFlag, check.Equals, ColumnFlagType(0b1000))
    67  	c.Assert(UniqueKeyFlag, check.Equals, ColumnFlagType(0b10000))
    68  	c.Assert(MultipleKeyFlag, check.Equals, ColumnFlagType(0b100000))
    69  	c.Assert(NullableFlag, check.Equals, ColumnFlagType(0b1000000))
    70  }
    71  
    72  type commonDataStructureSuite struct{}
    73  
    74  var _ = check.Suite(&commonDataStructureSuite{})
    75  
    76  func (s *commonDataStructureSuite) TestTableNameFuncs(c *check.C) {
    77  	defer testleak.AfterTest(c)()
    78  	t := &TableName{
    79  		Schema:  "test",
    80  		Table:   "t1",
    81  		TableID: 1071,
    82  	}
    83  	c.Assert(t.String(), check.Equals, "test.t1")
    84  	c.Assert(t.QuoteString(), check.Equals, "`test`.`t1`")
    85  	c.Assert(t.GetSchema(), check.Equals, "test")
    86  	c.Assert(t.GetTable(), check.Equals, "t1")
    87  	c.Assert(t.GetTableID(), check.Equals, int64(1071))
    88  }
    89  
    90  func (s *commonDataStructureSuite) TestRowChangedEventFuncs(c *check.C) {
    91  	defer testleak.AfterTest(c)()
    92  	deleteRow := &RowChangedEvent{
    93  		Table: &TableName{
    94  			Schema: "test",
    95  			Table:  "t1",
    96  		},
    97  		PreColumns: []*Column{
    98  			{
    99  				Name:  "a",
   100  				Value: 1,
   101  				Flag:  HandleKeyFlag | PrimaryKeyFlag,
   102  			}, {
   103  				Name:  "b",
   104  				Value: 2,
   105  				Flag:  0,
   106  			},
   107  		},
   108  	}
   109  	expectedKeyCols := []*Column{
   110  		{
   111  			Name:  "a",
   112  			Value: 1,
   113  			Flag:  HandleKeyFlag | PrimaryKeyFlag,
   114  		},
   115  	}
   116  	c.Assert(deleteRow.IsDelete(), check.IsTrue)
   117  	c.Assert(deleteRow.PrimaryKeyColumns(), check.DeepEquals, expectedKeyCols)
   118  	c.Assert(deleteRow.HandleKeyColumns(), check.DeepEquals, expectedKeyCols)
   119  
   120  	insertRow := &RowChangedEvent{
   121  		Table: &TableName{
   122  			Schema: "test",
   123  			Table:  "t1",
   124  		},
   125  		Columns: []*Column{
   126  			{
   127  				Name:  "a",
   128  				Value: 1,
   129  				Flag:  HandleKeyFlag,
   130  			}, {
   131  				Name:  "b",
   132  				Value: 2,
   133  				Flag:  0,
   134  			},
   135  		},
   136  	}
   137  	expectedPrimaryKeyCols := []*Column{}
   138  	expectedHandleKeyCols := []*Column{
   139  		{
   140  			Name:  "a",
   141  			Value: 1,
   142  			Flag:  HandleKeyFlag,
   143  		},
   144  	}
   145  	c.Assert(insertRow.IsDelete(), check.IsFalse)
   146  	c.Assert(insertRow.PrimaryKeyColumns(), check.DeepEquals, expectedPrimaryKeyCols)
   147  	c.Assert(insertRow.HandleKeyColumns(), check.DeepEquals, expectedHandleKeyCols)
   148  }
   149  
   150  func (s *commonDataStructureSuite) TestColumnValueString(c *check.C) {
   151  	defer testleak.AfterTest(c)()
   152  	testCases := []struct {
   153  		val      interface{}
   154  		expected string
   155  	}{
   156  		{interface{}(nil), "null"},
   157  		{interface{}(true), "1"},
   158  		{interface{}(false), "0"},
   159  		{interface{}(123), "123"},
   160  		{interface{}(int8(-123)), "-123"},
   161  		{interface{}(int16(-123)), "-123"},
   162  		{interface{}(int32(-123)), "-123"},
   163  		{interface{}(int64(-123)), "-123"},
   164  		{interface{}(uint8(123)), "123"},
   165  		{interface{}(uint16(123)), "123"},
   166  		{interface{}(uint32(123)), "123"},
   167  		{interface{}(uint64(123)), "123"},
   168  		{interface{}(float32(123.01)), "123.01"},
   169  		{interface{}(float64(123.01)), "123.01"},
   170  		{interface{}("123.01"), "123.01"},
   171  		{interface{}([]byte("123.01")), "123.01"},
   172  		{interface{}(complex(1, 2)), "(1+2i)"},
   173  	}
   174  	for _, tc := range testCases {
   175  		s := ColumnValueString(tc.val)
   176  		c.Assert(s, check.Equals, tc.expected)
   177  	}
   178  }
   179  
   180  func (s *commonDataStructureSuite) TestFromTiColumnInfo(c *check.C) {
   181  	defer testleak.AfterTest(c)()
   182  	col := &ColumnInfo{}
   183  	col.FromTiColumnInfo(&timodel.ColumnInfo{
   184  		Name:      timodel.CIStr{O: "col1"},
   185  		FieldType: types.FieldType{Tp: 3},
   186  	})
   187  	c.Assert(col.Name, check.Equals, "col1")
   188  	c.Assert(col.Type, check.Equals, uint8(3))
   189  }
   190  
   191  func (s *commonDataStructureSuite) TestDDLEventFromJob(c *check.C) {
   192  	defer testleak.AfterTest(c)()
   193  	job := &timodel.Job{
   194  		ID:         1071,
   195  		TableID:    49,
   196  		SchemaName: "test",
   197  		Type:       timodel.ActionAddColumn,
   198  		StartTS:    420536581131337731,
   199  		Query:      "alter table t1 add column a int",
   200  		BinlogInfo: &timodel.HistoryInfo{
   201  			TableInfo: &timodel.TableInfo{
   202  				ID:   49,
   203  				Name: timodel.CIStr{O: "t1"},
   204  				Columns: []*timodel.ColumnInfo{
   205  					{ID: 1, Name: timodel.CIStr{O: "id"}, FieldType: types.FieldType{Flag: mysql.PriKeyFlag}, State: timodel.StatePublic},
   206  					{ID: 2, Name: timodel.CIStr{O: "a"}, FieldType: types.FieldType{}, State: timodel.StatePublic},
   207  				},
   208  			},
   209  			FinishedTS: 420536581196873729,
   210  		},
   211  	}
   212  	preTableInfo := &TableInfo{
   213  		TableName: TableName{
   214  			Schema:  "test",
   215  			Table:   "t1",
   216  			TableID: 49,
   217  		},
   218  		TableInfo: &timodel.TableInfo{
   219  			ID:   49,
   220  			Name: timodel.CIStr{O: "t1"},
   221  			Columns: []*timodel.ColumnInfo{
   222  				{ID: 1, Name: timodel.CIStr{O: "id"}, FieldType: types.FieldType{Flag: mysql.PriKeyFlag}, State: timodel.StatePublic},
   223  			},
   224  		},
   225  	}
   226  	event := &DDLEvent{}
   227  	event.FromJob(job, preTableInfo)
   228  	c.Assert(event.StartTs, check.Equals, uint64(420536581131337731))
   229  	c.Assert(event.TableInfo.TableID, check.Equals, int64(49))
   230  	c.Assert(event.PreTableInfo.ColumnInfo, check.HasLen, 1)
   231  
   232  	event = &DDLEvent{}
   233  	event.FromJob(job, nil)
   234  	c.Assert(event.PreTableInfo, check.IsNil)
   235  }