diff --git a/sessionctx/variable/session.go b/sessionctx/variable/session.go index b903090472b76..9b8eeae24ca0e 100644 --- a/sessionctx/variable/session.go +++ b/sessionctx/variable/session.go @@ -2536,7 +2536,12 @@ func (s *SessionVars) SetSystemVarWithOldValAsRet(name string, val string) (stri if err != nil { return "", err } - oldV := sv.Value + // The map s.systems[sv.Name] is lazy initialized. If we directly read it, we might read empty result. + // Since this code path is not a hot path, we directly call GetSessionOrGlobalSystemVar to get the value safely. + oldV, err := s.GetSessionOrGlobalSystemVar(context.Background(), sv.Name) + if err != nil { + return "", err + } return oldV, sv.SetSessionFromHook(s, val) } diff --git a/sessionctx/variable/setvar_test.go b/sessionctx/variable/setvar_test.go index eb8eaa11e15b2..4e5db8b274ff9 100644 --- a/sessionctx/variable/setvar_test.go +++ b/sessionctx/variable/setvar_test.go @@ -110,6 +110,26 @@ func TestSetVarNonStringOrEnum(t *testing.T) { tk.MustQuery(fmt.Sprintf("select @@%v", c.varName)).Check(r) } } + + tk.MustQuery("select @@max_execution_time").Check(testkit.Rows("0")) + tk.MustExec("set @@max_execution_time=1000") + tk.MustQuery("select @@max_execution_time").Check(testkit.Rows("1000")) + tk.MustQuery("select /*+ set_var(max_execution_time=100) */ @@max_execution_time").Check(testkit.Rows("100")) + // The value is the changed value 1000, not the default value 0. + tk.MustQuery("select @@max_execution_time").Check(testkit.Rows("1000")) + + tk.MustExec("set @@global.max_execution_time=1000") + + tk2 := testkit.NewTestKit(t, store) + tk2.MustQuery("select @@max_execution_time").Check(testkit.Rows("1000")) + tk2.MustQuery("select /*+ set_var(max_execution_time=100) */ @@max_execution_time").Check(testkit.Rows("100")) + // The value is the global value 1000, not the default value 0. + tk2.MustQuery("select @@max_execution_time").Check(testkit.Rows("1000")) + tk2.MustExec("set @@max_execution_time=2000") + tk2.MustQuery("select @@max_execution_time").Check(testkit.Rows("2000")) + tk2.MustQuery("select /*+ set_var(max_execution_time=100) */ @@max_execution_time").Check(testkit.Rows("100")) + // The value is the changed value 2000, not the default value 0 or the global value 1000. + tk2.MustQuery("select @@max_execution_time").Check(testkit.Rows("2000")) } func TestSetVarStringOrEnum(t *testing.T) {