Skip to content

Commit b72ff3b

Browse files
authored
privilege: reuse chunk in loadTable function (pingcap#59821)
ref pingcap#55563
1 parent 72517f4 commit b72ff3b

File tree

1 file changed

+19
-17
lines changed

1 file changed

+19
-17
lines changed

pkg/privilege/privileges/cache.go

+19-17
Original file line numberDiff line numberDiff line change
@@ -902,6 +902,8 @@ func addUserFilterCondition(sql string, userList map[string]struct{}) string {
902902
return b.String()
903903
}
904904

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.
905907
func loadTable(exec sqlexec.SQLExecutor, sql string,
906908
decodeTableRow func(chunk.Row, []*resolve.ResultField) error) error {
907909
ctx := kv.WithInternalSourceType(context.Background(), kv.InternalTxnPrivilege)
@@ -930,10 +932,7 @@ func loadTable(exec sqlexec.SQLExecutor, sql string,
930932
return errors.Trace(err)
931933
}
932934
}
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)
937936
}
938937
}
939938

@@ -1138,7 +1137,10 @@ func (p *MySQLPrivilege) decodeGlobalGrantsTableRow(userList map[string]struct{}
11381137
for i, f := range fs {
11391138
switch f.ColumnAsName.L {
11401139
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)
11421144
case "with_grant_option":
11431145
value.GrantOption = row.GetEnum(i).String() == "Y"
11441146
default:
@@ -1167,7 +1169,7 @@ func (p *MySQLPrivilege) decodeDBTableRow(userList map[string]struct{}) func(chu
11671169
for i, f := range fs {
11681170
switch {
11691171
case f.ColumnAsName.L == "db":
1170-
value.DB = row.GetString(i)
1172+
value.DB = strings.Clone(row.GetString(i))
11711173
value.dbPatChars, value.dbPatTypes = stringutil.CompilePatternBinary(strings.ToUpper(value.DB), '\\')
11721174
case f.Column.GetType() == mysql.TypeEnum:
11731175
if row.GetEnum(i).String() != "Y" {
@@ -1204,9 +1206,9 @@ func (p *MySQLPrivilege) decodeTablesPrivTableRow(userList map[string]struct{})
12041206
for i, f := range fs {
12051207
switch f.ColumnAsName.L {
12061208
case "db":
1207-
value.DB = row.GetString(i)
1209+
value.DB = strings.Clone(row.GetString(i))
12081210
case "table_name":
1209-
value.TableName = row.GetString(i)
1211+
value.TableName = strings.Clone(row.GetString(i))
12101212
case "table_priv":
12111213
value.TablePriv = decodeSetToPrivilege(row.GetSet(i))
12121214
case "column_priv":
@@ -1236,13 +1238,13 @@ func (p *MySQLPrivilege) decodeRoleEdgesTable(row chunk.Row, fs []*resolve.Resul
12361238
for i, f := range fs {
12371239
switch f.ColumnAsName.L {
12381240
case "from_host":
1239-
fromHost = row.GetString(i)
1241+
fromHost = strings.Clone(row.GetString(i))
12401242
case "from_user":
1241-
fromUser = row.GetString(i)
1243+
fromUser = strings.Clone(row.GetString(i))
12421244
case "to_host":
1243-
toHost = row.GetString(i)
1245+
toHost = strings.Clone(row.GetString(i))
12441246
case "to_user":
1245-
toUser = row.GetString(i)
1247+
toUser = strings.Clone(row.GetString(i))
12461248
}
12471249
}
12481250
fromKey := auth.RoleIdentity{
@@ -1268,9 +1270,9 @@ func (p *MySQLPrivilege) decodeDefaultRoleTableRow(userList map[string]struct{})
12681270
for i, f := range fs {
12691271
switch f.ColumnAsName.L {
12701272
case "default_role_host":
1271-
value.DefaultRoleHost = row.GetString(i)
1273+
value.DefaultRoleHost = strings.Clone(row.GetString(i))
12721274
case "default_role_user":
1273-
value.DefaultRoleUser = row.GetString(i)
1275+
value.DefaultRoleUser = strings.Clone(row.GetString(i))
12741276
default:
12751277
value.assignUserOrHost(row, i, f)
12761278
}
@@ -1297,11 +1299,11 @@ func (p *MySQLPrivilege) decodeColumnsPrivTableRow(userList map[string]struct{})
12971299
for i, f := range fs {
12981300
switch f.ColumnAsName.L {
12991301
case "db":
1300-
value.DB = row.GetString(i)
1302+
value.DB = strings.Clone(row.GetString(i))
13011303
case "table_name":
1302-
value.TableName = row.GetString(i)
1304+
value.TableName = strings.Clone(row.GetString(i))
13031305
case "column_name":
1304-
value.ColumnName = row.GetString(i)
1306+
value.ColumnName = strings.Clone(row.GetString(i))
13051307
case "timestamp":
13061308
var err error
13071309
value.Timestamp, err = row.GetTime(i).GoTime(time.Local)

0 commit comments

Comments
 (0)