88
99import org .elasticsearch .common .io .stream .StreamOutput ;
1010import org .elasticsearch .test .ESTestCase ;
11+ import org .elasticsearch .xpack .esql .core .expression .Alias ;
1112import org .elasticsearch .xpack .esql .core .expression .Expression ;
1213import org .elasticsearch .xpack .esql .core .expression .FieldAttribute ;
1314import org .elasticsearch .xpack .esql .core .expression .FoldContext ;
1415import org .elasticsearch .xpack .esql .core .expression .Literal ;
1516import org .elasticsearch .xpack .esql .core .expression .Nullability ;
17+ import org .elasticsearch .xpack .esql .core .expression .UnresolvedAttribute ;
1618import org .elasticsearch .xpack .esql .core .tree .NodeInfo ;
1719import org .elasticsearch .xpack .esql .core .tree .Source ;
1820import org .elasticsearch .xpack .esql .core .type .DataType ;
19- import org .elasticsearch .xpack .esql .core .util .TestUtils ;
2021import org .elasticsearch .xpack .esql .expression .predicate .Range ;
22+ import org .elasticsearch .xpack .esql .expression .predicate .operator .arithmetic .Add ;
23+ import org .elasticsearch .xpack .esql .optimizer .rules .logical .OptimizerRules ;
24+ import org .elasticsearch .xpack .esql .parser .EsqlParser ;
2125
2226import java .io .IOException ;
27+ import java .util .ArrayList ;
2328import java .util .Collections ;
2429import java .util .List ;
30+ import java .util .Objects ;
2531
2632import static org .elasticsearch .xpack .esql .EsqlTestUtils .rangeOf ;
2733import static org .elasticsearch .xpack .esql .core .type .DataType .BOOLEAN ;
34+ import static org .elasticsearch .xpack .esql .core .util .TestUtils .getFieldAttribute ;
2835import static org .elasticsearch .xpack .esql .core .util .TestUtils .of ;
36+ import static org .hamcrest .Matchers .contains ;
2937
3038public class OptimizerRulesTests extends ESTestCase {
3139
32- private static final Literal FIVE = L (5 );
33- private static final Literal SIX = L (6 );
40+ private static final Literal FIVE = of (5 );
41+ private static final Literal SIX = of (6 );
3442
35- public static class DummyBooleanExpression extends Expression {
43+ public static final class DummyBooleanExpression extends Expression {
3644
3745 private final int id ;
3846
@@ -87,21 +95,13 @@ public boolean equals(Object obj) {
8795 }
8896 }
8997
90- private static Literal L (Object value ) {
91- return of (value );
92- }
93-
94- private static FieldAttribute getFieldAttribute () {
95- return TestUtils .getFieldAttribute ("a" );
96- }
97-
9898 //
9999 // Range optimization
100100 //
101101
102102 // 6 < a <= 5 -> FALSE
103103 public void testFoldExcludingRangeToFalse () {
104- FieldAttribute fa = getFieldAttribute ();
104+ FieldAttribute fa = getFieldAttribute ("a" );
105105
106106 Range r = rangeOf (fa , SIX , false , FIVE , true );
107107 assertTrue (r .foldable ());
@@ -110,13 +110,35 @@ public void testFoldExcludingRangeToFalse() {
110110
111111 // 6 < a <= 5.5 -> FALSE
112112 public void testFoldExcludingRangeWithDifferentTypesToFalse () {
113- FieldAttribute fa = getFieldAttribute ();
113+ FieldAttribute fa = getFieldAttribute ("a" );
114114
115- Range r = rangeOf (fa , SIX , false , L (5.5d ), true );
115+ Range r = rangeOf (fa , SIX , false , of (5.5d ), true );
116116 assertTrue (r .foldable ());
117117 assertEquals (Boolean .FALSE , r .fold (FoldContext .small ()));
118118 }
119119
120- // Conjunction
120+ public void testOptimizerExpressionRuleShouldNotVisitExcludedNodes () {
121+ var rule = new OptimizerRules .OptimizerExpressionRule <>(randomFrom (OptimizerRules .TransformDirection .values ())) {
122+ private final List <Expression > appliedTo = new ArrayList <>();
121123
124+ @ Override
125+ protected Expression rule (Expression e , LogicalOptimizerContext ctx ) {
126+ appliedTo .add (e );
127+ return e ;
128+ }
129+ };
130+
131+ rule .apply (
132+ new EsqlParser ().createStatement ("FROM index | EVAL x=f1+1 | KEEP x, f2 | LIMIT 1" ),
133+ new LogicalOptimizerContext (null , FoldContext .small ())
134+ );
135+
136+ var literal = new Literal (new Source (1 , 25 , "1" ), 1 , DataType .INTEGER );
137+ var attribute = new UnresolvedAttribute (new Source (1 , 20 , "f1" ), "f1" );
138+ var add = new Add (new Source (1 , 20 , "f1+1" ), attribute , literal );
139+ var alias = new Alias (new Source (1 , 18 , "x=f1+1" ), "x" , add );
140+
141+ // contains expressions only from EVAL
142+ assertThat (rule .appliedTo , contains (alias , add , attribute , literal ));
143+ }
122144}
0 commit comments