This is an automated email from the ASF dual-hosted git repository.

leaves12138 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 3cd37e7131 [core] Fix format table date partition pruning (#8011)
3cd37e7131 is described below

commit 3cd37e7131a701a1fbaf0dffdb7e2691951f676c
Author: YeJunHao <[email protected]>
AuthorDate: Thu May 28 17:47:01 2026 +0800

    [core] Fix format table date partition pruning (#8011)
---
 .../paimon/table/format/FormatTableScan.java       | 27 ++++++++++++++--
 .../paimon/table/format/FormatTableScanTest.java   | 37 ++++++++++++++++++----
 2 files changed, 55 insertions(+), 9 deletions(-)

diff --git 
a/paimon-core/src/main/java/org/apache/paimon/table/format/FormatTableScan.java 
b/paimon-core/src/main/java/org/apache/paimon/table/format/FormatTableScan.java
index 9a561a6bd1..9bbd64ccdf 100644
--- 
a/paimon-core/src/main/java/org/apache/paimon/table/format/FormatTableScan.java
+++ 
b/paimon-core/src/main/java/org/apache/paimon/table/format/FormatTableScan.java
@@ -19,7 +19,10 @@
 package org.apache.paimon.table.format;
 
 import org.apache.paimon.CoreOptions;
+import org.apache.paimon.casting.CastExecutor;
+import org.apache.paimon.casting.CastExecutors;
 import org.apache.paimon.data.BinaryRow;
+import org.apache.paimon.data.BinaryString;
 import org.apache.paimon.data.GenericRow;
 import org.apache.paimon.data.serializer.InternalRowSerializer;
 import org.apache.paimon.format.csv.CsvOptions;
@@ -43,7 +46,9 @@ import 
org.apache.paimon.table.format.predicate.PredicateUtils;
 import org.apache.paimon.table.source.InnerTableScan;
 import org.apache.paimon.table.source.Split;
 import org.apache.paimon.table.source.TableScan;
+import org.apache.paimon.types.DataType;
 import org.apache.paimon.types.RowType;
+import org.apache.paimon.types.VarCharType;
 import org.apache.paimon.utils.InternalRowPartitionComputer;
 import org.apache.paimon.utils.Pair;
 import org.apache.paimon.utils.PartitionPathUtils;
@@ -245,7 +250,8 @@ public class FormatTableScan implements InnerTableScan {
                 Map<String, String> equalityPrefix =
                         extractLeadingEqualityPartitionSpecWhenOnlyAnd(
                                 partitionKeys,
-                                ((DefaultPartitionPredicate) 
partitionFilter).predicate());
+                                ((DefaultPartitionPredicate) 
partitionFilter).predicate(),
+                                partitionType);
                 if (!equalityPrefix.isEmpty()) {
                     // Use optimized scan for specific partition path
                     String partitionPath =
@@ -313,7 +319,7 @@ public class FormatTableScan implements InnerTableScan {
     }
 
     public static Map<String, String> 
extractLeadingEqualityPartitionSpecWhenOnlyAnd(
-            List<String> partitionKeys, Predicate predicate) {
+            List<String> partitionKeys, Predicate predicate, RowType 
partitionType) {
         List<Predicate> predicates = PredicateBuilder.splitAnd(predicate);
         Map<String, String> equals = new HashMap<>();
         for (Predicate sub : predicates) {
@@ -324,7 +330,10 @@ public class FormatTableScan implements InnerTableScan {
                     LeafFunction function = ((LeafPredicate) sub).function();
                     String field = fieldRef.name();
                     if (function instanceof Equal && 
partitionKeys.contains(field)) {
-                        equals.put(field, ((LeafPredicate) 
sub).literals().get(0).toString());
+                        equals.put(
+                                field,
+                                partitionLiteralToString(
+                                        fieldRef.type(), ((LeafPredicate) 
sub).literals().get(0)));
                     }
                 }
             }
@@ -339,4 +348,16 @@ public class FormatTableScan implements InnerTableScan {
         }
         return result;
     }
+
+    private static String partitionLiteralToString(DataType type, Object 
literal) {
+        if (literal == null) {
+            return null;
+        }
+
+        CastExecutor<Object, BinaryString> executor =
+                (CastExecutor<Object, BinaryString>)
+                        CastExecutors.resolve(type, VarCharType.STRING_TYPE);
+        BinaryString value = executor.cast(literal);
+        return value == null ? null : value.toString();
+    }
 }
diff --git 
a/paimon-core/src/test/java/org/apache/paimon/table/format/FormatTableScanTest.java
 
b/paimon-core/src/test/java/org/apache/paimon/table/format/FormatTableScanTest.java
index e6602fb716..cda08b61e7 100644
--- 
a/paimon-core/src/test/java/org/apache/paimon/table/format/FormatTableScanTest.java
+++ 
b/paimon-core/src/test/java/org/apache/paimon/table/format/FormatTableScanTest.java
@@ -237,6 +237,31 @@ public class FormatTableScanTest {
         assertThat(searched.size()).isEqualTo(1);
     }
 
+    @TestTemplate
+    void testComputeScanPathWithDateEqualityFilter() {
+        Path tableLocation = new Path(tmpPath.toUri());
+        RowType datePartitionType = RowType.builder().field("dt", 
DataTypes.DATE()).build();
+        List<String> datePartitionKeys = datePartitionType.getFieldNames();
+
+        PredicateBuilder builder = new PredicateBuilder(datePartitionType);
+        Predicate equalityPredicate =
+                builder.equal(0, (int) 
java.time.LocalDate.parse("2026-05-01").toEpochDay());
+        PartitionPredicate partitionFilter =
+                PartitionPredicate.fromPredicate(datePartitionType, 
equalityPredicate);
+
+        Pair<Path, Integer> result =
+                FormatTableScan.computeScanPathAndLevel(
+                        tableLocation,
+                        datePartitionKeys,
+                        partitionFilter,
+                        datePartitionType,
+                        enablePartitionValueOnly);
+        String partitionPath = enablePartitionValueOnly ? "2026-05-01" : 
"dt=2026-05-01";
+
+        assertThat(result.getLeft().toString()).isEqualTo(tableLocation + 
partitionPath);
+        assertThat(result.getRight()).isEqualTo(0);
+    }
+
     @TestTemplate
     void testComputeScanPathWithFirstLevel() throws IOException {
         Path tableLocation = new Path(tmpPath.toUri());
@@ -554,7 +579,7 @@ public class FormatTableScanTest {
 
         Map<String, String> result =
                 FormatTableScan.extractLeadingEqualityPartitionSpecWhenOnlyAnd(
-                        partitionKeys, equalityPredicate);
+                        partitionKeys, equalityPredicate, type);
 
         assertThat(result).hasSize(3);
         assertThat(result.get("year")).isEqualTo("2023");
@@ -581,7 +606,7 @@ public class FormatTableScanTest {
 
         Map<String, String> result =
                 FormatTableScan.extractLeadingEqualityPartitionSpecWhenOnlyAnd(
-                        partitionKeys, mixedPredicate);
+                        partitionKeys, mixedPredicate, type);
 
         assertThat(result).isNotNull();
         assertThat(result).hasSize(2);
@@ -609,7 +634,7 @@ public class FormatTableScanTest {
 
         Map<String, String> result =
                 FormatTableScan.extractLeadingEqualityPartitionSpecWhenOnlyAnd(
-                        partitionKeys, mixedPredicate);
+                        partitionKeys, mixedPredicate, type);
         assertThat(result).hasSize(1);
         assertThat(result.get("year")).isEqualTo("2023");
         assertThat(result.containsKey("month")).isFalse();
@@ -635,7 +660,7 @@ public class FormatTableScanTest {
 
         Map<String, String> result =
                 FormatTableScan.extractLeadingEqualityPartitionSpecWhenOnlyAnd(
-                        partitionKeys, mixedPredicate);
+                        partitionKeys, mixedPredicate, type);
 
         assertThat(result).isEmpty();
     }
@@ -656,7 +681,7 @@ public class FormatTableScanTest {
 
         Map<String, String> result =
                 FormatTableScan.extractLeadingEqualityPartitionSpecWhenOnlyAnd(
-                        partitionKeys, nonEqualityPredicate);
+                        partitionKeys, nonEqualityPredicate, type);
 
         assertThat(result).isEmpty();
     }
@@ -676,7 +701,7 @@ public class FormatTableScanTest {
 
         Map<String, String> result =
                 FormatTableScan.extractLeadingEqualityPartitionSpecWhenOnlyAnd(
-                        partitionKeys, orPredicate);
+                        partitionKeys, orPredicate, type);
 
         assertThat(result).isEmpty();
     }

Reply via email to