diff --git a/executor/show.go b/executor/show.go index 8858407cd3a55..cdb815dce0bcd 100644 --- a/executor/show.go +++ b/executor/show.go @@ -650,45 +650,35 @@ func (e *ShowExec) fetchShowMasterStatus() error { func (e *ShowExec) fetchShowVariables() (err error) { var ( - value string - ok bool - sessionVars = e.ctx.GetSessionVars() - unreachedVars = make([]string, 0, len(variable.GetSysVars())) + value string + sessionVars = e.ctx.GetSessionVars() ) - for _, v := range variable.GetSysVars() { - if !e.GlobalScope { - // For a session scope variable, - // 1. try to fetch value from SessionVars.Systems; - // 2. if this variable is session-only, fetch value from SysVars - // otherwise, fetch the value from table `mysql.Global_Variables`. - value, ok, err = variable.GetSessionOnlySysVars(sessionVars, v.Name) - } else { - // If the scope of a system variable is ScopeNone, - // it's a read-only variable, so we return the default value of it. - // Otherwise, we have to fetch the values from table `mysql.Global_Variables` for global variable names. - value, ok, err = variable.GetScopeNoneSystemVar(v.Name) - } - if err != nil { - return errors.Trace(err) - } - if !ok { - unreachedVars = append(unreachedVars, v.Name) - continue + if e.GlobalScope { + // Collect global scope variables, + // 1. Exclude the variables of ScopeSession in variable.SysVars; + // 2. If the variable is ScopeNone, it's a read-only variable, return the default value of it, + // otherwise, fetch the value from table `mysql.Global_Variables`. + for _, v := range variable.GetSysVars() { + if v.Scope != variable.ScopeSession { + value, err = variable.GetGlobalSystemVar(sessionVars, v.Name) + if err != nil { + return errors.Trace(err) + } + e.appendRow([]interface{}{v.Name, value}) + } } - e.appendRow([]interface{}{v.Name, value}) + return nil } - if len(unreachedVars) != 0 { - systemVars, err := sessionVars.GlobalVarsAccessor.GetAllSysVars() + + // Collect session scope variables, + // If it is a session only variable, use the default value defined in code, + // otherwise, fetch the value from table `mysql.Global_Variables`. + for _, v := range variable.GetSysVars() { + value, err = variable.GetSessionSystemVar(sessionVars, v.Name) if err != nil { return errors.Trace(err) } - for _, varName := range unreachedVars { - varValue, ok := systemVars[varName] - if !ok { - varValue = variable.GetSysVar(varName).Value - } - e.appendRow([]interface{}{varName, varValue}) - } + e.appendRow([]interface{}{v.Name, value}) } return nil } diff --git a/executor/show_test.go b/executor/show_test.go index 8c459e1d5ed00..4db8aa2b43c20 100644 --- a/executor/show_test.go +++ b/executor/show_test.go @@ -30,6 +30,7 @@ import ( "github.com/pingcap/tidb/privilege/privileges" "github.com/pingcap/tidb/session" "github.com/pingcap/tidb/sessionctx" + "github.com/pingcap/tidb/sessionctx/variable" "github.com/pingcap/tidb/types" "github.com/pingcap/tidb/util/testkit" "github.com/pingcap/tidb/util/testutil" @@ -1135,3 +1136,26 @@ func (s *testSerialSuite1) TestShowCreateTableWithIntegerDisplayLengthWarnings(c " `e` bigint DEFAULT NULL\n" + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin")) } + +func (s *testSuite5) TestShowVar(c *C) { + tk := testkit.NewTestKit(c, s.store) + var showSQL string + for _, v := range variable.GetSysVars() { + // When ScopeSession only. `show global variables` must return empty. + if v.Scope == variable.ScopeSession { + showSQL = "show variables like '" + v.Name + "'" + res := tk.MustQuery(showSQL) + c.Check(res.Rows(), HasLen, 1) + showSQL = "show global variables like '" + v.Name + "'" + res = tk.MustQuery(showSQL) + c.Check(res.Rows(), HasLen, 0) + } else { + showSQL = "show global variables like '" + v.Name + "'" + res := tk.MustQuery(showSQL) + c.Check(res.Rows(), HasLen, 1) + showSQL = "show variables like '" + v.Name + "'" + res = tk.MustQuery(showSQL) + c.Check(res.Rows(), HasLen, 1) + } + } +}