diff --git a/sql/expression/in.go b/sql/expression/in.go index d9c695fa42..811feba266 100644 --- a/sql/expression/in.go +++ b/sql/expression/in.go @@ -246,6 +246,29 @@ func newInMap(ctx *sql.Context, right Tuple, lType sql.Type) (map[uint64]sql.Exp return elements, hasNull, nil } +// getTupleCollation returns the collation to use for a tuple. +// If the tuple consists entirely of string types with the same collation, that collation is returned. +// Otherwise, Default collation is returned. +func getTupleCollation(tup types.TupleType) sql.CollationID { + coll := sql.Collation_Unspecified + for _, typ := range tup { + // if any element is not text, return default + if !types.IsTextOnly(typ) { + return sql.Collation_Default + } + // all text elements must have the same collation + c := typ.(sql.StringType).Collation() + if coll == sql.Collation_Unspecified { + coll = c + continue + } + if coll != c { + return sql.Collation_Default + } + } + return coll +} + func hashOfSimple(ctx *sql.Context, i interface{}, t sql.Type) (uint64, error) { if i == nil { return 0, nil @@ -265,6 +288,10 @@ func hashOfSimple(ctx *sql.Context, i interface{}, t sql.Type) (uint64, error) { str = converted.(string) } } else { + if types.IsTuple(t) { + coll = getTupleCollation(t.(types.TupleType)) + } + x, err := convertOrTruncate(ctx, i, t.Promote()) if err != nil { return 0, err