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

Using `$null` on non-terminal relationship returns empty results

Open Helveg opened this issue 7 months ago • 1 comments

Since https://github.com/ppetzold/nestjs-paginate/pull/539 was merged, using filter.rel_A=$null while also specifying relations: ['rel_A.rel_B'] in the config results in an unexpected INNER JOIN on rel_A. This causes records where rel_A is NULL to be filtered out, leading to empty results.

Steps to Reproduce

  1. Configure pagination with:
    {
      relations: ['rel_A.rel_B']
    }
    
  2. Apply the filter:
    filter.rel_A.id=$null
    
  3. The generated query INNER JOINs rel_A, excluding records where rel_A IS NULL.

Expected Behavior

  • rel_A should be LEFT JOINED to preserve NULL values when filtering for primary keys of rel_A.id=$null.

Workaround

  • Adding joinMethods: { rel_A: 'leftJoinAndSelect' } to the config prevents this issue.
    {
      relations: ['rel_A.rel_B'],
      joinMethods: { rel_A: 'leftJoinAndSelect' }
    }
    
  • However, this behavior is unintended.

Suggested fix

Adding filters creates a map of columns to be left/inner joined here:

https://github.com/ppetzold/nestjs-paginate/blob/2b717aa85be7844980d526df908761cf189655e4/src/filter.ts#L394-L406

When a $null filter is added, then that column's value in the map should be set to leftJoinAndSelect, unless the user's configuration changes it.

Helveg avatar Mar 24 '25 14:03 Helveg