@an5/orm 1.3.4 → 1.3.5

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/an5Orm.js CHANGED
@@ -806,8 +806,9 @@ class TableClient {
806
806
  const vectorJson = JSON.stringify(finalArgs.vector);
807
807
  const col = (0, sql_utils_1.quoteIdentifier)(field);
808
808
  try {
809
- if (dim > 1998) {
810
- throw new Error("Vector dimension exceeds SQL Server limit of 1998");
809
+ const maxDim = elementType === 'float16' ? 3996 : 1998;
810
+ if (dim > maxDim) {
811
+ throw new Error(`Vector dimension ${dim} exceeds SQL Server limit of ${maxDim} for ${elementType}`);
811
812
  }
812
813
  let sqlText = `SELECT TOP (${take}) *, `;
813
814
  sqlText += `VECTOR_DISTANCE('${metric}', CAST(${col} AS VECTOR(${dim}, ${elementType})), CAST(@query_vector AS VECTOR(${dim}, ${elementType}))) AS distance `;
@@ -845,6 +846,7 @@ class TableClient {
845
846
  msg.includes("not a recognized built-in function") ||
846
847
  msg.includes("not a defined system type") ||
847
848
  msg.includes("limit of 1998") ||
849
+ msg.includes("limit of 3996") ||
848
850
  err?.number === 195 ||
849
851
  err?.number === 102 ||
850
852
  err?.number === 319 ||
package/dist/cli.js CHANGED
File without changes
@@ -402,6 +402,19 @@ namespace An5Orm
402
402
  // \`float[]\` does not convert to it.
403
403
  if (value is float[] floats) return FormatVector(floats.Select(v => (double)v));
404
404
  if (value is double[] doubles) return FormatVector(doubles);
405
+ if (value is ReadOnlyMemory<float> rom) return FormatVector(rom.ToArray().Select(v => (double)v));
406
+ if (value is Memory<float> mem) return FormatVector(mem.ToArray().Select(v => (double)v));
407
+ if (value is ReadOnlyMemory<double> romD) return FormatVector(romD.ToArray());
408
+ if (value is Memory<double> memD) return FormatVector(memD.ToArray());
409
+ if (value != null && value.GetType().Name.StartsWith("SqlVector"))
410
+ {
411
+ var memProp = value.GetType().GetProperty("Memory");
412
+ if (memProp != null)
413
+ {
414
+ var memVal = memProp.GetValue(value);
415
+ if (memVal != null) return Bindable(memVal);
416
+ }
417
+ }
405
418
  return value;
406
419
  }
407
420
 
@@ -1095,6 +1108,31 @@ namespace An5Orm
1095
1108
  for (int i = 0; i < asDouble.Length; i++) fromDouble[i] = (float)asDouble[i];
1096
1109
  return fromDouble;
1097
1110
  }
1111
+ if (value is ReadOnlyMemory<float> rom) return rom.ToArray();
1112
+ if (value is Memory<float> mem) return mem.ToArray();
1113
+ if (value is ReadOnlyMemory<double> romD)
1114
+ {
1115
+ var arr = romD.ToArray();
1116
+ var fromDouble = new float[arr.Length];
1117
+ for (int i = 0; i < arr.Length; i++) fromDouble[i] = (float)arr[i];
1118
+ return fromDouble;
1119
+ }
1120
+ if (value is Memory<double> memD)
1121
+ {
1122
+ var arr = memD.ToArray();
1123
+ var fromDouble = new float[arr.Length];
1124
+ for (int i = 0; i < arr.Length; i++) fromDouble[i] = (float)arr[i];
1125
+ return fromDouble;
1126
+ }
1127
+ if (value != null && value.GetType().Name.StartsWith("SqlVector"))
1128
+ {
1129
+ var memProp = value.GetType().GetProperty("Memory");
1130
+ if (memProp != null)
1131
+ {
1132
+ var memVal = memProp.GetValue(value);
1133
+ if (memVal != null) return DecodeVectorColumn(memVal);
1134
+ }
1135
+ }
1098
1136
 
1099
1137
  string text = value as string;
1100
1138
  byte[] bytes = value as byte[];
@@ -6,6 +6,8 @@ export interface PulledColumn {
6
6
  precision: number;
7
7
  scale: number;
8
8
  isNullable: boolean | number;
9
+ vectorDimensions?: number | null;
10
+ vectorBaseType?: string | null;
9
11
  }
10
12
  /**
11
13
  * The schema type of an introspected SQL Server column.
@@ -23,7 +23,17 @@ const dialect_1 = require("./dialect");
23
23
  function sqlServerTypeForColumn(col) {
24
24
  let sqlType = col.dataType.toUpperCase();
25
25
  const dt = col.dataType.toLowerCase();
26
- if (dt === 'nvarchar' || dt === 'varchar') {
26
+ if (dt === 'vector') {
27
+ if (col.vectorDimensions && col.vectorDimensions > 0) {
28
+ const baseType = col.vectorBaseType?.toLowerCase();
29
+ if (baseType && baseType !== 'float32') {
30
+ return `VECTOR(${col.vectorDimensions}, ${baseType})`;
31
+ }
32
+ return `VECTOR(${col.vectorDimensions})`;
33
+ }
34
+ return 'VECTOR';
35
+ }
36
+ else if (dt === 'nvarchar' || dt === 'varchar') {
27
37
  sqlType = col.maxLength === -1 ? `${sqlType.toUpperCase()}(MAX)` : `${sqlType.toUpperCase()}(${col.maxLength / 2})`;
28
38
  }
29
39
  else if (dt === 'char' || dt === 'nchar') {
package/dist/orm.js CHANGED
@@ -759,8 +759,9 @@ class TableClient extends adapters_1.AdapterTableClient {
759
759
  const vectorJson = JSON.stringify(finalArgs.vector);
760
760
  const col = (0, sql_utils_1.quoteIdentifier)(field);
761
761
  try {
762
- if (dim > 1998) {
763
- throw new Error("Vector dimension exceeds SQL Server limit of 1998");
762
+ const maxDim = elementType === 'float16' ? 3996 : 1998;
763
+ if (dim > maxDim) {
764
+ throw new Error(`Vector dimension ${dim} exceeds SQL Server limit of ${maxDim} for ${elementType}`);
764
765
  }
765
766
  let sqlText = `SELECT TOP (${take}) *, `;
766
767
  sqlText += `VECTOR_DISTANCE('${metric}', CAST(${col} AS VECTOR(${dim}, ${elementType})), CAST(@query_vector AS VECTOR(${dim}, ${elementType}))) AS distance `;
@@ -798,6 +799,7 @@ class TableClient extends adapters_1.AdapterTableClient {
798
799
  msg.includes("not a recognized built-in function") ||
799
800
  msg.includes("not a defined system type") ||
800
801
  msg.includes("limit of 1998") ||
802
+ msg.includes("limit of 3996") ||
801
803
  err?.number === 195 ||
802
804
  err?.number === 102 ||
803
805
  err?.number === 319 ||
package/dist/pull.js CHANGED
@@ -49,7 +49,20 @@ async function pull() {
49
49
  // nothing about the connection string being wrong.
50
50
  refuseIfNotSqlServer((0, config_1.providerFromConfig)(config, process.env), "db:pull");
51
51
  console.log("🔍 Pulling schema from database...");
52
- const tables = await (await getDb()).$queryRawUnsafe(`
52
+ const db = await getDb();
53
+ // Safely detect if the SQL Server catalog supports native VECTOR metadata columns
54
+ let hasVectorCatalog = false;
55
+ try {
56
+ const vecCheck = await db.$queryRawUnsafe(`SELECT COL_LENGTH('sys.columns', 'vector_dimensions') AS hasVec`);
57
+ hasVectorCatalog = !!(vecCheck?.[0]?.hasVec);
58
+ }
59
+ catch {
60
+ hasVectorCatalog = false;
61
+ }
62
+ const vectorColumnSelect = hasVectorCatalog
63
+ ? ",\n c.vector_dimensions AS vectorDimensions,\n c.vector_base_type_desc AS vectorBaseType"
64
+ : "";
65
+ const tables = await db.$queryRawUnsafe(`
53
66
  SELECT s.name AS schemaName, t.name AS tableName
54
67
  FROM sys.tables t
55
68
  JOIN sys.schemas s ON t.schema_id = s.schema_id
@@ -123,7 +136,7 @@ async function pull() {
123
136
  const { tableName, schemaName } = table;
124
137
  console.log(`Introspecting table [${tableName}]...`);
125
138
  // Get columns
126
- const columns = await (await getDb()).$queryRawUnsafe(`
139
+ const columns = await db.$queryRawUnsafe(`
127
140
  SELECT
128
141
  c.name AS columnName,
129
142
  ty.name AS dataType,
@@ -133,7 +146,7 @@ async function pull() {
133
146
  c.is_nullable AS isNullable,
134
147
  c.is_identity AS isIdentity,
135
148
  pk.is_primary_key AS isPrimaryKey,
136
- d.definition AS defaultValue
149
+ d.definition AS defaultValue${vectorColumnSelect}
137
150
  FROM sys.columns c
138
151
  JOIN sys.types ty ON c.user_type_id = ty.user_type_id
139
152
  LEFT JOIN (
@@ -351,14 +364,14 @@ async function pull() {
351
364
  ?? (existingViewNames[legacy] ? legacy : (0, pull_schema_1.blockNameForObject)(viewName));
352
365
  const targetFile = viewToFileMap[modelName] ?? viewToFileMap[key] ?? viewToFileMap[viewName] ?? defaultFile;
353
366
  console.log(`Introspecting view [${key}]...`);
354
- const columns = await (await getDb()).$queryRawUnsafe(`
367
+ const columns = await db.$queryRawUnsafe(`
355
368
  SELECT
356
369
  c.name AS columnName,
357
370
  ty.name AS dataType,
358
371
  c.max_length AS maxLength,
359
372
  c.precision AS precision,
360
373
  c.scale AS scale,
361
- c.is_nullable AS isNullable
374
+ c.is_nullable AS isNullable${vectorColumnSelect}
362
375
  FROM sys.columns c
363
376
  JOIN sys.types ty ON c.user_type_id = ty.user_type_id
364
377
  WHERE c.object_id = OBJECT_ID(@p_0)
@@ -418,6 +418,19 @@ namespace An5Orm
418
418
  // \`float[]\` does not convert to it.
419
419
  if (value is float[] floats) return FormatVector(floats.Select(v => (double)v));
420
420
  if (value is double[] doubles) return FormatVector(doubles);
421
+ if (value is ReadOnlyMemory<float> rom) return FormatVector(rom.ToArray().Select(v => (double)v));
422
+ if (value is Memory<float> mem) return FormatVector(mem.ToArray().Select(v => (double)v));
423
+ if (value is ReadOnlyMemory<double> romD) return FormatVector(romD.ToArray());
424
+ if (value is Memory<double> memD) return FormatVector(memD.ToArray());
425
+ if (value != null && value.GetType().Name.StartsWith("SqlVector"))
426
+ {
427
+ var memProp = value.GetType().GetProperty("Memory");
428
+ if (memProp != null)
429
+ {
430
+ var memVal = memProp.GetValue(value);
431
+ if (memVal != null) return Bindable(memVal);
432
+ }
433
+ }
421
434
  return value;
422
435
  }
423
436
 
@@ -1113,6 +1126,31 @@ namespace An5Orm
1113
1126
  for (int i = 0; i < asDouble.Length; i++) fromDouble[i] = (float)asDouble[i];
1114
1127
  return fromDouble;
1115
1128
  }
1129
+ if (value is ReadOnlyMemory<float> rom) return rom.ToArray();
1130
+ if (value is Memory<float> mem) return mem.ToArray();
1131
+ if (value is ReadOnlyMemory<double> romD)
1132
+ {
1133
+ var arr = romD.ToArray();
1134
+ var fromDouble = new float[arr.Length];
1135
+ for (int i = 0; i < arr.Length; i++) fromDouble[i] = (float)arr[i];
1136
+ return fromDouble;
1137
+ }
1138
+ if (value is Memory<double> memD)
1139
+ {
1140
+ var arr = memD.ToArray();
1141
+ var fromDouble = new float[arr.Length];
1142
+ for (int i = 0; i < arr.Length; i++) fromDouble[i] = (float)arr[i];
1143
+ return fromDouble;
1144
+ }
1145
+ if (value != null && value.GetType().Name.StartsWith("SqlVector"))
1146
+ {
1147
+ var memProp = value.GetType().GetProperty("Memory");
1148
+ if (memProp != null)
1149
+ {
1150
+ var memVal = memProp.GetValue(value);
1151
+ if (memVal != null) return DecodeVectorColumn(memVal);
1152
+ }
1153
+ }
1116
1154
 
1117
1155
  string text = value as string;
1118
1156
  byte[] bytes = value as byte[];
@@ -16,6 +16,8 @@ export interface PulledColumn {
16
16
  precision: number;
17
17
  scale: number;
18
18
  isNullable: boolean | number;
19
+ vectorDimensions?: number | null;
20
+ vectorBaseType?: string | null;
19
21
  }
20
22
 
21
23
  /**
@@ -28,7 +30,16 @@ export function sqlServerTypeForColumn(col: PulledColumn): string {
28
30
  let sqlType = col.dataType.toUpperCase();
29
31
  const dt = col.dataType.toLowerCase();
30
32
 
31
- if (dt === 'nvarchar' || dt === 'varchar') {
33
+ if (dt === 'vector') {
34
+ if (col.vectorDimensions && col.vectorDimensions > 0) {
35
+ const baseType = col.vectorBaseType?.toLowerCase();
36
+ if (baseType && baseType !== 'float32') {
37
+ return `VECTOR(${col.vectorDimensions}, ${baseType})`;
38
+ }
39
+ return `VECTOR(${col.vectorDimensions})`;
40
+ }
41
+ return 'VECTOR';
42
+ } else if (dt === 'nvarchar' || dt === 'varchar') {
32
43
  sqlType = col.maxLength === -1 ? `${sqlType.toUpperCase()}(MAX)` : `${sqlType.toUpperCase()}(${col.maxLength / 2})`;
33
44
  } else if (dt === 'char' || dt === 'nchar') {
34
45
  sqlType = `${sqlType.toUpperCase()}(${col.maxLength / 2})`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@an5/orm",
3
- "version": "1.3.4",
3
+ "version": "1.3.5",
4
4
  "description": "The lightweight ORM for SQL Server with support for TypeScript, Python, .NET (C#), Go, Rust, Java, Kotlin, and Swift.",
5
5
  "license": "MIT",
6
6
  "bin": {