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 36ce7c97ee [flink] Preserve vector layouts in schema-aware row 
conversion (#10677)
36ce7c97ee is described below

commit 36ce7c97ee2090d7cfc72c1f7e055cca892f12ba
Author: Jingsong Lee <[email protected]>
AuthorDate: Tue Oct 20 12:27:20 2026 +0800

    [flink] Preserve vector layouts in schema-aware row conversion (#10677)
---
 .../java/org/apache/paimon/flink/FlinkRowData.java | 76 +++++++++++++++++++---
 .../flink/compact/IncrementalClusterCompact.java   |  2 +-
 .../org/apache/paimon/flink/sorter/SortUtils.java  |  2 +-
 .../paimon/flink/FlinkRowDataWithVectorTest.java   | 75 +++++++++++++++++++++
 4 files changed, 144 insertions(+), 11 deletions(-)

diff --git 
a/paimon-flink/paimon-flink-common/src/main/java/org/apache/paimon/flink/FlinkRowData.java
 
b/paimon-flink/paimon-flink-common/src/main/java/org/apache/paimon/flink/FlinkRowData.java
index 2016ab4bf4..8db5c7d9e0 100644
--- 
a/paimon-flink/paimon-flink-common/src/main/java/org/apache/paimon/flink/FlinkRowData.java
+++ 
b/paimon-flink/paimon-flink-common/src/main/java/org/apache/paimon/flink/FlinkRowData.java
@@ -24,6 +24,12 @@ import org.apache.paimon.data.InternalArray;
 import org.apache.paimon.data.InternalMap;
 import org.apache.paimon.data.InternalRow;
 import org.apache.paimon.data.Timestamp;
+import org.apache.paimon.types.ArrayType;
+import org.apache.paimon.types.DataType;
+import org.apache.paimon.types.MapType;
+import org.apache.paimon.types.MultisetType;
+import org.apache.paimon.types.RowType;
+import org.apache.paimon.types.VectorType;
 
 import org.apache.flink.table.data.ArrayData;
 import org.apache.flink.table.data.DecimalData;
@@ -36,15 +42,23 @@ import org.apache.flink.types.RowKind;
 import org.apache.flink.types.variant.BinaryVariant;
 import org.apache.flink.types.variant.Variant;
 
+import javax.annotation.Nullable;
+
 import static org.apache.paimon.flink.FlinkRowWrapper.fromFlinkRowKind;
 
 /** Convert to Flink row data. */
 public class FlinkRowData implements RowData {
 
     protected InternalRow row;
+    @Nullable private final RowType rowType;
 
     public FlinkRowData(InternalRow row) {
+        this(row, null);
+    }
+
+    public FlinkRowData(InternalRow row, @Nullable RowType rowType) {
         this.row = row;
+        this.rowType = rowType;
     }
 
     public FlinkRowData replace(InternalRow row) {
@@ -134,17 +148,39 @@ public class FlinkRowData implements RowData {
 
     @Override
     public ArrayData getArray(int pos) {
-        return new FlinkArrayData(row.getArray(pos));
+        // VECTOR and ARRAY have different binary layouts even though Flink 
exposes both as ARRAY.
+        DataType type = fieldType(pos);
+        return new FlinkArrayData(
+                type instanceof VectorType ? row.getVector(pos) : 
row.getArray(pos),
+                arrayElementType(type));
     }
 
     @Override
     public MapData getMap(int pos) {
-        return new FlinkMapData(row.getMap(pos));
+        return new FlinkMapData(row.getMap(pos), fieldType(pos));
     }
 
     @Override
     public RowData getRow(int pos, int numFields) {
-        return new FlinkRowData(row.getRow(pos, numFields));
+        DataType type = fieldType(pos);
+        return new FlinkRowData(
+                row.getRow(pos, numFields), type instanceof RowType ? 
(RowType) type : null);
+    }
+
+    @Nullable
+    private DataType fieldType(int pos) {
+        return rowType == null ? null : rowType.getTypeAt(pos);
+    }
+
+    @Nullable
+    private static DataType arrayElementType(@Nullable DataType type) {
+        if (type instanceof ArrayType) {
+            return ((ArrayType) type).getElementType();
+        }
+        if (type instanceof VectorType) {
+            return ((VectorType) type).getElementType();
+        }
+        return null;
     }
 
     public Variant getVariant(int pos) {
@@ -156,9 +192,15 @@ public class FlinkRowData implements RowData {
     protected static class FlinkArrayData implements ArrayData {
 
         private final InternalArray array;
+        @Nullable private final DataType elementType;
 
         protected FlinkArrayData(InternalArray array) {
+            this(array, null);
+        }
+
+        private FlinkArrayData(InternalArray array, @Nullable DataType 
elementType) {
             this.array = array;
+            this.elementType = elementType;
         }
 
         @Override
@@ -238,17 +280,21 @@ public class FlinkRowData implements RowData {
 
         @Override
         public ArrayData getArray(int pos) {
-            return new FlinkArrayData(array.getArray(pos));
+            return new FlinkArrayData(
+                    elementType instanceof VectorType ? array.getVector(pos) : 
array.getArray(pos),
+                    arrayElementType(elementType));
         }
 
         @Override
         public MapData getMap(int pos) {
-            return new FlinkMapData(array.getMap(pos));
+            return new FlinkMapData(array.getMap(pos), elementType);
         }
 
         @Override
         public RowData getRow(int pos, int numFields) {
-            return new FlinkRowData(array.getRow(pos, numFields));
+            return new FlinkRowData(
+                    array.getRow(pos, numFields),
+                    elementType instanceof RowType ? (RowType) elementType : 
null);
         }
 
         @Override
@@ -290,9 +336,21 @@ public class FlinkRowData implements RowData {
     private static class FlinkMapData implements MapData {
 
         private final InternalMap map;
+        @Nullable private final DataType keyType;
+        @Nullable private final DataType valueType;
 
-        private FlinkMapData(InternalMap map) {
+        private FlinkMapData(InternalMap map, @Nullable DataType type) {
             this.map = map;
+            if (type instanceof MapType) {
+                this.keyType = ((MapType) type).getKeyType();
+                this.valueType = ((MapType) type).getValueType();
+            } else {
+                this.keyType =
+                        type instanceof MultisetType
+                                ? ((MultisetType) type).getElementType()
+                                : null;
+                this.valueType = null;
+            }
         }
 
         @Override
@@ -302,12 +360,12 @@ public class FlinkRowData implements RowData {
 
         @Override
         public ArrayData keyArray() {
-            return new FlinkArrayData(map.keyArray());
+            return new FlinkArrayData(map.keyArray(), keyType);
         }
 
         @Override
         public ArrayData valueArray() {
-            return new FlinkArrayData(map.valueArray());
+            return new FlinkArrayData(map.valueArray(), valueType);
         }
     }
 
diff --git 
a/paimon-flink/paimon-flink-common/src/main/java/org/apache/paimon/flink/compact/IncrementalClusterCompact.java
 
b/paimon-flink/paimon-flink-common/src/main/java/org/apache/paimon/flink/compact/IncrementalClusterCompact.java
index 25d43ddbc6..a4f25486e1 100644
--- 
a/paimon-flink/paimon-flink-common/src/main/java/org/apache/paimon/flink/compact/IncrementalClusterCompact.java
+++ 
b/paimon-flink/paimon-flink-common/src/main/java/org/apache/paimon/flink/compact/IncrementalClusterCompact.java
@@ -319,7 +319,7 @@ public class IncrementalClusterCompact {
                         },
                         InternalTypeInfo.fromRowType(rowType))
                 .setParallelism(sinkParallelism)
-                .map(FlinkRowData::new, input.getType())
+                .map(row -> new FlinkRowData(row, rowType), input.getType())
                 .setParallelism(sinkParallelism);
     }
 
diff --git 
a/paimon-flink/paimon-flink-common/src/main/java/org/apache/paimon/flink/sorter/SortUtils.java
 
b/paimon-flink/paimon-flink-common/src/main/java/org/apache/paimon/flink/sorter/SortUtils.java
index c841afa3f5..adfb5c60d5 100644
--- 
a/paimon-flink/paimon-flink-common/src/main/java/org/apache/paimon/flink/sorter/SortUtils.java
+++ 
b/paimon-flink/paimon-flink-common/src/main/java/org/apache/paimon/flink/sorter/SortUtils.java
@@ -201,7 +201,7 @@ public class SortUtils {
                             },
                             InternalTypeInfo.fromRowType(valueRowType))
                     .setParallelism(sinkParallelism)
-                    .map(FlinkRowData::new, inputStream.getType())
+                    .map(row -> new FlinkRowData(row, valueRowType), 
inputStream.getType())
                     .setParallelism(sinkParallelism);
         } else {
             return rangeShuffleResult
diff --git 
a/paimon-flink/paimon-flink-common/src/test/java/org/apache/paimon/flink/FlinkRowDataWithVectorTest.java
 
b/paimon-flink/paimon-flink-common/src/test/java/org/apache/paimon/flink/FlinkRowDataWithVectorTest.java
index ba8542d395..63317299bd 100644
--- 
a/paimon-flink/paimon-flink-common/src/test/java/org/apache/paimon/flink/FlinkRowDataWithVectorTest.java
+++ 
b/paimon-flink/paimon-flink-common/src/test/java/org/apache/paimon/flink/FlinkRowDataWithVectorTest.java
@@ -18,13 +18,23 @@
 
 package org.apache.paimon.flink;
 
+import org.apache.paimon.data.BinaryRow;
 import org.apache.paimon.data.BinaryVector;
+import org.apache.paimon.data.GenericArray;
+import org.apache.paimon.data.GenericMap;
 import org.apache.paimon.data.GenericRow;
 import org.apache.paimon.data.InternalRow;
+import org.apache.paimon.data.serializer.InternalRowSerializer;
+import org.apache.paimon.types.DataTypes;
+import org.apache.paimon.types.RowType;
+import org.apache.paimon.utils.KeyProjectedRow;
 
 import org.apache.flink.table.data.ArrayData;
+import org.apache.flink.table.data.MapData;
 import org.junit.jupiter.api.Test;
 
+import java.util.Collections;
+
 import static org.assertj.core.api.Assertions.assertThat;
 
 /** Tests for {@link FlinkRowData} and vector type. */
@@ -41,6 +51,71 @@ public class FlinkRowDataWithVectorTest {
         assertThat(arrayData.toFloatArray()).isEqualTo(values);
     }
 
+    @Test
+    public void testBinaryVectorAndArrayAsArrayData() {
+        float[] vector = new float[] {0.0f, 1.0f, 2.0f};
+        float[] array = new float[] {3.0f, 4.0f};
+        RowType rowType =
+                DataTypes.ROW(
+                        DataTypes.VECTOR(3, DataTypes.FLOAT()), 
DataTypes.ARRAY(DataTypes.FLOAT()));
+        BinaryRow row =
+                new InternalRowSerializer(rowType)
+                        .toBinaryRow(
+                                GenericRow.of(
+                                        
BinaryVector.fromPrimitiveArray(vector),
+                                        new GenericArray(array)));
+
+        FlinkRowData rowData = new FlinkRowData(row, rowType);
+
+        assertThat(rowData.getArray(0).toFloatArray()).isEqualTo(vector);
+        assertThat(rowData.getArray(1).toFloatArray()).isEqualTo(array);
+    }
+
+    @Test
+    public void testProjectedBinaryVectorAsArrayData() {
+        float[] vector = new float[] {0.0f, 1.0f, 2.0f};
+        RowType valueType = DataTypes.ROW(DataTypes.VECTOR(3, 
DataTypes.FLOAT()));
+        BinaryRow sortedRow =
+                new InternalRowSerializer(DataTypes.INT(), 
valueType.getTypeAt(0))
+                        .toBinaryRow(GenericRow.of(5, 
BinaryVector.fromPrimitiveArray(vector)));
+        KeyProjectedRow projected = new KeyProjectedRow(new int[] 
{1}).replaceRow(sortedRow);
+
+        assertThat(new FlinkRowData(projected, 
valueType).getArray(0).toFloatArray())
+                .isEqualTo(vector);
+    }
+
+    @Test
+    public void testNestedBinaryVectorsAsArrayData() {
+        float[] values = new float[] {0.0f, 1.0f, 2.0f};
+        BinaryVector vector = BinaryVector.fromPrimitiveArray(values);
+        RowType nestedRowType = DataTypes.ROW(DataTypes.VECTOR(3, 
DataTypes.FLOAT()));
+        RowType rowType =
+                DataTypes.ROW(
+                        nestedRowType,
+                        DataTypes.ARRAY(nestedRowType),
+                        DataTypes.MAP(
+                                nestedRowType.getTypeAt(0),
+                                DataTypes.ARRAY(nestedRowType.getTypeAt(0))));
+        BinaryRow row =
+                new InternalRowSerializer(rowType)
+                        .toBinaryRow(
+                                GenericRow.of(
+                                        GenericRow.of(vector),
+                                        new GenericArray(new Object[] 
{GenericRow.of(vector)}),
+                                        new GenericMap(
+                                                Collections.singletonMap(
+                                                        vector,
+                                                        new GenericArray(new 
Object[] {vector})))));
+
+        FlinkRowData rowData = new FlinkRowData(row, rowType);
+
+        assertThat(rowData.getRow(0, 
1).getArray(0).toFloatArray()).isEqualTo(values);
+        assertThat(rowData.getArray(1).getRow(0, 
1).getArray(0).toFloatArray()).isEqualTo(values);
+        MapData map = rowData.getMap(2);
+        
assertThat(map.keyArray().getArray(0).toFloatArray()).isEqualTo(values);
+        
assertThat(map.valueArray().getArray(0).getArray(0).toFloatArray()).isEqualTo(values);
+    }
+
     @Test
     public void testNullVector() {
         InternalRow row = GenericRow.of(1, null);

Reply via email to