Skip to content

Commit 0a8a31d

Browse files
committed
feat: add not_in page skip to canSkipPage
Skips page when min === max and the uniform value appears in the NOT IN list. Mirrors the neq logic but for multiple exclusion values.
1 parent 8d64f44 commit 0a8a31d

File tree

2 files changed

+25
-0
lines changed

2 files changed

+25
-0
lines changed

src/decode.test.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,20 @@ describe("canSkipPage", () => {
166166
const bigPage: PageInfo = { byteOffset: 0n, byteLength: 100, rowCount: 50, nullCount: 0, minValue: 10n, maxValue: 90n };
167167
expect(canSkipPage(bigPage, [{ column: "x", op: "in", value: [1, 5, 95] }], "x")).toBe(true);
168168
});
169+
170+
it("skips uniform page where value is in NOT IN list", () => {
171+
const uniform: PageInfo = { byteOffset: 0n, byteLength: 100, rowCount: 50, nullCount: 0, minValue: 42, maxValue: 42 };
172+
expect(canSkipPage(uniform, [{ column: "x", op: "not_in", value: [10, 42, 99] }], "x")).toBe(true);
173+
});
174+
175+
it("does not skip uniform page where value is not in NOT IN list", () => {
176+
const uniform: PageInfo = { byteOffset: 0n, byteLength: 100, rowCount: 50, nullCount: 0, minValue: 42, maxValue: 42 };
177+
expect(canSkipPage(uniform, [{ column: "x", op: "not_in", value: [10, 99] }], "x")).toBe(false);
178+
});
179+
180+
it("does not skip range page for NOT IN", () => {
181+
expect(canSkipPage(page, [{ column: "x", op: "not_in", value: [10, 50, 90] }], "x")).toBe(false);
182+
});
169183
});
170184

171185
describe("assembleRows", () => {

src/decode.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,17 @@ export function canSkipPage(page: PageInfo, filters: QueryDescriptor["filters"],
3939
})) return true;
4040
break;
4141
}
42+
// not_in: skip when entire page is a single value that appears in the NOT IN list
43+
case "not_in": {
44+
if (!Array.isArray(filter.value) || min !== max) break;
45+
if (filter.value.some(v => {
46+
let cv = v;
47+
if (typeof min === "bigint" && typeof cv === "number") cv = BigInt(Math.trunc(cv));
48+
else if (typeof min === "number" && typeof cv === "bigint") cv = Number(cv);
49+
return cv === min;
50+
})) return true;
51+
break;
52+
}
4253
case "between": {
4354
if (!Array.isArray(filter.value) || filter.value.length !== 2) break;
4455
let lo = filter.value[0];

0 commit comments

Comments
 (0)