diff --git a/internal/graph/schema.resolvers.go b/internal/graph/schema.resolvers.go index c84cb713..9cfb808e 100644 --- a/internal/graph/schema.resolvers.go +++ b/internal/graph/schema.resolvers.go @@ -676,6 +676,11 @@ func (r *queryResolver) JobsStatistics(ctx context.Context, filter []*model.JobF // Use request-scoped cache: multiple aliases with same (filter, groupBy) // but different sortBy/page hit the DB only once. if cache := getStatsGroupCache(ctx); cache != nil { + // Ensure the sort field is computed even if not in the GraphQL selection, + // because sortAndPageStats will sort by it in memory. + if sortBy != nil { + reqFields[sortByFieldName(*sortBy)] = true + } key := statsCacheKey(filter, groupBy, reqFields) var allStats []*model.JobsStatistics allStats, err = cache.getOrCompute(key, func() ([]*model.JobsStatistics, error) { diff --git a/internal/graph/stats_cache.go b/internal/graph/stats_cache.go index 92e8e85b..c4f0d7f8 100644 --- a/internal/graph/stats_cache.go +++ b/internal/graph/stats_cache.go @@ -107,6 +107,33 @@ func sortAndPageStats(allStats []*model.JobsStatistics, sortBy *model.SortByAggr return sorted } +// sortByFieldName maps a SortByAggregate enum to the corresponding reqFields key. +// This ensures the DB computes the column that sortAndPageStats will sort by. +func sortByFieldName(sortBy model.SortByAggregate) string { + switch sortBy { + case model.SortByAggregateTotaljobs: + return "totalJobs" + case model.SortByAggregateTotalusers: + return "totalUsers" + case model.SortByAggregateTotalwalltime: + return "totalWalltime" + case model.SortByAggregateTotalnodes: + return "totalNodes" + case model.SortByAggregateTotalnodehours: + return "totalNodeHours" + case model.SortByAggregateTotalcores: + return "totalCores" + case model.SortByAggregateTotalcorehours: + return "totalCoreHours" + case model.SortByAggregateTotalaccs: + return "totalAccs" + case model.SortByAggregateTotalacchours: + return "totalAccHours" + default: + return "totalJobs" + } +} + // statsFieldGetter returns a function that extracts the sortable int field // from a JobsStatistics struct for the given sort key. func statsFieldGetter(sortBy model.SortByAggregate) func(*model.JobsStatistics) int {