// Eval implements the Expression Eval interface. func (v *Variable) Eval(ctx context.Context, args map[interface{}]interface{}) (interface{}, error) { name := strings.ToLower(v.Name) sessionVars := variable.GetSessionVars(ctx) globalVars := variable.GetGlobalSysVarAccessor(ctx) if !v.IsSystem { // user vars if value, ok := sessionVars.Users[name]; ok { return value, nil } // select null user vars is permitted. return nil, nil } _, ok := variable.SysVars[name] if !ok { // select null sys vars is not permitted return nil, errors.Errorf("Unknown system variable '%s'", name) } if !v.IsGlobal { if value, ok := sessionVars.Systems[name]; ok { return value, nil } } value, err := globalVars.GetGlobalSysVar(ctx, name) if err != nil { return nil, errors.Trace(err) } return value, nil }
func (s *ShowPlan) fetchShowVariables(ctx context.Context) error { sessionVars := variable.GetSessionVars(ctx) globalVars := variable.GetGlobalSysVarAccessor(ctx) m := map[interface{}]interface{}{} for _, v := range variable.SysVars { if s.Pattern != nil { s.Pattern.Expr = expression.Value{Val: v.Name} } else if s.Where != nil { m[expression.ExprEvalIdentFunc] = func(name string) (interface{}, error) { if strings.EqualFold(name, "Variable_name") { return v.Name, nil } return nil, errors.Errorf("unknown field %s", name) } } match, err := s.evalCondition(ctx, m) if err != nil { return errors.Trace(err) } if !match { continue } var value string if !s.GlobalScope { // Try to get Session Scope variable value first. sv, ok := sessionVars.Systems[v.Name] if ok { value = sv } else { // If session scope variable is not set, get the global scope value. value, err = globalVars.GetGlobalSysVar(ctx, v.Name) if err != nil { return errors.Trace(err) } } } else { value, err = globalVars.GetGlobalSysVar(ctx, v.Name) if err != nil { return errors.Trace(err) } } row := &plan.Row{Data: []interface{}{v.Name, value}} s.rows = append(s.rows, row) } return nil }
// Exec implements the stmt.Statement Exec interface. func (s *SetStmt) Exec(ctx context.Context) (_ rset.Recordset, err error) { log.Debug("Set sys/user variables") sessionVars := variable.GetSessionVars(ctx) globalVars := variable.GetGlobalSysVarAccessor(ctx) for _, v := range s.Variables { // Variable is case insensitive, we use lower case. name := strings.ToLower(v.Name) if !v.IsSystem { // User variable. value, err := v.getValue(ctx) if err != nil { return nil, errors.Trace(err) } if value == nil { delete(sessionVars.Users, name) } else { sessionVars.Users[name] = fmt.Sprintf("%v", value) } return nil, nil } sysVar := variable.GetSysVar(name) if sysVar == nil { return nil, errors.Errorf("Unknown system variable '%s'", name) } if sysVar.Scope == variable.ScopeNone { return nil, errors.Errorf("Variable '%s' is a read only variable", name) } if v.IsGlobal { if sysVar.Scope&variable.ScopeGlobal > 0 { value, err := v.getValue(ctx) if err != nil { return nil, errors.Trace(err) } if value == nil { value = "" } svalue, err := types.ToString(value) if err != nil { return nil, errors.Trace(err) } err = globalVars.SetGlobalSysVar(ctx, name, svalue) return nil, errors.Trace(err) } return nil, errors.Errorf("Variable '%s' is a SESSION variable and can't be used with SET GLOBAL", name) } if sysVar.Scope&variable.ScopeSession > 0 { if value, err := v.getValue(ctx); err != nil { return nil, errors.Trace(err) } else if value == nil { sessionVars.Systems[name] = "" } else { sessionVars.Systems[name] = fmt.Sprintf("%v", value) } return nil, nil } return nil, errors.Errorf("Variable '%s' is a GLOBAL variable and should be set with SET GLOBAL", name) } return nil, nil }