Skip to content

Commit 7ba9261

Browse files
committed
fix: QueryModeError for table-not-found, filterToSql null guard, int64 Math.trunc, reducer logging
- query-do: 4 throw sites use QueryModeError("TABLE_NOT_FOUND") instead of plain Error - query-do: log reducer DO failures with this.log("error", ...) before collecting - wasm-engine: filterToSql emits IS NULL/IS NOT NULL when value is null/undefined - wasm-engine: registerDecodedColumnInner int64 path guards null + non-bigint with Math.trunc
1 parent 7fb81f3 commit 7ba9261

2 files changed

Lines changed: 16 additions & 6 deletions

File tree

src/query-do.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { mergeQueryResults } from "./merge.js";
1313
import { decodeColumnarBatch, columnarBatchToRows } from "./columnar.js";
1414
import { coalesceRanges, fetchBounded, withRetry, withTimeout } from "./coalesce.js";
1515
import { R2SpillBackend, encodeColumnarRun } from "./r2-spill.js";
16+
import { QueryModeError } from "./errors.js";
1617
import {
1718
type Operator, type RowBatch,
1819
buildEdgePipeline, drainPipeline, estimateRowSize,
@@ -678,7 +679,7 @@ export class QueryDO extends DurableObject<Env> {
678679
const metaCached = !!meta;
679680
if (!meta) {
680681
meta = (await this.loadTableFromR2(query.table)) ?? undefined;
681-
if (!meta) throw new Error(`Table "${query.table}" not found`);
682+
if (!meta) throw new QueryModeError("TABLE_NOT_FOUND", `Table "${query.table}" not found`);
682683
}
683684

684685
const { columns } = meta;
@@ -801,7 +802,7 @@ export class QueryDO extends DurableObject<Env> {
801802
let meta: TableMeta | undefined = this.footerCache.get(query.table);
802803
if (!meta) {
803804
meta = (await this.loadTableFromR2(query.table)) ?? undefined;
804-
if (!meta) throw new Error(`Table "${query.table}" not found`);
805+
if (!meta) throw new QueryModeError("TABLE_NOT_FOUND", `Table "${query.table}" not found`);
805806
}
806807

807808
// Use operator pipeline for any query that could produce unbounded results:
@@ -1252,7 +1253,7 @@ export class QueryDO extends DurableObject<Env> {
12521253
let leftMeta: TableMeta | undefined = this.footerCache.get(query.table);
12531254
if (!leftMeta) {
12541255
leftMeta = (await this.loadTableFromR2(query.table)) ?? undefined;
1255-
if (!leftMeta) throw new Error(`Table "${query.table}" not found`);
1256+
if (!leftMeta) throw new QueryModeError("TABLE_NOT_FOUND", `Table "${query.table}" not found`);
12561257
}
12571258

12581259
// Build left scan (no sort/limit/agg — those apply after join)
@@ -1272,7 +1273,7 @@ export class QueryDO extends DurableObject<Env> {
12721273
let rightMeta: TableMeta | undefined = this.footerCache.get(join.right.table);
12731274
if (!rightMeta) {
12741275
rightMeta = (await this.loadTableFromR2(join.right.table)) ?? undefined;
1275-
if (!rightMeta) throw new Error(`Table "${join.right.table}" not found`);
1276+
if (!rightMeta) throw new QueryModeError("TABLE_NOT_FOUND", `Table "${join.right.table}" not found`);
12761277
}
12771278

12781279
// Build right scan
@@ -1907,7 +1908,9 @@ export class QueryDO extends DurableObject<Env> {
19071908
if (s.status === "fulfilled") {
19081909
results.push(s.value);
19091910
} else {
1910-
failures.push(String(s.reason));
1911+
const reason = String(s.reason);
1912+
failures.push(reason);
1913+
this.log("error", "reducer_do_failed", { reason, tier });
19111914
}
19121915
}
19131916
if (failures.length > 0) {

src/wasm-engine.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -533,7 +533,10 @@ export class WasmEngine {
533533
const dataPtr = this.exports.alloc(rowCount * 8);
534534
if (!dataPtr) return false;
535535
const dst = new BigInt64Array(this.exports.memory.buffer, dataPtr, rowCount);
536-
for (let i = 0; i < rowCount; i++) dst[i] = BigInt(values[i] as bigint ?? 0n);
536+
for (let i = 0; i < rowCount; i++) {
537+
const v = values[i];
538+
dst[i] = v == null ? 0n : typeof v === "bigint" ? v : BigInt(Math.trunc(v as number));
539+
}
537540
this.exports.registerTableInt64(tPtr, tLen, cPtr, cLen, dataPtr, rowCount);
538541
return true;
539542
}
@@ -1010,6 +1013,10 @@ const COMPARISON_OP_MAP: Record<string, string> = { eq: "=", neq: "!=", gt: ">",
10101013
function filterToSql(f: FilterOp): string {
10111014
if (f.op === "is_null") return `${quote(f.column)} IS NULL`;
10121015
if (f.op === "is_not_null") return `${quote(f.column)} IS NOT NULL`;
1016+
// null/undefined value with eq/neq → IS NULL / IS NOT NULL
1017+
if (f.value === null || f.value === undefined) {
1018+
return `${quote(f.column)} ${f.op === "neq" ? "IS NOT NULL" : "IS NULL"}`;
1019+
}
10131020
if (f.op === "in" && Array.isArray(f.value)) {
10141021
return `${quote(f.column)} IN (${f.value.map(v => typeof v === "string" ? `'${escapeSql(v)}'` : String(v)).join(", ")})`;
10151022
}

0 commit comments

Comments
 (0)