This is an automated email from the ASF dual-hosted git repository.
brycemecum pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow.git
The following commit(s) were added to refs/heads/main by this push:
new 25d5c055ce GH-45862: [JS] Fix FixedSizeListBuilder behavior for null
slots (#45889)
25d5c055ce is described below
commit 25d5c055ceb55aaad12446da7e65bfec3530d6b3
Author: Bryce Mecum <[email protected]>
AuthorDate: Tue Mar 25 06:04:17 2025 -0700
GH-45862: [JS] Fix FixedSizeListBuilder behavior for null slots (#45889)
### Rationale for this change
`vectorFromArray` could produce an incorrect result when used on a
`FixedSizeList<T>` with one or more null slots in trailing positions.
### What changes are included in this PR?
Fixed behavior of the FixedSizeListBuilder.
### Are these changes tested?
Yes. This PR includes specific test cases to cover this bug fix.
### Are there any user-facing changes?
No.
* GitHub Issue: #45862
Lead-authored-by: Bryce Mecum <[email protected]>
Co-authored-by: Paul Taylor <[email protected]>
Signed-off-by: Bryce Mecum <[email protected]>
---
js/src/builder/fixedsizelist.ts | 8 +++++++-
js/test/unit/vector/vector-tests.ts | 39 ++++++++++++++++++++++++++++++++++++-
2 files changed, 45 insertions(+), 2 deletions(-)
diff --git a/js/src/builder/fixedsizelist.ts b/js/src/builder/fixedsizelist.ts
index f4b4b95df2..95df0ce901 100644
--- a/js/src/builder/fixedsizelist.ts
+++ b/js/src/builder/fixedsizelist.ts
@@ -24,10 +24,16 @@ export class FixedSizeListBuilder<T extends DataType = any,
TNull = any> extends
public setValue(index: number, value: T['TValue']) {
const [child] = this.children;
const start = index * this.stride;
- for (let i = -1, n = value.length; ++i < n;) {
+ for (let i = -1, n = this.stride; ++i < n;) {
child.set(start + i, value[i]);
}
}
+ public setValid(index: number, valid: boolean) {
+ if (!super.setValid(index, valid)) {
+ this.children[0].setValid((index + 1) * this.stride - 1, false);
+ }
+ return valid;
+ }
public addChild(child: Builder<T>, name = '0') {
if (this.numChildren > 0) {
throw new Error('FixedSizeListBuilder can only have one child.');
diff --git a/js/test/unit/vector/vector-tests.ts
b/js/test/unit/vector/vector-tests.ts
index c05838d7a9..9dadaf7c63 100644
--- a/js/test/unit/vector/vector-tests.ts
+++ b/js/test/unit/vector/vector-tests.ts
@@ -16,7 +16,7 @@
// under the License.
import {
- Bool, DateDay, DateMillisecond, Dictionary, Float64, Int32, List,
makeVector, Struct, Utf8, LargeUtf8, util, Vector, vectorFromArray, makeData
+ Bool, DateDay, DateMillisecond, Dictionary, Float64, Int32, List,
makeVector, Struct, Utf8, LargeUtf8, util, Vector, vectorFromArray, makeData,
FixedSizeList, Field,
} from 'apache-arrow';
describe(`makeVectorFromArray`, () => {
@@ -323,3 +323,40 @@ function basicVectorTests(vector: Vector, values: any[],
extras: any[]) {
}
});
}
+
+// GH-45862: Make sure vectorFromArray produces the correct result for
+// FixedSizeList with null slots
+describe(`vecorFromArray() with FixedSizeList<T> and null slots`, () => {
+ test(`correct child length with null slot first`, () => {
+ let vector = vectorFromArray(
+ [null, [1, 2, 3]],
+ new FixedSizeList(3, new Field('item', new Int32())),
+ );
+ let child = vector.getChildAt(0);
+
+ expect(child).toHaveLength(6);
+ expect(child?.nullCount).toBe(3);
+ });
+
+ test(`correct child length with null slot last`, () => {
+ let vector = vectorFromArray(
+ [[1, 2, 3], null],
+ new FixedSizeList(3, new Field('item', new Int32())),
+ );
+ let child = vector.getChildAt(0);
+
+ expect(child).toHaveLength(6);
+ expect(child?.nullCount).toBe(3);
+ });
+
+ test(`correct child length with null in the middle`, () => {
+ let vector = vectorFromArray(
+ [[1, 2, 3], null, [7, 8, 9]],
+ new FixedSizeList(3, new Field('item', new Int32())),
+ );
+ let child = vector.getChildAt(0);
+
+ expect(child).toHaveLength(9);
+ expect(child?.nullCount).toBe(3);
+ });
+});