Skip to content

Commit b62f51e

Browse files
committed
fix: Math.min/max stack overflow in SQL executor, bigint precision in IN sets, empty partials guard
- SQL executor: replace Math.min/max spread with reduce (stack overflow on 65K+ values) - decode.ts: keep bigint values as-is in IN/NOT_IN Set (was losing precision via Number()) - merge.ts: guard Math.max on empty partials array (returned -Infinity) - vector-search docs: fix inaccurate claim about filter-before-search ordering
1 parent e7b1475 commit b62f51e

File tree

4 files changed

+9
-12
lines changed

4 files changed

+9
-12
lines changed

docs/src/content/docs/vector-search.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,4 +83,4 @@ const results = await qm
8383
.collect()
8484
```
8585

86-
Filters are applied before vector search — only matching rows are scanned for similarity.
86+
Vector search runs across all matching fragments. When combined with filters, both are applied during the scan phase — the query engine evaluates filter predicates and vector distances together to return filtered nearest neighbors.

src/decode.ts

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -480,12 +480,12 @@ export function matchesFilter(
480480
case "in": {
481481
if (!Array.isArray(t)) return false;
482482
const set = getInSet(t);
483-
return set.has(typeof val === "bigint" ? Number(val) : val);
483+
return set.has(val);
484484
}
485485
case "not_in": {
486486
if (!Array.isArray(t)) return false;
487487
const set = getInSet(t);
488-
return !set.has(typeof val === "bigint" ? Number(val) : val);
488+
return !set.has(val);
489489
}
490490
case "between": {
491491
if (!Array.isArray(t) || t.length !== 2) return false;
@@ -514,15 +514,12 @@ export function matchesFilter(
514514
}
515515

516516
/** Cache IN/NOT_IN value sets — O(1) lookup instead of O(m) per row. */
517-
const inSetCache = new WeakMap<readonly (number | bigint | string)[], Set<number | string>>();
517+
const inSetCache = new WeakMap<readonly (number | bigint | string)[], Set<number | bigint | string>>();
518518

519-
function getInSet(values: readonly (number | bigint | string)[]): Set<number | string> {
519+
function getInSet(values: readonly (number | bigint | string)[]): Set<number | bigint | string> {
520520
let cached = inSetCache.get(values);
521521
if (cached) return cached;
522-
const set = new Set<number | string>();
523-
for (const v of values) {
524-
set.add(typeof v === "bigint" ? Number(v) : v);
525-
}
522+
const set = new Set<number | bigint | string>(values);
526523
inSetCache.set(values, set);
527524
return set;
528525
}

src/merge.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ export function mergeQueryResults(
121121
): QueryResult {
122122
const totalBytesRead = partials.reduce((s, p) => s + p.bytesRead, 0);
123123
const totalPagesSkipped = partials.reduce((s, p) => s + p.pagesSkipped, 0);
124-
const maxDuration = Math.max(...partials.map((p) => p.durationMs));
124+
const maxDuration = partials.length > 0 ? partials.reduce((m, p) => p.durationMs > m ? p.durationMs : m, 0) : 0;
125125
const columns =
126126
partials.length > 0 ? partials[0].columns : query.projections;
127127

src/sql/executor.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -202,8 +202,8 @@ function computeAgg(rows: Row[], agg: AggregateOp): number | bigint | string | b
202202
switch (agg.fn) {
203203
case "sum": return values.reduce((a, b) => a + b, 0);
204204
case "avg": return values.reduce((a, b) => a + b, 0) / values.length;
205-
case "min": return Math.min(...values);
206-
case "max": return Math.max(...values);
205+
case "min": return values.reduce((a, b) => a < b ? a : b);
206+
case "max": return values.reduce((a, b) => a > b ? a : b);
207207
case "stddev": {
208208
const mean = values.reduce((a, b) => a + b, 0) / values.length;
209209
const sq = values.reduce((a, b) => a + (b - mean) ** 2, 0) / values.length;

0 commit comments

Comments
 (0)