Skip to content

Commit d8c221a

Browse files
committed
Avoid inconsistent plans
1 parent b042096 commit d8c221a

File tree

1 file changed

+14
-14
lines changed

1 file changed

+14
-14
lines changed

x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/optimizer/rules/logical/PushDownMvExpandPastProject.java

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ public final class PushDownMvExpandPastProject extends OptimizerRules.OptimizerR
2525
protected LogicalPlan rule(MvExpand mvExpand) {
2626
if (mvExpand.child() instanceof Project pj) {
2727
List<NamedExpression> projections = new ArrayList<>(pj.projections());
28+
LogicalPlan finalChild = pj.child();
29+
NamedExpression finalTarget = mvExpand.target();
30+
Attribute expanded = mvExpand.expanded();
2831

2932
// Skip if the expanded field has the same name as a field in the projection's input set, and
3033
// the projection shadows that specific field from the projection input set.
@@ -34,7 +37,7 @@ protected LogicalPlan rule(MvExpand mvExpand) {
3437
// MvExpand[salary{r}#168,salary{r}#175]
3538
// \_Project[[$$salary$converted_to$keyword{r$}#178 AS salary#168]]
3639
// \_UnionAll[[salary{r}#174, $$salary$converted_to$keyword{r$}#178]]
37-
String expandedFieldName = mvExpand.expanded().name();
40+
String expandedFieldName = expanded.name();
3841
Set<String> inputNames = pj.inputSet().stream().map(NamedExpression::name).collect(Collectors.toSet());
3942
if (projections.stream()
4043
.anyMatch(
@@ -47,9 +50,8 @@ protected LogicalPlan rule(MvExpand mvExpand) {
4750

4851
// Find if the target is aliased in the project and create an alias with temporary names for it.
4952
for (int i = 0; i < projections.size(); i++) {
50-
NamedExpression projection = projections.get(i);
51-
if (projection instanceof Alias alias) {
52-
if (alias.toAttribute().semanticEquals(mvExpand.target().toAttribute())) {
53+
if (projections.get(i) instanceof Alias alias) {
54+
if (alias.toAttribute().semanticEquals(finalTarget.toAttribute())) {
5355
// Check if the alias's original field (child) is referenced elsewhere in the projections.
5456
// If the original field is not referenced by any other projection or alias,
5557
// we don't need to inject an Eval to preserve it, and can safely resolve renames and push down.
@@ -59,7 +61,7 @@ protected LogicalPlan rule(MvExpand mvExpand) {
5961
|| ne instanceof Alias as && as.child().semanticEquals(alias.child()) && as != alias
6062
) == false) {
6163
// The alias's original field is not referenced elsewhere, no need to preserve it,
62-
mvExpand = PushDownUtils.resolveRenamesFromProject(mvExpand, pj);
64+
finalTarget = (NamedExpression) alias.child();
6365
break;
6466
}
6567

@@ -69,31 +71,29 @@ protected LogicalPlan rule(MvExpand mvExpand) {
6971
TemporaryNameUtils.temporaryName(alias.child(), alias.toAttribute(), 0),
7072
alias.child()
7173
);
72-
projections.set(i, mvExpand.expanded());
73-
pj = pj.replaceChild(new Eval(aliasAlias.source(), pj.child(), List.of(aliasAlias)));
74-
mvExpand = new MvExpand(mvExpand.source(), pj, aliasAlias.toAttribute(), mvExpand.expanded());
74+
projections.set(i, expanded);
75+
finalChild = new Eval(aliasAlias.source(), finalChild, List.of(aliasAlias));
76+
finalTarget = aliasAlias.toAttribute();
7577
break;
76-
} else if (alias.child().semanticEquals(mvExpand.target().toAttribute())) {
78+
} else if (alias.child().semanticEquals(finalTarget.toAttribute())) {
7779
// for query like: row a = 2 | eval b = a | keep * | mv_expand a
7880
Alias aliasAlias = new Alias(
7981
alias.source(),
8082
TemporaryNameUtils.temporaryName(alias.child(), alias.toAttribute(), 0),
8183
alias.child()
8284
);
8385
projections.set(i, alias.replaceChild(aliasAlias.toAttribute()));
84-
pj = pj.replaceChild(new Eval(aliasAlias.source(), pj.child(), List.of(aliasAlias)));
85-
mvExpand = mvExpand.replaceChild(pj);
86+
finalChild = new Eval(aliasAlias.source(), finalChild, List.of(aliasAlias));
8687
break;
8788
}
8889
}
8990
}
9091

9192
// Push down the MvExpand past the Project
92-
MvExpand pushedDownMvExpand = mvExpand.replaceChild(pj.child());
93+
MvExpand pushedDownMvExpand = new MvExpand(mvExpand.source(), finalChild, finalTarget, expanded);
9394

9495
// Update projections to point to the expanded attribute
95-
Attribute target = mvExpand.target().toAttribute();
96-
Attribute expanded = mvExpand.expanded();
96+
Attribute target = finalTarget.toAttribute();
9797
for (int i = 0; i < projections.size(); i++) {
9898
NamedExpression ne = projections.get(i);
9999
if (ne instanceof Alias alias && alias.child().semanticEquals(target)) {

0 commit comments

Comments
 (0)