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-java.git
The following commit(s) were added to refs/heads/main by this push:
new 34060eb4 GH-836: Added support of ExtensionType for ComplexCopier
(#837)
34060eb4 is described below
commit 34060eb491a870f5ede5d30e007060b8310dc64f
Author: Ivan Chesnov <[email protected]>
AuthorDate: Wed Oct 1 15:43:26 2025 +0300
GH-836: Added support of ExtensionType for ComplexCopier (#837)
## What's Changed
Updated ComplexCopier to support ExtensionType - it contains two
**copy** methods
```
public static void copy(FieldReader input, FieldWriter output) //for not
breaking existing logic
public static void copy(FieldReader input, FieldWriter output,
ExtensionTypeWriterFactory extensionTypeWriterFactory)
```
Also updated ComplexCopier tests.
Closes #836.
---
vector/src/main/codegen/includes/vv_imports.ftl | 1 +
.../codegen/templates/AbstractFieldReader.java | 4 +
vector/src/main/codegen/templates/BaseReader.java | 3 +
.../src/main/codegen/templates/ComplexCopier.java | 39 +++++--
vector/src/main/codegen/templates/NullReader.java | 1 +
.../org/apache/arrow/vector/BaseValueVector.java | 13 +++
.../java/org/apache/arrow/vector/NullVector.java | 13 +++
.../java/org/apache/arrow/vector/ValueVector.java | 25 +++++
.../vector/complex/AbstractContainerVector.java | 13 +++
.../arrow/vector/complex/LargeListVector.java | 33 +++++-
.../arrow/vector/complex/LargeListViewVector.java | 15 +++
.../apache/arrow/vector/complex/ListVector.java | 33 +++++-
.../arrow/vector/complex/ListViewVector.java | 15 ++-
.../vector/complex/impl/AbstractBaseReader.java | 10 ++
.../vector/complex/impl/UnionExtensionWriter.java | 5 +
.../vector/complex/impl/UnionLargeListReader.java | 4 +
.../org/apache/arrow/vector/TestListVector.java | 43 ++++++++
.../org/apache/arrow/vector/TestMapVector.java | 96 +++++++++++++++++
.../vector/complex/impl/TestComplexCopier.java | 114 +++++++++++++++++++++
.../arrow/vector/complex/impl/UuidReaderImpl.java | 5 +
20 files changed, 476 insertions(+), 9 deletions(-)
diff --git a/vector/src/main/codegen/includes/vv_imports.ftl
b/vector/src/main/codegen/includes/vv_imports.ftl
index 7f216a7b..2bbcecc8 100644
--- a/vector/src/main/codegen/includes/vv_imports.ftl
+++ b/vector/src/main/codegen/includes/vv_imports.ftl
@@ -34,6 +34,7 @@ import org.apache.arrow.vector.complex.*;
import org.apache.arrow.vector.complex.reader.*;
import org.apache.arrow.vector.complex.impl.*;
import org.apache.arrow.vector.complex.writer.*;
+import org.apache.arrow.vector.complex.writer.BaseWriter.ExtensionWriter;
import org.apache.arrow.vector.complex.writer.BaseWriter.StructWriter;
import org.apache.arrow.vector.complex.writer.BaseWriter.ListWriter;
import org.apache.arrow.vector.complex.writer.BaseWriter.MapWriter;
diff --git a/vector/src/main/codegen/templates/AbstractFieldReader.java
b/vector/src/main/codegen/templates/AbstractFieldReader.java
index 7e84323b..c7c5b4d7 100644
--- a/vector/src/main/codegen/templates/AbstractFieldReader.java
+++ b/vector/src/main/codegen/templates/AbstractFieldReader.java
@@ -109,6 +109,10 @@ abstract class AbstractFieldReader extends
AbstractBaseReader implements FieldRe
</#list></#list>
+ public void copyAsValue(StructWriter writer, ExtensionTypeWriterFactory
writerFactory) {
+ fail("CopyAsValue StructWriter");
+ }
+
public void read(ExtensionHolder holder) {
fail("Extension");
}
diff --git a/vector/src/main/codegen/templates/BaseReader.java
b/vector/src/main/codegen/templates/BaseReader.java
index c52345af..4c6f49ab 100644
--- a/vector/src/main/codegen/templates/BaseReader.java
+++ b/vector/src/main/codegen/templates/BaseReader.java
@@ -49,6 +49,7 @@ public interface BaseReader extends Positionable{
boolean next();
int size();
void copyAsValue(StructWriter writer);
+ void copyAsValue(StructWriter writer, ExtensionTypeWriterFactory
writerFactory);
}
public interface ListReader extends BaseReader{
@@ -59,6 +60,7 @@ public interface BaseReader extends Positionable{
boolean next();
int size();
void copyAsValue(ListWriter writer);
+ void copyAsValue(ListWriter writer, ExtensionTypeWriterFactory
writerFactory);
}
public interface MapReader extends BaseReader{
@@ -69,6 +71,7 @@ public interface BaseReader extends Positionable{
boolean next();
int size();
void copyAsValue(MapWriter writer);
+ void copyAsValue(MapWriter writer, ExtensionTypeWriterFactory
writerFactory);
}
public interface ScalarReader extends
diff --git a/vector/src/main/codegen/templates/ComplexCopier.java
b/vector/src/main/codegen/templates/ComplexCopier.java
index 4fff7059..4df5478f 100644
--- a/vector/src/main/codegen/templates/ComplexCopier.java
+++ b/vector/src/main/codegen/templates/ComplexCopier.java
@@ -42,10 +42,14 @@ public class ComplexCopier {
* @param output field to write to
*/
public static void copy(FieldReader input, FieldWriter output) {
- writeValue(input, output);
+ writeValue(input, output, null);
}
- private static void writeValue(FieldReader reader, FieldWriter writer) {
+ public static void copy(FieldReader input, FieldWriter output,
ExtensionTypeWriterFactory extensionTypeWriterFactory) {
+ writeValue(input, output, extensionTypeWriterFactory);
+ }
+
+ private static void writeValue(FieldReader reader, FieldWriter writer,
ExtensionTypeWriterFactory extensionTypeWriterFactory) {
final MinorType mt = reader.getMinorType();
switch (mt) {
@@ -61,7 +65,7 @@ public class ComplexCopier {
FieldReader childReader = reader.reader();
FieldWriter childWriter = getListWriterForReader(childReader,
writer);
if (childReader.isSet()) {
- writeValue(childReader, childWriter);
+ writeValue(childReader, childWriter, extensionTypeWriterFactory);
} else {
childWriter.writeNull();
}
@@ -79,8 +83,8 @@ public class ComplexCopier {
FieldReader structReader = reader.reader();
if (structReader.isSet()) {
writer.startEntry();
- writeValue(mapReader.key(),
getMapWriterForReader(mapReader.key(), writer.key()));
- writeValue(mapReader.value(),
getMapWriterForReader(mapReader.value(), writer.value()));
+ writeValue(mapReader.key(),
getMapWriterForReader(mapReader.key(), writer.key()),
extensionTypeWriterFactory);
+ writeValue(mapReader.value(),
getMapWriterForReader(mapReader.value(), writer.value()),
extensionTypeWriterFactory);
writer.endEntry();
} else {
writer.writeNull();
@@ -99,7 +103,7 @@ public class ComplexCopier {
if (childReader.getMinorType() != Types.MinorType.NULL) {
FieldWriter childWriter = getStructWriterForReader(childReader,
writer, name);
if (childReader.isSet()) {
- writeValue(childReader, childWriter);
+ writeValue(childReader, childWriter,
extensionTypeWriterFactory);
} else {
childWriter.writeNull();
}
@@ -110,6 +114,20 @@ public class ComplexCopier {
writer.writeNull();
}
break;
+ case EXTENSIONTYPE:
+ if (extensionTypeWriterFactory == null) {
+ throw new IllegalArgumentException("Must provide
ExtensionTypeWriterFactory");
+ }
+ if (reader.isSet()) {
+ Object value = reader.readObject();
+ if (value != null) {
+ writer.addExtensionTypeWriterFactory(extensionTypeWriterFactory);
+ writer.writeExtension(value);
+ }
+ } else {
+ writer.writeNull();
+ }
+ break;
<#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/>
@@ -162,6 +180,9 @@ public class ComplexCopier {
return (FieldWriter) writer.map(name);
case LISTVIEW:
return (FieldWriter) writer.listView(name);
+ case EXTENSIONTYPE:
+ ExtensionWriter extensionWriter = writer.extension(name,
reader.getField().getType());
+ return (FieldWriter) extensionWriter;
default:
throw new
UnsupportedOperationException(reader.getMinorType().toString());
}
@@ -186,6 +207,9 @@ public class ComplexCopier {
return (FieldWriter) writer.list();
case LISTVIEW:
return (FieldWriter) writer.listView();
+ case EXTENSIONTYPE:
+ ExtensionWriter extensionWriter =
writer.extension(reader.getField().getType());
+ return (FieldWriter) extensionWriter;
default:
throw new
UnsupportedOperationException(reader.getMinorType().toString());
}
@@ -211,6 +235,9 @@ public class ComplexCopier {
return (FieldWriter) writer.listView();
case MAP:
return (FieldWriter) writer.map(false);
+ case EXTENSIONTYPE:
+ ExtensionWriter extensionWriter =
writer.extension(reader.getField().getType());
+ return (FieldWriter) extensionWriter;
default:
throw new
UnsupportedOperationException(reader.getMinorType().toString());
}
diff --git a/vector/src/main/codegen/templates/NullReader.java
b/vector/src/main/codegen/templates/NullReader.java
index 88e6ea98..05296334 100644
--- a/vector/src/main/codegen/templates/NullReader.java
+++ b/vector/src/main/codegen/templates/NullReader.java
@@ -86,6 +86,7 @@ public class NullReader extends AbstractBaseReader implements
FieldReader{
}
</#list></#list>
+ public void copyAsValue(StructWriter writer, ExtensionTypeWriterFactory
writerFactory){}
public void read(ExtensionHolder holder) {
holder.isSet = 0;
}
diff --git a/vector/src/main/java/org/apache/arrow/vector/BaseValueVector.java
b/vector/src/main/java/org/apache/arrow/vector/BaseValueVector.java
index 37dfa206..cc57cde2 100644
--- a/vector/src/main/java/org/apache/arrow/vector/BaseValueVector.java
+++ b/vector/src/main/java/org/apache/arrow/vector/BaseValueVector.java
@@ -22,6 +22,7 @@ import org.apache.arrow.memory.ArrowBuf;
import org.apache.arrow.memory.BufferAllocator;
import org.apache.arrow.memory.ReferenceManager;
import org.apache.arrow.util.Preconditions;
+import org.apache.arrow.vector.complex.impl.ExtensionTypeWriterFactory;
import org.apache.arrow.vector.complex.reader.FieldReader;
import org.apache.arrow.vector.util.DataSizeRoundingUtil;
import org.apache.arrow.vector.util.TransferPair;
@@ -260,6 +261,18 @@ public abstract class BaseValueVector implements
ValueVector {
throw new UnsupportedOperationException();
}
+ @Override
+ public void copyFrom(
+ int fromIndex, int thisIndex, ValueVector from,
ExtensionTypeWriterFactory writerFactory) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void copyFromSafe(
+ int fromIndex, int thisIndex, ValueVector from,
ExtensionTypeWriterFactory writerFactory) {
+ throw new UnsupportedOperationException();
+ }
+
/**
* Transfer the validity buffer from `validityBuffer` to the target vector's
`validityBuffer`.
* Start at `startIndex` and copy `length` number of elements. If the
starting index is 8 byte
diff --git a/vector/src/main/java/org/apache/arrow/vector/NullVector.java
b/vector/src/main/java/org/apache/arrow/vector/NullVector.java
index 6bfe540d..0d6dab28 100644
--- a/vector/src/main/java/org/apache/arrow/vector/NullVector.java
+++ b/vector/src/main/java/org/apache/arrow/vector/NullVector.java
@@ -27,6 +27,7 @@ import org.apache.arrow.memory.OutOfMemoryException;
import org.apache.arrow.memory.util.hash.ArrowBufHasher;
import org.apache.arrow.util.Preconditions;
import org.apache.arrow.vector.compare.VectorVisitor;
+import org.apache.arrow.vector.complex.impl.ExtensionTypeWriterFactory;
import org.apache.arrow.vector.complex.impl.NullReader;
import org.apache.arrow.vector.complex.reader.FieldReader;
import org.apache.arrow.vector.ipc.message.ArrowFieldNode;
@@ -329,6 +330,18 @@ public class NullVector implements FieldVector,
ValueIterableVector<Object> {
throw new UnsupportedOperationException();
}
+ @Override
+ public void copyFrom(
+ int fromIndex, int thisIndex, ValueVector from,
ExtensionTypeWriterFactory writerFactory) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void copyFromSafe(
+ int fromIndex, int thisIndex, ValueVector from,
ExtensionTypeWriterFactory writerFactory) {
+ throw new UnsupportedOperationException();
+ }
+
@Override
public String getName() {
return this.getField().getName();
diff --git a/vector/src/main/java/org/apache/arrow/vector/ValueVector.java
b/vector/src/main/java/org/apache/arrow/vector/ValueVector.java
index 3a505825..e0628c2e 100644
--- a/vector/src/main/java/org/apache/arrow/vector/ValueVector.java
+++ b/vector/src/main/java/org/apache/arrow/vector/ValueVector.java
@@ -22,6 +22,7 @@ import org.apache.arrow.memory.BufferAllocator;
import org.apache.arrow.memory.OutOfMemoryException;
import org.apache.arrow.memory.util.hash.ArrowBufHasher;
import org.apache.arrow.vector.compare.VectorVisitor;
+import org.apache.arrow.vector.complex.impl.ExtensionTypeWriterFactory;
import org.apache.arrow.vector.complex.reader.FieldReader;
import org.apache.arrow.vector.types.Types.MinorType;
import org.apache.arrow.vector.types.pojo.Field;
@@ -309,6 +310,30 @@ public interface ValueVector extends Closeable,
Iterable<ValueVector> {
*/
void copyFromSafe(int fromIndex, int thisIndex, ValueVector from);
+ /**
+ * Copy a cell value from a particular index in source vector to a
particular position in this
+ * vector.
+ *
+ * @param fromIndex position to copy from in source vector
+ * @param thisIndex position to copy to in this vector
+ * @param from source vector
+ * @param writerFactory the extension type writer factory to use for copying
extension type values
+ */
+ void copyFrom(
+ int fromIndex, int thisIndex, ValueVector from,
ExtensionTypeWriterFactory writerFactory);
+
+ /**
+ * Same as {@link #copyFrom(int, int, ValueVector)} except that it handles
the case when the
+ * capacity of the vector needs to be expanded before copy.
+ *
+ * @param fromIndex position to copy from in source vector
+ * @param thisIndex position to copy to in this vector
+ * @param from source vector
+ * @param writerFactory the extension type writer factory to use for copying
extension type values
+ */
+ void copyFromSafe(
+ int fromIndex, int thisIndex, ValueVector from,
ExtensionTypeWriterFactory writerFactory);
+
/**
* Accept a generic {@link VectorVisitor} and return the result.
*
diff --git
a/vector/src/main/java/org/apache/arrow/vector/complex/AbstractContainerVector.java
b/vector/src/main/java/org/apache/arrow/vector/complex/AbstractContainerVector.java
index a6a71cf1..429f9884 100644
---
a/vector/src/main/java/org/apache/arrow/vector/complex/AbstractContainerVector.java
+++
b/vector/src/main/java/org/apache/arrow/vector/complex/AbstractContainerVector.java
@@ -21,6 +21,7 @@ import org.apache.arrow.memory.OutOfMemoryException;
import org.apache.arrow.vector.DensityAwareVector;
import org.apache.arrow.vector.FieldVector;
import org.apache.arrow.vector.ValueVector;
+import org.apache.arrow.vector.complex.impl.ExtensionTypeWriterFactory;
import org.apache.arrow.vector.types.Types.MinorType;
import org.apache.arrow.vector.types.pojo.ArrowType;
import org.apache.arrow.vector.types.pojo.ArrowType.FixedSizeList;
@@ -151,6 +152,18 @@ public abstract class AbstractContainerVector implements
ValueVector, DensityAwa
throw new UnsupportedOperationException();
}
+ @Override
+ public void copyFrom(
+ int fromIndex, int thisIndex, ValueVector from,
ExtensionTypeWriterFactory writerFactory) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void copyFromSafe(
+ int fromIndex, int thisIndex, ValueVector from,
ExtensionTypeWriterFactory writerFactory) {
+ throw new UnsupportedOperationException();
+ }
+
@Override
public String getName() {
return name;
diff --git
a/vector/src/main/java/org/apache/arrow/vector/complex/LargeListVector.java
b/vector/src/main/java/org/apache/arrow/vector/complex/LargeListVector.java
index 997b5a8b..48c8127e 100644
--- a/vector/src/main/java/org/apache/arrow/vector/complex/LargeListVector.java
+++ b/vector/src/main/java/org/apache/arrow/vector/complex/LargeListVector.java
@@ -49,6 +49,7 @@ import org.apache.arrow.vector.ValueVector;
import org.apache.arrow.vector.ZeroVector;
import org.apache.arrow.vector.compare.VectorVisitor;
import org.apache.arrow.vector.complex.impl.ComplexCopier;
+import org.apache.arrow.vector.complex.impl.ExtensionTypeWriterFactory;
import org.apache.arrow.vector.complex.impl.UnionLargeListReader;
import org.apache.arrow.vector.complex.impl.UnionLargeListWriter;
import org.apache.arrow.vector.complex.reader.FieldReader;
@@ -482,12 +483,42 @@ public class LargeListVector extends BaseValueVector
*/
@Override
public void copyFrom(int inIndex, int outIndex, ValueVector from) {
+ copyFrom(inIndex, outIndex, from, null);
+ }
+
+ /**
+ * Copy a cell value from a particular index in source vector to a
particular position in this
+ * vector.
+ *
+ * @param inIndex position to copy from in source vector
+ * @param outIndex position to copy to in this vector
+ * @param from source vector
+ * @param writerFactory the extension type writer factory to use for copying
extension type values
+ */
+ @Override
+ public void copyFrom(
+ int inIndex, int outIndex, ValueVector from, ExtensionTypeWriterFactory
writerFactory) {
Preconditions.checkArgument(this.getMinorType() == from.getMinorType());
FieldReader in = from.getReader();
in.setPosition(inIndex);
UnionLargeListWriter out = getWriter();
out.setPosition(outIndex);
- ComplexCopier.copy(in, out);
+ ComplexCopier.copy(in, out, writerFactory);
+ }
+
+ /**
+ * Same as {@link #copyFrom(int, int, ValueVector)} except that it handles
the case when the
+ * capacity of the vector needs to be expanded before copy.
+ *
+ * @param inIndex position to copy from in source vector
+ * @param outIndex position to copy to in this vector
+ * @param from source vector
+ * @param writerFactory the extension type writer factory to use for copying
extension type values
+ */
+ @Override
+ public void copyFromSafe(
+ int inIndex, int outIndex, ValueVector from, ExtensionTypeWriterFactory
writerFactory) {
+ copyFrom(inIndex, outIndex, from, writerFactory);
}
/**
diff --git
a/vector/src/main/java/org/apache/arrow/vector/complex/LargeListViewVector.java
b/vector/src/main/java/org/apache/arrow/vector/complex/LargeListViewVector.java
index 2da7eb05..992a6644 100644
---
a/vector/src/main/java/org/apache/arrow/vector/complex/LargeListViewVector.java
+++
b/vector/src/main/java/org/apache/arrow/vector/complex/LargeListViewVector.java
@@ -41,6 +41,7 @@ import org.apache.arrow.vector.ValueIterableVector;
import org.apache.arrow.vector.ValueVector;
import org.apache.arrow.vector.ZeroVector;
import org.apache.arrow.vector.compare.VectorVisitor;
+import org.apache.arrow.vector.complex.impl.ExtensionTypeWriterFactory;
import org.apache.arrow.vector.complex.impl.UnionLargeListViewReader;
import org.apache.arrow.vector.complex.impl.UnionLargeListViewWriter;
import org.apache.arrow.vector.complex.impl.UnionListReader;
@@ -346,6 +347,20 @@ public class LargeListViewVector extends
BaseLargeRepeatedValueViewVector
"LargeListViewVector does not support copyFrom operation yet.");
}
+ @Override
+ public void copyFromSafe(
+ int inIndex, int outIndex, ValueVector from, ExtensionTypeWriterFactory
writerFactory) {
+ throw new UnsupportedOperationException(
+ "LargeListViewVector does not support copyFromSafe operation yet.");
+ }
+
+ @Override
+ public void copyFrom(
+ int inIndex, int outIndex, ValueVector from, ExtensionTypeWriterFactory
writerFactory) {
+ throw new UnsupportedOperationException(
+ "LargeListViewVector does not support copyFrom operation yet.");
+ }
+
@Override
public FieldVector getDataVector() {
return vector;
diff --git
a/vector/src/main/java/org/apache/arrow/vector/complex/ListVector.java
b/vector/src/main/java/org/apache/arrow/vector/complex/ListVector.java
index 93a313ef..89549257 100644
--- a/vector/src/main/java/org/apache/arrow/vector/complex/ListVector.java
+++ b/vector/src/main/java/org/apache/arrow/vector/complex/ListVector.java
@@ -42,6 +42,7 @@ import org.apache.arrow.vector.ValueVector;
import org.apache.arrow.vector.ZeroVector;
import org.apache.arrow.vector.compare.VectorVisitor;
import org.apache.arrow.vector.complex.impl.ComplexCopier;
+import org.apache.arrow.vector.complex.impl.ExtensionTypeWriterFactory;
import org.apache.arrow.vector.complex.impl.UnionListReader;
import org.apache.arrow.vector.complex.impl.UnionListWriter;
import org.apache.arrow.vector.complex.reader.FieldReader;
@@ -400,12 +401,42 @@ public class ListVector extends BaseRepeatedValueVector
*/
@Override
public void copyFrom(int inIndex, int outIndex, ValueVector from) {
+ copyFrom(inIndex, outIndex, from, null);
+ }
+
+ /**
+ * Same as {@link #copyFrom(int, int, ValueVector)} except that it handles
the case when the
+ * capacity of the vector needs to be expanded before copy.
+ *
+ * @param inIndex position to copy from in source vector
+ * @param outIndex position to copy to in this vector
+ * @param from source vector
+ * @param writerFactory the extension type writer factory to use for copying
extension type values
+ */
+ @Override
+ public void copyFromSafe(
+ int inIndex, int outIndex, ValueVector from, ExtensionTypeWriterFactory
writerFactory) {
+ copyFrom(inIndex, outIndex, from, writerFactory);
+ }
+
+ /**
+ * Copy a cell value from a particular index in source vector to a
particular position in this
+ * vector.
+ *
+ * @param inIndex position to copy from in source vector
+ * @param outIndex position to copy to in this vector
+ * @param from source vector
+ * @param writerFactory the extension type writer factory to use for copying
extension type values
+ */
+ @Override
+ public void copyFrom(
+ int inIndex, int outIndex, ValueVector from, ExtensionTypeWriterFactory
writerFactory) {
Preconditions.checkArgument(this.getMinorType() == from.getMinorType());
FieldReader in = from.getReader();
in.setPosition(inIndex);
FieldWriter out = getWriter();
out.setPosition(outIndex);
- ComplexCopier.copy(in, out);
+ ComplexCopier.copy(in, out, writerFactory);
}
/**
diff --git
a/vector/src/main/java/org/apache/arrow/vector/complex/ListViewVector.java
b/vector/src/main/java/org/apache/arrow/vector/complex/ListViewVector.java
index 8711db5e..27842404 100644
--- a/vector/src/main/java/org/apache/arrow/vector/complex/ListViewVector.java
+++ b/vector/src/main/java/org/apache/arrow/vector/complex/ListViewVector.java
@@ -42,6 +42,7 @@ import org.apache.arrow.vector.ValueVector;
import org.apache.arrow.vector.ZeroVector;
import org.apache.arrow.vector.compare.VectorVisitor;
import org.apache.arrow.vector.complex.impl.ComplexCopier;
+import org.apache.arrow.vector.complex.impl.ExtensionTypeWriterFactory;
import org.apache.arrow.vector.complex.impl.UnionListViewReader;
import org.apache.arrow.vector.complex.impl.UnionListViewWriter;
import org.apache.arrow.vector.complex.reader.FieldReader;
@@ -338,6 +339,12 @@ public class ListViewVector extends
BaseRepeatedValueViewVector
copyFrom(inIndex, outIndex, from);
}
+ @Override
+ public void copyFromSafe(
+ int inIndex, int outIndex, ValueVector from, ExtensionTypeWriterFactory
writerFactory) {
+ copyFrom(inIndex, outIndex, from, writerFactory);
+ }
+
@Override
public <OUT, IN> OUT accept(VectorVisitor<OUT, IN> visitor, IN value) {
return visitor.visit(this, value);
@@ -345,12 +352,18 @@ public class ListViewVector extends
BaseRepeatedValueViewVector
@Override
public void copyFrom(int inIndex, int outIndex, ValueVector from) {
+ copyFrom(inIndex, outIndex, from, null);
+ }
+
+ @Override
+ public void copyFrom(
+ int inIndex, int outIndex, ValueVector from, ExtensionTypeWriterFactory
writerFactory) {
Preconditions.checkArgument(this.getMinorType() == from.getMinorType());
FieldReader in = from.getReader();
in.setPosition(inIndex);
FieldWriter out = getWriter();
out.setPosition(outIndex);
- ComplexCopier.copy(in, out);
+ ComplexCopier.copy(in, out, writerFactory);
}
@Override
diff --git
a/vector/src/main/java/org/apache/arrow/vector/complex/impl/AbstractBaseReader.java
b/vector/src/main/java/org/apache/arrow/vector/complex/impl/AbstractBaseReader.java
index b2e95663..bf074ecb 100644
---
a/vector/src/main/java/org/apache/arrow/vector/complex/impl/AbstractBaseReader.java
+++
b/vector/src/main/java/org/apache/arrow/vector/complex/impl/AbstractBaseReader.java
@@ -115,4 +115,14 @@ abstract class AbstractBaseReader implements FieldReader {
public void copyAsValue(MapWriter writer) {
ComplexCopier.copy(this, (FieldWriter) writer);
}
+
+ @Override
+ public void copyAsValue(ListWriter writer, ExtensionTypeWriterFactory
writerFactory) {
+ ComplexCopier.copy(this, (FieldWriter) writer, writerFactory);
+ }
+
+ @Override
+ public void copyAsValue(MapWriter writer, ExtensionTypeWriterFactory
writerFactory) {
+ ComplexCopier.copy(this, (FieldWriter) writer, writerFactory);
+ }
}
diff --git
a/vector/src/main/java/org/apache/arrow/vector/complex/impl/UnionExtensionWriter.java
b/vector/src/main/java/org/apache/arrow/vector/complex/impl/UnionExtensionWriter.java
index d341384b..4219069c 100644
---
a/vector/src/main/java/org/apache/arrow/vector/complex/impl/UnionExtensionWriter.java
+++
b/vector/src/main/java/org/apache/arrow/vector/complex/impl/UnionExtensionWriter.java
@@ -76,4 +76,9 @@ public class UnionExtensionWriter extends AbstractFieldWriter
{
this.writer.setPosition(index);
}
}
+
+ @Override
+ public void writeNull() {
+ this.writer.writeNull();
+ }
}
diff --git
a/vector/src/main/java/org/apache/arrow/vector/complex/impl/UnionLargeListReader.java
b/vector/src/main/java/org/apache/arrow/vector/complex/impl/UnionLargeListReader.java
index be236c31..a9104cb0 100644
---
a/vector/src/main/java/org/apache/arrow/vector/complex/impl/UnionLargeListReader.java
+++
b/vector/src/main/java/org/apache/arrow/vector/complex/impl/UnionLargeListReader.java
@@ -105,4 +105,8 @@ public class UnionLargeListReader extends
AbstractFieldReader {
public void copyAsValue(UnionLargeListWriter writer) {
ComplexCopier.copy(this, (FieldWriter) writer);
}
+
+ public void copyAsValue(UnionLargeListWriter writer,
ExtensionTypeWriterFactory writerFactory) {
+ ComplexCopier.copy(this, (FieldWriter) writer, writerFactory);
+ }
}
diff --git a/vector/src/test/java/org/apache/arrow/vector/TestListVector.java
b/vector/src/test/java/org/apache/arrow/vector/TestListVector.java
index d58b7cc9..c6c7c5c8 100644
--- a/vector/src/test/java/org/apache/arrow/vector/TestListVector.java
+++ b/vector/src/test/java/org/apache/arrow/vector/TestListVector.java
@@ -1271,6 +1271,49 @@ public class TestListVector {
}
}
+ @Test
+ public void testCopyFromForExtensionType() throws Exception {
+ try (ListVector inVector = ListVector.empty("input", allocator);
+ ListVector outVector = ListVector.empty("output", allocator)) {
+ UnionListWriter writer = inVector.getWriter();
+ writer.allocate();
+ writer.setPosition(0);
+ UUID u1 = UUID.randomUUID();
+ UUID u2 = UUID.randomUUID();
+ writer.startList();
+ ExtensionWriter extensionWriter = writer.extension(new UuidType());
+ extensionWriter.addExtensionTypeWriterFactory(new UuidWriterFactory());
+ extensionWriter.writeExtension(u1);
+ extensionWriter.writeExtension(u2);
+ extensionWriter.writeNull();
+ writer.endList();
+
+ writer.setValueCount(1);
+
+ // copy values from input to output
+ outVector.allocateNew();
+ outVector.copyFrom(0, 0, inVector, new UuidWriterFactory());
+ outVector.setValueCount(1);
+
+ UnionListReader reader = outVector.getReader();
+ assertTrue(reader.isSet(), "shouldn't be null");
+ reader.setPosition(0);
+ reader.next();
+ FieldReader uuidReader = reader.reader();
+ UuidHolder holder = new UuidHolder();
+ uuidReader.read(holder);
+ ByteBuffer bb = ByteBuffer.wrap(holder.value);
+ UUID actualUuid = new UUID(bb.getLong(), bb.getLong());
+ assertEquals(u1, actualUuid);
+ reader.next();
+ uuidReader = reader.reader();
+ uuidReader.read(holder);
+ bb = ByteBuffer.wrap(holder.value);
+ actualUuid = new UUID(bb.getLong(), bb.getLong());
+ assertEquals(u2, actualUuid);
+ }
+ }
+
private void writeIntValues(UnionListWriter writer, int[] values) {
writer.startList();
for (int v : values) {
diff --git a/vector/src/test/java/org/apache/arrow/vector/TestMapVector.java
b/vector/src/test/java/org/apache/arrow/vector/TestMapVector.java
index 313d83ec..1a1810d0 100644
--- a/vector/src/test/java/org/apache/arrow/vector/TestMapVector.java
+++ b/vector/src/test/java/org/apache/arrow/vector/TestMapVector.java
@@ -22,24 +22,30 @@ import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertTrue;
+import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
+import java.util.UUID;
import org.apache.arrow.memory.ArrowBuf;
import org.apache.arrow.memory.BufferAllocator;
import org.apache.arrow.vector.complex.MapVector;
import org.apache.arrow.vector.complex.StructVector;
import org.apache.arrow.vector.complex.impl.UnionMapReader;
import org.apache.arrow.vector.complex.impl.UnionMapWriter;
+import org.apache.arrow.vector.complex.impl.UuidWriterFactory;
import org.apache.arrow.vector.complex.reader.FieldReader;
+import org.apache.arrow.vector.complex.writer.BaseWriter.ExtensionWriter;
import org.apache.arrow.vector.complex.writer.BaseWriter.ListWriter;
import org.apache.arrow.vector.complex.writer.BaseWriter.MapWriter;
import org.apache.arrow.vector.complex.writer.FieldWriter;
+import org.apache.arrow.vector.holder.UuidHolder;
import org.apache.arrow.vector.types.Types.MinorType;
import org.apache.arrow.vector.types.pojo.ArrowType;
import org.apache.arrow.vector.types.pojo.Field;
import org.apache.arrow.vector.types.pojo.FieldType;
+import org.apache.arrow.vector.types.pojo.UuidType;
import org.apache.arrow.vector.util.JsonStringArrayList;
import org.apache.arrow.vector.util.TransferPair;
import org.junit.jupiter.api.AfterEach;
@@ -1263,4 +1269,94 @@ public class TestMapVector {
assertEquals(11, getResultValue(resultStruct));
}
}
+
+ @Test
+ public void testMapVectorWithExtensionType() throws Exception {
+ try (final MapVector inVector = MapVector.empty("map", allocator, false)) {
+ inVector.allocateNew();
+ UnionMapWriter writer = inVector.getWriter();
+ writer.setPosition(0);
+ UUID u1 = UUID.randomUUID();
+ UUID u2 = UUID.randomUUID();
+ writer.startMap();
+ writer.startEntry();
+ writer.key().bigInt().writeBigInt(0);
+ ExtensionWriter extensionWriter = writer.value().extension(new
UuidType());
+ extensionWriter.addExtensionTypeWriterFactory(new UuidWriterFactory());
+ extensionWriter.writeExtension(u1);
+ writer.endEntry();
+ writer.startEntry();
+ writer.key().bigInt().writeBigInt(1);
+ extensionWriter = writer.value().extension(new UuidType());
+ extensionWriter.addExtensionTypeWriterFactory(new UuidWriterFactory());
+ extensionWriter.writeExtension(u2);
+ writer.endEntry();
+ writer.endMap();
+
+ writer.setValueCount(1);
+
+ UnionMapReader mapReader = inVector.getReader();
+ mapReader.setPosition(0);
+ mapReader.next();
+ FieldReader uuidReader = mapReader.value();
+ UuidHolder holder = new UuidHolder();
+ uuidReader.read(holder);
+ ByteBuffer bb = ByteBuffer.wrap(holder.value);
+ UUID actualUuid = new UUID(bb.getLong(), bb.getLong());
+ assertEquals(u1, actualUuid);
+ mapReader.next();
+ uuidReader = mapReader.value();
+ uuidReader.read(holder);
+ bb = ByteBuffer.wrap(holder.value);
+ actualUuid = new UUID(bb.getLong(), bb.getLong());
+ assertEquals(u2, actualUuid);
+ }
+ }
+
+ @Test
+ public void testCopyFromForExtensionType() throws Exception {
+ try (final MapVector inVector = MapVector.empty("in", allocator, false);
+ final MapVector outVector = MapVector.empty("out", allocator, false)) {
+ inVector.allocateNew();
+ UnionMapWriter writer = inVector.getWriter();
+ writer.setPosition(0);
+ UUID u1 = UUID.randomUUID();
+ UUID u2 = UUID.randomUUID();
+ writer.startMap();
+ writer.startEntry();
+ writer.key().bigInt().writeBigInt(0);
+ ExtensionWriter extensionWriter = writer.value().extension(new
UuidType());
+ extensionWriter.addExtensionTypeWriterFactory(new UuidWriterFactory());
+ extensionWriter.writeExtension(u1);
+ writer.endEntry();
+ writer.startEntry();
+ writer.key().bigInt().writeBigInt(1);
+ extensionWriter = writer.value().extension(new UuidType());
+ extensionWriter.addExtensionTypeWriterFactory(new UuidWriterFactory());
+ extensionWriter.writeExtension(u2);
+ writer.endEntry();
+ writer.endMap();
+
+ writer.setValueCount(1);
+ outVector.allocateNew();
+ outVector.copyFrom(0, 0, inVector, new UuidWriterFactory());
+ outVector.setValueCount(1);
+
+ UnionMapReader mapReader = outVector.getReader();
+ mapReader.setPosition(0);
+ mapReader.next();
+ FieldReader uuidReader = mapReader.value();
+ UuidHolder holder = new UuidHolder();
+ uuidReader.read(holder);
+ ByteBuffer bb = ByteBuffer.wrap(holder.value);
+ UUID actualUuid = new UUID(bb.getLong(), bb.getLong());
+ assertEquals(u1, actualUuid);
+ mapReader.next();
+ uuidReader = mapReader.value();
+ uuidReader.read(holder);
+ bb = ByteBuffer.wrap(holder.value);
+ actualUuid = new UUID(bb.getLong(), bb.getLong());
+ assertEquals(u2, actualUuid);
+ }
+ }
}
diff --git
a/vector/src/test/java/org/apache/arrow/vector/complex/impl/TestComplexCopier.java
b/vector/src/test/java/org/apache/arrow/vector/complex/impl/TestComplexCopier.java
index 3bc02c60..738e8905 100644
---
a/vector/src/test/java/org/apache/arrow/vector/complex/impl/TestComplexCopier.java
+++
b/vector/src/test/java/org/apache/arrow/vector/complex/impl/TestComplexCopier.java
@@ -20,6 +20,7 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.math.BigDecimal;
+import java.util.UUID;
import org.apache.arrow.memory.BufferAllocator;
import org.apache.arrow.memory.RootAllocator;
import org.apache.arrow.vector.DecimalVector;
@@ -30,12 +31,14 @@ import org.apache.arrow.vector.complex.MapVector;
import org.apache.arrow.vector.complex.StructVector;
import org.apache.arrow.vector.complex.reader.FieldReader;
import org.apache.arrow.vector.complex.writer.BaseWriter;
+import org.apache.arrow.vector.complex.writer.BaseWriter.ExtensionWriter;
import org.apache.arrow.vector.complex.writer.BaseWriter.StructWriter;
import org.apache.arrow.vector.complex.writer.FieldWriter;
import org.apache.arrow.vector.holders.DecimalHolder;
import org.apache.arrow.vector.types.Types;
import org.apache.arrow.vector.types.pojo.ArrowType;
import org.apache.arrow.vector.types.pojo.FieldType;
+import org.apache.arrow.vector.types.pojo.UuidType;
import org.apache.arrow.vector.util.DecimalUtility;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
@@ -845,4 +848,115 @@ public class TestComplexCopier {
assertTrue(VectorEqualsVisitor.vectorEquals(from, to));
}
}
+
+ @Test
+ public void testCopyListVectorWithExtensionType() {
+ try (ListVector from = ListVector.empty("v", allocator);
+ ListVector to = ListVector.empty("v", allocator)) {
+
+ UnionListWriter listWriter = from.getWriter();
+ listWriter.allocate();
+
+ for (int i = 0; i < COUNT; i++) {
+ listWriter.setPosition(i);
+ listWriter.startList();
+ ExtensionWriter extensionWriter = listWriter.extension(new UuidType());
+ extensionWriter.addExtensionTypeWriterFactory(new UuidWriterFactory());
+ extensionWriter.writeExtension(UUID.randomUUID());
+ extensionWriter.writeExtension(UUID.randomUUID());
+ listWriter.endList();
+ }
+ 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, new UuidWriterFactory());
+ }
+
+ to.setValueCount(COUNT);
+
+ // validate equals
+ assertTrue(VectorEqualsVisitor.vectorEquals(from, to));
+ }
+ }
+
+ @Test
+ public void testCopyMapVectorWithExtensionType() {
+ 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();
+ ExtensionWriter extensionKeyWriter = mapWriter.key().extension(new
UuidType());
+ extensionKeyWriter.addExtensionTypeWriterFactory(new
UuidWriterFactory());
+ extensionKeyWriter.writeExtension(UUID.randomUUID());
+ ExtensionWriter extensionValueWriter = mapWriter.value().extension(new
UuidType());
+ extensionValueWriter.addExtensionTypeWriterFactory(new
UuidWriterFactory());
+ extensionValueWriter.writeExtension(UUID.randomUUID());
+ 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, new UuidWriterFactory());
+ }
+ to.setValueCount(COUNT);
+
+ // validate equals
+ assertTrue(VectorEqualsVisitor.vectorEquals(from, to));
+ }
+ }
+
+ @Test
+ public void testCopyStructVectorWithExtensionType() {
+ try (final StructVector from = StructVector.empty("v", allocator);
+ final StructVector to = StructVector.empty("v", allocator)) {
+
+ from.allocateNewSafe();
+
+ NullableStructWriter structWriter = from.getWriter();
+ for (int i = 0; i < COUNT; i++) {
+ structWriter.setPosition(i);
+ structWriter.start();
+ ExtensionWriter extensionWriter1 =
structWriter.extension("timestamp1", new UuidType());
+ extensionWriter1.addExtensionTypeWriterFactory(new
UuidWriterFactory());
+ extensionWriter1.writeExtension(UUID.randomUUID());
+ ExtensionWriter extensionWriter2 =
structWriter.extension("timestamp2", new UuidType());
+ extensionWriter2.addExtensionTypeWriterFactory(new
UuidWriterFactory());
+ extensionWriter2.writeExtension(UUID.randomUUID());
+ 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, new UuidWriterFactory());
+ }
+ to.setValueCount(COUNT);
+
+ // validate equals
+ assertTrue(VectorEqualsVisitor.vectorEquals(from, to));
+ }
+ }
}
diff --git
a/vector/src/test/java/org/apache/arrow/vector/complex/impl/UuidReaderImpl.java
b/vector/src/test/java/org/apache/arrow/vector/complex/impl/UuidReaderImpl.java
index 16dd734d..6b98d3b3 100644
---
a/vector/src/test/java/org/apache/arrow/vector/complex/impl/UuidReaderImpl.java
+++
b/vector/src/test/java/org/apache/arrow/vector/complex/impl/UuidReaderImpl.java
@@ -61,4 +61,9 @@ public class UuidReaderImpl extends AbstractFieldReader {
UuidWriterImpl impl = (UuidWriterImpl) writer;
impl.vector.copyFromSafe(idx(), impl.idx(), vector);
}
+
+ @Override
+ public Object readObject() {
+ return vector.getObject(idx());
+ }
}