@vibeorm/sql 2.4.0 → 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;
@@ -50,19 +206,19 @@ function renderReplayCoverageGaps(params) {
50
206
  const collector = new ParamCollector(dialect);
51
207
  const namespace = collector.add(params.namespace);
52
208
  if (dialect.name === "postgres")
53
- 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')
54
- 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')
55
- 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')
56
- 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' AND NOT ${extensionMember("pg_class", "c.oid")}
57
- 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 '\\' AND NOT (${extensionOwnedNamespace})${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" };
58
214
  if (dialect.name === "mysql")
59
- return { text: `SELECT 'procedure' AS kind, ROUTINE_NAME AS name FROM information_schema.ROUTINES WHERE ROUTINE_SCHEMA = ${namespace} AND ROUTINE_TYPE = 'PROCEDURE'
60
- UNION ALL SELECT 'event', EVENT_NAME FROM information_schema.EVENTS WHERE EVENT_SCHEMA = ${collector.add(params.namespace)}
61
- 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" };
62
- 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" };
63
219
  }
64
220
  // packages/sql/src/dialects/migration-shadow.ts
65
- import { unsupportedCapability } from "@vibeorm/schema";
221
+ import { assertSqlNamespace, unsupportedCapability as unsupportedCapability7 } from "@vibeorm/schema";
66
222
  var SHADOW_DATABASE = Object.freeze({ schema: "_vibeorm_shadow", table: "_vibe_shadow", lock: 1447645267, timeoutSeconds: 60 });
67
223
  var SHADOW_CAPABILITIES = Object.freeze({
68
224
  postgres: Object.freeze({ serverProvisioning: true, dedicated: true }),
@@ -72,7 +228,7 @@ var SHADOW_CAPABILITIES = Object.freeze({
72
228
  function renderShadowOperation(params) {
73
229
  const { dialect, operation } = params;
74
230
  if (!SHADOW_CAPABILITIES[dialect.name].serverProvisioning)
75
- throw unsupportedCapability({ dialect: dialect.name, feature: "shadowDatabaseProvisioning" });
231
+ throw unsupportedCapability7({ dialect: dialect.name, feature: "shadowDatabaseProvisioning" });
76
232
  const pg = dialect.name === "postgres";
77
233
  const collector = new ParamCollector(dialect);
78
234
  const marker = pg ? `${dialect.quoteIdent({ name: SHADOW_DATABASE.schema })}.${dialect.quoteIdent({ name: SHADOW_DATABASE.table })}` : dialect.quoteIdent({ name: SHADOW_DATABASE.table });
@@ -97,7 +253,7 @@ function renderShadowOperation(params) {
97
253
  ORDER BY ordinal_position`);
98
254
  case "grants": {
99
255
  if (pg)
100
- throw unsupportedCapability({ dialect: dialect.name, feature: "mysqlShadowPrivileges" });
256
+ throw unsupportedCapability7({ dialect: dialect.name, feature: "mysqlShadowPrivileges" });
101
257
  return result("SHOW GRANTS FOR CURRENT_USER");
102
258
  }
103
259
  case "markerCreate":
@@ -125,19 +281,27 @@ UNION ALL SELECT ROUTINE_TYPE, ROUTINE_NAME, ROUTINE_SCHEMA FROM information_sch
125
281
  UNION ALL SELECT 'EVENT', EVENT_NAME, EVENT_SCHEMA FROM information_schema.EVENTS WHERE EVENT_SCHEMA = DATABASE()
126
282
  UNION ALL SELECT 'TRIGGER', TRIGGER_NAME, TRIGGER_SCHEMA FROM information_schema.TRIGGERS WHERE TRIGGER_SCHEMA = DATABASE()
127
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)`);
128
- case "resetPostgres": {
284
+ case "resetPostgres":
285
+ case "resetDedicatedPostgres": {
129
286
  if (!pg)
130
- throw unsupportedCapability({ dialect: dialect.name, feature: "postgresShadowReset" });
131
- 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
+ ];
132
296
  }
133
297
  case "mysqlForeignKeys": {
134
298
  if (pg)
135
- throw unsupportedCapability({ dialect: dialect.name, feature: "mysqlShadowReset" });
299
+ throw unsupportedCapability7({ dialect: dialect.name, feature: "mysqlShadowReset" });
136
300
  return result(`SET FOREIGN_KEY_CHECKS = ${operation.enabled ? "1" : "0"}`);
137
301
  }
138
302
  case "dropMysqlObject": {
139
303
  if (pg)
140
- throw unsupportedCapability({ dialect: dialect.name, feature: "mysqlShadowReset" });
304
+ throw unsupportedCapability7({ dialect: dialect.name, feature: "mysqlShadowReset" });
141
305
  return result(`DROP ${operation.object} ${dialect.quoteIdent({ name: operation.name })}`);
142
306
  }
143
307
  }
@@ -182,10 +346,10 @@ var SQLITE_SESSION_SQL = Object.freeze({
182
346
  foreignKeysOn: "PRAGMA foreign_keys = ON"
183
347
  });
184
348
  // packages/sql/src/composable.ts
185
- import { VibeError } from "@vibeorm/schema";
349
+ import { VibeError as VibeError2 } from "@vibeorm/schema";
186
350
  var fragments = new WeakMap;
187
351
  function invalid(message) {
188
- throw new VibeError({ code: "VIBE_VALIDATION", message });
352
+ throw new VibeError2({ code: "VIBE_VALIDATION", message });
189
353
  }
190
354
  function construct(parts) {
191
355
  const snapshot = Object.freeze([...parts]);
@@ -310,7 +474,7 @@ function sqlUsesIncoming(params) {
310
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 }))));
311
475
  }
312
476
  // packages/sql/src/result-decoder.ts
313
- import { VibeError as VibeError3 } from "@vibeorm/schema";
477
+ import { VibeError as VibeError4 } from "@vibeorm/schema";
314
478
 
315
479
  // packages/sql/src/pg-array.ts
316
480
  var PG_ARRAY_QUOTE = /^$|^NULL$|[{},"\\\s]/i;
@@ -365,7 +529,7 @@ function parsePgArrayLiteral(params) {
365
529
  }
366
530
 
367
531
  // packages/sql/src/codecs.ts
368
- import { VibeError as VibeError2, invalidStoredData } from "@vibeorm/schema";
532
+ import { VibeError as VibeError3, invalidStoredData } from "@vibeorm/schema";
369
533
  function enumMembershipCodec(params) {
370
534
  const { model, field, enum: enumName } = params;
371
535
  const members = new Set(params.members);
@@ -373,7 +537,7 @@ function enumMembershipCodec(params) {
373
537
  encode: (value) => {
374
538
  if (typeof value === "string" && members.has(value))
375
539
  return value;
376
- throw new VibeError2({
540
+ throw new VibeError3({
377
541
  code: "VIBE_VALIDATION",
378
542
  message: `Invalid value for enum ${enumName} on ${model}.${field}`,
379
543
  meta: { model, field, enum: enumName }
@@ -413,7 +577,7 @@ var bigIntCodec = {
413
577
  return BigInt(value.trim());
414
578
  if (typeof value === "number" && Number.isSafeInteger(value))
415
579
  return BigInt(value);
416
- 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 } });
417
581
  }
418
582
  };
419
583
  var decimalCodec = {
@@ -443,7 +607,7 @@ function parseDateTimeText(params) {
443
607
  var dateNativeCodec = {
444
608
  encode: (value) => {
445
609
  if (value instanceof Date && !Number.isFinite(value.getTime()) || typeof value === "number" && !Number.isFinite(value) || typeof value === "string" && /^[+-]?infinity$/i.test(value.trim())) {
446
- 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" });
447
611
  }
448
612
  return value;
449
613
  },
@@ -451,7 +615,7 @@ var dateNativeCodec = {
451
615
  const date = value instanceof Date ? value : typeof value === "string" ? parseDateTimeText({ text: value }) : typeof value === "number" ? new Date(value) : undefined;
452
616
  if (date !== undefined && Number.isFinite(date.getTime()))
453
617
  return date;
454
- 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" });
455
619
  }
456
620
  };
457
621
  var dateTextCodec = {
@@ -460,7 +624,7 @@ var dateTextCodec = {
460
624
  const date = value instanceof Date ? value : typeof value === "string" ? parseDateTimeText({ text: value }) : typeof value === "number" ? new Date(value) : undefined;
461
625
  if (date !== undefined && Number.isFinite(date.getTime()))
462
626
  return date.toISOString();
463
- 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" });
464
628
  },
465
629
  decode: dateNativeCodec.decode
466
630
  };
@@ -497,7 +661,7 @@ var jsonCodec = {
497
661
  try {
498
662
  return JSON.parse(value);
499
663
  } catch (cause) {
500
- throw new VibeError2({
664
+ throw new VibeError3({
501
665
  code: "VIBE_INTERNAL",
502
666
  message: "a Json column returned text that is not valid JSON",
503
667
  meta: { value },
@@ -547,7 +711,7 @@ var DIALECT_CODECS = {
547
711
 
548
712
  // packages/sql/src/result-decoder.ts
549
713
  function refuse(encoding, message) {
550
- throw new VibeError3({ code: encoding ? "VIBE_VALIDATION" : "VIBE_DATA_INVALID", message });
714
+ throw new VibeError4({ code: encoding ? "VIBE_VALIDATION" : "VIBE_DATA_INVALID", message });
551
715
  }
552
716
  function scalar(type, valid) {
553
717
  const convert = (params, encoding) => {
@@ -593,7 +757,7 @@ var extendedDecoder = Object.freeze({
593
757
  encode: (params) => {
594
758
  if (params.value === "infinity" || params.value === "-infinity") {
595
759
  if (params.dialect !== "postgres")
596
- 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" });
597
761
  return params.value;
598
762
  }
599
763
  return dateDecoder.encode(params);
@@ -651,15 +815,15 @@ var decode = Object.freeze({
651
815
  }
652
816
  });
653
817
  // packages/sql/src/exclusion.ts
654
- 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";
655
819
 
656
820
  // packages/sql/src/predicate.ts
657
- 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";
658
822
  function renderPredicate(params) {
659
823
  if (params.usage === "exclusionPredicate" && !params.dialect.capabilities.exclusionConstraints)
660
- throw unsupportedCapability2({ dialect: params.dialect.name, feature: "exclusionConstraints" });
824
+ throw unsupportedCapability8({ dialect: params.dialect.name, feature: "exclusionConstraints" });
661
825
  if (params.usage === "indexPredicate" && !params.dialect.capabilities.partialIndexes) {
662
- throw unsupportedCapability2({ dialect: params.dialect.name, feature: "partialIndexes" });
826
+ throw unsupportedCapability8({ dialect: params.dialect.name, feature: "partialIndexes" });
663
827
  }
664
828
  const context = {
665
829
  model: params.model,
@@ -694,7 +858,7 @@ var INT64_MIN = -(2n ** 63n);
694
858
  var INT64_MAX = 2n ** 63n - 1n;
695
859
  function refuse2(params) {
696
860
  const { context, rule, message } = params;
697
- throw new VibeError4({
861
+ throw new VibeError5({
698
862
  code: "VIBE_SCHEMA_INVALID",
699
863
  message: `${context.site} on "${context.model.name}": ${message}`,
700
864
  meta: { rule, model: context.model.name, site: context.site, ...params.meta ?? {} }
@@ -787,7 +951,7 @@ function resolveField(params) {
787
951
  });
788
952
  }
789
953
  if (context.usage === "check" && context.dialect.name === "mysql" && field.default?.kind === "autoincrement") {
790
- throw unsupportedCapability2({
954
+ throw unsupportedCapability8({
791
955
  dialect: "mysql",
792
956
  feature: `CHECK constraint referencing auto-increment column "${context.model.name}.${name}"`,
793
957
  hint: "mysql refuses this with error 3818 \u2014 enforce the rule in application code or on a non-generated column"
@@ -958,12 +1122,12 @@ function describe(params) {
958
1122
 
959
1123
  // packages/sql/src/exclusion.ts
960
1124
  function invalid2(rule) {
961
- 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}` } });
962
1126
  }
963
1127
  function compileExclusion(params) {
964
1128
  const { exclusion: spec, model, dialect } = params;
965
1129
  if (!dialect.capabilities.exclusionConstraints)
966
- throw unsupportedCapability3({ dialect: dialect.name, feature: "exclusionConstraints" });
1130
+ throw unsupportedCapability9({ dialect: dialect.name, feature: "exclusionConstraints" });
967
1131
  if (!spec.name || spec.name.includes("\x00"))
968
1132
  invalid2("name");
969
1133
  if (!["int8range", "tsrange", "tstzrange"].includes(spec.range.type))
@@ -1006,7 +1170,7 @@ function compileExclusion(params) {
1006
1170
  const column = field(key.field);
1007
1171
  if (column.isOptional)
1008
1172
  invalid2("nullable-key-requires-expression");
1009
- 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 })))
1010
1174
  invalid2("key-type");
1011
1175
  return `${dialect.quoteIdent({ name: column.dbName ?? column.name })} WITH =`;
1012
1176
  });
@@ -1016,13 +1180,13 @@ function compileExclusion(params) {
1016
1180
  }
1017
1181
  function renderExclusionSetup(params) {
1018
1182
  if (!params.dialect.capabilities.exclusionConstraints)
1019
- throw unsupportedCapability3({ dialect: params.dialect.name, feature: "exclusionConstraints" });
1183
+ throw unsupportedCapability9({ dialect: params.dialect.name, feature: "exclusionConstraints" });
1020
1184
  return params.exclusion.requiredExtensions.map((name) => `CREATE EXTENSION IF NOT EXISTS ${params.dialect.quoteIdent({ name })};`);
1021
1185
  }
1022
1186
  function renderExclusionDdl(params) {
1023
1187
  const { dialect, table, exclusion, operation } = params;
1024
1188
  if (!dialect.capabilities.exclusionConstraints)
1025
- throw unsupportedCapability3({ dialect: dialect.name, feature: "exclusionConstraints" });
1189
+ throw unsupportedCapability9({ dialect: dialect.name, feature: "exclusionConstraints" });
1026
1190
  const target = `ALTER TABLE ${dialect.quoteIdent({ name: table })}`;
1027
1191
  if (operation === "drop")
1028
1192
  return [`${target} DROP CONSTRAINT ${dialect.quoteIdent({ name: exclusion.name })};`];
@@ -1031,15 +1195,15 @@ function renderExclusionDdl(params) {
1031
1195
  function renderExclusionCatalog(params) {
1032
1196
  const { dialect, probe } = params;
1033
1197
  if (!dialect.capabilities.exclusionConstraints)
1034
- throw unsupportedCapability3({ dialect: dialect.name, feature: "exclusionConstraints" });
1035
- 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`;
1036
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`;
1037
1201
  }
1038
1202
  function renderExclusionProbe(params) {
1039
1203
  const { dialect, table, probe, definition } = params;
1040
1204
  if (!dialect.capabilities.exclusionConstraints)
1041
- throw unsupportedCapability3({ dialect: dialect.name, feature: "exclusionConstraints" });
1042
- 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}`];
1043
1207
  }
1044
1208
  // packages/sql/src/ast.ts
1045
1209
  var SET_OPERATORS = ["increment", "decrement", "multiply", "divide"];
@@ -1094,7 +1258,7 @@ function isExcludedRef(value) {
1094
1258
  }
1095
1259
  var ADVISORY_LOCK_RESULT_COLUMN = "acquired";
1096
1260
  // packages/sql/src/locks.ts
1097
- import { internalError, unsupportedCapability as unsupportedCapability4 } from "@vibeorm/schema";
1261
+ import { internalError, unsupportedCapability as unsupportedCapability10 } from "@vibeorm/schema";
1098
1262
  var ROW_LOCK_PROSE = Object.freeze({
1099
1263
  strengths: Object.freeze({
1100
1264
  update: "FOR UPDATE",
@@ -1114,7 +1278,7 @@ function renderRowLockClause(params) {
1114
1278
  if (syntax === null) {
1115
1279
  if (lock.strength === "update" && lock.wait === "wait")
1116
1280
  return null;
1117
- throw unsupportedCapability4({
1281
+ throw unsupportedCapability10({
1118
1282
  dialect: dialect.name,
1119
1283
  feature: `a ${describeRowLock({ lock })} locking read`,
1120
1284
  hint: `${dialect.name} has no locking-read clause at all`
@@ -1122,7 +1286,7 @@ function renderRowLockClause(params) {
1122
1286
  }
1123
1287
  const strengthText = syntax.strengths[lock.strength];
1124
1288
  if (strengthText === undefined) {
1125
- throw unsupportedCapability4({
1289
+ throw unsupportedCapability10({
1126
1290
  dialect: dialect.name,
1127
1291
  feature: `the ${describeRowLock({ lock: { ...lock, wait: "wait" } })} row-lock strength`,
1128
1292
  hint: `${dialect.name} can express: ${Object.keys(syntax.strengths).join(", ")}`
@@ -1130,7 +1294,7 @@ function renderRowLockClause(params) {
1130
1294
  }
1131
1295
  const waitText = syntax.wait[lock.wait];
1132
1296
  if (waitText === undefined) {
1133
- throw unsupportedCapability4({
1297
+ throw unsupportedCapability10({
1134
1298
  dialect: dialect.name,
1135
1299
  feature: `the "${lock.wait}" lock wait policy`,
1136
1300
  hint: `${dialect.name} can express: ${Object.keys(syntax.wait).join(", ")}`
@@ -1149,7 +1313,7 @@ function renderAdvisoryLock(params) {
1149
1313
  const { dialect, statement, collector } = params;
1150
1314
  const functions = dialect.advisoryLockFunctions;
1151
1315
  if (functions === null) {
1152
- throw unsupportedCapability4({
1316
+ throw unsupportedCapability10({
1153
1317
  dialect: dialect.name,
1154
1318
  feature: "advisory locks",
1155
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`
@@ -1191,10 +1355,10 @@ import {
1191
1355
  } from "@vibeorm/schema";
1192
1356
 
1193
1357
  // packages/sql/src/identifiers.ts
1194
- import { VibeError as VibeError6 } from "@vibeorm/schema";
1358
+ import { VibeError as VibeError7 } from "@vibeorm/schema";
1195
1359
  function assertNoNul(params) {
1196
1360
  if (params.name.includes("\x00")) {
1197
- throw new VibeError6({
1361
+ throw new VibeError7({
1198
1362
  code: "VIBE_VALIDATION",
1199
1363
  message: "an SQL identifier cannot contain a NUL character \u2014 the server would stop reading it there and address a different object",
1200
1364
  meta: { name: params.name.replaceAll("\x00", "\\0") }
@@ -1387,8 +1551,85 @@ var SQL_DIALECTS = {
1387
1551
  function getSqlDialect(params) {
1388
1552
  return SQL_DIALECTS[params.dialect];
1389
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
+ }
1390
1631
  // packages/sql/src/dialects/diagnostics.ts
1391
- import { unsupportedCapability as unsupportedCapability5 } from "@vibeorm/schema";
1632
+ import { unsupportedCapability as unsupportedCapability11 } from "@vibeorm/schema";
1392
1633
  var QUERIES = Object.freeze({
1393
1634
  postgresJsonWire: { dialect: "postgres", text: `SELECT '{"__vibeorm":1}'::jsonb AS "probe"` },
1394
1635
  sqliteTriggers: { dialect: "sqlite", text: "SELECT name, tbl_name, sql FROM sqlite_master WHERE type = 'trigger'" }
@@ -1396,7 +1637,7 @@ var QUERIES = Object.freeze({
1396
1637
  function renderDiagnostic(params) {
1397
1638
  const query = QUERIES[params.query];
1398
1639
  if (params.dialect.name !== query.dialect) {
1399
- 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}` });
1400
1641
  }
1401
1642
  return { text: query.text, values: [], returning: "none" };
1402
1643
  }
@@ -1405,7 +1646,7 @@ function isFixedDiagnostic(params) {
1405
1646
  }
1406
1647
 
1407
1648
  // packages/sql/src/dialects/postgres-diagnostics.ts
1408
- import { VibeError as VibeError7, unsupportedCapability as unsupportedCapability6 } from "@vibeorm/schema";
1649
+ import { VibeError as VibeError9, unsupportedCapability as unsupportedCapability12 } from "@vibeorm/schema";
1409
1650
  function renderPostgresExplain(params) {
1410
1651
  const { dialect, query, options } = params;
1411
1652
  requirePostgres({ dialect, feature: "query plan inspection (EXPLAIN)" });
@@ -1440,7 +1681,7 @@ var POSTGRES_WORKLOAD_LIMITS = Object.freeze({
1440
1681
  });
1441
1682
  function requirePostgres(params) {
1442
1683
  if (params.dialect.name !== "postgres") {
1443
- throw unsupportedCapability6({
1684
+ throw unsupportedCapability12({
1444
1685
  dialect: params.dialect.name,
1445
1686
  feature: params.feature,
1446
1687
  hint: "plan inspection and workload statistics are PostgreSQL-shaped; portable operation tracing works on every dialect"
@@ -1458,7 +1699,7 @@ function renderPostgresWorkload(params) {
1458
1699
  if (query === "statementSnapshot") {
1459
1700
  const bounded = limit ?? 20;
1460
1701
  if (!Number.isInteger(bounded) || bounded < POSTGRES_WORKLOAD_LIMITS.minLimit || bounded > POSTGRES_WORKLOAD_LIMITS.maxLimit) {
1461
- throw new VibeError7({
1702
+ throw new VibeError9({
1462
1703
  code: "VIBE_CONFIG",
1463
1704
  message: `workload snapshot limit must be an integer between ${POSTGRES_WORKLOAD_LIMITS.minLimit} and ${POSTGRES_WORKLOAD_LIMITS.maxLimit}, got ${String(limit)}`,
1464
1705
  meta: { limit }
@@ -1477,7 +1718,7 @@ function renderPostgresWorkload(params) {
1477
1718
  function requireArg(params) {
1478
1719
  const { value, name, query } = params;
1479
1720
  if (value === undefined || value.length === 0) {
1480
- throw new VibeError7({
1721
+ throw new VibeError9({
1481
1722
  code: "VIBE_CONFIG",
1482
1723
  message: `the "${query}" diagnostic read requires a ${name}`,
1483
1724
  meta: { query, argument: name }
@@ -1487,10 +1728,10 @@ function requireArg(params) {
1487
1728
  }
1488
1729
 
1489
1730
  // packages/sql/src/dialects/postgres-rls-readiness.ts
1490
- import { unsupportedCapability as unsupportedCapability8 } from "@vibeorm/schema";
1731
+ import { unsupportedCapability as unsupportedCapability14 } from "@vibeorm/schema";
1491
1732
 
1492
1733
  // packages/sql/src/dialects/postgres-rls.ts
1493
- 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";
1494
1735
  var NATIVE_RLS = Object.freeze({ policyName: "vibeorm_managed", tableSchema: "public", settingPrefix: "vibeorm.", parentAlias: "parent" });
1495
1736
  var COLUMN_TYPES = {
1496
1737
  String: { default: "text", native: { text: "text", varchar: "varchar", charactervarying: "varchar", uuid: "uuid" } },
@@ -1503,18 +1744,18 @@ var COLUMN_TYPES = {
1503
1744
  };
1504
1745
  function requireRls(params) {
1505
1746
  if (!params.dialect.capabilities.nativeRowLevelSecurity) {
1506
- throw unsupportedCapability7({ dialect: params.dialect.name, feature: "nativeRowLevelSecurity" });
1747
+ throw unsupportedCapability13({ dialect: params.dialect.name, feature: "nativeRowLevelSecurity" });
1507
1748
  }
1508
1749
  }
1509
1750
  function identifier2(params) {
1510
1751
  if (typeof params.name !== "string" || params.name.length === 0 || params.name.includes("\x00") || new TextEncoder().encode(params.name).length > 63) {
1511
- 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" });
1512
1753
  }
1513
1754
  return params.dialect.quoteIdent({ name: params.name });
1514
1755
  }
1515
1756
  function tableRef(params) {
1516
1757
  if (params.schema !== undefined && params.schema !== "public" && params.schema !== "pg_temp") {
1517
- 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" });
1518
1759
  }
1519
1760
  return `${identifier2({ dialect: params.dialect, name: params.schema ?? NATIVE_RLS.tableSchema })}.${identifier2({ dialect: params.dialect, name: params.table })}`;
1520
1761
  }
@@ -1555,14 +1796,14 @@ function renderRlsColumnType(params) {
1555
1796
  if (native !== undefined)
1556
1797
  return native;
1557
1798
  }
1558
- 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}` });
1559
1800
  }
1560
1801
  function protectedModel(params) {
1561
1802
  requireRls(params);
1562
1803
  assertValidSchemaIR({ schema: params.schema });
1563
1804
  const model = params.schema.models.find((entry) => entry.name === params.model);
1564
1805
  if (model === undefined || model.rls === undefined || model.rls === "unprotected") {
1565
- 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 } });
1566
1807
  }
1567
1808
  return model;
1568
1809
  }
@@ -1595,7 +1836,7 @@ function predicate(params) {
1595
1836
  }).join(" AND ");
1596
1837
  return `EXISTS (SELECT 1 FROM ${tableRef({ dialect, table: parent.dbName ?? parent.name })} AS ${alias} WHERE ${join})`;
1597
1838
  }
1598
- 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" });
1599
1840
  }
1600
1841
  function renderRlsPolicy(params) {
1601
1842
  const model = protectedModel(params);
@@ -1629,7 +1870,7 @@ function renderRlsContext(params) {
1629
1870
  function renderRlsRole(params) {
1630
1871
  requireRls(params);
1631
1872
  if (typeof params.role !== "string" || params.role.trim().length === 0 || params.role.includes("\x00")) {
1632
- 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" });
1633
1874
  }
1634
1875
  const collector = new ParamCollector(params.dialect);
1635
1876
  return query({ text: `SELECT set_config('role', ${collector.add(params.role)}, true)`, values: collector.values });
@@ -1781,7 +2022,7 @@ ORDER BY c.relname, p.polname`,
1781
2022
  });
1782
2023
  function requireRls2(params) {
1783
2024
  if (!params.dialect.capabilities.nativeRowLevelSecurity) {
1784
- throw unsupportedCapability8({ dialect: params.dialect.name, feature: "nativeRowLevelSecurity" });
2025
+ throw unsupportedCapability14({ dialect: params.dialect.name, feature: "nativeRowLevelSecurity" });
1785
2026
  }
1786
2027
  }
1787
2028
  function renderRlsReadinessQuery(params) {
@@ -1813,7 +2054,7 @@ function renderRlsPolicyPath(params) {
1813
2054
  }
1814
2055
 
1815
2056
  // packages/sql/src/render.ts
1816
- import { internalError as internalError2, unsupportedCapability as unsupportedCapability9 } from "@vibeorm/schema";
2057
+ import { assertSqlNamespace as assertSqlNamespace2, internalError as internalError2, unsupportedCapability as unsupportedCapability15 } from "@vibeorm/schema";
1817
2058
 
1818
2059
  // packages/sql/src/like.ts
1819
2060
  function escapeLikePattern(params) {
@@ -1919,7 +2160,10 @@ function quoteProjection(dialect, column) {
1919
2160
  return `encode(${ref}, 'base64') AS ${alias}`;
1920
2161
  }
1921
2162
  function renderTable(dialect, table) {
1922
- 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}`;
1923
2167
  if (table.alias === undefined)
1924
2168
  return name;
1925
2169
  return `${name} AS ${dialect.quoteIdent({ name: table.alias })}`;
@@ -1958,7 +2202,7 @@ function renderAggRef(dialect, agg) {
1958
2202
  function assertScalarArrays(dialect, feature) {
1959
2203
  if (dialect.capabilities.scalarArrays)
1960
2204
  return;
1961
- throw unsupportedCapability9({
2205
+ throw unsupportedCapability15({
1962
2206
  dialect: dialect.name,
1963
2207
  feature,
1964
2208
  hint: "only postgres has native array columns \u2014 model the list as a related table instead"
@@ -1992,7 +2236,7 @@ function renderExpr(params) {
1992
2236
  }
1993
2237
  const column = quoteCol(dialect, expr.column);
1994
2238
  if (dialect.inArrayStrategy === "any") {
1995
- const base = `${column} = ANY(${collector.add([...expr.values])})`;
2239
+ const base = `${column} = ANY(${collector.add(Array.isArray(expr.values) ? [...expr.values] : expr.values)})`;
1996
2240
  return expr.negate === true ? `NOT (${base})` : base;
1997
2241
  }
1998
2242
  const placeholders = collector.addMany(expr.values);
@@ -2089,11 +2333,11 @@ function renderExpr(params) {
2089
2333
  }
2090
2334
  case "arrayContainsAll": {
2091
2335
  assertScalarArrays(dialect, 'the scalar-list filter "hasEvery"');
2092
- 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)}`;
2093
2337
  }
2094
2338
  case "arrayOverlaps": {
2095
2339
  assertScalarArrays(dialect, 'the scalar-list filter "hasSome"');
2096
- 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)}`;
2097
2341
  }
2098
2342
  case "arrayIsEmpty": {
2099
2343
  assertScalarArrays(dialect, 'the scalar-list filter "isEmpty"');
@@ -2168,7 +2412,7 @@ function renderJsonLike(params) {
2168
2412
  function renderJsonFilter(params) {
2169
2413
  const { dialect, expr, collector } = params;
2170
2414
  if (!dialect.supportedJsonOps.includes(expr.op)) {
2171
- throw unsupportedCapability9({
2415
+ throw unsupportedCapability15({
2172
2416
  dialect: dialect.name,
2173
2417
  feature: `the json filter "${expr.op}"`,
2174
2418
  hint: `this dialect can express: ${dialect.supportedJsonOps.join(", ")}`
@@ -2232,7 +2476,7 @@ function renderJsonFilter(params) {
2232
2476
  const elements = Array.isArray(expr.value) ? expr.value : [expr.value];
2233
2477
  const tests = elements.map((element) => {
2234
2478
  if (element === null || typeof element === "object" && element !== null) {
2235
- throw unsupportedCapability9({
2479
+ throw unsupportedCapability15({
2236
2480
  dialect: dialect.name,
2237
2481
  feature: "json array_contains with object/array/null elements",
2238
2482
  hint: "sqlite expresses scalar-element containment only \u2014 deep structural containment needs postgres or mysql"
@@ -2383,7 +2627,7 @@ function renderSelect(params) {
2383
2627
  let distinctPrefix = "";
2384
2628
  if (statement.distinctOn !== undefined && statement.distinctOn.length > 0) {
2385
2629
  if (!dialect.capabilities.distinctOn) {
2386
- throw unsupportedCapability9({
2630
+ throw unsupportedCapability15({
2387
2631
  dialect: dialect.name,
2388
2632
  feature: "SELECT DISTINCT ON",
2389
2633
  hint: "postgres-only \u2014 the runtime emulates distinct client-side on this dialect"
@@ -2414,7 +2658,7 @@ function renderSelect(params) {
2414
2658
  }
2415
2659
  if (statement.lateralJoins !== undefined && statement.lateralJoins.length > 0) {
2416
2660
  if (!dialect.capabilities.lateralJoin) {
2417
- throw unsupportedCapability9({
2661
+ throw unsupportedCapability15({
2418
2662
  dialect: dialect.name,
2419
2663
  feature: "LATERAL JOIN relation loading",
2420
2664
  hint: 'use the portable "query" relation strategy on this dialect'
@@ -2499,7 +2743,7 @@ function renderInsert(params) {
2499
2743
  let target = "";
2500
2744
  if (onConflict.constraint !== undefined) {
2501
2745
  if (dialect.name !== "postgres") {
2502
- throw unsupportedCapability9({
2746
+ throw unsupportedCapability15({
2503
2747
  dialect: dialect.name,
2504
2748
  feature: "a named-constraint conflict target (ON CONFLICT ON CONSTRAINT)",
2505
2749
  hint: "only postgres names constraints in conflict targets \u2014 use a column-list target"
@@ -2514,7 +2758,7 @@ function renderInsert(params) {
2514
2758
  }
2515
2759
  text += ` ON CONFLICT${target} DO NOTHING`;
2516
2760
  } else if (onConflict.constraint !== undefined || onConflict.conflictWhere !== undefined) {
2517
- throw unsupportedCapability9({
2761
+ throw unsupportedCapability15({
2518
2762
  dialect: dialect.name,
2519
2763
  feature: "a refined conflict target (constraint / partial-index predicate) on INSERT IGNORE",
2520
2764
  hint: "mysql skips on any duplicate key \u2014 drop the refinement or gate the call per dialect"
@@ -2532,7 +2776,7 @@ function renderInsert(params) {
2532
2776
  throw internalError2({ message: "lastInsertIdColumn is a mysql (onDuplicateKey) construct" });
2533
2777
  }
2534
2778
  if (onConflict.constraint !== undefined && dialect.name !== "postgres") {
2535
- throw unsupportedCapability9({
2779
+ throw unsupportedCapability15({
2536
2780
  dialect: dialect.name,
2537
2781
  feature: "a named-constraint conflict target (ON CONFLICT ON CONSTRAINT)",
2538
2782
  hint: "sqlite conflict targets are column lists \u2014 name the indexed columns instead"
@@ -2548,14 +2792,14 @@ function renderInsert(params) {
2548
2792
  text += ` ON CONFLICT${target} DO UPDATE SET ${assignments}`;
2549
2793
  } else {
2550
2794
  if (onConflict.constraint !== undefined) {
2551
- throw unsupportedCapability9({
2795
+ throw unsupportedCapability15({
2552
2796
  dialect: dialect.name,
2553
2797
  feature: "a named-constraint conflict target on ON DUPLICATE KEY UPDATE",
2554
2798
  hint: "mysql's ODKU fires on any duplicate key \u2014 no target can be named"
2555
2799
  });
2556
2800
  }
2557
2801
  if (onConflict.conflictWhere !== undefined) {
2558
- throw unsupportedCapability9({
2802
+ throw unsupportedCapability15({
2559
2803
  dialect: dialect.name,
2560
2804
  feature: "a partial-index conflict target on ON DUPLICATE KEY UPDATE",
2561
2805
  hint: "mysql's ODKU fires on any duplicate key \u2014 a partial arbiter cannot be selected; gate the call per dialect"
@@ -2637,85 +2881,8 @@ function renderDelete(params) {
2637
2881
  const returning = applyReturning({ dialect, requested: statement.returning });
2638
2882
  return { text: text + returning.suffix, values: collector.values, returning: returning.status };
2639
2883
  }
2640
- // packages/sql/src/dialects/sqlite-table-definition.ts
2641
- import { VibeError as VibeError9 } from "@vibeorm/schema";
2642
- function tableDefinitionParts(params) {
2643
- const sql = params.sql;
2644
- if (!/^\s*CREATE\s+(?:TEMP(?:ORARY)?\s+)?TABLE\b/i.test(sql))
2645
- throw unavailable();
2646
- const parts = [];
2647
- let start = -1;
2648
- let depth = 0;
2649
- let quote;
2650
- for (let index = 0;index < sql.length; index++) {
2651
- const char = sql[index];
2652
- if (quote !== undefined) {
2653
- if (char === quote) {
2654
- if (quote !== "]" && sql[index + 1] === quote)
2655
- index++;
2656
- else
2657
- quote = undefined;
2658
- }
2659
- continue;
2660
- }
2661
- if (char === "'" || char === '"' || char === "`") {
2662
- quote = char;
2663
- continue;
2664
- }
2665
- if (char === "[") {
2666
- quote = "]";
2667
- continue;
2668
- }
2669
- if (char === "-" && sql[index + 1] === "-") {
2670
- const end = sql.indexOf(`
2671
- `, index + 2);
2672
- if (end < 0)
2673
- break;
2674
- index = end;
2675
- continue;
2676
- }
2677
- if (char === "/" && sql[index + 1] === "*") {
2678
- const end = sql.indexOf("*/", index + 2);
2679
- if (end < 0)
2680
- break;
2681
- index = end + 1;
2682
- continue;
2683
- }
2684
- if (char === "(") {
2685
- if (depth === 0)
2686
- start = index + 1;
2687
- depth++;
2688
- } else if (char === ")") {
2689
- depth--;
2690
- if (depth === 0 && start >= 0) {
2691
- parts.push(sql.slice(start, index).trim());
2692
- return { clauses: parts, suffix: sql.slice(index + 1) };
2693
- }
2694
- } else if (char === "," && depth === 1) {
2695
- parts.push(sql.slice(start, index).trim());
2696
- start = index + 1;
2697
- }
2698
- }
2699
- throw unavailable();
2700
- }
2701
- function unavailable() {
2702
- return new VibeError9({ code: "VIBE_MIGRATION", message: "Cannot preserve table definition", meta: { reason: "table-definition-unavailable" } });
2703
- }
2704
- function sqliteColumnClauses(params) {
2705
- const columns = [];
2706
- for (const part of tableDefinitionParts(params).clauses) {
2707
- const token = /^(?:"((?:[^"]|"")+)"|`((?:[^`]|``)+)`|\[([^\]]+)\]|([A-Za-z_][A-Za-z_0-9]*))/.exec(part);
2708
- if (token === null)
2709
- throw unavailable();
2710
- if (token[4] !== undefined && /^(?:CONSTRAINT|PRIMARY|UNIQUE|CHECK|FOREIGN)$/i.test(token[4]))
2711
- continue;
2712
- const name = token[1]?.replaceAll('""', '"') ?? token[2]?.replaceAll("``", "`") ?? token[3] ?? token[4];
2713
- columns.push({ name, sql: part });
2714
- }
2715
- return columns;
2716
- }
2717
2884
  // packages/sql/src/dialects/postgres-type-identity.ts
2718
- import { unsupportedCapability as unsupportedCapability10 } from "@vibeorm/schema";
2885
+ import { unsupportedCapability as unsupportedCapability16 } from "@vibeorm/schema";
2719
2886
  var IDENTIFIER = '(?:"(?:[^"\\x00]|"")+"|[a-zA-Z_][a-zA-Z_0-9$]*)';
2720
2887
  var MODIFIER_VALUE = `(?:[+-]?\\d+|${IDENTIFIER}|'(?:[^'\\x00]|'')*')`;
2721
2888
  var TYPE_NAME = new RegExp(`^\\s*(${IDENTIFIER})(?:\\s*\\.\\s*(${IDENTIFIER}))?\\s*(\\(\\s*${MODIFIER_VALUE}(?:\\s*,\\s*${MODIFIER_VALUE})*\\s*\\))?\\s*((?:\\[\\s*\\]\\s*)*)$`);
@@ -2742,13 +2909,13 @@ function parsePostgresTypeName(params) {
2742
2909
  }
2743
2910
  function renderPostgresTypeName(params) {
2744
2911
  if (params.dialect.name !== "postgres")
2745
- throw unsupportedCapability10({ dialect: params.dialect.name, feature: "postgresTypeIdentity" });
2912
+ throw unsupportedCapability16({ dialect: params.dialect.name, feature: "postgresTypeIdentity" });
2746
2913
  const { dialect, type } = params;
2747
2914
  return `${type.namespace === undefined ? "" : `${dialect.quoteIdent({ name: type.namespace })}.`}${dialect.quoteIdent({ name: type.name })}${type.modifier}${type.array ? "[]" : ""}`;
2748
2915
  }
2749
2916
  function renderPostgresTypeIdentity(params) {
2750
2917
  if (params.dialect.name !== "postgres")
2751
- throw unsupportedCapability10({ dialect: params.dialect.name, feature: "postgresTypeIdentity" });
2918
+ throw unsupportedCapability16({ dialect: params.dialect.name, feature: "postgresTypeIdentity" });
2752
2919
  const collector = new ParamCollector(params.dialect);
2753
2920
  const { source } = params;
2754
2921
  let text;
@@ -2761,11 +2928,11 @@ function renderPostgresTypeIdentity(params) {
2761
2928
  return { text, values: collector.values, returning: "none" };
2762
2929
  }
2763
2930
  // packages/sql/src/dialects/postgres-default-identity.ts
2764
- import { unsupportedCapability as unsupportedCapability11 } from "@vibeorm/schema";
2931
+ import { unsupportedCapability as unsupportedCapability17 } from "@vibeorm/schema";
2765
2932
  function renderPostgresDefaultFunctionIdentity(params) {
2766
2933
  const { dialect, table, column } = params;
2767
2934
  if (dialect.name !== "postgres")
2768
- throw unsupportedCapability11({ dialect: dialect.name, feature: "defaultFunctionIdentity" });
2935
+ throw unsupportedCapability17({ dialect: dialect.name, feature: "defaultFunctionIdentity" });
2769
2936
  const collector = new ParamCollector(dialect);
2770
2937
  const namespace = collector.add(table.namespace);
2771
2938
  const name = collector.add(table.name);
@@ -2789,28 +2956,28 @@ WHERE n.nspname = ${namespace} AND c.relname = ${name} AND a.attname = ${field}
2789
2956
  };
2790
2957
  }
2791
2958
  // packages/sql/src/dialects/constraint-owned-index.ts
2792
- import { unsupportedCapability as unsupportedCapability12 } from "@vibeorm/schema";
2959
+ import { unsupportedCapability as unsupportedCapability18 } from "@vibeorm/schema";
2793
2960
  function renderConstraintOwnedIndexDrop(params) {
2794
2961
  if (params.dialect.name !== "postgres")
2795
- throw unsupportedCapability12({ dialect: params.dialect.name, feature: "constraintOwnedIndexDrop" });
2962
+ throw unsupportedCapability18({ dialect: params.dialect.name, feature: "constraintOwnedIndexDrop" });
2796
2963
  const quote = (name) => params.dialect.quoteIdent({ name });
2797
2964
  return { text: `ALTER TABLE ${quote(params.table)} DROP CONSTRAINT ${quote(params.constraint)};`, values: [], returning: "none" };
2798
2965
  }
2799
2966
  // packages/sql/src/dialects/mysql-check-probe.ts
2800
- import { unsupportedCapability as unsupportedCapability13 } from "@vibeorm/schema";
2967
+ import { unsupportedCapability as unsupportedCapability19 } from "@vibeorm/schema";
2801
2968
  function renderMysqlCheckProbe(params) {
2802
2969
  if (params.dialect.name !== "mysql")
2803
- throw unsupportedCapability13({ dialect: params.dialect.name, feature: "temporaryCheckProbe" });
2970
+ throw unsupportedCapability19({ dialect: params.dialect.name, feature: "temporaryCheckProbe" });
2804
2971
  const q = (name) => params.dialect.quoteIdent({ name });
2805
2972
  const probe = q(params.probe);
2806
2973
  switch (params.operation) {
2807
2974
  case "clone":
2808
2975
  if (params.table === undefined)
2809
- 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" });
2810
2977
  return { text: `CREATE TEMPORARY TABLE ${probe} LIKE ${q(params.table.namespace)}.${q(params.table.name)}`, values: [], returning: "none" };
2811
2978
  case "add": {
2812
2979
  if (params.expression === undefined || params.definition === undefined)
2813
- 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" });
2814
2981
  const parts = tableDefinitionParts({ sql: params.definition });
2815
2982
  return { text: `CREATE TEMPORARY TABLE ${probe} (
2816
2983
  ${[...parts.clauses, `CONSTRAINT ${probe} CHECK (${params.expression})`].join(`,
@@ -2856,31 +3023,31 @@ function sqliteTableConstraints(params) {
2856
3023
  return result;
2857
3024
  }
2858
3025
  // packages/sql/src/dialects/migration-visibility.ts
2859
- import { unsupportedCapability as unsupportedCapability14 } from "@vibeorm/schema";
3026
+ import { unsupportedCapability as unsupportedCapability20 } from "@vibeorm/schema";
2860
3027
  function renderMigrationVisibility(params) {
2861
3028
  if (params.dialect.name !== "mysql")
2862
- throw unsupportedCapability14({ dialect: params.dialect.name, feature: "mysqlCatalogVisibility" });
3029
+ throw unsupportedCapability20({ dialect: params.dialect.name, feature: "mysqlCatalogVisibility" });
2863
3030
  const collector = new ParamCollector(params.dialect);
2864
3031
  const grantee = "CONCAT(QUOTE(SUBSTRING_INDEX(CURRENT_USER(), '@', 1)), '@', QUOTE(SUBSTRING_INDEX(CURRENT_USER(), '@', -1)))";
2865
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" };
2866
3033
  }
2867
3034
  // packages/sql/src/dialects/migration-inventory.ts
2868
- import { unsupportedCapability as unsupportedCapability15 } from "@vibeorm/schema";
3035
+ import { unsupportedCapability as unsupportedCapability21 } from "@vibeorm/schema";
2869
3036
  function renderSqliteColumnInventory(params) {
2870
3037
  if (params.dialect.name !== "sqlite")
2871
- throw unsupportedCapability15({ dialect: params.dialect.name, feature: "sqliteColumnInventory" });
3038
+ throw unsupportedCapability21({ dialect: params.dialect.name, feature: "sqliteColumnInventory" });
2872
3039
  const collector = new ParamCollector(params.dialect);
2873
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" };
2874
3041
  }
2875
3042
  function renderSqliteForeignKeyInventory(params) {
2876
3043
  if (params.dialect.name !== "sqlite")
2877
- throw unsupportedCapability15({ dialect: params.dialect.name, feature: "sqliteForeignKeyInventory" });
3044
+ throw unsupportedCapability21({ dialect: params.dialect.name, feature: "sqliteForeignKeyInventory" });
2878
3045
  const collector = new ParamCollector(params.dialect);
2879
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" };
2880
3047
  }
2881
3048
  function renderSqliteRebuildObjects(params) {
2882
3049
  if (params.dialect.name !== "sqlite")
2883
- throw unsupportedCapability15({ dialect: params.dialect.name, feature: "sqliteRebuildObjects" });
3050
+ throw unsupportedCapability21({ dialect: params.dialect.name, feature: "sqliteRebuildObjects" });
2884
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" };
2885
3052
  }
2886
3053
  function renderMigrationInventory(params) {
@@ -2900,6 +3067,8 @@ UNION ALL SELECT 'trigger', t.tgname::text, r.relname::text, NULL, NULL, NULL FR
2900
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')
2901
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
2902
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}`}
2903
3072
  ORDER BY kind, parent, name`, values: collector.values, returning: "none" };
2904
3073
  }
2905
3074
  if (params.dialect.name === "mysql") {
@@ -2917,12 +3086,17 @@ ORDER BY kind, parent, name`, values: collector.values, returning: "none" };
2917
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" };
2918
3087
  }
2919
3088
  // packages/sql/src/dialects/migration-objects.ts
2920
- import { internalError as internalError3, unsupportedCapability as unsupportedCapability16 } from "@vibeorm/schema";
3089
+ import { internalError as internalError3, unsupportedCapability as unsupportedCapability22 } from "@vibeorm/schema";
2921
3090
  function renderMigrationObjectQuery(params) {
2922
3091
  return objectQuery({ ...params, collector: new ParamCollector(params.dialect) });
2923
3092
  }
2924
3093
  function objectQuery(params) {
2925
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
+ }
2926
3100
  const physical = "table" in object ? object.table : object.name;
2927
3101
  const namespace = collector.add(physical.namespace);
2928
3102
  const name = collector.add(physical.name);
@@ -2984,7 +3158,7 @@ function objectQuery(params) {
2984
3158
  break;
2985
3159
  case "constraint":
2986
3160
  if (object.constraintType === "exclusion")
2987
- throw unsupportedCapability16({ dialect: "mysql", feature: "exclusionConstraints" });
3161
+ throw unsupportedCapability22({ dialect: "mysql", feature: "exclusionConstraints" });
2988
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)}`;
2989
3163
  break;
2990
3164
  case "index":
@@ -2994,15 +3168,15 @@ function objectQuery(params) {
2994
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}`;
2995
3169
  break;
2996
3170
  default:
2997
- throw unsupportedCapability16({ dialect: "mysql", feature: `inspect:${object.kind}` });
3171
+ throw unsupportedCapability22({ dialect: "mysql", feature: `inspect:${object.kind}` });
2998
3172
  }
2999
3173
  } else {
3000
3174
  if (physical.namespace !== "main" && physical.namespace !== "temp")
3001
- throw unsupportedCapability16({ dialect: "sqlite", feature: "attachedSchemaInspection" });
3175
+ throw unsupportedCapability22({ dialect: "sqlite", feature: "attachedSchemaInspection" });
3002
3176
  const catalog = `${dialect.quoteIdent({ name: physical.namespace })}.sqlite_schema`;
3003
3177
  const kind = object.kind === "table" || object.kind === "view" ? object.kind : object.kind === "trigger" ? "trigger" : object.kind === "index" ? "index" : "table";
3004
3178
  if (["function", "sequence", "postgresExtension", "enum"].includes(object.kind) || object.kind === "constraint" && object.constraintType === "exclusion")
3005
- throw unsupportedCapability16({ dialect: "sqlite", feature: `inspect:${object.kind}` });
3179
+ throw unsupportedCapability22({ dialect: "sqlite", feature: `inspect:${object.kind}` });
3006
3180
  const sqliteParams = new ParamCollector(dialect);
3007
3181
  if (object.kind === "column" || object.kind === "columnDefault" || object.kind === "generatedColumn") {
3008
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)}`;
@@ -3032,10 +3206,14 @@ function renderMigrationDependencies(params) {
3032
3206
  }
3033
3207
  function dependencyQuery(params) {
3034
3208
  if (params.dialect.name !== "postgres")
3035
- throw unsupportedCapability16({ dialect: params.dialect.name, feature: "catalogDependencies" });
3209
+ throw unsupportedCapability22({ dialect: params.dialect.name, feature: "catalogDependencies" });
3036
3210
  const object = params.identity;
3037
- const physical = "table" in object ? object.table : object.name;
3038
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;
3039
3217
  const namespace = collector.add(physical.namespace);
3040
3218
  const name = collector.add(physical.name);
3041
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}`;
@@ -3085,7 +3263,7 @@ function inspectionReferences(params) {
3085
3263
  function renderMigrationObjectBatch(params) {
3086
3264
  const { dialect } = params;
3087
3265
  if (dialect.name !== "postgres")
3088
- throw unsupportedCapability16({ dialect: dialect.name, feature: "batchedMigrationInspection" });
3266
+ throw unsupportedCapability22({ dialect: dialect.name, feature: "batchedMigrationInspection" });
3089
3267
  const groups = new Map;
3090
3268
  for (const [position, identity] of params.identities.entries()) {
3091
3269
  const kind = identity.kind === "constraint" ? `${identity.kind}:${identity.constraintType}` : identity.kind === "generatedColumn" ? "columnDefault" : identity.kind;
@@ -3118,16 +3296,16 @@ function renderMigrationNamespace(params) {
3118
3296
  }
3119
3297
  function renderCheckProbe(params) {
3120
3298
  if (params.dialect.name !== "postgres")
3121
- throw unsupportedCapability16({ dialect: params.dialect.name, feature: "rollbackCheckProbe" });
3299
+ throw unsupportedCapability22({ dialect: params.dialect.name, feature: "rollbackCheckProbe" });
3122
3300
  const q = (name) => params.dialect.quoteIdent({ name });
3123
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" };
3124
3302
  }
3125
3303
  // packages/sql/src/dialects/postgres-migration.ts
3126
- import { VibeError as VibeError10, unsupportedCapability as unsupportedCapability17 } from "@vibeorm/schema";
3304
+ import { VibeError as VibeError11, unsupportedCapability as unsupportedCapability23 } from "@vibeorm/schema";
3127
3305
  var SETTING_VALUE = /^[0-9]+(?:\.[0-9]+)?\s*(?:us|ms|s|min|h|d)?$/;
3128
3306
  function requirePostgres2(params) {
3129
3307
  if (params.dialect.name !== "postgres") {
3130
- throw unsupportedCapability17({ dialect: params.dialect.name, feature: params.feature });
3308
+ throw unsupportedCapability23({ dialect: params.dialect.name, feature: params.feature });
3131
3309
  }
3132
3310
  }
3133
3311
  function renderMigrationSessionRead(params) {
@@ -3142,7 +3320,7 @@ function renderMigrationSessionSet(params) {
3142
3320
  requirePostgres2({ dialect: params.dialect, feature: "migrationSessionSettings" });
3143
3321
  const { milliseconds, setting } = params;
3144
3322
  if (!Number.isSafeInteger(milliseconds) || milliseconds < 0) {
3145
- throw new VibeError10({
3323
+ throw new VibeError11({
3146
3324
  code: "VIBE_MIGRATION",
3147
3325
  message: `${setting} must be a non-negative integer number of milliseconds (got ${String(milliseconds)})`,
3148
3326
  meta: { reason: "execution-metadata-invalid", setting, value: milliseconds }
@@ -3271,12 +3449,14 @@ export {
3271
3449
  isFixedDiagnostic,
3272
3450
  isJsonParamCell,
3273
3451
  isListSetOperation,
3452
+ isNativeEnumArrayParameter,
3274
3453
  isSetOperation,
3275
3454
  isSqlDefaultCell,
3276
3455
  isSqlFragment,
3277
3456
  jsonParamCell,
3278
3457
  mapConflictColumns,
3279
3458
  mysqlDialect,
3459
+ nativeEnumArrayParameter,
3280
3460
  parseDateTimeText,
3281
3461
  parsePgArrayLiteral,
3282
3462
  parsePostgresTypeName,
@@ -3293,7 +3473,10 @@ export {
3293
3473
  renderExclusionProbe,
3294
3474
  renderExclusionSetup,
3295
3475
  renderExpr,
3476
+ renderExternalDependents,
3477
+ renderExternalOwnershipCatalog,
3296
3478
  renderFragment,
3479
+ renderIndexColumns,
3297
3480
  renderIndexStateQuery,
3298
3481
  renderMigrationDependencies,
3299
3482
  renderMigrationHistoryQuery,
@@ -3312,6 +3495,8 @@ export {
3312
3495
  renderMysqlObjectMembers,
3313
3496
  renderPostgresDefaultFunctionIdentity,
3314
3497
  renderPostgresExplain,
3498
+ renderPostgresIndexKeys,
3499
+ renderPostgresPhysicalCatalog,
3315
3500
  renderPostgresTypeIdentity,
3316
3501
  renderPostgresTypeName,
3317
3502
  renderPostgresWorkload,
@@ -3345,7 +3530,8 @@ export {
3345
3530
  sqliteTableConstraints,
3346
3531
  startsWithPattern,
3347
3532
  strictMatchPattern,
3533
+ tableDefinitionParts,
3348
3534
  toPgArrayLiteral
3349
3535
  };
3350
3536
 
3351
- //# debugId=B1F6683E5EF3B96D64756E2164756E21
3537
+ //# debugId=55E18657169AA23764756E2164756E21