This is an automated email from the ASF dual-hosted git repository.
kou pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-js.git
The following commit(s) were added to refs/heads/main by this push:
new 19d9de3 fix: Pass explicit length in Struct makeData calls (#404)
19d9de3 is described below
commit 19d9de3d925e76a4df7a02f5c92d2f15ee240db0
Author: Rusty Conover <[email protected]>
AuthorDate: Thu Mar 12 02:54:17 2026 -0400
fix: Pass explicit length in Struct makeData calls (#404)
## Summary
- Pass `length: data.length` in `setChildAt` to preserve the batch's row
count when constructing Struct data
- Pass `length: 0` explicitly in `_InternalEmptyPlaceholderRecordBatch`
instead of relying on reduce-over-children fallback
- Add tests for Struct `makeData` with empty children and `setChildAt`
row count preservation
Closes #403
## Test plan
- [x] `makeData` with empty children preserves explicit length
- [x] `makeData` with empty children and no length defaults to 0
- [x] `setChildAt` preserves `numRows` after column replacement
- [x] Full test suite passes (`yarn test -t src`)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Opus 4.6 <[email protected]>
---
src/recordbatch.ts | 4 +-
test/unit/data/struct-zero-children-tests.ts | 55 ++++++++++++++++++++++++++++
2 files changed, 57 insertions(+), 2 deletions(-)
diff --git a/src/recordbatch.ts b/src/recordbatch.ts
index 7c876dc..f70c69f 100644
--- a/src/recordbatch.ts
+++ b/src/recordbatch.ts
@@ -261,7 +261,7 @@ export class RecordBatch<T extends TypeMap = any> {
const field = fields[index].clone({ type: child.type });
[fields[index], children[index]] = [field, child.data[0]];
schema = new Schema(fields, new Map(this.schema.metadata));
- data = makeData({ type: new Struct<T>(fields), children });
+ data = makeData({ type: new Struct<T>(fields), length:
data.length, children });
}
return new RecordBatch(schema, data, this._metadata);
}
@@ -380,7 +380,7 @@ function collectDictionaries(fields: Field[], children:
readonly Data[], diction
export class _InternalEmptyPlaceholderRecordBatch<T extends TypeMap = any>
extends RecordBatch<T> {
constructor(schema: Schema<T>, metadata?: Map<string, string>) {
const children = schema.fields.map((f) => makeData({ type: f.type }));
- const data = makeData({ type: new Struct<T>(schema.fields), nullCount:
0, children });
+ const data = makeData({ type: new Struct<T>(schema.fields), length: 0,
nullCount: 0, children });
super(schema, data, metadata || new Map());
}
}
diff --git a/test/unit/data/struct-zero-children-tests.ts
b/test/unit/data/struct-zero-children-tests.ts
new file mode 100644
index 0000000..353034a
--- /dev/null
+++ b/test/unit/data/struct-zero-children-tests.ts
@@ -0,0 +1,55 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+import '../../jest-extensions.js';
+
+import {
+ makeData, makeVector,
+ Schema, Field, RecordBatch,
+ Struct, Int32
+} from 'apache-arrow';
+
+describe('Struct with zero children', () => {
+
+ test('makeData with empty children preserves explicit length', () => {
+ const data = makeData({ type: new Struct([]), length: 50, nullCount:
0, children: [] });
+ expect(data).toHaveLength(50);
+ });
+
+ test('makeData with empty children and no length defaults to 0', () => {
+ const data = makeData({ type: new Struct([]), children: [] });
+ expect(data).toHaveLength(0);
+ });
+
+ test('setChildAt preserves numRows after column replacement', () => {
+ const field = Field.new({ name: 'a', type: new Int32, nullable: true
});
+ const schema = new Schema([field]);
+ const childData = makeData({ type: new Int32, length: 10, nullCount: 0
});
+ const structData = makeData({
+ type: new Struct(schema.fields),
+ length: 10,
+ nullCount: 0,
+ children: [childData]
+ });
+ const batch = new RecordBatch(schema, structData);
+ expect(batch.numRows).toBe(10);
+
+ const newChild = makeVector(new Int32Array([1, 2, 3, 4, 5, 6, 7, 8, 9,
10]));
+ const newBatch = batch.setChildAt(0, newChild);
+ expect(newBatch.numRows).toBe(10);
+ });
+});