Skip to content

ESQL: Fix mv_expand inconsistent column order #129745

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

Merged
merged 14 commits into from
Jul 17, 2025

Conversation

kanoshiou
Copy link
Contributor

@kanoshiou kanoshiou commented Jun 20, 2025

The new attribute generated by mv_expand should remain in the original field positions. However, when ProjectAwayColumns is executed top-down and encounters an MvExpandExec with the child plan of ExchangeExec, the inserted Project may not respect that order.

Closes #129000

@elasticsearchmachine elasticsearchmachine added needs:triage Requires assignment of a team area label v9.1.0 external-contributor Pull request authored by a developer outside the Elasticsearch team labels Jun 20, 2025
kanoshiou and others added 2 commits July 2, 2025 09:53
# Conflicts:
#	x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java
@PeteGillinElastic PeteGillinElastic added :Analytics/ES|QL AKA ESQL and removed needs:triage Requires assignment of a team area label labels Jul 11, 2025
@elasticsearchmachine elasticsearchmachine added the Team:Analytics Meta label for analytical engine team (ESQL/Aggs/Geo) label Jul 11, 2025
@elasticsearchmachine
Copy link
Collaborator

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

Copy link
Contributor

@alex-spies alex-spies left a comment

Choose a reason for hiding this comment

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

Super nice find, thank you @kanoshiou !

I think the fix would work, but I'd like to attempt a fix that will also work for other plan nodes that we add in the future and might work similarly to MV_EXPAND; see my suggestion below.

@alex-spies alex-spies self-assigned this Jul 15, 2025
@alex-spies
Copy link
Contributor

Thanks again for your contribution @kanoshiou !

Do you mind if we push to your PR in order to try and augment the fix as described here?

@alex-spies alex-spies added >bug v8.19.0 v9.1.0 v9.0.5 v8.18.5 auto-backport Automatically create backport pull requests when merged labels Jul 15, 2025
@kanoshiou
Copy link
Contributor Author

Thanks for the review, @alex-spie!

I've updated the branch based on your comments and please feel free to push changes as needed!

Copy link
Contributor

@alex-spies alex-spies left a comment

Choose a reason for hiding this comment

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

Great, @kanoshiou , thanks for the iteration! This is very close. I only have a final set of remarks; once the remarks in ProjectAwayColumns.java are addressed, this LGTM.

Comment on lines 84 to 87
requiredAttrBuilder.remove(attribute);
}
}
output.addAll(requiredAttrBuilder.build());
Copy link
Contributor

Choose a reason for hiding this comment

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

Hm, adding the remaining required attributes is not wrong, but the requiredAttrBuilder should really be empty after removing all the attributes that we added to output, because all the required attributes have to be in the fragment's outputSet - otherwise, we're constructing an invalid plan.

Rather than removing attributes from requiredAttrBuilder and performing this addAll here, I think we can just assert that the size of output and the size of requiredAttrBuilder are the same. (Although the PlanConsistencyChecker will likely also catch this.)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

all the required attributes have to be in the fragment's outputSet

I gave it some thought, and it does make sense.

assert that the size of output and the size of requiredAttrBuilder are the same

I have a question: my understanding is that requiredAttrBuilder should be a subset of output, meaning its size should be less than or equal to that of output. Why, then, are they the same size here? If their sizes are the same, then why bother maintaining requiredAttrBuilder? Wouldn't it be ok to just use output for execution?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sorry, I confused outputSet with the new array list output.

Copy link
Contributor

Choose a reason for hiding this comment

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

Well, I was wrong. There's a bug in the planning of remote enrich that can make it so that the output of the fragment doesn't contain an attribute, but it's actually physically there and the projection needs to include it, or a downstream TopN won't know what attribute to sort on. This is what happened in #118531.

@kanoshiou , I'll re-instate your initial approach (but still using output rather than outputSet) and I'll add a comment to the problem.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks @alex-spies!

@@ -5698,9 +5749,9 @@ public void testPushTopNKeywordToSource() {
var exchange = asRemoteExchange(topN.child());

project = as(exchange.child(), ProjectExec.class);
assertThat(names(project.projections()), contains("abbrev", "name", "location", "country", "city"));
assertThat(names(project.projections()), contains("abbrev", "city", "country", "location", "name"));
Copy link
Contributor

Choose a reason for hiding this comment

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

Nice. The only reason these queries produced correct output was because there was a Project at the top that made the attribute order here irrelevant; but actually, we had changed it locally, and this shows that ProjectAwayColumns was never fully correct to begin with.

@alex-spies
Copy link
Contributor

@elasticmachine test this please


testMvExpandInconsistentColumnOrder3
required_capability: fix_mv_expand_inconsistent_column_order
from message_types,languages_lookup_non_unique_key
Copy link
Contributor

Choose a reason for hiding this comment

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

The multi cluster tests don't like the languages_lookup_non_unique_key index because it's a lookup index, and it's treated differently; the languages index is used in an enrich policy, and the multicluster tests also treat such indices differently. Finally, the CSV tests don't like having more than 1 index.

I'm going to push an update that replaces these tests by ones that use indices that our csv tests and multi cluster tests don't treat especially :)

Indices used in enrich policies, as lookup indices, or multiple indices
in the FROM pattern are all treated differently by different test
suites.
@alex-spies
Copy link
Contributor

@elasticmachine test this please

@kanoshiou
Copy link
Contributor Author

Thanks @alex-spies. I've updated the branch and please review when you have a moment.

Copy link
Contributor

@alex-spies alex-spies left a comment

Choose a reason for hiding this comment

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

This is great, thanks @kanoshiou !

@alex-spies
Copy link
Contributor

@elasticmachine test this please

Keep all the attributes from requiredAttrBuilder in the projection, even
when they're not in the fragment's output due to a bug.
@alex-spies
Copy link
Contributor

@elasticmachine test this please

@kanoshiou
Copy link
Contributor Author

Oh, I forgot to remove this line. It seems the CI test has not started yet. I'll update the branch shortly.

@kanoshiou
Copy link
Contributor Author

Please start a new round of test @alex-spies, thank you!

@alex-spies
Copy link
Contributor

@elasticmachine test this please

@alex-spies alex-spies merged commit ac0c508 into elastic:main Jul 17, 2025
34 checks passed
@alex-spies
Copy link
Contributor

Here we go! Thanks again @kanoshiou !

alex-spies pushed a commit to alex-spies/elasticsearch that referenced this pull request Jul 17, 2025
The new attribute generated by MV_EXPAND should remain in the original position. The projection added by ProjectAwayColumns does not respect the original order of attributes.

Make ProjectAwayColumns respect the order of attributes to fix this.
alex-spies pushed a commit to alex-spies/elasticsearch that referenced this pull request Jul 17, 2025
The new attribute generated by MV_EXPAND should remain in the original position. The projection added by ProjectAwayColumns does not respect the original order of attributes.

Make ProjectAwayColumns respect the order of attributes to fix this.

(cherry picked from commit ac0c508)

# Conflicts:
#	x-pack/plugin/esql/qa/server/src/main/java/org/elasticsearch/xpack/esql/qa/rest/generative/GenerativeRestTest.java
#	x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java
#	x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/optimizer/rules/physical/ProjectAwayColumns.java
#	x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/PhysicalPlanOptimizerTests.java
elasticsearchmachine pushed a commit that referenced this pull request Jul 17, 2025
The new attribute generated by MV_EXPAND should remain in the original position. The projection added by ProjectAwayColumns does not respect the original order of attributes.

Make ProjectAwayColumns respect the order of attributes to fix this.

Co-authored-by: kanoshiou <[email protected]>
ywangd pushed a commit to ywangd/elasticsearch that referenced this pull request Jul 17, 2025
The new attribute generated by MV_EXPAND should remain in the original position. The projection added by ProjectAwayColumns does not respect the original order of attributes.

Make ProjectAwayColumns respect the order of attributes to fix this.
elasticsearchmachine pushed a commit that referenced this pull request Jul 17, 2025
…1428)

* ESQL: Fix inconsistent column order in MV_EXPAND (#129745)

The new attribute generated by MV_EXPAND should remain in the original position. The projection added by ProjectAwayColumns does not respect the original order of attributes.

Make ProjectAwayColumns respect the order of attributes to fix this.

(cherry picked from commit ac0c508)

# Conflicts:
#	x-pack/plugin/esql/qa/server/src/main/java/org/elasticsearch/xpack/esql/qa/rest/generative/GenerativeRestTest.java
#	x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java
#	x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/optimizer/rules/physical/ProjectAwayColumns.java
#	x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/PhysicalPlanOptimizerTests.java

* Adapt approach for missing AttributeSetBuilder

Builder is only available on main/9.x, so we have to correctly use the
immutable AttributeSets directly.

---------

Co-authored-by: kanoshiou <[email protected]>
alex-spies pushed a commit to alex-spies/elasticsearch that referenced this pull request Jul 17, 2025
The new attribute generated by MV_EXPAND should remain in the original position. The projection added by ProjectAwayColumns does not respect the original order of attributes.

Make ProjectAwayColumns respect the order of attributes to fix this.

(cherry picked from commit ac0c508)

# Conflicts:
#	x-pack/plugin/esql/qa/server/src/main/java/org/elasticsearch/xpack/esql/qa/rest/generative/GenerativeRestTest.java
#	x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java
@alex-spies
Copy link
Contributor

💔 Some backports could not be created

Status Branch Result
9.0
8.19
8.18 Could not create pull request: fetch failed

Manual backport

To create the backport manually run:

backport --pr 129745

Questions ?

Please refer to the Backport tool documentation

alex-spies pushed a commit to alex-spies/elasticsearch that referenced this pull request Jul 17, 2025
The new attribute generated by MV_EXPAND should remain in the original position. The projection added by ProjectAwayColumns does not respect the original order of attributes.

Make ProjectAwayColumns respect the order of attributes to fix this.

(cherry picked from commit ac0c508)

# Conflicts:
#	x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/expression/AttributeSet.java
#	x-pack/plugin/esql/qa/server/src/main/java/org/elasticsearch/xpack/esql/qa/rest/generative/GenerativeRestTest.java
#	x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java
#	x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/optimizer/rules/physical/ProjectAwayColumns.java
#	x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/PhysicalPlanOptimizerTests.java
elasticsearchmachine pushed a commit that referenced this pull request Jul 17, 2025
The new attribute generated by MV_EXPAND should remain in the original position. The projection added by ProjectAwayColumns does not respect the original order of attributes.

Make ProjectAwayColumns respect the order of attributes to fix this.

(cherry picked from commit ac0c508)

# Conflicts:
#	x-pack/plugin/esql/qa/server/src/main/java/org/elasticsearch/xpack/esql/qa/rest/generative/GenerativeRestTest.java
#	x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java

Co-authored-by: kanoshiou <[email protected]>
elasticsearchmachine pushed a commit that referenced this pull request Jul 17, 2025
The new attribute generated by MV_EXPAND should remain in the original position. The projection added by ProjectAwayColumns does not respect the original order of attributes.

Make ProjectAwayColumns respect the order of attributes to fix this.

(cherry picked from commit ac0c508)

# Conflicts:
#	x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/expression/AttributeSet.java
#	x-pack/plugin/esql/qa/server/src/main/java/org/elasticsearch/xpack/esql/qa/rest/generative/GenerativeRestTest.java
#	x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java
#	x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/optimizer/rules/physical/ProjectAwayColumns.java
#	x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/PhysicalPlanOptimizerTests.java

Co-authored-by: kanoshiou <[email protected]>
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 backport pending >bug external-contributor Pull request authored by a developer outside the Elasticsearch team Team:Analytics Meta label for analytical engine team (ESQL/Aggs/Geo) v8.18.5 v8.19.0 v9.0.5 v9.1.0 v9.2.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

ES|QL: inconsistent column order
4 participants