|
27 | 27 | import org.elasticsearch.xpack.esql.plan.logical.Sample; |
28 | 28 | import org.elasticsearch.xpack.esql.plan.logical.TopN; |
29 | 29 | import org.elasticsearch.xpack.esql.plan.logical.join.InlineJoin; |
| 30 | +import org.elasticsearch.xpack.esql.plan.logical.join.Join; |
30 | 31 | import org.elasticsearch.xpack.esql.plan.logical.join.JoinTypes; |
31 | 32 | import org.elasticsearch.xpack.esql.plan.logical.join.StubRelation; |
32 | 33 | import org.elasticsearch.xpack.esql.plan.logical.local.EsqlProject; |
@@ -902,6 +903,55 @@ public void testInlineStatsAfterEnrichAndSort() { |
902 | 903 | var stub = as(agg.child(), StubRelation.class); |
903 | 904 | } |
904 | 905 |
|
| 906 | + /** |
| 907 | + * Project[[abbrev{f}#20, scalerank{f}#22 AS backup_scalerank#5, language_name{f}#29 AS scalerank#13]] |
| 908 | + * \_Limit[1000[INTEGER],true,false] |
| 909 | + * \_Join[LEFT,[scalerank{f}#22],[language_code{f}#28],null] |
| 910 | + * |_TopN[[Order[abbrev{f}#20,DESC,FIRST]],1000[INTEGER],false] |
| 911 | + * | \_EsRelation[airports][abbrev{f}#20, city{f}#26, city_location{f}#27, coun..] |
| 912 | + * \_EsRelation[languages_lookup][LOOKUP][language_code{f}#28, language_name{f}#29] |
| 913 | + */ |
| 914 | + public void testInlineJoinPrunedAfterSortAndLookupJoin() { |
| 915 | + var query = """ |
| 916 | + FROM airports |
| 917 | + | EVAL backup_scalerank = scalerank |
| 918 | + | RENAME scalerank AS language_code |
| 919 | + | SORT abbrev DESC |
| 920 | + | LOOKUP JOIN languages_lookup ON language_code |
| 921 | + | RENAME language_name as scalerank |
| 922 | + | DROP language_code |
| 923 | + | INLINE STATS count=COUNT(*) BY scalerank |
| 924 | + | KEEP abbrev, *scalerank |
| 925 | + """; |
| 926 | + if (releaseBuildForInlineStats(query)) { |
| 927 | + return; |
| 928 | + } |
| 929 | + var plan = planAirports(query); |
| 930 | + |
| 931 | + var project = as(plan, Project.class); |
| 932 | + assertThat(Expressions.names(project.projections()), is(List.of("abbrev", "backup_scalerank", "scalerank"))); |
| 933 | + |
| 934 | + var limit = as(project.child(), Limit.class); |
| 935 | + assertThat(limit.limit().fold(FoldContext.small()), equalTo(1000)); |
| 936 | + |
| 937 | + var join = as(limit.child(), Join.class); |
| 938 | + assertThat(join.config().type(), is(JoinTypes.LEFT)); |
| 939 | + |
| 940 | + var topN = as(join.left(), TopN.class); |
| 941 | + assertThat(topN.limit().fold(FoldContext.small()), equalTo(1000)); |
| 942 | + assertThat(topN.order(), hasSize(1)); |
| 943 | + var order = as(topN.order().get(0), Order.class); |
| 944 | + assertThat(order.direction(), equalTo(Order.OrderDirection.DESC)); |
| 945 | + assertThat(order.nullsPosition(), equalTo(Order.NullsPosition.FIRST)); |
| 946 | + assertThat(Expressions.name(order.child()), is("abbrev")); |
| 947 | + |
| 948 | + var leftRelation = as(topN.child(), EsRelation.class); |
| 949 | + assertThat(leftRelation.concreteIndices(), is(Set.of("airports"))); |
| 950 | + |
| 951 | + var rightRelation = as(join.right(), EsRelation.class); |
| 952 | + assertThat(rightRelation.concreteIndices(), is(Set.of("languages_lookup"))); |
| 953 | + } |
| 954 | + |
905 | 955 | public void testFailureWhenSortAndSortBreakerBeforeInlineStats() { |
906 | 956 | assumeTrue("LIMIT before INLINE STATS limitation check", EsqlCapabilities.Cap.INLINE_STATS.isEnabled()); |
907 | 957 | /* |
|
0 commit comments