This is an automated email from the ASF dual-hosted git repository.
jbonofre pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-java.git
The following commit(s) were added to refs/heads/main by this push:
new f804f9074 GH-812: Fix appending to an empty UnionVector (#1292)
f804f9074 is described below
commit f804f90748345cb0d19d16c31c81d8c9ac5f21ad
Author: hutiefang76 <[email protected]>
AuthorDate: Sun Oct 4 23:05:53 2026 +0800
GH-812: Fix appending to an empty UnionVector (#1292)
## What's Changed
Appending to a newly created `UnionVector` repeatedly reallocates its
type buffer until allocation fails: its value capacity remains zero
until it has child vectors. Check the type buffer capacity at this
stage, since the existing append loop creates and expands the child
vectors afterward.
The regression appends two floats to an empty union with a bounded
allocator. It fails before the change with an allocation error and
passes afterward. All 32 `TestVectorAppender` tests pass with both the
Netty and Unsafe allocators on JDK 21. Checkstyle and Spotless also
pass.
Closes #812.
Validation (JDK 21):
```sh
mvn -B -pl vector -am test -Dtest=TestVectorAppender
-Dsurefire.failIfNoSpecifiedTests=false
mvn -B -pl vector spotless:check
```
Developed with AI assistance; the regression was verified to fail before
the fix and pass afterward.
---
.../org/apache/arrow/vector/util/VectorAppender.java | 3 +--
.../apache/arrow/vector/util/TestVectorAppender.java | 20 ++++++++++++++++++++
2 files changed, 21 insertions(+), 2 deletions(-)
diff --git
a/vector/src/main/java/org/apache/arrow/vector/util/VectorAppender.java
b/vector/src/main/java/org/apache/arrow/vector/util/VectorAppender.java
index 2cfeb0a04..7176e86c7 100644
--- a/vector/src/main/java/org/apache/arrow/vector/util/VectorAppender.java
+++ b/vector/src/main/java/org/apache/arrow/vector/util/VectorAppender.java
@@ -601,8 +601,7 @@ public class VectorAppender implements
VectorVisitor<ValueVector, Void> {
UnionVector targetUnionVector = (UnionVector) targetVector;
int newValueCount = targetVector.getValueCount() +
deltaVector.getValueCount();
- // make sure there is enough capacity
- while (targetUnionVector.getValueCapacity() < newValueCount) {
+ while (targetUnionVector.getTypeBuffer().capacity() /
UnionVector.TYPE_WIDTH < newValueCount) {
targetUnionVector.reAlloc();
}
diff --git
a/vector/src/test/java/org/apache/arrow/vector/util/TestVectorAppender.java
b/vector/src/test/java/org/apache/arrow/vector/util/TestVectorAppender.java
index 9a8143f51..57dd852e3 100644
--- a/vector/src/test/java/org/apache/arrow/vector/util/TestVectorAppender.java
+++ b/vector/src/test/java/org/apache/arrow/vector/util/TestVectorAppender.java
@@ -804,6 +804,26 @@ public class TestVectorAppender {
}
}
+ @Test
+ public void testAppendToEmptyUnionVector() {
+ try (BufferAllocator limitedAllocator = allocator.newChildAllocator("empty
union", 0, 1048576);
+ UnionVector target = UnionVector.empty("target", limitedAllocator);
+ UnionVector delta = UnionVector.empty("delta", limitedAllocator)) {
+ delta.setType(0, Types.MinorType.FLOAT4);
+ delta.setType(1, Types.MinorType.FLOAT4);
+ Float4Vector values = delta.getFloat4Vector();
+ values.allocateNew();
+ ValueVectorDataPopulator.setVector(values, 1f, 2f);
+ delta.setValueCount(2);
+
+ delta.accept(new VectorAppender(target), null);
+
+ assertEquals(2, target.getValueCount());
+ assertEquals(1f, target.getObject(0));
+ assertEquals(2f, target.getObject(1));
+ }
+ }
+
@Test
public void testAppendUnionVector() {
final int length1 = 10;