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 e069a756ca [core] Fix data evolution scan pruning files after a column 
type change (#8843)
e069a756ca is described below

commit e069a756ca454318b55802b56e011ab95b6a0f8b
Author: Arnav Balyan <[email protected]>
AuthorDate: Sun Jul 26 12:46:05 2026 +0530

    [core] Fix data evolution scan pruning files after a column type change 
(#8843)
---
 .../operation/DataEvolutionFileStoreScan.java      |  6 ++-
 .../operation/DataEvolutionFileStoreScanTest.java  | 43 ++++++++++++++++++++++
 2 files changed, 48 insertions(+), 1 deletion(-)

diff --git 
a/paimon-core/src/main/java/org/apache/paimon/operation/DataEvolutionFileStoreScan.java
 
b/paimon-core/src/main/java/org/apache/paimon/operation/DataEvolutionFileStoreScan.java
index e097b3be53..06cde74f1f 100644
--- 
a/paimon-core/src/main/java/org/apache/paimon/operation/DataEvolutionFileStoreScan.java
+++ 
b/paimon-core/src/main/java/org/apache/paimon/operation/DataEvolutionFileStoreScan.java
@@ -303,6 +303,7 @@ public class DataEvolutionFileStoreScan extends 
AppendOnlyFileStoreScan {
         int[] fieldOffsets = new int[fieldsCount];
         Arrays.fill(rowOffsets, -1);
         Arrays.fill(fieldOffsets, -1);
+        Set<Integer> typeMismatchedFieldIds = new HashSet<>();
 
         InternalRow[] min = new InternalRow[metas.size()];
         InternalRow[] max = new InternalRow[metas.size()];
@@ -346,6 +347,7 @@ public class DataEvolutionFileStoreScan extends 
AppendOnlyFileStoreScan {
                             if (fieldId == fieldIdsWithStats[k]) {
                                 DataType fileType = 
dataFileSchemaWithStats.fields().get(k).type();
                                 if (!fileType.equalsIgnoreFieldId(targetType)) 
{
+                                    typeMismatchedFieldIds.add(targetFieldId);
                                     continue loop1;
                                 }
                                 rowOffsets[j] = i;
@@ -362,7 +364,9 @@ public class DataEvolutionFileStoreScan extends 
AppendOnlyFileStoreScan {
 
         long groupRowCount = metas.get(0).file().rowCount();
         for (int j = 0; j < fieldsCount; j++) {
-            if (rowOffsets[j] == -1 && 
excludedFileFieldIds.contains(allFields[j])) {
+            if (rowOffsets[j] == -1
+                    && (excludedFileFieldIds.contains(allFields[j])
+                            || typeMismatchedFieldIds.contains(allFields[j]))) 
{
                 rowOffsets[j] = -2;
             }
         }
diff --git 
a/paimon-core/src/test/java/org/apache/paimon/operation/DataEvolutionFileStoreScanTest.java
 
b/paimon-core/src/test/java/org/apache/paimon/operation/DataEvolutionFileStoreScanTest.java
index ee10f5b6d5..21fbcf629a 100644
--- 
a/paimon-core/src/test/java/org/apache/paimon/operation/DataEvolutionFileStoreScanTest.java
+++ 
b/paimon-core/src/test/java/org/apache/paimon/operation/DataEvolutionFileStoreScanTest.java
@@ -312,6 +312,49 @@ public class DataEvolutionFileStoreScanTest {
         assertThat(maxRow.getString(0).toString()).isEqualTo("yam");
     }
 
+    @Test
+    public void testTypeChangedColumnMustNotPrunePreAlterFiles() {
+        Schema baseSchema = createSchema("f0", "f1");
+        schemas.put(0L, TableSchema.create(0L, baseSchema));
+
+        Schema evolvedSchema =
+                Schema.newBuilder()
+                        .column("f0", DataTypes.BIGINT())
+                        .column("f1", DataTypes.STRING())
+                        .build();
+        TableSchema evolvedTableSchema = TableSchema.create(1L, evolvedSchema);
+        schemas.put(1L, evolvedTableSchema);
+
+        ManifestEntry preAlterFile =
+                createManifestEntry(
+                        0L,
+                        createSimpleStats(
+                                GenericRow.of(10, 
BinaryString.fromString("a")),
+                                GenericRow.of(99, 
BinaryString.fromString("z")),
+                                createBinaryArray(new int[] {0, 0}),
+                                new int[] {0, 1}));
+
+        EvolutionStats result =
+                DataEvolutionFileStoreScan.evolutionStats(
+                        evolvedTableSchema,
+                        scanTableSchema,
+                        Collections.singletonList(preAlterFile));
+
+        Predicate onChangedColumn =
+                new 
PredicateBuilder(evolvedTableSchema.logicalRowType()).equal(0, 50L);
+
+        boolean keepFile =
+                onChangedColumn.test(
+                        result.rowCount(),
+                        result.minValues(),
+                        result.maxValues(),
+                        result.nullCounts());
+
+        assertThat(keepFile)
+                .as("pre-ALTER file must not be pruned by a predicate on a 
type-changed column")
+                .isTrue();
+    }
+
     @Test
     public void testEvolutionStatsKeepDedicatedVectorFieldAsUnknown() {
         Schema schema = createSchema("f0", "f1", "f2");

Reply via email to