|
7 | 7 |
|
8 | 8 | package org.elasticsearch.xpack.esql.expression.function.scalar.string; |
9 | 9 |
|
| 10 | +import org.apache.lucene.queryparser.classic.QueryParser; |
10 | 11 | import org.apache.lucene.util.BytesRef; |
11 | 12 | import org.elasticsearch.common.io.stream.NamedWriteableRegistry; |
12 | 13 | import org.elasticsearch.common.io.stream.StreamInput; |
13 | 14 | import org.elasticsearch.common.io.stream.StreamOutput; |
| 15 | +import org.elasticsearch.common.lucene.BytesRefs; |
14 | 16 | import org.elasticsearch.compute.ann.Evaluator; |
15 | 17 | import org.elasticsearch.compute.operator.EvalOperator.ExpressionEvaluator; |
| 18 | +import org.elasticsearch.xpack.esql.capabilities.TranslationAware; |
16 | 19 | import org.elasticsearch.xpack.esql.core.expression.Expression; |
| 20 | +import org.elasticsearch.xpack.esql.core.expression.FieldAttribute; |
| 21 | +import org.elasticsearch.xpack.esql.core.expression.FoldContext; |
| 22 | +import org.elasticsearch.xpack.esql.core.querydsl.query.Query; |
| 23 | +import org.elasticsearch.xpack.esql.core.querydsl.query.WildcardQuery; |
17 | 24 | import org.elasticsearch.xpack.esql.core.tree.NodeInfo; |
18 | 25 | import org.elasticsearch.xpack.esql.core.tree.Source; |
19 | 26 | import org.elasticsearch.xpack.esql.core.type.DataType; |
|
22 | 29 | import org.elasticsearch.xpack.esql.expression.function.Param; |
23 | 30 | import org.elasticsearch.xpack.esql.expression.function.scalar.EsqlScalarFunction; |
24 | 31 | import org.elasticsearch.xpack.esql.io.stream.PlanStreamInput; |
| 32 | +import org.elasticsearch.xpack.esql.optimizer.rules.physical.local.LucenePushdownPredicates; |
| 33 | +import org.elasticsearch.xpack.esql.planner.TranslatorHandler; |
25 | 34 |
|
26 | 35 | import java.io.IOException; |
27 | 36 | import java.util.Arrays; |
|
31 | 40 | import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.ParamOrdinal.SECOND; |
32 | 41 | import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.isString; |
33 | 42 |
|
34 | | -public class EndsWith extends EsqlScalarFunction { |
| 43 | +public class EndsWith extends EsqlScalarFunction implements TranslationAware.SingleValueTranslationAware { |
35 | 44 | public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry(Expression.class, "EndsWith", EndsWith::new); |
36 | 45 |
|
37 | 46 | private final Expression str; |
@@ -129,6 +138,27 @@ public ExpressionEvaluator.Factory toEvaluator(ToEvaluator toEvaluator) { |
129 | 138 | return new EndsWithEvaluator.Factory(source(), toEvaluator.apply(str), toEvaluator.apply(suffix)); |
130 | 139 | } |
131 | 140 |
|
| 141 | + @Override |
| 142 | + public boolean translatable(LucenePushdownPredicates pushdownPredicates) { |
| 143 | + return pushdownPredicates.isPushableAttribute(str) && suffix.foldable(); |
| 144 | + } |
| 145 | + |
| 146 | + @Override |
| 147 | + public Query asQuery(TranslatorHandler handler) { |
| 148 | + LucenePushdownPredicates.checkIsPushableAttribute(str); |
| 149 | + var fieldName = handler.nameOf(str instanceof FieldAttribute fa ? fa.exactAttribute() : str); |
| 150 | + |
| 151 | + // TODO: Get the real FoldContext here |
| 152 | + var wildcardQuery = "*" + QueryParser.escape(BytesRefs.toString(suffix.fold(FoldContext.small()))); |
| 153 | + |
| 154 | + return new WildcardQuery(source(), fieldName, wildcardQuery); |
| 155 | + } |
| 156 | + |
| 157 | + @Override |
| 158 | + public Expression singleValueField() { |
| 159 | + return str; |
| 160 | + } |
| 161 | + |
132 | 162 | Expression str() { |
133 | 163 | return str; |
134 | 164 | } |
|
0 commit comments