Skip to content

Commit 15614a8

Browse files
guillep2klunnyzeripathlafriks
authored
Divide GetIssueStats query in smaller chunks (#10176)
* Divide GetIssueStats query in smaller chunks * Skip chunking if count is low enough * Fix lint * Define maxQueryParameters * Remove absMaxQueryParameters because of lint * Restart CI * Restart CI Co-authored-by: Lunny Xiao <[email protected]> Co-authored-by: zeripath <[email protected]> Co-authored-by: Lauris BH <[email protected]>
1 parent 7e92070 commit 15614a8

File tree

2 files changed

+36
-0
lines changed

2 files changed

+36
-0
lines changed

models/issue.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1352,6 +1352,36 @@ type IssueStatsOptions struct {
13521352

13531353
// GetIssueStats returns issue statistic information by given conditions.
13541354
func GetIssueStats(opts *IssueStatsOptions) (*IssueStats, error) {
1355+
if len(opts.IssueIDs) <= maxQueryParameters {
1356+
return getIssueStatsChunk(opts, opts.IssueIDs)
1357+
}
1358+
1359+
// If too long a list of IDs is provided, we get the statistics in
1360+
// smaller chunks and get accumulates. Note: this could potentially
1361+
// get us invalid results. The alternative is to insert the list of
1362+
// ids in a temporary table and join from them.
1363+
accum := &IssueStats{}
1364+
for i := 0; i < len(opts.IssueIDs); {
1365+
chunk := i + maxQueryParameters
1366+
if chunk > len(opts.IssueIDs) {
1367+
chunk = len(opts.IssueIDs)
1368+
}
1369+
stats, err := getIssueStatsChunk(opts, opts.IssueIDs[i:chunk])
1370+
if err != nil {
1371+
return nil, err
1372+
}
1373+
accum.OpenCount += stats.OpenCount
1374+
accum.ClosedCount += stats.ClosedCount
1375+
accum.YourRepositoriesCount += stats.YourRepositoriesCount
1376+
accum.AssignCount += stats.AssignCount
1377+
accum.CreateCount += stats.CreateCount
1378+
accum.OpenCount += stats.MentionCount
1379+
i = chunk
1380+
}
1381+
return accum, nil
1382+
}
1383+
1384+
func getIssueStatsChunk(opts *IssueStatsOptions, issueIDs []int64) (*IssueStats, error) {
13551385
stats := &IssueStats{}
13561386

13571387
countSession := func(opts *IssueStatsOptions) *xorm.Session {

models/models.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,12 @@ type Engine interface {
4848
SumInt(bean interface{}, columnName string) (res int64, err error)
4949
}
5050

51+
const (
52+
// When queries are broken down in parts because of the number
53+
// of parameters, attempt to break by this amount
54+
maxQueryParameters = 300
55+
)
56+
5157
var (
5258
x *xorm.Engine
5359
tables []interface{}

0 commit comments

Comments
 (0)