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 e62ff31169 [core] fix the wrong parsing for map type with string sub 
type (#6790)
e62ff31169 is described below

commit e62ff3116961c16297ac8fe7b5a6f77098ed0ea0
Author: Yann Byron <[email protected]>
AuthorDate: Tue Dec 16 20:01:28 2025 +0800

    [core] fix the wrong parsing for map type with string sub type (#6790)
---
 .../apache/paimon/casting/StringToMapCastRule.java |  7 ++--
 .../apache/paimon/casting/CastExecutorTest.java    |  8 +++++
 .../apache/paimon/spark/sql/DefaultValueTest.scala | 37 ++++++++++++++++++++++
 3 files changed, 50 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 475c29b648..02b21fc397 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
@@ -176,7 +176,7 @@ class StringToMapCastRule extends 
AbstractCastRule<BinaryString, InternalMap> {
                 : castExecutor.cast(BinaryString.fromString(valueStr));
     }
 
-    private List<String> splitMapEntries(String content) {
+    public List<String> splitMapEntries(String content) {
         List<String> entries = new ArrayList<>();
         StringBuilder current = new StringBuilder();
         Stack<Character> bracketStack = new Stack<>();
@@ -186,10 +186,13 @@ class StringToMapCastRule extends 
AbstractCastRule<BinaryString, InternalMap> {
         for (char c : content.toCharArray()) {
             if (escaped) {
                 escaped = false;
+                continue;
             } else if (c == '\\') {
                 escaped = true;
+                continue;
             } else if (c == '"') {
                 inQuotes = !inQuotes;
+                continue;
             } else if (!inQuotes) {
                 if (StringUtils.isOpenBracket(c)) {
                     bracketStack.push(c);
@@ -209,7 +212,7 @@ class StringToMapCastRule extends 
AbstractCastRule<BinaryString, InternalMap> {
 
     private void addCurrentEntry(List<String> entries, StringBuilder current) {
         if (current.length() > 0) {
-            entries.add(current.toString());
+            entries.add(current.toString().trim());
             current.setLength(0);
         }
     }
diff --git 
a/paimon-common/src/test/java/org/apache/paimon/casting/CastExecutorTest.java 
b/paimon-common/src/test/java/org/apache/paimon/casting/CastExecutorTest.java
index 457895f839..dd6d53bf4c 100644
--- 
a/paimon-common/src/test/java/org/apache/paimon/casting/CastExecutorTest.java
+++ 
b/paimon-common/src/test/java/org/apache/paimon/casting/CastExecutorTest.java
@@ -52,6 +52,7 @@ import org.apache.paimon.utils.DecimalUtils;
 import org.junit.jupiter.api.Test;
 
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.TimeZone;
 
@@ -898,6 +899,13 @@ public class CastExecutorTest {
                 BinaryString.fromString("{1, {2025-01-06, {1 -> [1, null, 2]}, 
null}}"));
     }
 
+    @Test
+    public void testSplitMapEntriesWithQuotes() {
+        String content = "1, \"abc\"";
+        List<String> result = 
StringToMapCastRule.INSTANCE.splitMapEntries(content);
+        assertThat(result).containsExactly("1", "abc");
+    }
+
     @SuppressWarnings("rawtypes")
     private void compareCastResult(CastExecutor<?, ?> cast, Object input, 
Object output) {
         assertThat(((CastExecutor) cast).cast(input)).isEqualTo(output);
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 f7c2c282ef..22edb8f61a 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
@@ -55,6 +55,43 @@ class DefaultValueTest extends PaimonSparkTestBase {
     }
   }
 
+  test("Default Value: map type with string element") {
+    withTable("t") {
+      spark.sql("""CREATE TABLE IF NOT EXISTS t (
+                  |  id BIGINT NOT NULL,
+                  |  col1 MAP<BIGINT, STRING> DEFAULT NULL,
+                  |  col2 MAP<BIGINT, STRING> DEFAULT map(),
+                  |  col3 MAP<BIGINT, STRING> DEFAULT map(9999, "hello")
+                  |) using paimon;
+                  |""".stripMargin)
+
+      spark.sql("""
+                  |INSERT INTO t VALUES
+                  |  (1, map(1, "a", 11, "aa"), map(2, "b"), map(3, "c")),
+                  |  (2, null, map(5, "e", 55, "ee"), map(6, "f")),
+                  |  (3, map(7, "g"), null, map(9, "i", 99, "ii")),
+                  |  (4, map(10, "j"), map(11, "k"), null),
+                  |  (5, null, null, map(15, "o")),
+                  |  (6, null, map(17, "q"), null),
+                  |  (7, map(19, "r"), null, null),
+                  |  (8, null, null, null)
+                  |""".stripMargin)
+
+      checkAnswer(
+        spark.sql("SELECT * FROM t ORDER BY id"),
+        Row(1, Map(1 -> "a", 11 -> "aa"), Map(2 -> "b"), Map(3 -> "c"))
+          :: Row(2, null, Map(5 -> "e", 55 -> "ee"), Map(6 -> "f"))
+          :: Row(3, Map(7 -> "g"), Map(), Map(9 -> "i", 99 -> "ii"))
+          :: Row(4, Map(10 -> "j"), Map(11 -> "k"), Map(9999 -> "hello"))
+          :: Row(5, null, Map(), Map(15 -> "o"))
+          :: Row(6, null, Map(17 -> "q"), Map(9999 -> "hello"))
+          :: Row(7, Map(19 -> "r"), Map(), Map(9999 -> "hello"))
+          :: Row(8, null, Map(), Map(9999 -> "hello"))
+          :: Nil
+      )
+    }
+  }
+
   test("Default Value: unsupported default value") {
     withTimeZone("Asia/Shanghai") {
       withTable("t") {

Reply via email to