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

JingsongLi 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 03a48bdaa9 [format] Validate nested types for JSON tables (#9585)
03a48bdaa9 is described below

commit 03a48bdaa93c51926c2b8b8f65362e79468bc240
Author: YangJie <[email protected]>
AuthorDate: Thu Sep 10 02:55:29 2026 -0400

    [format] Validate nested types for JSON tables (#9585)
---
 .../apache/paimon/format/json/JsonFileFormat.java  | 17 ++++++++++++--
 .../paimon/format/json/JsonFileFormatTest.java     | 27 ++++++++++++++++++++++
 2 files changed, 42 insertions(+), 2 deletions(-)

diff --git 
a/paimon-format/src/main/java/org/apache/paimon/format/json/JsonFileFormat.java 
b/paimon-format/src/main/java/org/apache/paimon/format/json/JsonFileFormat.java
index 3abbb6882c..2e1154ad64 100644
--- 
a/paimon-format/src/main/java/org/apache/paimon/format/json/JsonFileFormat.java
+++ 
b/paimon-format/src/main/java/org/apache/paimon/format/json/JsonFileFormat.java
@@ -28,9 +28,12 @@ import org.apache.paimon.fs.CloseShieldOutputStream;
 import org.apache.paimon.fs.PositionOutputStream;
 import org.apache.paimon.predicate.Predicate;
 import org.apache.paimon.reader.FileRecordReader;
+import org.apache.paimon.types.ArrayType;
 import org.apache.paimon.types.DataType;
 import org.apache.paimon.types.DataTypeRoot;
+import org.apache.paimon.types.MapType;
 import org.apache.paimon.types.RowType;
+import org.apache.paimon.types.VectorType;
 
 import javax.annotation.Nullable;
 
@@ -71,7 +74,6 @@ public class JsonFileFormat extends FileFormat {
     }
 
     private void validateDataType(DataType dataType) {
-        // JSON format supports all data types since they can be represented 
as JSON values
         DataTypeRoot typeRoot = dataType.getTypeRoot();
         switch (typeRoot) {
             case CHAR:
@@ -90,11 +92,22 @@ public class JsonFileFormat extends FileFormat {
             case TIME_WITHOUT_TIME_ZONE:
             case TIMESTAMP_WITHOUT_TIME_ZONE:
             case TIMESTAMP_WITH_LOCAL_TIME_ZONE:
+                break;
             case ARRAY:
+                validateDataType(((ArrayType) dataType).getElementType());
+                break;
             case VECTOR:
+                validateDataType(((VectorType) dataType).getElementType());
+                break;
             case MAP:
+                MapType mapType = (MapType) dataType;
+                validateDataType(mapType.getKeyType());
+                validateDataType(mapType.getValueType());
+                break;
             case ROW:
-                // All types are supported in JSON
+                for (DataType fieldType : ((RowType) 
dataType).getFieldTypes()) {
+                    validateDataType(fieldType);
+                }
                 break;
             default:
                 throw new UnsupportedOperationException(
diff --git 
a/paimon-format/src/test/java/org/apache/paimon/format/json/JsonFileFormatTest.java
 
b/paimon-format/src/test/java/org/apache/paimon/format/json/JsonFileFormatTest.java
index 5b79fab95b..3778f2a8f2 100644
--- 
a/paimon-format/src/test/java/org/apache/paimon/format/json/JsonFileFormatTest.java
+++ 
b/paimon-format/src/test/java/org/apache/paimon/format/json/JsonFileFormatTest.java
@@ -72,6 +72,33 @@ public class JsonFileFormatTest extends FormatReadWriteTest {
         return HadoopCompressionType.NONE.value();
     }
 
+    @Test
+    public void testValidateRejectsUnsupportedNestedType() {
+        JsonFileFormat format =
+                new JsonFileFormat(new FileFormatFactory.FormatContext(new 
Options(), 1024, 1024));
+
+        // VARIANT is not in the supported set, so it must be rejected 
wherever it is nested.
+        List<RowType> rejected =
+                Arrays.asList(
+                        RowType.of(DataTypes.ARRAY(DataTypes.VARIANT())),
+                        RowType.of(DataTypes.MAP(DataTypes.VARIANT(), 
DataTypes.STRING())),
+                        RowType.of(DataTypes.MAP(DataTypes.STRING(), 
DataTypes.VARIANT())),
+                        RowType.of(DataTypes.ROW(DataTypes.INT(), 
DataTypes.VARIANT())),
+                        
RowType.of(DataTypes.ARRAY(DataTypes.ROW(DataTypes.VARIANT()))));
+        for (RowType rowType : rejected) {
+            assertThatThrownBy(() -> format.validateDataFields(rowType))
+                    .isInstanceOf(UnsupportedOperationException.class)
+                    .hasMessageContaining("Unsupported data type for JSON 
format");
+        }
+
+        // Supported types nested the same way still validate.
+        format.validateDataFields(
+                RowType.of(
+                        DataTypes.ARRAY(DataTypes.STRING()),
+                        DataTypes.MAP(DataTypes.STRING(), DataTypes.INT()),
+                        DataTypes.ROW(DataTypes.INT(), 
DataTypes.ARRAY(DataTypes.DOUBLE()))));
+    }
+
     @Test
     public void testUnresolvableCastFailsWithClearMessage() throws Exception {
         JsonFileFormat format =

Reply via email to