Ver código fonte

Take match_phrase out of snapshot and make tech preview (#128925)

* Take match_phrase out of snapshot and make tech preview

* Update docs/changelog/128925.yaml

* PR feedback

* Adding regenerated test data

* Update docs/changelog/128925.yaml

Co-authored-by: Carlos Delgado <6339205+carlosdelest@users.noreply.github.com>

* [CI] Auto commit changes from spotless

* Checkstyle

* Correct docs

* Hopefully fix docs build

* Found one more bad docs link - here's hoping this now fixes the doc build

* OMG bitten by - vs _

---------

Co-authored-by: Carlos Delgado <6339205+carlosdelest@users.noreply.github.com>
Co-authored-by: elasticsearchmachine <infra-root+elasticsearchmachine@elastic.co>
Co-authored-by: Aurélien FOUCRET <aurelien.foucret@gmail.com>
Kathleen DeRusso 4 meses atrás
pai
commit
b214fbfcdc
15 arquivos alterados com 35 adições e 70 exclusões
  1. 5 0
      docs/changelog/128925.yaml
  2. 1 1
      docs/reference/query-languages/esql/_snippets/functions/description/match_phrase.md
  3. 1 1
      docs/reference/query-languages/esql/_snippets/functions/parameters/match_phrase.md
  4. 1 2
      docs/reference/query-languages/esql/_snippets/lists/search-functions.md
  5. 2 3
      docs/reference/query-languages/esql/functions-operators/search-functions.md
  6. 3 3
      docs/reference/query-languages/esql/kibana/definition/functions/match_phrase.json
  7. 2 1
      docs/reference/query-languages/esql/kibana/docs/functions/match_phrase.md
  8. 0 9
      x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/plugin/MatchPhraseFunctionIT.java
  9. 1 3
      x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/plugin/ScoringIT.java
  10. 1 1
      x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java
  11. 1 4
      x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/fulltext/FullTextWritables.java
  12. 3 2
      x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/fulltext/MatchPhrase.java
  13. 13 32
      x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/VerifierTests.java
  14. 0 7
      x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/fulltext/MatchPhraseTests.java
  15. 1 1
      x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/esql/60_usage.yml

+ 5 - 0
docs/changelog/128925.yaml

@@ -0,0 +1,5 @@
+pr: 128925
+summary: ES|QL - Add `match_phrase` full text function (tech preview)
+area: ES|QL
+type: enhancement
+issues: []

+ 1 - 1
docs/reference/query-languages/esql/_snippets/functions/description/match_phrase.md

@@ -2,5 +2,5 @@
 
 **Description**
 
-Use `MATCH_PHRASE` to perform a [match_phrase query](/reference/query-languages/query-dsl/query-dsl-match-query.md#query-dsl-match-query-phrase) on the specified field. Using `MATCH_PHRASE` is equivalent to using the `match_phrase` query in the Elasticsearch Query DSL.  MatchPhrase can be used on [text](/reference/elasticsearch/mapping-reference/text.md) fields, as well as other field types like keyword, boolean, or date types. MatchPhrase is not supported for [semantic_text](/reference/elasticsearch/mapping-reference/semantic-text.md) or numeric types.  MatchPhrase can use [function named parameters](/reference/query-languages/esql/esql-syntax.md#esql-function-named-params) to specify additional options for the match_phrase query. All [`match_phrase`](/reference/query-languages/query-dsl/query-dsl-match-query-phrase.md) query parameters are supported.  `MATCH_PHRASE` returns true if the provided query matches the row.
+Use `MATCH_PHRASE` to perform a [`match_phrase`](/reference/query-languages/query-dsl/query-dsl-match-query-phrase.md) on the specified field. Using `MATCH_PHRASE` is equivalent to using the `match_phrase` query in the Elasticsearch Query DSL.  MatchPhrase can be used on [text](/reference/elasticsearch/mapping-reference/text.md) fields, as well as other field types like keyword, boolean, or date types. MatchPhrase is not supported for [semantic_text](/reference/elasticsearch/mapping-reference/semantic-text.md) or numeric types.  MatchPhrase can use [function named parameters](/reference/query-languages/esql/esql-syntax.md#esql-function-named-params) to specify additional options for the match_phrase query. All [`match_phrase`](/reference/query-languages/query-dsl/query-dsl-match-query-phrase.md) query parameters are supported.  `MATCH_PHRASE` returns true if the provided query matches the row.
 

+ 1 - 1
docs/reference/query-languages/esql/_snippets/functions/parameters/match_phrase.md

@@ -9,5 +9,5 @@
 :   Value to find in the provided field.
 
 `options`
-:   (Optional) MatchPhrase additional options as [function named parameters](/reference/query-languages/esql/esql-syntax.md#esql-function-named-params). See [match_phrase query](/reference/query-languages/query-dsl/query-dsl-match-query.md#query-dsl-match-query-phrase) for more information.
+:   (Optional) MatchPhrase additional options as [function named parameters](/reference/query-languages/esql/esql-syntax.md#esql-function-named-params). See [`match_phrase`](/reference/query-languages/query-dsl/query-dsl-match-query-phrase.md) for more information.
 

+ 1 - 2
docs/reference/query-languages/esql/_snippets/lists/search-functions.md

@@ -1,7 +1,6 @@
 * [preview] [`KQL`](../../functions-operators/search-functions.md#esql-kql)
 * [preview] [`MATCH`](../../functions-operators/search-functions.md#esql-match)
-  % * [preview] [
-  `MATCH_PHRASE`](../../functions-operators/search-functions.md#esql-match-phrase)
+* [preview] [`MATCH_PHRASE`](../../functions-operators/search-functions.md#esql-match_phrase)
 * [preview] [`QSTR`](../../functions-operators/search-functions.md#esql-qstr)
   % * [preview] [
   `TERM`](../../functions-operators/search-functions.md#esql-term)

+ 2 - 3
docs/reference/query-languages/esql/functions-operators/search-functions.md

@@ -36,9 +36,8 @@ for information on the limitations of full text search.
 :::{include} ../_snippets/functions/layout/match.md
 :::
 
-% MATCH_PHRASE is currently hidden
-% :::{include} ../_snippets/functions/layout/match_phrase.md
-% :::
+:::{include} ../_snippets/functions/layout/match_phrase.md
+:::
 
 :::{include} ../_snippets/functions/layout/qstr.md
 :::

+ 3 - 3
docs/reference/query-languages/esql/kibana/definition/functions/match_phrase.json

@@ -2,7 +2,7 @@
   "comment" : "This is generated by ESQL’s AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it.",
   "type" : "scalar",
   "name" : "match_phrase",
-  "description" : "Use `MATCH_PHRASE` to perform a match_phrase query on the specified field.\nUsing `MATCH_PHRASE` is equivalent to using the `match_phrase` query in the Elasticsearch Query DSL.\n\nMatchPhrase can be used on text fields, as well as other field types like keyword, boolean, or date types.\nMatchPhrase is not supported for semantic_text or numeric types.\n\nMatchPhrase can use function named parameters to specify additional options for the\nmatch_phrase query.\nAll `match_phrase` query parameters are supported.\n\n`MATCH_PHRASE` returns true if the provided query matches the row.",
+  "description" : "Use `MATCH_PHRASE` to perform a `match_phrase` on the\nspecified field.\nUsing `MATCH_PHRASE` is equivalent to using the `match_phrase` query in the Elasticsearch Query DSL.\n\nMatchPhrase can be used on text fields, as well as other field types like keyword, boolean, or date types.\nMatchPhrase is not supported for semantic_text or numeric types.\n\nMatchPhrase can use function named parameters to specify additional options for the\nmatch_phrase query.\nAll `match_phrase` query parameters are supported.\n\n`MATCH_PHRASE` returns true if the provided query matches the row.",
   "signatures" : [
     {
       "params" : [
@@ -23,7 +23,7 @@
           "type" : "function_named_parameters",
           "mapParams" : "{name='zero_terms_query', values=[none, all], description='Indicates whether all documents or none are returned if the analyzer removes all tokens, such as when using a stop filter. Defaults to none.'}, {name='boost', values=[2.5], description='Floating point number used to decrease or increase the relevance scores of the query. Defaults to 1.0.'}, {name='analyzer', values=[standard], description='Analyzer used to convert the text in the query value into token. Defaults to the index-time analyzer mapped for the field. If no analyzer is mapped, the index’s default analyzer is used.'}, {name='slop', values=[1], description='Maximum number of positions allowed between matching tokens. Defaults to 0. Transposed terms have a slop of 2.'}",
           "optional" : true,
-          "description" : "(Optional) MatchPhrase additional options as <<esql-function-named-params,function named parameters>>. See <<query-dsl-match-query-phrase,match_phrase query>> for more information."
+          "description" : "(Optional) MatchPhrase additional options as <<esql-function-named-params,function named parameters>>. See [`match_phrase`](https://www.elastic.co/docs/reference/query-languages/query-dsl/query-dsl-match-query-phrase) for more information."
         }
       ],
       "variadic" : false,
@@ -48,7 +48,7 @@
           "type" : "function_named_parameters",
           "mapParams" : "{name='zero_terms_query', values=[none, all], description='Indicates whether all documents or none are returned if the analyzer removes all tokens, such as when using a stop filter. Defaults to none.'}, {name='boost', values=[2.5], description='Floating point number used to decrease or increase the relevance scores of the query. Defaults to 1.0.'}, {name='analyzer', values=[standard], description='Analyzer used to convert the text in the query value into token. Defaults to the index-time analyzer mapped for the field. If no analyzer is mapped, the index’s default analyzer is used.'}, {name='slop', values=[1], description='Maximum number of positions allowed between matching tokens. Defaults to 0. Transposed terms have a slop of 2.'}",
           "optional" : true,
-          "description" : "(Optional) MatchPhrase additional options as <<esql-function-named-params,function named parameters>>. See <<query-dsl-match-query-phrase,match_phrase query>> for more information."
+          "description" : "(Optional) MatchPhrase additional options as <<esql-function-named-params,function named parameters>>. See [`match_phrase`](https://www.elastic.co/docs/reference/query-languages/query-dsl/query-dsl-match-query-phrase) for more information."
         }
       ],
       "variadic" : false,

+ 2 - 1
docs/reference/query-languages/esql/kibana/docs/functions/match_phrase.md

@@ -1,7 +1,8 @@
 % This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it.
 
 ### MATCH PHRASE
-Use `MATCH_PHRASE` to perform a [match_phrase query](https://www.elastic.co/docs/reference/query-languages/query-dsl/query-dsl-match-query#query-dsl-match-query-phrase) on the specified field.
+Use `MATCH_PHRASE` to perform a [`match_phrase`](https://www.elastic.co/docs/reference/query-languages/query-dsl/query-dsl-match-query-phrase) on the
+specified field.
 Using `MATCH_PHRASE` is equivalent to using the `match_phrase` query in the Elasticsearch Query DSL.
 
 MatchPhrase can be used on [text](https://www.elastic.co/docs/reference/elasticsearch/mapping-reference/text) fields, as well as other field types like keyword, boolean, or date types.

+ 0 - 9
x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/plugin/MatchPhraseFunctionIT.java

@@ -13,9 +13,6 @@ import org.elasticsearch.action.support.WriteRequest;
 import org.elasticsearch.common.settings.Settings;
 import org.elasticsearch.xpack.esql.VerificationException;
 import org.elasticsearch.xpack.esql.action.AbstractEsqlIntegTestCase;
-import org.elasticsearch.xpack.esql.action.EsqlCapabilities;
-import org.elasticsearch.xpack.esql.action.EsqlQueryRequest;
-import org.elasticsearch.xpack.esql.action.EsqlQueryResponse;
 import org.hamcrest.Matchers;
 import org.junit.Before;
 
@@ -34,12 +31,6 @@ public class MatchPhraseFunctionIT extends AbstractEsqlIntegTestCase {
         createAndPopulateIndex();
     }
 
-    @Override
-    protected EsqlQueryResponse run(EsqlQueryRequest request) {
-        assumeTrue("match_phrase function capability not available", EsqlCapabilities.Cap.MATCH_PHRASE_FUNCTION.isEnabled());
-        return super.run(request);
-    }
-
     public void testSimpleWhereMatchPhrase() {
         var query = """
             FROM test

+ 1 - 3
x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/plugin/ScoringIT.java

@@ -50,12 +50,10 @@ public class ScoringIT extends AbstractEsqlIntegTestCase {
         params.add(new Object[] { "content:\"fox\"" });
         params.add(new Object[] { "qstr(\"content: fox\")" });
         params.add(new Object[] { "kql(\"content*: fox\")" });
+        params.add(new Object[] { "match_phrase(content, \"fox\")" });
         if (EsqlCapabilities.Cap.TERM_FUNCTION.isEnabled()) {
             params.add(new Object[] { "term(content, \"fox\")" });
         }
-        if (EsqlCapabilities.Cap.MATCH_PHRASE_FUNCTION.isEnabled()) {
-            params.add(new Object[] { "match_phrase(content, \"fox\")" });
-        }
         return params;
     }
 

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

@@ -1185,7 +1185,7 @@ public class EsqlCapabilities {
         /**
          * MATCH PHRASE function
          */
-        MATCH_PHRASE_FUNCTION(Build.current().isSnapshot());
+        MATCH_PHRASE_FUNCTION;
 
         private final boolean enabled;
 

+ 1 - 4
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/fulltext/FullTextWritables.java

@@ -23,15 +23,12 @@ public class FullTextWritables {
         entries.add(Match.ENTRY);
         entries.add(MultiMatch.ENTRY);
         entries.add(Kql.ENTRY);
+        entries.add(MatchPhrase.ENTRY);
 
         if (EsqlCapabilities.Cap.TERM_FUNCTION.isEnabled()) {
             entries.add(Term.ENTRY);
         }
 
-        if (EsqlCapabilities.Cap.MATCH_PHRASE_FUNCTION.isEnabled()) {
-            entries.add(MatchPhrase.ENTRY);
-        }
-
         return Collections.unmodifiableList(entries);
     }
 }

+ 3 - 2
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/fulltext/MatchPhrase.java

@@ -94,7 +94,8 @@ public class MatchPhrase extends FullTextFunction implements OptionalArgument, P
         returnType = "boolean",
         preview = true,
         description = """
-            Use `MATCH_PHRASE` to perform a <<query-dsl-match-query-phrase,match_phrase query>> on the specified field.
+            Use `MATCH_PHRASE` to perform a [`match_phrase`](/reference/query-languages/query-dsl/query-dsl-match-query-phrase.md) on the
+            specified field.
             Using `MATCH_PHRASE` is equivalent to using the `match_phrase` query in the Elasticsearch Query DSL.
 
             MatchPhrase can be used on <<text, text>> fields, as well as other field types like keyword, boolean, or date types.
@@ -149,7 +150,7 @@ public class MatchPhrase extends FullTextFunction implements OptionalArgument, P
                     description = "Floating point number used to decrease or increase the relevance scores of the query. Defaults to 1.0."
                 ) },
             description = "(Optional) MatchPhrase additional options as <<esql-function-named-params,function named parameters>>."
-                + " See <<query-dsl-match-query-phrase,match_phrase query>> for more information.",
+                + " See [`match_phrase`](/reference/query-languages/query-dsl/query-dsl-match-query-phrase.md) for more information.",
             optional = true
         ) Expression options
     ) {

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

@@ -1223,6 +1223,9 @@ public class VerifierTests extends ESTestCase {
         checkFieldBasedWithNonIndexedColumn(":", "text : \"cat\"", "operator");
         checkFieldBasedFunctionNotAllowedAfterCommands(":", "operator", "title : \"Meditation\"");
 
+        checkFieldBasedWithNonIndexedColumn("MatchPhrase", "match_phrase(text, \"cat\")", "function");
+        checkFieldBasedFunctionNotAllowedAfterCommands("MatchPhrase", "function", "match_phrase(title, \"Meditation\")");
+
         if (EsqlCapabilities.Cap.MULTI_MATCH_FUNCTION.isEnabled()) {
             checkFieldBasedWithNonIndexedColumn("MultiMatch", "multi_match(\"cat\", text)", "function");
             checkFieldBasedFunctionNotAllowedAfterCommands("MultiMatch", "function", "multi_match(\"Meditation\", title)");
@@ -1231,10 +1234,6 @@ public class VerifierTests extends ESTestCase {
             checkFieldBasedWithNonIndexedColumn("Term", "term(text, \"cat\")", "function");
             checkFieldBasedFunctionNotAllowedAfterCommands("Term", "function", "term(title, \"Meditation\")");
         }
-        if (EsqlCapabilities.Cap.MATCH_PHRASE_FUNCTION.isEnabled()) {
-            checkFieldBasedWithNonIndexedColumn("MatchPhrase", "match_phrase(text, \"cat\")", "function");
-            checkFieldBasedFunctionNotAllowedAfterCommands("MatchPhrase", "function", "match_phrase(title, \"Meditation\")");
-        }
     }
 
     private void checkFieldBasedFunctionNotAllowedAfterCommands(String functionName, String functionType, String functionInvocation) {
@@ -1358,15 +1357,13 @@ public class VerifierTests extends ESTestCase {
         checkFullTextFunctionsOnlyAllowedInWhere(":", "title:\"Meditation\"", "operator");
         checkFullTextFunctionsOnlyAllowedInWhere("QSTR", "qstr(\"Meditation\")", "function");
         checkFullTextFunctionsOnlyAllowedInWhere("KQL", "kql(\"Meditation\")", "function");
+        checkFullTextFunctionsOnlyAllowedInWhere("MatchPhrase", "match_phrase(title, \"Meditation\")", "function");
         if (EsqlCapabilities.Cap.TERM_FUNCTION.isEnabled()) {
             checkFullTextFunctionsOnlyAllowedInWhere("Term", "term(title, \"Meditation\")", "function");
         }
         if (EsqlCapabilities.Cap.MULTI_MATCH_FUNCTION.isEnabled()) {
             checkFullTextFunctionsOnlyAllowedInWhere("MultiMatch", "multi_match(\"Meditation\", title, body)", "function");
         }
-        if (EsqlCapabilities.Cap.MATCH_PHRASE_FUNCTION.isEnabled()) {
-            checkFullTextFunctionsOnlyAllowedInWhere("MatchPhrase", "match_phrase(title, \"Meditation\")", "function");
-        }
     }
 
     private void checkFullTextFunctionsOnlyAllowedInWhere(String functionName, String functionInvocation, String functionType)
@@ -1396,15 +1393,13 @@ public class VerifierTests extends ESTestCase {
         checkWithFullTextFunctionsDisjunctions("title : \"Meditation\"");
         checkWithFullTextFunctionsDisjunctions("qstr(\"title: Meditation\")");
         checkWithFullTextFunctionsDisjunctions("kql(\"title: Meditation\")");
+        checkWithFullTextFunctionsDisjunctions("match_phrase(title, \"Meditation\")");
         if (EsqlCapabilities.Cap.MULTI_MATCH_FUNCTION.isEnabled()) {
             checkWithFullTextFunctionsDisjunctions("multi_match(\"Meditation\", title, body)");
         }
         if (EsqlCapabilities.Cap.TERM_FUNCTION.isEnabled()) {
             checkWithFullTextFunctionsDisjunctions("term(title, \"Meditation\")");
         }
-        if (EsqlCapabilities.Cap.MATCH_PHRASE_FUNCTION.isEnabled()) {
-            checkWithFullTextFunctionsDisjunctions("match_phrase(title, \"Meditation\")");
-        }
     }
 
     private void checkWithFullTextFunctionsDisjunctions(String functionInvocation) {
@@ -1460,15 +1455,13 @@ public class VerifierTests extends ESTestCase {
         checkFullTextFunctionsWithNonBooleanFunctions(":", "title:\"Meditation\"", "operator");
         checkFullTextFunctionsWithNonBooleanFunctions("QSTR", "qstr(\"title: Meditation\")", "function");
         checkFullTextFunctionsWithNonBooleanFunctions("KQL", "kql(\"title: Meditation\")", "function");
+        checkFullTextFunctionsWithNonBooleanFunctions("MatchPhrase", "match_phrase(title, \"Meditation\")", "function");
         if (EsqlCapabilities.Cap.MULTI_MATCH_FUNCTION.isEnabled()) {
             checkFullTextFunctionsWithNonBooleanFunctions("MultiMatch", "multi_match(\"Meditation\", title, body)", "function");
         }
         if (EsqlCapabilities.Cap.TERM_FUNCTION.isEnabled()) {
             checkFullTextFunctionsWithNonBooleanFunctions("Term", "term(title, \"Meditation\")", "function");
         }
-        if (EsqlCapabilities.Cap.MATCH_PHRASE_FUNCTION.isEnabled()) {
-            checkFullTextFunctionsWithNonBooleanFunctions("MatchPhrase", "match_phrase(title, \"Meditation\")", "function");
-        }
     }
 
     private void checkFullTextFunctionsWithNonBooleanFunctions(String functionName, String functionInvocation, String functionType) {
@@ -1530,15 +1523,13 @@ public class VerifierTests extends ESTestCase {
     public void testFullTextFunctionsTargetsExistingField() throws Exception {
         testFullTextFunctionTargetsExistingField("match(title, \"Meditation\")");
         testFullTextFunctionTargetsExistingField("title : \"Meditation\"");
+        testFullTextFunctionTargetsExistingField("match_phrase(title, \"Meditation\")");
         if (EsqlCapabilities.Cap.MULTI_MATCH_FUNCTION.isEnabled()) {
             testFullTextFunctionTargetsExistingField("multi_match(\"Meditation\", title)");
         }
         if (EsqlCapabilities.Cap.TERM_FUNCTION.isEnabled()) {
             testFullTextFunctionTargetsExistingField("term(fist_name, \"Meditation\")");
         }
-        if (EsqlCapabilities.Cap.MATCH_PHRASE_FUNCTION.isEnabled()) {
-            testFullTextFunctionTargetsExistingField("match_phrase(title, \"Meditation\")");
-        }
     }
 
     private void testFullTextFunctionTargetsExistingField(String functionInvocation) throws Exception {
@@ -2060,12 +2051,10 @@ public class VerifierTests extends ESTestCase {
     public void testFullTextFunctionOptions() {
         checkOptionDataTypes(Match.ALLOWED_OPTIONS, "FROM test | WHERE match(title, \"Jean\", {\"%s\": %s})");
         checkOptionDataTypes(QueryString.ALLOWED_OPTIONS, "FROM test | WHERE QSTR(\"title: Jean\", {\"%s\": %s})");
+        checkOptionDataTypes(MatchPhrase.ALLOWED_OPTIONS, "FROM test | WHERE MATCH_PHRASE(title, \"Jean\", {\"%s\": %s})");
         if (EsqlCapabilities.Cap.MULTI_MATCH_FUNCTION.isEnabled()) {
             checkOptionDataTypes(MultiMatch.OPTIONS, "FROM test | WHERE MULTI_MATCH(\"Jean\", title, body, {\"%s\": %s})");
         }
-        if (EsqlCapabilities.Cap.MATCH_PHRASE_FUNCTION.isEnabled()) {
-            checkOptionDataTypes(MatchPhrase.ALLOWED_OPTIONS, "FROM test | WHERE MATCH_PHRASE(title, \"Jean\", {\"%s\": %s})");
-        }
     }
 
     /**
@@ -2120,15 +2109,13 @@ public class VerifierTests extends ESTestCase {
     public void testFullTextFunctionCurrentlyUnsupportedBehaviour() throws Exception {
         testFullTextFunctionsCurrentlyUnsupportedBehaviour("match(title, \"Meditation\")");
         testFullTextFunctionsCurrentlyUnsupportedBehaviour("title : \"Meditation\"");
+        testFullTextFunctionsCurrentlyUnsupportedBehaviour("match_phrase(title, \"Meditation\")");
         if (EsqlCapabilities.Cap.MULTI_MATCH_FUNCTION.isEnabled()) {
             testFullTextFunctionsCurrentlyUnsupportedBehaviour("multi_match(\"Meditation\", title)");
         }
         if (EsqlCapabilities.Cap.TERM_FUNCTION.isEnabled()) {
             testFullTextFunctionsCurrentlyUnsupportedBehaviour("term(title, \"Meditation\")");
         }
-        if (EsqlCapabilities.Cap.MATCH_PHRASE_FUNCTION.isEnabled()) {
-            testFullTextFunctionsCurrentlyUnsupportedBehaviour("match_phrase(title, \"Meditation\")");
-        }
     }
 
     private void testFullTextFunctionsCurrentlyUnsupportedBehaviour(String functionInvocation) throws Exception {
@@ -2143,6 +2130,8 @@ public class VerifierTests extends ESTestCase {
         checkFullTextFunctionNullArgs("match(title, null)", "second");
         checkFullTextFunctionNullArgs("qstr(null)", "");
         checkFullTextFunctionNullArgs("kql(null)", "");
+        checkFullTextFunctionNullArgs("match_phrase(null, \"query\")", "first");
+        checkFullTextFunctionNullArgs("match_phrase(title, null)", "second");
         if (EsqlCapabilities.Cap.MULTI_MATCH_FUNCTION.isEnabled()) {
             checkFullTextFunctionNullArgs("multi_match(null, title)", "first");
             checkFullTextFunctionNullArgs("multi_match(\"query\", null)", "second");
@@ -2151,10 +2140,6 @@ public class VerifierTests extends ESTestCase {
             checkFullTextFunctionNullArgs("term(null, \"query\")", "first");
             checkFullTextFunctionNullArgs("term(title, null)", "second");
         }
-        if (EsqlCapabilities.Cap.MATCH_PHRASE_FUNCTION.isEnabled()) {
-            checkFullTextFunctionNullArgs("match_phrase(null, \"query\")", "first");
-            checkFullTextFunctionNullArgs("match_phrase(title, null)", "second");
-        }
     }
 
     private void checkFullTextFunctionNullArgs(String functionInvocation, String argOrdinal) throws Exception {
@@ -2168,6 +2153,7 @@ public class VerifierTests extends ESTestCase {
         checkFullTextFunctionsConstantQuery("match(title, category)", "second");
         checkFullTextFunctionsConstantQuery("qstr(title)", "");
         checkFullTextFunctionsConstantQuery("kql(title)", "");
+        checkFullTextFunctionsConstantQuery("match_phrase(title, tags)", "second");
         if (EsqlCapabilities.Cap.MULTI_MATCH_FUNCTION.isEnabled()) {
             checkFullTextFunctionsConstantQuery("multi_match(category, body)", "first");
             checkFullTextFunctionsConstantQuery("multi_match(concat(title, \"world\"), title)", "first");
@@ -2175,9 +2161,6 @@ public class VerifierTests extends ESTestCase {
         if (EsqlCapabilities.Cap.TERM_FUNCTION.isEnabled()) {
             checkFullTextFunctionsConstantQuery("term(title, tags)", "second");
         }
-        if (EsqlCapabilities.Cap.MATCH_PHRASE_FUNCTION.isEnabled()) {
-            checkFullTextFunctionsConstantQuery("match_phrase(title, tags)", "second");
-        }
     }
 
     private void checkFullTextFunctionsConstantQuery(String functionInvocation, String argOrdinal) throws Exception {
@@ -2201,12 +2184,10 @@ public class VerifierTests extends ESTestCase {
         checkFullTextFunctionsInStats("title : \"Meditation\"");
         checkFullTextFunctionsInStats("qstr(\"title: Meditation\")");
         checkFullTextFunctionsInStats("kql(\"title: Meditation\")");
+        checkFullTextFunctionsInStats("match_phrase(title, \"Meditation\")");
         if (EsqlCapabilities.Cap.MULTI_MATCH_FUNCTION.isEnabled()) {
             checkFullTextFunctionsInStats("multi_match(\"Meditation\", title, body)");
         }
-        if (EsqlCapabilities.Cap.MATCH_PHRASE_FUNCTION.isEnabled()) {
-            checkFullTextFunctionsInStats("match_phrase(title, \"Meditation\")");
-        }
     }
 
     private void checkFullTextFunctionsInStats(String functionInvocation) {

+ 0 - 7
x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/fulltext/MatchPhraseTests.java

@@ -11,7 +11,6 @@ import com.carrotsearch.randomizedtesting.annotations.Name;
 import com.carrotsearch.randomizedtesting.annotations.ParametersFactory;
 
 import org.elasticsearch.index.query.QueryBuilder;
-import org.elasticsearch.xpack.esql.action.EsqlCapabilities;
 import org.elasticsearch.xpack.esql.core.expression.Expression;
 import org.elasticsearch.xpack.esql.core.expression.FieldAttribute;
 import org.elasticsearch.xpack.esql.core.expression.Literal;
@@ -23,7 +22,6 @@ import org.elasticsearch.xpack.esql.expression.function.FunctionName;
 import org.elasticsearch.xpack.esql.expression.function.TestCaseSupplier;
 import org.elasticsearch.xpack.esql.io.stream.PlanStreamOutput;
 import org.elasticsearch.xpack.esql.optimizer.rules.physical.local.LucenePushdownPredicates;
-import org.junit.Before;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -41,11 +39,6 @@ import static org.hamcrest.Matchers.equalTo;
 @FunctionName("match_phrase")
 public class MatchPhraseTests extends AbstractFunctionTestCase {
 
-    @Before
-    public void checkCapability() {
-        assumeTrue("MatchPhrase is not supported in this version of ESQL", EsqlCapabilities.Cap.MATCH_PHRASE_FUNCTION.isEnabled());
-    }
-
     public MatchPhraseTests(@Name("TestCase") Supplier<TestCaseSupplier.TestCase> testCaseSupplier) {
         this.testCase = testCaseSupplier.get();
     }

+ 1 - 1
x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/esql/60_usage.yml

@@ -130,7 +130,7 @@ setup:
   - match: {esql.functions.coalesce: $functions_coalesce}
   - gt: {esql.functions.categorize: $functions_categorize}
   # Testing for the entire function set isn't feasible, so we just check that we return the correct count as an approximation.
-  - length: {esql.functions: 156} # check the "sister" test below for a likely update to the same esql.functions length check
+  - length: {esql.functions: 157} # check the "sister" test below for a likely update to the same esql.functions length check
 
 ---
 "Basic ESQL usage output (telemetry) non-snapshot version":