@@ -56,97 +56,90 @@ type stmtSummaryRetriever struct {
56
56
table * model.TableInfo
57
57
columns []* model.ColumnInfo
58
58
extractor * plannercore.StatementsSummaryExtractor
59
- retrieved bool
60
59
61
- // only for evicted
62
- initiliazed bool
63
- rowIdx int
64
- rows [][]types.Datum
60
+ // lazily initialized
61
+ rowsReader * rowsReader
65
62
}
66
63
67
64
func (e * stmtSummaryRetriever ) retrieve (ctx context.Context , sctx sessionctx.Context ) ([][]types.Datum , error ) {
68
- if ( e .extractor != nil && e .extractor .SkipRequest ) || e . retrieved {
65
+ if e .extractor != nil && e .extractor .SkipRequest {
69
66
return nil , nil
70
67
}
71
- switch e .table .Name .O {
72
- case infoschema .TableStatementsSummary ,
73
- infoschema .ClusterTableStatementsSummary :
74
- return e .retrieveCurrent (sctx )
75
- case infoschema .TableStatementsSummaryHistory ,
76
- infoschema .ClusterTableStatementsSummaryHistory :
77
- return e .retrieveHistory (sctx )
78
- case infoschema .TableStatementsSummaryEvicted ,
79
- infoschema .ClusterTableStatementsSummaryEvicted :
80
- return e .retrieveEvicted (sctx )
68
+
69
+ if err := e .ensureRowsReader (sctx ); err != nil {
70
+ return nil , err
81
71
}
82
- return nil , nil
72
+ return e . rowsReader . read ( 1024 ) , nil
83
73
}
84
74
85
- func (e * stmtSummaryRetriever ) retrieveCurrent (sctx sessionctx.Context ) ([][]types.Datum , error ) {
86
- e .retrieved = true
75
+ func (e * stmtSummaryRetriever ) ensureRowsReader (sctx sessionctx.Context ) error {
76
+ if e .rowsReader != nil {
77
+ return nil
78
+ }
79
+
87
80
var err error
88
- var instanceAddr string
89
- if e .table .Name .O == infoschema .ClusterTableStatementsSummary {
90
- instanceAddr , err = infoschema .GetInstanceAddr (sctx )
91
- if err != nil {
92
- return nil , err
93
- }
81
+ if isEvictedTable (e .table .Name .O ) {
82
+ e .rowsReader , err = e .initEvictedRowsReader (sctx )
83
+ } else {
84
+ e .rowsReader , err = e .initSummaryRowsReader (sctx )
94
85
}
95
- user := sctx .GetSessionVars ().User
96
- reader := stmtsummary .NewStmtSummaryReader (user , hasPriv (sctx , mysql .ProcessPriv ), e .columns , instanceAddr , sctx .GetSessionVars ().StmtCtx .TimeZone )
97
- if e .extractor != nil && e .extractor .Enable {
98
- checker := stmtsummary .NewStmtSummaryChecker (e .extractor .Digests )
99
- reader .SetChecker (checker )
86
+
87
+ return err
88
+ }
89
+
90
+ func (e * stmtSummaryRetriever ) initEvictedRowsReader (sctx sessionctx.Context ) (* rowsReader , error ) {
91
+ if err := checkPrivilege (sctx ); err != nil {
92
+ return nil , err
93
+ }
94
+
95
+ rows := stmtsummary .StmtSummaryByDigestMap .ToEvictedCountDatum ()
96
+ if ! isClusterTable (e .table .Name .O ) {
97
+ // rows are full-columned, so we need to adjust them to the required columns.
98
+ return & rowsReader {rows : adjustColumns (rows , e .columns , e .table )}, nil
99
+ }
100
+
101
+ // Additional column `INSTANCE` for cluster table
102
+ rows , err := infoschema .AppendHostInfoToRows (sctx , rows )
103
+ if err != nil {
104
+ return nil , err
100
105
}
101
- return reader .GetStmtSummaryCurrentRows (), nil
106
+ // rows are full-columned, so we need to adjust them to the required columns.
107
+ return & rowsReader {rows : adjustColumns (rows , e .columns , e .table )}, nil
102
108
}
103
109
104
- func (e * stmtSummaryRetriever ) retrieveHistory (sctx sessionctx.Context ) ([][]types. Datum , error ) {
105
- e . retrieved = true
106
- var err error
107
- var instanceAddr string
108
- if e . table . Name . O == infoschema . ClusterTableStatementsSummaryHistory {
109
- instanceAddr , err = infoschema . GetInstanceAddr (sctx )
110
- if err != nil {
111
- return nil , err
112
- }
110
+ func (e * stmtSummaryRetriever ) initSummaryRowsReader (sctx sessionctx.Context ) (* rowsReader , error ) {
111
+ vars := sctx . GetSessionVars ()
112
+ user := vars . User
113
+ tz := vars . StmtCtx . TimeZone
114
+ columns := e . columns
115
+ priv := hasPriv (sctx , mysql . ProcessPriv )
116
+ instanceAddr , err := e . clusterTableInstanceAddr ( sctx )
117
+ if err != nil {
118
+ return nil , err
113
119
}
114
- user := sctx . GetSessionVars (). User
115
- reader := stmtsummary .NewStmtSummaryReader (user , hasPriv ( sctx , mysql . ProcessPriv ), e . columns , instanceAddr , sctx . GetSessionVars (). StmtCtx . TimeZone )
120
+
121
+ reader := stmtsummary .NewStmtSummaryReader (user , priv , columns , instanceAddr , tz )
116
122
if e .extractor != nil && e .extractor .Enable {
123
+ // set checker to filter out statements not matching the given digests
117
124
checker := stmtsummary .NewStmtSummaryChecker (e .extractor .Digests )
118
125
reader .SetChecker (checker )
119
126
}
120
- return reader .GetStmtSummaryHistoryRows (), nil
121
- }
122
127
123
- func (e * stmtSummaryRetriever ) retrieveEvicted (sctx sessionctx.Context ) ([][]types.Datum , error ) {
124
- if ! e .initiliazed {
125
- e .initiliazed = true
126
- if ! hasPriv (sctx , mysql .ProcessPriv ) {
127
- return nil , plannercore .ErrSpecificAccessDenied .GenWithStackByArgs ("PROCESS" )
128
- }
129
- e .rows = stmtsummary .StmtSummaryByDigestMap .ToEvictedCountDatum ()
130
- if e .table .Name .O == infoschema .ClusterTableStatementsSummaryEvicted {
131
- var err error
132
- e .rows , err = infoschema .AppendHostInfoToRows (sctx , e .rows )
133
- if err != nil {
134
- return nil , err
135
- }
136
- }
128
+ var rows [][]types.Datum
129
+ if isCurrentTable (e .table .Name .O ) {
130
+ rows = reader .GetStmtSummaryCurrentRows ()
137
131
}
138
- maxCount := 1024
139
- retCount := maxCount
140
- if e .rowIdx + maxCount > len (e .rows ) {
141
- retCount = len (e .rows ) - e .rowIdx
142
- e .retrieved = true
132
+ if isHistoryTable (e .table .Name .O ) {
133
+ rows = reader .GetStmtSummaryHistoryRows ()
143
134
}
144
- ret := make ([][]types.Datum , retCount )
145
- for i := e .rowIdx ; i < e .rowIdx + retCount ; i ++ {
146
- ret [i - e .rowIdx ] = e .rows [i ]
135
+ return & rowsReader {rows : rows }, nil
136
+ }
137
+
138
+ func (e * stmtSummaryRetriever ) clusterTableInstanceAddr (sctx sessionctx.Context ) (string , error ) {
139
+ if isClusterTable (e .table .Name .O ) {
140
+ return infoschema .GetInstanceAddr (sctx )
147
141
}
148
- e .rowIdx += retCount
149
- return adjustColumns (ret , e .columns , e .table ), nil
142
+ return "" , nil
150
143
}
151
144
152
145
// stmtSummaryRetriever is used to retrieve statements summary when
@@ -295,3 +288,66 @@ func (r *stmtSummaryRetrieverV2) getTimeRangesFromExtractor() []*stmtsummaryv2.S
295
288
}
296
289
return timeRanges
297
290
}
291
+
292
+ type rowsReader struct {
293
+ rows [][]types.Datum
294
+ }
295
+
296
+ func (r * rowsReader ) read (maxCount int ) [][]types.Datum {
297
+ if maxCount >= len (r .rows ) {
298
+ ret := r .rows
299
+ r .rows = nil
300
+ return ret
301
+ }
302
+ ret := r .rows [:maxCount ]
303
+ r .rows = r .rows [maxCount :]
304
+ return ret
305
+ }
306
+
307
+ func isClusterTable (originalTableName string ) bool {
308
+ switch originalTableName {
309
+ case infoschema .ClusterTableStatementsSummary ,
310
+ infoschema .ClusterTableStatementsSummaryHistory ,
311
+ infoschema .ClusterTableStatementsSummaryEvicted :
312
+ return true
313
+ }
314
+
315
+ return false
316
+ }
317
+
318
+ func isCurrentTable (originalTableName string ) bool {
319
+ switch originalTableName {
320
+ case infoschema .TableStatementsSummary ,
321
+ infoschema .ClusterTableStatementsSummary :
322
+ return true
323
+ }
324
+
325
+ return false
326
+ }
327
+
328
+ func isHistoryTable (originalTableName string ) bool {
329
+ switch originalTableName {
330
+ case infoschema .TableStatementsSummaryHistory ,
331
+ infoschema .ClusterTableStatementsSummaryHistory :
332
+ return true
333
+ }
334
+
335
+ return false
336
+ }
337
+
338
+ func isEvictedTable (originalTableName string ) bool {
339
+ switch originalTableName {
340
+ case infoschema .TableStatementsSummaryEvicted ,
341
+ infoschema .ClusterTableStatementsSummaryEvicted :
342
+ return true
343
+ }
344
+
345
+ return false
346
+ }
347
+
348
+ func checkPrivilege (sctx sessionctx.Context ) error {
349
+ if ! hasPriv (sctx , mysql .ProcessPriv ) {
350
+ return plannercore .ErrSpecificAccessDenied .GenWithStackByArgs ("PROCESS" )
351
+ }
352
+ return nil
353
+ }
0 commit comments