Skip to content

Commit 30399bb

Browse files
[ES|QL] Verify aggregation filter's type is boolean to avoid class_cast_exception (#116274) (#116360)
* validate agg filter's type is boolean (cherry picked from commit 0e044d7) # Conflicts: # x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/analysis/Verifier.java
1 parent 2796093 commit 30399bb

File tree

3 files changed

+23
-0
lines changed

3 files changed

+23
-0
lines changed

docs/changelog/116274.yaml

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pr: 116274
2+
summary: "[ES|QL] Verify aggregation filter's type is boolean to avoid `class_cast_exception`"
3+
area: ES|QL
4+
type: bug
5+
issues: []

x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/analysis/Verifier.java

+5
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969
import static org.elasticsearch.xpack.esql.common.Failure.fail;
7070
import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.ParamOrdinal.FIRST;
7171
import static org.elasticsearch.xpack.esql.core.type.DataType.BOOLEAN;
72+
import static org.elasticsearch.xpack.esql.core.type.DataType.NULL;
7273
import static org.elasticsearch.xpack.esql.optimizer.rules.physical.local.PushFiltersToSource.canPushToSource;
7374

7475
/**
@@ -317,6 +318,10 @@ private static void checkInvalidNamedExpressionUsage(
317318
Expression filter = fe.filter();
318319
failures.add(fail(filter, "WHERE clause allowed only for aggregate functions, none found in [{}]", fe.sourceText()));
319320
}
321+
Expression f = fe.filter(); // check the filter has to be a boolean term, similar as checkFilterConditionType
322+
if (f.dataType() != NULL && f.dataType() != BOOLEAN) {
323+
failures.add(fail(f, "Condition expression needs to be boolean, found [{}]", f.dataType()));
324+
}
320325
// but that the filter doesn't use grouping or aggregate functions
321326
fe.filter().forEachDown(c -> {
322327
if (c instanceof AggregateFunction af) {

x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/VerifierTests.java

+13
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,19 @@ public void testAggFilterOnBucketingOrAggFunctions() {
394394
assertEquals("1:60: Unknown column [m]", error("from test | stats m = max(languages), min(languages) WHERE m + 2 > 1 by emp_no"));
395395
}
396396

397+
public void testAggWithNonBooleanFilter() {
398+
for (String filter : List.of("\"true\"", "1", "1 + 0", "concat(\"a\", \"b\")")) {
399+
String type = (filter.equals("1") || filter.equals("1 + 0")) ? "INTEGER" : "KEYWORD";
400+
assertEquals("1:19: Condition expression needs to be boolean, found [" + type + "]", error("from test | where " + filter));
401+
for (String by : List.of("", " by languages", " by bucket(salary, 10)")) {
402+
assertEquals(
403+
"1:34: Condition expression needs to be boolean, found [" + type + "]",
404+
error("from test | stats count(*) where " + filter + by)
405+
);
406+
}
407+
}
408+
}
409+
397410
public void testGroupingInsideAggsAsAgg() {
398411
assertEquals(
399412
"1:18: can only use grouping function [bucket(emp_no, 5.)] part of the BY clause",

0 commit comments

Comments
 (0)