nestjs-query icon indicating copy to clipboard operation
nestjs-query copied to clipboard

Cursor pagination breaks when sorted by nullable column

Open thehappycoder opened this issue 3 years ago • 0 comments

Describe the bug Edit: This is currently blocking me from using cursor based pagination and I am going to switch back to offset based one in the time being.

When I query a non-first page using a cursor based pagination and order by a field that can be null, pagination breaks when the cursor contains a null value.

To Reproduce

  1. Have a nullable column
  2. Order by it: "sorting": [ { "direction": "DESC", "field": "order", "nulls": "NULLS LAST" } ]
  3. Go to the 2nd page (pass first: 10 to paging)

Expected behavior Get entries of the 2nd page

Actual No entries are returned

((((((("TransactionListItem"."order" < null)))) OR (((("TransactionListItem"."order" = null)) AND (("TransactionListItem"."internalId" > 104))))))

Possible fix

((((((("TransactionListItem"."order" < null)))) OR (((("TransactionListItem"."order" is null)) AND (("TransactionListItem"."internalId" > 104))))))

at packages/query-graphql/src/types/connection/cursor/pager/strategies/keyset.pager-strategy.ts

equalities.push({ [keySetField.field]: { eq: keySetField.value } } as Filter<DTO>);

Another case I've looked into that and it looks like more needs to be fixed to support this. For instance, hasNextPage breaks as well because lookup ahead (querying + 1 row in addition to usually requested 10) breaks when the next node on the next page has order=null. This doesn't return that extra row because there is no rows with order < 7.

((((((("TransactionListItem"."order" < 7)))) OR (((("TransactionListItem"."order" = 7)) AND (("TransactionListItem"."internalId" > 102))))))

thehappycoder avatar Dec 22 '21 09:12 thehappycoder