Skip to content

Commit e0fd370

Browse files
committed
ARROW-15382: [Java] fix SplitAndTransfer throws for (0,0) if vector empty
1 parent 443d095 commit e0fd370

5 files changed

Lines changed: 67 additions & 30 deletions

File tree

java/vector/src/main/java/org/apache/arrow/vector/BaseLargeVariableWidthVector.java

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -701,16 +701,14 @@ public void transferTo(BaseLargeVariableWidthVector target) {
701701
*/
702702
public void splitAndTransferTo(int startIndex, int length,
703703
BaseLargeVariableWidthVector target) {
704-
Preconditions.checkArgument(startIndex >= 0 && startIndex < valueCount,
705-
"Invalid startIndex: %s", startIndex);
706-
Preconditions.checkArgument(startIndex + length <= valueCount,
707-
"Invalid length: %s", length);
704+
Preconditions.checkArgument(startIndex >= 0 && length >= 0 && startIndex + length <= valueCount,
705+
"Invalid parameters startIndex: %s, length: %s for valueCount: %s", startIndex, length, valueCount);
708706
compareTypes(target, "splitAndTransferTo");
709707
target.clear();
710-
splitAndTransferValidityBuffer(startIndex, length, target);
711-
splitAndTransferOffsetBuffer(startIndex, length, target);
712-
target.setLastSet(length - 1);
713708
if (length > 0) {
709+
splitAndTransferValidityBuffer(startIndex, length, target);
710+
splitAndTransferOffsetBuffer(startIndex, length, target);
711+
target.setLastSet(length - 1);
714712
target.setValueCount(length);
715713
}
716714
}

java/vector/src/main/java/org/apache/arrow/vector/BaseVariableWidthVector.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -725,10 +725,10 @@ public void splitAndTransferTo(int startIndex, int length,
725725
"Invalid parameters startIndex: %s, length: %s for valueCount: %s", startIndex, length, valueCount);
726726
compareTypes(target, "splitAndTransferTo");
727727
target.clear();
728-
splitAndTransferValidityBuffer(startIndex, length, target);
729-
splitAndTransferOffsetBuffer(startIndex, length, target);
730-
target.setLastSet(length - 1);
731728
if (length > 0) {
729+
splitAndTransferValidityBuffer(startIndex, length, target);
730+
splitAndTransferOffsetBuffer(startIndex, length, target);
731+
target.setLastSet(length - 1);
732732
target.setValueCount(length);
733733
}
734734
}

java/vector/src/main/java/org/apache/arrow/vector/complex/ListVector.java

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -481,21 +481,23 @@ public void transfer() {
481481
public void splitAndTransfer(int startIndex, int length) {
482482
Preconditions.checkArgument(startIndex >= 0 && length >= 0 && startIndex + length <= valueCount,
483483
"Invalid parameters startIndex: %s, length: %s for valueCount: %s", startIndex, length, valueCount);
484-
final int startPoint = offsetBuffer.getInt(startIndex * OFFSET_WIDTH);
485-
final int sliceLength = offsetBuffer.getInt((startIndex + length) * OFFSET_WIDTH) - startPoint;
486484
to.clear();
487-
to.allocateOffsetBuffer((length + 1) * OFFSET_WIDTH);
488-
/* splitAndTransfer offset buffer */
489-
for (int i = 0; i < length + 1; i++) {
490-
final int relativeOffset = offsetBuffer.getInt((startIndex + i) * OFFSET_WIDTH) - startPoint;
491-
to.offsetBuffer.setInt(i * OFFSET_WIDTH, relativeOffset);
485+
if (length > 0) {
486+
final int startPoint = offsetBuffer.getInt(startIndex * OFFSET_WIDTH);
487+
final int sliceLength = offsetBuffer.getInt((startIndex + length) * OFFSET_WIDTH) - startPoint;
488+
to.allocateOffsetBuffer((length + 1) * OFFSET_WIDTH);
489+
/* splitAndTransfer offset buffer */
490+
for (int i = 0; i < length + 1; i++) {
491+
final int relativeOffset = offsetBuffer.getInt((startIndex + i) * OFFSET_WIDTH) - startPoint;
492+
to.offsetBuffer.setInt(i * OFFSET_WIDTH, relativeOffset);
493+
}
494+
/* splitAndTransfer validity buffer */
495+
splitAndTransferValidityBuffer(startIndex, length, to);
496+
/* splitAndTransfer data buffer */
497+
dataTransferPair.splitAndTransfer(startPoint, sliceLength);
498+
to.lastSet = length - 1;
499+
to.setValueCount(length);
492500
}
493-
/* splitAndTransfer validity buffer */
494-
splitAndTransferValidityBuffer(startIndex, length, to);
495-
/* splitAndTransfer data buffer */
496-
dataTransferPair.splitAndTransfer(startPoint, sliceLength);
497-
to.lastSet = length - 1;
498-
to.setValueCount(length);
499501
}
500502

501503
/*

java/vector/src/test/java/org/apache/arrow/vector/TestLargeVarCharVector.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ public void testInvalidStartIndex() {
163163
IllegalArgumentException.class,
164164
() -> tp.splitAndTransfer(valueCount, 10));
165165

166-
assertEquals("Invalid startIndex: 500", e.getMessage());
166+
assertEquals("Invalid parameters startIndex: 500, length: 10 for valueCount: 500", e.getMessage());
167167
}
168168
}
169169

@@ -182,7 +182,7 @@ public void testInvalidLength() {
182182
IllegalArgumentException.class,
183183
() -> tp.splitAndTransfer(0, valueCount * 2));
184184

185-
assertEquals("Invalid length: 1000", e.getMessage());
185+
assertEquals("Invalid parameters startIndex: 0, length: 1000 for valueCount: 500", e.getMessage());
186186
}
187187
}
188188

java/vector/src/test/java/org/apache/arrow/vector/TestSplitAndTransfer.java

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public class TestSplitAndTransfer {
4646
public void init() {
4747
allocator = new RootAllocator(Long.MAX_VALUE);
4848
}
49-
49+
5050
@After
5151
public void terminate() throws Exception {
5252
allocator.close();
@@ -62,21 +62,58 @@ private void populateVarcharVector(final VarCharVector vector, int valueCount, S
6262
}
6363
vector.setValueCount(valueCount);
6464
}
65-
65+
66+
@Test
67+
public void testWithEmptyVector() {
68+
// MapVector use TransferImpl from ListVector
69+
ListVector listVector = ListVector.empty("", allocator);
70+
TransferPair transferPair = listVector.getTransferPair(allocator);
71+
transferPair.splitAndTransfer(0, 0);
72+
assertEquals(0, transferPair.getTo().getValueCount());
73+
// BaseFixedWidthVector
74+
IntVector intVector = new IntVector("", allocator);
75+
transferPair = intVector.getTransferPair(allocator);
76+
transferPair.splitAndTransfer(0, 0);
77+
assertEquals(0, transferPair.getTo().getValueCount());
78+
// BaseVariableWidthVector
79+
VarCharVector varCharVector = new VarCharVector("", allocator);
80+
transferPair = varCharVector.getTransferPair(allocator);
81+
transferPair.splitAndTransfer(0, 0);
82+
assertEquals(0, transferPair.getTo().getValueCount());
83+
// BaseLargeVariableWidthVector
84+
LargeVarCharVector largeVarCharVector = new LargeVarCharVector("", allocator);
85+
transferPair = largeVarCharVector.getTransferPair(allocator);
86+
transferPair.splitAndTransfer(0, 0);
87+
assertEquals(0, transferPair.getTo().getValueCount());
88+
89+
StructVector structVector = StructVector.empty("", allocator);
90+
transferPair = structVector.getTransferPair(allocator);
91+
transferPair.splitAndTransfer(0, 0);
92+
assertEquals(0, transferPair.getTo().getValueCount());
93+
FixedSizeListVector fixedSizeListVector = FixedSizeListVector.empty("", 0, allocator);
94+
transferPair = fixedSizeListVector.getTransferPair(allocator);
95+
transferPair.splitAndTransfer(0, 0);
96+
assertEquals(0, transferPair.getTo().getValueCount());
97+
FixedSizeBinaryVector fixedSizeBinaryVector = new FixedSizeBinaryVector("", allocator, 4);
98+
transferPair = fixedSizeBinaryVector.getTransferPair(allocator);
99+
transferPair.splitAndTransfer(0, 0);
100+
assertEquals(0, transferPair.getTo().getValueCount());
101+
}
102+
66103
@Test /* VarCharVector */
67104
public void test() throws Exception {
68105
try (final VarCharVector varCharVector = new VarCharVector("myvector", allocator)) {
69106
varCharVector.allocateNew(10000, 1000);
70107

71108
final int valueCount = 500;
72109
final String[] compareArray = new String[valueCount];
73-
110+
74111
populateVarcharVector(varCharVector, valueCount, compareArray);
75-
112+
76113
final TransferPair tp = varCharVector.getTransferPair(allocator);
77114
final VarCharVector newVarCharVector = (VarCharVector) tp.getTo();
78115
final int[][] startLengths = {{0, 201}, {201, 0}, {201, 200}, {401, 99}};
79-
116+
80117
for (final int[] startLength : startLengths) {
81118
final int start = startLength[0];
82119
final int length = startLength[1];

0 commit comments

Comments
 (0)