-
Notifications
You must be signed in to change notification settings - Fork 24.9k
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
ESQL: Introduce language versioning to REST API #106824
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for tackling this! I think this is a great first draft. I've left a bunch of comments, but I think this is the right direction.
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/version/EsqlVersion.java
Outdated
Show resolved
Hide resolved
NIGHTLY(Integer.MAX_VALUE, Integer.MAX_VALUE, "\uD83D\uDE34"), | ||
PARTY_POPPER(2024, 4, "\uD83C\uDF89"); | ||
|
||
EsqlVersion(int year, int month, String emoji) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we think we might need to serialize this, we should explicitly pass in an ordinal value for serialization (that way it's proof against re-ordering the constants or deleting one). I don't know that we'll have to serialize these, but in case you aren't familiar with that pattern, I wanted to call it out.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Discussed with Mark: will add a disambiguation counter for good measure, so versions will be 2024.04.01.🎉
and if we end up really having to release two language versions in a month, there may be a 2024.04.02.💥
.
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/version/EsqlVersion.java
Outdated
Show resolved
Hide resolved
"[" + RequestXContent.ESQL_VERSION_FIELD + "] has invalid value [" + esqlVersion + "]", | ||
validationException | ||
); | ||
} else if (version == EsqlVersion.NIGHTLY && Build.current().isSnapshot() == false) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thinking out loud - does the snapshot check belong here, or in the EsqlVersion.parse
method? I can see arguments for both.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, personally I do think it belongs here - EsqlVersion
shouldn't need to worry about where we permit certain versions to be used IMHO, and why; also, this allows to keep EsqlVersion.parse
simple: either the string is a valid version or it's not - otherwise we'd have to throw an exception containing the reason why parsing failed and catch it in EsqlQueryRequest.validate()
. We might also parse versions coming from elsewhere in the future, and wouldn't want to prevent parsing of "nightly" just because we're not on a snapshot version.
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlQueryRequest.java
Show resolved
Hide resolved
x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/esql/action/EsqlQueryRequest.java
Show resolved
Hide resolved
@@ -46,10 +46,12 @@ final class RequestXContent { | |||
PARAM_PARSER.declareString(constructorArg(), TYPE); | |||
} | |||
|
|||
private static final ParseField QUERY_FIELD = new ParseField("query"); | |||
// TODO: Maybe esql_version would be better? This looks like there's a JSON attribute `esql` with subattribute `version`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, we should probably think about that a bit. Worth discussing with Kibana as well. For future proofing, I wonder if we want to set up a whole esql object, something like
"esql": {
"version": "2024.04.🎉 ",
"whatever_future_setting": "goes_here"
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Discussed with the team: probably just {"query": "...", "version": "2024.04.01.🎉"}
is fine.
x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/version/EsqlVersionTests.java
Outdated
Show resolved
Hide resolved
Hi @alex-spies, I've created a changelog YAML for you. |
Pinging @elastic/es-analytical-engine (Team:Analytics) |
import java.util.LinkedHashMap; | ||
import java.util.Map; | ||
|
||
public enum EsqlVersion implements VersionId<EsqlVersion> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Better make this a class similar to Version
- enum are quite restrictive and impossible to extend.
Having a class gives us future extension points - in the worse case we won't use them and the class will be like an enum.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can flip it to a class with constants when we need that. If we can get away with an enum
for a while I'd prefer that.
} | ||
|
||
private int year; | ||
private int month; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
month
can be made byte
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense; I'd like to still use an int
in the constructor. though, for easier readability if that's good with you?
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/version/EsqlVersion.java
Outdated
Show resolved
Hide resolved
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlQueryRequest.java
Show resolved
Hide resolved
for (EsqlVersion version : EsqlVersion.values()) { | ||
EsqlVersion existingVersionForKey = null; | ||
existingVersionForKey = stringToVersion.put(version.versionStringWithoutEmoji(), version); | ||
assert existingVersionForKey == null; | ||
existingVersionForKey = stringToVersion.put(version.toString(), version); | ||
assert existingVersionForKey == null; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for (EsqlVersion version : EsqlVersion.values()) { | |
EsqlVersion existingVersionForKey = null; | |
existingVersionForKey = stringToVersion.put(version.versionStringWithoutEmoji(), version); | |
assert existingVersionForKey == null; | |
existingVersionForKey = stringToVersion.put(version.toString(), version); | |
assert existingVersionForKey == null; | |
} | |
for (EsqlVersion version : EsqlVersion.values()) { | |
assert null == stringToVersion.put(version.versionStringWithoutEmoji(), version); | |
assert null == stringToVersion.put(version.toString(), version); | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I actually prefer an explicit throw here rather than just an assert. This should run once per instance of Elasticsearch, I don't think we need the performance gain of being able to disable asserts in production.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not entirely sure how assert
works, but I'd be worried that putting these onto one line will make it not perform the put
if assertions are disabled. FWIW, it doesn't really matter if it runs it or not - it'll slow down a reader either way. But the assert
on it's own line is fin.
You could make it a hard test. The extra test on startup is probably not going to hurt us.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This suggestion looks cleaner, but is not equivalent; disabling assertions breaks the version parsing altogether as no version strings are added to the stringToVersion
map anymore.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll add an explicit throw new AssertionError(...)
.
x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/action/EsqlQueryRequestTests.java
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, I think you should have tests for the functionality inherited from VersionId
interface, ie comparison of versions based on their id
.
|
||
@Override | ||
public int id() { | ||
return this == NIGHTLY ? Integer.MAX_VALUE : (10000 * year + 100 * month + revision); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we should have a test that generates the IDs for all the versions and makes sure there are no duplicates. There shouldn't be, but if someone typos a month I want something to fail.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No dups are already enforced in the construction of the map String -> Version
. I'll add a test, though, that ensures a strict ordering of the versions based on their id
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/action/EsqlQueryRequestTests.java
Outdated
Show resolved
Hide resolved
Might cause trouble for people on a terminal.
💚 All backports created successfully
Questions ?Please refer to the Backport tool documentation |
For the _query endpoint, add a parameter for the ESQL language version to the JSON payload. For now, it is optional and is only validated with no further action. (cherry picked from commit 147f5a0) # Conflicts: # x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/esql/action/EsqlQueryRequest.java # x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/esql/action/EsqlQueryRequestBuilder.java # x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlQueryRequest.java # x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlQueryRequestBuilder.java # x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/RequestXContent.java
For the _query endpoint, add a parameter for the ESQL language version to the JSON payload. For now, it is optional and is only validated with no further action. (cherry picked from commit 147f5a0) # Conflicts: # x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/esql/action/EsqlQueryRequest.java # x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/esql/action/EsqlQueryRequestBuilder.java # x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlQueryRequest.java # x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlQueryRequestBuilder.java # x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/RequestXContent.java # x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/action/EsqlQueryRequestTests.java
💚 All backports created successfully
Questions ?Please refer to the Backport tool documentation |
For the _query endpoint, add a parameter for the ESQL language version to the JSON payload. For now, it is optional and is only validated with no further action. (cherry picked from commit 147f5a0) # Conflicts: # x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/esql/action/EsqlQueryRequest.java # x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/esql/action/EsqlQueryRequestBuilder.java # x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlQueryRequest.java # x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlQueryRequestBuilder.java # x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/RequestXContent.java # x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/action/EsqlQueryRequestTests.java
Docs for #106824. Does not cover the [REST API specs](https://github.com/elastic/elasticsearch/blob/main/rest-api-spec/src/main/resources/rest-api-spec/api/esql.query.json) as these don't cover the request body.
First part of #104890
For the
_query
endpoint, add a parameter for the language version to the JSON payload. This will become a required parameter in a follow-up PR; in this PR, this parameter is only validated with no further action.