|
22 | 22 | import org.elasticsearch.xpack.esql.core.expression.Attribute; |
23 | 23 | import org.elasticsearch.xpack.esql.core.expression.AttributeSet; |
24 | 24 | import org.elasticsearch.xpack.esql.core.expression.EntryExpression; |
| 25 | +import org.elasticsearch.xpack.esql.core.expression.Expression; |
25 | 26 | import org.elasticsearch.xpack.esql.core.expression.Expressions; |
26 | 27 | import org.elasticsearch.xpack.esql.core.expression.FieldAttribute; |
27 | 28 | import org.elasticsearch.xpack.esql.core.expression.Literal; |
|
37 | 38 | import org.elasticsearch.xpack.esql.expression.function.aggregate.Min; |
38 | 39 | import org.elasticsearch.xpack.esql.expression.function.fulltext.Match; |
39 | 40 | import org.elasticsearch.xpack.esql.expression.function.fulltext.MatchOperator; |
| 41 | +import org.elasticsearch.xpack.esql.expression.predicate.operator.comparison.GreaterThan; |
40 | 42 | import org.elasticsearch.xpack.esql.index.EsIndex; |
41 | 43 | import org.elasticsearch.xpack.esql.index.IndexResolution; |
42 | 44 | import org.elasticsearch.xpack.esql.parser.ParsingException; |
|
50 | 52 | import org.elasticsearch.xpack.esql.plan.logical.Limit; |
51 | 53 | import org.elasticsearch.xpack.esql.plan.logical.LogicalPlan; |
52 | 54 | import org.elasticsearch.xpack.esql.plan.logical.Lookup; |
| 55 | +import org.elasticsearch.xpack.esql.plan.logical.Merge; |
53 | 56 | import org.elasticsearch.xpack.esql.plan.logical.OrderBy; |
54 | 57 | import org.elasticsearch.xpack.esql.plan.logical.Row; |
55 | 58 | import org.elasticsearch.xpack.esql.plan.logical.UnresolvedRelation; |
|
85 | 88 | import static org.elasticsearch.xpack.esql.core.tree.Source.EMPTY; |
86 | 89 | import static org.hamcrest.Matchers.contains; |
87 | 90 | import static org.hamcrest.Matchers.containsString; |
| 91 | +import static org.hamcrest.Matchers.empty; |
88 | 92 | import static org.hamcrest.Matchers.equalTo; |
89 | 93 | import static org.hamcrest.Matchers.hasItem; |
90 | 94 | import static org.hamcrest.Matchers.hasSize; |
@@ -2587,6 +2591,60 @@ public void testFunctionNamedParamsAsFunctionArgument() { |
2587 | 2591 | assertEquals(DataType.DOUBLE, ee.dataType()); |
2588 | 2592 | } |
2589 | 2593 |
|
| 2594 | + public void testBasicFork() { |
| 2595 | + assumeTrue("requires FORK capability", EsqlCapabilities.Cap.FORK.isEnabled()); |
| 2596 | + |
| 2597 | + LogicalPlan plan = analyze(""" |
| 2598 | + from test* |
| 2599 | + | WHERE x > 1 |
| 2600 | + | FORK [ WHERE b > 2 ] |
| 2601 | + [ WHERE C > 3 ] |
| 2602 | + [ WHERE d > 4 | SORT x | LIMIT 7 ] |
| 2603 | + """); |
| 2604 | + |
| 2605 | + Limit limit = as(plan, Limit.class); |
| 2606 | + Merge merge = as(limit.child(), Merge.class); |
| 2607 | + assertThat(merge.children(), empty()); |
| 2608 | + |
| 2609 | + // fork branch 1 |
| 2610 | + limit = as(merge.subPlans().get(0), Limit.class); |
| 2611 | + assertThat(as(limit.limit(), Literal.class).value(), equalTo(DEFAULT_LIMIT)); |
| 2612 | + Eval eval = as(limit.child(), Eval.class); |
| 2613 | + assertThat(as(eval.fields().get(0), Alias.class), equalTo(alias("_fork", string("fork1")))); |
| 2614 | + Filter filter = as(eval.child(), Filter.class); |
| 2615 | + assertThat(as(filter.condition(), GreaterThan.class), equalTo(greaterThan(attribute("b"), literal(2)))); |
| 2616 | + filter = as(filter.child(), Filter.class); |
| 2617 | + assertThat(as(filter.condition(), GreaterThan.class), equalTo(greaterThan(attribute("x"), literal(1)))); |
| 2618 | + var esRelation = as(filter.child(), EsRelation.class); |
| 2619 | + assertThat(esRelation.indexPattern(), equalTo("test")); |
| 2620 | + |
| 2621 | + // fork branch 2 |
| 2622 | + limit = as(merge.subPlans().get(1), Limit.class); |
| 2623 | + assertThat(as(limit.limit(), Literal.class).value(), equalTo(DEFAULT_LIMIT)); |
| 2624 | + eval = as(limit.child(), Eval.class); |
| 2625 | + assertThat(as(eval.fields().get(0), Alias.class), equalTo(alias("_fork", string("fork2")))); |
| 2626 | + filter = as(eval.child(), Filter.class); |
| 2627 | + assertThat(as(filter.condition(), GreaterThan.class), equalTo(greaterThan(attribute("C"), literal(3)))); |
| 2628 | + filter = as(filter.child(), Filter.class); |
| 2629 | + assertThat(as(filter.condition(), GreaterThan.class), equalTo(greaterThan(attribute("x"), literal(1)))); |
| 2630 | + esRelation = as(filter.child(), EsRelation.class); |
| 2631 | + assertThat(esRelation.indexPattern(), equalTo("test")); |
| 2632 | + |
| 2633 | + // fork branch 3 |
| 2634 | + limit = as(merge.subPlans().get(2), Limit.class); |
| 2635 | + assertThat(as(limit.limit(), Literal.class).value(), equalTo(MAX_LIMIT)); |
| 2636 | + eval = as(limit.child(), Eval.class); |
| 2637 | + assertThat(as(eval.fields().get(0), Alias.class), equalTo(alias("_fork", string("fork3")))); |
| 2638 | + limit = as(eval.child(), Limit.class); |
| 2639 | + var orderBy = as(limit.child(), OrderBy.class); |
| 2640 | + filter = as(orderBy.child(), Filter.class); |
| 2641 | + assertThat(as(filter.condition(), GreaterThan.class), equalTo(greaterThan(attribute("d"), literal(4)))); |
| 2642 | + filter = as(filter.child(), Filter.class); |
| 2643 | + assertThat(as(filter.condition(), GreaterThan.class), equalTo(greaterThan(attribute("x"), literal(1)))); |
| 2644 | + esRelation = as(filter.child(), EsRelation.class); |
| 2645 | + assertThat(esRelation.indexPattern(), equalTo("test")); |
| 2646 | + } |
| 2647 | + |
2590 | 2648 | private void verifyUnsupported(String query, String errorMessage) { |
2591 | 2649 | verifyUnsupported(query, errorMessage, "mapping-multi-field-variation.json"); |
2592 | 2650 | } |
@@ -2653,4 +2711,24 @@ private void assertEmptyEsRelation(LogicalPlan plan) { |
2653 | 2711 | protected IndexAnalyzers createDefaultIndexAnalyzers() { |
2654 | 2712 | return super.createDefaultIndexAnalyzers(); |
2655 | 2713 | } |
| 2714 | + |
| 2715 | + static GreaterThan greaterThan(Expression left, Expression right) { |
| 2716 | + return new GreaterThan(EMPTY, left, right); |
| 2717 | + } |
| 2718 | + |
| 2719 | + static UnresolvedAttribute attribute(String name) { |
| 2720 | + return new UnresolvedAttribute(EMPTY, name); |
| 2721 | + } |
| 2722 | + |
| 2723 | + static Alias alias(String name, Expression value) { |
| 2724 | + return new Alias(EMPTY, name, value); |
| 2725 | + } |
| 2726 | + |
| 2727 | + static Literal string(String value) { |
| 2728 | + return new Literal(EMPTY, value, DataType.KEYWORD); |
| 2729 | + } |
| 2730 | + |
| 2731 | + static Literal literal(int value) { |
| 2732 | + return new Literal(EMPTY, value, DataType.INTEGER); |
| 2733 | + } |
2656 | 2734 | } |
0 commit comments