LUCENE-8810: Honor MaxClausesCount in BooleanQuery (#787)

During Flattening, BooleanQuery will always try to flatten
nested clauses during rewrite. However, this can cause the
maximum number of clauses to be violated by the new query.
This commit disables flattening in the specific case.
This commit is contained in:
Atri Sharma 2019-07-15 19:04:27 +05:30 committed by Adrien Grand
parent 2885a11578
commit a94093102e
2 changed files with 31 additions and 12 deletions

View File

@ -481,23 +481,27 @@ public class BooleanQuery extends Query implements Iterable<BooleanClause> {
BooleanQuery.Builder builder = new BooleanQuery.Builder();
builder.setMinimumNumberShouldMatch(minimumNumberShouldMatch);
boolean actuallyRewritten = false;
for (BooleanClause clause : clauses) {
if (clause.getOccur() == Occur.SHOULD && clause.getQuery() instanceof BooleanQuery) {
BooleanQuery innerQuery = (BooleanQuery) clause.getQuery();
if (innerQuery.isPureDisjunction()) {
actuallyRewritten = true;
for (BooleanClause innerClause : innerQuery.clauses()) {
builder.add(innerClause);
try {
for (BooleanClause clause : clauses) {
if (clause.getOccur() == Occur.SHOULD && clause.getQuery() instanceof BooleanQuery) {
BooleanQuery innerQuery = (BooleanQuery) clause.getQuery();
if (innerQuery.isPureDisjunction()) {
actuallyRewritten = true;
for (BooleanClause innerClause : innerQuery.clauses()) {
builder.add(innerClause);
}
} else {
builder.add(clause);
}
} else {
builder.add(clause);
}
} else {
builder.add(clause);
}
}
if (actuallyRewritten) {
return builder.build();
if (actuallyRewritten) {
return builder.build();
}
} catch (TooManyClauses exception) {
// No-op : Do not flatten when the new query will violate max clause count
}
}

View File

@ -598,4 +598,19 @@ public class TestBooleanRewrites extends LuceneTestCase {
w.close();
dir.close();
}
public void testFlattenInnerDisjunctionsWithMoreThan1024Terms() throws IOException {
IndexSearcher searcher = newSearcher(new MultiReader());
BooleanQuery.Builder builder1024 = new BooleanQuery.Builder();
for(int i = 0; i < 1024; i++) {
builder1024.add(new TermQuery(new Term("foo", "bar-" + i)), Occur.SHOULD);
}
Query inner = builder1024.build();
Query query = new BooleanQuery.Builder()
.add(inner, Occur.SHOULD)
.add(new TermQuery(new Term("foo", "baz")), Occur.SHOULD)
.build();
assertSame(query, searcher.rewrite(query));
}
}