This is an automated email from the ASF dual-hosted git repository.
gustavodemorais pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/flink.git
The following commit(s) were added to refs/heads/master by this push:
new 3e6471436eb [FLINK-41260][table] Improve error msg by rejecting ORDER
BY in ARRAY_AGG and JSON_ARRAYAGG during planning
3e6471436eb is described below
commit 3e6471436eb6e1e3763345a79023a8583a1e1b23
Author: Rion Williams <[email protected]>
AuthorDate: Fri Oct 30 04:19:30 2026 -0500
[FLINK-41260][table] Improve error msg by rejecting ORDER BY in ARRAY_AGG
and JSON_ARRAYAGG during planning
Fixed in #29667
---
.../planner/calcite/FlinkCalciteSqlValidator.java | 21 +++++++++
.../calcite/FlinkCalciteSqlValidatorTest.java | 54 ++++++++++++++++++++++
2 files changed, 75 insertions(+)
diff --git
a/flink-table/flink-table-planner/src/main/java/org/apache/flink/table/planner/calcite/FlinkCalciteSqlValidator.java
b/flink-table/flink-table-planner/src/main/java/org/apache/flink/table/planner/calcite/FlinkCalciteSqlValidator.java
index 6f263ad6b1f..dc17475501c 100644
---
a/flink-table/flink-table-planner/src/main/java/org/apache/flink/table/planner/calcite/FlinkCalciteSqlValidator.java
+++
b/flink-table/flink-table-planner/src/main/java/org/apache/flink/table/planner/calcite/FlinkCalciteSqlValidator.java
@@ -389,6 +389,7 @@ public final class FlinkCalciteSqlValidator extends
FlinkSqlParsingValidator {
final SqlBasicCall call = (SqlBasicCall) node;
checkNoNamedAndPositionalMixedArgs(call);
checkDisabledSystemArgs(call);
+ checkArrayAggOrderBy(call);
// Special case for MODEL
if (node instanceof SqlExplicitModelCall) {
@@ -462,6 +463,26 @@ public final class FlinkCalciteSqlValidator extends
FlinkSqlParsingValidator {
}
}
+ /**
+ * Rejects ORDER BY in ARRAY_AGG and JSON_ARRAYAGG, which the runtime
functions do not
+ * implement.
+ */
+ private static void checkArrayAggOrderBy(SqlBasicCall call) {
+ if (call.getKind() == SqlKind.ARRAY_AGG
+ &&
call.getOperandList().stream().anyMatch(SqlNodeList.class::isInstance)) {
+ throw new ValidationException(
+ "ARRAY_AGG with ORDER BY is not supported. "
+ + "Remove the ORDER BY clause from the ARRAY_AGG
call.");
+ }
+ // JSON_ARRAYAGG(x ORDER BY y) is parsed as JSON_ARRAYAGG(x) WITHIN
GROUP (ORDER BY y)
+ if (call.getKind() == SqlKind.WITHIN_GROUP
+ && call.operand(0).getKind() == SqlKind.JSON_ARRAYAGG) {
+ throw new ValidationException(
+ "JSON_ARRAYAGG with ORDER BY is not supported. "
+ + "Remove the ORDER BY or WITHIN GROUP clause from
the JSON_ARRAYAGG call.");
+ }
+ }
+
/**
* Rejects the implicit PTF system arguments (on_time, uid) for functions
that disable them.
*
diff --git
a/flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/calcite/FlinkCalciteSqlValidatorTest.java
b/flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/calcite/FlinkCalciteSqlValidatorTest.java
index 831b3b6ecc4..37451e23fff 100644
---
a/flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/calcite/FlinkCalciteSqlValidatorTest.java
+++
b/flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/calcite/FlinkCalciteSqlValidatorTest.java
@@ -158,6 +158,60 @@ class FlinkCalciteSqlValidatorTest {
.hasMessageContaining("Cannot mix positional and named
arguments");
}
+ @ParameterizedTest
+ @ValueSource(
+ strings = {
+ "SELECT a, ARRAY_AGG(b ORDER BY b) FROM t2 GROUP BY a",
+ "SELECT a, ARRAY_AGG(DISTINCT b ORDER BY b) FROM t2 GROUP BY
a",
+ "SELECT a, ARRAY_AGG(b RESPECT NULLS ORDER BY b) FROM t2 GROUP
BY a",
+ "SELECT * FROM (SELECT a, ARRAY_AGG(b ORDER BY b) AS bs FROM
t2 GROUP BY a)"
+ })
+ void testArrayAggWithOrderBy(String sql) {
+ assertThatThrownBy(() -> plannerMocks.getParser().parse(sql))
+ .isInstanceOf(ValidationException.class)
+ .hasRootCauseMessage(
+ "ARRAY_AGG with ORDER BY is not supported. "
+ + "Remove the ORDER BY clause from the
ARRAY_AGG call.");
+ }
+
+ @ParameterizedTest
+ @ValueSource(
+ strings = {
+ "SELECT a, ARRAY_AGG(b) FROM t2 GROUP BY a",
+ "SELECT a, ARRAY_AGG(DISTINCT b) FROM t2 GROUP BY a",
+ "SELECT a, ARRAY_AGG(b RESPECT NULLS) FROM t2 GROUP BY a"
+ })
+ void testArrayAggWithoutOrderBy(String sql) {
+ assertDoesNotThrow(() -> plannerMocks.getParser().parse(sql));
+ }
+
+ @ParameterizedTest
+ @ValueSource(
+ strings = {
+ "SELECT a, JSON_ARRAYAGG(b ORDER BY b) FROM t2 GROUP BY a",
+ "SELECT a, JSON_ARRAYAGG(b ORDER BY b NULL ON NULL) FROM t2
GROUP BY a",
+ "SELECT a, JSON_ARRAYAGG(b) WITHIN GROUP (ORDER BY b) FROM t2
GROUP BY a",
+ "SELECT a, JSON_ARRAYAGG(b ABSENT ON NULL) WITHIN GROUP (ORDER
BY b) FROM t2 GROUP BY a",
+ "SELECT * FROM (SELECT a, JSON_ARRAYAGG(b ORDER BY b) AS bs
FROM t2 GROUP BY a)"
+ })
+ void testJsonArrayAggWithOrderBy(String sql) {
+ assertThatThrownBy(() -> plannerMocks.getParser().parse(sql))
+ .isInstanceOf(ValidationException.class)
+ .hasRootCauseMessage(
+ "JSON_ARRAYAGG with ORDER BY is not supported. "
+ + "Remove the ORDER BY or WITHIN GROUP clause
from the JSON_ARRAYAGG call.");
+ }
+
+ @ParameterizedTest
+ @ValueSource(
+ strings = {
+ "SELECT a, JSON_ARRAYAGG(b) FROM t2 GROUP BY a",
+ "SELECT a, JSON_ARRAYAGG(b NULL ON NULL) FROM t2 GROUP BY a"
+ })
+ void testJsonArrayAggWithoutOrderBy(String sql) {
+ assertDoesNotThrow(() -> plannerMocks.getParser().parse(sql));
+ }
+
/** Scalar function with named arguments for the mixed-argument validation
test. */
public static class NamedArgsScalarFunction extends ScalarFunction {
@FunctionHint(