diff --git a/cdc/entry/mounter_test.go b/cdc/entry/mounter_test.go index 7900076017a..db0d1ec65cd 100644 --- a/cdc/entry/mounter_test.go +++ b/cdc/entry/mounter_test.go @@ -1691,7 +1691,7 @@ func TestNewDMRowChange(t *testing.T) { " a1 INT NOT NULL," + " a3 INT NOT NULL," + " UNIQUE KEY dex1(a1, a3));", - "CREATE TABLE `BuildTiDBTableInfo` (\n" + + "CREATE TABLE `t1` (\n" + " `id` int(0) DEFAULT NULL,\n" + " `a1` int(0) NOT NULL,\n" + " `a3` int(0) NOT NULL,\n" + diff --git a/cdc/model/sink.go b/cdc/model/sink.go index f567efb17e4..32cf6d6f13f 100644 --- a/cdc/model/sink.go +++ b/cdc/model/sink.go @@ -538,7 +538,8 @@ func BuildTiDBTableInfo(tableName string, columns []*Column, indexColumns [][]in ret.Name = model.NewCIStr(tableName) hasPrimaryKeyColumn := false - // Add a mock id to identify columns inside cdc + hasHandleKeyColumn := false + // add a mock id to identify columns inside cdc nextMockColID := int64(100) // 100 is an arbitrary number for i, col := range columns { columnInfo := &model.ColumnInfo{ @@ -598,6 +599,12 @@ func BuildTiDBTableInfo(tableName string, columns []*Column, indexColumns [][]in if flag.IsUniqueKey() { columnInfo.AddFlag(mysql.UniqueKeyFlag) } + if flag.IsHandleKey() { + hasHandleKeyColumn = true + if !flag.IsPrimaryKey() && !flag.IsUniqueKey() { + log.Panic("Handle key must either be primary key or unique key") + } + } if !flag.IsNullable() { columnInfo.AddFlag(mysql.NotNullFlag) } @@ -609,6 +616,9 @@ func BuildTiDBTableInfo(tableName string, columns []*Column, indexColumns [][]in } ret.Columns = append(ret.Columns, columnInfo) } + if !hasHandleKeyColumn { + log.Panic("Handle key not found") + } hasPrimaryKeyIndex := false hasHandleIndex := false @@ -660,7 +670,7 @@ func BuildTiDBTableInfo(tableName string, columns []*Column, indexColumns [][]in if isHandle { indexInfo.ID = minIndexID if hasHandleIndex { - log.Panic("Invalid state: multiple handle index found", + log.Panic("Multiple handle index found", zap.Int("index", i), zap.Any("colOffsets", colOffsets), zap.String("indexName", indexInfo.Name.O)) @@ -676,11 +686,13 @@ func BuildTiDBTableInfo(tableName string, columns []*Column, indexColumns [][]in ret.Indices = append(ret.Indices, indexInfo) } - if hasPrimaryKeyColumn != hasPrimaryKeyIndex || !hasHandleIndex { - log.Panic("Invalid arguments", + if hasPrimaryKeyColumn != hasPrimaryKeyIndex { + log.Panic("Primary key column and primary key index is not consistent", zap.Bool("hasPrimaryKeyColumn", hasPrimaryKeyColumn), - zap.Bool("hasPrimaryKeyIndex", hasPrimaryKeyIndex), - zap.Bool("hasHandleIndex", hasHandleIndex)) + zap.Bool("hasPrimaryKeyIndex", hasPrimaryKeyIndex)) + } + if !hasHandleIndex { + log.Panic("Handle index is not specified") } return ret } diff --git a/cdc/sink/dmlsink/txn/mysql/mysql_test.go b/cdc/sink/dmlsink/txn/mysql/mysql_test.go index 4f604214643..5d7fef10ee3 100644 --- a/cdc/sink/dmlsink/txn/mysql/mysql_test.go +++ b/cdc/sink/dmlsink/txn/mysql/mysql_test.go @@ -345,6 +345,7 @@ func TestNewMySQLBackendExecDML(t *testing.T) { Value: "test", }, }, + IndexColumns: [][]int{{0}}, }, { StartTs: 5, @@ -364,6 +365,7 @@ func TestNewMySQLBackendExecDML(t *testing.T) { Value: "test", }, }, + IndexColumns: [][]int{{0}}, }, } @@ -398,6 +400,7 @@ func TestExecDMLRollbackErrDatabaseNotExists(t *testing.T) { Value: 1, }, }, + IndexColumns: [][]int{{0}}, }, { Table: &model.TableName{Schema: "s1", Table: "t1", TableID: 1}, @@ -409,6 +412,7 @@ func TestExecDMLRollbackErrDatabaseNotExists(t *testing.T) { Value: 2, }, }, + IndexColumns: [][]int{{0}}, }, } @@ -469,6 +473,7 @@ func TestExecDMLRollbackErrTableNotExists(t *testing.T) { Value: 1, }, }, + IndexColumns: [][]int{{0}}, }, { Table: &model.TableName{Schema: "s1", Table: "t1", TableID: 1}, @@ -480,6 +485,7 @@ func TestExecDMLRollbackErrTableNotExists(t *testing.T) { Value: 2, }, }, + IndexColumns: [][]int{{0}}, }, } diff --git a/pkg/applier/redo_test.go b/pkg/applier/redo_test.go index d00d2c0de14..e78cad66010 100644 --- a/pkg/applier/redo_test.go +++ b/pkg/applier/redo_test.go @@ -134,13 +134,14 @@ func TestApply(t *testing.T) { { Name: "a", Value: 1, - Flag: model.HandleKeyFlag, + Flag: model.HandleKeyFlag | model.UniqueKeyFlag, }, { Name: "b", Value: "2", Flag: 0, }, }, + IndexColumns: [][]int{{0}}, }, { StartTs: 1200, @@ -150,7 +151,7 @@ func TestApply(t *testing.T) { { Name: "a", Value: 1, - Flag: model.HandleKeyFlag, + Flag: model.HandleKeyFlag | model.UniqueKeyFlag, }, { Name: "b", Value: "2", @@ -161,13 +162,14 @@ func TestApply(t *testing.T) { { Name: "a", Value: 2, - Flag: model.HandleKeyFlag, + Flag: model.HandleKeyFlag | model.UniqueKeyFlag, }, { Name: "b", Value: "3", Flag: 0, }, }, + IndexColumns: [][]int{{0}}, }, } for _, dml := range dmls { @@ -191,7 +193,7 @@ func TestApply(t *testing.T) { Schema: "test", Table: "resolved", }, }, - Query: "create table resolved(id int)", + Query: "create table resolved(id int not null unique key)", Type: timodel.ActionCreateTable, }, } @@ -263,8 +265,8 @@ func getMockDB(t *testing.T) *sql.DB { // First, apply row which commitTs equal to resolvedTs mock.ExpectBegin() - mock.ExpectExec("DELETE FROM `test`.`t1` WHERE (`a` = ? AND `b` = ?)"). - WithArgs(1, "2"). + mock.ExpectExec("DELETE FROM `test`.`t1` WHERE (`a` = ?)"). + WithArgs(1). WillReturnResult(sqlmock.NewResult(1, 1)) mock.ExpectExec("REPLACE INTO `test`.`t1` (`a`,`b`) VALUES (?,?)"). WithArgs(2, "3"). @@ -274,7 +276,7 @@ func getMockDB(t *testing.T) *sql.DB { // Then, apply ddl which commitTs equal to resolvedTs mock.ExpectBegin() mock.ExpectExec("USE `test`;").WillReturnResult(sqlmock.NewResult(1, 1)) - mock.ExpectExec("create table resolved(id int)").WillReturnResult(sqlmock.NewResult(1, 1)) + mock.ExpectExec("create table resolved(id int not null unique key)").WillReturnResult(sqlmock.NewResult(1, 1)) mock.ExpectCommit() mock.ExpectClose()