Пример #1
0
// LoadCommonGlobalVariableIfNeeded loads and applies commonly used global variables for the session
// right before creating a transaction for the first time.
func (s *session) loadCommonGlobalVariablesIfNeeded() error {
	vars := s.sessionVars
	if vars.CommonGlobalLoaded {
		return nil
	}
	if s.Value(context.Initing) != nil {
		// When running bootstrap or upgrade, we should not access global storage.
		return nil
	}
	// Set the variable to true to prevent cyclic recursive call.
	vars.CommonGlobalLoaded = true
	rs, err := s.ExecRestrictedSQL(s, loadCommonGlobalVarsSQL)
	if err != nil {
		vars.CommonGlobalLoaded = false
		log.Errorf("Failed to load common global variables.")
		return errors.Trace(err)
	}
	for {
		row, err1 := rs.Next()
		if err1 != nil {
			vars.CommonGlobalLoaded = false
			log.Errorf("Failed to load common global variables.")
			return errors.Trace(err1)
		}
		if row == nil {
			break
		}
		varName := row.Data[0].GetString()
		if d := varsutil.GetSystemVar(vars, varName); d.IsNull() {
			varsutil.SetSystemVar(s.sessionVars, varName, row.Data[1])
		}
	}
	vars.CommonGlobalLoaded = true
	return nil
}
Пример #2
0
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()
		} else {
			value, err = globalVars.GetGlobalSysVar(v.Name)
			if err != nil {
				return errors.Trace(err)
			}
		}
		row := &Row{Data: types.MakeDatums(v.Name, value)}
		e.rows = append(e.rows, row)
	}
	return nil
}
Пример #3
0
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 = sv.GetString()
		row := types.MakeDatums(v.Name, value)
		records = append(records, row)
	}
	return
}
Пример #4
0
func (e *Evaluator) variable(v *ast.VariableExpr) bool {
	name := strings.ToLower(v.Name)
	sessionVars := e.ctx.GetSessionVars()
	globalVars := sessionVars.GlobalVarsAccessor
	if !v.IsSystem {
		if v.Value != nil && !v.Value.GetDatum().IsNull() {
			strVal, err := v.Value.GetDatum().ToString()
			if err != nil {
				e.err = errors.Trace(err)
				return false
			}
			sessionVars.Users[name] = strings.ToLower(strVal)
			v.SetString(strVal)
			return true
		}
		// user vars
		if value, ok := sessionVars.Users[name]; ok {
			v.SetString(value)
			return true
		}
		// select null user vars is permitted.
		v.SetNull()
		return true
	}

	sysVar, ok := variable.SysVars[name]
	if !ok {
		// select null sys vars is not permitted
		e.err = variable.UnknownSystemVar.GenByArgs(name)
		return false
	}
	if sysVar.Scope == variable.ScopeNone {
		v.SetString(sysVar.Value)
		return true
	}

	if !v.IsGlobal {
		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 {
					e.err = errors.Trace(err)
					return false
				}
				d.SetString(globalVal)
				err = varsutil.SetSystemVar(sessionVars, name, d)
				if err != nil {
					e.err = errors.Trace(err)
					return false
				}
			}
		}
		v.SetDatum(d)
		return true
	}
	value, err := globalVars.GetGlobalSysVar(name)
	if err != nil {
		e.err = errors.Trace(err)
		return false
	}

	v.SetString(value)
	return true
}
Пример #5
0
func (e *SetExecutor) executeSet() error {
	sessionVars := e.ctx.GetSessionVars()
	for _, v := range e.vars {
		// Variable is case insensitive, we use lower case.
		if v.Name == ast.SetNames {
			// This is set charset stmt.
			cs := v.Expr.(*expression.Constant).Value.GetString()
			var co string
			if v.ExtendValue != nil {
				co = v.ExtendValue.Value.GetString()
			}
			err := e.setCharset(cs, co)
			if err != nil {
				return errors.Trace(err)
			}
			continue
		}
		name := strings.ToLower(v.Name)
		if !v.IsSystem {
			// Set user variable.
			value, err := v.Expr.Eval(nil, e.ctx)
			if err != nil {
				return errors.Trace(err)
			}

			if value.IsNull() {
				delete(sessionVars.Users, name)
			} else {
				svalue, err1 := value.ToString()
				if err1 != nil {
					return errors.Trace(err1)
				}
				sessionVars.Users[name] = fmt.Sprintf("%v", svalue)
			}
			continue
		}

		// Set system variable
		sysVar := variable.GetSysVar(name)
		if sysVar == nil {
			return variable.UnknownSystemVar.GenByArgs(name)
		}
		if sysVar.Scope == variable.ScopeNone {
			return errors.Errorf("Variable '%s' is a read only variable", name)
		}
		if v.IsGlobal {
			// Set global scope system variable.
			if sysVar.Scope&variable.ScopeGlobal == 0 {
				return errors.Errorf("Variable '%s' is a SESSION variable and can't be used with SET GLOBAL", name)
			}
			value, err := e.getVarValue(v, sysVar)
			if err != nil {
				return errors.Trace(err)
			}
			if value.IsNull() {
				value.SetString("")
			}
			svalue, err := value.ToString()
			if err != nil {
				return errors.Trace(err)
			}
			err = sessionVars.GlobalVarsAccessor.SetGlobalSysVar(name, svalue)
			if err != nil {
				return errors.Trace(err)
			}
		} else {
			// Set session scope system variable.
			if sysVar.Scope&variable.ScopeSession == 0 {
				return errors.Errorf("Variable '%s' is a GLOBAL variable and should be set with SET GLOBAL", name)
			}
			value, err := e.getVarValue(v, nil)
			if err != nil {
				return errors.Trace(err)
			}
			err = varsutil.SetSystemVar(sessionVars, name, value)
			if err != nil {
				return errors.Trace(err)
			}
			e.loadSnapshotInfoSchemaIfNeeded(name)
			log.Infof("[%d] set system variable %s = %s", sessionVars.ConnectionID, name, value.GetString())
		}
	}
	return nil
}
Пример #6
0
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,
				er.ctxStack[stkLen-1].GetType(),
				datumToConstant(types.NewDatum(name), mysql.TypeString),
				er.ctxStack[stkLen-1])
			return
		}
		if _, ok := sessionVars.Users[name]; ok {
			f, err := expression.NewFunction(ast.GetVar,
				// TODO: Here is wrong, the sessionVars should store a name -> Datum map. Will fix it later.
				types.NewFieldType(mysql.TypeString),
				datumToConstant(types.NewStringDatum(name), mysql.TypeString))
			if err != nil {
				er.err = errors.Trace(err)
				return
			}
			er.ctxStack = append(er.ctxStack, f)
		} else {
			// select null user vars is permitted.
			er.ctxStack = append(er.ctxStack, &expression.Constant{RetType: types.NewFieldType(mysql.TypeNull)})
		}
		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
	}

	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
	}
	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
			}
		}
	}
	er.ctxStack = append(er.ctxStack, datumToConstant(d, mysql.TypeString))
	return
}
Пример #7
0
func (s *testEvaluatorSuite) TestGetTimeValue(c *C) {
	defer testleak.AfterTest(c)()
	v, err := GetTimeValue(nil, "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")
	ctx := mock.NewContext()
	sessionVars := ctx.GetSessionVars()
	varsutil.SetSystemVar(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"))
	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{})
	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"))

	tbl := []struct {
		Expr interface{}
		Ret  interface{}
	}{
		{"2012-12-12 00:00:00", "2012-12-12 00:00:00"},
		{CurrentTimestamp, time.Unix(1234, 0).Format(types.TimeFormat)},
		{ZeroTimestamp, "0000-00-00 00:00:00"},
		{ast.NewValueExpr("2012-12-12 00:00:00"), "2012-12-12 00:00:00"},
		{ast.NewValueExpr(int64(0)), "0000-00-00 00:00:00"},
		{ast.NewValueExpr(nil), nil},
		{&ast.FuncCallExpr{FnName: model.NewCIStr(CurrentTimestamp)}, CurrentTimestamp},
		{&ast.UnaryOperationExpr{Op: opcode.Minus, V: ast.NewValueExpr(int64(0))}, "0000-00-00 00:00:00"},
	}

	for i, t := range tbl {
		comment := Commentf("expr: %d", i)
		v, err := GetTimeValue(ctx, t.Expr, mysql.TypeTimestamp, types.MinFsp)
		c.Assert(err, IsNil)

		switch v.Kind() {
		case types.KindMysqlTime:
			c.Assert(v.GetMysqlTime().String(), DeepEquals, t.Ret, comment)
		default:
			c.Assert(v.GetValue(), DeepEquals, t.Ret, comment)
		}
	}

	errTbl := []struct {
		Expr interface{}
	}{
		{"2012-13-12 00:00:00"},
		{ast.NewValueExpr("2012-13-12 00:00:00")},
		{ast.NewValueExpr(int64(1))},
		{&ast.FuncCallExpr{FnName: model.NewCIStr("xxx")}},
		{&ast.UnaryOperationExpr{Op: opcode.Minus, V: ast.NewValueExpr(int64(1))}},
	}

	for _, t := range errTbl {
		_, err := GetTimeValue(ctx, t.Expr, mysql.TypeTimestamp, types.MinFsp)
		c.Assert(err, NotNil)
	}
}