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 9d3d6e058d [core] Fix dropping stats in data evolution scan (#8994)
9d3d6e058d is described below

commit 9d3d6e058dbe334ab3d29f92c9b3415b871f51f7
Author: YeJunHao <[email protected]>
AuthorDate: Wed Aug 5 13:18:16 2026 +0800

    [core] Fix dropping stats in data evolution scan (#8994)
---
 .../operation/DataEvolutionFileStoreScan.java      | 31 ++++++++++++----------
 .../paimon/table/DataEvolutionTableTest.java       | 21 ++++++++++-----
 2 files changed, 32 insertions(+), 20 deletions(-)

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 06cde74f1f..66f1aadbee 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
@@ -181,24 +181,27 @@ public class DataEvolutionFileStoreScan extends 
AppendOnlyFileStoreScan {
 
     @Override
     protected boolean postFilterManifestEntriesEnabled() {
-        // Always enable post-filtering. The list filterByStats handles 
predicate-based pruning
-        // and pruneByReadType strips per-file columns that are not requested 
— both
-        // need row-id-range grouping that single filterByStats(ManifestEntry) 
cannot see.
-        return inputFilter != null || readType != null;
+        return true;
     }
 
     @Override
     protected List<ManifestEntry> 
postFilterManifestEntries(List<ManifestEntry> entries) {
-        // group by row id range
-        RangeHelper<ManifestEntry> rangeHelper =
-                new RangeHelper<>(e -> e.file().nonNullRowIdRange());
-        List<List<ManifestEntry>> splitByRowId = 
rangeHelper.mergeOverlappingRanges(entries);
-
-        return splitByRowId.stream()
-                .filter(group -> inputFilter == null || filterByStats(group))
-                .flatMap(group -> pruneByReadType(group).stream())
-                .map(entry -> dropStats ? dropStats(entry) : entry)
-                .collect(Collectors.toList());
+        if (inputFilter != null || readType != null) {
+            // group by row id range
+            RangeHelper<ManifestEntry> rangeHelper =
+                    new RangeHelper<>(e -> e.file().nonNullRowIdRange());
+            List<List<ManifestEntry>> splitByRowId = 
rangeHelper.mergeOverlappingRanges(entries);
+
+            return splitByRowId.stream()
+                    .filter(group -> inputFilter == null || 
filterByStats(group))
+                    .flatMap(group -> pruneByReadType(group).stream())
+                    .map(entry -> dropStats ? dropStats(entry) : entry)
+                    .collect(Collectors.toList());
+        } else if (dropStats) {
+            return 
entries.stream().map(this::dropStats).collect(Collectors.toList());
+        } else {
+            return entries;
+        }
     }
 
     private boolean filterByStats(List<ManifestEntry> entries) {
diff --git 
a/paimon-core/src/test/java/org/apache/paimon/table/DataEvolutionTableTest.java 
b/paimon-core/src/test/java/org/apache/paimon/table/DataEvolutionTableTest.java
index 4f080f9667..592dcf687c 100644
--- 
a/paimon-core/src/test/java/org/apache/paimon/table/DataEvolutionTableTest.java
+++ 
b/paimon-core/src/test/java/org/apache/paimon/table/DataEvolutionTableTest.java
@@ -70,6 +70,7 @@ import java.util.OptionalLong;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.stream.Collectors;
 
+import static org.apache.paimon.stats.SimpleStats.EMPTY_STATS;
 import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
 
 /** Test for table with data evolution. */
@@ -2096,12 +2097,7 @@ public class DataEvolutionTableTest extends 
DataEvolutionTestBase {
         assertThat(plannedFileCount(table, readF2, null)).isEqualTo(2);
     }
 
-    /**
-     * System-field-only projection is filtered out of readType in
-     * DataEvolutionFileStoreScan.withReadType — readType stays null and
-     * postFilterManifestEntriesEnabled returns false. The column-pruning path 
is not entered, so
-     * every file in every group flows through unchanged.
-     */
+    /** System-field-only projection is not used for per-file column pruning. 
*/
     @Test
     public void testSystemFieldOnlyProjectionIsNotPruned() throws Exception {
         write(5);
@@ -2110,6 +2106,19 @@ public class DataEvolutionTableTest extends 
DataEvolutionTestBase {
         assertThat(plannedFileCount(table, RowType.of(SpecialFields.ROW_ID), 
null)).isEqualTo(2);
     }
 
+    @Test
+    public void testDropStatsWithoutFilterOrReadType() throws Exception {
+        write(5);
+
+        List<ManifestEntry> entries =
+                getTableDefault().store().newScan().dropStats().plan().files();
+
+        assertThat(entries.isEmpty()).isFalse();
+        for (ManifestEntry entry : entries) {
+            assertThat(entry.file().valueStats()).isEqualTo(EMPTY_STATS);
+        }
+    }
+
     private List<DataFileMeta> 
writeOneFullRowAndCollectNewFiles(FileStoreTable table)
             throws Exception {
         Schema schema = schemaDefault();

Reply via email to