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 extends Exception>
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 super T> 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();
}