Skip to content

ESQL: Prune InlineJoin right aggregations by delegating to the child plan - #139357

Merged
elasticsearchmachine merged 3 commits into
elastic:mainfrom
astefan:138283_fix
Dec 12, 2025
Merged

elasticsearchmachine merged 3 commits into
elastic:mainfrom
astefan:138283_fix

Conversation

@astefan

@astefan astefan commented Dec 11, 2025

Copy link
Copy Markdown
Contributor

Fixes #138283

if (aggregate.groupings().containsAll(remaining)) {
p = aggregate.child();
}
// TODO: deal with prunning partial groupings in InlineJoin right side

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am aware of another type of pruning bug regarding groupings pruning, but I chose to deal with that one in a separate PR.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

private static LogicalPlan pruneColumnsInInlineJoinRight(InlineJoin ij, AttributeSet.Builder used, Holder<Boolean> recheck) {
LogicalPlan p = ij;

used.addAll(ij.references());

@astefan astefan Dec 11, 2025 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was essential. Now the references are added to used after pruning happens, which makes much more sense imo.

@bpintea bpintea left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks Andrei. This turned out a bit tricky.
LGTM, left some questions only.

// if the right has no aggregation anymore, but it still has some other plans (evals, projects),
// we keep those and integrate them into the main plan. The InlineJoin is also replaced entirely.
p = InlineJoin.replaceStub(ij.left(), right);
p = new Project(ij.source(), p, mergeOutputExpressions(p.output(), ij.left().output()));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this have been:

Suggested change
p = new Project(ij.source(), p, mergeOutputExpressions(p.output(), ij.left().output()));
p = new Project(ij.source(), p, ij.output());

?
Maybe safer this computed way, though, only curious if it'd trigger some issues, as the output shouldn't change, I think.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The output of the InlineJoin has been (and my gut feeling is that still is with the GH issue I referenced above as the next bug to tackle) a tricky aspect. Unless the InlineJoin doesn't change/transform and a new Object is created, the output will stay the same once initialized. In the case of disappearing attributes (like some of the groupings, some of the aggregates), the output of the InlineJoin should reflect them. In this specific code, the left side becomes the Stub relation replacement for the right side and the resulting plan chunk is integrated in the main plan.

And with prunning the Aggregate completely, some stuff are not there in the output anymore and in one of the unit tests this was visible. And again, thank you for adding those unit tests, they were both a pain to deal with, but also a lifesaver to help me navigate the tricky aspects of InlineJoin pruning.

if (inlineJoin) {
p = emptyLocalRelation(aggregate);
// all aggregates are pruned, delegate to child plan
p = aggregate.child();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't we need a Projection here?
I suppose this is a stub, but is it always a stub?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be a Stub indeed, but we shouldn't assume that. New commands, new rules can add stuff in there.
Regarding the Projection, our tests are so good in this regard, btw, and if something doesn't break, it should be ok. Conceptually speaking, though, if whatever the output of the Agg is/was, at this point its output doesn't matter anymore and I don't think we need an explicit projection.

// already part of the IJ output (from the left-hand side): the agg can just be dropped entirely.
p = emptyLocalRelation(aggregate);
if (aggregate.groupings().containsAll(remaining)) {
p = aggregate.child();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, is it always safe?

@astefan astefan added the auto-backport Automatically create backport pull requests when merged label Dec 12, 2025
@elasticsearchmachine elasticsearchmachine added the Team:Analytics Meta label for analytical engine team (ESQL/Aggs/Geo) label Dec 12, 2025
@elasticsearchmachine

Copy link
Copy Markdown
Collaborator

Pinging @elastic/es-analytical-engine (Team:Analytics)

@elasticsearchmachine

Copy link
Copy Markdown
Collaborator

Hi @astefan, I've created a changelog YAML for you.

@astefan astefan added the auto-merge-without-approval Automatically merge pull request when CI checks pass (NB doesn't wait for reviews!) label Dec 12, 2025
@elasticsearchmachine
elasticsearchmachine merged commit 653e495 into elastic:main Dec 12, 2025
35 checks passed
@astefan
astefan deleted the 138283_fix branch December 12, 2025 19:35
parkertimmins pushed a commit to parkertimmins/elasticsearch that referenced this pull request Dec 17, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

:Analytics/ES|QL AKA ESQL auto-backport Automatically create backport pull requests when merged auto-merge-without-approval Automatically merge pull request when CI checks pass (NB doesn't wait for reviews!) >bug Team:Analytics Meta label for analytical engine team (ESQL/Aggs/Geo) v9.2.4 v9.3.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ESQL: incorrect planning: VerificationException, Output has changed

3 participants