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));
+ }
+ }
}