---
title: "Query Builder Core"
description: "The \"Query Builder Core\" subsystem serves as the foundational abstraction layer that decouples Drizzle's expressive DSL from the myriad of underlying database drivers and execution runtimes. By pro..."
last_updated: "2026-08-13T14:49:35.852265+00:00"
canonical_url: "https://www.doc0.dev/docs/e1b68fed-3c4e-4c95-b2ba-ebf050f78025/technical/query-engine/query-builder-core"
---

<details>
<summary>Relevant source files</summary>

The following files were used as context for generating this wiki page:

- [drizzle-orm/src/mysql2/session.ts](https://github.com/blade47/drizzle-orm/blob/main/drizzle-orm/src/mysql2/session.ts)
- [drizzle-orm/src/bun-sql/session.ts](https://github.com/blade47/drizzle-orm/blob/main/drizzle-orm/src/bun-sql/session.ts)
- [drizzle-orm/src/postgres-js/session.ts](https://github.com/blade47/drizzle-orm/blob/main/drizzle-orm/src/postgres-js/session.ts)
- [drizzle-orm/src/gel/session.ts](https://github.com/blade47/drizzle-orm/blob/main/drizzle-orm/src/gel/session.ts)
- [drizzle-orm/src/singlestore-core/session.ts](https://github.com/blade47/drizzle-orm/blob/main/drizzle-orm/src/singlestore-core/session.ts)
- [drizzle-orm/src/mysql-proxy/session.ts](https://github.com/blade47/drizzle-orm/blob/main/drizzle-orm/src/mysql-proxy/session.ts)
- [drizzle-orm/src/op-sqlite/session.ts](https://github.com/blade47/drizzle-orm/blob/main/drizzle-orm/src/op-sqlite/session.ts)
- [drizzle-orm/src/pg-proxy/session.ts](https://github.com/blade47/drizzle-orm/blob/main/drizzle-orm/src/pg-proxy/session.ts)
- [drizzle-orm/src/sqlite-core/session.ts](https://github.com/blade47/drizzle-orm/blob/main/drizzle-orm/src/sqlite-core/session.ts)
- [drizzle-orm/src/xata-http/session.ts](https://github.com/blade47/drizzle-orm/blob/main/drizzle-orm/src/xata-http/session.ts)
- [drizzle-orm/src/sqlite-proxy/session.ts](https://github.com/blade47/drizzle-orm/blob/main/drizzle-orm/src/sqlite-proxy/session.ts)
- [drizzle-orm/src/libsql/session.ts](https://github.com/blade47/drizzle-orm/blob/main/drizzle-orm/src/libsql/session.ts)
- [drizzle-orm/src/mysql-core/session.ts](https://github.com/blade47/drizzle-orm/blob/main/drizzle-orm/src/mysql-core/session.ts)
- [drizzle-orm/src/singlestore/session.ts](https://github.com/blade47/drizzle-orm/blob/main/drizzle-orm/src/singlestore/session.ts)
- [drizzle-orm/src/singlestore-proxy/session.ts](https://github.com/blade47/drizzle-orm/blob/main/drizzle-orm/src/singlestore-proxy/session.ts)
- [drizzle-orm/src/planetscale-serverless/session.ts](https://github.com/blade47/drizzle-orm/blob/main/drizzle-orm/src/planetscale-serverless/session.ts)
- [drizzle-orm/src/bun-sqlite/session.ts](https://github.com/blade47/drizzle-orm/blob/main/drizzle-orm/src/bun-sqlite/session.ts)
- [drizzle-orm/src/better-sqlite3/session.ts](https://github.com/blade47/drizzle-orm/blob/main/drizzle-orm/src/better-sqlite3/session.ts)
- [drizzle-orm/src/neon-serverless/session.ts](https://github.com/blade47/drizzle-orm/blob/main/drizzle-orm/src/neon-serverless/session.ts)
- [drizzle-orm/src/expo-sqlite/session.ts](https://github.com/blade47/drizzle-orm/blob/main/drizzle-orm/src/expo-sqlite/session.ts)
- [drizzle-orm/src/gel-core/query-builders/query-builder.ts](https://github.com/blade47/drizzle-orm/blob/main/drizzle-orm/src/gel-core/query-builders/query-builder.ts)
- [drizzle-orm/src/sqlite-core/db.ts](https://github.com/blade47/drizzle-orm/blob/main/drizzle-orm/src/sqlite-core/db.ts)
- [drizzle-orm/src/pg-core/query-builders/query-builder.ts](https://github.com/blade47/drizzle-orm/blob/main/drizzle-orm/src/pg-core/query-builders/query-builder.ts)
</details>

The "Query Builder Core" subsystem serves as the foundational abstraction layer that decouples Drizzle's expressive DSL from the myriad of underlying database drivers and execution runtimes. By providing standardized interfaces for statement preparation, query execution, and transactional lifecycle management, it enables the Drizzle ORM to support diverse targets—including PostgreSQL (Neon, Postgres.js, Bun SQL), MySQL (PlanetScale, MySQL2), and SQLite (Better-SQLite3, LibSQL, OP-SQLite)—without exposing developers to the idiosyncratic differences of each driver’s API.

At its heart, the core resides in driver-specific classes that extend base session and query classes. These implementations manage database connections, provide methods for transactional scope creation, and act as a factory for specific prepared query objects. Each driver maps the generic Drizzle execution methods (like `.execute()`, `.all()`, or `.get()`) to the target driver’s specific command execution protocols.

The architecture emphasizes type-safe query composition and efficient execution. By abstracting the interaction into prepared query objects, Drizzle defers the actual SQL generation and parameter binding until the moment of execution, allowing for driver-level optimizations, logging, and caching strategies. This design decouples the "query intent" from "query execution," permitting centralized features like query caching, tracing, and result set mapping to operate consistently across disparate backend storage engines.

## Session Lifecycle and Factory Mechanism

The base session classes are the primary orchestrators for driver-level interactions. They mandate the implementation of `prepareQuery`, which creates an instance of a prepared query subclass specifically tailored for the underlying driver. This factory pattern ensures that every dialect-specific detail—such as parameter placeholders, type parsing, or vendor-specific SQL extensions—is encapsulated within the prepared query instance rather than leaking into the main application logic.

Sources: [drizzle-orm/src/mysql-core/session.ts:180-191](https://github.com/blade47/drizzle-orm/blob/main/drizzle-orm/src/mysql-core/session.ts#L180-L191)

## Query Execution and Cache Pipeline

The execution flow for queries is centralized to leverage common cross-dialect features. The `queryWithCache` method, present in various prepared query implementations, serves as the main gateway for query dispatch. It checks the global cache configuration before invoking the driver's execution method. For mutation queries (INSERT, UPDATE, DELETE), this method orchestrates both the database execution and the necessary cache invalidation via the `onMutate` interface, ensuring data consistency across the application.

> [!NOTE]
> During mutations, `onMutate` is called concurrently with the database query to allow the cache to invalidate specific table entries based on the `queryMetadata` tables.

Sources: [drizzle-orm/src/mysql-core/session.ts:70-154](https://github.com/blade47/drizzle-orm/blob/main/drizzle-orm/src/mysql-core/session.ts#L70-L154), [drizzle-orm/src/sqlite-core/session.ts:71-155](https://github.com/blade47/drizzle-orm/blob/main/drizzle-orm/src/sqlite-core/session.ts#L71-L155)

## Transactional Scoping and Savepoints

Transactional management follows a consistent lifecycle across drivers: creating a transaction instance, executing an initialization command (e.g., `BEGIN`), performing the user-provided transaction callback, and finalizing with a commit or rollback command. Nested transactions are typically supported via `SAVEPOINT` logic, where the transaction instance tracks a `nestedIndex` to generate unique savepoint names.

```mermaid
sequenceDiagram
    participant User
    participant TX
    participant DB
    User->>TX: transaction(callback)
    TX->>DB: savepoint sp1
    activate DB
    TX->>DB: callback()
    DB-->>TX: success
    TX->>DB: release savepoint sp1
    deactivate DB
    User-->>TX: result
```

Sources: [drizzle-orm/src/mysql2/session.ts:331-349](https://github.com/blade47/drizzle-orm/blob/main/drizzle-orm/src/mysql2/session.ts#L331-L349), [drizzle-orm/src/sqlite-core/session.ts:151-162](https://github.com/blade47/drizzle-orm/blob/main/drizzle-orm/src/sqlite-core/session.ts#L151-L162)

## Parameter Placeholder Handling

To ensure security and compatibility, all drivers utilize the `fillPlaceholders` utility. This mechanism maps the user-provided parameter values against the query string's expected placeholders. This ensures that the final SQL string sent to the driver is correctly formatted and that parameters are passed via the driver’s secure parameterized query interface, preventing SQL injection.

Sources: [drizzle-orm/src/mysql2/session.ts:93-95](https://github.com/blade47/drizzle-orm/blob/main/drizzle-orm/src/mysql2/session.ts#L93-L95), [drizzle-orm/src/pg-core/session.ts:13-15](https://github.com/blade47/drizzle-orm/blob/main/drizzle-orm/src/pg-core/session.ts#L13-L15)

## Driver-Specific Result Mapping

Result mapping is a critical step where raw rows are transformed into the expected entity shape using `mapResultRow`. This utility is invoked within the prepared query’s execution methods (`execute` or `all`). By relying on column-based metadata, Drizzle can reconstruct nested relational objects or alias complex SQL expressions into predictable JavaScript object shapes.

Sources: [drizzle-orm/src/mysql2/session.ts:142-142](https://github.com/blade47/drizzle-orm/blob/main/drizzle-orm/src/mysql2/session.ts#L142-L142), [drizzle-orm/src/bun-sql/session.ts:74-74](https://github.com/blade47/drizzle-orm/blob/main/drizzle-orm/src/bun-sql/session.ts#L74-L74)

## Design Choices and Implementation Trade-offs

| Design Choice | Benefit | Cost |
| :--- | :--- | :--- |
| **Abstract Sessions** | Unified API for all databases. | Requires driver-specific implementations of low-level methods. |
| **Prepared Query Factory** | Consistent query caching and metadata tracking. | Increased object allocation per query. |
| **Lazy Dialect Loading** | Prevents circular dependencies during init. | Slightly deferred initialization error detection. |

Sources: [drizzle-orm/src/gel-core/query-builders/query-builder.ts:128-135](https://github.com/blade47/drizzle-orm/blob/main/drizzle-orm/src/gel-core/query-builders/query-builder.ts#L128-L135)

## Practical Example: Using the Query Builder

Developers interact with the core primarily through the database instance, which delegates execution to the session.

```typescript
// Example: Executing a query with the SQLite core API
const users = sqliteTable('users', { id: integer('id'), name: text('name') });

// db is an instance of BaseSQLiteDatabase
const allUsers = await db.select().from(users).all();

// Underlying execution chain:
// 1. db.select() -> SQLiteSelectBuilder
// 2. .from(users) -> sets table
// 3. .all() -> calls session.all()
// 4. session.prepareOneTimeQuery().all() -> maps to driver-specific execution
```

Sources: [drizzle-orm/src/sqlite-core/db.ts:396-402](https://github.com/blade47/drizzle-orm/blob/main/drizzle-orm/src/sqlite-core/db.ts#L396-L402), [drizzle-orm/src/sqlite-core/session.ts:280-285](https://github.com/blade47/drizzle-orm/blob/main/drizzle-orm/src/sqlite-core/session.ts#L280-L285)

## Related

- [Select Queries](https://www.doc0.dev/docs/e1b68fed-3c4e-4c95-b2ba-ebf050f78025/technical/query-engine/select-queries)
- [Data Mutations](https://www.doc0.dev/docs/e1b68fed-3c4e-4c95-b2ba-ebf050f78025/technical/query-engine/data-mutations)


## Sitemap

See the full [sitemap](https://www.doc0.dev/docs/e1b68fed-3c4e-4c95-b2ba-ebf050f78025/llms.txt) for all pages in this wiki.
