@@ -902,6 +902,8 @@ func addUserFilterCondition(sql string, userList map[string]struct{}) string {
902
902
return b .String ()
903
903
}
904
904
905
+ // loadTable loads the table data by executing the sql and decoding the result data.
906
+ // NOTE: the chunk Row passed to decodeTableRow function is reused, so decodeTableRow should clone when necessary.
905
907
func loadTable (exec sqlexec.SQLExecutor , sql string ,
906
908
decodeTableRow func (chunk.Row , []* resolve.ResultField ) error ) error {
907
909
ctx := kv .WithInternalSourceType (context .Background (), kv .InternalTxnPrivilege )
@@ -930,10 +932,7 @@ func loadTable(exec sqlexec.SQLExecutor, sql string,
930
932
return errors .Trace (err )
931
933
}
932
934
}
933
- // NOTE: decodeTableRow decodes data from a chunk Row, that is a shallow copy.
934
- // The result will reference memory in the chunk, so the chunk must not be reused
935
- // here, otherwise some werid bug will happen!
936
- req = chunk .Renew (req , 1024 )
935
+ req .GrowAndReset (1024 )
937
936
}
938
937
}
939
938
@@ -1138,7 +1137,10 @@ func (p *MySQLPrivilege) decodeGlobalGrantsTableRow(userList map[string]struct{}
1138
1137
for i , f := range fs {
1139
1138
switch f .ColumnAsName .L {
1140
1139
case "priv" :
1141
- value .PrivilegeName = strings .ToUpper (row .GetString (i ))
1140
+ // When all characters are upper, strings.ToUpper returns a reference instead of a new copy.
1141
+ // so strings.Clone is required here.
1142
+ tmp := strings .Clone (row .GetString (i ))
1143
+ value .PrivilegeName = strings .ToUpper (tmp )
1142
1144
case "with_grant_option" :
1143
1145
value .GrantOption = row .GetEnum (i ).String () == "Y"
1144
1146
default :
@@ -1167,7 +1169,7 @@ func (p *MySQLPrivilege) decodeDBTableRow(userList map[string]struct{}) func(chu
1167
1169
for i , f := range fs {
1168
1170
switch {
1169
1171
case f .ColumnAsName .L == "db" :
1170
- value .DB = row .GetString (i )
1172
+ value .DB = strings . Clone ( row .GetString (i ) )
1171
1173
value .dbPatChars , value .dbPatTypes = stringutil .CompilePatternBinary (strings .ToUpper (value .DB ), '\\' )
1172
1174
case f .Column .GetType () == mysql .TypeEnum :
1173
1175
if row .GetEnum (i ).String () != "Y" {
@@ -1204,9 +1206,9 @@ func (p *MySQLPrivilege) decodeTablesPrivTableRow(userList map[string]struct{})
1204
1206
for i , f := range fs {
1205
1207
switch f .ColumnAsName .L {
1206
1208
case "db" :
1207
- value .DB = row .GetString (i )
1209
+ value .DB = strings . Clone ( row .GetString (i ) )
1208
1210
case "table_name" :
1209
- value .TableName = row .GetString (i )
1211
+ value .TableName = strings . Clone ( row .GetString (i ) )
1210
1212
case "table_priv" :
1211
1213
value .TablePriv = decodeSetToPrivilege (row .GetSet (i ))
1212
1214
case "column_priv" :
@@ -1236,13 +1238,13 @@ func (p *MySQLPrivilege) decodeRoleEdgesTable(row chunk.Row, fs []*resolve.Resul
1236
1238
for i , f := range fs {
1237
1239
switch f .ColumnAsName .L {
1238
1240
case "from_host" :
1239
- fromHost = row .GetString (i )
1241
+ fromHost = strings . Clone ( row .GetString (i ) )
1240
1242
case "from_user" :
1241
- fromUser = row .GetString (i )
1243
+ fromUser = strings . Clone ( row .GetString (i ) )
1242
1244
case "to_host" :
1243
- toHost = row .GetString (i )
1245
+ toHost = strings . Clone ( row .GetString (i ) )
1244
1246
case "to_user" :
1245
- toUser = row .GetString (i )
1247
+ toUser = strings . Clone ( row .GetString (i ) )
1246
1248
}
1247
1249
}
1248
1250
fromKey := auth.RoleIdentity {
@@ -1268,9 +1270,9 @@ func (p *MySQLPrivilege) decodeDefaultRoleTableRow(userList map[string]struct{})
1268
1270
for i , f := range fs {
1269
1271
switch f .ColumnAsName .L {
1270
1272
case "default_role_host" :
1271
- value .DefaultRoleHost = row .GetString (i )
1273
+ value .DefaultRoleHost = strings . Clone ( row .GetString (i ) )
1272
1274
case "default_role_user" :
1273
- value .DefaultRoleUser = row .GetString (i )
1275
+ value .DefaultRoleUser = strings . Clone ( row .GetString (i ) )
1274
1276
default :
1275
1277
value .assignUserOrHost (row , i , f )
1276
1278
}
@@ -1297,11 +1299,11 @@ func (p *MySQLPrivilege) decodeColumnsPrivTableRow(userList map[string]struct{})
1297
1299
for i , f := range fs {
1298
1300
switch f .ColumnAsName .L {
1299
1301
case "db" :
1300
- value .DB = row .GetString (i )
1302
+ value .DB = strings . Clone ( row .GetString (i ) )
1301
1303
case "table_name" :
1302
- value .TableName = row .GetString (i )
1304
+ value .TableName = strings . Clone ( row .GetString (i ) )
1303
1305
case "column_name" :
1304
- value .ColumnName = row .GetString (i )
1306
+ value .ColumnName = strings . Clone ( row .GetString (i ) )
1305
1307
case "timestamp" :
1306
1308
var err error
1307
1309
value .Timestamp , err = row .GetTime (i ).GoTime (time .Local )
0 commit comments