summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDuckDuckWhale <28813824+DuckDuckWhale@users.noreply.github.com>2021-12-28 19:12:19 -0800
committerGitHub <noreply@github.com>2021-12-29 11:12:19 +0800
commit72f9050689912f5910a08d593ebe53078fe85aa4 (patch)
treea4e4532a560c5ee107bb4fcb4f97dc1ef6fef508
parente4e3df6c66dbeac6ac5bceff8ac4f05dbea30d70 (diff)
downloadgitea-72f9050689912f5910a08d593ebe53078fe85aa4.tar.gz
gitea-72f9050689912f5910a08d593ebe53078fe85aa4.zip
Fix: unstable sort skips/duplicates issues across pages (#18094)
When viewing issues in sorted order, some issues are duplicated across pages and some are missing. This is caused by the lack of tie-breakers in database queries, making pagination inconsistent.
-rw-r--r--models/issue.go30
1 files changed, 19 insertions, 11 deletions
diff --git a/models/issue.go b/models/issue.go
index ea8eb4a9aa..b05c8cccdd 100644
--- a/models/issue.go
+++ b/models/issue.go
@@ -1193,17 +1193,17 @@ type IssuesOptions struct {
func sortIssuesSession(sess *xorm.Session, sortType string, priorityRepoID int64) {
switch sortType {
case "oldest":
- sess.Asc("issue.created_unix")
+ sess.Asc("issue.created_unix").Asc("issue.id")
case "recentupdate":
- sess.Desc("issue.updated_unix")
+ sess.Desc("issue.updated_unix").Desc("issue.created_unix").Desc("issue.id")
case "leastupdate":
- sess.Asc("issue.updated_unix")
+ sess.Asc("issue.updated_unix").Asc("issue.created_unix").Asc("issue.id")
case "mostcomment":
- sess.Desc("issue.num_comments")
+ sess.Desc("issue.num_comments").Desc("issue.created_unix").Desc("issue.id")
case "leastcomment":
- sess.Asc("issue.num_comments")
+ sess.Asc("issue.num_comments").Desc("issue.created_unix").Desc("issue.id")
case "priority":
- sess.Desc("issue.priority")
+ sess.Desc("issue.priority").Desc("issue.created_unix").Desc("issue.id")
case "nearduedate":
// 253370764800 is 01/01/9999 @ 12:00am (UTC)
sess.Join("LEFT", "milestone", "issue.milestone_id = milestone.id").
@@ -1211,19 +1211,27 @@ func sortIssuesSession(sess *xorm.Session, sortType string, priorityRepoID int64
"WHEN issue.deadline_unix = 0 AND (milestone.deadline_unix = 0 OR milestone.deadline_unix IS NULL) THEN 253370764800 " +
"WHEN milestone.deadline_unix = 0 OR milestone.deadline_unix IS NULL THEN issue.deadline_unix " +
"WHEN milestone.deadline_unix < issue.deadline_unix OR issue.deadline_unix = 0 THEN milestone.deadline_unix " +
- "ELSE issue.deadline_unix END ASC")
+ "ELSE issue.deadline_unix END ASC").
+ Desc("issue.created_unix").
+ Desc("issue.id")
case "farduedate":
sess.Join("LEFT", "milestone", "issue.milestone_id = milestone.id").
OrderBy("CASE " +
"WHEN milestone.deadline_unix IS NULL THEN issue.deadline_unix " +
"WHEN milestone.deadline_unix < issue.deadline_unix OR issue.deadline_unix = 0 THEN milestone.deadline_unix " +
- "ELSE issue.deadline_unix END DESC")
+ "ELSE issue.deadline_unix END DESC").
+ Desc("issue.created_unix").
+ Desc("issue.id")
case "priorityrepo":
- sess.OrderBy("CASE WHEN issue.repo_id = " + strconv.FormatInt(priorityRepoID, 10) + " THEN 1 ELSE 2 END, issue.created_unix DESC")
+ sess.OrderBy("CASE " +
+ "WHEN issue.repo_id = " + strconv.FormatInt(priorityRepoID, 10) + " THEN 1 " +
+ "ELSE 2 END ASC").
+ Desc("issue.created_unix").
+ Desc("issue.id")
case "project-column-sorting":
- sess.Asc("project_issue.sorting")
+ sess.Asc("project_issue.sorting").Desc("issue.created_unix").Desc("issue.id")
default:
- sess.Desc("issue.created_unix")
+ sess.Desc("issue.created_unix").Desc("issue.id")
}
}