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.
tokarchuk/v1.17
DuckDuckWhale 3 years ago committed by GitHub
parent e4e3df6c66
commit 72f9050689
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 30
      models/issue.go

@ -1193,17 +1193,17 @@ type IssuesOptions struct {
func sortIssuesSession(sess *xorm.Session, sortType string, priorityRepoID int64) { func sortIssuesSession(sess *xorm.Session, sortType string, priorityRepoID int64) {
switch sortType { switch sortType {
case "oldest": case "oldest":
sess.Asc("issue.created_unix") sess.Asc("issue.created_unix").Asc("issue.id")
case "recentupdate": case "recentupdate":
sess.Desc("issue.updated_unix") sess.Desc("issue.updated_unix").Desc("issue.created_unix").Desc("issue.id")
case "leastupdate": case "leastupdate":
sess.Asc("issue.updated_unix") sess.Asc("issue.updated_unix").Asc("issue.created_unix").Asc("issue.id")
case "mostcomment": case "mostcomment":
sess.Desc("issue.num_comments") sess.Desc("issue.num_comments").Desc("issue.created_unix").Desc("issue.id")
case "leastcomment": case "leastcomment":
sess.Asc("issue.num_comments") sess.Asc("issue.num_comments").Desc("issue.created_unix").Desc("issue.id")
case "priority": case "priority":
sess.Desc("issue.priority") sess.Desc("issue.priority").Desc("issue.created_unix").Desc("issue.id")
case "nearduedate": case "nearduedate":
// 253370764800 is 01/01/9999 @ 12:00am (UTC) // 253370764800 is 01/01/9999 @ 12:00am (UTC)
sess.Join("LEFT", "milestone", "issue.milestone_id = milestone.id"). 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 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 = 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 " + "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": case "farduedate":
sess.Join("LEFT", "milestone", "issue.milestone_id = milestone.id"). sess.Join("LEFT", "milestone", "issue.milestone_id = milestone.id").
OrderBy("CASE " + OrderBy("CASE " +
"WHEN milestone.deadline_unix IS NULL THEN issue.deadline_unix " + "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 " + "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": 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": case "project-column-sorting":
sess.Asc("project_issue.sorting") sess.Asc("project_issue.sorting").Desc("issue.created_unix").Desc("issue.id")
default: default:
sess.Desc("issue.created_unix") sess.Desc("issue.created_unix").Desc("issue.id")
} }
} }

Loading…
Cancel
Save