@vibeorm/sql 2.4.0 → 3.0.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.
- package/LICENSE +21 -0
- package/dist/ast.d.ts +334 -11
- package/dist/codecs.d.ts +48 -0
- package/dist/dialect.d.ts +44 -0
- package/dist/dialects/external-dependents.d.ts +28 -0
- package/dist/dialects/external-ownership.d.ts +8 -0
- package/dist/dialects/migration-shadow.d.ts +5 -0
- package/dist/dialects/postgres-index-keys.d.ts +10 -0
- package/dist/dialects/postgres-physical-catalog.d.ts +17 -0
- package/dist/dialects/sqlite-fts.d.ts +28 -0
- package/dist/exclusion.d.ts +2 -0
- package/dist/index-columns.d.ts +15 -0
- package/dist/index.d.ts +20 -5
- package/dist/index.js +1023 -273
- package/dist/index.js.map +28 -20
- package/dist/json-list-parameter.d.ts +37 -0
- package/dist/native-enum-parameter.d.ts +17 -0
- package/dist/pg-array.d.ts +13 -0
- package/dist/render.d.ts +11 -1
- package/package.json +5 -3
- package/dist/ast.d.ts.map +0 -1
- package/dist/capabilities.d.ts.map +0 -1
- package/dist/codecs.d.ts.map +0 -1
- package/dist/composable.d.ts.map +0 -1
- package/dist/dialect.d.ts.map +0 -1
- package/dist/dialects/constraint-owned-index.d.ts.map +0 -1
- package/dist/dialects/diagnostics.d.ts.map +0 -1
- package/dist/dialects/migration-history.d.ts.map +0 -1
- package/dist/dialects/migration-inventory.d.ts.map +0 -1
- package/dist/dialects/migration-objects.d.ts.map +0 -1
- package/dist/dialects/migration-replay-coverage.d.ts.map +0 -1
- package/dist/dialects/migration-shadow.d.ts.map +0 -1
- package/dist/dialects/migration-visibility.d.ts.map +0 -1
- package/dist/dialects/module-dependency.d.ts.map +0 -1
- package/dist/dialects/mysql-check-probe.d.ts.map +0 -1
- package/dist/dialects/mysql.d.ts.map +0 -1
- package/dist/dialects/postgres-default-identity.d.ts.map +0 -1
- package/dist/dialects/postgres-diagnostics.d.ts.map +0 -1
- package/dist/dialects/postgres-migration.d.ts.map +0 -1
- package/dist/dialects/postgres-rls-readiness.d.ts.map +0 -1
- package/dist/dialects/postgres-rls.d.ts.map +0 -1
- package/dist/dialects/postgres-type-identity.d.ts.map +0 -1
- package/dist/dialects/postgres.d.ts.map +0 -1
- package/dist/dialects/registry.d.ts.map +0 -1
- package/dist/dialects/sqlite-constraints.d.ts.map +0 -1
- package/dist/dialects/sqlite-session.d.ts.map +0 -1
- package/dist/dialects/sqlite-table-definition.d.ts.map +0 -1
- package/dist/dialects/sqlite.d.ts.map +0 -1
- package/dist/exclusion.d.ts.map +0 -1
- package/dist/identifiers.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/json-transport.d.ts.map +0 -1
- package/dist/like.d.ts.map +0 -1
- package/dist/locks.d.ts.map +0 -1
- package/dist/module-journal.d.ts.map +0 -1
- package/dist/params.d.ts.map +0 -1
- package/dist/pg-array.d.ts.map +0 -1
- package/dist/predicate.d.ts.map +0 -1
- package/dist/render.d.ts.map +0 -1
- package/dist/result-decoder.d.ts.map +0 -1
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 VibeORM contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/dist/ast.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { NativeEnumArrayParameter } from "./native-enum-parameter.ts";
|
|
2
|
+
import type { JsonListParameter } from "./json-list-parameter.ts";
|
|
1
3
|
import type { SqlFragment } from "./composable.ts";
|
|
2
4
|
import type { RlsReadinessQuery } from "./dialects/postgres-rls-readiness.ts";
|
|
3
5
|
/**
|
|
@@ -14,11 +16,15 @@ export type ColRef = {
|
|
|
14
16
|
readonly table?: string;
|
|
15
17
|
readonly name: string;
|
|
16
18
|
/**
|
|
17
|
-
* Projection-only wire transform, postgres
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
* `
|
|
19
|
+
* Projection-only wire transform, postgres only. `castText` renders
|
|
20
|
+
* `"col"::text AS "col"`, `encodeBase64` renders
|
|
21
|
+
* `encode("col", 'base64') AS "col"`. Two users: the lateral subselect (SQL
|
|
22
|
+
* review B3 — raw `to_jsonb` would ship BigInt/Decimal as float64 JSON
|
|
23
|
+
* numbers and Bytes as `\x` hex text), and every row projection of a
|
|
24
|
+
* `Float[]`/`Json[]` column (bun:sql's array parser refuses float arrays
|
|
25
|
+
* printed with an exponent and json arrays holding integers beyond int32;
|
|
26
|
+
* the runtime parses the array literal text itself). Never set on
|
|
27
|
+
* filter/order refs.
|
|
22
28
|
*/
|
|
23
29
|
readonly transform?: "castText" | "encodeBase64";
|
|
24
30
|
/**
|
|
@@ -29,6 +35,14 @@ export type ColRef = {
|
|
|
29
35
|
* storage and read-back stay the exact text.
|
|
30
36
|
*/
|
|
31
37
|
readonly castReal?: boolean;
|
|
38
|
+
/**
|
|
39
|
+
* Order/distinct/compare cast, postgres `json` columns only (`Json @db.Json`,
|
|
40
|
+
* release-3.0 D3): `json` has no ordering or equality operator, so ORDER BY,
|
|
41
|
+
* DISTINCT ON and comparison sites render `"col"::jsonb` (`"col"::jsonb[]`
|
|
42
|
+
* for a `json[]` list column) — the order and distinctness of a jsonb
|
|
43
|
+
* column. Never set on projections, so read-back keeps the stored text.
|
|
44
|
+
*/
|
|
45
|
+
readonly castJsonb?: "jsonb" | "jsonb[]";
|
|
32
46
|
/**
|
|
33
47
|
* Projection alias: renders `ref AS "alias"`. PROJECTION-ONLY — filter,
|
|
34
48
|
* order and correlation refs never set it (the renderer ignores it outside
|
|
@@ -39,6 +53,8 @@ export type ColRef = {
|
|
|
39
53
|
};
|
|
40
54
|
export type TableRef = {
|
|
41
55
|
readonly name: string;
|
|
56
|
+
/** Explicit fixed PostgreSQL placement; absence preserves existing SQL. */
|
|
57
|
+
readonly namespace?: string;
|
|
42
58
|
readonly alias?: string;
|
|
43
59
|
};
|
|
44
60
|
/** Aggregate functions applied to one column. */
|
|
@@ -90,6 +106,11 @@ export type SqlExpr = {
|
|
|
90
106
|
readonly column: ColRef;
|
|
91
107
|
readonly values: readonly unknown[];
|
|
92
108
|
readonly negate?: boolean;
|
|
109
|
+
/**
|
|
110
|
+
* The column holds a time of day (`@db.Time(n)` / `@db.Timetz(n)`): the
|
|
111
|
+
* dialect renders the membership per `SqlDialect.timeOfDayInStrategy`.
|
|
112
|
+
*/
|
|
113
|
+
readonly timeOfDay?: boolean;
|
|
93
114
|
}
|
|
94
115
|
/**
|
|
95
116
|
* ORDERED-TUPLE membership: `("a", "b") IN ((?, ?), (?, ?))`. The composite
|
|
@@ -180,13 +201,13 @@ export type SqlExpr = {
|
|
|
180
201
|
| {
|
|
181
202
|
readonly kind: "arrayContainsAll";
|
|
182
203
|
readonly column: ColRef;
|
|
183
|
-
readonly values: readonly unknown[];
|
|
204
|
+
readonly values: readonly unknown[] | string | NativeEnumArrayParameter | JsonListParameter;
|
|
184
205
|
}
|
|
185
206
|
/** Scalar-list overlap: `"col" && $n` (one array param) — Prisma's `hasSome`. Postgres only. */
|
|
186
207
|
| {
|
|
187
208
|
readonly kind: "arrayOverlaps";
|
|
188
209
|
readonly column: ColRef;
|
|
189
|
-
readonly values: readonly unknown[];
|
|
210
|
+
readonly values: readonly unknown[] | string | NativeEnumArrayParameter | JsonListParameter;
|
|
190
211
|
}
|
|
191
212
|
/**
|
|
192
213
|
* Scalar-list emptiness via `array_length("col", 1) IS [NOT] NULL` — the v1
|
|
@@ -213,6 +234,15 @@ export type SqlExpr = {
|
|
|
213
234
|
readonly value: unknown;
|
|
214
235
|
readonly insensitive?: boolean;
|
|
215
236
|
readonly negate?: boolean;
|
|
237
|
+
/**
|
|
238
|
+
* The column's postgres type: absent (or `jsonb`) for the default
|
|
239
|
+
* `jsonb`, `json` for `Json @db.Json`. Postgres defines `=`, `<>` and
|
|
240
|
+
* `@>` for jsonb only, so on a `json` column every op casts the
|
|
241
|
+
* EXTRACTED value to jsonb (the string ops then read it as text), which
|
|
242
|
+
* gives a jsonb column's answer. Sqlite and mysql have one JSON type
|
|
243
|
+
* and ignore it.
|
|
244
|
+
*/
|
|
245
|
+
readonly storage?: "jsonb" | "json";
|
|
216
246
|
}
|
|
217
247
|
/**
|
|
218
248
|
* A bound extension fragment: literal text, bound parameters and quoted
|
|
@@ -366,6 +396,24 @@ export type LateralJoin = {
|
|
|
366
396
|
/** The correlated child select — may reference outer columns via table-qualified refs. */
|
|
367
397
|
readonly select: SelectStatement;
|
|
368
398
|
};
|
|
399
|
+
/**
|
|
400
|
+
* One correlated scalar `COUNT(*)` projected into a select list:
|
|
401
|
+
* `(SELECT COUNT(*) FROM … WHERE <correlation>) AS "alias"` — the relation
|
|
402
|
+
* `_count` of the round-trip campaign's R-03b, which saves the separate grouped
|
|
403
|
+
* count statement. Portable: postgres, sqlite and mysql all evaluate a
|
|
404
|
+
* correlated scalar subquery once per output row; the runtime wraps a paged
|
|
405
|
+
* root in a derived table first, so the subqueries run only for the page.
|
|
406
|
+
* The select must be ONE ungrouped `COUNT(*)` (`columns: []`, `selectExpr`
|
|
407
|
+
* countAll, no grouping, paging, distinct or lock) — anything else is refused
|
|
408
|
+
* at render. Its parameters join the statement's single sequence in text order
|
|
409
|
+
* (the select list renders before FROM).
|
|
410
|
+
*/
|
|
411
|
+
export type CountSubquery = {
|
|
412
|
+
/** Output column the count is exposed under (`__vibe_count_0`). */
|
|
413
|
+
readonly alias: string;
|
|
414
|
+
/** The correlated count select — references outer columns via table-qualified refs. */
|
|
415
|
+
readonly select: SelectStatement;
|
|
416
|
+
};
|
|
369
417
|
/**
|
|
370
418
|
* One `INNER JOIN "table" AS alias ON left = right [AND …]` clause — plain
|
|
371
419
|
* equality joins only, portable across all dialects. Added for the
|
|
@@ -381,6 +429,75 @@ export type InnerJoin = {
|
|
|
381
429
|
readonly right: ColRef;
|
|
382
430
|
}[];
|
|
383
431
|
};
|
|
432
|
+
/**
|
|
433
|
+
* How one member of a {@link KeyTableJoin} tuple binds inside the derived
|
|
434
|
+
* table. `value` binds the parameter as it is: it stays COERCIBLE, so a text
|
|
435
|
+
* column's OWN collation decides `=` — the equality `col IN (?, …)` uses.
|
|
436
|
+
* `integer` and `decimal` cast the parameter into the column's numeric family:
|
|
437
|
+
* BigInt and Decimal values travel as strings, and a derived-table string
|
|
438
|
+
* compared with a numeric column goes through a double (measured on mysql:
|
|
439
|
+
* `9007199254740993` matched `9007199254740992`).
|
|
440
|
+
*
|
|
441
|
+
* `integer` renders `CAST(? AS SIGNED)`. `decimal` renders
|
|
442
|
+
* `CAST(? AS DECIMAL(65, scale))` with the tested column's own scale: 65 is
|
|
443
|
+
* MySQL's maximum precision, so the cast holds every value a
|
|
444
|
+
* `DECIMAL(p, scale)` column can hold. A fixed `DECIMAL(65,30)` held only 35
|
|
445
|
+
* integer digits and clipped a `Decimal(65, 0)` key onto its maximum, which
|
|
446
|
+
* matched nothing (review finding 1); the column's own precision would clip a
|
|
447
|
+
* wider value onto the column's maximum and pair it with a row it does not
|
|
448
|
+
* equal (measured: `CAST('100000' AS DECIMAL(5,0))` is `99999`). `scale` is
|
|
449
|
+
* 0–30, MySQL's range.
|
|
450
|
+
*
|
|
451
|
+
* `citext` (postgres only) renders `CAST($n AS citext)`: a postgres `citext`
|
|
452
|
+
* key compares case-insensitively, and a bare VALUES parameter would be
|
|
453
|
+
* `text`, whose `=` against a citext column is the case-sensitive text
|
|
454
|
+
* operator. A VALUES cell has no column to infer a type from, so every member
|
|
455
|
+
* of a postgres key table binds typed: `citext`, `text` (`CAST($n AS text)`,
|
|
456
|
+
* a text or varchar column) or `integer` (`CAST($n AS bigint)`, exact against
|
|
457
|
+
* any integer column) — any other member refuses on postgres. `text` is
|
|
458
|
+
* postgres-only; mysql binds text members as `value`.
|
|
459
|
+
*/
|
|
460
|
+
export type KeyTableMember = {
|
|
461
|
+
readonly kind: "value";
|
|
462
|
+
} | {
|
|
463
|
+
readonly kind: "integer";
|
|
464
|
+
} | {
|
|
465
|
+
readonly kind: "decimal";
|
|
466
|
+
readonly scale: number;
|
|
467
|
+
} | {
|
|
468
|
+
readonly kind: "citext";
|
|
469
|
+
} | {
|
|
470
|
+
readonly kind: "text";
|
|
471
|
+
};
|
|
472
|
+
/**
|
|
473
|
+
* The batch's key tuples as a derived table, each tagged with its ORDINAL
|
|
474
|
+
* (row `i` carries `i`), INNER JOINed on the tested columns — mysql:
|
|
475
|
+
* `INNER JOIN (VALUES ROW(?, 0), ROW(?, 1)) AS \`alias\` (\`__vibe_k0\`, \`ordinal\`)
|
|
476
|
+
* ON col = \`alias\`.\`__vibe_k0\``; postgres only over `citext` members
|
|
477
|
+
* (`(VALUES (CAST($1 AS citext), 0), …)`, release 3.0 nested writes).
|
|
478
|
+
* Member columns are named `__vibe_k<i>` (a reserved prefix, so unqualified
|
|
479
|
+
* child columns never collide with them).
|
|
480
|
+
*
|
|
481
|
+
* Why it exists (EPIC R): a relation load used to stitch children to parents
|
|
482
|
+
* by comparing decoded keys in JavaScript, while mysql's collations equate
|
|
483
|
+
* spellings (`acme` = `Acme` = `ACME`, `cafe` = `Café`, `x ` = `x`) that
|
|
484
|
+
* JavaScript keeps apart — the foreign key and the `IN` filter accepted the
|
|
485
|
+
* child, the stitch dropped it. Joined this way the DATABASE pairs every child
|
|
486
|
+
* row with every batch key it considers equal, and the projected ordinal names
|
|
487
|
+
* the key; the join is also the membership filter.
|
|
488
|
+
*/
|
|
489
|
+
export type KeyTableJoin = {
|
|
490
|
+
/** Derived-table alias (`__vibe_keys`); the ordinal projects as `alias.ordinalAlias`. */
|
|
491
|
+
readonly alias: string;
|
|
492
|
+
/** The statement's columns, compared member by member (`=`), in tuple order. */
|
|
493
|
+
readonly columns: readonly ColRef[];
|
|
494
|
+
/** How each member binds, in tuple order — see {@link KeyTableMember}. */
|
|
495
|
+
readonly members: readonly KeyTableMember[];
|
|
496
|
+
/** Encoded key tuples; never empty, each as long as `columns`. */
|
|
497
|
+
readonly rows: readonly (readonly unknown[])[];
|
|
498
|
+
/** Output name of the ordinal column. */
|
|
499
|
+
readonly ordinalAlias: string;
|
|
500
|
+
};
|
|
384
501
|
/**
|
|
385
502
|
* A `ROW_NUMBER() OVER (PARTITION BY … [ORDER BY …]) AS "alias"` projection,
|
|
386
503
|
* appended after `columns` — the distinct emulation on dialects without
|
|
@@ -410,6 +527,8 @@ export type SelectStatement = {
|
|
|
410
527
|
* combined with `selectExpr`.
|
|
411
528
|
*/
|
|
412
529
|
readonly aggregates?: readonly AggSelect[];
|
|
530
|
+
/** Correlated `COUNT(*)` subqueries, rendered after `aggregates` — see {@link CountSubquery}. */
|
|
531
|
+
readonly countSubqueries?: readonly CountSubquery[];
|
|
413
532
|
/**
|
|
414
533
|
* `SELECT DISTINCT ON (cols)` — postgres only (`capabilities.distinctOn`;
|
|
415
534
|
* other dialects refuse at render time and the runtime emulates client-side
|
|
@@ -427,6 +546,8 @@ export type SelectStatement = {
|
|
|
427
546
|
readonly lateralJoins?: readonly LateralJoin[];
|
|
428
547
|
/** Plain equality INNER JOINs — portable, see {@link InnerJoin}. */
|
|
429
548
|
readonly innerJoins?: readonly InnerJoin[];
|
|
549
|
+
/** Key-table join, rendered after `innerJoins` — mysql only, see {@link KeyTableJoin}. */
|
|
550
|
+
readonly keyTable?: KeyTableJoin;
|
|
430
551
|
/** ROW_NUMBER window projection — see {@link RowNumberProjection}. */
|
|
431
552
|
readonly rowNumber?: RowNumberProjection;
|
|
432
553
|
readonly where?: SqlExpr;
|
|
@@ -479,14 +600,21 @@ export declare function isSqlDefaultCell(value: unknown): boolean;
|
|
|
479
600
|
* Sqlite/mysql render the bare placeholder — their Json transport is already
|
|
480
601
|
* plain text. The COLLECTED parameter is the plain text either way: this
|
|
481
602
|
* wrapper never crosses the wire.
|
|
603
|
+
*
|
|
604
|
+
* `storage: "json"` marks a postgres `json` column (`Json @db.Json`): the cell
|
|
605
|
+
* renders `$n::text::json`, so the column stores the text as written (key
|
|
606
|
+
* order and spelling kept) instead of jsonb's normalized text (release-3.0
|
|
607
|
+
* D3). Absent = jsonb; dialects without a param cast ignore it.
|
|
482
608
|
*/
|
|
483
609
|
export type JsonParamCell = {
|
|
484
610
|
readonly __jsonParam: true;
|
|
485
611
|
readonly text: string;
|
|
612
|
+
readonly storage?: "json";
|
|
486
613
|
};
|
|
487
614
|
/** Wrap a Json column's encoded (stringified) parameter for cast-site rendering. */
|
|
488
615
|
export declare function jsonParamCell(params: {
|
|
489
616
|
text: string;
|
|
617
|
+
storage?: "json";
|
|
490
618
|
}): JsonParamCell;
|
|
491
619
|
/** Is this VALUES/SET cell a {@link JsonParamCell}? */
|
|
492
620
|
export declare function isJsonParamCell(value: unknown): value is JsonParamCell;
|
|
@@ -508,6 +636,17 @@ export declare function excludedRef(params: {
|
|
|
508
636
|
}): ExcludedRef;
|
|
509
637
|
/** Is this SET cell an {@link ExcludedRef}? */
|
|
510
638
|
export declare function isExcludedRef(value: unknown): value is ExcludedRef;
|
|
639
|
+
/**
|
|
640
|
+
* One RETURNING column: a bare column name renders `"col"`; the object form
|
|
641
|
+
* renders `"col"::text AS "col"` (postgres only) — the `Float[]`/`Json[]`
|
|
642
|
+
* projection rule {@link ColRef.transform} documents, applied to RETURNING.
|
|
643
|
+
*/
|
|
644
|
+
export type ReturningColumn = string | {
|
|
645
|
+
readonly name: string;
|
|
646
|
+
readonly castText: true;
|
|
647
|
+
};
|
|
648
|
+
/** The column name a {@link ReturningColumn} exposes in the result row. */
|
|
649
|
+
export declare function returningColumnName(column: ReturningColumn): string;
|
|
511
650
|
export type InsertStatement = {
|
|
512
651
|
readonly kind: "insert";
|
|
513
652
|
readonly table: TableRef;
|
|
@@ -517,7 +656,7 @@ export type InsertStatement = {
|
|
|
517
656
|
/** Upsert clause: ON CONFLICT (pg/sqlite) or ON DUPLICATE KEY (mysql). */
|
|
518
657
|
readonly onConflict?: OnConflictClause;
|
|
519
658
|
/** Rendered as RETURNING where the dialect supports it, else omitted+flagged. */
|
|
520
|
-
readonly returning?: readonly
|
|
659
|
+
readonly returning?: readonly ReturningColumn[];
|
|
521
660
|
};
|
|
522
661
|
/** Conflicting rows are updated with these column values. */
|
|
523
662
|
export type OnConflictUpdate = {
|
|
@@ -574,13 +713,13 @@ export type UpdateStatement = {
|
|
|
574
713
|
/** Column → parameter value, or an atomic {@link SetOperation}. */
|
|
575
714
|
readonly set: Readonly<Record<string, unknown>>;
|
|
576
715
|
readonly where?: SqlExpr;
|
|
577
|
-
readonly returning?: readonly
|
|
716
|
+
readonly returning?: readonly ReturningColumn[];
|
|
578
717
|
};
|
|
579
718
|
export type DeleteStatement = {
|
|
580
719
|
readonly kind: "delete";
|
|
581
720
|
readonly table: TableRef;
|
|
582
721
|
readonly where?: SqlExpr;
|
|
583
|
-
readonly returning?: readonly
|
|
722
|
+
readonly returning?: readonly ReturningColumn[];
|
|
584
723
|
};
|
|
585
724
|
/** Native RLS DDL, kept distinct from ordinary row-query expressions. */
|
|
586
725
|
export type RlsEnableStatement = {
|
|
@@ -660,7 +799,191 @@ export type AdvisoryLockStatement = {
|
|
|
660
799
|
};
|
|
661
800
|
/** The column an advisory try-lock projects its verdict into. */
|
|
662
801
|
export declare const ADVISORY_LOCK_RESULT_COLUMN: string;
|
|
663
|
-
|
|
802
|
+
/**
|
|
803
|
+
* A cell of an {@link InsertSelectStatement} that reads a column of an EARLIER
|
|
804
|
+
* chain step: `"step"."column"`. A column reference, not a parameter — the
|
|
805
|
+
* value comes from the step's rows inside the same statement (a child row
|
|
806
|
+
* taking its parent's key from the parent step, round-trip campaign EPIC F).
|
|
807
|
+
* The step must be named in the insert's `from` list.
|
|
808
|
+
*/
|
|
809
|
+
export type StepColumnRef = {
|
|
810
|
+
readonly __stepColumn: true;
|
|
811
|
+
readonly step: string;
|
|
812
|
+
readonly column: string;
|
|
813
|
+
};
|
|
814
|
+
/** Reference `column` of the earlier chain step `step` from an INSERT … SELECT cell. */
|
|
815
|
+
export declare function stepColumnRef(params: {
|
|
816
|
+
step: string;
|
|
817
|
+
column: string;
|
|
818
|
+
}): StepColumnRef;
|
|
819
|
+
/** Is this INSERT … SELECT cell a {@link StepColumnRef}? */
|
|
820
|
+
export declare function isStepColumnRef(value: unknown): value is StepColumnRef;
|
|
821
|
+
/**
|
|
822
|
+
* `INSERT INTO t (cols) SELECT <cells> [FROM "step", …] [WHERE <expr>]
|
|
823
|
+
* [RETURNING …]` — an INSERT whose ONE row is a SELECT list instead of a
|
|
824
|
+
* VALUES row, so a WHERE can veto the write inside the statement and cells can
|
|
825
|
+
* read earlier steps. Valid ONLY as a {@link ChainStep} statement.
|
|
826
|
+
*
|
|
827
|
+
* Cells take the same forms as a VALUES cell — a codec-encoded value, a
|
|
828
|
+
* {@link JsonParamCell}, a {@link DbNowMarker} — plus {@link StepColumnRef}.
|
|
829
|
+
* The {@link SQL_DEFAULT_CELL} is refused: `DEFAULT` is not allowed in a SELECT
|
|
830
|
+
* list; an omitted column takes its default by being absent from `columns`.
|
|
831
|
+
*
|
|
832
|
+
* Parameter typing (O-03, probed on PostgreSQL): a bare parameter in this
|
|
833
|
+
* one-row SELECT list takes the TARGET column's type, exactly as in VALUES.
|
|
834
|
+
*/
|
|
835
|
+
export type InsertSelectStatement = {
|
|
836
|
+
readonly kind: "insertSelect";
|
|
837
|
+
readonly table: TableRef;
|
|
838
|
+
readonly columns: readonly string[];
|
|
839
|
+
/** One cell per column, aligned to `columns` — deterministic parameter order. */
|
|
840
|
+
readonly cells: readonly unknown[];
|
|
841
|
+
/** Earlier chain steps the SELECT reads FROM, in order (absent: a one-row SELECT without FROM). */
|
|
842
|
+
readonly from?: readonly string[];
|
|
843
|
+
/**
|
|
844
|
+
* Several source rows (round-trip campaign EPIC F): the SELECT reads them
|
|
845
|
+
* from a derived table `alias`, joined after the `from` steps, and the
|
|
846
|
+
* `cells` read its columns through `stepColumnRef({ step: alias, column })`.
|
|
847
|
+
* See {@link ChainRowSource} for how the rows are typed.
|
|
848
|
+
*/
|
|
849
|
+
readonly source?: ChainRowSource;
|
|
850
|
+
readonly where?: SqlExpr;
|
|
851
|
+
readonly returning?: readonly ReturningColumn[];
|
|
852
|
+
};
|
|
853
|
+
/**
|
|
854
|
+
* Rows an {@link InsertSelectStatement} inserts, as ONE derived table:
|
|
855
|
+
* `(SELECT <cols> FROM (VALUES (<typed NULL row>), ($1, $2), …) AS "alias"
|
|
856
|
+
* (<cols>) OFFSET 1) AS "alias"`.
|
|
857
|
+
*
|
|
858
|
+
* Why the typed NULL row (review O-03): a bare parameter outside the INSERT's
|
|
859
|
+
* own VALUES has no type, and PostgreSQL resolves an all-parameter column of a
|
|
860
|
+
* VALUES list or UNION in FROM as `text` ("column is of type integer but
|
|
861
|
+
* expression is of type text"). The first row is one `(SELECT "col" FROM
|
|
862
|
+
* <typedBy> WHERE FALSE)` per column — a NULL of the TARGET column's exact
|
|
863
|
+
* type (enums, `numeric(p,s)`, `varchar(n)`, domains and arrays included) —
|
|
864
|
+
* so every parameter below takes that type, with no cast map anywhere;
|
|
865
|
+
* `OFFSET 1` drops the row. (A `UNION ALL` of one-row SELECTs types the same
|
|
866
|
+
* way but costs ~10× the planning time at 1000 rows — EPIC F shape gate.)
|
|
867
|
+
*
|
|
868
|
+
* Cells take the VALUES forms: a codec-encoded value, a {@link JsonParamCell}
|
|
869
|
+
* or a {@link DbNowMarker}; the DEFAULT cell is refused (a homogeneous row set
|
|
870
|
+
* omits the column instead). A cell carrying its OWN type (the Json cast, the
|
|
871
|
+
* clock) must agree with the column's type under VALUES' common-type rules,
|
|
872
|
+
* which are stricter than INSERT's assignment casts — the builder keeps such
|
|
873
|
+
* columns out (EPIC F eligibility). Rows are read in list order, which is the
|
|
874
|
+
* order the INSERT consumes them.
|
|
875
|
+
*/
|
|
876
|
+
export type ChainRowSource = {
|
|
877
|
+
readonly alias: string;
|
|
878
|
+
/** The table whose columns type the rows — normally the INSERT's own table. */
|
|
879
|
+
readonly typedBy: TableRef;
|
|
880
|
+
readonly columns: readonly string[];
|
|
881
|
+
/** At least one row, each aligned to `columns`. */
|
|
882
|
+
readonly rows: readonly (readonly unknown[])[];
|
|
883
|
+
};
|
|
884
|
+
/** What one chain step may be: a read, or a data-modifying statement with RETURNING. */
|
|
885
|
+
export type ChainStepStatement = SelectStatement | InsertStatement | InsertSelectStatement | UpdateStatement | DeleteStatement;
|
|
886
|
+
/**
|
|
887
|
+
* One named step: rendered `"name" AS (<statement>)`. Later steps and the
|
|
888
|
+
* result read it as a table (`FROM "name"`, `EXISTS (SELECT 1 FROM "name" …)`,
|
|
889
|
+
* a {@link StepColumnRef}). A data-modifying step contributes the rows its
|
|
890
|
+
* RETURNING list names.
|
|
891
|
+
*/
|
|
892
|
+
export type ChainStep = {
|
|
893
|
+
readonly name: string;
|
|
894
|
+
readonly statement: ChainStepStatement;
|
|
895
|
+
};
|
|
896
|
+
/**
|
|
897
|
+
* The chain's final SELECT: the rows of `rowsFrom` (in that order, `UNION
|
|
898
|
+
* ALL`), each projecting `columns`.
|
|
899
|
+
*
|
|
900
|
+
* `verdict` adds one column `alias` = `expr` to every row, AND guarantees a
|
|
901
|
+
* row: when the `rowsFrom` steps return nothing, the result is exactly ONE
|
|
902
|
+
* verdict row whose `columns` are all NULL. A caller recognizes it by NULL in
|
|
903
|
+
* a column the steps never return as NULL (a primary key). Accounting
|
|
904
|
+
* consequence: such a statement returns one row per written row OR one
|
|
905
|
+
* verdict row — a caller that counts returned rows as row changes must undo a
|
|
906
|
+
* verdict-row outcome (the upsert fold always rolls it back).
|
|
907
|
+
*/
|
|
908
|
+
export type ChainResult = {
|
|
909
|
+
readonly rowsFrom: readonly string[];
|
|
910
|
+
readonly columns: readonly string[];
|
|
911
|
+
readonly verdict?: {
|
|
912
|
+
readonly alias: string;
|
|
913
|
+
readonly expr: SqlExpr;
|
|
914
|
+
};
|
|
915
|
+
/**
|
|
916
|
+
* In-statement vetoes (round-trip campaign EPIC F), checked in order: when
|
|
917
|
+
* `step` returned no row (fewer than `minRows`, EPIC W), the STATEMENT FAILS — so the database undoes every
|
|
918
|
+
* effect of every step, trigger writes included — with an error whose
|
|
919
|
+
* message carries `__vibe_veto:<token>:<nonce>:` ({@link CHAIN_VETO_PREFIX},
|
|
920
|
+
* {@link chainVetoToken}). Requires `tally`: the veto is the tally column's
|
|
921
|
+
* guard, so it is evaluated exactly once, on the one guaranteed result row.
|
|
922
|
+
*/
|
|
923
|
+
readonly veto?: readonly ChainVeto[];
|
|
924
|
+
/**
|
|
925
|
+
* One column `alias` on every result row: the number of rows the listed
|
|
926
|
+
* data-modifying steps returned (their RETURNING rows = their direct
|
|
927
|
+
* effects). Guarantees one row like `verdict`. Row-change accounting reads
|
|
928
|
+
* it instead of counting result rows (effect `writeTally`).
|
|
929
|
+
*/
|
|
930
|
+
readonly tally?: ChainTally;
|
|
931
|
+
};
|
|
932
|
+
/**
|
|
933
|
+
* Fail the statement when `step` returned no row; `token` names the veto in the
|
|
934
|
+
* error. `nonce` is bound as a PARAMETER into the marker (never SQL text): a
|
|
935
|
+
* per-call random value the caller requires back in the error, so a user value
|
|
936
|
+
* that merely looks like a marker is never read as a veto.
|
|
937
|
+
*
|
|
938
|
+
* `minRows` (EPIC W) makes the veto count-sensitive: the statement fails when
|
|
939
|
+
* `step` returned FEWER rows than that (a multi-row INSERT a trigger shortened).
|
|
940
|
+
* Omitted or 1 = "no row". A positive safe integer, rendered as SQL text.
|
|
941
|
+
*/
|
|
942
|
+
export type ChainVeto = {
|
|
943
|
+
readonly step: string;
|
|
944
|
+
readonly token: string;
|
|
945
|
+
readonly nonce: string;
|
|
946
|
+
readonly minRows?: number;
|
|
947
|
+
};
|
|
948
|
+
/** Count the RETURNING rows of `steps` into the result column `alias`. */
|
|
949
|
+
export type ChainTally = {
|
|
950
|
+
readonly alias: string;
|
|
951
|
+
readonly steps: readonly string[];
|
|
952
|
+
};
|
|
953
|
+
/** Marker every chain veto error message carries, followed by `<token>:<nonce>:`. */
|
|
954
|
+
export declare const CHAIN_VETO_PREFIX: string;
|
|
955
|
+
/** Allowed veto tokens: lower-case words — they are rendered into SQL text. */
|
|
956
|
+
export declare const CHAIN_VETO_TOKEN_PATTERN: RegExp;
|
|
957
|
+
/**
|
|
958
|
+
* The veto token a database error message carries for this `nonce`, or
|
|
959
|
+
* `undefined`. Matches the marker anywhere in the text, so a localized server
|
|
960
|
+
* message (`lc_messages`) still yields it: the marker is the invalid VALUE the
|
|
961
|
+
* message quotes. A marker without the caller's nonce is not a veto.
|
|
962
|
+
*/
|
|
963
|
+
export declare function chainVetoToken(params: {
|
|
964
|
+
message: string;
|
|
965
|
+
nonce: string;
|
|
966
|
+
}): string | undefined;
|
|
967
|
+
/**
|
|
968
|
+
* ONE statement made of an ordered chain of named steps — reads (a locked
|
|
969
|
+
* probe) and data-modifying statements with RETURNING — ending in a final
|
|
970
|
+
* SELECT over them (round-trip campaign EPIC 4, reused by EPIC F). Renders as
|
|
971
|
+
* `WITH "a" AS (…), "b" AS (…) SELECT …` on a dialect whose
|
|
972
|
+
* `statementChain` strategy names the form (postgres); every other dialect
|
|
973
|
+
* refuses at render time (`VIBE_UNSUPPORTED_CAPABILITY`) — callers gate on
|
|
974
|
+
* the strategy first and keep their multi-statement path there.
|
|
975
|
+
*
|
|
976
|
+
* PostgreSQL semantics the builder relies on: every step sees ONE snapshot
|
|
977
|
+
* (a step never sees another step's writes — only its RETURNING rows), steps
|
|
978
|
+
* that reference a step run after it, and the statement is atomic: an error in
|
|
979
|
+
* any step undoes every step's effects, trigger writes included.
|
|
980
|
+
*/
|
|
981
|
+
export type ChainStatement = {
|
|
982
|
+
readonly kind: "chain";
|
|
983
|
+
readonly steps: readonly ChainStep[];
|
|
984
|
+
readonly result: ChainResult;
|
|
985
|
+
};
|
|
986
|
+
export type SqlStatement = SelectStatement | InsertStatement | UpdateStatement | DeleteStatement | RlsEnableStatement | RlsForceStatement | RlsDisableStatement | RlsNoForceStatement | RlsDropPolicyStatement | RlsPolicyStatement | RlsContextStatement | RlsRoleStatement | AdvisoryLockStatement | ChainStatement;
|
|
664
987
|
/** Readiness statements remain distinct from application queries. */
|
|
665
988
|
export type RlsReadinessStatement = {
|
|
666
989
|
readonly kind: "rlsReadiness";
|
package/dist/codecs.d.ts
CHANGED
|
@@ -113,6 +113,54 @@ export declare function decodeIsNoop(params: {
|
|
|
113
113
|
export declare function parseDateTimeText(params: {
|
|
114
114
|
text: string;
|
|
115
115
|
}): Date | undefined;
|
|
116
|
+
/**
|
|
117
|
+
* The time-of-day codec for a DateTime field's native type, or `undefined`
|
|
118
|
+
* when the native type is not `time`/`timetz` (the DateTime table row
|
|
119
|
+
* applies). The one native-type rule is `timeOfDayType` in @vibeorm/schema,
|
|
120
|
+
* shared with the dialect refusal in schema validation.
|
|
121
|
+
*/
|
|
122
|
+
export declare function timeOfDayCodec(params: {
|
|
123
|
+
nativeType: string | undefined;
|
|
124
|
+
}): ScalarCodec | undefined;
|
|
125
|
+
/**
|
|
126
|
+
* The SHORTEST decimal that round-trips through float32 to the same value as
|
|
127
|
+
* `value` — what postgres itself prints for a `real` (`0.1`, `3.4028235e+38`).
|
|
128
|
+
*
|
|
129
|
+
* A driver that reads a `real` in BINARY format (bun:sql with named
|
|
130
|
+
* statements) hands back the float32 widened to float64:
|
|
131
|
+
* `0.10000000149011612` for a stored `0.1`. Text-format drivers already give
|
|
132
|
+
* the short form, and for those this is the identity — the shortest form of a
|
|
133
|
+
* short value is itself — so it is safe on every driver. Smallest `p` in 1..9
|
|
134
|
+
* with `fround(toPrecision(p)) === fround(value)`; nine significant digits
|
|
135
|
+
* always identify a float32. `±0`, NaN and ±Infinity pass through.
|
|
136
|
+
*/
|
|
137
|
+
export declare function shortestFloat32(params: {
|
|
138
|
+
value: number;
|
|
139
|
+
}): number;
|
|
140
|
+
/**
|
|
141
|
+
* `Float @db.Real` — a refinement of the Float codec keyed by the native type,
|
|
142
|
+
* not by the scalar type, so it is not a table row: the runtime routes a
|
|
143
|
+
* field with `nativeType: "Real"` here. Decode = {@link numberCodec} then
|
|
144
|
+
* {@link shortestFloat32}. Real aggregates that postgres returns as `real`
|
|
145
|
+
* (`min`/`max`/`sum`) use it too; `avg` returns double precision and must not.
|
|
146
|
+
*/
|
|
147
|
+
export declare const float32Codec: ScalarCodec;
|
|
148
|
+
/**
|
|
149
|
+
* Element decoders for a postgres array that arrived as its TEXT literal
|
|
150
|
+
* (`{1e-07,NULL}`, `{"{\"a\": 1}"}`) — the runtime projects `Float[]`/`Json[]`
|
|
151
|
+
* as `::text`, and drivers return arrays whose type OID they do not know
|
|
152
|
+
* (`uuid[]` on bun:sql; `xml[]`, `bit[]`, `citext[]` on node-postgres) as the
|
|
153
|
+
* literal. Each element is postgres's text output for its type:
|
|
154
|
+
*
|
|
155
|
+
* - Boolean `t`/`f`, Bytes `\x` hex and Json text need their own conversion;
|
|
156
|
+
* - every other scalar's regular postgres codec already accepts the text form
|
|
157
|
+
* (`Number("1e-07")`, `Number("NaN")`, `Number("-0")`, BigInt/Decimal text,
|
|
158
|
+
* `parseDateTimeText` for `2024-06-01 12:34:56.789+00`), so `null` means
|
|
159
|
+
* "decode with the field's own codec".
|
|
160
|
+
*/
|
|
161
|
+
export declare function postgresArrayElementFromText(params: {
|
|
162
|
+
scalarType: ScalarType;
|
|
163
|
+
}): ((text: string) => unknown) | null;
|
|
116
164
|
/** postgres (and pglite — same wire behaviour). */
|
|
117
165
|
export declare const POSTGRES_CODECS: CodecTable;
|
|
118
166
|
/** sqlite — no boolean, date or json types; everything rides TEXT/INTEGER. */
|
package/dist/dialect.d.ts
CHANGED
|
@@ -72,6 +72,14 @@ export type ConflictKeyEquality = {
|
|
|
72
72
|
* created otherwise, and sqlite's default collating sequence is BINARY);
|
|
73
73
|
* mysql does not, because its server default `utf8mb4_0900_ai_ci` ignores
|
|
74
74
|
* case and accents.
|
|
75
|
+
*
|
|
76
|
+
* Consumers: the batched upsert's duplicate-key check
|
|
77
|
+
* (packages/runtime/src/bulk-upsert.ts) and the relation loader
|
|
78
|
+
* (packages/runtime/src/relation-loader.ts, `associatesInDatabase`). Where
|
|
79
|
+
* this is false, a relation key with a `String` member is paired with its
|
|
80
|
+
* parents by the DATABASE through a key table (`SelectStatement.keyTable`,
|
|
81
|
+
* mysql only) instead of by JavaScript string equality, which would drop
|
|
82
|
+
* children whose key the collation equates (`acme` under `Acme`).
|
|
75
83
|
*/
|
|
76
84
|
readonly textIsBinaryByDefault: boolean;
|
|
77
85
|
/** Character capacity of the default String column, if bounded. Also consumed by migrate. */
|
|
@@ -100,6 +108,15 @@ export type SqlDialect = {
|
|
|
100
108
|
* member, so composite membership always chunks against `paramBudget`.
|
|
101
109
|
*/
|
|
102
110
|
readonly tupleInStrategy: "rowValue" | "expand";
|
|
111
|
+
/**
|
|
112
|
+
* Membership on a time-of-day column (`inArray` with `timeOfDay`): `in`
|
|
113
|
+
* renders like any other membership; `equalities` renders an OR of `=`
|
|
114
|
+
* comparisons. MySQL 8.4 types a `?` inside a multi-value IN list against a
|
|
115
|
+
* TIME(n) column as TIME(6) and matches nothing unless n is 6 (live on
|
|
116
|
+
* 8.4.11; 26.7 matches); `=` converts the parameter to the column's TIME on
|
|
117
|
+
* every version.
|
|
118
|
+
*/
|
|
119
|
+
readonly timeOfDayInStrategy: "in" | "equalities";
|
|
103
120
|
/** Upsert clause form. */
|
|
104
121
|
readonly upsertForm: "onConflict" | "onDuplicateKey";
|
|
105
122
|
/** Which equality decides a duplicate conflict key here (batched upsert). */
|
|
@@ -136,6 +153,20 @@ export type SqlDialect = {
|
|
|
136
153
|
* non-native dialects — documented in docs/dialect-notes.md.
|
|
137
154
|
*/
|
|
138
155
|
readonly strictMatchStrategy: "native" | "glob" | "binary";
|
|
156
|
+
/**
|
|
157
|
+
* `sql.greatest` (NULL-ignoring two-operand maximum): `native` renders
|
|
158
|
+
* `GREATEST(l, r)`, whose PostgreSQL semantics already ignore NULL; `frame`
|
|
159
|
+
* binds both operands once in a correlated derived table and compares the
|
|
160
|
+
* bound columns with CASE (MySQL's GREATEST returns NULL on any NULL, and
|
|
161
|
+
* SQLite has none). `wrapped-frame` is the frame with each operand in its own
|
|
162
|
+
* scalar subquery: MySQL 8.4 refuses a derived-table select list that holds a
|
|
163
|
+
* nested frame beside a direct outer column reference (ER_ILLEGAL_REFERENCE
|
|
164
|
+
* 1247). In both frames a bare NULL value operand renders as the NULL
|
|
165
|
+
* literal. Only a node with a nested greatest operand uses a frame; a node
|
|
166
|
+
* without one keeps the 2.x CASE form (2.x semantics, types and aggregate
|
|
167
|
+
* scope), which repeats its two operands, so nesting stays linear.
|
|
168
|
+
*/
|
|
169
|
+
readonly greatestForm: "native" | "frame" | "wrapped-frame";
|
|
139
170
|
/** ORDER BY NULLS FIRST/LAST: native clause or `col IS NULL` emulation term. */
|
|
140
171
|
readonly orderByNullsMode: "native" | "emulate";
|
|
141
172
|
/** Dialects where OFFSET requires a LIMIT clause declare the filler literal. */
|
|
@@ -197,6 +228,19 @@ export type SqlDialect = {
|
|
|
197
228
|
* rows are grouped by column set into separate statements there (M4).
|
|
198
229
|
*/
|
|
199
230
|
readonly rowDefaultKeyword: boolean;
|
|
231
|
+
/**
|
|
232
|
+
* How a {@link ChainStatement} (an ordered chain of read and data-modifying
|
|
233
|
+
* steps ending in one SELECT — round-trip campaign EPIC 4/F) renders, or
|
|
234
|
+
* `null` where the dialect cannot run one as a single statement.
|
|
235
|
+
* `dataModifyingCte` is PostgreSQL's `WITH "step" AS (INSERT/UPDATE/DELETE …
|
|
236
|
+
* RETURNING …) SELECT …` (PGlite included). SQLite and MySQL accept only
|
|
237
|
+
* SELECT inside WITH, so they are `null`: the runtime keeps its
|
|
238
|
+
* multi-statement path there (an optimisation, not a feature — plan D4) and
|
|
239
|
+
* the renderer refuses a chain with `VIBE_UNSUPPORTED_CAPABILITY`. An
|
|
240
|
+
* internal SQL-shape strategy, deliberately NOT in the public capability
|
|
241
|
+
* table (review O-11).
|
|
242
|
+
*/
|
|
243
|
+
readonly statementChain: "dataModifyingCte" | null;
|
|
200
244
|
/**
|
|
201
245
|
* Conservative bound-parameter budget per statement (M7). Hard limits:
|
|
202
246
|
* sqlite errors past SQLITE_MAX_VARIABLE_NUMBER (32766 by default), mysql
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { SqlDialect } from "../dialect.ts";
|
|
2
|
+
import type { RenderedQuery } from "../render.ts";
|
|
3
|
+
/** An application type, relation or column whose planned drop or retype must not break another owner's objects. */
|
|
4
|
+
export type ExternalDependentTarget = {
|
|
5
|
+
readonly kind: "type" | "relation";
|
|
6
|
+
readonly namespace: string;
|
|
7
|
+
readonly name: string;
|
|
8
|
+
} | {
|
|
9
|
+
readonly kind: "column";
|
|
10
|
+
readonly namespace: string;
|
|
11
|
+
readonly name: string;
|
|
12
|
+
readonly column: string;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Normal (`deptype = 'n'`) catalog dependents of each target, answered per
|
|
16
|
+
* target position. A target covers its array type; a relation also covers its
|
|
17
|
+
* row type, and a relation or column also covers the sequences it owns
|
|
18
|
+
* (identity and serial), whose dependents are what a drop would break. Each
|
|
19
|
+
* dependent is anchored to its relation (columns, defaults, view rules,
|
|
20
|
+
* triggers, table constraints, policies, composite types) or to its own
|
|
21
|
+
* namespace and name (routines, domains), so ownership can be decided outside
|
|
22
|
+
* SQL. Read-only.
|
|
23
|
+
*/
|
|
24
|
+
export declare function renderExternalDependents(params: {
|
|
25
|
+
dialect: SqlDialect;
|
|
26
|
+
targets: readonly ExternalDependentTarget[];
|
|
27
|
+
}): RenderedQuery;
|
|
28
|
+
//# sourceMappingURL=external-dependents.d.ts.map
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { SqlDialect } from "../dialect.ts";
|
|
2
|
+
import type { RenderedQuery } from "../render.ts";
|
|
3
|
+
/** Complete catalog ownership edges, including endpoints outside the migration namespace. */
|
|
4
|
+
export declare function renderExternalOwnershipCatalog(params: {
|
|
5
|
+
dialect: SqlDialect;
|
|
6
|
+
operation: "namespaces" | "inheritance" | "ownedSequences" | "foreignKeys";
|
|
7
|
+
}): RenderedQuery;
|
|
8
|
+
//# sourceMappingURL=external-ownership.d.ts.map
|
|
@@ -28,6 +28,11 @@ export type ShadowOperation = {
|
|
|
28
28
|
readonly insert: boolean;
|
|
29
29
|
} | {
|
|
30
30
|
readonly kind: "resetPostgres";
|
|
31
|
+
}
|
|
32
|
+
/** `ownedNamespaces` must come from a validated dedicated-shadow marker or declared package configuration for db reset, never from discovery. */
|
|
33
|
+
| {
|
|
34
|
+
readonly kind: "resetDedicatedPostgres";
|
|
35
|
+
readonly ownedNamespaces: readonly string[];
|
|
31
36
|
} | {
|
|
32
37
|
readonly kind: "mysqlForeignKeys";
|
|
33
38
|
readonly enabled: boolean;
|