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() {

Reply via email to