Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import org.elasticsearch.client.Request;
import org.elasticsearch.client.Response;
import org.elasticsearch.client.ResponseException;
import org.elasticsearch.common.collect.Iterators;
import org.elasticsearch.test.ListMatcher;
import org.elasticsearch.test.MapMatcher;
import org.elasticsearch.test.TestClustersThreadFilter;
Expand All @@ -21,6 +22,7 @@
import org.elasticsearch.xcontent.XContentType;
import org.elasticsearch.xpack.esql.AssertWarnings;
import org.elasticsearch.xpack.esql.qa.rest.RestEsqlTestCase;
import org.hamcrest.Matcher;
import org.junit.ClassRule;

import java.io.IOException;
Expand All @@ -39,6 +41,7 @@
import static org.elasticsearch.xpack.esql.qa.rest.RestEsqlTestCase.runEsql;
import static org.elasticsearch.xpack.esql.qa.single_node.RestEsqlIT.commonProfile;
import static org.elasticsearch.xpack.esql.qa.single_node.RestEsqlIT.fixTypesOnProfile;
import static org.hamcrest.Matchers.anyOf;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.startsWith;
Expand Down Expand Up @@ -79,7 +82,7 @@ public void testEquality() throws IOException {
case "match_only_text", "semantic_text" -> true;
default -> throw new UnsupportedOperationException("unknown type [" + type + "]");
};
testPushQuery(value, esqlQuery, luceneQuery, filterInCompute, true);
testPushQuery(value, esqlQuery, List.of(luceneQuery), filterInCompute, true);
}

public void testEqualityTooBigToPush() throws IOException {
Expand All @@ -93,7 +96,7 @@ public void testEqualityTooBigToPush() throws IOException {
case "semantic_text" -> "FieldExistsQuery [field=_primary_term]";
default -> throw new UnsupportedOperationException("unknown type [" + type + "]");
};
testPushQuery(value, esqlQuery, luceneQuery, true, true);
testPushQuery(value, esqlQuery, List.of(luceneQuery), true, true);
}

/**
Expand All @@ -111,7 +114,7 @@ public void testEqualityOrTooBig() throws IOException {
case "semantic_text" -> "FieldExistsQuery [field=_primary_term]";
default -> throw new UnsupportedOperationException("unknown type [" + type + "]");
};
testPushQuery(value, esqlQuery, luceneQuery, true, true);
testPushQuery(value, esqlQuery, List.of(luceneQuery), true, true);
}

public void testEqualityOrOther() throws IOException {
Expand All @@ -131,7 +134,7 @@ public void testEqualityOrOther() throws IOException {
case "match_only_text", "semantic_text" -> true;
default -> throw new UnsupportedOperationException("unknown type [" + type + "]");
};
testPushQuery(value, esqlQuery, luceneQuery, filterInCompute, true);
testPushQuery(value, esqlQuery, List.of(luceneQuery), filterInCompute, true);
}

public void testEqualityAndOther() throws IOException {
Expand All @@ -140,23 +143,23 @@ public void testEqualityAndOther() throws IOException {
FROM test
| WHERE test == "%value" AND foo == 1
""";
String luceneQuery = switch (type) {
case "text", "auto" -> "#test.keyword:%value -_ignored:test.keyword #foo:[1 TO 1]";
case "match_only_text" -> "foo:[1 TO 1]";
List<String> luceneQueryOptions = switch (type) {
case "text", "auto" -> List.of("#test.keyword:%value -_ignored:test.keyword #foo:[1 TO 1]");
case "match_only_text" -> List.of("foo:[1 TO 1]");
case "semantic_text" ->
/*
* single_value_match is here because there are extra documents hiding in the index
* that don't have the `foo` field.
*/
"#foo:[1 TO 1] #single_value_match(foo)";
List.of("#foo:[1 TO 1] #single_value_match(foo)", "foo:[1 TO 1]");
default -> throw new UnsupportedOperationException("unknown type [" + type + "]");
};
boolean filterInCompute = switch (type) {
case "text", "auto" -> false;
case "match_only_text", "semantic_text" -> true;
default -> throw new UnsupportedOperationException("unknown type [" + type + "]");
};
testPushQuery(value, esqlQuery, luceneQuery, filterInCompute, true);
testPushQuery(value, esqlQuery, luceneQueryOptions, filterInCompute, true);
}

public void testInequality() throws IOException {
Expand All @@ -171,7 +174,7 @@ public void testInequality() throws IOException {
case "semantic_text" -> "FieldExistsQuery [field=_primary_term]";
default -> throw new UnsupportedOperationException("unknown type [" + type + "]");
};
testPushQuery(value, esqlQuery, luceneQuery, true, true);
testPushQuery(value, esqlQuery, List.of(luceneQuery), true, true);
}

public void testInequalityTooBigToPush() throws IOException {
Expand All @@ -185,7 +188,7 @@ public void testInequalityTooBigToPush() throws IOException {
case "semantic_text" -> "FieldExistsQuery [field=_primary_term]";
default -> throw new UnsupportedOperationException("unknown type [" + type + "]");
};
testPushQuery(value, esqlQuery, luceneQuery, true, false);
testPushQuery(value, esqlQuery, List.of(luceneQuery), true, false);
}

public void testCaseInsensitiveEquality() throws IOException {
Expand All @@ -199,10 +202,10 @@ public void testCaseInsensitiveEquality() throws IOException {
case "semantic_text" -> "FieldExistsQuery [field=_primary_term]";
default -> throw new UnsupportedOperationException("unknown type [" + type + "]");
};
testPushQuery(value, esqlQuery, luceneQuery, true, true);
testPushQuery(value, esqlQuery, List.of(luceneQuery), true, true);
}

private void testPushQuery(String value, String esqlQuery, String luceneQuery, boolean filterInCompute, boolean found)
private void testPushQuery(String value, String esqlQuery, List<String> luceneQueryOptions, boolean filterInCompute, boolean found)
throws IOException {
indexValue(value);
String differentValue = randomValueOtherThan(value, () -> randomAlphaOfLength(value.isEmpty() ? 1 : value.length()));
Expand All @@ -222,6 +225,12 @@ private void testPushQuery(String value, String esqlQuery, String luceneQuery, b
matchesList().item(matchesMap().entry("name", "test").entry("type", "text")),
equalTo(found ? List.of(List.of(value)) : List.of())
);
Matcher<String> luceneQueryMatcher = anyOf(
() -> Iterators.map(
luceneQueryOptions.iterator(),
(String s) -> equalTo(s.replaceAll("%value", value).replaceAll("%different_value", differentValue))
)
);

@SuppressWarnings("unchecked")
List<Map<String, Object>> profiles = (List<Map<String, Object>>) ((Map<String, Object>) result.get("profile")).get("drivers");
Expand All @@ -232,7 +241,7 @@ private void testPushQuery(String value, String esqlQuery, String luceneQuery, b
@SuppressWarnings("unchecked")
List<Map<String, Object>> operators = (List<Map<String, Object>>) p.get("operators");
for (Map<String, Object> o : operators) {
sig.add(checkOperatorProfile(o, luceneQuery.replaceAll("%value", value).replaceAll("%different_value", differentValue)));
sig.add(checkOperatorProfile(o, luceneQueryMatcher));
}
String description = p.get("description").toString();
switch (description) {
Expand Down Expand Up @@ -317,7 +326,7 @@ private void indexValue(String value) throws IOException {

private static final Pattern TO_NAME = Pattern.compile("\\[.+", Pattern.DOTALL);

private static String checkOperatorProfile(Map<String, Object> o, String query) {
private static String checkOperatorProfile(Map<String, Object> o, Matcher<String> query) {
String name = (String) o.get("operator");
name = TO_NAME.matcher(name).replaceAll("");
if (name.equals("LuceneSourceOperator")) {
Expand Down