@vibeorm/sql 2.0.0-alpha.2 → 2.0.0-alpha.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/ast.d.ts CHANGED
@@ -251,6 +251,25 @@ export type ListSetOperation = {
251
251
  };
252
252
  /** Narrow an UPDATE set value to a {@link ListSetOperation}. */
253
253
  export declare function isListSetOperation(value: unknown): value is ListSetOperation;
254
+ /**
255
+ * Database-clock marker: renders the DIALECT's `now()` expression — plus an
256
+ * optional whole-second offset bound as a parameter — instead of binding a
257
+ * client-side timestamp. Flows as a VALUES cell, an UPDATE SET value, or a
258
+ * comparison operand; the runtime's public `dbNow()` sentinel compiles to
259
+ * this marker for DateTime fields (leases, TTLs — anything that must trust
260
+ * the database's clock, never the process's). Same structural-marker
261
+ * discipline as {@link SetOperation}: unlikely key, exact shape.
262
+ */
263
+ export type DbNowMarker = {
264
+ readonly __dbNow: true;
265
+ readonly offsetSeconds: number;
266
+ };
267
+ /** Build a {@link DbNowMarker}; `offsetSeconds` must be a whole number. */
268
+ export declare function dbNowMarker(params: {
269
+ offsetSeconds: number;
270
+ }): DbNowMarker;
271
+ /** Narrow a value to a {@link DbNowMarker}. */
272
+ export declare function isDbNowMarker(value: unknown): value is DbNowMarker;
254
273
  /** ORDER BY a column, with optional NULLS placement (native or emulated per dialect). */
255
274
  export type OrderByColumn = {
256
275
  readonly column: ColRef;
@@ -436,6 +455,11 @@ export type InsertStatement = {
436
455
  export type OnConflictUpdate = {
437
456
  /** Conflict target columns (ignored by the mysql form). */
438
457
  readonly columns: readonly string[];
458
+ /**
459
+ * Named-constraint target: `ON CONFLICT ON CONSTRAINT "name" DO UPDATE`.
460
+ * Postgres only; replaces the column-list target when present.
461
+ */
462
+ readonly constraint?: string;
439
463
  readonly update: Readonly<Record<string, unknown>>;
440
464
  /**
441
465
  * MySQL only (`upsertForm: "onDuplicateKey"`): append
@@ -449,10 +473,21 @@ export type OnConflictUpdate = {
449
473
  /**
450
474
  * Conflicting rows are skipped (`createMany({ skipDuplicates: true })`).
451
475
  * An empty/absent target means "any conflict" — the mysql form (INSERT IGNORE)
452
- * can only express that, so it ignores `columns` entirely.
476
+ * can only express that, so it ignores a bare `columns` target (documented
477
+ * degradation) and REFUSES the refined targets below.
453
478
  */
454
479
  export type OnConflictDoNothing = {
455
480
  readonly columns?: readonly string[];
481
+ /**
482
+ * Partial-index target predicate, RAW SQL: `ON CONFLICT (cols) WHERE pred
483
+ * DO NOTHING` (postgres/sqlite; requires `columns`). Raw — and rendered
484
+ * verbatim — because BOTH engines match the clause against the index's OWN
485
+ * stored predicate structurally: a bound parameter could never match, so
486
+ * the text mirrors the schema declaration's `where:` string byte-for-byte.
487
+ */
488
+ readonly conflictWhere?: string;
489
+ /** Named-constraint target (`ON CONSTRAINT "name"`) — postgres only. */
490
+ readonly constraint?: string;
456
491
  readonly doNothing: true;
457
492
  };
458
493
  export type OnConflictClause = OnConflictUpdate | OnConflictDoNothing;
package/dist/ast.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"ast.d.ts","sourceRoot":"","sources":["../src/ast.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAIvD,sDAAsD;AACtD,MAAM,MAAM,MAAM,GAAG;IACnB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;;;;;OAMG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,UAAU,GAAG,cAAc,CAAC;IACjD;;;;;;OAMG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B;;;;;OAKG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAIF,iDAAiD;AACjD,MAAM,MAAM,KAAK,GAAG,OAAO,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,CAAC;AAE5D,uEAAuE;AACvE,MAAM,MAAM,MAAM,GACd;IAAE,QAAQ,CAAC,EAAE,EAAE,UAAU,CAAA;CAAE,GAC3B;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEpD;;;;GAIG;AACH,MAAM,MAAM,SAAS,GAAG;IACtB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB,CAAC;AAIF;;;;GAIG;AACH,MAAM,MAAM,YAAY,GACpB,QAAQ,GACR,iBAAiB,GACjB,oBAAoB,GACpB,kBAAkB,GAClB,gBAAgB,GAChB,mBAAmB,GACnB,iBAAiB,CAAC;AAItB,MAAM,MAAM,YAAY,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,KAAK,GAAG,IAAI,GAAG,KAAK,CAAC;AAErE,MAAM,MAAM,OAAO,GACf;IAAE,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,EAAE,EAAE,YAAY,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;CAAE;AACvG,4FAA4F;GAC1F;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,EAAE,EAAE,YAAY,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACrG;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,GAC/E;IACE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,SAAS,OAAO,EAAE,CAAC;IACpC,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;CAC3B,GACD;IACE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,4DAA4D;IAC5D,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAC/B,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;CAC3B;AACH;;;;;;;;;GASG;GACD;IACE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,EAAE,QAAQ,GAAG,UAAU,GAAG,YAAY,GAAG,UAAU,CAAC;IAC/D,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;CAC3B,GACD;IAAE,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,SAAS,OAAO,EAAE,CAAA;CAAE,GAC/D;IAAE,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,SAAS,OAAO,EAAE,CAAA;CAAE,GAC9D;IAAE,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;CAAE;AACrD;;;;;;GAMG;GACD;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC;IAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE;AAC1F,wEAAwE;GACtE;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,EAAE,EAAE,YAAY,CAAC;IAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;CAAE;AACvG;;;GAGG;GACD;IAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE;AAC5G,kGAAkG;GAChG;IAAE,QAAQ,CAAC,IAAI,EAAE,kBAAkB,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,SAAS,OAAO,EAAE,CAAA;CAAE;AACrG,gGAAgG;GAC9F;IAAE,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,SAAS,OAAO,EAAE,CAAA;CAAE;AAClG;;;;GAIG;GACD;IAAE,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;CAAE;AACrF;;;;;;GAMG;GACD;IACE,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC;IAC5C,QAAQ,CAAC,EAAE,EAAE,YAAY,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAC/B,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;CAC3B;AACH;;;;;GAKG;GACD;IAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAA;CAAE;AACnE,8EAA8E;GAC5E;IAAE,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAIpD;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,UAAU,GAClB;IAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GACtD;IAAE,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAA;CAAE,CAAC;AAI7B,2EAA2E;AAC3E,MAAM,MAAM,WAAW,GAAG,WAAW,GAAG,WAAW,GAAG,UAAU,GAAG,QAAQ,CAAC;AAE5E;;;;;;;;GAQG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB,CAAC;AAIF,oEAAoE;AACpE,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,YAAY,CAWpE;AAED;;;;;;;;GAQG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,CAAC,QAAQ,EAAE,QAAQ,GAAG,QAAQ,CAAC;IACvC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;CACzB,CAAC;AAIF,gEAAgE;AAChE,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,gBAAgB,CAM5E;AAID,yFAAyF;AACzF,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,SAAS,EAAE,KAAK,GAAG,MAAM,CAAC;IACnC,kEAAkE;IAClE,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;CACnC,CAAC;AAEF,qFAAqF;AACrF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,SAAS,EAAE,KAAK,GAAG,MAAM,CAAC;CACpC,CAAC;AAEF;;;;;;;;;;GAUG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC;IACjC,QAAQ,CAAC,SAAS,EAAE,KAAK,GAAG,MAAM,CAAC;CACpC,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG,aAAa,GAAG,gBAAgB,GAAG,eAAe,CAAC;AAI3E;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,iFAAiF;IACjF,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,yEAAyE;IACzE,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,iGAAiG;IACjG,QAAQ,CAAC,GAAG,EAAE,WAAW,GAAG,YAAY,CAAC;IACzC,0FAA0F;IAC1F,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC;CAClC,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,MAAM,SAAS,GAAG;IACtB,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC;IACzB,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,EAAE,SAAS;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAC3E,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,MAAM,mBAAmB,GAAG;IAChC,QAAQ,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IACxC,0EAA0E;IAC1E,QAAQ,CAAC,OAAO,EAAE,SAAS,SAAS,EAAE,CAAC;IACvC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC;IACzB,2EAA2E;IAC3E,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC;;;OAGG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,UAAU,CAAC;IACjC;;;;OAIG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,SAAS,EAAE,CAAC;IAC3C;;;;;OAKG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACxC;;;;OAIG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,eAAe,CAAC;IACtC,+EAA+E;IAC/E,QAAQ,CAAC,YAAY,CAAC,EAAE,SAAS,WAAW,EAAE,CAAC;IAC/C,oEAAoE;IACpE,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,SAAS,EAAE,CAAC;IAC3C,sEAAsE;IACtE,QAAQ,CAAC,SAAS,CAAC,EAAE,mBAAmB,CAAC;IACzC,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,4EAA4E;IAC5E,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,SAAS,EAAE,CAAC;IACxC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;OAKG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;CAClC,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,EAAE;IAAE,QAAQ,CAAC,YAAY,EAAE,IAAI,CAAA;CAA0C,CAAC;AAEvG,iEAAiE;AACjE,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAExD;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,aAAa,GAAG;IAAE,QAAQ,CAAC,WAAW,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAElF,oFAAoF;AACpF,wBAAgB,aAAa,CAAC,MAAM,EAAE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,aAAa,CAErE;AAED,uDAAuD;AACvD,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,aAAa,CAMtE;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,uEAAuE;IACvE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,SAAS,OAAO,EAAE,CAAC,EAAE,CAAC;IAC/C,0EAA0E;IAC1E,QAAQ,CAAC,UAAU,CAAC,EAAE,gBAAgB,CAAC;IACvC,iFAAiF;IACjF,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACxC,CAAC;AAEF,6DAA6D;AAC7D,MAAM,MAAM,gBAAgB,GAAG;IAC7B,2DAA2D;IAC3D,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACnD;;;;;;OAMG;IACH,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;CACtC,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,mBAAmB,GAAG;IAChC,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,gBAAgB,GAAG,mBAAmB,CAAC;AAEtE,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC;IACzB,mEAAmE;IACnE,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAChD,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACxC,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC;IACzB,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACxC,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,eAAe,GAAG,eAAe,GAAG,eAAe,GAAG,eAAe,CAAC"}
1
+ {"version":3,"file":"ast.d.ts","sourceRoot":"","sources":["../src/ast.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"capabilities.d.ts","sourceRoot":"","sources":["../src/capabilities.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAEpE,eAAO,MAAM,qBAAqB,EAAE,mBAanC,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAE,mBAajC,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,mBAahC,CAAC;AAEF,eAAO,MAAM,oBAAoB,EAAE,QAAQ,CAAC,MAAM,CAAC,OAAO,EAAE,mBAAmB,CAAC,CAI/E,CAAC"}
1
+ {"version":3,"file":"capabilities.d.ts","sourceRoot":"","sources":["../src/capabilities.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAEpE,eAAO,MAAM,qBAAqB,EAAE,mBAcnC,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAE,mBAcjC,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,mBAchC,CAAC;AAEF,eAAO,MAAM,oBAAoB,EAAE,QAAQ,CAAC,MAAM,CAAC,OAAO,EAAE,mBAAmB,CAAC,CAI/E,CAAC"}
package/dist/dialect.d.ts CHANGED
@@ -7,6 +7,7 @@
7
7
  */
8
8
  import type { Dialect, DialectCapabilities } from "@vibeorm/schema";
9
9
  import type { JsonFilterOp } from "./ast.ts";
10
+ import type { ParamCollector } from "./params.ts";
10
11
  export type SqlDialect = {
11
12
  readonly name: Dialect;
12
13
  /** Frozen feature table — consumed by runtime, migrate, generator, tests. */
@@ -99,5 +100,16 @@ export type SqlDialect = {
99
100
  placeholder(params: {
100
101
  index: number;
101
102
  }): string;
103
+ /**
104
+ * The database-clock expression for `DbNowMarker` sites: `now()` on
105
+ * postgres, `NOW(6)` on mysql, and on sqlite an ISO-8601 `strftime` whose
106
+ * text shape matches the DateTime codec's stored text exactly (so string
107
+ * comparisons against stored values stay correct). A NON-zero whole-second
108
+ * offset binds as a parameter; a zero offset binds nothing.
109
+ */
110
+ renderDbNow(params: {
111
+ offsetSeconds: number;
112
+ collector: ParamCollector;
113
+ }): string;
102
114
  };
103
115
  //# sourceMappingURL=dialect.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"dialect.d.ts","sourceRoot":"","sources":["../src/dialect.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACpE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAE7C,MAAM,MAAM,UAAU,GAAG;IACvB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,6EAA6E;IAC7E,QAAQ,CAAC,YAAY,EAAE,mBAAmB,CAAC;IAG3C,2FAA2F;IAC3F,QAAQ,CAAC,eAAe,EAAE,KAAK,GAAG,QAAQ,CAAC;IAC3C,0BAA0B;IAC1B,QAAQ,CAAC,UAAU,EAAE,YAAY,GAAG,gBAAgB,CAAC;IACrD;;;;;OAKG;IACH,QAAQ,CAAC,aAAa,EAAE,qBAAqB,GAAG,cAAc,CAAC;IAC/D,6EAA6E;IAC7E,QAAQ,CAAC,eAAe,EAAE,OAAO,GAAG,OAAO,CAAC;IAC5C;;;;;;;OAOG;IACH,QAAQ,CAAC,mBAAmB,EAAE,QAAQ,GAAG,MAAM,GAAG,QAAQ,CAAC;IAC3D,gFAAgF;IAChF,QAAQ,CAAC,gBAAgB,EAAE,QAAQ,GAAG,SAAS,CAAC;IAChD,gFAAgF;IAChF,QAAQ,CAAC,mBAAmB,EAAE;QAAE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACpE,sFAAsF;IACtF,QAAQ,CAAC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IACzC;;;;;OAKG;IACH,QAAQ,CAAC,YAAY,EAAE,WAAW,GAAG,eAAe,GAAG,cAAc,CAAC;IACtE;;;;OAIG;IACH,QAAQ,CAAC,gBAAgB,EAAE,SAAS,YAAY,EAAE,CAAC;IACnD;;;;;;;;OAQG;IACH,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B;;;;OAIG;IACH,QAAQ,CAAC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC;;;;;OAKG;IACH,QAAQ,CAAC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC;;;;OAIG;IACH,QAAQ,CAAC,iBAAiB,EAAE,OAAO,CAAC;IACpC;;;;;;OAMG;IACH,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAG7B,+DAA+D;IAC/D,UAAU,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,MAAM,CAAC;IAC7C,wEAAwE;IACxE,WAAW,CAAC,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,MAAM,CAAC;CAChD,CAAC"}
1
+ {"version":3,"file":"dialect.d.ts","sourceRoot":"","sources":["../src/dialect.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACpE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD,MAAM,MAAM,UAAU,GAAG;IACvB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,6EAA6E;IAC7E,QAAQ,CAAC,YAAY,EAAE,mBAAmB,CAAC;IAG3C,2FAA2F;IAC3F,QAAQ,CAAC,eAAe,EAAE,KAAK,GAAG,QAAQ,CAAC;IAC3C,0BAA0B;IAC1B,QAAQ,CAAC,UAAU,EAAE,YAAY,GAAG,gBAAgB,CAAC;IACrD;;;;;OAKG;IACH,QAAQ,CAAC,aAAa,EAAE,qBAAqB,GAAG,cAAc,CAAC;IAC/D,6EAA6E;IAC7E,QAAQ,CAAC,eAAe,EAAE,OAAO,GAAG,OAAO,CAAC;IAC5C;;;;;;;OAOG;IACH,QAAQ,CAAC,mBAAmB,EAAE,QAAQ,GAAG,MAAM,GAAG,QAAQ,CAAC;IAC3D,gFAAgF;IAChF,QAAQ,CAAC,gBAAgB,EAAE,QAAQ,GAAG,SAAS,CAAC;IAChD,gFAAgF;IAChF,QAAQ,CAAC,mBAAmB,EAAE;QAAE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACpE,sFAAsF;IACtF,QAAQ,CAAC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IACzC;;;;;OAKG;IACH,QAAQ,CAAC,YAAY,EAAE,WAAW,GAAG,eAAe,GAAG,cAAc,CAAC;IACtE;;;;OAIG;IACH,QAAQ,CAAC,gBAAgB,EAAE,SAAS,YAAY,EAAE,CAAC;IACnD;;;;;;;;OAQG;IACH,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B;;;;OAIG;IACH,QAAQ,CAAC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC;;;;;OAKG;IACH,QAAQ,CAAC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC;;;;OAIG;IACH,QAAQ,CAAC,iBAAiB,EAAE,OAAO,CAAC;IACpC;;;;;;OAMG;IACH,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAG7B,+DAA+D;IAC/D,UAAU,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,MAAM,CAAC;IAC7C,wEAAwE;IACxE,WAAW,CAAC,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,MAAM,CAAC;IAC/C;;;;;;OAMG;IACH,WAAW,CAAC,MAAM,EAAE;QAAE,aAAa,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,cAAc,CAAA;KAAE,GAAG,MAAM,CAAC;CACnF,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"mysql.d.ts","sourceRoot":"","sources":["../../src/dialects/mysql.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAGhD,eAAO,MAAM,YAAY,EAAE,UAyC1B,CAAC"}
1
+ {"version":3,"file":"mysql.d.ts","sourceRoot":"","sources":["../../src/dialects/mysql.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAGhD,eAAO,MAAM,YAAY,EAAE,UA+C1B,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"postgres.d.ts","sourceRoot":"","sources":["../../src/dialects/postgres.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAGhD,eAAO,MAAM,eAAe,EAAE,UAsC7B,CAAC"}
1
+ {"version":3,"file":"postgres.d.ts","sourceRoot":"","sources":["../../src/dialects/postgres.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAGhD,eAAO,MAAM,eAAe,EAAE,UA0C7B,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"sqlite.d.ts","sourceRoot":"","sources":["../../src/dialects/sqlite.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAGhD,eAAO,MAAM,aAAa,EAAE,UAiD3B,CAAC"}
1
+ {"version":3,"file":"sqlite.d.ts","sourceRoot":"","sources":["../../src/dialects/sqlite.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAGhD,eAAO,MAAM,aAAa,EAAE,UAyD3B,CAAC"}
package/dist/index.d.ts CHANGED
@@ -4,8 +4,8 @@
4
4
  * SQL AST + per-dialect renderers + capability tables. Every SQL-text decision
5
5
  * lives in this package; see the root sql-catalog.md for the reviewable surface.
6
6
  */
7
- export type { AggFn, AggRef, AggSelect, ColRef, ComparisonOp, DeleteStatement, InnerJoin, InsertStatement, JsonFilterOp, LateralJoin, ListSetOperation, OnConflictClause, OnConflictDoNothing, OnConflictUpdate, OrderByAggregate, OrderByColumn, OrderBySubquery, OrderTerm, RowNumberProjection, JsonParamCell, SelectExpr, SelectStatement, SetOperation, SetOperator, SqlExpr, SqlStatement, TableRef, UpdateStatement, } from "./ast.ts";
8
- export { SQL_DEFAULT_CELL, isJsonParamCell, isListSetOperation, isSetOperation, isSqlDefaultCell, jsonParamCell, } from "./ast.ts";
7
+ export type { AggFn, AggRef, AggSelect, ColRef, ComparisonOp, DeleteStatement, InnerJoin, InsertStatement, JsonFilterOp, LateralJoin, ListSetOperation, OnConflictClause, OnConflictDoNothing, OnConflictUpdate, OrderByAggregate, OrderByColumn, OrderBySubquery, OrderTerm, RowNumberProjection, DbNowMarker, JsonParamCell, SelectExpr, SelectStatement, SetOperation, SetOperator, SqlExpr, SqlStatement, TableRef, UpdateStatement, } from "./ast.ts";
8
+ export { SQL_DEFAULT_CELL, dbNowMarker, isDbNowMarker, isJsonParamCell, isListSetOperation, isSetOperation, isSqlDefaultCell, jsonParamCell, } from "./ast.ts";
9
9
  export type { SqlDialect } from "./dialect.ts";
10
10
  export { postgresDialect } from "./dialects/postgres.ts";
11
11
  export { sqliteDialect } from "./dialects/sqlite.ts";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,YAAY,EACV,KAAK,EACL,MAAM,EACN,SAAS,EACT,MAAM,EACN,YAAY,EACZ,eAAe,EACf,SAAS,EACT,eAAe,EACf,YAAY,EACZ,WAAW,EACX,gBAAgB,EAChB,gBAAgB,EAChB,mBAAmB,EACnB,gBAAgB,EAChB,gBAAgB,EAChB,aAAa,EACb,eAAe,EACf,SAAS,EACT,mBAAmB,EACnB,aAAa,EACb,UAAU,EACV,eAAe,EACf,YAAY,EACZ,WAAW,EACX,OAAO,EACP,YAAY,EACZ,QAAQ,EACR,eAAe,GAChB,MAAM,UAAU,CAAC;AAClB,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,kBAAkB,EAClB,cAAc,EACd,gBAAgB,EAChB,aAAa,GACd,MAAM,UAAU,CAAC;AAIlB,YAAY,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAIrE,OAAO,EACL,oBAAoB,EACpB,kBAAkB,EAClB,qBAAqB,EACrB,mBAAmB,GACpB,MAAM,mBAAmB,CAAC;AAI3B,OAAO,EACL,cAAc,EACd,YAAY,EACZ,eAAe,EACf,aAAa,EACb,YAAY,GACb,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAIzE,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC1E,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAI7C,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,YAAY,EACV,KAAK,EACL,MAAM,EACN,SAAS,EACT,MAAM,EACN,YAAY,EACZ,eAAe,EACf,SAAS,EACT,eAAe,EACf,YAAY,EACZ,WAAW,EACX,gBAAgB,EAChB,gBAAgB,EAChB,mBAAmB,EACnB,gBAAgB,EAChB,gBAAgB,EAChB,aAAa,EACb,eAAe,EACf,SAAS,EACT,mBAAmB,EACnB,WAAW,EACX,aAAa,EACb,UAAU,EACV,eAAe,EACf,YAAY,EACZ,WAAW,EACX,OAAO,EACP,YAAY,EACZ,QAAQ,EACR,eAAe,GAChB,MAAM,UAAU,CAAC;AAClB,OAAO,EACL,gBAAgB,EAChB,WAAW,EACX,aAAa,EACb,eAAe,EACf,kBAAkB,EAClB,cAAc,EACd,gBAAgB,EAChB,aAAa,GACd,MAAM,UAAU,CAAC;AAIlB,YAAY,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAIrE,OAAO,EACL,oBAAoB,EACpB,kBAAkB,EAClB,qBAAqB,EACrB,mBAAmB,GACpB,MAAM,mBAAmB,CAAC;AAI3B,OAAO,EACL,cAAc,EACd,YAAY,EACZ,eAAe,EACf,aAAa,EACb,YAAY,GACb,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAIzE,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC1E,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAI7C,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC"}
package/dist/index.js CHANGED
@@ -20,6 +20,18 @@ function isListSetOperation(value) {
20
20
  const candidate = value;
21
21
  return typeof candidate.__listOp === "string" && LIST_SET_OPERATORS.includes(candidate.__listOp);
22
22
  }
23
+ function dbNowMarker(params) {
24
+ return { __dbNow: true, offsetSeconds: params.offsetSeconds };
25
+ }
26
+ function isDbNowMarker(value) {
27
+ if (typeof value !== "object" || value === null || Array.isArray(value))
28
+ return false;
29
+ const keys = Object.keys(value);
30
+ if (keys.length !== 2 || !keys.includes("__dbNow") || !keys.includes("offsetSeconds"))
31
+ return false;
32
+ const candidate = value;
33
+ return candidate.__dbNow === true && typeof candidate.offsetSeconds === "number" && Number.isInteger(candidate.offsetSeconds);
34
+ }
23
35
  var SQL_DEFAULT_CELL = Object.freeze({ __sqlDefault: true });
24
36
  function isSqlDefaultCell(value) {
25
37
  return value === SQL_DEFAULT_CELL;
@@ -39,6 +51,7 @@ var POSTGRES_CAPABILITIES = {
39
51
  lateralJoin: true,
40
52
  distinctOn: true,
41
53
  partialIndexes: true,
54
+ conflictTargetConstraint: true,
42
55
  transactionalDdl: true,
43
56
  createManyAndReturn: true,
44
57
  jsonColumnType: true,
@@ -53,6 +66,7 @@ var SQLITE_CAPABILITIES = {
53
66
  lateralJoin: false,
54
67
  distinctOn: false,
55
68
  partialIndexes: true,
69
+ conflictTargetConstraint: false,
56
70
  transactionalDdl: true,
57
71
  createManyAndReturn: true,
58
72
  jsonColumnType: false,
@@ -67,6 +81,7 @@ var MYSQL_CAPABILITIES = {
67
81
  lateralJoin: false,
68
82
  distinctOn: false,
69
83
  partialIndexes: false,
84
+ conflictTargetConstraint: false,
70
85
  transactionalDdl: false,
71
86
  createManyAndReturn: false,
72
87
  jsonColumnType: true,
@@ -111,6 +126,11 @@ var postgresDialect = {
111
126
  },
112
127
  placeholder({ index }) {
113
128
  return `$${index}`;
129
+ },
130
+ renderDbNow({ offsetSeconds, collector }) {
131
+ if (offsetSeconds === 0)
132
+ return "now()";
133
+ return `(now() + make_interval(secs => ${collector.add(offsetSeconds)}))`;
114
134
  }
115
135
  };
116
136
  // packages/sql/src/dialects/sqlite.ts
@@ -145,6 +165,11 @@ var sqliteDialect = {
145
165
  },
146
166
  placeholder() {
147
167
  return "?";
168
+ },
169
+ renderDbNow({ offsetSeconds, collector }) {
170
+ if (offsetSeconds === 0)
171
+ return `strftime('%Y-%m-%dT%H:%M:%fZ', 'now')`;
172
+ return `strftime('%Y-%m-%dT%H:%M:%fZ', 'now', ${collector.add(offsetSeconds)} || ' seconds')`;
148
173
  }
149
174
  };
150
175
  // packages/sql/src/dialects/mysql.ts
@@ -179,6 +204,11 @@ var mysqlDialect = {
179
204
  },
180
205
  placeholder() {
181
206
  return "?";
207
+ },
208
+ renderDbNow({ offsetSeconds, collector }) {
209
+ if (offsetSeconds === 0)
210
+ return "NOW(6)";
211
+ return `DATE_ADD(NOW(6), INTERVAL ${collector.add(offsetSeconds)} SECOND)`;
182
212
  }
183
213
  };
184
214
  // packages/sql/src/dialects/registry.ts
@@ -478,6 +508,9 @@ function renderExpr(params) {
478
508
  if (op === undefined) {
479
509
  throw internalError({ message: `unknown comparison operator "${expr.op}"` });
480
510
  }
511
+ if (isDbNowMarker(expr.value)) {
512
+ return `${quoteCol(dialect, expr.column)} ${op} ${dialect.renderDbNow({ offsetSeconds: expr.value.offsetSeconds, collector })}`;
513
+ }
481
514
  return `${quoteCol(dialect, expr.column)} ${op} ${collector.add(expr.value)}`;
482
515
  }
483
516
  case "cmpCol": {
@@ -912,6 +945,9 @@ function renderInsert(params) {
912
945
  const rowsSql = statement.rows.map((row) => `(${row.map((value) => {
913
946
  if (isJsonParamCell(value))
914
947
  return `${collector.add(value.text)}${dialect.jsonParamCast}`;
948
+ if (isDbNowMarker(value)) {
949
+ return dialect.renderDbNow({ offsetSeconds: value.offsetSeconds, collector });
950
+ }
915
951
  if (!isSqlDefaultCell(value))
916
952
  return collector.add(value);
917
953
  if (!dialect.rowDefaultKeyword) {
@@ -925,8 +961,29 @@ function renderInsert(params) {
925
961
  if (onConflict !== undefined) {
926
962
  if ("doNothing" in onConflict) {
927
963
  if (dialect.doNothingForm === "onConflictDoNothing") {
928
- const target = onConflict.columns === undefined || onConflict.columns.length === 0 ? "" : ` (${onConflict.columns.map((name) => dialect.quoteIdent({ name })).join(", ")})`;
964
+ let target = "";
965
+ if (onConflict.constraint !== undefined) {
966
+ if (dialect.name !== "postgres") {
967
+ throw unsupportedCapability({
968
+ dialect: dialect.name,
969
+ feature: "a named-constraint conflict target (ON CONFLICT ON CONSTRAINT)",
970
+ hint: "only postgres names constraints in conflict targets \u2014 use a column-list target"
971
+ });
972
+ }
973
+ target = ` ON CONSTRAINT ${dialect.quoteIdent({ name: onConflict.constraint })}`;
974
+ } else if (onConflict.columns !== undefined && onConflict.columns.length > 0) {
975
+ target = ` (${onConflict.columns.map((name) => dialect.quoteIdent({ name })).join(", ")})`;
976
+ if (onConflict.conflictWhere !== undefined) {
977
+ target += ` WHERE ${onConflict.conflictWhere}`;
978
+ }
979
+ }
929
980
  text += ` ON CONFLICT${target} DO NOTHING`;
981
+ } else if (onConflict.constraint !== undefined || onConflict.conflictWhere !== undefined) {
982
+ throw unsupportedCapability({
983
+ dialect: dialect.name,
984
+ feature: "a refined conflict target (constraint / partial-index predicate) on INSERT IGNORE",
985
+ hint: "mysql skips on any duplicate key \u2014 drop the refinement or gate the call per dialect"
986
+ });
930
987
  }
931
988
  } else {
932
989
  const updates = Object.entries(onConflict.update);
@@ -939,9 +996,23 @@ function renderInsert(params) {
939
996
  if (onConflict.lastInsertIdColumn !== undefined) {
940
997
  throw internalError({ message: "lastInsertIdColumn is a mysql (onDuplicateKey) construct" });
941
998
  }
942
- const conflictColumns = onConflict.columns.map((name) => dialect.quoteIdent({ name })).join(", ");
943
- text += ` ON CONFLICT (${conflictColumns}) DO UPDATE SET ${assignments}`;
999
+ if (onConflict.constraint !== undefined && dialect.name !== "postgres") {
1000
+ throw unsupportedCapability({
1001
+ dialect: dialect.name,
1002
+ feature: "a named-constraint conflict target (ON CONFLICT ON CONSTRAINT)",
1003
+ hint: "sqlite conflict targets are column lists \u2014 name the indexed columns instead"
1004
+ });
1005
+ }
1006
+ const target = onConflict.constraint !== undefined ? ` ON CONSTRAINT ${dialect.quoteIdent({ name: onConflict.constraint })}` : ` (${onConflict.columns.map((name) => dialect.quoteIdent({ name })).join(", ")})`;
1007
+ text += ` ON CONFLICT${target} DO UPDATE SET ${assignments}`;
944
1008
  } else {
1009
+ if (onConflict.constraint !== undefined) {
1010
+ throw unsupportedCapability({
1011
+ dialect: dialect.name,
1012
+ feature: "a named-constraint conflict target on ON DUPLICATE KEY UPDATE",
1013
+ hint: "mysql's ODKU fires on any duplicate key \u2014 no target can be named"
1014
+ });
1015
+ }
945
1016
  const trick = onConflict.lastInsertIdColumn === undefined ? "" : `, ${dialect.quoteIdent({ name: onConflict.lastInsertIdColumn })} = LAST_INSERT_ID(${dialect.quoteIdent({ name: onConflict.lastInsertIdColumn })})`;
946
1017
  text += ` ON DUPLICATE KEY UPDATE ${assignments}${trick}`;
947
1018
  }
@@ -975,6 +1046,9 @@ function renderAssignments(params) {
975
1046
  if (isSetOperation(value)) {
976
1047
  return `${column} = ${read} ${SET_OPERATION_SQL[value.__op]} ${collector.add(value.value)}`;
977
1048
  }
1049
+ if (isDbNowMarker(value)) {
1050
+ return `${column} = ${dialect.renderDbNow({ offsetSeconds: value.offsetSeconds, collector })}`;
1051
+ }
978
1052
  if (isListSetOperation(value)) {
979
1053
  assertScalarArrays(dialect, 'the scalar-list update operation "push"');
980
1054
  if (value.__listOp === "append") {
@@ -1008,11 +1082,13 @@ export {
1008
1082
  isSetOperation,
1009
1083
  isListSetOperation,
1010
1084
  isJsonParamCell,
1085
+ isDbNowMarker,
1011
1086
  getSqlDialect,
1012
1087
  escapeLikePattern,
1013
1088
  escapeGlobPattern,
1014
1089
  endsWithPattern,
1015
1090
  decodeIsNoop,
1091
+ dbNowMarker,
1016
1092
  containsPattern,
1017
1093
  SQL_DIALECTS,
1018
1094
  SQL_DEFAULT_CELL,
@@ -1027,4 +1103,4 @@ export {
1027
1103
  DIALECT_CAPABILITIES
1028
1104
  };
1029
1105
 
1030
- //# debugId=2B8F0892BD46367D64756E2164756E21
1106
+ //# debugId=CA83D2CED1E762E664756E2164756E21
package/dist/index.js.map CHANGED
@@ -2,18 +2,18 @@
2
2
  "version": 3,
3
3
  "sources": ["../src/ast.ts", "../src/capabilities.ts", "../src/dialects/postgres.ts", "../src/dialects/sqlite.ts", "../src/dialects/mysql.ts", "../src/dialects/registry.ts", "../src/codecs.ts", "../src/render.ts", "../src/like.ts", "../src/params.ts"],
4
4
  "sourcesContent": [
5
- "/**\n * The SQL AST — the small statement language the runtime and migrate packages\n * build and dialects render.\n *\n * Deliberately minimal at P0 (single-table statements, no joins/subqueries);\n * grows with the runtime in P2/P3. Every shape added here needs a catalog case\n * (tests/catalog/cases.ts) in the same change.\n */\n\nimport type { SqlFragmentSpec } from \"@vibeorm/schema\";\n\n// ─── References ───────────────────────────────────────────────────\n\n/** A column reference, optionally table-qualified. */\nexport type ColRef = {\n readonly table?: string;\n readonly name: string;\n /**\n * Projection-only wire transform, postgres lateral joins only (SQL review\n * B3): raw `to_jsonb` would ship BigInt/Decimal as float64 JSON numbers and\n * Bytes as `\\x` hex text, so the subselect casts instead — `castText`\n * renders `\"col\"::text AS \"col\"`, `encodeBase64` renders\n * `encode(\"col\", 'base64') AS \"col\"`. Never set on filter/order refs.\n */\n readonly transform?: \"castText\" | \"encodeBase64\";\n /**\n * Comparison/order/aggregate cast, sqlite Decimal only (SQL review B4):\n * Decimal stores as exact TEXT there and text comparison is lexicographic —\n * compare, ORDER BY and aggregate sites render `CAST(\"col\" AS REAL)` (with\n * NUMBER operands) instead. Never set on projections or GROUP BY keys, so\n * storage and read-back stay the exact text.\n */\n readonly castReal?: boolean;\n /**\n * Projection alias: renders `ref AS \"alias\"`. PROJECTION-ONLY — filter,\n * order and correlation refs never set it (the renderer ignores it outside\n * a projection list). Used by the single-statement M2M join to expose the\n * join table's parent-key column under a reserved name (`__vibe_parent`).\n */\n readonly alias?: string;\n};\n\nexport type TableRef = {\n readonly name: string;\n readonly alias?: string;\n};\n\n// ─── Aggregates ───────────────────────────────────────────────────\n\n/** Aggregate functions applied to one column. */\nexport type AggFn = \"count\" | \"avg\" | \"sum\" | \"min\" | \"max\";\n\n/** Reference to an aggregate expression: `COUNT(*)` or `FN(\"col\")`. */\nexport type AggRef =\n | { readonly fn: \"countAll\" }\n | { readonly fn: AggFn; readonly column: ColRef };\n\n/**\n * One aggregate projection: `FN(\"col\") AS \"alias\"`. The alias is part of the\n * catalog contract — the runtime derives result keys from it deterministically\n * (`_count___all`, `_avg__score`), never by parsing the SQL text back.\n */\nexport type AggSelect = {\n readonly agg: AggRef;\n readonly alias: string;\n};\n\n// ─── JSON filters ─────────────────────────────────────────────────\n\n/**\n * JSON path predicates (Prisma's Json filter surface). `not` is `equals` with\n * `negate` — there is no separate op. Which ops a dialect can express is\n * declared on `SqlDialect.supportedJsonOps` and enforced at render time too.\n */\nexport type JsonFilterOp =\n | \"equals\"\n | \"string_contains\"\n | \"string_starts_with\"\n | \"string_ends_with\"\n | \"array_contains\"\n | \"array_starts_with\"\n | \"array_ends_with\";\n\n// ─── Expressions ──────────────────────────────────────────────────\n\nexport type ComparisonOp = \"eq\" | \"ne\" | \"gt\" | \"gte\" | \"lt\" | \"lte\";\n\nexport type SqlExpr =\n | { readonly kind: \"cmp\"; readonly op: ComparisonOp; readonly column: ColRef; readonly value: unknown }\n /** Column-to-column comparison — the correlation predicate of EXISTS/lateral subqueries. */\n | { readonly kind: \"cmpCol\"; readonly op: ComparisonOp; readonly left: ColRef; readonly right: ColRef }\n | { readonly kind: \"isNull\"; readonly column: ColRef; readonly negate?: boolean }\n | {\n readonly kind: \"inArray\";\n readonly column: ColRef;\n readonly values: readonly unknown[];\n readonly negate?: boolean;\n }\n | {\n readonly kind: \"like\";\n readonly column: ColRef;\n /** Pre-built pattern (see like.ts helpers for escaping). */\n readonly pattern: string;\n readonly insensitive?: boolean;\n readonly negate?: boolean;\n }\n /**\n * Case-SENSITIVE string match (`mode: \"strict\"`, board #20). `value` is the\n * RAW operand — pattern building happens at render time because escaping\n * differs per strategy (LIKE's `%`/`_`/`\\` vs GLOB's `*`/`?`/`[`). Renders\n * per `SqlDialect.strictMatchStrategy`: plain `=`/`LIKE` on postgres\n * (already byte-sensitive — a deliberate, documented no-op), `=`/`GLOB` on\n * sqlite, `= CAST(? AS BINARY)`/`LIKE CAST(? AS BINARY)` on mysql. The\n * non-native forms defeat plain indexes; docs/dialect-notes.md carries the\n * cost and the functional/`_bin`-index mitigation.\n */\n | {\n readonly kind: \"strictMatch\";\n readonly column: ColRef;\n readonly op: \"equals\" | \"contains\" | \"startsWith\" | \"endsWith\";\n readonly value: string;\n readonly negate?: boolean;\n }\n | { readonly kind: \"and\"; readonly operands: readonly SqlExpr[] }\n | { readonly kind: \"or\"; readonly operands: readonly SqlExpr[] }\n | { readonly kind: \"not\"; readonly operand: SqlExpr }\n /**\n * Correlated subquery test: `[NOT] EXISTS (SELECT …)`. The inner select\n * correlates to the outer scope through table-qualified `cmpCol` predicates;\n * its parameters merge into the statement's single parameter sequence in\n * render order. Relation filters (`some`/`every`/`none`/`is`/`isNot`)\n * compile to this shape.\n */\n | { readonly kind: \"exists\"; readonly select: SelectStatement; readonly negate?: boolean }\n /** Aggregate comparison — the HAVING predicate: `COUNT(\"col\") > $n`. */\n | { readonly kind: \"aggCmp\"; readonly op: ComparisonOp; readonly agg: AggRef; readonly value: unknown }\n /**\n * Scalar-list membership: `$n = ANY(\"col\")` — Prisma's `has`. Postgres only\n * (`capabilities.scalarArrays`); other dialects refuse at render time.\n */\n | { readonly kind: \"arrayHas\"; readonly column: ColRef; readonly value: unknown; readonly negate?: boolean }\n /** Scalar-list superset: `\"col\" @> $n` (one array param) — Prisma's `hasEvery`. Postgres only. */\n | { readonly kind: \"arrayContainsAll\"; readonly column: ColRef; readonly values: readonly unknown[] }\n /** Scalar-list overlap: `\"col\" && $n` (one array param) — Prisma's `hasSome`. Postgres only. */\n | { readonly kind: \"arrayOverlaps\"; readonly column: ColRef; readonly values: readonly unknown[] }\n /**\n * Scalar-list emptiness via `array_length(\"col\", 1) IS [NOT] NULL` — the v1\n * semantics kept deliberately: `empty: true` matches NULL **and** empty\n * arrays, `empty: false` matches only rows with at least one element.\n */\n | { readonly kind: \"arrayIsEmpty\"; readonly column: ColRef; readonly empty: boolean }\n /**\n * JSON path predicate. The path is always BOUND as a parameter (a `text[]`\n * on postgres, a `$.a.b[0]` path string on sqlite/mysql) — path segments\n * never become SQL text. `value` is the RAW JS operand; each dialect decides\n * its wire form (JSON.stringify for jsonb/json comparisons, LIKE patterns\n * for the string ops). `insensitive` applies to the string ops only.\n */\n | {\n readonly kind: \"jsonFilter\";\n readonly column: ColRef;\n readonly path: readonly (string | number)[];\n readonly op: JsonFilterOp;\n readonly value: unknown;\n readonly insensitive?: boolean;\n readonly negate?: boolean;\n }\n /**\n * A bound extension fragment: literal text, bound parameters and quoted\n * identifiers in order (extensions.md §3 sql plane — trgm operators, rank\n * and distance terms). Parameters flow through the shared ParamCollector,\n * identifiers through dialect.quoteIdent — never hand-written.\n */\n | { readonly kind: \"fragment\"; readonly fragment: SqlFragmentSpec }\n /** Escape hatch for dialect-reviewed fragments. Text only — no parameters. */\n | { readonly kind: \"raw\"; readonly text: string };\n\n// ─── Projections ──────────────────────────────────────────────────\n\n/**\n * An aggregate projection.\n *\n * `countAll` renders `COUNT(*)`. The alias matters for portability: postgres\n * names the bare column `count`, sqlite and mysql name it `COUNT(*)` — callers\n * that must read the value back always pass an alias. Combined with a\n * non-empty `columns` list (grouped counts, `SELECT \"fk\", COUNT(*) … GROUP\n * BY \"fk\"`), it renders AFTER the columns.\n *\n * `one` renders the constant `1` — the conventional EXISTS projection; it\n * cannot be combined with a column list.\n */\nexport type SelectExpr =\n | { readonly kind: \"countAll\"; readonly alias?: string }\n | { readonly kind: \"one\" };\n\n// ─── SET operations ───────────────────────────────────────────────\n\n/** Arithmetic applied to a column's current value in an UPDATE ... SET. */\nexport type SetOperator = \"increment\" | \"decrement\" | \"multiply\" | \"divide\";\n\n/**\n * An atomic update expression: `\"col\" = \"col\" <op> $n`.\n *\n * Recognised structurally inside `UpdateStatement.set`, so the marker key is\n * deliberately unlikely (`__op`). Three layers keep a user's JSON payload from\n * ever being mistaken for one: the Json codec stringifies JSON values before\n * they reach the AST, the query builder only emits this shape for numeric\n * fields, and {@link isSetOperation} demands an exact two-key object.\n */\nexport type SetOperation = {\n readonly __op: SetOperator;\n readonly value: number;\n};\n\nconst SET_OPERATORS: readonly string[] = [\"increment\", \"decrement\", \"multiply\", \"divide\"];\n\n/** Narrow an UPDATE set value to an atomic {@link SetOperation}. */\nexport function isSetOperation(value: unknown): value is SetOperation {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) return false;\n const keys = Object.keys(value);\n if (keys.length !== 2 || !keys.includes(\"__op\") || !keys.includes(\"value\")) return false;\n const candidate = value as { __op: unknown; value: unknown };\n return (\n typeof candidate.__op === \"string\" &&\n SET_OPERATORS.includes(candidate.__op) &&\n typeof candidate.value === \"number\" &&\n Number.isFinite(candidate.value)\n );\n}\n\n/**\n * A scalar-list update expression (Prisma's `{ push: … }` on list columns):\n * `append` is one element (`\"col\" = array_append(\"col\", $n)`), `concat` an\n * array of elements (`\"col\" = \"col\" || $n`). Postgres only — the query builder\n * gates on `capabilities.scalarArrays` at build time and the renderer refuses\n * too. Same structural-marker discipline as {@link SetOperation}: the key is\n * unlikely, the shape exact, and Json payloads are stringified before they\n * could ever reach an UPDATE set.\n */\nexport type ListSetOperation = {\n readonly __listOp: \"append\" | \"concat\";\n readonly value: unknown;\n};\n\nconst LIST_SET_OPERATORS: readonly string[] = [\"append\", \"concat\"];\n\n/** Narrow an UPDATE set value to a {@link ListSetOperation}. */\nexport function isListSetOperation(value: unknown): value is ListSetOperation {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) return false;\n const keys = Object.keys(value);\n if (keys.length !== 2 || !keys.includes(\"__listOp\") || !keys.includes(\"value\")) return false;\n const candidate = value as { __listOp: unknown };\n return typeof candidate.__listOp === \"string\" && LIST_SET_OPERATORS.includes(candidate.__listOp);\n}\n\n// ─── Ordering ─────────────────────────────────────────────────────\n\n/** ORDER BY a column, with optional NULLS placement (native or emulated per dialect). */\nexport type OrderByColumn = {\n readonly column: ColRef;\n readonly direction: \"asc\" | \"desc\";\n /** NULLS placement; rendered natively or emulated per dialect. */\n readonly nulls?: \"first\" | \"last\";\n};\n\n/** ORDER BY an aggregate expression — grouped selects ordering by `COUNT(\"col\")`. */\nexport type OrderByAggregate = {\n readonly agg: AggRef;\n readonly direction: \"asc\" | \"desc\";\n};\n\n/**\n * ORDER BY a correlated scalar subquery — relation orderBy\n * (`orderBy: { posts: { _count: \"desc\" } }` → `(SELECT COUNT(*) …)` /\n * `orderBy: { author: { email: \"asc\" } }` → `(SELECT \"email\" …)`).\n * Portable: all three dialects order by scalar subqueries. The subquery\n * correlates to the outer scope through table-qualified `cmpCol` predicates,\n * exactly like `exists`; its parameters merge into the statement's single\n * sequence in render order. NULLS placement is deliberately unsupported here\n * (emulating it would render the subquery twice and duplicate its params) —\n * missing relations sort at each engine's native NULL position.\n */\nexport type OrderBySubquery = {\n readonly select: SelectStatement;\n readonly direction: \"asc\" | \"desc\";\n};\n\nexport type OrderTerm = OrderByColumn | OrderByAggregate | OrderBySubquery;\n\n// ─── Statements ───────────────────────────────────────────────────\n\n/**\n * One `LEFT JOIN LATERAL (…) AS alias ON true` clause aggregating a correlated\n * subquery into a single JSON value per outer row — the \"join\" relation-loading\n * strategy (postgres/pglite only; gated on `capabilities.lateralJoin`).\n *\n * Renders (agg `jsonArray`):\n * `LEFT JOIN LATERAL (SELECT COALESCE(jsonb_agg(to_jsonb(\"__sub\".*)), '[]'::jsonb)\n * AS \"columnAlias\" FROM (<select>) AS \"__sub\") AS \"alias\" ON true`\n * and (agg `jsonObject`):\n * `LEFT JOIN LATERAL (SELECT to_jsonb(\"__sub\".*) AS \"columnAlias\"\n * FROM (<select>) AS \"__sub\") AS \"alias\" ON true`\n *\n * `to_jsonb` over a subselect (not `json_build_object`) sidesteps postgres's\n * 100-argument function limit on wide models (v1 lesson). The inner select's\n * ORDER BY drives the aggregate's element order. Consumers must run the codec\n * table over the parsed JSON children: `to_jsonb` turns timestamps into\n * strings and loses BigInt-ness (LEARNINGS).\n */\nexport type LateralJoin = {\n /** Join alias (`__lat_0`) — the outer projection selects `alias.columnAlias`. */\n readonly alias: string;\n /** Column the aggregated JSON value is exposed under (`__rel_posts`). */\n readonly columnAlias: string;\n /** `jsonArray` for to-many (aggregated array), `jsonObject` for to-one (LIMIT 1 row or NULL). */\n readonly agg: \"jsonArray\" | \"jsonObject\";\n /** The correlated child select — may reference outer columns via table-qualified refs. */\n readonly select: SelectStatement;\n};\n\n/**\n * One `INNER JOIN \"table\" AS alias ON left = right [AND …]` clause — plain\n * equality joins only, portable across all dialects. Added for the\n * single-statement implicit-M2M load (child rows joined to their join-table\n * membership rows); extra join-table columns project through the statement's\n * `columns` list with a table qualifier + `alias`.\n */\nexport type InnerJoin = {\n readonly table: TableRef;\n /** Equality pairs ANDed into the ON clause; never empty. */\n readonly on: readonly { readonly left: ColRef; readonly right: ColRef }[];\n};\n\n/**\n * A `ROW_NUMBER() OVER (PARTITION BY … [ORDER BY …]) AS \"alias\"` projection,\n * appended after `columns` — the distinct emulation on dialects without\n * `DISTINCT ON` (sqlite ≥3.25, mysql ≥8.0 both have window functions): the\n * outer statement filters `alias = 1` on the derived table, restoring\n * SQL-side take/skip and bounded transfer (N10).\n */\nexport type RowNumberProjection = {\n readonly partitionBy: readonly ColRef[];\n /** Intra-partition order picking the representative row; may be empty. */\n readonly orderBy: readonly OrderTerm[];\n readonly alias: string;\n};\n\nexport type SelectStatement = {\n readonly kind: \"select\";\n readonly table: TableRef;\n /** Empty array renders as `SELECT *` (unless `selectExpr` replaces it). */\n readonly columns: readonly ColRef[];\n /**\n * Aggregate projection. Replaces the column list when `columns` is empty;\n * a `countAll` with columns renders after them (grouped counts).\n */\n readonly selectExpr?: SelectExpr;\n /**\n * Aliased aggregate projections (`AVG(\"col\") AS \"_avg__col\"`), rendered\n * after `columns` — the aggregate/groupBy/count-select shapes. Cannot be\n * combined with `selectExpr`.\n */\n readonly aggregates?: readonly AggSelect[];\n /**\n * `SELECT DISTINCT ON (cols)` — postgres only (`capabilities.distinctOn`;\n * other dialects refuse at render time and the runtime emulates client-side\n * instead). ORDER BY must lead with these columns; the query builder\n * guarantees that arrangement.\n */\n readonly distinctOn?: readonly ColRef[];\n /**\n * Derived-table FROM: renders `FROM (<fromSelect>) AS \"<table.name>\"` —\n * `table.name` is the subquery ALIAS and `table.alias` must be unset. Used\n * by aggregate-over-a-subset shapes (`aggregate({ take, skip, orderBy })`).\n */\n readonly fromSelect?: SelectStatement;\n /** Lateral JSON-aggregation joins — postgres-only, see {@link LateralJoin}. */\n readonly lateralJoins?: readonly LateralJoin[];\n /** Plain equality INNER JOINs — portable, see {@link InnerJoin}. */\n readonly innerJoins?: readonly InnerJoin[];\n /** ROW_NUMBER window projection — see {@link RowNumberProjection}. */\n readonly rowNumber?: RowNumberProjection;\n readonly where?: SqlExpr;\n readonly groupBy?: readonly ColRef[];\n /** HAVING predicate — grouped selects; may contain `aggCmp` expressions. */\n readonly having?: SqlExpr;\n readonly orderBy?: readonly OrderTerm[];\n readonly limit?: number;\n readonly offset?: number;\n /**\n * Row-locking read (`SELECT … FOR UPDATE`) — the overlay flows on dialects\n * without RETURNING read a row they are about to write. Rendered only where\n * the dialect names a lock clause (`dialect.selectForUpdate`); sqlite has\n * none and needs none — its write transactions already exclude each other.\n */\n readonly lockForUpdate?: boolean;\n};\n\n/**\n * Sentinel VALUES cell: render the `DEFAULT` keyword instead of a placeholder\n * (M4) — a heterogeneous createMany row that omits a field lets the COLUMN\n * default apply (or NULL on a defaultless nullable column), exactly like a\n * single-row insert that omits it. Postgres/mysql only\n * (`dialect.rowDefaultKeyword`); sqlite groups rows instead.\n */\nexport const SQL_DEFAULT_CELL: { readonly __sqlDefault: true } = Object.freeze({ __sqlDefault: true });\n\n/** Is this VALUES cell the {@link SQL_DEFAULT_CELL} sentinel? */\nexport function isSqlDefaultCell(value: unknown): boolean {\n return value === SQL_DEFAULT_CELL;\n}\n\n/**\n * VALUES/SET cell carrying a Json column's parameter (the codec's JSON text).\n *\n * Why it exists: OID-typed drivers (bun:sql) resolve each parameter's postgres\n * type and re-serialize the JS value AS that type — a pre-stringified Json\n * param bound straight into a bare jsonb slot arrives DOUBLE-ENCODED (a jsonb\n * string holding the document; live-proven on Bun 1.3.14). The postgres\n * renderer pins the parameter's type instead (`$n::text::jsonb`,\n * `SqlDialect.jsonParamCast`), so every driver sends the text through and the\n * SERVER parses it; text-param drivers (node-postgres, pglite) are unaffected.\n * Sqlite/mysql render the bare placeholder — their Json transport is already\n * plain text. The COLLECTED parameter is the plain text either way: this\n * wrapper never crosses the wire.\n */\nexport type JsonParamCell = { readonly __jsonParam: true; readonly text: string };\n\n/** Wrap a Json column's encoded (stringified) parameter for cast-site rendering. */\nexport function jsonParamCell(params: { text: string }): JsonParamCell {\n return { __jsonParam: true, text: params.text };\n}\n\n/** Is this VALUES/SET cell a {@link JsonParamCell}? */\nexport function isJsonParamCell(value: unknown): value is JsonParamCell {\n return (\n typeof value === \"object\" &&\n value !== null &&\n (value as { __jsonParam?: unknown }).__jsonParam === true\n );\n}\n\nexport type InsertStatement = {\n readonly kind: \"insert\";\n readonly table: TableRef;\n readonly columns: readonly string[];\n /** Row values aligned to `columns` — deterministic parameter order. */\n readonly rows: readonly (readonly unknown[])[];\n /** Upsert clause: ON CONFLICT (pg/sqlite) or ON DUPLICATE KEY (mysql). */\n readonly onConflict?: OnConflictClause;\n /** Rendered as RETURNING where the dialect supports it, else omitted+flagged. */\n readonly returning?: readonly string[];\n};\n\n/** Conflicting rows are updated with these column values. */\nexport type OnConflictUpdate = {\n /** Conflict target columns (ignored by the mysql form). */\n readonly columns: readonly string[];\n readonly update: Readonly<Record<string, unknown>>;\n /**\n * MySQL only (`upsertForm: \"onDuplicateKey\"`): append\n * `` `col` = LAST_INSERT_ID(`col`) `` to the update list so the UPDATE arm\n * records the addressed row's key — without it `LAST_INSERT_ID()` is stale\n * on the update arm and the read-back can resolve a wrong, unrelated row\n * (SQL review B2, live-proven on 8.4). Only meaningful for integer keys.\n */\n readonly lastInsertIdColumn?: string;\n};\n\n/**\n * Conflicting rows are skipped (`createMany({ skipDuplicates: true })`).\n * An empty/absent target means \"any conflict\" — the mysql form (INSERT IGNORE)\n * can only express that, so it ignores `columns` entirely.\n */\nexport type OnConflictDoNothing = {\n readonly columns?: readonly string[];\n readonly doNothing: true;\n};\n\nexport type OnConflictClause = OnConflictUpdate | OnConflictDoNothing;\n\nexport type UpdateStatement = {\n readonly kind: \"update\";\n readonly table: TableRef;\n /** Column → parameter value, or an atomic {@link SetOperation}. */\n readonly set: Readonly<Record<string, unknown>>;\n readonly where?: SqlExpr;\n readonly returning?: readonly string[];\n};\n\nexport type DeleteStatement = {\n readonly kind: \"delete\";\n readonly table: TableRef;\n readonly where?: SqlExpr;\n readonly returning?: readonly string[];\n};\n\nexport type SqlStatement = SelectStatement | InsertStatement | UpdateStatement | DeleteStatement;\n",
6
- "/**\n * Per-dialect capability tables — the frozen feature contract.\n *\n * Mirrored verbatim by tests/capabilities.test.ts: changing a value here forces\n * a reviewed test change. Runtime fallbacks, migrate DDL, generator output and\n * E2E `skipUnlessCapability()` all read these same objects.\n */\n\nimport type { Dialect, DialectCapabilities } from \"@vibeorm/schema\";\n\nexport const POSTGRES_CAPABILITIES: DialectCapabilities = {\n returning: true,\n scalarArrays: true,\n nativeEnums: true,\n ilike: true,\n lateralJoin: true,\n distinctOn: true,\n partialIndexes: true,\n transactionalDdl: true,\n createManyAndReturn: true,\n jsonColumnType: true,\n orderByNulls: true,\n fullTextEngines: [\"bm25\", \"tsvector\"],\n};\n\nexport const SQLITE_CAPABILITIES: DialectCapabilities = {\n returning: true,\n scalarArrays: false,\n nativeEnums: false,\n ilike: false,\n lateralJoin: false,\n distinctOn: false,\n partialIndexes: true,\n transactionalDdl: true,\n createManyAndReturn: true,\n jsonColumnType: false,\n orderByNulls: true,\n fullTextEngines: [\"fts5\"],\n};\n\nexport const MYSQL_CAPABILITIES: DialectCapabilities = {\n returning: false,\n scalarArrays: false,\n nativeEnums: true,\n ilike: false,\n lateralJoin: false,\n distinctOn: false,\n partialIndexes: false,\n transactionalDdl: false,\n createManyAndReturn: false,\n jsonColumnType: true,\n orderByNulls: false,\n fullTextEngines: [\"fulltext\"],\n};\n\nexport const DIALECT_CAPABILITIES: Readonly<Record<Dialect, DialectCapabilities>> = {\n postgres: POSTGRES_CAPABILITIES,\n sqlite: SQLITE_CAPABILITIES,\n mysql: MYSQL_CAPABILITIES,\n};\n",
7
- "/**\n * PostgreSQL dialect. Also serves PGlite — the differences are adapter-level\n * (single connection, bundled extension set), not SQL-text-level.\n */\n\nimport type { SqlDialect } from \"../dialect.ts\";\nimport { POSTGRES_CAPABILITIES } from \"../capabilities.ts\";\n\nexport const postgresDialect: SqlDialect = {\n name: \"postgres\",\n capabilities: POSTGRES_CAPABILITIES,\n\n inArrayStrategy: \"any\",\n upsertForm: \"onConflict\",\n doNothingForm: \"onConflictDoNothing\",\n insensitiveLike: \"ilike\",\n // Postgres `=`/`LIKE` are already byte-sensitive — strict mode is a no-op.\n strictMatchStrategy: \"native\",\n orderByNullsMode: \"native\",\n offsetRequiresLimit: null,\n likeEscapeClause: null,\n jsonPathMode: \"operators\",\n supportedJsonOps: [\n \"equals\",\n \"string_contains\",\n \"string_starts_with\",\n \"string_ends_with\",\n \"array_contains\",\n \"array_starts_with\",\n \"array_ends_with\",\n ],\n // Json params bind as TEXT and the server parses (`$n::text::jsonb`):\n // OID-typed drivers (bun:sql) would re-serialize a bare jsonb-slot param\n // and double-encode the document (JsonParamCell, ast.ts).\n jsonParamCast: \"::text::jsonb\",\n lastInsertIdSql: null,\n selectForUpdate: \" FOR UPDATE\",\n rowDefaultKeyword: true,\n paramBudget: 30000,\n\n quoteIdent({ name }) {\n return `\"${name.replaceAll('\"', '\"\"')}\"`;\n },\n placeholder({ index }) {\n return `$${index}`;\n },\n};\n",
8
- "/**\n * SQLite dialect (bun:sqlite adapter lands in P4).\n *\n * Notes pinned by catalog cases:\n * - OFFSET requires LIMIT → `LIMIT -1 OFFSET n`.\n * - LIKE has no default escape character → explicit ` ESCAPE '\\'` clause.\n * - Case-insensitive matching uses LOWER()/LOWER() (default LIKE is only\n * ASCII-case-insensitive, and we want deterministic semantics).\n */\n\nimport type { SqlDialect } from \"../dialect.ts\";\nimport { SQLITE_CAPABILITIES } from \"../capabilities.ts\";\n\nexport const sqliteDialect: SqlDialect = {\n name: \"sqlite\",\n capabilities: SQLITE_CAPABILITIES,\n\n inArrayStrategy: \"expand\",\n upsertForm: \"onConflict\",\n doNothingForm: \"onConflictDoNothing\",\n insensitiveLike: \"lower\",\n // LIKE is ASCII-case-insensitive here — strict pattern matching rides GLOB\n // (byte-exact; its `*`/`?`/`[` metachars get their own escaping, like.ts).\n strictMatchStrategy: \"glob\",\n orderByNullsMode: \"native\",\n offsetRequiresLimit: { limitText: \"-1\" },\n likeEscapeClause: \" ESCAPE '\\\\'\",\n // json_extract covers scalar extraction + LIKE over extracted text; the\n // expressible array subset (N6, board #21) is wired: `$[0]` / `$[#-1]` path\n // elements for array_starts_with/array_ends_with (sqlite ≥3.31; bun:sqlite\n // bundles far newer) and json_each() EXISTS for SCALAR-element\n // array_contains. Deep structural jsonb-style containment (object/array/\n // null members) has no cheap faithful form — the renderer refuses those\n // ELEMENT shapes with VIBE_UNSUPPORTED_CAPABILITY even though the op itself\n // is listed here.\n jsonPathMode: \"sqliteExtract\",\n supportedJsonOps: [\n \"equals\",\n \"string_contains\",\n \"string_starts_with\",\n \"string_ends_with\",\n \"array_contains\",\n \"array_starts_with\",\n \"array_ends_with\",\n ],\n // Json transport is already plain text here — no param cast needed.\n jsonParamCast: \"\",\n lastInsertIdSql: null,\n // No FOR UPDATE in sqlite — and none needed: a write transaction holds the\n // single writer lock, so overlay reads inside it cannot race another writer.\n selectForUpdate: null,\n // No per-row DEFAULT keyword in VALUES — heterogeneous createMany rows are\n // grouped by column set into separate statements (M4).\n rowDefaultKeyword: false,\n paramBudget: 900,\n\n quoteIdent({ name }) {\n return `\"${name.replaceAll('\"', '\"\"')}\"`;\n },\n placeholder() {\n return \"?\";\n },\n};\n",
9
- "/**\n * MySQL dialect (mysql2 adapter lands in P4).\n *\n * Notes pinned by catalog cases:\n * - No RETURNING → renderer omits it and flags `returning: \"omitted\"`; the\n * runtime re-selects by PK (app-generated ids) or insertId.\n * - Upserts use ON DUPLICATE KEY UPDATE (no conflict-target refinement).\n * - OFFSET requires LIMIT → the documented huge-limit idiom.\n * - No NULLS FIRST/LAST → `col IS NULL` emulation terms.\n * - No `ON CONFLICT ... DO NOTHING` → `INSERT IGNORE`, which is broader: it\n * downgrades other row-level errors to warnings too.\n */\n\nimport type { SqlDialect } from \"../dialect.ts\";\nimport { MYSQL_CAPABILITIES } from \"../capabilities.ts\";\n\nexport const mysqlDialect: SqlDialect = {\n name: \"mysql\",\n capabilities: MYSQL_CAPABILITIES,\n\n inArrayStrategy: \"expand\",\n upsertForm: \"onDuplicateKey\",\n doNothingForm: \"insertIgnore\",\n insensitiveLike: \"lower\",\n // `_ci` collations fold `=` and `LIKE` — strict mode casts the OPERAND to\n // BINARY (byte-wise comparison; CAST form, the unary BINARY operator is\n // deprecated since 8.0.27). Operand-side: no assumption about the column's\n // charset, and the cost (index defeat) is documented in dialect-notes.md.\n strictMatchStrategy: \"binary\",\n orderByNullsMode: \"emulate\",\n offsetRequiresLimit: { limitText: \"18446744073709551615\" },\n likeEscapeClause: null,\n // JSON_EXTRACT/JSON_UNQUOTE for scalars and strings; JSON_CONTAINS for\n // array containment; `$[0]` / `$[last]` path elements for the edge ops.\n jsonPathMode: \"mysqlExtract\",\n supportedJsonOps: [\n \"equals\",\n \"string_contains\",\n \"string_starts_with\",\n \"string_ends_with\",\n \"array_contains\",\n \"array_starts_with\",\n \"array_ends_with\",\n ],\n // Json transport is already plain text here — no param cast needed.\n jsonParamCast: \"\",\n lastInsertIdSql: \"SELECT LAST_INSERT_ID() AS `id`\",\n selectForUpdate: \" FOR UPDATE\",\n rowDefaultKeyword: true,\n paramBudget: 10000,\n\n quoteIdent({ name }) {\n return `\\`${name.replaceAll(\"`\", \"``\")}\\``;\n },\n placeholder() {\n return \"?\";\n },\n};\n",
5
+ "/**\n * The SQL AST — the small statement language the runtime and migrate packages\n * build and dialects render.\n *\n * Deliberately minimal at P0 (single-table statements, no joins/subqueries);\n * grows with the runtime in P2/P3. Every shape added here needs a catalog case\n * (tests/catalog/cases.ts) in the same change.\n */\n\nimport type { SqlFragmentSpec } from \"@vibeorm/schema\";\n\n// ─── References ───────────────────────────────────────────────────\n\n/** A column reference, optionally table-qualified. */\nexport type ColRef = {\n readonly table?: string;\n readonly name: string;\n /**\n * Projection-only wire transform, postgres lateral joins only (SQL review\n * B3): raw `to_jsonb` would ship BigInt/Decimal as float64 JSON numbers and\n * Bytes as `\\x` hex text, so the subselect casts instead — `castText`\n * renders `\"col\"::text AS \"col\"`, `encodeBase64` renders\n * `encode(\"col\", 'base64') AS \"col\"`. Never set on filter/order refs.\n */\n readonly transform?: \"castText\" | \"encodeBase64\";\n /**\n * Comparison/order/aggregate cast, sqlite Decimal only (SQL review B4):\n * Decimal stores as exact TEXT there and text comparison is lexicographic —\n * compare, ORDER BY and aggregate sites render `CAST(\"col\" AS REAL)` (with\n * NUMBER operands) instead. Never set on projections or GROUP BY keys, so\n * storage and read-back stay the exact text.\n */\n readonly castReal?: boolean;\n /**\n * Projection alias: renders `ref AS \"alias\"`. PROJECTION-ONLY — filter,\n * order and correlation refs never set it (the renderer ignores it outside\n * a projection list). Used by the single-statement M2M join to expose the\n * join table's parent-key column under a reserved name (`__vibe_parent`).\n */\n readonly alias?: string;\n};\n\nexport type TableRef = {\n readonly name: string;\n readonly alias?: string;\n};\n\n// ─── Aggregates ───────────────────────────────────────────────────\n\n/** Aggregate functions applied to one column. */\nexport type AggFn = \"count\" | \"avg\" | \"sum\" | \"min\" | \"max\";\n\n/** Reference to an aggregate expression: `COUNT(*)` or `FN(\"col\")`. */\nexport type AggRef =\n | { readonly fn: \"countAll\" }\n | { readonly fn: AggFn; readonly column: ColRef };\n\n/**\n * One aggregate projection: `FN(\"col\") AS \"alias\"`. The alias is part of the\n * catalog contract — the runtime derives result keys from it deterministically\n * (`_count___all`, `_avg__score`), never by parsing the SQL text back.\n */\nexport type AggSelect = {\n readonly agg: AggRef;\n readonly alias: string;\n};\n\n// ─── JSON filters ─────────────────────────────────────────────────\n\n/**\n * JSON path predicates (Prisma's Json filter surface). `not` is `equals` with\n * `negate` — there is no separate op. Which ops a dialect can express is\n * declared on `SqlDialect.supportedJsonOps` and enforced at render time too.\n */\nexport type JsonFilterOp =\n | \"equals\"\n | \"string_contains\"\n | \"string_starts_with\"\n | \"string_ends_with\"\n | \"array_contains\"\n | \"array_starts_with\"\n | \"array_ends_with\";\n\n// ─── Expressions ──────────────────────────────────────────────────\n\nexport type ComparisonOp = \"eq\" | \"ne\" | \"gt\" | \"gte\" | \"lt\" | \"lte\";\n\nexport type SqlExpr =\n | { readonly kind: \"cmp\"; readonly op: ComparisonOp; readonly column: ColRef; readonly value: unknown }\n /** Column-to-column comparison — the correlation predicate of EXISTS/lateral subqueries. */\n | { readonly kind: \"cmpCol\"; readonly op: ComparisonOp; readonly left: ColRef; readonly right: ColRef }\n | { readonly kind: \"isNull\"; readonly column: ColRef; readonly negate?: boolean }\n | {\n readonly kind: \"inArray\";\n readonly column: ColRef;\n readonly values: readonly unknown[];\n readonly negate?: boolean;\n }\n | {\n readonly kind: \"like\";\n readonly column: ColRef;\n /** Pre-built pattern (see like.ts helpers for escaping). */\n readonly pattern: string;\n readonly insensitive?: boolean;\n readonly negate?: boolean;\n }\n /**\n * Case-SENSITIVE string match (`mode: \"strict\"`, board #20). `value` is the\n * RAW operand — pattern building happens at render time because escaping\n * differs per strategy (LIKE's `%`/`_`/`\\` vs GLOB's `*`/`?`/`[`). Renders\n * per `SqlDialect.strictMatchStrategy`: plain `=`/`LIKE` on postgres\n * (already byte-sensitive — a deliberate, documented no-op), `=`/`GLOB` on\n * sqlite, `= CAST(? AS BINARY)`/`LIKE CAST(? AS BINARY)` on mysql. The\n * non-native forms defeat plain indexes; docs/dialect-notes.md carries the\n * cost and the functional/`_bin`-index mitigation.\n */\n | {\n readonly kind: \"strictMatch\";\n readonly column: ColRef;\n readonly op: \"equals\" | \"contains\" | \"startsWith\" | \"endsWith\";\n readonly value: string;\n readonly negate?: boolean;\n }\n | { readonly kind: \"and\"; readonly operands: readonly SqlExpr[] }\n | { readonly kind: \"or\"; readonly operands: readonly SqlExpr[] }\n | { readonly kind: \"not\"; readonly operand: SqlExpr }\n /**\n * Correlated subquery test: `[NOT] EXISTS (SELECT …)`. The inner select\n * correlates to the outer scope through table-qualified `cmpCol` predicates;\n * its parameters merge into the statement's single parameter sequence in\n * render order. Relation filters (`some`/`every`/`none`/`is`/`isNot`)\n * compile to this shape.\n */\n | { readonly kind: \"exists\"; readonly select: SelectStatement; readonly negate?: boolean }\n /** Aggregate comparison — the HAVING predicate: `COUNT(\"col\") > $n`. */\n | { readonly kind: \"aggCmp\"; readonly op: ComparisonOp; readonly agg: AggRef; readonly value: unknown }\n /**\n * Scalar-list membership: `$n = ANY(\"col\")` — Prisma's `has`. Postgres only\n * (`capabilities.scalarArrays`); other dialects refuse at render time.\n */\n | { readonly kind: \"arrayHas\"; readonly column: ColRef; readonly value: unknown; readonly negate?: boolean }\n /** Scalar-list superset: `\"col\" @> $n` (one array param) — Prisma's `hasEvery`. Postgres only. */\n | { readonly kind: \"arrayContainsAll\"; readonly column: ColRef; readonly values: readonly unknown[] }\n /** Scalar-list overlap: `\"col\" && $n` (one array param) — Prisma's `hasSome`. Postgres only. */\n | { readonly kind: \"arrayOverlaps\"; readonly column: ColRef; readonly values: readonly unknown[] }\n /**\n * Scalar-list emptiness via `array_length(\"col\", 1) IS [NOT] NULL` — the v1\n * semantics kept deliberately: `empty: true` matches NULL **and** empty\n * arrays, `empty: false` matches only rows with at least one element.\n */\n | { readonly kind: \"arrayIsEmpty\"; readonly column: ColRef; readonly empty: boolean }\n /**\n * JSON path predicate. The path is always BOUND as a parameter (a `text[]`\n * on postgres, a `$.a.b[0]` path string on sqlite/mysql) — path segments\n * never become SQL text. `value` is the RAW JS operand; each dialect decides\n * its wire form (JSON.stringify for jsonb/json comparisons, LIKE patterns\n * for the string ops). `insensitive` applies to the string ops only.\n */\n | {\n readonly kind: \"jsonFilter\";\n readonly column: ColRef;\n readonly path: readonly (string | number)[];\n readonly op: JsonFilterOp;\n readonly value: unknown;\n readonly insensitive?: boolean;\n readonly negate?: boolean;\n }\n /**\n * A bound extension fragment: literal text, bound parameters and quoted\n * identifiers in order (extensions.md §3 sql plane — trgm operators, rank\n * and distance terms). Parameters flow through the shared ParamCollector,\n * identifiers through dialect.quoteIdent — never hand-written.\n */\n | { readonly kind: \"fragment\"; readonly fragment: SqlFragmentSpec }\n /** Escape hatch for dialect-reviewed fragments. Text only — no parameters. */\n | { readonly kind: \"raw\"; readonly text: string };\n\n// ─── Projections ──────────────────────────────────────────────────\n\n/**\n * An aggregate projection.\n *\n * `countAll` renders `COUNT(*)`. The alias matters for portability: postgres\n * names the bare column `count`, sqlite and mysql name it `COUNT(*)` — callers\n * that must read the value back always pass an alias. Combined with a\n * non-empty `columns` list (grouped counts, `SELECT \"fk\", COUNT(*) … GROUP\n * BY \"fk\"`), it renders AFTER the columns.\n *\n * `one` renders the constant `1` — the conventional EXISTS projection; it\n * cannot be combined with a column list.\n */\nexport type SelectExpr =\n | { readonly kind: \"countAll\"; readonly alias?: string }\n | { readonly kind: \"one\" };\n\n// ─── SET operations ───────────────────────────────────────────────\n\n/** Arithmetic applied to a column's current value in an UPDATE ... SET. */\nexport type SetOperator = \"increment\" | \"decrement\" | \"multiply\" | \"divide\";\n\n/**\n * An atomic update expression: `\"col\" = \"col\" <op> $n`.\n *\n * Recognised structurally inside `UpdateStatement.set`, so the marker key is\n * deliberately unlikely (`__op`). Three layers keep a user's JSON payload from\n * ever being mistaken for one: the Json codec stringifies JSON values before\n * they reach the AST, the query builder only emits this shape for numeric\n * fields, and {@link isSetOperation} demands an exact two-key object.\n */\nexport type SetOperation = {\n readonly __op: SetOperator;\n readonly value: number;\n};\n\nconst SET_OPERATORS: readonly string[] = [\"increment\", \"decrement\", \"multiply\", \"divide\"];\n\n/** Narrow an UPDATE set value to an atomic {@link SetOperation}. */\nexport function isSetOperation(value: unknown): value is SetOperation {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) return false;\n const keys = Object.keys(value);\n if (keys.length !== 2 || !keys.includes(\"__op\") || !keys.includes(\"value\")) return false;\n const candidate = value as { __op: unknown; value: unknown };\n return (\n typeof candidate.__op === \"string\" &&\n SET_OPERATORS.includes(candidate.__op) &&\n typeof candidate.value === \"number\" &&\n Number.isFinite(candidate.value)\n );\n}\n\n/**\n * A scalar-list update expression (Prisma's `{ push: … }` on list columns):\n * `append` is one element (`\"col\" = array_append(\"col\", $n)`), `concat` an\n * array of elements (`\"col\" = \"col\" || $n`). Postgres only — the query builder\n * gates on `capabilities.scalarArrays` at build time and the renderer refuses\n * too. Same structural-marker discipline as {@link SetOperation}: the key is\n * unlikely, the shape exact, and Json payloads are stringified before they\n * could ever reach an UPDATE set.\n */\nexport type ListSetOperation = {\n readonly __listOp: \"append\" | \"concat\";\n readonly value: unknown;\n};\n\nconst LIST_SET_OPERATORS: readonly string[] = [\"append\", \"concat\"];\n\n/** Narrow an UPDATE set value to a {@link ListSetOperation}. */\nexport function isListSetOperation(value: unknown): value is ListSetOperation {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) return false;\n const keys = Object.keys(value);\n if (keys.length !== 2 || !keys.includes(\"__listOp\") || !keys.includes(\"value\")) return false;\n const candidate = value as { __listOp: unknown };\n return typeof candidate.__listOp === \"string\" && LIST_SET_OPERATORS.includes(candidate.__listOp);\n}\n\n/**\n * Database-clock marker: renders the DIALECT's `now()` expression — plus an\n * optional whole-second offset bound as a parameter — instead of binding a\n * client-side timestamp. Flows as a VALUES cell, an UPDATE SET value, or a\n * comparison operand; the runtime's public `dbNow()` sentinel compiles to\n * this marker for DateTime fields (leases, TTLs — anything that must trust\n * the database's clock, never the process's). Same structural-marker\n * discipline as {@link SetOperation}: unlikely key, exact shape.\n */\nexport type DbNowMarker = {\n readonly __dbNow: true;\n readonly offsetSeconds: number;\n};\n\n/** Build a {@link DbNowMarker}; `offsetSeconds` must be a whole number. */\nexport function dbNowMarker(params: { offsetSeconds: number }): DbNowMarker {\n return { __dbNow: true, offsetSeconds: params.offsetSeconds };\n}\n\n/** Narrow a value to a {@link DbNowMarker}. */\nexport function isDbNowMarker(value: unknown): value is DbNowMarker {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) return false;\n const keys = Object.keys(value);\n if (keys.length !== 2 || !keys.includes(\"__dbNow\") || !keys.includes(\"offsetSeconds\")) return false;\n const candidate = value as { __dbNow: unknown; offsetSeconds: unknown };\n return (\n candidate.__dbNow === true &&\n typeof candidate.offsetSeconds === \"number\" &&\n Number.isInteger(candidate.offsetSeconds)\n );\n}\n\n// ─── Ordering ─────────────────────────────────────────────────────\n\n/** ORDER BY a column, with optional NULLS placement (native or emulated per dialect). */\nexport type OrderByColumn = {\n readonly column: ColRef;\n readonly direction: \"asc\" | \"desc\";\n /** NULLS placement; rendered natively or emulated per dialect. */\n readonly nulls?: \"first\" | \"last\";\n};\n\n/** ORDER BY an aggregate expression — grouped selects ordering by `COUNT(\"col\")`. */\nexport type OrderByAggregate = {\n readonly agg: AggRef;\n readonly direction: \"asc\" | \"desc\";\n};\n\n/**\n * ORDER BY a correlated scalar subquery — relation orderBy\n * (`orderBy: { posts: { _count: \"desc\" } }` → `(SELECT COUNT(*) …)` /\n * `orderBy: { author: { email: \"asc\" } }` → `(SELECT \"email\" …)`).\n * Portable: all three dialects order by scalar subqueries. The subquery\n * correlates to the outer scope through table-qualified `cmpCol` predicates,\n * exactly like `exists`; its parameters merge into the statement's single\n * sequence in render order. NULLS placement is deliberately unsupported here\n * (emulating it would render the subquery twice and duplicate its params) —\n * missing relations sort at each engine's native NULL position.\n */\nexport type OrderBySubquery = {\n readonly select: SelectStatement;\n readonly direction: \"asc\" | \"desc\";\n};\n\nexport type OrderTerm = OrderByColumn | OrderByAggregate | OrderBySubquery;\n\n// ─── Statements ───────────────────────────────────────────────────\n\n/**\n * One `LEFT JOIN LATERAL (…) AS alias ON true` clause aggregating a correlated\n * subquery into a single JSON value per outer row — the \"join\" relation-loading\n * strategy (postgres/pglite only; gated on `capabilities.lateralJoin`).\n *\n * Renders (agg `jsonArray`):\n * `LEFT JOIN LATERAL (SELECT COALESCE(jsonb_agg(to_jsonb(\"__sub\".*)), '[]'::jsonb)\n * AS \"columnAlias\" FROM (<select>) AS \"__sub\") AS \"alias\" ON true`\n * and (agg `jsonObject`):\n * `LEFT JOIN LATERAL (SELECT to_jsonb(\"__sub\".*) AS \"columnAlias\"\n * FROM (<select>) AS \"__sub\") AS \"alias\" ON true`\n *\n * `to_jsonb` over a subselect (not `json_build_object`) sidesteps postgres's\n * 100-argument function limit on wide models (v1 lesson). The inner select's\n * ORDER BY drives the aggregate's element order. Consumers must run the codec\n * table over the parsed JSON children: `to_jsonb` turns timestamps into\n * strings and loses BigInt-ness (LEARNINGS).\n */\nexport type LateralJoin = {\n /** Join alias (`__lat_0`) — the outer projection selects `alias.columnAlias`. */\n readonly alias: string;\n /** Column the aggregated JSON value is exposed under (`__rel_posts`). */\n readonly columnAlias: string;\n /** `jsonArray` for to-many (aggregated array), `jsonObject` for to-one (LIMIT 1 row or NULL). */\n readonly agg: \"jsonArray\" | \"jsonObject\";\n /** The correlated child select — may reference outer columns via table-qualified refs. */\n readonly select: SelectStatement;\n};\n\n/**\n * One `INNER JOIN \"table\" AS alias ON left = right [AND …]` clause — plain\n * equality joins only, portable across all dialects. Added for the\n * single-statement implicit-M2M load (child rows joined to their join-table\n * membership rows); extra join-table columns project through the statement's\n * `columns` list with a table qualifier + `alias`.\n */\nexport type InnerJoin = {\n readonly table: TableRef;\n /** Equality pairs ANDed into the ON clause; never empty. */\n readonly on: readonly { readonly left: ColRef; readonly right: ColRef }[];\n};\n\n/**\n * A `ROW_NUMBER() OVER (PARTITION BY … [ORDER BY …]) AS \"alias\"` projection,\n * appended after `columns` — the distinct emulation on dialects without\n * `DISTINCT ON` (sqlite ≥3.25, mysql ≥8.0 both have window functions): the\n * outer statement filters `alias = 1` on the derived table, restoring\n * SQL-side take/skip and bounded transfer (N10).\n */\nexport type RowNumberProjection = {\n readonly partitionBy: readonly ColRef[];\n /** Intra-partition order picking the representative row; may be empty. */\n readonly orderBy: readonly OrderTerm[];\n readonly alias: string;\n};\n\nexport type SelectStatement = {\n readonly kind: \"select\";\n readonly table: TableRef;\n /** Empty array renders as `SELECT *` (unless `selectExpr` replaces it). */\n readonly columns: readonly ColRef[];\n /**\n * Aggregate projection. Replaces the column list when `columns` is empty;\n * a `countAll` with columns renders after them (grouped counts).\n */\n readonly selectExpr?: SelectExpr;\n /**\n * Aliased aggregate projections (`AVG(\"col\") AS \"_avg__col\"`), rendered\n * after `columns` — the aggregate/groupBy/count-select shapes. Cannot be\n * combined with `selectExpr`.\n */\n readonly aggregates?: readonly AggSelect[];\n /**\n * `SELECT DISTINCT ON (cols)` — postgres only (`capabilities.distinctOn`;\n * other dialects refuse at render time and the runtime emulates client-side\n * instead). ORDER BY must lead with these columns; the query builder\n * guarantees that arrangement.\n */\n readonly distinctOn?: readonly ColRef[];\n /**\n * Derived-table FROM: renders `FROM (<fromSelect>) AS \"<table.name>\"` —\n * `table.name` is the subquery ALIAS and `table.alias` must be unset. Used\n * by aggregate-over-a-subset shapes (`aggregate({ take, skip, orderBy })`).\n */\n readonly fromSelect?: SelectStatement;\n /** Lateral JSON-aggregation joins — postgres-only, see {@link LateralJoin}. */\n readonly lateralJoins?: readonly LateralJoin[];\n /** Plain equality INNER JOINs — portable, see {@link InnerJoin}. */\n readonly innerJoins?: readonly InnerJoin[];\n /** ROW_NUMBER window projection — see {@link RowNumberProjection}. */\n readonly rowNumber?: RowNumberProjection;\n readonly where?: SqlExpr;\n readonly groupBy?: readonly ColRef[];\n /** HAVING predicate — grouped selects; may contain `aggCmp` expressions. */\n readonly having?: SqlExpr;\n readonly orderBy?: readonly OrderTerm[];\n readonly limit?: number;\n readonly offset?: number;\n /**\n * Row-locking read (`SELECT … FOR UPDATE`) — the overlay flows on dialects\n * without RETURNING read a row they are about to write. Rendered only where\n * the dialect names a lock clause (`dialect.selectForUpdate`); sqlite has\n * none and needs none — its write transactions already exclude each other.\n */\n readonly lockForUpdate?: boolean;\n};\n\n/**\n * Sentinel VALUES cell: render the `DEFAULT` keyword instead of a placeholder\n * (M4) — a heterogeneous createMany row that omits a field lets the COLUMN\n * default apply (or NULL on a defaultless nullable column), exactly like a\n * single-row insert that omits it. Postgres/mysql only\n * (`dialect.rowDefaultKeyword`); sqlite groups rows instead.\n */\nexport const SQL_DEFAULT_CELL: { readonly __sqlDefault: true } = Object.freeze({ __sqlDefault: true });\n\n/** Is this VALUES cell the {@link SQL_DEFAULT_CELL} sentinel? */\nexport function isSqlDefaultCell(value: unknown): boolean {\n return value === SQL_DEFAULT_CELL;\n}\n\n/**\n * VALUES/SET cell carrying a Json column's parameter (the codec's JSON text).\n *\n * Why it exists: OID-typed drivers (bun:sql) resolve each parameter's postgres\n * type and re-serialize the JS value AS that type — a pre-stringified Json\n * param bound straight into a bare jsonb slot arrives DOUBLE-ENCODED (a jsonb\n * string holding the document; live-proven on Bun 1.3.14). The postgres\n * renderer pins the parameter's type instead (`$n::text::jsonb`,\n * `SqlDialect.jsonParamCast`), so every driver sends the text through and the\n * SERVER parses it; text-param drivers (node-postgres, pglite) are unaffected.\n * Sqlite/mysql render the bare placeholder — their Json transport is already\n * plain text. The COLLECTED parameter is the plain text either way: this\n * wrapper never crosses the wire.\n */\nexport type JsonParamCell = { readonly __jsonParam: true; readonly text: string };\n\n/** Wrap a Json column's encoded (stringified) parameter for cast-site rendering. */\nexport function jsonParamCell(params: { text: string }): JsonParamCell {\n return { __jsonParam: true, text: params.text };\n}\n\n/** Is this VALUES/SET cell a {@link JsonParamCell}? */\nexport function isJsonParamCell(value: unknown): value is JsonParamCell {\n return (\n typeof value === \"object\" &&\n value !== null &&\n (value as { __jsonParam?: unknown }).__jsonParam === true\n );\n}\n\nexport type InsertStatement = {\n readonly kind: \"insert\";\n readonly table: TableRef;\n readonly columns: readonly string[];\n /** Row values aligned to `columns` — deterministic parameter order. */\n readonly rows: readonly (readonly unknown[])[];\n /** Upsert clause: ON CONFLICT (pg/sqlite) or ON DUPLICATE KEY (mysql). */\n readonly onConflict?: OnConflictClause;\n /** Rendered as RETURNING where the dialect supports it, else omitted+flagged. */\n readonly returning?: readonly string[];\n};\n\n/** Conflicting rows are updated with these column values. */\nexport type OnConflictUpdate = {\n /** Conflict target columns (ignored by the mysql form). */\n readonly columns: readonly string[];\n /**\n * Named-constraint target: `ON CONFLICT ON CONSTRAINT \"name\" DO UPDATE`.\n * Postgres only; replaces the column-list target when present.\n */\n readonly constraint?: string;\n readonly update: Readonly<Record<string, unknown>>;\n /**\n * MySQL only (`upsertForm: \"onDuplicateKey\"`): append\n * `` `col` = LAST_INSERT_ID(`col`) `` to the update list so the UPDATE arm\n * records the addressed row's key — without it `LAST_INSERT_ID()` is stale\n * on the update arm and the read-back can resolve a wrong, unrelated row\n * (SQL review B2, live-proven on 8.4). Only meaningful for integer keys.\n */\n readonly lastInsertIdColumn?: string;\n};\n\n/**\n * Conflicting rows are skipped (`createMany({ skipDuplicates: true })`).\n * An empty/absent target means \"any conflict\" — the mysql form (INSERT IGNORE)\n * can only express that, so it ignores a bare `columns` target (documented\n * degradation) and REFUSES the refined targets below.\n */\nexport type OnConflictDoNothing = {\n readonly columns?: readonly string[];\n /**\n * Partial-index target predicate, RAW SQL: `ON CONFLICT (cols) WHERE pred\n * DO NOTHING` (postgres/sqlite; requires `columns`). Raw — and rendered\n * verbatim — because BOTH engines match the clause against the index's OWN\n * stored predicate structurally: a bound parameter could never match, so\n * the text mirrors the schema declaration's `where:` string byte-for-byte.\n */\n readonly conflictWhere?: string;\n /** Named-constraint target (`ON CONSTRAINT \"name\"`) — postgres only. */\n readonly constraint?: string;\n readonly doNothing: true;\n};\n\nexport type OnConflictClause = OnConflictUpdate | OnConflictDoNothing;\n\nexport type UpdateStatement = {\n readonly kind: \"update\";\n readonly table: TableRef;\n /** Column → parameter value, or an atomic {@link SetOperation}. */\n readonly set: Readonly<Record<string, unknown>>;\n readonly where?: SqlExpr;\n readonly returning?: readonly string[];\n};\n\nexport type DeleteStatement = {\n readonly kind: \"delete\";\n readonly table: TableRef;\n readonly where?: SqlExpr;\n readonly returning?: readonly string[];\n};\n\nexport type SqlStatement = SelectStatement | InsertStatement | UpdateStatement | DeleteStatement;\n",
6
+ "/**\n * Per-dialect capability tables — the frozen feature contract.\n *\n * Mirrored verbatim by tests/capabilities.test.ts: changing a value here forces\n * a reviewed test change. Runtime fallbacks, migrate DDL, generator output and\n * E2E `skipUnlessCapability()` all read these same objects.\n */\n\nimport type { Dialect, DialectCapabilities } from \"@vibeorm/schema\";\n\nexport const POSTGRES_CAPABILITIES: DialectCapabilities = {\n returning: true,\n scalarArrays: true,\n nativeEnums: true,\n ilike: true,\n lateralJoin: true,\n distinctOn: true,\n partialIndexes: true,\n conflictTargetConstraint: true,\n transactionalDdl: true,\n createManyAndReturn: true,\n jsonColumnType: true,\n orderByNulls: true,\n fullTextEngines: [\"bm25\", \"tsvector\"],\n};\n\nexport const SQLITE_CAPABILITIES: DialectCapabilities = {\n returning: true,\n scalarArrays: false,\n nativeEnums: false,\n ilike: false,\n lateralJoin: false,\n distinctOn: false,\n partialIndexes: true,\n conflictTargetConstraint: false,\n transactionalDdl: true,\n createManyAndReturn: true,\n jsonColumnType: false,\n orderByNulls: true,\n fullTextEngines: [\"fts5\"],\n};\n\nexport const MYSQL_CAPABILITIES: DialectCapabilities = {\n returning: false,\n scalarArrays: false,\n nativeEnums: true,\n ilike: false,\n lateralJoin: false,\n distinctOn: false,\n partialIndexes: false,\n conflictTargetConstraint: false,\n transactionalDdl: false,\n createManyAndReturn: false,\n jsonColumnType: true,\n orderByNulls: false,\n fullTextEngines: [\"fulltext\"],\n};\n\nexport const DIALECT_CAPABILITIES: Readonly<Record<Dialect, DialectCapabilities>> = {\n postgres: POSTGRES_CAPABILITIES,\n sqlite: SQLITE_CAPABILITIES,\n mysql: MYSQL_CAPABILITIES,\n};\n",
7
+ "/**\n * PostgreSQL dialect. Also serves PGlite — the differences are adapter-level\n * (single connection, bundled extension set), not SQL-text-level.\n */\n\nimport type { SqlDialect } from \"../dialect.ts\";\nimport { POSTGRES_CAPABILITIES } from \"../capabilities.ts\";\n\nexport const postgresDialect: SqlDialect = {\n name: \"postgres\",\n capabilities: POSTGRES_CAPABILITIES,\n\n inArrayStrategy: \"any\",\n upsertForm: \"onConflict\",\n doNothingForm: \"onConflictDoNothing\",\n insensitiveLike: \"ilike\",\n // Postgres `=`/`LIKE` are already byte-sensitive — strict mode is a no-op.\n strictMatchStrategy: \"native\",\n orderByNullsMode: \"native\",\n offsetRequiresLimit: null,\n likeEscapeClause: null,\n jsonPathMode: \"operators\",\n supportedJsonOps: [\n \"equals\",\n \"string_contains\",\n \"string_starts_with\",\n \"string_ends_with\",\n \"array_contains\",\n \"array_starts_with\",\n \"array_ends_with\",\n ],\n // Json params bind as TEXT and the server parses (`$n::text::jsonb`):\n // OID-typed drivers (bun:sql) would re-serialize a bare jsonb-slot param\n // and double-encode the document (JsonParamCell, ast.ts).\n jsonParamCast: \"::text::jsonb\",\n lastInsertIdSql: null,\n selectForUpdate: \" FOR UPDATE\",\n rowDefaultKeyword: true,\n paramBudget: 30000,\n\n quoteIdent({ name }) {\n return `\"${name.replaceAll('\"', '\"\"')}\"`;\n },\n placeholder({ index }) {\n return `$${index}`;\n },\n renderDbNow({ offsetSeconds, collector }) {\n if (offsetSeconds === 0) return \"now()\";\n return `(now() + make_interval(secs => ${collector.add(offsetSeconds)}))`;\n },\n};\n",
8
+ "/**\n * SQLite dialect (bun:sqlite adapter lands in P4).\n *\n * Notes pinned by catalog cases:\n * - OFFSET requires LIMIT → `LIMIT -1 OFFSET n`.\n * - LIKE has no default escape character → explicit ` ESCAPE '\\'` clause.\n * - Case-insensitive matching uses LOWER()/LOWER() (default LIKE is only\n * ASCII-case-insensitive, and we want deterministic semantics).\n */\n\nimport type { SqlDialect } from \"../dialect.ts\";\nimport { SQLITE_CAPABILITIES } from \"../capabilities.ts\";\n\nexport const sqliteDialect: SqlDialect = {\n name: \"sqlite\",\n capabilities: SQLITE_CAPABILITIES,\n\n inArrayStrategy: \"expand\",\n upsertForm: \"onConflict\",\n doNothingForm: \"onConflictDoNothing\",\n insensitiveLike: \"lower\",\n // LIKE is ASCII-case-insensitive here — strict pattern matching rides GLOB\n // (byte-exact; its `*`/`?`/`[` metachars get their own escaping, like.ts).\n strictMatchStrategy: \"glob\",\n orderByNullsMode: \"native\",\n offsetRequiresLimit: { limitText: \"-1\" },\n likeEscapeClause: \" ESCAPE '\\\\'\",\n // json_extract covers scalar extraction + LIKE over extracted text; the\n // expressible array subset (N6, board #21) is wired: `$[0]` / `$[#-1]` path\n // elements for array_starts_with/array_ends_with (sqlite ≥3.31; bun:sqlite\n // bundles far newer) and json_each() EXISTS for SCALAR-element\n // array_contains. Deep structural jsonb-style containment (object/array/\n // null members) has no cheap faithful form — the renderer refuses those\n // ELEMENT shapes with VIBE_UNSUPPORTED_CAPABILITY even though the op itself\n // is listed here.\n jsonPathMode: \"sqliteExtract\",\n supportedJsonOps: [\n \"equals\",\n \"string_contains\",\n \"string_starts_with\",\n \"string_ends_with\",\n \"array_contains\",\n \"array_starts_with\",\n \"array_ends_with\",\n ],\n // Json transport is already plain text here — no param cast needed.\n jsonParamCast: \"\",\n lastInsertIdSql: null,\n // No FOR UPDATE in sqlite — and none needed: a write transaction holds the\n // single writer lock, so overlay reads inside it cannot race another writer.\n selectForUpdate: null,\n // No per-row DEFAULT keyword in VALUES — heterogeneous createMany rows are\n // grouped by column set into separate statements (M4).\n rowDefaultKeyword: false,\n paramBudget: 900,\n\n quoteIdent({ name }) {\n return `\"${name.replaceAll('\"', '\"\"')}\"`;\n },\n placeholder() {\n return \"?\";\n },\n renderDbNow({ offsetSeconds, collector }) {\n // The format string mirrors Date#toISOString() (`%f` = SS.SSS), which is\n // exactly what the DateTime codec stores — lexicographic comparisons\n // against stored text stay correct. The offset rides sqlite's relative\n // modifier syntax (`'300 seconds'` / `'-300 seconds'`).\n if (offsetSeconds === 0) return `strftime('%Y-%m-%dT%H:%M:%fZ', 'now')`;\n return `strftime('%Y-%m-%dT%H:%M:%fZ', 'now', ${collector.add(offsetSeconds)} || ' seconds')`;\n },\n};\n",
9
+ "/**\n * MySQL dialect (mysql2 adapter lands in P4).\n *\n * Notes pinned by catalog cases:\n * - No RETURNING → renderer omits it and flags `returning: \"omitted\"`; the\n * runtime re-selects by PK (app-generated ids) or insertId.\n * - Upserts use ON DUPLICATE KEY UPDATE (no conflict-target refinement).\n * - OFFSET requires LIMIT → the documented huge-limit idiom.\n * - No NULLS FIRST/LAST → `col IS NULL` emulation terms.\n * - No `ON CONFLICT ... DO NOTHING` → `INSERT IGNORE`, which is broader: it\n * downgrades other row-level errors to warnings too.\n */\n\nimport type { SqlDialect } from \"../dialect.ts\";\nimport { MYSQL_CAPABILITIES } from \"../capabilities.ts\";\n\nexport const mysqlDialect: SqlDialect = {\n name: \"mysql\",\n capabilities: MYSQL_CAPABILITIES,\n\n inArrayStrategy: \"expand\",\n upsertForm: \"onDuplicateKey\",\n doNothingForm: \"insertIgnore\",\n insensitiveLike: \"lower\",\n // `_ci` collations fold `=` and `LIKE` — strict mode casts the OPERAND to\n // BINARY (byte-wise comparison; CAST form, the unary BINARY operator is\n // deprecated since 8.0.27). Operand-side: no assumption about the column's\n // charset, and the cost (index defeat) is documented in dialect-notes.md.\n strictMatchStrategy: \"binary\",\n orderByNullsMode: \"emulate\",\n offsetRequiresLimit: { limitText: \"18446744073709551615\" },\n likeEscapeClause: null,\n // JSON_EXTRACT/JSON_UNQUOTE for scalars and strings; JSON_CONTAINS for\n // array containment; `$[0]` / `$[last]` path elements for the edge ops.\n jsonPathMode: \"mysqlExtract\",\n supportedJsonOps: [\n \"equals\",\n \"string_contains\",\n \"string_starts_with\",\n \"string_ends_with\",\n \"array_contains\",\n \"array_starts_with\",\n \"array_ends_with\",\n ],\n // Json transport is already plain text here — no param cast needed.\n jsonParamCast: \"\",\n lastInsertIdSql: \"SELECT LAST_INSERT_ID() AS `id`\",\n selectForUpdate: \" FOR UPDATE\",\n rowDefaultKeyword: true,\n paramBudget: 10000,\n\n quoteIdent({ name }) {\n return `\\`${name.replaceAll(\"`\", \"``\")}\\``;\n },\n placeholder() {\n return \"?\";\n },\n renderDbNow({ offsetSeconds, collector }) {\n // NOW(6): microsecond precision — assignment to a lower-precision column\n // truncates, matching the driver's own Date serialization precision.\n if (offsetSeconds === 0) return \"NOW(6)\";\n return `DATE_ADD(NOW(6), INTERVAL ${collector.add(offsetSeconds)} SECOND)`;\n },\n};\n",
10
10
  "/**\n * Dialect registry: the one place a `Dialect` name becomes a `SqlDialect`.\n *\n * Runtime and adapters resolve through this map so nobody re-implements the\n * lookup (and nobody can quietly forget a dialect — the Record type is total).\n */\n\nimport type { Dialect } from \"@vibeorm/schema\";\nimport type { SqlDialect } from \"../dialect.ts\";\nimport { postgresDialect } from \"./postgres.ts\";\nimport { sqliteDialect } from \"./sqlite.ts\";\nimport { mysqlDialect } from \"./mysql.ts\";\n\nexport const SQL_DIALECTS: Readonly<Record<Dialect, SqlDialect>> = {\n postgres: postgresDialect,\n sqlite: sqliteDialect,\n mysql: mysqlDialect,\n};\n\n/** The SQL dialect a dialect name selects. */\nexport function getSqlDialect(params: { dialect: Dialect }): SqlDialect {\n return SQL_DIALECTS[params.dialect];\n}\n",
11
11
  "/**\n * The pure codec tables — constitution rule 6.\n *\n * ONE place defines how a JS value becomes a driver parameter (`encode`) and\n * how a driver value becomes a JS value (`decode`), per dialect × scalar type.\n * Nothing else in any package may coerce: v1's BigInt-as-string, enum-array and\n * timestamp bugs all came from coercion scattered across query builders and\n * relation loaders (LEARNINGS.md).\n *\n * These tables are PURE — dialect × scalar type only, no schema/model\n * awareness. The FieldMeta-aware entry points (`getCodec`/`encodeValue`/\n * `decodeValue`/`decodeRow`/`decodeRows`) live in @vibeorm/runtime, which\n * re-exports these tables so existing consumers keep one import site.\n *\n * The two rules that make it work:\n * - EVERY parameter bound by the query builder passes through `encode`.\n * - EVERY row materialized by the client passes through `decode` — including\n * every relation-loaded child row (the v1 lesson).\n *\n * Enum fields ride the String codec: enum values are plain strings on the wire\n * on all three dialects.\n */\n\nimport { VibeError } from \"@vibeorm/schema\";\nimport type { Dialect, ScalarType } from \"@vibeorm/schema\";\n\n// ─── Types ────────────────────────────────────────────────────────\n\n/**\n * One scalar type's transport rules for one dialect. Both directions see only\n * non-null values — the runtime's `encodeValue`/`decodeValue` short-circuit\n * null/undefined.\n */\nexport type ScalarCodec = {\n readonly encode: (value: unknown) => unknown;\n readonly decode: (value: unknown) => unknown;\n};\n\nexport type CodecTable = Readonly<Record<ScalarType, ScalarCodec>>;\n\n// ─── Wire fidelity (board #30) ────────────────────────────────────\n\n/**\n * What a DRIVER actually delivers for NON-LIST **base-table storage** columns\n * on its result path — declared per adapter (`DatabaseAdapter.wire`), verified\n * live per driver, and consumed by the runtime's decode plans to skip decoders\n * that are provably no-ops for that driver. The claims hold because base-table\n * storage types follow the declared field types by construction (migrate's\n * mappings); VIEW columns can hide any expression type under a declared field\n * type (mysql `COUNT(*)` is BIGINT-as-string under an `Int` field), so the\n * runtime exempts views from pruning entirely.\n *\n * Why it exists: the codec tables above are keyed per DIALECT, but wire forms\n * differ per DRIVER (node-postgres hands `Date` objects where a text-mode\n * driver hands strings). Without a declaration every DateTime/Json/Int column\n * pays an idempotency probe per row per read; with one, the decode plan keeps\n * only decoders that do real work. The codec DEFINITIONS stay right here —\n * rule 6 — only plan membership changes, and only under a declaration.\n *\n * An adapter that declares nothing gets the full idempotency-guarded plan\n * (today's behaviour). Declarations are PROMISES: declare only what the\n * driver verifiably does.\n */\nexport type WireFidelity = {\n /** DateTime columns arrive as JS `Date` instances (`\"native\"`) or as text/number (`\"text\"`). */\n readonly dateTime?: \"native\" | \"text\";\n /** Json columns arrive already parsed (`\"parsed\"`) or as raw JSON text (`\"text\"`). */\n readonly json?: \"parsed\" | \"text\";\n /** Int/Float columns arrive as JS numbers (`\"native\"`) or as text (`\"text\"`). */\n readonly numbers?: \"native\" | \"text\";\n};\n\n/**\n * Is this scalar type's DECODE a no-op under the declared wire fidelity?\n * Provable against the decode implementations in this file, identically on\n * every dialect table:\n *\n * - `DateTime` + `dateTime: \"native\"` — every DateTime decode\n * (postgres/sqlite/mysql all share {@link dateNativeCodec}'s decode) returns\n * a `Date` instance unchanged.\n * - `Json` + `json: \"parsed\"` — {@link jsonCodec}'s decode returns non-strings\n * unchanged. (For a driver that pre-parses, skipping is also the CORRECT\n * reading of a stored top-level JSON **string**: the driver hands a bare JS\n * string, which the guarded decode would wrongly re-parse.)\n * - `Int`/`Float` + `numbers: \"native\"` — {@link numberCodec}'s decode returns\n * numbers unchanged.\n *\n * Everything else always decodes: BigInt (string→BigInt is real work on every\n * driver that can't send int64), Decimal (mysql pads), Boolean (0/1→boolean),\n * Bytes, and every LIST field (array wire forms differ per driver and are not\n * covered by the declaration).\n */\nexport function decodeIsNoop(params: { scalarType: ScalarType; wire: WireFidelity | undefined }): boolean {\n const { scalarType, wire } = params;\n if (wire === undefined) return false;\n if (scalarType === \"DateTime\") return wire.dateTime === \"native\";\n if (scalarType === \"Json\") return wire.json === \"parsed\";\n if (scalarType === \"Int\" || scalarType === \"Float\") return wire.numbers === \"native\";\n return false;\n}\n\n// ─── Shared codec pieces ──────────────────────────────────────────\n\nconst identity = (value: unknown): unknown => value;\n\n/** Values that already are what the driver wants, in both directions. */\nconst passthroughCodec: ScalarCodec = { encode: identity, decode: identity };\n\n/** Numbers that some drivers hand back as text (numeric-ish column types). */\nconst numberCodec: ScalarCodec = {\n encode: identity,\n decode: (value) => (typeof value === \"string\" ? Number(value) : value),\n};\n\n/**\n * BigInt. No driver serializes a JS `bigint` parameter, so it always goes out\n * as text; sqlite's INTEGER affinity converts it back on the way in. Incoming\n * values arrive as strings (postgres `int8`, mysql `BIGINT`) or numbers.\n */\nconst bigIntCodec: ScalarCodec = {\n encode: (value) => (typeof value === \"bigint\" ? value.toString() : value),\n decode: (value) => {\n if (typeof value === \"bigint\") return value;\n if (typeof value === \"string\" || typeof value === \"number\") return BigInt(value);\n return value;\n },\n};\n\n/**\n * Decimal stays a string in JS, in both directions and on every dialect: no\n * float rounding, and no decimal library forced on the consumer. Numbers and\n * bigints passed in are stringified rather than silently losing precision.\n *\n * Decode is identity on postgres and sqlite: both preserve the scale the\n * value was WRITTEN with (`numeric` keeps the input's display scale; sqlite\n * stores the text), so `\"12.340\"` round-trips as `\"12.340\"` — trimming would\n * destroy information the engine kept. MySQL cannot preserve it (fixed-scale\n * DECIMAL) and gets its own decode — see {@link mysqlDecimalCodec}.\n */\nconst decimalCodec: ScalarCodec = {\n encode: (value) => (typeof value === \"number\" || typeof value === \"bigint\" ? String(value) : value),\n decode: identity,\n};\n\n/**\n * MySQL Decimal: same encode, but decode trims the fixed-scale padding.\n * MySQL's DECIMAL is fixed-scale, so the written scale is unrecoverable and\n * every value comes back padded to the column's full scale — verified live on\n * 8.4, `DECIMAL(65, 30)` returns `\"42.420000000000000000000000000000\"` where\n * postgres/sqlite return `\"42.42\"`. Trailing FRACTIONAL zeros (and a\n * then-dangling point) are an artifact of storage, not the value, so decode\n * trims them to the minimal exact string. Integer zeros are never touched.\n */\nconst mysqlDecimalCodec: ScalarCodec = {\n encode: decimalCodec.encode,\n decode: (value) => {\n if (typeof value !== \"string\" || !value.includes(\".\")) return value;\n const trimmed = value.replace(/0+$/, \"\").replace(/\\.$/, \"\");\n return trimmed === \"\" || trimmed === \"-\" ? \"0\" : trimmed;\n },\n};\n\n/** DateTime where the driver speaks `Date` objects (postgres, mysql). */\nconst dateNativeCodec: ScalarCodec = {\n encode: identity,\n decode: (value) => {\n if (value instanceof Date) return value;\n if (typeof value === \"string\" || typeof value === \"number\") return new Date(value);\n return value;\n },\n};\n\n/** DateTime on sqlite: stored as ISO-8601 UTC text, parsed back on read. */\nconst dateTextCodec: ScalarCodec = {\n encode: (value) => (value instanceof Date ? value.toISOString() : value),\n decode: dateNativeCodec.decode,\n};\n\n/** Does the string carry an explicit zone (Z or a ±hh[:]mm offset)? */\nconst EXPLICIT_ZONE = /(?:Z|[+-]\\d{2}:?\\d{2})$/i;\n/** Date-only ISO form — ECMA-262 already parses it as UTC. */\nconst DATE_ONLY = /^\\d{4}-\\d{2}-\\d{2}$/;\n\n/**\n * DateTime on mysql (N4 + MYSQL-2): mysql2 serializes `Date` per the\n * adapter's pinned `timezone: \"Z\"`, but passes STRINGS verbatim — an ISO-8601\n * string operand hard-errors on strict-mode servers (1292). Encode normalizes\n * parseable strings/numbers to `Date` — and ZONE-LESS strings\n * (`2026-01-15T12:00:00`, `2026-01-15 12:00:00`) parse as UTC, never\n * process-local time (MYSQL-2, live-proven: TZ=America/New_York stored 17:00Z\n * for a noon literal): postgres under the session's pinned UTC parses the\n * same literal as UTC, so treat-as-UTC is the only reading that stores the\n * SAME instant on both dialects. Strings with an explicit Z/offset parse\n * as written; garbage passes through so the driver's own error names it.\n */\nconst mysqlDateCodec: ScalarCodec = {\n encode: (value) => {\n if (value instanceof Date) return value;\n if (typeof value === \"number\") {\n const parsed = new Date(value); // epoch millis — zone-free by definition\n if (!Number.isNaN(parsed.getTime())) return parsed;\n return value;\n }\n if (typeof value === \"string\") {\n const trimmed = value.trim();\n if (!EXPLICIT_ZONE.test(trimmed) && !DATE_ONLY.test(trimmed)) {\n // Zone-less date-time — pin it to UTC (mysql-style space separator\n // normalized to T first).\n const asUtc = new Date(`${trimmed.replace(\" \", \"T\")}Z`);\n if (!Number.isNaN(asUtc.getTime())) return asUtc;\n }\n const parsed = new Date(trimmed);\n if (!Number.isNaN(parsed.getTime())) return parsed;\n }\n return value;\n },\n decode: dateNativeCodec.decode,\n};\n\n/** Booleans stored as 0/1 (sqlite INTEGER). */\nconst booleanIntCodec: ScalarCodec = {\n encode: (value) => (typeof value === \"boolean\" ? (value ? 1 : 0) : value),\n decode: (value) => (typeof value === \"number\" ? value !== 0 : value),\n};\n\n/**\n * Booleans the driver sends natively but reads back as 0/1 (mysql TINYINT(1)).\n */\nconst booleanNativeInCodec: ScalarCodec = {\n encode: identity,\n decode: booleanIntCodec.decode,\n};\n\n/**\n * JSON is serialized by US, on every dialect, and never handed to a driver as a\n * live object. Two reasons: drivers disagree (node-postgres stringifies objects,\n * bun:sqlite and mysql2 do not), and a JSON payload that happens to look like an\n * atomic UPDATE operation must never reach the SQL AST as an object\n * (see `isSetOperation` in ast.ts). Reads arrive as text on postgres and\n * sqlite, and already parsed from mysql2's JSON columns.\n */\nconst jsonCodec: ScalarCodec = {\n encode: (value) => JSON.stringify(value),\n decode: (value) => {\n if (typeof value !== \"string\") return value;\n try {\n return JSON.parse(value);\n } catch (cause) {\n throw new VibeError({\n code: \"VIBE_INTERNAL\",\n message: \"a Json column returned text that is not valid JSON\",\n meta: { value },\n cause,\n });\n }\n },\n};\n\n// ─── Per-dialect tables ───────────────────────────────────────────\n\n/** postgres (and pglite — same wire behaviour). */\nexport const POSTGRES_CODECS: CodecTable = {\n String: passthroughCodec,\n Boolean: passthroughCodec,\n Int: numberCodec,\n BigInt: bigIntCodec,\n Float: numberCodec,\n Decimal: decimalCodec,\n DateTime: dateNativeCodec,\n Json: jsonCodec,\n Bytes: passthroughCodec,\n};\n\n/** sqlite — no boolean, date or json types; everything rides TEXT/INTEGER. */\nexport const SQLITE_CODECS: CodecTable = {\n String: passthroughCodec,\n Boolean: booleanIntCodec,\n Int: numberCodec,\n BigInt: bigIntCodec,\n Float: numberCodec,\n Decimal: decimalCodec,\n DateTime: dateTextCodec,\n Json: jsonCodec,\n Bytes: passthroughCodec,\n};\n\n/** mysql — native DATETIME and JSON, booleans stored as TINYINT(1). */\nexport const MYSQL_CODECS: CodecTable = {\n String: passthroughCodec,\n Boolean: booleanNativeInCodec,\n Int: numberCodec,\n BigInt: bigIntCodec,\n Float: numberCodec,\n Decimal: mysqlDecimalCodec,\n DateTime: mysqlDateCodec,\n Json: jsonCodec,\n Bytes: passthroughCodec,\n};\n\n/** The whole table, keyed by dialect. */\nexport const DIALECT_CODECS: Readonly<Record<Dialect, CodecTable>> = {\n postgres: POSTGRES_CODECS,\n sqlite: SQLITE_CODECS,\n mysql: MYSQL_CODECS,\n};\n",
12
- "/**\n * Statement renderer: SQL AST × dialect → { text, values, returning }.\n *\n * The shared grammar lives here; every dialect divergence goes through an\n * explicit SqlDialect strategy field. Malformed ASTs throw VIBE_INTERNAL —\n * the AST is built by VibeORM code, so a bad shape is always our bug.\n */\n\nimport { internalError, unsupportedCapability } from \"@vibeorm/schema\";\nimport type { SqlFragmentSpec } from \"@vibeorm/schema\";\nimport type { ColRef, OrderTerm, SqlStatement, SqlExpr, TableRef } from \"./ast.ts\";\nimport type {\n AggFn,\n AggRef,\n DeleteStatement,\n InsertStatement,\n LateralJoin,\n SelectExpr,\n SelectStatement,\n SetOperator,\n UpdateStatement,\n} from \"./ast.ts\";\nimport { isJsonParamCell, isListSetOperation, isSetOperation, isSqlDefaultCell } from \"./ast.ts\";\nimport type { SqlDialect } from \"./dialect.ts\";\nimport { containsPattern, endsWithPattern, startsWithPattern, strictMatchPattern } from \"./like.ts\";\nimport { ParamCollector } from \"./params.ts\";\n\n// ─── Result shape ─────────────────────────────────────────────────\n\nexport type RenderedQuery = {\n readonly text: string;\n readonly values: unknown[];\n /**\n * RETURNING status: \"native\" (rendered), \"omitted\" (requested but the dialect\n * lacks it — caller must re-select), \"none\" (not requested).\n */\n readonly returning: \"native\" | \"omitted\" | \"none\";\n};\n\n// ─── Entry point ──────────────────────────────────────────────────\n\nexport function renderStatement(params: { dialect: SqlDialect; statement: SqlStatement }): RenderedQuery {\n const { dialect, statement } = params;\n const collector = new ParamCollector(dialect);\n switch (statement.kind) {\n case \"select\":\n return renderSelect({ dialect, statement, collector });\n case \"insert\":\n return renderInsert({ dialect, statement, collector });\n case \"update\":\n return renderUpdate({ dialect, statement, collector });\n case \"delete\":\n return renderDelete({ dialect, statement, collector });\n }\n}\n\n// ─── Shared pieces ────────────────────────────────────────────────\n\nfunction quoteCol(dialect: SqlDialect, column: ColRef): string {\n const name = dialect.quoteIdent({ name: column.name });\n const ref = column.table === undefined ? name : `${dialect.quoteIdent({ name: column.table })}.${name}`;\n // B4: sqlite Decimal compare/order/aggregate sites read the TEXT column as\n // REAL — the builder sets this only there, never on projections.\n if (column.castReal === true) {\n if (dialect.name !== \"sqlite\") {\n throw internalError({ message: \"ColRef.castReal is a sqlite Decimal construct\" });\n }\n return `CAST(${ref} AS REAL)`;\n }\n return ref;\n}\n\n/**\n * Projection rendering: a plain reference, or its B3 wire transform\n * (`\"col\"::text AS \"col\"` / `encode(\"col\", 'base64') AS \"col\"`) — postgres\n * lateral subselects only; any other dialect reaching one is a builder bug.\n */\nfunction quoteProjection(dialect: SqlDialect, column: ColRef): string {\n if (column.transform === undefined) {\n const base = quoteCol(dialect, column);\n if (column.alias === undefined) return base;\n return `${base} AS ${dialect.quoteIdent({ name: column.alias })}`;\n }\n if (dialect.name !== \"postgres\") {\n throw internalError({ message: \"ColRef.transform is a postgres lateral-join construct\" });\n }\n const ref = quoteCol(dialect, column);\n const alias = dialect.quoteIdent({ name: column.name });\n if (column.transform === \"castText\") return `${ref}::text AS ${alias}`;\n return `encode(${ref}, 'base64') AS ${alias}`;\n}\n\nfunction renderTable(dialect: SqlDialect, table: TableRef): string {\n const name = dialect.quoteIdent({ name: table.name });\n if (table.alias === undefined) return name;\n return `${name} AS ${dialect.quoteIdent({ name: table.alias })}`;\n}\n\nfunction assertCount(value: number, what: string): void {\n if (!Number.isSafeInteger(value) || value < 0) {\n throw internalError({ message: `${what} must be a non-negative integer, got ${value}` });\n }\n}\n\nconst COMPARISON_SQL: Readonly<Record<string, string>> = {\n eq: \"=\",\n ne: \"<>\",\n gt: \">\",\n gte: \">=\",\n lt: \"<\",\n lte: \"<=\",\n};\n\n/**\n * Atomic SET arithmetic. `divide` is plain `/`: integer columns therefore\n * follow each dialect's own integer-division rule (pg/sqlite truncate, mysql\n * promotes to decimal) — pinned by the update-atomic-ops catalog case.\n */\nconst SET_OPERATION_SQL: Readonly<Record<SetOperator, string>> = {\n increment: \"+\",\n decrement: \"-\",\n multiply: \"*\",\n divide: \"/\",\n};\n\nconst AGG_FN_SQL: Readonly<Record<AggFn, string>> = {\n count: \"COUNT\",\n avg: \"AVG\",\n sum: \"SUM\",\n min: \"MIN\",\n max: \"MAX\",\n};\n\n/** `COUNT(*)` / `FN(\"col\")` — shared by projections, HAVING and ORDER BY. */\nfunction renderAggRef(dialect: SqlDialect, agg: AggRef): string {\n if (agg.fn === \"countAll\") return \"COUNT(*)\";\n return `${AGG_FN_SQL[agg.fn]}(${quoteCol(dialect, agg.column)})`;\n}\n\nfunction assertScalarArrays(dialect: SqlDialect, feature: string): void {\n if (dialect.capabilities.scalarArrays) return;\n throw unsupportedCapability({\n dialect: dialect.name,\n feature,\n hint: \"only postgres has native array columns — model the list as a related table instead\",\n });\n}\n\n// ─── Expressions ──────────────────────────────────────────────────\n\n/**\n * Render one boolean expression into SQL text, collecting parameters into the\n * shared collector. Public so extension delegates can AND user `where` trees\n * (compiled by the runtime) into their own statements.\n */\nexport function renderExpr(params: { dialect: SqlDialect; expr: SqlExpr; collector: ParamCollector }): string {\n const { dialect, expr, collector } = params;\n\n switch (expr.kind) {\n case \"cmp\": {\n const op = COMPARISON_SQL[expr.op];\n if (op === undefined) {\n throw internalError({ message: `unknown comparison operator \"${expr.op}\"` });\n }\n return `${quoteCol(dialect, expr.column)} ${op} ${collector.add(expr.value)}`;\n }\n\n case \"cmpCol\": {\n const op = COMPARISON_SQL[expr.op];\n if (op === undefined) {\n throw internalError({ message: `unknown comparison operator \"${expr.op}\"` });\n }\n return `${quoteCol(dialect, expr.left)} ${op} ${quoteCol(dialect, expr.right)}`;\n }\n\n case \"isNull\":\n return `${quoteCol(dialect, expr.column)} IS ${expr.negate === true ? \"NOT NULL\" : \"NULL\"}`;\n\n case \"inArray\": {\n if (expr.values.length === 0) {\n // Empty IN matches nothing; empty NOT IN matches everything.\n return expr.negate === true ? \"1 = 1\" : \"1 = 0\";\n }\n const column = quoteCol(dialect, expr.column);\n if (dialect.inArrayStrategy === \"any\") {\n const base = `${column} = ANY(${collector.add([...expr.values])})`;\n return expr.negate === true ? `NOT (${base})` : base;\n }\n const placeholders = collector.addMany(expr.values);\n return `${column} ${expr.negate === true ? \"NOT IN\" : \"IN\"} (${placeholders.join(\", \")})`;\n }\n\n case \"like\": {\n const column = quoteCol(dialect, expr.column);\n const placeholder = collector.add(expr.pattern);\n let base: string;\n if (expr.insensitive === true) {\n base =\n dialect.insensitiveLike === \"ilike\"\n ? `${column} ILIKE ${placeholder}`\n : `LOWER(${column}) LIKE LOWER(${placeholder})`;\n } else {\n base = `${column} LIKE ${placeholder}`;\n }\n if (dialect.likeEscapeClause !== null) {\n base = `${base}${dialect.likeEscapeClause}`;\n }\n return expr.negate === true ? `NOT (${base})` : base;\n }\n\n case \"strictMatch\": {\n const column = quoteCol(dialect, expr.column);\n let base: string;\n if (expr.op === \"equals\") {\n // pg and sqlite `=` are already byte-exact; only mysql's `_ci`\n // collations fold equality and need the BINARY cast.\n base =\n dialect.strictMatchStrategy === \"binary\"\n ? `${column} = CAST(${collector.add(expr.value)} AS BINARY)`\n : `${column} = ${collector.add(expr.value)}`;\n } else {\n const pattern = strictMatchPattern({\n strategy: dialect.strictMatchStrategy,\n op: expr.op,\n value: expr.value,\n });\n if (dialect.strictMatchStrategy === \"glob\") {\n base = `${column} GLOB ${collector.add(pattern)}`;\n } else {\n const placeholder = collector.add(pattern);\n base =\n dialect.strictMatchStrategy === \"binary\"\n ? `${column} LIKE CAST(${placeholder} AS BINARY)`\n : `${column} LIKE ${placeholder}`;\n if (dialect.likeEscapeClause !== null) base = `${base}${dialect.likeEscapeClause}`;\n }\n }\n return expr.negate === true ? `NOT (${base})` : base;\n }\n\n case \"and\":\n case \"or\": {\n if (expr.operands.length === 0) {\n // Neutral elements: empty AND is always-true, empty OR always-false.\n return expr.kind === \"and\" ? \"1 = 1\" : \"1 = 0\";\n }\n if (expr.operands.length === 1) {\n return renderExpr({ dialect, expr: expr.operands[0]!, collector });\n }\n const joiner = expr.kind === \"and\" ? \" AND \" : \" OR \";\n const rendered = expr.operands.map((operand) => renderExpr({ dialect, expr: operand, collector }));\n return `(${rendered.join(joiner)})`;\n }\n\n case \"not\":\n return `NOT (${renderExpr({ dialect, expr: expr.operand, collector })})`;\n\n case \"aggCmp\": {\n const op = COMPARISON_SQL[expr.op];\n if (op === undefined) {\n throw internalError({ message: `unknown comparison operator \"${expr.op}\"` });\n }\n return `${renderAggRef(dialect, expr.agg)} ${op} ${collector.add(expr.value)}`;\n }\n\n case \"arrayHas\": {\n assertScalarArrays(dialect, \"the scalar-list filter \\\"has\\\"\");\n const base = `${collector.add(expr.value)} = ANY(${quoteCol(dialect, expr.column)})`;\n return expr.negate === true ? `NOT (${base})` : base;\n }\n\n case \"arrayContainsAll\": {\n assertScalarArrays(dialect, \"the scalar-list filter \\\"hasEvery\\\"\");\n return `${quoteCol(dialect, expr.column)} @> ${collector.add([...expr.values])}`;\n }\n\n case \"arrayOverlaps\": {\n assertScalarArrays(dialect, \"the scalar-list filter \\\"hasSome\\\"\");\n return `${quoteCol(dialect, expr.column)} && ${collector.add([...expr.values])}`;\n }\n\n case \"arrayIsEmpty\": {\n assertScalarArrays(dialect, \"the scalar-list filter \\\"isEmpty\\\"\");\n // v1 semantics kept: array_length of NULL and of '{}' are both NULL, so\n // `isEmpty: true` matches NULL **and** empty lists.\n const column = quoteCol(dialect, expr.column);\n return `array_length(${column}, 1) IS ${expr.empty ? \"NULL\" : \"NOT NULL\"}`;\n }\n\n case \"jsonFilter\":\n return renderJsonFilter({ dialect, expr, collector });\n\n case \"exists\": {\n // The subquery shares the statement's collector, so its parameters land\n // in the single sequence exactly where they appear in the text.\n const sub = renderSelect({ dialect, statement: expr.select, collector });\n return `${expr.negate === true ? \"NOT \" : \"\"}EXISTS (${sub.text})`;\n }\n\n case \"fragment\":\n return renderFragment({ dialect, fragment: expr.fragment, collector });\n\n case \"raw\":\n return expr.text;\n }\n}\n\n// ─── Bound fragments (extension SQL plane) ───────────────────\n\n/**\n * Render a neutral bound fragment (extensions.md §3): literal text verbatim,\n * `{ param }` through the collector (single placeholder sequence), `{ ident }`\n * paths through dialect.quoteIdent. Exported so extension delegates can build\n * full statements sharing one collector with core-compiled WHERE trees.\n */\nexport function renderFragment(params: {\n dialect: SqlDialect;\n fragment: SqlFragmentSpec;\n collector: ParamCollector;\n}): string {\n const { dialect, fragment, collector } = params;\n let text = \"\";\n for (const part of fragment.parts) {\n if (typeof part === \"string\") {\n text += part;\n } else if (\"param\" in part) {\n text += collector.add(part.param);\n } else {\n text += part.ident.map((name) => dialect.quoteIdent({ name })).join(\".\");\n }\n }\n return text;\n}\n\n// ─── JSON path filters ─────────────────────────────────────────────\n\n/** `$.a.b[0]` path string for sqlite/mysql — always bound, never spliced. */\nfunction jsonPathString(path: readonly (string | number)[]): string {\n let out = \"$\";\n for (const segment of path) {\n if (typeof segment === \"number\") {\n out += `[${segment}]`;\n } else if (/^[A-Za-z_][A-Za-z0-9_]*$/.test(segment)) {\n out += `.${segment}`;\n } else {\n out += `.\"${segment.replaceAll('\"', '\\\\\"')}\"`;\n }\n }\n return out;\n}\n\ntype JsonFilterExpr = Extract<SqlExpr, { kind: \"jsonFilter\" }>;\n\nfunction jsonStringPattern(params: { expr: JsonFilterExpr }): string {\n const { expr } = params;\n if (typeof expr.value !== \"string\") {\n throw internalError({ message: `json ${expr.op} expects a string operand` });\n }\n if (expr.op === \"string_contains\") return containsPattern({ raw: expr.value });\n if (expr.op === \"string_starts_with\") return startsWithPattern({ raw: expr.value });\n return endsWithPattern({ raw: expr.value });\n}\n\n/** Case-[in]sensitive LIKE over an extracted-text expression, per dialect. */\nfunction renderJsonLike(params: {\n dialect: SqlDialect;\n target: string;\n expr: JsonFilterExpr;\n collector: ParamCollector;\n}): string {\n const { dialect, target, expr, collector } = params;\n const placeholder = collector.add(jsonStringPattern({ expr }));\n let base: string;\n if (expr.insensitive === true) {\n base =\n dialect.insensitiveLike === \"ilike\"\n ? `${target} ILIKE ${placeholder}`\n : `LOWER(${target}) LIKE LOWER(${placeholder})`;\n } else {\n base = `${target} LIKE ${placeholder}`;\n }\n if (dialect.likeEscapeClause !== null) base = `${base}${dialect.likeEscapeClause}`;\n return expr.negate === true ? `NOT (${base})` : base;\n}\n\n/**\n * One JSON path predicate, per dialect strategy. The path is BOUND: a `text[]`\n * parameter on postgres (cast so string-literal array forms work too), a\n * `$.a.b` path string elsewhere. Values bind as JSON text for json/jsonb\n * comparisons and as LIKE patterns for the string ops.\n */\nfunction renderJsonFilter(params: {\n dialect: SqlDialect;\n expr: JsonFilterExpr;\n collector: ParamCollector;\n}): string {\n const { dialect, expr, collector } = params;\n if (!dialect.supportedJsonOps.includes(expr.op)) {\n throw unsupportedCapability({\n dialect: dialect.name,\n feature: `the json filter \"${expr.op}\"`,\n hint: `this dialect can express: ${dialect.supportedJsonOps.join(\", \")}`,\n });\n }\n const cmp = expr.negate === true ? \"<>\" : \"=\";\n\n if (dialect.jsonPathMode === \"operators\") {\n const column = quoteCol(dialect, expr.column);\n const pathParam = `${collector.add(expr.path.map(String))}::text[]`;\n switch (expr.op) {\n case \"equals\":\n return `(${column} #> ${pathParam}) ${cmp} ${collector.add(JSON.stringify(expr.value))}${dialect.jsonParamCast}`;\n case \"string_contains\":\n case \"string_starts_with\":\n case \"string_ends_with\":\n return renderJsonLike({ dialect, target: `(${column} #>> ${pathParam})`, expr, collector });\n case \"array_contains\":\n return `(${column} #> ${pathParam}) @> ${collector.add(JSON.stringify(expr.value))}${dialect.jsonParamCast}`;\n case \"array_starts_with\":\n return `(${column} #> ${pathParam}) -> 0 = ${collector.add(JSON.stringify(expr.value))}${dialect.jsonParamCast}`;\n case \"array_ends_with\":\n return `(${column} #> ${pathParam}) -> -1 = ${collector.add(JSON.stringify(expr.value))}${dialect.jsonParamCast}`;\n }\n }\n\n if (dialect.jsonPathMode === \"sqliteExtract\") {\n const column = quoteCol(dialect, expr.column);\n // Compare an extracted JSON value the way `equals` does: booleans surface\n // as 0/1, objects/arrays as canonical minified JSON text (key order\n // matters, documented in the catalog), scalars as SQL values.\n const compareExtracted = (target: string, value: unknown): string => {\n if (typeof value === \"boolean\") {\n return `${target} ${cmp} ${collector.add(value ? 1 : 0)}`;\n }\n if (typeof value === \"object\" && value !== null) {\n return `${target} ${cmp} json(${collector.add(JSON.stringify(value))})`;\n }\n return `${target} ${cmp} ${collector.add(value)}`;\n };\n switch (expr.op) {\n case \"equals\":\n return compareExtracted(`json_extract(${column}, ${collector.add(jsonPathString(expr.path))})`, expr.value);\n case \"string_contains\":\n case \"string_starts_with\":\n case \"string_ends_with\": {\n const target = `json_extract(${column}, ${collector.add(jsonPathString(expr.path))})`;\n return renderJsonLike({ dialect, target, expr, collector });\n }\n case \"array_starts_with\":\n case \"array_ends_with\": {\n // Edge-element access: `$[0]` / `$[#-1]` path elements (sqlite ≥3.31;\n // bun:sqlite bundles far newer) — N6/board #21.\n const edge = expr.op === \"array_starts_with\" ? \"[0]\" : \"[#-1]\";\n return compareExtracted(\n `json_extract(${column}, ${collector.add(`${jsonPathString(expr.path)}${edge}`)})`,\n expr.value,\n );\n }\n case \"array_contains\": {\n // Scalar-needle containment via json_each() EXISTS — one EXISTS per\n // element, ANDed (jsonb `@>` semantics for scalar members). Deep\n // structural containment (object/array members) has no cheap faithful\n // sqlite form and stays refused; JSON null members compare through\n // json_each's 'null' type tag, not SQL NULL, so they are refused too.\n //\n // Haystack type guard (wave-C review): json_each() over a path holding\n // a SCALAR yields one row carrying that scalar, so an unguarded EXISTS\n // matched `{ tags: \"a\" }` against needle `[\"a\"]` where postgres (`@>`\n // with an array needle) and mysql (JSON_CONTAINS against an array\n // literal) are false. json_type() is NULL for a missing path, so\n // missing paths and NULL columns stay non-matches — and an empty\n // needle reduces to the guard alone: contained in every ARRAY (pg's\n // `@> '[]'` truth) and in nothing else.\n const guard = `json_type(${column}, ${collector.add(jsonPathString(expr.path))}) = 'array'`;\n const elements = Array.isArray(expr.value) ? expr.value : [expr.value];\n const tests = elements.map((element) => {\n if (element === null || (typeof element === \"object\" && element !== null)) {\n throw unsupportedCapability({\n dialect: dialect.name,\n feature: \"json array_contains with object/array/null elements\",\n hint: \"sqlite expresses scalar-element containment only — deep structural containment needs postgres or mysql\",\n });\n }\n const bound = typeof element === \"boolean\" ? (element ? 1 : 0) : element;\n return `EXISTS (SELECT 1 FROM json_each(${column}, ${collector.add(jsonPathString(expr.path))}) WHERE ${dialect.quoteIdent({ name: \"json_each\" })}.${dialect.quoteIdent({ name: \"value\" })} = ${collector.add(bound)})`;\n });\n return tests.length === 0 ? guard : `(${[guard, ...tests].join(\" AND \")})`;\n }\n default:\n throw internalError({ message: `json op \"${expr.op}\" leaked past supportedJsonOps on sqlite` });\n }\n }\n\n // mysqlExtract\n const column = quoteCol(dialect, expr.column);\n const pathString = jsonPathString(expr.path);\n switch (expr.op) {\n case \"equals\":\n return `JSON_EXTRACT(${column}, ${collector.add(pathString)}) ${cmp} CAST(${collector.add(JSON.stringify(expr.value))} AS JSON)`;\n case \"string_contains\":\n case \"string_starts_with\":\n case \"string_ends_with\": {\n const target = `JSON_UNQUOTE(JSON_EXTRACT(${column}, ${collector.add(pathString)}))`;\n return renderJsonLike({ dialect, target, expr, collector });\n }\n case \"array_contains\":\n return `JSON_CONTAINS(JSON_EXTRACT(${column}, ${collector.add(pathString)}), CAST(${collector.add(JSON.stringify(expr.value))} AS JSON))`;\n case \"array_starts_with\":\n return `JSON_EXTRACT(${column}, ${collector.add(`${pathString}[0]`)}) ${cmp} CAST(${collector.add(JSON.stringify(expr.value))} AS JSON)`;\n case \"array_ends_with\":\n return `JSON_EXTRACT(${column}, ${collector.add(`${pathString}[last]`)}) ${cmp} CAST(${collector.add(JSON.stringify(expr.value))} AS JSON)`;\n }\n}\n\n// ─── Ordering ─────────────────────────────────────────────────────\n\nfunction renderOrderTerm(params: { dialect: SqlDialect; term: OrderTerm; collector: ParamCollector }): string {\n const { dialect, term, collector } = params;\n if (\"agg\" in term) {\n return `${renderAggRef(dialect, term.agg)} ${term.direction === \"asc\" ? \"ASC\" : \"DESC\"}`;\n }\n if (\"select\" in term) {\n // Relation orderBy: a correlated scalar subquery — its parameters merge\n // into the shared sequence exactly where they appear in the text.\n const sub = renderSelect({ dialect, statement: term.select, collector });\n return `(${sub.text}) ${term.direction === \"asc\" ? \"ASC\" : \"DESC\"}`;\n }\n const column = quoteCol(dialect, term.column);\n const direction = term.direction === \"asc\" ? \"ASC\" : \"DESC\";\n if (term.nulls === undefined) {\n return `${column} ${direction}`;\n }\n if (dialect.orderByNullsMode === \"native\") {\n return `${column} ${direction} NULLS ${term.nulls === \"first\" ? \"FIRST\" : \"LAST\"}`;\n }\n // Emulation (mysql): the engine's native order already places NULLs FIRST on\n // ASC and LAST on DESC — those pairings render the bare term (the redundant\n // boolean pre-term cost a per-row evaluation and could defeat index-order\n // scans, #14). Only the diverging pairings need the `IS NULL` pre-term:\n // false(0) sorts first, so plain `IS NULL` pushes nulls last and\n // `IS NULL DESC` pulls them first.\n if ((term.nulls === \"first\") === (term.direction === \"asc\")) {\n return `${column} ${direction}`;\n }\n const nullsTerm = term.nulls === \"first\" ? `${column} IS NULL DESC` : `${column} IS NULL`;\n return `${nullsTerm}, ${column} ${direction}`;\n}\n\n// ─── Projections ──────────────────────────────────────────────────\n\nfunction renderSelectExpr(params: { dialect: SqlDialect; expr: SelectExpr }): string {\n const { dialect, expr } = params;\n if (expr.kind === \"one\") return \"1\";\n const alias = expr.alias === undefined ? \"\" : ` AS ${dialect.quoteIdent({ name: expr.alias })}`;\n return `COUNT(*)${alias}`;\n}\n\n// ─── Lateral JSON joins ───────────────────────────────────\n\n/**\n * `LEFT JOIN LATERAL (… to_jsonb …) AS alias ON true`. Postgres-only SQL by\n * design — the runtime gates the \"join\" strategy on `capabilities.lateralJoin`\n * at build time, and this renderer refuses too (dialect honesty, rule 4).\n */\nfunction renderLateralJoin(params: {\n dialect: SqlDialect;\n join: LateralJoin;\n collector: ParamCollector;\n}): string {\n const { dialect, join, collector } = params;\n const inner = renderSelect({ dialect, statement: join.select, collector });\n const columnAlias = dialect.quoteIdent({ name: join.columnAlias });\n const subAlias = dialect.quoteIdent({ name: \"__sub\" });\n // N2 (SQL review): jsonb_agg over a subquery only \"usually\" preserves the\n // subquery's order — pin it with an explicit ORDER BY inside the aggregate\n // (the subquery keeps its own ORDER BY for LIMIT). Only column terms that\n // are PROJECTED (and untransformed — a B3 ::text cast would re-sort\n // lexicographically) can be referenced through `__sub`; anything else keeps\n // the old behavior.\n let aggOrder = \"\";\n if (join.agg === \"jsonArray\" && join.select.orderBy !== undefined && join.select.orderBy.length > 0) {\n const projected = new Set(\n join.select.columns\n .filter((column) => column.transform === undefined && column.castReal !== true)\n .map((column) => column.name),\n );\n const terms = join.select.orderBy;\n const columnTerms = terms.filter(\n (term): term is Extract<OrderTerm, { column: ColRef }> => !(\"agg\" in term),\n );\n if (columnTerms.length === terms.length && columnTerms.every((term) => projected.has(term.column.name))) {\n const rendered = columnTerms.map((term) =>\n renderOrderTerm({ dialect, term: { ...term, column: { table: \"__sub\", name: term.column.name } }, collector }),\n );\n aggOrder = ` ORDER BY ${rendered.join(\", \")}`;\n }\n }\n const projection =\n join.agg === \"jsonArray\"\n ? `COALESCE(jsonb_agg(to_jsonb(${subAlias}.*)${aggOrder}), '[]'::jsonb) AS ${columnAlias}`\n : `to_jsonb(${subAlias}.*) AS ${columnAlias}`;\n const alias = dialect.quoteIdent({ name: join.alias });\n return `LEFT JOIN LATERAL (SELECT ${projection} FROM (${inner.text}) AS ${subAlias}) AS ${alias} ON true`;\n}\n\n// ─── RETURNING ────────────────────────────────────────────────────\n\nfunction applyReturning(params: {\n dialect: SqlDialect;\n requested: readonly string[] | undefined;\n}): { suffix: string; status: \"native\" | \"omitted\" | \"none\" } {\n const { dialect, requested } = params;\n if (requested === undefined || requested.length === 0) {\n return { suffix: \"\", status: \"none\" };\n }\n if (!dialect.capabilities.returning) {\n return { suffix: \"\", status: \"omitted\" };\n }\n const columns = requested.map((name) => dialect.quoteIdent({ name })).join(\", \");\n return { suffix: ` RETURNING ${columns}`, status: \"native\" };\n}\n\n// ─── SELECT ───────────────────────────────────────────────────────\n\nfunction renderSelect(params: {\n dialect: SqlDialect;\n statement: SelectStatement;\n collector: ParamCollector;\n}): RenderedQuery {\n const { dialect, statement, collector } = params;\n\n if (statement.selectExpr !== undefined && statement.columns.length > 0 && statement.selectExpr.kind !== \"countAll\") {\n throw internalError({ message: \"only countAll can combine with a column list\" });\n }\n if (\n statement.selectExpr !== undefined &&\n statement.aggregates !== undefined &&\n statement.aggregates.length > 0\n ) {\n throw internalError({ message: \"selectExpr and aggregates cannot combine\" });\n }\n const columnList = statement.columns.map((column) => quoteProjection(dialect, column));\n if (statement.selectExpr !== undefined) {\n columnList.push(renderSelectExpr({ dialect, expr: statement.selectExpr }));\n }\n if (statement.aggregates !== undefined) {\n for (const selection of statement.aggregates) {\n columnList.push(`${renderAggRef(dialect, selection.agg)} AS ${dialect.quoteIdent({ name: selection.alias })}`);\n }\n }\n if (statement.rowNumber !== undefined) {\n const rowNumber = statement.rowNumber;\n if (rowNumber.partitionBy.length === 0) {\n throw internalError({ message: \"rowNumber needs at least one partition column\" });\n }\n const partition = rowNumber.partitionBy.map((column) => quoteCol(dialect, column)).join(\", \");\n const order =\n rowNumber.orderBy.length === 0\n ? \"\"\n : ` ORDER BY ${rowNumber.orderBy.map((term) => renderOrderTerm({ dialect, term, collector })).join(\", \")}`;\n columnList.push(\n `ROW_NUMBER() OVER (PARTITION BY ${partition}${order}) AS ${dialect.quoteIdent({ name: rowNumber.alias })}`,\n );\n }\n let distinctPrefix = \"\";\n if (statement.distinctOn !== undefined && statement.distinctOn.length > 0) {\n if (!dialect.capabilities.distinctOn) {\n throw unsupportedCapability({\n dialect: dialect.name,\n feature: \"SELECT DISTINCT ON\",\n hint: \"postgres-only — the runtime emulates distinct client-side on this dialect\",\n });\n }\n distinctPrefix = `DISTINCT ON (${statement.distinctOn.map((column) => quoteCol(dialect, column)).join(\", \")}) `;\n }\n const columns = columnList.length === 0 ? \"*\" : columnList.join(\", \");\n\n let from: string;\n if (statement.fromSelect !== undefined) {\n if (statement.table.alias !== undefined) {\n throw internalError({ message: \"fromSelect uses table.name as the subquery alias — table.alias must be unset\" });\n }\n // The subquery renders before WHERE/ORDER BY, so its parameters land in\n // the shared sequence exactly where they appear in the text.\n const inner = renderSelect({ dialect, statement: statement.fromSelect, collector });\n from = `(${inner.text}) AS ${dialect.quoteIdent({ name: statement.table.name })}`;\n } else {\n from = renderTable(dialect, statement.table);\n }\n let text = `SELECT ${distinctPrefix}${columns} FROM ${from}`;\n\n if (statement.innerJoins !== undefined && statement.innerJoins.length > 0) {\n for (const join of statement.innerJoins) {\n if (join.on.length === 0) {\n throw internalError({ message: \"inner join needs at least one ON pair\" });\n }\n const on = join.on\n .map((pair) => `${quoteCol(dialect, pair.left)} = ${quoteCol(dialect, pair.right)}`)\n .join(\" AND \");\n text += ` INNER JOIN ${renderTable(dialect, join.table)} ON ${on}`;\n }\n }\n\n if (statement.lateralJoins !== undefined && statement.lateralJoins.length > 0) {\n if (!dialect.capabilities.lateralJoin) {\n throw unsupportedCapability({\n dialect: dialect.name,\n feature: \"LATERAL JOIN relation loading\",\n hint: 'use the portable \"query\" relation strategy on this dialect',\n });\n }\n for (const join of statement.lateralJoins) {\n text += ` ${renderLateralJoin({ dialect, join, collector })}`;\n }\n }\n\n if (statement.where !== undefined) {\n text += ` WHERE ${renderExpr({ dialect, expr: statement.where, collector })}`;\n }\n if (statement.groupBy !== undefined && statement.groupBy.length > 0) {\n text += ` GROUP BY ${statement.groupBy.map((column) => quoteCol(dialect, column)).join(\", \")}`;\n }\n if (statement.having !== undefined) {\n text += ` HAVING ${renderExpr({ dialect, expr: statement.having, collector })}`;\n }\n if (statement.orderBy !== undefined && statement.orderBy.length > 0) {\n const terms = statement.orderBy.map((term) => renderOrderTerm({ dialect, term, collector }));\n text += ` ORDER BY ${terms.join(\", \")}`;\n }\n\n if (statement.limit !== undefined) {\n assertCount(statement.limit, \"limit\");\n text += ` LIMIT ${statement.limit}`;\n }\n if (statement.offset !== undefined) {\n assertCount(statement.offset, \"offset\");\n if (statement.limit === undefined && dialect.offsetRequiresLimit !== null) {\n text += ` LIMIT ${dialect.offsetRequiresLimit.limitText}`;\n }\n text += ` OFFSET ${statement.offset}`;\n }\n if (statement.lockForUpdate === true && dialect.selectForUpdate !== null) {\n text += dialect.selectForUpdate;\n }\n\n return { text, values: collector.values, returning: \"none\" };\n}\n\n// ─── INSERT (incl. upsert) ────────────────────────────────────────\n\nfunction renderInsert(params: {\n dialect: SqlDialect;\n statement: InsertStatement;\n collector: ParamCollector;\n}): RenderedQuery {\n const { dialect, statement, collector } = params;\n\n if (statement.columns.length === 0) {\n throw internalError({ message: \"insert requires at least one column\" });\n }\n if (statement.rows.length === 0) {\n throw internalError({ message: \"insert requires at least one row\" });\n }\n for (const row of statement.rows) {\n if (row.length !== statement.columns.length) {\n throw internalError({\n message: `insert row has ${row.length} values but ${statement.columns.length} columns`,\n });\n }\n }\n\n const onConflict = statement.onConflict;\n const skipConflicts = onConflict !== undefined && \"doNothing\" in onConflict;\n const insertKeyword =\n skipConflicts && dialect.doNothingForm === \"insertIgnore\" ? \"INSERT IGNORE INTO\" : \"INSERT INTO\";\n\n const columnList = statement.columns.map((name) => dialect.quoteIdent({ name })).join(\", \");\n const rowsSql = statement.rows\n .map(\n (row) =>\n `(${row\n .map((value) => {\n // Json cell: the param's type is pinned (`$n::text::jsonb` on\n // postgres) so OID-typed drivers cannot double-encode the document.\n if (isJsonParamCell(value)) return `${collector.add(value.text)}${dialect.jsonParamCast}`;\n if (!isSqlDefaultCell(value)) return collector.add(value);\n // M4: a heterogeneous createMany cell defers to the COLUMN default.\n if (!dialect.rowDefaultKeyword) {\n throw internalError({\n message: `${dialect.name} cannot render a per-row DEFAULT cell — rows must be grouped by column set`,\n });\n }\n return \"DEFAULT\";\n })\n .join(\", \")})`,\n )\n .join(\", \");\n let text = `${insertKeyword} ${renderTable(dialect, statement.table)} (${columnList}) VALUES ${rowsSql}`;\n\n if (onConflict !== undefined) {\n if (\"doNothing\" in onConflict) {\n if (dialect.doNothingForm === \"onConflictDoNothing\") {\n const target =\n onConflict.columns === undefined || onConflict.columns.length === 0\n ? \"\"\n : ` (${onConflict.columns.map((name) => dialect.quoteIdent({ name })).join(\", \")})`;\n text += ` ON CONFLICT${target} DO NOTHING`;\n }\n } else {\n const updates = Object.entries(onConflict.update);\n if (updates.length === 0) {\n throw internalError({ message: \"upsert update must set at least one column\" });\n }\n // The update arm's self-references MUST be table-qualified: inside\n // `ON CONFLICT … DO UPDATE SET`, postgres has BOTH the target row and\n // the `excluded` pseudo-relation in scope, so a bare `\"views\" + $n`\n // is rejected as ambiguous (SQLSTATE 42702). Sqlite and mysql accept\n // the qualified form with identical semantics (the pre-update row), so\n // one rule covers every dialect instead of a per-dialect divergence.\n const selfRef = dialect.quoteIdent({ name: statement.table.name });\n const assignments = renderAssignments({ dialect, entries: updates, collector, selfRef });\n if (dialect.upsertForm === \"onConflict\") {\n if (onConflict.lastInsertIdColumn !== undefined) {\n throw internalError({ message: \"lastInsertIdColumn is a mysql (onDuplicateKey) construct\" });\n }\n const conflictColumns = onConflict.columns.map((name) => dialect.quoteIdent({ name })).join(\", \");\n text += ` ON CONFLICT (${conflictColumns}) DO UPDATE SET ${assignments}`;\n } else {\n // B2: the update arm must record WHICH row it addressed — without this,\n // LAST_INSERT_ID() is stale after ODKU takes the update arm and the\n // read-back can resolve an unrelated row.\n const trick =\n onConflict.lastInsertIdColumn === undefined\n ? \"\"\n : `, ${dialect.quoteIdent({ name: onConflict.lastInsertIdColumn })} = LAST_INSERT_ID(${dialect.quoteIdent({ name: onConflict.lastInsertIdColumn })})`;\n text += ` ON DUPLICATE KEY UPDATE ${assignments}${trick}`;\n }\n }\n }\n\n const returning = applyReturning({ dialect, requested: statement.returning });\n return { text: text + returning.suffix, values: collector.values, returning: returning.status };\n}\n\n// ─── UPDATE ───────────────────────────────────────────────────────\n\nfunction renderUpdate(params: {\n dialect: SqlDialect;\n statement: UpdateStatement;\n collector: ParamCollector;\n}): RenderedQuery {\n const { dialect, statement, collector } = params;\n\n const assignments = Object.entries(statement.set);\n if (assignments.length === 0) {\n throw internalError({ message: \"update must set at least one column\" });\n }\n const setSql = renderAssignments({ dialect, entries: assignments, collector });\n let text = `UPDATE ${renderTable(dialect, statement.table)} SET ${setSql}`;\n\n if (statement.where !== undefined) {\n text += ` WHERE ${renderExpr({ dialect, expr: statement.where, collector })}`;\n }\n\n const returning = applyReturning({ dialect, requested: statement.returning });\n return { text: text + returning.suffix, values: collector.values, returning: returning.status };\n}\n\n// ─── Assignments (SET / DO UPDATE SET) ────────────────────────────\n\n/**\n * `SET` assignments, shared by UPDATE and the upsert update arm.\n *\n * `selfRef` (the quoted target table) qualifies the READ side of an operation\n * that reads the column it writes — required inside `ON CONFLICT DO UPDATE`,\n * where a bare reference is ambiguous with `excluded` on postgres. The write\n * side is never qualified: `SET \"t\".\"col\" = …` is a syntax error everywhere.\n * A plain UPDATE passes no `selfRef` — it has no second relation in scope.\n */\nfunction renderAssignments(params: {\n dialect: SqlDialect;\n entries: readonly (readonly [string, unknown])[];\n collector: ParamCollector;\n selfRef?: string;\n}): string {\n const { dialect, entries, collector, selfRef } = params;\n return entries\n .map(([name, value]) => {\n const column = dialect.quoteIdent({ name });\n const read = selfRef === undefined ? column : `${selfRef}.${column}`;\n // Json cell: same param-type pinning as the VALUES cells above.\n if (isJsonParamCell(value)) {\n return `${column} = ${collector.add(value.text)}${dialect.jsonParamCast}`;\n }\n if (isSetOperation(value)) {\n return `${column} = ${read} ${SET_OPERATION_SQL[value.__op]} ${collector.add(value.value)}`;\n }\n if (isListSetOperation(value)) {\n assertScalarArrays(dialect, 'the scalar-list update operation \"push\"');\n if (value.__listOp === \"append\") {\n return `${column} = array_append(${read}, ${collector.add(value.value)})`;\n }\n return `${column} = ${read} || ${collector.add(value.value)}`;\n }\n return `${column} = ${collector.add(value)}`;\n })\n .join(\", \");\n}\n\n// ─── DELETE ───────────────────────────────────────────────────────\n\nfunction renderDelete(params: {\n dialect: SqlDialect;\n statement: DeleteStatement;\n collector: ParamCollector;\n}): RenderedQuery {\n const { dialect, statement, collector } = params;\n\n let text = `DELETE FROM ${renderTable(dialect, statement.table)}`;\n if (statement.where !== undefined) {\n text += ` WHERE ${renderExpr({ dialect, expr: statement.where, collector })}`;\n }\n\n const returning = applyReturning({ dialect, requested: statement.returning });\n return { text: text + returning.suffix, values: collector.values, returning: returning.status };\n}\n",
12
+ "/**\n * Statement renderer: SQL AST × dialect → { text, values, returning }.\n *\n * The shared grammar lives here; every dialect divergence goes through an\n * explicit SqlDialect strategy field. Malformed ASTs throw VIBE_INTERNAL —\n * the AST is built by VibeORM code, so a bad shape is always our bug.\n */\n\nimport { internalError, unsupportedCapability } from \"@vibeorm/schema\";\nimport type { SqlFragmentSpec } from \"@vibeorm/schema\";\nimport type { ColRef, OrderTerm, SqlStatement, SqlExpr, TableRef } from \"./ast.ts\";\nimport type {\n AggFn,\n AggRef,\n DeleteStatement,\n InsertStatement,\n LateralJoin,\n SelectExpr,\n SelectStatement,\n SetOperator,\n UpdateStatement,\n} from \"./ast.ts\";\nimport { isDbNowMarker, isJsonParamCell, isListSetOperation, isSetOperation, isSqlDefaultCell } from \"./ast.ts\";\nimport type { SqlDialect } from \"./dialect.ts\";\nimport { containsPattern, endsWithPattern, startsWithPattern, strictMatchPattern } from \"./like.ts\";\nimport { ParamCollector } from \"./params.ts\";\n\n// ─── Result shape ─────────────────────────────────────────────────\n\nexport type RenderedQuery = {\n readonly text: string;\n readonly values: unknown[];\n /**\n * RETURNING status: \"native\" (rendered), \"omitted\" (requested but the dialect\n * lacks it — caller must re-select), \"none\" (not requested).\n */\n readonly returning: \"native\" | \"omitted\" | \"none\";\n};\n\n// ─── Entry point ──────────────────────────────────────────────────\n\nexport function renderStatement(params: { dialect: SqlDialect; statement: SqlStatement }): RenderedQuery {\n const { dialect, statement } = params;\n const collector = new ParamCollector(dialect);\n switch (statement.kind) {\n case \"select\":\n return renderSelect({ dialect, statement, collector });\n case \"insert\":\n return renderInsert({ dialect, statement, collector });\n case \"update\":\n return renderUpdate({ dialect, statement, collector });\n case \"delete\":\n return renderDelete({ dialect, statement, collector });\n }\n}\n\n// ─── Shared pieces ────────────────────────────────────────────────\n\nfunction quoteCol(dialect: SqlDialect, column: ColRef): string {\n const name = dialect.quoteIdent({ name: column.name });\n const ref = column.table === undefined ? name : `${dialect.quoteIdent({ name: column.table })}.${name}`;\n // B4: sqlite Decimal compare/order/aggregate sites read the TEXT column as\n // REAL — the builder sets this only there, never on projections.\n if (column.castReal === true) {\n if (dialect.name !== \"sqlite\") {\n throw internalError({ message: \"ColRef.castReal is a sqlite Decimal construct\" });\n }\n return `CAST(${ref} AS REAL)`;\n }\n return ref;\n}\n\n/**\n * Projection rendering: a plain reference, or its B3 wire transform\n * (`\"col\"::text AS \"col\"` / `encode(\"col\", 'base64') AS \"col\"`) — postgres\n * lateral subselects only; any other dialect reaching one is a builder bug.\n */\nfunction quoteProjection(dialect: SqlDialect, column: ColRef): string {\n if (column.transform === undefined) {\n const base = quoteCol(dialect, column);\n if (column.alias === undefined) return base;\n return `${base} AS ${dialect.quoteIdent({ name: column.alias })}`;\n }\n if (dialect.name !== \"postgres\") {\n throw internalError({ message: \"ColRef.transform is a postgres lateral-join construct\" });\n }\n const ref = quoteCol(dialect, column);\n const alias = dialect.quoteIdent({ name: column.name });\n if (column.transform === \"castText\") return `${ref}::text AS ${alias}`;\n return `encode(${ref}, 'base64') AS ${alias}`;\n}\n\nfunction renderTable(dialect: SqlDialect, table: TableRef): string {\n const name = dialect.quoteIdent({ name: table.name });\n if (table.alias === undefined) return name;\n return `${name} AS ${dialect.quoteIdent({ name: table.alias })}`;\n}\n\nfunction assertCount(value: number, what: string): void {\n if (!Number.isSafeInteger(value) || value < 0) {\n throw internalError({ message: `${what} must be a non-negative integer, got ${value}` });\n }\n}\n\nconst COMPARISON_SQL: Readonly<Record<string, string>> = {\n eq: \"=\",\n ne: \"<>\",\n gt: \">\",\n gte: \">=\",\n lt: \"<\",\n lte: \"<=\",\n};\n\n/**\n * Atomic SET arithmetic. `divide` is plain `/`: integer columns therefore\n * follow each dialect's own integer-division rule (pg/sqlite truncate, mysql\n * promotes to decimal) — pinned by the update-atomic-ops catalog case.\n */\nconst SET_OPERATION_SQL: Readonly<Record<SetOperator, string>> = {\n increment: \"+\",\n decrement: \"-\",\n multiply: \"*\",\n divide: \"/\",\n};\n\nconst AGG_FN_SQL: Readonly<Record<AggFn, string>> = {\n count: \"COUNT\",\n avg: \"AVG\",\n sum: \"SUM\",\n min: \"MIN\",\n max: \"MAX\",\n};\n\n/** `COUNT(*)` / `FN(\"col\")` — shared by projections, HAVING and ORDER BY. */\nfunction renderAggRef(dialect: SqlDialect, agg: AggRef): string {\n if (agg.fn === \"countAll\") return \"COUNT(*)\";\n return `${AGG_FN_SQL[agg.fn]}(${quoteCol(dialect, agg.column)})`;\n}\n\nfunction assertScalarArrays(dialect: SqlDialect, feature: string): void {\n if (dialect.capabilities.scalarArrays) return;\n throw unsupportedCapability({\n dialect: dialect.name,\n feature,\n hint: \"only postgres has native array columns — model the list as a related table instead\",\n });\n}\n\n// ─── Expressions ──────────────────────────────────────────────────\n\n/**\n * Render one boolean expression into SQL text, collecting parameters into the\n * shared collector. Public so extension delegates can AND user `where` trees\n * (compiled by the runtime) into their own statements.\n */\nexport function renderExpr(params: { dialect: SqlDialect; expr: SqlExpr; collector: ParamCollector }): string {\n const { dialect, expr, collector } = params;\n\n switch (expr.kind) {\n case \"cmp\": {\n const op = COMPARISON_SQL[expr.op];\n if (op === undefined) {\n throw internalError({ message: `unknown comparison operator \"${expr.op}\"` });\n }\n // Database-clock operand: the dialect's now() expression, never a param.\n if (isDbNowMarker(expr.value)) {\n return `${quoteCol(dialect, expr.column)} ${op} ${dialect.renderDbNow({ offsetSeconds: expr.value.offsetSeconds, collector })}`;\n }\n return `${quoteCol(dialect, expr.column)} ${op} ${collector.add(expr.value)}`;\n }\n\n case \"cmpCol\": {\n const op = COMPARISON_SQL[expr.op];\n if (op === undefined) {\n throw internalError({ message: `unknown comparison operator \"${expr.op}\"` });\n }\n return `${quoteCol(dialect, expr.left)} ${op} ${quoteCol(dialect, expr.right)}`;\n }\n\n case \"isNull\":\n return `${quoteCol(dialect, expr.column)} IS ${expr.negate === true ? \"NOT NULL\" : \"NULL\"}`;\n\n case \"inArray\": {\n if (expr.values.length === 0) {\n // Empty IN matches nothing; empty NOT IN matches everything.\n return expr.negate === true ? \"1 = 1\" : \"1 = 0\";\n }\n const column = quoteCol(dialect, expr.column);\n if (dialect.inArrayStrategy === \"any\") {\n const base = `${column} = ANY(${collector.add([...expr.values])})`;\n return expr.negate === true ? `NOT (${base})` : base;\n }\n const placeholders = collector.addMany(expr.values);\n return `${column} ${expr.negate === true ? \"NOT IN\" : \"IN\"} (${placeholders.join(\", \")})`;\n }\n\n case \"like\": {\n const column = quoteCol(dialect, expr.column);\n const placeholder = collector.add(expr.pattern);\n let base: string;\n if (expr.insensitive === true) {\n base =\n dialect.insensitiveLike === \"ilike\"\n ? `${column} ILIKE ${placeholder}`\n : `LOWER(${column}) LIKE LOWER(${placeholder})`;\n } else {\n base = `${column} LIKE ${placeholder}`;\n }\n if (dialect.likeEscapeClause !== null) {\n base = `${base}${dialect.likeEscapeClause}`;\n }\n return expr.negate === true ? `NOT (${base})` : base;\n }\n\n case \"strictMatch\": {\n const column = quoteCol(dialect, expr.column);\n let base: string;\n if (expr.op === \"equals\") {\n // pg and sqlite `=` are already byte-exact; only mysql's `_ci`\n // collations fold equality and need the BINARY cast.\n base =\n dialect.strictMatchStrategy === \"binary\"\n ? `${column} = CAST(${collector.add(expr.value)} AS BINARY)`\n : `${column} = ${collector.add(expr.value)}`;\n } else {\n const pattern = strictMatchPattern({\n strategy: dialect.strictMatchStrategy,\n op: expr.op,\n value: expr.value,\n });\n if (dialect.strictMatchStrategy === \"glob\") {\n base = `${column} GLOB ${collector.add(pattern)}`;\n } else {\n const placeholder = collector.add(pattern);\n base =\n dialect.strictMatchStrategy === \"binary\"\n ? `${column} LIKE CAST(${placeholder} AS BINARY)`\n : `${column} LIKE ${placeholder}`;\n if (dialect.likeEscapeClause !== null) base = `${base}${dialect.likeEscapeClause}`;\n }\n }\n return expr.negate === true ? `NOT (${base})` : base;\n }\n\n case \"and\":\n case \"or\": {\n if (expr.operands.length === 0) {\n // Neutral elements: empty AND is always-true, empty OR always-false.\n return expr.kind === \"and\" ? \"1 = 1\" : \"1 = 0\";\n }\n if (expr.operands.length === 1) {\n return renderExpr({ dialect, expr: expr.operands[0]!, collector });\n }\n const joiner = expr.kind === \"and\" ? \" AND \" : \" OR \";\n const rendered = expr.operands.map((operand) => renderExpr({ dialect, expr: operand, collector }));\n return `(${rendered.join(joiner)})`;\n }\n\n case \"not\":\n return `NOT (${renderExpr({ dialect, expr: expr.operand, collector })})`;\n\n case \"aggCmp\": {\n const op = COMPARISON_SQL[expr.op];\n if (op === undefined) {\n throw internalError({ message: `unknown comparison operator \"${expr.op}\"` });\n }\n return `${renderAggRef(dialect, expr.agg)} ${op} ${collector.add(expr.value)}`;\n }\n\n case \"arrayHas\": {\n assertScalarArrays(dialect, \"the scalar-list filter \\\"has\\\"\");\n const base = `${collector.add(expr.value)} = ANY(${quoteCol(dialect, expr.column)})`;\n return expr.negate === true ? `NOT (${base})` : base;\n }\n\n case \"arrayContainsAll\": {\n assertScalarArrays(dialect, \"the scalar-list filter \\\"hasEvery\\\"\");\n return `${quoteCol(dialect, expr.column)} @> ${collector.add([...expr.values])}`;\n }\n\n case \"arrayOverlaps\": {\n assertScalarArrays(dialect, \"the scalar-list filter \\\"hasSome\\\"\");\n return `${quoteCol(dialect, expr.column)} && ${collector.add([...expr.values])}`;\n }\n\n case \"arrayIsEmpty\": {\n assertScalarArrays(dialect, \"the scalar-list filter \\\"isEmpty\\\"\");\n // v1 semantics kept: array_length of NULL and of '{}' are both NULL, so\n // `isEmpty: true` matches NULL **and** empty lists.\n const column = quoteCol(dialect, expr.column);\n return `array_length(${column}, 1) IS ${expr.empty ? \"NULL\" : \"NOT NULL\"}`;\n }\n\n case \"jsonFilter\":\n return renderJsonFilter({ dialect, expr, collector });\n\n case \"exists\": {\n // The subquery shares the statement's collector, so its parameters land\n // in the single sequence exactly where they appear in the text.\n const sub = renderSelect({ dialect, statement: expr.select, collector });\n return `${expr.negate === true ? \"NOT \" : \"\"}EXISTS (${sub.text})`;\n }\n\n case \"fragment\":\n return renderFragment({ dialect, fragment: expr.fragment, collector });\n\n case \"raw\":\n return expr.text;\n }\n}\n\n// ─── Bound fragments (extension SQL plane) ───────────────────\n\n/**\n * Render a neutral bound fragment (extensions.md §3): literal text verbatim,\n * `{ param }` through the collector (single placeholder sequence), `{ ident }`\n * paths through dialect.quoteIdent. Exported so extension delegates can build\n * full statements sharing one collector with core-compiled WHERE trees.\n */\nexport function renderFragment(params: {\n dialect: SqlDialect;\n fragment: SqlFragmentSpec;\n collector: ParamCollector;\n}): string {\n const { dialect, fragment, collector } = params;\n let text = \"\";\n for (const part of fragment.parts) {\n if (typeof part === \"string\") {\n text += part;\n } else if (\"param\" in part) {\n text += collector.add(part.param);\n } else {\n text += part.ident.map((name) => dialect.quoteIdent({ name })).join(\".\");\n }\n }\n return text;\n}\n\n// ─── JSON path filters ─────────────────────────────────────────────\n\n/** `$.a.b[0]` path string for sqlite/mysql — always bound, never spliced. */\nfunction jsonPathString(path: readonly (string | number)[]): string {\n let out = \"$\";\n for (const segment of path) {\n if (typeof segment === \"number\") {\n out += `[${segment}]`;\n } else if (/^[A-Za-z_][A-Za-z0-9_]*$/.test(segment)) {\n out += `.${segment}`;\n } else {\n out += `.\"${segment.replaceAll('\"', '\\\\\"')}\"`;\n }\n }\n return out;\n}\n\ntype JsonFilterExpr = Extract<SqlExpr, { kind: \"jsonFilter\" }>;\n\nfunction jsonStringPattern(params: { expr: JsonFilterExpr }): string {\n const { expr } = params;\n if (typeof expr.value !== \"string\") {\n throw internalError({ message: `json ${expr.op} expects a string operand` });\n }\n if (expr.op === \"string_contains\") return containsPattern({ raw: expr.value });\n if (expr.op === \"string_starts_with\") return startsWithPattern({ raw: expr.value });\n return endsWithPattern({ raw: expr.value });\n}\n\n/** Case-[in]sensitive LIKE over an extracted-text expression, per dialect. */\nfunction renderJsonLike(params: {\n dialect: SqlDialect;\n target: string;\n expr: JsonFilterExpr;\n collector: ParamCollector;\n}): string {\n const { dialect, target, expr, collector } = params;\n const placeholder = collector.add(jsonStringPattern({ expr }));\n let base: string;\n if (expr.insensitive === true) {\n base =\n dialect.insensitiveLike === \"ilike\"\n ? `${target} ILIKE ${placeholder}`\n : `LOWER(${target}) LIKE LOWER(${placeholder})`;\n } else {\n base = `${target} LIKE ${placeholder}`;\n }\n if (dialect.likeEscapeClause !== null) base = `${base}${dialect.likeEscapeClause}`;\n return expr.negate === true ? `NOT (${base})` : base;\n}\n\n/**\n * One JSON path predicate, per dialect strategy. The path is BOUND: a `text[]`\n * parameter on postgres (cast so string-literal array forms work too), a\n * `$.a.b` path string elsewhere. Values bind as JSON text for json/jsonb\n * comparisons and as LIKE patterns for the string ops.\n */\nfunction renderJsonFilter(params: {\n dialect: SqlDialect;\n expr: JsonFilterExpr;\n collector: ParamCollector;\n}): string {\n const { dialect, expr, collector } = params;\n if (!dialect.supportedJsonOps.includes(expr.op)) {\n throw unsupportedCapability({\n dialect: dialect.name,\n feature: `the json filter \"${expr.op}\"`,\n hint: `this dialect can express: ${dialect.supportedJsonOps.join(\", \")}`,\n });\n }\n const cmp = expr.negate === true ? \"<>\" : \"=\";\n\n if (dialect.jsonPathMode === \"operators\") {\n const column = quoteCol(dialect, expr.column);\n const pathParam = `${collector.add(expr.path.map(String))}::text[]`;\n switch (expr.op) {\n case \"equals\":\n return `(${column} #> ${pathParam}) ${cmp} ${collector.add(JSON.stringify(expr.value))}${dialect.jsonParamCast}`;\n case \"string_contains\":\n case \"string_starts_with\":\n case \"string_ends_with\":\n return renderJsonLike({ dialect, target: `(${column} #>> ${pathParam})`, expr, collector });\n case \"array_contains\":\n return `(${column} #> ${pathParam}) @> ${collector.add(JSON.stringify(expr.value))}${dialect.jsonParamCast}`;\n case \"array_starts_with\":\n return `(${column} #> ${pathParam}) -> 0 = ${collector.add(JSON.stringify(expr.value))}${dialect.jsonParamCast}`;\n case \"array_ends_with\":\n return `(${column} #> ${pathParam}) -> -1 = ${collector.add(JSON.stringify(expr.value))}${dialect.jsonParamCast}`;\n }\n }\n\n if (dialect.jsonPathMode === \"sqliteExtract\") {\n const column = quoteCol(dialect, expr.column);\n // Compare an extracted JSON value the way `equals` does: booleans surface\n // as 0/1, objects/arrays as canonical minified JSON text (key order\n // matters, documented in the catalog), scalars as SQL values.\n const compareExtracted = (target: string, value: unknown): string => {\n if (typeof value === \"boolean\") {\n return `${target} ${cmp} ${collector.add(value ? 1 : 0)}`;\n }\n if (typeof value === \"object\" && value !== null) {\n return `${target} ${cmp} json(${collector.add(JSON.stringify(value))})`;\n }\n return `${target} ${cmp} ${collector.add(value)}`;\n };\n switch (expr.op) {\n case \"equals\":\n return compareExtracted(`json_extract(${column}, ${collector.add(jsonPathString(expr.path))})`, expr.value);\n case \"string_contains\":\n case \"string_starts_with\":\n case \"string_ends_with\": {\n const target = `json_extract(${column}, ${collector.add(jsonPathString(expr.path))})`;\n return renderJsonLike({ dialect, target, expr, collector });\n }\n case \"array_starts_with\":\n case \"array_ends_with\": {\n // Edge-element access: `$[0]` / `$[#-1]` path elements (sqlite ≥3.31;\n // bun:sqlite bundles far newer) — N6/board #21.\n const edge = expr.op === \"array_starts_with\" ? \"[0]\" : \"[#-1]\";\n return compareExtracted(\n `json_extract(${column}, ${collector.add(`${jsonPathString(expr.path)}${edge}`)})`,\n expr.value,\n );\n }\n case \"array_contains\": {\n // Scalar-needle containment via json_each() EXISTS — one EXISTS per\n // element, ANDed (jsonb `@>` semantics for scalar members). Deep\n // structural containment (object/array members) has no cheap faithful\n // sqlite form and stays refused; JSON null members compare through\n // json_each's 'null' type tag, not SQL NULL, so they are refused too.\n //\n // Haystack type guard (wave-C review): json_each() over a path holding\n // a SCALAR yields one row carrying that scalar, so an unguarded EXISTS\n // matched `{ tags: \"a\" }` against needle `[\"a\"]` where postgres (`@>`\n // with an array needle) and mysql (JSON_CONTAINS against an array\n // literal) are false. json_type() is NULL for a missing path, so\n // missing paths and NULL columns stay non-matches — and an empty\n // needle reduces to the guard alone: contained in every ARRAY (pg's\n // `@> '[]'` truth) and in nothing else.\n const guard = `json_type(${column}, ${collector.add(jsonPathString(expr.path))}) = 'array'`;\n const elements = Array.isArray(expr.value) ? expr.value : [expr.value];\n const tests = elements.map((element) => {\n if (element === null || (typeof element === \"object\" && element !== null)) {\n throw unsupportedCapability({\n dialect: dialect.name,\n feature: \"json array_contains with object/array/null elements\",\n hint: \"sqlite expresses scalar-element containment only — deep structural containment needs postgres or mysql\",\n });\n }\n const bound = typeof element === \"boolean\" ? (element ? 1 : 0) : element;\n return `EXISTS (SELECT 1 FROM json_each(${column}, ${collector.add(jsonPathString(expr.path))}) WHERE ${dialect.quoteIdent({ name: \"json_each\" })}.${dialect.quoteIdent({ name: \"value\" })} = ${collector.add(bound)})`;\n });\n return tests.length === 0 ? guard : `(${[guard, ...tests].join(\" AND \")})`;\n }\n default:\n throw internalError({ message: `json op \"${expr.op}\" leaked past supportedJsonOps on sqlite` });\n }\n }\n\n // mysqlExtract\n const column = quoteCol(dialect, expr.column);\n const pathString = jsonPathString(expr.path);\n switch (expr.op) {\n case \"equals\":\n return `JSON_EXTRACT(${column}, ${collector.add(pathString)}) ${cmp} CAST(${collector.add(JSON.stringify(expr.value))} AS JSON)`;\n case \"string_contains\":\n case \"string_starts_with\":\n case \"string_ends_with\": {\n const target = `JSON_UNQUOTE(JSON_EXTRACT(${column}, ${collector.add(pathString)}))`;\n return renderJsonLike({ dialect, target, expr, collector });\n }\n case \"array_contains\":\n return `JSON_CONTAINS(JSON_EXTRACT(${column}, ${collector.add(pathString)}), CAST(${collector.add(JSON.stringify(expr.value))} AS JSON))`;\n case \"array_starts_with\":\n return `JSON_EXTRACT(${column}, ${collector.add(`${pathString}[0]`)}) ${cmp} CAST(${collector.add(JSON.stringify(expr.value))} AS JSON)`;\n case \"array_ends_with\":\n return `JSON_EXTRACT(${column}, ${collector.add(`${pathString}[last]`)}) ${cmp} CAST(${collector.add(JSON.stringify(expr.value))} AS JSON)`;\n }\n}\n\n// ─── Ordering ─────────────────────────────────────────────────────\n\nfunction renderOrderTerm(params: { dialect: SqlDialect; term: OrderTerm; collector: ParamCollector }): string {\n const { dialect, term, collector } = params;\n if (\"agg\" in term) {\n return `${renderAggRef(dialect, term.agg)} ${term.direction === \"asc\" ? \"ASC\" : \"DESC\"}`;\n }\n if (\"select\" in term) {\n // Relation orderBy: a correlated scalar subquery — its parameters merge\n // into the shared sequence exactly where they appear in the text.\n const sub = renderSelect({ dialect, statement: term.select, collector });\n return `(${sub.text}) ${term.direction === \"asc\" ? \"ASC\" : \"DESC\"}`;\n }\n const column = quoteCol(dialect, term.column);\n const direction = term.direction === \"asc\" ? \"ASC\" : \"DESC\";\n if (term.nulls === undefined) {\n return `${column} ${direction}`;\n }\n if (dialect.orderByNullsMode === \"native\") {\n return `${column} ${direction} NULLS ${term.nulls === \"first\" ? \"FIRST\" : \"LAST\"}`;\n }\n // Emulation (mysql): the engine's native order already places NULLs FIRST on\n // ASC and LAST on DESC — those pairings render the bare term (the redundant\n // boolean pre-term cost a per-row evaluation and could defeat index-order\n // scans, #14). Only the diverging pairings need the `IS NULL` pre-term:\n // false(0) sorts first, so plain `IS NULL` pushes nulls last and\n // `IS NULL DESC` pulls them first.\n if ((term.nulls === \"first\") === (term.direction === \"asc\")) {\n return `${column} ${direction}`;\n }\n const nullsTerm = term.nulls === \"first\" ? `${column} IS NULL DESC` : `${column} IS NULL`;\n return `${nullsTerm}, ${column} ${direction}`;\n}\n\n// ─── Projections ──────────────────────────────────────────────────\n\nfunction renderSelectExpr(params: { dialect: SqlDialect; expr: SelectExpr }): string {\n const { dialect, expr } = params;\n if (expr.kind === \"one\") return \"1\";\n const alias = expr.alias === undefined ? \"\" : ` AS ${dialect.quoteIdent({ name: expr.alias })}`;\n return `COUNT(*)${alias}`;\n}\n\n// ─── Lateral JSON joins ───────────────────────────────────\n\n/**\n * `LEFT JOIN LATERAL (… to_jsonb …) AS alias ON true`. Postgres-only SQL by\n * design — the runtime gates the \"join\" strategy on `capabilities.lateralJoin`\n * at build time, and this renderer refuses too (dialect honesty, rule 4).\n */\nfunction renderLateralJoin(params: {\n dialect: SqlDialect;\n join: LateralJoin;\n collector: ParamCollector;\n}): string {\n const { dialect, join, collector } = params;\n const inner = renderSelect({ dialect, statement: join.select, collector });\n const columnAlias = dialect.quoteIdent({ name: join.columnAlias });\n const subAlias = dialect.quoteIdent({ name: \"__sub\" });\n // N2 (SQL review): jsonb_agg over a subquery only \"usually\" preserves the\n // subquery's order — pin it with an explicit ORDER BY inside the aggregate\n // (the subquery keeps its own ORDER BY for LIMIT). Only column terms that\n // are PROJECTED (and untransformed — a B3 ::text cast would re-sort\n // lexicographically) can be referenced through `__sub`; anything else keeps\n // the old behavior.\n let aggOrder = \"\";\n if (join.agg === \"jsonArray\" && join.select.orderBy !== undefined && join.select.orderBy.length > 0) {\n const projected = new Set(\n join.select.columns\n .filter((column) => column.transform === undefined && column.castReal !== true)\n .map((column) => column.name),\n );\n const terms = join.select.orderBy;\n const columnTerms = terms.filter(\n (term): term is Extract<OrderTerm, { column: ColRef }> => !(\"agg\" in term),\n );\n if (columnTerms.length === terms.length && columnTerms.every((term) => projected.has(term.column.name))) {\n const rendered = columnTerms.map((term) =>\n renderOrderTerm({ dialect, term: { ...term, column: { table: \"__sub\", name: term.column.name } }, collector }),\n );\n aggOrder = ` ORDER BY ${rendered.join(\", \")}`;\n }\n }\n const projection =\n join.agg === \"jsonArray\"\n ? `COALESCE(jsonb_agg(to_jsonb(${subAlias}.*)${aggOrder}), '[]'::jsonb) AS ${columnAlias}`\n : `to_jsonb(${subAlias}.*) AS ${columnAlias}`;\n const alias = dialect.quoteIdent({ name: join.alias });\n return `LEFT JOIN LATERAL (SELECT ${projection} FROM (${inner.text}) AS ${subAlias}) AS ${alias} ON true`;\n}\n\n// ─── RETURNING ────────────────────────────────────────────────────\n\nfunction applyReturning(params: {\n dialect: SqlDialect;\n requested: readonly string[] | undefined;\n}): { suffix: string; status: \"native\" | \"omitted\" | \"none\" } {\n const { dialect, requested } = params;\n if (requested === undefined || requested.length === 0) {\n return { suffix: \"\", status: \"none\" };\n }\n if (!dialect.capabilities.returning) {\n return { suffix: \"\", status: \"omitted\" };\n }\n const columns = requested.map((name) => dialect.quoteIdent({ name })).join(\", \");\n return { suffix: ` RETURNING ${columns}`, status: \"native\" };\n}\n\n// ─── SELECT ───────────────────────────────────────────────────────\n\nfunction renderSelect(params: {\n dialect: SqlDialect;\n statement: SelectStatement;\n collector: ParamCollector;\n}): RenderedQuery {\n const { dialect, statement, collector } = params;\n\n if (statement.selectExpr !== undefined && statement.columns.length > 0 && statement.selectExpr.kind !== \"countAll\") {\n throw internalError({ message: \"only countAll can combine with a column list\" });\n }\n if (\n statement.selectExpr !== undefined &&\n statement.aggregates !== undefined &&\n statement.aggregates.length > 0\n ) {\n throw internalError({ message: \"selectExpr and aggregates cannot combine\" });\n }\n const columnList = statement.columns.map((column) => quoteProjection(dialect, column));\n if (statement.selectExpr !== undefined) {\n columnList.push(renderSelectExpr({ dialect, expr: statement.selectExpr }));\n }\n if (statement.aggregates !== undefined) {\n for (const selection of statement.aggregates) {\n columnList.push(`${renderAggRef(dialect, selection.agg)} AS ${dialect.quoteIdent({ name: selection.alias })}`);\n }\n }\n if (statement.rowNumber !== undefined) {\n const rowNumber = statement.rowNumber;\n if (rowNumber.partitionBy.length === 0) {\n throw internalError({ message: \"rowNumber needs at least one partition column\" });\n }\n const partition = rowNumber.partitionBy.map((column) => quoteCol(dialect, column)).join(\", \");\n const order =\n rowNumber.orderBy.length === 0\n ? \"\"\n : ` ORDER BY ${rowNumber.orderBy.map((term) => renderOrderTerm({ dialect, term, collector })).join(\", \")}`;\n columnList.push(\n `ROW_NUMBER() OVER (PARTITION BY ${partition}${order}) AS ${dialect.quoteIdent({ name: rowNumber.alias })}`,\n );\n }\n let distinctPrefix = \"\";\n if (statement.distinctOn !== undefined && statement.distinctOn.length > 0) {\n if (!dialect.capabilities.distinctOn) {\n throw unsupportedCapability({\n dialect: dialect.name,\n feature: \"SELECT DISTINCT ON\",\n hint: \"postgres-only — the runtime emulates distinct client-side on this dialect\",\n });\n }\n distinctPrefix = `DISTINCT ON (${statement.distinctOn.map((column) => quoteCol(dialect, column)).join(\", \")}) `;\n }\n const columns = columnList.length === 0 ? \"*\" : columnList.join(\", \");\n\n let from: string;\n if (statement.fromSelect !== undefined) {\n if (statement.table.alias !== undefined) {\n throw internalError({ message: \"fromSelect uses table.name as the subquery alias — table.alias must be unset\" });\n }\n // The subquery renders before WHERE/ORDER BY, so its parameters land in\n // the shared sequence exactly where they appear in the text.\n const inner = renderSelect({ dialect, statement: statement.fromSelect, collector });\n from = `(${inner.text}) AS ${dialect.quoteIdent({ name: statement.table.name })}`;\n } else {\n from = renderTable(dialect, statement.table);\n }\n let text = `SELECT ${distinctPrefix}${columns} FROM ${from}`;\n\n if (statement.innerJoins !== undefined && statement.innerJoins.length > 0) {\n for (const join of statement.innerJoins) {\n if (join.on.length === 0) {\n throw internalError({ message: \"inner join needs at least one ON pair\" });\n }\n const on = join.on\n .map((pair) => `${quoteCol(dialect, pair.left)} = ${quoteCol(dialect, pair.right)}`)\n .join(\" AND \");\n text += ` INNER JOIN ${renderTable(dialect, join.table)} ON ${on}`;\n }\n }\n\n if (statement.lateralJoins !== undefined && statement.lateralJoins.length > 0) {\n if (!dialect.capabilities.lateralJoin) {\n throw unsupportedCapability({\n dialect: dialect.name,\n feature: \"LATERAL JOIN relation loading\",\n hint: 'use the portable \"query\" relation strategy on this dialect',\n });\n }\n for (const join of statement.lateralJoins) {\n text += ` ${renderLateralJoin({ dialect, join, collector })}`;\n }\n }\n\n if (statement.where !== undefined) {\n text += ` WHERE ${renderExpr({ dialect, expr: statement.where, collector })}`;\n }\n if (statement.groupBy !== undefined && statement.groupBy.length > 0) {\n text += ` GROUP BY ${statement.groupBy.map((column) => quoteCol(dialect, column)).join(\", \")}`;\n }\n if (statement.having !== undefined) {\n text += ` HAVING ${renderExpr({ dialect, expr: statement.having, collector })}`;\n }\n if (statement.orderBy !== undefined && statement.orderBy.length > 0) {\n const terms = statement.orderBy.map((term) => renderOrderTerm({ dialect, term, collector }));\n text += ` ORDER BY ${terms.join(\", \")}`;\n }\n\n if (statement.limit !== undefined) {\n assertCount(statement.limit, \"limit\");\n text += ` LIMIT ${statement.limit}`;\n }\n if (statement.offset !== undefined) {\n assertCount(statement.offset, \"offset\");\n if (statement.limit === undefined && dialect.offsetRequiresLimit !== null) {\n text += ` LIMIT ${dialect.offsetRequiresLimit.limitText}`;\n }\n text += ` OFFSET ${statement.offset}`;\n }\n if (statement.lockForUpdate === true && dialect.selectForUpdate !== null) {\n text += dialect.selectForUpdate;\n }\n\n return { text, values: collector.values, returning: \"none\" };\n}\n\n// ─── INSERT (incl. upsert) ────────────────────────────────────────\n\nfunction renderInsert(params: {\n dialect: SqlDialect;\n statement: InsertStatement;\n collector: ParamCollector;\n}): RenderedQuery {\n const { dialect, statement, collector } = params;\n\n if (statement.columns.length === 0) {\n throw internalError({ message: \"insert requires at least one column\" });\n }\n if (statement.rows.length === 0) {\n throw internalError({ message: \"insert requires at least one row\" });\n }\n for (const row of statement.rows) {\n if (row.length !== statement.columns.length) {\n throw internalError({\n message: `insert row has ${row.length} values but ${statement.columns.length} columns`,\n });\n }\n }\n\n const onConflict = statement.onConflict;\n const skipConflicts = onConflict !== undefined && \"doNothing\" in onConflict;\n const insertKeyword =\n skipConflicts && dialect.doNothingForm === \"insertIgnore\" ? \"INSERT IGNORE INTO\" : \"INSERT INTO\";\n\n const columnList = statement.columns.map((name) => dialect.quoteIdent({ name })).join(\", \");\n const rowsSql = statement.rows\n .map(\n (row) =>\n `(${row\n .map((value) => {\n // Json cell: the param's type is pinned (`$n::text::jsonb` on\n // postgres) so OID-typed drivers cannot double-encode the document.\n if (isJsonParamCell(value)) return `${collector.add(value.text)}${dialect.jsonParamCast}`;\n // Database-clock cell: the dialect's now() expression.\n if (isDbNowMarker(value)) {\n return dialect.renderDbNow({ offsetSeconds: value.offsetSeconds, collector });\n }\n if (!isSqlDefaultCell(value)) return collector.add(value);\n // M4: a heterogeneous createMany cell defers to the COLUMN default.\n if (!dialect.rowDefaultKeyword) {\n throw internalError({\n message: `${dialect.name} cannot render a per-row DEFAULT cell — rows must be grouped by column set`,\n });\n }\n return \"DEFAULT\";\n })\n .join(\", \")})`,\n )\n .join(\", \");\n let text = `${insertKeyword} ${renderTable(dialect, statement.table)} (${columnList}) VALUES ${rowsSql}`;\n\n if (onConflict !== undefined) {\n if (\"doNothing\" in onConflict) {\n if (dialect.doNothingForm === \"onConflictDoNothing\") {\n let target = \"\";\n if (onConflict.constraint !== undefined) {\n if (dialect.name !== \"postgres\") {\n throw unsupportedCapability({\n dialect: dialect.name,\n feature: \"a named-constraint conflict target (ON CONFLICT ON CONSTRAINT)\",\n hint: \"only postgres names constraints in conflict targets — use a column-list target\",\n });\n }\n target = ` ON CONSTRAINT ${dialect.quoteIdent({ name: onConflict.constraint })}`;\n } else if (onConflict.columns !== undefined && onConflict.columns.length > 0) {\n target = ` (${onConflict.columns.map((name) => dialect.quoteIdent({ name })).join(\", \")})`;\n if (onConflict.conflictWhere !== undefined) {\n // RAW predicate — the engines match it against the index's own\n // predicate structurally; parameters could never match (ast.ts).\n target += ` WHERE ${onConflict.conflictWhere}`;\n }\n }\n text += ` ON CONFLICT${target} DO NOTHING`;\n } else if (onConflict.constraint !== undefined || onConflict.conflictWhere !== undefined) {\n // INSERT IGNORE fires on ANY duplicate key. A bare column target\n // degrades to that documented wider skip; a REFINED target (named\n // constraint, partial-index predicate) must not silently widen —\n // the builder gates first, the renderer defends.\n throw unsupportedCapability({\n dialect: dialect.name,\n feature: \"a refined conflict target (constraint / partial-index predicate) on INSERT IGNORE\",\n hint: \"mysql skips on any duplicate key — drop the refinement or gate the call per dialect\",\n });\n }\n } else {\n const updates = Object.entries(onConflict.update);\n if (updates.length === 0) {\n throw internalError({ message: \"upsert update must set at least one column\" });\n }\n // The update arm's self-references MUST be table-qualified: inside\n // `ON CONFLICT … DO UPDATE SET`, postgres has BOTH the target row and\n // the `excluded` pseudo-relation in scope, so a bare `\"views\" + $n`\n // is rejected as ambiguous (SQLSTATE 42702). Sqlite and mysql accept\n // the qualified form with identical semantics (the pre-update row), so\n // one rule covers every dialect instead of a per-dialect divergence.\n const selfRef = dialect.quoteIdent({ name: statement.table.name });\n const assignments = renderAssignments({ dialect, entries: updates, collector, selfRef });\n if (dialect.upsertForm === \"onConflict\") {\n if (onConflict.lastInsertIdColumn !== undefined) {\n throw internalError({ message: \"lastInsertIdColumn is a mysql (onDuplicateKey) construct\" });\n }\n if (onConflict.constraint !== undefined && dialect.name !== \"postgres\") {\n throw unsupportedCapability({\n dialect: dialect.name,\n feature: \"a named-constraint conflict target (ON CONFLICT ON CONSTRAINT)\",\n hint: \"sqlite conflict targets are column lists — name the indexed columns instead\",\n });\n }\n const target =\n onConflict.constraint !== undefined\n ? ` ON CONSTRAINT ${dialect.quoteIdent({ name: onConflict.constraint })}`\n : ` (${onConflict.columns.map((name) => dialect.quoteIdent({ name })).join(\", \")})`;\n text += ` ON CONFLICT${target} DO UPDATE SET ${assignments}`;\n } else {\n if (onConflict.constraint !== undefined) {\n throw unsupportedCapability({\n dialect: dialect.name,\n feature: \"a named-constraint conflict target on ON DUPLICATE KEY UPDATE\",\n hint: \"mysql's ODKU fires on any duplicate key — no target can be named\",\n });\n }\n // B2: the update arm must record WHICH row it addressed — without this,\n // LAST_INSERT_ID() is stale after ODKU takes the update arm and the\n // read-back can resolve an unrelated row.\n const trick =\n onConflict.lastInsertIdColumn === undefined\n ? \"\"\n : `, ${dialect.quoteIdent({ name: onConflict.lastInsertIdColumn })} = LAST_INSERT_ID(${dialect.quoteIdent({ name: onConflict.lastInsertIdColumn })})`;\n text += ` ON DUPLICATE KEY UPDATE ${assignments}${trick}`;\n }\n }\n }\n\n const returning = applyReturning({ dialect, requested: statement.returning });\n return { text: text + returning.suffix, values: collector.values, returning: returning.status };\n}\n\n// ─── UPDATE ───────────────────────────────────────────────────────\n\nfunction renderUpdate(params: {\n dialect: SqlDialect;\n statement: UpdateStatement;\n collector: ParamCollector;\n}): RenderedQuery {\n const { dialect, statement, collector } = params;\n\n const assignments = Object.entries(statement.set);\n if (assignments.length === 0) {\n throw internalError({ message: \"update must set at least one column\" });\n }\n const setSql = renderAssignments({ dialect, entries: assignments, collector });\n let text = `UPDATE ${renderTable(dialect, statement.table)} SET ${setSql}`;\n\n if (statement.where !== undefined) {\n text += ` WHERE ${renderExpr({ dialect, expr: statement.where, collector })}`;\n }\n\n const returning = applyReturning({ dialect, requested: statement.returning });\n return { text: text + returning.suffix, values: collector.values, returning: returning.status };\n}\n\n// ─── Assignments (SET / DO UPDATE SET) ────────────────────────────\n\n/**\n * `SET` assignments, shared by UPDATE and the upsert update arm.\n *\n * `selfRef` (the quoted target table) qualifies the READ side of an operation\n * that reads the column it writes — required inside `ON CONFLICT DO UPDATE`,\n * where a bare reference is ambiguous with `excluded` on postgres. The write\n * side is never qualified: `SET \"t\".\"col\" = …` is a syntax error everywhere.\n * A plain UPDATE passes no `selfRef` — it has no second relation in scope.\n */\nfunction renderAssignments(params: {\n dialect: SqlDialect;\n entries: readonly (readonly [string, unknown])[];\n collector: ParamCollector;\n selfRef?: string;\n}): string {\n const { dialect, entries, collector, selfRef } = params;\n return entries\n .map(([name, value]) => {\n const column = dialect.quoteIdent({ name });\n const read = selfRef === undefined ? column : `${selfRef}.${column}`;\n // Json cell: same param-type pinning as the VALUES cells above.\n if (isJsonParamCell(value)) {\n return `${column} = ${collector.add(value.text)}${dialect.jsonParamCast}`;\n }\n if (isSetOperation(value)) {\n return `${column} = ${read} ${SET_OPERATION_SQL[value.__op]} ${collector.add(value.value)}`;\n }\n if (isDbNowMarker(value)) {\n return `${column} = ${dialect.renderDbNow({ offsetSeconds: value.offsetSeconds, collector })}`;\n }\n if (isListSetOperation(value)) {\n assertScalarArrays(dialect, 'the scalar-list update operation \"push\"');\n if (value.__listOp === \"append\") {\n return `${column} = array_append(${read}, ${collector.add(value.value)})`;\n }\n return `${column} = ${read} || ${collector.add(value.value)}`;\n }\n return `${column} = ${collector.add(value)}`;\n })\n .join(\", \");\n}\n\n// ─── DELETE ───────────────────────────────────────────────────────\n\nfunction renderDelete(params: {\n dialect: SqlDialect;\n statement: DeleteStatement;\n collector: ParamCollector;\n}): RenderedQuery {\n const { dialect, statement, collector } = params;\n\n let text = `DELETE FROM ${renderTable(dialect, statement.table)}`;\n if (statement.where !== undefined) {\n text += ` WHERE ${renderExpr({ dialect, expr: statement.where, collector })}`;\n }\n\n const returning = applyReturning({ dialect, requested: statement.returning });\n return { text: text + returning.suffix, values: collector.values, returning: returning.status };\n}\n",
13
13
  "/**\n * LIKE pattern helpers.\n *\n * User input must be escaped before being embedded in a LIKE pattern, so that\n * `%`, `_` and `\\` in data match literally. All dialects use `\\` as the escape\n * character (sqlite only via the explicit ESCAPE clause the dialect appends —\n * see SqlDialect.likeEscapeClause).\n */\n\n/** Escape LIKE wildcards (`%`, `_`) and the escape character itself. */\nexport function escapeLikePattern(params: { raw: string }): string {\n return params.raw.replaceAll(\"\\\\\", \"\\\\\\\\\").replaceAll(\"%\", \"\\\\%\").replaceAll(\"_\", \"\\\\_\");\n}\n\n/** Pattern for a `contains` filter: `%value%` with the value escaped. */\nexport function containsPattern(params: { raw: string }): string {\n return `%${escapeLikePattern({ raw: params.raw })}%`;\n}\n\n/** Pattern for a `startsWith` filter: `value%` with the value escaped. */\nexport function startsWithPattern(params: { raw: string }): string {\n return `${escapeLikePattern({ raw: params.raw })}%`;\n}\n\n/** Pattern for an `endsWith` filter: `%value` with the value escaped. */\nexport function endsWithPattern(params: { raw: string }): string {\n return `%${escapeLikePattern({ raw: params.raw })}`;\n}\n\n/**\n * Escape sqlite GLOB metacharacters (`*`, `?`, `[`) via single-character\n * classes — GLOB has no ESCAPE clause, and LIKE's backslash escaping does NOT\n * apply to it (board #20; `]` is literal outside a class). Used by the\n * `strictMatch` renderer on dialects with `strictMatchStrategy: \"glob\"`.\n */\nexport function escapeGlobPattern(params: { raw: string }): string {\n return params.raw.replace(/[*?[]/g, (char) => `[${char}]`);\n}\n\n/**\n * The BOUND pattern a `strictMatch` pattern op renders, per strategy — the\n * ONE derivation point, used by the renderer AND the runtime's render-cache\n * mirror (which must bind the identical parameter, LEARNINGS mirror rule).\n */\nexport function strictMatchPattern(params: {\n strategy: \"native\" | \"glob\" | \"binary\";\n op: \"contains\" | \"startsWith\" | \"endsWith\";\n value: string;\n}): string {\n const { strategy, op, value } = params;\n if (strategy === \"glob\") {\n const inner = escapeGlobPattern({ raw: value });\n return op === \"contains\" ? `*${inner}*` : op === \"startsWith\" ? `${inner}*` : `*${inner}`;\n }\n return op === \"contains\"\n ? containsPattern({ raw: value })\n : op === \"startsWith\"\n ? startsWithPattern({ raw: value })\n : endsWithPattern({ raw: value });\n}\n",
14
14
  "/**\n * Parameter collection during rendering.\n *\n * The single place placeholder indices are produced — renderers never\n * hand-write `$1`/`?`, so numbering and value order can never drift apart.\n */\n\nimport type { SqlDialect } from \"./dialect.ts\";\n\nexport class ParamCollector {\n private readonly dialect: SqlDialect;\n readonly values: unknown[];\n\n constructor(dialect: SqlDialect) {\n this.dialect = dialect;\n this.values = [];\n }\n\n /** Register one parameter value; returns its placeholder text. */\n add(value: unknown): string {\n this.values.push(value);\n return this.dialect.placeholder({ index: this.values.length });\n }\n\n /** Register many values; returns their placeholders in order. */\n addMany(values: readonly unknown[]): string[] {\n return values.map((value) => this.add(value));\n }\n}\n"
15
15
  ],
16
- "mappings": "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",
17
- "debugId": "2B8F0892BD46367D64756E2164756E21",
16
+ "mappings": "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",
17
+ "debugId": "CA83D2CED1E762E664756E2164756E21",
18
18
  "names": []
19
19
  }
@@ -1 +1 @@
1
- {"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,KAAK,EAAqB,YAAY,EAAE,OAAO,EAAY,MAAM,UAAU,CAAC;AAanF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE/C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAI7C,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC;IAC3B;;;OAGG;IACH,QAAQ,CAAC,SAAS,EAAE,QAAQ,GAAG,SAAS,GAAG,MAAM,CAAC;CACnD,CAAC;AAIF,wBAAgB,eAAe,CAAC,MAAM,EAAE;IAAE,OAAO,EAAE,UAAU,CAAC;IAAC,SAAS,EAAE,YAAY,CAAA;CAAE,GAAG,aAAa,CAavG;AAgGD;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE;IAAE,OAAO,EAAE,UAAU,CAAC;IAAC,IAAI,EAAE,OAAO,CAAC;IAAC,SAAS,EAAE,cAAc,CAAA;CAAE,GAAG,MAAM,CAsJ5G;AAID;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE;IACrC,OAAO,EAAE,UAAU,CAAC;IACpB,QAAQ,EAAE,eAAe,CAAC;IAC1B,SAAS,EAAE,cAAc,CAAC;CAC3B,GAAG,MAAM,CAaT"}
1
+ {"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,KAAK,EAAqB,YAAY,EAAE,OAAO,EAAY,MAAM,UAAU,CAAC;AAanF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE/C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAI7C,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC;IAC3B;;;OAGG;IACH,QAAQ,CAAC,SAAS,EAAE,QAAQ,GAAG,SAAS,GAAG,MAAM,CAAC;CACnD,CAAC;AAIF,wBAAgB,eAAe,CAAC,MAAM,EAAE;IAAE,OAAO,EAAE,UAAU,CAAC;IAAC,SAAS,EAAE,YAAY,CAAA;CAAE,GAAG,aAAa,CAavG;AAgGD;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE;IAAE,OAAO,EAAE,UAAU,CAAC;IAAC,IAAI,EAAE,OAAO,CAAC;IAAC,SAAS,EAAE,cAAc,CAAA;CAAE,GAAG,MAAM,CA0J5G;AAID;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE;IACrC,OAAO,EAAE,UAAU,CAAC;IACpB,QAAQ,EAAE,eAAe,CAAC;IAC1B,SAAS,EAAE,cAAc,CAAC;CAC3B,GAAG,MAAM,CAaT"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vibeorm/sql",
3
- "version": "2.0.0-alpha.2",
3
+ "version": "2.0.0-alpha.4",
4
4
  "description": "Dialect-aware SQL layer for VibeORM v2 — SQL AST, renderers and capability tables for postgres, sqlite and mysql",
5
5
  "keywords": [
6
6
  "orm",
@@ -40,10 +40,11 @@
40
40
  "README.md"
41
41
  ],
42
42
  "engines": {
43
+ "node": ">=18",
43
44
  "bun": ">=1.2.0"
44
45
  },
45
46
  "dependencies": {
46
- "@vibeorm/schema": "2.0.0-alpha.2"
47
+ "@vibeorm/schema": "2.0.0-alpha.4"
47
48
  },
48
49
  "publishConfig": {
49
50
  "access": "public"