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

morningman pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/master by this push:
     new 1b7f43d9fca [fix][paimon] Fix Paimon date partition conversion failure 
(#54043)
1b7f43d9fca is described below

commit 1b7f43d9fca6c01542cf43336155e4a5d2c0b606
Author: Petrichor <[email protected]>
AuthorDate: Mon Aug 4 06:03:05 2025 +0800

    [fix][paimon] Fix Paimon date partition conversion failure (#54043)
    
    ### What problem does this PR solve?
    
    **Background**: PR [#46641](https://github.com/apache/doris/pull/46641)
    worked around Paimon date partition failures by treating date partitions
    as unpartitioned tables.
    
    **Root Cause**: Paimon stores date partition values as integers (e.g.,
    `20231225` for `2023-12-25`), but the previous implementation failed to
    convert these to Doris-compatible date formats, resulting in:
    ```
    org.apache.doris.common.AnalysisException: errCode = 2, detailMessage = 
date literal [19737] is invalid: null
    ```
---
 .../apache/doris/datasource/paimon/PaimonUtil.java |  21 +++++++++++++++------
 regression-test/data/mtmv_p0/test_paimon_mtmv.out  | Bin 1353 -> 1394 bytes
 .../suites/mtmv_p0/test_paimon_mtmv.groovy         |  14 ++++++++++----
 3 files changed, 25 insertions(+), 10 deletions(-)

diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/datasource/paimon/PaimonUtil.java 
b/fe/fe-core/src/main/java/org/apache/doris/datasource/paimon/PaimonUtil.java
index a0ede02a32a..8f82f3c3aa0 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/datasource/paimon/PaimonUtil.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/datasource/paimon/PaimonUtil.java
@@ -59,6 +59,7 @@ import org.apache.paimon.types.DecimalType;
 import org.apache.paimon.types.MapType;
 import org.apache.paimon.types.RowType;
 import org.apache.paimon.types.VarCharType;
+import org.apache.paimon.utils.DateTimeUtils;
 import org.apache.paimon.utils.InstantiationUtil;
 import org.apache.paimon.utils.Pair;
 import org.apache.paimon.utils.Projection;
@@ -116,12 +117,23 @@ public class PaimonUtil {
         Map<String, PartitionItem> nameToPartitionItem = Maps.newHashMap();
         Map<String, Partition> nameToPartition = Maps.newHashMap();
         PaimonPartitionInfo partitionInfo = new 
PaimonPartitionInfo(nameToPartitionItem, nameToPartition);
+        List<Type> types = partitionColumns.stream()
+                .map(Column::getType)
+                .collect(Collectors.toList());
+        Map<String, Type> columnNameToType = partitionColumns.stream()
+                .collect(Collectors.toMap(Column::getName, Column::getType));
 
         for (Partition partition : paimonPartitions) {
             Map<String, String> spec = partition.spec();
             StringBuilder sb = new StringBuilder();
             for (Map.Entry<String, String> entry : spec.entrySet()) {
-                
sb.append(entry.getKey()).append("=").append(entry.getValue()).append("/");
+                sb.append(entry.getKey()).append("=");
+                // Paimon stores DATE type as days since 1970-01-01 (epoch), 
so we convert the integer to a date string.
+                if (columnNameToType.getOrDefault(entry.getKey(), 
Type.NULL).isDateV2()) {
+                    
sb.append(DateTimeUtils.formatDate(Integer.parseInt(entry.getValue()))).append("/");
+                } else {
+                    sb.append(entry.getValue()).append("/");
+                }
             }
             if (sb.length() > 0) {
                 sb.deleteCharAt(sb.length() - 1);
@@ -131,7 +143,7 @@ public class PaimonUtil {
             try {
                 // partition values return by paimon api, may have problem,
                 // to avoid affecting the query, we catch exceptions here
-                nameToPartitionItem.put(partitionName, 
toListPartitionItem(partitionName, partitionColumns));
+                nameToPartitionItem.put(partitionName, 
toListPartitionItem(partitionName, types));
             } catch (Exception e) {
                 LOG.warn("toListPartitionItem failed, partitionColumns: {}, 
partitionValues: {}",
                         partitionColumns, partition.spec(), e);
@@ -140,11 +152,8 @@ public class PaimonUtil {
         return partitionInfo;
     }
 
-    public static ListPartitionItem toListPartitionItem(String partitionName, 
List<Column> partitionColumns)
+    public static ListPartitionItem toListPartitionItem(String partitionName, 
List<Type> types)
             throws AnalysisException {
-        List<Type> types = partitionColumns.stream()
-                .map(Column::getType)
-                .collect(Collectors.toList());
         // Partition name will be in format: nation=cn/city=beijing
         // parse it to get values "cn" and "beijing"
         List<String> partitionValues = 
HiveUtil.toPartitionValues(partitionName);
diff --git a/regression-test/data/mtmv_p0/test_paimon_mtmv.out 
b/regression-test/data/mtmv_p0/test_paimon_mtmv.out
index 0cfe4bd293c..5c7547c0687 100644
Binary files a/regression-test/data/mtmv_p0/test_paimon_mtmv.out and 
b/regression-test/data/mtmv_p0/test_paimon_mtmv.out differ
diff --git a/regression-test/suites/mtmv_p0/test_paimon_mtmv.groovy 
b/regression-test/suites/mtmv_p0/test_paimon_mtmv.groovy
index abd0f64450e..c4ea889f923 100644
--- a/regression-test/suites/mtmv_p0/test_paimon_mtmv.groovy
+++ b/regression-test/suites/mtmv_p0/test_paimon_mtmv.groovy
@@ -268,8 +268,7 @@ suite("test_paimon_mtmv", 
"p0,external,mtmv,external_docker,external_docker_dori
 
     // date type will has problem
     order_qt_date_partition_base_table "SELECT * FROM 
${catalogName}.`test_paimon_spark`.date_partition"
-    test {
-         sql """
+    sql """
             CREATE MATERIALIZED VIEW ${mvName}
                 BUILD DEFERRED REFRESH AUTO ON MANUAL
                 partition by (`create_date`)
@@ -278,8 +277,15 @@ suite("test_paimon_mtmv", 
"p0,external,mtmv,external_docker,external_docker_dori
                 AS
                 SELECT * FROM 
${catalogName}.`test_paimon_spark`.date_partition;
             """
-          exception "Unable to find a suitable base table"
-      }
+    sql """
+         REFRESH MATERIALIZED VIEW ${mvName} auto;
+     """
+    waitingMTMVTaskFinishedByMvName(mvName)
+    def showPaimonDateTypePartitionsResult = sql """show partitions from 
${mvName}"""
+    logger.info("showPaimonDateTypePartitionsResult: " + 
showPaimonDateTypePartitionsResult.toString())
+    
assertTrue(showPaimonDateTypePartitionsResult.toString().contains("p_20200101"))
+    order_qt_date_type_partition "select * FROM ${mvName}"
+    sql """drop materialized view if exists ${mvName};"""
 
     sql """
         CREATE MATERIALIZED VIEW ${mvName}


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to