Skip to content

Filtering

where() adds a filter to the plan. Filters compile to WHERE clauses with bound parameters. Values are never interpolated into SQL.

db.from(users).where("age", ">", 18);
db.from(users).where("age", ">=", 18);
db.from(users).where("age", "<", 65);
db.from(users).where("age", "<=", 65);
db.from(users).where("email", "=", "a@b.c");
db.from(users).where("email", "!=", "a@b.c");
Operator Meaning
= != equality / inequality
> >= < <= numeric / date comparison
like pattern match (% wildcard)
in value in a list
is is not null checks
between range (inclusive)
db.from(users).where("id", "in", [1, 2, 3]);
// → WHERE "id" IN (?, ?, ?)
db.from(users).where("email", "like", "ada%");
db.from(users).where("age", "is", null);
db.from(users).where("age", "is not", null);
db.from(users).where("age", "between", [18, 65]);

Pass a function to or() to group alternatives:

db.from(users).or((b) =>
b.where("age", "<", 18).where("age", ">", 65),
);
// → WHERE ("age" < ? OR "age" > ?)
db.from(users).whereExists(
db.from(posts).where("authorId", "=", /* column ref */ "users.id"),
);

You can pass a raw FilterNode to where() — this is how RLS policies inject filters:

import { applyPolicy } from "@mountsqli/auth";
const scoped = applyPolicy(db.from(files), allowOwner("ownerId"), { userId });
  • Chain where() to AND multiple conditions.
  • Use in for membership instead of multiple or equals.
  • Keep filters in the plan; don’t filter rows in app code.
  • Using = with null — use is null instead.
  • String-interpolating a value into a raw expression — bind it as a param.