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

lzljs3620320 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 8f37174497 [core] support null as the default value of map type (#6785)
8f37174497 is described below

commit 8f371744970dc85db10032cacafaa46095aa63e9
Author: Yann Byron <[email protected]>
AuthorDate: Wed Dec 10 15:13:41 2025 +0800

    [core] support null as the default value of map type (#6785)
---
 .../apache/paimon/casting/StringToMapCastRule.java | 13 +++++++--
 .../apache/paimon/data/DefaultValueRowTest.java    | 27 ++++++++++++++++++
 .../apache/paimon/spark/sql/DefaultValueTest.scala | 33 ++++++++++++++++++++++
 3 files changed, 71 insertions(+), 2 deletions(-)

diff --git 
a/paimon-common/src/main/java/org/apache/paimon/casting/StringToMapCastRule.java
 
b/paimon-common/src/main/java/org/apache/paimon/casting/StringToMapCastRule.java
index cc366605ee..475c29b648 100644
--- 
a/paimon-common/src/main/java/org/apache/paimon/casting/StringToMapCastRule.java
+++ 
b/paimon-common/src/main/java/org/apache/paimon/casting/StringToMapCastRule.java
@@ -82,7 +82,13 @@ class StringToMapCastRule extends 
AbstractCastRule<BinaryString, InternalMap> {
             if ("{}".equals(str) || "MAP()".equalsIgnoreCase(str)) {
                 return new GenericMap(new HashMap<>());
             }
-            return new GenericMap(parseDefaultMap(str, keyCastExecutor, 
valueCastExecutor));
+            Map<Object, Object> defaultMapValue =
+                    parseDefaultMap(str, keyCastExecutor, valueCastExecutor);
+            if (defaultMapValue == null) {
+                return null;
+            } else {
+                return new GenericMap(defaultMapValue);
+            }
         } catch (Exception e) {
             throw new RuntimeException("Cannot parse '" + value + "' as MAP: " 
+ e.getMessage(), e);
         }
@@ -104,7 +110,10 @@ class StringToMapCastRule extends 
AbstractCastRule<BinaryString, InternalMap> {
             CastExecutor<BinaryString, Object> keyCastExecutor,
             CastExecutor<BinaryString, Object> valueCastExecutor) {
 
-        Map<Object, Object> mapContent = Maps.newHashMap();
+        if (str.equalsIgnoreCase("NULL")) {
+            return null;
+        }
+
         Matcher bracketMatcher = BRACKET_MAP_PATTERN.matcher(str);
         if (bracketMatcher.matches()) {
             // Parse bracket format (arrow-separated entries)
diff --git 
a/paimon-common/src/test/java/org/apache/paimon/data/DefaultValueRowTest.java 
b/paimon-common/src/test/java/org/apache/paimon/data/DefaultValueRowTest.java
index 9dcb1061fc..43fccf10d1 100644
--- 
a/paimon-common/src/test/java/org/apache/paimon/data/DefaultValueRowTest.java
+++ 
b/paimon-common/src/test/java/org/apache/paimon/data/DefaultValueRowTest.java
@@ -94,6 +94,33 @@ public class DefaultValueRowTest {
 
         InternalMap propertiesValue = wrappedRow.getMap(1);
         assertThat(propertiesValue).isNotNull();
+        assertThat(propertiesValue.size()).isEqualTo(2);
+    }
+
+    @Test
+    public void testDefaultValueRowWithNullMapType() {
+        // Test with Map default value
+        RowType rowType =
+                RowType.of(
+                        new DataField(0, "id", DataTypes.INT()),
+                        new DataField(
+                                1,
+                                "properties",
+                                DataTypes.MAP(DataTypes.STRING(), 
DataTypes.STRING()),
+                                "Default properties",
+                                "null"));
+
+        DefaultValueRow defaultValueRow = DefaultValueRow.create(rowType);
+
+        GenericRow originalRow = new GenericRow(2);
+        originalRow.setField(0, 200);
+        originalRow.setField(1, null); // Use default properties
+
+        DefaultValueRow wrappedRow = defaultValueRow.replaceRow(originalRow);
+        InternalMap propertiesValue = wrappedRow.getMap(1);
+
+        assertThat(wrappedRow.getInt(0)).isEqualTo(200);
+        assertThat(propertiesValue).isNull();
     }
 
     @Test
diff --git 
a/paimon-spark/paimon-spark-ut/src/test/scala/org/apache/paimon/spark/sql/DefaultValueTest.scala
 
b/paimon-spark/paimon-spark-ut/src/test/scala/org/apache/paimon/spark/sql/DefaultValueTest.scala
index 9be4d4b377..f7c2c282ef 100644
--- 
a/paimon-spark/paimon-spark-ut/src/test/scala/org/apache/paimon/spark/sql/DefaultValueTest.scala
+++ 
b/paimon-spark/paimon-spark-ut/src/test/scala/org/apache/paimon/spark/sql/DefaultValueTest.scala
@@ -20,8 +20,41 @@ package org.apache.paimon.spark.sql
 
 import org.apache.paimon.spark.PaimonSparkTestBase
 
+import org.apache.spark.sql.Row
+
 class DefaultValueTest extends PaimonSparkTestBase {
 
+  test("Default Value: MAP TYPE") {
+    withTable("t") {
+      spark.sql("""CREATE TABLE IF NOT EXISTS t (
+                  |  id BIGINT NOT NULL,
+                  |  col1 MAP<INT, DOUBLE> DEFAULT NULL,
+                  |  col2 MAP<INT, DOUBLE> DEFAULT map(),
+                  |  col3 MAP<INT, DOUBLE> DEFAULT map(99, 99.99D)
+                  |) using paimon;
+                  |""".stripMargin)
+
+      spark.sql("""
+                  |INSERT INTO t VALUES
+                  |  (1, map(1, 1.1), map(2, 2.2), map(3, 3.3)),
+                  |  (2, null, map(5, 5.5), map(6, 6.6)),
+                  |  (3, map(7, 7.7), null, map(9, 9.9)),
+                  |  (4, map(10, 10.1), map(11, 11.11), null),
+                  |  (5, null, null, null)
+                  |""".stripMargin)
+
+      checkAnswer(
+        spark.sql("SELECT * FROM t ORDER BY id"),
+        Row(1, Map(1 -> 1.1), Map(2 -> 2.2), Map(3 -> 3.3))
+          :: Row(2, null, Map(5 -> 5.5), Map(6 -> 6.6))
+          :: Row(3, Map(7 -> 7.7), Map(), Map(9 -> 9.9))
+          :: Row(4, Map(10 -> 10.1), Map(11 -> 11.11), Map(99 -> 99.99))
+          :: Row(5, null, Map(), Map(99 -> 99.99))
+          :: Nil
+      )
+    }
+  }
+
   test("Default Value: unsupported default value") {
     withTimeZone("Asia/Shanghai") {
       withTable("t") {

Reply via email to