Skip to content

Commit

Permalink
sessionctx/varsutil: refactor system variable (pingcap#2359)
Browse files Browse the repository at this point in the history
Make varsutil package manage all the system variable get and set method.
  • Loading branch information
coocood authored Jan 3, 2017
1 parent b80488f commit 235a797
Show file tree
Hide file tree
Showing 14 changed files with 133 additions and 135 deletions.
7 changes: 5 additions & 2 deletions bootstrap.go
Original file line number Diff line number Diff line change
Expand Up @@ -312,8 +312,11 @@ func doDMLWorks(s Session) {
// Init global system variables table.
values := make([]string, 0, len(variable.SysVars))
for k, v := range variable.SysVars {
value := fmt.Sprintf(`("%s", "%s")`, strings.ToLower(k), v.Value)
values = append(values, value)
// Session only variable should not be inserted.
if v.Scope != variable.ScopeSession {
value := fmt.Sprintf(`("%s", "%s")`, strings.ToLower(k), v.Value)
values = append(values, value)
}
}
sql := fmt.Sprintf("INSERT INTO %s.%s VALUES %s;", mysql.SystemDB, mysql.GlobalVariablesTable,
strings.Join(values, ", "))
Expand Down
14 changes: 12 additions & 2 deletions bootstrap_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ func (s *testSessionSuite) TestBootstrap(c *C) {
c.Assert(r, NotNil)
v, err := r.Next()
c.Assert(err, IsNil)
c.Assert(v.Data[0].GetInt64(), Equals, int64(len(variable.SysVars)))
c.Assert(v.Data[0].GetInt64(), Equals, globalVarsCount())

// Check a storage operations are default autocommit after the second start.
mustExecSQL(c, se, "USE test;")
Expand Down Expand Up @@ -83,6 +83,16 @@ func (s *testSessionSuite) TestBootstrap(c *C) {
c.Assert(err, IsNil)
}

func globalVarsCount() int64 {
var count int64
for _, v := range variable.SysVars {
if v.Scope != variable.ScopeSession {
count++
}
}
return count
}

// Create a new session on store but only do ddl works.
func (s *testSessionSuite) bootstrapWithOnlyDDLWork(store kv.Storage, c *C) {
ss := &session{
Expand Down Expand Up @@ -127,7 +137,7 @@ func (s *testSessionSuite) TestBootstrapWithError(c *C) {
r = mustExecSQL(c, se, "SELECT COUNT(*) from mysql.global_variables;")
v, err := r.Next()
c.Assert(err, IsNil)
c.Assert(v.Data[0].GetInt64(), Equals, int64(len(variable.SysVars)))
c.Assert(v.Data[0].GetInt64(), Equals, globalVarsCount())

r = mustExecSQL(c, se, `SELECT VARIABLE_VALUE from mysql.TiDB where VARIABLE_NAME="bootstrapped";`)
row, err = r.Next()
Expand Down
4 changes: 2 additions & 2 deletions executor/executor_ddl.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,11 +166,11 @@ func (e *DDLExec) executeDropDatabase(s *ast.DropDatabaseStmt) error {
sessionVars := e.ctx.GetSessionVars()
if err == nil && strings.ToLower(sessionVars.CurrentDB) == dbName.L {
sessionVars.CurrentDB = ""
err = varsutil.SetSystemVar(sessionVars, variable.CharsetDatabase, types.NewStringDatum("utf8"))
err = varsutil.SetSessionSystemVar(sessionVars, variable.CharsetDatabase, types.NewStringDatum("utf8"))
if err != nil {
return errors.Trace(err)
}
err = varsutil.SetSystemVar(sessionVars, variable.CollationDatabase, types.NewStringDatum("utf8_unicode_ci"))
err = varsutil.SetSessionSystemVar(sessionVars, variable.CollationDatabase, types.NewStringDatum("utf8_unicode_ci"))
if err != nil {
return errors.Trace(err)
}
Expand Down
4 changes: 2 additions & 2 deletions executor/executor_set.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ func (e *SetExecutor) executeSet() error {
if err != nil {
return errors.Trace(err)
}
err = varsutil.SetSystemVar(sessionVars, name, value)
err = varsutil.SetSessionSystemVar(sessionVars, name, value)
if err != nil {
return errors.Trace(err)
}
Expand Down Expand Up @@ -168,7 +168,7 @@ func (e *SetExecutor) getVarValue(v *expression.VarAssignment, sysVar *variable.
if sysVar != nil {
value = types.NewStringDatum(sysVar.Value)
} else {
s, err1 := e.ctx.GetSessionVars().GlobalVarsAccessor.GetGlobalSysVar(strings.ToLower(v.Name))
s, err1 := varsutil.GetGlobalSystemVar(e.ctx.GetSessionVars(), v.Name)
if err1 != nil {
return value, errors.Trace(err1)
}
Expand Down
15 changes: 9 additions & 6 deletions executor/executor_set_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,16 +133,19 @@ func (s *testSuite) TestSetCharset(c *C) {
ctx := tk.Se.(context.Context)
sessionVars := ctx.GetSessionVars()
for _, v := range variable.SetNamesVariables {
sVar := varsutil.GetSystemVar(sessionVars, v)
c.Assert(sVar.GetString() != "utf8", IsTrue)
sVar, err := varsutil.GetSessionSystemVar(sessionVars, v)
c.Assert(err, IsNil)
c.Assert(sVar != "utf8", IsTrue)
}
tk.MustExec(`SET NAMES utf8`)
for _, v := range variable.SetNamesVariables {
sVar := varsutil.GetSystemVar(sessionVars, v)
c.Assert(sVar.GetString(), Equals, "utf8")
sVar, err := varsutil.GetSessionSystemVar(sessionVars, v)
c.Assert(err, IsNil)
c.Assert(sVar, Equals, "utf8")
}
sVar := varsutil.GetSystemVar(sessionVars, variable.CollationConnection)
c.Assert(sVar.GetString(), Equals, "utf8_general_ci")
sVar, err := varsutil.GetSessionSystemVar(sessionVars, variable.CollationConnection)
c.Assert(err, IsNil)
c.Assert(sVar, Equals, "utf8_general_ci")

// Issue 1523
tk.MustExec(`SET NAMES binary`)
Expand Down
23 changes: 5 additions & 18 deletions executor/show.go
Original file line number Diff line number Diff line change
Expand Up @@ -303,30 +303,17 @@ func (e *ShowExec) fetchShowCharset() error {

func (e *ShowExec) fetchShowVariables() error {
sessionVars := e.ctx.GetSessionVars()
globalVars := sessionVars.GlobalVarsAccessor
for _, v := range variable.SysVars {
var err error
var value string
if !e.GlobalScope {
// Try to get Session Scope variable value first.
sv := varsutil.GetSystemVar(sessionVars, v.Name)
if sv.IsNull() {
value, err = globalVars.GetGlobalSysVar(v.Name)
if err != nil {
return errors.Trace(err)
}
sv.SetString(value)
err = varsutil.SetSystemVar(sessionVars, v.Name, sv)
if err != nil {
return errors.Trace(err)
}
}
value = sv.GetString()
value, err = varsutil.GetSessionSystemVar(sessionVars, v.Name)
} else {
value, err = globalVars.GetGlobalSysVar(v.Name)
if err != nil {
return errors.Trace(err)
}
value, err = varsutil.GetGlobalSystemVar(sessionVars, v.Name)
}
if err != nil {
return errors.Trace(err)
}
row := &Row{Data: types.MakeDatums(v.Name, value)}
e.rows = append(e.rows, row)
Expand Down
9 changes: 6 additions & 3 deletions expression/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,9 +143,12 @@ func getSystemTimestamp(ctx context.Context) (time.Time, error) {

// check whether use timestamp varibale
sessionVars := ctx.GetSessionVars()
ts := varsutil.GetSystemVar(sessionVars, "timestamp")
if !ts.IsNull() && ts.GetString() != "" {
timestamp, err := ts.ToInt64(ctx.GetSessionVars().StmtCtx)
val, err := varsutil.GetSessionSystemVar(sessionVars, "timestamp")
if err != nil {
return value, errors.Trace(err)
}
if val != "" {
timestamp, err := types.StrToInt(sessionVars.StmtCtx, val)
if err != nil {
return time.Time{}, errors.Trace(err)
}
Expand Down
8 changes: 4 additions & 4 deletions expression/helper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,31 +36,31 @@ func (s *testExpressionSuite) TestGetTimeValue(c *C) {
c.Assert(timeValue.String(), Equals, "2012-12-12 00:00:00")
ctx := mock.NewContext()
sessionVars := ctx.GetSessionVars()
varsutil.SetSystemVar(sessionVars, "timestamp", types.NewStringDatum(""))
varsutil.SetSessionSystemVar(sessionVars, "timestamp", types.NewStringDatum(""))
v, err = GetTimeValue(ctx, "2012-12-12 00:00:00", mysql.TypeTimestamp, types.MinFsp)
c.Assert(err, IsNil)

c.Assert(v.Kind(), Equals, types.KindMysqlTime)
timeValue = v.GetMysqlTime()
c.Assert(timeValue.String(), Equals, "2012-12-12 00:00:00")

varsutil.SetSystemVar(sessionVars, "timestamp", types.NewStringDatum("0"))
varsutil.SetSessionSystemVar(sessionVars, "timestamp", types.NewStringDatum("0"))
v, err = GetTimeValue(ctx, "2012-12-12 00:00:00", mysql.TypeTimestamp, types.MinFsp)
c.Assert(err, IsNil)

c.Assert(v.Kind(), Equals, types.KindMysqlTime)
timeValue = v.GetMysqlTime()
c.Assert(timeValue.String(), Equals, "2012-12-12 00:00:00")

varsutil.SetSystemVar(sessionVars, "timestamp", types.Datum{})
varsutil.SetSessionSystemVar(sessionVars, "timestamp", types.Datum{})
v, err = GetTimeValue(ctx, "2012-12-12 00:00:00", mysql.TypeTimestamp, types.MinFsp)
c.Assert(err, IsNil)

c.Assert(v.Kind(), Equals, types.KindMysqlTime)
timeValue = v.GetMysqlTime()
c.Assert(timeValue.String(), Equals, "2012-12-12 00:00:00")

varsutil.SetSystemVar(sessionVars, "timestamp", types.NewStringDatum("1234"))
varsutil.SetSessionSystemVar(sessionVars, "timestamp", types.NewStringDatum("1234"))

tbl := []struct {
Expr interface{}
Expand Down
16 changes: 3 additions & 13 deletions infoschema/tables.go
Original file line number Diff line number Diff line change
Expand Up @@ -310,22 +310,12 @@ func dataForColltions() (records [][]types.Datum) {

func dataForSessionVar(ctx context.Context) (records [][]types.Datum, err error) {
sessionVars := ctx.GetSessionVars()
globalVars := sessionVars.GlobalVarsAccessor
for _, v := range variable.SysVars {
var value string
sv := varsutil.GetSystemVar(sessionVars, v.Name)
if sv.IsNull() {
value, err = globalVars.GetGlobalSysVar(v.Name)
if err != nil {
return nil, errors.Trace(err)
}
sv.SetString(value)
err = varsutil.SetSystemVar(sessionVars, v.Name, sv)
if err != nil {
return nil, errors.Trace(err)
}
value, err = varsutil.GetSessionSystemVar(sessionVars, v.Name)
if err != nil {
return nil, errors.Trace(err)
}
value = sv.GetString()
row := types.MakeDatums(v.Name, value)
records = append(records, row)
}
Expand Down
49 changes: 9 additions & 40 deletions plan/expression_rewriter.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import (
"github.com/pingcap/tidb/infoschema"
"github.com/pingcap/tidb/mysql"
"github.com/pingcap/tidb/parser/opcode"
"github.com/pingcap/tidb/sessionctx/variable"
"github.com/pingcap/tidb/sessionctx/varsutil"
"github.com/pingcap/tidb/util/types"
)
Expand Down Expand Up @@ -493,7 +492,6 @@ func (er *expressionRewriter) rewriteVariable(v *ast.VariableExpr) {
stkLen := len(er.ctxStack)
name := strings.ToLower(v.Name)
sessionVars := er.b.ctx.GetSessionVars()
globalVars := sessionVars.GlobalVarsAccessor
if !v.IsSystem {
if v.Value != nil {
er.ctxStack[stkLen-1], er.err = expression.NewFunction(ast.SetVar,
Expand All @@ -518,47 +516,18 @@ func (er *expressionRewriter) rewriteVariable(v *ast.VariableExpr) {
}
return
}

sysVar, ok := variable.SysVars[name]
if !ok {
// select null sys vars is not permitted
er.err = variable.UnknownSystemVar.GenByArgs(name)
return
}
if sysVar.Scope == variable.ScopeNone {
er.ctxStack = append(er.ctxStack, datumToConstant(types.NewDatum(sysVar.Value), mysql.TypeString))
return
}

var val string
var err error
if v.IsGlobal {
value, err := globalVars.GetGlobalSysVar(name)
if err != nil {
er.err = errors.Trace(err)
return
}
er.ctxStack = append(er.ctxStack, datumToConstant(types.NewDatum(value), mysql.TypeString))
return
val, err = varsutil.GetGlobalSystemVar(sessionVars, name)
} else {
val, err = varsutil.GetSessionSystemVar(sessionVars, name)
}
d := varsutil.GetSystemVar(sessionVars, name)
if d.IsNull() {
if sysVar.Scope&variable.ScopeGlobal == 0 {
d.SetString(sysVar.Value)
} else {
// Get global system variable and fill it in session.
globalVal, err := globalVars.GetGlobalSysVar(name)
if err != nil {
er.err = errors.Trace(err)
return
}
d.SetString(globalVal)
err = varsutil.SetSystemVar(sessionVars, name, d)
if err != nil {
er.err = errors.Trace(err)
return
}
}
if err != nil {
er.err = errors.Trace(err)
return
}
er.ctxStack = append(er.ctxStack, datumToConstant(d, mysql.TypeString))
er.ctxStack = append(er.ctxStack, datumToConstant(types.NewStringDatum(val), mysql.TypeString))
return
}

Expand Down
4 changes: 2 additions & 2 deletions session.go
Original file line number Diff line number Diff line change
Expand Up @@ -855,8 +855,8 @@ func (s *session) loadCommonGlobalVariablesIfNeeded() error {
break
}
varName := row.Data[0].GetString()
if d := varsutil.GetSystemVar(vars, varName); d.IsNull() {
varsutil.SetSystemVar(s.sessionVars, varName, row.Data[1])
if _, ok := vars.Systems[varName]; !ok {
varsutil.SetSessionSystemVar(s.sessionVars, varName, row.Data[1])
}
}
vars.CommonGlobalLoaded = true
Expand Down
7 changes: 5 additions & 2 deletions sessionctx/variable/sysvar.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,16 @@ func GetSysVar(name string) *SysVar {
const (
CodeUnknownStatusVar terror.ErrCode = 1
CodeUnknownSystemVar terror.ErrCode = 1193
CodeIncorrectScope terror.ErrCode = 1238
)

var tidbSysVars map[string]bool

// Variable errors
var (
UnknownStatusVar = terror.ClassVariable.New(CodeUnknownStatusVar, "unknown status variable")
UnknownSystemVar = terror.ClassVariable.New(CodeUnknownSystemVar, "unknown system variable '%s'")
UnknownStatusVar = terror.ClassVariable.New(CodeUnknownStatusVar, "unknown status variable")
UnknownSystemVar = terror.ClassVariable.New(CodeUnknownSystemVar, "unknown system variable '%s'")
ErrIncorrectScope = terror.ClassVariable.New(CodeIncorrectScope, "Incorrect variable scope")
)

func init() {
Expand All @@ -76,6 +78,7 @@ func init() {
// Register terror to mysql error map.
mySQLErrCodes := map[terror.ErrCode]uint16{
CodeUnknownSystemVar: mysql.ErrUnknownSystemVariable,
CodeIncorrectScope: mysql.ErrIncorrectGlobalLocalVar,
}
terror.ErrClassToMySQLCodes[terror.ClassVariable] = mySQLErrCodes

Expand Down
Loading

0 comments on commit 235a797

Please sign in to comment.