diff --git a/vector/src/main/codegen/templates/ComplexCopier.java b/vector/src/main/codegen/templates/ComplexCopier.java index 6655f6c2a7..ebcc7ebfa0 100644 --- a/vector/src/main/codegen/templates/ComplexCopier.java +++ b/vector/src/main/codegen/templates/ComplexCopier.java @@ -117,6 +117,17 @@ public static void copy(FieldReader reader, FieldWriter writer) { writer.writeNull(); } break; + case FIXEDSIZEBINARY: + if (reader.isSet()) { + NullableFixedSizeBinaryHolder fixedSizeBinaryHolder = new NullableFixedSizeBinaryHolder(); + reader.read(fixedSizeBinaryHolder); + if (fixedSizeBinaryHolder.isSet == 1) { + writer.writeFixedSizeBinary(fixedSizeBinaryHolder.buffer); + } + } 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/> @@ -160,6 +171,13 @@ private static FieldWriter getStructWriterForReader(FieldReader reader, StructWr + case FIXEDSIZEBINARY: + if (reader.getField().getType() instanceof ArrowType.FixedSizeBinary) { + ArrowType.FixedSizeBinary type = (ArrowType.FixedSizeBinary) reader.getField().getType(); + return (FieldWriter) writer.fixedSizeBinary(name, type.getByteWidth()); + } else { + return (FieldWriter) writer.fixedSizeBinary(name); + } case STRUCT: return (FieldWriter) writer.struct(name); case FIXED_SIZE_LIST: @@ -187,6 +205,8 @@ private static FieldWriter getListWriterForReader(FieldReader reader, ListWriter return (FieldWriter) writer.<#if name == "Int">integer<#else>${uncappedName}(); + case FIXEDSIZEBINARY: + return (FieldWriter) writer.fixedSizeBinary(); case STRUCT: return (FieldWriter) writer.struct(); case FIXED_SIZE_LIST: @@ -214,6 +234,8 @@ private static FieldWriter getMapWriterForReader(FieldReader reader, MapWriter w return (FieldWriter) writer.<#if name == "Int">integer<#else>${uncappedName}(); + case FIXEDSIZEBINARY: + return (FieldWriter) writer.fixedSizeBinary(); case STRUCT: return (FieldWriter) writer.struct(); case FIXED_SIZE_LIST: 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 b2a8cf9ba4..9e6bb0b1a2 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 @@ -16,11 +16,15 @@ */ package org.apache.arrow.vector.complex.impl; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import java.math.BigDecimal; +import java.util.List; import java.util.UUID; +import org.apache.arrow.memory.ArrowBuf; import org.apache.arrow.memory.BufferAllocator; import org.apache.arrow.memory.RootAllocator; import org.apache.arrow.vector.DecimalVector; @@ -36,6 +40,7 @@ import org.apache.arrow.vector.complex.writer.FieldWriter; import org.apache.arrow.vector.extension.UuidType; import org.apache.arrow.vector.holders.DecimalHolder; +import org.apache.arrow.vector.holders.FixedSizeBinaryHolder; import org.apache.arrow.vector.types.Types; import org.apache.arrow.vector.types.pojo.ArrowType; import org.apache.arrow.vector.types.pojo.FieldType; @@ -207,6 +212,60 @@ public void testCopyListVector() { } } + @Test + public void testCopyListOfFixedSizeBinary() { + final int byteWidth = 4; + try (ListVector from = ListVector.empty("v", allocator); + ListVector to = ListVector.empty("v", allocator); + ArrowBuf buf = allocator.buffer(byteWidth)) { + + from.addOrGetVector(FieldType.nullable(new ArrowType.FixedSizeBinary(byteWidth))); + to.addOrGetVector(FieldType.nullable(new ArrowType.FixedSizeBinary(byteWidth))); + + UnionListWriter listWriter = from.getWriter(); + listWriter.allocate(); + + FixedSizeBinaryHolder holder = new FixedSizeBinaryHolder(); + holder.byteWidth = byteWidth; + holder.buffer = buf; + + for (int i = 0; i < COUNT; i++) { + listWriter.setPosition(i); + listWriter.startList(); + + buf.setBytes(0, new byte[] {1, 2, 3, 4}); + listWriter.fixedSizeBinary().write(holder); + + buf.setBytes(0, new byte[] {5, 6, 7, 8}); + listWriter.fixedSizeBinary().write(holder); + + listWriter.endList(); + } + from.setValueCount(COUNT); + + 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); + + for (int i = 0; i < COUNT; i++) { + @SuppressWarnings("unchecked") + List expected = (List) from.getObject(i); + @SuppressWarnings("unchecked") + List actual = (List) to.getObject(i); + + assertEquals(expected.size(), actual.size()); + for (int j = 0; j < expected.size(); j++) { + assertArrayEquals(expected.get(j), actual.get(j)); + } + } + } + } + @Test public void testCopyListVectorToANonEmptyList() { try (ListVector from = ListVector.empty("v", allocator); @@ -705,6 +764,43 @@ public void testCopyStructVector() { } } + @Test + public void testCopyStructOfFixedSizeBinary() { + final int byteWidth = 4; + try (final StructVector from = StructVector.empty("v", allocator); + final StructVector to = StructVector.empty("v", allocator); + ArrowBuf buf = allocator.buffer(byteWidth)) { + from.allocateNewSafe(); + NullableStructWriter structWriter = from.getWriter(); + + FixedSizeBinaryHolder holder = new FixedSizeBinaryHolder(); + holder.byteWidth = byteWidth; + holder.buffer = buf; + + for (int i = 0; i < COUNT; i++) { + structWriter.setPosition(i); + structWriter.start(); + buf.setBytes(0, new byte[] {(byte) i, (byte) (i + 1), (byte) (i + 2), (byte) (i + 3)}); + structWriter.fixedSizeBinary("fsb", byteWidth).write(holder); + 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 testCopyDecimalVectorWrongScale() { try (FixedSizeListVector from = FixedSizeListVector.empty("v", 3, allocator);