@vibeorm/sql 5.9.0 → 5.11.0

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.
Files changed (47) hide show
  1. package/dist/ast.d.ts +337 -4
  2. package/dist/codecs.d.ts +106 -12
  3. package/dist/composable.d.ts +44 -4
  4. package/dist/dialect.d.ts +73 -1
  5. package/dist/dialects/migration-inventory.d.ts +0 -11
  6. package/dist/dialects/mysql-generated-columns.d.ts +1 -5
  7. package/dist/dialects/mysql-index-expressions.d.ts +1 -19
  8. package/dist/dialects/mysql-json-keys.d.ts +26 -0
  9. package/dist/dialects/mysql-row-rules.d.ts +1 -7
  10. package/dist/dialects/postgres-generated-columns.d.ts +0 -5
  11. package/dist/dialects/postgres-index-expressions.d.ts +1 -11
  12. package/dist/dialects/postgres-rls-readiness.d.ts +0 -2
  13. package/dist/dialects/postgres-rls.d.ts +7 -1
  14. package/dist/dialects/postgres-row-rules.d.ts +1 -24
  15. package/dist/dialects/sqlite-fts.d.ts +2 -2
  16. package/dist/dialects/sqlite-generated-columns.d.ts +1 -12
  17. package/dist/dialects/sqlite-index-expressions.d.ts +1 -24
  18. package/dist/dialects/sqlite-json-equality.d.ts +1 -14
  19. package/dist/dialects/sqlite-row-rules.d.ts +1 -7
  20. package/dist/dialects/sqlite-table-definition.d.ts +0 -19
  21. package/dist/dialects/test-databases.d.ts +96 -0
  22. package/dist/expr-fragment.d.ts +13 -0
  23. package/dist/identifiers.d.ts +1 -4
  24. package/dist/index.d.ts +11 -6
  25. package/dist/index.js +3023 -2064
  26. package/dist/index.js.map +47 -43
  27. package/dist/json-patch.d.ts +0 -14
  28. package/dist/json-path.d.ts +1 -2
  29. package/dist/key-list.d.ts +38 -21
  30. package/dist/native-types.d.ts +3 -1
  31. package/dist/params.d.ts +0 -2
  32. package/dist/query/expressions.d.ts +1 -33
  33. package/dist/query/index.js.map +7 -7
  34. package/dist/query/mutations.d.ts +1 -14
  35. package/dist/query/reusable.d.ts +1 -16
  36. package/dist/query/select.d.ts +1 -10
  37. package/dist/query/sources.d.ts +1 -36
  38. package/dist/query/state.d.ts +1 -77
  39. package/dist/query-plan.d.ts +2 -2
  40. package/dist/result-decoder.d.ts +21 -1
  41. package/dist/row-rules.d.ts +1 -19
  42. package/dist/sql-bindings.d.ts +7 -43
  43. package/dist/sql-handles.d.ts +1 -3
  44. package/dist/sql-input.d.ts +8 -24
  45. package/dist/timestamp-identity.d.ts +6 -12
  46. package/dist/timestamp-text.d.ts +36 -0
  47. package/package.json +2 -2
package/dist/dialect.d.ts CHANGED
@@ -20,6 +20,13 @@ import type { ParamCollector } from "./params.ts";
20
20
  export type RowLockSyntax = {
21
21
  readonly strengths: Readonly<Partial<Record<RowLockStrength, string>>>;
22
22
  readonly wait: Readonly<Partial<Record<RowLockWaitPolicy, string>>>;
23
+ /**
24
+ * The spelling of a strength when the lock names no `OF` table and no wait
25
+ * policy, where it differs from `strengths`: a form more servers of the
26
+ * family parse (MySQL's `LOCK IN SHARE MODE`, which MariaDB and MySQL before
27
+ * 8.0.1 accept while `FOR SHARE` is a syntax error there).
28
+ */
29
+ readonly plain?: Readonly<Partial<Record<RowLockStrength, string>>>;
23
30
  };
24
31
  /** The blocking and try function names for one advisory-lock mode. */
25
32
  export type AdvisoryLockModeFunctions = {
@@ -203,6 +210,55 @@ export type SqlDialect = {
203
210
  * where every adapter pins zone-less values to UTC (postgres).
204
211
  */
205
212
  readonly requiresUtcDateTimeWire: boolean;
213
+ /**
214
+ * How a dictionary of shared lists reads its distinct keys back out of
215
+ * the JSON the statement built (`SelectStatement.fromJsonKeys`).
216
+ * `"elements"`: one set-returning call per list on the way and a cast of
217
+ * the key text to the key-list's base type (postgres). `"jsonTable"`:
218
+ * one `JSON_TABLE` whose row path walks the lists, `JSON`-typed columns
219
+ * grouped as JSON and unquoted outside (MySQL; see
220
+ * `dialects/mysql-json-keys.ts` for why no other form is both right and
221
+ * indexed).
222
+ */
223
+ readonly keysFromJson: "elements" | "jsonTable";
224
+ /**
225
+ * How a common table is held to one evaluation (`CommonTable.materialized`):
226
+ * `"keyword"` — `AS MATERIALIZED (…)`; `"limit"` — the dialect has no such
227
+ * keyword and merges a common table into each reference unless its select
228
+ * is limited, so an unlimited select gets the largest `LIMIT` (MySQL).
229
+ */
230
+ readonly pinnedCommonTable: "keyword" | "limit";
231
+ /**
232
+ * Where a statement with carrier rows returns the lists it builds once
233
+ * per distinct target. `"firstRow"`: all of them as one JSON list on the
234
+ * statement's first row, built by an uncorrelated scalar subquery over the
235
+ * distinct keys (`SelectStatement.fromTableArrays`); PostgreSQL prices that
236
+ * subquery once, where it prices a lateral once per row of the statement
237
+ * and the estimate alone starts the JIT compiler from about 1 000 rows.
238
+ * `"carrierRow"`: each target's lists on the first row that reads it, from
239
+ * a lateral gated on that row (`SelectStatement.fromRow`); MySQL has no
240
+ * JIT compiler, runs the gated lateral once per target, and has no arrays
241
+ * to read the keys back through. The runtime builds `"carrierRow"` on a
242
+ * `"firstRow"` dialect too where a statement's root is proven to return
243
+ * a few rows: the estimate is bounded there and the statement is cheaper.
244
+ */
245
+ readonly carriedLists: "firstRow" | "carrierRow";
246
+ /**
247
+ * The server setting that caps one JSON value where the server can answer
248
+ * a larger one without failing the statement (MySQL `max_allowed_packet`,
249
+ * 64 MB by default). Measured on MySQL 26.7 with the statements the
250
+ * runtime builds: a carried row whose lists together pass the cap arrives
251
+ * as SQL NULL with warning 1301, a dictionary past it as its JSON text cut
252
+ * a little past the cap with the same warning, and one list past it fails
253
+ * the statement (errno 1301), which leaves a transaction open. The
254
+ * runtime reads a NULL or unparsable text where the statement always
255
+ * builds a JSON value as that overflow (`VIBE_RESULT_TOO_LARGE`), and the
256
+ * client answers a find that fails with that code under the `"query"`
257
+ * strategy. `null`: the server fails the statement itself and the error
258
+ * reaches the caller (PostgreSQL: 1 GB, and a failed statement aborts its
259
+ * transaction).
260
+ */
261
+ readonly silentSizeLimit: string | null;
206
262
  } | null;
207
263
  /**
208
264
  * The relation strategy a client uses when neither the call nor the client
@@ -218,8 +274,14 @@ export type SqlDialect = {
218
274
  * PostgreSQL and MySQL turn it into a semi-join. `inSelect`: an uncorrelated
219
275
  * `key IN (SELECT key …)` — SQLite runs a correlated `EXISTS` once per outer
220
276
  * row (`post where author.email = x`: 134 → 0.15 ms, Post 500 000).
277
+ * `eqSelect`: a to-one through ONE foreign-key column pinned this way renders
278
+ * `fk = (SELECT key …)`, every other shape the correlated `EXISTS` —
279
+ * PostgreSQL plans the semi-join as a loop into all of the parent's children
280
+ * and sorts them for a page, but reads a page of `fk = (SELECT …)` in index
281
+ * order (newest 20 of 4 000 orders of one person: 889 → 11 buffers,
282
+ * 1.16 → 0.01 ms; an `IN (SELECT …)` keeps the semi-join plan).
221
283
  */
222
- readonly relationFilterStrategy: "exists" | "inSelect";
284
+ readonly relationFilterStrategy: "exists" | "inSelect" | "eqSelect";
223
285
  /**
224
286
  * DB-02: when a find with a TOTAL order (it ends with the full primary key)
225
287
  * pages with `skip` ≥ `minSkip`, the runtime cuts the page as primary keys
@@ -484,5 +546,15 @@ export type SqlDialect = {
484
546
  offsetSeconds: number;
485
547
  collector: ParamCollector;
486
548
  }): string;
549
+ /**
550
+ * True when any pair of the two equally long lists of rendered expressions
551
+ * differs, NULL counting as a value: `IS DISTINCT FROM` on postgres, `IS
552
+ * NOT` on sqlite, `NOT (… <=> …)` on mysql. One pair compares the two
553
+ * expressions; several compare row constructors.
554
+ */
555
+ renderRowsDiffer(params: {
556
+ left: readonly string[];
557
+ right: readonly string[];
558
+ }): string;
487
559
  };
488
560
  //# sourceMappingURL=dialect.d.ts.map
@@ -1,16 +1,5 @@
1
1
  import type { SqlDialect } from "../dialect.ts";
2
2
  import type { RenderedQuery } from "../render.ts";
3
- /**
4
- * Ends a MySQL catalog listing whose row count has no small bound (the
5
- * migration inventory, the visibility proof). `sql_select_limit` (session or
6
- * global, e.g. 1 000 under `mysql --safe-updates`) silently cuts the rows of a
7
- * SELECT without its own LIMIT, and a cut listing reads its last objects (or
8
- * grants) as missing; an explicit LIMIT takes precedence over it. After the
9
- * last `UNION` branch (and its ORDER BY) the LIMIT applies to the whole union.
10
- * The value is MySQL's largest row count, so nothing is ever cut. The batched
11
- * object readers end the same way (`migration-objects.ts`, LEFTOVERS-01).
12
- */
13
- export declare const MYSQL_NO_ROW_LIMIT: string;
14
3
  /** SQLite column metadata includes generated columns omitted by table_info. */
15
4
  export declare function renderSqliteColumnInventory(params: {
16
5
  dialect: SqlDialect;
@@ -1,11 +1,7 @@
1
1
  import type { QualifiedSqlName } from "@vibeorm/schema";
2
2
  import type { SqlDialect } from "../dialect.ts";
3
- import type { ExtractedGeneratedColumn, GeneratedColumnDeclaration } from "../generated-columns.ts";
3
+ import type { ExtractedGeneratedColumn } from "../generated-columns.ts";
4
4
  import type { RenderedQuery } from "../render.ts";
5
- /** MySQL stored syntax, placed after complete type/charset/collation information. */
6
- export declare function renderMysqlGeneratedColumnClause({ generated }: {
7
- readonly generated: GeneratedColumnDeclaration;
8
- }): string;
9
5
  /** Temporary CREATE/DROP operations avoid ALTER's implicit-commit boundary. */
10
6
  export type MysqlGeneratedColumnProbe = {
11
7
  readonly operation: "context";
@@ -1,20 +1,2 @@
1
- import type { IndexKeyTermIR } from "@vibeorm/schema";
2
- import type { SqlDialect } from "../dialect.ts";
3
- import type { IndexExpressionProbeParams, IndexKeyOperand } from "../index-expressions.ts";
4
- import type { PredicateModel } from "../predicate.ts";
5
- import type { RenderedQuery } from "../render.ts";
6
- /** Qualify only expression-bearing keys through schema's shared width rule; never impose new bounds on ordinary indexes. */
7
- export declare function assertMysqlIndexKeyStorage({ model, terms }: {
8
- readonly dialect: SqlDialect;
9
- readonly model: PredicateModel;
10
- readonly terms: readonly IndexKeyTermIR[];
11
- }): void;
12
- /** Recover SHOW CREATE key interiors, including exact CAST/charset/collation bytes. */
13
- export declare function extractMysqlIndexKeys({ definition, index, backslashEscapes }: {
14
- readonly definition: string;
15
- readonly index: string;
16
- readonly backslashEscapes: boolean;
17
- }): readonly IndexKeyOperand[] | undefined;
18
- /** Reuse E's temporary-clone/read/drop operations, extending only CREATE's key replacement seam. */
19
- export declare function renderMysqlIndexExpressionProbe({ ...params }: IndexExpressionProbeParams): readonly RenderedQuery[];
1
+ export {};
20
2
  //# sourceMappingURL=mysql-index-expressions.d.ts.map
@@ -0,0 +1,26 @@
1
+ /**
2
+ * MySQL's text for the two pieces of a dictionary of shared lists that it
3
+ * cannot share with PostgreSQL: the distinct keys read back out of the JSON a
4
+ * statement built (`SelectStatement.fromJsonKeys`), and a common table that
5
+ * must be evaluated once (`CommonTable.materialized`).
6
+ *
7
+ * Every choice below was measured on MySQL 26.7 (500 roots, 1 000 keys):
8
+ *
9
+ * - A `VARCHAR` column of `JSON_TABLE` takes the CONNECTION's collation with
10
+ * implicit coercibility. Compared with a foreign-key column it fails
11
+ * (`ER_CANT_AGGREGATE_2COLLATIONS`) whenever the two collations differ, and
12
+ * mysql2 connects as `utf8mb4_unicode_ci` while MySQL creates columns as
13
+ * `utf8mb4_0900_ai_ci`.
14
+ * - The same column declared `COLLATE utf8mb4_bin` runs, but the binary
15
+ * collation wins the comparison and the foreign-key index is not used
16
+ * (627 ms against 25 ms).
17
+ * - `JSON_UNQUOTE(<a JSON value>)` is coercible like a bound literal, also
18
+ * through a materialized derived table, so the COLUMN's collation decides
19
+ * the comparison and its index serves it: the key matches its children
20
+ * exactly as `WHERE fk IN (?)` matches them.
21
+ * - `DISTINCT` on a `JSON` column compares the values exactly. On text under
22
+ * `utf8mb4_bin` it pads (`'a'` and `'a '` are one key), which would lose an
23
+ * entry where the key column's own collation does not pad.
24
+ */
25
+ export {};
26
+ //# sourceMappingURL=mysql-json-keys.d.ts.map
@@ -1,8 +1,2 @@
1
- import type { SqlDialect } from "../dialect.ts";
2
- import type { EventRowRuleContext, RenderedRowRule } from "../row-rules.ts";
3
- /** Emit mode-safe SIGNAL diagnostics and one unfiltered BEFORE trigger per event. */
4
- export declare function renderMysqlRowRule({ dialect, context }: {
5
- readonly dialect: SqlDialect;
6
- readonly context: EventRowRuleContext;
7
- }): RenderedRowRule;
1
+ export {};
8
2
  //# sourceMappingURL=mysql-row-rules.d.ts.map
@@ -1,11 +1,6 @@
1
1
  import type { QualifiedSqlName } from "@vibeorm/schema";
2
2
  import type { SqlDialect } from "../dialect.ts";
3
- import type { GeneratedColumnDeclaration } from "../generated-columns.ts";
4
3
  import type { RenderedQuery } from "../render.ts";
5
- /** PostgreSQL stored syntax; the public dispatcher performs declaration admission. */
6
- export declare function renderPostgresGeneratedColumnClause({ generated }: {
7
- readonly generated: GeneratedColumnDeclaration;
8
- }): string;
9
4
  /** The migration owner creates the desired base context inside the private savepoint. */
10
5
  export type PostgresGeneratedColumnProbe = {
11
6
  readonly operation: "savepoint" | "rollback" | "release";
@@ -1,12 +1,2 @@
1
- import type { IndexExpressionProbeParams, IndexKeyOperand } from "../index-expressions.ts";
2
- import type { RenderedQuery } from "../render.ts";
3
- /** CREATE INDEX extraction is conservative; structured catalog rows remain authoritative. */
4
- export declare function extractPostgresIndexKeys({ definition, index, included }: {
5
- readonly definition: string;
6
- readonly index: string;
7
- /** INCLUDE columns the caller read from the catalog; an INCLUDE clause of another length is refused. */
8
- readonly included?: number;
9
- }): readonly IndexKeyOperand[] | undefined;
10
- /** Caller owns a fixed search_path and rollback savepoint; no populated user table is indexed. */
11
- export declare function renderPostgresIndexExpressionProbe({ ...params }: IndexExpressionProbeParams): readonly RenderedQuery[];
1
+ export {};
12
2
  //# sourceMappingURL=postgres-index-expressions.d.ts.map
@@ -2,8 +2,6 @@ import type { SqlDialect } from "../dialect.ts";
2
2
  import type { RenderedQuery } from "../render.ts";
3
3
  /** Throwaway policy identity; never installed on a live table by readiness. */
4
4
  export declare const NATIVE_RLS_PROBE_POLICY: "vibeorm_probe";
5
- /** The reads `catalog` folds, in the order their JSON columns appear. */
6
- export declare const RLS_READINESS_CATALOG_KEYS: readonly ("identity" | "elevatedRoles" | "schemaControl" | "tables" | "policies" | "views" | "routines" | "triggers")[];
7
5
  /** Read-only catalog SQL; exported for exact statement routing in adapter tests. */
8
6
  export declare const RLS_READINESS_SQL: {
9
7
  readonly identity: string;
@@ -43,11 +43,17 @@ export declare function renderRlsColumnType(params: {
43
43
  dialect: SqlDialect;
44
44
  field: FieldIR;
45
45
  }): string;
46
- /** Desired predicate only, for drift probes; it is NOT server-canonical deparse. */
46
+ /**
47
+ * Desired predicate only, for drift probes; it is NOT server-canonical deparse.
48
+ * `qualify` names the table a `where` rule's columns are read from, for a
49
+ * statement with another relation in scope (`excluded` in `ON CONFLICT … DO
50
+ * UPDATE`); the policy itself and the drift probes render them bare.
51
+ */
47
52
  export declare function renderRlsPredicate(params: {
48
53
  dialect: SqlDialect;
49
54
  schema: SchemaIR;
50
55
  model: string;
56
+ qualify?: string;
51
57
  }): string;
52
58
  /** One PERMISSIVE ALL/PUBLIC policy with equal existing/proposed-row checks. */
53
59
  export declare function renderRlsPolicy(params: {
@@ -1,25 +1,2 @@
1
- import type { FieldIR, QualifiedSqlName, RowRuleIR, SqlObjectIdentity } from "@vibeorm/schema";
2
- import type { SqlDialect } from "../dialect.ts";
3
- import type { RenderedRowRule } from "../row-rules.ts";
4
- /** A finalized PostgreSQL comparison context, supplied by the canonical schema collector. */
5
- export type PostgresRowRuleContext = {
6
- readonly model: string;
7
- readonly table: QualifiedSqlName;
8
- readonly rule: RowRuleIR;
9
- readonly functionIdentity: Extract<SqlObjectIdentity, {
10
- readonly kind: "function";
11
- }>;
12
- readonly triggerIdentity: {
13
- readonly kind: "trigger";
14
- readonly table: QualifiedSqlName;
15
- readonly name: string;
16
- };
17
- readonly protectedFields: readonly FieldIR[];
18
- readonly gateField?: FieldIR;
19
- };
20
- /** Emit one ordinary invoker function and an unfiltered BEFORE row trigger; no live objects are taken over. */
21
- export declare function renderPostgresRowRule({ dialect, context }: {
22
- readonly dialect: SqlDialect;
23
- readonly context: PostgresRowRuleContext;
24
- }): RenderedRowRule;
1
+ export {};
25
2
  //# sourceMappingURL=postgres-row-rules.d.ts.map
@@ -1,4 +1,4 @@
1
- /** @internal SQLite FTS synchronization SQL and its independently verifiable catalog spelling. */
1
+ /** SQLite FTS synchronization SQL and its independently verifiable catalog spelling. */
2
2
  export declare function renderSqliteFtsUpdateTrigger(params: {
3
3
  table: string;
4
4
  ftsTable: string;
@@ -7,7 +7,7 @@ export declare function renderSqliteFtsUpdateTrigger(params: {
7
7
  readonly create: string;
8
8
  readonly definition: string;
9
9
  };
10
- /** @internal Recognize only complete generated legacy/current triggers and their external-content FTS5 table. */
10
+ /** Recognize only complete generated legacy/current triggers and their external-content FTS5 table. */
11
11
  export declare function sqliteFtsUpdateUpgrade(params: {
12
12
  create: string;
13
13
  installed: string;
@@ -1,15 +1,4 @@
1
- import type { ExtractedGeneratedColumn, GeneratedColumnDeclaration } from "../generated-columns.ts";
2
- /** SQLite stored syntax; adding a stored column still requires the migrate rebuild path. */
3
- export declare function renderSqliteGeneratedColumnClause({ generated }: {
4
- readonly generated: GeneratedColumnDeclaration;
5
- }): string;
6
- /** Shared source-slice extraction for SQLite source and MySQL SHOW CREATE, not SQL equivalence. */
7
- export declare function extractGenerationFromDefinition({ definition, column, backslashEscapes, mysql }: {
8
- readonly definition: string;
9
- readonly column: string;
10
- readonly backslashEscapes?: boolean;
11
- readonly mysql?: boolean;
12
- }): ExtractedGeneratedColumn | undefined;
1
+ import type { ExtractedGeneratedColumn } from "../generated-columns.ts";
13
2
  /** Recover the exact AS interior; omitted storage means virtual, never inferred stored. */
14
3
  export declare function extractSqliteGeneratedColumn({ definition, column }: {
15
4
  readonly definition: string;
@@ -1,25 +1,2 @@
1
- import type { IndexKeyOperand } from "../index-expressions.ts";
2
- import type { TableDefinitionToken } from "./sqlite-table-definition.ts";
3
- /** Exact outer-key slices shared by CREATE INDEX and MySQL table-key clauses. */
4
- export declare function extractIndexKeyList({ sql, open, close, tokens, wrapped, removeWrapper }: {
5
- readonly sql: string;
6
- readonly open: TableDefinitionToken;
7
- readonly close: TableDefinitionToken;
8
- readonly tokens: readonly TableDefinitionToken[];
9
- readonly wrapped?: boolean;
10
- readonly removeWrapper?: boolean;
11
- }): readonly IndexKeyOperand[] | undefined;
12
- /** Parse the CREATE INDEX header without interpreting any scalar expression. */
13
- export declare function extractStandaloneIndexKeys({ definition, index, postgres, included }: {
14
- readonly definition: string;
15
- readonly index: string;
16
- readonly postgres?: boolean;
17
- /** PostgreSQL INCLUDE columns the caller read from the catalog (default none). */
18
- readonly included?: number;
19
- }): readonly IndexKeyOperand[] | undefined;
20
- /** SQLite source spelling is the evidence; CAST alone never proves a plain Decimal key. */
21
- export declare function extractSqliteIndexKeys({ definition, index }: {
22
- readonly definition: string;
23
- readonly index: string;
24
- }): readonly IndexKeyOperand[] | undefined;
1
+ export {};
25
2
  //# sourceMappingURL=sqlite-index-expressions.d.ts.map
@@ -1,15 +1,2 @@
1
- import type { SqlDialect } from "../dialect.ts";
2
- /**
3
- * Compare both JSON trees by decoded key/index paths, node type and atomic value.
4
- * Object order and JSON escape spelling do not matter; array positions do.
5
- * Container nodes retain empty-object/array distinctions, and multiplicity stops
6
- * duplicate object members from disappearing as they would in a set difference.
7
- * SQL NULL remains unknown. The tree input is guarded against non-JSON scalar
8
- * text even when SQLite evaluates this expression before the outer type guard.
9
- */
10
- export declare function renderSqliteJsonEquality(params: {
11
- dialect: SqlDialect;
12
- left: string;
13
- right: string;
14
- }): string;
1
+ export {};
15
2
  //# sourceMappingURL=sqlite-json-equality.d.ts.map
@@ -1,8 +1,2 @@
1
- import type { SqlDialect } from "../dialect.ts";
2
- import type { EventRowRuleContext, RenderedRowRule } from "../row-rules.ts";
3
- /** Emit literal-only ABORT diagnostics and one unfiltered BEFORE trigger per event. */
4
- export declare function renderSqliteRowRule({ dialect, context }: {
5
- readonly dialect: SqlDialect;
6
- readonly context: EventRowRuleContext;
7
- }): RenderedRowRule;
1
+ export {};
8
2
  //# sourceMappingURL=sqlite-row-rules.d.ts.map
@@ -8,30 +8,11 @@ export type TableDefinitionParts = {
8
8
  readonly clauses: readonly string[];
9
9
  readonly suffix: string;
10
10
  };
11
- /** A source token with balanced-parenthesis depth and original byte boundaries. */
12
- export type TableDefinitionToken = {
13
- readonly value: string;
14
- readonly kind: "word" | "quoted" | "literal" | "symbol";
15
- readonly start: number;
16
- readonly end: number;
17
- readonly depth: number;
18
- };
19
- /** Scan SQL delimiters without looking inside quoted strings, identifiers or comments. */
20
- export declare function tableDefinitionTokens({ sql, backslashEscapes }: {
21
- readonly sql: string;
22
- readonly backslashEscapes?: boolean;
23
- }): readonly TableDefinitionToken[];
24
11
  /** Extract a CREATE TABLE list with a quote/comment-aware delimiter walk. */
25
12
  export declare function tableDefinitionParts({ sql, backslashEscapes }: {
26
13
  readonly sql: string;
27
14
  readonly backslashEscapes?: boolean;
28
15
  }): TableDefinitionParts;
29
- /** Read column names for SQLite source and MySQL SHOW CREATE using the same lexer. */
30
- export declare function tableColumnClauses({ sql, backslashEscapes, mysql }: {
31
- readonly sql: string;
32
- readonly backslashEscapes?: boolean;
33
- readonly mysql?: boolean;
34
- }): readonly SqliteColumnClause[];
35
16
  /** Return column clauses without rewriting any SQL inside them. */
36
17
  export declare function sqliteColumnClauses({ sql }: {
37
18
  readonly sql: string;
@@ -0,0 +1,96 @@
1
+ import type { Dialect } from "@vibeorm/schema";
2
+ import type { SqlDialect } from "../dialect.ts";
3
+ import type { RenderedQuery } from "../render.ts";
4
+ /**
5
+ * Which dialects can copy a migrated database on the server. PostgreSQL clones
6
+ * a template database (`CREATE DATABASE … TEMPLATE`). MySQL has no template
7
+ * databases, and its only server-side copy (`CREATE TABLE … LIKE`) leaves the
8
+ * foreign keys behind; SQLite copies files and sends no SQL for it.
9
+ */
10
+ export declare const TEST_DATABASE_CAPABILITIES: Readonly<Record<Dialect, Readonly<{
11
+ templateDatabases: boolean;
12
+ }>>>;
13
+ /**
14
+ * A caller's test-database prefix: lower-case, a plain identifier start, and
15
+ * the word `test` in it, so a prefix cannot name an application's databases.
16
+ */
17
+ export declare const TEST_DATABASE_PREFIX_PATTERN: RegExp;
18
+ /** What a test-database name is, by its shape under one prefix. */
19
+ export type TestDatabaseKind = "template" | "clone";
20
+ /** `undefined` for a valid prefix, else why it is refused. */
21
+ export declare function testDatabasePrefixIssue(params: {
22
+ prefix: unknown;
23
+ }): string | undefined;
24
+ /** The kind of a database name under `prefix`, or `undefined` for every other name. */
25
+ export declare function testDatabaseKind(params: {
26
+ prefix: string;
27
+ name: string;
28
+ }): TestDatabaseKind | undefined;
29
+ /** When a clone was created (ms since the epoch, the creating process's clock), read from its name. */
30
+ export declare function testCloneCreatedAt(params: {
31
+ prefix: string;
32
+ name: string;
33
+ }): number | undefined;
34
+ /** The template marker's creation time (server milliseconds), or `undefined` for any other comment. */
35
+ export declare function parseTestTemplateMarker(params: {
36
+ text: unknown;
37
+ }): number | undefined;
38
+ /** Test-database statements on the administration connection. */
39
+ export type TestDatabaseOperation =
40
+ /**
41
+ * One row whether or not the database exists: its template flag (null when
42
+ * absent), its comment, the sessions connected to it other than this one, and
43
+ * the server clock in milliseconds.
44
+ */
45
+ {
46
+ readonly kind: "state";
47
+ readonly prefix: string;
48
+ readonly name: string;
49
+ }
50
+ /** An empty database to build a template in. */
51
+ | {
52
+ readonly kind: "createTemplate";
53
+ readonly prefix: string;
54
+ readonly name: string;
55
+ }
56
+ /** The template's creation time (server milliseconds), as its database comment. */
57
+ | {
58
+ readonly kind: "markTemplate";
59
+ readonly prefix: string;
60
+ readonly name: string;
61
+ readonly created: number;
62
+ }
63
+ /**
64
+ * Set: the build's last step and the ready signal — a template that refuses
65
+ * connections, because one connection to it blocks every clone. Cleared before
66
+ * a template is dropped.
67
+ */
68
+ | {
69
+ readonly kind: "flagTemplate";
70
+ readonly prefix: string;
71
+ readonly name: string;
72
+ readonly template: boolean;
73
+ } | {
74
+ readonly kind: "clone";
75
+ readonly prefix: string;
76
+ readonly name: string;
77
+ readonly template: string;
78
+ }
79
+ /** `force` (PostgreSQL 13+) ends the sessions still connected; only a clone may be forced. */
80
+ | {
81
+ readonly kind: "drop";
82
+ readonly prefix: string;
83
+ readonly name: string;
84
+ readonly force?: boolean;
85
+ }
86
+ /** Every database whose name starts with the prefix, its template flag, comment and other sessions, and the server clock. */
87
+ | {
88
+ readonly kind: "list";
89
+ readonly prefix: string;
90
+ };
91
+ /** Render one test-database statement; dialects without template databases refuse. */
92
+ export declare function renderTestDatabaseOperation(params: {
93
+ dialect: SqlDialect;
94
+ operation: TestDatabaseOperation;
95
+ }): RenderedQuery;
96
+ //# sourceMappingURL=test-databases.d.ts.map
@@ -0,0 +1,13 @@
1
+ import type { SqlExpr } from "./ast.ts";
2
+ import type { SqlFragment } from "./composable.ts";
3
+ import type { SqlDialect } from "./dialect.ts";
4
+ /**
5
+ * A compiled boolean expression as an opaque fragment for the caller's own
6
+ * statement: the text the dialect renders, every bound value a fragment
7
+ * value, so the enclosing statement numbers the placeholders.
8
+ */
9
+ export declare function exprToFragment(params: {
10
+ dialect: SqlDialect;
11
+ expr: SqlExpr;
12
+ }): SqlFragment;
13
+ //# sourceMappingURL=expr-fragment.d.ts.map
@@ -7,8 +7,5 @@
7
7
  * containing one is not an identifier at all. Refused at render time, the
8
8
  * earliest point every path (IR, raw `sql.ident`, extension DDL) shares.
9
9
  */
10
- /** Return `name` unchanged, or throw `VIBE_VALIDATION` when it contains a NUL. */
11
- export declare function assertNoNul(params: {
12
- name: string;
13
- }): string;
10
+ export {};
14
11
  //# sourceMappingURL=identifiers.d.ts.map
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export { cloneTimestampDate, compareTimestampDates, timestampIdentityKey, timestampIdentityText } from "./timestamp-identity.ts";
2
+ export { parsePlainTimestampText } from "./timestamp-text.ts";
2
3
  export { nativeEnumArrayParameter, isNativeEnumArrayParameter } from "./native-enum-parameter.ts";
3
4
  export type { NativeEnumArrayParameter } from "./native-enum-parameter.ts";
4
5
  export { isJsonListParameter, jsonListParameter } from "./json-list-parameter.ts";
@@ -21,12 +22,15 @@ export { renderReplayCoverageGaps } from "./dialects/migration-replay-coverage.t
21
22
  export { SHADOW_DATABASE, SHADOW_CAPABILITIES, renderShadowOperation } from "./dialects/migration-shadow.ts";
22
23
  export { AUTOMATIC_SHADOW_NAME_PATTERN, SHADOW_MARKER_CAPABILITIES, automaticShadowMarkerText, parseAutomaticShadowMarker, renderAutomaticShadowOperation } from "./dialects/migration-shadow-marker.ts";
23
24
  export type { AutomaticShadowMarker, AutomaticShadowOperation } from "./dialects/migration-shadow-marker.ts";
25
+ export { TEST_DATABASE_CAPABILITIES, TEST_DATABASE_PREFIX_PATTERN, parseTestTemplateMarker, renderTestDatabaseOperation, testCloneCreatedAt, testDatabaseKind, testDatabasePrefixIssue } from "./dialects/test-databases.ts";
26
+ export type { TestDatabaseKind, TestDatabaseOperation } from "./dialects/test-databases.ts";
24
27
  export type { ShadowOperation } from "./dialects/migration-shadow.ts";
25
28
  export { MODULE_JOURNAL_COLUMN, renderModuleJournal } from "./module-journal.ts";
26
29
  export { renderSqliteFtsUpdateTrigger, sqliteFtsUpdateUpgrade } from "./dialects/sqlite-fts.ts";
27
30
  export { SQLITE_SESSION_SQL } from "./dialects/sqlite-session.ts";
28
- export { sql, isSqlFragment, renderSqlFragment, compileSql, sqlUsesIncoming, mapConflictColumns } from "./composable.ts";
31
+ export { sql, isSqlFragment, renderSqlFragment, compileSql, sqlUsesIncoming, mapConflictColumns, captureSqlTemplate, compileSqlTemplate, PlainSqlTemplate } from "./composable.ts";
29
32
  export { registerSqlHandleCheck } from "./sql-handles.ts";
33
+ export { exprToFragment } from "./expr-fragment.ts";
30
34
  export type { SqlFragment, SqlTag } from "./composable.ts";
31
35
  export { createSqlQuery, createSqlCommand, isSqlQuery, isSqlCommand, compileSqlQuery, compileSqlCommand } from "./query-plan.ts";
32
36
  export type { SqlQuery, SqlCommand, SqlPlanRender, CompiledSqlQuery, CompiledSqlCommand, ReusableSqlQuery, ReusableSqlCommand } from "./query-plan.ts";
@@ -35,7 +39,7 @@ export { isSqlParam, createSqlInput, sqlInputContract, createSqlInputScope, seal
35
39
  export type { SqlParam, SqlInput, SqlInputMap, SqlInputValue, SqlInputValues, SqlInputTokens, SqlExecutionParams, SqlInputContract, SqlInputScope } from "./sql-input.ts";
36
40
  export { isSqlBindingCollector, recordSqlBinding, recordSqlBindingCheck } from "./sql-bindings.ts";
37
41
  export type { SqlBindingSource, SqlParameterTransport, SqlBindingEncoder } from "./sql-bindings.ts";
38
- export { decode, encode, resultScalarContract, sameResultDecoder } from "./result-decoder.ts";
42
+ export { decode, decodeResultColumn, encode, resultScalarContract, sameResultDecoder } from "./result-decoder.ts";
39
43
  export type { ResultDecoder, ResultReadDecoder, ResultParameterEncoder, ResultScalarContract, Decoded, ExtendedDateTime } from "./result-decoder.ts";
40
44
  /**
41
45
  * @vibeorm/sql — dialect-aware SQL layer for VibeORM v2.
@@ -44,7 +48,7 @@ export type { ResultDecoder, ResultReadDecoder, ResultParameterEncoder, ResultSc
44
48
  * lives in this package; see the root sql-catalog.md for the reviewable surface.
45
49
  */
46
50
  export { compileExclusion, renderExclusionSetup, renderExclusionDdl, renderExclusionCatalog, renderExclusionProbe } from "./exclusion.ts";
47
- export type { AdvisoryLockKey, AdvisoryLockStatement, AdvisoryLocksStatement, AggFn, AggRef, AggSelect, ChainResult, ChainRowSource, ChainCapture, CaptureReturningColumn, CaptureCascade, CaptureCascadeReturningColumn, CaptureCell, CaptureHop, OtherRowReturningColumn, ChainStatement, ChainStep, ChainStepStatement, ChainTally, ChainVeto, ColRef, ComparisonOp, DateTruncation, GroupKeyExpression, GroupingSets, CountSubquery, ScalarSubquery, DeleteStatement, ExcludedRef, InnerJoin, KeyListMember, KeyPage, KeyRows, KeyTableJoin, KeyTableMember, InsertSelectStatement, InsertStatement, ReturningColumn, JsonFilterOp, LateralJoin, LeftJoin, ListSetOperation, OnConflictClause, OnConflictDoNothing, OnConflictUpdate, OrderByAggregate, OrderByColumn, OrderBySubquery, OrderTerm, RowLock, RowNumberProjection, DbNowMarker, JsonParamCell, SelectExpr, SelectStatement, SetOperation, SetOperator, SqlExpr, SqlStatement, StepColumnRef, SourceColumnRef, UpdateSource, UpdateTableSource, UpdateSelectSource, TableRef, UpdateStatement, } from "./ast.ts";
51
+ export type { AdvisoryLockKey, AdvisoryLockStatement, AdvisoryLocksStatement, AggFn, AggRef, AggSelect, ChainResult, ChainRowSource, ChainCapture, CaptureReturningColumn, CaptureCascade, CaptureCascadeReturningColumn, CaptureCell, CaptureHop, OtherRowReturningColumn, ServerVersionReturningColumn, ChainStatement, ChainStep, ChainStepStatement, ChainTally, ChainVeto, ColRef, ComparisonOp, DateTruncation, GroupKeyExpression, GroupingSets, CountSubquery, ScalarSubquery, DeleteStatement, ExcludedRef, InnerJoin, KeyListMember, KeyPage, KeyRows, KeyTableJoin, KeyTableMember, InsertSelectStatement, InsertStatement, ReturningColumn, JsonFilterOp, LateralJoin, LeftJoin, ListSetOperation, OnConflictClause, OnConflictDoNothing, UnchangedColumn, UnchangedExactness, OnConflictUpdate, OrderByAggregate, OrderByColumn, OrderBySubquery, OrderTerm, RowLock, RowNumberProjection, RowSourceColumn, CommonTable, FirstRowList, JsonKeyColumn, JsonKeys, TableArrays, JsonSlot, JsonStep, WindowColumn, DbNowMarker, JsonParamCell, SelectExpr, SelectStatement, SetOperation, SetOperator, SqlExpr, SqlStatement, StepColumnRef, SourceColumnRef, UpdateSource, UpdateTableSource, UpdateSelectSource, TableRef, UpdateStatement, } from "./ast.ts";
48
52
  export { ADVISORY_LOCK_RESULT_COLUMN, CHAIN_VETO_PREFIX, CHAIN_VETO_TOKEN_PATTERN, COALESCE_REF_NAME, SQL_DEFAULT_CELL, SQL_KEEP_CELL, chainVetoToken, coalesceRef, dbNowMarker, excludedRef, isDbNowMarker, isExcludedRef, isJsonParamCell, isListSetOperation, isSetOperation, isSqlDefaultCell, isSqlKeepCell, isStepColumnRef, isSourceColumnRef, sourceColumnRef, isCaptureReturningColumn, isOtherRowReturningColumn, jsonParamCell, returningColumnName, stepColumnRef, } from "./ast.ts";
49
53
  export type { AdvisoryLockFunctions, AdvisoryLockModeFunctions, RowLockSyntax, EmptyInsertSyntax, SqlDialect, } from "./dialect.ts";
50
54
  export { ADVISORY_KEY_BOUNDS, describeRowLock, renderAdvisoryLock, renderAdvisoryLocks, renderRowLockClause } from "./locks.ts";
@@ -54,7 +58,8 @@ export { sqliteDialect } from "./dialects/sqlite.ts";
54
58
  export { mysqlDialect } from "./dialects/mysql.ts";
55
59
  export { SQL_DIALECTS, getSqlDialect } from "./dialects/registry.ts";
56
60
  export { tableDefinitionParts } from "./dialects/sqlite-table-definition.ts";
57
- export { keyListBindsUntypedRows, postgresBulkInsertArrayCastOf, postgresKeyListElementTypeOf } from "./key-list.ts";
61
+ export { jsonKeyTokenCast, jsonKeysTyped, keyListBindsUntypedRows, mysqlJsonKeyTypeOf, postgresBulkInsertArrayCastOf, postgresKeyListElementTypeOf } from "./key-list.ts";
62
+ export type { MysqlJsonKeyType } from "./key-list.ts";
58
63
  export { renderPredicate, renderSchemaExpression } from "./predicate.ts";
59
64
  export { renderLocalDateCheck } from "./local-date.ts";
60
65
  export { isTimeZoneName, renderDateTruncation } from "./date-truncation.ts";
@@ -70,8 +75,8 @@ export { renderRowRule } from "./row-rules.ts";
70
75
  export type { RenderedRowRule, RowRuleStatement, RowRuleTriggerPlacement } from "./row-rules.ts";
71
76
  export type { PredicateModel, PredicateUsage } from "./predicate.ts";
72
77
  export { DIALECT_CAPABILITIES, MYSQL_CAPABILITIES, POSTGRES_CAPABILITIES, SQLITE_CAPABILITIES, } from "./capabilities.ts";
73
- export { DIALECT_CODECS, MYSQL_CODECS, POSTGRES_CODECS, SQLITE_CODECS, decodeIsNoop, decodedDateTimeRefusal, enumMembershipCodec, float32Codec, localDateCodec, parseDateTimeText, parseExtendedDateTimeText, parseJsonText, postgresArrayElementFromText, shortestFloat32, timeOfDayCodec, } from "./codecs.ts";
74
- export type { CodecTable, ScalarCodec, WireFidelity } from "./codecs.ts";
78
+ export { DIALECT_CODECS, MYSQL_CODECS, POSTGRES_CODECS, SQLITE_CODECS, dateTimeTextLayoutError, decodeIsNoop, decodedDateTimeRefusal, undecodableDateTimeText, enumMembershipCodec, float32Codec, localDateCodec, parseDateTimeText, parseExtendedDateTimeText, parseJsonText, postgresArrayElementFromText, shortestFloat32, timeOfDayCodec, dateOnlyCodec, dateTimeZoneKey, mysqlBoundTimestampText, parseZoneLessDateTime, zonedCodec, } from "./codecs.ts";
79
+ export type { CodecTable, DateTimeZone, ScalarCodec, WireFidelity } from "./codecs.ts";
75
80
  export { isRollupChain, renderExpr, renderFragment, renderProjection, renderStatement } from "./render.ts";
76
81
  export type { RenderedQuery } from "./render.ts";
77
82
  export { snapshotSqlValue } from "./parameter-snapshot.ts";