Skip to content

Query Execution

Execution is the path from a builder call to typed rows. It has four steps.

sequenceDiagram
  participant B as Builder
  participant C as Compiler
  participant D as Driver
  participant DB as Database
  B->>C: compilePlan(plan, dialect)
  C->>D: { sql, params, columnTypes }
  D->>DB: execute(sql, params)
  DB-->>D: raw rows
  D-->>B: typed rows (decoded)
  1. CompilecompilePlan(plan, dialect){ sql, params, columnTypes }.
  2. Bind — the driver sends SQL + params to the database.
  3. Run — the database returns rows (driver-agnostic).
  4. Decode — the driver uses columnTypes to decode values (e.g. 0/1boolean) back into the InferTable shape.

The plan carries columnTypes, so the driver knows bool columns should become boolean even though the DB stored 0/1. Your app never sees the raw form.

The builder forks a new plan per method; the compiled output is also derived, never mutated. This is why concurrent queries don’t interfere.

  • Await terminal methods (all, findOne, insert, …) — that’s when execution happens.
  • Let the driver decode types; don’t re-cast in app code.
  • Calling builder methods and expecting execution (only terminals run).
  • Assuming bool returns 0/1 (the driver decodes it).