Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,13 @@
- **Docs & references**: `ARCHITECTURE.md` contains dependency graphs (requires GraphViz to regenerate), `docker/README.md` explains local DB setup, `docs/benchmarking.md` covers performance benchmarking, `examples/` provides sample apps, and `sandbox/` hosts debugging helpers like the DMMF explorer.

- **Client architecture (Prisma 7)**:
- `ClientEngine` in `packages/client/src/runtime/core/engines/client/` orchestrates query execution using WASM query compiler.
- `ClientEngine` in `packages/client/src/runtime/core/engines/client/` orchestrates query execution using Wasm query compiler.
- Two executor implementations: `LocalExecutor` (driver adapters, direct DB) and `RemoteExecutor` (Accelerate/Data Proxy).
- `QueryInterpreter` class in `packages/client-engine-runtime/src/interpreter/query-interpreter.ts` executes query plans against `SqlQueryable` (driver adapter interface).
- Query flow: `PrismaClient` → `ClientEngine.request()` → query compiler → `executor.execute()` → `QueryInterpreter.run()` → driver adapter.
- `ExecutePlanParams` interface in `packages/client/src/runtime/core/engines/client/Executor.ts` defines what's passed through the execution chain.
- `TransactionManager` in `packages/client-engine-runtime/src/transaction-manager/transaction-manager.ts` owns interactive transaction IDs and implements nested transactions using savepoints. Savepoint SQL is provider-specific (e.g. PostgreSQL uses `ROLLBACK TO SAVEPOINT <name>`, MySQL/SQLite use `ROLLBACK TO <name>`, SQL Server uses `SAVE TRANSACTION <name>` / `ROLLBACK TRANSACTION <name>` and has no release statement).
- `Transaction` in `packages/driver-adapter-utils` models savepoint behavior as async methods (`createSavepoint`, `rollbackToSavepoint`, optional `releaseSavepoint`) instead of returning SQL via `savepoint(action, name)`. `TransactionManager` expects adapter methods for savepoints and does not synthesize provider fallback SQL.
- Fluent API `dataPath` is built in `packages/client/src/runtime/core/model/applyFluent.ts` by appending `['select', <relationName>]` on each hop; runtime unpacking in `packages/client/src/runtime/RequestHandler.ts` currently strips `'select'`/`'include'` segments before `deepGet`.
- In extension context resolution, `dataPath` should be interpreted as selector/field pairs (`select|include`, relation field). Do not strip by raw string value or relation fields literally named `select`/`include` get dropped.

Expand Down
1 change: 1 addition & 0 deletions eslint.config.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ module.exports = [
'**/fixtures/**',
'**/__fixtures__/**',
'**/generated/**',
'**/.generated/**',
'**/prism.ts',
'**/charm.ts',
'**/pnpm-lock.yaml',
Expand Down
12 changes: 12 additions & 0 deletions packages/adapter-better-sqlite3/src/better-sqlite3.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,18 @@ class BetterSQLite3Transaction extends BetterSQLite3Queryable<StdClient> impleme
this.#unlockParent()
return Promise.resolve()
}

async createSavepoint(name: string): Promise<void> {
await this.executeRaw({ sql: `SAVEPOINT ${name}`, args: [], argTypes: [] })
}

async rollbackToSavepoint(name: string): Promise<void> {
await this.executeRaw({ sql: `ROLLBACK TO ${name}`, args: [], argTypes: [] })
}

async releaseSavepoint(name: string): Promise<void> {
await this.executeRaw({ sql: `RELEASE SAVEPOINT ${name}`, args: [], argTypes: [] })
}
}

export class PrismaBetterSqlite3Adapter extends BetterSQLite3Queryable<StdClient> implements SqlDriverAdapter {
Expand Down
12 changes: 12 additions & 0 deletions packages/adapter-d1/src/d1-http.ts
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,18 @@ class D1HttpTransaction extends D1HttpQueryable implements Transaction {
async rollback(): Promise<void> {
debug(`[js::rollback]`)
}

async createSavepoint(name: string): Promise<void> {
await this.executeRaw({ sql: `SAVEPOINT ${name}`, args: [], argTypes: [] })
}

async rollbackToSavepoint(name: string): Promise<void> {
await this.executeRaw({ sql: `ROLLBACK TO ${name}`, args: [], argTypes: [] })
}

async releaseSavepoint(name: string): Promise<void> {
await this.executeRaw({ sql: `RELEASE SAVEPOINT ${name}`, args: [], argTypes: [] })
}
}

export class PrismaD1HttpAdapter extends D1HttpQueryable implements SqlDriverAdapter {
Expand Down
12 changes: 12 additions & 0 deletions packages/adapter-d1/src/d1-worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,18 @@ class D1WorkerTransaction extends D1WorkerQueryable<StdClient> implements Transa
async rollback(): Promise<void> {
debug(`[js::rollback]`)
}

async createSavepoint(name: string): Promise<void> {
await this.executeRaw({ sql: `SAVEPOINT ${name}`, args: [], argTypes: [] })
}

async rollbackToSavepoint(name: string): Promise<void> {
await this.executeRaw({ sql: `ROLLBACK TO ${name}`, args: [], argTypes: [] })
}

async releaseSavepoint(name: string): Promise<void> {
await this.executeRaw({ sql: `RELEASE SAVEPOINT ${name}`, args: [], argTypes: [] })
}
}

export class PrismaD1WorkerAdapter extends D1WorkerQueryable<StdClient> implements SqlDriverAdapter {
Expand Down
12 changes: 12 additions & 0 deletions packages/adapter-libsql/src/libsql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,18 @@ class LibSqlTransaction extends LibSqlQueryable<TransactionClient> implements Tr
this.#unlockParent()
}
}

async createSavepoint(name: string): Promise<void> {
await this.executeRaw({ sql: `SAVEPOINT ${name}`, args: [], argTypes: [] })
}

async rollbackToSavepoint(name: string): Promise<void> {
await this.executeRaw({ sql: `ROLLBACK TO ${name}`, args: [], argTypes: [] })
}

async releaseSavepoint(name: string): Promise<void> {
await this.executeRaw({ sql: `RELEASE SAVEPOINT ${name}`, args: [], argTypes: [] })
}
}

export class PrismaLibSqlAdapter extends LibSqlQueryable<StdClient> implements SqlDriverAdapter {
Expand Down
12 changes: 12 additions & 0 deletions packages/adapter-mariadb/src/mariadb.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,18 @@ class MariaDbTransaction extends MariaDbQueryable<mariadb.Connection> implements
this.cleanup?.()
await this.client.end()
}

async createSavepoint(name: string): Promise<void> {
await this.executeRaw({ sql: `SAVEPOINT ${name}`, args: [], argTypes: [] })
}

async rollbackToSavepoint(name: string): Promise<void> {
await this.executeRaw({ sql: `ROLLBACK TO ${name}`, args: [], argTypes: [] })
}

async releaseSavepoint(name: string): Promise<void> {
await this.executeRaw({ sql: `RELEASE SAVEPOINT ${name}`, args: [], argTypes: [] })
}
}

export type PrismaMariadbOptions = {
Expand Down
8 changes: 8 additions & 0 deletions packages/adapter-mssql/src/mssql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,14 @@ class MssqlTransaction extends MssqlQueryable implements Transaction {
release()
}
}

async createSavepoint(name: string): Promise<void> {
await this.executeRaw({ sql: `SAVE TRANSACTION ${name}`, args: [], argTypes: [] })
}

async rollbackToSavepoint(name: string): Promise<void> {
await this.executeRaw({ sql: `ROLLBACK TRANSACTION ${name}`, args: [], argTypes: [] })
}
}

export type PrismaMssqlOptions = {
Expand Down
12 changes: 12 additions & 0 deletions packages/adapter-neon/src/neon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,18 @@ class NeonTransaction extends NeonWsQueryable<neon.PoolClient> implements Transa
this.cleanup?.()
this.client.release()
}

async createSavepoint(name: string): Promise<void> {
await this.executeRaw({ sql: `SAVEPOINT ${name}`, args: [], argTypes: [] })
}

async rollbackToSavepoint(name: string): Promise<void> {
await this.executeRaw({ sql: `ROLLBACK TO SAVEPOINT ${name}`, args: [], argTypes: [] })
}

async releaseSavepoint(name: string): Promise<void> {
await this.executeRaw({ sql: `RELEASE SAVEPOINT ${name}`, args: [], argTypes: [] })
}
}

export type PrismaNeonOptions = {
Expand Down
12 changes: 12 additions & 0 deletions packages/adapter-pg/src/pg.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,18 @@ class PgTransaction extends PgQueryable<TransactionClient> implements Transactio
this.cleanup?.()
this.client.release()
}

async createSavepoint(name: string): Promise<void> {
await this.executeRaw({ sql: `SAVEPOINT ${name}`, args: [], argTypes: [] })
}

async rollbackToSavepoint(name: string): Promise<void> {
await this.executeRaw({ sql: `ROLLBACK TO SAVEPOINT ${name}`, args: [], argTypes: [] })
}

async releaseSavepoint(name: string): Promise<void> {
await this.executeRaw({ sql: `RELEASE SAVEPOINT ${name}`, args: [], argTypes: [] })
}
}

export type PrismaPgOptions = {
Expand Down
12 changes: 12 additions & 0 deletions packages/adapter-planetscale/src/planetscale.ts
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,18 @@ class PlanetScaleTransaction extends PlanetScaleQueryable<planetScale.Transactio
this.txDeferred.reject(new RollbackError())
return await this.txResultPromise
}

async createSavepoint(name: string): Promise<void> {
await this.executeRaw({ sql: `SAVEPOINT ${name}`, args: [], argTypes: [] })
}

async rollbackToSavepoint(name: string): Promise<void> {
await this.executeRaw({ sql: `ROLLBACK TO ${name}`, args: [], argTypes: [] })
}

async releaseSavepoint(name: string): Promise<void> {
await this.executeRaw({ sql: `RELEASE SAVEPOINT ${name}`, args: [], argTypes: [] })
}
}

export class PrismaPlanetScaleAdapter extends PlanetScaleQueryable<planetScale.Client> implements SqlDriverAdapter {
Expand Down
12 changes: 12 additions & 0 deletions packages/adapter-ppg/src/ppg.ts
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,18 @@ class PrismaPostgresTransaction implements Transaction {
}
}

async createSavepoint(name: string): Promise<void> {
await this.executeRaw({ sql: `SAVEPOINT ${name}`, args: [], argTypes: [] })
}

async rollbackToSavepoint(name: string): Promise<void> {
await this.executeRaw({ sql: `ROLLBACK TO SAVEPOINT ${name}`, args: [], argTypes: [] })
}

async releaseSavepoint(name: string): Promise<void> {
await this.executeRaw({ sql: `RELEASE SAVEPOINT ${name}`, args: [], argTypes: [] })
}

async executeRaw(params: SqlQuery): Promise<number> {
await this.#ensureBegun()
return executeRawStatement(this.#session, params)
Expand Down
Loading
Loading