Skip to content

Commit a50e0be

Browse files
committed
Add MatchPhraseTests
1 parent 0ebbf82 commit a50e0be

File tree

1 file changed

+102
-0
lines changed
  • x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/fulltext

1 file changed

+102
-0
lines changed
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License
4+
* 2.0; you may not use this file except in compliance with the Elastic License
5+
* 2.0.
6+
*/
7+
8+
package org.elasticsearch.xpack.esql.expression.function.fulltext;
9+
10+
import com.carrotsearch.randomizedtesting.annotations.Name;
11+
import com.carrotsearch.randomizedtesting.annotations.ParametersFactory;
12+
13+
import org.elasticsearch.index.query.QueryBuilder;
14+
import org.elasticsearch.xpack.esql.core.expression.Expression;
15+
import org.elasticsearch.xpack.esql.core.expression.FieldAttribute;
16+
import org.elasticsearch.xpack.esql.core.expression.Literal;
17+
import org.elasticsearch.xpack.esql.core.expression.MapExpression;
18+
import org.elasticsearch.xpack.esql.core.tree.Source;
19+
import org.elasticsearch.xpack.esql.core.type.DataType;
20+
import org.elasticsearch.xpack.esql.expression.function.FunctionName;
21+
import org.elasticsearch.xpack.esql.expression.function.TestCaseSupplier;
22+
import org.elasticsearch.xpack.esql.io.stream.PlanStreamOutput;
23+
import org.elasticsearch.xpack.esql.optimizer.rules.physical.local.LucenePushdownPredicates;
24+
25+
import java.util.ArrayList;
26+
import java.util.List;
27+
import java.util.function.Supplier;
28+
29+
import static org.elasticsearch.xpack.esql.SerializationTestUtils.serializeDeserialize;
30+
import static org.elasticsearch.xpack.esql.core.type.DataType.BOOLEAN;
31+
import static org.elasticsearch.xpack.esql.core.type.DataType.INTEGER;
32+
import static org.elasticsearch.xpack.esql.core.type.DataType.KEYWORD;
33+
import static org.elasticsearch.xpack.esql.core.type.DataType.UNSUPPORTED;
34+
import static org.elasticsearch.xpack.esql.planner.TranslatorHandler.TRANSLATOR_HANDLER;
35+
import static org.hamcrest.Matchers.equalTo;
36+
37+
@FunctionName("match_phrase")
38+
public class MatchPhraseTests extends AbstractMatchFullTextFunctionTests {
39+
40+
public MatchPhraseTests(@Name("TestCase") Supplier<TestCaseSupplier.TestCase> testCaseSupplier) {
41+
this.testCase = testCaseSupplier.get();
42+
}
43+
44+
@ParametersFactory
45+
public static Iterable<Object[]> parameters() {
46+
return parameterSuppliersFromTypedData(addFunctionNamedParams(testCaseSuppliers()));
47+
}
48+
49+
/**
50+
* Adds function named parameters to all the test case suppliers provided
51+
*/
52+
private static List<TestCaseSupplier> addFunctionNamedParams(List<TestCaseSupplier> suppliers) {
53+
List<TestCaseSupplier> result = new ArrayList<>();
54+
for (TestCaseSupplier supplier : suppliers) {
55+
List<DataType> dataTypes = new ArrayList<>(supplier.types());
56+
dataTypes.add(UNSUPPORTED);
57+
result.add(new TestCaseSupplier(supplier.name() + ", options", dataTypes, () -> {
58+
List<TestCaseSupplier.TypedData> values = new ArrayList<>(supplier.get().getData());
59+
values.add(
60+
new TestCaseSupplier.TypedData(
61+
new MapExpression(
62+
Source.EMPTY,
63+
List.of(new Literal(Source.EMPTY, "slop", INTEGER), new Literal(Source.EMPTY, randomAlphaOfLength(10), KEYWORD))
64+
),
65+
UNSUPPORTED,
66+
"options"
67+
).forceLiteral()
68+
);
69+
70+
return new TestCaseSupplier.TestCase(values, equalTo("MatchPhraseEvaluator"), BOOLEAN, equalTo(true));
71+
}));
72+
}
73+
return result;
74+
}
75+
76+
@Override
77+
protected Expression build(Source source, List<Expression> args) {
78+
MatchPhrase matchPhrase = new MatchPhrase(source, args.get(0), args.get(1), args.size() > 2 ? args.get(2) : null);
79+
// We need to add the QueryBuilder to the match_phrase expression, as it is used to implement equals() and hashCode() and
80+
// thus test the serialization methods. But we can only do this if the parameters make sense .
81+
if (args.get(0) instanceof FieldAttribute && args.get(1).foldable()) {
82+
QueryBuilder queryBuilder = TRANSLATOR_HANDLER.asQuery(LucenePushdownPredicates.DEFAULT, matchPhrase).toQueryBuilder();
83+
matchPhrase.replaceQueryBuilder(queryBuilder);
84+
}
85+
return matchPhrase;
86+
}
87+
88+
/**
89+
* Copy of the overridden method that doesn't check for children size, as the {@code options} child isn't serialized in MatchPhrase.
90+
*/
91+
@Override
92+
protected Expression serializeDeserializeExpression(Expression expression) {
93+
Expression newExpression = serializeDeserialize(
94+
expression,
95+
PlanStreamOutput::writeNamedWriteable,
96+
in -> in.readNamedWriteable(Expression.class),
97+
testCase.getConfiguration() // The configuration query should be == to the source text of the function for this to work
98+
);
99+
// Fields use synthetic sources, which can't be serialized. So we use the originals instead.
100+
return newExpression.replaceChildren(expression.children());
101+
}
102+
}

0 commit comments

Comments
 (0)