Skip to content

Commit ac13587

Browse files
committed
Add first optimizer test
1 parent ce38db5 commit ac13587

File tree

3 files changed

+38
-181
lines changed

3 files changed

+38
-181
lines changed

x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/AbstractLogicalPlanOptimizerTests.java

Lines changed: 0 additions & 169 deletions
Original file line numberDiff line numberDiff line change
@@ -7,202 +7,33 @@
77

88
package org.elasticsearch.xpack.esql.optimizer;
99

10-
import org.apache.lucene.util.BytesRef;
11-
import org.elasticsearch.Build;
12-
import org.elasticsearch.common.logging.LoggerMessageFormat;
13-
import org.elasticsearch.common.lucene.BytesRefs;
14-
import org.elasticsearch.compute.aggregation.QuantileStates;
15-
import org.elasticsearch.compute.data.Block;
16-
import org.elasticsearch.compute.data.LongVectorBlock;
17-
import org.elasticsearch.compute.test.TestBlockFactory;
18-
import org.elasticsearch.core.Tuple;
19-
import org.elasticsearch.dissect.DissectParser;
2010
import org.elasticsearch.index.IndexMode;
2111
import org.elasticsearch.test.ESTestCase;
2212
import org.elasticsearch.xpack.esql.EsqlTestUtils;
23-
import org.elasticsearch.xpack.esql.VerificationException;
24-
import org.elasticsearch.xpack.esql.action.EsqlCapabilities;
2513
import org.elasticsearch.xpack.esql.analysis.Analyzer;
2614
import org.elasticsearch.xpack.esql.analysis.AnalyzerContext;
2715
import org.elasticsearch.xpack.esql.analysis.AnalyzerTestUtils;
2816
import org.elasticsearch.xpack.esql.analysis.EnrichResolution;
29-
import org.elasticsearch.xpack.esql.common.Failures;
30-
import org.elasticsearch.xpack.esql.core.expression.Alias;
31-
import org.elasticsearch.xpack.esql.core.expression.Attribute;
32-
import org.elasticsearch.xpack.esql.core.expression.AttributeSet;
33-
import org.elasticsearch.xpack.esql.core.expression.EntryExpression;
34-
import org.elasticsearch.xpack.esql.core.expression.Expression;
35-
import org.elasticsearch.xpack.esql.core.expression.Expressions;
36-
import org.elasticsearch.xpack.esql.core.expression.FieldAttribute;
37-
import org.elasticsearch.xpack.esql.core.expression.FoldContext;
38-
import org.elasticsearch.xpack.esql.core.expression.Literal;
39-
import org.elasticsearch.xpack.esql.core.expression.MapExpression;
40-
import org.elasticsearch.xpack.esql.core.expression.NamedExpression;
41-
import org.elasticsearch.xpack.esql.core.expression.Nullability;
42-
import org.elasticsearch.xpack.esql.core.expression.ReferenceAttribute;
43-
import org.elasticsearch.xpack.esql.core.expression.UnresolvedAttribute;
44-
import org.elasticsearch.xpack.esql.core.expression.predicate.operator.comparison.BinaryComparison;
45-
import org.elasticsearch.xpack.esql.core.tree.Source;
46-
import org.elasticsearch.xpack.esql.core.type.DataType;
4717
import org.elasticsearch.xpack.esql.core.type.EsField;
48-
import org.elasticsearch.xpack.esql.core.type.PotentiallyUnmappedKeywordEsField;
49-
import org.elasticsearch.xpack.esql.core.util.Holder;
50-
import org.elasticsearch.xpack.esql.core.util.StringUtils;
51-
import org.elasticsearch.xpack.esql.expression.Order;
5218
import org.elasticsearch.xpack.esql.expression.function.EsqlFunctionRegistry;
53-
import org.elasticsearch.xpack.esql.expression.function.aggregate.AggregateFunction;
54-
import org.elasticsearch.xpack.esql.expression.function.aggregate.Count;
55-
import org.elasticsearch.xpack.esql.expression.function.aggregate.FromPartial;
56-
import org.elasticsearch.xpack.esql.expression.function.aggregate.Max;
57-
import org.elasticsearch.xpack.esql.expression.function.aggregate.Min;
58-
import org.elasticsearch.xpack.esql.expression.function.aggregate.Percentile;
59-
import org.elasticsearch.xpack.esql.expression.function.aggregate.Rate;
60-
import org.elasticsearch.xpack.esql.expression.function.aggregate.Sum;
61-
import org.elasticsearch.xpack.esql.expression.function.aggregate.ToPartial;
62-
import org.elasticsearch.xpack.esql.expression.function.aggregate.Values;
63-
import org.elasticsearch.xpack.esql.expression.function.fulltext.Match;
64-
import org.elasticsearch.xpack.esql.expression.function.fulltext.MultiMatch;
65-
import org.elasticsearch.xpack.esql.expression.function.grouping.Bucket;
66-
import org.elasticsearch.xpack.esql.expression.function.grouping.Categorize;
67-
import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToDouble;
68-
import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToInteger;
69-
import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToLong;
70-
import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToString;
71-
import org.elasticsearch.xpack.esql.expression.function.scalar.math.Round;
72-
import org.elasticsearch.xpack.esql.expression.function.scalar.multivalue.MvAvg;
73-
import org.elasticsearch.xpack.esql.expression.function.scalar.multivalue.MvCount;
74-
import org.elasticsearch.xpack.esql.expression.function.scalar.multivalue.MvDedupe;
75-
import org.elasticsearch.xpack.esql.expression.function.scalar.multivalue.MvMax;
76-
import org.elasticsearch.xpack.esql.expression.function.scalar.multivalue.MvMedian;
77-
import org.elasticsearch.xpack.esql.expression.function.scalar.multivalue.MvMin;
78-
import org.elasticsearch.xpack.esql.expression.function.scalar.multivalue.MvSum;
79-
import org.elasticsearch.xpack.esql.expression.function.scalar.nulls.Coalesce;
80-
import org.elasticsearch.xpack.esql.expression.function.scalar.string.Concat;
81-
import org.elasticsearch.xpack.esql.expression.predicate.logical.And;
82-
import org.elasticsearch.xpack.esql.expression.predicate.logical.Not;
83-
import org.elasticsearch.xpack.esql.expression.predicate.logical.Or;
84-
import org.elasticsearch.xpack.esql.expression.predicate.nulls.IsNotNull;
85-
import org.elasticsearch.xpack.esql.expression.predicate.operator.arithmetic.Add;
86-
import org.elasticsearch.xpack.esql.expression.predicate.operator.arithmetic.Div;
87-
import org.elasticsearch.xpack.esql.expression.predicate.operator.arithmetic.Mod;
88-
import org.elasticsearch.xpack.esql.expression.predicate.operator.arithmetic.Mul;
89-
import org.elasticsearch.xpack.esql.expression.predicate.operator.arithmetic.Neg;
90-
import org.elasticsearch.xpack.esql.expression.predicate.operator.arithmetic.Sub;
91-
import org.elasticsearch.xpack.esql.expression.predicate.operator.comparison.Equals;
92-
import org.elasticsearch.xpack.esql.expression.predicate.operator.comparison.EsqlBinaryComparison;
93-
import org.elasticsearch.xpack.esql.expression.predicate.operator.comparison.GreaterThan;
94-
import org.elasticsearch.xpack.esql.expression.predicate.operator.comparison.In;
95-
import org.elasticsearch.xpack.esql.expression.predicate.operator.comparison.InsensitiveEquals;
96-
import org.elasticsearch.xpack.esql.expression.predicate.operator.comparison.LessThan;
9719
import org.elasticsearch.xpack.esql.index.EsIndex;
9820
import org.elasticsearch.xpack.esql.index.IndexResolution;
99-
import org.elasticsearch.xpack.esql.optimizer.rules.logical.LiteralsOnTheRight;
100-
import org.elasticsearch.xpack.esql.optimizer.rules.logical.OptimizerRules;
101-
import org.elasticsearch.xpack.esql.optimizer.rules.logical.PruneRedundantOrderBy;
102-
import org.elasticsearch.xpack.esql.optimizer.rules.logical.PushDownAndCombineLimits;
103-
import org.elasticsearch.xpack.esql.optimizer.rules.logical.PushDownCompletion;
104-
import org.elasticsearch.xpack.esql.optimizer.rules.logical.PushDownEnrich;
105-
import org.elasticsearch.xpack.esql.optimizer.rules.logical.PushDownEval;
106-
import org.elasticsearch.xpack.esql.optimizer.rules.logical.PushDownRegexExtract;
107-
import org.elasticsearch.xpack.esql.optimizer.rules.logical.SplitInWithFoldableValue;
10821
import org.elasticsearch.xpack.esql.parser.EsqlParser;
109-
import org.elasticsearch.xpack.esql.parser.ParsingException;
110-
import org.elasticsearch.xpack.esql.plan.GeneratingPlan;
111-
import org.elasticsearch.xpack.esql.plan.logical.Aggregate;
112-
import org.elasticsearch.xpack.esql.plan.logical.ChangePoint;
113-
import org.elasticsearch.xpack.esql.plan.logical.Dissect;
114-
import org.elasticsearch.xpack.esql.plan.logical.Enrich;
115-
import org.elasticsearch.xpack.esql.plan.logical.EsRelation;
116-
import org.elasticsearch.xpack.esql.plan.logical.Eval;
117-
import org.elasticsearch.xpack.esql.plan.logical.Filter;
118-
import org.elasticsearch.xpack.esql.plan.logical.Grok;
119-
import org.elasticsearch.xpack.esql.plan.logical.Limit;
12022
import org.elasticsearch.xpack.esql.plan.logical.LogicalPlan;
121-
import org.elasticsearch.xpack.esql.plan.logical.MvExpand;
122-
import org.elasticsearch.xpack.esql.plan.logical.OrderBy;
123-
import org.elasticsearch.xpack.esql.plan.logical.Project;
124-
import org.elasticsearch.xpack.esql.plan.logical.Row;
125-
import org.elasticsearch.xpack.esql.plan.logical.Sample;
126-
import org.elasticsearch.xpack.esql.plan.logical.TimeSeriesAggregate;
127-
import org.elasticsearch.xpack.esql.plan.logical.TopN;
128-
import org.elasticsearch.xpack.esql.plan.logical.UnaryPlan;
129-
import org.elasticsearch.xpack.esql.plan.logical.inference.Completion;
130-
import org.elasticsearch.xpack.esql.plan.logical.join.InlineJoin;
131-
import org.elasticsearch.xpack.esql.plan.logical.join.Join;
132-
import org.elasticsearch.xpack.esql.plan.logical.join.JoinConfig;
133-
import org.elasticsearch.xpack.esql.plan.logical.join.JoinTypes;
134-
import org.elasticsearch.xpack.esql.plan.logical.join.LookupJoin;
135-
import org.elasticsearch.xpack.esql.plan.logical.local.EsqlProject;
136-
import org.elasticsearch.xpack.esql.plan.logical.local.LocalRelation;
137-
import org.elasticsearch.xpack.esql.plan.logical.local.LocalSupplier;
13823
import org.junit.BeforeClass;
13924

140-
import java.time.Duration;
141-
import java.util.ArrayList;
142-
import java.util.Arrays;
14325
import java.util.List;
144-
import java.util.Locale;
14526
import java.util.Map;
14627
import java.util.Set;
147-
import java.util.function.BiFunction;
148-
import java.util.function.Function;
14928

150-
import static java.util.Arrays.asList;
151-
import static java.util.Collections.emptyList;
15229
import static java.util.Collections.emptyMap;
153-
import static java.util.Collections.singletonList;
154-
import static org.elasticsearch.test.ListMatcher.matchesList;
155-
import static org.elasticsearch.test.MapMatcher.assertMap;
156-
import static org.elasticsearch.xpack.esql.EsqlTestUtils.L;
157-
import static org.elasticsearch.xpack.esql.EsqlTestUtils.ONE;
15830
import static org.elasticsearch.xpack.esql.EsqlTestUtils.TEST_VERIFIER;
159-
import static org.elasticsearch.xpack.esql.EsqlTestUtils.THREE;
160-
import static org.elasticsearch.xpack.esql.EsqlTestUtils.TWO;
161-
import static org.elasticsearch.xpack.esql.EsqlTestUtils.as;
162-
import static org.elasticsearch.xpack.esql.EsqlTestUtils.asLimit;
16331
import static org.elasticsearch.xpack.esql.EsqlTestUtils.emptyInferenceResolution;
164-
import static org.elasticsearch.xpack.esql.EsqlTestUtils.emptySource;
165-
import static org.elasticsearch.xpack.esql.EsqlTestUtils.fieldAttribute;
166-
import static org.elasticsearch.xpack.esql.EsqlTestUtils.getFieldAttribute;
16732
import static org.elasticsearch.xpack.esql.EsqlTestUtils.loadMapping;
168-
import static org.elasticsearch.xpack.esql.EsqlTestUtils.localSource;
169-
import static org.elasticsearch.xpack.esql.EsqlTestUtils.randomLiteral;
170-
import static org.elasticsearch.xpack.esql.EsqlTestUtils.referenceAttribute;
171-
import static org.elasticsearch.xpack.esql.EsqlTestUtils.singleValue;
17233
import static org.elasticsearch.xpack.esql.EsqlTestUtils.unboundLogicalOptimizerContext;
17334
import static org.elasticsearch.xpack.esql.EsqlTestUtils.withDefaultLimitWarning;
174-
import static org.elasticsearch.xpack.esql.analysis.Analyzer.NO_FIELDS;
175-
import static org.elasticsearch.xpack.esql.analysis.AnalyzerTestUtils.analyze;
17635
import static org.elasticsearch.xpack.esql.analysis.AnalyzerTestUtils.defaultLookupResolution;
177-
import static org.elasticsearch.xpack.esql.core.expression.Literal.NULL;
178-
import static org.elasticsearch.xpack.esql.core.tree.Source.EMPTY;
179-
import static org.elasticsearch.xpack.esql.core.type.DataType.DOUBLE;
180-
import static org.elasticsearch.xpack.esql.core.type.DataType.GEO_POINT;
181-
import static org.elasticsearch.xpack.esql.core.type.DataType.INTEGER;
18236
import static org.elasticsearch.xpack.esql.core.type.DataType.KEYWORD;
183-
import static org.elasticsearch.xpack.esql.core.type.DataType.LONG;
184-
import static org.elasticsearch.xpack.esql.core.type.DataType.TEXT;
185-
import static org.elasticsearch.xpack.esql.expression.predicate.operator.comparison.EsqlBinaryComparison.BinaryComparisonOperation.EQ;
186-
import static org.elasticsearch.xpack.esql.expression.predicate.operator.comparison.EsqlBinaryComparison.BinaryComparisonOperation.GT;
187-
import static org.elasticsearch.xpack.esql.expression.predicate.operator.comparison.EsqlBinaryComparison.BinaryComparisonOperation.GTE;
188-
import static org.elasticsearch.xpack.esql.expression.predicate.operator.comparison.EsqlBinaryComparison.BinaryComparisonOperation.LT;
189-
import static org.elasticsearch.xpack.esql.expression.predicate.operator.comparison.EsqlBinaryComparison.BinaryComparisonOperation.LTE;
190-
import static org.hamcrest.Matchers.allOf;
191-
import static org.hamcrest.Matchers.anyOf;
192-
import static org.hamcrest.Matchers.contains;
193-
import static org.hamcrest.Matchers.containsInAnyOrder;
194-
import static org.hamcrest.Matchers.containsString;
195-
import static org.hamcrest.Matchers.empty;
196-
import static org.hamcrest.Matchers.emptyArray;
197-
import static org.hamcrest.Matchers.equalTo;
198-
import static org.hamcrest.Matchers.everyItem;
199-
import static org.hamcrest.Matchers.hasItem;
200-
import static org.hamcrest.Matchers.hasSize;
201-
import static org.hamcrest.Matchers.instanceOf;
202-
import static org.hamcrest.Matchers.is;
203-
import static org.hamcrest.Matchers.not;
204-
import static org.hamcrest.Matchers.nullValue;
205-
import static org.hamcrest.Matchers.startsWith;
20637

20738
//@TestLogging(value = "org.elasticsearch.xpack.esql:TRACE", reason = "debug")
20839
public abstract class AbstractLogicalPlanOptimizerTests extends ESTestCase {

x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/LogicalPlanOptimizerTests.java

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,11 @@
1818
import org.elasticsearch.core.Tuple;
1919
import org.elasticsearch.dissect.DissectParser;
2020
import org.elasticsearch.index.IndexMode;
21-
import org.elasticsearch.test.ESTestCase;
2221
import org.elasticsearch.xpack.esql.EsqlTestUtils;
2322
import org.elasticsearch.xpack.esql.VerificationException;
2423
import org.elasticsearch.xpack.esql.action.EsqlCapabilities;
2524
import org.elasticsearch.xpack.esql.analysis.Analyzer;
2625
import org.elasticsearch.xpack.esql.analysis.AnalyzerContext;
27-
import org.elasticsearch.xpack.esql.analysis.AnalyzerTestUtils;
28-
import org.elasticsearch.xpack.esql.analysis.EnrichResolution;
2926
import org.elasticsearch.xpack.esql.common.Failures;
3027
import org.elasticsearch.xpack.esql.core.expression.Alias;
3128
import org.elasticsearch.xpack.esql.core.expression.Attribute;
@@ -44,7 +41,6 @@
4441
import org.elasticsearch.xpack.esql.core.expression.predicate.operator.comparison.BinaryComparison;
4542
import org.elasticsearch.xpack.esql.core.tree.Source;
4643
import org.elasticsearch.xpack.esql.core.type.DataType;
47-
import org.elasticsearch.xpack.esql.core.type.EsField;
4844
import org.elasticsearch.xpack.esql.core.type.PotentiallyUnmappedKeywordEsField;
4945
import org.elasticsearch.xpack.esql.core.util.Holder;
5046
import org.elasticsearch.xpack.esql.core.util.StringUtils;
@@ -105,7 +101,6 @@
105101
import org.elasticsearch.xpack.esql.optimizer.rules.logical.PushDownEval;
106102
import org.elasticsearch.xpack.esql.optimizer.rules.logical.PushDownRegexExtract;
107103
import org.elasticsearch.xpack.esql.optimizer.rules.logical.SplitInWithFoldableValue;
108-
import org.elasticsearch.xpack.esql.parser.EsqlParser;
109104
import org.elasticsearch.xpack.esql.parser.ParsingException;
110105
import org.elasticsearch.xpack.esql.plan.GeneratingPlan;
111106
import org.elasticsearch.xpack.esql.plan.logical.Aggregate;
@@ -135,15 +130,13 @@
135130
import org.elasticsearch.xpack.esql.plan.logical.local.EsqlProject;
136131
import org.elasticsearch.xpack.esql.plan.logical.local.LocalRelation;
137132
import org.elasticsearch.xpack.esql.plan.logical.local.LocalSupplier;
138-
import org.junit.BeforeClass;
139133

140134
import java.time.Duration;
141135
import java.util.ArrayList;
142136
import java.util.Arrays;
143137
import java.util.List;
144138
import java.util.Locale;
145139
import java.util.Map;
146-
import java.util.Set;
147140
import java.util.function.BiFunction;
148141
import java.util.function.Function;
149142

@@ -164,16 +157,13 @@
164157
import static org.elasticsearch.xpack.esql.EsqlTestUtils.emptySource;
165158
import static org.elasticsearch.xpack.esql.EsqlTestUtils.fieldAttribute;
166159
import static org.elasticsearch.xpack.esql.EsqlTestUtils.getFieldAttribute;
167-
import static org.elasticsearch.xpack.esql.EsqlTestUtils.loadMapping;
168160
import static org.elasticsearch.xpack.esql.EsqlTestUtils.localSource;
169161
import static org.elasticsearch.xpack.esql.EsqlTestUtils.randomLiteral;
170162
import static org.elasticsearch.xpack.esql.EsqlTestUtils.referenceAttribute;
171163
import static org.elasticsearch.xpack.esql.EsqlTestUtils.singleValue;
172-
import static org.elasticsearch.xpack.esql.EsqlTestUtils.unboundLogicalOptimizerContext;
173164
import static org.elasticsearch.xpack.esql.EsqlTestUtils.withDefaultLimitWarning;
174165
import static org.elasticsearch.xpack.esql.analysis.Analyzer.NO_FIELDS;
175166
import static org.elasticsearch.xpack.esql.analysis.AnalyzerTestUtils.analyze;
176-
import static org.elasticsearch.xpack.esql.analysis.AnalyzerTestUtils.defaultLookupResolution;
177167
import static org.elasticsearch.xpack.esql.core.expression.Literal.NULL;
178168
import static org.elasticsearch.xpack.esql.core.tree.Source.EMPTY;
179169
import static org.elasticsearch.xpack.esql.core.type.DataType.DOUBLE;

x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/rules/logical/PushDownJoinPastProjectTests.java

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,14 @@
88
package org.elasticsearch.xpack.esql.optimizer.rules.logical;
99

1010
import org.elasticsearch.xpack.esql.action.EsqlCapabilities;
11+
import org.elasticsearch.xpack.esql.core.expression.AttributeSet;
1112
import org.elasticsearch.xpack.esql.optimizer.AbstractLogicalPlanOptimizerTests;
13+
import org.elasticsearch.xpack.esql.plan.logical.EsRelation;
14+
import org.elasticsearch.xpack.esql.plan.logical.Project;
15+
import org.elasticsearch.xpack.esql.plan.logical.join.Join;
16+
17+
import static org.elasticsearch.xpack.esql.EsqlTestUtils.as;
18+
import static org.elasticsearch.xpack.esql.EsqlTestUtils.asLimit;
1219

1320
public class PushDownJoinPastProjectTests extends AbstractLogicalPlanOptimizerTests {
1421
/**
@@ -43,7 +50,36 @@ public void testMultipleLookupProject() {
4350

4451
var plan = optimizedPlan(query);
4552

46-
// TODO: here
47-
assert false;
53+
var project = as(plan, Project.class);
54+
var upperLimit = asLimit(project.child(), 1000, true);
55+
56+
var join1 = as(upperLimit.child(), Join.class);
57+
var lookupRel1 = as(join1.right(), EsRelation.class);
58+
var limit1 = asLimit(join1.left(), 1000, true);
59+
60+
AttributeSet lookupIndexFields1 = lookupRel1.outputSet();
61+
var rightKeys1 = join1.config().rightFields();
62+
var leftKeys1 = join1.config().leftFields();
63+
// Left join key should be updated to use an attribute from the main index directly
64+
assertTrue(leftKeys1.size() == 1 && leftKeys1.get(0).name() == "languages");
65+
assertTrue(rightKeys1.size() == 1 && rightKeys1.get(0).name() == "language_code");
66+
assertTrue(lookupIndexFields1.contains(rightKeys1.get(0)));
67+
68+
var join2 = as(limit1.child(), Join.class);
69+
var lookupRel2 = as(join2.right(), EsRelation.class);
70+
var limit2 = asLimit(join2.left(), 1000, false);
71+
72+
AttributeSet lookupIndexFields2 = lookupRel2.outputSet();
73+
var rightKeys2 = join2.config().rightFields();
74+
var leftKeys2 = join2.config().leftFields();
75+
// Left join key should be updated to use an attribute from the main index directly
76+
assertTrue(leftKeys2.size() == 1 && leftKeys2.get(0).name() == "languages");
77+
assertTrue(rightKeys2.size() == 1 && rightKeys2.get(0).name() == "language_code");
78+
assertTrue(lookupIndexFields2.contains(rightKeys2.get(0)));
79+
80+
var mainRel = as(limit2.child(), EsRelation.class);
81+
AttributeSet mainFields = mainRel.outputSet();
82+
assertTrue(mainFields.contains(leftKeys1.get(0)));
83+
assertTrue(mainFields.contains(leftKeys2.get(0)));
4884
}
4985
}

0 commit comments

Comments
 (0)