Skip to content

Commit 0990286

Browse files
lunnytechknowlogick
authored andcommitted
fix bugs when too many IN variables (go-gitea#4594) (go-gitea#4597)
1 parent 940e30b commit 0990286

File tree

1 file changed

+194
-95
lines changed

1 file changed

+194
-95
lines changed

models/issue_list.go

+194-95
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@ import "fmt"
99
// IssueList defines a list of issues
1010
type IssueList []*Issue
1111

12+
const (
13+
// default variables number on IN () in SQL
14+
defaultMaxInSize = 50
15+
)
16+
1217
func (issues IssueList) getRepoIDs() []int64 {
1318
repoIDs := make(map[int64]struct{}, len(issues))
1419
for _, issue := range issues {
@@ -26,11 +31,20 @@ func (issues IssueList) loadRepositories(e Engine) ([]*Repository, error) {
2631

2732
repoIDs := issues.getRepoIDs()
2833
repoMaps := make(map[int64]*Repository, len(repoIDs))
29-
err := e.
30-
In("id", repoIDs).
31-
Find(&repoMaps)
32-
if err != nil {
33-
return nil, fmt.Errorf("find repository: %v", err)
34+
var left = len(repoIDs)
35+
for left > 0 {
36+
var limit = defaultMaxInSize
37+
if left < limit {
38+
limit = left
39+
}
40+
err := e.
41+
In("id", repoIDs[:limit]).
42+
Find(&repoMaps)
43+
if err != nil {
44+
return nil, fmt.Errorf("find repository: %v", err)
45+
}
46+
left = left - limit
47+
repoIDs = repoIDs[limit:]
3448
}
3549

3650
for _, issue := range issues {
@@ -61,11 +75,20 @@ func (issues IssueList) loadPosters(e Engine) error {
6175

6276
posterIDs := issues.getPosterIDs()
6377
posterMaps := make(map[int64]*User, len(posterIDs))
64-
err := e.
65-
In("id", posterIDs).
66-
Find(&posterMaps)
67-
if err != nil {
68-
return err
78+
var left = len(posterIDs)
79+
for left > 0 {
80+
var limit = defaultMaxInSize
81+
if left < limit {
82+
limit = left
83+
}
84+
err := e.
85+
In("id", posterIDs[:limit]).
86+
Find(&posterMaps)
87+
if err != nil {
88+
return err
89+
}
90+
left = left - limit
91+
posterIDs = posterIDs[limit:]
6992
}
7093

7194
for _, issue := range issues {
@@ -99,23 +122,34 @@ func (issues IssueList) loadLabels(e Engine) error {
99122
}
100123

101124
var issueLabels = make(map[int64][]*Label, len(issues)*3)
102-
rows, err := e.Table("label").
103-
Join("LEFT", "issue_label", "issue_label.label_id = label.id").
104-
In("issue_label.issue_id", issues.getIssueIDs()).
105-
Asc("label.name").
106-
Rows(new(LabelIssue))
107-
if err != nil {
108-
return err
109-
}
110-
defer rows.Close()
111-
112-
for rows.Next() {
113-
var labelIssue LabelIssue
114-
err = rows.Scan(&labelIssue)
125+
var issueIDs = issues.getIssueIDs()
126+
var left = len(issueIDs)
127+
for left > 0 {
128+
var limit = defaultMaxInSize
129+
if left < limit {
130+
limit = left
131+
}
132+
rows, err := e.Table("label").
133+
Join("LEFT", "issue_label", "issue_label.label_id = label.id").
134+
In("issue_label.issue_id", issueIDs[:limit]).
135+
Asc("label.name").
136+
Rows(new(LabelIssue))
115137
if err != nil {
116138
return err
117139
}
118-
issueLabels[labelIssue.IssueLabel.IssueID] = append(issueLabels[labelIssue.IssueLabel.IssueID], labelIssue.Label)
140+
141+
for rows.Next() {
142+
var labelIssue LabelIssue
143+
err = rows.Scan(&labelIssue)
144+
if err != nil {
145+
rows.Close()
146+
return err
147+
}
148+
issueLabels[labelIssue.IssueLabel.IssueID] = append(issueLabels[labelIssue.IssueLabel.IssueID], labelIssue.Label)
149+
}
150+
rows.Close()
151+
left = left - limit
152+
issueIDs = issueIDs[limit:]
119153
}
120154

121155
for _, issue := range issues {
@@ -141,11 +175,20 @@ func (issues IssueList) loadMilestones(e Engine) error {
141175
}
142176

143177
milestoneMaps := make(map[int64]*Milestone, len(milestoneIDs))
144-
err := e.
145-
In("id", milestoneIDs).
146-
Find(&milestoneMaps)
147-
if err != nil {
148-
return err
178+
var left = len(milestoneIDs)
179+
for left > 0 {
180+
var limit = defaultMaxInSize
181+
if left < limit {
182+
limit = left
183+
}
184+
err := e.
185+
In("id", milestoneIDs[:limit]).
186+
Find(&milestoneMaps)
187+
if err != nil {
188+
return err
189+
}
190+
left = left - limit
191+
milestoneIDs = milestoneIDs[limit:]
149192
}
150193

151194
for _, issue := range issues {
@@ -165,23 +208,35 @@ func (issues IssueList) loadAssignees(e Engine) error {
165208
}
166209

167210
var assignees = make(map[int64][]*User, len(issues))
168-
rows, err := e.Table("issue_assignees").
169-
Join("INNER", "`user`", "`user`.id = `issue_assignees`.assignee_id").
170-
In("`issue_assignees`.issue_id", issues.getIssueIDs()).
171-
Rows(new(AssigneeIssue))
172-
if err != nil {
173-
return err
174-
}
175-
defer rows.Close()
176-
177-
for rows.Next() {
178-
var assigneeIssue AssigneeIssue
179-
err = rows.Scan(&assigneeIssue)
211+
var issueIDs = issues.getIssueIDs()
212+
var left = len(issueIDs)
213+
for left > 0 {
214+
var limit = defaultMaxInSize
215+
if left < limit {
216+
limit = left
217+
}
218+
rows, err := e.Table("issue_assignees").
219+
Join("INNER", "`user`", "`user`.id = `issue_assignees`.assignee_id").
220+
In("`issue_assignees`.issue_id", issueIDs[:limit]).
221+
Rows(new(AssigneeIssue))
180222
if err != nil {
181223
return err
182224
}
183225

184-
assignees[assigneeIssue.IssueAssignee.IssueID] = append(assignees[assigneeIssue.IssueAssignee.IssueID], assigneeIssue.Assignee)
226+
for rows.Next() {
227+
var assigneeIssue AssigneeIssue
228+
err = rows.Scan(&assigneeIssue)
229+
if err != nil {
230+
rows.Close()
231+
return err
232+
}
233+
234+
assignees[assigneeIssue.IssueAssignee.IssueID] = append(assignees[assigneeIssue.IssueAssignee.IssueID], assigneeIssue.Assignee)
235+
}
236+
rows.Close()
237+
238+
left = left - limit
239+
issueIDs = issueIDs[limit:]
185240
}
186241

187242
for _, issue := range issues {
@@ -207,21 +262,32 @@ func (issues IssueList) loadPullRequests(e Engine) error {
207262
}
208263

209264
pullRequestMaps := make(map[int64]*PullRequest, len(issuesIDs))
210-
rows, err := e.
211-
In("issue_id", issuesIDs).
212-
Rows(new(PullRequest))
213-
if err != nil {
214-
return err
215-
}
216-
defer rows.Close()
217-
218-
for rows.Next() {
219-
var pr PullRequest
220-
err = rows.Scan(&pr)
265+
var left = len(issuesIDs)
266+
for left > 0 {
267+
var limit = defaultMaxInSize
268+
if left < limit {
269+
limit = left
270+
}
271+
rows, err := e.
272+
In("issue_id", issuesIDs[:limit]).
273+
Rows(new(PullRequest))
221274
if err != nil {
222275
return err
223276
}
224-
pullRequestMaps[pr.IssueID] = &pr
277+
278+
for rows.Next() {
279+
var pr PullRequest
280+
err = rows.Scan(&pr)
281+
if err != nil {
282+
rows.Close()
283+
return err
284+
}
285+
pullRequestMaps[pr.IssueID] = &pr
286+
}
287+
288+
rows.Close()
289+
left = left - limit
290+
issuesIDs = issuesIDs[limit:]
225291
}
226292

227293
for _, issue := range issues {
@@ -236,22 +302,34 @@ func (issues IssueList) loadAttachments(e Engine) (err error) {
236302
}
237303

238304
var attachments = make(map[int64][]*Attachment, len(issues))
239-
rows, err := e.Table("attachment").
240-
Join("INNER", "issue", "issue.id = attachment.issue_id").
241-
In("issue.id", issues.getIssueIDs()).
242-
Rows(new(Attachment))
243-
if err != nil {
244-
return err
245-
}
246-
defer rows.Close()
247-
248-
for rows.Next() {
249-
var attachment Attachment
250-
err = rows.Scan(&attachment)
305+
var issuesIDs = issues.getIssueIDs()
306+
var left = len(issuesIDs)
307+
for left > 0 {
308+
var limit = defaultMaxInSize
309+
if left < limit {
310+
limit = left
311+
}
312+
rows, err := e.Table("attachment").
313+
Join("INNER", "issue", "issue.id = attachment.issue_id").
314+
In("issue.id", issuesIDs[:limit]).
315+
Rows(new(Attachment))
251316
if err != nil {
252317
return err
253318
}
254-
attachments[attachment.IssueID] = append(attachments[attachment.IssueID], &attachment)
319+
320+
for rows.Next() {
321+
var attachment Attachment
322+
err = rows.Scan(&attachment)
323+
if err != nil {
324+
rows.Close()
325+
return err
326+
}
327+
attachments[attachment.IssueID] = append(attachments[attachment.IssueID], &attachment)
328+
}
329+
330+
rows.Close()
331+
left = left - limit
332+
issuesIDs = issuesIDs[limit:]
255333
}
256334

257335
for _, issue := range issues {
@@ -266,22 +344,33 @@ func (issues IssueList) loadComments(e Engine) (err error) {
266344
}
267345

268346
var comments = make(map[int64][]*Comment, len(issues))
269-
rows, err := e.Table("comment").
270-
Join("INNER", "issue", "issue.id = comment.issue_id").
271-
In("issue.id", issues.getIssueIDs()).
272-
Rows(new(Comment))
273-
if err != nil {
274-
return err
275-
}
276-
defer rows.Close()
277-
278-
for rows.Next() {
279-
var comment Comment
280-
err = rows.Scan(&comment)
347+
var issuesIDs = issues.getIssueIDs()
348+
var left = len(issuesIDs)
349+
for left > 0 {
350+
var limit = defaultMaxInSize
351+
if left < limit {
352+
limit = left
353+
}
354+
rows, err := e.Table("comment").
355+
Join("INNER", "issue", "issue.id = comment.issue_id").
356+
In("issue.id", issuesIDs[:limit]).
357+
Rows(new(Comment))
281358
if err != nil {
282359
return err
283360
}
284-
comments[comment.IssueID] = append(comments[comment.IssueID], &comment)
361+
362+
for rows.Next() {
363+
var comment Comment
364+
err = rows.Scan(&comment)
365+
if err != nil {
366+
rows.Close()
367+
return err
368+
}
369+
comments[comment.IssueID] = append(comments[comment.IssueID], &comment)
370+
}
371+
rows.Close()
372+
left = left - limit
373+
issuesIDs = issuesIDs[limit:]
285374
}
286375

287376
for _, issue := range issues {
@@ -307,25 +396,35 @@ func (issues IssueList) loadTotalTrackedTimes(e Engine) (err error) {
307396
}
308397
}
309398

310-
// select issue_id, sum(time) from tracked_time where issue_id in (<issue ids in current page>) group by issue_id
311-
rows, err := e.Table("tracked_time").
312-
Select("issue_id, sum(time) as time").
313-
In("issue_id", ids).
314-
GroupBy("issue_id").
315-
Rows(new(totalTimesByIssue))
316-
if err != nil {
317-
return err
318-
}
319-
320-
defer rows.Close()
399+
var left = len(ids)
400+
for left > 0 {
401+
var limit = defaultMaxInSize
402+
if left < limit {
403+
limit = left
404+
}
321405

322-
for rows.Next() {
323-
var totalTime totalTimesByIssue
324-
err = rows.Scan(&totalTime)
406+
// select issue_id, sum(time) from tracked_time where issue_id in (<issue ids in current page>) group by issue_id
407+
rows, err := e.Table("tracked_time").
408+
Select("issue_id, sum(time) as time").
409+
In("issue_id", ids[:limit]).
410+
GroupBy("issue_id").
411+
Rows(new(totalTimesByIssue))
325412
if err != nil {
326413
return err
327414
}
328-
trackedTimes[totalTime.IssueID] = totalTime.Time
415+
416+
for rows.Next() {
417+
var totalTime totalTimesByIssue
418+
err = rows.Scan(&totalTime)
419+
if err != nil {
420+
rows.Close()
421+
return err
422+
}
423+
trackedTimes[totalTime.IssueID] = totalTime.Time
424+
}
425+
rows.Close()
426+
left = left - limit
427+
ids = ids[limit:]
329428
}
330429

331430
for _, issue := range issues {

0 commit comments

Comments
 (0)