Skip to content

Commit

Permalink
*: Remove SetCharsetStmt, use SetStmt instead (pingcap#1422)
Browse files Browse the repository at this point in the history
"set @@session.sql_mode=1, names utf8, charset utf8;" is a valid sql statement.
  • Loading branch information
shenli authored Jul 11, 2016
1 parent 8c504c4 commit cbac6da
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 29 deletions.
14 changes: 13 additions & 1 deletion ast/misc.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ var (
_ StmtNode = &GrantStmt{}
_ StmtNode = &PrepareStmt{}
_ StmtNode = &RollbackStmt{}
_ StmtNode = &SetCharsetStmt{}
_ StmtNode = &SetPwdStmt{}
_ StmtNode = &SetStmt{}
_ StmtNode = &UseStmt{}
Expand Down Expand Up @@ -228,13 +227,24 @@ func (n *UseStmt) Accept(v Visitor) (Node, bool) {
return v.Leave(n)
}

const (
// SetNames is the const for set names/charset stmt.
// If VariableAssignment.Name == Names, it should be set names/charset stmt.
SetNames = "SetNAMES"
)

// VariableAssignment is a variable assignment struct.
type VariableAssignment struct {
node
Name string
Value ExprNode
IsGlobal bool
IsSystem bool

// VariableAssignment should be able to store information for SetCharset/SetPWD Stmt.
// For SetCharsetStmt, Value is charset, ExtendValue is collation.
// TODO: Use SetStmt to implement set password statement.
ExtendValue ExprNode
}

// Accept implements Node interface.
Expand Down Expand Up @@ -276,6 +286,7 @@ func (n *SetStmt) Accept(v Visitor) (Node, bool) {
return v.Leave(n)
}

/*
// SetCharsetStmt is a statement to assign values to character and collation variables.
// See https://dev.mysql.com/doc/refman/5.7/en/set-statement.html
type SetCharsetStmt struct {
Expand All @@ -294,6 +305,7 @@ func (n *SetCharsetStmt) Accept(v Visitor) (Node, bool) {
n = newNode.(*SetCharsetStmt)
return v.Leave(n)
}
*/

// SetPwdStmt is a statement to assign a password to user account.
// See https://dev.mysql.com/doc/refman/5.7/en/set-password.html
Expand Down
30 changes: 20 additions & 10 deletions executor/executor_simple.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ import (

// SimpleExec represents simple statement executor.
// For statements do simple execution.
// includes `UseStmt`, 'SetStmt`, `SetCharsetStmt`.
// `DoStmt`, `BeginStmt`, `CommitStmt`, `RollbackStmt`.
// includes `UseStmt`, 'SetStmt`, `DoStmt`,
// `BeginStmt`, `CommitStmt`, `RollbackStmt`.
// TODO: list all simple statements.
type SimpleExec struct {
Statement ast.StmtNode
Expand Down Expand Up @@ -69,8 +69,6 @@ func (e *SimpleExec) Next() (*Row, error) {
err = e.executeUse(x)
case *ast.SetStmt:
err = e.executeSet(x)
case *ast.SetCharsetStmt:
err = e.executeSetCharset(x)
case *ast.DoStmt:
err = e.executeDo(x)
case *ast.BeginStmt:
Expand Down Expand Up @@ -125,6 +123,19 @@ func (e *SimpleExec) executeSet(s *ast.SetStmt) error {
globalVars := variable.GetGlobalVarAccessor(e.ctx)
for _, v := range s.Variables {
// Variable is case insensitive, we use lower case.
if v.Name == ast.SetNames {
// This is set charset stmt.
cs := v.Value.GetValue().(string)
var co string
if v.ExtendValue != nil {
co = v.ExtendValue.GetValue().(string)
}
err := e.setCharset(cs, co)
if err != nil {
return errors.Trace(err)
}
continue
}
name := strings.ToLower(v.Name)
if !v.IsSystem {
// Set user variable.
Expand Down Expand Up @@ -191,23 +202,22 @@ func (e *SimpleExec) executeSet(s *ast.SetStmt) error {
return nil
}

func (e *SimpleExec) executeSetCharset(s *ast.SetCharsetStmt) error {
collation := s.Collate
func (e *SimpleExec) setCharset(cs, co string) error {
var err error
if len(collation) == 0 {
collation, err = charset.GetDefaultCollation(s.Charset)
if len(co) == 0 {
co, err = charset.GetDefaultCollation(cs)
if err != nil {
return errors.Trace(err)
}
}
sessionVars := variable.GetSessionVars(e.ctx)
for _, v := range variable.SetNamesVariables {
err = sessionVars.SetSystemVar(v, types.NewStringDatum(s.Charset))
err = sessionVars.SetSystemVar(v, types.NewStringDatum(cs))
if err != nil {
return errors.Trace(err)
}
}
err = sessionVars.SetSystemVar(variable.CollationConnection, types.NewStringDatum(collation))
err = sessionVars.SetSystemVar(variable.CollationConnection, types.NewStringDatum(co))
if err != nil {
return errors.Trace(err)
}
Expand Down
37 changes: 22 additions & 15 deletions parser/parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -3656,21 +3656,6 @@ SetStmt:
{
$$ = &ast.SetStmt{Variables: $2.([]*ast.VariableAssignment)}
}
| "SET" "NAMES" StringName
{
$$ = &ast.SetCharsetStmt{Charset: $3.(string)}
}
| "SET" "NAMES" StringName "COLLATE" StringName
{
$$ = &ast.SetCharsetStmt{
Charset: $3.(string),
Collate: $5.(string),
}
}
| "SET" CharsetKw StringName
{
$$ = &ast.SetCharsetStmt{Charset: $3.(string)}
}
| "SET" "PASSWORD" eq PasswordOpt
{
$$ = &ast.SetPwdStmt{Password: $4.(string)}
Expand Down Expand Up @@ -3748,6 +3733,28 @@ VariableAssignment:
v = strings.TrimPrefix(v, "@")
$$ = &ast.VariableAssignment{Name: v, Value: $3.(ast.ExprNode)}
}
| "NAMES" StringName
{
$$ = &ast.VariableAssignment{
Name: ast.SetNames,
Value: ast.NewValueExpr($2.(string)),
}
}
| "NAMES" StringName "COLLATE" StringName
{
$$ = &ast.VariableAssignment{
Name: ast.SetNames,
Value: ast.NewValueExpr($2.(string)),
ExtendValue: ast.NewValueExpr($4.(string)),
}
}
| CharsetKw StringName
{
$$ = &ast.VariableAssignment{
Name: ast.SetNames,
Value: ast.NewValueExpr($2.(string)),
}
}

VariableAssignmentList:
{
Expand Down
4 changes: 4 additions & 0 deletions parser/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,10 @@ func (s *testParserSuite) TestDMLStmt(c *C) {
{"set names utf8", true},
{"set names utf8 collate utf8_unicode_ci", true},

// For set names and set vars
{"set names utf8, @@session.sql_mode=1;", true},
{"set @@session.sql_mode=1, names utf8, charset utf8;", true},

// For show character set
{"show character set;", true},
// For on duplicate key update
Expand Down
1 change: 0 additions & 1 deletion perfschema/statement.go
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,6 @@ func (ps *perfSchema) registerStatements() {
ps.RegisterStatement("sql", "rollback", (*ast.RollbackStmt)(nil))
ps.RegisterStatement("sql", "select", (*ast.SelectStmt)(nil))
ps.RegisterStatement("sql", "set", (*ast.SetStmt)(nil))
ps.RegisterStatement("sql", "set_charset", (*ast.SetCharsetStmt)(nil))
ps.RegisterStatement("sql", "set_password", (*ast.SetPwdStmt)(nil))
ps.RegisterStatement("sql", "show", (*ast.ShowStmt)(nil))
ps.RegisterStatement("sql", "truncate", (*ast.TruncateTableStmt)(nil))
Expand Down
2 changes: 0 additions & 2 deletions plan/planbuilder.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,6 @@ func (b *planBuilder) build(node ast.Node) Plan {
return b.buildUpdate(x)
case *ast.UseStmt:
return b.buildSimple(x)
case *ast.SetCharsetStmt:
return b.buildSimple(x)
case *ast.SetStmt:
return b.buildSimple(x)
case *ast.ShowStmt:
Expand Down

0 comments on commit cbac6da

Please sign in to comment.