Skip to content

Commit

Permalink
Fix random failure on SearchQueryIT#testTermExpansionExceptionOnSpanF…
Browse files Browse the repository at this point in the history
…ailure

This change moves an integration test that relies on setting
the value of a static variable (boolean max clause count) to
an unit test where we are sure that the same jvm is used to access
the static variable.
  • Loading branch information
jimczi committed Jun 7, 2018
1 parent 6ad7217 commit 280a2f5
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 65 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -137,47 +137,42 @@ public static SpanMultiTermQueryBuilder fromXContent(XContentParser parser) thro
return new SpanMultiTermQueryBuilder(subQuery).queryName(queryName).boost(boost);
}

public static class TopTermSpanBooleanQueryRewriteWithMaxClause extends SpanMultiTermQueryWrapper.SpanRewriteMethod {

private MultiTermQuery multiTermQuery;
static class TopTermSpanBooleanQueryRewriteWithMaxClause extends SpanMultiTermQueryWrapper.SpanRewriteMethod {
private final long maxExpansions;

TopTermSpanBooleanQueryRewriteWithMaxClause(long max) {
maxExpansions = max;
TopTermSpanBooleanQueryRewriteWithMaxClause() {
this.maxExpansions = BooleanQuery.getMaxClauseCount();
}

@Override
public SpanQuery rewrite(IndexReader reader, MultiTermQuery query) throws IOException {
multiTermQuery = query;
return (SpanQuery) this.delegate.rewrite(reader, multiTermQuery);
}

final ScoringRewrite<List<SpanQuery>> delegate = new ScoringRewrite<List<SpanQuery>>() {

@Override
protected List<SpanQuery> getTopLevelBuilder() {
return new ArrayList();
}
final MultiTermQuery.RewriteMethod delegate = new ScoringRewrite<List<SpanQuery>>() {
@Override
protected List<SpanQuery> getTopLevelBuilder() {
return new ArrayList();
}

@Override
protected Query build(List<SpanQuery> builder) {
return new SpanOrQuery((SpanQuery[]) builder.toArray(new SpanQuery[builder.size()]));
}
@Override
protected Query build(List<SpanQuery> builder) {
return new SpanOrQuery((SpanQuery[]) builder.toArray(new SpanQuery[builder.size()]));
}

@Override
protected void checkMaxClauseCount(int count) {
if (count > maxExpansions) {
throw new ElasticsearchException("[" + multiTermQuery.toString() + " ] " +
"exceeds maxClauseCount [ Boolean maxClauseCount is set to " + BooleanQuery.getMaxClauseCount() + "]");
@Override
protected void checkMaxClauseCount(int count) {
if (count > maxExpansions) {
throw new RuntimeException("[" + query.toString() + " ] " +
"exceeds maxClauseCount [ Boolean maxClauseCount is set to " + BooleanQuery.getMaxClauseCount() + "]");
}
}
}

@Override
protected void addClause(List<SpanQuery> topLevel, Term term, int docCount, float boost, TermContext states) {
SpanTermQuery q = new SpanTermQuery(term, states);
topLevel.add(q);
}
};
@Override
protected void addClause(List<SpanQuery> topLevel, Term term, int docCount, float boost, TermContext states) {
SpanTermQuery q = new SpanTermQuery(term, states);
topLevel.add(q);
}
};
return (SpanQuery) delegate.rewrite(reader, query);
}
}

@Override
Expand Down Expand Up @@ -222,6 +217,7 @@ protected Query doToQuery(QueryShardContext context) throws IOException {
QueryParsers.parseRewriteMethod(prefixBuilder.rewrite(), null, LoggingDeprecationHandler.INSTANCE);
prefixQuery.setRewriteMethod(rewriteMethod);
}
subQuery = prefixQuery;
spanQuery = new SpanMultiTermQueryWrapper<>(prefixQuery);
} else {
String origFieldName = ((PrefixQueryBuilder) multiTermQueryBuilder).fieldName();
Expand All @@ -240,9 +236,12 @@ protected Query doToQuery(QueryShardContext context) throws IOException {
+ MultiTermQuery.class.getName() + " but was " + subQuery.getClass().getName());
}
spanQuery = new SpanMultiTermQueryWrapper<>((MultiTermQuery) subQuery);
if (((MultiTermQuery) subQuery).getRewriteMethod() instanceof TopTermsRewrite == false) {
((SpanMultiTermQueryWrapper<MultiTermQuery>) spanQuery).setRewriteMethod(new
TopTermSpanBooleanQueryRewriteWithMaxClause(BooleanQuery.getMaxClauseCount()));
}
if (subQuery instanceof MultiTermQuery) {
MultiTermQuery multiTermQuery = (MultiTermQuery) subQuery;
SpanMultiTermQueryWrapper<?> wrapper = (SpanMultiTermQueryWrapper<?>) spanQuery;
if (multiTermQuery.getRewriteMethod() instanceof TopTermsRewrite == false) {
wrapper.setRewriteMethod(new TopTermSpanBooleanQueryRewriteWithMaxClause());
}
}
if (boost != AbstractQueryBuilder.DEFAULT_BOOST) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,13 @@

package org.elasticsearch.index.query;

import org.apache.lucene.analysis.core.WhitespaceAnalyzer;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.RandomIndexWriter;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.BoostQuery;
import org.apache.lucene.search.MultiTermQuery;
import org.apache.lucene.search.PrefixQuery;
Expand All @@ -30,6 +36,7 @@
import org.apache.lucene.search.spans.SpanMultiTermQueryWrapper;
import org.apache.lucene.search.spans.SpanQuery;
import org.apache.lucene.search.spans.SpanTermQuery;
import org.apache.lucene.store.Directory;
import org.elasticsearch.Version;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.compress.CompressedXContent;
Expand All @@ -41,6 +48,7 @@

import java.io.IOException;

import static java.util.Collections.singleton;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.equalTo;
Expand Down Expand Up @@ -251,14 +259,37 @@ public void testDefaultMaxRewriteBuilder() throws Exception {
MultiTermQuery.RewriteMethod rewriteMethod = ((SpanMultiTermQueryWrapper)query).getRewriteMethod();
assertTrue(rewriteMethod instanceof SpanMultiTermQueryBuilder.TopTermSpanBooleanQueryRewriteWithMaxClause);
}
}

public void testTermExpansionExceptionOnSpanFailure() throws Exception {
try (Directory directory = newDirectory()) {
try (RandomIndexWriter iw = new RandomIndexWriter(random(), directory, new WhitespaceAnalyzer())) {
for (int i = 0; i < 3; i++) {
iw.addDocument(singleton(new TextField("body", "foo bar" + Integer.toString(i), Field.Store.NO)));
}
try (IndexReader reader = iw.getReader()) {
int origBoolMaxClauseCount = BooleanQuery.getMaxClauseCount();
BooleanQuery.setMaxClauseCount(1);
try {
QueryBuilder queryBuilder = new SpanMultiTermQueryBuilder(
QueryBuilders.prefixQuery("body", "bar")
);
Query query = queryBuilder.toQuery(createShardContext(reader));
RuntimeException exc = expectThrows(RuntimeException.class, () -> query.rewrite(reader));
assertThat(exc.getMessage(), containsString("maxClauseCount"));

} finally {
BooleanQuery.setMaxClauseCount(origBoolMaxClauseCount);
}
}
}
}
}

public void testTopNMultiTermsRewriteInsideSpan() throws Exception {

Query query = QueryBuilders.spanMultiTermQueryBuilder(QueryBuilders.prefixQuery("foo", "b").rewrite
("top_terms_boost_2000")).
toQuery(createShardContext());
Query query = QueryBuilders.spanMultiTermQueryBuilder(
QueryBuilders.prefixQuery("foo", "b").rewrite("top_terms_boost_2000")
).toQuery(createShardContext());

if (query instanceof SpanBoostQuery) {
query = ((SpanBoostQuery)query).getQuery();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1825,31 +1825,4 @@ public void testRangeQueryRangeFields_24744() throws Exception {
SearchResponse searchResponse = client().prepareSearch("test").setQuery(range).get();
assertHitCount(searchResponse, 1);
}

public void testTermExpansionExceptionOnSpanFailure() throws ExecutionException, InterruptedException {
Settings.Builder builder = Settings.builder();
builder.put(SETTING_NUMBER_OF_SHARDS, 1).build();

createIndex("test", builder.build());
ArrayList<IndexRequestBuilder> reqs = new ArrayList<>();
int origBoolMaxClauseCount = BooleanQuery.getMaxClauseCount();
try {
BooleanQuery.setMaxClauseCount(2);
for (int i = 0; i < BooleanQuery.getMaxClauseCount() + 1; i++) {
reqs.add(client().prepareIndex("test", "_doc", Integer.toString(i)).setSource("body", "foo" +
Integer.toString(i) + " bar baz"));
}
indexRandom(true, false, reqs);

QueryBuilder queryBuilder = new SpanNearQueryBuilder(new SpanMultiTermQueryBuilder(QueryBuilders.wildcardQuery
("body", "f*")), 0).addClause(new SpanTermQueryBuilder("body", "bar"));

expectThrows(ElasticsearchException.class, () ->
client().prepareSearch().setIndices("test").setQuery(queryBuilder).get());
} finally {
BooleanQuery.setMaxClauseCount(origBoolMaxClauseCount);
}

}

}

0 comments on commit 280a2f5

Please sign in to comment.