This is an automated email from the ASF dual-hosted git repository.
JingsongLi pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/paimon.git
The following commit(s) were added to refs/heads/master by this push:
new 8e23d1eae7 [arrow] Fix Arrow conversion for missing complex columns
(#8650)
8e23d1eae7 is described below
commit 8e23d1eae7abd706681f83b8781d82a2176d81fc
Author: umi <[email protected]>
AuthorDate: Thu Jul 16 23:29:31 2026 +0800
[arrow] Fix Arrow conversion for missing complex columns (#8650)
Schema evolution maps fields missing from an older data file to index
`-1`. `VectorMappingUtils` previously represented those fields with a
generic all-null `ColumnVector` lambda. `ArrowBatchReader` also used an
independent all-null lambda for fields missing from an input Arrow
schema. Arrow complex-type writers select their implementation from the
current logical schema and cast the runtime vector to `MapColumnVector`,
`ArrayColumnVector`, or other typed vectors before writing, which can
cause `ClassCastException` for missing complex columns.
---
.../paimon/arrow/reader/ArrowBatchReader.java | 6 +-
.../paimon/arrow/writer/ArrowFieldWriter.java | 14 +++
.../ArrowVectorizedBatchConverterTest.java | 126 +++++++++++++++++++++
.../paimon/arrow/vector/ArrowFormatWriterTest.java | 45 ++++++++
.../paimon/data/columnar/AllNullColumnVector.java | 32 ++++++
.../apache/paimon/utils/VectorMappingUtils.java | 3 +-
.../paimon/utils/VectorMappingUtilsTest.java | 14 +++
.../arrow/converter/ArrowBatchConverterTest.java | 56 +++++++++
8 files changed, 291 insertions(+), 5 deletions(-)
diff --git
a/paimon-arrow/src/main/java/org/apache/paimon/arrow/reader/ArrowBatchReader.java
b/paimon-arrow/src/main/java/org/apache/paimon/arrow/reader/ArrowBatchReader.java
index cccc1b01f8..ab939d70b4 100644
---
a/paimon-arrow/src/main/java/org/apache/paimon/arrow/reader/ArrowBatchReader.java
+++
b/paimon-arrow/src/main/java/org/apache/paimon/arrow/reader/ArrowBatchReader.java
@@ -20,6 +20,7 @@ package org.apache.paimon.arrow.reader;
import org.apache.paimon.arrow.converter.Arrow2PaimonVectorConverter;
import org.apache.paimon.data.InternalRow;
+import org.apache.paimon.data.columnar.AllNullColumnVector;
import org.apache.paimon.data.columnar.ColumnVector;
import org.apache.paimon.data.columnar.ColumnarRow;
import org.apache.paimon.data.columnar.VectorizedColumnBatch;
@@ -68,9 +69,6 @@ public class ArrowBatchReader {
this.caseSensitive = caseSensitive;
}
- /** A {@link ColumnVector} that always returns null for any position. */
- private static final ColumnVector NULL_COLUMN_VECTOR = i -> true;
-
public Iterable<InternalRow> readBatch(VectorSchemaRoot vsr) {
int[] mapping = new int[projectedRowType.getFieldCount()];
Schema arrowSchema = vsr.getSchema();
@@ -89,7 +87,7 @@ public class ArrowBatchReader {
if (mapping[i] >= 0) {
batch.columns[i] =
convertors[i].convertVector(vsr.getVector(mapping[i]));
} else {
- batch.columns[i] = NULL_COLUMN_VECTOR;
+ batch.columns[i] = AllNullColumnVector.INSTANCE;
}
}
diff --git
a/paimon-arrow/src/main/java/org/apache/paimon/arrow/writer/ArrowFieldWriter.java
b/paimon-arrow/src/main/java/org/apache/paimon/arrow/writer/ArrowFieldWriter.java
index e785d48bf0..d635545d94 100644
---
a/paimon-arrow/src/main/java/org/apache/paimon/arrow/writer/ArrowFieldWriter.java
+++
b/paimon-arrow/src/main/java/org/apache/paimon/arrow/writer/ArrowFieldWriter.java
@@ -20,6 +20,7 @@ package org.apache.paimon.arrow.writer;
import org.apache.paimon.CoreOptions;
import org.apache.paimon.data.DataGetters;
+import org.apache.paimon.data.columnar.AllNullColumnVector;
import org.apache.paimon.data.columnar.ColumnVector;
import org.apache.arrow.vector.FieldVector;
@@ -57,6 +58,19 @@ public abstract class ArrowFieldWriter {
@Nullable int[] pickedInColumn,
int startIndex,
int batchRows) {
+ if (batchRows == 0) {
+ fieldVector.setValueCount(0);
+ return;
+ }
+
+ if (columnVector == AllNullColumnVector.INSTANCE) {
+ for (int i = 0; i < batchRows; i++) {
+ fieldVector.setNull(i);
+ }
+ fieldVector.setValueCount(batchRows);
+ return;
+ }
+
doWrite(columnVector, pickedInColumn, startIndex, batchRows);
fieldVector.setValueCount(batchRows);
}
diff --git
a/paimon-arrow/src/test/java/org/apache/paimon/arrow/converter/ArrowVectorizedBatchConverterTest.java
b/paimon-arrow/src/test/java/org/apache/paimon/arrow/converter/ArrowVectorizedBatchConverterTest.java
index ac4defe479..00dc92553a 100644
---
a/paimon-arrow/src/test/java/org/apache/paimon/arrow/converter/ArrowVectorizedBatchConverterTest.java
+++
b/paimon-arrow/src/test/java/org/apache/paimon/arrow/converter/ArrowVectorizedBatchConverterTest.java
@@ -24,12 +24,15 @@ import org.apache.paimon.data.BinaryVector;
import org.apache.paimon.data.GenericRow;
import org.apache.paimon.data.InternalRow;
import org.apache.paimon.data.InternalVector;
+import org.apache.paimon.data.columnar.AllNullColumnVector;
import org.apache.paimon.data.columnar.ColumnVector;
import org.apache.paimon.data.columnar.ColumnarVec;
import org.apache.paimon.data.columnar.RowToColumnConverter;
import org.apache.paimon.data.columnar.VecColumnVector;
import org.apache.paimon.data.columnar.VectorizedColumnBatch;
import org.apache.paimon.data.columnar.heap.HeapFloatVector;
+import org.apache.paimon.data.columnar.heap.HeapIntVector;
+import org.apache.paimon.data.columnar.heap.HeapMapVector;
import org.apache.paimon.data.columnar.heap.HeapVectorColumnVector;
import org.apache.paimon.data.columnar.writable.WritableColumnVector;
import org.apache.paimon.reader.VectorizedRecordIterator;
@@ -37,8 +40,12 @@ import org.apache.paimon.types.DataTypes;
import org.apache.paimon.types.RowType;
import org.apache.arrow.memory.RootAllocator;
+import org.apache.arrow.vector.FieldVector;
import org.apache.arrow.vector.VectorSchemaRoot;
import org.apache.arrow.vector.complex.FixedSizeListVector;
+import org.apache.arrow.vector.complex.ListVector;
+import org.apache.arrow.vector.complex.MapVector;
+import org.apache.arrow.vector.complex.StructVector;
import org.junit.jupiter.api.Test;
import java.util.List;
@@ -49,6 +56,125 @@ import static org.assertj.core.api.Assertions.assertThat;
/** Tests for {@link ArrowVectorizedBatchConverter}. */
public class ArrowVectorizedBatchConverterTest {
+ @Test
+ public void testAllNullColumnVectorForComplexTypes() {
+ RowType rowType =
+ RowType.of(
+ DataTypes.MAP(DataTypes.STRING(), DataTypes.INT()),
+ DataTypes.ARRAY(DataTypes.INT()),
+ DataTypes.ROW(
+ DataTypes.FIELD(0, "a", DataTypes.INT()),
+ DataTypes.FIELD(1, "b", DataTypes.STRING())),
+ DataTypes.ARRAY(DataTypes.MAP(DataTypes.STRING(),
DataTypes.INT())),
+ DataTypes.VECTOR(3, DataTypes.FLOAT()),
+ DataTypes.VARIANT());
+
+ try (RootAllocator allocator = new RootAllocator();
+ VectorSchemaRoot vsr =
ArrowUtils.createVectorSchemaRoot(rowType, allocator)) {
+ ArrowFieldWriter[] fieldWriters =
ArrowUtils.createArrowFieldWriters(vsr, rowType);
+ int rows = 2;
+ int[] pickedInColumn = new int[] {3, 1, 4};
+
+ for (ArrowFieldWriter fieldWriter : fieldWriters) {
+ fieldWriter.reset();
+ fieldWriter.write(AllNullColumnVector.INSTANCE,
pickedInColumn, 1, rows);
+ }
+ vsr.setRowCount(rows);
+
+ for (FieldVector fieldVector : vsr.getFieldVectors()) {
+ assertThat(fieldVector.getValueCount()).isEqualTo(rows);
+ assertThat(fieldVector.isNull(0)).isTrue();
+ assertThat(fieldVector.isNull(1)).isTrue();
+ }
+
+ MapVector mapVector = (MapVector) vsr.getVector(0);
+ assertThat(mapVector.getDataVector().getValueCount()).isZero();
+
+ ListVector arrayVector = (ListVector) vsr.getVector(1);
+ assertThat(arrayVector.getDataVector().getValueCount()).isZero();
+
+ StructVector rowVector = (StructVector) vsr.getVector(2);
+ assertThat(rowVector.getChildrenFromFields())
+ .allSatisfy(child ->
assertThat(child.getValueCount()).isEqualTo(rows));
+
+ ListVector nestedArrayVector = (ListVector) vsr.getVector(3);
+
assertThat(nestedArrayVector.getDataVector().getValueCount()).isZero();
+
+ FixedSizeListVector vector = (FixedSizeListVector)
vsr.getVector(4);
+ assertThat(vector.getDataVector().getValueCount()).isEqualTo(rows
* 3);
+
+ StructVector variantVector = (StructVector) vsr.getVector(5);
+ assertThat(variantVector.getChildrenFromFields())
+ .allSatisfy(child ->
assertThat(child.getValueCount()).isEqualTo(rows));
+
+ arrayVector.validateFull();
+ rowVector.validateFull();
+ variantVector.validateFull();
+ }
+ }
+
+ @Test
+ public void testAllNullMapColumnVectorAfterNonNullBatch() {
+ RowType rowType = RowType.of(DataTypes.MAP(DataTypes.INT(),
DataTypes.INT()));
+ try (RootAllocator allocator = new RootAllocator();
+ VectorSchemaRoot vsr =
ArrowUtils.createVectorSchemaRoot(rowType, allocator)) {
+ ArrowFieldWriter fieldWriter =
ArrowUtils.createArrowFieldWriters(vsr, rowType)[0];
+
+ HeapIntVector keys = new HeapIntVector(2);
+ HeapIntVector values = new HeapIntVector(2);
+ keys.setInt(0, 1);
+ keys.setInt(1, 2);
+ values.setInt(0, 10);
+ values.setInt(1, 20);
+ HeapMapVector nonNullVector = new HeapMapVector(2, keys, values);
+ nonNullVector.putOffsetLength(0, 0, 1);
+ nonNullVector.putOffsetLength(1, 1, 1);
+
+ fieldWriter.reset();
+ fieldWriter.write(nonNullVector, null, 0, 2);
+
+ MapVector mapVector = (MapVector) vsr.getVector(0);
+ assertThat(mapVector.isNull(0)).isFalse();
+ assertThat(mapVector.isNull(1)).isFalse();
+ assertThat(mapVector.getDataVector().getValueCount()).isEqualTo(2);
+ mapVector.getDataVector().validateFull();
+
+ fieldWriter.reset();
+ fieldWriter.write(AllNullColumnVector.INSTANCE, null, 0, 3);
+
+ assertThat(mapVector.getValueCount()).isEqualTo(3);
+ assertThat(mapVector.isNull(0)).isTrue();
+ assertThat(mapVector.isNull(1)).isTrue();
+ assertThat(mapVector.isNull(2)).isTrue();
+ assertThat(mapVector.getDataVector().getValueCount()).isZero();
+ assertThat(mapVector.getDataVector().getChildrenFromFields())
+ .allSatisfy(child ->
assertThat(child.getValueCount()).isZero());
+ mapVector.getDataVector().validateFull();
+
+ fieldWriter.reset();
+ fieldWriter.write(nonNullVector, null, 0, 2);
+
+ assertThat(mapVector.isNull(0)).isFalse();
+ assertThat(mapVector.isNull(1)).isFalse();
+ assertThat(mapVector.getDataVector().getValueCount()).isEqualTo(2);
+ mapVector.getDataVector().validateFull();
+ }
+ }
+
+ @Test
+ public void testEmptyBatchDoesNotRequireTypedColumnVector() {
+ RowType rowType = RowType.of(DataTypes.MAP(DataTypes.INT(),
DataTypes.INT()));
+ try (RootAllocator allocator = new RootAllocator();
+ VectorSchemaRoot vsr =
ArrowUtils.createVectorSchemaRoot(rowType, allocator)) {
+ ArrowFieldWriter fieldWriter =
ArrowUtils.createArrowFieldWriters(vsr, rowType)[0];
+
+ fieldWriter.reset();
+ fieldWriter.write(i -> true, new int[0], 0, 0);
+
+ assertThat(vsr.getVector(0).getValueCount()).isZero();
+ }
+ }
+
@Test
public void testVectorColumnWrite() {
RowType rowType = RowType.of(DataTypes.VECTOR(3, DataTypes.FLOAT()));
diff --git
a/paimon-arrow/src/test/java/org/apache/paimon/arrow/vector/ArrowFormatWriterTest.java
b/paimon-arrow/src/test/java/org/apache/paimon/arrow/vector/ArrowFormatWriterTest.java
index b445423178..c6942e1efe 100644
---
a/paimon-arrow/src/test/java/org/apache/paimon/arrow/vector/ArrowFormatWriterTest.java
+++
b/paimon-arrow/src/test/java/org/apache/paimon/arrow/vector/ArrowFormatWriterTest.java
@@ -31,6 +31,8 @@ import org.apache.paimon.data.GenericMap;
import org.apache.paimon.data.GenericRow;
import org.apache.paimon.data.InternalRow;
import org.apache.paimon.data.Timestamp;
+import org.apache.paimon.data.columnar.AllNullColumnVector;
+import org.apache.paimon.data.columnar.ColumnarRow;
import org.apache.paimon.data.variant.GenericVariant;
import org.apache.paimon.data.variant.PaimonShreddingUtils;
import org.apache.paimon.data.variant.Variant;
@@ -148,6 +150,49 @@ public class ArrowFormatWriterTest {
}
}
+ @Test
+ public void testMissingMapColumnVectorizedRoundTrip() {
+ RowType inputRowType = RowType.builder().field("id",
DataTypes.INT()).build();
+ RowType projectedRowType =
+ RowType.builder()
+ .field("id", DataTypes.INT())
+ .field("map", DataTypes.MAP(DataTypes.STRING(),
DataTypes.INT()))
+ .build();
+
+ try (ArrowFormatWriter inputWriter = new
ArrowFormatWriter(inputRowType, 3, true);
+ ArrowFormatWriter outputWriter = new
ArrowFormatWriter(projectedRowType, 3, true)) {
+ inputWriter.write(GenericRow.of(1));
+ inputWriter.write(GenericRow.of(2));
+ inputWriter.write(GenericRow.of(3));
+ inputWriter.flush();
+
+ ArrowBatchReader reader = new ArrowBatchReader(projectedRowType,
true);
+ ColumnarRow row =
+ (ColumnarRow)
+
reader.readBatch(inputWriter.getVectorSchemaRoot()).iterator().next();
+
assertThat(row.batch().columns[1]).isSameAs(AllNullColumnVector.INSTANCE);
+
+ outputWriter.write(row.batch().columns, null, 0, 3);
+ outputWriter.flush();
+
+ VectorSchemaRoot output = outputWriter.getVectorSchemaRoot();
+ assertThat(output.getRowCount()).isEqualTo(3);
+ IntVector idVector = (IntVector) output.getVector("id");
+ assertThat(idVector.get(0)).isEqualTo(1);
+ assertThat(idVector.get(1)).isEqualTo(2);
+ assertThat(idVector.get(2)).isEqualTo(3);
+
+ MapVector mapVector = (MapVector) output.getVector("map");
+ assertThat(mapVector.isNull(0)).isTrue();
+ assertThat(mapVector.isNull(1)).isTrue();
+ assertThat(mapVector.isNull(2)).isTrue();
+ assertThat(mapVector.getDataVector().getValueCount()).isZero();
+ assertThat(mapVector.getDataVector().getChildrenFromFields())
+ .allSatisfy(child ->
assertThat(child.getValueCount()).isZero());
+ mapVector.getDataVector().validateFull();
+ }
+ }
+
@Test
public void testWriteVector() {
RowType rowType =
diff --git
a/paimon-common/src/main/java/org/apache/paimon/data/columnar/AllNullColumnVector.java
b/paimon-common/src/main/java/org/apache/paimon/data/columnar/AllNullColumnVector.java
new file mode 100644
index 0000000000..9be608dc57
--- /dev/null
+++
b/paimon-common/src/main/java/org/apache/paimon/data/columnar/AllNullColumnVector.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.paimon.data.columnar;
+
+/** A singleton column vector whose values are all null. */
+public final class AllNullColumnVector implements ColumnVector {
+
+ public static final AllNullColumnVector INSTANCE = new
AllNullColumnVector();
+
+ private AllNullColumnVector() {}
+
+ @Override
+ public boolean isNullAt(int i) {
+ return true;
+ }
+}
diff --git
a/paimon-common/src/main/java/org/apache/paimon/utils/VectorMappingUtils.java
b/paimon-common/src/main/java/org/apache/paimon/utils/VectorMappingUtils.java
index 99e8fd455c..54007caaf8 100644
---
a/paimon-common/src/main/java/org/apache/paimon/utils/VectorMappingUtils.java
+++
b/paimon-common/src/main/java/org/apache/paimon/utils/VectorMappingUtils.java
@@ -26,6 +26,7 @@ import org.apache.paimon.data.InternalRow;
import org.apache.paimon.data.InternalVector;
import org.apache.paimon.data.PartitionInfo;
import org.apache.paimon.data.Timestamp;
+import org.apache.paimon.data.columnar.AllNullColumnVector;
import org.apache.paimon.data.columnar.ArrayColumnVector;
import org.apache.paimon.data.columnar.BooleanColumnVector;
import org.apache.paimon.data.columnar.ByteColumnVector;
@@ -109,7 +110,7 @@ public class VectorMappingUtils {
if (realIndex >= 0) {
newVectors[i] = vectors[indexMapping[i]];
} else {
- newVectors[i] = index -> true;
+ newVectors[i] = AllNullColumnVector.INSTANCE;
}
}
return newVectors;
diff --git
a/paimon-common/src/test/java/org/apache/paimon/utils/VectorMappingUtilsTest.java
b/paimon-common/src/test/java/org/apache/paimon/utils/VectorMappingUtilsTest.java
index 34488c61e1..29be76a89d 100644
---
a/paimon-common/src/test/java/org/apache/paimon/utils/VectorMappingUtilsTest.java
+++
b/paimon-common/src/test/java/org/apache/paimon/utils/VectorMappingUtilsTest.java
@@ -24,6 +24,7 @@ import org.apache.paimon.data.BinaryString;
import org.apache.paimon.data.BinaryVector;
import org.apache.paimon.data.PartitionInfo;
import org.apache.paimon.data.Timestamp;
+import org.apache.paimon.data.columnar.AllNullColumnVector;
import org.apache.paimon.data.columnar.BooleanColumnVector;
import org.apache.paimon.data.columnar.ByteColumnVector;
import org.apache.paimon.data.columnar.BytesColumnVector;
@@ -92,6 +93,19 @@ public class VectorMappingUtilsTest {
}
}
+ @Test
+ public void testCreateIndexMappedVectorsWithMissingColumns() {
+ ColumnVector existingVector = i -> false;
+
+ ColumnVector[] newColumnVectors =
+ VectorMappingUtils.createMappedVectors(
+ new int[] {-1, 0, -1}, new ColumnVector[]
{existingVector});
+
+ Assertions.assertThat(newColumnVectors)
+ .containsExactly(
+ AllNullColumnVector.INSTANCE, existingVector,
AllNullColumnVector.INSTANCE);
+ }
+
@Test
public void testForType() {
RowType rowType =
diff --git
a/paimon-core/src/test/java/org/apache/paimon/arrow/converter/ArrowBatchConverterTest.java
b/paimon-core/src/test/java/org/apache/paimon/arrow/converter/ArrowBatchConverterTest.java
index 96470b72ee..b3ff49d047 100644
---
a/paimon-core/src/test/java/org/apache/paimon/arrow/converter/ArrowBatchConverterTest.java
+++
b/paimon-core/src/test/java/org/apache/paimon/arrow/converter/ArrowBatchConverterTest.java
@@ -39,6 +39,7 @@ import org.apache.paimon.reader.FileRecordIterator;
import org.apache.paimon.reader.RecordReader;
import org.apache.paimon.reader.VectorizedRecordIterator;
import org.apache.paimon.schema.Schema;
+import org.apache.paimon.schema.SchemaChange;
import org.apache.paimon.table.FileStoreTable;
import org.apache.paimon.table.sink.StreamTableCommit;
import org.apache.paimon.table.sink.StreamTableWrite;
@@ -341,6 +342,61 @@ public class ArrowBatchConverterTest {
}
}
+ @TestTemplate
+ public void testSchemaEvolutionWithMissingMapType() throws Exception {
+ assumeThat(testMode).isEqualTo("vectorized_without_dv");
+
+ RowType initialRowType = RowType.builder().field("id",
DataTypes.INT()).build();
+ Map<String, String> options = new HashMap<>();
+ options.put(CoreOptions.FILE_FORMAT.key(), "orc");
+ Schema schema =
+ new Schema(
+ initialRowType.getFields(),
+ Collections.emptyList(),
+ Collections.emptyList(),
+ options,
+ "");
+ Identifier identifier = Identifier.create("default",
UUID.randomUUID().toString());
+ catalog.createTable(identifier, schema, false);
+
+ FileStoreTable table = (FileStoreTable) catalog.getTable(identifier);
+ try (StreamTableWrite write = table.newStreamWriteBuilder().newWrite();
+ StreamTableCommit commit =
table.newStreamWriteBuilder().newCommit()) {
+ write.withIOManager(new IOManagerImpl(tempDir.toString()));
+ write.write(GenericRow.of(1));
+ commit.commit(0, write.prepareCommit(false, 0));
+ }
+
+ catalog.alterTable(
+ identifier,
+ SchemaChange.addColumn("map",
DataTypes.MAP(DataTypes.STRING(), DataTypes.INT())),
+ false);
+ table = (FileStoreTable) catalog.getTable(identifier);
+ RowType evolvedRowType = table.rowType();
+
+ RecordReader.RecordIterator<InternalRow> iterator =
+
table.newRead().createReader(table.newReadBuilder().newScan().plan()).readBatch();
+ assertThat(iterator).isInstanceOf(VectorizedRecordIterator.class);
+
+ try (RootAllocator allocator = new RootAllocator()) {
+ VectorSchemaRoot vsr =
ArrowUtils.createVectorSchemaRoot(evolvedRowType, allocator);
+ ArrowBatchConverter arrowWriter = createArrowWriter(iterator,
evolvedRowType, vsr);
+ arrowWriter.next(1);
+
+ assertThat(vsr.getRowCount()).isEqualTo(1);
+ assertThat(((IntVector) vsr.getVector("id")).get(0)).isEqualTo(1);
+
+ MapVector mapVector = (MapVector) vsr.getVector("map");
+ assertThat(mapVector.isNull(0)).isTrue();
+ assertThat(mapVector.getDataVector().getValueCount()).isZero();
+ assertThat(mapVector.getDataVector().getChildrenFromFields())
+ .allSatisfy(child ->
assertThat(child.getValueCount()).isZero());
+ mapVector.getDataVector().validateFull();
+
+ arrowWriter.close();
+ }
+ }
+
@TestTemplate
public void testMapRowType() throws Exception {
testDv(false);