diff --git a/pkg/models/task_collection_test.go b/pkg/models/task_collection_test.go index fa21f6aad..97f5f1ea8 100644 --- a/pkg/models/task_collection_test.go +++ b/pkg/models/task_collection_test.go @@ -1046,6 +1046,9 @@ func TestTaskCollection_ReadAll(t *testing.T) { a: &user.User{ID: 1}, }, want: []*Task{ + // The only tasks with a position set + task1, + task2, // the other ones don't have a position set task3, task4, @@ -1076,9 +1079,51 @@ func TestTaskCollection_ReadAll(t *testing.T) { task31, task32, task33, - // The only tasks with a position set - task1, + }, + }, + { + name: "order by due date", + fields: fields{ + SortBy: []string{"due_date", "id"}, + OrderBy: []string{"asc", "desc"}, + }, + args: args{ + a: &user.User{ID: 1}, + }, + want: []*Task{ + // The only tasks with a due date + task6, + task5, + // The other ones don't have a due date + task33, + task32, + task31, + task30, + task29, + task28, + task27, + task26, + task25, + task24, + task23, + task22, + task21, + task20, + task19, + task18, + task17, + task16, + task15, + task12, + task11, + task10, + task9, + task8, + task7, + task4, + task3, task2, + task1, }, }, { diff --git a/pkg/models/tasks.go b/pkg/models/tasks.go index b7a139a92..ee9a74fdf 100644 --- a/pkg/models/tasks.go +++ b/pkg/models/tasks.go @@ -296,17 +296,30 @@ func getRawTasksForLists(s *xorm.Session, lists []*List, a web.Auth, opts *taskO if err := param.validate(); err != nil { return nil, 0, 0, err } - orderby += param.sortBy + " " + param.orderBy.String() - // Postgres sorts by default entries with null values after ones with values. - // To make that consistent with the sort order we have and other dbms, we're adding a separate clause here. - if db.Type() == schemas.POSTGRES { + // Mysql sorts columns with null values before ones without null value. + // Because it does not have support for NULLS FIRST or NULLS LAST we work around this by + // first sorting for null (or not null) values and then the order we actually want to. + if db.Type() == schemas.MYSQL { if param.orderBy == orderAscending { - orderby += " NULLS FIRST" + orderby += param.sortBy + " IS NULL, " } if param.orderBy == orderDescending { + orderby += param.sortBy + " IS NOT NULL, " + } + } + + orderby += param.sortBy + " " + param.orderBy.String() + + // Postgres and sqlite allow us to control how columns with null values are sorted. + // To make that consistent with the sort order we have and other dbms, we're adding a separate clause here. + if db.Type() == schemas.POSTGRES || db.Type() == schemas.SQLITE { + if param.orderBy == orderAscending { orderby += " NULLS LAST" } + if param.orderBy == orderDescending { + orderby += " NULLS FIRST" + } } if (i + 1) < len(opts.sortby) {