Repository: pingcap/tidb
File: pkg/privilege/privileges/cache.go (Go)

Code before:
		}
	}
	slices.Sort(gs[sortFromIdx:])

	// Show column scope grants, column and table are combined.
	// A map of "DB.Table" => Priv(col1, col2 ...)
	sortFromIdx = len(gs)
	columnPrivTable := make(map[string]privOnColumns)
	p.columnsPriv.Ascend(func(itm itemColumnsPriv) bool {
		logutil.BgLogger().Info("column privilege record in cache #1", zap.String("user", itm.username), zap.Int("len", len(itm.data)))
		for _, record := range itm.data {
			logutil.BgLogger().Info("column privilege record in cache #2",
				zap.String("user", record.User),
				zap.String("host", record.Host),
				zap.String("DB", record.DB),
				zap.String("table", record.TableName),
				zap.String("column", record.ColumnName),
				zap.String("privileges", record.ColumnPriv.String()),
			)
			if !collectColumnGrant(&record, user, host, columnPrivTable, sqlMode) {
				for _, r := range allRoles {
					collectColumnGrant(&record, r.Username, r.Hostname, columnPrivTable, sqlMode)
				}
			}
		}
		return true
	})
	for k, v := range columnPrivTable {
		privCols := privOnColumnsToString(v)
		s := fmt.Sprintf(`GRANT %s ON %s TO '%s'@'%s'`, privCols, k, user, host)
		gs = append(gs, s)
	}
	slices.Sort(gs[sortFromIdx:])

	// Show role grants.
	graphKey := auth.RoleIdentity{
		Username: user,
		Hostname: host,
	}
	edgeTable, ok := p.roleGraph[graphKey]
	g = ""
	if ok {
		sortedRes := make([]string, 0, 10)
		for k := range edgeTable.roleList {
			tmp := fmt.Sprintf("'%s'@'%s'", k.Username, k.Hostname)
			sortedRes = append(sortedRes, tmp)
		}
		slices.Sort(sortedRes)
		for i, r := range sortedRes {
			g += r
			if i != len(sortedRes)-1 {

Review comment (security):
```suggestion
				zap.String("privileges", record.ColumnPriv.String()),
				zap.Int("len(allRoles)", len(allRoles)),
```

Code after:
				s = fmt.Sprintf(`GRANT %s ON %s TO '%s'@'%s'`, g, k, user, host)
			}
			gs = append(gs, s)
		} else if len(g) == 0 && (priv&mysql.GrantPriv) > 0 {
			// We have GRANT OPTION on the table, but no privilege granted.
			// Wo we need to print a special USAGE line.
			s := fmt.Sprintf(`GRANT USAGE ON %s TO '%s'@'%s' WITH GRANT OPTION`, k, user, host)
			gs = append(gs, s)
		}
	}
	slices.Sort(gs[sortFromIdx:])

	// Show column scope grants, column and table are combined.
	// A map of "DB.Table" => Priv(col1, col2 ...)
	sortFromIdx = len(gs)
	columnPrivTable := make(map[string]privOnColumns)
	p.columnsPriv.Ascend(func(itm itemColumnsPriv) bool {
		logutil.BgLogger().Info("show column privilege record in cache #1", zap.String("user", itm.username), zap.Int("len", len(itm.data)))
		for _, record := range itm.data {
			logutil.BgLogger().Info("show column privilege record in cache #2",
				zap.String("user", record.User),
				zap.String("host", record.Host),
				zap.String("DB", record.DB),
				zap.String("table", record.TableName),
				zap.String("column", record.ColumnName),
				zap.String("privileges", record.ColumnPriv.String()),
				zap.Int("len(allRoles)", len(allRoles)),
			)
			if !collectColumnGrant(&record, user, host, columnPrivTable, sqlMode) {
				for _, r := range allRoles {
					collectColumnGrant(&record, r.Username, r.Hostname, columnPrivTable, sqlMode)
				}
			}
		}
		return true
	})
	for k, v := range columnPrivTable {
		privCols := privOnColumnsToString(v)
		s := fmt.Sprintf(`GRANT %s ON %s TO '%s'@'%s'`, privCols, k, user, host)
		gs = append(gs, s)
	}
	slices.Sort(gs[sortFromIdx:])

	// Show role grants.
	graphKey := auth.RoleIdentity{
		Username: user,
		Hostname: host,
	}
	edgeTable, ok := p.roleGraph[graphKey]
	g = ""
	if ok {