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") {