@vibeorm/sql 2.2.0 → 2.3.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
@@ -16,6 +16,130 @@ class ParamCollector {
16
16
  }
17
17
  }
18
18
 
19
+ // packages/sql/src/dialects/module-dependency.ts
20
+ function renderModuleDependencyQuery(params) {
21
+ const { dialect, operation } = params;
22
+ if (operation.kind === "visibility")
23
+ return dialect.name === "mysql" ? { text: "SHOW GRANTS FOR CURRENT_USER", values: [], returning: "none" } : undefined;
24
+ if (dialect.name === "sqlite" || operation.tables.length === 0)
25
+ return;
26
+ const collector = new ParamCollector(dialect);
27
+ const owned = operation.tables.map((table, index) => `SELECT ${collector.add(operation.namespace)}${index === 0 ? " AS namespace" : ""}, ${collector.add(table)}${index === 0 ? " AS table_name" : ""}`).join(" UNION ALL ");
28
+ const pg = dialect.name === "postgres";
29
+ const nameKey = ({ column }) => pg ? column : `CAST(IF(@@lower_case_table_names = 0, ${column}, LOWER(${column})) AS BINARY)`;
30
+ const isOwned = ({ namespace, table }) => `EXISTS (SELECT 1 FROM owned_tables o WHERE ${nameKey({ column: namespace })} = ${nameKey({ column: "o.namespace" })} AND ${nameKey({ column: table })} = ${nameKey({ column: "o.table_name" })})`;
31
+ const sourceNamespace = pg ? "sn.nspname" : "fk.CONSTRAINT_SCHEMA";
32
+ const sourceTable = pg ? "s.relname" : "fk.TABLE_NAME";
33
+ const targetNamespace = pg ? "tn.nspname" : "fk.UNIQUE_CONSTRAINT_SCHEMA";
34
+ const targetTable = pg ? "t.relname" : "fk.REFERENCED_TABLE_NAME";
35
+ const from = pg ? "pg_catalog.pg_constraint fk JOIN pg_catalog.pg_class s ON s.oid = fk.conrelid JOIN pg_catalog.pg_namespace sn ON sn.oid = s.relnamespace JOIN pg_catalog.pg_class t ON t.oid = fk.confrelid JOIN pg_catalog.pg_namespace tn ON tn.oid = t.relnamespace WHERE fk.contype = 'f'" : "information_schema.REFERENTIAL_CONSTRAINTS fk";
36
+ return {
37
+ text: `WITH owned_tables AS (${owned})
38
+ SELECT * FROM (SELECT ${pg ? "fk.conname" : "fk.CONSTRAINT_NAME"} AS constraint_name, ${sourceNamespace} AS source_namespace, ${sourceTable} AS source_table, ${targetNamespace} AS target_namespace, ${targetTable} AS target_table, ${isOwned({ namespace: sourceNamespace, table: sourceTable })} AS source_owned, ${isOwned({ namespace: targetNamespace, table: targetTable })} AS target_owned FROM ${from}) dependencies
39
+ WHERE source_owned OR target_owned
40
+ ORDER BY source_namespace, source_table, constraint_name`,
41
+ values: collector.values,
42
+ returning: "none"
43
+ };
44
+ }
45
+ // packages/sql/src/dialects/migration-replay-coverage.ts
46
+ function renderReplayCoverageGaps(params) {
47
+ const { dialect } = params;
48
+ const collector = new ParamCollector(dialect);
49
+ const namespace = collector.add(params.namespace);
50
+ 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" };
56
+ 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" };
61
+ }
62
+ // packages/sql/src/dialects/migration-shadow.ts
63
+ import { unsupportedCapability } from "@vibeorm/schema";
64
+ var SHADOW_DATABASE = Object.freeze({ schema: "_vibeorm_shadow", table: "_vibe_shadow", lock: 1447645267, timeoutSeconds: 60 });
65
+ var SHADOW_CAPABILITIES = Object.freeze({
66
+ postgres: Object.freeze({ serverProvisioning: true, dedicated: true }),
67
+ mysql: Object.freeze({ serverProvisioning: true, dedicated: true }),
68
+ sqlite: Object.freeze({ serverProvisioning: false, dedicated: false })
69
+ });
70
+ function renderShadowOperation(params) {
71
+ const { dialect, operation } = params;
72
+ if (!SHADOW_CAPABILITIES[dialect.name].serverProvisioning)
73
+ throw unsupportedCapability({ dialect: dialect.name, feature: "shadowDatabaseProvisioning" });
74
+ const pg = dialect.name === "postgres";
75
+ const collector = new ParamCollector(dialect);
76
+ const marker = pg ? `${dialect.quoteIdent({ name: SHADOW_DATABASE.schema })}.${dialect.quoteIdent({ name: SHADOW_DATABASE.table })}` : dialect.quoteIdent({ name: SHADOW_DATABASE.table });
77
+ const result = (text) => [{ text, values: collector.values, returning: "none" }];
78
+ switch (operation.kind) {
79
+ case "createDatabase":
80
+ return result(`CREATE DATABASE ${dialect.quoteIdent({ name: operation.name })}`);
81
+ case "dropDatabase":
82
+ return result(`DROP DATABASE ${dialect.quoteIdent({ name: operation.name })}`);
83
+ case "identity":
84
+ return result(pg ? `SELECT current_database()::text AS database, (SELECT oid::text FROM pg_catalog.pg_database WHERE datname = current_database()) AS database_id, current_schema()::text AS namespace` : `SELECT DATABASE() AS \`database\`, @@lower_case_table_names AS name_folding, @@server_uuid AS server_id`);
85
+ case "lock":
86
+ return result(pg ? `SELECT pg_catalog.pg_advisory_lock(${collector.add(SHADOW_DATABASE.lock)})` : `SELECT GET_LOCK(${collector.add(`vibeorm_shadow:${operation.database}`)}, ${collector.add(SHADOW_DATABASE.timeoutSeconds)}) AS acquired`);
87
+ case "unlock":
88
+ return result(pg ? `SELECT pg_catalog.pg_advisory_unlock(${collector.add(SHADOW_DATABASE.lock)}) AS released` : `SELECT RELEASE_LOCK(${collector.add(`vibeorm_shadow:${operation.database}`)}) AS released`);
89
+ case "markerExists":
90
+ return result(pg ? `SELECT c.relname AS name FROM pg_catalog.pg_class c JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace WHERE n.nspname = ${collector.add(SHADOW_DATABASE.schema)} AND c.relname = ${collector.add(SHADOW_DATABASE.table)}` : `SELECT TABLE_NAME AS name FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ${collector.add(SHADOW_DATABASE.table)}`);
91
+ case "markerRead":
92
+ return result(`SELECT payload FROM ${marker}`);
93
+ case "markerColumns":
94
+ return result(`SELECT column_name AS name, data_type AS type, is_nullable AS nullable FROM information_schema.columns AS marker_column WHERE table_schema = ${pg ? collector.add(SHADOW_DATABASE.schema) : "DATABASE()"} AND table_name = ${collector.add(SHADOW_DATABASE.table)} AND ${pg ? `EXISTS (SELECT 1 FROM pg_catalog.pg_class r JOIN pg_catalog.pg_namespace n ON n.oid = r.relnamespace WHERE n.nspname = marker_column.table_schema AND r.relname = marker_column.table_name AND r.relkind = 'r' AND r.relpersistence = 'p' AND NOT r.relrowsecurity AND NOT r.relforcerowsecurity AND NOT r.relhasrules AND NOT r.relhastriggers AND NOT r.relispartition AND NOT EXISTS (SELECT 1 FROM pg_catalog.pg_attrdef a WHERE a.adrelid = r.oid) AND NOT EXISTS (SELECT 1 FROM pg_catalog.pg_constraint c WHERE c.conrelid = r.oid AND c.contype <> 'n') AND NOT EXISTS (SELECT 1 FROM pg_catalog.pg_index i WHERE i.indrelid = r.oid) AND NOT EXISTS (SELECT 1 FROM pg_catalog.pg_inherits i WHERE i.inhrelid = r.oid OR i.inhparent = r.oid) AND NOT EXISTS (SELECT 1 FROM pg_catalog.pg_attribute a WHERE a.attrelid = r.oid AND (a.attisdropped OR a.attidentity <> '' OR a.attgenerated <> '')))` : `EXISTS (SELECT 1 FROM information_schema.TABLES t WHERE t.TABLE_SCHEMA = marker_column.table_schema AND t.TABLE_NAME = marker_column.table_name AND t.TABLE_TYPE = 'BASE TABLE' AND t.ENGINE = 'InnoDB') AND NOT EXISTS (SELECT 1 FROM information_schema.COLUMNS c WHERE c.TABLE_SCHEMA = marker_column.table_schema AND c.TABLE_NAME = marker_column.table_name AND (c.COLUMN_DEFAULT IS NOT NULL OR c.EXTRA <> '')) AND NOT EXISTS (SELECT 1 FROM information_schema.TRIGGERS t WHERE t.EVENT_OBJECT_SCHEMA = DATABASE() AND t.EVENT_OBJECT_TABLE = ${collector.add(SHADOW_DATABASE.table)}) AND NOT EXISTS (SELECT 1 FROM information_schema.TABLE_CONSTRAINTS c WHERE c.TABLE_SCHEMA = DATABASE() AND c.TABLE_NAME = ${collector.add(SHADOW_DATABASE.table)})`}
95
+ ORDER BY ordinal_position`);
96
+ case "grants": {
97
+ if (pg)
98
+ throw unsupportedCapability({ dialect: dialect.name, feature: "mysqlShadowPrivileges" });
99
+ return result("SHOW GRANTS FOR CURRENT_USER");
100
+ }
101
+ case "markerCreate":
102
+ return pg ? [{ text: `CREATE SCHEMA ${dialect.quoteIdent({ name: SHADOW_DATABASE.schema })}`, values: [], returning: "none" }, { text: `CREATE TABLE ${marker} (payload text NOT NULL)`, values: [], returning: "none" }] : result(`CREATE TABLE ${marker} (payload LONGTEXT NOT NULL) ENGINE=InnoDB`);
103
+ case "markerWrite":
104
+ return result(operation.insert ? `INSERT INTO ${marker} (payload) VALUES (${collector.add(operation.value)})` : `UPDATE ${marker} SET payload = ${collector.add(operation.value)}`);
105
+ case "journal":
106
+ return result(`SELECT name, checksum, statement_index, error FROM ${dialect.quoteIdent({ name: "_vibe_migrations" })} ORDER BY name`);
107
+ case "inventory":
108
+ return result(pg ? `SELECT 'namespace' AS kind, nspname::text AS name, nspname::text AS namespace FROM pg_catalog.pg_namespace WHERE nspname NOT IN ('public', 'information_schema') AND nspname NOT LIKE 'pg\\_%' ESCAPE '\\'
109
+ UNION ALL SELECT 'relation', c.relname::text, n.nspname::text FROM pg_catalog.pg_class c JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace WHERE n.nspname <> 'information_schema' AND n.nspname NOT LIKE 'pg\\_%' ESCAPE '\\'
110
+ UNION ALL SELECT 'routine', p.proname::text, n.nspname::text FROM pg_catalog.pg_proc p JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace WHERE n.nspname <> 'information_schema' AND n.nspname NOT LIKE 'pg\\_%' ESCAPE '\\'
111
+ UNION ALL SELECT 'type', t.typname::text, n.nspname::text FROM pg_catalog.pg_type t JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace WHERE n.nspname <> 'information_schema' AND n.nspname NOT LIKE 'pg\\_%' ESCAPE '\\' AND t.typrelid = 0 AND t.typelem = 0
112
+ UNION ALL SELECT 'extension', e.extname::text, n.nspname::text FROM pg_catalog.pg_extension e JOIN pg_catalog.pg_namespace n ON n.oid = e.extnamespace WHERE e.extname <> 'plpgsql'
113
+ UNION ALL SELECT 'marker-dependency', d.objid::text, '${SHADOW_DATABASE.schema}' FROM pg_catalog.pg_depend d JOIN pg_catalog.pg_class c ON d.classid = 'pg_class'::regclass AND d.objid = c.oid JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace WHERE n.nspname = '${SHADOW_DATABASE.schema}' AND d.deptype NOT IN ('i', 'a') AND d.refclassid <> 'pg_namespace'::regclass
114
+ UNION ALL SELECT 'marker-trigger', t.tgname::text, n.nspname::text FROM pg_catalog.pg_trigger t JOIN pg_catalog.pg_class c ON c.oid = t.tgrelid JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace WHERE n.nspname = '${SHADOW_DATABASE.schema}'
115
+ UNION ALL SELECT 'namespace-object', o.name::text, n.nspname::text FROM pg_catalog.pg_depend d JOIN pg_catalog.pg_namespace n ON d.refclassid = 'pg_namespace'::regclass AND d.refobjid = n.oid CROSS JOIN LATERAL pg_catalog.pg_identify_object(d.classid, d.objid, d.objsubid) o WHERE n.nspname <> 'information_schema' AND n.nspname NOT LIKE 'pg\\_%' ESCAPE '\\' AND d.classid NOT IN ('pg_class'::regclass, 'pg_proc'::regclass, 'pg_type'::regclass, 'pg_extension'::regclass)
116
+ UNION ALL SELECT 'database-object', evtname::text, '' FROM pg_catalog.pg_event_trigger
117
+ UNION ALL SELECT 'database-object', pubname::text, '' FROM pg_catalog.pg_publication
118
+ UNION ALL SELECT 'database-object', subname::text, '' FROM pg_catalog.pg_subscription WHERE subdbid = (SELECT oid FROM pg_catalog.pg_database WHERE datname = current_database())
119
+ UNION ALL SELECT 'database-object', srvname::text, '' FROM pg_catalog.pg_foreign_server
120
+ UNION ALL SELECT 'database-object', fdwname::text, '' FROM pg_catalog.pg_foreign_data_wrapper
121
+ UNION ALL SELECT 'database-object', c.oid::text, '' FROM pg_catalog.pg_cast c JOIN pg_catalog.pg_type s ON s.oid = c.castsource JOIN pg_catalog.pg_type t ON t.oid = c.casttarget LEFT JOIN pg_catalog.pg_proc p ON p.oid = c.castfunc WHERE s.typnamespace <> 'pg_catalog'::regnamespace OR t.typnamespace <> 'pg_catalog'::regnamespace OR p.pronamespace <> 'pg_catalog'::regnamespace` : `SELECT TABLE_TYPE AS kind, TABLE_NAME AS name, TABLE_SCHEMA AS namespace FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE()
122
+ UNION ALL SELECT ROUTINE_TYPE, ROUTINE_NAME, ROUTINE_SCHEMA FROM information_schema.ROUTINES WHERE ROUTINE_SCHEMA = DATABASE()
123
+ UNION ALL SELECT 'EVENT', EVENT_NAME, EVENT_SCHEMA FROM information_schema.EVENTS WHERE EVENT_SCHEMA = DATABASE()
124
+ UNION ALL SELECT 'TRIGGER', TRIGGER_NAME, TRIGGER_SCHEMA FROM information_schema.TRIGGERS WHERE TRIGGER_SCHEMA = DATABASE()
125
+ 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": {
127
+ 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" }];
130
+ }
131
+ case "mysqlForeignKeys": {
132
+ if (pg)
133
+ throw unsupportedCapability({ dialect: dialect.name, feature: "mysqlShadowReset" });
134
+ return result(`SET FOREIGN_KEY_CHECKS = ${operation.enabled ? "1" : "0"}`);
135
+ }
136
+ case "dropMysqlObject": {
137
+ if (pg)
138
+ throw unsupportedCapability({ dialect: dialect.name, feature: "mysqlShadowReset" });
139
+ return result(`DROP ${operation.object} ${dialect.quoteIdent({ name: operation.name })}`);
140
+ }
141
+ }
142
+ }
19
143
  // packages/sql/src/module-journal.ts
20
144
  var MODULE_JOURNAL_COLUMN = "module_origin";
21
145
  function renderModuleJournal(params) {
@@ -525,15 +649,15 @@ var decode = Object.freeze({
525
649
  }
526
650
  });
527
651
  // packages/sql/src/exclusion.ts
528
- import { VibeError as VibeError5, fieldTypeIdentity as fieldTypeIdentity2, unsupportedCapability as unsupportedCapability2 } from "@vibeorm/schema";
652
+ import { VibeError as VibeError5, fieldTypeIdentity as fieldTypeIdentity2, unsupportedCapability as unsupportedCapability3 } from "@vibeorm/schema";
529
653
 
530
654
  // packages/sql/src/predicate.ts
531
- import { VibeError as VibeError4, fieldTypeIdentity, isEnumType, unsupportedCapability } from "@vibeorm/schema";
655
+ import { VibeError as VibeError4, fieldTypeIdentity, isEnumType, unsupportedCapability as unsupportedCapability2 } from "@vibeorm/schema";
532
656
  function renderPredicate(params) {
533
657
  if (params.usage === "exclusionPredicate" && !params.dialect.capabilities.exclusionConstraints)
534
- throw unsupportedCapability({ dialect: params.dialect.name, feature: "exclusionConstraints" });
658
+ throw unsupportedCapability2({ dialect: params.dialect.name, feature: "exclusionConstraints" });
535
659
  if (params.usage === "indexPredicate" && !params.dialect.capabilities.partialIndexes) {
536
- throw unsupportedCapability({ dialect: params.dialect.name, feature: "partialIndexes" });
660
+ throw unsupportedCapability2({ dialect: params.dialect.name, feature: "partialIndexes" });
537
661
  }
538
662
  const context = {
539
663
  model: params.model,
@@ -661,7 +785,7 @@ function resolveField(params) {
661
785
  });
662
786
  }
663
787
  if (context.usage === "check" && context.dialect.name === "mysql" && field.default?.kind === "autoincrement") {
664
- throw unsupportedCapability({
788
+ throw unsupportedCapability2({
665
789
  dialect: "mysql",
666
790
  feature: `CHECK constraint referencing auto-increment column "${context.model.name}.${name}"`,
667
791
  hint: "mysql refuses this with error 3818 \u2014 enforce the rule in application code or on a non-generated column"
@@ -837,7 +961,7 @@ function invalid2(rule) {
837
961
  function compileExclusion(params) {
838
962
  const { exclusion: spec, model, dialect } = params;
839
963
  if (!dialect.capabilities.exclusionConstraints)
840
- throw unsupportedCapability2({ dialect: dialect.name, feature: "exclusionConstraints" });
964
+ throw unsupportedCapability3({ dialect: dialect.name, feature: "exclusionConstraints" });
841
965
  if (!spec.name || spec.name.includes("\x00"))
842
966
  invalid2("name");
843
967
  if (!["int8range", "tsrange", "tstzrange"].includes(spec.range.type))
@@ -867,8 +991,8 @@ function compileExclusion(params) {
867
991
  if (timezone !== (spec.range.type === "tstzrange"))
868
992
  invalid2("range-timezone");
869
993
  }
870
- const sql2 = dialect.quoteIdent({ name: column.dbName ?? column.name });
871
- return literal === undefined ? sql2 : `COALESCE(${sql2}, ${literal})`;
994
+ const sql = dialect.quoteIdent({ name: column.dbName ?? column.name });
995
+ return literal === undefined ? sql : `COALESCE(${sql}, ${literal})`;
872
996
  };
873
997
  const keys = spec.keys.map((key) => {
874
998
  if ("expression" in key) {
@@ -890,13 +1014,13 @@ function compileExclusion(params) {
890
1014
  }
891
1015
  function renderExclusionSetup(params) {
892
1016
  if (!params.dialect.capabilities.exclusionConstraints)
893
- throw unsupportedCapability2({ dialect: params.dialect.name, feature: "exclusionConstraints" });
1017
+ throw unsupportedCapability3({ dialect: params.dialect.name, feature: "exclusionConstraints" });
894
1018
  return params.exclusion.requiredExtensions.map((name) => `CREATE EXTENSION IF NOT EXISTS ${params.dialect.quoteIdent({ name })};`);
895
1019
  }
896
1020
  function renderExclusionDdl(params) {
897
1021
  const { dialect, table, exclusion, operation } = params;
898
1022
  if (!dialect.capabilities.exclusionConstraints)
899
- throw unsupportedCapability2({ dialect: dialect.name, feature: "exclusionConstraints" });
1023
+ throw unsupportedCapability3({ dialect: dialect.name, feature: "exclusionConstraints" });
900
1024
  const target = `ALTER TABLE ${dialect.quoteIdent({ name: table })}`;
901
1025
  if (operation === "drop")
902
1026
  return [`${target} DROP CONSTRAINT ${dialect.quoteIdent({ name: exclusion.name })};`];
@@ -905,14 +1029,14 @@ function renderExclusionDdl(params) {
905
1029
  function renderExclusionCatalog(params) {
906
1030
  const { dialect, probe } = params;
907
1031
  if (!dialect.capabilities.exclusionConstraints)
908
- throw unsupportedCapability2({ dialect: dialect.name, feature: "exclusionConstraints" });
1032
+ throw unsupportedCapability3({ dialect: dialect.name, feature: "exclusionConstraints" });
909
1033
  const scope = probe === undefined ? "n.nspname = 'public'" : `t.oid = ${dialect.quoteStringLiteral({ value: probe })}::regclass`;
910
1034
  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`;
911
1035
  }
912
1036
  function renderExclusionProbe(params) {
913
1037
  const { dialect, table, probe, definition } = params;
914
1038
  if (!dialect.capabilities.exclusionConstraints)
915
- throw unsupportedCapability2({ dialect: dialect.name, feature: "exclusionConstraints" });
1039
+ throw unsupportedCapability3({ dialect: dialect.name, feature: "exclusionConstraints" });
916
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}`];
917
1041
  }
918
1042
  // packages/sql/src/ast.ts
@@ -968,7 +1092,7 @@ function isExcludedRef(value) {
968
1092
  }
969
1093
  var ADVISORY_LOCK_RESULT_COLUMN = "acquired";
970
1094
  // packages/sql/src/locks.ts
971
- import { internalError, unsupportedCapability as unsupportedCapability3 } from "@vibeorm/schema";
1095
+ import { internalError, unsupportedCapability as unsupportedCapability4 } from "@vibeorm/schema";
972
1096
  var ROW_LOCK_PROSE = Object.freeze({
973
1097
  strengths: Object.freeze({
974
1098
  update: "FOR UPDATE",
@@ -988,7 +1112,7 @@ function renderRowLockClause(params) {
988
1112
  if (syntax === null) {
989
1113
  if (lock.strength === "update" && lock.wait === "wait")
990
1114
  return null;
991
- throw unsupportedCapability3({
1115
+ throw unsupportedCapability4({
992
1116
  dialect: dialect.name,
993
1117
  feature: `a ${describeRowLock({ lock })} locking read`,
994
1118
  hint: `${dialect.name} has no locking-read clause at all`
@@ -996,7 +1120,7 @@ function renderRowLockClause(params) {
996
1120
  }
997
1121
  const strengthText = syntax.strengths[lock.strength];
998
1122
  if (strengthText === undefined) {
999
- throw unsupportedCapability3({
1123
+ throw unsupportedCapability4({
1000
1124
  dialect: dialect.name,
1001
1125
  feature: `the ${describeRowLock({ lock: { ...lock, wait: "wait" } })} row-lock strength`,
1002
1126
  hint: `${dialect.name} can express: ${Object.keys(syntax.strengths).join(", ")}`
@@ -1004,7 +1128,7 @@ function renderRowLockClause(params) {
1004
1128
  }
1005
1129
  const waitText = syntax.wait[lock.wait];
1006
1130
  if (waitText === undefined) {
1007
- throw unsupportedCapability3({
1131
+ throw unsupportedCapability4({
1008
1132
  dialect: dialect.name,
1009
1133
  feature: `the "${lock.wait}" lock wait policy`,
1010
1134
  hint: `${dialect.name} can express: ${Object.keys(syntax.wait).join(", ")}`
@@ -1023,7 +1147,7 @@ function renderAdvisoryLock(params) {
1023
1147
  const { dialect, statement, collector } = params;
1024
1148
  const functions = dialect.advisoryLockFunctions;
1025
1149
  if (functions === null) {
1026
- throw unsupportedCapability3({
1150
+ throw unsupportedCapability4({
1027
1151
  dialect: dialect.name,
1028
1152
  feature: "advisory locks",
1029
1153
  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`
@@ -1249,7 +1373,7 @@ function getSqlDialect(params) {
1249
1373
  return SQL_DIALECTS[params.dialect];
1250
1374
  }
1251
1375
  // packages/sql/src/dialects/diagnostics.ts
1252
- import { unsupportedCapability as unsupportedCapability4 } from "@vibeorm/schema";
1376
+ import { unsupportedCapability as unsupportedCapability5 } from "@vibeorm/schema";
1253
1377
  var QUERIES = Object.freeze({
1254
1378
  postgresJsonWire: { dialect: "postgres", text: `SELECT '{"__vibeorm":1}'::jsonb AS "probe"` },
1255
1379
  sqliteTriggers: { dialect: "sqlite", text: "SELECT name, tbl_name, sql FROM sqlite_master WHERE type = 'trigger'" }
@@ -1257,7 +1381,7 @@ var QUERIES = Object.freeze({
1257
1381
  function renderDiagnostic(params) {
1258
1382
  const query = QUERIES[params.query];
1259
1383
  if (params.dialect.name !== query.dialect) {
1260
- throw unsupportedCapability4({ dialect: params.dialect.name, feature: params.query, hint: `this diagnostic requires ${query.dialect}` });
1384
+ throw unsupportedCapability5({ dialect: params.dialect.name, feature: params.query, hint: `this diagnostic requires ${query.dialect}` });
1261
1385
  }
1262
1386
  return { text: query.text, values: [], returning: "none" };
1263
1387
  }
@@ -1266,7 +1390,7 @@ function isFixedDiagnostic(params) {
1266
1390
  }
1267
1391
 
1268
1392
  // packages/sql/src/dialects/postgres-diagnostics.ts
1269
- import { VibeError as VibeError6, unsupportedCapability as unsupportedCapability5 } from "@vibeorm/schema";
1393
+ import { VibeError as VibeError6, unsupportedCapability as unsupportedCapability6 } from "@vibeorm/schema";
1270
1394
  function renderPostgresExplain(params) {
1271
1395
  const { dialect, query, options } = params;
1272
1396
  requirePostgres({ dialect, feature: "query plan inspection (EXPLAIN)" });
@@ -1301,7 +1425,7 @@ var POSTGRES_WORKLOAD_LIMITS = Object.freeze({
1301
1425
  });
1302
1426
  function requirePostgres(params) {
1303
1427
  if (params.dialect.name !== "postgres") {
1304
- throw unsupportedCapability5({
1428
+ throw unsupportedCapability6({
1305
1429
  dialect: params.dialect.name,
1306
1430
  feature: params.feature,
1307
1431
  hint: "plan inspection and workload statistics are PostgreSQL-shaped; portable operation tracing works on every dialect"
@@ -1348,10 +1472,10 @@ function requireArg(params) {
1348
1472
  }
1349
1473
 
1350
1474
  // packages/sql/src/dialects/postgres-rls-readiness.ts
1351
- import { unsupportedCapability as unsupportedCapability7 } from "@vibeorm/schema";
1475
+ import { unsupportedCapability as unsupportedCapability8 } from "@vibeorm/schema";
1352
1476
 
1353
1477
  // packages/sql/src/dialects/postgres-rls.ts
1354
- import { RlsContextError, VibeError as VibeError7, assertValidSchemaIR, unsupportedCapability as unsupportedCapability6, validateRlsContextIR } from "@vibeorm/schema";
1478
+ import { RlsContextError, VibeError as VibeError7, assertValidSchemaIR, unsupportedCapability as unsupportedCapability7, validateRlsContextIR } from "@vibeorm/schema";
1355
1479
  var NATIVE_RLS = Object.freeze({ policyName: "vibeorm_managed", tableSchema: "public", settingPrefix: "vibeorm.", parentAlias: "parent" });
1356
1480
  var COLUMN_TYPES = {
1357
1481
  String: { default: "text", native: { text: "text", varchar: "varchar", charactervarying: "varchar", uuid: "uuid" } },
@@ -1364,7 +1488,7 @@ var COLUMN_TYPES = {
1364
1488
  };
1365
1489
  function requireRls(params) {
1366
1490
  if (!params.dialect.capabilities.nativeRowLevelSecurity) {
1367
- throw unsupportedCapability6({ dialect: params.dialect.name, feature: "nativeRowLevelSecurity" });
1491
+ throw unsupportedCapability7({ dialect: params.dialect.name, feature: "nativeRowLevelSecurity" });
1368
1492
  }
1369
1493
  }
1370
1494
  function identifier2(params) {
@@ -1375,7 +1499,7 @@ function identifier2(params) {
1375
1499
  }
1376
1500
  function tableRef(params) {
1377
1501
  if (params.schema !== undefined && params.schema !== "public" && params.schema !== "pg_temp") {
1378
- throw unsupportedCapability6({ dialect: params.dialect.name, feature: "nativeRowLevelSecurity", hint: "Only public tables and temporary policy probes are supported" });
1502
+ throw unsupportedCapability7({ dialect: params.dialect.name, feature: "nativeRowLevelSecurity", hint: "Only public tables and temporary policy probes are supported" });
1379
1503
  }
1380
1504
  return `${identifier2({ dialect: params.dialect, name: params.schema ?? NATIVE_RLS.tableSchema })}.${identifier2({ dialect: params.dialect, name: params.table })}`;
1381
1505
  }
@@ -1416,7 +1540,7 @@ function renderRlsColumnType(params) {
1416
1540
  if (native !== undefined)
1417
1541
  return native;
1418
1542
  }
1419
- throw unsupportedCapability6({ dialect: params.dialect.name, feature: "nativeRowLevelSecurity", hint: `Unsupported physical ownership type on field ${field.name}` });
1543
+ throw unsupportedCapability7({ dialect: params.dialect.name, feature: "nativeRowLevelSecurity", hint: `Unsupported physical ownership type on field ${field.name}` });
1420
1544
  }
1421
1545
  function protectedModel(params) {
1422
1546
  requireRls(params);
@@ -1642,7 +1766,7 @@ ORDER BY c.relname, p.polname`,
1642
1766
  });
1643
1767
  function requireRls2(params) {
1644
1768
  if (!params.dialect.capabilities.nativeRowLevelSecurity) {
1645
- throw unsupportedCapability7({ dialect: params.dialect.name, feature: "nativeRowLevelSecurity" });
1769
+ throw unsupportedCapability8({ dialect: params.dialect.name, feature: "nativeRowLevelSecurity" });
1646
1770
  }
1647
1771
  }
1648
1772
  function renderRlsReadinessQuery(params) {
@@ -1674,7 +1798,7 @@ function renderRlsPolicyPath(params) {
1674
1798
  }
1675
1799
 
1676
1800
  // packages/sql/src/render.ts
1677
- import { internalError as internalError2, unsupportedCapability as unsupportedCapability8 } from "@vibeorm/schema";
1801
+ import { internalError as internalError2, unsupportedCapability as unsupportedCapability9 } from "@vibeorm/schema";
1678
1802
 
1679
1803
  // packages/sql/src/like.ts
1680
1804
  function escapeLikePattern(params) {
@@ -1819,7 +1943,7 @@ function renderAggRef(dialect, agg) {
1819
1943
  function assertScalarArrays(dialect, feature) {
1820
1944
  if (dialect.capabilities.scalarArrays)
1821
1945
  return;
1822
- throw unsupportedCapability8({
1946
+ throw unsupportedCapability9({
1823
1947
  dialect: dialect.name,
1824
1948
  feature,
1825
1949
  hint: "only postgres has native array columns \u2014 model the list as a related table instead"
@@ -1876,8 +2000,8 @@ function renderExpr(params) {
1876
2000
  const columns = expr.columns.map((column) => quoteCol(dialect, column));
1877
2001
  if (dialect.tupleInStrategy === "rowValue") {
1878
2002
  const tuples = expr.rows.map((row) => `(${collector.addMany(row).join(", ")})`);
1879
- const base2 = `(${columns.join(", ")}) IN (${tuples.join(", ")})`;
1880
- return expr.negate === true ? `NOT (${base2})` : base2;
2003
+ const base = `(${columns.join(", ")}) IN (${tuples.join(", ")})`;
2004
+ return expr.negate === true ? `NOT (${base})` : base;
1881
2005
  }
1882
2006
  const conjunctions = expr.rows.map((row) => {
1883
2007
  const terms = row.map((value, index) => `${columns[index]} = ${collector.add(value)}`);
@@ -2029,7 +2153,7 @@ function renderJsonLike(params) {
2029
2153
  function renderJsonFilter(params) {
2030
2154
  const { dialect, expr, collector } = params;
2031
2155
  if (!dialect.supportedJsonOps.includes(expr.op)) {
2032
- throw unsupportedCapability8({
2156
+ throw unsupportedCapability9({
2033
2157
  dialect: dialect.name,
2034
2158
  feature: `the json filter "${expr.op}"`,
2035
2159
  hint: `this dialect can express: ${dialect.supportedJsonOps.join(", ")}`
@@ -2037,25 +2161,25 @@ function renderJsonFilter(params) {
2037
2161
  }
2038
2162
  const cmp = expr.negate === true ? "<>" : "=";
2039
2163
  if (dialect.jsonPathMode === "operators") {
2040
- const column2 = quoteCol(dialect, expr.column);
2164
+ const column = quoteCol(dialect, expr.column);
2041
2165
  const pathParam = `${collector.add(expr.path.map(String))}::text[]`;
2042
2166
  switch (expr.op) {
2043
2167
  case "equals":
2044
- return `(${column2} #> ${pathParam}) ${cmp} ${collector.add(JSON.stringify(expr.value))}${dialect.jsonParamCast}`;
2168
+ return `(${column} #> ${pathParam}) ${cmp} ${collector.add(JSON.stringify(expr.value))}${dialect.jsonParamCast}`;
2045
2169
  case "string_contains":
2046
2170
  case "string_starts_with":
2047
2171
  case "string_ends_with":
2048
- return renderJsonLike({ dialect, target: `(${column2} #>> ${pathParam})`, expr, collector });
2172
+ return renderJsonLike({ dialect, target: `(${column} #>> ${pathParam})`, expr, collector });
2049
2173
  case "array_contains":
2050
- return `(${column2} #> ${pathParam}) @> ${collector.add(JSON.stringify(expr.value))}${dialect.jsonParamCast}`;
2174
+ return `(${column} #> ${pathParam}) @> ${collector.add(JSON.stringify(expr.value))}${dialect.jsonParamCast}`;
2051
2175
  case "array_starts_with":
2052
- return `(${column2} #> ${pathParam}) -> 0 = ${collector.add(JSON.stringify(expr.value))}${dialect.jsonParamCast}`;
2176
+ return `(${column} #> ${pathParam}) -> 0 = ${collector.add(JSON.stringify(expr.value))}${dialect.jsonParamCast}`;
2053
2177
  case "array_ends_with":
2054
- return `(${column2} #> ${pathParam}) -> -1 = ${collector.add(JSON.stringify(expr.value))}${dialect.jsonParamCast}`;
2178
+ return `(${column} #> ${pathParam}) -> -1 = ${collector.add(JSON.stringify(expr.value))}${dialect.jsonParamCast}`;
2055
2179
  }
2056
2180
  }
2057
2181
  if (dialect.jsonPathMode === "sqliteExtract") {
2058
- const column2 = quoteCol(dialect, expr.column);
2182
+ const column = quoteCol(dialect, expr.column);
2059
2183
  const typeMatches = (type, value) => {
2060
2184
  if (typeof value === "number")
2061
2185
  return `${type} IN ('integer', 'real')`;
@@ -2063,11 +2187,11 @@ function renderJsonFilter(params) {
2063
2187
  return `${type} = '${tag}'`;
2064
2188
  };
2065
2189
  const compareExtracted = (path, value) => {
2066
- const type = `json_type(${column2}, ${collector.add(path)})`;
2190
+ const type = `json_type(${column}, ${collector.add(path)})`;
2067
2191
  const guard = typeMatches(type, value);
2068
2192
  let base = guard;
2069
2193
  if (value !== null) {
2070
- const target = `json_extract(${column2}, ${collector.add(path)})`;
2194
+ const target = `json_extract(${column}, ${collector.add(path)})`;
2071
2195
  const bound = typeof value === "boolean" ? value ? 1 : 0 : value;
2072
2196
  const operand = typeof value === "object" ? `json(${collector.add(JSON.stringify(value))})` : collector.add(bound);
2073
2197
  base = `(${guard} AND ${target} = ${operand})`;
@@ -2080,7 +2204,7 @@ function renderJsonFilter(params) {
2080
2204
  case "string_contains":
2081
2205
  case "string_starts_with":
2082
2206
  case "string_ends_with": {
2083
- const target = `json_extract(${column2}, ${collector.add(jsonPathString(expr.path))})`;
2207
+ const target = `json_extract(${column}, ${collector.add(jsonPathString(expr.path))})`;
2084
2208
  return renderJsonLike({ dialect, target, expr, collector });
2085
2209
  }
2086
2210
  case "array_starts_with":
@@ -2089,11 +2213,11 @@ function renderJsonFilter(params) {
2089
2213
  return compareExtracted(`${jsonPathString(expr.path)}${edge}`, expr.value);
2090
2214
  }
2091
2215
  case "array_contains": {
2092
- const guard = `json_type(${column2}, ${collector.add(jsonPathString(expr.path))}) = 'array'`;
2216
+ const guard = `json_type(${column}, ${collector.add(jsonPathString(expr.path))}) = 'array'`;
2093
2217
  const elements = Array.isArray(expr.value) ? expr.value : [expr.value];
2094
2218
  const tests = elements.map((element) => {
2095
2219
  if (element === null || typeof element === "object" && element !== null) {
2096
- throw unsupportedCapability8({
2220
+ throw unsupportedCapability9({
2097
2221
  dialect: dialect.name,
2098
2222
  feature: "json array_contains with object/array/null elements",
2099
2223
  hint: "sqlite expresses scalar-element containment only \u2014 deep structural containment needs postgres or mysql"
@@ -2102,7 +2226,7 @@ function renderJsonFilter(params) {
2102
2226
  const bound = typeof element === "boolean" ? element ? 1 : 0 : element;
2103
2227
  const path = collector.add(jsonPathString(expr.path));
2104
2228
  const type = `${dialect.quoteIdent({ name: "json_each" })}.${dialect.quoteIdent({ name: "type" })}`;
2105
- return `EXISTS (SELECT 1 FROM json_each(${column2}, ${path}) WHERE ${typeMatches(type, element)} AND ${dialect.quoteIdent({ name: "json_each" })}.${dialect.quoteIdent({ name: "value" })} = ${collector.add(bound)})`;
2229
+ return `EXISTS (SELECT 1 FROM json_each(${column}, ${path}) WHERE ${typeMatches(type, element)} AND ${dialect.quoteIdent({ name: "json_each" })}.${dialect.quoteIdent({ name: "value" })} = ${collector.add(bound)})`;
2106
2230
  });
2107
2231
  return tests.length === 0 ? guard : `(${[guard, ...tests].join(" AND ")})`;
2108
2232
  }
@@ -2244,7 +2368,7 @@ function renderSelect(params) {
2244
2368
  let distinctPrefix = "";
2245
2369
  if (statement.distinctOn !== undefined && statement.distinctOn.length > 0) {
2246
2370
  if (!dialect.capabilities.distinctOn) {
2247
- throw unsupportedCapability8({
2371
+ throw unsupportedCapability9({
2248
2372
  dialect: dialect.name,
2249
2373
  feature: "SELECT DISTINCT ON",
2250
2374
  hint: "postgres-only \u2014 the runtime emulates distinct client-side on this dialect"
@@ -2275,7 +2399,7 @@ function renderSelect(params) {
2275
2399
  }
2276
2400
  if (statement.lateralJoins !== undefined && statement.lateralJoins.length > 0) {
2277
2401
  if (!dialect.capabilities.lateralJoin) {
2278
- throw unsupportedCapability8({
2402
+ throw unsupportedCapability9({
2279
2403
  dialect: dialect.name,
2280
2404
  feature: "LATERAL JOIN relation loading",
2281
2405
  hint: 'use the portable "query" relation strategy on this dialect'
@@ -2360,7 +2484,7 @@ function renderInsert(params) {
2360
2484
  let target = "";
2361
2485
  if (onConflict.constraint !== undefined) {
2362
2486
  if (dialect.name !== "postgres") {
2363
- throw unsupportedCapability8({
2487
+ throw unsupportedCapability9({
2364
2488
  dialect: dialect.name,
2365
2489
  feature: "a named-constraint conflict target (ON CONFLICT ON CONSTRAINT)",
2366
2490
  hint: "only postgres names constraints in conflict targets \u2014 use a column-list target"
@@ -2375,7 +2499,7 @@ function renderInsert(params) {
2375
2499
  }
2376
2500
  text += ` ON CONFLICT${target} DO NOTHING`;
2377
2501
  } else if (onConflict.constraint !== undefined || onConflict.conflictWhere !== undefined) {
2378
- throw unsupportedCapability8({
2502
+ throw unsupportedCapability9({
2379
2503
  dialect: dialect.name,
2380
2504
  feature: "a refined conflict target (constraint / partial-index predicate) on INSERT IGNORE",
2381
2505
  hint: "mysql skips on any duplicate key \u2014 drop the refinement or gate the call per dialect"
@@ -2393,7 +2517,7 @@ function renderInsert(params) {
2393
2517
  throw internalError2({ message: "lastInsertIdColumn is a mysql (onDuplicateKey) construct" });
2394
2518
  }
2395
2519
  if (onConflict.constraint !== undefined && dialect.name !== "postgres") {
2396
- throw unsupportedCapability8({
2520
+ throw unsupportedCapability9({
2397
2521
  dialect: dialect.name,
2398
2522
  feature: "a named-constraint conflict target (ON CONFLICT ON CONSTRAINT)",
2399
2523
  hint: "sqlite conflict targets are column lists \u2014 name the indexed columns instead"
@@ -2409,14 +2533,14 @@ function renderInsert(params) {
2409
2533
  text += ` ON CONFLICT${target} DO UPDATE SET ${assignments}`;
2410
2534
  } else {
2411
2535
  if (onConflict.constraint !== undefined) {
2412
- throw unsupportedCapability8({
2536
+ throw unsupportedCapability9({
2413
2537
  dialect: dialect.name,
2414
2538
  feature: "a named-constraint conflict target on ON DUPLICATE KEY UPDATE",
2415
2539
  hint: "mysql's ODKU fires on any duplicate key \u2014 no target can be named"
2416
2540
  });
2417
2541
  }
2418
2542
  if (onConflict.conflictWhere !== undefined) {
2419
- throw unsupportedCapability8({
2543
+ throw unsupportedCapability9({
2420
2544
  dialect: dialect.name,
2421
2545
  feature: "a partial-index conflict target on ON DUPLICATE KEY UPDATE",
2422
2546
  hint: "mysql's ODKU fires on any duplicate key \u2014 a partial arbiter cannot be selected; gate the call per dialect"
@@ -2501,18 +2625,18 @@ function renderDelete(params) {
2501
2625
  // packages/sql/src/dialects/sqlite-table-definition.ts
2502
2626
  import { VibeError as VibeError8 } from "@vibeorm/schema";
2503
2627
  function tableDefinitionParts(params) {
2504
- const sql2 = params.sql;
2505
- if (!/^\s*CREATE\s+(?:TEMP(?:ORARY)?\s+)?TABLE\b/i.test(sql2))
2628
+ const sql = params.sql;
2629
+ if (!/^\s*CREATE\s+(?:TEMP(?:ORARY)?\s+)?TABLE\b/i.test(sql))
2506
2630
  throw unavailable();
2507
2631
  const parts = [];
2508
2632
  let start = -1;
2509
2633
  let depth = 0;
2510
2634
  let quote;
2511
- for (let index = 0;index < sql2.length; index++) {
2512
- const char = sql2[index];
2635
+ for (let index = 0;index < sql.length; index++) {
2636
+ const char = sql[index];
2513
2637
  if (quote !== undefined) {
2514
2638
  if (char === quote) {
2515
- if (quote !== "]" && sql2[index + 1] === quote)
2639
+ if (quote !== "]" && sql[index + 1] === quote)
2516
2640
  index++;
2517
2641
  else
2518
2642
  quote = undefined;
@@ -2527,16 +2651,16 @@ function tableDefinitionParts(params) {
2527
2651
  quote = "]";
2528
2652
  continue;
2529
2653
  }
2530
- if (char === "-" && sql2[index + 1] === "-") {
2531
- const end = sql2.indexOf(`
2654
+ if (char === "-" && sql[index + 1] === "-") {
2655
+ const end = sql.indexOf(`
2532
2656
  `, index + 2);
2533
2657
  if (end < 0)
2534
2658
  break;
2535
2659
  index = end;
2536
2660
  continue;
2537
2661
  }
2538
- if (char === "/" && sql2[index + 1] === "*") {
2539
- const end = sql2.indexOf("*/", index + 2);
2662
+ if (char === "/" && sql[index + 1] === "*") {
2663
+ const end = sql.indexOf("*/", index + 2);
2540
2664
  if (end < 0)
2541
2665
  break;
2542
2666
  index = end + 1;
@@ -2549,11 +2673,11 @@ function tableDefinitionParts(params) {
2549
2673
  } else if (char === ")") {
2550
2674
  depth--;
2551
2675
  if (depth === 0 && start >= 0) {
2552
- parts.push(sql2.slice(start, index).trim());
2553
- return { clauses: parts, suffix: sql2.slice(index + 1) };
2676
+ parts.push(sql.slice(start, index).trim());
2677
+ return { clauses: parts, suffix: sql.slice(index + 1) };
2554
2678
  }
2555
2679
  } else if (char === "," && depth === 1) {
2556
- parts.push(sql2.slice(start, index).trim());
2680
+ parts.push(sql.slice(start, index).trim());
2557
2681
  start = index + 1;
2558
2682
  }
2559
2683
  }
@@ -2575,12 +2699,58 @@ function sqliteColumnClauses(params) {
2575
2699
  }
2576
2700
  return columns;
2577
2701
  }
2702
+ // packages/sql/src/dialects/postgres-type-identity.ts
2703
+ import { unsupportedCapability as unsupportedCapability10 } from "@vibeorm/schema";
2704
+ var IDENTIFIER = '(?:"(?:[^"\\x00]|"")+"|[a-zA-Z_][a-zA-Z_0-9$]*)';
2705
+ var MODIFIER_VALUE = `(?:[+-]?\\d+|${IDENTIFIER}|'(?:[^'\\x00]|'')*')`;
2706
+ var TYPE_NAME = new RegExp(`^\\s*(${IDENTIFIER})(?:\\s*\\.\\s*(${IDENTIFIER}))?\\s*(\\(\\s*${MODIFIER_VALUE}(?:\\s*,\\s*${MODIFIER_VALUE})*\\s*\\))?\\s*((?:\\[\\s*\\]\\s*)*)$`);
2707
+ var MODIFIER_TOKEN = new RegExp(MODIFIER_VALUE, "g");
2708
+ function modifier(params) {
2709
+ if (params.raw === undefined)
2710
+ return "";
2711
+ const tokens = params.raw.slice(1, -1).match(MODIFIER_TOKEN) ?? [];
2712
+ return `(${tokens.map((token) => /^[+-]?\d+$/.test(token) ? BigInt(token).toString() : token.startsWith("'") || token.startsWith('"') ? token : token.toLowerCase()).join(",")})`;
2713
+ }
2714
+ function identifier3(params) {
2715
+ return params.value.startsWith('"') ? params.value.slice(1, -1).replaceAll('""', '"') : params.value.toLowerCase();
2716
+ }
2717
+ function parsePostgresTypeName(params) {
2718
+ const match = TYPE_NAME.exec(params.raw);
2719
+ if (match === null)
2720
+ return;
2721
+ return {
2722
+ ...match[2] === undefined ? {} : { namespace: identifier3({ value: match[1] }) },
2723
+ name: identifier3({ value: match[2] ?? match[1] }),
2724
+ modifier: modifier({ ...match[3] === undefined ? {} : { raw: match[3] } }),
2725
+ array: (match[4]?.length ?? 0) > 0
2726
+ };
2727
+ }
2728
+ function renderPostgresTypeName(params) {
2729
+ if (params.dialect.name !== "postgres")
2730
+ throw unsupportedCapability10({ dialect: params.dialect.name, feature: "postgresTypeIdentity" });
2731
+ const { dialect, type } = params;
2732
+ return `${type.namespace === undefined ? "" : `${dialect.quoteIdent({ name: type.namespace })}.`}${dialect.quoteIdent({ name: type.name })}${type.modifier}${type.array ? "[]" : ""}`;
2733
+ }
2734
+ function renderPostgresTypeIdentity(params) {
2735
+ if (params.dialect.name !== "postgres")
2736
+ throw unsupportedCapability10({ dialect: params.dialect.name, feature: "postgresTypeIdentity" });
2737
+ const collector = new ParamCollector(params.dialect);
2738
+ const { source } = params;
2739
+ let text;
2740
+ if ("table" in source) {
2741
+ text = `SELECT tn.nspname::text AS "namespace", base.typname::text AS "name" FROM pg_catalog.pg_attribute a JOIN pg_catalog.pg_class c ON c.oid = a.attrelid JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace JOIN pg_catalog.pg_type t ON t.oid = a.atttypid JOIN pg_catalog.pg_type base ON base.oid = CASE WHEN t.typelem <> 0 AND t.typlen = -1 THEN t.typelem ELSE t.oid END JOIN pg_catalog.pg_namespace tn ON tn.oid = base.typnamespace WHERE n.nspname = ${collector.add(source.table.namespace)} AND c.relname = ${collector.add(source.table.name)} AND a.attname = ${collector.add(source.column)} AND a.attnum > 0 AND NOT a.attisdropped`;
2742
+ } else {
2743
+ const name = renderPostgresTypeName({ dialect: params.dialect, type: { ...source.type, modifier: "", array: false } });
2744
+ text = `SELECT n.nspname::text AS "namespace", t.typname::text AS "name" FROM pg_catalog.pg_type t JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace WHERE t.oid = pg_catalog.to_regtype(${collector.add(name)})`;
2745
+ }
2746
+ return { text, values: collector.values, returning: "none" };
2747
+ }
2578
2748
  // packages/sql/src/dialects/postgres-default-identity.ts
2579
- import { unsupportedCapability as unsupportedCapability9 } from "@vibeorm/schema";
2749
+ import { unsupportedCapability as unsupportedCapability11 } from "@vibeorm/schema";
2580
2750
  function renderPostgresDefaultFunctionIdentity(params) {
2581
2751
  const { dialect, table, column } = params;
2582
2752
  if (dialect.name !== "postgres")
2583
- throw unsupportedCapability9({ dialect: dialect.name, feature: "defaultFunctionIdentity" });
2753
+ throw unsupportedCapability11({ dialect: dialect.name, feature: "defaultFunctionIdentity" });
2584
2754
  const collector = new ParamCollector(dialect);
2585
2755
  const namespace = collector.add(table.namespace);
2586
2756
  const name = collector.add(table.name);
@@ -2604,28 +2774,28 @@ WHERE n.nspname = ${namespace} AND c.relname = ${name} AND a.attname = ${field}
2604
2774
  };
2605
2775
  }
2606
2776
  // packages/sql/src/dialects/constraint-owned-index.ts
2607
- import { unsupportedCapability as unsupportedCapability10 } from "@vibeorm/schema";
2777
+ import { unsupportedCapability as unsupportedCapability12 } from "@vibeorm/schema";
2608
2778
  function renderConstraintOwnedIndexDrop(params) {
2609
2779
  if (params.dialect.name !== "postgres")
2610
- throw unsupportedCapability10({ dialect: params.dialect.name, feature: "constraintOwnedIndexDrop" });
2780
+ throw unsupportedCapability12({ dialect: params.dialect.name, feature: "constraintOwnedIndexDrop" });
2611
2781
  const quote = (name) => params.dialect.quoteIdent({ name });
2612
2782
  return { text: `ALTER TABLE ${quote(params.table)} DROP CONSTRAINT ${quote(params.constraint)};`, values: [], returning: "none" };
2613
2783
  }
2614
2784
  // packages/sql/src/dialects/mysql-check-probe.ts
2615
- import { unsupportedCapability as unsupportedCapability11 } from "@vibeorm/schema";
2785
+ import { unsupportedCapability as unsupportedCapability13 } from "@vibeorm/schema";
2616
2786
  function renderMysqlCheckProbe(params) {
2617
2787
  if (params.dialect.name !== "mysql")
2618
- throw unsupportedCapability11({ dialect: params.dialect.name, feature: "temporaryCheckProbe" });
2788
+ throw unsupportedCapability13({ dialect: params.dialect.name, feature: "temporaryCheckProbe" });
2619
2789
  const q = (name) => params.dialect.quoteIdent({ name });
2620
2790
  const probe = q(params.probe);
2621
2791
  switch (params.operation) {
2622
2792
  case "clone":
2623
2793
  if (params.table === undefined)
2624
- throw unsupportedCapability11({ dialect: "mysql", feature: "temporaryCheckProbe", hint: "A source table is required" });
2794
+ throw unsupportedCapability13({ dialect: "mysql", feature: "temporaryCheckProbe", hint: "A source table is required" });
2625
2795
  return { text: `CREATE TEMPORARY TABLE ${probe} LIKE ${q(params.table.namespace)}.${q(params.table.name)}`, values: [], returning: "none" };
2626
2796
  case "add": {
2627
2797
  if (params.expression === undefined || params.definition === undefined)
2628
- throw unsupportedCapability11({ dialect: "mysql", feature: "temporaryCheckProbe", hint: "An authored expression and temporary clone definition are required" });
2798
+ throw unsupportedCapability13({ dialect: "mysql", feature: "temporaryCheckProbe", hint: "An authored expression and temporary clone definition are required" });
2629
2799
  const parts = tableDefinitionParts({ sql: params.definition });
2630
2800
  return { text: `CREATE TEMPORARY TABLE ${probe} (
2631
2801
  ${[...parts.clauses, `CONSTRAINT ${probe} CHECK (${params.expression})`].join(`,
@@ -2644,8 +2814,8 @@ function renderMigrationHistoryQuery(params) {
2644
2814
  return { text: `SELECT ${q("name")}, ${q("checksum")}, ${q("statement_index")}, ${q("error")} FROM ${q(params.namespace)}.${q("_vibe_migrations")} ORDER BY ${q("id")}`, values: [], returning: "none" };
2645
2815
  }
2646
2816
  // packages/sql/src/dialects/sqlite-constraints.ts
2647
- var IDENTIFIER = '(?:"(?:[^" ]| |"")+"|`(?:[^`]|``)+`|\\[[^\\]]+\\]|[A-Za-z_][A-Za-z_0-9]*)';
2648
- function identifier3(value) {
2817
+ var IDENTIFIER2 = '(?:"(?:[^" ]| |"")+"|`(?:[^`]|``)+`|\\[[^\\]]+\\]|[A-Za-z_][A-Za-z_0-9]*)';
2818
+ function identifier4(value) {
2649
2819
  const text = value.trim();
2650
2820
  if (text.startsWith('"'))
2651
2821
  return text.slice(1, -1).replaceAll('""', '"');
@@ -2658,44 +2828,44 @@ function identifier3(value) {
2658
2828
  function sqliteTableConstraints(params) {
2659
2829
  const result = [];
2660
2830
  for (const clause of tableDefinitionParts(params).clauses) {
2661
- const named = new RegExp(`^CONSTRAINT\\s+(${IDENTIFIER})\\s+`, "i").exec(clause);
2831
+ const named = new RegExp(`^CONSTRAINT\\s+(${IDENTIFIER2})\\s+`, "i").exec(clause);
2662
2832
  const body = named === null ? clause : clause.slice(named[0].length);
2663
2833
  const kind = /^(CHECK|FOREIGN\s+KEY|UNIQUE|PRIMARY\s+KEY)\s*\(/i.exec(body);
2664
2834
  if (kind === null)
2665
2835
  continue;
2666
2836
  const type = /^CHECK$/i.test(kind[1]) ? "check" : /^FOREIGN/i.test(kind[1]) ? "foreignKey" : /^PRIMARY/i.test(kind[1]) ? "primaryKey" : "unique";
2667
2837
  const parts = tableDefinitionParts({ sql: `CREATE TABLE x ${body.slice(kind[0].indexOf("("))}` });
2668
- const columns = type === "check" ? [] : parts.clauses.map(identifier3);
2669
- result.push({ name: named === null ? `@sqlite:${type}:${result.length}` : identifier3(named[1]), named: named !== null, type, sql: body, columns });
2838
+ const columns = type === "check" ? [] : parts.clauses.map(identifier4);
2839
+ result.push({ name: named === null ? `@sqlite:${type}:${result.length}` : identifier4(named[1]), named: named !== null, type, sql: body, columns });
2670
2840
  }
2671
2841
  return result;
2672
2842
  }
2673
2843
  // packages/sql/src/dialects/migration-visibility.ts
2674
- import { unsupportedCapability as unsupportedCapability12 } from "@vibeorm/schema";
2844
+ import { unsupportedCapability as unsupportedCapability14 } from "@vibeorm/schema";
2675
2845
  function renderMigrationVisibility(params) {
2676
2846
  if (params.dialect.name !== "mysql")
2677
- throw unsupportedCapability12({ dialect: params.dialect.name, feature: "mysqlCatalogVisibility" });
2847
+ throw unsupportedCapability14({ dialect: params.dialect.name, feature: "mysqlCatalogVisibility" });
2678
2848
  const collector = new ParamCollector(params.dialect);
2679
2849
  const grantee = "CONCAT(QUOTE(SUBSTRING_INDEX(CURRENT_USER(), '@', 1)), '@', QUOTE(SUBSTRING_INDEX(CURRENT_USER(), '@', -1)))";
2680
2850
  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" };
2681
2851
  }
2682
2852
  // packages/sql/src/dialects/migration-inventory.ts
2683
- import { unsupportedCapability as unsupportedCapability13 } from "@vibeorm/schema";
2853
+ import { unsupportedCapability as unsupportedCapability15 } from "@vibeorm/schema";
2684
2854
  function renderSqliteColumnInventory(params) {
2685
2855
  if (params.dialect.name !== "sqlite")
2686
- throw unsupportedCapability13({ dialect: params.dialect.name, feature: "sqliteColumnInventory" });
2856
+ throw unsupportedCapability15({ dialect: params.dialect.name, feature: "sqliteColumnInventory" });
2687
2857
  const collector = new ParamCollector(params.dialect);
2688
2858
  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" };
2689
2859
  }
2690
2860
  function renderSqliteForeignKeyInventory(params) {
2691
2861
  if (params.dialect.name !== "sqlite")
2692
- throw unsupportedCapability13({ dialect: params.dialect.name, feature: "sqliteForeignKeyInventory" });
2862
+ throw unsupportedCapability15({ dialect: params.dialect.name, feature: "sqliteForeignKeyInventory" });
2693
2863
  const collector = new ParamCollector(params.dialect);
2694
2864
  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" };
2695
2865
  }
2696
2866
  function renderSqliteRebuildObjects(params) {
2697
2867
  if (params.dialect.name !== "sqlite")
2698
- throw unsupportedCapability13({ dialect: params.dialect.name, feature: "sqliteRebuildObjects" });
2868
+ throw unsupportedCapability15({ dialect: params.dialect.name, feature: "sqliteRebuildObjects" });
2699
2869
  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" };
2700
2870
  }
2701
2871
  function renderMigrationInventory(params) {
@@ -2732,10 +2902,12 @@ ORDER BY kind, parent, name`, values: collector.values, returning: "none" };
2732
2902
  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" };
2733
2903
  }
2734
2904
  // packages/sql/src/dialects/migration-objects.ts
2735
- import { unsupportedCapability as unsupportedCapability14 } from "@vibeorm/schema";
2905
+ import { internalError as internalError3, unsupportedCapability as unsupportedCapability16 } from "@vibeorm/schema";
2736
2906
  function renderMigrationObjectQuery(params) {
2737
- const { dialect, identity: object } = params;
2738
- const collector = new ParamCollector(dialect);
2907
+ return objectQuery({ ...params, collector: new ParamCollector(params.dialect) });
2908
+ }
2909
+ function objectQuery(params) {
2910
+ const { dialect, identity: object, collector } = params;
2739
2911
  const physical = "table" in object ? object.table : object.name;
2740
2912
  const namespace = collector.add(physical.namespace);
2741
2913
  const name = collector.add(physical.name);
@@ -2753,7 +2925,7 @@ function renderMigrationObjectQuery(params) {
2753
2925
  text = `SELECT pg_catalog.pg_get_triggerdef(t.oid, false) AS "definition", t.tgenabled::text AS "enabled", pn.nspname::text AS "functionNamespace", p.proname::text AS "functionName", pg_catalog.pg_get_function_identity_arguments(p.oid) AS "functionArguments" ${relation} JOIN pg_catalog.pg_trigger t ON t.tgrelid = c.oid JOIN pg_catalog.pg_proc p ON p.oid = t.tgfoid JOIN pg_catalog.pg_namespace pn ON pn.oid = p.pronamespace WHERE ${where} AND t.tgname = ${collector.add(object.name)} AND NOT t.tgisinternal`;
2754
2926
  break;
2755
2927
  case "function":
2756
- text = `SELECT pg_catalog.pg_get_functiondef(p.oid) AS "definition", p.provolatile::text AS "volatility", p.prosecdef AS "securityDefiner", p.proisstrict AS "strict", p.proconfig::text AS "config", pg_catalog.pg_get_function_result(p.oid) AS "result" FROM pg_catalog.pg_proc p JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace WHERE n.nspname = ${namespace} AND p.proname = ${name} AND p.prokind = 'f' AND ARRAY(SELECT tn.nspname || '.' || t.typname 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 ORDER BY a.ord) = ${collector.add(object.argumentTypes.map((type) => `${type.namespace}.${type.name}`))}::text[]`;
2928
+ text = `SELECT pg_catalog.pg_get_functiondef(p.oid) AS "definition", p.provolatile::text AS "volatility", p.prosecdef AS "securityDefiner", CASE WHEN p.prosecdef THEN pg_catalog.pg_get_userbyid(p.proowner)::text ELSE NULL END AS "definerOwner", p.proisstrict AS "strict", p.proconfig::text AS "config", pg_catalog.pg_get_function_result(p.oid) AS "result" FROM pg_catalog.pg_proc p JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace WHERE n.nspname = ${namespace} AND p.proname = ${name} AND p.prokind = 'f' AND ARRAY(SELECT tn.nspname || '.' || t.typname 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 ORDER BY a.ord) = ${collector.add(object.argumentTypes.map((type) => `${type.namespace}.${type.name}`))}::text[]`;
2757
2929
  break;
2758
2930
  case "view":
2759
2931
  text = `SELECT pg_catalog.pg_get_viewdef(c.oid, false) AS "definition", c.relkind::text AS "type", c.reloptions::text AS "options" ${relation} WHERE ${where} AND c.relkind IN ('v', 'm')`;
@@ -2764,7 +2936,7 @@ function renderMigrationObjectQuery(params) {
2764
2936
  case "column":
2765
2937
  case "columnDefault":
2766
2938
  case "generatedColumn":
2767
- text = `SELECT pg_catalog.format_type(a.atttypid, a.atttypmod) AS "type", a.attnotnull AS "notNull", a.attgenerated::text AS "generated", a.attidentity::text AS "identity", pg_catalog.pg_get_expr(d.adbin, d.adrelid, false) AS "definition" ${relation} JOIN pg_catalog.pg_attribute a ON a.attrelid = c.oid LEFT JOIN pg_catalog.pg_attrdef d ON d.adrelid = c.oid AND d.adnum = a.attnum WHERE ${where} AND a.attname = ${collector.add(object.column)} AND a.attnum > 0 AND NOT a.attisdropped`;
2939
+ text = `SELECT pg_catalog.format_type(a.atttypid, a.atttypmod) AS "type", a.attnotnull AS "notNull", a.attgenerated::text AS "generated", a.attidentity::text AS "identity", cn.nspname::text AS "collationNamespace", coll.collname::text AS "collationName", pg_catalog.pg_get_expr(d.adbin, d.adrelid, false) AS "definition" ${relation} JOIN pg_catalog.pg_attribute a ON a.attrelid = c.oid LEFT JOIN pg_catalog.pg_collation coll ON coll.oid = a.attcollation LEFT JOIN pg_catalog.pg_namespace cn ON cn.oid = coll.collnamespace LEFT JOIN pg_catalog.pg_attrdef d ON d.adrelid = c.oid AND d.adnum = a.attnum WHERE ${where} AND a.attname = ${collector.add(object.column)} AND a.attnum > 0 AND NOT a.attisdropped`;
2768
2940
  break;
2769
2941
  case "index":
2770
2942
  text = `SELECT pg_catalog.pg_get_indexdef(i.indexrelid, 0, false) AS "definition", i.indisunique AS "unique", i.indisvalid AS "valid", i.indisready AS "ready", con.conname::text AS "constraint", con.contype::text AS "constraintType" ${relation} JOIN pg_catalog.pg_index i ON i.indrelid = c.oid JOIN pg_catalog.pg_class ix ON ix.oid = i.indexrelid LEFT JOIN pg_catalog.pg_constraint con ON con.conindid = i.indexrelid AND con.contype IN ('p', 'u', 'x') WHERE ${where} AND ix.relname = ${collector.add(object.name)}`;
@@ -2793,11 +2965,11 @@ function renderMigrationObjectQuery(params) {
2793
2965
  case "column":
2794
2966
  case "columnDefault":
2795
2967
  case "generatedColumn":
2796
- text = `SELECT COLUMN_TYPE AS type, IS_NULLABLE AS nullable, COLUMN_DEFAULT AS definition, GENERATION_EXPRESSION AS generated, EXTRA AS extra, COLLATION_NAME AS collation FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = ${namespace} AND TABLE_NAME = ${name} AND COLUMN_NAME = ${collector.add(object.column)}`;
2968
+ text = `SELECT COLUMN_TYPE AS type, IS_NULLABLE AS nullable, COLUMN_DEFAULT AS definition, GENERATION_EXPRESSION AS ${dialect.quoteIdent({ name: "generated" })}, EXTRA AS extra, COLLATION_NAME AS collation FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = ${namespace} AND TABLE_NAME = ${name} AND COLUMN_NAME = ${collector.add(object.column)}`;
2797
2969
  break;
2798
2970
  case "constraint":
2799
2971
  if (object.constraintType === "exclusion")
2800
- throw unsupportedCapability14({ dialect: "mysql", feature: "exclusionConstraints" });
2972
+ throw unsupportedCapability16({ dialect: "mysql", feature: "exclusionConstraints" });
2801
2973
  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)}`;
2802
2974
  break;
2803
2975
  case "index":
@@ -2807,15 +2979,15 @@ function renderMigrationObjectQuery(params) {
2807
2979
  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}`;
2808
2980
  break;
2809
2981
  default:
2810
- throw unsupportedCapability14({ dialect: "mysql", feature: `inspect:${object.kind}` });
2982
+ throw unsupportedCapability16({ dialect: "mysql", feature: `inspect:${object.kind}` });
2811
2983
  }
2812
2984
  } else {
2813
2985
  if (physical.namespace !== "main" && physical.namespace !== "temp")
2814
- throw unsupportedCapability14({ dialect: "sqlite", feature: "attachedSchemaInspection" });
2986
+ throw unsupportedCapability16({ dialect: "sqlite", feature: "attachedSchemaInspection" });
2815
2987
  const catalog = `${dialect.quoteIdent({ name: physical.namespace })}.sqlite_schema`;
2816
2988
  const kind = object.kind === "table" || object.kind === "view" ? object.kind : object.kind === "trigger" ? "trigger" : object.kind === "index" ? "index" : "table";
2817
2989
  if (["function", "sequence", "postgresExtension", "enum"].includes(object.kind) || object.kind === "constraint" && object.constraintType === "exclusion")
2818
- throw unsupportedCapability14({ dialect: "sqlite", feature: `inspect:${object.kind}` });
2990
+ throw unsupportedCapability16({ dialect: "sqlite", feature: `inspect:${object.kind}` });
2819
2991
  const sqliteParams = new ParamCollector(dialect);
2820
2992
  if (object.kind === "column" || object.kind === "columnDefault" || object.kind === "generatedColumn") {
2821
2993
  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)}`;
@@ -2841,11 +3013,14 @@ function renderMysqlObjectMembers(params) {
2841
3013
  return { text, values: collector.values, returning: "none" };
2842
3014
  }
2843
3015
  function renderMigrationDependencies(params) {
3016
+ return dependencyQuery({ ...params, collector: new ParamCollector(params.dialect) });
3017
+ }
3018
+ function dependencyQuery(params) {
2844
3019
  if (params.dialect.name !== "postgres")
2845
- throw unsupportedCapability14({ dialect: params.dialect.name, feature: "catalogDependencies" });
3020
+ throw unsupportedCapability16({ dialect: params.dialect.name, feature: "catalogDependencies" });
2846
3021
  const object = params.identity;
2847
3022
  const physical = "table" in object ? object.table : object.name;
2848
- const collector = new ParamCollector(params.dialect);
3023
+ const collector = params.collector;
2849
3024
  const namespace = collector.add(physical.namespace);
2850
3025
  const name = collector.add(physical.name);
2851
3026
  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}`;
@@ -2885,6 +3060,41 @@ function renderMigrationDependencies(params) {
2885
3060
  }
2886
3061
  return { text: `SELECT DISTINCT json_build_array(d.deptype, a.type, a.object_names, a.object_args)::text AS address FROM (${source}) s JOIN pg_catalog.pg_depend d ON d.classid = s.classid AND d.objid = s.objid AND d.objsubid = s.objsubid CROSS JOIN LATERAL pg_catalog.pg_identify_object_as_address(d.refclassid, d.refobjid, d.refobjsubid) a ORDER BY address`, values: collector.values, returning: "none" };
2887
3062
  }
3063
+ function inspectionReferences(params) {
3064
+ const values = [];
3065
+ return { values, add(value) {
3066
+ values.push(value);
3067
+ return `request.${params.dialect.quoteIdent({ name: `p${values.length}` })}`;
3068
+ } };
3069
+ }
3070
+ function renderMigrationObjectBatch(params) {
3071
+ const { dialect } = params;
3072
+ if (dialect.name !== "postgres")
3073
+ throw unsupportedCapability16({ dialect: dialect.name, feature: "batchedMigrationInspection" });
3074
+ const groups = new Map;
3075
+ for (const [position, identity] of params.identities.entries()) {
3076
+ const kind = identity.kind === "constraint" ? `${identity.kind}:${identity.constraintType}` : identity.kind === "generatedColumn" ? "columnDefault" : identity.kind;
3077
+ const group = groups.get(kind) ?? [];
3078
+ group.push({ identity, position });
3079
+ groups.set(kind, group);
3080
+ }
3081
+ return [...groups.values()].map((group) => {
3082
+ const identity = group[0].identity;
3083
+ const facts = objectQuery({ dialect, identity, collector: inspectionReferences({ dialect }) });
3084
+ const dependencies = dependencyQuery({ dialect, identity, collector: inspectionReferences({ dialect }) });
3085
+ if (JSON.stringify(dependencies.values) !== JSON.stringify(facts.values))
3086
+ throw internalError3({ message: "Batched catalog queries bind their identity in different orders", meta: { kind: identity.kind } });
3087
+ const columns = facts.values.map((value, index) => `${dialect.quoteIdent({ name: `p${index + 1}` })} ${Array.isArray(value) ? "text[]" : "text"}`);
3088
+ const requests = group.map(({ identity, position }) => ({ position, ...Object.fromEntries(renderMigrationObjectQuery({ dialect, identity }).values.map((value, index) => [`p${index + 1}`, value])) }));
3089
+ const collector = new ParamCollector(dialect);
3090
+ return {
3091
+ text: `SELECT request.position, to_jsonb(facts) AS facts, ARRAY(SELECT address FROM (${dependencies.text}) dependency ORDER BY address) AS "dependencyAddresses" FROM jsonb_to_recordset(${collector.add(JSON.stringify(requests))}::text::jsonb) AS request(position integer, ${columns.join(", ")}) CROSS JOIN LATERAL (${facts.text}) facts`,
3092
+ values: collector.values,
3093
+ returning: "none",
3094
+ positions: group.map(({ position }) => position)
3095
+ };
3096
+ });
3097
+ }
2888
3098
  function renderMigrationServerVersion(params) {
2889
3099
  return { text: params.dialect.name === "sqlite" ? "SELECT sqlite_version() AS version" : "SELECT version() AS version", values: [], returning: "none" };
2890
3100
  }
@@ -2893,16 +3103,16 @@ function renderMigrationNamespace(params) {
2893
3103
  }
2894
3104
  function renderCheckProbe(params) {
2895
3105
  if (params.dialect.name !== "postgres")
2896
- throw unsupportedCapability14({ dialect: params.dialect.name, feature: "rollbackCheckProbe" });
3106
+ throw unsupportedCapability16({ dialect: params.dialect.name, feature: "rollbackCheckProbe" });
2897
3107
  const q = (name) => params.dialect.quoteIdent({ name });
2898
3108
  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" };
2899
3109
  }
2900
3110
  // packages/sql/src/dialects/postgres-migration.ts
2901
- import { VibeError as VibeError9, unsupportedCapability as unsupportedCapability15 } from "@vibeorm/schema";
3111
+ import { VibeError as VibeError9, unsupportedCapability as unsupportedCapability17 } from "@vibeorm/schema";
2902
3112
  var SETTING_VALUE = /^[0-9]+(?:\.[0-9]+)?\s*(?:us|ms|s|min|h|d)?$/;
2903
3113
  function requirePostgres2(params) {
2904
3114
  if (params.dialect.name !== "postgres") {
2905
- throw unsupportedCapability15({ dialect: params.dialect.name, feature: params.feature });
3115
+ throw unsupportedCapability17({ dialect: params.dialect.name, feature: params.feature });
2906
3116
  }
2907
3117
  }
2908
3118
  function renderMigrationSessionRead(params) {
@@ -3005,113 +3215,122 @@ WHERE n.nspname = pg_catalog.current_schema() AND c.relname = ${table} AND a.att
3005
3215
  };
3006
3216
  }
3007
3217
  export {
3008
- toPgArrayLiteral,
3009
- strictMatchPattern,
3010
- startsWithPattern,
3011
- sqliteTableConstraints,
3012
- sqliteDialect,
3013
- sqliteColumnClauses,
3014
- sqlUsesIncoming,
3015
- sql,
3016
- renderStatement,
3017
- renderSqliteRebuildObjects,
3018
- renderSqliteForeignKeyInventory,
3019
- renderSqliteColumnInventory,
3020
- renderSqlFragment,
3021
- renderRowLockClause,
3022
- renderRlsRole,
3023
- renderRlsReadinessQuery,
3024
- renderRlsProbeTable,
3025
- renderRlsPredicate,
3026
- renderRlsPolicyPath,
3027
- renderRlsPolicy,
3028
- renderRlsNoForce,
3029
- renderRlsForce,
3030
- renderRlsEnable,
3031
- renderRlsDropPolicy,
3032
- renderRlsDisable,
3033
- renderRlsContext,
3034
- renderRlsColumnType,
3035
- renderRelationStateQuery,
3036
- renderPredicate,
3037
- renderPostgresWorkload,
3038
- renderPostgresExplain,
3039
- renderPostgresDefaultFunctionIdentity,
3040
- renderMysqlObjectMembers,
3041
- renderMysqlCheckProbe,
3042
- renderModuleJournal,
3043
- renderMigrationVisibility,
3044
- renderMigrationSessionSet,
3045
- renderMigrationSessionRestore,
3046
- renderMigrationSessionRead,
3047
- renderMigrationServerVersion,
3048
- renderMigrationObjectQuery,
3049
- renderMigrationNamespace,
3050
- renderMigrationInventory,
3051
- renderMigrationHistoryQuery,
3052
- renderMigrationDependencies,
3053
- renderIndexStateQuery,
3054
- renderFragment,
3055
- renderExpr,
3056
- renderExclusionSetup,
3057
- renderExclusionProbe,
3058
- renderExclusionDdl,
3059
- renderExclusionCatalog,
3060
- renderDiagnostic,
3061
- renderConstraintStateQuery,
3062
- renderConstraintOwnedIndexDrop,
3063
- renderColumnStateQuery,
3064
- renderCheckProbe,
3065
- renderAdvisoryLock,
3066
- projectionOutputName,
3067
- postgresDialect,
3068
- parsePgArrayLiteral,
3069
- parseDateTimeText,
3070
- mysqlDialect,
3071
- mapConflictColumns,
3072
- jsonParamCell,
3073
- isSqlFragment,
3074
- isSqlDefaultCell,
3075
- isSetOperation,
3076
- isListSetOperation,
3077
- isJsonParamCell,
3078
- isFixedDiagnostic,
3079
- isExcludedRef,
3080
- isDbNowMarker,
3081
- getSqlDialect,
3082
- excludedRef,
3083
- escapeLikePattern,
3084
- escapeGlobPattern,
3085
- enumMembershipCodec,
3086
- endsWithPattern,
3087
- describeRowLock,
3088
- decodeIsNoop,
3089
- decode,
3090
- dbNowMarker,
3091
- containsPattern,
3092
- compileSql,
3093
- compileExclusion,
3094
- SQL_DIALECTS,
3095
- SQL_DEFAULT_CELL,
3096
- SQLITE_SESSION_SQL,
3097
- SQLITE_CODECS,
3098
- SQLITE_CAPABILITIES,
3099
- RLS_READINESS_SQL,
3100
- ParamCollector,
3101
- POSTGRES_WORKLOAD_LIMITS,
3102
- POSTGRES_DIAGNOSTIC_SQL,
3103
- POSTGRES_CODECS,
3104
- POSTGRES_CAPABILITIES,
3105
- NATIVE_RLS_PROBE_POLICY,
3106
- NATIVE_RLS,
3107
- MYSQL_CODECS,
3108
- MYSQL_CAPABILITIES,
3109
- MODULE_JOURNAL_COLUMN,
3110
- JSON_TRANSPORT,
3111
- DIALECT_CODECS,
3112
- DIALECT_CAPABILITIES,
3218
+ ADVISORY_KEY_BOUNDS,
3113
3219
  ADVISORY_LOCK_RESULT_COLUMN,
3114
- ADVISORY_KEY_BOUNDS
3220
+ DIALECT_CAPABILITIES,
3221
+ DIALECT_CODECS,
3222
+ JSON_TRANSPORT,
3223
+ MODULE_JOURNAL_COLUMN,
3224
+ MYSQL_CAPABILITIES,
3225
+ MYSQL_CODECS,
3226
+ NATIVE_RLS,
3227
+ NATIVE_RLS_PROBE_POLICY,
3228
+ POSTGRES_CAPABILITIES,
3229
+ POSTGRES_CODECS,
3230
+ POSTGRES_DIAGNOSTIC_SQL,
3231
+ POSTGRES_WORKLOAD_LIMITS,
3232
+ ParamCollector,
3233
+ RLS_READINESS_SQL,
3234
+ SHADOW_CAPABILITIES,
3235
+ SHADOW_DATABASE,
3236
+ SQLITE_CAPABILITIES,
3237
+ SQLITE_CODECS,
3238
+ SQLITE_SESSION_SQL,
3239
+ SQL_DEFAULT_CELL,
3240
+ SQL_DIALECTS,
3241
+ compileExclusion,
3242
+ compileSql,
3243
+ containsPattern,
3244
+ dbNowMarker,
3245
+ decode,
3246
+ decodeIsNoop,
3247
+ describeRowLock,
3248
+ endsWithPattern,
3249
+ enumMembershipCodec,
3250
+ escapeGlobPattern,
3251
+ escapeLikePattern,
3252
+ excludedRef,
3253
+ getSqlDialect,
3254
+ isDbNowMarker,
3255
+ isExcludedRef,
3256
+ isFixedDiagnostic,
3257
+ isJsonParamCell,
3258
+ isListSetOperation,
3259
+ isSetOperation,
3260
+ isSqlDefaultCell,
3261
+ isSqlFragment,
3262
+ jsonParamCell,
3263
+ mapConflictColumns,
3264
+ mysqlDialect,
3265
+ parseDateTimeText,
3266
+ parsePgArrayLiteral,
3267
+ parsePostgresTypeName,
3268
+ postgresDialect,
3269
+ projectionOutputName,
3270
+ renderAdvisoryLock,
3271
+ renderCheckProbe,
3272
+ renderColumnStateQuery,
3273
+ renderConstraintOwnedIndexDrop,
3274
+ renderConstraintStateQuery,
3275
+ renderDiagnostic,
3276
+ renderExclusionCatalog,
3277
+ renderExclusionDdl,
3278
+ renderExclusionProbe,
3279
+ renderExclusionSetup,
3280
+ renderExpr,
3281
+ renderFragment,
3282
+ renderIndexStateQuery,
3283
+ renderMigrationDependencies,
3284
+ renderMigrationHistoryQuery,
3285
+ renderMigrationInventory,
3286
+ renderMigrationNamespace,
3287
+ renderMigrationObjectBatch,
3288
+ renderMigrationObjectQuery,
3289
+ renderMigrationServerVersion,
3290
+ renderMigrationSessionRead,
3291
+ renderMigrationSessionRestore,
3292
+ renderMigrationSessionSet,
3293
+ renderMigrationVisibility,
3294
+ renderModuleDependencyQuery,
3295
+ renderModuleJournal,
3296
+ renderMysqlCheckProbe,
3297
+ renderMysqlObjectMembers,
3298
+ renderPostgresDefaultFunctionIdentity,
3299
+ renderPostgresExplain,
3300
+ renderPostgresTypeIdentity,
3301
+ renderPostgresTypeName,
3302
+ renderPostgresWorkload,
3303
+ renderPredicate,
3304
+ renderRelationStateQuery,
3305
+ renderReplayCoverageGaps,
3306
+ renderRlsColumnType,
3307
+ renderRlsContext,
3308
+ renderRlsDisable,
3309
+ renderRlsDropPolicy,
3310
+ renderRlsEnable,
3311
+ renderRlsForce,
3312
+ renderRlsNoForce,
3313
+ renderRlsPolicy,
3314
+ renderRlsPolicyPath,
3315
+ renderRlsPredicate,
3316
+ renderRlsProbeTable,
3317
+ renderRlsReadinessQuery,
3318
+ renderRlsRole,
3319
+ renderRowLockClause,
3320
+ renderShadowOperation,
3321
+ renderSqlFragment,
3322
+ renderSqliteColumnInventory,
3323
+ renderSqliteForeignKeyInventory,
3324
+ renderSqliteRebuildObjects,
3325
+ renderStatement,
3326
+ sql,
3327
+ sqlUsesIncoming,
3328
+ sqliteColumnClauses,
3329
+ sqliteDialect,
3330
+ sqliteTableConstraints,
3331
+ startsWithPattern,
3332
+ strictMatchPattern,
3333
+ toPgArrayLiteral
3115
3334
  };
3116
3335
 
3117
- //# debugId=760F5D93FBC694E964756E2164756E21
3336
+ //# debugId=E08264A778510D8664756E2164756E21