Example #1
0
// 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
}
Example #2
0
File: show.go Project: netroby/tidb
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
}
Example #3
0
File: set.go Project: netroby/tidb
// 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
}