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(

Reply via email to