-
Notifications
You must be signed in to change notification settings - Fork 25.1k
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: Reuse child outputSet inside the plan where possible #124611
Conversation
Avoid creating outputSet between nodes that passthrough their input Relates elastic#124395
Pinging @elastic/es-analytical-engine (Team:Analytics) |
Hi @costin, I've created a changelog YAML for you. |
The initial PR (making AttributeMap/Set immutable) become larger and ended up in chasing subtle bugs with planning - I've extracted this small change as it has a direct impact on queries with many 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.
Thanks @costin, I like the idea and I think it makes a lot of sense.
It only needs a little change to UnaryPlan
, see comment below.
@Override | ||
public AttributeSet outputSet() { | ||
return child().outputSet(); | ||
} | ||
|
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 afraid this is incorrect: now all the subplans that override output()
but not outputSet()
(eg. Eval
) return a wrong output set, based on the child rather than on the actual output
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 is dangerous, we normally don't have to override outputSet
but rely it to be constructed from output()
.
A IMHO better way that remains safe:
public AttributeSet outputSet() {
if (lazyOutputSet == null) {
List<Attribute> output = output();
lazyOutputSet = (output == child.output?) child.outputSet() : new AttributeSet(output);
}
return lazyOutputSet;
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 this change itself makes sense. I'd like it a little better if the improvements were tracked by benches - I think this would strongly benefit from a micro benchmark (or a nightly!) that demonstrates the effect of this improvement on execution times of our optimizer(s).
@Override | ||
public AttributeSet outputSet() { | ||
return child().outputSet(); | ||
} | ||
|
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 is dangerous, we normally don't have to override outputSet
but rely it to be constructed from output()
.
A IMHO better way that remains safe:
public AttributeSet outputSet() {
if (lazyOutputSet == null) {
List<Attribute> output = output();
lazyOutputSet = (output == child.output?) child.outputSet() : new AttributeSet(output);
}
return lazyOutputSet;
|
||
@Override | ||
public AttributeSet outputSet() { | ||
return child().outputSet(); |
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.
With a better default implementation of this in UnaryPlan
, this might be obsolete. Same goes for the corresponding overrides in the other classes.
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.
Love it!
LGTM, thanks @costin
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!
return child().output(); | ||
} |
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.
Out of scope, but I noticed this is redundant.
…24611) Avoid creating outputSet between nodes that passthrough their input Relates elastic#124395
…24611) Avoid creating outputSet between nodes that passthrough their input Relates elastic#124395
…24611) Avoid creating outputSet between nodes that passthrough their input Relates elastic#124395
Avoid creating outputSet between nodes that passthrough their input
Relates #124395