Skip to content

[ES|QL] add validation_only option #127995

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -50,6 +50,7 @@ public class EsqlQueryRequest extends org.elasticsearch.xpack.core.esql.action.E
private TimeValue waitForCompletionTimeout = DEFAULT_WAIT_FOR_COMPLETION;
private TimeValue keepAlive = DEFAULT_KEEP_ALIVE;
private boolean keepOnCompletion;
private boolean validationOnly;
private boolean onSnapshotBuild = Build.current().isSnapshot();
private boolean acceptedPragmaRisks = false;
private Boolean allowPartialResults = null;
@@ -202,6 +203,14 @@ public void keepOnCompletion(boolean keepOnCompletion) {
this.keepOnCompletion = keepOnCompletion;
}

public boolean validationOnly() {
return validationOnly;
}

public void validationOnly(boolean validationOnly) {
this.validationOnly = validationOnly;
}

/**
* Add a "table" to the request for use with things like {@code LOOKUP}.
*/
Original file line number Diff line number Diff line change
@@ -85,6 +85,7 @@ String fields() {
static final ParseField WAIT_FOR_COMPLETION_TIMEOUT = new ParseField("wait_for_completion_timeout");
static final ParseField KEEP_ALIVE = new ParseField("keep_alive");
static final ParseField KEEP_ON_COMPLETION = new ParseField("keep_on_completion");
static final ParseField VALIDATION_ONLY = new ParseField("validation_only");

private static final ObjectParser<EsqlQueryRequest, Void> SYNC_PARSER = objectParserSync(EsqlQueryRequest::syncEsqlQueryRequest);
private static final ObjectParser<EsqlQueryRequest, Void> ASYNC_PARSER = objectParserAsync(EsqlQueryRequest::asyncEsqlQueryRequest);
@@ -114,6 +115,7 @@ private static void objectParserCommon(ObjectParser<EsqlQueryRequest, ?> parser)
parser.declareString((request, localeTag) -> request.locale(Locale.forLanguageTag(localeTag)), LOCALE_FIELD);
parser.declareBoolean(EsqlQueryRequest::profile, PROFILE_FIELD);
parser.declareField((p, r, c) -> new ParseTables(r, p).parseTables(), TABLES_FIELD, ObjectParser.ValueType.OBJECT);
parser.declareBoolean(EsqlQueryRequest::validationOnly, VALIDATION_ONLY);
}

private static ObjectParser<EsqlQueryRequest, Void> objectParserSync(Supplier<EsqlQueryRequest> supplier) {
Original file line number Diff line number Diff line change
@@ -250,7 +250,7 @@ private void innerExecute(Task task, EsqlQueryRequest request, ActionListener<Es
services,
ActionListener.wrap(result -> {
recordCCSTelemetry(task, executionInfo, request, null);
planExecutor.metrics().recordTook(executionInfo.overallTook().millis());
// planExecutor.metrics().recordTook(executionInfo.overallTook().millis());
listener.onResponse(toResponse(task, request, configuration, result));
}, ex -> {
recordCCSTelemetry(task, executionInfo, request, ex);
Original file line number Diff line number Diff line change
@@ -15,6 +15,7 @@
import org.elasticsearch.index.SlowLogFieldProvider;
import org.elasticsearch.index.SlowLogFields;
import org.elasticsearch.xcontent.json.JsonStringEncoder;
import org.elasticsearch.xpack.esql.action.EsqlExecutionInfo;
import org.elasticsearch.xpack.esql.session.Result;

import java.nio.charset.StandardCharsets;
@@ -66,7 +67,8 @@ public void onQueryPhase(Result esqlResult, String query) {
if (esqlResult == null) {
return; // TODO review, it happens in some tests, not sure if it's a thing also in prod
}
long tookInNanos = esqlResult.executionInfo().overallTook().nanos();
EsqlExecutionInfo executionResult = esqlResult.executionInfo();
long tookInNanos = executionResult == null ? 0 : executionResult.overallTook().nanos();
log(() -> Message.of(esqlResult, query, includeUser ? additionalFields.queryFields() : Map.of()), tookInNanos);
}

Original file line number Diff line number Diff line change
@@ -181,12 +181,13 @@ public void execute(EsqlQueryRequest request, EsqlExecutionInfo executionInfo, P
new EsqlCCSUtils.CssPartialErrorsActionListener(executionInfo, listener) {
@Override
public void onResponse(LogicalPlan analyzedPlan) {
preMapper.preMapper(
analyzedPlan,
listener.delegateFailureAndWrap(
(l, p) -> executeOptimizedPlan(request, executionInfo, planRunner, optimizedPlan(p), l)
)
);
preMapper.preMapper(analyzedPlan, listener.delegateFailureAndWrap((l, p) -> {
if (request.validationOnly()) {
l.onResponse(new Result(new ArrayList<>(), new ArrayList<>(), DriverCompletionInfo.EMPTY, null));
} else {
executeOptimizedPlan(request, executionInfo, planRunner, optimizedPlan(p), l);
}
}));
}
}
);