diff --git a/enginetest/queries/information_schema_queries.go b/enginetest/queries/information_schema_queries.go index 70a5258f8a..4b9f3aedc9 100644 --- a/enginetest/queries/information_schema_queries.go +++ b/enginetest/queries/information_schema_queries.go @@ -1775,6 +1775,26 @@ from information_schema.routines where routine_schema = 'mydb' and routine_type }, }, }, + { + Name: "information_schema.columns in expression uses info schema collation", + SetUpScript: []string{ + "create table TEST (COL int);", + }, + Assertions: []ScriptTestAssertion{ + { + Query: "select table_schema, table_name, column_name table_comment from information_schema.columns where (table_name, column_name) in (('TEST', 'COL'));", + Expected: []sql.Row{ + {"mydb", "TEST", "COL"}, + }, + }, + { + Query: "select table_schema, table_name, column_name table_comment from information_schema.columns where (table_name, column_name) in (('test', 'col'));", + Expected: []sql.Row{ + {"mydb", "TEST", "COL"}, + }, + }, + }, + }, } var SkippedInfoSchemaScripts = []ScriptTest{ diff --git a/enginetest/queries/script_queries.go b/enginetest/queries/script_queries.go index 682ae79fd8..476ebcbfad 100644 --- a/enginetest/queries/script_queries.go +++ b/enginetest/queries/script_queries.go @@ -7143,7 +7143,6 @@ where }, }, }, - { Name: "unix_timestamp script tests", SetUpScript: []string{ @@ -7174,7 +7173,6 @@ where }, }, }, - { Name: "name_const queries", SetUpScript: []string{ @@ -7258,6 +7256,31 @@ where }, }, }, + { + Name: "mismatched collation using hash in tuples", + SetUpScript: []string{ + "create table t (t1 text collate utf8mb4_0900_bin, t2 text collate utf8mb4_0900_ai_ci)", + "insert into t values ('ABC', 'DEF')", + }, + Assertions: []ScriptTestAssertion{ + { + Query: "select * from t where (t1, t2) in (('ABC', 'DEF'));", + Expected: []sql.Row{ + {"ABC", "DEF"}, + }, + }, + { + Query: "select * from t where (t1, t2) in (('ABC', 'def'));", + Expected: []sql.Row{ + {"ABC", "DEF"}, + }, + }, + { + Query: "select * from t where (t1, t2) in (('abc', 'DEF'));", + Expected: []sql.Row{}, + }, + }, + }, } var SpatialScriptTests = []ScriptTest{ diff --git a/sql/expression/in.go b/sql/expression/in.go index d9c695fa42..f648f9816f 100644 --- a/sql/expression/in.go +++ b/sql/expression/in.go @@ -253,7 +253,19 @@ func hashOfSimple(ctx *sql.Context, i interface{}, t sql.Type) (uint64, error) { var str string coll := sql.Collation_Default - if types.IsTextOnly(t) { + if types.IsTuple(t) { + tup := i.([]interface{}) + tupType := t.(types.TupleType) + hashes := make([]uint64, len(tup)) + for idx, v := range tup { + h, err := hashOfSimple(ctx, v, tupType[idx]) + if err != nil { + return 0, err + } + hashes[idx] = h + } + str = fmt.Sprintf("%v", hashes) + } else if types.IsTextOnly(t) { coll = t.(sql.StringType).Collation() if s, ok := i.(string); ok { str = s diff --git a/sql/expression/in_test.go b/sql/expression/in_test.go index 3f1267e72e..af3bef9592 100644 --- a/sql/expression/in_test.go +++ b/sql/expression/in_test.go @@ -414,6 +414,23 @@ func TestHashInTuple(t *testing.T) { nil, nil, }, + { + "heterogeneous collations with nested", + expression.NewTuple( + expression.NewLiteral("ABC", types.MustCreateString(sqltypes.VarChar, 20, sql.Collation_Default)), + expression.NewLiteral("def", types.MustCreateString(sqltypes.VarChar, 20, sql.Collation_utf8mb4_0900_ai_ci)), + ), + expression.NewTuple( + expression.NewTuple( + expression.NewLiteral("ABC", types.MustCreateString(sqltypes.VarChar, 20, sql.Collation_Default)), + expression.NewLiteral("DEF", types.MustCreateString(sqltypes.VarChar, 20, sql.Collation_Default)), + ), + ), + nil, + true, + nil, + nil, + }, { "left get field tuple is in right", expression.NewTuple(