diff --git a/benchmarks/src/main/java/org/elasticsearch/benchmark/_nightly/esql/QueryPlanningBenchmark.java b/benchmarks/src/main/java/org/elasticsearch/benchmark/_nightly/esql/QueryPlanningBenchmark.java index 5d1a8ba595f97..8c4aa2582355e 100644 --- a/benchmarks/src/main/java/org/elasticsearch/benchmark/_nightly/esql/QueryPlanningBenchmark.java +++ b/benchmarks/src/main/java/org/elasticsearch/benchmark/_nightly/esql/QueryPlanningBenchmark.java @@ -119,7 +119,7 @@ public void setup() { } private LogicalPlan plan(EsqlParser parser, Analyzer analyzer, LogicalPlanOptimizer optimizer, String query) { - var parsed = parser.createStatement(query, new QueryParams(), telemetry, config); + var parsed = parser.createStatement(query, new QueryParams(), telemetry); var analyzed = analyzer.analyze(parsed); var optimized = optimizer.optimize(analyzed); return optimized; diff --git a/docs/reference/query-languages/esql/kibana/definition/settings/time_zone.json b/docs/reference/query-languages/esql/kibana/definition/settings/time_zone.json new file mode 100644 index 0000000000000..72f463117505c --- /dev/null +++ b/docs/reference/query-languages/esql/kibana/definition/settings/time_zone.json @@ -0,0 +1,9 @@ +{ + "comment" : "This is generated by ESQL’s DocsV3Support. Do not edit it. See ../README.md for how to regenerate it.", + "name" : "time_zone", + "type" : "keyword", + "serverlessOnly" : false, + "preview" : true, + "snapshotOnly" : true, + "description" : "The default timezone to be used in the query, by the functions and commands that require it. Defaults to UTC" +} diff --git a/x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/QlIllegalArgumentException.java b/x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/QlIllegalArgumentException.java index 73c8c8b0ed80e..877661dd38ef4 100644 --- a/x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/QlIllegalArgumentException.java +++ b/x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/QlIllegalArgumentException.java @@ -6,6 +6,12 @@ */ package org.elasticsearch.xpack.esql.core; +/** + * Like {@link IllegalArgumentException}, but treated as a server error. + *

+ * Throw this in case of bugs, and the other in case of wrong user input. + *

+ */ public class QlIllegalArgumentException extends QlServerException { public QlIllegalArgumentException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { super(message, cause, enableSuppression, writableStackTrace); diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/java/org/elasticsearch/xpack/esql/EsqlTestUtils.java b/x-pack/plugin/esql/qa/testFixtures/src/main/java/org/elasticsearch/xpack/esql/EsqlTestUtils.java index 886f1b893fe80..16dff7fa6729c 100644 --- a/x-pack/plugin/esql/qa/testFixtures/src/main/java/org/elasticsearch/xpack/esql/EsqlTestUtils.java +++ b/x-pack/plugin/esql/qa/testFixtures/src/main/java/org/elasticsearch/xpack/esql/EsqlTestUtils.java @@ -13,6 +13,7 @@ import org.apache.lucene.util.BytesRef; import org.elasticsearch.ExceptionsHelper; import org.elasticsearch.client.internal.Client; +import org.elasticsearch.cluster.ClusterName; import org.elasticsearch.cluster.RemoteException; import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; import org.elasticsearch.cluster.project.ProjectResolver; @@ -103,6 +104,7 @@ import org.elasticsearch.xpack.esql.planner.PlannerSettings; import org.elasticsearch.xpack.esql.planner.PlannerUtils; import org.elasticsearch.xpack.esql.plugin.EsqlPlugin; +import org.elasticsearch.xpack.esql.plugin.EsqlQueryClusterSettings; import org.elasticsearch.xpack.esql.plugin.QueryPragmas; import org.elasticsearch.xpack.esql.plugin.TransportActionServices; import org.elasticsearch.xpack.esql.session.Configuration; @@ -445,7 +447,7 @@ public static LogicalOptimizerContext unboundLogicalOptimizerContext() { createMockTransportService(), mock(SearchService.class), null, - mock(ClusterService.class), + createMockClusterService(), mock(ProjectResolver.class), mock(IndexNameExpressionResolver.class), null, @@ -454,6 +456,12 @@ public static LogicalOptimizerContext unboundLogicalOptimizerContext() { TEST_PLANNER_SETTINGS ); + private static ClusterService createMockClusterService() { + var service = mock(ClusterService.class); + doReturn(new ClusterName("test-cluster")).when(service).getClusterName(); + return service; + } + private static TransportService createMockTransportService() { var service = mock(TransportService.class); doReturn(createMockThreadPool()).when(service).getThreadPool(); @@ -495,6 +503,15 @@ public static Configuration configuration(String query) { return configuration(new QueryPragmas(Settings.EMPTY), query); } + public static EsqlQueryClusterSettings queryClusterSettings() { + return new EsqlQueryClusterSettings( + EsqlPlugin.QUERY_RESULT_TRUNCATION_MAX_SIZE.getDefault(Settings.EMPTY), + EsqlPlugin.QUERY_RESULT_TRUNCATION_DEFAULT_SIZE.getDefault(Settings.EMPTY), + EsqlPlugin.QUERY_TIMESERIES_RESULT_TRUNCATION_MAX_SIZE.getDefault(Settings.EMPTY), + EsqlPlugin.QUERY_TIMESERIES_RESULT_TRUNCATION_DEFAULT_SIZE.getDefault(Settings.EMPTY) + ); + } + public static Literal L(Object value) { return of(value); } diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/execution/PlanExecutor.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/execution/PlanExecutor.java index 974b73718ff0b..685979672af76 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/execution/PlanExecutor.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/execution/PlanExecutor.java @@ -16,18 +16,13 @@ import org.elasticsearch.xpack.esql.analysis.PreAnalyzer; import org.elasticsearch.xpack.esql.analysis.Verifier; import org.elasticsearch.xpack.esql.common.Failures; -import org.elasticsearch.xpack.esql.core.expression.FoldContext; import org.elasticsearch.xpack.esql.enrich.EnrichPolicyResolver; import org.elasticsearch.xpack.esql.expression.function.EsqlFunctionRegistry; -import org.elasticsearch.xpack.esql.optimizer.LogicalOptimizerContext; -import org.elasticsearch.xpack.esql.optimizer.LogicalPlanOptimizer; -import org.elasticsearch.xpack.esql.optimizer.LogicalPlanPreOptimizer; -import org.elasticsearch.xpack.esql.optimizer.LogicalPreOptimizerContext; import org.elasticsearch.xpack.esql.plan.logical.LogicalPlan; import org.elasticsearch.xpack.esql.planner.mapper.Mapper; +import org.elasticsearch.xpack.esql.plugin.EsqlQueryClusterSettings; import org.elasticsearch.xpack.esql.plugin.TransportActionServices; import org.elasticsearch.xpack.esql.querylog.EsqlQueryLog; -import org.elasticsearch.xpack.esql.session.Configuration; import org.elasticsearch.xpack.esql.session.EsqlSession; import org.elasticsearch.xpack.esql.session.IndexResolver; import org.elasticsearch.xpack.esql.session.Result; @@ -72,8 +67,7 @@ public PlanExecutor( public void esql( EsqlQueryRequest request, String sessionId, - Configuration cfg, - FoldContext foldContext, + EsqlQueryClusterSettings esqlQueryClusterSettings, EnrichPolicyResolver enrichPolicyResolver, EsqlExecutionInfo executionInfo, IndicesExpressionGrouper indicesExpressionGrouper, @@ -84,13 +78,11 @@ public void esql( final PlanTelemetry planTelemetry = new PlanTelemetry(functionRegistry); final var session = new EsqlSession( sessionId, - cfg, + esqlQueryClusterSettings, indexResolver, enrichPolicyResolver, preAnalyzer, - new LogicalPlanPreOptimizer(new LogicalPreOptimizerContext(foldContext, services.inferenceService())), functionRegistry, - new LogicalPlanOptimizer(new LogicalOptimizerContext(cfg, foldContext)), mapper, verifier, planTelemetry, diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlParser.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlParser.java index 7226a0e7d4394..1c844d3c15f6c 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlParser.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlParser.java @@ -22,7 +22,6 @@ import org.elasticsearch.xpack.esql.expression.function.EsqlFunctionRegistry; import org.elasticsearch.xpack.esql.plan.EsqlStatement; import org.elasticsearch.xpack.esql.plan.logical.LogicalPlan; -import org.elasticsearch.xpack.esql.session.Configuration; import org.elasticsearch.xpack.esql.telemetry.PlanTelemetry; import java.util.BitSet; @@ -100,32 +99,32 @@ public void setEsqlConfig(EsqlConfig config) { } // testing utility - public LogicalPlan createStatement(String query, Configuration configuration) { - return createStatement(query, new QueryParams(), configuration); + public LogicalPlan createStatement(String query) { + return createStatement(query, new QueryParams()); } // testing utility - public LogicalPlan createStatement(String query, QueryParams params, Configuration configuration) { - return createStatement(query, params, new PlanTelemetry(new EsqlFunctionRegistry()), configuration); + public LogicalPlan createStatement(String query, QueryParams params) { + return createStatement(query, params, new PlanTelemetry(new EsqlFunctionRegistry())); } - public LogicalPlan createStatement(String query, QueryParams params, PlanTelemetry metrics, Configuration configuration) { + public LogicalPlan createStatement(String query, QueryParams params, PlanTelemetry metrics) { if (log.isDebugEnabled()) { log.debug("Parsing as statement: {}", query); } - return invokeParser(query, params, metrics, EsqlBaseParser::singleStatement, AstBuilder::plan, configuration); + return invokeParser(query, params, metrics, EsqlBaseParser::singleStatement, AstBuilder::plan); } // testing utility - public EsqlStatement createQuery(String query, QueryParams params, Configuration configuration) { - return createQuery(query, params, new PlanTelemetry(new EsqlFunctionRegistry()), configuration); + public EsqlStatement createQuery(String query, QueryParams params) { + return createQuery(query, params, new PlanTelemetry(new EsqlFunctionRegistry())); } - public EsqlStatement createQuery(String query, QueryParams params, PlanTelemetry metrics, Configuration configuration) { + public EsqlStatement createQuery(String query, QueryParams params, PlanTelemetry metrics) { if (log.isDebugEnabled()) { log.debug("Parsing as statement: {}", query); } - return invokeParser(query, params, metrics, EsqlBaseParser::statements, AstBuilder::statement, configuration); + return invokeParser(query, params, metrics, EsqlBaseParser::statements, AstBuilder::statement); } private T invokeParser( @@ -133,8 +132,7 @@ private T invokeParser( QueryParams params, PlanTelemetry metrics, Function parseFunction, - BiFunction result, - Configuration configuration + BiFunction result ) { if (query.length() > MAX_LENGTH) { throw new ParsingException("ESQL statement is too large [{} characters > {}]", query.length(), MAX_LENGTH); diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/QuerySettings.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/QuerySettings.java index eca9bbcd22fd6..1945e41ff59de 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/QuerySettings.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/QuerySettings.java @@ -7,17 +7,25 @@ package org.elasticsearch.xpack.esql.plan; +import org.elasticsearch.core.Nullable; import org.elasticsearch.transport.RemoteClusterService; +import org.elasticsearch.xpack.esql.core.expression.Expression; import org.elasticsearch.xpack.esql.core.type.DataType; +import org.elasticsearch.xpack.esql.expression.Foldables; import org.elasticsearch.xpack.esql.parser.ParsingException; -import java.util.function.Predicate; +import java.time.ZoneId; +import java.time.ZoneOffset; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.stream.Stream; -public enum QuerySettings { +public class QuerySettings { // TODO check cluster state and see if project routing is allowed // see https://github.com/elastic/elasticsearch/pull/134446 // PROJECT_ROUTING(..., state -> state.getRemoteClusterNames().crossProjectEnabled()); - PROJECT_ROUTING( + public static final QuerySettingDef PROJECT_ROUTING = new QuerySettingDef<>( "project_routing", DataType.KEYWORD, true, @@ -25,85 +33,118 @@ public enum QuerySettings { true, "A project routing expression, " + "used to define which projects to route the query to. " - + "Only supported if Cross-Project Search is enabled." - ),; + + "Only supported if Cross-Project Search is enabled.", + (value, settings) -> Foldables.stringLiteralValueOf(value, "Unexpected value"), + (_rcs) -> null + ); - private String settingName; - private DataType type; - private final boolean serverlessOnly; - private final boolean snapshotOnly; - private final boolean preview; - private final String description; - private final Predicate validator; + public static final QuerySettingDef TIME_ZONE = new QuerySettingDef<>( + "time_zone", + DataType.KEYWORD, + false, + true, + true, + "The default timezone to be used in the query, by the functions and commands that require it. Defaults to UTC", + (value, _rcs) -> { + String timeZone = Foldables.stringLiteralValueOf(value, "Unexpected value"); + try { + return ZoneId.of(timeZone); + } catch (Exception exc) { + throw new IllegalArgumentException("Invalid time zone [" + timeZone + "]"); + } + }, + (_rcs) -> ZoneOffset.UTC + ); + + public static final Map> SETTINGS_BY_NAME = Stream.of(PROJECT_ROUTING, TIME_ZONE) + .collect(Collectors.toMap(QuerySettingDef::name, Function.identity()));; + + public static void validate(EsqlStatement statement, RemoteClusterService clusterService) { + for (QuerySetting setting : statement.settings()) { + QuerySettingDef def = SETTINGS_BY_NAME.get(setting.name()); + if (def == null) { + throw new ParsingException(setting.source(), "Unknown setting [" + setting.name() + "]"); + } - QuerySettings( + if (setting.value().dataType() != def.type()) { + throw new ParsingException(setting.source(), "Setting [" + setting.name() + "] must be of type " + def.type()); + } + + String error = def.validator().validate(setting.value(), clusterService); + if (error != null) { + throw new ParsingException("Error validating setting [" + setting.name() + "]: " + error); + } + } + } + + /** + * Definition of a query setting. + * + * @param name The name to be used when setting it in the query. E.g. {@code SET name=value} + * @param type The allowed datatype of the setting. + * @param serverlessOnly + * @param preview + * @param snapshotOnly + * @param description The user-facing description of the setting. + * @param validator A validation function to check the setting value. + * Defaults to calling the {@link #parser} and returning the error message of any exception it throws. + * @param parser A function to parse the setting value into the final object. + * @param defaultValueSupplier A supplier of the default value to be used when the setting is not set. + * @param The type of the setting value. + */ + public record QuerySettingDef( String name, DataType type, boolean serverlessOnly, boolean preview, boolean snapshotOnly, String description, - Predicate validator + Validator validator, + Parser parser, + Function defaultValueSupplier ) { - this.settingName = name; - this.type = type; - this.serverlessOnly = serverlessOnly; - this.preview = preview; - this.snapshotOnly = snapshotOnly; - this.description = description; - this.validator = validator; - } - - QuerySettings(String name, DataType type, boolean serverlessOnly, boolean preview, boolean snapshotOnly, String description) { - this(name, type, serverlessOnly, preview, snapshotOnly, description, state -> true); - } - - public String settingName() { - return settingName; - } - - public DataType type() { - return type; - } - - public boolean serverlessOnly() { - return serverlessOnly; - } - - public boolean snapshotOnly() { - return snapshotOnly; - } - - public boolean preview() { - return preview; - } + public QuerySettingDef( + String name, + DataType type, + boolean serverlessOnly, + boolean preview, + boolean snapshotOnly, + String description, + Parser parser, + Function defaultValueSupplier + ) { + this(name, type, serverlessOnly, preview, snapshotOnly, description, (value, rcs) -> { + try { + parser.parse(value, rcs); + return null; + } catch (Exception exc) { + return exc.getMessage(); + } + }, parser, defaultValueSupplier); + } - public String description() { - return description; - } + public T get(Expression value, RemoteClusterService clusterService) { + if (value == null) { + return defaultValueSupplier.apply(clusterService); + } + return parser.parse(value, clusterService); + } - public Predicate validator() { - return validator; - } + @FunctionalInterface + public interface Validator { + /** + * Validates the setting value and returns the error message if there's an error, or null otherwise. + */ + @Nullable + String validate(Expression value, RemoteClusterService clusterService); + } - public static void validate(EsqlStatement statement, RemoteClusterService clusterService) { - for (QuerySetting setting : statement.settings()) { - boolean found = false; - for (QuerySettings qs : values()) { - if (qs.settingName().equals(setting.name())) { - found = true; - if (setting.value().dataType() != qs.type()) { - throw new ParsingException(setting.source(), "Setting [" + setting.name() + "] must be of type " + qs.type()); - } - if (qs.validator().test(clusterService) == false) { - throw new ParsingException(setting.source(), "Setting [" + setting.name() + "] is not allowed"); - } - break; - } - } - if (found == false) { - throw new ParsingException(setting.source(), "Unknown setting [" + setting.name() + "]"); - } + @FunctionalInterface + public interface Parser { + /** + * Parses an already validated expression. + */ + T parse(Expression value, RemoteClusterService clusterService); } } } diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plugin/EsqlQueryClusterSettings.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plugin/EsqlQueryClusterSettings.java new file mode 100644 index 0000000000000..1c0a300ca620d --- /dev/null +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plugin/EsqlQueryClusterSettings.java @@ -0,0 +1,15 @@ +/* + * 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.plugin; + +public record EsqlQueryClusterSettings( + int resultTruncationMaxSize, + int resultTruncationDefaultSize, + int timeseriesResultTruncationMaxSize, + int timeseriesResultTruncationDefaultSize +) {} diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plugin/TransportEsqlQueryAction.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plugin/TransportEsqlQueryAction.java index db702cdc325db..03b86ac1b1ccd 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plugin/TransportEsqlQueryAction.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plugin/TransportEsqlQueryAction.java @@ -44,7 +44,6 @@ import org.elasticsearch.xpack.esql.action.EsqlQueryResponse; import org.elasticsearch.xpack.esql.action.EsqlQueryTask; import org.elasticsearch.xpack.esql.core.async.AsyncTaskManagementService; -import org.elasticsearch.xpack.esql.core.expression.FoldContext; import org.elasticsearch.xpack.esql.enrich.AbstractLookupService; import org.elasticsearch.xpack.esql.enrich.EnrichLookupService; import org.elasticsearch.xpack.esql.enrich.EnrichPolicyResolver; @@ -53,16 +52,13 @@ import org.elasticsearch.xpack.esql.expression.function.UnsupportedAttribute; import org.elasticsearch.xpack.esql.inference.InferenceService; import org.elasticsearch.xpack.esql.planner.PlannerSettings; -import org.elasticsearch.xpack.esql.session.Configuration; import org.elasticsearch.xpack.esql.session.EsqlSession.PlanRunner; import org.elasticsearch.xpack.esql.session.Result; import java.io.IOException; -import java.time.ZoneOffset; import java.util.ArrayList; import java.util.Collections; import java.util.List; -import java.util.Locale; import java.util.Map; import java.util.concurrent.Executor; import java.util.concurrent.atomic.AtomicInteger; @@ -240,29 +236,11 @@ private void innerExecute(Task task, EsqlQueryRequest request, ActionListener computeService.execute( + PlanRunner planRunner = (plan, configuration, foldCtx, resultListener) -> computeService.execute( sessionId, (CancellableTask) task, flags, @@ -275,8 +253,12 @@ private void innerExecute(Task task, EsqlQueryRequest request, ActionListener { recordCCSTelemetry(task, executionInfo, request, null); planExecutor.metrics().recordTook(executionInfo.overallTook().millis()); - var response = toResponse(task, request, configuration, result); + var response = toResponse(task, request, request.profile(), result); assert response.isAsync() == request.async() : "The response must be async if the request was async"; if (response.isAsync()) { @@ -385,7 +367,7 @@ private EsqlExecutionInfo createEsqlExecutionInfo(EsqlQueryRequest request) { ); } - private EsqlQueryResponse toResponse(Task task, EsqlQueryRequest request, Configuration configuration, Result result) { + private EsqlQueryResponse toResponse(Task task, EsqlQueryRequest request, boolean profileEnabled, Result result) { List columns = result.schema().stream().map(c -> { List originalTypes; if (c instanceof UnsupportedAttribute ua) { @@ -397,7 +379,7 @@ private EsqlQueryResponse toResponse(Task task, EsqlQueryRequest request, Config } return new ColumnInfoImpl(c.name(), c.dataType().outputType(), originalTypes); }).toList(); - EsqlQueryResponse.Profile profile = configuration.profile() + EsqlQueryResponse.Profile profile = profileEnabled ? new EsqlQueryResponse.Profile(result.completionInfo().driverProfiles(), result.completionInfo().planProfiles()) : null; if (task instanceof EsqlQueryTask asyncTask && request.keepOnCompletion()) { diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/session/EsqlSession.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/session/EsqlSession.java index ded34107f5aec..b26d33c67af55 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/session/EsqlSession.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/session/EsqlSession.java @@ -45,6 +45,7 @@ import org.elasticsearch.xpack.esql.analysis.PreAnalyzer; import org.elasticsearch.xpack.esql.analysis.Verifier; import org.elasticsearch.xpack.esql.core.expression.Attribute; +import org.elasticsearch.xpack.esql.core.expression.FoldContext; import org.elasticsearch.xpack.esql.core.expression.ReferenceAttribute; import org.elasticsearch.xpack.esql.core.tree.NodeUtils; import org.elasticsearch.xpack.esql.core.tree.Source; @@ -55,8 +56,10 @@ import org.elasticsearch.xpack.esql.index.IndexResolution; import org.elasticsearch.xpack.esql.inference.InferenceResolution; import org.elasticsearch.xpack.esql.inference.InferenceService; +import org.elasticsearch.xpack.esql.optimizer.LogicalOptimizerContext; import org.elasticsearch.xpack.esql.optimizer.LogicalPlanOptimizer; import org.elasticsearch.xpack.esql.optimizer.LogicalPlanPreOptimizer; +import org.elasticsearch.xpack.esql.optimizer.LogicalPreOptimizerContext; import org.elasticsearch.xpack.esql.optimizer.PhysicalOptimizerContext; import org.elasticsearch.xpack.esql.optimizer.PhysicalPlanOptimizer; import org.elasticsearch.xpack.esql.parser.EsqlParser; @@ -77,15 +80,18 @@ import org.elasticsearch.xpack.esql.planner.PlannerUtils; import org.elasticsearch.xpack.esql.planner.mapper.Mapper; import org.elasticsearch.xpack.esql.planner.premapper.PreMapper; +import org.elasticsearch.xpack.esql.plugin.EsqlQueryClusterSettings; import org.elasticsearch.xpack.esql.plugin.TransportActionServices; import org.elasticsearch.xpack.esql.telemetry.PlanTelemetry; +import java.time.ZoneOffset; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Set; import java.util.concurrent.atomic.AtomicReference; @@ -106,31 +112,29 @@ public class EsqlSession { * Abstracts away the underlying execution engine. */ public interface PlanRunner { - void run(PhysicalPlan plan, ActionListener listener); + void run(PhysicalPlan plan, Configuration configuration, FoldContext foldContext, ActionListener listener); } private static final TransportVersion LOOKUP_JOIN_CCS = TransportVersion.fromName("lookup_join_ccs"); private final String sessionId; - private final Configuration configuration; + private final EsqlQueryClusterSettings clusterSettings; private final IndexResolver indexResolver; private final EnrichPolicyResolver enrichPolicyResolver; private final PreAnalyzer preAnalyzer; private final Verifier verifier; private final EsqlFunctionRegistry functionRegistry; - private final LogicalPlanPreOptimizer logicalPlanPreOptimizer; - private final LogicalPlanOptimizer logicalPlanOptimizer; private final PreMapper preMapper; private final Mapper mapper; - private final PhysicalPlanOptimizer physicalPlanOptimizer; private final PlanTelemetry planTelemetry; private final IndicesExpressionGrouper indicesExpressionGrouper; private final InferenceService inferenceService; private final RemoteClusterService remoteClusterService; private final BlockFactory blockFactory; private final ByteSizeValue intermediateLocalRelationMaxSize; + private final String clusterName; private boolean explainMode; private String parsedPlanString; @@ -138,13 +142,11 @@ public interface PlanRunner { public EsqlSession( String sessionId, - Configuration configuration, + EsqlQueryClusterSettings clusterSettings, IndexResolver indexResolver, EnrichPolicyResolver enrichPolicyResolver, PreAnalyzer preAnalyzer, - LogicalPlanPreOptimizer logicalPlanPreOptimizer, EsqlFunctionRegistry functionRegistry, - LogicalPlanOptimizer logicalPlanOptimizer, Mapper mapper, Verifier verifier, PlanTelemetry planTelemetry, @@ -152,16 +154,13 @@ public EsqlSession( TransportActionServices services ) { this.sessionId = sessionId; - this.configuration = configuration; + this.clusterSettings = clusterSettings; this.indexResolver = indexResolver; this.enrichPolicyResolver = enrichPolicyResolver; this.preAnalyzer = preAnalyzer; - this.logicalPlanPreOptimizer = logicalPlanPreOptimizer; this.verifier = verifier; this.functionRegistry = functionRegistry; this.mapper = mapper; - this.logicalPlanOptimizer = logicalPlanOptimizer; - this.physicalPlanOptimizer = new PhysicalPlanOptimizer(new PhysicalOptimizerContext(configuration)); this.planTelemetry = planTelemetry; this.indicesExpressionGrouper = indicesExpressionGrouper; this.inferenceService = services.inferenceService(); @@ -169,6 +168,7 @@ public EsqlSession( this.remoteClusterService = services.transportService().getRemoteClusterService(); this.blockFactory = services.blockFactoryProvider().blockFactory(); this.intermediateLocalRelationMaxSize = services.plannerSettings().intermediateLocalRelationMaxSize(); + this.clusterName = services.clusterService().getClusterName().value(); } public String sessionId() { @@ -183,26 +183,65 @@ public void execute(EsqlQueryRequest request, EsqlExecutionInfo executionInfo, P assert executionInfo != null : "Null EsqlExecutionInfo"; LOGGER.debug("ESQL query:\n{}", request.query()); EsqlStatement statement = parse(request.query(), request.params()); + Configuration configuration = new Configuration( + ZoneOffset.UTC, // TODO: Use the time_zone setting instead? + request.locale() != null ? request.locale() : Locale.US, + // TODO: plug-in security + null, + clusterName, + request.pragmas(), + clusterSettings.resultTruncationMaxSize(), + clusterSettings.resultTruncationDefaultSize(), + request.query(), + request.profile(), + request.tables(), + System.nanoTime(), + request.allowPartialResults(), + clusterSettings.timeseriesResultTruncationMaxSize(), + clusterSettings.timeseriesResultTruncationDefaultSize() + ); + FoldContext foldContext = configuration.newFoldContext(); + var logicalPlanPreOptimizer = new LogicalPlanPreOptimizer(new LogicalPreOptimizerContext(foldContext, inferenceService)); + var logicalPlanOptimizer = new LogicalPlanOptimizer(new LogicalOptimizerContext(configuration, foldContext)); + var physicalPlanOptimizer = new PhysicalPlanOptimizer(new PhysicalOptimizerContext(configuration)); + LogicalPlan plan = statement.plan(); if (plan instanceof Explain explain) { explainMode = true; plan = explain.query(); parsedPlanString = plan.toString(); } - analyzedPlan(plan, executionInfo, request.filter(), new EsqlCCSUtils.CssPartialErrorsActionListener(executionInfo, listener) { - @Override - public void onResponse(LogicalPlan analyzedPlan) { - assert ThreadPool.assertCurrentThreadPool( - ThreadPool.Names.SEARCH, - ThreadPool.Names.SEARCH_COORDINATION, - ThreadPool.Names.SYSTEM_READ - ); - SubscribableListener.newForked(l -> preOptimizedPlan(analyzedPlan, l)) - .andThen((l, p) -> preMapper.preMapper(optimizedPlan(p), l)) - .andThen((l, p) -> executeOptimizedPlan(request, executionInfo, planRunner, p, l)) - .addListener(listener); + analyzedPlan( + plan, + configuration, + executionInfo, + request.filter(), + new EsqlCCSUtils.CssPartialErrorsActionListener(executionInfo, listener) { + @Override + public void onResponse(LogicalPlan analyzedPlan) { + assert ThreadPool.assertCurrentThreadPool( + ThreadPool.Names.SEARCH, + ThreadPool.Names.SEARCH_COORDINATION, + ThreadPool.Names.SYSTEM_READ + ); + SubscribableListener.newForked(l -> preOptimizedPlan(analyzedPlan, logicalPlanPreOptimizer, l)) + .andThen((l, p) -> preMapper.preMapper(optimizedPlan(p, logicalPlanOptimizer), l)) + .andThen( + (l, p) -> executeOptimizedPlan( + request, + executionInfo, + planRunner, + p, + configuration, + foldContext, + physicalPlanOptimizer, + l + ) + ) + .addListener(listener); + } } - }); + ); } /** @@ -214,6 +253,9 @@ public void executeOptimizedPlan( EsqlExecutionInfo executionInfo, PlanRunner planRunner, LogicalPlan optimizedPlan, + Configuration configuration, + FoldContext foldContext, + PhysicalPlanOptimizer physicalPlanOptimizer, ActionListener listener ) { assert ThreadPool.assertCurrentThreadPool( @@ -222,7 +264,7 @@ public void executeOptimizedPlan( ThreadPool.Names.SYSTEM_READ ); if (explainMode) {// TODO: INLINE STATS come back to the explain mode branch and reevaluate - PhysicalPlan physicalPlan = logicalPlanToPhysicalPlan(optimizedPlan, request); + PhysicalPlan physicalPlan = logicalPlanToPhysicalPlan(optimizedPlan, request, physicalPlanOptimizer); String physicalPlanString = physicalPlan.toString(); List fields = List.of( new ReferenceAttribute(EMPTY, null, "role", DataType.KEYWORD), @@ -235,20 +277,23 @@ public void executeOptimizedPlan( values.add(List.of("coordinator", "optimizedPhysicalPlan", physicalPlanString)); var blocks = BlockUtils.fromList(PlannerUtils.NON_BREAKING_BLOCK_FACTORY, values); physicalPlan = new LocalSourceExec(Source.EMPTY, fields, LocalSupplier.of(new Page(blocks))); - planRunner.run(physicalPlan, listener); + planRunner.run(physicalPlan, configuration, foldContext, listener); } else { // TODO: this could be snuck into the underlying listener EsqlCCSUtils.updateExecutionInfoAtEndOfPlanning(executionInfo); // execute any potential subplans - executeSubPlans(optimizedPlan, planRunner, executionInfo, request, listener); + executeSubPlans(optimizedPlan, configuration, foldContext, planRunner, executionInfo, request, physicalPlanOptimizer, listener); } } private void executeSubPlans( LogicalPlan optimizedPlan, + Configuration configuration, + FoldContext foldContext, PlanRunner runner, EsqlExecutionInfo executionInfo, EsqlQueryRequest request, + PhysicalPlanOptimizer physicalPlanOptimizer, ActionListener listener ) { var subPlansResults = new HashSet(); @@ -261,17 +306,20 @@ private void executeSubPlans( new DriverCompletionInfo.Accumulator(), optimizedPlan, subPlan, + configuration, + foldContext, executionInfo, runner, request, subPlansResults, + physicalPlanOptimizer, // Ensure we don't have subplan flag stuck in there on failure ActionListener.runAfter(listener, executionInfo::finishSubPlans) ); } else { - PhysicalPlan physicalPlan = logicalPlanToPhysicalPlan(optimizedPlan, request); + PhysicalPlan physicalPlan = logicalPlanToPhysicalPlan(optimizedPlan, request, physicalPlanOptimizer); // execute main plan - runner.run(physicalPlan, listener); + runner.run(physicalPlan, configuration, foldContext, listener); } } @@ -279,19 +327,22 @@ private void executeSubPlan( DriverCompletionInfo.Accumulator completionInfoAccumulator, LogicalPlan optimizedPlan, InlineJoin.LogicalPlanTuple subPlans, + Configuration configuration, + FoldContext foldContext, EsqlExecutionInfo executionInfo, PlanRunner runner, EsqlQueryRequest request, Set subPlansResults, + PhysicalPlanOptimizer physicalPlanOptimizer, ActionListener listener ) { LOGGER.debug("Executing subplan:\n{}", subPlans.stubReplacedSubPlan()); // Create a physical plan out of the logical sub-plan - var physicalSubPlan = logicalPlanToPhysicalPlan(subPlans.stubReplacedSubPlan(), request); + var physicalSubPlan = logicalPlanToPhysicalPlan(subPlans.stubReplacedSubPlan(), request, physicalPlanOptimizer); executionInfo.startSubPlans(); - runner.run(physicalSubPlan, listener.delegateFailureAndWrap((next, result) -> { + runner.run(physicalSubPlan, configuration, foldContext, listener.delegateFailureAndWrap((next, result) -> { AtomicReference localRelationPage = new AtomicReference<>(); try { // Translate the subquery into a separate, coordinator based plan and the results 'broadcasted' as a local relation @@ -318,22 +369,30 @@ private void executeSubPlan( if (newSubPlan == null) {// run the final "main" plan executionInfo.finishSubPlans(); LOGGER.debug("Executing final plan:\n{}", newLogicalPlan); - var newPhysicalPlan = logicalPlanToPhysicalPlan(newLogicalPlan, request); - runner.run(newPhysicalPlan, releasingNext.delegateFailureAndWrap((finalListener, finalResult) -> { - completionInfoAccumulator.accumulate(finalResult.completionInfo()); - finalListener.onResponse( - new Result(finalResult.schema(), finalResult.pages(), completionInfoAccumulator.finish(), executionInfo) - ); - })); + var newPhysicalPlan = logicalPlanToPhysicalPlan(newLogicalPlan, request, physicalPlanOptimizer); + runner.run( + newPhysicalPlan, + configuration, + foldContext, + releasingNext.delegateFailureAndWrap((finalListener, finalResult) -> { + completionInfoAccumulator.accumulate(finalResult.completionInfo()); + finalListener.onResponse( + new Result(finalResult.schema(), finalResult.pages(), completionInfoAccumulator.finish(), executionInfo) + ); + }) + ); } else {// continue executing the subplans executeSubPlan( completionInfoAccumulator, newLogicalPlan, newSubPlan, + configuration, + foldContext, executionInfo, runner, request, subPlansResults, + physicalPlanOptimizer, releasingNext ); } @@ -369,7 +428,7 @@ private static void releaseLocalRelationBlocks(AtomicReference localRelati } private EsqlStatement parse(String query, QueryParams params) { - var parsed = new EsqlParser().createQuery(query, params, planTelemetry, configuration); + var parsed = new EsqlParser().createQuery(query, params, planTelemetry); if (LOGGER.isDebugEnabled()) { LOGGER.debug("Parsed logical plan:\n{}", parsed.plan()); LOGGER.debug("Parsed settings:\n[{}]", parsed.settings().stream().map(QuerySetting::toString).collect(joining("; "))); @@ -427,6 +486,7 @@ static void handleFieldCapsFailures( public void analyzedPlan( LogicalPlan parsed, + Configuration configuration, EsqlExecutionInfo executionInfo, QueryBuilder requestFilter, ActionListener logicalPlanListener @@ -441,11 +501,12 @@ public void analyzedPlan( var result = FieldNameUtils.resolveFieldNames(parsed, preAnalysis.enriches().isEmpty() == false); var description = requestFilter == null ? "the only attempt without filter" : "first attempt with filter"; - resolveIndices(parsed, executionInfo, description, requestFilter, preAnalysis, result, logicalPlanListener); + resolveIndices(parsed, configuration, executionInfo, description, requestFilter, preAnalysis, result, logicalPlanListener); } private void resolveIndices( LogicalPlan parsed, + Configuration configuration, EsqlExecutionInfo executionInfo, String description, QueryBuilder requestFilter, @@ -472,7 +533,9 @@ private void resolveIndices( .andThen((l, r) -> { inferenceService.inferenceResolver(functionRegistry).resolveInferenceIds(parsed, l.map(r::withInferenceResolution)); }) - .andThen((l, r) -> analyzeWithRetry(parsed, executionInfo, description, requestFilter, preAnalysis, r, l)) + .andThen( + (l, r) -> analyzeWithRetry(parsed, configuration, executionInfo, description, requestFilter, preAnalysis, r, l) + ) .addListener(logicalPlanListener); } @@ -744,6 +807,7 @@ private void preAnalyzeMainIndices( private void analyzeWithRetry( LogicalPlan parsed, + Configuration configuration, EsqlExecutionInfo executionInfo, String description, QueryBuilder requestFilter, @@ -758,7 +822,7 @@ private void analyzeWithRetry( // when the resolution result is not valid for a different reason. EsqlCCSUtils.updateExecutionInfoWithClustersWithNoMatchingIndices(executionInfo, result.indices, requestFilter != null); } - LogicalPlan plan = analyzedPlan(parsed, result, executionInfo); + LogicalPlan plan = analyzedPlan(parsed, configuration, result, executionInfo); LOGGER.debug("Analyzed plan ({}):\n{}", description, plan); // the analysis succeeded from the first attempt, irrespective if it had a filter or not, just continue with the planning listener.onResponse(plan); @@ -770,15 +834,19 @@ private void analyzeWithRetry( } else { // retrying the index resolution without index filtering. executionInfo.clusterInfo.clear(); - resolveIndices(parsed, executionInfo, "second attempt, without filter", null, preAnalysis, result, listener); + resolveIndices(parsed, configuration, executionInfo, "second attempt, without filter", null, preAnalysis, result, listener); } } catch (Exception e) { listener.onFailure(e); } } - private PhysicalPlan logicalPlanToPhysicalPlan(LogicalPlan optimizedPlan, EsqlQueryRequest request) { - PhysicalPlan physicalPlan = optimizedPhysicalPlan(optimizedPlan); + private PhysicalPlan logicalPlanToPhysicalPlan( + LogicalPlan optimizedPlan, + EsqlQueryRequest request, + PhysicalPlanOptimizer physicalPlanOptimizer + ) { + PhysicalPlan physicalPlan = optimizedPhysicalPlan(optimizedPlan, physicalPlanOptimizer); physicalPlan = physicalPlan.transformUp(FragmentExec.class, f -> { QueryBuilder filter = request.filter(); if (filter != null) { @@ -795,7 +863,8 @@ private PhysicalPlan logicalPlanToPhysicalPlan(LogicalPlan optimizedPlan, EsqlQu return EstimatesRowSize.estimateRowSize(0, physicalPlan); } - private LogicalPlan analyzedPlan(LogicalPlan parsed, PreAnalysisResult r, EsqlExecutionInfo executionInfo) throws Exception { + private LogicalPlan analyzedPlan(LogicalPlan parsed, Configuration configuration, PreAnalysisResult r, EsqlExecutionInfo executionInfo) + throws Exception { handleFieldCapsFailures(configuration.allowPartialResults(), executionInfo, r.indices.failures()); Analyzer analyzer = new Analyzer( new AnalyzerContext(configuration, functionRegistry, r.indices, r.lookupIndices, r.enrichResolution, r.inferenceResolution), @@ -806,7 +875,7 @@ private LogicalPlan analyzedPlan(LogicalPlan parsed, PreAnalysisResult r, EsqlEx return plan; } - public LogicalPlan optimizedPlan(LogicalPlan logicalPlan) { + public LogicalPlan optimizedPlan(LogicalPlan logicalPlan, LogicalPlanOptimizer logicalPlanOptimizer) { if (logicalPlan.preOptimized() == false) { throw new IllegalStateException("Expected pre-optimized plan"); } @@ -815,11 +884,15 @@ public LogicalPlan optimizedPlan(LogicalPlan logicalPlan) { return plan; } - public void preOptimizedPlan(LogicalPlan logicalPlan, ActionListener listener) { + public void preOptimizedPlan( + LogicalPlan logicalPlan, + LogicalPlanPreOptimizer logicalPlanPreOptimizer, + ActionListener listener + ) { logicalPlanPreOptimizer.preOptimize(logicalPlan, listener); } - public PhysicalPlan physicalPlan(LogicalPlan optimizedPlan) { + private PhysicalPlan physicalPlan(LogicalPlan optimizedPlan) { if (optimizedPlan.optimized() == false) { throw new IllegalStateException("Expected optimized plan"); } @@ -829,7 +902,7 @@ public PhysicalPlan physicalPlan(LogicalPlan optimizedPlan) { return plan; } - public PhysicalPlan optimizedPhysicalPlan(LogicalPlan optimizedPlan) { + private PhysicalPlan optimizedPhysicalPlan(LogicalPlan optimizedPlan, PhysicalPlanOptimizer physicalPlanOptimizer) { var plan = physicalPlanOptimizer.optimize(physicalPlan(optimizedPlan)); LOGGER.debug("Optimized physical plan:\n{}", plan); return plan; 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 1c822a11a811f..2a89d84e01fcb 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 @@ -75,6 +75,8 @@ import org.elasticsearch.xpack.esql.optimizer.LogicalPlanOptimizer; import org.elasticsearch.xpack.esql.optimizer.LogicalPlanPreOptimizer; import org.elasticsearch.xpack.esql.optimizer.LogicalPreOptimizerContext; +import org.elasticsearch.xpack.esql.optimizer.PhysicalOptimizerContext; +import org.elasticsearch.xpack.esql.optimizer.PhysicalPlanOptimizer; import org.elasticsearch.xpack.esql.optimizer.TestLocalPhysicalPlanOptimizer; import org.elasticsearch.xpack.esql.parser.EsqlParser; import org.elasticsearch.xpack.esql.plan.logical.Enrich; @@ -126,6 +128,7 @@ import static org.elasticsearch.xpack.esql.EsqlTestUtils.classpathResources; import static org.elasticsearch.xpack.esql.EsqlTestUtils.emptyInferenceResolution; import static org.elasticsearch.xpack.esql.EsqlTestUtils.loadMapping; +import static org.elasticsearch.xpack.esql.EsqlTestUtils.queryClusterSettings; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.everyItem; import static org.hamcrest.Matchers.greaterThan; @@ -578,20 +581,18 @@ private static TestPhysicalOperationProviders testOperationProviders( } private ActualResults executePlan(BigArrays bigArrays) throws Exception { - LogicalPlan parsed = parser.createStatement(testCase.query, EsqlTestUtils.TEST_CFG); + LogicalPlan parsed = parser.createStatement(testCase.query); var testDatasets = testDatasets(parsed); LogicalPlan analyzed = analyzedPlan(parsed, testDatasets); FoldContext foldCtx = FoldContext.small(); EsqlSession session = new EsqlSession( getTestName(), - configuration, + queryClusterSettings(), null, null, null, - new LogicalPlanPreOptimizer(new LogicalPreOptimizerContext(foldCtx, mock(InferenceService.class))), functionRegistry, - new LogicalPlanOptimizer(new LogicalOptimizerContext(configuration, foldCtx)), mapper, TEST_VERIFIER, new PlanTelemetry(functionRegistry), @@ -601,13 +602,18 @@ private ActualResults executePlan(BigArrays bigArrays) throws Exception { TestPhysicalOperationProviders physicalOperationProviders = testOperationProviders(foldCtx, testDatasets); PlainActionFuture listener = new PlainActionFuture<>(); - - session.preOptimizedPlan(analyzed, listener.delegateFailureAndWrap((l, preOptimized) -> { + var logicalPlanPreOptimizer = new LogicalPlanPreOptimizer(new LogicalPreOptimizerContext(foldCtx, mock(InferenceService.class))); + var logicalPlanOptimizer = new LogicalPlanOptimizer(new LogicalOptimizerContext(configuration, foldCtx)); + var physicalPlanOptimizer = new PhysicalPlanOptimizer(new PhysicalOptimizerContext(configuration)); + session.preOptimizedPlan(analyzed, logicalPlanPreOptimizer, listener.delegateFailureAndWrap((l, preOptimized) -> { session.executeOptimizedPlan( new EsqlQueryRequest(), new EsqlExecutionInfo(randomBoolean()), - planRunner(bigArrays, foldCtx, physicalOperationProviders), - session.optimizedPlan(preOptimized), + planRunner(bigArrays, physicalOperationProviders), + session.optimizedPlan(preOptimized, logicalPlanOptimizer), + configuration, + foldCtx, + physicalPlanOptimizer, listener.delegateFailureAndWrap( // Wrap so we can capture the warnings in the calling thread (next, result) -> next.onResponse( @@ -667,8 +673,14 @@ private void assertWarnings(List warnings) { testCase.assertWarnings(false).assertWarnings(normalized); } - PlanRunner planRunner(BigArrays bigArrays, FoldContext foldCtx, TestPhysicalOperationProviders physicalOperationProviders) { - return (physicalPlan, listener) -> executeSubPlan(bigArrays, foldCtx, physicalOperationProviders, physicalPlan, listener); + PlanRunner planRunner(BigArrays bigArrays, TestPhysicalOperationProviders physicalOperationProviders) { + return (physicalPlan, configuration, foldContext, listener) -> executeSubPlan( + bigArrays, + foldContext, + physicalOperationProviders, + physicalPlan, + listener + ); } void executeSubPlan( diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/AnalyzerTestUtils.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/AnalyzerTestUtils.java index 6f6c76efaf08e..5dcf4ead1d9ba 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/AnalyzerTestUtils.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/AnalyzerTestUtils.java @@ -130,7 +130,7 @@ public static LogicalPlan analyze(String query, String index, String mapping) { } public static LogicalPlan analyze(String query, Analyzer analyzer) { - var plan = new EsqlParser().createStatement(query, configuration(query)); + var plan = new EsqlParser().createStatement(query); // System.out.println(plan); var analyzed = analyzer.analyze(plan); // System.out.println(analyzed); @@ -138,7 +138,7 @@ public static LogicalPlan analyze(String query, Analyzer analyzer) { } public static LogicalPlan analyze(String query, String mapping, QueryParams params) { - var plan = new EsqlParser().createStatement(query, params, configuration(query)); + var plan = new EsqlParser().createStatement(query, params); var analyzer = analyzer(loadMapping(mapping, "test"), TEST_VERIFIER, configuration(query)); return analyzer.analyze(plan); } diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/ParsingTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/ParsingTests.java index 75b762a908c0d..899d3d0647efa 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/ParsingTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/ParsingTests.java @@ -110,7 +110,7 @@ public void testInlineCast() throws IOException { if (EsqlDataTypeConverter.converterFunctionFactory(expectedType) == null) { continue; } - LogicalPlan plan = parser.createStatement("ROW a = 1::" + nameOrAlias, TEST_CFG); + LogicalPlan plan = parser.createStatement("ROW a = 1::" + nameOrAlias); Row row = as(plan, Row.class); assertThat(row.fields(), hasSize(1)); Function functionCall = (Function) row.fields().get(0).child(); @@ -360,7 +360,7 @@ private String error(String query, QueryParams params) { } private EsqlStatement parse(String query, QueryParams params) { - return parser.createQuery(query, params, TEST_CFG); + return parser.createQuery(query, params); } private String error(String query) { diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/VerifierTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/VerifierTests.java index 389fadfed1693..2a139d820ed3a 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/VerifierTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/VerifierTests.java @@ -39,7 +39,6 @@ import java.util.Map; import java.util.Set; -import static org.elasticsearch.xpack.esql.EsqlTestUtils.TEST_CFG; import static org.elasticsearch.xpack.esql.EsqlTestUtils.paramAsConstant; import static org.elasticsearch.xpack.esql.EsqlTestUtils.withDefaultLimitWarning; import static org.elasticsearch.xpack.esql.analysis.AnalyzerTestUtils.TEXT_EMBEDDING_INFERENCE_ID; @@ -2777,7 +2776,7 @@ private void query(String query) { } private void query(String query, Analyzer analyzer) { - analyzer.analyze(parser.createStatement(query, TEST_CFG)); + analyzer.analyze(parser.createStatement(query)); } private String error(String query) { @@ -2808,7 +2807,7 @@ private String error(String query, Analyzer analyzer, Class Throwable e = expectThrows( exception, "Expected error for query [" + query + "] but no error was raised", - () -> analyzer.analyze(parser.createStatement(query, new QueryParams(parameters), TEST_CFG)) + () -> analyzer.analyze(parser.createStatement(query, new QueryParams(parameters))) ); assertThat(e, instanceOf(exception)); diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/CheckLicenseTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/CheckLicenseTests.java index 039b34252c12e..68a6f38cdd69a 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/CheckLicenseTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/CheckLicenseTests.java @@ -79,7 +79,7 @@ public EsqlFunctionRegistry snapshotRegistry() { } }; - var plan = parser.createStatement(esql, EsqlTestUtils.TEST_CFG); + var plan = parser.createStatement(esql); plan = plan.transformDown( Limit.class, l -> Objects.equals(l.limit().fold(FoldContext.small()), 10) diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/DocsV3Support.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/DocsV3Support.java index 2e5402b791366..1d9b91585839c 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/DocsV3Support.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/DocsV3Support.java @@ -42,7 +42,7 @@ import org.elasticsearch.xpack.esql.expression.predicate.operator.comparison.LessThan; import org.elasticsearch.xpack.esql.expression.predicate.operator.comparison.LessThanOrEqual; import org.elasticsearch.xpack.esql.expression.predicate.operator.comparison.NotEquals; -import org.elasticsearch.xpack.esql.plan.QuerySettings; +import org.elasticsearch.xpack.esql.plan.QuerySettings.QuerySettingDef; import org.elasticsearch.xpack.esql.plan.logical.LogicalPlan; import org.elasticsearch.xpack.esql.session.Configuration; @@ -1081,10 +1081,10 @@ void renderTypes(String name, List args) thro public static class SettingsDocsSupport extends DocsV3Support { - private final QuerySettings setting; + private final QuerySettingDef setting; - public SettingsDocsSupport(QuerySettings setting, Class testClass, Callbacks callbacks) { - super("settings", setting.settingName(), testClass, Set::of, callbacks); + public SettingsDocsSupport(QuerySettingDef setting, Class testClass, Callbacks callbacks) { + super("settings", setting.name(), testClass, Set::of, callbacks); this.setting = setting; } diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/inference/InferenceResolverTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/inference/InferenceResolverTests.java index 30a711541f831..0cd27d63f20e7 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/inference/InferenceResolverTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/inference/InferenceResolverTests.java @@ -30,7 +30,6 @@ import java.util.List; -import static org.elasticsearch.xpack.esql.EsqlTestUtils.configuration; import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.empty; @@ -114,7 +113,7 @@ public void testCollectInferenceIds() { private void assertCollectInferenceIds(String query, List expectedInferenceIds) { InferenceResolver inferenceResolver = inferenceResolver(); - List inferenceIds = inferenceResolver.collectInferenceIds(new EsqlParser().createStatement(query, configuration(query))); + List inferenceIds = inferenceResolver.collectInferenceIds(new EsqlParser().createStatement(query)); assertThat(inferenceIds, containsInAnyOrder(expectedInferenceIds.toArray(new String[0]))); } diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/AbstractLogicalPlanOptimizerTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/AbstractLogicalPlanOptimizerTests.java index 35c75d99ab925..fc61454f05060 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/AbstractLogicalPlanOptimizerTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/AbstractLogicalPlanOptimizerTests.java @@ -201,7 +201,7 @@ protected LogicalPlan plan(String query) { } protected LogicalPlan plan(String query, LogicalPlanOptimizer optimizer) { - var analyzed = analyzer.analyze(parser.createStatement(query, EsqlTestUtils.TEST_CFG)); + var analyzed = analyzer.analyze(parser.createStatement(query)); // System.out.println(analyzed); var optimized = optimizer.optimize(analyzed); // System.out.println(optimized); @@ -209,7 +209,7 @@ protected LogicalPlan plan(String query, LogicalPlanOptimizer optimizer) { } protected LogicalPlan planAirports(String query) { - var analyzed = analyzerAirports.analyze(parser.createStatement(query, EsqlTestUtils.TEST_CFG)); + var analyzed = analyzerAirports.analyze(parser.createStatement(query)); // System.out.println(analyzed); var optimized = logicalOptimizer.optimize(analyzed); // System.out.println(optimized); @@ -217,7 +217,7 @@ protected LogicalPlan planAirports(String query) { } protected LogicalPlan planExtra(String query) { - var analyzed = analyzerExtra.analyze(parser.createStatement(query, EsqlTestUtils.TEST_CFG)); + var analyzed = analyzerExtra.analyze(parser.createStatement(query)); // System.out.println(analyzed); var optimized = logicalOptimizer.optimize(analyzed); // System.out.println(optimized); @@ -225,15 +225,15 @@ protected LogicalPlan planExtra(String query) { } protected LogicalPlan planTypes(String query) { - return logicalOptimizer.optimize(analyzerTypes.analyze(parser.createStatement(query, EsqlTestUtils.TEST_CFG))); + return logicalOptimizer.optimize(analyzerTypes.analyze(parser.createStatement(query))); } protected LogicalPlan planMultiIndex(String query) { - return logicalOptimizer.optimize(multiIndexAnalyzer.analyze(parser.createStatement(query, EsqlTestUtils.TEST_CFG))); + return logicalOptimizer.optimize(multiIndexAnalyzer.analyze(parser.createStatement(query))); } protected LogicalPlan planSample(String query) { - var analyzed = sampleDataIndexAnalyzer.analyze(parser.createStatement(query, EsqlTestUtils.TEST_CFG)); + var analyzed = sampleDataIndexAnalyzer.analyze(parser.createStatement(query)); return logicalOptimizer.optimize(analyzed); } diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/LocalLogicalPlanOptimizerTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/LocalLogicalPlanOptimizerTests.java index f3abfa52e5ddb..ca334fecc2165 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/LocalLogicalPlanOptimizerTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/LocalLogicalPlanOptimizerTests.java @@ -532,7 +532,7 @@ public void testSparseDocument() throws Exception { TEST_VERIFIER ); - var analyzed = analyzer.analyze(parser.createStatement(query, EsqlTestUtils.TEST_CFG)); + var analyzed = analyzer.analyze(parser.createStatement(query)); var optimized = logicalOptimizer.optimize(analyzed); var localContext = new LocalLogicalOptimizerContext(EsqlTestUtils.TEST_CFG, FoldContext.small(), searchStats); var plan = new LocalLogicalPlanOptimizer(localContext).localOptimize(optimized); @@ -1086,7 +1086,7 @@ private LocalRelation asEmptyRelation(Object o) { } private LogicalPlan plan(String query, Analyzer analyzer) { - var analyzed = analyzer.analyze(parser.createStatement(query, EsqlTestUtils.TEST_CFG)); + var analyzed = analyzer.analyze(parser.createStatement(query)); return logicalOptimizer.optimize(analyzed); } diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/LogicalPlanOptimizerTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/LogicalPlanOptimizerTests.java index 2a65a9f2bda4b..4c5004fd3c9ff 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/LogicalPlanOptimizerTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/LogicalPlanOptimizerTests.java @@ -5292,26 +5292,20 @@ public void testEmptyMappingIndex() { TEST_VERIFIER ); - var plan = logicalOptimizer.optimize(analyzer.analyze(parser.createStatement("from empty_test", EsqlTestUtils.TEST_CFG))); + var plan = logicalOptimizer.optimize(analyzer.analyze(parser.createStatement("from empty_test"))); as(plan, LocalRelation.class); assertThat(plan.output(), equalTo(NO_FIELDS)); - plan = logicalOptimizer.optimize( - analyzer.analyze(parser.createStatement("from empty_test metadata _id | eval x = 1", EsqlTestUtils.TEST_CFG)) - ); + plan = logicalOptimizer.optimize(analyzer.analyze(parser.createStatement("from empty_test metadata _id | eval x = 1"))); as(plan, LocalRelation.class); assertThat(Expressions.names(plan.output()), contains("_id", "x")); - plan = logicalOptimizer.optimize( - analyzer.analyze(parser.createStatement("from empty_test metadata _id, _version | limit 5", EsqlTestUtils.TEST_CFG)) - ); + plan = logicalOptimizer.optimize(analyzer.analyze(parser.createStatement("from empty_test metadata _id, _version | limit 5"))); as(plan, LocalRelation.class); assertThat(Expressions.names(plan.output()), contains("_id", "_version")); plan = logicalOptimizer.optimize( - analyzer.analyze( - parser.createStatement("from empty_test | eval x = \"abc\" | enrich languages_idx on x", EsqlTestUtils.TEST_CFG) - ) + analyzer.analyze(parser.createStatement("from empty_test | eval x = \"abc\" | enrich languages_idx on x")) ); LocalRelation local = as(plan, LocalRelation.class); assertThat(Expressions.names(local.output()), contains(NO_FIELDS.get(0).name(), "x", "language_code", "language_name")); @@ -6691,7 +6685,7 @@ private void doTestSimplifyComparisonArithmetics( private void assertSemanticMatching(String expected, String provided) { BinaryComparison bc = extractPlannedBinaryComparison(provided); - LogicalPlan exp = analyzerTypes.analyze(parser.createStatement("FROM types | WHERE " + expected, EsqlTestUtils.TEST_CFG)); + LogicalPlan exp = analyzerTypes.analyze(parser.createStatement("FROM types | WHERE " + expected)); assertSemanticMatching(bc, extractPlannedBinaryComparison(exp)); } @@ -6719,7 +6713,7 @@ private Expression getComparisonFromLogicalPlan(LogicalPlan plan) { private void assertNotSimplified(String comparison) { String query = "FROM types | WHERE " + comparison; Expression optimized = getComparisonFromLogicalPlan(planTypes(query)); - Expression raw = getComparisonFromLogicalPlan(analyzerTypes.analyze(parser.createStatement(query, EsqlTestUtils.TEST_CFG))); + Expression raw = getComparisonFromLogicalPlan(analyzerTypes.analyze(parser.createStatement(query))); assertTrue(raw.semanticEquals(optimized)); } @@ -7413,7 +7407,7 @@ public void testMultipleLookupShadowing() { public void testTranslateMetricsWithoutGrouping() { var query = "TS k8s | STATS max(rate(network.total_bytes_in))"; - var plan = logicalOptimizer.optimize(metricsAnalyzer.analyze(parser.createStatement(query, EsqlTestUtils.TEST_CFG))); + var plan = logicalOptimizer.optimize(metricsAnalyzer.analyze(parser.createStatement(query))); Limit limit = as(plan, Limit.class); Aggregate finalAggs = as(limit.child(), Aggregate.class); assertThat(finalAggs, not(instanceOf(TimeSeriesAggregate.class))); @@ -7433,7 +7427,7 @@ public void testTranslateMetricsWithoutGrouping() { public void testTranslateMixedAggsWithoutGrouping() { var query = "TS k8s | STATS max(rate(network.total_bytes_in)), max(network.cost)"; - var plan = logicalOptimizer.optimize(metricsAnalyzer.analyze(parser.createStatement(query, EsqlTestUtils.TEST_CFG))); + var plan = logicalOptimizer.optimize(metricsAnalyzer.analyze(parser.createStatement(query))); Limit limit = as(plan, Limit.class); Aggregate finalAggs = as(limit.child(), Aggregate.class); assertThat(finalAggs, not(instanceOf(TimeSeriesAggregate.class))); @@ -7457,7 +7451,7 @@ public void testTranslateMixedAggsWithoutGrouping() { public void testTranslateMixedAggsWithMathWithoutGrouping() { var query = "TS k8s | STATS max(rate(network.total_bytes_in)), max(network.cost + 0.2) * 1.1"; - var plan = logicalOptimizer.optimize(metricsAnalyzer.analyze(parser.createStatement(query, EsqlTestUtils.TEST_CFG))); + var plan = logicalOptimizer.optimize(metricsAnalyzer.analyze(parser.createStatement(query))); Project project = as(plan, Project.class); Eval mulEval = as(project.child(), Eval.class); assertThat(mulEval.fields(), hasSize(1)); @@ -7494,7 +7488,7 @@ public void testTranslateMixedAggsWithMathWithoutGrouping() { public void testTranslateMetricsGroupedByOneDimension() { var query = "TS k8s | STATS sum(rate(network.total_bytes_in)) BY cluster | SORT cluster | LIMIT 10"; - var plan = logicalOptimizer.optimize(metricsAnalyzer.analyze(parser.createStatement(query, EsqlTestUtils.TEST_CFG))); + var plan = logicalOptimizer.optimize(metricsAnalyzer.analyze(parser.createStatement(query))); TopN topN = as(plan, TopN.class); Aggregate aggsByCluster = as(topN.child(), Aggregate.class); assertThat(aggsByCluster, not(instanceOf(TimeSeriesAggregate.class))); @@ -7518,7 +7512,7 @@ public void testTranslateMetricsGroupedByOneDimension() { public void testTranslateMetricsGroupedByTwoDimension() { var query = "TS k8s | STATS avg(rate(network.total_bytes_in)) BY cluster, pod"; - var plan = logicalOptimizer.optimize(metricsAnalyzer.analyze(parser.createStatement(query, EsqlTestUtils.TEST_CFG))); + var plan = logicalOptimizer.optimize(metricsAnalyzer.analyze(parser.createStatement(query))); Project project = as(plan, Project.class); Eval eval = as(project.child(), Eval.class); assertThat(eval.fields(), hasSize(1)); @@ -7557,7 +7551,7 @@ public void testTranslateMetricsGroupedByTwoDimension() { public void testTranslateMetricsGroupedByTimeBucket() { var query = "TS k8s | STATS sum(rate(network.total_bytes_in)) BY bucket(@timestamp, 1h)"; - var plan = logicalOptimizer.optimize(metricsAnalyzer.analyze(parser.createStatement(query, EsqlTestUtils.TEST_CFG))); + var plan = logicalOptimizer.optimize(metricsAnalyzer.analyze(parser.createStatement(query))); Limit limit = as(plan, Limit.class); Aggregate finalAgg = as(limit.child(), Aggregate.class); assertThat(finalAgg, not(instanceOf(TimeSeriesAggregate.class))); @@ -7590,7 +7584,7 @@ public void testTranslateMetricsGroupedByTimeBucketAndDimensions() { | SORT cluster | LIMIT 10 """; - var plan = logicalOptimizer.optimize(metricsAnalyzer.analyze(parser.createStatement(query, EsqlTestUtils.TEST_CFG))); + var plan = logicalOptimizer.optimize(metricsAnalyzer.analyze(parser.createStatement(query))); Project project = as(plan, Project.class); TopN topN = as(project.child(), TopN.class); Eval eval = as(topN.child(), Eval.class); @@ -7631,7 +7625,7 @@ public void testTranslateSumOfTwoRates() { | SORT cluster | LIMIT 10 """; - var plan = logicalOptimizer.optimize(metricsAnalyzer.analyze(parser.createStatement(query, EsqlTestUtils.TEST_CFG))); + var plan = logicalOptimizer.optimize(metricsAnalyzer.analyze(parser.createStatement(query))); TopN topN = as(plan, TopN.class); Aggregate finalAgg = as(topN.child(), Aggregate.class); Eval eval = as(finalAgg.child(), Eval.class); @@ -7651,7 +7645,7 @@ public void testTranslateMixedAggsGroupedByTimeBucketAndDimensions() { | SORT cluster | LIMIT 10 """; - var plan = logicalOptimizer.optimize(metricsAnalyzer.analyze(parser.createStatement(query, EsqlTestUtils.TEST_CFG))); + var plan = logicalOptimizer.optimize(metricsAnalyzer.analyze(parser.createStatement(query))); Project project = as(plan, Project.class); TopN topN = as(project.child(), TopN.class); Eval eval = as(topN.child(), Eval.class); @@ -7698,7 +7692,7 @@ public void testAdjustMetricsRateBeforeFinalAgg() { | SORT cluster | LIMIT 10 """; - var plan = logicalOptimizer.optimize(metricsAnalyzer.analyze(parser.createStatement(query, EsqlTestUtils.TEST_CFG))); + var plan = logicalOptimizer.optimize(metricsAnalyzer.analyze(parser.createStatement(query))); Project project = as(plan, Project.class); TopN topN = as(project.child(), TopN.class); Eval evalDiv = as(topN.child(), Eval.class); @@ -7750,7 +7744,7 @@ public void testAdjustMetricsRateBeforeFinalAgg() { public void testTranslateMaxOverTime() { var query = "TS k8s | STATS sum(max_over_time(network.bytes_in)) BY bucket(@timestamp, 1h)"; - var plan = logicalOptimizer.optimize(metricsAnalyzer.analyze(parser.createStatement(query, EsqlTestUtils.TEST_CFG))); + var plan = logicalOptimizer.optimize(metricsAnalyzer.analyze(parser.createStatement(query))); Limit limit = as(plan, Limit.class); Aggregate finalAgg = as(limit.child(), Aggregate.class); assertThat(finalAgg, not(instanceOf(TimeSeriesAggregate.class))); @@ -7778,7 +7772,7 @@ public void testTranslateMaxOverTime() { public void testTranslateAvgOverTime() { var query = "TS k8s | STATS sum(avg_over_time(network.bytes_in)) BY bucket(@timestamp, 1h)"; - var plan = logicalOptimizer.optimize(metricsAnalyzer.analyze(parser.createStatement(query, EsqlTestUtils.TEST_CFG))); + var plan = logicalOptimizer.optimize(metricsAnalyzer.analyze(parser.createStatement(query))); Limit limit = as(plan, Limit.class); Aggregate finalAgg = as(limit.child(), Aggregate.class); assertThat(finalAgg, not(instanceOf(TimeSeriesAggregate.class))); @@ -7813,7 +7807,7 @@ public void testTranslateLastOverTime() { TS k8s | STATS avg(last_over_time(network.bytes_in)) BY bucket(@timestamp, 1 minute) | LIMIT 10 """; - var plan = logicalOptimizer.optimize(metricsAnalyzer.analyze(parser.createStatement(query, EsqlTestUtils.TEST_CFG))); + var plan = logicalOptimizer.optimize(metricsAnalyzer.analyze(parser.createStatement(query))); var project = as(plan, Project.class); var eval = as(project.child(), Eval.class); var limit = as(eval.child(), Limit.class); @@ -7842,7 +7836,7 @@ public void testTranslateWithInlineFilter() { TS k8s | STATS sum(last_over_time(network.bytes_in)) WHERE cluster == "prod" BY bucket(@timestamp, 1 minute) | LIMIT 10 """; - var plan = logicalOptimizer.optimize(metricsAnalyzer.analyze(parser.createStatement(query, EsqlTestUtils.TEST_CFG))); + var plan = logicalOptimizer.optimize(metricsAnalyzer.analyze(parser.createStatement(query))); var limit = as(plan, Limit.class); Aggregate finalAgg = as(limit.child(), Aggregate.class); assertThat(finalAgg, not(instanceOf(TimeSeriesAggregate.class))); @@ -7871,7 +7865,7 @@ public void testTranslateWithInlineFilterWithImplicitLastOverTime() { TS k8s | STATS avg(network.bytes_in) WHERE cluster == "prod" BY bucket(@timestamp, 1 minute) | LIMIT 10 """; - var plan = logicalOptimizer.optimize(metricsAnalyzer.analyze(parser.createStatement(query, EsqlTestUtils.TEST_CFG))); + var plan = logicalOptimizer.optimize(metricsAnalyzer.analyze(parser.createStatement(query))); var project = as(plan, Project.class); var eval = as(project.child(), Eval.class); var limit = as(eval.child(), Limit.class); @@ -8483,7 +8477,7 @@ public void testPruneRedundantOrderBy() { | mv_expand x | sort y """; - LogicalPlan analyzed = analyzer.analyze(parser.createStatement(query, EsqlTestUtils.TEST_CFG)); + LogicalPlan analyzed = analyzer.analyze(parser.createStatement(query)); LogicalPlan optimized = rule.apply(analyzed); // check that all the redundant SORTs are removed in a single run @@ -9076,7 +9070,7 @@ public void testTranslateDataGroupedByTBucket() { public void testTranslateMetricsGroupedByTBucketInTSMode() { var query = "TS k8s | STATS sum(rate(network.total_bytes_in)) BY tbucket(1h)"; - var plan = logicalOptimizer.optimize(metricsAnalyzer.analyze(parser.createStatement(query, EsqlTestUtils.TEST_CFG))); + var plan = logicalOptimizer.optimize(metricsAnalyzer.analyze(parser.createStatement(query))); Limit limit = as(plan, Limit.class); Aggregate finalAgg = as(limit.child(), Aggregate.class); assertThat(finalAgg, not(instanceOf(TimeSeriesAggregate.class))); @@ -9113,7 +9107,7 @@ public void testDecayOriginMustBeLiteral() { Exception e = expectThrows( VerificationException.class, - () -> logicalOptimizer.optimize(defaultAnalyzer().analyze(parser.createStatement(query, EsqlTestUtils.TEST_CFG))) + () -> logicalOptimizer.optimize(defaultAnalyzer().analyze(parser.createStatement(query))) ); assertThat(e.getMessage(), containsString("has non-literal value [origin]")); } @@ -9129,7 +9123,7 @@ public void testDecayScaleMustBeLiteral() { Exception e = expectThrows( VerificationException.class, - () -> logicalOptimizer.optimize(defaultAnalyzer().analyze(parser.createStatement(query, EsqlTestUtils.TEST_CFG))) + () -> logicalOptimizer.optimize(defaultAnalyzer().analyze(parser.createStatement(query))) ); assertThat(e.getMessage(), containsString("has non-literal value [scale]")); } diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/OptimizerRulesTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/OptimizerRulesTests.java index fe4fd96120a01..b36cb3f6c6a42 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/OptimizerRulesTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/OptimizerRulesTests.java @@ -8,7 +8,6 @@ import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.test.ESTestCase; -import org.elasticsearch.xpack.esql.EsqlTestUtils; import org.elasticsearch.xpack.esql.core.expression.Alias; import org.elasticsearch.xpack.esql.core.expression.Expression; import org.elasticsearch.xpack.esql.core.expression.FieldAttribute; @@ -129,7 +128,7 @@ protected Expression rule(Expression e, LogicalOptimizerContext ctx) { }; rule.apply( - new EsqlParser().createStatement("FROM index | EVAL x=f1+1 | KEEP x, f2 | LIMIT 1", EsqlTestUtils.TEST_CFG), + new EsqlParser().createStatement("FROM index | EVAL x=f1+1 | KEEP x, f2 | LIMIT 1"), new LogicalOptimizerContext(null, FoldContext.small()) ); diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/OptimizerVerificationTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/OptimizerVerificationTests.java index 54488aa9399b4..df5f7e48193c0 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/OptimizerVerificationTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/OptimizerVerificationTests.java @@ -8,7 +8,6 @@ package org.elasticsearch.xpack.esql.optimizer; import org.elasticsearch.common.Strings; -import org.elasticsearch.xpack.esql.EsqlTestUtils; import org.elasticsearch.xpack.esql.VerificationException; import org.elasticsearch.xpack.esql.action.EsqlCapabilities; import org.elasticsearch.xpack.esql.analysis.Analyzer; @@ -35,7 +34,7 @@ public class OptimizerVerificationTests extends AbstractLogicalPlanOptimizerTests { private LogicalPlan plan(String query, Analyzer analyzer) { - var analyzed = analyzer.analyze(parser.createStatement(query, EsqlTestUtils.TEST_CFG)); + var analyzed = analyzer.analyze(parser.createStatement(query)); return logicalOptimizer.optimize(analyzed); } diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/PhysicalPlanOptimizerTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/PhysicalPlanOptimizerTests.java index e50a2b64a8620..9c9a9ac48ef6f 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/PhysicalPlanOptimizerTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/PhysicalPlanOptimizerTests.java @@ -8273,7 +8273,7 @@ private PhysicalPlan physicalPlan(String query, TestDataSource dataSource) { } private PhysicalPlan physicalPlan(String query, TestDataSource dataSource, boolean assertSerialization) { - var logical = logicalOptimizer.optimize(dataSource.analyzer.analyze(parser.createStatement(query, config))); + var logical = logicalOptimizer.optimize(dataSource.analyzer.analyze(parser.createStatement(query))); // System.out.println("Logical\n" + logical); var physical = mapper.map(logical); // System.out.println("Physical\n" + physical); diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/TestPlannerOptimizer.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/TestPlannerOptimizer.java index 018fb23a03bbd..cdb793f7efd61 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/TestPlannerOptimizer.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/TestPlannerOptimizer.java @@ -91,7 +91,7 @@ private PhysicalPlan optimizedPlan(PhysicalPlan plan, SearchStats searchStats, E } private PhysicalPlan physicalPlan(String query, Analyzer analyzer) { - LogicalPlan logical = logicalOptimizer.optimize(analyzer.analyze(parser.createStatement(query, EsqlTestUtils.TEST_CFG))); + LogicalPlan logical = logicalOptimizer.optimize(analyzer.analyze(parser.createStatement(query))); // System.out.println("Logical\n" + logical); PhysicalPlan physical = mapper.map(logical); return physical; diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/rules/logical/PropagateInlineEvalsTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/rules/logical/PropagateInlineEvalsTests.java index 840b8012c6a62..c8714fbdb035a 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/rules/logical/PropagateInlineEvalsTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/rules/logical/PropagateInlineEvalsTests.java @@ -169,7 +169,7 @@ public void testGroupingAliasingMoved_To_LeftSideOfJoin_WithExpression() { } private LogicalPlan plan(String query, LogicalPlanOptimizer optimizer) { - return optimizer.optimize(analyzer.analyze(parser.createStatement(query, EsqlTestUtils.TEST_CFG))); + return optimizer.optimize(analyzer.analyze(parser.createStatement(query))); } @Override diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/rules/logical/local/IgnoreNullMetricsTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/rules/logical/local/IgnoreNullMetricsTests.java index 3d755a7703b15..8a37f0b692ca2 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/rules/logical/local/IgnoreNullMetricsTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/rules/logical/local/IgnoreNullMetricsTests.java @@ -93,7 +93,7 @@ private static void init() { } private LogicalPlan plan(String query, Analyzer analyzer) { - var analyzed = analyzer.analyze(parser.createStatement(query, EsqlTestUtils.TEST_CFG)); + var analyzed = analyzer.analyze(parser.createStatement(query)); return logicalOptimizer.optimize(analyzed); } diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/parser/AbstractStatementParserTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/parser/AbstractStatementParserTests.java index 07ab624e4a2a9..462b9f7373ecf 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/parser/AbstractStatementParserTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/parser/AbstractStatementParserTests.java @@ -11,7 +11,6 @@ import org.elasticsearch.common.lucene.BytesRefs; import org.elasticsearch.index.IndexMode; import org.elasticsearch.test.ESTestCase; -import org.elasticsearch.xpack.esql.EsqlTestUtils; import org.elasticsearch.xpack.esql.VerificationException; import org.elasticsearch.xpack.esql.core.expression.Expression; import org.elasticsearch.xpack.esql.core.expression.Literal; @@ -58,11 +57,11 @@ LogicalPlan statement(String e) { } LogicalPlan statement(String e, QueryParams params) { - return parser.createStatement(e, params, EsqlTestUtils.TEST_CFG); + return parser.createStatement(e, params); } LogicalPlan processingCommand(String e) { - return parser.createStatement("row a = 1 | " + e, EsqlTestUtils.TEST_CFG); + return parser.createStatement("row a = 1 | " + e); } static UnresolvedAttribute attribute(String name) { @@ -171,7 +170,7 @@ void expectVerificationError(String query, String errorMessage) { "Query [" + query + "] is expected to throw " + VerificationException.class + " with message [" + errorMessage + "]", VerificationException.class, containsString(errorMessage), - () -> parser.createStatement(query, EsqlTestUtils.TEST_CFG) + () -> parser.createStatement(query) ); } diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/parser/ExpressionTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/parser/ExpressionTests.java index 0696f2c99e03e..c39dc70f3ad39 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/parser/ExpressionTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/parser/ExpressionTests.java @@ -9,7 +9,6 @@ import org.elasticsearch.common.lucene.BytesRefs; import org.elasticsearch.test.ESTestCase; -import org.elasticsearch.xpack.esql.EsqlTestUtils; import org.elasticsearch.xpack.esql.core.expression.Alias; import org.elasticsearch.xpack.esql.core.expression.Expression; import org.elasticsearch.xpack.esql.core.expression.FoldContext; @@ -660,7 +659,7 @@ private Project projectExpression(String e) { } private LogicalPlan parse(String s) { - return parser.createStatement(s, EsqlTestUtils.TEST_CFG); + return parser.createStatement(s); } private Literal l(Object value, DataType type) { diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/parser/GrammarInDevelopmentParsingTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/parser/GrammarInDevelopmentParsingTests.java index 6e05f2470d69b..1227d470ce39c 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/parser/GrammarInDevelopmentParsingTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/parser/GrammarInDevelopmentParsingTests.java @@ -8,7 +8,6 @@ package org.elasticsearch.xpack.esql.parser; import org.elasticsearch.test.ESTestCase; -import org.elasticsearch.xpack.esql.EsqlTestUtils; import org.elasticsearch.xpack.esql.plan.logical.LogicalPlan; import static org.hamcrest.Matchers.containsString; @@ -17,7 +16,7 @@ public class GrammarInDevelopmentParsingTests extends ESTestCase { public void testDevelopmentInline() throws Exception { - LogicalPlan plan = parser().createStatement("row a = 1 | inline stats b = min(a) by c, d.e", EsqlTestUtils.TEST_CFG); + LogicalPlan plan = parser().createStatement("row a = 1 | inline stats b = min(a) by c, d.e"); assertNotNull(plan); } @@ -30,7 +29,7 @@ public void testDevelopmentMatch() throws Exception { } void parse(String query, String errorMessage) { - ParsingException pe = expectThrows(ParsingException.class, () -> parser().createStatement(query, EsqlTestUtils.TEST_CFG)); + ParsingException pe = expectThrows(ParsingException.class, () -> parser().createStatement(query)); assertThat(pe.getMessage(), containsString("mismatched input '" + errorMessage + "'")); // check the parser eliminated the DEV_ tokens from the message assertThat(pe.getMessage(), not(containsString("DEV_"))); diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/parser/StatementParserTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/parser/StatementParserTests.java index 30ad258954d0c..d92d1b21a98e9 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/parser/StatementParserTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/parser/StatementParserTests.java @@ -14,7 +14,6 @@ import org.elasticsearch.core.Tuple; import org.elasticsearch.index.IndexMode; import org.elasticsearch.test.ESTestCase; -import org.elasticsearch.xpack.esql.EsqlTestUtils; import org.elasticsearch.xpack.esql.action.EsqlCapabilities; import org.elasticsearch.xpack.esql.core.capabilities.UnresolvedException; import org.elasticsearch.xpack.esql.core.expression.Alias; @@ -4038,11 +4037,7 @@ public void testRerankComputedFieldsWithoutName() { public void testRerankWithPositionalParameters() { var queryParams = new QueryParams(List.of(paramAsConstant(null, "query text"), paramAsConstant(null, "reranker"))); var rerank = as( - parser.createStatement( - "row a = 1 | RERANK rerank_score = ? ON title WITH { \"inference_id\" : ? }", - queryParams, - EsqlTestUtils.TEST_CFG - ), + parser.createStatement("row a = 1 | RERANK rerank_score = ? ON title WITH { \"inference_id\" : ? }", queryParams), Rerank.class ); @@ -4057,8 +4052,7 @@ public void testRerankWithNamedParameters() { var rerank = as( parser.createStatement( "row a = 1 | RERANK rerank_score=?queryText ON title WITH { \"inference_id\": ?inferenceId }", - queryParams, - EsqlTestUtils.TEST_CFG + queryParams ), Rerank.class ); @@ -4137,11 +4131,7 @@ public void testCompletionDefaultFieldName() { public void testCompletionWithPositionalParameters() { var queryParams = new QueryParams(List.of(paramAsConstant(null, "inferenceId"))); var plan = as( - parser.createStatement( - "row a = 1 | COMPLETION prompt_field WITH { \"inference_id\" : ? }", - queryParams, - EsqlTestUtils.TEST_CFG - ), + parser.createStatement("row a = 1 | COMPLETION prompt_field WITH { \"inference_id\" : ? }", queryParams), Completion.class ); @@ -4153,11 +4143,7 @@ public void testCompletionWithPositionalParameters() { public void testCompletionWithNamedParameters() { var queryParams = new QueryParams(List.of(paramAsConstant("inferenceId", "myInference"))); var plan = as( - parser.createStatement( - "row a = 1 | COMPLETION prompt_field WITH { \"inference_id\" : ?inferenceId }", - queryParams, - EsqlTestUtils.TEST_CFG - ), + parser.createStatement("row a = 1 | COMPLETION prompt_field WITH { \"inference_id\" : ?inferenceId }", queryParams), Completion.class ); diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/plan/QuerySettingsTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/plan/QuerySettingsTests.java index 000539a232354..f0547325e7665 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/plan/QuerySettingsTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/plan/QuerySettingsTests.java @@ -7,56 +7,99 @@ package org.elasticsearch.xpack.esql.plan; -import org.elasticsearch.common.lucene.BytesRefs; import org.elasticsearch.test.ESTestCase; import org.elasticsearch.xpack.esql.core.expression.Alias; +import org.elasticsearch.xpack.esql.core.expression.Expression; import org.elasticsearch.xpack.esql.core.expression.Literal; import org.elasticsearch.xpack.esql.core.tree.Source; import org.elasticsearch.xpack.esql.core.type.DataType; import org.elasticsearch.xpack.esql.expression.function.DocsV3Support; import org.elasticsearch.xpack.esql.parser.ParsingException; +import org.hamcrest.Matcher; import org.junit.AfterClass; +import java.time.ZoneId; +import java.time.ZoneOffset; import java.util.List; +import static org.hamcrest.Matchers.both; import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.nullValue; public class QuerySettingsTests extends ESTestCase { + public void testNonExistingSetting() { + String settingName = "non_existing"; - public void test() { + assertInvalid(settingName, Literal.keyword(Source.EMPTY, "12"), "Unknown setting [" + settingName + "]"); + } - QuerySetting project_routing = new QuerySetting( - Source.EMPTY, - new Alias(Source.EMPTY, "project_routing", new Literal(Source.EMPTY, BytesRefs.toBytesRef("my-project"), DataType.KEYWORD)) - ); - QuerySettings.validate(new EsqlStatement(null, List.of(project_routing)), null); + public void testProjectRouting() { + var setting = QuerySettings.PROJECT_ROUTING; - QuerySetting wrong_type = new QuerySetting( - Source.EMPTY, - new Alias(Source.EMPTY, "project_routing", new Literal(Source.EMPTY, 12, DataType.INTEGER)) - ); - assertThat( - expectThrows(ParsingException.class, () -> QuerySettings.validate(new EsqlStatement(null, List.of(wrong_type)), null)) - .getMessage(), - containsString("Setting [project_routing] must be of type KEYWORD") + assertDefault(setting, nullValue()); + assertValid(setting, Literal.keyword(Source.EMPTY, "my-project"), equalTo("my-project")); + + assertInvalid( + setting.name(), + new Literal(Source.EMPTY, 12, DataType.INTEGER), + "Setting [" + setting.name() + "] must be of type KEYWORD" ); + } + + public void testTimeZone() { + var setting = QuerySettings.TIME_ZONE; + + assertDefault(setting, both(equalTo(ZoneId.of("Z"))).and(equalTo(ZoneOffset.UTC))); + + assertValid(setting, Literal.keyword(Source.EMPTY, "UTC"), equalTo(ZoneId.of("UTC"))); + assertValid(setting, Literal.keyword(Source.EMPTY, "Z"), both(equalTo(ZoneId.of("Z"))).and(equalTo(ZoneOffset.UTC))); + assertValid(setting, Literal.keyword(Source.EMPTY, "Europe/Madrid"), equalTo(ZoneId.of("Europe/Madrid"))); + assertValid(setting, Literal.keyword(Source.EMPTY, "+05:00"), equalTo(ZoneId.of("+05:00"))); + assertValid(setting, Literal.keyword(Source.EMPTY, "+05"), equalTo(ZoneId.of("+05"))); + assertValid(setting, Literal.keyword(Source.EMPTY, "+07:15"), equalTo(ZoneId.of("+07:15"))); - QuerySetting non_existing = new QuerySetting( - Source.EMPTY, - new Alias(Source.EMPTY, "non_existing", new Literal(Source.EMPTY, BytesRefs.toBytesRef("12"), DataType.KEYWORD)) + assertInvalid(setting.name(), Literal.integer(Source.EMPTY, 12), "Setting [" + setting.name() + "] must be of type KEYWORD"); + assertInvalid( + setting.name(), + Literal.keyword(Source.EMPTY, "Europe/New York"), + "Error validating setting [" + setting.name() + "]: Invalid time zone [Europe/New York]" ); + } + + private static void assertValid( + QuerySettings.QuerySettingDef settingDef, + Expression valueExpression, + Matcher parsedValueMatcher + ) { + QuerySetting setting = new QuerySetting(Source.EMPTY, new Alias(Source.EMPTY, settingDef.name(), valueExpression)); + QuerySettings.validate(new EsqlStatement(null, List.of(setting)), null); + + T value = settingDef.get(valueExpression, null); + + assertThat(value, parsedValueMatcher); + } + + private static void assertInvalid(String settingName, Expression valueExpression, String expectedMessage) { + QuerySetting setting = new QuerySetting(Source.EMPTY, new Alias(Source.EMPTY, settingName, valueExpression)); assertThat( - expectThrows(ParsingException.class, () -> QuerySettings.validate(new EsqlStatement(null, List.of(non_existing)), null)) + expectThrows(ParsingException.class, () -> QuerySettings.validate(new EsqlStatement(null, List.of(setting)), null)) .getMessage(), - containsString("Unknown setting [non_existing]") + containsString(expectedMessage) ); } + private static void assertDefault(QuerySettings.QuerySettingDef settingDef, Matcher defaultMatcher) { + T value = settingDef.get(null, null); + + assertThat(value, defaultMatcher); + } + @AfterClass public static void generateDocs() throws Exception { - for (QuerySettings value : QuerySettings.values()) { + for (QuerySettings.QuerySettingDef def : QuerySettings.SETTINGS_BY_NAME.values()) { DocsV3Support.SettingsDocsSupport settingsDocsSupport = new DocsV3Support.SettingsDocsSupport( - value, + def, QuerySettingsTests.class, DocsV3Support.callbacksFromSystemProperty() ); diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/planner/FilterTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/planner/FilterTests.java index 374c6db74a50b..0b77af3436f02 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/planner/FilterTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/planner/FilterTests.java @@ -370,7 +370,7 @@ public static QueryBuilder singleValueQuery(String query, QueryBuilder inner, St } private PhysicalPlan plan(String query, QueryBuilder restFilter) { - var logical = logicalOptimizer.optimize(analyzer.analyze(parser.createStatement(query, EsqlTestUtils.TEST_CFG))); + var logical = logicalOptimizer.optimize(analyzer.analyze(parser.createStatement(query))); // System.out.println("Logical\n" + logical); var physical = mapper.map(logical); // System.out.println("physical\n" + physical); diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/plugin/ClusterRequestTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/plugin/ClusterRequestTests.java index be40f535dad16..f9dff219b8632 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/plugin/ClusterRequestTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/plugin/ClusterRequestTests.java @@ -179,7 +179,7 @@ static LogicalPlan parse(String query) { ), TEST_VERIFIER ); - return logicalOptimizer.optimize(analyzer.analyze(new EsqlParser().createStatement(query, EsqlTestUtils.TEST_CFG))); + return logicalOptimizer.optimize(analyzer.analyze(new EsqlParser().createStatement(query))); } @Override diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/plugin/DataNodeRequestSerializationTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/plugin/DataNodeRequestSerializationTests.java index 1a1d981ca0ba1..abf9b527f008d 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/plugin/DataNodeRequestSerializationTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/plugin/DataNodeRequestSerializationTests.java @@ -302,7 +302,7 @@ static LogicalPlan parse(String query) { ), TEST_VERIFIER ); - return logicalOptimizer.optimize(analyzer.analyze(new EsqlParser().createStatement(query, EsqlTestUtils.TEST_CFG))); + return logicalOptimizer.optimize(analyzer.analyze(new EsqlParser().createStatement(query))); } static PhysicalPlan mapAndMaybeOptimize(LogicalPlan logicalPlan) { diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/session/FieldNameUtilsTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/session/FieldNameUtilsTests.java index 16d3665db10e0..efd2402188ce8 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/session/FieldNameUtilsTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/session/FieldNameUtilsTests.java @@ -8,7 +8,6 @@ package org.elasticsearch.xpack.esql.session; import org.elasticsearch.test.ESTestCase; -import org.elasticsearch.xpack.esql.EsqlTestUtils; import org.elasticsearch.xpack.esql.action.EsqlCapabilities; import org.elasticsearch.xpack.esql.parser.EsqlParser; @@ -3152,7 +3151,7 @@ private void assertFieldNames(String query, Set expected, Set wi } private void assertFieldNames(String query, boolean hasEnriches, Set expected, Set wildCardIndices) { - var preAnalysisResult = FieldNameUtils.resolveFieldNames(parser.createStatement(query, EsqlTestUtils.TEST_CFG), hasEnriches); + var preAnalysisResult = FieldNameUtils.resolveFieldNames(parser.createStatement(query), hasEnriches); assertThat("Query-wide field names", preAnalysisResult.fieldNames(), equalTo(expected)); assertThat("Lookup Indices that expect wildcard lookups", preAnalysisResult.wildcardJoinIndices(), equalTo(wildCardIndices)); } diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/telemetry/PlanExecutorMetricsTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/telemetry/PlanExecutorMetricsTests.java index 7a2565aaad9ce..bf8434e3c11c5 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/telemetry/PlanExecutorMetricsTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/telemetry/PlanExecutorMetricsTests.java @@ -36,7 +36,6 @@ import org.elasticsearch.xpack.esql.action.EsqlResolveFieldsAction; import org.elasticsearch.xpack.esql.action.EsqlResolveFieldsResponse; import org.elasticsearch.xpack.esql.analysis.EnrichResolution; -import org.elasticsearch.xpack.esql.core.expression.FoldContext; import org.elasticsearch.xpack.esql.enrich.EnrichPolicyResolver; import org.elasticsearch.xpack.esql.execution.PlanExecutor; import org.elasticsearch.xpack.esql.plugin.EsqlPlugin; @@ -55,6 +54,7 @@ import java.util.List; import java.util.Map; +import static org.elasticsearch.xpack.esql.EsqlTestUtils.queryClusterSettings; import static org.elasticsearch.xpack.esql.EsqlTestUtils.withDefaultLimitWarning; import static org.hamcrest.Matchers.instanceOf; import static org.mockito.ArgumentMatchers.any; @@ -163,7 +163,8 @@ public void testFailedMetric() { var request = new EsqlQueryRequest(); // test a failed query: xyz field doesn't exist request.query("from test | stats m = max(xyz)"); - EsqlSession.PlanRunner runPhase = (p, r) -> fail("this shouldn't happen"); + request.allowPartialResults(false); + EsqlSession.PlanRunner runPhase = (p, configuration, foldContext, r) -> fail("this shouldn't happen"); IndicesExpressionGrouper groupIndicesByCluster = (indicesOptions, indexExpressions, returnLocalAll) -> Map.of( "", new OriginalIndices(new String[] { "test" }, IndicesOptions.DEFAULT) @@ -172,8 +173,7 @@ public void testFailedMetric() { planExecutor.esql( request, randomAlphaOfLength(10), - EsqlTestUtils.TEST_CFG, - FoldContext.small(), + queryClusterSettings(), enrichResolver, new EsqlExecutionInfo(randomBoolean()), groupIndicesByCluster, @@ -199,12 +199,11 @@ public void onFailure(Exception e) { // fix the failing query: foo field does exist request.query("from test | stats m = max(foo)"); - runPhase = (p, r) -> r.onResponse(null); + runPhase = (p, configuration, foldContext, r) -> r.onResponse(null); planExecutor.esql( request, randomAlphaOfLength(10), - EsqlTestUtils.TEST_CFG, - FoldContext.small(), + queryClusterSettings(), enrichResolver, new EsqlExecutionInfo(randomBoolean()), groupIndicesByCluster, diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/telemetry/VerifierMetricsTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/telemetry/VerifierMetricsTests.java index 05e0f70b949f0..7013cc6bc9ea0 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/telemetry/VerifierMetricsTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/telemetry/VerifierMetricsTests.java @@ -10,7 +10,6 @@ import org.elasticsearch.license.XPackLicenseState; import org.elasticsearch.test.ESTestCase; import org.elasticsearch.xpack.core.watcher.common.stats.Counters; -import org.elasticsearch.xpack.esql.EsqlTestUtils; import org.elasticsearch.xpack.esql.action.EsqlCapabilities; import org.elasticsearch.xpack.esql.analysis.Verifier; import org.elasticsearch.xpack.esql.expression.function.EsqlFunctionRegistry; @@ -834,7 +833,7 @@ private Counters esql(String esql, Verifier v) { metrics = new Metrics(new EsqlFunctionRegistry()); verifier = new Verifier(metrics, new XPackLicenseState(() -> 0L)); } - analyzer(verifier).analyze(parser.createStatement(esql, EsqlTestUtils.TEST_CFG)); + analyzer(verifier).analyze(parser.createStatement(esql)); return metrics == null ? null : metrics.stats(); }