You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@arrow.apache.org by li...@apache.org on 2022/11/08 17:10:09 UTC

[arrow] branch master updated: ARROW-18209: [Java] Make ComplexCopier agnostic of specific implementation of MapWriter (UnionMapWriter) (#14557)

This is an automated email from the ASF dual-hosted git repository.

lidavidm pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/arrow.git


The following commit(s) were added to refs/heads/master by this push:
     new 8a5aa67182 ARROW-18209: [Java] Make ComplexCopier agnostic of specific implementation of MapWriter (UnionMapWriter) (#14557)
8a5aa67182 is described below

commit 8a5aa6718295eaa3f336125eace4a343a65c922f
Author: kambhamvivekshankar <v_...@yahoo.com>
AuthorDate: Tue Nov 8 22:39:58 2022 +0530

    ARROW-18209: [Java] Make ComplexCopier agnostic of specific implementation of MapWriter (UnionMapWriter) (#14557)
    
    Making ComplexCopier independent of UnionMapWriter lets us use different implementations, like PromotableWriter instead. This helps us to copy map vector with a map value. Otherwise we get the following error: ClassCast class org.apache.arrow.vector.complex.impl.PromotableWriter cannot be cast to class org.apache.arrow.vector.complex.impl.UnionMapWriter
    
    Lead-authored-by: Kambham Vivek Shankar <v_...@yahoo.com>
    Co-authored-by: kambhamvivekshankar <v_...@yahoo.com>
    Signed-off-by: David Li <li...@gmail.com>
---
 .../src/main/codegen/templates/ComplexCopier.java  | 45 ++++++++----
 .../vector/complex/impl/TestComplexCopier.java     | 79 ++++++++++++++++++++++
 2 files changed, 111 insertions(+), 13 deletions(-)

diff --git a/java/vector/src/main/codegen/templates/ComplexCopier.java b/java/vector/src/main/codegen/templates/ComplexCopier.java
index 39a84041e7..1a3ba940e7 100644
--- a/java/vector/src/main/codegen/templates/ComplexCopier.java
+++ b/java/vector/src/main/codegen/templates/ComplexCopier.java
@@ -15,9 +15,7 @@
  * limitations under the License.
  */
 
-import org.apache.arrow.vector.complex.MapVector;
 import org.apache.arrow.vector.complex.impl.UnionMapReader;
-import org.apache.arrow.vector.complex.impl.UnionMapWriter;
 import org.apache.arrow.vector.complex.reader.FieldReader;
 import org.apache.arrow.vector.complex.writer.FieldWriter;
 import org.apache.arrow.vector.types.Types;
@@ -73,23 +71,20 @@ public class ComplexCopier {
         break;
       case MAP:
         if (reader.isSet()) {
-          UnionMapWriter mapWriter = (UnionMapWriter) writer;
           UnionMapReader mapReader = (UnionMapReader) reader;
-
-          mapWriter.startMap();
+          writer.startMap();
           while (mapReader.next()) {
             FieldReader structReader = reader.reader();
-            UnionMapWriter structWriter = (UnionMapWriter) writer.struct();
             if (structReader.isSet()) {
-              mapWriter.startEntry();
-              writeValue(mapReader.key(), getStructWriterForReader(mapReader.key(), structWriter.key(), MapVector.KEY_NAME));
-              writeValue(mapReader.value(), getStructWriterForReader(mapReader.value(), structWriter.value(), MapVector.VALUE_NAME));
-              mapWriter.endEntry();
+              writer.startEntry();
+              writeValue(mapReader.key(), getMapWriterForReader(mapReader.key(), writer.key()));
+              writeValue(mapReader.value(), getMapWriterForReader(mapReader.value(), writer.value()));
+              writer.endEntry();
             } else {
-              structWriter.writeNull();
+              writer.writeNull();
             }
           }
-          mapWriter.endMap();
+          writer.endMap();
         } else {
           writer.writeNull();
         }
@@ -160,8 +155,9 @@ public class ComplexCopier {
       return (FieldWriter) writer.struct(name);
     case FIXED_SIZE_LIST:
     case LIST:
-    case MAP:
       return (FieldWriter) writer.list(name);
+    case MAP:
+      return (FieldWriter) writer.map(name);
     default:
       throw new UnsupportedOperationException(reader.getMinorType().toString());
     }
@@ -188,4 +184,27 @@ public class ComplexCopier {
       throw new UnsupportedOperationException(reader.getMinorType().toString());
     }
   }
+
+  private static FieldWriter getMapWriterForReader(FieldReader reader, MapWriter writer) {
+    switch (reader.getMinorType()) {
+    <#list vv.types as type><#list type.minor as minor><#assign name = minor.class?cap_first />
+    <#assign fields = minor.fields!type.fields />
+    <#assign uncappedName = name?uncap_first/>
+    <#if !minor.typeParams?? || minor.class?starts_with("Decimal") >
+      case ${name?upper_case}:
+      return (FieldWriter) writer.<#if name == "Int">integer<#else>${uncappedName}</#if>();
+    </#if>
+    </#list></#list>
+      case STRUCT:
+        return (FieldWriter) writer.struct();
+      case FIXED_SIZE_LIST:
+      case LIST:
+      case NULL:
+        return (FieldWriter) writer.list();
+      case MAP:
+        return (FieldWriter) writer.map(false);
+      default:
+        throw new UnsupportedOperationException(reader.getMinorType().toString());
+    }
+  }
 }
diff --git a/java/vector/src/test/java/org/apache/arrow/vector/complex/impl/TestComplexCopier.java b/java/vector/src/test/java/org/apache/arrow/vector/complex/impl/TestComplexCopier.java
index f314a98ee3..29f2517033 100644
--- a/java/vector/src/test/java/org/apache/arrow/vector/complex/impl/TestComplexCopier.java
+++ b/java/vector/src/test/java/org/apache/arrow/vector/complex/impl/TestComplexCopier.java
@@ -760,4 +760,83 @@ public class TestComplexCopier {
       assertTrue(VectorEqualsVisitor.vectorEquals(from, to));
     }
   }
+
+  @Test
+  public void testCopyStructOfMap() {
+    try (final StructVector from = StructVector.empty("v", allocator);
+         final StructVector to = StructVector.empty("v", allocator);) {
+
+      from.allocateNew();
+
+      NullableStructWriter structWriter = from.getWriter();
+      for (int i = 0; i < COUNT; i++) {
+        structWriter.setPosition(i);
+        structWriter.start();
+        BaseWriter.MapWriter innerMapWriter = structWriter.map("f1");
+        innerMapWriter.startMap();
+        innerMapWriter.startEntry();
+        innerMapWriter.key().integer().writeInt(i);
+        innerMapWriter.value().integer().writeInt(i);
+        innerMapWriter.endEntry();
+        innerMapWriter.endMap();
+        structWriter.end();
+      }
+
+      from.setValueCount(COUNT);
+
+      // copy values
+      FieldReader in = from.getReader();
+      FieldWriter out = to.getWriter();
+      for (int i = 0; i < COUNT; i++) {
+        in.setPosition(i);
+        out.setPosition(i);
+        ComplexCopier.copy(in, out);
+      }
+      to.setValueCount(COUNT);
+
+      // validate equals
+      assertTrue(VectorEqualsVisitor.vectorEquals(from, to));
+    }
+  }
+
+  @Test
+  public void testCopyMapVectorWithMapValue() {
+    try (final MapVector from = MapVector.empty("v", allocator, false);
+         final MapVector to = MapVector.empty("v", allocator, false)) {
+
+      from.allocateNew();
+
+      UnionMapWriter mapWriter = from.getWriter();
+      for (int i = 0; i < COUNT; i++) {
+        mapWriter.setPosition(i);
+        mapWriter.startMap();
+        mapWriter.startEntry();
+        mapWriter.key().integer().writeInt(i);
+        BaseWriter.MapWriter innerMapWriter = mapWriter.value().map(false);
+        innerMapWriter.startMap();
+        innerMapWriter.startEntry();
+        innerMapWriter.key().integer().writeInt(i);
+        innerMapWriter.value().integer().writeInt(i);
+        innerMapWriter.endEntry();
+        innerMapWriter.endMap();
+        mapWriter.endEntry();
+        mapWriter.endMap();
+      }
+
+      from.setValueCount(COUNT);
+
+      // copy values
+      FieldReader in = from.getReader();
+      FieldWriter out = to.getWriter();
+      for (int i = 0; i < COUNT; i++) {
+        in.setPosition(i);
+        out.setPosition(i);
+        ComplexCopier.copy(in, out);
+      }
+      to.setValueCount(COUNT);
+
+      // validate equals
+      assertTrue(VectorEqualsVisitor.vectorEquals(from, to));
+    }
+  }
 }