diff --git a/x-pack/plugin/esql/qa/server/mixed-cluster/src/javaRestTest/java/org/elasticsearch/xpack/esql/qa/mixed/MixedClusterEsqlSpecIT.java b/x-pack/plugin/esql/qa/server/mixed-cluster/src/javaRestTest/java/org/elasticsearch/xpack/esql/qa/mixed/MixedClusterEsqlSpecIT.java index b22925b44ebab..f5d8f472fd59f 100644 --- a/x-pack/plugin/esql/qa/server/mixed-cluster/src/javaRestTest/java/org/elasticsearch/xpack/esql/qa/mixed/MixedClusterEsqlSpecIT.java +++ b/x-pack/plugin/esql/qa/server/mixed-cluster/src/javaRestTest/java/org/elasticsearch/xpack/esql/qa/mixed/MixedClusterEsqlSpecIT.java @@ -8,7 +8,6 @@ package org.elasticsearch.xpack.esql.qa.mixed; import org.elasticsearch.Version; -import org.elasticsearch.features.NodeFeature; import org.elasticsearch.test.cluster.ElasticsearchCluster; import org.elasticsearch.test.rest.TestFeatureService; import org.elasticsearch.xpack.esql.CsvSpecReader.CsvTestCase; @@ -22,7 +21,6 @@ import static org.elasticsearch.xpack.esql.CsvTestUtils.isEnabled; import static org.elasticsearch.xpack.esql.action.EsqlCapabilities.Cap.JOIN_LOOKUP_V10; -import static org.elasticsearch.xpack.esql.qa.rest.EsqlSpecTestCase.Mode.ASYNC; public class MixedClusterEsqlSpecIT extends EsqlSpecTestCase { @ClassRule @@ -49,10 +47,6 @@ protected static boolean oldClusterHasFeature(String featureId) { return oldClusterTestFeatureService.clusterHasFeature(featureId); } - protected static boolean oldClusterHasFeature(NodeFeature feature) { - return oldClusterHasFeature(feature.id()); - } - @AfterClass public static void cleanUp() { oldClusterTestFeatureService = null; @@ -74,14 +68,6 @@ public MixedClusterEsqlSpecIT( protected void shouldSkipTest(String testName) throws IOException { super.shouldSkipTest(testName); assumeTrue("Test " + testName + " is skipped on " + bwcVersion, isEnabled(testName, instructions, bwcVersion)); - if (mode == ASYNC) { - assumeTrue("Async is not supported on " + bwcVersion, supportsAsync()); - } - } - - @Override - protected boolean supportsAsync() { - return oldClusterHasFeature(ASYNC_QUERY_FEATURE_ID); } @Override diff --git a/x-pack/plugin/esql/qa/server/src/main/java/org/elasticsearch/xpack/esql/qa/rest/EsqlSpecTestCase.java b/x-pack/plugin/esql/qa/server/src/main/java/org/elasticsearch/xpack/esql/qa/rest/EsqlSpecTestCase.java index 49f5b01f247cf..18bfb6b8676ce 100644 --- a/x-pack/plugin/esql/qa/server/src/main/java/org/elasticsearch/xpack/esql/qa/rest/EsqlSpecTestCase.java +++ b/x-pack/plugin/esql/qa/server/src/main/java/org/elasticsearch/xpack/esql/qa/rest/EsqlSpecTestCase.java @@ -75,9 +75,6 @@ @TimeoutSuite(millis = 30 * TimeUnits.MINUTE) public abstract class EsqlSpecTestCase extends ESRestTestCase { - // To avoid referencing the main module, we replicate EsqlFeatures.ASYNC_QUERY.id() here - protected static final String ASYNC_QUERY_FEATURE_ID = "esql.async_query"; - private static final Logger LOGGER = LogManager.getLogger(EsqlSpecTestCase.class); private final String fileName; private final String groupName; @@ -140,10 +137,6 @@ public void setup() throws IOException { } } - protected boolean supportsAsync() { - return clusterHasFeature(ASYNC_QUERY_FEATURE_ID); // the Async API was introduced in 8.13.0 - } - @AfterClass public static void wipeTestData() throws IOException { try { @@ -281,7 +274,6 @@ protected boolean deduplicateExactWarnings() { private Map runEsql(RequestObjectBuilder requestObject, AssertWarnings assertWarnings) throws IOException { if (mode == Mode.ASYNC) { - assert supportsAsync(); return RestEsqlTestCase.runEsqlAsync(requestObject, assertWarnings); } else { return RestEsqlTestCase.runEsqlSync(requestObject, assertWarnings); diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java index 4531532fac3c5..1acc72d4ea33e 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java @@ -27,6 +27,113 @@ */ public class EsqlCapabilities { public enum Cap { + /** + * Introduction of {@code MV_SORT}, {@code MV_SLICE}, and {@code MV_ZIP}. + * Added in #106095. + */ + MV_SORT, + + /** + * When we disabled some broken optimizations around {@code nullable}. + * Fixed in #105691. + */ + DISABLE_NULLABLE_OPTS, + + /** + * Introduction of {@code ST_X} and {@code ST_Y}. Added in #105768. + */ + ST_X_Y, + + /** + * Changed precision of {@code geo_point} and {@code cartesian_point} fields, by loading from source into WKB. Done in #103691. + */ + SPATIAL_POINTS_FROM_SOURCE, + + /** + * Support for loading {@code geo_shape} and {@code cartesian_shape} fields. Done in #104269. + */ + SPATIAL_SHAPES, + + /** + * Support for spatial aggregation {@code ST_CENTROID}. Done in #104269. + */ + ST_CENTROID_AGG, + + /** + * Support for spatial aggregation {@code ST_INTERSECTS}. Done in #104907. + */ + ST_INTERSECTS, + + /** + * Support for spatial aggregation {@code ST_CONTAINS} and {@code ST_WITHIN}. Done in #106503. + */ + ST_CONTAINS_WITHIN, + + /** + * Support for spatial aggregation {@code ST_DISJOINT}. Done in #107007. + */ + ST_DISJOINT, + + /** + * The introduction of the {@code VALUES} agg. + */ + AGG_VALUES, + + /** + * Does ESQL support async queries. + */ + ASYNC_QUERY, + + /** + * Does ESQL support FROM OPTIONS? + */ + @Deprecated + FROM_OPTIONS, + + /** + * Cast string literals to a desired data type. + */ + STRING_LITERAL_AUTO_CASTING, + + /** + * Base64 encoding and decoding functions. + */ + BASE64_DECODE_ENCODE, + + /** + * Support for the :: casting operator + */ + CASTING_OPERATOR, + + /** + * Blocks can be labelled with {@link org.elasticsearch.compute.data.Block.MvOrdering#SORTED_ASCENDING} for optimizations. + */ + MV_ORDERING_SORTED_ASCENDING, + + /** + * Support for metrics counter fields + */ + METRICS_COUNTER_FIELDS, + + /** + * Cast string literals to a desired data type for IN predicate and more types for BinaryComparison. + */ + STRING_LITERAL_AUTO_CASTING_EXTENDED, + + /** + * Support for metadata fields. + */ + METADATA_FIELDS, + + /** + * Support for timespan units abbreviations + */ + TIMESPAN_ABBREVIATIONS, + + /** + * Support metrics counter types + */ + COUNTER_TYPES, /** * Support for function {@code BIT_LENGTH}. Done in #115792 diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plugin/EsqlFeatures.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plugin/EsqlFeatures.java index e4310a0bbf3a6..89b4231a999d4 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plugin/EsqlFeatures.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plugin/EsqlFeatures.java @@ -24,132 +24,16 @@ * examples below are *just* used for that. Don't make more of those - add them * to {@link EsqlCapabilities} instead. *

- * NOTE: You can't remove a feature now and probably never will be able to. + * NOTE: You can only remove features on major version boundaries. * Only add more of these if you need a fast CPU level check. *

*/ public class EsqlFeatures implements FeatureSpecification { - /** - * Introduction of {@code MV_SORT}, {@code MV_SLICE}, and {@code MV_ZIP}. - * Added in #106095. - */ - private static final NodeFeature MV_SORT = new NodeFeature("esql.mv_sort", true); - - /** - * When we disabled some broken optimizations around {@code nullable}. - * Fixed in #105691. - */ - private static final NodeFeature DISABLE_NULLABLE_OPTS = new NodeFeature("esql.disable_nullable_opts", true); - - /** - * Introduction of {@code ST_X} and {@code ST_Y}. Added in #105768. - */ - private static final NodeFeature ST_X_Y = new NodeFeature("esql.st_x_y", true); - - /** - * Changed precision of {@code geo_point} and {@code cartesian_point} fields, by loading from source into WKB. Done in #103691. - */ - private static final NodeFeature SPATIAL_POINTS_FROM_SOURCE = new NodeFeature("esql.spatial_points_from_source", true); - - /** - * Support for loading {@code geo_shape} and {@code cartesian_shape} fields. Done in #104269. - */ - private static final NodeFeature SPATIAL_SHAPES = new NodeFeature("esql.spatial_shapes", true); - - /** - * Support for spatial aggregation {@code ST_CENTROID}. Done in #104269. - */ - private static final NodeFeature ST_CENTROID_AGG = new NodeFeature("esql.st_centroid_agg", true); - - /** - * Support for spatial aggregation {@code ST_INTERSECTS}. Done in #104907. - */ - private static final NodeFeature ST_INTERSECTS = new NodeFeature("esql.st_intersects", true); - - /** - * Support for spatial aggregation {@code ST_CONTAINS} and {@code ST_WITHIN}. Done in #106503. - */ - private static final NodeFeature ST_CONTAINS_WITHIN = new NodeFeature("esql.st_contains_within", true); - - /** - * Support for spatial aggregation {@code ST_DISJOINT}. Done in #107007. - */ - private static final NodeFeature ST_DISJOINT = new NodeFeature("esql.st_disjoint", true); - - /** - * The introduction of the {@code VALUES} agg. - */ - private static final NodeFeature AGG_VALUES = new NodeFeature("esql.agg_values", true); - - /** - * Does ESQL support async queries. - */ - public static final NodeFeature ASYNC_QUERY = new NodeFeature("esql.async_query", true); - - /** - * Does ESQL support FROM OPTIONS? - */ - @Deprecated - public static final NodeFeature FROM_OPTIONS = new NodeFeature("esql.from_options", true); - - /** - * Cast string literals to a desired data type. - */ - public static final NodeFeature STRING_LITERAL_AUTO_CASTING = new NodeFeature("esql.string_literal_auto_casting", true); - - /** - * Base64 encoding and decoding functions. - */ - public static final NodeFeature BASE64_DECODE_ENCODE = new NodeFeature("esql.base64_decode_encode", true); - - /** - * Support for the :: casting operator - */ - public static final NodeFeature CASTING_OPERATOR = new NodeFeature("esql.casting_operator", true); - - /** - * Blocks can be labelled with {@link org.elasticsearch.compute.data.Block.MvOrdering#SORTED_ASCENDING} for optimizations. - */ - public static final NodeFeature MV_ORDERING_SORTED_ASCENDING = new NodeFeature("esql.mv_ordering_sorted_ascending", true); - - /** - * Support for metrics counter fields - */ - public static final NodeFeature METRICS_COUNTER_FIELDS = new NodeFeature("esql.metrics_counter_fields", true); - - /** - * Cast string literals to a desired data type for IN predicate and more types for BinaryComparison. - */ - public static final NodeFeature STRING_LITERAL_AUTO_CASTING_EXTENDED = new NodeFeature( - "esql.string_literal_auto_casting_extended", - true - ); - - /** - * Support for metadata fields. - */ - public static final NodeFeature METADATA_FIELDS = new NodeFeature("esql.metadata_fields", true); - - /** - * Support for timespan units abbreviations - */ - public static final NodeFeature TIMESPAN_ABBREVIATIONS = new NodeFeature("esql.timespan_abbreviations", true); - - /** - * Support metrics counter types - */ - public static final NodeFeature COUNTER_TYPES = new NodeFeature("esql.counter_types", true); - /** * Support metrics syntax */ public static final NodeFeature METRICS_SYNTAX = new NodeFeature("esql.metrics_syntax"); - /** - * Internal resolve_fields API for ES|QL - */ - public static final NodeFeature RESOLVE_FIELDS_API = new NodeFeature("esql.resolve_fields_api", true); - private Set snapshotBuildFeatures() { assert Build.current().isSnapshot() : Build.current(); return Set.of(METRICS_SYNTAX); @@ -157,30 +41,7 @@ private Set snapshotBuildFeatures() { @Override public Set getFeatures() { - Set features = Set.of( - ASYNC_QUERY, - AGG_VALUES, - BASE64_DECODE_ENCODE, - MV_SORT, - DISABLE_NULLABLE_OPTS, - ST_X_Y, - FROM_OPTIONS, - SPATIAL_POINTS_FROM_SOURCE, - SPATIAL_SHAPES, - ST_CENTROID_AGG, - ST_INTERSECTS, - ST_CONTAINS_WITHIN, - ST_DISJOINT, - STRING_LITERAL_AUTO_CASTING, - CASTING_OPERATOR, - MV_ORDERING_SORTED_ASCENDING, - METRICS_COUNTER_FIELDS, - STRING_LITERAL_AUTO_CASTING_EXTENDED, - METADATA_FIELDS, - TIMESPAN_ABBREVIATIONS, - COUNTER_TYPES, - RESOLVE_FIELDS_API - ); + Set features = Set.of(); if (Build.current().isSnapshot()) { return Collections.unmodifiableSet(Sets.union(features, snapshotBuildFeatures())); } else { diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/CsvTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/CsvTests.java index ee5073c05cab1..6cbf910906aaf 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/CsvTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/CsvTests.java @@ -241,7 +241,10 @@ public final void test() throws Throwable { * The csv tests support all but a few features. The unsupported features * are tested in integration tests. */ - assumeFalse("metadata fields aren't supported", testCase.requiredCapabilities.contains(cap(EsqlFeatures.METADATA_FIELDS))); + assumeFalse( + "metadata fields aren't supported", + testCase.requiredCapabilities.contains(EsqlCapabilities.Cap.METADATA_FIELDS.capabilityName()) + ); assumeFalse( "enrich can't load fields in csv tests", testCase.requiredCapabilities.contains(EsqlCapabilities.Cap.ENRICH_LOAD.capabilityName()) diff --git a/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/esql/100_bug_fix.yml b/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/esql/100_bug_fix.yml index cffc161b11539..a77a5a775442a 100644 --- a/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/esql/100_bug_fix.yml +++ b/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/esql/100_bug_fix.yml @@ -257,9 +257,6 @@ --- "mv_dedupe from index #104745": - - requires: - cluster_features: ["esql.mv_ordering_sorted_ascending"] - reason: "fixed by introducing a sorted, non-deduplicated MvOrdering" - do: indices.create: index: idx_with_multivalues diff --git a/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/esql/40_tsdb.yml b/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/esql/40_tsdb.yml index ebf464ba667db..b9415bce62ea9 100644 --- a/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/esql/40_tsdb.yml +++ b/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/esql/40_tsdb.yml @@ -1,7 +1,5 @@ setup: - requires: - cluster_features: ["esql.metrics_counter_fields"] - reason: "require metrics counter fields" test_runner_features: allowed_warnings_regex - do: indices.create: diff --git a/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/esql/80_text.yml b/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/esql/80_text.yml index 3a989d2c87bf3..bfb49bdc7e5c5 100644 --- a/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/esql/80_text.yml +++ b/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/esql/80_text.yml @@ -574,10 +574,6 @@ setup: --- "values function": - - requires: - cluster_features: esql.agg_values - reason: "values is available in 8.14+" - - do: esql.query: body: