diff --git a/README_DREMIO.md b/README_DREMIO.md index bde341581071b..9dca7941d18dc 100644 --- a/README_DREMIO.md +++ b/README_DREMIO.md @@ -1,8 +1,5 @@ -git checkout -b dremio_24.3_12.0 apache-arrow-12.0.1 - -Apply starting from the bottom and working upwards. - -git cherry-pick d4dc6d525cfd89aa7ca7a23e0d755f5f2e3b2c48 +git cherry-pick cf53c1e023605fd506a3617bbd9fe1788b33c5a3 +git cherry-pick 0230230a4a28d0e1e2aa23570804a14444c58e4a git cherry-pick 0002859096a93cd9b0630db757a277b75a483263 git cherry-pick 5ed2f61a9fa72d011248bf9cfec7a9734d5b2aa0 git cherry-pick c601e318a897b3a6fd5f4fd3068beda1460173a2 diff --git a/java/pom.xml b/java/pom.xml index 6b3a35ec9786d..747320d2f8a40 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -33,7 +33,7 @@ 5.9.0 1.7.25 31.1-jre - 4.1.93.Final + 4.1.96.Final 1.56.0 3.21.9 2.13.4 diff --git a/java/vector/src/main/codegen/templates/BaseWriter.java b/java/vector/src/main/codegen/templates/BaseWriter.java index 4d63fb73e98c8..3b35d22692e68 100644 --- a/java/vector/src/main/codegen/templates/BaseWriter.java +++ b/java/vector/src/main/codegen/templates/BaseWriter.java @@ -106,6 +106,7 @@ public interface ComplexWriter { void copyReader(FieldReader reader); StructWriter rootAsStruct(); ListWriter rootAsList(); + MapWriter rootAsMap(boolean keysSorted); void setPosition(int index); void setValueCount(int count); diff --git a/java/vector/src/main/java/org/apache/arrow/vector/complex/impl/ComplexWriterImpl.java b/java/vector/src/main/java/org/apache/arrow/vector/complex/impl/ComplexWriterImpl.java index 13b26bb67dace..8d2694b6df887 100644 --- a/java/vector/src/main/java/org/apache/arrow/vector/complex/impl/ComplexWriterImpl.java +++ b/java/vector/src/main/java/org/apache/arrow/vector/complex/impl/ComplexWriterImpl.java @@ -19,6 +19,7 @@ import org.apache.arrow.util.Preconditions; import org.apache.arrow.vector.complex.ListVector; +import org.apache.arrow.vector.complex.MapVector; import org.apache.arrow.vector.complex.NonNullableStructVector; import org.apache.arrow.vector.complex.StateTool; import org.apache.arrow.vector.complex.StructVector; @@ -32,6 +33,7 @@ public class ComplexWriterImpl extends AbstractFieldWriter implements ComplexWri private NullableStructWriter structRoot; private UnionListWriter listRoot; + private UnionMapWriter mapRoot; private final NonNullableStructVector container; Mode mode = Mode.INIT; @@ -39,7 +41,7 @@ public class ComplexWriterImpl extends AbstractFieldWriter implements ComplexWri private final boolean unionEnabled; private final NullableStructWriterFactory nullableStructWriterFactory; - private enum Mode { INIT, STRUCT, LIST } + private enum Mode { INIT, STRUCT, LIST, MAP } /** * Constructs a new instance. @@ -107,6 +109,9 @@ public void clear() { case LIST: listRoot.clear(); break; + case MAP: + mapRoot.clear(); + break; default: break; } @@ -121,6 +126,9 @@ public void setValueCount(int count) { case LIST: listRoot.setValueCount(count); break; + case MAP: + mapRoot.setValueCount(count); + break; default: break; } @@ -136,6 +144,9 @@ public void setPosition(int index) { case LIST: listRoot.setPosition(index); break; + case MAP: + mapRoot.setPosition(index); + break; default: break; } @@ -223,5 +234,29 @@ public ListWriter rootAsList() { return listRoot; } + @Override + public MapWriter rootAsMap(boolean keysSorted) { + switch (mode) { + case INIT: + int vectorCount = container.size(); + // TODO allow dictionaries in complex types + MapVector mapVector = container.addOrGetMap(name, keysSorted); + if (container.size() > vectorCount) { + mapVector.allocateNew(); + } + mapRoot = new UnionMapWriter(mapVector); + mapRoot.setPosition(idx()); + mode = Mode.MAP; + break; + + case MAP: + break; + + default: + check(Mode.INIT, Mode.STRUCT); + } + + return mapRoot; + } } diff --git a/java/vector/src/test/java/org/apache/arrow/vector/complex/writer/TestComplexWriter.java b/java/vector/src/test/java/org/apache/arrow/vector/complex/writer/TestComplexWriter.java index 55041496653a6..e42926b6163d0 100644 --- a/java/vector/src/test/java/org/apache/arrow/vector/complex/writer/TestComplexWriter.java +++ b/java/vector/src/test/java/org/apache/arrow/vector/complex/writer/TestComplexWriter.java @@ -1401,4 +1401,108 @@ public void testStructOfList() { Assert.assertEquals(0, size); } } + + @Test + public void testMap() { + try (NonNullableStructVector parent = NonNullableStructVector.empty("parent", allocator)) { + ComplexWriter writer = new ComplexWriterImpl("root", parent); + MapWriter mapWriter = writer.rootAsMap(false); + for (int i = 0; i < COUNT; i++) { + mapWriter.startMap(); + for (int j = 0; j < i % 7; j++) { + mapWriter.startEntry(); + if (j % 2 == 0) { + mapWriter.key().integer().writeInt(j); + mapWriter.value().integer().writeInt(j + 1); + } else { + IntHolder keyHolder = new IntHolder(); + keyHolder.value = j; + IntHolder valueHolder = new IntHolder(); + valueHolder.value = j + 1; + mapWriter.key().integer().write(keyHolder); + mapWriter.value().integer().write(valueHolder); + } + mapWriter.endEntry(); + } + mapWriter.endMap(); + } + writer.setValueCount(COUNT); + UnionMapReader mapReader = (UnionMapReader) new SingleStructReaderImpl(parent).reader("root"); + for (int i = 0; i < COUNT; i++) { + mapReader.setPosition(i); + for (int j = 0; j < i % 7; j++) { + mapReader.next(); + assertEquals(j, mapReader.key().readInteger().intValue()); + assertEquals(j + 1, mapReader.value().readInteger().intValue()); + } + } + } + } + + @Test + public void testMapWithNulls() { + try (NonNullableStructVector parent = NonNullableStructVector.empty("parent", allocator)) { + ComplexWriter writer = new ComplexWriterImpl("root", parent); + MapWriter mapWriter = writer.rootAsMap(false); + mapWriter.startMap(); + mapWriter.startEntry(); + mapWriter.key().integer().writeNull(); + mapWriter.value().integer().writeInt(1); + mapWriter.endEntry(); + mapWriter.endMap(); + writer.setValueCount(1); + UnionMapReader mapReader = (UnionMapReader) new SingleStructReaderImpl(parent).reader("root"); + Assert.assertNull(mapReader.key().readInteger()); + assertEquals(1, mapReader.value().readInteger().intValue()); + } + } + + @Test + public void testMapWithListKey() { + try (NonNullableStructVector parent = NonNullableStructVector.empty("parent", allocator)) { + ComplexWriter writer = new ComplexWriterImpl("root", parent); + MapWriter mapWriter = writer.rootAsMap(false); + mapWriter.startMap(); + mapWriter.startEntry(); + mapWriter.key().list().startList(); + for (int i = 0; i < 3; i++) { + mapWriter.key().list().integer().writeInt(i); + } + mapWriter.key().list().endList(); + mapWriter.value().integer().writeInt(1); + mapWriter.endEntry(); + mapWriter.endMap(); + writer.setValueCount(1); + UnionMapReader mapReader = (UnionMapReader) new SingleStructReaderImpl(parent).reader("root"); + mapReader.key().next(); + assertEquals(0, mapReader.key().reader().readInteger().intValue()); + mapReader.key().next(); + assertEquals(1, mapReader.key().reader().readInteger().intValue()); + mapReader.key().next(); + assertEquals(2, mapReader.key().reader().readInteger().intValue()); + assertEquals(1, mapReader.value().readInteger().intValue()); + } + } + + @Test + public void testMapWithStructKey() { + try (NonNullableStructVector parent = NonNullableStructVector.empty("parent", allocator)) { + ComplexWriter writer = new ComplexWriterImpl("root", parent); + MapWriter mapWriter = writer.rootAsMap(false); + mapWriter.startMap(); + mapWriter.startEntry(); + mapWriter.key().struct().start(); + mapWriter.key().struct().integer("value1").writeInt(1); + mapWriter.key().struct().integer("value2").writeInt(2); + mapWriter.key().struct().end(); + mapWriter.value().integer().writeInt(1); + mapWriter.endEntry(); + mapWriter.endMap(); + writer.setValueCount(1); + UnionMapReader mapReader = (UnionMapReader) new SingleStructReaderImpl(parent).reader("root"); + assertEquals(1, mapReader.key().reader("value1").readInteger().intValue()); + assertEquals(2, mapReader.key().reader("value2").readInteger().intValue()); + assertEquals(1, mapReader.value().readInteger().intValue()); + } + } }