The SQL DSL (Documentation Index
Fetch the complete documentation index at: https://mintlify.com/prisma/prisma-next/llms.txt
Use this file to discover all available pages before exploring further.
db.sql) is Prisma Next’s lower-level query builder. It lets you compose type-safe SQL plans from individual operations — select, where, order, limit, join — without writing raw SQL strings. Plans are built offline (no network I/O) and executed separately, which makes them easy to inspect, test, and log.
Importing and using db.sql
db.sql is available on both the postgres() (Node) and postgresServerless() facades. It is part of the static authoring surface and is safe to use at module scope:
Selecting columns
Use.select() with field names from your contract. The return type is inferred from the columns you pick:
Filtering with .where()
The .where() callback receives two arguments: f (field references) and fns (built-in predicate functions). Use fns to build expressions:
fns predicates: eq, ne, gt, gte, lt, lte, in, notIn, and, or, exists, notExists. Extension packs may add additional predicates (for example, fns.cosineDistance from pgvector).
Ordering with .orderBy()
Pass a callback that selects a field and specifies a direction:
Limiting and paginating
Use.limit() for a hard row cap:
Joining related tables
Use.innerJoin() or .outerLeftJoin() to bring in columns from a related table. Use .as() to alias tables, then reference fields by alias in the expression callback:
innerJoin, outerLeftJoin, outerRightJoin, outerFullJoin, and lateralJoin (requires the lateral capability in your contract).
Mutations: insert, update, delete
The table proxy also exposesinsert(), update(), and delete(). Mutation queries support .returning() to get back the affected rows:
Building a plan with .build()
.build() compiles the current builder state into a SqlQueryPlan. This is a pure in-memory operation — no database connection required:
Building and executing are separate steps.
.build() produces a serializable plan object; runtime.execute(plan) sends it to the database. You can build plans at module scope, cache them, or serialize them for logging — none of that requires a live connection.Executing a plan with runtime.execute()
Call db.runtime() (synchronous — returns the cached runtime) and pass the plan to execute():
Result types from contract.d.ts
The return type of runtime.execute(plan) is fully inferred from the columns you selected. No manual casting is needed:
Parameterized queries
Values you pass tofns predicates are automatically encoded as bind parameters — you never interpolate raw values into query strings: