From 4bb007fd268b3ca4ba552657a97b45c2bdcf4418 Mon Sep 17 00:00:00 2001 From: ti-srebot <66930949+ti-srebot@users.noreply.github.com> Date: Fri, 3 Sep 2021 11:32:15 +0800 Subject: [PATCH] expression: Fix wrong charset and collation for case when function (#26663) (#26672) --- expression/builtin_control.go | 9 ++++++++- expression/expr_to_pb_test.go | 2 +- expression/integration_test.go | 12 ++++++++++++ 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/expression/builtin_control.go b/expression/builtin_control.go index 13f539648e049..5eaa39c703811 100644 --- a/expression/builtin_control.go +++ b/expression/builtin_control.go @@ -189,7 +189,14 @@ func (c *caseWhenFunctionClass) getFunction(ctx sessionctx.Context, args []Expre } fieldTp.Decimal, fieldTp.Flen = decimal, flen if fieldTp.EvalType().IsStringKind() && !isBinaryStr { - fieldTp.Charset, fieldTp.Collate = charset.CharsetUTF8MB4, charset.CollationUTF8MB4 + fieldTp.Charset, fieldTp.Collate = DeriveCollationFromExprs(ctx, args...) + if fieldTp.Charset == charset.CharsetBin && fieldTp.Collate == charset.CollationBin { + // When args are Json and Numerical type(eg. Int), the fieldTp is String. + // Both their charset/collation is binary, but the String need a default charset/collation. + fieldTp.Charset, fieldTp.Collate = charset.GetDefaultCharsetAndCollate() + } + } else { + fieldTp.Charset, fieldTp.Collate = charset.CharsetBin, charset.CollationBin } if isBinaryFlag { fieldTp.Flag |= mysql.BinaryFlag diff --git a/expression/expr_to_pb_test.go b/expression/expr_to_pb_test.go index a82c0e9276629..027a1dbd360b1 100644 --- a/expression/expr_to_pb_test.go +++ b/expression/expr_to_pb_test.go @@ -558,7 +558,7 @@ func (s *testEvaluatorSuite) TestControlFunc2Pb(c *C) { pbExprs, err := ExpressionsToPBList(sc, controlFuncs, client) c.Assert(err, IsNil) jsons := []string{ - "{\"tp\":10000,\"children\":[{\"tp\":201,\"val\":\"gAAAAAAAAAE=\",\"sig\":0,\"field_type\":{\"tp\":3,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"collate\":63,\"charset\":\"\"},\"has_distinct\":false},{\"tp\":201,\"val\":\"gAAAAAAAAAI=\",\"sig\":0,\"field_type\":{\"tp\":3,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"collate\":63,\"charset\":\"\"},\"has_distinct\":false},{\"tp\":201,\"val\":\"gAAAAAAAAAM=\",\"sig\":0,\"field_type\":{\"tp\":3,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"collate\":63,\"charset\":\"\"},\"has_distinct\":false}],\"sig\":4208,\"field_type\":{\"tp\":3,\"flag\":128,\"flen\":-1,\"decimal\":0,\"collate\":63,\"charset\":\"\"},\"has_distinct\":false}", + "{\"tp\":10000,\"children\":[{\"tp\":201,\"val\":\"gAAAAAAAAAE=\",\"sig\":0,\"field_type\":{\"tp\":3,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"collate\":63,\"charset\":\"\"},\"has_distinct\":false},{\"tp\":201,\"val\":\"gAAAAAAAAAI=\",\"sig\":0,\"field_type\":{\"tp\":3,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"collate\":63,\"charset\":\"\"},\"has_distinct\":false},{\"tp\":201,\"val\":\"gAAAAAAAAAM=\",\"sig\":0,\"field_type\":{\"tp\":3,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"collate\":63,\"charset\":\"\"},\"has_distinct\":false}],\"sig\":4208,\"field_type\":{\"tp\":3,\"flag\":128,\"flen\":-1,\"decimal\":0,\"collate\":63,\"charset\":\"binary\"},\"has_distinct\":false}", "{\"tp\":10000,\"children\":[{\"tp\":201,\"val\":\"gAAAAAAAAAE=\",\"sig\":0,\"field_type\":{\"tp\":3,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"collate\":63,\"charset\":\"\"},\"has_distinct\":false},{\"tp\":201,\"val\":\"gAAAAAAAAAI=\",\"sig\":0,\"field_type\":{\"tp\":3,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"collate\":63,\"charset\":\"\"},\"has_distinct\":false},{\"tp\":201,\"val\":\"gAAAAAAAAAM=\",\"sig\":0,\"field_type\":{\"tp\":3,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"collate\":63,\"charset\":\"\"},\"has_distinct\":false}],\"sig\":4107,\"field_type\":{\"tp\":3,\"flag\":128,\"flen\":24,\"decimal\":0,\"collate\":63,\"charset\":\"binary\"},\"has_distinct\":false}", "{\"tp\":10000,\"children\":[{\"tp\":201,\"val\":\"gAAAAAAAAAE=\",\"sig\":0,\"field_type\":{\"tp\":3,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"collate\":63,\"charset\":\"\"},\"has_distinct\":false},{\"tp\":201,\"val\":\"gAAAAAAAAAI=\",\"sig\":0,\"field_type\":{\"tp\":3,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"collate\":63,\"charset\":\"\"},\"has_distinct\":false}],\"sig\":4101,\"field_type\":{\"tp\":3,\"flag\":128,\"flen\":24,\"decimal\":0,\"collate\":63,\"charset\":\"binary\"},\"has_distinct\":false}", "null", diff --git a/expression/integration_test.go b/expression/integration_test.go index 56d6b734b3069..a4cf05b46b392 100644 --- a/expression/integration_test.go +++ b/expression/integration_test.go @@ -9207,6 +9207,18 @@ func (s *testIntegrationSuite) TestRefineArgNullValues(c *C) { )) } +func (s *testIntegrationSerialSuite) TestIssue26662(c *C) { + collate.SetNewCollationEnabledForTest(true) + defer collate.SetNewCollationEnabledForTest(false) + tk := testkit.NewTestKit(c, s.store) + tk.MustExec("use test") + tk.MustExec("drop table if exists t1;") + tk.MustExec("create table t1(a varchar(36) NOT NULL) ENGINE = InnoDB DEFAULT CHARSET = utf8 COLLATE = utf8_general_ci;") + tk.MustExec("set names utf8;") + tk.MustQuery("select t2.b from (select t1.a as b from t1 union all select t1.a as b from t1) t2 where case when (t2.b is not null) then t2.b else '' end > '1234567';"). + Check(testkit.Rows()) +} + func (s *testIntegrationSuite) TestConstPropNullFunctions(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test")