This is an automated email from the ASF dual-hosted git repository.
mbudiu pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/calcite.git
The following commit(s) were added to refs/heads/main by this push:
new 9014934d8c [CALCITE-7193] In an aggregation validator treats lambda
variable names as column names
9014934d8c is described below
commit 9014934d8c24a5242a6840efe20134e820426c24
Author: Mihai Budiu <[email protected]>
AuthorDate: Mon Sep 22 16:35:07 2025 -0700
[CALCITE-7193] In an aggregation validator treats lambda variable names as
column names
Signed-off-by: Mihai Budiu <[email protected]>
---
.../java/org/apache/calcite/sql/validate/AggChecker.java | 10 +++++++++-
.../org/apache/calcite/sql/validate/SqlLambdaScope.java | 5 +++++
.../java/org/apache/calcite/test/SqlValidatorTest.java | 16 ++++++++++++++++
3 files changed, 30 insertions(+), 1 deletion(-)
diff --git a/core/src/main/java/org/apache/calcite/sql/validate/AggChecker.java
b/core/src/main/java/org/apache/calcite/sql/validate/AggChecker.java
index 43ccc3453b..21253ef31f 100644
--- a/core/src/main/java/org/apache/calcite/sql/validate/AggChecker.java
+++ b/core/src/main/java/org/apache/calcite/sql/validate/AggChecker.java
@@ -123,11 +123,19 @@ && isMeasureExp(id)) {
return call.accept(this);
}
+ SqlValidatorScope firstScope = scopes.getFirst();
+ if (firstScope instanceof SqlLambdaScope) {
+ SqlLambdaScope lambdaScope = (SqlLambdaScope) firstScope;
+ if (lambdaScope.isParameter(id)) {
+ return null;
+ }
+ }
+
// Didn't find the identifier in the group-by list as is, now find
// it fully-qualified.
// TODO: It would be better if we always compared fully-qualified
// to fully-qualified.
- final SqlQualified fqId = scopes.getFirst().fullyQualify(id);
+ final SqlQualified fqId = firstScope.fullyQualify(id);
if (isGroupExpr(fqId.identifier)) {
return null;
}
diff --git
a/core/src/main/java/org/apache/calcite/sql/validate/SqlLambdaScope.java
b/core/src/main/java/org/apache/calcite/sql/validate/SqlLambdaScope.java
index 02fb615c76..22003912d4 100644
--- a/core/src/main/java/org/apache/calcite/sql/validate/SqlLambdaScope.java
+++ b/core/src/main/java/org/apache/calcite/sql/validate/SqlLambdaScope.java
@@ -52,6 +52,11 @@ public SqlLambdaScope(
lambdaExpr.getParameters().forEach(param ->
parameterTypes.put(param.toString(), any));
}
+ /** True if the identifier matches one of the parameter names. */
+ public boolean isParameter(SqlIdentifier id) {
+ return this.parameterTypes.containsKey(id.toString());
+ }
+
@Override public SqlNode getNode() {
return lambdaExpr;
}
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 a662b2f70d..29c5a32031 100644
--- a/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java
+++ b/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java
@@ -43,6 +43,7 @@
import org.apache.calcite.sql.fun.SqlCase;
import org.apache.calcite.sql.fun.SqlLibrary;
import org.apache.calcite.sql.fun.SqlLibraryOperatorTableFactory;
+import org.apache.calcite.sql.fun.SqlLibraryOperators;
import org.apache.calcite.sql.fun.SqlStdOperatorTable;
import org.apache.calcite.sql.parser.SqlParseException;
import org.apache.calcite.sql.parser.SqlParser;
@@ -7848,6 +7849,21 @@ void testGroupExpressionEquivalenceParams() {
+ "'\\(`X`, `Y`\\) -> `X` \\+ 1 \\+ `DEPTNO`'");
}
+ /** Test case for <a
href="https://issues.apache.org/jira/browse/CALCITE-7193">[CALCITE-7193]
+ * In an aggregation validator treats lambda variable names as column
names</a>. */
+ @Test void testGroupByLambda() {
+ SqlOperatorTable chain =
+ SqlOperatorTables.chain(
+ SqlOperatorTables.of(
+ SqlLibraryOperators.ARRAY_AGG,
+ SqlLibraryOperators.EXISTS),
+ SqlStdOperatorTable.instance());
+ final String sql = "SELECT \"EXISTS\"(ARRAY_AGG(empno), x -> x > 1) FROM
emp GROUP BY deptno";
+ sql(sql)
+ .withOperatorTable(chain)
+ .ok();
+ }
+
@Test void testPercentileFunctionsBigQuery() {
final SqlOperatorTable opTable = operatorTableFor(SqlLibrary.BIG_QUERY);
final String sql = "select\n"