Rindle

API index and search · Build metadata

Source snapshot

packages/query-compiler/src/dialect.ts

Source revision 05d0bf2c2e56 · build details
Source revision: 05d0bf2c2e56.
TypeScript input SHA-256: aabe6cfcc4172b870d5e272142958e9ea8d8784c2aa23133156e5a7ee633318e
Generated 2026-09-04T23:58:25.590Z with TypeScript 6.0.3. Public TypeScript checks and declaration emit passed. Package runtime tests are separate.
1// The dialect seam (§6.1). The walker is dialect-independent; only these leaves differ2// between SQLite and Postgres: the Postgres leaf carries the §6.2 `::text::<type>` casts and3// explicit NULLS ordering; the SQLite leaf binds natives with NO casts (the canonical store4// needs no reconciliation — DAEMON-INTERACTIVE-TXN-DESIGN.md §5.4).56import type { Dir } from "./ast.ts";7import type { ColumnType } from "./catalog.ts";89/** A scalar value bindable as a parameter (an array filter value is split into scalars). */10export type LitScalar = null | boolean | number | string;1112export interface Dialect {13  readonly name: "postgres" | "sqlite";1415  /** `json_object('k', v, …)` | `jsonb_build_object('k', v, …)`. `parts` are the flat16   *  `'key', valueExpr` fragments, in order. */17  objectBuild(parts: string[]): string;1819  /** The array aggregate over `elem` with `orderSql` (e.g. ` ORDER BY __o0 ASC`) inside:20   *  `json_group_array(elem ORDER BY …)` | `jsonb_agg(elem ORDER BY …)`. */21  groupArray(elem: string, orderSql: string): string;2223  /** The empty-array default for the `COALESCE` wrapper: `'[]'` | `'[]'::jsonb`. */24  readonly emptyArray: string;2526  /** Re-assert the JSON subtype on a value round-tripped through a subquery's `AS` column27   *  (`json(x)` in SQLite; identity in Postgres, where `jsonb` is a real type). */28  reassertJson(x: string): string;2930  /** The truthy/falsy constants for empty `AND`/`OR` folding and boolean keyword positions:31   *  `1`/`0` | `TRUE`/`FALSE`. */32  readonly trueLit: string;33  readonly falseLit: string;3435  /** An `ORDER BY` direction with the engine's null-low ordering made explicit where the36   *  dialect default differs (§8): SQLite is null-low by default (`ASC`/`DESC`); Postgres's37   *  default is the opposite, so it must emit `ASC NULLS FIRST` / `DESC NULLS LAST`. */38  orderDir(dir: Dir): string;3940  /** Project a stored column into the value model's representation for the result JSON.41   *  Identity in SQLite; the outbound half of §6.2 in Postgres (e.g. timestamptz → epoch-ms). */42  projectColumn(colRef: string, col: ColumnType | null): string;4344  /** Bind a scalar filter/paging value as a parameter: push onto `params`, return the45   *  placeholder SQL. `col` is the compared column's type when known (drives the Postgres46   *  `::text::<type>` casts, §6.2); `null` ⇒ infer from the JS type. SQLite ignores `col`47   *  and `isComparison` — it binds natives. */48  bindValue(params: unknown[], value: LitScalar, col: ColumnType | null, isComparison: boolean): string;4950  /** Double-quote an identifier, doubling embedded `"`. Identical across dialects (kept on51   *  the seam for uniformity). */52  quoteIdent(name: string): string;53}5455function quoteIdent(name: string): string {56  return `"${name.replace(/"/g, '""')}"`;57}5859/**60 * The SQLite dialect — the daemon backend's session-read target (DAEMON-INTERACTIVE-TXN §5.4)61 * and the offline differential oracle (§9). It binds native values as parameters (no62 * `::text::<type>` casts — SQLite is the canonical store, so there is no driver seam to pin63 * and no second representation to reconcile), relies on SQLite's null-low default ordering64 * (which matches the engine's `null < everything`), and re-asserts the `json()` subtype where65 * objects round-trip through a subquery column. Matches `rindle-d2s`'s raw SQL shapes so the66 * two agree modulo parameterization; the executing connection must run67 * `PRAGMA case_sensitive_like = ON` (every daemon cluster connection does — `open_wal2`).68 */69export const sqliteDialect: Dialect = {70  name: "sqlite",71  objectBuild: (parts) => `json_object(${parts.join(", ")})`,72  groupArray: (elem, orderSql) => `json_group_array(${elem}${orderSql})`,73  emptyArray: "'[]'",74  reassertJson: (x) => `json(${x})`,75  trueLit: "1",76  falseLit: "0",77  orderDir: (dir) => (dir === "asc" ? "ASC" : "DESC"),78  projectColumn: (colRef) => colRef,79  bindValue: (params, value) => {80    // SQLite has no boolean type; its driver binds 1/0. Everything else binds natively.81    params.push(typeof value === "boolean" ? (value ? 1 : 0) : value);82    return "?";83  },84  quoteIdent,85};86