diff --git a/executor/set.go b/executor/set.go index 2a5001858f95f..b4bbf85b84611 100644 --- a/executor/set.go +++ b/executor/set.go @@ -60,10 +60,10 @@ func (e *SetExecutor) Next(ctx context.Context, req *chunk.Chunk) error { sessionVars := e.ctx.GetSessionVars() for _, v := range e.vars { // Variable is case insensitive, we use lower case. - if v.Name == ast.SetNames { + if v.Name == ast.SetNames || v.Name == ast.SetCharset { // This is set charset stmt. if v.IsDefault { - err := e.setCharset(mysql.DefaultCharset, "") + err := e.setCharset(mysql.DefaultCharset, "", v.Name == ast.SetNames) if err != nil { return err } @@ -78,7 +78,7 @@ func (e *SetExecutor) Next(ctx context.Context, req *chunk.Chunk) error { if v.ExtendValue != nil { co = v.ExtendValue.Value.GetString() } - err = e.setCharset(cs, co) + err = e.setCharset(cs, co, v.Name == ast.SetNames) if err != nil { return err } @@ -240,7 +240,7 @@ func (e *SetExecutor) setSysVariable(name string, v *expression.VarAssignment) e return nil } -func (e *SetExecutor) setCharset(cs, co string) error { +func (e *SetExecutor) setCharset(cs, co string, isSetName bool) error { var err error if len(co) == 0 { if co, err = charset.GetDefaultCollation(cs); err != nil { @@ -256,12 +256,33 @@ func (e *SetExecutor) setCharset(cs, co string) error { } } sessionVars := e.ctx.GetSessionVars() - for _, v := range variable.SetNamesVariables { + if isSetName { + for _, v := range variable.SetNamesVariables { + if err = sessionVars.SetSystemVar(v, cs); err != nil { + return errors.Trace(err) + } + } + return errors.Trace(sessionVars.SetSystemVar(variable.CollationConnection, co)) + } + // Set charset statement, see also https://dev.mysql.com/doc/refman/8.0/en/set-character-set.html. + for _, v := range variable.SetCharsetVariables { if err = sessionVars.SetSystemVar(v, cs); err != nil { return errors.Trace(err) } } - return sessionVars.SetSystemVar(variable.CollationConnection, co) + csDb, err := sessionVars.GlobalVarsAccessor.GetGlobalSysVar(variable.CharsetDatabase) + if err != nil { + return err + } + coDb, err := sessionVars.GlobalVarsAccessor.GetGlobalSysVar(variable.CollationDatabase) + if err != nil { + return err + } + err = sessionVars.SetSystemVar(variable.CharacterSetConnection, csDb) + if err != nil { + return errors.Trace(err) + } + return errors.Trace(sessionVars.SetSystemVar(variable.CollationConnection, coDb)) } func (e *SetExecutor) getVarValue(v *expression.VarAssignment, sysVar *variable.SysVar) (value types.Datum, err error) { diff --git a/executor/set_test.go b/executor/set_test.go index 916f4a7463a2c..b2127f6c0e7de 100644 --- a/executor/set_test.go +++ b/executor/set_test.go @@ -542,7 +542,7 @@ func (s *testSuite5) TestSetCharset(c *C) { tk.MustExec(`SET CHARACTER SET latin1`) check( "latin1", - "latin1", + "utf8mb4", "latin1", "utf8mb4", "utf8mb4", diff --git a/go.mod b/go.mod index 4acea73b1102e..8d233d01e909c 100644 --- a/go.mod +++ b/go.mod @@ -32,7 +32,7 @@ require ( github.com/pingcap/goleveldb v0.0.0-20191226122134-f82aafb29989 github.com/pingcap/kvproto v0.0.0-20200706115936-1e0910aabe6c github.com/pingcap/log v0.0.0-20200511115504-543df19646ad - github.com/pingcap/parser v0.0.0-20200623164729-3a18f1e5dceb + github.com/pingcap/parser v0.0.0-20200708150102-420619df5c94 github.com/pingcap/pd/v4 v4.0.0-rc.2.0.20200520083007-2c251bd8f181 github.com/pingcap/sysutil v0.0.0-20200408114249-ed3bd6f7fdb1 github.com/pingcap/tidb-tools v4.0.1-0.20200530144555-cdec43635625+incompatible diff --git a/go.sum b/go.sum index 09579847a32fe..9ebd4ae68be9e 100644 --- a/go.sum +++ b/go.sum @@ -421,8 +421,9 @@ github.com/pingcap/log v0.0.0-20200511115504-543df19646ad/go.mod h1:4rbK1p9ILyIf github.com/pingcap/parser v0.0.0-20200424075042-8222d8b724a4/go.mod h1:9v0Edh8IbgjGYW2ArJr19E+bvL8zKahsFp+ixWeId+4= github.com/pingcap/parser v0.0.0-20200507022230-f3bf29096657/go.mod h1:9v0Edh8IbgjGYW2ArJr19E+bvL8zKahsFp+ixWeId+4= github.com/pingcap/parser v0.0.0-20200603032439-c4ecb4508d2f/go.mod h1:9v0Edh8IbgjGYW2ArJr19E+bvL8zKahsFp+ixWeId+4= -github.com/pingcap/parser v0.0.0-20200623164729-3a18f1e5dceb h1:v9iX5qIr8nG3QxMtlcTT+1DI0YD4HqABy7tuohbp28E= github.com/pingcap/parser v0.0.0-20200623164729-3a18f1e5dceb/go.mod h1:vQdbJqobJAgFyiRNNtXahpMoGWwPEuWciVEK5A20NS0= +github.com/pingcap/parser v0.0.0-20200708150102-420619df5c94 h1:2ClwFuxJTpDMdjJesnr4bGX4uNRIMl6h8mN1gulFc2M= +github.com/pingcap/parser v0.0.0-20200708150102-420619df5c94/go.mod h1:vQdbJqobJAgFyiRNNtXahpMoGWwPEuWciVEK5A20NS0= github.com/pingcap/pd/v4 v4.0.0-rc.1.0.20200422143320-428acd53eba2/go.mod h1:s+utZtXDznOiL24VK0qGmtoHjjXNsscJx3m1n8cC56s= github.com/pingcap/pd/v4 v4.0.0-rc.2.0.20200520083007-2c251bd8f181 h1:FM+PzdoR3fmWAJx3ug+p5aOgs5aZYwFkoDL7Potdsz0= github.com/pingcap/pd/v4 v4.0.0-rc.2.0.20200520083007-2c251bd8f181/go.mod h1:q4HTx/bA8aKBa4S7L+SQKHvjRPXCRV0tA0yRw0qkZSA= diff --git a/sessionctx/variable/sysvar.go b/sessionctx/variable/sysvar.go index a274f3b067afd..c5d14e7e15d57 100644 --- a/sessionctx/variable/sysvar.go +++ b/sessionctx/variable/sysvar.go @@ -748,6 +748,12 @@ var SetNamesVariables = []string{ "character_set_results", } +// SetCharsetVariables is the system variable names related to set charset statements. +var SetCharsetVariables = []string{ + "character_set_client", + "character_set_results", +} + const ( // CharacterSetConnection is the name for character_set_connection system variable. CharacterSetConnection = "character_set_connection"