From 686977e8316760a2e6efa8753ad5369598644536 Mon Sep 17 00:00:00 2001 From: Feng Liyuan Date: Tue, 18 Jun 2019 18:55:54 +0800 Subject: [PATCH 1/6] *: add a column describing memory usage for table information_schema.processlist Closes #10199 --- infoschema/tables.go | 3 ++- infoschema/tables_test.go | 15 +++++++++++++-- planner/core/logical_plans.go | 2 +- session/session.go | 2 +- util/processinfo.go | 8 +++++++- 5 files changed, 24 insertions(+), 6 deletions(-) diff --git a/infoschema/tables.go b/infoschema/tables.go index b998c368e2300..0e9c93df2a0be 100644 --- a/infoschema/tables.go +++ b/infoschema/tables.go @@ -543,6 +543,7 @@ var tableProcesslistCols = []columnInfo{ {"TIME", mysql.TypeLong, 7, mysql.NotNullFlag, 0, nil}, {"STATE", mysql.TypeVarchar, 7, 0, nil, nil}, {"INFO", mysql.TypeString, 512, 0, nil, nil}, + {"MEM", mysql.TypeLonglong, 21, 0, nil, nil}, } var tableTiDBIndexesCols = []columnInfo{ @@ -862,7 +863,7 @@ func dataForProcesslist(ctx sessionctx.Context) [][]types.Datum { continue } - rows := pi.ToRow(true) + rows := pi.ToRowWithMem(true) record := types.MakeDatums(rows...) records = append(records, record) } diff --git a/infoschema/tables_test.go b/infoschema/tables_test.go index 08da19bbfcd68..2fa74b5afec55 100644 --- a/infoschema/tables_test.go +++ b/infoschema/tables_test.go @@ -131,6 +131,7 @@ func (s *testTableSuite) TestInfoschemaFieldValue(c *C) { User: "root", Host: "127.0.0.1", Command: mysql.ComQuery, + StmtCtx: tk.Se.GetSessionVars().StmtCtx, } tk.Se.SetSessionManager(sm) tk.MustQuery("SELECT user,host,command FROM information_schema.processlist;").Check(testkit.Rows("root 127.0.0.1 Query")) @@ -342,7 +343,9 @@ func (s *testTableSuite) TestSomeTables(c *C) { DB: "information_schema", Command: byte(1), State: 1, - Info: "do something"} + Info: "do something", + StmtCtx: tk.Se.GetSessionVars().StmtCtx, + } sm.processInfoMap[2] = &util.ProcessInfo{ ID: 2, User: "user-2", @@ -350,9 +353,17 @@ func (s *testTableSuite) TestSomeTables(c *C) { DB: "test", Command: byte(2), State: 2, - Info: "do something"} + Info: "do something", + StmtCtx: tk.Se.GetSessionVars().StmtCtx, + } tk.Se.SetSessionManager(sm) tk.MustQuery("select * from information_schema.PROCESSLIST order by ID;").Check( + testkit.Rows("1 user-1 localhost information_schema Quit 9223372036 1 do something 0", + "2 user-2 localhost test Init DB 9223372036 2 do something 0")) + tk.MustQuery("SHOW PROCESSLIST;").Check( + testkit.Rows("1 user-1 localhost information_schema Quit 9223372036 1 do something", + "2 user-2 localhost test Init DB 9223372036 2 do something")) + tk.MustQuery("SHOW FULL PROCESSLIST;").Check( testkit.Rows("1 user-1 localhost information_schema Quit 9223372036 1 do something", "2 user-2 localhost test Init DB 9223372036 2 do something")) diff --git a/planner/core/logical_plans.go b/planner/core/logical_plans.go index 411937b4a315f..bc92c0241dcf6 100644 --- a/planner/core/logical_plans.go +++ b/planner/core/logical_plans.go @@ -322,7 +322,7 @@ type LogicalUnionScan struct { conditions []expression.Expression } -// DataSource represents a tablescan without condition push down. +// DataSource represents a tableScan without condition push down. type DataSource struct { logicalSchemaProducer diff --git a/session/session.go b/session/session.go index 8e00084fc1e4f..a68aa8ed4c131 100644 --- a/session/session.go +++ b/session/session.go @@ -98,7 +98,7 @@ var ( sessionExecuteParseDurationGeneral = metrics.SessionExecuteParseDuration.WithLabelValues(metrics.LblGeneral) ) -// Session context +// Session context, it is consistent with the lifecycle of a client connection. type Session interface { sessionctx.Context Status() uint16 // Flag of current status, such as autocommit. diff --git a/util/processinfo.go b/util/processinfo.go index 1fb103ac0e56b..8005a184f7992 100644 --- a/util/processinfo.go +++ b/util/processinfo.go @@ -41,7 +41,7 @@ type ProcessInfo struct { MaxExecutionTime uint64 } -// ToRow returns []interface{} for the row data of "show processlist" and "select * from infoschema.processlist". +// ToRow returns []interface{} for the row data of "show processlist". func (pi *ProcessInfo) ToRow(full bool) []interface{} { var info interface{} if pi.Info != nil { @@ -64,6 +64,12 @@ func (pi *ProcessInfo) ToRow(full bool) []interface{} { } } +// ToRowWithMem returns []interface{} for the row data of +// "select * from information_schema.processlist". +func (pi *ProcessInfo) ToRowWithMem(full bool) []interface{} { + return append(pi.ToRow(full), pi.StmtCtx.MemTracker.BytesConsumed()) +} + // SessionManager is an interface for session manage. Show processlist and // kill statement rely on this interface. type SessionManager interface { From 2636d3107cfba0a3def3de237768a77511345952 Mon Sep 17 00:00:00 2001 From: Feng Liyuan Date: Wed, 19 Jun 2019 15:46:42 +0800 Subject: [PATCH 2/6] util: more precise function name --- executor/show.go | 2 +- infoschema/tables.go | 2 +- util/misc_test.go | 69 ++++++++++++++++++++++++++++++++++++++++++++ util/processinfo.go | 10 +++---- 4 files changed, 76 insertions(+), 7 deletions(-) diff --git a/executor/show.go b/executor/show.go index 2b5553bc16727..2897a0ffae0b9 100644 --- a/executor/show.go +++ b/executor/show.go @@ -274,7 +274,7 @@ func (e *ShowExec) fetchShowProcessList() error { if !hasProcessPriv && pi.User != loginUser.Username { continue } - row := pi.ToRow(e.Full) + row := pi.ToRowForShow(e.Full) e.appendRow(row) } return nil diff --git a/infoschema/tables.go b/infoschema/tables.go index 0e9c93df2a0be..71a2701577eb9 100644 --- a/infoschema/tables.go +++ b/infoschema/tables.go @@ -863,7 +863,7 @@ func dataForProcesslist(ctx sessionctx.Context) [][]types.Datum { continue } - rows := pi.ToRowWithMem(true) + rows := pi.ToRow() record := types.MakeDatums(rows...) records = append(records, record) } diff --git a/util/misc_test.go b/util/misc_test.go index 1ae47e6e2f6a7..7c365a98fdb5a 100644 --- a/util/misc_test.go +++ b/util/misc_test.go @@ -14,10 +14,17 @@ package util import ( + "bytes" "time" . "github.com/pingcap/check" "github.com/pingcap/errors" + "github.com/pingcap/parser" + "github.com/pingcap/parser/mysql" + "github.com/pingcap/parser/terror" + "github.com/pingcap/tidb/sessionctx/stmtctx" + "github.com/pingcap/tidb/util/memory" + "github.com/pingcap/tidb/util/stringutil" "github.com/pingcap/tidb/util/testleak" ) @@ -113,3 +120,65 @@ func (s *testMiscSuite) TestCompatibleParseGCTime(c *C) { c.Assert(err, NotNil) } } + +func (s *testMiscSuite) TestBasicFunc(c *C) { + // Test for GetStack. + b := GetStack() + c.Assert(len(b) < 4096, IsTrue) + + // Test for WithRecovery. + var recover interface{} + WithRecovery(func() { + panic("test") + }, func(r interface{}) { + recover = r + }) + c.Assert(recover, Equals, "test") + + // Test for SyntaxError. + c.Assert(SyntaxError(nil), IsNil) + c.Assert(terror.ErrorEqual(SyntaxError(errors.New("test")), parser.ErrParse), IsTrue) + c.Assert(terror.ErrorEqual(SyntaxError(parser.ErrSyntax.GenWithStackByArgs()), parser.ErrSyntax), IsTrue) + + // Test for SyntaxWarn. + c.Assert(SyntaxWarn(nil), IsNil) + c.Assert(terror.ErrorEqual(SyntaxWarn(errors.New("test")), parser.ErrParse), IsTrue) + + // Test for ProcessInfo. + pi := ProcessInfo{ + ID: 1, + User: "test", + Host: "www", + DB: "db", + Command: mysql.ComSleep, + Plan: nil, + Time: time.Now(), + State: 1, + Info: "test", + StmtCtx: &stmtctx.StatementContext{ + MemTracker: memory.NewTracker(stringutil.StringerStr(""), -1), + }, + } + row := pi.ToRowForShow(false) + row2 := pi.ToRowForShow(true) + c.Assert(row, DeepEquals, row2) + c.Assert(len(row), Equals, 8) + c.Assert(row[0], Equals, pi.ID) + c.Assert(row[1], Equals, pi.User) + c.Assert(row[2], Equals, pi.Host) + c.Assert(row[3], Equals, pi.DB) + c.Assert(row[4], Equals, "Sleep") + c.Assert(row[5], Equals, uint64(0)) + c.Assert(row[6], Equals, "1") + c.Assert(row[7], Equals, "test") + + row3 := pi.ToRow() + c.Assert(row3[:8], DeepEquals, row) + c.Assert(row3[8], Equals, int64(0)) + + // Test for RandomBuf. + buf := RandomBuf(5) + c.Assert(len(buf), Equals, 5) + c.Assert(bytes.Contains(buf, []byte("$")), IsFalse) + c.Assert(bytes.Contains(buf, []byte{0}), IsFalse) +} diff --git a/util/processinfo.go b/util/processinfo.go index 8005a184f7992..b926bcac16dc1 100644 --- a/util/processinfo.go +++ b/util/processinfo.go @@ -41,8 +41,8 @@ type ProcessInfo struct { MaxExecutionTime uint64 } -// ToRow returns []interface{} for the row data of "show processlist". -func (pi *ProcessInfo) ToRow(full bool) []interface{} { +// ToRowForShow returns []interface{} for the row data of "show processlist". +func (pi *ProcessInfo) ToRowForShow(full bool) []interface{} { var info interface{} if pi.Info != nil { if full { @@ -64,10 +64,10 @@ func (pi *ProcessInfo) ToRow(full bool) []interface{} { } } -// ToRowWithMem returns []interface{} for the row data of +// ToRow returns []interface{} for the row data of // "select * from information_schema.processlist". -func (pi *ProcessInfo) ToRowWithMem(full bool) []interface{} { - return append(pi.ToRow(full), pi.StmtCtx.MemTracker.BytesConsumed()) +func (pi *ProcessInfo) ToRow() []interface{} { + return append(pi.ToRowForShow(true), pi.StmtCtx.MemTracker.BytesConsumed()) } // SessionManager is an interface for session manage. Show processlist and From 17549f73e56a3fbf98f7d73d9025f347d477a44f Mon Sep 17 00:00:00 2001 From: Feng Liyuan Date: Thu, 20 Jun 2019 10:40:33 +0800 Subject: [PATCH 3/6] adjust test --- infoschema/tables_test.go | 54 +++++---------------------------------- 1 file changed, 7 insertions(+), 47 deletions(-) diff --git a/infoschema/tables_test.go b/infoschema/tables_test.go index 2fa74b5afec55..37ec63627e92b 100644 --- a/infoschema/tables_test.go +++ b/infoschema/tables_test.go @@ -353,64 +353,24 @@ func (s *testTableSuite) TestSomeTables(c *C) { DB: "test", Command: byte(2), State: 2, - Info: "do something", - StmtCtx: tk.Se.GetSessionVars().StmtCtx, - } - tk.Se.SetSessionManager(sm) - tk.MustQuery("select * from information_schema.PROCESSLIST order by ID;").Check( - testkit.Rows("1 user-1 localhost information_schema Quit 9223372036 1 do something 0", - "2 user-2 localhost test Init DB 9223372036 2 do something 0")) - tk.MustQuery("SHOW PROCESSLIST;").Check( - testkit.Rows("1 user-1 localhost information_schema Quit 9223372036 1 do something", - "2 user-2 localhost test Init DB 9223372036 2 do something")) - tk.MustQuery("SHOW FULL PROCESSLIST;").Check( - testkit.Rows("1 user-1 localhost information_schema Quit 9223372036 1 do something", - "2 user-2 localhost test Init DB 9223372036 2 do something")) - - sm = &mockSessionManager{make(map[uint64]*util.ProcessInfo, 2)} - sm.processInfoMap[1] = &util.ProcessInfo{ - ID: 1, - User: "user-1", - Host: "localhost", - DB: "information_schema", - Command: byte(1), - State: 1, - Info: nil, - StmtCtx: tk.Se.GetSessionVars().StmtCtx, - } - sm.processInfoMap[2] = &util.ProcessInfo{ - ID: 2, - User: "user-2", - Host: "localhost", - DB: nil, - Command: byte(2), - State: 2, Info: strings.Repeat("x", 101), StmtCtx: tk.Se.GetSessionVars().StmtCtx, } tk.Se.SetSessionManager(sm) - tk.MustQuery("select * from information_schema.PROCESSLIST order by ID;").Check( + tk.MustQuery("select * from information_schema.PROCESSLIST order by ID;").Sort().Check( testkit.Rows( - fmt.Sprintf("1 user-1 localhost information_schema Quit 9223372036 1 %s", ""), - fmt.Sprintf("2 user-2 localhost Init DB 9223372036 2 %s", strings.Repeat("x", 101)), + fmt.Sprintf("1 user-1 localhost information_schema Quit 9223372036 1 %s 0", "do something"), + fmt.Sprintf("2 user-2 localhost test Init DB 9223372036 2 %s 0", strings.Repeat("x", 101)), )) tk.MustQuery("SHOW PROCESSLIST;").Sort().Check( testkit.Rows( - fmt.Sprintf("1 user-1 localhost information_schema Quit 9223372036 1 %s", ""), - fmt.Sprintf("2 user-2 localhost Init DB 9223372036 2 %s", strings.Repeat("x", 100)), + fmt.Sprintf("1 user-1 localhost information_schema Quit 9223372036 1 %s", "do something"), + fmt.Sprintf("2 user-2 localhost test Init DB 9223372036 2 %s", strings.Repeat("x", 100)), )) tk.MustQuery("SHOW FULL PROCESSLIST;").Sort().Check( testkit.Rows( - fmt.Sprintf("1 user-1 localhost information_schema Quit 9223372036 1 %s", ""), - fmt.Sprintf("2 user-2 localhost Init DB 9223372036 2 %s", strings.Repeat("x", 101)), - )) - tk.MustQuery("select * from information_schema.PROCESSLIST where db is null;").Check( - testkit.Rows( - fmt.Sprintf("2 user-2 localhost Init DB 9223372036 2 %s", strings.Repeat("x", 101)), - )) - tk.MustQuery("select * from information_schema.PROCESSLIST where Info is null;").Check( - testkit.Rows( - fmt.Sprintf("1 user-1 localhost information_schema Quit 9223372036 1 %s", ""), + fmt.Sprintf("1 user-1 localhost information_schema Quit 9223372036 1 %s", "do something"), + fmt.Sprintf("2 user-2 localhost test Init DB 9223372036 2 %s", strings.Repeat("x", 101)), )) } From 3078f54c110bcfc1d1a518d2bcc2a7ed5f4c1708 Mon Sep 17 00:00:00 2001 From: Feng Liyuan Date: Thu, 20 Jun 2019 10:44:17 +0800 Subject: [PATCH 4/6] adjust comment --- util/processinfo.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/util/processinfo.go b/util/processinfo.go index b926bcac16dc1..b09edf810b184 100644 --- a/util/processinfo.go +++ b/util/processinfo.go @@ -41,7 +41,7 @@ type ProcessInfo struct { MaxExecutionTime uint64 } -// ToRowForShow returns []interface{} for the row data of "show processlist". +// ToRowForShow returns []interface{} for the row data of "SHOW [FULL] PROCESSLIST". func (pi *ProcessInfo) ToRowForShow(full bool) []interface{} { var info interface{} if pi.Info != nil { @@ -65,7 +65,7 @@ func (pi *ProcessInfo) ToRowForShow(full bool) []interface{} { } // ToRow returns []interface{} for the row data of -// "select * from information_schema.processlist". +// "SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST". func (pi *ProcessInfo) ToRow() []interface{} { return append(pi.ToRowForShow(true), pi.StmtCtx.MemTracker.BytesConsumed()) } From 07b8acae7a0cce6b568f469d0628d690912010f3 Mon Sep 17 00:00:00 2001 From: Feng Liyuan Date: Thu, 17 Oct 2019 20:44:11 +0800 Subject: [PATCH 5/6] fix test --- infoschema/tables_test.go | 51 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/infoschema/tables_test.go b/infoschema/tables_test.go index 37ec63627e92b..1b2d6b194708a 100644 --- a/infoschema/tables_test.go +++ b/infoschema/tables_test.go @@ -18,6 +18,7 @@ import ( "os" "strconv" "strings" + "time" . "github.com/pingcap/check" "github.com/pingcap/parser/auth" @@ -359,8 +360,8 @@ func (s *testTableSuite) TestSomeTables(c *C) { tk.Se.SetSessionManager(sm) tk.MustQuery("select * from information_schema.PROCESSLIST order by ID;").Sort().Check( testkit.Rows( - fmt.Sprintf("1 user-1 localhost information_schema Quit 9223372036 1 %s 0", "do something"), - fmt.Sprintf("2 user-2 localhost test Init DB 9223372036 2 %s 0", strings.Repeat("x", 101)), + fmt.Sprintf("1 user-1 localhost information_schema Quit 9223372036 1 %s 0 ", "do something"), + fmt.Sprintf("2 user-2 localhost test Init DB 9223372036 2 %s 0 ", strings.Repeat("x", 101)), )) tk.MustQuery("SHOW PROCESSLIST;").Sort().Check( testkit.Rows( @@ -372,6 +373,52 @@ func (s *testTableSuite) TestSomeTables(c *C) { fmt.Sprintf("1 user-1 localhost information_schema Quit 9223372036 1 %s", "do something"), fmt.Sprintf("2 user-2 localhost test Init DB 9223372036 2 %s", strings.Repeat("x", 101)), )) + + sm = &mockSessionManager{make(map[uint64]*util.ProcessInfo, 2)} + sm.processInfoMap[1] = &util.ProcessInfo{ + ID: 1, + User: "user-1", + Host: "localhost", + DB: "information_schema", + Command: byte(1), + State: 1, + StmtCtx: tk.Se.GetSessionVars().StmtCtx, + } + sm.processInfoMap[2] = &util.ProcessInfo{ + ID: 2, + User: "user-2", + Host: "localhost", + Command: byte(2), + State: 2, + Info: strings.Repeat("x", 101), + StmtCtx: tk.Se.GetSessionVars().StmtCtx, + CurTxnStartTS: 410090409861578752, + } + tk.Se.SetSessionManager(sm) + tk.Se.GetSessionVars().TimeZone = time.UTC + tk.MustQuery("select * from information_schema.PROCESSLIST order by ID;").Check( + testkit.Rows( + fmt.Sprintf("1 user-1 localhost information_schema Quit 9223372036 1 %s 0 ", ""), + fmt.Sprintf("2 user-2 localhost Init DB 9223372036 2 %s 0 07-29 03:26:05.158(410090409861578752)", strings.Repeat("x", 101)), + )) + tk.MustQuery("SHOW PROCESSLIST;").Sort().Check( + testkit.Rows( + fmt.Sprintf("1 user-1 localhost information_schema Quit 9223372036 1 %s", ""), + fmt.Sprintf("2 user-2 localhost Init DB 9223372036 2 %s", strings.Repeat("x", 100)), + )) + tk.MustQuery("SHOW FULL PROCESSLIST;").Sort().Check( + testkit.Rows( + fmt.Sprintf("1 user-1 localhost information_schema Quit 9223372036 1 %s", ""), + fmt.Sprintf("2 user-2 localhost Init DB 9223372036 2 %s", strings.Repeat("x", 101)), + )) + tk.MustQuery("select * from information_schema.PROCESSLIST where db is null;").Check( + testkit.Rows( + fmt.Sprintf("2 user-2 localhost Init DB 9223372036 2 %s 0 07-29 03:26:05.158(410090409861578752)", strings.Repeat("x", 101)), + )) + tk.MustQuery("select * from information_schema.PROCESSLIST where Info is null;").Check( + testkit.Rows( + fmt.Sprintf("1 user-1 localhost information_schema Quit 9223372036 1 %s 0 ", ""), + )) } func (s *testTableSuite) TestSchemataCharacterSet(c *C) { From 5f915f9297282783577d459709cef396e4010730 Mon Sep 17 00:00:00 2001 From: Feng Liyuan Date: Thu, 17 Oct 2019 20:55:54 +0800 Subject: [PATCH 6/6] fix test --- infoschema/tables_test.go | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/infoschema/tables_test.go b/infoschema/tables_test.go index 1b2d6b194708a..2a7cacd591a53 100644 --- a/infoschema/tables_test.go +++ b/infoschema/tables_test.go @@ -18,7 +18,6 @@ import ( "os" "strconv" "strings" - "time" . "github.com/pingcap/check" "github.com/pingcap/parser/auth" @@ -360,8 +359,8 @@ func (s *testTableSuite) TestSomeTables(c *C) { tk.Se.SetSessionManager(sm) tk.MustQuery("select * from information_schema.PROCESSLIST order by ID;").Sort().Check( testkit.Rows( - fmt.Sprintf("1 user-1 localhost information_schema Quit 9223372036 1 %s 0 ", "do something"), - fmt.Sprintf("2 user-2 localhost test Init DB 9223372036 2 %s 0 ", strings.Repeat("x", 101)), + fmt.Sprintf("1 user-1 localhost information_schema Quit 9223372036 1 %s 0", "do something"), + fmt.Sprintf("2 user-2 localhost test Init DB 9223372036 2 %s 0", strings.Repeat("x", 101)), )) tk.MustQuery("SHOW PROCESSLIST;").Sort().Check( testkit.Rows( @@ -382,24 +381,24 @@ func (s *testTableSuite) TestSomeTables(c *C) { DB: "information_schema", Command: byte(1), State: 1, + Info: nil, StmtCtx: tk.Se.GetSessionVars().StmtCtx, } sm.processInfoMap[2] = &util.ProcessInfo{ - ID: 2, - User: "user-2", - Host: "localhost", - Command: byte(2), - State: 2, - Info: strings.Repeat("x", 101), - StmtCtx: tk.Se.GetSessionVars().StmtCtx, - CurTxnStartTS: 410090409861578752, + ID: 2, + User: "user-2", + Host: "localhost", + DB: nil, + Command: byte(2), + State: 2, + Info: strings.Repeat("x", 101), + StmtCtx: tk.Se.GetSessionVars().StmtCtx, } tk.Se.SetSessionManager(sm) - tk.Se.GetSessionVars().TimeZone = time.UTC tk.MustQuery("select * from information_schema.PROCESSLIST order by ID;").Check( testkit.Rows( - fmt.Sprintf("1 user-1 localhost information_schema Quit 9223372036 1 %s 0 ", ""), - fmt.Sprintf("2 user-2 localhost Init DB 9223372036 2 %s 0 07-29 03:26:05.158(410090409861578752)", strings.Repeat("x", 101)), + fmt.Sprintf("1 user-1 localhost information_schema Quit 9223372036 1 %s 0", ""), + fmt.Sprintf("2 user-2 localhost Init DB 9223372036 2 %s 0", strings.Repeat("x", 101)), )) tk.MustQuery("SHOW PROCESSLIST;").Sort().Check( testkit.Rows( @@ -413,11 +412,11 @@ func (s *testTableSuite) TestSomeTables(c *C) { )) tk.MustQuery("select * from information_schema.PROCESSLIST where db is null;").Check( testkit.Rows( - fmt.Sprintf("2 user-2 localhost Init DB 9223372036 2 %s 0 07-29 03:26:05.158(410090409861578752)", strings.Repeat("x", 101)), + fmt.Sprintf("2 user-2 localhost Init DB 9223372036 2 %s 0", strings.Repeat("x", 101)), )) tk.MustQuery("select * from information_schema.PROCESSLIST where Info is null;").Check( testkit.Rows( - fmt.Sprintf("1 user-1 localhost information_schema Quit 9223372036 1 %s 0 ", ""), + fmt.Sprintf("1 user-1 localhost information_schema Quit 9223372036 1 %s 0", ""), )) }