From c82ae766aa22386a6d2fa84c6389286a2d247ab6 Mon Sep 17 00:00:00 2001 From: Gustavo de Morais Date: Tue, 28 Jul 2026 13:30:29 +0200 Subject: [PATCH] [FLINK-40250][table] Throw ValidationException for non-orderable types used as keys GenerateUtils#generateCompare threw a raw UnsupportedOperationException when a non-orderable type (MAP, MULTISET, VARIANT, TIMESTAMP_WITH_TIME_ZONE, BITMAP) was used as an ordering, grouping, or join key. This is invalid user SQL, so it now throws a ValidationException with a clearer message, consistent with the equality comparison path in ScalarOperatorGens. --- .../flink/table/test/program/FailingSqlTestStep.java | 4 +--- .../flink/table/planner/codegen/GenerateUtils.scala | 8 +++++--- .../plan/nodes/exec/stream/BitmapSemanticTest.java | 9 ++++++--- .../table/planner/runtime/batch/sql/CalcITCase.scala | 6 +++++- 4 files changed, 17 insertions(+), 10 deletions(-) diff --git a/flink-table/flink-table-api-java/src/test/java/org/apache/flink/table/test/program/FailingSqlTestStep.java b/flink-table/flink-table-api-java/src/test/java/org/apache/flink/table/test/program/FailingSqlTestStep.java index da04ac889d1a17..7a9e94a94f4922 100644 --- a/flink-table/flink-table-api-java/src/test/java/org/apache/flink/table/test/program/FailingSqlTestStep.java +++ b/flink-table/flink-table-api-java/src/test/java/org/apache/flink/table/test/program/FailingSqlTestStep.java @@ -42,10 +42,8 @@ public final class FailingSqlTestStep implements TestStep { FailingSqlTestStep( String sql, Class expectedException, String expectedErrorMessage) { Preconditions.checkArgument( - // UnsupportedOperationException is a special case in GenerateUtils#generateCompare expectedException == ValidationException.class - || expectedException == TableRuntimeException.class - || expectedException == UnsupportedOperationException.class, + || expectedException == TableRuntimeException.class, "Usually a SQL query should fail with either validation or runtime exception. " + "Otherwise this might require an update to the exception design."); this.sql = sql; diff --git a/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/planner/codegen/GenerateUtils.scala b/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/planner/codegen/GenerateUtils.scala index 9cfae27fe44fed..8a864de361c459 100644 --- a/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/planner/codegen/GenerateUtils.scala +++ b/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/planner/codegen/GenerateUtils.scala @@ -20,6 +20,7 @@ package org.apache.flink.table.planner.codegen import org.apache.flink.api.common.ExecutionConfig import org.apache.flink.api.common.serialization.SerializerConfigImpl import org.apache.flink.api.common.typeinfo.{AtomicType => AtomicTypeInfo} +import org.apache.flink.table.api.ValidationException import org.apache.flink.table.data._ import org.apache.flink.table.data.binary.{BinaryRowData, BinaryStringData} import org.apache.flink.table.data.utils.JoinedRowData @@ -636,9 +637,10 @@ object GenerateUtils { INTERVAL_YEAR_MONTH | INTERVAL_DAY_TIME => s"($leftTerm > $rightTerm ? 1 : $leftTerm < $rightTerm ? -1 : 0)" case TIMESTAMP_WITH_TIME_ZONE | MULTISET | MAP | VARIANT | BITMAP => - throw new UnsupportedOperationException( - s"Type($t) is not an orderable data type, " + - s"it is not supported as a ORDER_BY/GROUP_BY/JOIN_EQUAL field.") + throw new ValidationException( + s"Type '$t' cannot be ordered, so it cannot be used as a key for sorting, grouping, " + + s"or joining (for example in ORDER BY, GROUP BY, DISTINCT, or a join condition). " + + s"Remove it from the key, or replace it with a value that can be ordered.") // TODO support MULTISET and MAP? case ARRAY => val at = t.asInstanceOf[ArrayType] diff --git a/flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/plan/nodes/exec/stream/BitmapSemanticTest.java b/flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/plan/nodes/exec/stream/BitmapSemanticTest.java index a2fb4bb9982b18..12e87ba4d400f3 100644 --- a/flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/plan/nodes/exec/stream/BitmapSemanticTest.java +++ b/flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/plan/nodes/exec/stream/BitmapSemanticTest.java @@ -19,6 +19,7 @@ package org.apache.flink.table.planner.plan.nodes.exec.stream; import org.apache.flink.table.api.DataTypes; +import org.apache.flink.table.api.ValidationException; import org.apache.flink.table.functions.AggregateFunction; import org.apache.flink.table.functions.ScalarFunction; import org.apache.flink.table.functions.TableFunction; @@ -217,9 +218,11 @@ public List programs() { "INSERT INTO sink_t " + "SELECT FIRST_VALUE(ts) OVER (ORDER BY bm) " + "FROM TABLE(TUMBLE(TABLE t, DESCRIPTOR(ts), INTERVAL '1' SECOND))", - UnsupportedOperationException.class, - "Type(BITMAP) is not an orderable data type, " - + "it is not supported as a ORDER_BY/GROUP_BY/JOIN_EQUAL field.") + ValidationException.class, + "Type 'BITMAP' cannot be ordered, so it cannot be used as a key for " + + "sorting, grouping, or joining (for example in ORDER BY, " + + "GROUP BY, DISTINCT, or a join condition). Remove it from the " + + "key, or replace it with a value that can be ordered.") .build(); static final TableTestProgram BITMAP_AS_DISTINCT_KEY = diff --git a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/planner/runtime/batch/sql/CalcITCase.scala b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/planner/runtime/batch/sql/CalcITCase.scala index 42d53d9ede1768..1ffedf2b0aeb41 100644 --- a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/planner/runtime/batch/sql/CalcITCase.scala +++ b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/planner/runtime/batch/sql/CalcITCase.scala @@ -1063,8 +1063,12 @@ class CalcITCase extends BatchTestBase { assertThatThrownBy( () => checkResult("SELECT COUNT(*) FROM SmallTable3 GROUP BY MAP[1, 'Hello', 2, 'Hi']", Seq())) + .isInstanceOf(classOf[ValidationException]) .hasMessage( - "Type(MAP NOT NULL) is not an orderable data type, it is not supported as a ORDER_BY/GROUP_BY/JOIN_EQUAL field.") + "Type 'MAP NOT NULL' cannot be ordered, so it cannot " + + "be used as a key for sorting, grouping, or joining (for example in ORDER BY, GROUP " + + "BY, DISTINCT, or a join condition). Remove it from the key, or replace it with a " + + "value that can be ordered.") } @Test