fix(issues): keep one row per issue when sorting by exclusive label order (#39364)

Sorting by an exclusive label scope joined `issue_label`, returning one
row per label. Issues with several labels were listed repeatedly and
pushed others off the page, and `IssueIDs` returned inflated totals.

The sort key now comes from a correlated subquery, so each issue yields
one row.

Fixes: https://github.com/go-gitea/gitea/issues/35711
Co-authored-by: silverwind <me@silverwind.io>
This commit is contained in:
Jeremy Schoemakerandsilverwind authored and GitHub committed 2026-10-22 03:40:31 +00:00
1 parent c1c6bdfedd
commit cf7050b91d
2 files changed
+26 -5

No files matched your search

+21
View File
@@ -124,6 +124,27 @@ func TestViewIssuesSortByType(t *testing.T) {
})
}
func TestIssueIDsSortByLabelScope(t *testing.T) {
assert.NoError(t, unittest.LoadFixtures())
high := &issues_model.Label{RepoID: 1, Name: "priority/high", Exclusive: true, ExclusiveOrder: 1}
low := &issues_model.Label{RepoID: 1, Name: "priority/low", Exclusive: true, ExclusiveOrder: 2}
assert.NoError(t, db.Insert(t.Context(), high, low))
assert.NoError(t, db.Insert(t.Context(),
&issues_model.IssueLabel{IssueID: 1, LabelID: low.ID},
&issues_model.IssueLabel{IssueID: 2, LabelID: high.ID},
))
for page, expectedIDs := range [][]int64{{2, 1, 11}, {5, 3}} {
issueIDs, total, err := issues_model.IssueIDs(t.Context(), &issues_model.IssuesOptions{
RepoIDs: []int64{1},
SortType: issues_model.ScopeSortPrefix + "priority",
Paginator: &db.ListOptions{Page: page + 1, PageSize: 3},
})
assert.NoError(t, err)
assert.Equal(t, expectedIDs, issueIDs)
assert.EqualValues(t, 5, total)
}
}
func TestViewIssuesKeyword(t *testing.T) {
defer tests.PrepareTestEnv(t)()