This is an automated email from the ASF dual-hosted git repository. mbudiu pushed a commit to branch issue7377 in repository https://gitbox.apache.org/repos/asf/calcite.git
commit c83fb3a404f4e9a7acf706e22236fb39776ad740 Author: Mihai Budiu <[email protected]> AuthorDate: Wed Jan 14 20:48:56 2026 -0800 [CALCITE-7377] Validator should reject a DESCRIPTOR in a table function when it is not an identifier Signed-off-by: Mihai Budiu <[email protected]> --- .../java/org/apache/calcite/runtime/CalciteResource.java | 3 +++ .../java/org/apache/calcite/sql/SqlWindowTableFunction.java | 11 ++++++++--- .../org/apache/calcite/runtime/CalciteResource.properties | 1 + .../test/java/org/apache/calcite/test/SqlValidatorTest.java | 13 +++++++++++++ 4 files changed, 25 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/org/apache/calcite/runtime/CalciteResource.java b/core/src/main/java/org/apache/calcite/runtime/CalciteResource.java index 124c5d5203..026715fbf1 100644 --- a/core/src/main/java/org/apache/calcite/runtime/CalciteResource.java +++ b/core/src/main/java/org/apache/calcite/runtime/CalciteResource.java @@ -1180,4 +1180,7 @@ ExInst<RuntimeException> multipleCapturingGroupsForRegexpFunctions(String value, @BaseMessage("SELECT BY cannot be used with ORDER BY") ExInst<SqlValidatorException> selectByCannotWithOrderBy(); + + @BaseMessage("The argument of DESCRIPTOR must be an identifier") + ExInst<SqlValidatorException> descriptorMustBeIdentifier(); } diff --git a/core/src/main/java/org/apache/calcite/sql/SqlWindowTableFunction.java b/core/src/main/java/org/apache/calcite/sql/SqlWindowTableFunction.java index 6decf5b119..ca2fdd19a8 100644 --- a/core/src/main/java/org/apache/calcite/sql/SqlWindowTableFunction.java +++ b/core/src/main/java/org/apache/calcite/sql/SqlWindowTableFunction.java @@ -233,11 +233,16 @@ boolean checkIntervalOperands(SqlCallBinding callBinding, int startPos) { void validateColumnNames(SqlValidator validator, List<String> fieldNames, List<SqlNode> columnNames) { final SqlNameMatcher matcher = validator.getCatalogReader().nameMatcher(); - Ord.forEach(SqlIdentifier.simpleNames(columnNames), (name, i) -> { - if (matcher.indexOf(fieldNames, name) < 0) { + Ord.forEach(columnNames, (name, i) -> { + if (!(name instanceof SqlIdentifier) || !((SqlIdentifier) name).isSimple()) { + throw SqlUtil.newContextException(name.getParserPosition(), + RESOURCE.descriptorMustBeIdentifier()); + } + String simpleName = ((SqlIdentifier) name).getSimple(); + if (matcher.indexOf(fieldNames, simpleName) < 0) { final SqlIdentifier columnName = (SqlIdentifier) columnNames.get(i); throw SqlUtil.newContextException(columnName.getParserPosition(), - RESOURCE.unknownIdentifier(name)); + RESOURCE.unknownIdentifier(simpleName)); } }); } diff --git a/core/src/main/resources/org/apache/calcite/runtime/CalciteResource.properties b/core/src/main/resources/org/apache/calcite/runtime/CalciteResource.properties index 3ffb88a552..e0b1414a16 100644 --- a/core/src/main/resources/org/apache/calcite/runtime/CalciteResource.properties +++ b/core/src/main/resources/org/apache/calcite/runtime/CalciteResource.properties @@ -386,4 +386,5 @@ IllegalRowIndex=Index in ROW type does not have a constant integer or string val CannotInferReturnType=Cannot infer return type for {0}; operand types: {1} SelectByCannotWithGroupBy=SELECT BY cannot be used with GROUP BY SelectByCannotWithOrderBy=SELECT BY cannot be used with ORDER BY +DescriptorMustBeIdentifier=The argument of DESCRIPTOR must be an identifier # End CalciteResource.properties diff --git a/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java b/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java index 40cf5bddf8..dd66362819 100644 --- a/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java +++ b/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java @@ -11593,6 +11593,14 @@ private void checkCustomColumnResolving(String table) { sql("select * from table(tumble(table orders, descriptor(^column_not_exist^), " + "interval '2' hour))") .fails("Unknown identifier 'COLUMN_NOT_EXIST'"); + // Test case for [CALCITE-7377] Validator should reject a DESCRIPTOR in a table + // function when it is not an identifier + sql("select * from table(tumble(table orders, descriptor(^1+2^), " + + "interval '2' hour))") + .fails("The argument of DESCRIPTOR must be an identifier"); + sql("select * from table(tumble(table orders, descriptor(^orders.rowtime^), " + + "interval '2' hour))") + .fails("The argument of DESCRIPTOR must be an identifier"); } @Test void testTumbleTableFunction() { @@ -11758,6 +11766,11 @@ private void checkCustomColumnResolving(String table) { sql("select * from table(\n" + "hop(TABLE ^tabler_not_exist^, descriptor(rowtime), interval '2' hour, interval '1' hour))") .fails("Object 'TABLER_NOT_EXIST' not found"); + // Test case for [CALCITE-7377] Validator should reject a DESCRIPTOR in a table function + // when it is not an identifier + sql("select * from table(\n" + + "hop(table orders, descriptor(^1 + 2^), interval '2' hour, interval '1' hour))") + .fails("The argument of DESCRIPTOR must be an identifier"); } @Test void testSessionTableFunction() {
