From c08cdff4986896d322a912cc95df0ef57d027e71 Mon Sep 17 00:00:00 2001 From: Sasha <64744993+r1tsuu@users.noreply.github.com> Date: Wed, 4 Jun 2025 03:56:10 +0300 Subject: [PATCH] fix(db-postgres): `in` query with `null` (#12661) Previously, this was possible in MongoDB but not in Postgres/SQLite (having `null` in an `in` query) ``` const { docs } = await payload.find({ collection: 'posts', where: { text: { in: ['text-1', 'text-3', null] } }, }) ``` This PR fixes that behavior --- packages/drizzle/src/queries/parseParams.ts | 20 +++++++++++++- test/database/int.spec.ts | 29 +++++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/packages/drizzle/src/queries/parseParams.ts b/packages/drizzle/src/queries/parseParams.ts index 8ca750366..5cb08cac8 100644 --- a/packages/drizzle/src/queries/parseParams.ts +++ b/packages/drizzle/src/queries/parseParams.ts @@ -367,7 +367,25 @@ export function parseParams({ break } - constraints.push(adapter.operators[queryOperator](resolvedColumn, queryValue)) + const orConditions: SQL[] = [] + let resolvedQueryValue = queryValue + if ( + operator === 'in' && + Array.isArray(queryValue) && + queryValue.some((v) => v === null) + ) { + orConditions.push(isNull(resolvedColumn)) + resolvedQueryValue = queryValue.filter((v) => v !== null) + } + let constraint = adapter.operators[queryOperator]( + resolvedColumn, + resolvedQueryValue, + ) + if (orConditions.length) { + orConditions.push(constraint) + constraint = or(...orConditions) + } + constraints.push(constraint) } } } diff --git a/test/database/int.spec.ts b/test/database/int.spec.ts index 514f1bf92..a628f23a8 100644 --- a/test/database/int.spec.ts +++ b/test/database/int.spec.ts @@ -2619,4 +2619,33 @@ describe('database', () => { expect(res.testBlocks[0]?.text).toBe('text') expect(res.testBlocksLocalized[0]?.text).toBe('text-localized') }) + + it('should support in with null', async () => { + await payload.delete({ collection: 'posts', where: {} }) + const post_1 = await payload.create({ + collection: 'posts', + data: { title: 'a', text: 'text-1' }, + }) + const post_2 = await payload.create({ + collection: 'posts', + data: { title: 'a', text: 'text-2' }, + }) + const post_3 = await payload.create({ + collection: 'posts', + data: { title: 'a', text: 'text-3' }, + }) + const post_null = await payload.create({ + collection: 'posts', + data: { title: 'a', text: null }, + }) + + const { docs } = await payload.find({ + collection: 'posts', + where: { text: { in: ['text-1', 'text-3', null] } }, + }) + expect(docs).toHaveLength(3) + expect(docs[0].id).toBe(post_null.id) + expect(docs[1].id).toBe(post_3.id) + expect(docs[2].id).toBe(post_1.id) + }) })