From c7ee2060fe41b126caea89381d1be5b4fb063e6c Mon Sep 17 00:00:00 2001 From: wjHuang Date: Fri, 15 May 2020 13:30:49 +0800 Subject: [PATCH 1/2] cherry pick #17116 to release-4.0 Signed-off-by: sre-bot --- executor/set.go | 2 +- expression/builtin_info.go | 1 + expression/integration_test.go | 61 ++++++++++++++++++++++++++++++++++ session/session.go | 7 +--- sessionctx/variable/session.go | 21 +++++++++++- 5 files changed, 84 insertions(+), 8 deletions(-) diff --git a/executor/set.go b/executor/set.go index 3ecc8fba9a938..0fed40596cb11 100644 --- a/executor/set.go +++ b/executor/set.go @@ -253,7 +253,7 @@ func (e *SetExecutor) setCharset(cs, co string) error { return errors.Trace(err) } } - return errors.Trace(sessionVars.SetSystemVar(variable.CollationConnection, co)) + return sessionVars.SetSystemVar(variable.CollationConnection, co) } func (e *SetExecutor) getVarValue(v *expression.VarAssignment, sysVar *variable.SysVar) (value types.Datum, err error) { diff --git a/expression/builtin_info.go b/expression/builtin_info.go index 422829bd32053..db7050a81ed5e 100644 --- a/expression/builtin_info.go +++ b/expression/builtin_info.go @@ -673,6 +673,7 @@ func (c *collationFunctionClass) getFunction(ctx sessionctx.Context, args []Expr if err != nil { return nil, err } + bf.tp.Charset, bf.tp.Collate = ctx.GetSessionVars().GetCharsetInfo() sig := &builtinCollationSig{bf} return sig, nil } diff --git a/expression/integration_test.go b/expression/integration_test.go index 758141f8e5ca7..124583757bfca 100755 --- a/expression/integration_test.go +++ b/expression/integration_test.go @@ -6372,3 +6372,64 @@ func (s *testIntegrationSuite) TestIssue16697(c *C) { } } } +<<<<<<< HEAD +======= + +func (s *testIntegrationSuite) TestIssue17045(c *C) { + tk := testkit.NewTestKit(c, s.store) + tk.MustExec("use test") + tk.MustExec("drop table if exists t") + tk.MustExec("create table t(a int,b varchar(20),c datetime,d double,e int,f int as(a+b),key(a),key(b),key(c),key(d),key(e),key(f));") + tk.MustExec("insert into t(a,b,e) values(null,\"5\",null);") + tk.MustExec("insert into t(a,b,e) values(\"5\",null,null);") + tk.MustQuery("select /*+ use_index_merge(t)*/ * from t where t.e=5 or t.a=5;").Check(testkit.Rows("5 ")) +} + +func (s *testIntegrationSuite) TestIssue17098(c *C) { + tk := testkit.NewTestKit(c, s.store) + tk.MustExec("use test") + tk.MustExec("drop table if exists t1, t2") + tk.MustExec("create table t1(a char) collate utf8mb4_bin;") + tk.MustExec("create table t2(a char) collate utf8mb4_bin;;") + tk.MustExec("insert into t1 values('a');") + tk.MustExec("insert into t2 values('a');") + tk.MustQuery("select collation(t1.a) from t1 union select collation(t2.a) from t2;").Check(testkit.Rows("utf8mb4_bin")) +} + +func (s *testIntegrationSuite) TestIssue17115(c *C) { + tk := testkit.NewTestKit(c, s.store) + tk.MustQuery("select collation(user());").Check(testkit.Rows("utf8mb4_bin")) + tk.MustQuery("select collation(compress('abc'));").Check(testkit.Rows("binary")) +} + +func (s *testIntegrationSuite) TestIndexedVirtualGeneratedColumnTruncate(c *C) { + tk := testkit.NewTestKit(c, s.store) + tk.MustExec("use test") + tk.MustExec("drop table if exists t1") + tk.MustExec("create table t(a int, b tinyint as(a+100) unique key)") + tk.MustExec("insert ignore into t values(200, default)") + tk.MustExec("update t set a=1 where a=200") + tk.MustExec("admin check table t") + tk.MustExec("delete from t") + tk.MustExec("insert ignore into t values(200, default)") + tk.MustExec("admin check table t") + tk.MustExec("insert ignore into t values(200, default) on duplicate key update a=100") + tk.MustExec("admin check table t") + tk.MustExec("delete from t") + tk.MustExec("admin check table t") + + tk.MustExec("begin") + tk.MustExec("insert ignore into t values(200, default)") + tk.MustExec("update t set a=1 where a=200") + tk.MustExec("admin check table t") + tk.MustExec("delete from t") + tk.MustExec("insert ignore into t values(200, default)") + tk.MustExec("admin check table t") + tk.MustExec("insert ignore into t values(200, default) on duplicate key update a=100") + tk.MustExec("admin check table t") + tk.MustExec("delete from t") + tk.MustExec("admin check table t") + tk.MustExec("commit") + tk.MustExec("admin check table t") +} +>>>>>>> ea2e215... *: fix a bug caused by the wrong collation setting which leads to the wrong result of collation function (#17116) diff --git a/session/session.go b/session/session.go index 42ddb2729cd79..6f297b7c34f7e 100644 --- a/session/session.go +++ b/session/session.go @@ -321,12 +321,7 @@ func (s *session) SetCollation(coID int) error { for _, v := range variable.SetNamesVariables { terror.Log(s.sessionVars.SetSystemVar(v, cs)) } - err = s.sessionVars.SetSystemVar(variable.CollationConnection, co) - if err != nil { - // Some clients may use the unsupported collations, such as utf8mb4_0900_ai_ci, We shouldn't return error or use the ERROR level log. - logutil.BgLogger().Warn(err.Error()) - } - return nil + return s.sessionVars.SetSystemVar(variable.CollationConnection, co) } func (s *session) PreparedPlanCache() *kvcache.SimpleLRUCache { diff --git a/sessionctx/variable/session.go b/sessionctx/variable/session.go index 8d890904583bd..c73575709fa6c 100644 --- a/sessionctx/variable/session.go +++ b/sessionctx/variable/session.go @@ -29,6 +29,7 @@ import ( "github.com/pingcap/errors" "github.com/pingcap/parser/ast" "github.com/pingcap/parser/auth" + "github.com/pingcap/parser/charset" "github.com/pingcap/parser/mysql" "github.com/pingcap/parser/terror" pumpcli "github.com/pingcap/tidb-tools/tidb-binlog/pump_client" @@ -1242,7 +1243,25 @@ func (s *SessionVars) SetSystemVar(name string, val string) error { s.MetricSchemaRangeDuration = tidbOptInt64(val, DefTiDBMetricSchemaRangeDuration) case CollationConnection, CollationDatabase, CollationServer: if _, err := collate.GetCollationByName(val); err != nil { - return errors.Trace(err) + var ok bool + var charsetVal string + var err2 error + if name == CollationConnection { + charsetVal, ok = s.systems[CharacterSetConnection] + } else if name == CollationDatabase { + charsetVal, ok = s.systems[CharsetDatabase] + } else { + // CollationServer + charsetVal, ok = s.systems[CharacterSetServer] + } + if !ok { + return err + } + val, err2 = charset.GetDefaultCollation(charsetVal) + if err2 != nil { + return err2 + } + logutil.BgLogger().Warn(err.Error()) } case TiDBSlowLogThreshold: atomic.StoreUint64(&config.GetGlobalConfig().Log.SlowThreshold, uint64(tidbOptInt64(val, logutil.DefaultSlowThreshold))) From 97cbc4953041a8d5ea4c4b062db538062e1bbad9 Mon Sep 17 00:00:00 2001 From: wjHuang Date: Wed, 3 Jun 2020 10:50:25 +0800 Subject: [PATCH 2/2] Update integration_test.go --- expression/integration_test.go | 55 ---------------------------------- 1 file changed, 55 deletions(-) diff --git a/expression/integration_test.go b/expression/integration_test.go index 124583757bfca..32dae150b518d 100755 --- a/expression/integration_test.go +++ b/expression/integration_test.go @@ -6372,64 +6372,9 @@ func (s *testIntegrationSuite) TestIssue16697(c *C) { } } } -<<<<<<< HEAD -======= - -func (s *testIntegrationSuite) TestIssue17045(c *C) { - tk := testkit.NewTestKit(c, s.store) - tk.MustExec("use test") - tk.MustExec("drop table if exists t") - tk.MustExec("create table t(a int,b varchar(20),c datetime,d double,e int,f int as(a+b),key(a),key(b),key(c),key(d),key(e),key(f));") - tk.MustExec("insert into t(a,b,e) values(null,\"5\",null);") - tk.MustExec("insert into t(a,b,e) values(\"5\",null,null);") - tk.MustQuery("select /*+ use_index_merge(t)*/ * from t where t.e=5 or t.a=5;").Check(testkit.Rows("5 ")) -} - -func (s *testIntegrationSuite) TestIssue17098(c *C) { - tk := testkit.NewTestKit(c, s.store) - tk.MustExec("use test") - tk.MustExec("drop table if exists t1, t2") - tk.MustExec("create table t1(a char) collate utf8mb4_bin;") - tk.MustExec("create table t2(a char) collate utf8mb4_bin;;") - tk.MustExec("insert into t1 values('a');") - tk.MustExec("insert into t2 values('a');") - tk.MustQuery("select collation(t1.a) from t1 union select collation(t2.a) from t2;").Check(testkit.Rows("utf8mb4_bin")) -} func (s *testIntegrationSuite) TestIssue17115(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustQuery("select collation(user());").Check(testkit.Rows("utf8mb4_bin")) tk.MustQuery("select collation(compress('abc'));").Check(testkit.Rows("binary")) } - -func (s *testIntegrationSuite) TestIndexedVirtualGeneratedColumnTruncate(c *C) { - tk := testkit.NewTestKit(c, s.store) - tk.MustExec("use test") - tk.MustExec("drop table if exists t1") - tk.MustExec("create table t(a int, b tinyint as(a+100) unique key)") - tk.MustExec("insert ignore into t values(200, default)") - tk.MustExec("update t set a=1 where a=200") - tk.MustExec("admin check table t") - tk.MustExec("delete from t") - tk.MustExec("insert ignore into t values(200, default)") - tk.MustExec("admin check table t") - tk.MustExec("insert ignore into t values(200, default) on duplicate key update a=100") - tk.MustExec("admin check table t") - tk.MustExec("delete from t") - tk.MustExec("admin check table t") - - tk.MustExec("begin") - tk.MustExec("insert ignore into t values(200, default)") - tk.MustExec("update t set a=1 where a=200") - tk.MustExec("admin check table t") - tk.MustExec("delete from t") - tk.MustExec("insert ignore into t values(200, default)") - tk.MustExec("admin check table t") - tk.MustExec("insert ignore into t values(200, default) on duplicate key update a=100") - tk.MustExec("admin check table t") - tk.MustExec("delete from t") - tk.MustExec("admin check table t") - tk.MustExec("commit") - tk.MustExec("admin check table t") -} ->>>>>>> ea2e215... *: fix a bug caused by the wrong collation setting which leads to the wrong result of collation function (#17116)