@vibeorm/sql 2.3.1 → 2.5.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/dist/index.js CHANGED
@@ -1,5 +1,40 @@
1
1
  // @bun
2
+ // packages/sql/src/native-enum-parameter.ts
3
+ var NATIVE_ENUM_ARRAY_PARAMETER = Symbol("vibeorm.nativeEnumArrayParameter");
4
+ function nativeEnumArrayParameter(params) {
5
+ return { [NATIVE_ENUM_ARRAY_PARAMETER]: true, value: params.value, type: params.type };
6
+ }
7
+ function isNativeEnumArrayParameter(value) {
8
+ return typeof value === "object" && value !== null && NATIVE_ENUM_ARRAY_PARAMETER in value;
9
+ }
10
+ // packages/sql/src/dialects/external-ownership.ts
11
+ import { unsupportedCapability } from "@vibeorm/schema";
12
+ function renderExternalOwnershipCatalog(params) {
13
+ if (params.dialect.name !== "postgres")
14
+ throw unsupportedCapability({ dialect: params.dialect.name, feature: "externalObjects" });
15
+ const scope = "n.nspname <> 'information_schema' AND n.nspname NOT LIKE 'pg\\_%' ESCAPE '\\' AND n.nspname NOT IN ('_vibeorm_shadow', '_vibe_shadow')";
16
+ let text;
17
+ switch (params.operation) {
18
+ case "namespaces":
19
+ text = `SELECT n.nspname::text AS namespace, has_schema_privilege(n.oid, 'USAGE') AS visible FROM pg_catalog.pg_namespace n WHERE ${scope} ORDER BY n.nspname`;
20
+ break;
21
+ case "inheritance":
22
+ text = `SELECT n.nspname::text AS namespace, c.relname::text AS name, pn.nspname::text AS "parentNamespace", p.relname::text AS "parentName" FROM pg_catalog.pg_inherits i JOIN pg_catalog.pg_class c ON c.oid = i.inhrelid JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace JOIN pg_catalog.pg_class p ON p.oid = i.inhparent JOIN pg_catalog.pg_namespace pn ON pn.oid = p.relnamespace WHERE ${scope} ORDER BY n.nspname, c.relname, pn.nspname, p.relname`;
23
+ break;
24
+ case "ownedSequences":
25
+ text = `SELECT n.nspname::text AS namespace, s.relname::text AS name, tn.nspname::text AS "tableNamespace", t.relname::text AS "tableName" FROM pg_catalog.pg_depend d JOIN pg_catalog.pg_class s ON s.oid = d.objid AND s.relkind = 'S' JOIN pg_catalog.pg_namespace n ON n.oid = s.relnamespace JOIN pg_catalog.pg_class t ON t.oid = d.refobjid JOIN pg_catalog.pg_namespace tn ON tn.oid = t.relnamespace WHERE d.classid = 'pg_class'::regclass AND d.refclassid = 'pg_class'::regclass AND d.deptype IN ('a', 'i') AND d.refobjsubid > 0 AND ${scope} ORDER BY n.nspname, s.relname`;
26
+ break;
27
+ case "foreignKeys":
28
+ text = `SELECT n.nspname::text AS namespace, t.relname::text AS table, rn.nspname::text AS "refNamespace", r.relname::text AS "refTable", c.conname::text AS name FROM pg_catalog.pg_constraint c JOIN pg_catalog.pg_class t ON t.oid = c.conrelid JOIN pg_catalog.pg_namespace n ON n.oid = t.relnamespace JOIN pg_catalog.pg_class r ON r.oid = c.confrelid JOIN pg_catalog.pg_namespace rn ON rn.oid = r.relnamespace WHERE c.contype = 'f' AND ${scope} ORDER BY n.nspname, t.relname, c.conname`;
29
+ break;
30
+ }
31
+ return { text, values: [], returning: "none" };
32
+ }
33
+ // packages/sql/src/dialects/external-dependents.ts
34
+ import { unsupportedCapability as unsupportedCapability3 } from "@vibeorm/schema";
35
+
2
36
  // packages/sql/src/params.ts
37
+ import { unsupportedCapability as unsupportedCapability2 } from "@vibeorm/schema";
3
38
  class ParamCollector {
4
39
  dialect;
5
40
  values;
@@ -8,6 +43,12 @@ class ParamCollector {
8
43
  this.values = [];
9
44
  }
10
45
  add(value) {
46
+ if (isNativeEnumArrayParameter(value)) {
47
+ if (!this.dialect.capabilities.scalarArrays)
48
+ throw unsupportedCapability2({ dialect: this.dialect.name, feature: "scalarArrays" });
49
+ this.values.push(value.value);
50
+ return `${this.dialect.placeholder({ index: this.values.length })}::${this.dialect.quoteIdent({ name: value.type.namespace })}.${this.dialect.quoteIdent({ name: value.type.name })}[]`;
51
+ }
11
52
  this.values.push(value);
12
53
  return this.dialect.placeholder({ index: this.values.length });
13
54
  }
@@ -16,6 +57,121 @@ class ParamCollector {
16
57
  }
17
58
  }
18
59
 
60
+ // packages/sql/src/dialects/external-dependents.ts
61
+ function renderExternalDependents(params) {
62
+ if (params.dialect.name !== "postgres")
63
+ throw unsupportedCapability3({ dialect: params.dialect.name, feature: "externalObjects" });
64
+ const collector = new ParamCollector(params.dialect);
65
+ const requests = params.targets.map((target, position) => ({ position, kind: target.kind, namespace: target.namespace, name: target.name, column: target.kind === "column" ? target.column : null }));
66
+ const request = collector.add(JSON.stringify(requests));
67
+ const text = `WITH request AS (
68
+ SELECT * FROM jsonb_to_recordset(${request}::text::jsonb) AS request(position integer, kind text, namespace text, name text, "column" text)
69
+ ), target AS (
70
+ SELECT request.position, 'pg_type'::regclass AS classid, t.oid AS objid, NULL::integer AS objsubid FROM request JOIN pg_catalog.pg_namespace n ON n.nspname = request.namespace JOIN pg_catalog.pg_type t ON t.typnamespace = n.oid AND t.typname = request.name WHERE request.kind = 'type'
71
+ UNION ALL SELECT request.position, 'pg_class'::regclass, c.oid, a.attnum::integer FROM request JOIN pg_catalog.pg_namespace n ON n.nspname = request.namespace JOIN pg_catalog.pg_class c ON c.relnamespace = n.oid AND c.relname = request.name LEFT JOIN pg_catalog.pg_attribute a ON request.kind = 'column' AND a.attrelid = c.oid AND a.attname = request."column" AND NOT a.attisdropped WHERE request.kind = 'relation' OR request.kind = 'column' AND a.attnum IS NOT NULL
72
+ ), owned AS (
73
+ SELECT position, classid, objid, objsubid FROM target
74
+ UNION SELECT target.position, 'pg_type'::regclass, c.reltype, NULL FROM target JOIN pg_catalog.pg_class c ON c.oid = target.objid WHERE target.classid = 'pg_class'::regclass AND target.objsubid IS NULL AND c.reltype <> 0
75
+ UNION SELECT target.position, 'pg_class'::regclass, s.oid, NULL FROM target JOIN pg_catalog.pg_depend sd ON sd.refclassid = target.classid AND sd.refobjid = target.objid AND (target.objsubid IS NULL OR sd.refobjsubid = target.objsubid) AND sd.classid = 'pg_class'::regclass AND sd.deptype IN ('a', 'i') JOIN pg_catalog.pg_class s ON s.oid = sd.objid AND s.relkind = 'S'
76
+ ), referenced AS (
77
+ SELECT position, classid, objid, objsubid FROM owned
78
+ UNION SELECT owned.position, 'pg_type'::regclass, t.typarray, NULL FROM owned JOIN pg_catalog.pg_type t ON t.oid = owned.objid WHERE owned.classid = 'pg_type'::regclass AND t.typarray <> 0
79
+ )
80
+ SELECT DISTINCT referenced.position, dependent.type AS "dependentType", dependent.identity AS "dependentIdentity", ref.identity AS referenced, d.classid::regclass::text AS "dependentClass",
81
+ rn.nspname::text AS "relationNamespace", rel.relname::text AS "relationName", rel.relkind::text AS "relationKind", col.attname::text AS "columnName",
82
+ COALESCE(pn.nspname, tn.nspname, dependent.schema)::text AS "objectNamespace", COALESCE(p.proname, ty.typname)::text AS "objectName"
83
+ FROM referenced
84
+ JOIN pg_catalog.pg_depend d ON d.refclassid = referenced.classid AND d.refobjid = referenced.objid AND (referenced.objsubid IS NULL OR d.refobjsubid = referenced.objsubid) AND d.deptype = 'n'
85
+ CROSS JOIN LATERAL pg_catalog.pg_identify_object(d.classid, d.objid, d.objsubid) dependent
86
+ CROSS JOIN LATERAL pg_catalog.pg_identify_object(d.refclassid, d.refobjid, d.refobjsubid) ref
87
+ LEFT JOIN pg_catalog.pg_class self ON d.classid = 'pg_class'::regclass AND self.oid = d.objid
88
+ LEFT JOIN pg_catalog.pg_index ix ON ix.indexrelid = self.oid
89
+ LEFT JOIN pg_catalog.pg_attrdef ad ON d.classid = 'pg_attrdef'::regclass AND ad.oid = d.objid
90
+ LEFT JOIN pg_catalog.pg_rewrite rw ON d.classid = 'pg_rewrite'::regclass AND rw.oid = d.objid
91
+ LEFT JOIN pg_catalog.pg_trigger tg ON d.classid = 'pg_trigger'::regclass AND tg.oid = d.objid
92
+ LEFT JOIN pg_catalog.pg_constraint con ON d.classid = 'pg_constraint'::regclass AND con.oid = d.objid
93
+ LEFT JOIN pg_catalog.pg_policy pol ON d.classid = 'pg_policy'::regclass AND pol.oid = d.objid
94
+ LEFT JOIN pg_catalog.pg_type ty ON d.classid = 'pg_type'::regclass AND ty.oid = d.objid
95
+ LEFT JOIN pg_catalog.pg_namespace tn ON tn.oid = ty.typnamespace
96
+ LEFT JOIN pg_catalog.pg_proc p ON d.classid = 'pg_proc'::regclass AND p.oid = d.objid
97
+ LEFT JOIN pg_catalog.pg_namespace pn ON pn.oid = p.pronamespace
98
+ LEFT JOIN pg_catalog.pg_class rel ON rel.oid = COALESCE(ix.indrelid, self.oid, ad.adrelid, rw.ev_class, tg.tgrelid, NULLIF(con.conrelid, 0), pol.polrelid, NULLIF(ty.typrelid, 0))
99
+ LEFT JOIN pg_catalog.pg_namespace rn ON rn.oid = rel.relnamespace
100
+ LEFT JOIN pg_catalog.pg_attribute col ON col.attrelid = rel.oid AND col.attnum = CASE WHEN self.oid IS NOT NULL AND d.objsubid > 0 THEN d.objsubid WHEN ad.oid IS NOT NULL THEN ad.adnum END
101
+ ORDER BY 1, 2, 3, 4`;
102
+ return { text, values: collector.values, returning: "none" };
103
+ }
104
+ // packages/sql/src/dialects/postgres-physical-catalog.ts
105
+ import { unsupportedCapability as unsupportedCapability4 } from "@vibeorm/schema";
106
+ function renderPostgresPhysicalCatalog(params) {
107
+ const { dialect } = params;
108
+ if (dialect.name !== "postgres")
109
+ throw unsupportedCapability4({ dialect: dialect.name, feature: "postgresPhysicalCatalog" });
110
+ const collector = new ParamCollector(dialect);
111
+ const namespace = collector.add(params.namespace);
112
+ const extensionOwnedFilter = `NOT EXISTS (SELECT 1 FROM pg_catalog.pg_depend d JOIN pg_catalog.pg_class c ON c.oid = d.objid JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace WHERE d.classid = 'pg_class'::regclass AND d.deptype = 'e' AND n.nspname = ${namespace} AND c.relname = table_name)`;
113
+ let text;
114
+ switch (params.query) {
115
+ case "tables":
116
+ text = `SELECT table_name FROM information_schema.tables WHERE table_schema = ${namespace} AND table_type = 'BASE TABLE' AND table_name <> '_vibe_migrations' AND ${extensionOwnedFilter} ORDER BY table_name`;
117
+ break;
118
+ case "views":
119
+ text = `SELECT table_name FROM information_schema.views WHERE table_schema = ${namespace} AND ${extensionOwnedFilter} ORDER BY table_name`;
120
+ break;
121
+ case "columns":
122
+ text = `SELECT table_name, column_name, data_type, udt_name, udt_schema, is_nullable, is_identity, is_generated, collation_name, column_default, datetime_precision, character_maximum_length, numeric_precision, numeric_scale, ordinal_position, (SELECT format_type(a.atttypid, a.atttypmod) FROM pg_attribute a JOIN pg_class c ON c.oid = a.attrelid JOIN pg_namespace n ON n.oid = c.relnamespace WHERE n.nspname = ${namespace} AND c.relname = columns.table_name AND a.attname = columns.column_name) AS full_type FROM information_schema.columns AS columns WHERE table_schema = ${namespace} ORDER BY table_name, ordinal_position`;
123
+ break;
124
+ case "constraints":
125
+ text = `SELECT c.conname AS constraint_name, CASE c.contype WHEN 'p' THEN 'PRIMARY KEY' ELSE 'UNIQUE' END AS constraint_type, cl.relname AS table_name, att.attname AS column_name FROM pg_catalog.pg_constraint c JOIN pg_catalog.pg_class cl ON cl.oid = c.conrelid JOIN pg_catalog.pg_namespace n ON n.oid = cl.relnamespace JOIN unnest(c.conkey) WITH ORDINALITY AS k(attnum, ord) ON true JOIN pg_catalog.pg_attribute att ON att.attrelid = c.conrelid AND att.attnum = k.attnum WHERE c.contype IN ('p', 'u') AND n.nspname = ${namespace} ORDER BY cl.relname, c.conname, k.ord`;
126
+ break;
127
+ case "checks":
128
+ text = `SELECT cl.relname AS table_name, c.conname AS constraint_name, pg_get_constraintdef(c.oid) AS definition FROM pg_catalog.pg_constraint c JOIN pg_catalog.pg_class cl ON cl.oid = c.conrelid JOIN pg_catalog.pg_namespace n ON n.oid = cl.relnamespace WHERE c.contype = 'c' AND n.nspname = ${namespace} ORDER BY cl.relname, c.conname`;
129
+ break;
130
+ case "foreignKeys":
131
+ text = `SELECT c.conname AS constraint_name, cl.relname AS table_name, att.attname AS column_name, fn.nspname AS foreign_namespace, fcl.relname AS foreign_table_name, fatt.attname AS foreign_column_name, c.confdeltype AS on_delete_char, c.confupdtype AS on_update_char, c.convalidated AS validated, c.condeferrable AS deferrable, (SELECT bool_and(t.tgenabled IN ('O', 'A')) FROM pg_catalog.pg_trigger t WHERE t.tgconstraint = c.oid) AS triggers_enabled FROM pg_catalog.pg_constraint c JOIN pg_catalog.pg_class cl ON cl.oid = c.conrelid JOIN pg_catalog.pg_namespace n ON n.oid = cl.relnamespace JOIN pg_catalog.pg_class fcl ON fcl.oid = c.confrelid JOIN pg_catalog.pg_namespace fn ON fn.oid = fcl.relnamespace JOIN unnest(c.conkey) WITH ORDINALITY AS lk(attnum, ord) ON true JOIN unnest(c.confkey) WITH ORDINALITY AS rk(attnum, ord) ON lk.ord = rk.ord JOIN pg_catalog.pg_attribute att ON att.attrelid = c.conrelid AND att.attnum = lk.attnum JOIN pg_catalog.pg_attribute fatt ON fatt.attrelid = c.confrelid AND fatt.attnum = rk.attnum WHERE c.contype = 'f' AND n.nspname = ${namespace} ORDER BY cl.relname, c.conname, lk.ord`;
132
+ break;
133
+ case "enums":
134
+ text = `SELECT t.typname AS type_name, n.nspname AS type_namespace, e.enumlabel AS enum_value, e.enumsortorder AS sort_order FROM pg_type t JOIN pg_enum e ON t.oid = e.enumtypid JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace WHERE n.nspname = ${namespace} ORDER BY t.typname, e.enumsortorder`;
135
+ break;
136
+ case "indexes":
137
+ text = `SELECT tablename AS table_name, indexname AS index_name, indexdef AS index_def, con.conname AS backing_constraint, con.contype AS backing_constraint_type, health.indisvalid AS valid, health.indisready AS ready, health.indimmediate AS immediate, health.indexprs IS NULL AS plain_columns, health.indnkeyatts AS key_count, health.indnatts AS attribute_count FROM pg_indexes ix JOIN pg_catalog.pg_namespace ns ON ns.nspname = ix.schemaname JOIN pg_catalog.pg_class idx ON idx.relnamespace = ns.oid AND idx.relname = ix.indexname JOIN pg_catalog.pg_index health ON health.indexrelid = idx.oid LEFT JOIN pg_catalog.pg_constraint con ON con.conindid = idx.oid AND con.contype IN ('p', 'u', 'x') WHERE schemaname = ${namespace} ORDER BY tablename, indexname`;
138
+ break;
139
+ }
140
+ return { text, values: collector.values, returning: "none" };
141
+ }
142
+ // packages/sql/src/dialects/postgres-index-keys.ts
143
+ import { unsupportedCapability as unsupportedCapability5 } from "@vibeorm/schema";
144
+ function renderPostgresIndexKeys(params) {
145
+ const { dialect } = params;
146
+ if (dialect.name !== "postgres")
147
+ throw unsupportedCapability5({ dialect: dialect.name, feature: "indexOperatorClasses" });
148
+ const collector = new ParamCollector(dialect);
149
+ const scope = params.table === undefined ? "n.nspname <> 'information_schema' AND n.nspname NOT LIKE 'pg\\_%' ESCAPE '\\'" : `n.nspname = ${collector.add(params.table.namespace)} AND c.relname = ${collector.add(params.table.name)}`;
150
+ const defaultResolution = `LEFT JOIN LATERAL (WITH RECURSIVE input_types AS (SELECT t.oid, t.typbasetype, t.typtype, t.typelem, t.typcategory FROM pg_catalog.pg_type t WHERE t.oid = a.atttypid UNION ALL SELECT t.oid, t.typbasetype, t.typtype, t.typelem, t.typcategory FROM pg_catalog.pg_type t JOIN input_types previous ON t.oid = previous.typbasetype WHERE previous.typtype = 'd'), candidates AS (SELECT candidate.oid, CASE WHEN candidate.opcintype = input.oid THEN 0 WHEN class_input.typispreferred AND class_input.typcategory = input.typcategory THEN 1 ELSE 2 END AS priority FROM pg_catalog.pg_opclass candidate JOIN pg_catalog.pg_type class_input ON class_input.oid = candidate.opcintype CROSS JOIN input_types input WHERE input.typtype <> 'd' AND candidate.opcdefault AND candidate.opcmethod = idx.relam AND (candidate.opcintype = input.oid OR EXISTS (SELECT 1 FROM pg_catalog.pg_cast cast_entry WHERE cast_entry.castsource = input.oid AND cast_entry.casttarget = candidate.opcintype AND cast_entry.castmethod = 'b' AND cast_entry.castcontext = 'i') OR input.typtype = 'e' AND candidate.opcintype = 'pg_catalog.anyenum'::regtype OR input.typelem <> 0 AND candidate.opcintype = 'pg_catalog.anyarray'::regtype)) SELECT (array_agg(candidate.oid))[1] AS oid FROM candidates candidate WHERE candidate.priority = (SELECT min(priority) FROM candidates) HAVING count(*) = 1) resolved_default ON true`;
151
+ return {
152
+ text: `SELECT n.nspname AS table_namespace, c.relname AS table_name, idx.relname AS index_name, am.amname AS method, i.indisunique AS unique, pg_catalog.pg_get_expr(i.indpred, i.indrelid, false) AS predicate, i.indnullsnotdistinct AS nulls_not_distinct, k.ordinality AS ordinal, a.attname AS column_name, (i.indoption[k.ordinality - 1] & 1) <> 0 AS descending, opn.nspname AS operator_namespace, op.opcname AS operator_name, COALESCE(op.oid = resolved_default.oid, false) AS exact_default FROM pg_catalog.pg_index i JOIN pg_catalog.pg_class c ON c.oid = i.indrelid JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace JOIN pg_catalog.pg_class idx ON idx.oid = i.indexrelid JOIN pg_catalog.pg_am am ON am.oid = idx.relam CROSS JOIN LATERAL unnest(i.indkey) WITH ORDINALITY k(attnum, ordinality) LEFT JOIN pg_catalog.pg_attribute a ON a.attrelid = c.oid AND a.attnum = k.attnum JOIN pg_catalog.pg_opclass op ON op.oid = i.indclass[k.ordinality - 1] JOIN pg_catalog.pg_namespace opn ON opn.oid = op.opcnamespace ${defaultResolution} WHERE ${scope} AND k.ordinality <= i.indnkeyatts ORDER BY n.nspname, c.relname, idx.relname, k.ordinality`,
153
+ values: collector.values,
154
+ returning: "none"
155
+ };
156
+ }
157
+ // packages/sql/src/index-columns.ts
158
+ import { VibeError, isSqlObjectIdentity, unsupportedCapability as unsupportedCapability6 } from "@vibeorm/schema";
159
+ function renderIndexColumns(params) {
160
+ const { dialect, columns, unique } = params;
161
+ const hasOperatorClass = columns.some((column) => column.operatorClass !== undefined);
162
+ if (hasOperatorClass && !dialect.capabilities.indexOperatorClasses)
163
+ throw unsupportedCapability6({ dialect: dialect.name, feature: "indexOperatorClasses" });
164
+ if (hasOperatorClass && unique)
165
+ throw unsupportedCapability6({ dialect: dialect.name, feature: "uniqueIndexOperatorClasses", hint: "custom unique operator classes can change client selector equality" });
166
+ return columns.map((column) => {
167
+ const operatorClass = column.operatorClass;
168
+ if (operatorClass !== undefined && !isSqlObjectIdentity({ kind: "table", name: operatorClass })) {
169
+ throw new VibeError({ code: "VIBE_SCHEMA_INVALID", message: "Index operator class must be a qualified SQL name { namespace, name }", meta: { rule: "index-operator-class-identity", column: column.name } });
170
+ }
171
+ const ops = operatorClass === undefined ? "" : ` ${dialect.quoteIdent({ name: operatorClass.namespace })}.${dialect.quoteIdent({ name: operatorClass.name })}`;
172
+ return `${dialect.quoteIdent({ name: column.name })}${ops}${column.desc ? " DESC" : ""}`;
173
+ });
174
+ }
19
175
  // packages/sql/src/dialects/module-dependency.ts
20
176
  function renderModuleDependencyQuery(params) {
21
177
  const { dialect, operation } = params;
@@ -43,24 +199,26 @@ ORDER BY source_namespace, source_table, constraint_name`,
43
199
  };
44
200
  }
45
201
  // packages/sql/src/dialects/migration-replay-coverage.ts
202
+ var extensionMember = (classid, objid) => `EXISTS (SELECT 1 FROM pg_catalog.pg_depend d WHERE d.classid = '${classid}'::regclass AND d.objid = ${objid} AND d.deptype = 'e')`;
203
+ var extensionOwnedNamespace = `(EXISTS (SELECT 1 FROM pg_catalog.pg_extension e WHERE e.extnamespace = n.oid) OR ${extensionMember("pg_namespace", "n.oid")}) AND NOT EXISTS (SELECT 1 FROM pg_catalog.pg_class c WHERE c.relnamespace = n.oid AND c.relkind IN ('r', 'p', 'v', 'm', 'f', 'S') AND NOT ${extensionMember("pg_class", "c.oid")}) AND NOT EXISTS (SELECT 1 FROM pg_catalog.pg_proc p WHERE p.pronamespace = n.oid AND NOT ${extensionMember("pg_proc", "p.oid")}) AND NOT EXISTS (SELECT 1 FROM pg_catalog.pg_type t WHERE t.typnamespace = n.oid AND (t.typrelid = 0 AND t.typelem = 0 OR t.typtype = 'c' AND EXISTS (SELECT 1 FROM pg_catalog.pg_class c WHERE c.oid = t.typrelid AND c.relkind = 'c')) AND NOT ${extensionMember("pg_type", "t.oid")})`;
46
204
  function renderReplayCoverageGaps(params) {
47
205
  const { dialect } = params;
48
206
  const collector = new ParamCollector(dialect);
49
207
  const namespace = collector.add(params.namespace);
50
208
  if (dialect.name === "postgres")
51
- return { text: `SELECT 'type' AS kind, t.typname::text AS name FROM pg_catalog.pg_type t JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace WHERE n.nspname = ${namespace} AND (t.typtype IN ('b', 'd', 'r', 'm') AND t.typelem = 0 OR t.typtype = 'c' AND EXISTS (SELECT 1 FROM pg_catalog.pg_class c WHERE c.oid = t.typrelid AND c.relkind = 'c')) AND NOT EXISTS (SELECT 1 FROM pg_catalog.pg_depend d WHERE d.classid = 'pg_type'::regclass AND d.objid = t.oid AND d.deptype = 'e')
52
- UNION ALL SELECT 'routine', p.proname::text FROM pg_catalog.pg_proc p JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace WHERE n.nspname = ${namespace} AND p.prokind <> 'f' AND NOT EXISTS (SELECT 1 FROM pg_catalog.pg_depend d WHERE d.classid = 'pg_proc'::regclass AND d.objid = p.oid AND d.deptype = 'e')
53
- UNION ALL SELECT 'relation-layout', c.relname::text FROM pg_catalog.pg_class c JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace WHERE n.nspname = ${namespace} AND (c.relkind IN ('p', 'f') OR c.relispartition OR EXISTS (SELECT 1 FROM pg_catalog.pg_inherits i WHERE i.inhrelid = c.oid)) AND NOT EXISTS (SELECT 1 FROM pg_catalog.pg_depend d WHERE d.classid = 'pg_class'::regclass AND d.objid = c.oid AND d.deptype = 'e')
54
- UNION ALL SELECT 'rule', r.rulename::text FROM pg_catalog.pg_rewrite r JOIN pg_catalog.pg_class c ON c.oid = r.ev_class JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace WHERE n.nspname = ${namespace} AND r.rulename <> '_RETURN'
55
- UNION ALL SELECT 'namespace', n.nspname::text FROM pg_catalog.pg_namespace n WHERE n.nspname <> ${namespace} AND n.nspname <> 'information_schema' AND n.nspname NOT LIKE 'pg\\_%' ESCAPE '\\'${params.privateNamespace === undefined ? "" : ` AND n.nspname <> ${collector.add(params.privateNamespace)}`}`, values: collector.values, returning: "none" };
209
+ return { text: `SELECT 'type' AS kind, t.typname::text AS name, n.nspname::text AS namespace, NULL::text AS parent FROM pg_catalog.pg_type t JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace WHERE n.nspname = ${namespace} AND (t.typtype IN ('b', 'd', 'r', 'm') AND t.typelem = 0 OR t.typtype = 'c' AND EXISTS (SELECT 1 FROM pg_catalog.pg_class c WHERE c.oid = t.typrelid AND c.relkind = 'c')) AND NOT EXISTS (SELECT 1 FROM pg_catalog.pg_depend d WHERE d.classid = 'pg_type'::regclass AND d.objid = t.oid AND d.deptype = 'e')
210
+ UNION ALL SELECT 'routine', p.proname::text, n.nspname::text, NULL::text FROM pg_catalog.pg_proc p JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace WHERE n.nspname = ${namespace} AND p.prokind <> 'f' AND NOT EXISTS (SELECT 1 FROM pg_catalog.pg_depend d WHERE d.classid = 'pg_proc'::regclass AND d.objid = p.oid AND d.deptype = 'e')
211
+ UNION ALL SELECT 'relation-layout', c.relname::text, n.nspname::text, NULL::text FROM pg_catalog.pg_class c JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace WHERE n.nspname = ${namespace} AND (c.relkind IN ('p', 'f') OR c.relispartition OR EXISTS (SELECT 1 FROM pg_catalog.pg_inherits i WHERE i.inhrelid = c.oid)) AND NOT EXISTS (SELECT 1 FROM pg_catalog.pg_depend d WHERE d.classid = 'pg_class'::regclass AND d.objid = c.oid AND d.deptype = 'e')
212
+ UNION ALL SELECT 'rule', r.rulename::text, n.nspname::text, c.relname::text FROM pg_catalog.pg_rewrite r JOIN pg_catalog.pg_class c ON c.oid = r.ev_class JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace WHERE n.nspname = ${namespace} AND r.rulename <> '_RETURN' AND NOT ${extensionMember("pg_class", "c.oid")}
213
+ UNION ALL SELECT 'namespace', n.nspname::text, n.nspname::text, NULL::text FROM pg_catalog.pg_namespace n WHERE n.nspname <> ${namespace} AND n.nspname <> 'information_schema' AND n.nspname NOT LIKE 'pg\\_%' ESCAPE '\\' AND NOT (${extensionOwnedNamespace})${params.privateNamespace === undefined ? "" : ` AND n.nspname <> ${collector.add(params.privateNamespace)}`}`, values: collector.values, returning: "none" };
56
214
  if (dialect.name === "mysql")
57
- return { text: `SELECT 'procedure' AS kind, ROUTINE_NAME AS name FROM information_schema.ROUTINES WHERE ROUTINE_SCHEMA = ${namespace} AND ROUTINE_TYPE = 'PROCEDURE'
58
- UNION ALL SELECT 'event', EVENT_NAME FROM information_schema.EVENTS WHERE EVENT_SCHEMA = ${collector.add(params.namespace)}
59
- UNION ALL SELECT DISTINCT 'partition', TABLE_NAME FROM information_schema.PARTITIONS WHERE TABLE_SCHEMA = ${collector.add(params.namespace)} AND PARTITION_NAME IS NOT NULL`, values: collector.values, returning: "none" };
60
- return { text: `SELECT 'table-options' AS kind, name FROM pragma_table_list WHERE schema = ${namespace} AND name NOT LIKE 'sqlite\\_%' ESCAPE '\\' AND (type = 'virtual' OR wr <> 0 OR strict <> 0)`, values: collector.values, returning: "none" };
215
+ return { text: `SELECT 'procedure' AS kind, ROUTINE_NAME AS name, ROUTINE_SCHEMA AS namespace, NULL AS parent FROM information_schema.ROUTINES WHERE ROUTINE_SCHEMA = ${namespace} AND ROUTINE_TYPE = 'PROCEDURE'
216
+ UNION ALL SELECT 'event', EVENT_NAME, EVENT_SCHEMA, NULL FROM information_schema.EVENTS WHERE EVENT_SCHEMA = ${collector.add(params.namespace)}
217
+ UNION ALL SELECT DISTINCT 'partition', TABLE_NAME, TABLE_SCHEMA, NULL FROM information_schema.PARTITIONS WHERE TABLE_SCHEMA = ${collector.add(params.namespace)} AND PARTITION_NAME IS NOT NULL`, values: collector.values, returning: "none" };
218
+ return { text: `SELECT 'table-options' AS kind, name, schema AS namespace, NULL AS parent FROM pragma_table_list WHERE schema = ${namespace} AND name NOT LIKE 'sqlite\\_%' ESCAPE '\\' AND (type = 'virtual' OR wr <> 0 OR strict <> 0)`, values: collector.values, returning: "none" };
61
219
  }
62
220
  // packages/sql/src/dialects/migration-shadow.ts
63
- import { unsupportedCapability } from "@vibeorm/schema";
221
+ import { assertSqlNamespace, unsupportedCapability as unsupportedCapability7 } from "@vibeorm/schema";
64
222
  var SHADOW_DATABASE = Object.freeze({ schema: "_vibeorm_shadow", table: "_vibe_shadow", lock: 1447645267, timeoutSeconds: 60 });
65
223
  var SHADOW_CAPABILITIES = Object.freeze({
66
224
  postgres: Object.freeze({ serverProvisioning: true, dedicated: true }),
@@ -70,14 +228,14 @@ var SHADOW_CAPABILITIES = Object.freeze({
70
228
  function renderShadowOperation(params) {
71
229
  const { dialect, operation } = params;
72
230
  if (!SHADOW_CAPABILITIES[dialect.name].serverProvisioning)
73
- throw unsupportedCapability({ dialect: dialect.name, feature: "shadowDatabaseProvisioning" });
231
+ throw unsupportedCapability7({ dialect: dialect.name, feature: "shadowDatabaseProvisioning" });
74
232
  const pg = dialect.name === "postgres";
75
233
  const collector = new ParamCollector(dialect);
76
234
  const marker = pg ? `${dialect.quoteIdent({ name: SHADOW_DATABASE.schema })}.${dialect.quoteIdent({ name: SHADOW_DATABASE.table })}` : dialect.quoteIdent({ name: SHADOW_DATABASE.table });
77
235
  const result = (text) => [{ text, values: collector.values, returning: "none" }];
78
236
  switch (operation.kind) {
79
237
  case "createDatabase":
80
- return result(`CREATE DATABASE ${dialect.quoteIdent({ name: operation.name })}`);
238
+ return result(`CREATE DATABASE ${dialect.quoteIdent({ name: operation.name })}${pg ? " TEMPLATE template0" : ""}`);
81
239
  case "dropDatabase":
82
240
  return result(`DROP DATABASE ${dialect.quoteIdent({ name: operation.name })}`);
83
241
  case "identity":
@@ -95,7 +253,7 @@ function renderShadowOperation(params) {
95
253
  ORDER BY ordinal_position`);
96
254
  case "grants": {
97
255
  if (pg)
98
- throw unsupportedCapability({ dialect: dialect.name, feature: "mysqlShadowPrivileges" });
256
+ throw unsupportedCapability7({ dialect: dialect.name, feature: "mysqlShadowPrivileges" });
99
257
  return result("SHOW GRANTS FOR CURRENT_USER");
100
258
  }
101
259
  case "markerCreate":
@@ -123,19 +281,27 @@ UNION ALL SELECT ROUTINE_TYPE, ROUTINE_NAME, ROUTINE_SCHEMA FROM information_sch
123
281
  UNION ALL SELECT 'EVENT', EVENT_NAME, EVENT_SCHEMA FROM information_schema.EVENTS WHERE EVENT_SCHEMA = DATABASE()
124
282
  UNION ALL SELECT 'TRIGGER', TRIGGER_NAME, TRIGGER_SCHEMA FROM information_schema.TRIGGERS WHERE TRIGGER_SCHEMA = DATABASE()
125
283
  UNION ALL SELECT 'EXTERNAL FOREIGN KEY', CONCAT(TABLE_NAME, '.', CONSTRAINT_NAME), CONSTRAINT_SCHEMA FROM information_schema.REFERENTIAL_CONSTRAINTS WHERE UNIQUE_CONSTRAINT_SCHEMA = DATABASE() AND CAST(CONSTRAINT_SCHEMA AS BINARY) <> CAST(DATABASE() AS BINARY)`);
126
- case "resetPostgres": {
284
+ case "resetPostgres":
285
+ case "resetDedicatedPostgres": {
127
286
  if (!pg)
128
- throw unsupportedCapability({ dialect: dialect.name, feature: "postgresShadowReset" });
129
- return [{ text: 'DROP SCHEMA "public" CASCADE', values: [], returning: "none" }, { text: 'CREATE SCHEMA "public"', values: [], returning: "none" }];
287
+ throw unsupportedCapability7({ dialect: dialect.name, feature: "postgresShadowReset" });
288
+ const owned = operation.kind === "resetDedicatedPostgres" ? operation.ownedNamespaces : [];
289
+ for (const namespace of owned)
290
+ assertSqlNamespace({ namespace, dialect: "postgres", allowPublic: false });
291
+ return [
292
+ ...owned.map((namespace) => ({ text: `DROP SCHEMA IF EXISTS ${dialect.quoteIdent({ name: namespace })} CASCADE`, values: [], returning: "none" })),
293
+ { text: 'DROP SCHEMA "public" CASCADE', values: [], returning: "none" },
294
+ { text: 'CREATE SCHEMA "public"', values: [], returning: "none" }
295
+ ];
130
296
  }
131
297
  case "mysqlForeignKeys": {
132
298
  if (pg)
133
- throw unsupportedCapability({ dialect: dialect.name, feature: "mysqlShadowReset" });
299
+ throw unsupportedCapability7({ dialect: dialect.name, feature: "mysqlShadowReset" });
134
300
  return result(`SET FOREIGN_KEY_CHECKS = ${operation.enabled ? "1" : "0"}`);
135
301
  }
136
302
  case "dropMysqlObject": {
137
303
  if (pg)
138
- throw unsupportedCapability({ dialect: dialect.name, feature: "mysqlShadowReset" });
304
+ throw unsupportedCapability7({ dialect: dialect.name, feature: "mysqlShadowReset" });
139
305
  return result(`DROP ${operation.object} ${dialect.quoteIdent({ name: operation.name })}`);
140
306
  }
141
307
  }
@@ -180,10 +346,10 @@ var SQLITE_SESSION_SQL = Object.freeze({
180
346
  foreignKeysOn: "PRAGMA foreign_keys = ON"
181
347
  });
182
348
  // packages/sql/src/composable.ts
183
- import { VibeError } from "@vibeorm/schema";
349
+ import { VibeError as VibeError2 } from "@vibeorm/schema";
184
350
  var fragments = new WeakMap;
185
351
  function invalid(message) {
186
- throw new VibeError({ code: "VIBE_VALIDATION", message });
352
+ throw new VibeError2({ code: "VIBE_VALIDATION", message });
187
353
  }
188
354
  function construct(parts) {
189
355
  const snapshot = Object.freeze([...parts]);
@@ -308,7 +474,7 @@ function sqlUsesIncoming(params) {
308
474
  return partsOf(params.fragment).some((part) => typeof part !== "string" && (("row" in part) && part.row === "incoming" || ("greatest" in part) && part.greatest.some((fragment) => sqlUsesIncoming({ fragment }))));
309
475
  }
310
476
  // packages/sql/src/result-decoder.ts
311
- import { VibeError as VibeError3 } from "@vibeorm/schema";
477
+ import { VibeError as VibeError4 } from "@vibeorm/schema";
312
478
 
313
479
  // packages/sql/src/pg-array.ts
314
480
  var PG_ARRAY_QUOTE = /^$|^NULL$|[{},"\\\s]/i;
@@ -363,7 +529,7 @@ function parsePgArrayLiteral(params) {
363
529
  }
364
530
 
365
531
  // packages/sql/src/codecs.ts
366
- import { VibeError as VibeError2, invalidStoredData } from "@vibeorm/schema";
532
+ import { VibeError as VibeError3, invalidStoredData } from "@vibeorm/schema";
367
533
  function enumMembershipCodec(params) {
368
534
  const { model, field, enum: enumName } = params;
369
535
  const members = new Set(params.members);
@@ -371,7 +537,7 @@ function enumMembershipCodec(params) {
371
537
  encode: (value) => {
372
538
  if (typeof value === "string" && members.has(value))
373
539
  return value;
374
- throw new VibeError2({
540
+ throw new VibeError3({
375
541
  code: "VIBE_VALIDATION",
376
542
  message: `Invalid value for enum ${enumName} on ${model}.${field}`,
377
543
  meta: { model, field, enum: enumName }
@@ -411,7 +577,7 @@ var bigIntCodec = {
411
577
  return BigInt(value.trim());
412
578
  if (typeof value === "number" && Number.isSafeInteger(value))
413
579
  return BigInt(value);
414
- throw new VibeError2({ code: "VIBE_DATA_INVALID", message: "BigInt requires an integer string or a safe integer", meta: { value } });
580
+ throw new VibeError3({ code: "VIBE_DATA_INVALID", message: "BigInt requires an integer string or a safe integer", meta: { value } });
415
581
  }
416
582
  };
417
583
  var decimalCodec = {
@@ -441,7 +607,7 @@ function parseDateTimeText(params) {
441
607
  var dateNativeCodec = {
442
608
  encode: (value) => {
443
609
  if (value instanceof Date && !Number.isFinite(value.getTime()) || typeof value === "number" && !Number.isFinite(value) || typeof value === "string" && /^[+-]?infinity$/i.test(value.trim())) {
444
- throw new VibeError2({ code: "VIBE_VALIDATION", message: "DateTime parameters require finite timestamps; use an extended timestamp encoder for infinity" });
610
+ throw new VibeError3({ code: "VIBE_VALIDATION", message: "DateTime parameters require finite timestamps; use an extended timestamp encoder for infinity" });
445
611
  }
446
612
  return value;
447
613
  },
@@ -449,7 +615,7 @@ var dateNativeCodec = {
449
615
  const date = value instanceof Date ? value : typeof value === "string" ? parseDateTimeText({ text: value }) : typeof value === "number" ? new Date(value) : undefined;
450
616
  if (date !== undefined && Number.isFinite(date.getTime()))
451
617
  return date;
452
- throw new VibeError2({ code: "VIBE_DATA_INVALID", message: "DateTime requires a finite timestamp; use an explicit extended timestamp decoder for infinity" });
618
+ throw new VibeError3({ code: "VIBE_DATA_INVALID", message: "DateTime requires a finite timestamp; use an explicit extended timestamp decoder for infinity" });
453
619
  }
454
620
  };
455
621
  var dateTextCodec = {
@@ -458,7 +624,7 @@ var dateTextCodec = {
458
624
  const date = value instanceof Date ? value : typeof value === "string" ? parseDateTimeText({ text: value }) : typeof value === "number" ? new Date(value) : undefined;
459
625
  if (date !== undefined && Number.isFinite(date.getTime()))
460
626
  return date.toISOString();
461
- throw new VibeError2({ code: "VIBE_VALIDATION", message: "DateTime parameters require a valid finite timestamp" });
627
+ throw new VibeError3({ code: "VIBE_VALIDATION", message: "DateTime parameters require a valid finite timestamp" });
462
628
  },
463
629
  decode: dateNativeCodec.decode
464
630
  };
@@ -495,7 +661,7 @@ var jsonCodec = {
495
661
  try {
496
662
  return JSON.parse(value);
497
663
  } catch (cause) {
498
- throw new VibeError2({
664
+ throw new VibeError3({
499
665
  code: "VIBE_INTERNAL",
500
666
  message: "a Json column returned text that is not valid JSON",
501
667
  meta: { value },
@@ -545,7 +711,7 @@ var DIALECT_CODECS = {
545
711
 
546
712
  // packages/sql/src/result-decoder.ts
547
713
  function refuse(encoding, message) {
548
- throw new VibeError3({ code: encoding ? "VIBE_VALIDATION" : "VIBE_DATA_INVALID", message });
714
+ throw new VibeError4({ code: encoding ? "VIBE_VALIDATION" : "VIBE_DATA_INVALID", message });
549
715
  }
550
716
  function scalar(type, valid) {
551
717
  const convert = (params, encoding) => {
@@ -591,7 +757,7 @@ var extendedDecoder = Object.freeze({
591
757
  encode: (params) => {
592
758
  if (params.value === "infinity" || params.value === "-infinity") {
593
759
  if (params.dialect !== "postgres")
594
- throw new VibeError3({ code: "VIBE_UNSUPPORTED_CAPABILITY", message: "Timestamp infinity parameters require PostgreSQL" });
760
+ throw new VibeError4({ code: "VIBE_UNSUPPORTED_CAPABILITY", message: "Timestamp infinity parameters require PostgreSQL" });
595
761
  return params.value;
596
762
  }
597
763
  return dateDecoder.encode(params);
@@ -649,15 +815,15 @@ var decode = Object.freeze({
649
815
  }
650
816
  });
651
817
  // packages/sql/src/exclusion.ts
652
- import { VibeError as VibeError5, fieldTypeIdentity as fieldTypeIdentity2, unsupportedCapability as unsupportedCapability3 } from "@vibeorm/schema";
818
+ import { VibeError as VibeError6, fieldTypeIdentity as fieldTypeIdentity2, isEnumType as isEnumType2, unsupportedCapability as unsupportedCapability9 } from "@vibeorm/schema";
653
819
 
654
820
  // packages/sql/src/predicate.ts
655
- import { VibeError as VibeError4, fieldTypeIdentity, isEnumType, unsupportedCapability as unsupportedCapability2 } from "@vibeorm/schema";
821
+ import { VibeError as VibeError5, fieldTypeIdentity, isEnumType, unsupportedCapability as unsupportedCapability8 } from "@vibeorm/schema";
656
822
  function renderPredicate(params) {
657
823
  if (params.usage === "exclusionPredicate" && !params.dialect.capabilities.exclusionConstraints)
658
- throw unsupportedCapability2({ dialect: params.dialect.name, feature: "exclusionConstraints" });
824
+ throw unsupportedCapability8({ dialect: params.dialect.name, feature: "exclusionConstraints" });
659
825
  if (params.usage === "indexPredicate" && !params.dialect.capabilities.partialIndexes) {
660
- throw unsupportedCapability2({ dialect: params.dialect.name, feature: "partialIndexes" });
826
+ throw unsupportedCapability8({ dialect: params.dialect.name, feature: "partialIndexes" });
661
827
  }
662
828
  const context = {
663
829
  model: params.model,
@@ -692,7 +858,7 @@ var INT64_MIN = -(2n ** 63n);
692
858
  var INT64_MAX = 2n ** 63n - 1n;
693
859
  function refuse2(params) {
694
860
  const { context, rule, message } = params;
695
- throw new VibeError4({
861
+ throw new VibeError5({
696
862
  code: "VIBE_SCHEMA_INVALID",
697
863
  message: `${context.site} on "${context.model.name}": ${message}`,
698
864
  meta: { rule, model: context.model.name, site: context.site, ...params.meta ?? {} }
@@ -785,7 +951,7 @@ function resolveField(params) {
785
951
  });
786
952
  }
787
953
  if (context.usage === "check" && context.dialect.name === "mysql" && field.default?.kind === "autoincrement") {
788
- throw unsupportedCapability2({
954
+ throw unsupportedCapability8({
789
955
  dialect: "mysql",
790
956
  feature: `CHECK constraint referencing auto-increment column "${context.model.name}.${name}"`,
791
957
  hint: "mysql refuses this with error 3818 \u2014 enforce the rule in application code or on a non-generated column"
@@ -956,12 +1122,12 @@ function describe(params) {
956
1122
 
957
1123
  // packages/sql/src/exclusion.ts
958
1124
  function invalid2(rule) {
959
- throw new VibeError5({ code: "VIBE_SCHEMA_INVALID", message: `Invalid exclusion constraint: ${rule}`, meta: { rule: `exclusion-${rule}` } });
1125
+ throw new VibeError6({ code: "VIBE_SCHEMA_INVALID", message: `Invalid exclusion constraint: ${rule}`, meta: { rule: `exclusion-${rule}` } });
960
1126
  }
961
1127
  function compileExclusion(params) {
962
1128
  const { exclusion: spec, model, dialect } = params;
963
1129
  if (!dialect.capabilities.exclusionConstraints)
964
- throw unsupportedCapability3({ dialect: dialect.name, feature: "exclusionConstraints" });
1130
+ throw unsupportedCapability9({ dialect: dialect.name, feature: "exclusionConstraints" });
965
1131
  if (!spec.name || spec.name.includes("\x00"))
966
1132
  invalid2("name");
967
1133
  if (!["int8range", "tsrange", "tstzrange"].includes(spec.range.type))
@@ -1004,7 +1170,7 @@ function compileExclusion(params) {
1004
1170
  const column = field(key.field);
1005
1171
  if (column.isOptional)
1006
1172
  invalid2("nullable-key-requires-expression");
1007
- if (!["String", "Int", "BigInt", "Float", "Decimal", "Boolean", "DateTime"].includes(fieldTypeIdentity2({ type: column.type })))
1173
+ if (!isEnumType2(column.type) && !["String", "Int", "BigInt", "Float", "Decimal", "Boolean", "DateTime"].includes(fieldTypeIdentity2({ type: column.type })))
1008
1174
  invalid2("key-type");
1009
1175
  return `${dialect.quoteIdent({ name: column.dbName ?? column.name })} WITH =`;
1010
1176
  });
@@ -1014,13 +1180,13 @@ function compileExclusion(params) {
1014
1180
  }
1015
1181
  function renderExclusionSetup(params) {
1016
1182
  if (!params.dialect.capabilities.exclusionConstraints)
1017
- throw unsupportedCapability3({ dialect: params.dialect.name, feature: "exclusionConstraints" });
1183
+ throw unsupportedCapability9({ dialect: params.dialect.name, feature: "exclusionConstraints" });
1018
1184
  return params.exclusion.requiredExtensions.map((name) => `CREATE EXTENSION IF NOT EXISTS ${params.dialect.quoteIdent({ name })};`);
1019
1185
  }
1020
1186
  function renderExclusionDdl(params) {
1021
1187
  const { dialect, table, exclusion, operation } = params;
1022
1188
  if (!dialect.capabilities.exclusionConstraints)
1023
- throw unsupportedCapability3({ dialect: dialect.name, feature: "exclusionConstraints" });
1189
+ throw unsupportedCapability9({ dialect: dialect.name, feature: "exclusionConstraints" });
1024
1190
  const target = `ALTER TABLE ${dialect.quoteIdent({ name: table })}`;
1025
1191
  if (operation === "drop")
1026
1192
  return [`${target} DROP CONSTRAINT ${dialect.quoteIdent({ name: exclusion.name })};`];
@@ -1029,15 +1195,15 @@ function renderExclusionDdl(params) {
1029
1195
  function renderExclusionCatalog(params) {
1030
1196
  const { dialect, probe } = params;
1031
1197
  if (!dialect.capabilities.exclusionConstraints)
1032
- throw unsupportedCapability3({ dialect: dialect.name, feature: "exclusionConstraints" });
1033
- const scope = probe === undefined ? "n.nspname = 'public'" : `t.oid = ${dialect.quoteStringLiteral({ value: probe })}::regclass`;
1198
+ throw unsupportedCapability9({ dialect: dialect.name, feature: "exclusionConstraints" });
1199
+ const scope = probe === undefined ? `n.nspname = ${dialect.quoteStringLiteral({ value: params.namespace ?? "public" })}` : `t.oid = ${dialect.quoteStringLiteral({ value: probe })}::regclass`;
1034
1200
  return `SELECT t.relname AS table_name, c.conname AS constraint_name, pg_catalog.pg_get_constraintdef(c.oid, true) AS definition, c.convalidated AS validated, i.indisvalid AS valid, i.indisready AS ready FROM pg_catalog.pg_constraint c JOIN pg_catalog.pg_class t ON t.oid = c.conrelid JOIN pg_catalog.pg_namespace n ON n.oid = t.relnamespace JOIN pg_catalog.pg_index i ON i.indexrelid = c.conindid WHERE c.contype = 'x' AND ${scope} ORDER BY t.relname, c.conname`;
1035
1201
  }
1036
1202
  function renderExclusionProbe(params) {
1037
1203
  const { dialect, table, probe, definition } = params;
1038
1204
  if (!dialect.capabilities.exclusionConstraints)
1039
- throw unsupportedCapability3({ dialect: dialect.name, feature: "exclusionConstraints" });
1040
- return [`CREATE TEMP TABLE ${dialect.quoteIdent({ name: probe })} (LIKE ${dialect.quoteIdent({ name: "public" })}.${dialect.quoteIdent({ name: table })})`, `ALTER TABLE ${dialect.quoteIdent({ name: probe })} ADD CONSTRAINT ${dialect.quoteIdent({ name: `${probe}_x` })} ${definition}`];
1205
+ throw unsupportedCapability9({ dialect: dialect.name, feature: "exclusionConstraints" });
1206
+ return [`CREATE TEMP TABLE ${dialect.quoteIdent({ name: probe })} (LIKE ${dialect.quoteIdent({ name: params.namespace ?? "public" })}.${dialect.quoteIdent({ name: table })})`, `ALTER TABLE ${dialect.quoteIdent({ name: probe })} ADD CONSTRAINT ${dialect.quoteIdent({ name: `${probe}_x` })} ${definition}`];
1041
1207
  }
1042
1208
  // packages/sql/src/ast.ts
1043
1209
  var SET_OPERATORS = ["increment", "decrement", "multiply", "divide"];
@@ -1092,7 +1258,7 @@ function isExcludedRef(value) {
1092
1258
  }
1093
1259
  var ADVISORY_LOCK_RESULT_COLUMN = "acquired";
1094
1260
  // packages/sql/src/locks.ts
1095
- import { internalError, unsupportedCapability as unsupportedCapability4 } from "@vibeorm/schema";
1261
+ import { internalError, unsupportedCapability as unsupportedCapability10 } from "@vibeorm/schema";
1096
1262
  var ROW_LOCK_PROSE = Object.freeze({
1097
1263
  strengths: Object.freeze({
1098
1264
  update: "FOR UPDATE",
@@ -1112,7 +1278,7 @@ function renderRowLockClause(params) {
1112
1278
  if (syntax === null) {
1113
1279
  if (lock.strength === "update" && lock.wait === "wait")
1114
1280
  return null;
1115
- throw unsupportedCapability4({
1281
+ throw unsupportedCapability10({
1116
1282
  dialect: dialect.name,
1117
1283
  feature: `a ${describeRowLock({ lock })} locking read`,
1118
1284
  hint: `${dialect.name} has no locking-read clause at all`
@@ -1120,7 +1286,7 @@ function renderRowLockClause(params) {
1120
1286
  }
1121
1287
  const strengthText = syntax.strengths[lock.strength];
1122
1288
  if (strengthText === undefined) {
1123
- throw unsupportedCapability4({
1289
+ throw unsupportedCapability10({
1124
1290
  dialect: dialect.name,
1125
1291
  feature: `the ${describeRowLock({ lock: { ...lock, wait: "wait" } })} row-lock strength`,
1126
1292
  hint: `${dialect.name} can express: ${Object.keys(syntax.strengths).join(", ")}`
@@ -1128,7 +1294,7 @@ function renderRowLockClause(params) {
1128
1294
  }
1129
1295
  const waitText = syntax.wait[lock.wait];
1130
1296
  if (waitText === undefined) {
1131
- throw unsupportedCapability4({
1297
+ throw unsupportedCapability10({
1132
1298
  dialect: dialect.name,
1133
1299
  feature: `the "${lock.wait}" lock wait policy`,
1134
1300
  hint: `${dialect.name} can express: ${Object.keys(syntax.wait).join(", ")}`
@@ -1147,7 +1313,7 @@ function renderAdvisoryLock(params) {
1147
1313
  const { dialect, statement, collector } = params;
1148
1314
  const functions = dialect.advisoryLockFunctions;
1149
1315
  if (functions === null) {
1150
- throw unsupportedCapability4({
1316
+ throw unsupportedCapability10({
1151
1317
  dialect: dialect.name,
1152
1318
  feature: "advisory locks",
1153
1319
  hint: dialect.name === "mysql" ? "mysql's GET_LOCK is SESSION-scoped \u2014 it survives a rollback, so it cannot be released with the transaction" : `${dialect.name} has no advisory-lock functions`
@@ -1189,10 +1355,10 @@ import {
1189
1355
  } from "@vibeorm/schema";
1190
1356
 
1191
1357
  // packages/sql/src/identifiers.ts
1192
- import { VibeError as VibeError6 } from "@vibeorm/schema";
1358
+ import { VibeError as VibeError7 } from "@vibeorm/schema";
1193
1359
  function assertNoNul(params) {
1194
1360
  if (params.name.includes("\x00")) {
1195
- throw new VibeError6({
1361
+ throw new VibeError7({
1196
1362
  code: "VIBE_VALIDATION",
1197
1363
  message: "an SQL identifier cannot contain a NUL character \u2014 the server would stop reading it there and address a different object",
1198
1364
  meta: { name: params.name.replaceAll("\x00", "\\0") }
@@ -1385,8 +1551,85 @@ var SQL_DIALECTS = {
1385
1551
  function getSqlDialect(params) {
1386
1552
  return SQL_DIALECTS[params.dialect];
1387
1553
  }
1554
+ // packages/sql/src/dialects/sqlite-table-definition.ts
1555
+ import { VibeError as VibeError8 } from "@vibeorm/schema";
1556
+ function tableDefinitionParts(params) {
1557
+ const sql = params.sql;
1558
+ if (!/^\s*CREATE\s+(?:TEMP(?:ORARY)?\s+)?TABLE\b/i.test(sql))
1559
+ throw unavailable();
1560
+ const parts = [];
1561
+ let start = -1;
1562
+ let depth = 0;
1563
+ let quote;
1564
+ for (let index = 0;index < sql.length; index++) {
1565
+ const char = sql[index];
1566
+ if (quote !== undefined) {
1567
+ if (char === quote) {
1568
+ if (quote !== "]" && sql[index + 1] === quote)
1569
+ index++;
1570
+ else
1571
+ quote = undefined;
1572
+ }
1573
+ continue;
1574
+ }
1575
+ if (char === "'" || char === '"' || char === "`") {
1576
+ quote = char;
1577
+ continue;
1578
+ }
1579
+ if (char === "[") {
1580
+ quote = "]";
1581
+ continue;
1582
+ }
1583
+ if (char === "-" && sql[index + 1] === "-") {
1584
+ const end = sql.indexOf(`
1585
+ `, index + 2);
1586
+ if (end < 0)
1587
+ break;
1588
+ index = end;
1589
+ continue;
1590
+ }
1591
+ if (char === "/" && sql[index + 1] === "*") {
1592
+ const end = sql.indexOf("*/", index + 2);
1593
+ if (end < 0)
1594
+ break;
1595
+ index = end + 1;
1596
+ continue;
1597
+ }
1598
+ if (char === "(") {
1599
+ if (depth === 0)
1600
+ start = index + 1;
1601
+ depth++;
1602
+ } else if (char === ")") {
1603
+ depth--;
1604
+ if (depth === 0 && start >= 0) {
1605
+ parts.push(sql.slice(start, index).trim());
1606
+ return { clauses: parts, suffix: sql.slice(index + 1) };
1607
+ }
1608
+ } else if (char === "," && depth === 1) {
1609
+ parts.push(sql.slice(start, index).trim());
1610
+ start = index + 1;
1611
+ }
1612
+ }
1613
+ throw unavailable();
1614
+ }
1615
+ function unavailable() {
1616
+ return new VibeError8({ code: "VIBE_MIGRATION", message: "Cannot preserve table definition", meta: { reason: "table-definition-unavailable" } });
1617
+ }
1618
+ function sqliteColumnClauses(params) {
1619
+ const columns = [];
1620
+ for (const part of tableDefinitionParts(params).clauses) {
1621
+ const token = /^(?:"((?:[^"]|"")+)"|`((?:[^`]|``)+)`|\[([^\]]+)\]|([A-Za-z_][A-Za-z_0-9]*))/.exec(part);
1622
+ if (token === null)
1623
+ throw unavailable();
1624
+ if (token[4] !== undefined && /^(?:CONSTRAINT|PRIMARY|UNIQUE|CHECK|FOREIGN)$/i.test(token[4]))
1625
+ continue;
1626
+ const name = token[1]?.replaceAll('""', '"') ?? token[2]?.replaceAll("``", "`") ?? token[3] ?? token[4];
1627
+ columns.push({ name, sql: part });
1628
+ }
1629
+ return columns;
1630
+ }
1388
1631
  // packages/sql/src/dialects/diagnostics.ts
1389
- import { unsupportedCapability as unsupportedCapability5 } from "@vibeorm/schema";
1632
+ import { unsupportedCapability as unsupportedCapability11 } from "@vibeorm/schema";
1390
1633
  var QUERIES = Object.freeze({
1391
1634
  postgresJsonWire: { dialect: "postgres", text: `SELECT '{"__vibeorm":1}'::jsonb AS "probe"` },
1392
1635
  sqliteTriggers: { dialect: "sqlite", text: "SELECT name, tbl_name, sql FROM sqlite_master WHERE type = 'trigger'" }
@@ -1394,7 +1637,7 @@ var QUERIES = Object.freeze({
1394
1637
  function renderDiagnostic(params) {
1395
1638
  const query = QUERIES[params.query];
1396
1639
  if (params.dialect.name !== query.dialect) {
1397
- throw unsupportedCapability5({ dialect: params.dialect.name, feature: params.query, hint: `this diagnostic requires ${query.dialect}` });
1640
+ throw unsupportedCapability11({ dialect: params.dialect.name, feature: params.query, hint: `this diagnostic requires ${query.dialect}` });
1398
1641
  }
1399
1642
  return { text: query.text, values: [], returning: "none" };
1400
1643
  }
@@ -1403,7 +1646,7 @@ function isFixedDiagnostic(params) {
1403
1646
  }
1404
1647
 
1405
1648
  // packages/sql/src/dialects/postgres-diagnostics.ts
1406
- import { VibeError as VibeError7, unsupportedCapability as unsupportedCapability6 } from "@vibeorm/schema";
1649
+ import { VibeError as VibeError9, unsupportedCapability as unsupportedCapability12 } from "@vibeorm/schema";
1407
1650
  function renderPostgresExplain(params) {
1408
1651
  const { dialect, query, options } = params;
1409
1652
  requirePostgres({ dialect, feature: "query plan inspection (EXPLAIN)" });
@@ -1438,7 +1681,7 @@ var POSTGRES_WORKLOAD_LIMITS = Object.freeze({
1438
1681
  });
1439
1682
  function requirePostgres(params) {
1440
1683
  if (params.dialect.name !== "postgres") {
1441
- throw unsupportedCapability6({
1684
+ throw unsupportedCapability12({
1442
1685
  dialect: params.dialect.name,
1443
1686
  feature: params.feature,
1444
1687
  hint: "plan inspection and workload statistics are PostgreSQL-shaped; portable operation tracing works on every dialect"
@@ -1456,7 +1699,7 @@ function renderPostgresWorkload(params) {
1456
1699
  if (query === "statementSnapshot") {
1457
1700
  const bounded = limit ?? 20;
1458
1701
  if (!Number.isInteger(bounded) || bounded < POSTGRES_WORKLOAD_LIMITS.minLimit || bounded > POSTGRES_WORKLOAD_LIMITS.maxLimit) {
1459
- throw new VibeError7({
1702
+ throw new VibeError9({
1460
1703
  code: "VIBE_CONFIG",
1461
1704
  message: `workload snapshot limit must be an integer between ${POSTGRES_WORKLOAD_LIMITS.minLimit} and ${POSTGRES_WORKLOAD_LIMITS.maxLimit}, got ${String(limit)}`,
1462
1705
  meta: { limit }
@@ -1475,7 +1718,7 @@ function renderPostgresWorkload(params) {
1475
1718
  function requireArg(params) {
1476
1719
  const { value, name, query } = params;
1477
1720
  if (value === undefined || value.length === 0) {
1478
- throw new VibeError7({
1721
+ throw new VibeError9({
1479
1722
  code: "VIBE_CONFIG",
1480
1723
  message: `the "${query}" diagnostic read requires a ${name}`,
1481
1724
  meta: { query, argument: name }
@@ -1485,10 +1728,10 @@ function requireArg(params) {
1485
1728
  }
1486
1729
 
1487
1730
  // packages/sql/src/dialects/postgres-rls-readiness.ts
1488
- import { unsupportedCapability as unsupportedCapability8 } from "@vibeorm/schema";
1731
+ import { unsupportedCapability as unsupportedCapability14 } from "@vibeorm/schema";
1489
1732
 
1490
1733
  // packages/sql/src/dialects/postgres-rls.ts
1491
- import { RlsContextError, VibeError as VibeError8, assertValidSchemaIR, unsupportedCapability as unsupportedCapability7, validateRlsContextIR } from "@vibeorm/schema";
1734
+ import { RlsContextError, VibeError as VibeError10, assertValidSchemaIR, unsupportedCapability as unsupportedCapability13, validateRlsContextIR } from "@vibeorm/schema";
1492
1735
  var NATIVE_RLS = Object.freeze({ policyName: "vibeorm_managed", tableSchema: "public", settingPrefix: "vibeorm.", parentAlias: "parent" });
1493
1736
  var COLUMN_TYPES = {
1494
1737
  String: { default: "text", native: { text: "text", varchar: "varchar", charactervarying: "varchar", uuid: "uuid" } },
@@ -1501,18 +1744,18 @@ var COLUMN_TYPES = {
1501
1744
  };
1502
1745
  function requireRls(params) {
1503
1746
  if (!params.dialect.capabilities.nativeRowLevelSecurity) {
1504
- throw unsupportedCapability7({ dialect: params.dialect.name, feature: "nativeRowLevelSecurity" });
1747
+ throw unsupportedCapability13({ dialect: params.dialect.name, feature: "nativeRowLevelSecurity" });
1505
1748
  }
1506
1749
  }
1507
1750
  function identifier2(params) {
1508
1751
  if (typeof params.name !== "string" || params.name.length === 0 || params.name.includes("\x00") || new TextEncoder().encode(params.name).length > 63) {
1509
- throw new VibeError8({ code: "VIBE_SCHEMA_INVALID", message: "Native RLS identifiers must be nonempty PostgreSQL identifiers of at most 63 bytes" });
1752
+ throw new VibeError10({ code: "VIBE_SCHEMA_INVALID", message: "Native RLS identifiers must be nonempty PostgreSQL identifiers of at most 63 bytes" });
1510
1753
  }
1511
1754
  return params.dialect.quoteIdent({ name: params.name });
1512
1755
  }
1513
1756
  function tableRef(params) {
1514
1757
  if (params.schema !== undefined && params.schema !== "public" && params.schema !== "pg_temp") {
1515
- throw unsupportedCapability7({ dialect: params.dialect.name, feature: "nativeRowLevelSecurity", hint: "Only public tables and temporary policy probes are supported" });
1758
+ throw unsupportedCapability13({ dialect: params.dialect.name, feature: "nativeRowLevelSecurity", hint: "Only public tables and temporary policy probes are supported" });
1516
1759
  }
1517
1760
  return `${identifier2({ dialect: params.dialect, name: params.schema ?? NATIVE_RLS.tableSchema })}.${identifier2({ dialect: params.dialect, name: params.table })}`;
1518
1761
  }
@@ -1553,14 +1796,14 @@ function renderRlsColumnType(params) {
1553
1796
  if (native !== undefined)
1554
1797
  return native;
1555
1798
  }
1556
- throw unsupportedCapability7({ dialect: params.dialect.name, feature: "nativeRowLevelSecurity", hint: `Unsupported physical ownership type on field ${field.name}` });
1799
+ throw unsupportedCapability13({ dialect: params.dialect.name, feature: "nativeRowLevelSecurity", hint: `Unsupported physical ownership type on field ${field.name}` });
1557
1800
  }
1558
1801
  function protectedModel(params) {
1559
1802
  requireRls(params);
1560
1803
  assertValidSchemaIR({ schema: params.schema });
1561
1804
  const model = params.schema.models.find((entry) => entry.name === params.model);
1562
1805
  if (model === undefined || model.rls === undefined || model.rls === "unprotected") {
1563
- throw new VibeError8({ code: "VIBE_SCHEMA_INVALID", message: "Native RLS policy rendering requires a protected model", meta: { model: params.model } });
1806
+ throw new VibeError10({ code: "VIBE_SCHEMA_INVALID", message: "Native RLS policy rendering requires a protected model", meta: { model: params.model } });
1564
1807
  }
1565
1808
  return model;
1566
1809
  }
@@ -1593,7 +1836,7 @@ function predicate(params) {
1593
1836
  }).join(" AND ");
1594
1837
  return `EXISTS (SELECT 1 FROM ${tableRef({ dialect, table: parent.dbName ?? parent.name })} AS ${alias} WHERE ${join})`;
1595
1838
  }
1596
- throw new VibeError8({ code: "VIBE_SCHEMA_INVALID", message: "Native RLS requires a protected policy rule" });
1839
+ throw new VibeError10({ code: "VIBE_SCHEMA_INVALID", message: "Native RLS requires a protected policy rule" });
1597
1840
  }
1598
1841
  function renderRlsPolicy(params) {
1599
1842
  const model = protectedModel(params);
@@ -1627,7 +1870,7 @@ function renderRlsContext(params) {
1627
1870
  function renderRlsRole(params) {
1628
1871
  requireRls(params);
1629
1872
  if (typeof params.role !== "string" || params.role.trim().length === 0 || params.role.includes("\x00")) {
1630
- throw new VibeError8({ code: "VIBE_CONFIG", message: "PGlite native RLS requires a trusted nonempty runtime role name" });
1873
+ throw new VibeError10({ code: "VIBE_CONFIG", message: "PGlite native RLS requires a trusted nonempty runtime role name" });
1631
1874
  }
1632
1875
  const collector = new ParamCollector(params.dialect);
1633
1876
  return query({ text: `SELECT set_config('role', ${collector.add(params.role)}, true)`, values: collector.values });
@@ -1779,7 +2022,7 @@ ORDER BY c.relname, p.polname`,
1779
2022
  });
1780
2023
  function requireRls2(params) {
1781
2024
  if (!params.dialect.capabilities.nativeRowLevelSecurity) {
1782
- throw unsupportedCapability8({ dialect: params.dialect.name, feature: "nativeRowLevelSecurity" });
2025
+ throw unsupportedCapability14({ dialect: params.dialect.name, feature: "nativeRowLevelSecurity" });
1783
2026
  }
1784
2027
  }
1785
2028
  function renderRlsReadinessQuery(params) {
@@ -1811,7 +2054,7 @@ function renderRlsPolicyPath(params) {
1811
2054
  }
1812
2055
 
1813
2056
  // packages/sql/src/render.ts
1814
- import { internalError as internalError2, unsupportedCapability as unsupportedCapability9 } from "@vibeorm/schema";
2057
+ import { assertSqlNamespace as assertSqlNamespace2, internalError as internalError2, unsupportedCapability as unsupportedCapability15 } from "@vibeorm/schema";
1815
2058
 
1816
2059
  // packages/sql/src/like.ts
1817
2060
  function escapeLikePattern(params) {
@@ -1917,7 +2160,10 @@ function quoteProjection(dialect, column) {
1917
2160
  return `encode(${ref}, 'base64') AS ${alias}`;
1918
2161
  }
1919
2162
  function renderTable(dialect, table) {
1920
- const name = dialect.quoteIdent({ name: table.name });
2163
+ if (table.namespace !== undefined)
2164
+ assertSqlNamespace2({ namespace: table.namespace, dialect: dialect.name });
2165
+ const relation = dialect.quoteIdent({ name: table.name });
2166
+ const name = table.namespace === undefined ? relation : `${dialect.quoteIdent({ name: table.namespace })}.${relation}`;
1921
2167
  if (table.alias === undefined)
1922
2168
  return name;
1923
2169
  return `${name} AS ${dialect.quoteIdent({ name: table.alias })}`;
@@ -1956,7 +2202,7 @@ function renderAggRef(dialect, agg) {
1956
2202
  function assertScalarArrays(dialect, feature) {
1957
2203
  if (dialect.capabilities.scalarArrays)
1958
2204
  return;
1959
- throw unsupportedCapability9({
2205
+ throw unsupportedCapability15({
1960
2206
  dialect: dialect.name,
1961
2207
  feature,
1962
2208
  hint: "only postgres has native array columns \u2014 model the list as a related table instead"
@@ -1990,7 +2236,7 @@ function renderExpr(params) {
1990
2236
  }
1991
2237
  const column = quoteCol(dialect, expr.column);
1992
2238
  if (dialect.inArrayStrategy === "any") {
1993
- const base = `${column} = ANY(${collector.add([...expr.values])})`;
2239
+ const base = `${column} = ANY(${collector.add(Array.isArray(expr.values) ? [...expr.values] : expr.values)})`;
1994
2240
  return expr.negate === true ? `NOT (${base})` : base;
1995
2241
  }
1996
2242
  const placeholders = collector.addMany(expr.values);
@@ -2087,11 +2333,11 @@ function renderExpr(params) {
2087
2333
  }
2088
2334
  case "arrayContainsAll": {
2089
2335
  assertScalarArrays(dialect, 'the scalar-list filter "hasEvery"');
2090
- return `${quoteCol(dialect, expr.column)} @> ${collector.add([...expr.values])}`;
2336
+ return `${quoteCol(dialect, expr.column)} @> ${collector.add(Array.isArray(expr.values) ? [...expr.values] : expr.values)}`;
2091
2337
  }
2092
2338
  case "arrayOverlaps": {
2093
2339
  assertScalarArrays(dialect, 'the scalar-list filter "hasSome"');
2094
- return `${quoteCol(dialect, expr.column)} && ${collector.add([...expr.values])}`;
2340
+ return `${quoteCol(dialect, expr.column)} && ${collector.add(Array.isArray(expr.values) ? [...expr.values] : expr.values)}`;
2095
2341
  }
2096
2342
  case "arrayIsEmpty": {
2097
2343
  assertScalarArrays(dialect, 'the scalar-list filter "isEmpty"');
@@ -2166,7 +2412,7 @@ function renderJsonLike(params) {
2166
2412
  function renderJsonFilter(params) {
2167
2413
  const { dialect, expr, collector } = params;
2168
2414
  if (!dialect.supportedJsonOps.includes(expr.op)) {
2169
- throw unsupportedCapability9({
2415
+ throw unsupportedCapability15({
2170
2416
  dialect: dialect.name,
2171
2417
  feature: `the json filter "${expr.op}"`,
2172
2418
  hint: `this dialect can express: ${dialect.supportedJsonOps.join(", ")}`
@@ -2230,7 +2476,7 @@ function renderJsonFilter(params) {
2230
2476
  const elements = Array.isArray(expr.value) ? expr.value : [expr.value];
2231
2477
  const tests = elements.map((element) => {
2232
2478
  if (element === null || typeof element === "object" && element !== null) {
2233
- throw unsupportedCapability9({
2479
+ throw unsupportedCapability15({
2234
2480
  dialect: dialect.name,
2235
2481
  feature: "json array_contains with object/array/null elements",
2236
2482
  hint: "sqlite expresses scalar-element containment only \u2014 deep structural containment needs postgres or mysql"
@@ -2381,7 +2627,7 @@ function renderSelect(params) {
2381
2627
  let distinctPrefix = "";
2382
2628
  if (statement.distinctOn !== undefined && statement.distinctOn.length > 0) {
2383
2629
  if (!dialect.capabilities.distinctOn) {
2384
- throw unsupportedCapability9({
2630
+ throw unsupportedCapability15({
2385
2631
  dialect: dialect.name,
2386
2632
  feature: "SELECT DISTINCT ON",
2387
2633
  hint: "postgres-only \u2014 the runtime emulates distinct client-side on this dialect"
@@ -2412,7 +2658,7 @@ function renderSelect(params) {
2412
2658
  }
2413
2659
  if (statement.lateralJoins !== undefined && statement.lateralJoins.length > 0) {
2414
2660
  if (!dialect.capabilities.lateralJoin) {
2415
- throw unsupportedCapability9({
2661
+ throw unsupportedCapability15({
2416
2662
  dialect: dialect.name,
2417
2663
  feature: "LATERAL JOIN relation loading",
2418
2664
  hint: 'use the portable "query" relation strategy on this dialect'
@@ -2497,7 +2743,7 @@ function renderInsert(params) {
2497
2743
  let target = "";
2498
2744
  if (onConflict.constraint !== undefined) {
2499
2745
  if (dialect.name !== "postgres") {
2500
- throw unsupportedCapability9({
2746
+ throw unsupportedCapability15({
2501
2747
  dialect: dialect.name,
2502
2748
  feature: "a named-constraint conflict target (ON CONFLICT ON CONSTRAINT)",
2503
2749
  hint: "only postgres names constraints in conflict targets \u2014 use a column-list target"
@@ -2512,7 +2758,7 @@ function renderInsert(params) {
2512
2758
  }
2513
2759
  text += ` ON CONFLICT${target} DO NOTHING`;
2514
2760
  } else if (onConflict.constraint !== undefined || onConflict.conflictWhere !== undefined) {
2515
- throw unsupportedCapability9({
2761
+ throw unsupportedCapability15({
2516
2762
  dialect: dialect.name,
2517
2763
  feature: "a refined conflict target (constraint / partial-index predicate) on INSERT IGNORE",
2518
2764
  hint: "mysql skips on any duplicate key \u2014 drop the refinement or gate the call per dialect"
@@ -2530,7 +2776,7 @@ function renderInsert(params) {
2530
2776
  throw internalError2({ message: "lastInsertIdColumn is a mysql (onDuplicateKey) construct" });
2531
2777
  }
2532
2778
  if (onConflict.constraint !== undefined && dialect.name !== "postgres") {
2533
- throw unsupportedCapability9({
2779
+ throw unsupportedCapability15({
2534
2780
  dialect: dialect.name,
2535
2781
  feature: "a named-constraint conflict target (ON CONFLICT ON CONSTRAINT)",
2536
2782
  hint: "sqlite conflict targets are column lists \u2014 name the indexed columns instead"
@@ -2546,14 +2792,14 @@ function renderInsert(params) {
2546
2792
  text += ` ON CONFLICT${target} DO UPDATE SET ${assignments}`;
2547
2793
  } else {
2548
2794
  if (onConflict.constraint !== undefined) {
2549
- throw unsupportedCapability9({
2795
+ throw unsupportedCapability15({
2550
2796
  dialect: dialect.name,
2551
2797
  feature: "a named-constraint conflict target on ON DUPLICATE KEY UPDATE",
2552
2798
  hint: "mysql's ODKU fires on any duplicate key \u2014 no target can be named"
2553
2799
  });
2554
2800
  }
2555
2801
  if (onConflict.conflictWhere !== undefined) {
2556
- throw unsupportedCapability9({
2802
+ throw unsupportedCapability15({
2557
2803
  dialect: dialect.name,
2558
2804
  feature: "a partial-index conflict target on ON DUPLICATE KEY UPDATE",
2559
2805
  hint: "mysql's ODKU fires on any duplicate key \u2014 a partial arbiter cannot be selected; gate the call per dialect"
@@ -2635,85 +2881,8 @@ function renderDelete(params) {
2635
2881
  const returning = applyReturning({ dialect, requested: statement.returning });
2636
2882
  return { text: text + returning.suffix, values: collector.values, returning: returning.status };
2637
2883
  }
2638
- // packages/sql/src/dialects/sqlite-table-definition.ts
2639
- import { VibeError as VibeError9 } from "@vibeorm/schema";
2640
- function tableDefinitionParts(params) {
2641
- const sql = params.sql;
2642
- if (!/^\s*CREATE\s+(?:TEMP(?:ORARY)?\s+)?TABLE\b/i.test(sql))
2643
- throw unavailable();
2644
- const parts = [];
2645
- let start = -1;
2646
- let depth = 0;
2647
- let quote;
2648
- for (let index = 0;index < sql.length; index++) {
2649
- const char = sql[index];
2650
- if (quote !== undefined) {
2651
- if (char === quote) {
2652
- if (quote !== "]" && sql[index + 1] === quote)
2653
- index++;
2654
- else
2655
- quote = undefined;
2656
- }
2657
- continue;
2658
- }
2659
- if (char === "'" || char === '"' || char === "`") {
2660
- quote = char;
2661
- continue;
2662
- }
2663
- if (char === "[") {
2664
- quote = "]";
2665
- continue;
2666
- }
2667
- if (char === "-" && sql[index + 1] === "-") {
2668
- const end = sql.indexOf(`
2669
- `, index + 2);
2670
- if (end < 0)
2671
- break;
2672
- index = end;
2673
- continue;
2674
- }
2675
- if (char === "/" && sql[index + 1] === "*") {
2676
- const end = sql.indexOf("*/", index + 2);
2677
- if (end < 0)
2678
- break;
2679
- index = end + 1;
2680
- continue;
2681
- }
2682
- if (char === "(") {
2683
- if (depth === 0)
2684
- start = index + 1;
2685
- depth++;
2686
- } else if (char === ")") {
2687
- depth--;
2688
- if (depth === 0 && start >= 0) {
2689
- parts.push(sql.slice(start, index).trim());
2690
- return { clauses: parts, suffix: sql.slice(index + 1) };
2691
- }
2692
- } else if (char === "," && depth === 1) {
2693
- parts.push(sql.slice(start, index).trim());
2694
- start = index + 1;
2695
- }
2696
- }
2697
- throw unavailable();
2698
- }
2699
- function unavailable() {
2700
- return new VibeError9({ code: "VIBE_MIGRATION", message: "Cannot preserve table definition", meta: { reason: "table-definition-unavailable" } });
2701
- }
2702
- function sqliteColumnClauses(params) {
2703
- const columns = [];
2704
- for (const part of tableDefinitionParts(params).clauses) {
2705
- const token = /^(?:"((?:[^"]|"")+)"|`((?:[^`]|``)+)`|\[([^\]]+)\]|([A-Za-z_][A-Za-z_0-9]*))/.exec(part);
2706
- if (token === null)
2707
- throw unavailable();
2708
- if (token[4] !== undefined && /^(?:CONSTRAINT|PRIMARY|UNIQUE|CHECK|FOREIGN)$/i.test(token[4]))
2709
- continue;
2710
- const name = token[1]?.replaceAll('""', '"') ?? token[2]?.replaceAll("``", "`") ?? token[3] ?? token[4];
2711
- columns.push({ name, sql: part });
2712
- }
2713
- return columns;
2714
- }
2715
2884
  // packages/sql/src/dialects/postgres-type-identity.ts
2716
- import { unsupportedCapability as unsupportedCapability10 } from "@vibeorm/schema";
2885
+ import { unsupportedCapability as unsupportedCapability16 } from "@vibeorm/schema";
2717
2886
  var IDENTIFIER = '(?:"(?:[^"\\x00]|"")+"|[a-zA-Z_][a-zA-Z_0-9$]*)';
2718
2887
  var MODIFIER_VALUE = `(?:[+-]?\\d+|${IDENTIFIER}|'(?:[^'\\x00]|'')*')`;
2719
2888
  var TYPE_NAME = new RegExp(`^\\s*(${IDENTIFIER})(?:\\s*\\.\\s*(${IDENTIFIER}))?\\s*(\\(\\s*${MODIFIER_VALUE}(?:\\s*,\\s*${MODIFIER_VALUE})*\\s*\\))?\\s*((?:\\[\\s*\\]\\s*)*)$`);
@@ -2740,13 +2909,13 @@ function parsePostgresTypeName(params) {
2740
2909
  }
2741
2910
  function renderPostgresTypeName(params) {
2742
2911
  if (params.dialect.name !== "postgres")
2743
- throw unsupportedCapability10({ dialect: params.dialect.name, feature: "postgresTypeIdentity" });
2912
+ throw unsupportedCapability16({ dialect: params.dialect.name, feature: "postgresTypeIdentity" });
2744
2913
  const { dialect, type } = params;
2745
2914
  return `${type.namespace === undefined ? "" : `${dialect.quoteIdent({ name: type.namespace })}.`}${dialect.quoteIdent({ name: type.name })}${type.modifier}${type.array ? "[]" : ""}`;
2746
2915
  }
2747
2916
  function renderPostgresTypeIdentity(params) {
2748
2917
  if (params.dialect.name !== "postgres")
2749
- throw unsupportedCapability10({ dialect: params.dialect.name, feature: "postgresTypeIdentity" });
2918
+ throw unsupportedCapability16({ dialect: params.dialect.name, feature: "postgresTypeIdentity" });
2750
2919
  const collector = new ParamCollector(params.dialect);
2751
2920
  const { source } = params;
2752
2921
  let text;
@@ -2759,11 +2928,11 @@ function renderPostgresTypeIdentity(params) {
2759
2928
  return { text, values: collector.values, returning: "none" };
2760
2929
  }
2761
2930
  // packages/sql/src/dialects/postgres-default-identity.ts
2762
- import { unsupportedCapability as unsupportedCapability11 } from "@vibeorm/schema";
2931
+ import { unsupportedCapability as unsupportedCapability17 } from "@vibeorm/schema";
2763
2932
  function renderPostgresDefaultFunctionIdentity(params) {
2764
2933
  const { dialect, table, column } = params;
2765
2934
  if (dialect.name !== "postgres")
2766
- throw unsupportedCapability11({ dialect: dialect.name, feature: "defaultFunctionIdentity" });
2935
+ throw unsupportedCapability17({ dialect: dialect.name, feature: "defaultFunctionIdentity" });
2767
2936
  const collector = new ParamCollector(dialect);
2768
2937
  const namespace = collector.add(table.namespace);
2769
2938
  const name = collector.add(table.name);
@@ -2787,28 +2956,28 @@ WHERE n.nspname = ${namespace} AND c.relname = ${name} AND a.attname = ${field}
2787
2956
  };
2788
2957
  }
2789
2958
  // packages/sql/src/dialects/constraint-owned-index.ts
2790
- import { unsupportedCapability as unsupportedCapability12 } from "@vibeorm/schema";
2959
+ import { unsupportedCapability as unsupportedCapability18 } from "@vibeorm/schema";
2791
2960
  function renderConstraintOwnedIndexDrop(params) {
2792
2961
  if (params.dialect.name !== "postgres")
2793
- throw unsupportedCapability12({ dialect: params.dialect.name, feature: "constraintOwnedIndexDrop" });
2962
+ throw unsupportedCapability18({ dialect: params.dialect.name, feature: "constraintOwnedIndexDrop" });
2794
2963
  const quote = (name) => params.dialect.quoteIdent({ name });
2795
2964
  return { text: `ALTER TABLE ${quote(params.table)} DROP CONSTRAINT ${quote(params.constraint)};`, values: [], returning: "none" };
2796
2965
  }
2797
2966
  // packages/sql/src/dialects/mysql-check-probe.ts
2798
- import { unsupportedCapability as unsupportedCapability13 } from "@vibeorm/schema";
2967
+ import { unsupportedCapability as unsupportedCapability19 } from "@vibeorm/schema";
2799
2968
  function renderMysqlCheckProbe(params) {
2800
2969
  if (params.dialect.name !== "mysql")
2801
- throw unsupportedCapability13({ dialect: params.dialect.name, feature: "temporaryCheckProbe" });
2970
+ throw unsupportedCapability19({ dialect: params.dialect.name, feature: "temporaryCheckProbe" });
2802
2971
  const q = (name) => params.dialect.quoteIdent({ name });
2803
2972
  const probe = q(params.probe);
2804
2973
  switch (params.operation) {
2805
2974
  case "clone":
2806
2975
  if (params.table === undefined)
2807
- throw unsupportedCapability13({ dialect: "mysql", feature: "temporaryCheckProbe", hint: "A source table is required" });
2976
+ throw unsupportedCapability19({ dialect: "mysql", feature: "temporaryCheckProbe", hint: "A source table is required" });
2808
2977
  return { text: `CREATE TEMPORARY TABLE ${probe} LIKE ${q(params.table.namespace)}.${q(params.table.name)}`, values: [], returning: "none" };
2809
2978
  case "add": {
2810
2979
  if (params.expression === undefined || params.definition === undefined)
2811
- throw unsupportedCapability13({ dialect: "mysql", feature: "temporaryCheckProbe", hint: "An authored expression and temporary clone definition are required" });
2980
+ throw unsupportedCapability19({ dialect: "mysql", feature: "temporaryCheckProbe", hint: "An authored expression and temporary clone definition are required" });
2812
2981
  const parts = tableDefinitionParts({ sql: params.definition });
2813
2982
  return { text: `CREATE TEMPORARY TABLE ${probe} (
2814
2983
  ${[...parts.clauses, `CONSTRAINT ${probe} CHECK (${params.expression})`].join(`,
@@ -2854,31 +3023,31 @@ function sqliteTableConstraints(params) {
2854
3023
  return result;
2855
3024
  }
2856
3025
  // packages/sql/src/dialects/migration-visibility.ts
2857
- import { unsupportedCapability as unsupportedCapability14 } from "@vibeorm/schema";
3026
+ import { unsupportedCapability as unsupportedCapability20 } from "@vibeorm/schema";
2858
3027
  function renderMigrationVisibility(params) {
2859
3028
  if (params.dialect.name !== "mysql")
2860
- throw unsupportedCapability14({ dialect: params.dialect.name, feature: "mysqlCatalogVisibility" });
3029
+ throw unsupportedCapability20({ dialect: params.dialect.name, feature: "mysqlCatalogVisibility" });
2861
3030
  const collector = new ParamCollector(params.dialect);
2862
3031
  const grantee = "CONCAT(QUOTE(SUBSTRING_INDEX(CURRENT_USER(), '@', 1)), '@', QUOTE(SUBSTRING_INDEX(CURRENT_USER(), '@', -1)))";
2863
3032
  return { text: `SELECT PRIVILEGE_TYPE AS privilege FROM information_schema.USER_PRIVILEGES WHERE GRANTEE = ${grantee} UNION SELECT PRIVILEGE_TYPE AS privilege FROM information_schema.SCHEMA_PRIVILEGES WHERE GRANTEE = ${grantee} AND ${collector.add(params.namespace)} LIKE TABLE_SCHEMA`, values: collector.values, returning: "none" };
2864
3033
  }
2865
3034
  // packages/sql/src/dialects/migration-inventory.ts
2866
- import { unsupportedCapability as unsupportedCapability15 } from "@vibeorm/schema";
3035
+ import { unsupportedCapability as unsupportedCapability21 } from "@vibeorm/schema";
2867
3036
  function renderSqliteColumnInventory(params) {
2868
3037
  if (params.dialect.name !== "sqlite")
2869
- throw unsupportedCapability15({ dialect: params.dialect.name, feature: "sqliteColumnInventory" });
3038
+ throw unsupportedCapability21({ dialect: params.dialect.name, feature: "sqliteColumnInventory" });
2870
3039
  const collector = new ParamCollector(params.dialect);
2871
3040
  return { text: `SELECT name, hidden, pk, dflt_value AS definition FROM pragma_table_xinfo(${collector.add(params.table)}, ${collector.add(params.namespace)}) ORDER BY cid`, values: collector.values, returning: "none" };
2872
3041
  }
2873
3042
  function renderSqliteForeignKeyInventory(params) {
2874
3043
  if (params.dialect.name !== "sqlite")
2875
- throw unsupportedCapability15({ dialect: params.dialect.name, feature: "sqliteForeignKeyInventory" });
3044
+ throw unsupportedCapability21({ dialect: params.dialect.name, feature: "sqliteForeignKeyInventory" });
2876
3045
  const collector = new ParamCollector(params.dialect);
2877
3046
  return { text: `SELECT id, seq, "from", "to", "table", on_update, on_delete, match FROM pragma_foreign_key_list(${collector.add(params.table)}, ${collector.add(params.namespace)}) ORDER BY id, seq`, values: collector.values, returning: "none" };
2878
3047
  }
2879
3048
  function renderSqliteRebuildObjects(params) {
2880
3049
  if (params.dialect.name !== "sqlite")
2881
- throw unsupportedCapability15({ dialect: params.dialect.name, feature: "sqliteRebuildObjects" });
3050
+ throw unsupportedCapability21({ dialect: params.dialect.name, feature: "sqliteRebuildObjects" });
2882
3051
  return { text: "SELECT name, tbl_name, type, sql FROM main.sqlite_schema WHERE type IN ('index', 'trigger') AND sql IS NOT NULL ORDER BY type, name", values: [], returning: "none" };
2883
3052
  }
2884
3053
  function renderMigrationInventory(params) {
@@ -2898,6 +3067,8 @@ UNION ALL SELECT 'trigger', t.tgname::text, r.relname::text, NULL, NULL, NULL FR
2898
3067
  UNION ALL SELECT 'column', a.attname::text, r.relname::text, NULL, NULL, NULL FROM relations r JOIN pg_catalog.pg_attribute a ON a.attrelid = r.oid WHERE a.attnum > 0 AND NOT a.attisdropped AND r.relkind IN ('r','p')
2899
3068
  UNION ALL SELECT CASE WHEN a.attgenerated <> '' THEN 'generatedColumn' ELSE 'columnDefault' END, a.attname::text, r.relname::text, NULL, NULL, NULL FROM relations r JOIN pg_catalog.pg_attribute a ON a.attrelid = r.oid JOIN pg_catalog.pg_attrdef d ON d.adrelid = r.oid AND d.adnum = a.attnum WHERE a.attnum > 0 AND NOT a.attisdropped
2900
3069
  UNION ALL SELECT 'function', p.proname::text, NULL, NULL, COALESCE((SELECT json_agg(json_build_object('namespace', tn.nspname, 'name', t.typname) ORDER BY a.ord)::text FROM unnest(p.proargtypes) WITH ORDINALITY a(oid, ord) JOIN pg_catalog.pg_type t ON t.oid = a.oid JOIN pg_catalog.pg_namespace tn ON tn.oid = t.typnamespace), '[]'), NULL FROM pg_catalog.pg_proc p JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace WHERE n.nspname = ${namespace} AND p.prokind = 'f' AND NOT EXISTS (SELECT 1 FROM pg_catalog.pg_depend d WHERE d.classid = 'pg_proc'::regclass AND d.objid = p.oid AND d.deptype = 'e')
3070
+ UNION ALL SELECT 'enum', t.typname::text, NULL, NULL, NULL, NULL FROM pg_catalog.pg_type t JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace WHERE n.nspname = ${namespace} AND t.typtype = 'e' AND NOT EXISTS (SELECT 1 FROM pg_catalog.pg_depend d WHERE d.classid = 'pg_type'::regclass AND d.objid = t.oid AND d.deptype = 'e')
3071
+ ${params.namespace === "public" ? "" : `UNION ALL SELECT 'namespace', n.nspname::text, NULL, NULL, NULL, NULL FROM pg_catalog.pg_namespace n WHERE n.nspname = ${namespace}`}
2901
3072
  ORDER BY kind, parent, name`, values: collector.values, returning: "none" };
2902
3073
  }
2903
3074
  if (params.dialect.name === "mysql") {
@@ -2915,12 +3086,17 @@ ORDER BY kind, parent, name`, values: collector.values, returning: "none" };
2915
3086
  return { text: `SELECT type AS kind, name, tbl_name AS parent, sql AS definition FROM ${schema}.sqlite_schema WHERE name NOT LIKE 'sqlite\\_%' ESCAPE '\\' AND name <> '_vibe_migrations' ORDER BY type, tbl_name, name`, values: [], returning: "none" };
2916
3087
  }
2917
3088
  // packages/sql/src/dialects/migration-objects.ts
2918
- import { internalError as internalError3, unsupportedCapability as unsupportedCapability16 } from "@vibeorm/schema";
3089
+ import { internalError as internalError3, unsupportedCapability as unsupportedCapability22 } from "@vibeorm/schema";
2919
3090
  function renderMigrationObjectQuery(params) {
2920
3091
  return objectQuery({ ...params, collector: new ParamCollector(params.dialect) });
2921
3092
  }
2922
3093
  function objectQuery(params) {
2923
3094
  const { dialect, identity: object, collector } = params;
3095
+ if (object.kind === "namespace") {
3096
+ if (dialect.name !== "postgres")
3097
+ throw unsupportedCapability22({ dialect: dialect.name, feature: "fixedNamespaces" });
3098
+ return { text: `SELECT n.nspname::text AS "name" FROM pg_catalog.pg_namespace n WHERE n.nspname = ${collector.add(object.name)}`, values: collector.values, returning: "none" };
3099
+ }
2924
3100
  const physical = "table" in object ? object.table : object.name;
2925
3101
  const namespace = collector.add(physical.namespace);
2926
3102
  const name = collector.add(physical.name);
@@ -2982,7 +3158,7 @@ function objectQuery(params) {
2982
3158
  break;
2983
3159
  case "constraint":
2984
3160
  if (object.constraintType === "exclusion")
2985
- throw unsupportedCapability16({ dialect: "mysql", feature: "exclusionConstraints" });
3161
+ throw unsupportedCapability22({ dialect: "mysql", feature: "exclusionConstraints" });
2986
3162
  text = `SELECT tc.CONSTRAINT_TYPE AS type, tc.ENFORCED AS enforced, cc.CHECK_CLAUSE AS definition, rc.UPDATE_RULE AS onUpdate, rc.DELETE_RULE AS onDelete, rc.MATCH_OPTION AS matchOption FROM information_schema.TABLE_CONSTRAINTS tc LEFT JOIN information_schema.CHECK_CONSTRAINTS cc ON cc.CONSTRAINT_SCHEMA = tc.CONSTRAINT_SCHEMA AND cc.CONSTRAINT_NAME = tc.CONSTRAINT_NAME LEFT JOIN information_schema.REFERENTIAL_CONSTRAINTS rc ON rc.CONSTRAINT_SCHEMA = tc.CONSTRAINT_SCHEMA AND rc.TABLE_NAME = tc.TABLE_NAME AND rc.CONSTRAINT_NAME = tc.CONSTRAINT_NAME WHERE tc.TABLE_SCHEMA = ${namespace} AND tc.TABLE_NAME = ${name} AND tc.CONSTRAINT_NAME = ${collector.add(object.name)}`;
2987
3163
  break;
2988
3164
  case "index":
@@ -2992,15 +3168,15 @@ function objectQuery(params) {
2992
3168
  text = `SELECT TABLE_TYPE AS type, ENGINE AS engine, TABLE_COLLATION AS collation FROM information_schema.TABLES WHERE TABLE_SCHEMA = ${namespace} AND TABLE_NAME = ${name}`;
2993
3169
  break;
2994
3170
  default:
2995
- throw unsupportedCapability16({ dialect: "mysql", feature: `inspect:${object.kind}` });
3171
+ throw unsupportedCapability22({ dialect: "mysql", feature: `inspect:${object.kind}` });
2996
3172
  }
2997
3173
  } else {
2998
3174
  if (physical.namespace !== "main" && physical.namespace !== "temp")
2999
- throw unsupportedCapability16({ dialect: "sqlite", feature: "attachedSchemaInspection" });
3175
+ throw unsupportedCapability22({ dialect: "sqlite", feature: "attachedSchemaInspection" });
3000
3176
  const catalog = `${dialect.quoteIdent({ name: physical.namespace })}.sqlite_schema`;
3001
3177
  const kind = object.kind === "table" || object.kind === "view" ? object.kind : object.kind === "trigger" ? "trigger" : object.kind === "index" ? "index" : "table";
3002
3178
  if (["function", "sequence", "postgresExtension", "enum"].includes(object.kind) || object.kind === "constraint" && object.constraintType === "exclusion")
3003
- throw unsupportedCapability16({ dialect: "sqlite", feature: `inspect:${object.kind}` });
3179
+ throw unsupportedCapability22({ dialect: "sqlite", feature: `inspect:${object.kind}` });
3004
3180
  const sqliteParams = new ParamCollector(dialect);
3005
3181
  if (object.kind === "column" || object.kind === "columnDefault" || object.kind === "generatedColumn") {
3006
3182
  text = `SELECT x.type AS type, x."notnull" AS "notNull", x.pk AS primaryKeyPosition, x.hidden AS generated, x.dflt_value AS definition, (SELECT sql FROM ${catalog} WHERE name = ${sqliteParams.add(physical.name)} AND type = 'table') AS tableDefinition FROM pragma_table_xinfo(${sqliteParams.add(physical.name)}, ${sqliteParams.add(physical.namespace)}) x WHERE x.name = ${sqliteParams.add(object.column)}`;
@@ -3030,10 +3206,14 @@ function renderMigrationDependencies(params) {
3030
3206
  }
3031
3207
  function dependencyQuery(params) {
3032
3208
  if (params.dialect.name !== "postgres")
3033
- throw unsupportedCapability16({ dialect: params.dialect.name, feature: "catalogDependencies" });
3209
+ throw unsupportedCapability22({ dialect: params.dialect.name, feature: "catalogDependencies" });
3034
3210
  const object = params.identity;
3035
- const physical = "table" in object ? object.table : object.name;
3036
3211
  const collector = params.collector;
3212
+ if (object.kind === "namespace") {
3213
+ const namespace = collector.add(object.name);
3214
+ return { text: `SELECT DISTINCT json_build_array(d.deptype, a.type, a.object_names, a.object_args)::text AS address FROM pg_catalog.pg_namespace n JOIN pg_catalog.pg_depend d ON d.classid = 'pg_namespace'::regclass AND d.objid = n.oid AND d.objsubid = 0 CROSS JOIN LATERAL pg_catalog.pg_identify_object_as_address(d.refclassid, d.refobjid, d.refobjsubid) a WHERE n.nspname = ${namespace} ORDER BY address`, values: collector.values, returning: "none" };
3215
+ }
3216
+ const physical = "table" in object ? object.table : object.name;
3037
3217
  const namespace = collector.add(physical.namespace);
3038
3218
  const name = collector.add(physical.name);
3039
3219
  const relation = `SELECT c.oid FROM pg_catalog.pg_class c JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace WHERE n.nspname = ${namespace} AND c.relname = ${name}`;
@@ -3083,7 +3263,7 @@ function inspectionReferences(params) {
3083
3263
  function renderMigrationObjectBatch(params) {
3084
3264
  const { dialect } = params;
3085
3265
  if (dialect.name !== "postgres")
3086
- throw unsupportedCapability16({ dialect: dialect.name, feature: "batchedMigrationInspection" });
3266
+ throw unsupportedCapability22({ dialect: dialect.name, feature: "batchedMigrationInspection" });
3087
3267
  const groups = new Map;
3088
3268
  for (const [position, identity] of params.identities.entries()) {
3089
3269
  const kind = identity.kind === "constraint" ? `${identity.kind}:${identity.constraintType}` : identity.kind === "generatedColumn" ? "columnDefault" : identity.kind;
@@ -3116,16 +3296,16 @@ function renderMigrationNamespace(params) {
3116
3296
  }
3117
3297
  function renderCheckProbe(params) {
3118
3298
  if (params.dialect.name !== "postgres")
3119
- throw unsupportedCapability16({ dialect: params.dialect.name, feature: "rollbackCheckProbe" });
3299
+ throw unsupportedCapability22({ dialect: params.dialect.name, feature: "rollbackCheckProbe" });
3120
3300
  const q = (name) => params.dialect.quoteIdent({ name });
3121
3301
  return { text: `ALTER TABLE ${q(params.table.namespace)}.${q(params.table.name)} ADD CONSTRAINT ${q(params.name)} CHECK (${params.expression}) NOT VALID`, values: [], returning: "none" };
3122
3302
  }
3123
3303
  // packages/sql/src/dialects/postgres-migration.ts
3124
- import { VibeError as VibeError10, unsupportedCapability as unsupportedCapability17 } from "@vibeorm/schema";
3304
+ import { VibeError as VibeError11, unsupportedCapability as unsupportedCapability23 } from "@vibeorm/schema";
3125
3305
  var SETTING_VALUE = /^[0-9]+(?:\.[0-9]+)?\s*(?:us|ms|s|min|h|d)?$/;
3126
3306
  function requirePostgres2(params) {
3127
3307
  if (params.dialect.name !== "postgres") {
3128
- throw unsupportedCapability17({ dialect: params.dialect.name, feature: params.feature });
3308
+ throw unsupportedCapability23({ dialect: params.dialect.name, feature: params.feature });
3129
3309
  }
3130
3310
  }
3131
3311
  function renderMigrationSessionRead(params) {
@@ -3140,7 +3320,7 @@ function renderMigrationSessionSet(params) {
3140
3320
  requirePostgres2({ dialect: params.dialect, feature: "migrationSessionSettings" });
3141
3321
  const { milliseconds, setting } = params;
3142
3322
  if (!Number.isSafeInteger(milliseconds) || milliseconds < 0) {
3143
- throw new VibeError10({
3323
+ throw new VibeError11({
3144
3324
  code: "VIBE_MIGRATION",
3145
3325
  message: `${setting} must be a non-negative integer number of milliseconds (got ${String(milliseconds)})`,
3146
3326
  meta: { reason: "execution-metadata-invalid", setting, value: milliseconds }
@@ -3269,12 +3449,14 @@ export {
3269
3449
  isFixedDiagnostic,
3270
3450
  isJsonParamCell,
3271
3451
  isListSetOperation,
3452
+ isNativeEnumArrayParameter,
3272
3453
  isSetOperation,
3273
3454
  isSqlDefaultCell,
3274
3455
  isSqlFragment,
3275
3456
  jsonParamCell,
3276
3457
  mapConflictColumns,
3277
3458
  mysqlDialect,
3459
+ nativeEnumArrayParameter,
3278
3460
  parseDateTimeText,
3279
3461
  parsePgArrayLiteral,
3280
3462
  parsePostgresTypeName,
@@ -3291,7 +3473,10 @@ export {
3291
3473
  renderExclusionProbe,
3292
3474
  renderExclusionSetup,
3293
3475
  renderExpr,
3476
+ renderExternalDependents,
3477
+ renderExternalOwnershipCatalog,
3294
3478
  renderFragment,
3479
+ renderIndexColumns,
3295
3480
  renderIndexStateQuery,
3296
3481
  renderMigrationDependencies,
3297
3482
  renderMigrationHistoryQuery,
@@ -3310,6 +3495,8 @@ export {
3310
3495
  renderMysqlObjectMembers,
3311
3496
  renderPostgresDefaultFunctionIdentity,
3312
3497
  renderPostgresExplain,
3498
+ renderPostgresIndexKeys,
3499
+ renderPostgresPhysicalCatalog,
3313
3500
  renderPostgresTypeIdentity,
3314
3501
  renderPostgresTypeName,
3315
3502
  renderPostgresWorkload,
@@ -3343,7 +3530,8 @@ export {
3343
3530
  sqliteTableConstraints,
3344
3531
  startsWithPattern,
3345
3532
  strictMatchPattern,
3533
+ tableDefinitionParts,
3346
3534
  toPgArrayLiteral
3347
3535
  };
3348
3536
 
3349
- //# debugId=C1F0ADA45113049064756E2164756E21
3537
+ //# debugId=55E18657169AA23764756E2164756E21