Skip to content

Commit 44e8bfa

Browse files
committed
ESQL: fix handling equality with MV constants properly (elastic#137032)
Deal with equality (and implicitly the IN operator) properly when it comes to multi-valued constants (literals): they should emit a warning header, a contract set in place in the compute engine Evaluators. Fixes elastic#136998 Fixes elastic#136939
1 parent 969dd4a commit 44e8bfa

File tree

5 files changed

+129
-0
lines changed

5 files changed

+129
-0
lines changed

docs/changelog/137032.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
pr: 137032
2+
summary: Fix handling equality with MV constants properly
3+
area: ES|QL
4+
type: bug
5+
issues:
6+
- 136998
7+
- 136939

x-pack/plugin/esql/qa/testFixtures/src/main/resources/folding.csv-spec

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,3 +103,69 @@ a:s | b:s | x:i | y:s | z:s
103103
"some" | "string" | 4 | "somestring" | "anotherstring"
104104
;
105105

106+
mvBoolean_Equals_MultiValueConstant
107+
required_capability: fix_mv_constant_equals_field
108+
109+
FROM employees
110+
| WHERE is_rehired == ([true, false])
111+
| KEEP is_rehired
112+
;
113+
warning:Line 2:9: evaluation of [is_rehired == ([true, false])] failed, treating result as null. Only first 20 failures recorded.
114+
warning:Line 2:9: java.lang.IllegalArgumentException: single-value function encountered multi-value
115+
116+
is_rehired:boolean
117+
;
118+
119+
computedBoolean_Equals_MultiValueConstant
120+
required_capability: fix_mv_constant_equals_field
121+
122+
FROM employees
123+
| EVAL x = gender IS NULL
124+
| WHERE x == [true, false]
125+
| KEEP x
126+
;
127+
warning:Line 3:9: evaluation of [x == [true, false]] failed, treating result as null. Only first 20 failures recorded.
128+
warning:Line 3:9: java.lang.IllegalArgumentException: single-value function encountered multi-value
129+
130+
x:boolean
131+
;
132+
133+
computedBoolean_Equals_SingleMultiValueConstant
134+
required_capability: fix_mv_constant_equals_field
135+
136+
FROM employees
137+
| EVAL x = gender IS NULL
138+
| WHERE x == [true]
139+
| KEEP x
140+
| LIMIT 1
141+
;
142+
143+
x:boolean
144+
true
145+
;
146+
147+
mvDouble_IN_MultiValueConstant
148+
required_capability: fix_mv_constant_equals_field
149+
150+
FROM employees
151+
| WHERE salary_change IN ([1,2,3])
152+
| KEEP salary_change
153+
;
154+
warning:Line 2:9: evaluation of [salary_change IN ([1,2,3])] failed, treating result as null. Only first 20 failures recorded.
155+
warning:Line 2:9: java.lang.IllegalArgumentException: single-value function encountered multi-value
156+
157+
salary_change:double
158+
;
159+
160+
mvDouble_Equals_MultiValueConstant
161+
required_capability: fix_mv_constant_equals_field
162+
163+
FROM employees
164+
| WHERE salary_change == [1,2,3]
165+
| KEEP salary_change
166+
;
167+
warning:Line 2:9: evaluation of [salary_change == [1,2,3]] failed, treating result as null. Only first 20 failures recorded.
168+
warning:Line 2:9: java.lang.IllegalArgumentException: single-value function encountered multi-value
169+
170+
salary_change:double
171+
;

x-pack/plugin/esql/qa/testFixtures/src/main/resources/string.csv-spec

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2579,6 +2579,54 @@ warning:Line 2:9: java.lang.IllegalArgumentException: single-value function enco
25792579
2023-10-23T13:55:01.544Z|Connected to 10.1.0.1
25802580
;
25812581

2582+
mvStringEqualsMultiValueConstant
2583+
required_capability: fix_mv_constant_equals_field
2584+
FROM mv_text
2585+
| WHERE message == ["Connected to 10.1.0.1", "Banana"]
2586+
| KEEP @timestamp, message
2587+
;
2588+
warning:Line 2:9: evaluation of [message == [\"Connected to 10.1.0.1\", \"Banana\"]] failed, treating result as null. Only first 20 failures recorded.
2589+
warning:Line 2:9: java.lang.IllegalArgumentException: single-value function encountered multi-value
2590+
2591+
@timestamp:date | message:text
2592+
;
2593+
2594+
mvString_IN_MultiValueConstant
2595+
required_capability: fix_mv_constant_equals_field
2596+
FROM mv_text
2597+
| WHERE message IN (["Connected to 10.1.0.1", "Banana"])
2598+
| KEEP @timestamp, message
2599+
;
2600+
warning:Line 2:9: evaluation of [message IN ([\"Connected to 10.1.0.1\", \"Banana\"])] failed, treating result as null. Only first 20 failures recorded.
2601+
warning:Line 2:9: java.lang.IllegalArgumentException: single-value function encountered multi-value
2602+
2603+
@timestamp:date | message:text
2604+
;
2605+
2606+
mvKeyword_IN_MultiValueConstant
2607+
required_capability: fix_mv_constant_equals_field
2608+
FROM employees
2609+
| WHERE job_positions IN (["Tech Lead" , "Data Scientist", "Senior Team Lead"])
2610+
| KEEP emp_no, job_positions
2611+
;
2612+
warning:Line 2:9: evaluation of [job_positions IN ([\"Tech Lead\" , \"Data Scientist\", \"Senior Team Lead\"])] failed, treating result as null. Only first 20 failures recorded.
2613+
warning:Line 2:9: java.lang.IllegalArgumentException: single-value function encountered multi-value
2614+
2615+
emp_no:integer | job_positions:keyword
2616+
;
2617+
2618+
mvKeywordEqualsMultiValueConstant
2619+
required_capability: fix_mv_constant_equals_field
2620+
FROM employees
2621+
| WHERE job_positions == ["Tech Lead" , "Data Scientist", "Senior Team Lead"]
2622+
| KEEP emp_no, job_positions
2623+
;
2624+
warning:Line 2:9: evaluation of [job_positions == [\"Tech Lead\" , \"Data Scientist\", \"Senior Team Lead\"]] failed, treating result as null. Only first 20 failures recorded.
2625+
warning:Line 2:9: java.lang.IllegalArgumentException: single-value function encountered multi-value
2626+
2627+
emp_no:integer | job_positions:keyword
2628+
;
2629+
25822630
url_encode sample for docs
25832631
required_capability: url_encode
25842632

x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1637,6 +1637,7 @@ public enum Cap {
16371637
*/
16381638
LOOKUP_JOIN_SEMANTIC_FILTER_DEDUP,
16391639

1640+
FIX_MV_CONSTANT_EQUALS_FIELD,
16401641
// Last capability should still have a comma for fewer merge conflicts when adding new ones :)
16411642
// This comment prevents the semicolon from being on the previous capability when Spotless formats the file.
16421643
;

x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/Equals.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import org.elasticsearch.xpack.esql.querydsl.query.SingleValueQuery;
2828

2929
import java.time.ZoneId;
30+
import java.util.Collection;
3031
import java.util.Map;
3132

3233
public class Equals extends EsqlBinaryComparison implements Negatable<EsqlBinaryComparison> {
@@ -139,6 +140,12 @@ public Equals(Source source, Expression left, Expression right, ZoneId zoneId) {
139140
@Override
140141
public Translatable translatable(LucenePushdownPredicates pushdownPredicates) {
141142
if (right() instanceof Literal lit) {
143+
// Multi-valued literals are not supported going further. This also makes sure that we are handling multi-valued literals with
144+
// a "warning" header, as well (see EqualsKeywordsEvaluator, for example, where lhs and rhs are both dealt with equally when
145+
// it comes to multi-value handling).
146+
if (lit.value() instanceof Collection<?>) {
147+
return Translatable.NO;
148+
}
142149
if (left().dataType() == DataType.TEXT && left() instanceof FieldAttribute fa) {
143150
if (pushdownPredicates.canUseEqualityOnSyntheticSourceDelegate(fa, ((BytesRef) lit.value()).utf8ToString())) {
144151
return Translatable.YES_BUT_RECHECK_NEGATED;

0 commit comments

Comments
 (0)