fix(drizzle): equals polymorphic querying with object notation (#8316)

Previously, this wasn't valid in Postgres / SQLite:
```ts
const res = await payload.find({
  collection: 'polymorphic-relationships',
  where: {
    polymorphic: {
      equals: {
        relationTo: 'movies',
        value: movie.id,
      },
    },
  },
})
```

Now it works and actually in more performant way than this:
```ts
const res = await payload.find({
  collection: 'polymorphic-relationships',
  where: {
    and: [
      {
        'polymorphic.relationTo': {
          equals: 'movies',
        },
      },
      {
        'polymorphic.value': {
          equals: 'movies',
        },
      },
    ],
  },
})
``` 

Why? Because with the object notation, the output SQL is: `movies_id =
1` - checks exactly 1 column in the `*_rels` table, while with the
separate query by `relationTo` and `value` we need to check against
_each_ possible relationship collection with OR.
This commit is contained in:
Sasha
2024-09-20 18:18:13 +03:00
committed by GitHub
parent 2596b85027
commit 265d7fa0e2
6 changed files with 121 additions and 12 deletions

View File

@@ -186,12 +186,12 @@ export interface PayloadLockedDocument {
relationTo: 'users';
value: string | User;
} | null);
editedAt?: string | null;
globalSlug?: string | null;
user: {
relationTo: 'users';
value: string | User;
};
editedAt?: string | null;
updatedAt: string;
createdAt: string;
}

View File

@@ -1,6 +1,6 @@
import type { Payload, PayloadRequest } from 'payload'
import { randomBytes } from 'crypto'
import { randomBytes, randomUUID } from 'crypto'
import path from 'path'
import { fileURLToPath } from 'url'
@@ -1168,6 +1168,51 @@ describe('Relationships', () => {
expect(queryOne.docs).toHaveLength(1)
expect(queryTwo.docs).toHaveLength(1)
})
it('should allow querying on polymorphic relationships with an object syntax', async () => {
const movie = await payload.create({
collection: 'movies',
data: {
name: 'Pulp Fiction 2',
},
})
await payload.create({
collection: polymorphicRelationshipsSlug,
data: {
polymorphic: {
relationTo: 'movies',
value: movie.id,
},
},
})
const res = await payload.find({
collection: 'polymorphic-relationships',
where: {
polymorphic: {
equals: {
relationTo: 'movies',
value: movie.id,
},
},
},
})
expect(res.docs).toHaveLength(1)
const res_2 = await payload.find({
collection: 'polymorphic-relationships',
where: {
polymorphic: {
equals: {
relationTo: 'movies',
value: payload.db.idType === 'uuid' ? randomUUID() : 99,
},
},
},
})
expect(res_2.docs).toHaveLength(0)
})
})
})