Skip to content

Commit

Permalink
table: set the datum collation correctly in CastValue() (#30931)
Browse files Browse the repository at this point in the history
close #30930
  • Loading branch information
tangenta authored Dec 22, 2021
1 parent beb5451 commit 9063d3b
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 3 deletions.
14 changes: 14 additions & 0 deletions executor/write_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1096,6 +1096,20 @@ func TestReplace(t *testing.T) {
tk.MustExec("drop table t1, t2")
}

func TestReplaceWithCICollation(t *testing.T) {
collate.SetNewCollationEnabledForTest(true)
defer collate.SetNewCollationEnabledForTest(false)
store, clean := testkit.CreateMockStore(t)
defer clean()
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")

tk.MustExec("create table t (a varchar(20) charset utf8mb4 collate utf8mb4_general_ci primary key);")
tk.MustExec("replace into t(a) values (_binary'A '),(_binary'A');")
tk.MustQuery("select a from t use index(primary);").Check(testkit.Rows("A"))
tk.MustQuery("select a from t ignore index(primary);").Check(testkit.Rows("A"))
}

func TestGeneratedColumnForInsert(t *testing.T) {
store, clean := testkit.CreateMockStore(t)
defer clean()
Expand Down
6 changes: 3 additions & 3 deletions table/column.go
Original file line number Diff line number Diff line change
Expand Up @@ -363,18 +363,18 @@ func validateStringDatum(ctx sessionctx.Context, origin, casted *types.Datum, co
src := casted.GetBytes()
encBytes, err := enc.Transform(nil, src, charset.OpDecode)
if err != nil {
casted.SetBytesAsString(encBytes, charset.CollationUTF8MB4, 0)
casted.SetBytesAsString(encBytes, col.Collate, 0)
nSrc := charset.CountValidBytesDecode(enc, src)
return handleWrongCharsetValue(ctx, col, src, nSrc)
}
casted.SetBytesAsString(encBytes, charset.CollationUTF8MB4, 0)
casted.SetBytesAsString(encBytes, col.Collate, 0)
return nil
}
// Check if the string is valid in the given column charset.
str := casted.GetBytes()
if !charset.IsValid(enc, str) {
replace, _ := enc.Transform(nil, str, charset.OpReplace)
casted.SetBytesAsString(replace, charset.CollationUTF8MB4, 0)
casted.SetBytesAsString(replace, col.Collate, 0)
nSrc := charset.CountValidBytes(enc, str)
return handleWrongCharsetValue(ctx, col, str, nSrc)
}
Expand Down
12 changes: 12 additions & 0 deletions table/column_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,18 @@ func TestCastValue(t *testing.T) {
colInfoS.Charset = charset.CharsetASCII
_, err = CastValue(ctx, types.NewDatum([]byte{0x32, 0xf0}), &colInfoS, false, true)
require.NoError(t, err)

colInfoS.Charset = charset.CharsetUTF8MB4
colInfoS.Collate = "utf8mb4_general_ci"
val, err = CastValue(ctx, types.NewBinaryLiteralDatum([]byte{0xE5, 0xA5, 0xBD}), &colInfoS, false, false)
require.NoError(t, err)
require.Equal(t, "utf8mb4_general_ci", val.Collation())
val, err = CastValue(ctx, types.NewBinaryLiteralDatum([]byte{0xE5, 0xA5, 0xBD, 0x81}), &colInfoS, false, false)
require.Error(t, err, "[table:1366]Incorrect string value '\\x81' for column ''")
require.Equal(t, "utf8mb4_general_ci", val.Collation())
val, err = CastValue(ctx, types.NewDatum([]byte{0xE5, 0xA5, 0xBD, 0x81}), &colInfoS, false, false)
require.Error(t, err, "[table:1366]Incorrect string value '\\x81' for column ''")
require.Equal(t, "utf8mb4_general_ci", val.Collation())
}

func TestGetDefaultValue(t *testing.T) {
Expand Down

0 comments on commit 9063d3b

Please sign in to comment.