fix: make sure null values are always sorted last across all dmbs

This commit is contained in:
kolaente 2022-05-28 10:35:26 +02:00
parent f5ebada913
commit 34275d9178
Signed by: konrad
GPG Key ID: F40E70337AB24C9B
2 changed files with 65 additions and 7 deletions

View File

@ -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,
},
},
{

View File

@ -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) {