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

executor: fix wrong behavior of set charset statement (#16984) #17289

Merged
merged 13 commits into from
Jul 31, 2020
Merged
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