]> source.dussan.org Git - gitea.git/commitdiff
Fix: unstable sort skips/duplicates issues across pages (#18095)
authorDuckDuckWhale <28813824+DuckDuckWhale@users.noreply.github.com>
Wed, 29 Dec 2021 11:44:34 +0000 (03:44 -0800)
committerGitHub <noreply@github.com>
Wed, 29 Dec 2021 11:44:34 +0000 (19:44 +0800)
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.

Co-authored-by: Lauris BH <lauris@nix.lv>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
models/issue.go

index 6e5c144785f3b92370aa2489043934a730b3f051..4e8b41f8ce0159093325d271dad2237df05ee249 100644 (file)
@@ -1145,17 +1145,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").
@@ -1163,17 +1163,25 @@ 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")
        default:
-               sess.Desc("issue.created_unix")
+               sess.Desc("issue.created_unix").Desc("issue.id")
        }
 }