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
Show file tree
Hide file tree
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
Expand Up @@ -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;
Expand Down Expand Up @@ -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}.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}));
}
}
);
Expand Down