diff --git a/drizzle-orm/src/sql/expressions/conditions.ts b/drizzle-orm/src/sql/expressions/conditions.ts index 506e082396..379c47f79b 100644 --- a/drizzle-orm/src/sql/expressions/conditions.ts +++ b/drizzle-orm/src/sql/expressions/conditions.ts @@ -166,16 +166,25 @@ export function or( /** * Negate the meaning of an expression using the `not` keyword. * + * A condition that is equal to `undefined` is passed through as `undefined`, + * so `not` composes with `and`/`or`, which may return `undefined`. + * * ## Examples * * ```ts * // Select cars _not_ made by GM or Ford. * db.select().from(cars) * .where(not(inArray(cars.make, ['GM', 'Ford']))) + * + * // Composes with `and`/`or`, which can return `undefined`. + * db.select().from(cars) + * .where(not(and(eq(cars.make, 'GM'), eq(cars.year, 1950)))) * ``` */ -export function not(condition: SQLWrapper): SQL { - return sql`not ${condition}`; +export function not(condition: SQLWrapper): SQL; +export function not(condition: SQLWrapper | undefined): SQL | undefined; +export function not(condition: SQLWrapper | undefined): SQL | undefined { + return condition === undefined ? undefined : sql`not ${condition}`; } /** diff --git a/drizzle-orm/type-tests/geldb/select.ts b/drizzle-orm/type-tests/geldb/select.ts index e18b74c4b5..0f17e41e3f 100644 --- a/drizzle-orm/type-tests/geldb/select.ts +++ b/drizzle-orm/type-tests/geldb/select.ts @@ -440,6 +440,8 @@ const allOperators = await db ne(users.id, 1), or(eq(users.id, 1), ne(users.id, 1)), not(eq(users.id, 1)), + not(and(eq(users.id, 1), ne(users.id, 1))), + not(or(eq(users.id, 1), ne(users.id, 1))), gt(users.id, 1), gte(users.id, 1), lt(users.id, 1), diff --git a/drizzle-orm/type-tests/mysql/select.ts b/drizzle-orm/type-tests/mysql/select.ts index 2dc826af73..62e3f9c2bc 100644 --- a/drizzle-orm/type-tests/mysql/select.ts +++ b/drizzle-orm/type-tests/mysql/select.ts @@ -308,6 +308,8 @@ const allOperators = await db ne(users.id, 1), or(eq(users.id, 1), ne(users.id, 1)), not(eq(users.id, 1)), + not(and(eq(users.id, 1), ne(users.id, 1))), + not(or(eq(users.id, 1), ne(users.id, 1))), gt(users.id, 1), gte(users.id, 1), lt(users.id, 1), diff --git a/drizzle-orm/type-tests/pg/select.ts b/drizzle-orm/type-tests/pg/select.ts index dcf99428a6..e809f61738 100644 --- a/drizzle-orm/type-tests/pg/select.ts +++ b/drizzle-orm/type-tests/pg/select.ts @@ -439,6 +439,8 @@ const allOperators = await db ne(users.id, 1), or(eq(users.id, 1), ne(users.id, 1)), not(eq(users.id, 1)), + not(and(eq(users.id, 1), ne(users.id, 1))), + not(or(eq(users.id, 1), ne(users.id, 1))), gt(users.id, 1), gte(users.id, 1), lt(users.id, 1), diff --git a/drizzle-orm/type-tests/singlestore/select.ts b/drizzle-orm/type-tests/singlestore/select.ts index 6ec81f6c3f..ae32727647 100644 --- a/drizzle-orm/type-tests/singlestore/select.ts +++ b/drizzle-orm/type-tests/singlestore/select.ts @@ -376,6 +376,8 @@ const allOperators = await db ne(users.id, 1), or(eq(users.id, 1), ne(users.id, 1)), not(eq(users.id, 1)), + not(and(eq(users.id, 1), ne(users.id, 1))), + not(or(eq(users.id, 1), ne(users.id, 1))), gt(users.id, 1), gte(users.id, 1), lt(users.id, 1), diff --git a/drizzle-orm/type-tests/sqlite/select.ts b/drizzle-orm/type-tests/sqlite/select.ts index 0140fc19bb..5f54f46a1b 100644 --- a/drizzle-orm/type-tests/sqlite/select.ts +++ b/drizzle-orm/type-tests/sqlite/select.ts @@ -387,6 +387,8 @@ const allOperators = db ne(users.id, 1), or(eq(users.id, 1), ne(users.id, 1)), not(eq(users.id, 1)), + not(and(eq(users.id, 1), ne(users.id, 1))), + not(or(eq(users.id, 1), ne(users.id, 1))), gt(users.id, 1), gte(users.id, 1), lt(users.id, 1),