1
0
Эх сурвалжийг харах

Revert "Add MV_CONTAINS function (#133099)"

This reverts commit 1e584281fda0cda7ad0bd542210ef06ff521ca03.
David Turner 1 сар өмнө
parent
commit
b22e953564
19 өөрчлөгдсөн 0 нэмэгдсэн , 1701 устгасан
  1. 0 5
      docs/changelog/133099.yaml
  2. 0 6
      docs/reference/query-languages/esql/_snippets/functions/description/mv_contains.md
  3. 0 34
      docs/reference/query-languages/esql/_snippets/functions/examples/mv_contains.md
  4. 0 26
      docs/reference/query-languages/esql/_snippets/functions/layout/mv_contains.md
  5. 0 10
      docs/reference/query-languages/esql/_snippets/functions/parameters/mv_contains.md
  6. 0 24
      docs/reference/query-languages/esql/_snippets/functions/types/mv_contains.md
  7. 0 1
      docs/reference/query-languages/esql/_snippets/lists/mv-functions.md
  8. 0 3
      docs/reference/query-languages/esql/functions-operators/mv-functions.md
  9. 0 1
      docs/reference/query-languages/esql/images/functions/mv_contains.svg
  10. 0 321
      docs/reference/query-languages/esql/kibana/definition/functions/mv_contains.json
  11. 0 9
      docs/reference/query-languages/esql/kibana/docs/functions/mv_contains.md
  12. 0 60
      x-pack/plugin/esql/qa/testFixtures/src/main/resources/string.csv-spec
  13. 0 6
      x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java
  14. 0 2
      x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/EsqlFunctionRegistry.java
  15. 0 742
      x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvContains.java
  16. 0 1
      x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvFunctionWritables.java
  17. 0 45
      x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvContainsErrorTests.java
  18. 0 37
      x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvContainsSerializationTests.java
  19. 0 368
      x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvContainsTests.java

+ 0 - 5
docs/changelog/133099.yaml

@@ -1,5 +0,0 @@
-pr: 133099
-summary: Add MV_CONTAINS function
-area: ES|QL
-type: enhancement
-issues: []

+ 0 - 6
docs/reference/query-languages/esql/_snippets/functions/description/mv_contains.md

@@ -1,6 +0,0 @@
-% This is generated by ESQL's AbstractFunctionTestCase. Do not edit it. See ../README.md for how to regenerate it.
-
-**Description**
-
-Checks if all values yielded by the second multivalue expression are present in the values yielded by the first multivalue expression. Returns a boolean. Null values are treated as an empty set.
-

+ 0 - 34
docs/reference/query-languages/esql/_snippets/functions/examples/mv_contains.md

@@ -1,34 +0,0 @@
-% This is generated by ESQL's AbstractFunctionTestCase. Do not edit it. See ../README.md for how to regenerate it.
-
-**Examples**
-
-```esql
-ROW set = ["a", "b", "c"], element = "a"
-| EVAL set_contains_element = mv_contains(set, element)
-```
-
-| set:keyword | element:keyword | set_contains_element:boolean |
-| --- | --- | --- |
-| [a, b, c] | a | true |
-
-```esql
-ROW setA = ["a","c"], setB = ["a", "b", "c"]
-| EVAL a_subset_of_b = mv_contains(setB, setA)
-| EVAL b_subset_of_a = mv_contains(setA, setB)
-```
-
-| setA:keyword | setB:keyword | a_subset_of_b:boolean | b_subset_of_a:boolean |
-| --- | --- | --- | --- |
-| [a, c] | [a, b, c] | true | false |
-
-```esql
-FROM airports
-| WHERE mv_contains(type, ["major","military"]) AND scalerank == 9
-| KEEP scalerank, name, country
-```
-
-| scalerank:integer | name:text | country:keyword |
-| --- | --- | --- |
-| 9 | Chandigarh Int'l | India |
-
-

+ 0 - 26
docs/reference/query-languages/esql/_snippets/functions/layout/mv_contains.md

@@ -1,26 +0,0 @@
-% This is generated by ESQL's AbstractFunctionTestCase. Do not edit it. See ../README.md for how to regenerate it.
-
-## `MV_CONTAINS` [esql-mv_contains]
-```{applies_to}
-stack: preview 9.2.0
-```
-
-**Syntax**
-
-:::{image} ../../../images/functions/mv_contains.svg
-:alt: Embedded
-:class: text-center
-:::
-
-
-:::{include} ../parameters/mv_contains.md
-:::
-
-:::{include} ../description/mv_contains.md
-:::
-
-:::{include} ../types/mv_contains.md
-:::
-
-:::{include} ../examples/mv_contains.md
-:::

+ 0 - 10
docs/reference/query-languages/esql/_snippets/functions/parameters/mv_contains.md

@@ -1,10 +0,0 @@
-% This is generated by ESQL's AbstractFunctionTestCase. Do not edit it. See ../README.md for how to regenerate it.
-
-**Parameters**
-
-`superset`
-:   Multivalue expression.
-
-`subset`
-:   Multivalue expression.
-

+ 0 - 24
docs/reference/query-languages/esql/_snippets/functions/types/mv_contains.md

@@ -1,24 +0,0 @@
-% This is generated by ESQL's AbstractFunctionTestCase. Do not edit it. See ../README.md for how to regenerate it.
-
-**Supported types**
-
-| superset | subset | result |
-| --- | --- | --- |
-| boolean | boolean | boolean |
-| cartesian_point | cartesian_point | boolean |
-| cartesian_shape | cartesian_shape | boolean |
-| date | date | boolean |
-| date_nanos | date_nanos | boolean |
-| double | double | boolean |
-| geo_point | geo_point | boolean |
-| geo_shape | geo_shape | boolean |
-| integer | integer | boolean |
-| ip | ip | boolean |
-| keyword | keyword | boolean |
-| keyword | text | boolean |
-| long | long | boolean |
-| text | keyword | boolean |
-| text | text | boolean |
-| unsigned_long | unsigned_long | boolean |
-| version | version | boolean |
-

+ 0 - 1
docs/reference/query-languages/esql/_snippets/lists/mv-functions.md

@@ -1,7 +1,6 @@
 * [`MV_APPEND`](../../functions-operators/mv-functions.md#esql-mv_append)
 * [`MV_AVG`](../../functions-operators/mv-functions.md#esql-mv_avg)
 * [`MV_CONCAT`](../../functions-operators/mv-functions.md#esql-mv_concat)
-* [preview] [`MV_CONTAINS`](../../functions-operators/mv-functions.md#esql-mv_contains)
 * [`MV_COUNT`](../../functions-operators/mv-functions.md#esql-mv_count)
 * [`MV_DEDUPE`](../../functions-operators/mv-functions.md#esql-mv_dedupe)
 * [`MV_FIRST`](../../functions-operators/mv-functions.md#esql-mv_first)

+ 0 - 3
docs/reference/query-languages/esql/functions-operators/mv-functions.md

@@ -21,9 +21,6 @@ mapped_pages:
 :::{include} ../_snippets/functions/layout/mv_concat.md
 :::
 
-:::{include} ../_snippets/functions/layout/mv_contains.md
-:::
-
 :::{include} ../_snippets/functions/layout/mv_count.md
 :::
 

+ 0 - 1
docs/reference/query-languages/esql/images/functions/mv_contains.svg

@@ -1 +0,0 @@
-<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="516" height="46" viewbox="0 0 516 46"><defs><style type="text/css">.c{fill:none;stroke:#222222;}.k{fill:#000000;font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;font-size:20px;}.s{fill:#e4f4ff;stroke:#222222;}.syn{fill:#8D8D8D;font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;font-size:20px;}</style></defs><path class="c" d="M0 31h5m152 0h10m32 0h10m116 0h10m32 0h10m92 0h10m32 0h5"/><rect class="s" x="5" y="5" width="152" height="36"/><text class="k" x="15" y="31">MV_CONTAINS</text><rect class="s" x="167" y="5" width="32" height="36" rx="7"/><text class="syn" x="177" y="31">(</text><rect class="s" x="209" y="5" width="116" height="36" rx="7"/><text class="k" x="219" y="31">superset</text><rect class="s" x="335" y="5" width="32" height="36" rx="7"/><text class="syn" x="345" y="31">,</text><rect class="s" x="377" y="5" width="92" height="36" rx="7"/><text class="k" x="387" y="31">subset</text><rect class="s" x="479" y="5" width="32" height="36" rx="7"/><text class="syn" x="489" y="31">)</text></svg>

+ 0 - 321
docs/reference/query-languages/esql/kibana/definition/functions/mv_contains.json

@@ -1,321 +0,0 @@
-{
-  "comment" : "This is generated by ESQL's AbstractFunctionTestCase. Do not edit it. See ../README.md for how to regenerate it.",
-  "type" : "scalar",
-  "name" : "mv_contains",
-  "description" : "Checks if all values yielded by the second multivalue expression are present in the values yielded by the first multivalue expression. Returns a boolean. Null values are treated as an empty set.",
-  "signatures" : [
-    {
-      "params" : [
-        {
-          "name" : "superset",
-          "type" : "boolean",
-          "optional" : false,
-          "description" : "Multivalue expression."
-        },
-        {
-          "name" : "subset",
-          "type" : "boolean",
-          "optional" : false,
-          "description" : "Multivalue expression."
-        }
-      ],
-      "variadic" : false,
-      "returnType" : "boolean"
-    },
-    {
-      "params" : [
-        {
-          "name" : "superset",
-          "type" : "cartesian_point",
-          "optional" : false,
-          "description" : "Multivalue expression."
-        },
-        {
-          "name" : "subset",
-          "type" : "cartesian_point",
-          "optional" : false,
-          "description" : "Multivalue expression."
-        }
-      ],
-      "variadic" : false,
-      "returnType" : "boolean"
-    },
-    {
-      "params" : [
-        {
-          "name" : "superset",
-          "type" : "cartesian_shape",
-          "optional" : false,
-          "description" : "Multivalue expression."
-        },
-        {
-          "name" : "subset",
-          "type" : "cartesian_shape",
-          "optional" : false,
-          "description" : "Multivalue expression."
-        }
-      ],
-      "variadic" : false,
-      "returnType" : "boolean"
-    },
-    {
-      "params" : [
-        {
-          "name" : "superset",
-          "type" : "date",
-          "optional" : false,
-          "description" : "Multivalue expression."
-        },
-        {
-          "name" : "subset",
-          "type" : "date",
-          "optional" : false,
-          "description" : "Multivalue expression."
-        }
-      ],
-      "variadic" : false,
-      "returnType" : "boolean"
-    },
-    {
-      "params" : [
-        {
-          "name" : "superset",
-          "type" : "date_nanos",
-          "optional" : false,
-          "description" : "Multivalue expression."
-        },
-        {
-          "name" : "subset",
-          "type" : "date_nanos",
-          "optional" : false,
-          "description" : "Multivalue expression."
-        }
-      ],
-      "variadic" : false,
-      "returnType" : "boolean"
-    },
-    {
-      "params" : [
-        {
-          "name" : "superset",
-          "type" : "double",
-          "optional" : false,
-          "description" : "Multivalue expression."
-        },
-        {
-          "name" : "subset",
-          "type" : "double",
-          "optional" : false,
-          "description" : "Multivalue expression."
-        }
-      ],
-      "variadic" : false,
-      "returnType" : "boolean"
-    },
-    {
-      "params" : [
-        {
-          "name" : "superset",
-          "type" : "geo_point",
-          "optional" : false,
-          "description" : "Multivalue expression."
-        },
-        {
-          "name" : "subset",
-          "type" : "geo_point",
-          "optional" : false,
-          "description" : "Multivalue expression."
-        }
-      ],
-      "variadic" : false,
-      "returnType" : "boolean"
-    },
-    {
-      "params" : [
-        {
-          "name" : "superset",
-          "type" : "geo_shape",
-          "optional" : false,
-          "description" : "Multivalue expression."
-        },
-        {
-          "name" : "subset",
-          "type" : "geo_shape",
-          "optional" : false,
-          "description" : "Multivalue expression."
-        }
-      ],
-      "variadic" : false,
-      "returnType" : "boolean"
-    },
-    {
-      "params" : [
-        {
-          "name" : "superset",
-          "type" : "integer",
-          "optional" : false,
-          "description" : "Multivalue expression."
-        },
-        {
-          "name" : "subset",
-          "type" : "integer",
-          "optional" : false,
-          "description" : "Multivalue expression."
-        }
-      ],
-      "variadic" : false,
-      "returnType" : "boolean"
-    },
-    {
-      "params" : [
-        {
-          "name" : "superset",
-          "type" : "ip",
-          "optional" : false,
-          "description" : "Multivalue expression."
-        },
-        {
-          "name" : "subset",
-          "type" : "ip",
-          "optional" : false,
-          "description" : "Multivalue expression."
-        }
-      ],
-      "variadic" : false,
-      "returnType" : "boolean"
-    },
-    {
-      "params" : [
-        {
-          "name" : "superset",
-          "type" : "keyword",
-          "optional" : false,
-          "description" : "Multivalue expression."
-        },
-        {
-          "name" : "subset",
-          "type" : "keyword",
-          "optional" : false,
-          "description" : "Multivalue expression."
-        }
-      ],
-      "variadic" : false,
-      "returnType" : "boolean"
-    },
-    {
-      "params" : [
-        {
-          "name" : "superset",
-          "type" : "keyword",
-          "optional" : false,
-          "description" : "Multivalue expression."
-        },
-        {
-          "name" : "subset",
-          "type" : "text",
-          "optional" : false,
-          "description" : "Multivalue expression."
-        }
-      ],
-      "variadic" : false,
-      "returnType" : "boolean"
-    },
-    {
-      "params" : [
-        {
-          "name" : "superset",
-          "type" : "long",
-          "optional" : false,
-          "description" : "Multivalue expression."
-        },
-        {
-          "name" : "subset",
-          "type" : "long",
-          "optional" : false,
-          "description" : "Multivalue expression."
-        }
-      ],
-      "variadic" : false,
-      "returnType" : "boolean"
-    },
-    {
-      "params" : [
-        {
-          "name" : "superset",
-          "type" : "text",
-          "optional" : false,
-          "description" : "Multivalue expression."
-        },
-        {
-          "name" : "subset",
-          "type" : "keyword",
-          "optional" : false,
-          "description" : "Multivalue expression."
-        }
-      ],
-      "variadic" : false,
-      "returnType" : "boolean"
-    },
-    {
-      "params" : [
-        {
-          "name" : "superset",
-          "type" : "text",
-          "optional" : false,
-          "description" : "Multivalue expression."
-        },
-        {
-          "name" : "subset",
-          "type" : "text",
-          "optional" : false,
-          "description" : "Multivalue expression."
-        }
-      ],
-      "variadic" : false,
-      "returnType" : "boolean"
-    },
-    {
-      "params" : [
-        {
-          "name" : "superset",
-          "type" : "unsigned_long",
-          "optional" : false,
-          "description" : "Multivalue expression."
-        },
-        {
-          "name" : "subset",
-          "type" : "unsigned_long",
-          "optional" : false,
-          "description" : "Multivalue expression."
-        }
-      ],
-      "variadic" : false,
-      "returnType" : "boolean"
-    },
-    {
-      "params" : [
-        {
-          "name" : "superset",
-          "type" : "version",
-          "optional" : false,
-          "description" : "Multivalue expression."
-        },
-        {
-          "name" : "subset",
-          "type" : "version",
-          "optional" : false,
-          "description" : "Multivalue expression."
-        }
-      ],
-      "variadic" : false,
-      "returnType" : "boolean"
-    }
-  ],
-  "examples" : [
-    "ROW set = [\"a\", \"b\", \"c\"], element = \"a\"\n| EVAL set_contains_element = mv_contains(set, element)",
-    "ROW setA = [\"a\",\"c\"], setB = [\"a\", \"b\", \"c\"]\n| EVAL a_subset_of_b = mv_contains(setB, setA)\n| EVAL b_subset_of_a = mv_contains(setA, setB)",
-    "FROM airports\n| WHERE mv_contains(type, [\"major\",\"military\"]) AND scalerank == 9\n| KEEP scalerank, name, country"
-  ],
-  "preview" : false,
-  "snapshot_only" : false
-}

+ 0 - 9
docs/reference/query-languages/esql/kibana/docs/functions/mv_contains.md

@@ -1,9 +0,0 @@
-% This is generated by ESQL's AbstractFunctionTestCase. Do not edit it. See ../README.md for how to regenerate it.
-
-### MV CONTAINS
-Checks if all values yielded by the second multivalue expression are present in the values yielded by the first multivalue expression. Returns a boolean. Null values are treated as an empty set.
-
-```esql
-ROW set = ["a", "b", "c"], element = "a"
-| EVAL set_contains_element = mv_contains(set, element)
-```

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

@@ -2026,66 +2026,6 @@ l1:integer | l2:integer
 null       | 0
 ;
 
-mvContains
-required_capability: fn_mv_contains
-// tag::mv_contains[]
-ROW set = ["a", "b", "c"], element = "a"
-| EVAL set_contains_element = mv_contains(set, element)
-// end::mv_contains[]
-;
-
-// tag::mv_contains-result[]
-set:keyword | element:keyword | set_contains_element:boolean 
-[a, b, c]   | a               | true         
-// end::mv_contains-result[]
-;
-
-mvContains_bothsides
-required_capability: fn_mv_contains
-// tag::mv_contains_bothsides[]
-ROW setA = ["a","c"], setB = ["a", "b", "c"]
-| EVAL a_subset_of_b = mv_contains(setB, setA)
-| EVAL b_subset_of_a = mv_contains(setA, setB)
-// end::mv_contains_bothsides[]
-;
-
-// tag::mv_contains_bothsides-result[]
-setA:keyword | setB:keyword | a_subset_of_b:boolean | b_subset_of_a:boolean 
-[a, c]       | [a, b, c]    | true                  | false
-// end::mv_contains_bothsides-result[]
-;
-
-mvContainsCombinations
-required_capability: fn_mv_contains
-
-ROW a = "a", b = ["a", "b", "c"], n = null
-| EVAL aa = mv_contains(a, a), 
-       bb = mv_contains(b, b), 
-       ab = mv_contains(a, b), 
-       ba = mv_contains(b,a), 
-       na = mv_contains(n, a), 
-       an = mv_contains(a, n), 
-       nn = mv_contains(n,n)
-;
-
-a:keyword | b:keyword | n:null | aa:boolean | bb:boolean   | ab:boolean | ba:boolean | na:boolean | an:boolean | nn:boolean
-a         | [a, b, c] | null   | true       | true         | false      | true       | false      | true       | true
-;
-
-mvContains_where
-required_capability: fn_mv_contains
-// tag::mv_contains_where[]
-FROM airports
-| WHERE mv_contains(type, ["major","military"]) AND scalerank == 9
-| KEEP scalerank, name, country
-// end::mv_contains_where[]
-;
-
-// tag::mv_contains_where-result[]
-scalerank:integer | name:text               | country:keyword  
-9                 | Chandigarh Int'l        | India
-// end::mv_contains_where-result[]
-;
 
 mvAppend
 required_capability: fn_mv_append

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

@@ -250,12 +250,6 @@ public class EsqlCapabilities {
          */
         FN_MONTH_NAME,
 
-        /**
-         * support for MV_CONTAINS function
-         * <a href="https://github.com/elastic/elasticsearch/pull/133099/">Add MV_CONTAINS function #133099</a>
-         */
-        FN_MV_CONTAINS,
-
         /**
          * Fixes for multiple functions not serializing their source, and emitting warnings with wrong line number and text.
          */

+ 0 - 2
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/EsqlFunctionRegistry.java

@@ -123,7 +123,6 @@ import org.elasticsearch.xpack.esql.expression.function.scalar.math.Tau;
 import org.elasticsearch.xpack.esql.expression.function.scalar.multivalue.MvAppend;
 import org.elasticsearch.xpack.esql.expression.function.scalar.multivalue.MvAvg;
 import org.elasticsearch.xpack.esql.expression.function.scalar.multivalue.MvConcat;
-import org.elasticsearch.xpack.esql.expression.function.scalar.multivalue.MvContains;
 import org.elasticsearch.xpack.esql.expression.function.scalar.multivalue.MvCount;
 import org.elasticsearch.xpack.esql.expression.function.scalar.multivalue.MvDedupe;
 import org.elasticsearch.xpack.esql.expression.function.scalar.multivalue.MvFirst;
@@ -453,7 +452,6 @@ public class EsqlFunctionRegistry {
                 def(MvAppend.class, MvAppend::new, "mv_append"),
                 def(MvAvg.class, MvAvg::new, "mv_avg"),
                 def(MvConcat.class, MvConcat::new, "mv_concat"),
-                def(MvContains.class, MvContains::new, "mv_contains"),
                 def(MvCount.class, MvCount::new, "mv_count"),
                 def(MvDedupe.class, MvDedupe::new, "mv_dedupe"),
                 def(MvFirst.class, MvFirst::new, "mv_first"),

+ 0 - 742
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvContains.java

@@ -1,742 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License
- * 2.0; you may not use this file except in compliance with the Elastic License
- * 2.0.
- */
-
-package org.elasticsearch.xpack.esql.expression.function.scalar.multivalue;
-
-import org.apache.lucene.util.BytesRef;
-import org.elasticsearch.common.io.stream.NamedWriteableRegistry;
-import org.elasticsearch.common.io.stream.StreamInput;
-import org.elasticsearch.compute.data.Block;
-import org.elasticsearch.compute.data.BooleanBlock;
-import org.elasticsearch.compute.data.BytesRefBlock;
-import org.elasticsearch.compute.data.DoubleBlock;
-import org.elasticsearch.compute.data.ElementType;
-import org.elasticsearch.compute.data.IntBlock;
-import org.elasticsearch.compute.data.LongBlock;
-import org.elasticsearch.compute.data.Page;
-import org.elasticsearch.compute.operator.DriverContext;
-import org.elasticsearch.compute.operator.EvalOperator;
-import org.elasticsearch.compute.operator.EvalOperator.ExpressionEvaluator;
-import org.elasticsearch.core.Releasables;
-import org.elasticsearch.xpack.esql.EsqlIllegalArgumentException;
-import org.elasticsearch.xpack.esql.core.expression.Expression;
-import org.elasticsearch.xpack.esql.core.expression.FoldContext;
-import org.elasticsearch.xpack.esql.core.expression.Nullability;
-import org.elasticsearch.xpack.esql.core.expression.function.scalar.BinaryScalarFunction;
-import org.elasticsearch.xpack.esql.core.tree.NodeInfo;
-import org.elasticsearch.xpack.esql.core.tree.Source;
-import org.elasticsearch.xpack.esql.core.type.DataType;
-import org.elasticsearch.xpack.esql.evaluator.mapper.EvaluatorMapper;
-import org.elasticsearch.xpack.esql.expression.function.Example;
-import org.elasticsearch.xpack.esql.expression.function.FunctionAppliesTo;
-import org.elasticsearch.xpack.esql.expression.function.FunctionAppliesToLifecycle;
-import org.elasticsearch.xpack.esql.expression.function.FunctionInfo;
-import org.elasticsearch.xpack.esql.expression.function.Param;
-import org.elasticsearch.xpack.esql.planner.PlannerUtils;
-
-import java.io.IOException;
-
-import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.ParamOrdinal.FIRST;
-import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.ParamOrdinal.SECOND;
-import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.isRepresentableExceptCounters;
-import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.isType;
-
-/**
- * Function that takes two multivalued expressions and checks if values of one expression are all present(equals) in the other.
- * <p>
- * Given Set A = {"a","b","c"} and Set B = {"b","c"}, the relationship between first (row) and second (column) arguments is:
- * <ul>
- *     <li>A, B &rArr; true  (A &sube; B)</li>
- *     <li>B, A &rArr; false (A &#8840; B)</li>
- *     <li>A, A &rArr; true (A &equiv; A)</li>
- *     <li>B, B &rArr; true (B &equiv; B)</li>
- *     <li>A, null &rArr; true (B &sube; &empty;)</li>
- *     <li>null, A &rArr; false (&empty; &#8840; B)</li>
- *     <li>B, null &rArr; true (B &sube; &empty;)</li>
- *     <li>null, B &rArr; false (&empty; &#8840; B)</li>
- *     <li>null, null &rArr; true (&empty; &equiv; &empty;)</li>
- * </ul>
- */
-public class MvContains extends BinaryScalarFunction implements EvaluatorMapper {
-    public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry(
-        Expression.class,
-        "MvContains",
-        MvContains::new
-    );
-
-    @FunctionInfo(
-        returnType = "boolean",
-        description = "Checks if all values yielded by the second multivalue expression are present in the values yielded by "
-            + "the first multivalue expression. Returns a boolean. Null values are treated as an empty set.",
-        examples = {
-            @Example(file = "string", tag = "mv_contains"),
-            @Example(file = "string", tag = "mv_contains_bothsides"),
-            @Example(file = "string", tag = "mv_contains_where"), },
-        appliesTo = { @FunctionAppliesTo(lifeCycle = FunctionAppliesToLifecycle.PREVIEW, version = "9.2.0") }
-    )
-    public MvContains(
-        Source source,
-        @Param(
-            name = "superset",
-            type = {
-                "boolean",
-                "cartesian_point",
-                "cartesian_shape",
-                "date",
-                "date_nanos",
-                "double",
-                "geo_point",
-                "geo_shape",
-                "integer",
-                "ip",
-                "keyword",
-                "long",
-                "text",
-                "unsigned_long",
-                "version" },
-            description = "Multivalue expression."
-        ) Expression superset,
-        @Param(
-            name = "subset",
-            type = {
-                "boolean",
-                "cartesian_point",
-                "cartesian_shape",
-                "date",
-                "date_nanos",
-                "double",
-                "geo_point",
-                "geo_shape",
-                "integer",
-                "ip",
-                "keyword",
-                "long",
-                "text",
-                "unsigned_long",
-                "version" },
-            description = "Multivalue expression."
-        ) Expression subset
-    ) {
-        super(source, superset, subset);
-    }
-
-    private MvContains(StreamInput in) throws IOException {
-        super(in);
-    }
-
-    @Override
-    public String getWriteableName() {
-        return ENTRY.name;
-    }
-
-    @Override
-    protected TypeResolution resolveType() {
-        if (childrenResolved() == false) {
-            return new TypeResolution("Unresolved children");
-        }
-
-        TypeResolution resolution = isRepresentableExceptCounters(left(), sourceText(), FIRST);
-        if (resolution.unresolved()) {
-            return resolution;
-        }
-        if (left().dataType() == DataType.NULL) {
-            return isRepresentableExceptCounters(right(), sourceText(), SECOND);
-        }
-        return isType(right(), t -> t.noText() == left().dataType().noText(), sourceText(), SECOND, left().dataType().noText().typeName());
-    }
-
-    @Override
-    public DataType dataType() {
-        return DataType.BOOLEAN;
-    }
-
-    @Override
-    public Nullability nullable() {
-        return Nullability.FALSE;
-    }
-
-    @Override
-    protected MvContains replaceChildren(Expression newLeft, Expression newRight) {
-        return new MvContains(source(), newLeft, newRight);
-    }
-
-    @Override
-    protected NodeInfo<? extends Expression> info() {
-        return NodeInfo.create(this, MvContains::new, left(), right());
-    }
-
-    @Override
-    public Object fold(FoldContext ctx) {
-        return EvaluatorMapper.super.fold(source(), ctx);
-    }
-
-    @Override
-    public ExpressionEvaluator.Factory toEvaluator(ToEvaluator toEvaluator) {
-        var supersetType = PlannerUtils.toElementType(left().dataType());
-        var subsetType = PlannerUtils.toElementType(right().dataType());
-        if (supersetType != ElementType.NULL && subsetType != ElementType.NULL && supersetType != subsetType) {
-            throw new EsqlIllegalArgumentException(
-                "Incompatible data types for MvContains, superset type({}) value({}) and subset type({}) value({}) don't match.",
-                supersetType,
-                left(),
-                subsetType,
-                right()
-            );
-        }
-        if (supersetType == ElementType.NULL || subsetType == ElementType.NULL) {
-            return new MvContainsNullEvaluator(toEvaluator.apply(right()));
-        }
-        return switch (supersetType) {
-            case BOOLEAN -> new MvContainsBooleanEvaluator.Factory(source(), toEvaluator.apply(left()), toEvaluator.apply(right()));
-            case BYTES_REF -> new MvContainsBytesRefEvaluator.Factory(source(), toEvaluator.apply(left()), toEvaluator.apply(right()));
-            case DOUBLE -> new MvContainsDoubleEvaluator.Factory(source(), toEvaluator.apply(left()), toEvaluator.apply(right()));
-            case INT -> new MvContainsIntEvaluator.Factory(source(), toEvaluator.apply(left()), toEvaluator.apply(right()));
-            case LONG -> new MvContainsLongEvaluator.Factory(source(), toEvaluator.apply(left()), toEvaluator.apply(right()));
-            default -> throw EsqlIllegalArgumentException.illegalDataType(dataType());
-        };
-    }
-
-    // @Evaluator(extraName = "Int") see end of file.
-    static void process(BooleanBlock.Builder builder, int position, IntBlock field1, IntBlock field2) {
-        appendTo(builder, containsAll(field1, field2, position, IntBlock::getInt));
-    }
-
-    // @Evaluator(extraName = "Boolean") see end of file.
-    static void process(BooleanBlock.Builder builder, int position, BooleanBlock field1, BooleanBlock field2) {
-        appendTo(builder, containsAll(field1, field2, position, BooleanBlock::getBoolean));
-    }
-
-    // @Evaluator(extraName = "Long") see end of file.
-    static void process(BooleanBlock.Builder builder, int position, LongBlock field1, LongBlock field2) {
-        appendTo(builder, containsAll(field1, field2, position, LongBlock::getLong));
-    }
-
-    // @Evaluator(extraName = "Double") see end of file.
-    static void process(BooleanBlock.Builder builder, int position, DoubleBlock field1, DoubleBlock field2) {
-        appendTo(builder, containsAll(field1, field2, position, DoubleBlock::getDouble));
-    }
-
-    // @Evaluator(extraName = "BytesRef") see end of file.
-    static void process(BooleanBlock.Builder builder, int position, BytesRefBlock field1, BytesRefBlock field2) {
-        appendTo(builder, containsAll(field1, field2, position, (block, index) -> {
-            var ref = new BytesRef();
-            // we pass in a reference, but sometimes we only get a return value, see ConstantBytesRefVector.getBytesRef
-            ref = block.getBytesRef(index, ref);
-            // pass empty ref as null
-            if (ref.length == 0) {
-                return null;
-            }
-            return ref;
-        }));
-    }
-
-    static void appendTo(BooleanBlock.Builder builder, Boolean bool) {
-        if (bool == null) {
-            builder.appendNull();
-        } else {
-            builder.beginPositionEntry().appendBoolean(bool).endPositionEntry();
-        }
-    }
-
-    /**
-     * A block is considered a subset if the superset contains values that test equal for all the values in the subset, independent of
-     * order. Duplicates are ignored in the sense that for each duplicate in the subset, we will search/match against the first/any value
-     * in the superset.
-     *
-     * @param superset block to check against
-     * @param subset   block containing values that should be present in the other block.
-     * @return {@code true} if the given blocks are a superset and subset to each other, {@code false} if not.
-     */
-    static <BlockType extends Block, Type> Boolean containsAll(
-        BlockType superset,
-        BlockType subset,
-        final int position,
-        ValueExtractor<BlockType, Type> valueExtractor
-    ) {
-        if (superset == subset) {
-            return true;
-        }
-        if (subset.areAllValuesNull()) {
-            return true;
-        }
-
-        final var subsetCount = subset.getValueCount(position);
-        final var startIndex = subset.getFirstValueIndex(position);
-        for (int subsetIndex = startIndex; subsetIndex < startIndex + subsetCount; subsetIndex++) {
-            var value = valueExtractor.extractValue(subset, subsetIndex);
-            if (hasValue(superset, position, value, valueExtractor) == false) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    /**
-     * Check if the block has the value at any of it's positions
-     * @param superset Block to search
-     * @param value to search for
-     * @return true if the supplied long value is in the supplied Block
-     */
-    static <BlockType extends Block, Type> boolean hasValue(
-        BlockType superset,
-        final int position,
-        Type value,
-        ValueExtractor<BlockType, Type> valueExtractor
-    ) {
-        final var supersetCount = superset.getValueCount(position);
-        final var startIndex = superset.getFirstValueIndex(position);
-        for (int supersetIndex = startIndex; supersetIndex < startIndex + supersetCount; supersetIndex++) {
-            var element = valueExtractor.extractValue(superset, supersetIndex);
-            if (element != null && element.equals(value)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    interface ValueExtractor<BlockType extends Block, Type> {
-        Type extractValue(BlockType block, int position);
-    }
-
-    private static final class MvContainsNullEvaluator implements ExpressionEvaluator.Factory {
-        private final ExpressionEvaluator.Factory subsetFieldEvaluator;
-
-        private MvContainsNullEvaluator(ExpressionEvaluator.Factory subsetFieldEvaluator) {
-            this.subsetFieldEvaluator = subsetFieldEvaluator;
-        }
-
-        @Override
-        public ExpressionEvaluator get(DriverContext context) {
-            return new ExpressionEvaluator() {
-                final ExpressionEvaluator subsetField = subsetFieldEvaluator.get(context);
-
-                @Override
-                public Block eval(Page page) {
-                    try (Block block = subsetField.eval(page)) {
-                        var position = page.getPositionCount();
-                        return context.blockFactory().newConstantBooleanBlockWith(block.isNull(position), position);
-                    }
-                }
-
-                @Override
-                public void close() {
-                    Releasables.closeExpectNoException(subsetField);
-                }
-
-                @Override
-                public String toString() {
-                    return "MvContainsNullEvaluator[" + "subsetField=" + subsetFieldEvaluator + "]";
-                }
-            };
-        }
-
-        @Override
-        public String toString() {
-            return "MvContainsNullEvaluator[" + "subsetField=" + subsetFieldEvaluator + "]";
-        }
-    }
-
-    /**
-     *  Currently {@code EvaluatorImplementer} generates:
-     *          if (allBlocksAreNulls) {
-     *           result.appendNull();
-     *           continue position;
-     *         }
-     *  when all params are null, this violates our contract of always returning a boolean.
-     *  It should probably also generate the warnings method conditionally - omitted here.
-     *  TODO extend code generation to handle this case
-     */
-    public static class MvContainsBooleanEvaluator implements EvalOperator.ExpressionEvaluator {
-        private final EvalOperator.ExpressionEvaluator field1;
-        private final EvalOperator.ExpressionEvaluator field2;
-        private final DriverContext driverContext;
-
-        public MvContainsBooleanEvaluator(
-            EvalOperator.ExpressionEvaluator field1,
-            EvalOperator.ExpressionEvaluator field2,
-            DriverContext driverContext
-        ) {
-            this.field1 = field1;
-            this.field2 = field2;
-            this.driverContext = driverContext;
-        }
-
-        @Override
-        public Block eval(Page page) {
-            try (BooleanBlock field1Block = (BooleanBlock) field1.eval(page)) {
-                try (BooleanBlock field2Block = (BooleanBlock) field2.eval(page)) {
-                    return eval(page.getPositionCount(), field1Block, field2Block);
-                }
-            }
-        }
-
-        public BooleanBlock eval(int positionCount, BooleanBlock field1Block, BooleanBlock field2Block) {
-            try (BooleanBlock.Builder result = driverContext.blockFactory().newBooleanBlockBuilder(positionCount)) {
-                for (int p = 0; p < positionCount; p++) {
-                    MvContains.process(result, p, field1Block, field2Block);
-                }
-                return result.build();
-            }
-        }
-
-        @Override
-        public String toString() {
-            return "MvContainsBooleanEvaluator[" + "field1=" + field1 + ", field2=" + field2 + "]";
-        }
-
-        @Override
-        public void close() {
-            Releasables.closeExpectNoException(field1, field2);
-        }
-
-        public static class Factory implements EvalOperator.ExpressionEvaluator.Factory {
-            private final Source source;
-            private final EvalOperator.ExpressionEvaluator.Factory field1;
-            private final EvalOperator.ExpressionEvaluator.Factory field2;
-
-            public Factory(
-                Source source,
-                EvalOperator.ExpressionEvaluator.Factory field1,
-                EvalOperator.ExpressionEvaluator.Factory field2
-            ) {
-                this.source = source;
-                this.field1 = field1;
-                this.field2 = field2;
-            }
-
-            @Override
-            public MvContainsBooleanEvaluator get(DriverContext context) {
-                return new MvContainsBooleanEvaluator(field1.get(context), field2.get(context), context);
-            }
-
-            @Override
-            public String toString() {
-                return "MvContainsBooleanEvaluator[" + "field1=" + field1 + ", field2=" + field2 + "]";
-            }
-        }
-    }
-
-    /**
-     *  Currently {@code EvaluatorImplementer} generates:
-     *          if (allBlocksAreNulls) {
-     *           result.appendNull();
-     *           continue position;
-     *         }
-     *  when all params are null, this violates our contract of always returning a boolean.
-     *  It should probably also generate the warnings method conditionally - omitted here.
-     *  TODO extend code generation to handle this case
-     */
-    public static class MvContainsBytesRefEvaluator implements EvalOperator.ExpressionEvaluator {
-        private final EvalOperator.ExpressionEvaluator field1;
-        private final EvalOperator.ExpressionEvaluator field2;
-        private final DriverContext driverContext;
-
-        public MvContainsBytesRefEvaluator(
-            EvalOperator.ExpressionEvaluator field1,
-            EvalOperator.ExpressionEvaluator field2,
-            DriverContext driverContext
-        ) {
-            this.field1 = field1;
-            this.field2 = field2;
-            this.driverContext = driverContext;
-        }
-
-        @Override
-        public Block eval(Page page) {
-            try (BytesRefBlock field1Block = (BytesRefBlock) field1.eval(page)) {
-                try (BytesRefBlock field2Block = (BytesRefBlock) field2.eval(page)) {
-                    return eval(page.getPositionCount(), field1Block, field2Block);
-                }
-            }
-        }
-
-        public BooleanBlock eval(int positionCount, BytesRefBlock field1Block, BytesRefBlock field2Block) {
-            try (BooleanBlock.Builder result = driverContext.blockFactory().newBooleanBlockBuilder(positionCount)) {
-                for (int p = 0; p < positionCount; p++) {
-                    MvContains.process(result, p, field1Block, field2Block);
-                }
-                return result.build();
-            }
-        }
-
-        @Override
-        public String toString() {
-            return "MvContainsBytesRefEvaluator[" + "field1=" + field1 + ", field2=" + field2 + "]";
-        }
-
-        @Override
-        public void close() {
-            Releasables.closeExpectNoException(field1, field2);
-        }
-
-        public static class Factory implements EvalOperator.ExpressionEvaluator.Factory {
-            private final Source source;
-            private final EvalOperator.ExpressionEvaluator.Factory field1;
-            private final EvalOperator.ExpressionEvaluator.Factory field2;
-
-            public Factory(
-                Source source,
-                EvalOperator.ExpressionEvaluator.Factory field1,
-                EvalOperator.ExpressionEvaluator.Factory field2
-            ) {
-                this.source = source;
-                this.field1 = field1;
-                this.field2 = field2;
-            }
-
-            @Override
-            public MvContainsBytesRefEvaluator get(DriverContext context) {
-                return new MvContainsBytesRefEvaluator(field1.get(context), field2.get(context), context);
-            }
-
-            @Override
-            public String toString() {
-                return "MvContainsBytesRefEvaluator[" + "field1=" + field1 + ", field2=" + field2 + "]";
-            }
-        }
-    }
-
-    /**
-     *  Currently {@code EvaluatorImplementer} generates:
-     *          if (allBlocksAreNulls) {
-     *           result.appendNull();
-     *           continue position;
-     *         }
-     *  when all params are null, this violates our contract of always returning a boolean.
-     *  It should probably also generate the warnings method conditionally - omitted here.
-     *  TODO extend code generation to handle this case
-     */
-    public static class MvContainsDoubleEvaluator implements EvalOperator.ExpressionEvaluator {
-        private final EvalOperator.ExpressionEvaluator field1;
-        private final EvalOperator.ExpressionEvaluator field2;
-        private final DriverContext driverContext;
-
-        public MvContainsDoubleEvaluator(
-            EvalOperator.ExpressionEvaluator field1,
-            EvalOperator.ExpressionEvaluator field2,
-            DriverContext driverContext
-        ) {
-            this.field1 = field1;
-            this.field2 = field2;
-            this.driverContext = driverContext;
-        }
-
-        @Override
-        public Block eval(Page page) {
-            try (DoubleBlock field1Block = (DoubleBlock) field1.eval(page)) {
-                try (DoubleBlock field2Block = (DoubleBlock) field2.eval(page)) {
-                    return eval(page.getPositionCount(), field1Block, field2Block);
-                }
-            }
-        }
-
-        public BooleanBlock eval(int positionCount, DoubleBlock field1Block, DoubleBlock field2Block) {
-            try (BooleanBlock.Builder result = driverContext.blockFactory().newBooleanBlockBuilder(positionCount)) {
-                for (int p = 0; p < positionCount; p++) {
-                    MvContains.process(result, p, field1Block, field2Block);
-                }
-                return result.build();
-            }
-        }
-
-        @Override
-        public String toString() {
-            return "MvContainsDoubleEvaluator[" + "field1=" + field1 + ", field2=" + field2 + "]";
-        }
-
-        @Override
-        public void close() {
-            Releasables.closeExpectNoException(field1, field2);
-        }
-
-        public static class Factory implements EvalOperator.ExpressionEvaluator.Factory {
-            private final Source source;
-            private final EvalOperator.ExpressionEvaluator.Factory field1;
-            private final EvalOperator.ExpressionEvaluator.Factory field2;
-
-            public Factory(
-                Source source,
-                EvalOperator.ExpressionEvaluator.Factory field1,
-                EvalOperator.ExpressionEvaluator.Factory field2
-            ) {
-                this.source = source;
-                this.field1 = field1;
-                this.field2 = field2;
-            }
-
-            @Override
-            public MvContainsDoubleEvaluator get(DriverContext context) {
-                return new MvContainsDoubleEvaluator(field1.get(context), field2.get(context), context);
-            }
-
-            @Override
-            public String toString() {
-                return "MvContainsDoubleEvaluator[" + "field1=" + field1 + ", field2=" + field2 + "]";
-            }
-        }
-    }
-
-    /**
-     *  Currently {@code EvaluatorImplementer} generates:
-     *          if (allBlocksAreNulls) {
-     *           result.appendNull();
-     *           continue position;
-     *         }
-     *  when all params are null, this violates our contract of always returning a boolean.
-     *  It should probably also generate the warnings method conditionally - omitted here.
-     *  TODO extend code generation to handle this case
-     */
-    public static class MvContainsIntEvaluator implements EvalOperator.ExpressionEvaluator {
-        private final EvalOperator.ExpressionEvaluator field1;
-        private final EvalOperator.ExpressionEvaluator field2;
-        private final DriverContext driverContext;
-
-        public MvContainsIntEvaluator(
-            EvalOperator.ExpressionEvaluator field1,
-            EvalOperator.ExpressionEvaluator field2,
-            DriverContext driverContext
-        ) {
-            this.field1 = field1;
-            this.field2 = field2;
-            this.driverContext = driverContext;
-        }
-
-        @Override
-        public Block eval(Page page) {
-            try (IntBlock field1Block = (IntBlock) field1.eval(page)) {
-                try (IntBlock field2Block = (IntBlock) field2.eval(page)) {
-                    return eval(page.getPositionCount(), field1Block, field2Block);
-                }
-            }
-        }
-
-        public BooleanBlock eval(int positionCount, IntBlock field1Block, IntBlock field2Block) {
-            try (BooleanBlock.Builder result = driverContext.blockFactory().newBooleanBlockBuilder(positionCount)) {
-                for (int p = 0; p < positionCount; p++) {
-                    MvContains.process(result, p, field1Block, field2Block);
-                }
-                return result.build();
-            }
-        }
-
-        @Override
-        public String toString() {
-            return "MvContainsIntEvaluator[" + "field1=" + field1 + ", field2=" + field2 + "]";
-        }
-
-        @Override
-        public void close() {
-            Releasables.closeExpectNoException(field1, field2);
-        }
-
-        public static class Factory implements EvalOperator.ExpressionEvaluator.Factory {
-            private final Source source;
-            private final EvalOperator.ExpressionEvaluator.Factory field1;
-            private final EvalOperator.ExpressionEvaluator.Factory field2;
-
-            public Factory(
-                Source source,
-                EvalOperator.ExpressionEvaluator.Factory field1,
-                EvalOperator.ExpressionEvaluator.Factory field2
-            ) {
-                this.source = source;
-                this.field1 = field1;
-                this.field2 = field2;
-            }
-
-            @Override
-            public MvContainsIntEvaluator get(DriverContext context) {
-                return new MvContainsIntEvaluator(field1.get(context), field2.get(context), context);
-            }
-
-            @Override
-            public String toString() {
-                return "MvContainsIntEvaluator[" + "field1=" + field1 + ", field2=" + field2 + "]";
-            }
-        }
-    }
-
-    /**
-     *  Currently {@code EvaluatorImplementer} generates:
-     *          if (allBlocksAreNulls) {
-     *           result.appendNull();
-     *           continue position;
-     *         }
-     *  when all params are null, this violates our contract of always returning a boolean.
-     *  It should probably also generate the warnings method conditionally - omitted here.
-     *  TODO extend code generation to handle this case
-     */
-    public static class MvContainsLongEvaluator implements EvalOperator.ExpressionEvaluator {
-        private final EvalOperator.ExpressionEvaluator field1;
-        private final EvalOperator.ExpressionEvaluator field2;
-        private final DriverContext driverContext;
-
-        public MvContainsLongEvaluator(
-            EvalOperator.ExpressionEvaluator field1,
-            EvalOperator.ExpressionEvaluator field2,
-            DriverContext driverContext
-        ) {
-            this.field1 = field1;
-            this.field2 = field2;
-            this.driverContext = driverContext;
-        }
-
-        @Override
-        public Block eval(Page page) {
-            try (LongBlock field1Block = (LongBlock) field1.eval(page)) {
-                try (LongBlock field2Block = (LongBlock) field2.eval(page)) {
-                    return eval(page.getPositionCount(), field1Block, field2Block);
-                }
-            }
-        }
-
-        public BooleanBlock eval(int positionCount, LongBlock field1Block, LongBlock field2Block) {
-            try (BooleanBlock.Builder result = driverContext.blockFactory().newBooleanBlockBuilder(positionCount)) {
-                for (int p = 0; p < positionCount; p++) {
-                    MvContains.process(result, p, field1Block, field2Block);
-                }
-                return result.build();
-            }
-        }
-
-        @Override
-        public String toString() {
-            return "MvContainsLongEvaluator[" + "field1=" + field1 + ", field2=" + field2 + "]";
-        }
-
-        @Override
-        public void close() {
-            Releasables.closeExpectNoException(field1, field2);
-        }
-
-        public static class Factory implements EvalOperator.ExpressionEvaluator.Factory {
-            private final Source source;
-            private final EvalOperator.ExpressionEvaluator.Factory field1;
-            private final EvalOperator.ExpressionEvaluator.Factory field2;
-
-            public Factory(
-                Source source,
-                EvalOperator.ExpressionEvaluator.Factory field1,
-                EvalOperator.ExpressionEvaluator.Factory field2
-            ) {
-                this.source = source;
-                this.field1 = field1;
-                this.field2 = field2;
-            }
-
-            @Override
-            public MvContainsLongEvaluator get(DriverContext context) {
-                return new MvContainsLongEvaluator(field1.get(context), field2.get(context), context);
-            }
-
-            @Override
-            public String toString() {
-                return "MvContainsLongEvaluator[" + "field1=" + field1 + ", field2=" + field2 + "]";
-            }
-        }
-    }
-}

+ 0 - 1
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvFunctionWritables.java

@@ -17,7 +17,6 @@ public class MvFunctionWritables {
             MvAppend.ENTRY,
             MvAvg.ENTRY,
             MvConcat.ENTRY,
-            MvContains.ENTRY,
             MvCount.ENTRY,
             MvDedupe.ENTRY,
             MvFirst.ENTRY,

+ 0 - 45
x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvContainsErrorTests.java

@@ -1,45 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License
- * 2.0; you may not use this file except in compliance with the Elastic License
- * 2.0.
- */
-
-package org.elasticsearch.xpack.esql.expression.function.scalar.multivalue;
-
-import org.elasticsearch.xpack.esql.core.expression.Expression;
-import org.elasticsearch.xpack.esql.core.tree.Source;
-import org.elasticsearch.xpack.esql.core.type.DataType;
-import org.elasticsearch.xpack.esql.expression.function.ErrorsForCasesWithoutExamplesTestCase;
-import org.elasticsearch.xpack.esql.expression.function.TestCaseSupplier;
-import org.hamcrest.Matcher;
-
-import java.util.List;
-import java.util.Set;
-
-import static org.hamcrest.Matchers.equalTo;
-
-public class MvContainsErrorTests extends ErrorsForCasesWithoutExamplesTestCase {
-    @Override
-    protected List<TestCaseSupplier> cases() {
-        return paramsToSuppliers(MvContainsTests.parameters());
-    }
-
-    @Override
-    protected Expression build(Source source, List<Expression> args) {
-        return new MvContains(source, args.get(0), args.get(1));
-    }
-
-    @Override
-    protected Matcher<String> expectedTypeErrorMatcher(List<Set<DataType>> validPerPosition, List<DataType> signature) {
-        return equalTo(
-            "second argument of ["
-                + sourceForSignature(signature)
-                + "] must be ["
-                + signature.get(0).noText().typeName()
-                + "], found value [] type ["
-                + signature.get(1).typeName()
-                + "]"
-        );
-    }
-}

+ 0 - 37
x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvContainsSerializationTests.java

@@ -1,37 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License
- * 2.0; you may not use this file except in compliance with the Elastic License
- * 2.0.
- */
-
-package org.elasticsearch.xpack.esql.expression.function.scalar.multivalue;
-
-import org.elasticsearch.xpack.esql.core.expression.Expression;
-import org.elasticsearch.xpack.esql.core.tree.Source;
-import org.elasticsearch.xpack.esql.expression.AbstractExpressionSerializationTests;
-
-import java.io.IOException;
-
-public class MvContainsSerializationTests extends AbstractExpressionSerializationTests<MvContains> {
-    @Override
-    protected MvContains createTestInstance() {
-        Source source = randomSource();
-        Expression field1 = randomChild();
-        Expression field2 = randomChild();
-        return new MvContains(source, field1, field2);
-    }
-
-    @Override
-    protected MvContains mutateInstance(MvContains instance) throws IOException {
-        Source source = randomSource();
-        Expression field1 = randomChild();
-        Expression field2 = randomChild();
-        if (randomBoolean()) {
-            field1 = randomValueOtherThan(field1, AbstractExpressionSerializationTests::randomChild);
-        } else {
-            field2 = randomValueOtherThan(field2, AbstractExpressionSerializationTests::randomChild);
-        }
-        return new MvContains(source, field1, field2);
-    }
-}

+ 0 - 368
x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvContainsTests.java

@@ -1,368 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License
- * 2.0; you may not use this file except in compliance with the Elastic License
- * 2.0.
- */
-
-package org.elasticsearch.xpack.esql.expression.function.scalar.multivalue;
-
-import com.carrotsearch.randomizedtesting.annotations.Name;
-import com.carrotsearch.randomizedtesting.annotations.ParametersFactory;
-
-import org.apache.lucene.util.BytesRef;
-import org.elasticsearch.geo.GeometryTestUtils;
-import org.elasticsearch.geo.ShapeTestUtils;
-import org.elasticsearch.test.ESTestCase;
-import org.elasticsearch.xpack.esql.core.expression.Expression;
-import org.elasticsearch.xpack.esql.core.tree.Source;
-import org.elasticsearch.xpack.esql.core.type.DataType;
-import org.elasticsearch.xpack.esql.expression.function.AbstractScalarFunctionTestCase;
-import org.elasticsearch.xpack.esql.expression.function.TestCaseSupplier;
-import org.hamcrest.Matcher;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Objects;
-import java.util.Set;
-import java.util.function.Supplier;
-import java.util.stream.Collectors;
-
-import static org.elasticsearch.xpack.esql.EsqlTestUtils.randomLiteral;
-import static org.elasticsearch.xpack.esql.core.util.SpatialCoordinateTypes.CARTESIAN;
-import static org.elasticsearch.xpack.esql.core.util.SpatialCoordinateTypes.GEO;
-import static org.elasticsearch.xpack.esql.expression.function.TestCaseSupplier.TypedData.MULTI_ROW_NULL;
-import static org.elasticsearch.xpack.esql.expression.function.TestCaseSupplier.TypedData.NULL;
-import static org.hamcrest.Matchers.anyOf;
-import static org.hamcrest.Matchers.equalTo;
-
-public class MvContainsTests extends AbstractScalarFunctionTestCase {
-    public MvContainsTests(@Name("TestCase") Supplier<TestCaseSupplier.TestCase> testCaseSupplier) {
-        this.testCase = testCaseSupplier.get();
-    }
-
-    @ParametersFactory
-    public static Iterable<Object[]> parameters() {
-        List<TestCaseSupplier> suppliers = new ArrayList<>();
-        booleans(suppliers);
-        ints(suppliers);
-        longs(suppliers);
-        doubles(suppliers);
-        bytesRefs(suppliers);
-
-        return parameterSuppliersFromTypedData(
-            anyNullIsNull(
-                suppliers,
-                (nullPosition, nullValueDataType, original) -> original.expectedType(),
-                (nullPosition, nullData, original) -> original
-            )
-        );
-    }
-
-    @Override
-    protected Expression build(Source source, List<Expression> args) {
-        return new MvContains(source, args.get(0), args.get(1));
-    }
-
-    private static void booleans(List<TestCaseSupplier> suppliers) {
-        suppliers.add(new TestCaseSupplier(List.of(DataType.BOOLEAN, DataType.BOOLEAN), () -> {
-            List<Boolean> field1 = randomList(1, 10, ESTestCase::randomBoolean);
-            List<Boolean> field2 = randomList(1, 2, ESTestCase::randomBoolean);
-            var result = field1.containsAll(field2);
-            return new TestCaseSupplier.TestCase(
-                List.of(
-                    new TestCaseSupplier.TypedData(field1, DataType.BOOLEAN, "field1"),
-                    new TestCaseSupplier.TypedData(field2, DataType.BOOLEAN, "field2")
-                ),
-                "MvContainsBooleanEvaluator[field1=Attribute[channel=0], field2=Attribute[channel=1]]",
-                DataType.BOOLEAN,
-                equalTo(result)
-            );
-        }));
-    }
-
-    private static void ints(List<TestCaseSupplier> suppliers) {
-        suppliers.add(new TestCaseSupplier(List.of(DataType.INTEGER, DataType.INTEGER), () -> {
-            List<Integer> field1 = randomList(1, 10, ESTestCase::randomInt);
-            List<Integer> field2 = randomList(1, 10, ESTestCase::randomInt);
-            var result = field1.containsAll(field2);
-            return new TestCaseSupplier.TestCase(
-                List.of(
-                    new TestCaseSupplier.TypedData(field1, DataType.INTEGER, "field1"),
-                    new TestCaseSupplier.TypedData(field2, DataType.INTEGER, "field2")
-                ),
-                "MvContainsIntEvaluator[field1=Attribute[channel=0], field2=Attribute[channel=1]]",
-                DataType.BOOLEAN,
-                equalTo(result)
-            );
-        }));
-    }
-
-    private static void longs(List<TestCaseSupplier> suppliers) {
-        suppliers.add(new TestCaseSupplier(List.of(DataType.LONG, DataType.LONG), () -> {
-            List<Long> field1 = randomList(1, 10, ESTestCase::randomLong);
-            List<Long> field2 = randomList(1, 10, ESTestCase::randomLong);
-            var result = field1.containsAll(field2);
-            return new TestCaseSupplier.TestCase(
-                List.of(
-                    new TestCaseSupplier.TypedData(field1, DataType.LONG, "field1"),
-                    new TestCaseSupplier.TypedData(field2, DataType.LONG, "field2")
-                ),
-                "MvContainsLongEvaluator[field1=Attribute[channel=0], field2=Attribute[channel=1]]",
-                DataType.BOOLEAN,
-                equalTo(result)
-            );
-        }));
-        suppliers.add(new TestCaseSupplier(List.of(DataType.UNSIGNED_LONG, DataType.UNSIGNED_LONG), () -> {
-            List<Long> field1 = randomList(1, 10, ESTestCase::randomLong);
-            List<Long> field2 = randomList(1, 10, ESTestCase::randomLong);
-            var result = field1.containsAll(field2);
-            return new TestCaseSupplier.TestCase(
-                List.of(
-                    new TestCaseSupplier.TypedData(field1, DataType.UNSIGNED_LONG, "field1"),
-                    new TestCaseSupplier.TypedData(field2, DataType.UNSIGNED_LONG, "field2")
-                ),
-                "MvContainsLongEvaluator[field1=Attribute[channel=0], field2=Attribute[channel=1]]",
-                DataType.BOOLEAN,
-                equalTo(result)
-            );
-        }));
-        suppliers.add(new TestCaseSupplier(List.of(DataType.DATETIME, DataType.DATETIME), () -> {
-            List<Long> field1 = randomList(1, 10, ESTestCase::randomLong);
-            List<Long> field2 = randomList(1, 10, ESTestCase::randomLong);
-            var result = field1.containsAll(field2);
-            return new TestCaseSupplier.TestCase(
-                List.of(
-                    new TestCaseSupplier.TypedData(field1, DataType.DATETIME, "field1"),
-                    new TestCaseSupplier.TypedData(field2, DataType.DATETIME, "field2")
-                ),
-                "MvContainsLongEvaluator[field1=Attribute[channel=0], field2=Attribute[channel=1]]",
-                DataType.BOOLEAN,
-                equalTo(result)
-            );
-        }));
-        suppliers.add(new TestCaseSupplier(List.of(DataType.DATE_NANOS, DataType.DATE_NANOS), () -> {
-            List<Long> field1 = randomList(1, 10, ESTestCase::randomNonNegativeLong);
-            List<Long> field2 = randomList(1, 10, ESTestCase::randomNonNegativeLong);
-            var result = field1.containsAll(field2);
-            return new TestCaseSupplier.TestCase(
-                List.of(
-                    new TestCaseSupplier.TypedData(field1, DataType.DATE_NANOS, "field1"),
-                    new TestCaseSupplier.TypedData(field2, DataType.DATE_NANOS, "field2")
-                ),
-                "MvContainsLongEvaluator[field1=Attribute[channel=0], field2=Attribute[channel=1]]",
-                DataType.BOOLEAN,
-                equalTo(result)
-            );
-        }));
-    }
-
-    private static void doubles(List<TestCaseSupplier> suppliers) {
-        suppliers.add(new TestCaseSupplier(List.of(DataType.DOUBLE, DataType.DOUBLE), () -> {
-            List<Double> field1 = randomList(1, 10, ESTestCase::randomDouble);
-            List<Double> field2 = randomList(1, 10, ESTestCase::randomDouble);
-            var result = field1.containsAll(field2);
-            return new TestCaseSupplier.TestCase(
-                List.of(
-                    new TestCaseSupplier.TypedData(field1, DataType.DOUBLE, "field1"),
-                    new TestCaseSupplier.TypedData(field2, DataType.DOUBLE, "field2")
-                ),
-                "MvContainsDoubleEvaluator[field1=Attribute[channel=0], field2=Attribute[channel=1]]",
-                DataType.BOOLEAN,
-                equalTo(result)
-            );
-        }));
-    }
-
-    private static void bytesRefs(List<TestCaseSupplier> suppliers) {
-        for (DataType lhs : new DataType[] { DataType.KEYWORD, DataType.TEXT }) {
-            for (DataType rhs : new DataType[] { DataType.KEYWORD, DataType.TEXT }) {
-                suppliers.add(new TestCaseSupplier(List.of(lhs, rhs), () -> {
-                    List<Object> field1 = randomList(1, 10, () -> randomLiteral(lhs).value());
-                    List<Object> field2 = randomList(1, 10, () -> randomLiteral(rhs).value());
-                    var result = field1.containsAll(field2);
-                    return new TestCaseSupplier.TestCase(
-                        List.of(
-                            new TestCaseSupplier.TypedData(field1, lhs, "field1"),
-                            new TestCaseSupplier.TypedData(field2, rhs, "field2")
-                        ),
-                        "MvContainsBytesRefEvaluator[field1=Attribute[channel=0], field2=Attribute[channel=1]]",
-                        DataType.BOOLEAN,
-                        equalTo(result)
-                    );
-                }));
-            }
-        }
-        suppliers.add(new TestCaseSupplier(List.of(DataType.IP, DataType.IP), () -> {
-            List<Object> field1 = randomList(1, 10, () -> randomLiteral(DataType.IP).value());
-            List<Object> field2 = randomList(1, 10, () -> randomLiteral(DataType.IP).value());
-            var result = field1.containsAll(field2);
-            return new TestCaseSupplier.TestCase(
-                List.of(
-                    new TestCaseSupplier.TypedData(field1, DataType.IP, "field"),
-                    new TestCaseSupplier.TypedData(field2, DataType.IP, "field")
-                ),
-                "MvContainsBytesRefEvaluator[field1=Attribute[channel=0], field2=Attribute[channel=1]]",
-                DataType.BOOLEAN,
-                equalTo(result)
-            );
-        }));
-
-        suppliers.add(new TestCaseSupplier(List.of(DataType.VERSION, DataType.VERSION), () -> {
-            List<Object> field1 = randomList(1, 10, () -> randomLiteral(DataType.VERSION).value());
-            List<Object> field2 = randomList(1, 10, () -> randomLiteral(DataType.VERSION).value());
-            var result = field1.containsAll(field2);
-            return new TestCaseSupplier.TestCase(
-                List.of(
-                    new TestCaseSupplier.TypedData(field1, DataType.VERSION, "field"),
-                    new TestCaseSupplier.TypedData(field2, DataType.VERSION, "field")
-                ),
-                "MvContainsBytesRefEvaluator[field1=Attribute[channel=0], field2=Attribute[channel=1]]",
-                DataType.BOOLEAN,
-                equalTo(result)
-            );
-        }));
-
-        suppliers.add(new TestCaseSupplier(List.of(DataType.GEO_POINT, DataType.GEO_POINT), () -> {
-            List<Object> field1 = randomList(1, 10, () -> new BytesRef(GEO.asWkt(GeometryTestUtils.randomPoint())));
-            List<Object> field2 = randomList(1, 10, () -> new BytesRef(GEO.asWkt(GeometryTestUtils.randomPoint())));
-            var result = field1.containsAll(field2);
-            return new TestCaseSupplier.TestCase(
-                List.of(
-                    new TestCaseSupplier.TypedData(field1, DataType.GEO_POINT, "field1"),
-                    new TestCaseSupplier.TypedData(field2, DataType.GEO_POINT, "field2")
-                ),
-                "MvContainsBytesRefEvaluator[field1=Attribute[channel=0], field2=Attribute[channel=1]]",
-                DataType.BOOLEAN,
-                equalTo(result)
-            );
-        }));
-
-        suppliers.add(new TestCaseSupplier(List.of(DataType.CARTESIAN_POINT, DataType.CARTESIAN_POINT), () -> {
-            List<Object> field1 = randomList(1, 10, () -> new BytesRef(CARTESIAN.asWkt(ShapeTestUtils.randomPoint())));
-            List<Object> field2 = randomList(1, 10, () -> new BytesRef(CARTESIAN.asWkt(ShapeTestUtils.randomPoint())));
-            var result = field1.containsAll(field2);
-            return new TestCaseSupplier.TestCase(
-                List.of(
-                    new TestCaseSupplier.TypedData(field1, DataType.CARTESIAN_POINT, "field1"),
-                    new TestCaseSupplier.TypedData(field2, DataType.CARTESIAN_POINT, "field2")
-                ),
-                "MvContainsBytesRefEvaluator[field1=Attribute[channel=0], field2=Attribute[channel=1]]",
-                DataType.BOOLEAN,
-                equalTo(result)
-            );
-        }));
-
-        suppliers.add(new TestCaseSupplier(List.of(DataType.GEO_SHAPE, DataType.GEO_SHAPE), () -> {
-            var field1 = randomList(1, 3, () -> new BytesRef(GEO.asWkt(GeometryTestUtils.randomGeometry(randomBoolean(), 500))));
-            var field2 = randomList(1, 3, () -> new BytesRef(GEO.asWkt(GeometryTestUtils.randomGeometry(randomBoolean(), 500))));
-            var result = field1.containsAll(field2);
-            return new TestCaseSupplier.TestCase(
-                List.of(
-                    new TestCaseSupplier.TypedData(field1, DataType.GEO_SHAPE, "field1"),
-                    new TestCaseSupplier.TypedData(field2, DataType.GEO_SHAPE, "field2")
-                ),
-                "MvContainsBytesRefEvaluator[field1=Attribute[channel=0], field2=Attribute[channel=1]]",
-                DataType.BOOLEAN,
-                equalTo(result)
-            );
-        }));
-
-        suppliers.add(new TestCaseSupplier(List.of(DataType.CARTESIAN_SHAPE, DataType.CARTESIAN_SHAPE), () -> {
-            var field1 = randomList(1, 3, () -> new BytesRef(CARTESIAN.asWkt(ShapeTestUtils.randomGeometry(randomBoolean(), 500))));
-            var field2 = randomList(1, 3, () -> new BytesRef(CARTESIAN.asWkt(ShapeTestUtils.randomGeometry(randomBoolean(), 500))));
-            var result = field1.containsAll(field2);
-            return new TestCaseSupplier.TestCase(
-                List.of(
-                    new TestCaseSupplier.TypedData(field1, DataType.CARTESIAN_SHAPE, "field1"),
-                    new TestCaseSupplier.TypedData(field2, DataType.CARTESIAN_SHAPE, "field2")
-                ),
-                "MvContainsBytesRefEvaluator[field1=Attribute[channel=0], field2=Attribute[channel=1]]",
-                DataType.BOOLEAN,
-                equalTo(result)
-            );
-        }));
-    }
-
-    // Adjusted from static method anyNullIsNull in {@code AbstractScalarFunctionTestCase#}
-    protected static List<TestCaseSupplier> anyNullIsNull(
-        List<TestCaseSupplier> testCaseSuppliers,
-        ExpectedType expectedType,
-        ExpectedEvaluatorToString evaluatorToString
-    ) {
-        List<TestCaseSupplier> suppliers = new ArrayList<>(testCaseSuppliers);
-
-        /*
-         * For each original test case, add as many copies as there were
-         * arguments, replacing one of the arguments with null and keeping
-         * the others.
-         *
-         * Also, if this was the first time we saw the signature we copy it
-         * *again*, replacing the argument with null, but annotating the
-         * argument’s type as `null` explicitly.
-         */
-        Set<List<DataType>> uniqueSignatures = new HashSet<>();
-        for (TestCaseSupplier original : testCaseSuppliers) {
-            boolean firstTimeSeenSignature = uniqueSignatures.add(original.types());
-            for (int typeIndex = 0; typeIndex < original.types().size(); typeIndex++) {
-                int nullPosition = typeIndex;
-
-                suppliers.add(new TestCaseSupplier("G1: " + original.name() + " null in " + nullPosition, original.types(), () -> {
-                    TestCaseSupplier.TestCase originalTestCase = original.get();
-                    List<TestCaseSupplier.TypedData> typeDataWithNull = new ArrayList<>(originalTestCase.getData());
-                    var data = typeDataWithNull.get(nullPosition);
-                    typeDataWithNull.set(nullPosition, data.withData(data.isMultiRow() ? Collections.singletonList(null) : null));
-                    TestCaseSupplier.TypedData nulledData = originalTestCase.getData().get(nullPosition);
-                    return new TestCaseSupplier.TestCase(
-                        typeDataWithNull,
-                        evaluatorToString.evaluatorToString(nullPosition, nulledData, originalTestCase.evaluatorToString()),
-                        expectedType.expectedType(nullPosition, DataType.BOOLEAN, originalTestCase),
-                        equalTo(nullPosition == 1)
-                    );
-                }));
-
-                if (firstTimeSeenSignature) {
-                    var typesWithNull = new ArrayList<>(original.types());
-                    typesWithNull.set(nullPosition, DataType.NULL);
-                    boolean newSignature = uniqueSignatures.add(typesWithNull);
-                    if (newSignature) {
-                        suppliers.add(
-                            new TestCaseSupplier(
-                                "G2: " + toSpaceSeparatedString(typesWithNull) + " null in " + nullPosition,
-                                typesWithNull,
-                                () -> {
-                                    TestCaseSupplier.TestCase originalTestCase = original.get();
-                                    var typeDataWithNull = new ArrayList<>(originalTestCase.getData());
-                                    typeDataWithNull.set(
-                                        nullPosition,
-                                        typeDataWithNull.get(nullPosition).isMultiRow() ? MULTI_ROW_NULL : NULL
-                                    );
-                                    return new TestCaseSupplier.TestCase(
-                                        typeDataWithNull,
-                                        "MvContainsNullEvaluator[subsetField=Attribute[channel=1]]",
-                                        expectedType.expectedType(nullPosition, DataType.BOOLEAN, originalTestCase),
-                                        equalTo(nullPosition == 1)
-                                    );
-                                }
-                            )
-                        );
-                    }
-                }
-            }
-        }
-
-        return suppliers;
-    }
-
-    private static String toSpaceSeparatedString(ArrayList<DataType> typesWithNull) {
-        return typesWithNull.stream().map(Objects::toString).collect(Collectors.joining(" "));
-    }
-
-    // We always return a boolean.
-    @Override
-    protected Matcher<Object> allNullsMatcher() {
-        return anyOf(equalTo(false), equalTo(true));
-    }
-}