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 ea9de8320e..25ef7dec16 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,8 @@ public final int getTotalValueLengthUpToIndex(int index) { } 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 baf5e672c8..fcf9636328 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,26 @@ public void testSizeOfViewBufferElements() { } } + @ParameterizedTest + @MethodSource({"vectorCreatorProvider"}) + public void testSetSafeEmptyValueAtViewBufferBoundary( + Function 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)); + } + } + @Test public void testNullableVarType1() {