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 fc2da5cdd1 [core] Reject dot-paths in fields.* options on row columns
(#7757)
fc2da5cdd1 is described below
commit fc2da5cdd1d25430bbe937cb047ea18040912593
Author: Arnav Balyan <[email protected]>
AuthorDate: Thu May 7 09:00:20 2026 +0530
[core] Reject dot-paths in fields.* options on row columns (#7757)
- `fields.<row>.<inner>.aggregate-function` is silently ignored at write
time, the parent row overwrites instead of aggregating. (during write
time)
- Reject the misconfig at ddl when the parent field is a RowType. Ensure
we can strictly reject this case instead of allowing silent overwrites.
---
.../org/apache/paimon/schema/SchemaValidation.java | 20 +++++++++++++++-
.../apache/paimon/schema/SchemaValidationTest.java | 28 ++++++++++++++++++++++
2 files changed, 47 insertions(+), 1 deletion(-)
diff --git
a/paimon-core/src/main/java/org/apache/paimon/schema/SchemaValidation.java
b/paimon-core/src/main/java/org/apache/paimon/schema/SchemaValidation.java
index 443766adc2..09d6674924 100644
--- a/paimon-core/src/main/java/org/apache/paimon/schema/SchemaValidation.java
+++ b/paimon-core/src/main/java/org/apache/paimon/schema/SchemaValidation.java
@@ -487,7 +487,8 @@ public class SchemaValidation {
.forEach(
k -> {
if (k.startsWith(FIELDS_PREFIX)) {
- String[] fields =
k.split("\\.")[1].split(FIELDS_SEPARATOR);
+ String[] segments = k.split("\\.");
+ String[] fields =
segments[1].split(FIELDS_SEPARATOR);
for (String field : fields) {
checkArgument(
DEFAULT_AGG_FUNCTION.equals(field)
@@ -496,6 +497,23 @@ public class SchemaValidation {
"Field %s can not be found
in table schema.",
field));
}
+ // PAIMON-6471: dot paths into a ROW field's
members
+ // (e.g. fields.row.inner.aggregate-function)
are silently
+ // dropped today and produce wrong results.
This check
+ // rejects them.
+ if (segments.length > 3 && fields.length == 1)
{
+ String parent = fields[0];
+ schema.fields().stream()
+ .filter(f ->
f.name().equals(parent))
+ .findFirst()
+ .ifPresent(
+ f ->
+ checkArgument(
+ !(f.type()
instanceof RowType),
+
"Nested-field path is not supported on ROW field '%s': %s",
+ parent,
+ k));
+ }
}
});
}
diff --git
a/paimon-core/src/test/java/org/apache/paimon/schema/SchemaValidationTest.java
b/paimon-core/src/test/java/org/apache/paimon/schema/SchemaValidationTest.java
index e7534a4373..d2bad5248c 100644
---
a/paimon-core/src/test/java/org/apache/paimon/schema/SchemaValidationTest.java
+++
b/paimon-core/src/test/java/org/apache/paimon/schema/SchemaValidationTest.java
@@ -180,6 +180,34 @@ class SchemaValidationTest {
assertThatCode(() ->
validateTableSchemaExec(options)).doesNotThrowAnyException();
}
+ @Test
+ public void testNestedRowAggregateOptionRejected() {
+ // PAIMON-6471: nested-path agg config was silently ignored, leaving
the parent ROW
+ // on the default aggregator and producing wrong results without any
error.
+ List<DataField> fields =
+ Arrays.asList(
+ new DataField(0, "id", DataTypes.INT()),
+ new DataField(
+ 1,
+ "data",
+ DataTypes.ROW(
+ DataTypes.FIELD(2, "num",
DataTypes.INT()),
+ DataTypes.FIELD(3, "info",
DataTypes.STRING()))));
+
+ Map<String, String> options = new HashMap<>();
+ options.put("merge-engine", "aggregation");
+ options.put("fields.data.num.aggregate-function", "sum");
+ options.put("fields.data.sequence-group", "data");
+ options.put(BUCKET.key(), "1");
+
+ TableSchema schema =
+ new TableSchema(1, fields, 10, emptyList(),
singletonList("id"), options, "");
+
+ assertThatThrownBy(() -> validateTableSchema(schema))
+ .hasMessageContaining("Nested-field path is not supported on
ROW field 'data'")
+ .hasMessageContaining("fields.data.num.aggregate-function");
+ }
+
@Test
public void testChainTableAllowsNonDeduplicateMergeEngine() {
Map<String, String> options = new HashMap<>();