This is an automated email from the ASF dual-hosted git repository.
lidavidm 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 c85a554d5 GH-1190: Reserve view slots for empty view vector values
(#1192)
c85a554d5 is described below
commit c85a554d5b9e4e5c08b4703e5d41de5352bcda7c
Author: Goutam Adwant <[email protected]>
AuthorDate: Tue Aug 25 18:27:11 2026 -0700
GH-1190: Reserve view slots for empty view vector values (#1192)
## What's Changed
Fixes `BaseVariableWidthViewVector.handleSafe` so `setSafe` reserves a
full 16-byte view slot for the target index even when the value length
is zero.
Closes #1190.
---
.../arrow/vector/BaseVariableWidthViewVector.java | 4 +-
.../arrow/vector/TestVariableWidthViewVector.java | 54 ++++++++++++++++++++++
2 files changed, 57 insertions(+), 1 deletion(-)
diff --git
a/vector/src/main/java/org/apache/arrow/vector/BaseVariableWidthViewVector.java
b/vector/src/main/java/org/apache/arrow/vector/BaseVariableWidthViewVector.java
index ea9de8320..8d2a2d740 100644
---
a/vector/src/main/java/org/apache/arrow/vector/BaseVariableWidthViewVector.java
+++
b/vector/src/main/java/org/apache/arrow/vector/BaseVariableWidthViewVector.java
@@ -1405,7 +1405,9 @@ public abstract class BaseVariableWidthViewVector extends
BaseValueVector
}
protected final void handleSafe(int index, int dataLength) {
- final long targetCapacity = roundUpToMultipleOf16((long) index *
ELEMENT_SIZE + dataLength);
+ // The view buffer stores one fixed-width view per value; payload bytes
are allocated
+ // separately.
+ final long targetCapacity = roundUpToMultipleOf16(((long) index + 1) *
ELEMENT_SIZE);
if (viewBuffer.capacity() < targetCapacity) {
reallocViewBuffer(targetCapacity);
}
diff --git
a/vector/src/test/java/org/apache/arrow/vector/TestVariableWidthViewVector.java
b/vector/src/test/java/org/apache/arrow/vector/TestVariableWidthViewVector.java
index baf5e672c..c4a1ae9b6 100644
---
a/vector/src/test/java/org/apache/arrow/vector/TestVariableWidthViewVector.java
+++
b/vector/src/test/java/org/apache/arrow/vector/TestVariableWidthViewVector.java
@@ -540,6 +540,60 @@ public class TestVariableWidthViewVector {
}
}
+ @ParameterizedTest
+ @MethodSource({"vectorCreatorProvider"})
+ public void testSetSafeEmptyValueAtViewBufferBoundary(
+ Function<BufferAllocator, BaseVariableWidthViewVector> vectorCreator) {
+ try (final BaseVariableWidthViewVector vector =
vectorCreator.apply(allocator)) {
+ final byte[] emptyValue = new byte[0];
+ vector.allocateNew();
+ final int valueCapacity = vector.getValueCapacity();
+
+ for (int i = 0; i <= valueCapacity; i++) {
+ vector.setSafe(i, emptyValue);
+ }
+
+ vector.setValueCount(valueCapacity + 1);
+ assertTrue(vector.getValueCapacity() > valueCapacity);
+ assertEquals(0, vector.getValueLength(valueCapacity));
+ assertArrayEquals(emptyValue, vector.get(valueCapacity));
+ }
+ }
+
+ @ParameterizedTest
+ @MethodSource({"vectorCreatorProvider"})
+ public void testSetValueCountFillsEmptiesAtViewBufferBoundary(
+ Function<BufferAllocator, BaseVariableWidthViewVector> vectorCreator) {
+ try (final BaseVariableWidthViewVector vector =
vectorCreator.apply(allocator)) {
+ vector.allocateNew();
+ final int valueCapacity = vector.getValueCapacity();
+
+ vector.setSafe(valueCapacity - 1, "x".getBytes(StandardCharsets.UTF_8));
+ vector.setValueCount(valueCapacity + 1);
+
+ assertTrue(vector.getValueCapacity() > valueCapacity);
+ assertTrue(vector.isNull(valueCapacity));
+ }
+ }
+
+ @ParameterizedTest
+ @MethodSource({"vectorCreatorProvider"})
+ public void testSetNullAtViewBufferBoundary(
+ Function<BufferAllocator, BaseVariableWidthViewVector> vectorCreator) {
+ try (final BaseVariableWidthViewVector vector =
vectorCreator.apply(allocator)) {
+ vector.allocateNew();
+ final int valueCapacity = vector.getValueCapacity();
+
+ for (int i = 0; i <= valueCapacity; i++) {
+ vector.setNull(i);
+ }
+ vector.setValueCount(valueCapacity + 1);
+
+ assertTrue(vector.getValueCapacity() > valueCapacity);
+ assertTrue(vector.isNull(valueCapacity));
+ }
+ }
+
@Test
public void testNullableVarType1() {