|
97 | 97 | import org.elasticsearch.xpack.esql.optimizer.rules.logical.OptimizerRules;
|
98 | 98 | import org.elasticsearch.xpack.esql.optimizer.rules.logical.PruneRedundantOrderBy;
|
99 | 99 | import org.elasticsearch.xpack.esql.optimizer.rules.logical.PushDownAndCombineLimits;
|
| 100 | +import org.elasticsearch.xpack.esql.optimizer.rules.logical.PushDownAndCombineOrderBy; |
100 | 101 | import org.elasticsearch.xpack.esql.optimizer.rules.logical.PushDownEnrich;
|
101 | 102 | import org.elasticsearch.xpack.esql.optimizer.rules.logical.PushDownEval;
|
102 | 103 | import org.elasticsearch.xpack.esql.optimizer.rules.logical.PushDownInferencePlan;
|
|
165 | 166 | import static org.elasticsearch.xpack.esql.EsqlTestUtils.localSource;
|
166 | 167 | import static org.elasticsearch.xpack.esql.EsqlTestUtils.randomLiteral;
|
167 | 168 | import static org.elasticsearch.xpack.esql.EsqlTestUtils.referenceAttribute;
|
| 169 | +import static org.elasticsearch.xpack.esql.EsqlTestUtils.relation; |
168 | 170 | import static org.elasticsearch.xpack.esql.EsqlTestUtils.singleValue;
|
169 | 171 | import static org.elasticsearch.xpack.esql.EsqlTestUtils.withDefaultLimitWarning;
|
170 | 172 | import static org.elasticsearch.xpack.esql.analysis.Analyzer.NO_FIELDS;
|
@@ -5738,6 +5740,51 @@ public void testPushShadowingGeneratingPlanPastRenamingProjectWithResolution() {
|
5738 | 5740 | }
|
5739 | 5741 | }
|
5740 | 5742 |
|
| 5743 | + /* |
| 5744 | + * Test for: https://github.com/elastic/elasticsearch/issues/134407 |
| 5745 | + * |
| 5746 | + * Input: |
| 5747 | + * OrderBy[[Order[a{f}#2,ASC,ANY]]] |
| 5748 | + * \_Project[[aTemp{r}#3 AS a#2]] |
| 5749 | + * \_Eval[[null[INTEGER] AS aTemp#3]] |
| 5750 | + * \_EsRelation[uYiPqAFD][LOOKUP][a{f}#2] |
| 5751 | + * |
| 5752 | + * Output: |
| 5753 | + * Project[[aTemp{r}#3 AS a#2]] |
| 5754 | + * \_OrderBy[[Order[aTemp{r}#3,ASC,ANY]]] |
| 5755 | + * \_Eval[[null[INTEGER] AS aTemp#3]] |
| 5756 | + * \_EsRelation[uYiPqAFD][LOOKUP][a{f}#2] |
| 5757 | + */ |
| 5758 | + public void testPushDownOrderByPastRename() { |
| 5759 | + FieldAttribute a = getFieldAttribute("a"); |
| 5760 | + EsRelation relation = relation().withAttributes(List.of(a)); |
| 5761 | + |
| 5762 | + Alias aTemp = new Alias(EMPTY, "aTemp", new Literal(EMPTY, null, a.dataType())); |
| 5763 | + Eval eval = new Eval(EMPTY, relation, List.of(aTemp)); |
| 5764 | + |
| 5765 | + // Rename the null literal to "a" so that the OrderBy can refer to it. Requires re-using the id of original "a" attribute. |
| 5766 | + Alias aliasA = new Alias(EMPTY, "a", aTemp.toAttribute(), a.id()); |
| 5767 | + Project project = new Project(EMPTY, eval, List.of(aliasA)); |
| 5768 | + |
| 5769 | + // OrderBy sorts on original `a` attribute; after pushing down it should sort on aTemp. |
| 5770 | + OrderBy orderBy = new OrderBy(EMPTY, project, List.of(new Order(EMPTY, a, Order.OrderDirection.ASC, Order.NullsPosition.ANY))); |
| 5771 | + |
| 5772 | + LogicalPlan optimized = new PushDownAndCombineOrderBy().apply(orderBy); |
| 5773 | + |
| 5774 | + var projectOut = as(optimized, Project.class); |
| 5775 | + assertThat(projectOut.projections(), equalTo(project.projections())); |
| 5776 | + var orderByOutput = as(projectOut.child(), OrderBy.class); |
| 5777 | + var orderAttr = as(orderByOutput.order().getFirst().child(), ReferenceAttribute.class); |
| 5778 | + |
| 5779 | + // the actual fix test |
| 5780 | + assertThat(orderAttr.name(), equalTo("aTemp")); |
| 5781 | + assertThat(orderAttr.id(), equalTo(aTemp.id())); |
| 5782 | + |
| 5783 | + var evalOutput = as(orderByOutput.child(), Eval.class); |
| 5784 | + assertThat(evalOutput.fields(), equalTo(eval.fields())); |
| 5785 | + assertThat(evalOutput.child(), equalTo(relation)); |
| 5786 | + } |
| 5787 | + |
5741 | 5788 | /**
|
5742 | 5789 | * Expects
|
5743 | 5790 | * <pre>{@code
|
|
0 commit comments