-
Notifications
You must be signed in to change notification settings - Fork 25.6k
ES|QL: Add grammar for SET instruction #134029
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
ES|QL: Add grammar for SET instruction #134029
Conversation
import java.util.List; | ||
import java.util.Objects; | ||
|
||
public class QuerySettings { |
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 treating this as a command or as part of the AST in general (ie. it's not a LogicalPlan or a Node).
It's on purpose, we don't want it to be part of the query (for now at least), so it doesn't need resolution/serialization/traversal for now.
Ah, I'm not calling it Set
. There is only one Set
in Java.
Suggestions for a better name are welcome of course
Hi @luigidellaquila, I've created a changelog YAML for you. |
: {this.isDevVersion()}? setCommand+ singleStatement EOF | ||
| singleStatement EOF | ||
; |
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 will become
statements
: setCommand* singleStatement EOF
;
as soon as it's out of dev mode
Pinging @elastic/es-analytical-engine (Team:Analytics) |
|
||
public class QuerySettings { | ||
|
||
private final List<Alias> fields; |
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 wonder if it is worth storing it in a name->value
map? I suspect it will be accessed by name most of the times
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 just realized we might want to store multiple settings with same name in order to be able to resolve correct one as well as warn about others. Probably list is fine as long as we have an accessor by setting name as well as a flat structure.
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 @idegtiarenko, I added a higher level method EsqlQuery.setting(name)
that encapsulates the logic for value masking (last one wins).
I also refactored the tests a bit, now they should be more readable.
assertThat(query.settings().size(), is(1)); | ||
assertThat(query.settings().get(0).fields().size(), is(1)); | ||
assertThat(query.settings().get(0).fields().get(0).name(), is("foo")); | ||
assertThat(query.settings().get(0).fields().get(0).child().fold(FoldContext.small()), is(BytesRefs.toBytesRef("bar"))); |
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 looks a bit too complex with 2 nested lists. Is it possible to collect query settings into a flat structure?
I imagine usage could become much simpler if we have something like assertThat(query.settings().setting("foo").fold(..), is(..))
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 simplified this, both with an API method and with some helper methods in the test class, so that I can both check the correctness of the high level logic and the small details in the parsed objects.
…nto esql/project_routing
Following up on the off-line discussions, we have two options here:
In both cases we'll allow multiple SET statements in the same query, eg. the following will be valid also with the second option.
My understanding is that Kibana will use one field per SET, but as a user I tend to prefer a single SET and a comma separated list of The PR now implements the second option (multiple fields in the same SET, multiple SET in the same query), but we can easily add limitations if we think it's too much. @quackaplop WDYT? |
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.
👍 from my side.
I believe this change could be merged once we have confirmation on multiple key-value pairs per SET
We should only allow a single field per set. We can consider expanding it further, but we don't need this now |
: SET setFields SEMICOLON | ||
; | ||
|
||
setFields |
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.
Pretty sure we do not need this one
Thanks @quackaplop, I simplified the grammar and the code in general, now we only allow a single field per SET |
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/EsqlQuery.java
Outdated
Show resolved
Hide resolved
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/session/EsqlSession.java
Outdated
Show resolved
Hide resolved
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/session/EsqlSession.java
Outdated
Show resolved
Hide resolved
…nto esql/project_routing
|
||
import java.util.Objects; | ||
|
||
public class QuerySetting { |
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.
Do we want to add toString
here?
import java.util.List; | ||
|
||
public record EsqlStatement(LogicalPlan plan, List<QuerySetting> settings) { | ||
/** |
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.
Do we want to add toString here mainly for reporting? Also, how do we feel about this sitting under "plan.logical", given that it is actually not deriving from LogicalPlan
?
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.
how do we feel about this sitting under "plan.logical", given that it is actually not deriving from LogicalPlan
I don't have a strong opinion on this, I put it there just because it gets parsed together with the logical plan, but "logically" it's a different thing. Let me move it to a separate package
private EsqlStatement parse(String query, QueryParams params) { | ||
var parsed = new EsqlParser().createQuery(query, params, planTelemetry, configuration); | ||
if (LOGGER.isDebugEnabled()) { | ||
LOGGER.debug("Parsed logical plan:\n{}", parsed.plan()); |
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.
...and maybe using toString
here instead?
Thanks for the feedback @idegtiarenko @quackaplop, if there are no further observations I'll go on and merge |
…SET and INLINESTATS commands) (#134358) Three PRs have just been merged that cause failures in `test-release`, and a third PR changes ES|QL railroad diagrams for another recently released change to `KNN` (also a snapshot-only feature). * #132729 - `DecayTests` has over 300 failures * #134029 - `ParsingTests` had six new failures * #124725 - Failures in `VerifierTests` and `OptimizerVerificationTests` This PR attempts to fix all in one, because if we do this in separate PRs they will fail due to the failures cause by the other PRs.
…SET and INLINESTATS commands) (elastic#134358) Three PRs have just been merged that cause failures in `test-release`, and a third PR changes ES|QL railroad diagrams for another recently released change to `KNN` (also a snapshot-only feature). * elastic#132729 - `DecayTests` has over 300 failures * elastic#134029 - `ParsingTests` had six new failures * elastic#124725 - Failures in `VerifierTests` and `OptimizerVerificationTests` This PR attempts to fix all in one, because if we do this in separate PRs they will fail due to the failures cause by the other PRs.
## Summary Closes #233942 Implements parsing for `SET` pseudo-commands, which come before the main query. ``` SET key1 = 123; SET key2 = "asdf"; FROM index | LIMIT 123 ``` In `query` AST node introduces `header` section, which contain AST nodes before the main command. Although each `SET` instruction can now have a single key-value pair, it is implemented such that it will be able to store a list of those pairs. The reason is because in Elasticsearch team first implemented it to hold multiple key-value pairs, then changed to store only one, further they commented ([see thread](elastic/elasticsearch#134029)) that they may add support for a list of key-value pairs to `SET` back. ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios
## Summary Closes elastic#233942 Implements parsing for `SET` pseudo-commands, which come before the main query. ``` SET key1 = 123; SET key2 = "asdf"; FROM index | LIMIT 123 ``` In `query` AST node introduces `header` section, which contain AST nodes before the main command. Although each `SET` instruction can now have a single key-value pair, it is implemented such that it will be able to store a list of those pairs. The reason is because in Elasticsearch team first implemented it to hold multiple key-value pairs, then changed to store only one, further they commented ([see thread](elastic/elasticsearch#134029)) that they may add support for a list of key-value pairs to `SET` back. ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios
Adding grammar for a SET instruction (not properly a command) to pass settings to a query