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 =