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