Skip to content

Commit

Permalink
executor: fix wrong behavior of set charset statement (#16984) (#17289)
Browse files Browse the repository at this point in the history
  • Loading branch information
sre-bot authored Jul 31, 2020
1 parent e7c73b0 commit 7b0b0c0
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 9 deletions.
33 changes: 27 additions & 6 deletions executor/set.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand All @@ -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
}
Expand Down Expand Up @@ -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 {
Expand All @@ -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) {
Expand Down
2 changes: 1 addition & 1 deletion executor/set_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -542,7 +542,7 @@ func (s *testSuite5) TestSetCharset(c *C) {
tk.MustExec(`SET CHARACTER SET latin1`)
check(
"latin1",
"latin1",
"utf8mb4",
"latin1",
"utf8mb4",
"utf8mb4",
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -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=
Expand Down
6 changes: 6 additions & 0 deletions sessionctx/variable/sysvar.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down

0 comments on commit 7b0b0c0

Please sign in to comment.