diff --git a/nodejs/__test__/arrow.test.ts b/nodejs/__test__/arrow.test.ts index 9e2ef66f..26b1fdbf 100644 --- a/nodejs/__test__/arrow.test.ts +++ b/nodejs/__test__/arrow.test.ts @@ -1008,5 +1008,34 @@ describe.each([arrow15, arrow16, arrow17, arrow18])( expect(result).toEqual(null); }); }); + + describe("boolean null handling", function () { + it("should handle null values in nullable boolean fields", () => { + const { makeArrowTable } = require("../lancedb/arrow"); + const schema = new Schema([new Field("test", new arrow.Bool(), true)]); + + // Test with all null values + const data = [{ test: null }]; + const table = makeArrowTable(data, { schema }); + + expect(table.numRows).toBe(1); + expect(table.schema.names).toEqual(["test"]); + expect(table.getChild("test")!.get(0)).toBeNull(); + }); + + it("should handle mixed null and non-null boolean values", () => { + const { makeArrowTable } = require("../lancedb/arrow"); + const schema = new Schema([new Field("test", new Bool(), true)]); + + // Test with mixed values + const data = [{ test: true }, { test: null }, { test: false }]; + const table = makeArrowTable(data, { schema }); + + expect(table.numRows).toBe(3); + expect(table.getChild("test")!.get(0)).toBe(true); + expect(table.getChild("test")!.get(1)).toBeNull(); + expect(table.getChild("test")!.get(2)).toBe(false); + }); + }); }, ); diff --git a/nodejs/lancedb/arrow.ts b/nodejs/lancedb/arrow.ts index 52a892ff..306926b8 100644 --- a/nodejs/lancedb/arrow.ts +++ b/nodejs/lancedb/arrow.ts @@ -755,6 +755,20 @@ function makeVector( // biome-ignore lint/suspicious/noExplicitAny: skip ): Vector { if (type !== undefined) { + // workaround for: https://github.com/apache/arrow-js/issues/68 + if (DataType.isBool(type)) { + const hasNonNullValue = values.some((v) => v !== null && v !== undefined); + if (!hasNonNullValue) { + const nullBitmap = new Uint8Array(Math.ceil(values.length / 8)); + const data = makeData({ + type: type, + length: values.length, + nullCount: values.length, + nullBitmap, + }); + return arrowMakeVector(data); + } + } // No need for inference, let Arrow create it if (type instanceof Int) { if (DataType.isInt(type) && type.bitWidth === 64) {