Skip to content

Commit 35c4d0e

Browse files
author
elasticsearchmachine
committed
Use 3 value logic to determine which functions to push
1 parent 4bc64ab commit 35c4d0e

File tree

9 files changed

+36
-28
lines changed

9 files changed

+36
-28
lines changed

x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/expression/Expression.java

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -212,11 +212,27 @@ public String propertiesToString(boolean skipIfChild) {
212212
return super.propertiesToString(false);
213213
}
214214

215-
public boolean isPushable() {
216-
return false;
215+
public PushableOptions pushableOptions() {
216+
return PushableOptions.NOT_SUPPORTED;
217217
}
218218

219219
public String asScript() {
220220
throw new UnsupportedOperationException("asScript not implemented for " + getWriteableName());
221221
}
222+
223+
public enum PushableOptions {
224+
SUPPORTED,
225+
NOT_SUPPORTED,
226+
PREFERRED;
227+
228+
public PushableOptions and(PushableOptions other) {
229+
if (this == NOT_SUPPORTED || other == NOT_SUPPORTED) {
230+
return NOT_SUPPORTED;
231+
}
232+
if (this == PREFERRED || other == PREFERRED) {
233+
return PREFERRED;
234+
}
235+
return SUPPORTED;
236+
}
237+
}
222238
}

x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/expression/FieldAttribute.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -260,8 +260,8 @@ public EsField field() {
260260
}
261261

262262
@Override
263-
public boolean isPushable() {
264-
return true;
263+
public PushableOptions pushableOptions() {
264+
return PushableOptions.SUPPORTED;
265265
}
266266

267267
@Override

x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/expression/Literal.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -238,8 +238,9 @@ private static long wkbAsLong(DataType dataType, BytesRef wkb) {
238238
}
239239

240240
@Override
241-
public boolean isPushable() {
242-
return true;
241+
public PushableOptions pushableOptions() {
242+
// Don't mess with nulls, they don't have the same meaning in Lucene
243+
return value() == null ? PushableOptions.NOT_SUPPORTED : PushableOptions.SUPPORTED;
243244
}
244245

245246
@Override

x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/vector/Magnitude.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,8 +133,8 @@ public String toString() {
133133
}
134134

135135
@Override
136-
public boolean isPushable() {
137-
return true;
136+
public PushableOptions pushableOptions() {
137+
return PushableOptions.PREFERRED;
138138
}
139139

140140
private record ScalarEvaluator(

x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/vector/VectorSimilarityFunction.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,10 +90,12 @@ public final EvalOperator.ExpressionEvaluator.Factory toEvaluator(EvaluatorMappe
9090
}
9191

9292
@Override
93-
public boolean isPushable() {
93+
public PushableOptions pushableOptions() {
9494
// Can only push if one of the arguments is a literal, and the other a field name
9595
return left().foldable() && left().dataType() != NULL && right() instanceof FieldAttribute
96-
|| right().foldable() && right().dataType() != NULL && left() instanceof FieldAttribute;
96+
|| right().foldable() && right().dataType() != NULL && left() instanceof FieldAttribute
97+
? PushableOptions.PREFERRED
98+
: PushableOptions.NOT_SUPPORTED;
9799
}
98100

99101
@Override

x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/predicate/operator/arithmetic/EsqlArithmeticOperation.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -165,8 +165,8 @@ public static String formatIncompatibleTypesMessage(String symbol, DataType left
165165
}
166166

167167
@Override
168-
public boolean isPushable() {
169-
return left().isPushable() && right().isPushable();
168+
public PushableOptions pushableOptions() {
169+
return left().pushableOptions().and(right().pushableOptions());
170170
}
171171

172172
@Override

x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/optimizer/rules/physical/local/PushScriptsToSource.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import org.elasticsearch.search.sort.SortBuilder;
1414
import org.elasticsearch.search.sort.SortOrder;
1515
import org.elasticsearch.xpack.esql.core.expression.Alias;
16+
import org.elasticsearch.xpack.esql.core.expression.Expression;
1617
import org.elasticsearch.xpack.esql.core.expression.FieldAttribute;
1718
import org.elasticsearch.xpack.esql.core.type.DataType;
1819
import org.elasticsearch.xpack.esql.core.type.EsField;
@@ -38,8 +39,7 @@ protected PhysicalPlan rule(EvalExec evalExec, LocalPhysicalOptimizerContext ctx
3839
List<Alias> nonPushedAliases = new ArrayList<>();
3940
EvalExec scriptEval = null;
4041
for (Alias alias : aliases) {
41-
if (aliasPushed == false && alias.child().isPushable()) {
42-
42+
if (aliasPushed == false && alias.child().pushableOptions() == Expression.PushableOptions.PREFERRED) {
4343
if (esQueryExec.sorts() != null
4444
&& esQueryExec.sorts()
4545
.stream()

x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/optimizer/rules/physical/local/PushTopNToSource.java

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
import org.elasticsearch.geometry.Geometry;
1111
import org.elasticsearch.geometry.Point;
1212
import org.elasticsearch.script.Script;
13-
import org.elasticsearch.search.sort.ScriptSortBuilder;
1413
import org.elasticsearch.xpack.esql.core.expression.Alias;
1514
import org.elasticsearch.xpack.esql.core.expression.Attribute;
1615
import org.elasticsearch.xpack.esql.core.expression.AttributeMap;
@@ -20,8 +19,6 @@
2019
import org.elasticsearch.xpack.esql.core.expression.MetadataAttribute;
2120
import org.elasticsearch.xpack.esql.core.expression.NameId;
2221
import org.elasticsearch.xpack.esql.core.expression.ReferenceAttribute;
23-
import org.elasticsearch.xpack.esql.core.type.DataType;
24-
import org.elasticsearch.xpack.esql.core.type.EsField;
2522
import org.elasticsearch.xpack.esql.expression.Foldables;
2623
import org.elasticsearch.xpack.esql.expression.Order;
2724
import org.elasticsearch.xpack.esql.expression.function.scalar.spatial.BinarySpatialFunction;
@@ -133,27 +130,18 @@ private static PushableGeoDistance from(FoldContext ctx, Attribute attr, Express
133130
record PushableCompoundExec(EvalExec evalExec, EsQueryExec queryExec, List<EsQueryExec.Sort> pushableSorts) implements Pushable {
134131
public PhysicalPlan rewrite(TopNExec topNExec) {
135132
List<Alias> evalExecAlias = evalExec.fields();
136-
List<FieldAttribute> additionalQueryAttrs = new ArrayList<>();
137-
boolean aliasChanged = false;
138133
for (EsQueryExec.Sort pushableSort : pushableSorts) {
139134
if (pushableSort instanceof EsQueryExec.ScriptSort scriptSort) {
140135
// Change eval alias to the script sort field
141136
for(int i = 0; i < evalExecAlias.size(); i++) {
142137
Alias alias = evalExecAlias.get(i);
143138
if (alias.id().equals(scriptSort.alias().id())) {
144139
evalExecAlias.set(i, alias.replaceChild(scriptSort.field()));
145-
additionalQueryAttrs.add(scriptSort.field());
146-
aliasChanged = true;
147140
break;
148141
}
149142
}
150143
}
151144
}
152-
if (aliasChanged) {
153-
EsQueryExec newQueryExec = queryExec.withSorts(pushableSorts).withLimit(topNExec.limit());
154-
// newQueryExec.attrs().addAll(additionalQueryAttrs);
155-
EvalExec newEvalExec = new EvalExec(evalExec.source(), evalExec.child(), evalExecAlias);
156-
}
157145

158146
// We need to keep the EVAL in place because the coordinator will have its own TopNExec so we need to keep the distance
159147
return evalExec.replaceChild(queryExec.withSorts(pushableSorts).withLimit(topNExec.limit()));
@@ -191,7 +179,7 @@ && canPushLimit(topNExec, plannerSettings)) {
191179
distances.put(alias.id(), distance);
192180
} else if (alias.child() instanceof Attribute attr) {
193181
aliasReplacedByBuilder.put(alias.toAttribute(), attr.toAttribute());
194-
} else if (alias.child().isPushable()) {
182+
} else if (alias.child().pushableOptions() == Expression.PushableOptions.PREFERRED) {
195183
pushableExpressions.put(alias.id(), alias);
196184
}
197185
});

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import org.elasticsearch.search.sort.FieldSortBuilder;
3939
import org.elasticsearch.search.sort.GeoDistanceSortBuilder;
4040
import org.elasticsearch.test.ESTestCase;
41+
import org.elasticsearch.test.junit.annotations.TestLogging;
4142
import org.elasticsearch.xpack.core.enrich.EnrichPolicy;
4243
import org.elasticsearch.xpack.esql.EsqlTestUtils;
4344
import org.elasticsearch.xpack.esql.EsqlTestUtils.TestConfigurableSearchStats;
@@ -216,7 +217,7 @@
216217
import static org.hamcrest.Matchers.nullValue;
217218
import static org.hamcrest.Matchers.startsWith;
218219

219-
// @TestLogging(value = "org.elasticsearch.xpack.esql:TRACE", reason = "debug")
220+
@TestLogging(value = "org.elasticsearch.xpack.esql:TRACE", reason = "debug")
220221
public class PhysicalPlanOptimizerTests extends ESTestCase {
221222

222223
private static final String PARAM_FORMATTING = "%1$s";

0 commit comments

Comments
 (0)