Skip to content

Commit

Permalink
sqlmodel(dm): generate key in lower case (#9498)
Browse files Browse the repository at this point in the history
close #9489
  • Loading branch information
hihihuhu authored Aug 8, 2023
1 parent e616696 commit b35406e
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 2 deletions.
21 changes: 20 additions & 1 deletion pkg/sqlmodel/causality.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"strings"

timodel "github.com/pingcap/tidb/parser/model"
"github.com/pingcap/tidb/parser/mysql"
"github.com/pingcap/tidb/sessionctx"
"github.com/pingcap/tidb/tablecodec"
"github.com/pingcap/tiflow/dm/pkg/log"
Expand All @@ -41,6 +42,19 @@ func (r *RowChange) CausalityKeys() []string {
return ret
}

func columnNeeds2LowerCase(col *timodel.ColumnInfo) bool {
switch col.GetType() {
case mysql.TypeVarchar, mysql.TypeString, mysql.TypeVarString, mysql.TypeTinyBlob,
mysql.TypeMediumBlob, mysql.TypeBlob, mysql.TypeLongBlob:
return collationNeeds2LowerCase(col.GetCollate())
}
return false
}

func collationNeeds2LowerCase(collation string) bool {
return strings.HasSuffix(collation, "_ci")
}

func columnValue2String(value interface{}) string {
var data string
switch v := value.(type) {
Expand Down Expand Up @@ -99,7 +113,12 @@ func genKeyString(
continue // ignore `null` value.
}
// one column key looks like:`column_val.column_name.`
buf.WriteString(columnValue2String(data))

val := columnValue2String(data)
if columnNeeds2LowerCase(columns[i]) {
val = strings.ToLower(val)
}
buf.WriteString(val)
buf.WriteString(".")
buf.WriteString(columns[i].Name.L)
buf.WriteString(".")
Expand Down
12 changes: 12 additions & 0 deletions pkg/sqlmodel/causality_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,18 @@ func TestGetCausalityString(t *testing.T) {
values: []interface{}{16, "xyz"},
keys: []string{"16.a.db.tbl", "xyz.b.db.tbl"},
},
{
// case insensitive
schema: `create table t_ci(a int unique, b varchar(16) primary key)default charset=utf8 collate=utf8_unicode_ci`,
values: []interface{}{16, "XyZ"},
keys: []string{"16.a.db.tbl", "xyz.b.db.tbl"},
},
{
// case sensitive
schema: `create table t_bin(a int unique, b varchar(16) primary key)default charset=utf8 collate=utf8_bin`,
values: []interface{}{16, "XyZ"},
keys: []string{"16.a.db.tbl", "XyZ.b.db.tbl"},
},
{
// primary key of multiple columns
schema: `create table t7(a int, b int, primary key(a, b))`,
Expand Down
4 changes: 3 additions & 1 deletion pkg/sqlmodel/row_change_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"github.com/pingcap/tidb/ddl"
"github.com/pingcap/tidb/parser"
"github.com/pingcap/tidb/parser/ast"
"github.com/pingcap/tidb/parser/charset"
timodel "github.com/pingcap/tidb/parser/model"
timock "github.com/pingcap/tidb/util/mock"
cdcmodel "github.com/pingcap/tiflow/cdc/model"
Expand All @@ -33,7 +34,8 @@ func mockTableInfo(t *testing.T, sql string) *timodel.TableInfo {
se := timock.NewContext()
node, err := p.ParseOneStmt(sql, "", "")
require.NoError(t, err)
ti, err := ddl.MockTableInfo(se, node.(*ast.CreateTableStmt), 1)
dbChs, dbColl := charset.GetDefaultCharsetAndCollate()
ti, err := ddl.BuildTableInfoWithStmt(se, node.(*ast.CreateTableStmt), dbChs, dbColl, nil)
require.NoError(t, err)
return ti
}
Expand Down

0 comments on commit b35406e

Please sign in to comment.