Skip to content

Commit

Permalink
Add test with null bitmap
Browse files Browse the repository at this point in the history
  • Loading branch information
kylebarron committed Oct 31, 2023
1 parent 4d3d5d5 commit 5d55874
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 1 deletion.
41 changes: 40 additions & 1 deletion tests/ffi.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@ import { readFileSync } from "fs";
import { describe, it, expect } from "vitest";
import * as arrow from "apache-arrow";
import * as wasm from "rust-arrow-ffi";
import { arrowTableToFFI, arraysEqual, loadIPCTableFromDisk } from "./utils";
import {
arrowTableToFFI,
arraysEqual,
loadIPCTableFromDisk,
validityEqual,
} from "./utils";
import { parseField, parseVector } from "../src";
import { Type } from "../src/types";

Expand Down Expand Up @@ -622,3 +627,37 @@ describe("date32", (t) => {
// expect(originalVector.get(i), wasmVector.get(i));
// }
// });

describe("nullable int", (t) => {
function test(copy: boolean) {
let columnIndex = TEST_TABLE.schema.fields.findIndex(
(field) => field.name == "nullable_int"
);

const originalField = TEST_TABLE.schema.fields[columnIndex];
// declare it's not null
const originalVector = TEST_TABLE.getChildAt(columnIndex) as arrow.Vector;
const fieldPtr = FFI_TABLE.schemaAddr(columnIndex);
const field = parseField(WASM_MEMORY.buffer, fieldPtr);

expect(field.name).toStrictEqual(originalField.name);
expect(field.typeId).toStrictEqual(originalField.typeId);
expect(field.nullable).toStrictEqual(originalField.nullable);

const arrayPtr = FFI_TABLE.arrayAddr(0, columnIndex);
const wasmVector = parseVector(
WASM_MEMORY.buffer,
arrayPtr,
field.type,
copy
);

expect(
validityEqual(originalVector, wasmVector),
"validity should be equal"
).toBeTruthy();
}

it("copy=false", () => test(false));
it("copy=true", () => test(true));
});
10 changes: 10 additions & 0 deletions tests/pyarrow_generate_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,15 @@ def timestamp_array() -> pa.Array:
return arr


def nullable_int() -> pa.Array:
# True means null
mask = [True, False, True]
arr = pa.array([1, 2, 3], type=pa.uint8(), mask=mask)
assert isinstance(arr, pa.UInt8Array)
assert not arr[0].is_valid
return arr


class MyExtensionType(pa.ExtensionType):
"""
Refer to https://arrow.apache.org/docs/python/extending_types.html for
Expand Down Expand Up @@ -160,6 +169,7 @@ def table() -> pa.Table:
"date32": date32_array(),
"date64": date64_array(),
"timestamp": timestamp_array(),
"nullable_int": nullable_int(),
}
)

Expand Down
Binary file modified tests/table.arrow
Binary file not shown.
29 changes: 29 additions & 0 deletions tests/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,32 @@ export function arraysEqual<T>(

return true;
}

export function validityEqual(v1: arrow.Vector, v2: arrow.Vector): boolean {
if (v1.length !== v2.length) {
return false;
}

if (v1.data.length !== v2.data.length) {
console.log("todo: support different data lengths");
return false;
}
for (let i = 0; i < v1.data.length; i++) {
const d1 = v1.data[i];
const d2 = v2.data[i];
// Check that null bitmaps have same length
if (d1 !== null && d2 !== null) {
if (d1.nullBitmap.length !== d2.nullBitmap.length) {
return false;
}
}
}

for (let i = 0; i < v1.length; i++) {
if (v1.isValid(i) !== v2.isValid(i)) {
return false;
}
}

return true;
}

0 comments on commit 5d55874

Please sign in to comment.