Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

*: fix a bug caused by the wrong collation setting which leads to the wrong result of collation function (#17116) #17231

Merged
merged 8 commits into from
Jul 28, 2020
Next Next commit
cherry pick #17116 to release-4.0
Signed-off-by: sre-bot <[email protected]>
  • Loading branch information
wjhuang2016 authored and sre-bot committed May 15, 2020
commit c7ee2060fe41b126caea89381d1be5b4fb063e6c
2 changes: 1 addition & 1 deletion executor/set.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
1 change: 1 addition & 0 deletions expression/builtin_info.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down
61 changes: 61 additions & 0 deletions expression/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 <nil> <nil> <nil> <nil> <nil>"))
}

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)
7 changes: 1 addition & 6 deletions session/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
21 changes: 20 additions & 1 deletion sessionctx/variable/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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)))
Expand Down