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.git


The following commit(s) were added to refs/heads/main by this push:
     new 84f6edef69 GH-40999: [Java] Fix AIOOBE trying to splitAndTransfer DUV 
within nullable struct  (#41000)
84f6edef69 is described below

commit 84f6edef697fd0fa0f5fce252c017a31e4ba3944
Author: James Henderson <[email protected]>
AuthorDate: Mon Apr 8 00:34:27 2024 +0100

    GH-40999: [Java] Fix AIOOBE trying to splitAndTransfer DUV within nullable 
struct  (#41000)
    
    We add a `typeId >= 0` guard to `DUV.TransferImpl.splitAndTransfer` to fix 
#40999.
    
    ### Are these changes tested?
    
    Yes
    
    ### Are there any user-facing changes?
    
    No
    * GitHub Issue: #40999
    
    Authored-by: James Henderson <[email protected]>
    Signed-off-by: David Li <[email protected]>
---
 .../main/codegen/templates/DenseUnionVector.java   | 10 ++++----
 .../apache/arrow/vector/TestDenseUnionVector.java  | 28 ++++++++++++++++++++++
 2 files changed, 34 insertions(+), 4 deletions(-)

diff --git a/java/vector/src/main/codegen/templates/DenseUnionVector.java 
b/java/vector/src/main/codegen/templates/DenseUnionVector.java
index 27fd8e9798..42e96f7aca 100644
--- a/java/vector/src/main/codegen/templates/DenseUnionVector.java
+++ b/java/vector/src/main/codegen/templates/DenseUnionVector.java
@@ -676,10 +676,12 @@ public class DenseUnionVector extends 
AbstractContainerVector implements FieldVe
 
       for (int i = startIndex; i < startIndex + length; i++) {
         byte typeId = typeBuffer.getByte(i);
-        to.offsetBuffer.setInt((long) (i - startIndex) * OFFSET_WIDTH, 
typeCounts[typeId]);
-        typeCounts[typeId] += 1;
-        if (typeStarts[typeId] == -1) {
-          typeStarts[typeId] = offsetBuffer.getInt((long) i * OFFSET_WIDTH);
+        if (typeId >= 0) {
+          to.offsetBuffer.setInt((long) (i - startIndex) * OFFSET_WIDTH, 
typeCounts[typeId]);
+          typeCounts[typeId] += 1;
+          if (typeStarts[typeId] == -1) {
+            typeStarts[typeId] = offsetBuffer.getInt((long) i * OFFSET_WIDTH);
+          }
         }
       }
 
diff --git 
a/java/vector/src/test/java/org/apache/arrow/vector/TestDenseUnionVector.java 
b/java/vector/src/test/java/org/apache/arrow/vector/TestDenseUnionVector.java
index 2c29861561..0621fd4527 100644
--- 
a/java/vector/src/test/java/org/apache/arrow/vector/TestDenseUnionVector.java
+++ 
b/java/vector/src/test/java/org/apache/arrow/vector/TestDenseUnionVector.java
@@ -363,6 +363,34 @@ public class TestDenseUnionVector {
     }
   }
 
+  @Test
+  public void testSplitAndTransferDuvInStruct() {
+    try (StructVector struct = StructVector.empty("struct", allocator)) {
+      DenseUnionVector duv = struct.addOrGet("duv",
+          FieldType.notNullable(MinorType.DENSEUNION.getType()),
+          DenseUnionVector.class);
+      byte i32TypeId = duv.registerNewTypeId(Field.notNullable("i32", 
MinorType.INT.getType()));
+      duv.addVector(i32TypeId, new IntVector("i32", allocator));
+
+      struct.setIndexDefined(0);
+      duv.setTypeId(0, i32TypeId);
+      duv.setSafe(0, newIntHolder(42));
+
+      struct.setNull(1);
+      struct.setValueCount(2);
+
+      try (StructVector dest = StructVector.empty("dest", allocator)) {
+        TransferPair pair = struct.makeTransferPair(dest);
+        pair.splitAndTransfer(0, 2);
+
+        assertEquals(2, dest.getValueCount());
+        assertFalse(dest.isNull(0));
+        assertEquals(42, dest.getObject(0).get("duv"));
+        assertTrue(dest.isNull(1));
+      }
+    }
+  }
+
   @Test
   public void testGetFieldTypeInfo() throws Exception {
     Map<String, String> metadata = new HashMap<>();

Reply via email to