sunchao commented on code in PR #5603:
URL: https://github.com/apache/datafusion-comet/pull/5603#discussion_r3901211316


##########
spark/src/main/scala/org/apache/comet/vector/NativeUtil.scala:
##########
@@ -322,6 +333,149 @@ class NativeUtil extends AutoCloseable {
 }
 
 object NativeUtil {
+
+  /**
+   * Create a vector whose physical struct children remain positional when the 
exported Arrow
+   * schema contains duplicate names. Arrow's default struct factory indexes 
children by name and
+   * collapses such fields.
+   */
+  private[comet] def createVector(field: Field, allocator: BufferAllocator): 
FieldVector = {
+    val runtimeField = fieldForAllocation(field)
+    createPinnedVector(runtimeField, field, allocator)
+  }
+
+  /**
+   * Preserve Arrow's default allocation path unless a duplicate-name struct 
needs positional
+   * runtime children. This is called for every imported column of every 
native batch.
+   */
+  private[comet] def createVectorForImport(
+      field: Field,
+      allocator: BufferAllocator): FieldVector = {
+    val runtimeField = fieldForAllocation(field)
+    if (runtimeField eq field) {
+      field.createVector(allocator).asInstanceOf[FieldVector]
+    } else {
+      createPinnedVector(runtimeField, field, allocator)
+    }
+  }
+
+  private def createPinnedVector(
+      runtimeField: Field,
+      exportField: Field,
+      allocator: BufferAllocator): FieldVector = {
+    exportField.getType match {
+      case _: ArrowType.List | _: ArrowType.LargeList | _: 
ArrowType.FixedSizeList =>
+        val vector = new RenamedListVector(runtimeField, exportField, 
allocator)
+        vector.initializeChildrenFromFields(runtimeField.getChildren)
+        vector
+      case _: ArrowType.Map =>
+        val vector = new RenamedMapVector(runtimeField, exportField, allocator)
+        vector.initializeChildrenFromFields(runtimeField.getChildren)
+        vector
+      case _: ArrowType.Struct =>
+        val vector = new RenamedStructVector(runtimeField, exportField, 
allocator)
+        // The Field-based StructVector constructor creates the direct 
children. Initialize each
+        // child's descendants from the runtime schema without adding the 
direct children twice.
+        val runtimeChildren = runtimeField.getChildren
+        var ordinal = 0
+        while (ordinal < runtimeChildren.size()) {
+          vector
+            .getChildByOrdinal(ordinal)
+            .asInstanceOf[FieldVector]
+            
.initializeChildrenFromFields(runtimeChildren.get(ordinal).getChildren)

Review Comment:
   [P2] Preserve case-distinct direct children before the ordinal loop
   
   Could this also materialize every direct child for case-distinct names such 
as `a INT` and `A INT`? An ordinary nonconstant `from_json` result with that 
explicit `StructType` reaches this allocator when the dispatcher is enabled and 
the native JSON opt-in is off. `fieldForAllocation` leaves these names 
unchanged, but Arrow 18.3.0's Field-based `StructVector` constructor creates a 
`NullableStructWriter` whose name cache lowercases them. The second same-type 
field reuses the first writer without creating another vector. Consequently, 
`getChildByOrdinal(1)` is null and this call fails before row processing.
   
   BASE's explicit root-child initialization installed both children under its 
default replacement policy. Please preserve both physical children here and add 
a same-type, case-distinct regression through the ordinary dispatcher. Simply 
repeating the old initialization under the new conflict-error policy is not 
sufficient. This is a source-derived failure prediction, not an executed 
reproduction.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to