Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support nullable values in cursor pagination #5362

Open
atfera opened this issue Mar 20, 2024 · 1 comment
Open

Support nullable values in cursor pagination #5362

atfera opened this issue Mar 20, 2024 · 1 comment
Labels
enhancement New feature or request

Comments

@atfera
Copy link

atfera commented Mar 20, 2024

Is your feature request related to a problem? Please describe.

Hello,
I'm running into an issue when trying to use cursor pagination with columns that can have null values, even though I'm also using a unique non nullable column to build the Cursor (like id column).

I tried to do some research about it, and yeah it's not easy to implement, mainly because databases handle nulls differently.
And I also noticed that ordering with NULL FIRST | LAST doesn't work in mikro-orm with the cursor pagination.

For the moment, I switched to offset pagination to make it work.

Maybe the docs need to be updated to precise that it must be ordered by non-null columns.

Reproduction

import { Entity, PrimaryKey, Property } from '@mikro-orm/core';

@Entity()
export class User {

  @PrimaryKey()
  id!: number;

  @Property()
  name!: string;

  @Property({ nullable: true })
  age?: number | null;
}
import { MikroORM, QueryOrder } from '@mikro-orm/sqlite';
import { User } from './user.entity';
import { faker } from '@faker-js/faker';

let orm: MikroORM;

beforeAll(async () => {
  orm = await MikroORM.init({
    dbName: 'sqlite.db',
    entities: ['dist/**/*.entity.js'],
    entitiesTs: ['src/**/*.entity.ts'],
    debug: ['query', 'query-params'],
    allowGlobalContext: true, // only for testing
  });
  await orm.schema.refreshDatabase();
});

afterAll(async () => {
  await orm.close(true);
});

test('cursor pagination', async () => {
  Array.from({ length: 500 }).forEach(() => {
    orm.em.create(User, {
      name: faker.person.fullName(),
      age: Math.floor(Math.random() * 10) ? faker.number.int({max: 100, min: 0}) : null
    });
  });

  await orm.em.flush();

  const res = await orm.em.findByCursor(User, {}, {
    first: 100,
    orderBy: {
      age: QueryOrder.ASC,
      id: QueryOrder.ASC,
    }
  });
  console.log(res)
});

Error:

 CursorError: Cannot create cursor, value for 'User.age' is missing.
@atfera atfera added the enhancement New feature or request label Mar 20, 2024
@B4nan
Copy link
Member

B4nan commented Mar 21, 2024

One possible workaround could be using a formula property and adding a fallback to the null values (and using that for ordering instead of the nullable column).

@atfera atfera changed the title Support non nullable values in cursor pagination Support nullable values in cursor pagination Mar 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants