@@ -37,6 +37,7 @@ import (
3737 "github.com/pingcap/tidb/pkg/sessionctx"
3838 "github.com/pingcap/tidb/pkg/sessionctx/vardef"
3939 "github.com/pingcap/tidb/pkg/sessionctx/variable"
40+ "github.com/pingcap/tidb/pkg/testkit/testutil"
4041 "github.com/pingcap/tidb/pkg/types"
4142 "github.com/pingcap/tidb/pkg/util"
4243 "github.com/pingcap/tidb/pkg/util/logutil"
@@ -191,7 +192,7 @@ select * from t;`
191192 `0.1,0.2,0.03,127.0.0.1:20160,0.05,0.6,0.8,0.0.0.0:20160,70724,23333,65536,0,0,0,30000,3000,10000,1000,500000,500005,300000,300005,0,0,,` +
192193 `Cop_backoff_regionMiss_total_times: 200 Cop_backoff_regionMiss_total_time: 0.2 Cop_backoff_regionMiss_max_time: 0.2 Cop_backoff_regionMiss_max_addr: 127.0.0.1 Cop_backoff_regionMiss_avg_time: 0.2 Cop_backoff_regionMiss_p90_time: 0.2 Cop_backoff_rpcPD_total_times: 200 Cop_backoff_rpcPD_total_time: 0.2 Cop_backoff_rpcPD_max_time: 0.2 Cop_backoff_rpcPD_max_addr: 127.0.0.1 Cop_backoff_rpcPD_avg_time: 0.2 Cop_backoff_rpcPD_p90_time: 0.2 Cop_backoff_rpcTiKV_total_times: 200 Cop_backoff_rpcTiKV_total_time: 0.2 Cop_backoff_rpcTiKV_max_time: 0.2 Cop_backoff_rpcTiKV_max_addr: 127.0.0.1 Cop_backoff_rpcTiKV_avg_time: 0.2 Cop_backoff_rpcTiKV_p90_time: 0.2,` +
193194 `0,0,1,0,1,1,0,default,2.158,2.123,0.05,0.01,0.021,1,1,,,60e9378c746d9a2be1c791047e008967cf252eb6de9167ad3aa6098fa2d523f4,` +
194- `,update t set i = 1;,select * from t;`
195+ `,update t set i = 1;,null, select * from t;`
195196 require .Equal (t , expectRecordString , recordString )
196197
197198 // Issue 20928
@@ -214,7 +215,7 @@ select * from t;`
214215 `0.1,0.2,0.03,127.0.0.1:20160,0.05,0.6,0.8,0.0.0.0:20160,70724,23333,65536,0,0,0,30000,3000,10000,1000,500000,500005,300000,300005,0,0,,` +
215216 `Cop_backoff_regionMiss_total_times: 200 Cop_backoff_regionMiss_total_time: 0.2 Cop_backoff_regionMiss_max_time: 0.2 Cop_backoff_regionMiss_max_addr: 127.0.0.1 Cop_backoff_regionMiss_avg_time: 0.2 Cop_backoff_regionMiss_p90_time: 0.2 Cop_backoff_rpcPD_total_times: 200 Cop_backoff_rpcPD_total_time: 0.2 Cop_backoff_rpcPD_max_time: 0.2 Cop_backoff_rpcPD_max_addr: 127.0.0.1 Cop_backoff_rpcPD_avg_time: 0.2 Cop_backoff_rpcPD_p90_time: 0.2 Cop_backoff_rpcTiKV_total_times: 200 Cop_backoff_rpcTiKV_total_time: 0.2 Cop_backoff_rpcTiKV_max_time: 0.2 Cop_backoff_rpcTiKV_max_addr: 127.0.0.1 Cop_backoff_rpcTiKV_avg_time: 0.2 Cop_backoff_rpcTiKV_p90_time: 0.2,` +
216217 `0,0,1,0,1,1,0,default,2.158,2.123,0.05,0.01,0.021,1,1,,,60e9378c746d9a2be1c791047e008967cf252eb6de9167ad3aa6098fa2d523f4,` +
217- `,update t set i = 1;,select * from t;`
218+ `,update t set i = 1;,null, select * from t;`
218219 require .Equal (t , expectRecordString , recordString )
219220
220221 // fix sql contain '# ' bug
@@ -284,6 +285,57 @@ select * from t;
284285 require .Equal (t , value , "[t:i: a]" )
285286}
286287
288+ func TestParseSlowLogSessionConnectAttrs (t * testing.T ) {
289+ // Slow log entry that includes Session_connect_attrs JSON.
290+ slowLogStr := `# Time: 2019-04-28T15:24:04.309074+08:00
291+ # Txn_start_ts: 405888132465033227
292+ # User@Host: root[root] @ localhost [127.0.0.1]
293+ # Query_time: 0.216905
294+ # Digest: 42a1c8aae6f133e934d4bf0147491709a8812ea05ff8819ec522780fe657b772
295+ # Is_internal: false
296+ # Succ: true
297+ ` + testutil .DefaultSessionConnectAttrsSlowLogLine () + `
298+ # Prev_stmt: begin;
299+ select * from t;
300+ `
301+ loc , err := time .LoadLocation ("Asia/Shanghai" )
302+ require .NoError (t , err )
303+ ctx := mock .NewContext ()
304+ ctx .ResetSessionAndStmtTimeZone (loc )
305+
306+ // Use the retriever directly (without initialize) to avoid reading
307+ // from actual slow log files on disk, which can produce extra rows.
308+ retriever , err := newSlowQueryRetriever ()
309+ require .NoError (t , err )
310+ retriever .columnValueFactoryMap = make (map [string ]slowQueryColumnValueFactory , len (retriever .outputCols ))
311+ for idx , col := range retriever .outputCols {
312+ factory , err := getColumnValueFactoryByName (col .Name .O , idx )
313+ require .NoError (t , err )
314+ require .NotNil (t , factory , "column %s should have a factory" , col .Name .O )
315+ retriever .columnValueFactoryMap [col .Name .O ] = factory
316+ }
317+
318+ reader := bufio .NewReader (bytes .NewBufferString (slowLogStr ))
319+ rows , err := parseLog (retriever , ctx , reader )
320+ require .NoError (t , err )
321+ require .Len (t , rows , 1 )
322+
323+ // Find the Session_connect_attrs column.
324+ colIdx := - 1
325+ for i , col := range retriever .outputCols {
326+ if col .Name .L == strings .ToLower (variable .SlowLogSessionConnectAttrs ) {
327+ colIdx = i
328+ break
329+ }
330+ }
331+ require .NotEqual (t , - 1 , colIdx , "Session_connect_attrs column should exist" )
332+
333+ // Verify the parsed JSON contains the expected keys.
334+ bj := rows [0 ][colIdx ].GetMysqlJSON ()
335+ bjStr := bj .String ()
336+ testutil .RequireContainsDefaultSessionConnectAttrs (t , bjStr )
337+ }
338+
287339// It changes variable.MaxOfMaxAllowedPacket, so must be stayed in SerialSuite.
288340func TestParseSlowLogFileSerial (t * testing.T ) {
289341 loc , err := time .LoadLocation ("Asia/Shanghai" )
0 commit comments