diff --git a/docs/changelog/125060.yaml b/docs/changelog/125060.yaml new file mode 100644 index 0000000000000..3c5b04810a258 --- /dev/null +++ b/docs/changelog/125060.yaml @@ -0,0 +1,16 @@ +pr: 125060 +summary: Allow partial results by default in ES|QL +area: ES|QL +type: breaking +issues: [122802] + +breaking: + title: Allow partial results by default in ES|QL + area: ES|QL + details: >- + In earlier versions of {es}, ES|QL would fail the entire query if it encountered any error. ES|QL now returns partial results instead of failing when encountering errors. + + impact: >- + Callers should check the `is_partial` flag returned in the response to determine if the result is partial or complete. If returning partial results is not desired, this option can be overridden per request via an `allow_partial_results` parameter in the query URL or globally via the cluster setting `esql.query.allow_partial_results`. + + notable: true diff --git a/docs/reference/release-notes/8.19.0.asciidoc b/docs/reference/release-notes/8.19.0.asciidoc index c1da01b518483..095379df09b7a 100644 --- a/docs/reference/release-notes/8.19.0.asciidoc +++ b/docs/reference/release-notes/8.19.0.asciidoc @@ -1,8 +1,16 @@ [[release-notes-8.19.0]] == {es} version 8.19.0 -coming[8.19.0] - -Also see <>. +[[breaking-changes-8.19.0]] +[float] +=== Breaking changes +ES|QL:: +* In earlier versions of {es}, ES|QL would fail the entire query if it encountered any error. + ES|QL now returns partial results instead of failing when encountering errors. + Callers should check the `is_partial` flag returned in the response to determine + if the result is partial or complete. If returning partial results is not desired, + this option can be overridden per request via an `allow_partial_results` parameter + in the query URL or globally via the cluster setting `esql.query.allow_partial_results`. + {es-pull}125060[#125060] (issue: {es-issue}122802[#122802]) diff --git a/test/external-modules/esql-heap-attack/src/javaRestTest/java/org/elasticsearch/xpack/esql/heap_attack/Clusters.java b/test/external-modules/esql-heap-attack/src/javaRestTest/java/org/elasticsearch/xpack/esql/heap_attack/Clusters.java index 9fe176ca6be9d..1c237404a78cc 100644 --- a/test/external-modules/esql-heap-attack/src/javaRestTest/java/org/elasticsearch/xpack/esql/heap_attack/Clusters.java +++ b/test/external-modules/esql-heap-attack/src/javaRestTest/java/org/elasticsearch/xpack/esql/heap_attack/Clusters.java @@ -21,6 +21,7 @@ static ElasticsearchCluster buildCluster() { .module("test-esql-heap-attack") .setting("xpack.security.enabled", "false") .setting("xpack.license.self_generated.type", "trial") + .setting("esql.query.allow_partial_results", "false") .jvmArg("-Xmx512m"); String javaVersion = JvmInfo.jvmInfo().version(); if (javaVersion.equals("20") || javaVersion.equals("21")) { diff --git a/x-pack/plugin/build.gradle b/x-pack/plugin/build.gradle index 55f2e322528e4..80827f4baeebf 100644 --- a/x-pack/plugin/build.gradle +++ b/x-pack/plugin/build.gradle @@ -223,6 +223,7 @@ tasks.named("yamlRestTestV7CompatTransform").configure({ task -> task.skipTest("esql/40_tsdb/from index pattern unsupported counter", "TODO: support for subset of metric fields") task.skipTest("esql/40_unsupported_types/unsupported", "TODO: support for subset of metric fields") task.skipTest("esql/40_unsupported_types/unsupported with sort", "TODO: support for subset of metric fields") + task.skipTest("esql/63_enrich_int_range/Invalid age as double", "TODO: require disable allow_partial_results") }) tasks.named('yamlRestTestV7CompatTest').configure { diff --git a/x-pack/plugin/esql/qa/security/src/javaRestTest/java/org/elasticsearch/xpack/esql/EsqlSecurityIT.java b/x-pack/plugin/esql/qa/security/src/javaRestTest/java/org/elasticsearch/xpack/esql/EsqlSecurityIT.java index a809bd50a45b8..b2cef7366c0f0 100644 --- a/x-pack/plugin/esql/qa/security/src/javaRestTest/java/org/elasticsearch/xpack/esql/EsqlSecurityIT.java +++ b/x-pack/plugin/esql/qa/security/src/javaRestTest/java/org/elasticsearch/xpack/esql/EsqlSecurityIT.java @@ -312,7 +312,10 @@ public void testIndexPatternErrorMessageComparison_ESQL_SearchDSL() throws Excep searchRequest.setOptions(RequestOptions.DEFAULT.toBuilder().addHeader("es-security-runas-user", "metadata1_read2")); // ES|QL query on the same index pattern - var esqlResp = expectThrows(ResponseException.class, () -> runESQLCommand("metadata1_read2", "FROM index-user1,index-user2")); + var esqlResp = expectThrows( + ResponseException.class, + () -> runESQLCommand("metadata1_read2", "FROM index-user1,index-user2", false) + ); var srchResp = expectThrows(ResponseException.class, () -> client().performRequest(searchRequest)); for (ResponseException r : List.of(esqlResp, srchResp)) { @@ -331,7 +334,8 @@ public void testLimitedPrivilege() throws Exception { ResponseException.class, () -> runESQLCommand( "metadata1_read2", - "FROM index-user1,index-user2 METADATA _index | STATS sum=sum(value), index=VALUES(_index)" + "FROM index-user1,index-user2 METADATA _index | STATS sum=sum(value), index=VALUES(_index)", + false ) ); assertThat( @@ -344,7 +348,7 @@ public void testLimitedPrivilege() throws Exception { resp = expectThrows( ResponseException.class, - () -> runESQLCommand("metadata1_read2", "FROM index-user1,index-user2 METADATA _index | STATS index=VALUES(_index)") + () -> runESQLCommand("metadata1_read2", "FROM index-user1,index-user2 METADATA _index | STATS index=VALUES(_index)", false) ); assertThat( EntityUtils.toString(resp.getResponse().getEntity()), @@ -356,7 +360,7 @@ public void testLimitedPrivilege() throws Exception { resp = expectThrows( ResponseException.class, - () -> runESQLCommand("metadata1_read2", "FROM index-user1,index-user2 | STATS sum=sum(value)") + () -> runESQLCommand("metadata1_read2", "FROM index-user1,index-user2 | STATS sum=sum(value)", false) ); assertThat( EntityUtils.toString(resp.getResponse().getEntity()), @@ -368,7 +372,7 @@ public void testLimitedPrivilege() throws Exception { resp = expectThrows( ResponseException.class, - () -> runESQLCommand("alias_user1", "FROM first-alias,index-user1 METADATA _index | KEEP _index, org, value | LIMIT 10") + () -> runESQLCommand("alias_user1", "FROM first-alias,index-user1 METADATA _index | KEEP _index, org, value | LIMIT 10", false) ); assertThat( EntityUtils.toString(resp.getResponse().getEntity()), @@ -382,7 +386,8 @@ public void testLimitedPrivilege() throws Exception { ResponseException.class, () -> runESQLCommand( "alias_user2", - "from second-alias,index-user2 METADATA _index | stats sum=sum(value), index=VALUES(_index)" + "from second-alias,index-user2 METADATA _index | stats sum=sum(value), index=VALUES(_index)", + false ) ); assertThat( @@ -826,6 +831,10 @@ public void testDataStream() throws IOException { } protected Response runESQLCommand(String user, String command) throws IOException { + return runESQLCommand(user, command, null); + } + + protected Response runESQLCommand(String user, String command, Boolean allowPartialResults) throws IOException { if (command.toLowerCase(Locale.ROOT).contains("limit") == false) { // add a (high) limit to avoid warnings on default limit command += " | limit 10000000"; @@ -839,6 +848,9 @@ protected Response runESQLCommand(String user, String command) throws IOExceptio request.setJsonEntity(Strings.toString(json)); request.setOptions(RequestOptions.DEFAULT.toBuilder().addHeader("es-security-runas-user", user)); request.addParameter("error_trace", "true"); + if (allowPartialResults != null) { + request.addParameter("allow_partial_results", Boolean.toString(allowPartialResults)); + } return client().performRequest(request); } diff --git a/x-pack/plugin/esql/qa/server/multi-clusters/src/javaRestTest/java/org/elasticsearch/xpack/esql/ccq/EsqlRestValidationIT.java b/x-pack/plugin/esql/qa/server/multi-clusters/src/javaRestTest/java/org/elasticsearch/xpack/esql/ccq/EsqlRestValidationIT.java index 55500aa1c9537..aed164f9e8873 100644 --- a/x-pack/plugin/esql/qa/server/multi-clusters/src/javaRestTest/java/org/elasticsearch/xpack/esql/ccq/EsqlRestValidationIT.java +++ b/x-pack/plugin/esql/qa/server/multi-clusters/src/javaRestTest/java/org/elasticsearch/xpack/esql/ccq/EsqlRestValidationIT.java @@ -83,6 +83,6 @@ private RestClient remoteClusterClient() throws IOException { @Before public void skipTestOnOldVersions() { - assumeTrue("skip on old versions", Clusters.localClusterVersion().equals(Version.V_8_16_0)); + assumeTrue("skip on old versions", Clusters.localClusterVersion().equals(Version.V_8_19_0)); } } diff --git a/x-pack/plugin/esql/qa/server/multi-clusters/src/javaRestTest/java/org/elasticsearch/xpack/esql/ccq/RequestIndexFilteringIT.java b/x-pack/plugin/esql/qa/server/multi-clusters/src/javaRestTest/java/org/elasticsearch/xpack/esql/ccq/RequestIndexFilteringIT.java index 5a12fe22b9561..4ceff2703d064 100644 --- a/x-pack/plugin/esql/qa/server/multi-clusters/src/javaRestTest/java/org/elasticsearch/xpack/esql/ccq/RequestIndexFilteringIT.java +++ b/x-pack/plugin/esql/qa/server/multi-clusters/src/javaRestTest/java/org/elasticsearch/xpack/esql/ccq/RequestIndexFilteringIT.java @@ -30,6 +30,7 @@ import org.junit.rules.TestRule; import java.io.IOException; +import java.util.List; import java.util.Map; import static org.elasticsearch.test.MapMatcher.assertMap; @@ -94,6 +95,12 @@ protected String from(String... indexName) { @Override public Map runEsql(RestEsqlTestCase.RequestObjectBuilder requestObject) throws IOException { + if (requestObject.allowPartialResults() != null) { + assumeTrue( + "require allow_partial_results on local cluster", + clusterHasCapability("POST", "/_query", List.of(), List.of("support_partial_results")).orElse(false) + ); + } requestObject.includeCCSMetadata(true); return super.runEsql(requestObject); } diff --git a/x-pack/plugin/esql/qa/server/single-node/src/javaRestTest/java/org/elasticsearch/xpack/esql/qa/single_node/RestEsqlIT.java b/x-pack/plugin/esql/qa/server/single-node/src/javaRestTest/java/org/elasticsearch/xpack/esql/qa/single_node/RestEsqlIT.java index 31ef072c11b09..0cab974d05ed9 100644 --- a/x-pack/plugin/esql/qa/server/single-node/src/javaRestTest/java/org/elasticsearch/xpack/esql/qa/single_node/RestEsqlIT.java +++ b/x-pack/plugin/esql/qa/server/single-node/src/javaRestTest/java/org/elasticsearch/xpack/esql/qa/single_node/RestEsqlIT.java @@ -110,7 +110,7 @@ public void testInvalidPragma() throws IOException { request.setJsonEntity("{\"f\":" + i + "}"); assertOK(client().performRequest(request)); } - RequestObjectBuilder builder = requestObjectBuilder().query("from test-index | limit 1 | keep f"); + RequestObjectBuilder builder = requestObjectBuilder().query("from test-index | limit 1 | keep f").allowPartialResults(false); builder.pragmas(Settings.builder().put("data_partitioning", "invalid-option").build()); ResponseException re = expectThrows(ResponseException.class, () -> runEsqlSync(builder)); assertThat(EntityUtils.toString(re.getResponse().getEntity()), containsString("No enum constant")); diff --git a/x-pack/plugin/esql/qa/server/src/main/java/org/elasticsearch/xpack/esql/qa/rest/EsqlRestValidationTestCase.java b/x-pack/plugin/esql/qa/server/src/main/java/org/elasticsearch/xpack/esql/qa/rest/EsqlRestValidationTestCase.java index 9ec4f60f4c843..6a66d5a4270c7 100644 --- a/x-pack/plugin/esql/qa/server/src/main/java/org/elasticsearch/xpack/esql/qa/rest/EsqlRestValidationTestCase.java +++ b/x-pack/plugin/esql/qa/server/src/main/java/org/elasticsearch/xpack/esql/qa/rest/EsqlRestValidationTestCase.java @@ -129,6 +129,7 @@ private Request createRequest(String indexName) throws IOException { final var request = new Request("POST", "/_query"); request.addParameter("error_trace", "true"); request.addParameter("pretty", "true"); + request.addParameter("allow_partial_results", Boolean.toString(false)); request.setJsonEntity( Strings.toString(JsonXContent.contentBuilder().startObject().field("query", "from " + indexName).endObject()) ); diff --git a/x-pack/plugin/esql/qa/server/src/main/java/org/elasticsearch/xpack/esql/qa/rest/RequestIndexFilteringTestCase.java b/x-pack/plugin/esql/qa/server/src/main/java/org/elasticsearch/xpack/esql/qa/rest/RequestIndexFilteringTestCase.java index 1fdc11174ee09..0183e180c15d8 100644 --- a/x-pack/plugin/esql/qa/server/src/main/java/org/elasticsearch/xpack/esql/qa/rest/RequestIndexFilteringTestCase.java +++ b/x-pack/plugin/esql/qa/server/src/main/java/org/elasticsearch/xpack/esql/qa/rest/RequestIndexFilteringTestCase.java @@ -198,17 +198,26 @@ public void testIndicesDontExist() throws IOException { int docsTest1 = 0; // we are interested only in the created index, not necessarily that it has data indexTimestampData(docsTest1, "test1", "2024-11-26", "id1"); - ResponseException e = expectThrows(ResponseException.class, () -> runEsql(timestampFilter("gte", "2020-01-01").query(from("foo")))); + ResponseException e = expectThrows( + ResponseException.class, + () -> runEsql(timestampFilter("gte", "2020-01-01").query(from("foo")).allowPartialResults(false)) + ); assertEquals(400, e.getResponse().getStatusLine().getStatusCode()); assertThat(e.getMessage(), containsString("verification_exception")); assertThat(e.getMessage(), anyOf(containsString("Unknown index [foo]"), containsString("Unknown index [remote_cluster:foo]"))); - e = expectThrows(ResponseException.class, () -> runEsql(timestampFilter("gte", "2020-01-01").query(from("foo*")))); + e = expectThrows( + ResponseException.class, + () -> runEsql(timestampFilter("gte", "2020-01-01").query(from("foo*")).allowPartialResults(false)) + ); assertEquals(400, e.getResponse().getStatusLine().getStatusCode()); assertThat(e.getMessage(), containsString("verification_exception")); assertThat(e.getMessage(), anyOf(containsString("Unknown index [foo*]"), containsString("Unknown index [remote_cluster:foo*]"))); - e = expectThrows(ResponseException.class, () -> runEsql(timestampFilter("gte", "2020-01-01").query(from("foo", "test1")))); + e = expectThrows( + ResponseException.class, + () -> runEsql(timestampFilter("gte", "2020-01-01").query(from("foo", "test1")).allowPartialResults(false)) + ); assertEquals(404, e.getResponse().getStatusLine().getStatusCode()); assertThat(e.getMessage(), containsString("index_not_found_exception")); assertThat(e.getMessage(), anyOf(containsString("no such index [foo]"), containsString("no such index [remote_cluster:foo]"))); @@ -217,7 +226,7 @@ public void testIndicesDontExist() throws IOException { var pattern = from("test1"); e = expectThrows( ResponseException.class, - () -> runEsql(timestampFilter("gte", "2020-01-01").query(pattern + " | LOOKUP JOIN foo ON id1")) + () -> runEsql(timestampFilter("gte", "2020-01-01").query(pattern + " | LOOKUP JOIN foo ON id1").allowPartialResults(false)) ); assertEquals(400, e.getResponse().getStatusLine().getStatusCode()); assertThat( diff --git a/x-pack/plugin/esql/qa/server/src/main/java/org/elasticsearch/xpack/esql/qa/rest/RestEsqlTestCase.java b/x-pack/plugin/esql/qa/server/src/main/java/org/elasticsearch/xpack/esql/qa/rest/RestEsqlTestCase.java index 735dc2af2f7af..22b56cfc0871b 100644 --- a/x-pack/plugin/esql/qa/server/src/main/java/org/elasticsearch/xpack/esql/qa/rest/RestEsqlTestCase.java +++ b/x-pack/plugin/esql/qa/server/src/main/java/org/elasticsearch/xpack/esql/qa/rest/RestEsqlTestCase.java @@ -132,7 +132,7 @@ public static class RequestObjectBuilder { private Boolean includeCCSMetadata = null; private CheckedConsumer filter; - private Boolean allPartialResults = null; + private Boolean allowPartialResults = null; public RequestObjectBuilder() throws IOException { this(randomFrom(XContentType.values())); @@ -210,11 +210,15 @@ public RequestObjectBuilder filter(CheckedConsumer return this; } - public RequestObjectBuilder allPartialResults(boolean allPartialResults) { - this.allPartialResults = allPartialResults; + public RequestObjectBuilder allowPartialResults(boolean allowPartialResults) { + this.allowPartialResults = allowPartialResults; return this; } + public Boolean allowPartialResults() { + return allowPartialResults; + } + public RequestObjectBuilder build() throws IOException { if (isBuilt == false) { if (tables != null) { @@ -1369,8 +1373,8 @@ protected static Request prepareRequestWithOptions(RequestObjectBuilder requestO requestObject.build(); Request request = prepareRequest(mode); String mediaType = attachBody(requestObject, request); - if (requestObject.allPartialResults != null) { - request.addParameter("allow_partial_results", String.valueOf(requestObject.allPartialResults)); + if (requestObject.allowPartialResults != null) { + request.addParameter("allow_partial_results", String.valueOf(requestObject.allowPartialResults)); } RequestOptions.Builder options = request.getOptions().toBuilder(); diff --git a/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/action/AbstractCrossClusterTestCase.java b/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/action/AbstractCrossClusterTestCase.java index bea757cbf484f..992572fc3220d 100644 --- a/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/action/AbstractCrossClusterTestCase.java +++ b/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/action/AbstractCrossClusterTestCase.java @@ -25,6 +25,7 @@ import org.elasticsearch.transport.RemoteClusterAware; import org.elasticsearch.xcontent.XContentBuilder; import org.elasticsearch.xcontent.json.JsonXContent; +import org.elasticsearch.xpack.esql.plugin.EsqlPlugin; import org.junit.After; import org.junit.Before; @@ -76,6 +77,11 @@ protected Collection> nodePlugins(String clusterAlias) { return plugins; } + @Override + protected Settings nodeSettings() { + return Settings.builder().put(super.nodeSettings()).put(EsqlPlugin.QUERY_ALLOW_PARTIAL_RESULTS.getKey(), false).build(); + } + public static class InternalExchangePlugin extends Plugin { @Override public List> getSettings() { diff --git a/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/action/AbstractEsqlIntegTestCase.java b/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/action/AbstractEsqlIntegTestCase.java index 5406f3f773205..00d30066899ae 100644 --- a/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/action/AbstractEsqlIntegTestCase.java +++ b/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/action/AbstractEsqlIntegTestCase.java @@ -139,6 +139,14 @@ protected Collection> nodePlugins() { return CollectionUtils.appendToCopy(super.nodePlugins(), EsqlPlugin.class); } + @Override + protected Settings nodeSettings(int nodeOrdinal, Settings otherSettings) { + return Settings.builder() + .put(super.nodeSettings(nodeOrdinal, otherSettings)) + .put(EsqlPlugin.QUERY_ALLOW_PARTIAL_RESULTS.getKey(), false) + .build(); + } + protected void setRequestCircuitBreakerLimit(ByteSizeValue limit) { if (limit != null) { assertAcked( diff --git a/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/action/CrossClusterCancellationIT.java b/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/action/CrossClusterCancellationIT.java index 4a5de9dd7d632..f435a61d89084 100644 --- a/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/action/CrossClusterCancellationIT.java +++ b/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/action/CrossClusterCancellationIT.java @@ -14,25 +14,20 @@ import org.elasticsearch.action.index.IndexRequest; import org.elasticsearch.action.support.PlainActionFuture; import org.elasticsearch.action.support.WriteRequest; -import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.transport.TransportAddress; import org.elasticsearch.compute.operator.DriverTaskRunner; import org.elasticsearch.compute.operator.exchange.ExchangeService; import org.elasticsearch.core.TimeValue; -import org.elasticsearch.plugins.Plugin; import org.elasticsearch.tasks.TaskCancelledException; import org.elasticsearch.tasks.TaskInfo; -import org.elasticsearch.test.AbstractMultiClustersTestCase; import org.elasticsearch.transport.TransportService; import org.elasticsearch.xcontent.XContentBuilder; import org.elasticsearch.xcontent.json.JsonXContent; import org.elasticsearch.xpack.esql.EsqlTestUtils; import org.elasticsearch.xpack.esql.plugin.ComputeService; -import org.junit.After; -import org.junit.Before; import java.util.ArrayList; -import java.util.Collection; import java.util.List; import java.util.concurrent.TimeUnit; @@ -44,44 +39,20 @@ import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.instanceOf; -public class CrossClusterCancellationIT extends AbstractMultiClustersTestCase { +public class CrossClusterCancellationIT extends AbstractCrossClusterTestCase { private static final String REMOTE_CLUSTER = "cluster-a"; @Override - protected Collection remoteClusterAlias() { + protected List remoteClusterAlias() { return List.of(REMOTE_CLUSTER); } @Override - protected Collection> nodePlugins(String clusterAlias) { - List> plugins = new ArrayList<>(super.nodePlugins(clusterAlias)); - plugins.add(EsqlPluginWithEnterpriseOrTrialLicense.class); - plugins.add(InternalExchangePlugin.class); - plugins.add(SimplePauseFieldPlugin.class); - return plugins; - } - - public static class InternalExchangePlugin extends Plugin { - @Override - public List> getSettings() { - return List.of( - Setting.timeSetting( - ExchangeService.INACTIVE_SINKS_INTERVAL_SETTING, - TimeValue.timeValueMillis(between(3000, 4000)), - Setting.Property.NodeScope - ) - ); - } - } - - @Before - public void resetPlugin() { - SimplePauseFieldPlugin.resetPlugin(); - } - - @After - public void releasePlugin() { - SimplePauseFieldPlugin.release(); + protected Settings nodeSettings() { + return Settings.builder() + .put(super.nodeSettings()) + .put(ExchangeService.INACTIVE_SINKS_INTERVAL_SETTING, TimeValue.timeValueMillis(between(3000, 4000))) + .build(); } @Override diff --git a/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/action/ManyShardsIT.java b/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/action/ManyShardsIT.java index c52e1b538972b..59ba9b9eda5d8 100644 --- a/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/action/ManyShardsIT.java +++ b/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/action/ManyShardsIT.java @@ -69,6 +69,7 @@ protected Collection> nodePlugins() { @Override protected Settings nodeSettings(int nodeOrdinal, Settings otherSettings) { return Settings.builder() + .put(super.nodeSettings(nodeOrdinal, otherSettings)) .put(ExchangeService.INACTIVE_SINKS_INTERVAL_SETTING, TimeValue.timeValueMillis(between(3000, 5000))) .build(); } diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plugin/EsqlPlugin.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plugin/EsqlPlugin.java index 56773005edd5c..0c4f1d9d969f4 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plugin/EsqlPlugin.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plugin/EsqlPlugin.java @@ -105,7 +105,7 @@ public class EsqlPlugin extends Plugin implements ActionPlugin { public static final Setting QUERY_ALLOW_PARTIAL_RESULTS = Setting.boolSetting( "esql.query.allow_partial_results", - false, + true, Setting.Property.NodeScope, Setting.Property.Dynamic ); diff --git a/x-pack/plugin/security/qa/multi-cluster/src/javaRestTest/java/org/elasticsearch/xpack/remotecluster/CrossClusterEsqlRCS1MissingIndicesIT.java b/x-pack/plugin/security/qa/multi-cluster/src/javaRestTest/java/org/elasticsearch/xpack/remotecluster/CrossClusterEsqlRCS1MissingIndicesIT.java index 23f33b2351c21..f5c06129eb025 100644 --- a/x-pack/plugin/security/qa/multi-cluster/src/javaRestTest/java/org/elasticsearch/xpack/remotecluster/CrossClusterEsqlRCS1MissingIndicesIT.java +++ b/x-pack/plugin/security/qa/multi-cluster/src/javaRestTest/java/org/elasticsearch/xpack/remotecluster/CrossClusterEsqlRCS1MissingIndicesIT.java @@ -47,6 +47,7 @@ public class CrossClusterEsqlRCS1MissingIndicesIT extends AbstractRemoteClusterS .apply(commonClusterConfig) .setting("remote_cluster.port", "0") .setting("xpack.ml.enabled", "false") + .setting("esql.query.allow_partial_results", "false") .setting("xpack.security.remote_cluster_server.ssl.enabled", () -> String.valueOf(SSL_ENABLED_REF.get())) .setting("xpack.security.remote_cluster_server.ssl.key", "remote-cluster.key") .setting("xpack.security.remote_cluster_server.ssl.certificate", "remote-cluster.crt") @@ -62,6 +63,7 @@ public class CrossClusterEsqlRCS1MissingIndicesIT extends AbstractRemoteClusterS .module("x-pack-enrich") .apply(commonClusterConfig) .setting("xpack.ml.enabled", "false") + .setting("esql.query.allow_partial_results", "false") .setting("xpack.security.remote_cluster_client.ssl.enabled", () -> String.valueOf(SSL_ENABLED_REF.get())) .build(); } diff --git a/x-pack/plugin/security/qa/multi-cluster/src/javaRestTest/java/org/elasticsearch/xpack/remotecluster/RemoteClusterSecurityEsqlIT.java b/x-pack/plugin/security/qa/multi-cluster/src/javaRestTest/java/org/elasticsearch/xpack/remotecluster/RemoteClusterSecurityEsqlIT.java index dcf993ea4ce7a..7f65d38bd049e 100644 --- a/x-pack/plugin/security/qa/multi-cluster/src/javaRestTest/java/org/elasticsearch/xpack/remotecluster/RemoteClusterSecurityEsqlIT.java +++ b/x-pack/plugin/security/qa/multi-cluster/src/javaRestTest/java/org/elasticsearch/xpack/remotecluster/RemoteClusterSecurityEsqlIT.java @@ -78,6 +78,7 @@ public class RemoteClusterSecurityEsqlIT extends AbstractRemoteClusterSecurityTe .apply(commonClusterConfig) .setting("remote_cluster.port", "0") .setting("xpack.ml.enabled", "false") + .setting("esql.query.allow_partial_results", "false") .setting("xpack.security.remote_cluster_server.ssl.enabled", () -> String.valueOf(SSL_ENABLED_REF.get())) .setting("xpack.security.remote_cluster_server.ssl.key", "remote-cluster.key") .setting("xpack.security.remote_cluster_server.ssl.certificate", "remote-cluster.crt") @@ -97,6 +98,7 @@ public class RemoteClusterSecurityEsqlIT extends AbstractRemoteClusterSecurityTe .module("ingest-common") .apply(commonClusterConfig) .setting("xpack.ml.enabled", "false") + .setting("esql.query.allow_partial_results", "false") .setting("xpack.security.remote_cluster_client.ssl.enabled", () -> String.valueOf(SSL_ENABLED_REF.get())) .setting("xpack.security.remote_cluster_client.ssl.certificate_authorities", "remote-cluster-ca.crt") .setting("xpack.security.authc.token.enabled", "true") diff --git a/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/esql/63_enrich_int_range.yml b/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/esql/63_enrich_int_range.yml index 4d84a10507504..07a8d2ee5aa9c 100644 --- a/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/esql/63_enrich_int_range.yml +++ b/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/esql/63_enrich_int_range.yml @@ -192,8 +192,17 @@ teardown: --- "Invalid age as double": + - requires: + test_runner_features: [ capabilities ] + capabilities: + - method: POST + path: /_query + parameters: [ ] + capabilities: [ support_partial_results ] + reason: "disable partial_results" - do: catch: /ENRICH range and input types are incompatible. range\[INTEGER\], input\[DOUBLE\]/ esql.query: + allow_partial_results: false body: query: 'FROM employees | ENRICH ages-policy ON salary | STATS count=COUNT(*) BY description | SORT count DESC, description ASC'