From 6d1e7247547cf8f9b034b5ffebf96a2fe1d588f7 Mon Sep 17 00:00:00 2001 From: Andrei Stefan Date: Mon, 27 Oct 2025 12:02:24 +0200 Subject: [PATCH 1/4] Extends constant MVs handling with warnings to general binary comparisons --- .../src/main/resources/folding.csv-spec | 144 ++++++++++++++++++ .../src/main/resources/string.csv-spec | 24 +++ .../xpack/esql/action/EsqlCapabilities.java | 2 + .../predicate/operator/comparison/Equals.java | 7 - .../comparison/EsqlBinaryComparison.java | 10 +- 5 files changed, 179 insertions(+), 8 deletions(-) diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/folding.csv-spec b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/folding.csv-spec index dd5e0e7fa3345..466620904aab5 100644 --- a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/folding.csv-spec +++ b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/folding.csv-spec @@ -116,6 +116,19 @@ warning:Line 2:9: java.lang.IllegalArgumentException: single-value function enco is_rehired:boolean ; +mvBoolean_NotEquals_MultiValueConstant +required_capability: fix_mv_constant_equals_field + +FROM employees +| WHERE is_rehired != ([true, false]) +| KEEP is_rehired +; +warning:Line 2:9: evaluation of [is_rehired != ([true, false])] failed, treating result as null. Only first 20 failures recorded. +warning:Line 2:9: java.lang.IllegalArgumentException: single-value function encountered multi-value + + is_rehired:boolean +; + computedBoolean_Equals_MultiValueConstant required_capability: fix_mv_constant_equals_field @@ -130,6 +143,20 @@ warning:Line 3:9: java.lang.IllegalArgumentException: single-value function enco x:boolean ; +computedBoolean_NotEquals_MultiValueConstant +required_capability: fix_mv_constant_comparison_field + +FROM employees +| EVAL x = gender IS NULL +| WHERE x != [true, false] +| KEEP x +; +warning:Line 3:9: evaluation of [x != [true, false]] failed, treating result as null. Only first 20 failures recorded. +warning:Line 3:9: java.lang.IllegalArgumentException: single-value function encountered multi-value + + x:boolean +; + computedBoolean_Equals_SingleMultiValueConstant required_capability: fix_mv_constant_equals_field @@ -169,3 +196,120 @@ warning:Line 2:9: java.lang.IllegalArgumentException: single-value function enco salary_change:double ; + +svDouble_NotEquals_MultiValueConstant +required_capability: fix_mv_constant_comparison_field + +FROM employees +| WHERE salary::double != [1,2,3] +| KEEP salary +; +warning:Line 2:9: evaluation of [salary::double != [1,2,3]] failed, treating result as null. Only first 20 failures recorded. +warning:Line 2:9: java.lang.IllegalArgumentException: single-value function encountered multi-value + + salary:integer +; + +integer_GreaterThan_MultiValueConstant +required_capability: fix_mv_constant_comparison_field + +FROM employees +| WHERE salary > [1,2,3] +| KEEP salary +; +warning:Line 2:9: evaluation of [salary > [1,2,3]] failed, treating result as null. Only first 20 failures recorded. +warning:Line 2:9: java.lang.IllegalArgumentException: single-value function encountered multi-value + + salary:integer +; + +keyword_GreaterThan_MultiValueConstant +required_capability: fix_mv_constant_comparison_field + +FROM employees +| WHERE first_name > ["A","B"] +| KEEP first_name +; +warning:Line 2:9: evaluation of [first_name > [\"A\",\"B\"]] failed, treating result as null. Only first 20 failures recorded. +warning:Line 2:9: java.lang.IllegalArgumentException: single-value function encountered multi-value + + first_name:keyword +; + +dateNanos_GreaterThan_MultiValueConstant +required_capability: fix_mv_constant_comparison_field + +FROM date_nanos +| WHERE nanos > [1.0,2.0]::date_nanos +; +warning:Line 2:9: evaluation of [nanos > [1.0,2.0]::date_nanos] failed, treating result as null. Only first 20 failures recorded. +warning:Line 2:9: java.lang.IllegalArgumentException: single-value function encountered multi-value + + millis:date | nanos:date_nanos | num:long +; + +long_GreaterThan_MultiValueConstant +required_capability: fix_mv_constant_comparison_field + +FROM date_nanos +| WHERE num > [1,2] +; +warning:Line 2:9: evaluation of [num > [1,2]] failed, treating result as null. Only first 20 failures recorded. +warning:Line 2:9: java.lang.IllegalArgumentException: single-value function encountered multi-value + + millis:date | nanos:date_nanos | num:long +; + +version_GreaterThan_MultiValueConstant +required_capability: fix_mv_constant_comparison_field + +FROM apps +| WHERE version > to_ver(["1.2.3.4","127.0.0.1"]) +; +warning:Line 2:9: evaluation of [version > to_ver([\"1.2.3.4\",\"127.0.0.1\"])] failed, treating result as null. Only first 20 failures recorded. +warning:Line 2:9: java.lang.IllegalArgumentException: single-value function encountered multi-value + + id:i | name:s | version:v +; + +ip_GreaterThanOrLessThan_MultiValueConstant +required_capability: fix_mv_constant_comparison_field + +from hosts +| where ip1 > ["1.2.3.4","127.0.0.1"]::ip OR ip0 < to_ip(["1.2.3.4","127.0.0.1"]) +| keep ip1, ip0 +; +warning:Line 2:9: evaluation of [ip1 > [\"1.2.3.4\",\"127.0.0.1\"]::ip] failed, treating result as null. Only first 20 failures recorded. +warning:Line 2:9: java.lang.IllegalArgumentException: single-value function encountered multi-value +warning:Line 2:46: evaluation of [ip0 < to_ip([\"1.2.3.4\",\"127.0.0.1\"])] failed, treating result as null. Only first 20 failures recorded. +warning:Line 2:46: java.lang.IllegalArgumentException: single-value function encountered multi-value + + ip1:ip | ip0:ip +; + +ul_GreaterThan_MultiValueConstant +required_capability: fix_mv_constant_comparison_field + +from ul_logs +| where bytes_in > [16002960716282089759, 17281501450843634251] +| keep bytes_in +; +warning:Line 2:9: evaluation of [bytes_in > [16002960716282089759, 17281501450843634251]] failed, treating result as null. Only first 20 failures recorded. +warning:Line 2:9: java.lang.IllegalArgumentException: single-value function encountered multi-value + + bytes_in:ul +; + +ul_NotEquals_MultiValueConstant +required_capability: fix_mv_constant_comparison_field + +from ul_logs +| where bytes_in != [16002960716282089759, 17281501450843634251] +| keep bytes_in +; +warning:Line 2:9: evaluation of [bytes_in != [16002960716282089759, 17281501450843634251]] failed, treating result as null. Only first 20 failures recorded. +warning:Line 2:9: java.lang.IllegalArgumentException: single-value function encountered multi-value + + bytes_in:ul +; + diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/string.csv-spec b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/string.csv-spec index c1ec0bcd1f639..673c1ce7f158b 100644 --- a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/string.csv-spec +++ b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/string.csv-spec @@ -2594,6 +2594,18 @@ warning:Line 2:9: java.lang.IllegalArgumentException: single-value function enco @timestamp:date | message:text ; +mvStringNotEqualsMultiValueConstant +required_capability: fix_mv_constant_comparison_field +FROM mv_text +| WHERE message != ["Connected to 10.1.0.1", "Banana"] +| KEEP @timestamp, message +; +warning:Line 2:9: evaluation of [message != [\"Connected to 10.1.0.1\", \"Banana\"]] failed, treating result as null. Only first 20 failures recorded. +warning:Line 2:9: java.lang.IllegalArgumentException: single-value function encountered multi-value + + @timestamp:date | message:text +; + mvString_IN_MultiValueConstant required_capability: fix_mv_constant_equals_field FROM mv_text @@ -2630,6 +2642,18 @@ warning:Line 2:9: java.lang.IllegalArgumentException: single-value function enco emp_no:integer | job_positions:keyword ; +mvKeywordNotEqualsMultiValueConstant +required_capability: fix_mv_constant_comparison_field +FROM employees +| WHERE job_positions != ["Tech Lead" , "Data Scientist", "Senior Team Lead"] +| KEEP emp_no, job_positions +; +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. +warning:Line 2:9: java.lang.IllegalArgumentException: single-value function encountered multi-value + + emp_no:integer | job_positions:keyword +; + url_encode sample for docs required_capability: url_encode diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java index 13b337a668ac1..36f111b370b36 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java @@ -1628,6 +1628,8 @@ public enum Cap { * Support for vector similarity functtions pushdown */ VECTOR_SIMILARITY_FUNCTIONS_PUSHDOWN(Build.current().isSnapshot()), + + FIX_MV_CONSTANT_COMPARISON_FIELD, // Last capability should still have a comma for fewer merge conflicts when adding new ones :) // This comment prevents the semicolon from being on the previous capability when Spotless formats the file. ; diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/Equals.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/Equals.java index 0ab0e3c20a2f9..63cda52368eb8 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/Equals.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/Equals.java @@ -27,7 +27,6 @@ import org.elasticsearch.xpack.esql.querydsl.query.SingleValueQuery; import java.time.ZoneId; -import java.util.Collection; import java.util.Map; public class Equals extends EsqlBinaryComparison implements Negatable { @@ -140,12 +139,6 @@ public Equals(Source source, Expression left, Expression right, ZoneId zoneId) { @Override public Translatable translatable(LucenePushdownPredicates pushdownPredicates) { if (right() instanceof Literal lit) { - // Multi-valued literals are not supported going further. This also makes sure that we are handling multi-valued literals with - // a "warning" header, as well (see EqualsKeywordsEvaluator, for example, where lhs and rhs are both dealt with equally when - // it comes to multi-value handling). - if (lit.value() instanceof Collection) { - return Translatable.NO; - } if (left().dataType() == DataType.TEXT && left() instanceof FieldAttribute fa) { if (pushdownPredicates.canUseEqualityOnSyntheticSourceDelegate(fa, ((BytesRef) lit.value()).utf8ToString())) { return Translatable.YES_BUT_RECHECK_NEGATED; diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/EsqlBinaryComparison.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/EsqlBinaryComparison.java index 1c483ebc14744..2d41a2e80789c 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/EsqlBinaryComparison.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/EsqlBinaryComparison.java @@ -22,6 +22,7 @@ import org.elasticsearch.xpack.esql.core.expression.Expressions; import org.elasticsearch.xpack.esql.core.expression.FieldAttribute; import org.elasticsearch.xpack.esql.core.expression.FoldContext; +import org.elasticsearch.xpack.esql.core.expression.Literal; import org.elasticsearch.xpack.esql.core.expression.TypeResolutions; import org.elasticsearch.xpack.esql.core.expression.TypedAttribute; import org.elasticsearch.xpack.esql.core.expression.predicate.operator.comparison.BinaryComparison; @@ -47,6 +48,7 @@ import java.time.OffsetTime; import java.time.ZoneId; import java.time.ZonedDateTime; +import java.util.Collection; import java.util.List; import java.util.Map; @@ -329,7 +331,13 @@ public static String formatIncompatibleTypesMessage(DataType leftType, DataType @Override public Translatable translatable(LucenePushdownPredicates pushdownPredicates) { - if (right().foldable()) { + if (right() instanceof Literal lit) { + // Multi-valued literals are not supported going further. This also makes sure that we are handling multi-valued literals with + // a "warning" header, as well (see EqualsKeywordsEvaluator, for example, where lhs and rhs are both dealt with equally when + // it comes to multi-value handling). + if (lit.value() instanceof Collection) { + return Translatable.NO; + } if (pushdownPredicates.isPushableFieldAttribute(left())) { return Translatable.YES; } From 4a3afd75d9f90402fcaa0efac37d5a02af2f1e0a Mon Sep 17 00:00:00 2001 From: Andrei Stefan Date: Thu, 30 Oct 2025 17:55:15 +0200 Subject: [PATCH 2/4] Update docs/changelog/137387.yaml --- docs/changelog/137387.yaml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 docs/changelog/137387.yaml diff --git a/docs/changelog/137387.yaml b/docs/changelog/137387.yaml new file mode 100644 index 0000000000000..d19fa31e577b2 --- /dev/null +++ b/docs/changelog/137387.yaml @@ -0,0 +1,5 @@ +pr: 137387 +summary: Extends constant MVs handling with warnings to general binary comparisons +area: ES|QL +type: bug +issues: [] From c079a22bad39305cfc4b6b71b3d33d7c7c319b8f Mon Sep 17 00:00:00 2001 From: Andrei Stefan Date: Mon, 27 Oct 2025 12:02:24 +0200 Subject: [PATCH 3/4] Extends constant MVs handling with warnings to general binary comparisons --- .../src/main/resources/folding.csv-spec | 144 ++++++++++++++++++ .../src/main/resources/string.csv-spec | 24 +++ .../xpack/esql/action/EsqlCapabilities.java | 2 + .../comparison/EsqlBinaryComparison.java | 10 +- 4 files changed, 179 insertions(+), 1 deletion(-) diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/folding.csv-spec b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/folding.csv-spec index dd5e0e7fa3345..466620904aab5 100644 --- a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/folding.csv-spec +++ b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/folding.csv-spec @@ -116,6 +116,19 @@ warning:Line 2:9: java.lang.IllegalArgumentException: single-value function enco is_rehired:boolean ; +mvBoolean_NotEquals_MultiValueConstant +required_capability: fix_mv_constant_equals_field + +FROM employees +| WHERE is_rehired != ([true, false]) +| KEEP is_rehired +; +warning:Line 2:9: evaluation of [is_rehired != ([true, false])] failed, treating result as null. Only first 20 failures recorded. +warning:Line 2:9: java.lang.IllegalArgumentException: single-value function encountered multi-value + + is_rehired:boolean +; + computedBoolean_Equals_MultiValueConstant required_capability: fix_mv_constant_equals_field @@ -130,6 +143,20 @@ warning:Line 3:9: java.lang.IllegalArgumentException: single-value function enco x:boolean ; +computedBoolean_NotEquals_MultiValueConstant +required_capability: fix_mv_constant_comparison_field + +FROM employees +| EVAL x = gender IS NULL +| WHERE x != [true, false] +| KEEP x +; +warning:Line 3:9: evaluation of [x != [true, false]] failed, treating result as null. Only first 20 failures recorded. +warning:Line 3:9: java.lang.IllegalArgumentException: single-value function encountered multi-value + + x:boolean +; + computedBoolean_Equals_SingleMultiValueConstant required_capability: fix_mv_constant_equals_field @@ -169,3 +196,120 @@ warning:Line 2:9: java.lang.IllegalArgumentException: single-value function enco salary_change:double ; + +svDouble_NotEquals_MultiValueConstant +required_capability: fix_mv_constant_comparison_field + +FROM employees +| WHERE salary::double != [1,2,3] +| KEEP salary +; +warning:Line 2:9: evaluation of [salary::double != [1,2,3]] failed, treating result as null. Only first 20 failures recorded. +warning:Line 2:9: java.lang.IllegalArgumentException: single-value function encountered multi-value + + salary:integer +; + +integer_GreaterThan_MultiValueConstant +required_capability: fix_mv_constant_comparison_field + +FROM employees +| WHERE salary > [1,2,3] +| KEEP salary +; +warning:Line 2:9: evaluation of [salary > [1,2,3]] failed, treating result as null. Only first 20 failures recorded. +warning:Line 2:9: java.lang.IllegalArgumentException: single-value function encountered multi-value + + salary:integer +; + +keyword_GreaterThan_MultiValueConstant +required_capability: fix_mv_constant_comparison_field + +FROM employees +| WHERE first_name > ["A","B"] +| KEEP first_name +; +warning:Line 2:9: evaluation of [first_name > [\"A\",\"B\"]] failed, treating result as null. Only first 20 failures recorded. +warning:Line 2:9: java.lang.IllegalArgumentException: single-value function encountered multi-value + + first_name:keyword +; + +dateNanos_GreaterThan_MultiValueConstant +required_capability: fix_mv_constant_comparison_field + +FROM date_nanos +| WHERE nanos > [1.0,2.0]::date_nanos +; +warning:Line 2:9: evaluation of [nanos > [1.0,2.0]::date_nanos] failed, treating result as null. Only first 20 failures recorded. +warning:Line 2:9: java.lang.IllegalArgumentException: single-value function encountered multi-value + + millis:date | nanos:date_nanos | num:long +; + +long_GreaterThan_MultiValueConstant +required_capability: fix_mv_constant_comparison_field + +FROM date_nanos +| WHERE num > [1,2] +; +warning:Line 2:9: evaluation of [num > [1,2]] failed, treating result as null. Only first 20 failures recorded. +warning:Line 2:9: java.lang.IllegalArgumentException: single-value function encountered multi-value + + millis:date | nanos:date_nanos | num:long +; + +version_GreaterThan_MultiValueConstant +required_capability: fix_mv_constant_comparison_field + +FROM apps +| WHERE version > to_ver(["1.2.3.4","127.0.0.1"]) +; +warning:Line 2:9: evaluation of [version > to_ver([\"1.2.3.4\",\"127.0.0.1\"])] failed, treating result as null. Only first 20 failures recorded. +warning:Line 2:9: java.lang.IllegalArgumentException: single-value function encountered multi-value + + id:i | name:s | version:v +; + +ip_GreaterThanOrLessThan_MultiValueConstant +required_capability: fix_mv_constant_comparison_field + +from hosts +| where ip1 > ["1.2.3.4","127.0.0.1"]::ip OR ip0 < to_ip(["1.2.3.4","127.0.0.1"]) +| keep ip1, ip0 +; +warning:Line 2:9: evaluation of [ip1 > [\"1.2.3.4\",\"127.0.0.1\"]::ip] failed, treating result as null. Only first 20 failures recorded. +warning:Line 2:9: java.lang.IllegalArgumentException: single-value function encountered multi-value +warning:Line 2:46: evaluation of [ip0 < to_ip([\"1.2.3.4\",\"127.0.0.1\"])] failed, treating result as null. Only first 20 failures recorded. +warning:Line 2:46: java.lang.IllegalArgumentException: single-value function encountered multi-value + + ip1:ip | ip0:ip +; + +ul_GreaterThan_MultiValueConstant +required_capability: fix_mv_constant_comparison_field + +from ul_logs +| where bytes_in > [16002960716282089759, 17281501450843634251] +| keep bytes_in +; +warning:Line 2:9: evaluation of [bytes_in > [16002960716282089759, 17281501450843634251]] failed, treating result as null. Only first 20 failures recorded. +warning:Line 2:9: java.lang.IllegalArgumentException: single-value function encountered multi-value + + bytes_in:ul +; + +ul_NotEquals_MultiValueConstant +required_capability: fix_mv_constant_comparison_field + +from ul_logs +| where bytes_in != [16002960716282089759, 17281501450843634251] +| keep bytes_in +; +warning:Line 2:9: evaluation of [bytes_in != [16002960716282089759, 17281501450843634251]] failed, treating result as null. Only first 20 failures recorded. +warning:Line 2:9: java.lang.IllegalArgumentException: single-value function encountered multi-value + + bytes_in:ul +; + diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/string.csv-spec b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/string.csv-spec index c1ec0bcd1f639..673c1ce7f158b 100644 --- a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/string.csv-spec +++ b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/string.csv-spec @@ -2594,6 +2594,18 @@ warning:Line 2:9: java.lang.IllegalArgumentException: single-value function enco @timestamp:date | message:text ; +mvStringNotEqualsMultiValueConstant +required_capability: fix_mv_constant_comparison_field +FROM mv_text +| WHERE message != ["Connected to 10.1.0.1", "Banana"] +| KEEP @timestamp, message +; +warning:Line 2:9: evaluation of [message != [\"Connected to 10.1.0.1\", \"Banana\"]] failed, treating result as null. Only first 20 failures recorded. +warning:Line 2:9: java.lang.IllegalArgumentException: single-value function encountered multi-value + + @timestamp:date | message:text +; + mvString_IN_MultiValueConstant required_capability: fix_mv_constant_equals_field FROM mv_text @@ -2630,6 +2642,18 @@ warning:Line 2:9: java.lang.IllegalArgumentException: single-value function enco emp_no:integer | job_positions:keyword ; +mvKeywordNotEqualsMultiValueConstant +required_capability: fix_mv_constant_comparison_field +FROM employees +| WHERE job_positions != ["Tech Lead" , "Data Scientist", "Senior Team Lead"] +| KEEP emp_no, job_positions +; +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. +warning:Line 2:9: java.lang.IllegalArgumentException: single-value function encountered multi-value + + emp_no:integer | job_positions:keyword +; + url_encode sample for docs required_capability: url_encode diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java index 13b337a668ac1..36f111b370b36 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java @@ -1628,6 +1628,8 @@ public enum Cap { * Support for vector similarity functtions pushdown */ VECTOR_SIMILARITY_FUNCTIONS_PUSHDOWN(Build.current().isSnapshot()), + + FIX_MV_CONSTANT_COMPARISON_FIELD, // Last capability should still have a comma for fewer merge conflicts when adding new ones :) // This comment prevents the semicolon from being on the previous capability when Spotless formats the file. ; diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/EsqlBinaryComparison.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/EsqlBinaryComparison.java index 1c483ebc14744..2d41a2e80789c 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/EsqlBinaryComparison.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/EsqlBinaryComparison.java @@ -22,6 +22,7 @@ import org.elasticsearch.xpack.esql.core.expression.Expressions; import org.elasticsearch.xpack.esql.core.expression.FieldAttribute; import org.elasticsearch.xpack.esql.core.expression.FoldContext; +import org.elasticsearch.xpack.esql.core.expression.Literal; import org.elasticsearch.xpack.esql.core.expression.TypeResolutions; import org.elasticsearch.xpack.esql.core.expression.TypedAttribute; import org.elasticsearch.xpack.esql.core.expression.predicate.operator.comparison.BinaryComparison; @@ -47,6 +48,7 @@ import java.time.OffsetTime; import java.time.ZoneId; import java.time.ZonedDateTime; +import java.util.Collection; import java.util.List; import java.util.Map; @@ -329,7 +331,13 @@ public static String formatIncompatibleTypesMessage(DataType leftType, DataType @Override public Translatable translatable(LucenePushdownPredicates pushdownPredicates) { - if (right().foldable()) { + if (right() instanceof Literal lit) { + // Multi-valued literals are not supported going further. This also makes sure that we are handling multi-valued literals with + // a "warning" header, as well (see EqualsKeywordsEvaluator, for example, where lhs and rhs are both dealt with equally when + // it comes to multi-value handling). + if (lit.value() instanceof Collection) { + return Translatable.NO; + } if (pushdownPredicates.isPushableFieldAttribute(left())) { return Translatable.YES; } From 85b8acaeb8d047216dca95ec471c6eb46d737e41 Mon Sep 17 00:00:00 2001 From: Andrei Stefan Date: Fri, 31 Oct 2025 10:26:31 +0200 Subject: [PATCH 4/4] Don't touch Equals --- .../expression/predicate/operator/comparison/Equals.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/Equals.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/Equals.java index 63cda52368eb8..0ab0e3c20a2f9 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/Equals.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/Equals.java @@ -27,6 +27,7 @@ import org.elasticsearch.xpack.esql.querydsl.query.SingleValueQuery; import java.time.ZoneId; +import java.util.Collection; import java.util.Map; public class Equals extends EsqlBinaryComparison implements Negatable { @@ -139,6 +140,12 @@ public Equals(Source source, Expression left, Expression right, ZoneId zoneId) { @Override public Translatable translatable(LucenePushdownPredicates pushdownPredicates) { if (right() instanceof Literal lit) { + // Multi-valued literals are not supported going further. This also makes sure that we are handling multi-valued literals with + // a "warning" header, as well (see EqualsKeywordsEvaluator, for example, where lhs and rhs are both dealt with equally when + // it comes to multi-value handling). + if (lit.value() instanceof Collection) { + return Translatable.NO; + } if (left().dataType() == DataType.TEXT && left() instanceof FieldAttribute fa) { if (pushdownPredicates.canUseEqualityOnSyntheticSourceDelegate(fa, ((BytesRef) lit.value()).utf8ToString())) { return Translatable.YES_BUT_RECHECK_NEGATED;