From b595d8a5794229062abf51748a31636575e0c5bc Mon Sep 17 00:00:00 2001 From: Will Jones Date: Thu, 20 Mar 2025 08:07:10 -0700 Subject: [PATCH] fix(nodejs): workaround for apache-arrow null vector issue (#2244) Fixes #2240 --- nodejs/__test__/table.test.ts | 9 +++++++++ nodejs/lancedb/arrow.ts | 17 ++++++++++++++++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/nodejs/__test__/table.test.ts b/nodejs/__test__/table.test.ts index 22f6b9c3..966e4050 100644 --- a/nodejs/__test__/table.test.ts +++ b/nodejs/__test__/table.test.ts @@ -279,6 +279,15 @@ describe.each([arrow15, arrow16, arrow17, arrow18])( expect(res.getChild("y")?.toJSON()).toEqual([2, null, null, null]); expect(res.getChild("z")?.toJSON()).toEqual([null, null, 3n, 5n]); }); + + it("should handle null vectors at end of data", async () => { + // https://github.com/lancedb/lancedb/issues/2240 + const data = [{ vector: [1, 2, 3] }, { vector: null }]; + const db = await connect("memory://"); + + const table = await db.createTable("my_table", data); + expect(await table.countRows()).toEqual(2); + }); }, ); diff --git a/nodejs/lancedb/arrow.ts b/nodejs/lancedb/arrow.ts index 00f8ffed..4b3be487 100644 --- a/nodejs/lancedb/arrow.ts +++ b/nodejs/lancedb/arrow.ts @@ -37,10 +37,10 @@ import { Utf8, Vector, makeVector as arrowMakeVector, + vectorFromArray as badVectorFromArray, makeBuilder, makeData, makeTable, - vectorFromArray, } from "apache-arrow"; import { Buffers } from "apache-arrow/data"; import { type EmbeddingFunction } from "./embedding/embedding_function"; @@ -186,6 +186,21 @@ export class VectorColumnOptions { } } +// biome-ignore lint/suspicious/noExplicitAny: skip +function vectorFromArray(data: any, type?: DataType) { + // Workaround for: https://github.com/apache/arrow/issues/45862 + // If FSL type with float + if (DataType.isFixedSizeList(type) && DataType.isFloat(type.valueType)) { + const extendedData = [...data, new Array(type.listSize).fill(0.0)]; + const array = badVectorFromArray(extendedData, type); + return array.slice(0, data.length); + } else if (type === undefined) { + return badVectorFromArray(data); + } else { + return badVectorFromArray(data, type); + } +} + /** Options to control the makeArrowTable call. */ export class MakeArrowTableOptions { /*