LUCENE-8811: Move max clause checks to IndexSearcher

This commit is contained in:
Alan Woodward 2019-06-26 09:36:42 +01:00
parent 889f73105f
commit 53f56fb7ad
39 changed files with 343 additions and 129 deletions

View File

@ -39,6 +39,11 @@ API Changes
This change is fully backwards compatible since ExecutorService directly This change is fully backwards compatible since ExecutorService directly
implements Executor. (Simon Willnauer) implements Executor. (Simon Willnauer)
* LUCENE-8811: BooleanQuery#setMaxClauseCount() and #getMaxClauseCount() have
moved to IndexSearcher. The checks are now implemented using a QueryVisitor
and apply to all queries, rather than only booleans. (Atri Sharma, Adrien
Grand, Alan Woodward)
New Features New Features
* LUCENE-8815: Provide a DoubleValues implementation for retrieving the value of features without * LUCENE-8815: Provide a DoubleValues implementation for retrieving the value of features without

View File

@ -178,3 +178,7 @@ by the LegacyBM25Similarity class which can be found in the lucene-misc jar.
IndexWriter#getDocStats() should be used instead of #maxDoc() / #numDocs() which offers a consistent IndexWriter#getDocStats() should be used instead of #maxDoc() / #numDocs() which offers a consistent
view on document stats. Previously calling two methods in order ot get point in time stats was subject view on document stats. Previously calling two methods in order ot get point in time stats was subject
to concurrent changes. to concurrent changes.
## maxClausesCount moved from BooleanQuery To IndexSearcher (LUCENE-8811) ##
IndexSearcher now performs max clause count checks on all types of queries (including BooleanQueries).
This led to a logical move of the clauses count from BooleanQuery to IndexSearcher.

View File

@ -86,8 +86,8 @@ public final class BlendedTermQuery extends Query {
* object constructed for the given term. * object constructed for the given term.
*/ */
public Builder add(Term term, float boost, TermStates context) { public Builder add(Term term, float boost, TermStates context) {
if (numTerms >= BooleanQuery.getMaxClauseCount()) { if (numTerms >= IndexSearcher.getMaxClauseCount()) {
throw new BooleanQuery.TooManyClauses(); throw new IndexSearcher.TooManyClauses();
} }
terms = ArrayUtil.grow(terms, numTerms + 1); terms = ArrayUtil.grow(terms, numTerms + 1);
boosts = ArrayUtil.grow(boosts, numTerms + 1); boosts = ArrayUtil.grow(boosts, numTerms + 1);

View File

@ -41,35 +41,32 @@ import org.apache.lucene.search.BooleanClause.Occur;
*/ */
public class BooleanQuery extends Query implements Iterable<BooleanClause> { public class BooleanQuery extends Query implements Iterable<BooleanClause> {
private static int maxClauseCount = 1024;
/** Thrown when an attempt is made to add more than {@link /** Thrown when an attempt is made to add more than {@link
* #getMaxClauseCount()} clauses. This typically happens if * #getMaxClauseCount()} clauses. This typically happens if
* a PrefixQuery, FuzzyQuery, WildcardQuery, or TermRangeQuery * a PrefixQuery, FuzzyQuery, WildcardQuery, or TermRangeQuery
* is expanded to many terms during search. * is expanded to many terms during search.
* @deprecated use {@link IndexSearcher.TooManyClauses}
*/ */
public static class TooManyClauses extends RuntimeException { @Deprecated
public TooManyClauses() { public static class TooManyClauses extends IndexSearcher.TooManyClauses { }
super("maxClauseCount is set to " + maxClauseCount);
}
}
/** Return the maximum number of clauses permitted, 1024 by default. /** Return the maximum number of clauses permitted, 1024 by default.
* Attempts to add more than the permitted number of clauses cause {@link * Attempts to add more than the permitted number of clauses cause {@link
* TooManyClauses} to be thrown. * TooManyClauses} to be thrown.
* @see #setMaxClauseCount(int) * @see IndexSearcher#setMaxClauseCount(int)
* @deprecated use {@link IndexSearcher#getMaxClauseCount()}
*/ */
public static int getMaxClauseCount() { return maxClauseCount; } @Deprecated
public static int getMaxClauseCount() { return IndexSearcher.getMaxClauseCount(); }
/** /**
* Set the maximum number of clauses permitted per BooleanQuery. * Set the maximum number of clauses permitted per BooleanQuery.
* Default value is 1024. * Default value is 1024.
* @deprecated use {@link IndexSearcher#setMaxClauseCount(int)}
*/ */
@Deprecated
public static void setMaxClauseCount(int maxClauseCount) { public static void setMaxClauseCount(int maxClauseCount) {
if (maxClauseCount < 1) { IndexSearcher.setMaxClauseCount(maxClauseCount);
throw new IllegalArgumentException("maxClauseCount must be >= 1");
}
BooleanQuery.maxClauseCount = maxClauseCount;
} }
/** A builder for boolean queries. */ /** A builder for boolean queries. */
@ -107,11 +104,14 @@ public class BooleanQuery extends Query implements Iterable<BooleanClause> {
* Add a new clause to this {@link Builder}. Note that the order in which * Add a new clause to this {@link Builder}. Note that the order in which
* clauses are added does not have any impact on matching documents or query * clauses are added does not have any impact on matching documents or query
* performance. * performance.
* @throws TooManyClauses if the new number of clauses exceeds the maximum clause number * @throws IndexSearcher.TooManyClauses if the new number of clauses exceeds the maximum clause number
*/ */
public Builder add(BooleanClause clause) { public Builder add(BooleanClause clause) {
if (clauses.size() >= maxClauseCount) { // We do the final deep check for max clauses count limit during
throw new TooManyClauses(); //<code>IndexSearcher.rewrite</code> but do this check to short
// circuit in case a single query holds more than numClauses
if (clauses.size() >= IndexSearcher.maxClauseCount) {
throw new IndexSearcher.TooManyClauses();
} }
clauses.add(clause); clauses.add(clause);
return this; return this;
@ -121,7 +121,7 @@ public class BooleanQuery extends Query implements Iterable<BooleanClause> {
* Add a new clause to this {@link Builder}. Note that the order in which * Add a new clause to this {@link Builder}. Note that the order in which
* clauses are added does not have any impact on matching documents or query * clauses are added does not have any impact on matching documents or query
* performance. * performance.
* @throws TooManyClauses if the new number of clauses exceeds the maximum clause number * @throws IndexSearcher.TooManyClauses if the new number of clauses exceeds the maximum clause number
*/ */
public Builder add(Query query, Occur occur) { public Builder add(Query query, Occur occur) {
return add(new BooleanClause(query, occur)); return add(new BooleanClause(query, occur));

View File

@ -74,7 +74,7 @@ public class FuzzyQuery extends MultiTermQuery {
* @param maxEdits must be {@code >= 0} and {@code <=} {@link LevenshteinAutomata#MAXIMUM_SUPPORTED_DISTANCE}. * @param maxEdits must be {@code >= 0} and {@code <=} {@link LevenshteinAutomata#MAXIMUM_SUPPORTED_DISTANCE}.
* @param prefixLength length of common (non-fuzzy) prefix * @param prefixLength length of common (non-fuzzy) prefix
* @param maxExpansions the maximum number of terms to match. If this number is * @param maxExpansions the maximum number of terms to match. If this number is
* greater than {@link BooleanQuery#getMaxClauseCount} when the query is rewritten, * greater than {@link IndexSearcher#getMaxClauseCount} when the query is rewritten,
* then the maxClauseCount will be used instead. * then the maxClauseCount will be used instead.
* @param transpositions true if transpositions should be treated as a primitive * @param transpositions true if transpositions should be treated as a primitive
* edit operation. If this is false, comparisons will implement the classic * edit operation. If this is false, comparisons will implement the classic

View File

@ -88,6 +88,7 @@ import org.apache.lucene.util.ThreadInterruptedException;
*/ */
public class IndexSearcher { public class IndexSearcher {
static int maxClauseCount = 1024;
private static QueryCache DEFAULT_QUERY_CACHE; private static QueryCache DEFAULT_QUERY_CACHE;
private static QueryCachingPolicy DEFAULT_CACHING_POLICY = new UsageTrackingQueryCachingPolicy(); private static QueryCachingPolicy DEFAULT_CACHING_POLICY = new UsageTrackingQueryCachingPolicy();
static { static {
@ -115,6 +116,7 @@ public class IndexSearcher {
// in the next release // in the next release
protected final IndexReaderContext readerContext; protected final IndexReaderContext readerContext;
protected final List<LeafReaderContext> leafContexts; protected final List<LeafReaderContext> leafContexts;
/** used with executor - each slice holds a set of leafs executed within one thread */ /** used with executor - each slice holds a set of leafs executed within one thread */
private final LeafSlice[] leafSlices; private final LeafSlice[] leafSlices;
@ -225,6 +227,24 @@ public class IndexSearcher {
this(context, null); this(context, null);
} }
/** Return the maximum number of clauses permitted, 1024 by default.
* Attempts to add more than the permitted number of clauses cause {@link
* TooManyClauses} to be thrown.
* @see #setMaxClauseCount(int)
*/
public static int getMaxClauseCount() { return maxClauseCount; }
/**
* Set the maximum number of clauses permitted per Query.
* Default value is 1024.
*/
public static void setMaxClauseCount(int value) {
if (value < 1) {
throw new IllegalArgumentException("maxClauseCount must be >= 1");
}
maxClauseCount = value;
}
/** /**
* Set the {@link QueryCache} to use when scores are not needed. * Set the {@link QueryCache} to use when scores are not needed.
* A value of {@code null} indicates that query matches should never be * A value of {@code null} indicates that query matches should never be
@ -433,8 +453,8 @@ public class IndexSearcher {
* this method can be used for efficient 'deep-paging' across potentially * this method can be used for efficient 'deep-paging' across potentially
* large result sets. * large result sets.
* *
* @throws BooleanQuery.TooManyClauses If a query would exceed * @throws TooManyClauses If a query would exceed
* {@link BooleanQuery#getMaxClauseCount()} clauses. * {@link IndexSearcher#getMaxClauseCount()} clauses.
*/ */
public TopDocs searchAfter(ScoreDoc after, Query query, int numHits) throws IOException { public TopDocs searchAfter(ScoreDoc after, Query query, int numHits) throws IOException {
final int limit = Math.max(1, reader.maxDoc()); final int limit = Math.max(1, reader.maxDoc());
@ -470,8 +490,8 @@ public class IndexSearcher {
/** Finds the top <code>n</code> /** Finds the top <code>n</code>
* hits for <code>query</code>. * hits for <code>query</code>.
* *
* @throws BooleanQuery.TooManyClauses If a query would exceed * @throws TooManyClauses If a query would exceed
* {@link BooleanQuery#getMaxClauseCount()} clauses. * {@link IndexSearcher#getMaxClauseCount()} clauses.
*/ */
public TopDocs search(Query query, int n) public TopDocs search(Query query, int n)
throws IOException { throws IOException {
@ -482,8 +502,8 @@ public class IndexSearcher {
* *
* <p>{@link LeafCollector#collect(int)} is called for every matching document. * <p>{@link LeafCollector#collect(int)} is called for every matching document.
* *
* @throws BooleanQuery.TooManyClauses If a query would exceed * @throws TooManyClauses If a query would exceed
* {@link BooleanQuery#getMaxClauseCount()} clauses. * {@link IndexSearcher#getMaxClauseCount()} clauses.
*/ */
public void search(Query query, Collector results) public void search(Query query, Collector results)
throws IOException { throws IOException {
@ -502,8 +522,8 @@ public class IndexSearcher {
* <code>true</code> then the maximum score over all * <code>true</code> then the maximum score over all
* collected hits will be computed. * collected hits will be computed.
* *
* @throws BooleanQuery.TooManyClauses If a query would exceed * @throws TooManyClauses If a query would exceed
* {@link BooleanQuery#getMaxClauseCount()} clauses. * {@link IndexSearcher#getMaxClauseCount()} clauses.
*/ */
public TopFieldDocs search(Query query, int n, public TopFieldDocs search(Query query, int n,
Sort sort, boolean doDocScores) throws IOException { Sort sort, boolean doDocScores) throws IOException {
@ -530,8 +550,8 @@ public class IndexSearcher {
* this method can be used for efficient 'deep-paging' across potentially * this method can be used for efficient 'deep-paging' across potentially
* large result sets. * large result sets.
* *
* @throws BooleanQuery.TooManyClauses If a query would exceed * @throws TooManyClauses If a query would exceed
* {@link BooleanQuery#getMaxClauseCount()} clauses. * {@link IndexSearcher#getMaxClauseCount()} clauses.
*/ */
public TopDocs searchAfter(ScoreDoc after, Query query, int n, Sort sort) throws IOException { public TopDocs searchAfter(ScoreDoc after, Query query, int n, Sort sort) throws IOException {
return searchAfter(after, query, n, sort, false); return searchAfter(after, query, n, sort, false);
@ -550,8 +570,8 @@ public class IndexSearcher {
* <code>true</code> then the maximum score over all * <code>true</code> then the maximum score over all
* collected hits will be computed. * collected hits will be computed.
* *
* @throws BooleanQuery.TooManyClauses If a query would exceed * @throws TooManyClauses If a query would exceed
* {@link BooleanQuery#getMaxClauseCount()} clauses. * {@link IndexSearcher#getMaxClauseCount()} clauses.
*/ */
public TopFieldDocs searchAfter(ScoreDoc after, Query query, int numHits, Sort sort, public TopFieldDocs searchAfter(ScoreDoc after, Query query, int numHits, Sort sort,
boolean doDocScores) throws IOException { boolean doDocScores) throws IOException {
@ -678,8 +698,8 @@ public class IndexSearcher {
* to match documents * to match documents
* @param collector * @param collector
* to receive hits * to receive hits
* @throws BooleanQuery.TooManyClauses If a query would exceed * @throws TooManyClauses If a query would exceed
* {@link BooleanQuery#getMaxClauseCount()} clauses. * {@link IndexSearcher#getMaxClauseCount()} clauses.
*/ */
protected void search(List<LeafReaderContext> leaves, Weight weight, Collector collector) protected void search(List<LeafReaderContext> leaves, Weight weight, Collector collector)
throws IOException { throws IOException {
@ -709,8 +729,8 @@ public class IndexSearcher {
} }
/** Expert: called to re-write queries into primitive queries. /** Expert: called to re-write queries into primitive queries.
* @throws BooleanQuery.TooManyClauses If a query would exceed * @throws TooManyClauses If a query would exceed
* {@link BooleanQuery#getMaxClauseCount()} clauses. * {@link IndexSearcher#getMaxClauseCount()} clauses.
*/ */
public Query rewrite(Query original) throws IOException { public Query rewrite(Query original) throws IOException {
Query query = original; Query query = original;
@ -718,9 +738,44 @@ public class IndexSearcher {
rewrittenQuery = query.rewrite(reader)) { rewrittenQuery = query.rewrite(reader)) {
query = rewrittenQuery; query = rewrittenQuery;
} }
query.visit(getNumClausesCheckVisitor());
return query; return query;
} }
/** Returns a QueryVisitor which recursively checks the total
* number of clauses that a query and its children cumulatively
* have and validates that the total number does not exceed
* the specified limit
*/
private static QueryVisitor getNumClausesCheckVisitor() {
return new QueryVisitor() {
int numClauses;
@Override
public QueryVisitor getSubVisitor(BooleanClause.Occur occur, Query parent) {
// Return this instance even for MUST_NOT and not an empty QueryVisitor
return this;
}
@Override
public void visitLeaf(Query query) {
if (numClauses > maxClauseCount) {
throw new TooManyClauses();
}
++numClauses;
}
@Override
public void consumeTerms(Query query, Term... terms) {
if (numClauses > maxClauseCount) {
throw new TooManyClauses();
}
++numClauses;
}
};
}
/** Returns an Explanation that describes how <code>doc</code> scored against /** Returns an Explanation that describes how <code>doc</code> scored against
* <code>query</code>. * <code>query</code>.
* *
@ -743,8 +798,8 @@ public class IndexSearcher {
* Computing an explanation is as expensive as executing the query over the * Computing an explanation is as expensive as executing the query over the
* entire index. * entire index.
* <p>Applications should call {@link IndexSearcher#explain(Query, int)}. * <p>Applications should call {@link IndexSearcher#explain(Query, int)}.
* @throws BooleanQuery.TooManyClauses If a query would exceed * @throws TooManyClauses If a query would exceed
* {@link BooleanQuery#getMaxClauseCount()} clauses. * {@link IndexSearcher#getMaxClauseCount()} clauses.
*/ */
protected Explanation explain(Weight weight, int doc) throws IOException { protected Explanation explain(Weight weight, int doc) throws IOException {
int n = ReaderUtil.subIndex(doc, leafContexts); int n = ReaderUtil.subIndex(doc, leafContexts);
@ -854,4 +909,15 @@ public class IndexSearcher {
public Executor getExecutor() { public Executor getExecutor() {
return executor; return executor;
} }
/** Thrown when an attempt is made to add more than {@link
* #getMaxClauseCount()} clauses. This typically happens if
* a PrefixQuery, FuzzyQuery, WildcardQuery, or TermRangeQuery
* is expanded to many terms during search.
*/
public static class TooManyClauses extends RuntimeException {
public TooManyClauses() {
super("maxClauseCount is set to " + maxClauseCount);
}
}
} }

View File

@ -43,10 +43,10 @@ import org.apache.lucene.util.AttributeSource;
* <p><b>NOTE</b>: if {@link #setRewriteMethod} is either * <p><b>NOTE</b>: if {@link #setRewriteMethod} is either
* {@link #CONSTANT_SCORE_BOOLEAN_REWRITE} or {@link * {@link #CONSTANT_SCORE_BOOLEAN_REWRITE} or {@link
* #SCORING_BOOLEAN_REWRITE}, you may encounter a * #SCORING_BOOLEAN_REWRITE}, you may encounter a
* {@link BooleanQuery.TooManyClauses} exception during * {@link IndexSearcher.TooManyClauses} exception during
* searching, which happens when the number of terms to be * searching, which happens when the number of terms to be
* searched exceeds {@link * searched exceeds {@link
* BooleanQuery#getMaxClauseCount()}. Setting {@link * IndexSearcher#getMaxClauseCount()}. Setting {@link
* #setRewriteMethod} to {@link #CONSTANT_SCORE_REWRITE} * #setRewriteMethod} to {@link #CONSTANT_SCORE_REWRITE}
* prevents this. * prevents this.
* *
@ -87,7 +87,7 @@ public abstract class MultiTermQuery extends Query {
* <p> This method is faster than the BooleanQuery * <p> This method is faster than the BooleanQuery
* rewrite methods when the number of matched terms or * rewrite methods when the number of matched terms or
* matched documents is non-trivial. Also, it will never * matched documents is non-trivial. Also, it will never
* hit an errant {@link BooleanQuery.TooManyClauses} * hit an errant {@link IndexSearcher.TooManyClauses}
* exception. * exception.
* *
* @see #setRewriteMethod */ * @see #setRewriteMethod */
@ -107,8 +107,8 @@ public abstract class MultiTermQuery extends Query {
* #CONSTANT_SCORE_REWRITE} instead. * #CONSTANT_SCORE_REWRITE} instead.
* *
* <p><b>NOTE</b>: This rewrite method will hit {@link * <p><b>NOTE</b>: This rewrite method will hit {@link
* BooleanQuery.TooManyClauses} if the number of terms * IndexSearcher.TooManyClauses} if the number of terms
* exceeds {@link BooleanQuery#getMaxClauseCount}. * exceeds {@link IndexSearcher#getMaxClauseCount}.
* *
* @see #setRewriteMethod */ * @see #setRewriteMethod */
public final static RewriteMethod SCORING_BOOLEAN_REWRITE = ScoringRewrite.SCORING_BOOLEAN_REWRITE; public final static RewriteMethod SCORING_BOOLEAN_REWRITE = ScoringRewrite.SCORING_BOOLEAN_REWRITE;
@ -119,8 +119,8 @@ public abstract class MultiTermQuery extends Query {
* query's boost. * query's boost.
* *
* <p><b>NOTE</b>: This rewrite method will hit {@link * <p><b>NOTE</b>: This rewrite method will hit {@link
* BooleanQuery.TooManyClauses} if the number of terms * IndexSearcher.TooManyClauses} if the number of terms
* exceeds {@link BooleanQuery#getMaxClauseCount}. * exceeds {@link IndexSearcher#getMaxClauseCount}.
* *
* @see #setRewriteMethod */ * @see #setRewriteMethod */
public final static RewriteMethod CONSTANT_SCORE_BOOLEAN_REWRITE = ScoringRewrite.CONSTANT_SCORE_BOOLEAN_REWRITE; public final static RewriteMethod CONSTANT_SCORE_BOOLEAN_REWRITE = ScoringRewrite.CONSTANT_SCORE_BOOLEAN_REWRITE;
@ -143,7 +143,7 @@ public abstract class MultiTermQuery extends Query {
* Create a TopTermsScoringBooleanQueryRewrite for * Create a TopTermsScoringBooleanQueryRewrite for
* at most <code>size</code> terms. * at most <code>size</code> terms.
* <p> * <p>
* NOTE: if {@link BooleanQuery#getMaxClauseCount} is smaller than * NOTE: if {@link IndexSearcher#getMaxClauseCount} is smaller than
* <code>size</code>, then it will be used instead. * <code>size</code>, then it will be used instead.
*/ */
public TopTermsScoringBooleanQueryRewrite(int size) { public TopTermsScoringBooleanQueryRewrite(int size) {
@ -152,7 +152,7 @@ public abstract class MultiTermQuery extends Query {
@Override @Override
protected int getMaxSize() { protected int getMaxSize() {
return BooleanQuery.getMaxClauseCount(); return IndexSearcher.getMaxClauseCount();
} }
@Override @Override
@ -192,7 +192,7 @@ public abstract class MultiTermQuery extends Query {
* Create a TopTermsBlendedScoringBooleanQueryRewrite for at most * Create a TopTermsBlendedScoringBooleanQueryRewrite for at most
* <code>size</code> terms. * <code>size</code> terms.
* <p> * <p>
* NOTE: if {@link BooleanQuery#getMaxClauseCount} is smaller than * NOTE: if {@link IndexSearcher#getMaxClauseCount} is smaller than
* <code>size</code>, then it will be used instead. * <code>size</code>, then it will be used instead.
*/ */
public TopTermsBlendedFreqScoringRewrite(int size) { public TopTermsBlendedFreqScoringRewrite(int size) {
@ -201,7 +201,7 @@ public abstract class MultiTermQuery extends Query {
@Override @Override
protected int getMaxSize() { protected int getMaxSize() {
return BooleanQuery.getMaxClauseCount(); return IndexSearcher.getMaxClauseCount();
} }
@Override @Override
@ -239,7 +239,7 @@ public abstract class MultiTermQuery extends Query {
* Create a TopTermsBoostOnlyBooleanQueryRewrite for * Create a TopTermsBoostOnlyBooleanQueryRewrite for
* at most <code>size</code> terms. * at most <code>size</code> terms.
* <p> * <p>
* NOTE: if {@link BooleanQuery#getMaxClauseCount} is smaller than * NOTE: if {@link IndexSearcher#getMaxClauseCount} is smaller than
* <code>size</code>, then it will be used instead. * <code>size</code>, then it will be used instead.
*/ */
public TopTermsBoostOnlyBooleanQueryRewrite(int size) { public TopTermsBoostOnlyBooleanQueryRewrite(int size) {
@ -248,7 +248,7 @@ public abstract class MultiTermQuery extends Query {
@Override @Override
protected int getMaxSize() { protected int getMaxSize() {
return BooleanQuery.getMaxClauseCount(); return IndexSearcher.getMaxClauseCount();
} }
@Override @Override

View File

@ -115,7 +115,7 @@ final class MultiTermQueryConstantScoreWrapper<Q extends MultiTermQuery> extends
* terms could be collected. If {@code false} is returned, the enum is * terms could be collected. If {@code false} is returned, the enum is
* left positioned on the next term. */ * left positioned on the next term. */
private boolean collectTerms(LeafReaderContext context, TermsEnum termsEnum, List<TermAndState> terms) throws IOException { private boolean collectTerms(LeafReaderContext context, TermsEnum termsEnum, List<TermAndState> terms) throws IOException {
final int threshold = Math.min(BOOLEAN_REWRITE_TERM_COUNT_THRESHOLD, BooleanQuery.getMaxClauseCount()); final int threshold = Math.min(BOOLEAN_REWRITE_TERM_COUNT_THRESHOLD, IndexSearcher.getMaxClauseCount());
for (int i = 0; i < threshold; ++i) { for (int i = 0; i < threshold; ++i) {
final BytesRef term = termsEnum.next(); final BytesRef term = termsEnum.next();
if (term == null) { if (term == null) {

View File

@ -47,8 +47,8 @@ public abstract class ScoringRewrite<B> extends TermCollectingRewrite<B> {
* MultiTermQuery#CONSTANT_SCORE_REWRITE} instead. * MultiTermQuery#CONSTANT_SCORE_REWRITE} instead.
* *
* <p><b>NOTE</b>: This rewrite method will hit {@link * <p><b>NOTE</b>: This rewrite method will hit {@link
* BooleanQuery.TooManyClauses} if the number of terms * IndexSearcher.TooManyClauses} if the number of terms
* exceeds {@link BooleanQuery#getMaxClauseCount}. * exceeds {@link IndexSearcher#getMaxClauseCount}.
* *
* @see MultiTermQuery#setRewriteMethod */ * @see MultiTermQuery#setRewriteMethod */
public final static ScoringRewrite<BooleanQuery.Builder> SCORING_BOOLEAN_REWRITE = new ScoringRewrite<BooleanQuery.Builder>() { public final static ScoringRewrite<BooleanQuery.Builder> SCORING_BOOLEAN_REWRITE = new ScoringRewrite<BooleanQuery.Builder>() {
@ -71,8 +71,8 @@ public abstract class ScoringRewrite<B> extends TermCollectingRewrite<B> {
@Override @Override
protected void checkMaxClauseCount(int count) { protected void checkMaxClauseCount(int count) {
if (count > BooleanQuery.getMaxClauseCount()) if (count > IndexSearcher.getMaxClauseCount())
throw new BooleanQuery.TooManyClauses(); throw new IndexSearcher.TooManyClauses();
} }
}; };
@ -82,8 +82,8 @@ public abstract class ScoringRewrite<B> extends TermCollectingRewrite<B> {
* query's boost. * query's boost.
* *
* <p><b>NOTE</b>: This rewrite method will hit {@link * <p><b>NOTE</b>: This rewrite method will hit {@link
* BooleanQuery.TooManyClauses} if the number of terms * IndexSearcher.TooManyClauses} if the number of terms
* exceeds {@link BooleanQuery#getMaxClauseCount}. * exceeds {@link IndexSearcher#getMaxClauseCount}.
* *
* @see MultiTermQuery#setRewriteMethod */ * @see MultiTermQuery#setRewriteMethod */
public final static RewriteMethod CONSTANT_SCORE_BOOLEAN_REWRITE = new RewriteMethod() { public final static RewriteMethod CONSTANT_SCORE_BOOLEAN_REWRITE = new RewriteMethod() {

View File

@ -92,8 +92,8 @@ public final class SynonymQuery extends Query {
throw new IllegalArgumentException("boost must be a positive float between 0 (exclusive) and 1 (inclusive)"); throw new IllegalArgumentException("boost must be a positive float between 0 (exclusive) and 1 (inclusive)");
} }
terms.add(new TermAndBoost(term, boost)); terms.add(new TermAndBoost(term, boost));
if (terms.size() > BooleanQuery.getMaxClauseCount()) { if (terms.size() > IndexSearcher.getMaxClauseCount()) {
throw new BooleanQuery.TooManyClauses(); throw new IndexSearcher.TooManyClauses();
} }
return this; return this;
} }

View File

@ -109,7 +109,7 @@ public class TermInSetQuery extends Query implements Accountable {
@Override @Override
public Query rewrite(IndexReader reader) throws IOException { public Query rewrite(IndexReader reader) throws IOException {
final int threshold = Math.min(BOOLEAN_REWRITE_TERM_COUNT_THRESHOLD, BooleanQuery.getMaxClauseCount()); final int threshold = Math.min(BOOLEAN_REWRITE_TERM_COUNT_THRESHOLD, IndexSearcher.getMaxClauseCount());
if (termData.size() <= threshold) { if (termData.size() <= threshold) {
BooleanQuery.Builder bq = new BooleanQuery.Builder(); BooleanQuery.Builder bq = new BooleanQuery.Builder();
TermIterator iterator = termData.iterator(); TermIterator iterator = termData.iterator();
@ -251,7 +251,7 @@ public class TermInSetQuery extends Query implements Accountable {
// We will first try to collect up to 'threshold' terms into 'matchingTerms' // We will first try to collect up to 'threshold' terms into 'matchingTerms'
// if there are two many terms, we will fall back to building the 'builder' // if there are two many terms, we will fall back to building the 'builder'
final int threshold = Math.min(BOOLEAN_REWRITE_TERM_COUNT_THRESHOLD, BooleanQuery.getMaxClauseCount()); final int threshold = Math.min(BOOLEAN_REWRITE_TERM_COUNT_THRESHOLD, IndexSearcher.getMaxClauseCount());
assert termData.size() > threshold : "Query should have been rewritten"; assert termData.size() > threshold : "Query should have been rewritten";
List<TermAndState> matchingTerms = new ArrayList<>(threshold); List<TermAndState> matchingTerms = new ArrayList<>(threshold);
DocIdSetBuilder builder = null; DocIdSetBuilder builder = null;

View File

@ -45,7 +45,7 @@ public abstract class TopTermsRewrite<B> extends TermCollectingRewrite<B> {
* Create a TopTermsBooleanQueryRewrite for * Create a TopTermsBooleanQueryRewrite for
* at most <code>size</code> terms. * at most <code>size</code> terms.
* <p> * <p>
* NOTE: if {@link BooleanQuery#getMaxClauseCount} is smaller than * NOTE: if {@link IndexSearcher#getMaxClauseCount} is smaller than
* <code>size</code>, then it will be used instead. * <code>size</code>, then it will be used instead.
*/ */
public TopTermsRewrite(int size) { public TopTermsRewrite(int size) {

View File

@ -108,7 +108,7 @@
* </ol> * </ol>
* Boolean queries are constructed by adding two or more * Boolean queries are constructed by adding two or more
* {@link org.apache.lucene.search.BooleanClause BooleanClause} * {@link org.apache.lucene.search.BooleanClause BooleanClause}
* instances. If too many clauses are added, a {@link org.apache.lucene.search.BooleanQuery.TooManyClauses TooManyClauses} * instances. If too many clauses are added, a {@link org.apache.lucene.search.IndexSearcher.TooManyClauses TooManyClauses}
* exception will be thrown during searching. This most often occurs * exception will be thrown during searching. This most often occurs
* when a {@link org.apache.lucene.search.Query Query} * when a {@link org.apache.lucene.search.Query Query}
* is rewritten into a {@link org.apache.lucene.search.BooleanQuery BooleanQuery} with many * is rewritten into a {@link org.apache.lucene.search.BooleanQuery BooleanQuery} with many
@ -116,7 +116,7 @@
* for example by {@link org.apache.lucene.search.WildcardQuery WildcardQuery}. * for example by {@link org.apache.lucene.search.WildcardQuery WildcardQuery}.
* The default setting for the maximum number * The default setting for the maximum number
* of clauses is 1024, but this can be changed via the * of clauses is 1024, but this can be changed via the
* static method {@link org.apache.lucene.search.BooleanQuery#setMaxClauseCount(int)}. * static method {@link org.apache.lucene.search.IndexSearcher#setMaxClauseCount(int)}.
* *
* <h3>Phrases</h3> * <h3>Phrases</h3>
* *

View File

@ -30,6 +30,7 @@ import org.apache.lucene.analysis.tokenattributes.TermToBytesRefAttribute;
import org.apache.lucene.index.Term; import org.apache.lucene.index.Term;
import org.apache.lucene.search.BooleanClause; import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery; import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.MultiPhraseQuery; import org.apache.lucene.search.MultiPhraseQuery;
import org.apache.lucene.search.PhraseQuery; import org.apache.lucene.search.PhraseQuery;
import org.apache.lucene.search.Query; import org.apache.lucene.search.Query;
@ -571,7 +572,7 @@ public class QueryBuilder {
List<SpanQuery> clauses = new ArrayList<>(); List<SpanQuery> clauses = new ArrayList<>();
int[] articulationPoints = graph.articulationPoints(); int[] articulationPoints = graph.articulationPoints();
int lastState = 0; int lastState = 0;
int maxClauseCount = BooleanQuery.getMaxClauseCount(); int maxClauseCount = IndexSearcher.getMaxClauseCount();
for (int i = 0; i <= articulationPoints.length; i++) { for (int i = 0; i <= articulationPoints.length; i++) {
int start = lastState; int start = lastState;
int end = -1; int end = -1;
@ -588,7 +589,7 @@ public class QueryBuilder {
SpanQuery q = createSpanQuery(ts, field); SpanQuery q = createSpanQuery(ts, field);
if (q != null) { if (q != null) {
if (queries.size() >= maxClauseCount) { if (queries.size() >= maxClauseCount) {
throw new BooleanQuery.TooManyClauses(); throw new IndexSearcher.TooManyClauses();
} }
queries.add(q); queries.add(q);
} }
@ -605,7 +606,7 @@ public class QueryBuilder {
queryPos = new SpanTermQuery(terms[0]); queryPos = new SpanTermQuery(terms[0]);
} else { } else {
if (terms.length >= maxClauseCount) { if (terms.length >= maxClauseCount) {
throw new BooleanQuery.TooManyClauses(); throw new IndexSearcher.TooManyClauses();
} }
SpanTermQuery[] orClauses = new SpanTermQuery[terms.length]; SpanTermQuery[] orClauses = new SpanTermQuery[terms.length];
for (int idx = 0; idx < terms.length; idx++) { for (int idx = 0; idx < terms.length; idx++) {
@ -618,7 +619,7 @@ public class QueryBuilder {
if (queryPos != null) { if (queryPos != null) {
if (clauses.size() >= maxClauseCount) { if (clauses.size() >= maxClauseCount) {
throw new BooleanQuery.TooManyClauses(); throw new IndexSearcher.TooManyClauses();
} }
clauses.add(queryPos); clauses.add(queryPos);
} }

View File

@ -175,7 +175,7 @@ public class TestBooleanQuery extends LuceneTestCase {
public void testException() { public void testException() {
expectThrows(IllegalArgumentException.class, () -> { expectThrows(IllegalArgumentException.class, () -> {
BooleanQuery.setMaxClauseCount(0); IndexSearcher.setMaxClauseCount(0);
}); });
} }

View File

@ -0,0 +1,132 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.lucene.search;
import java.io.IOException;
import java.util.Arrays;
import org.apache.lucene.index.MultiReader;
import org.apache.lucene.index.Term;
import org.apache.lucene.util.LuceneTestCase;
public class TestMaxClauseLimit extends LuceneTestCase {
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)), BooleanClause.Occur.SHOULD);
}
Query inner = builder1024.build();
Query query = new BooleanQuery.Builder()
.add(inner, BooleanClause.Occur.SHOULD)
.add(new TermQuery(new Term("foo", "baz")), BooleanClause.Occur.SHOULD)
.build();
expectThrows(IndexSearcher.TooManyClauses.class, () -> {
searcher.rewrite(query);
});
}
public void testLargeTermsNestedFirst() throws IOException {
IndexSearcher searcher = newSearcher(new MultiReader());
BooleanQuery.Builder nestedBuilder = new BooleanQuery.Builder();
nestedBuilder.setMinimumNumberShouldMatch(5);
for(int i = 0; i < 600; i++) {
nestedBuilder.add(new TermQuery(new Term("foo", "bar-" + i)), BooleanClause.Occur.SHOULD);
}
Query inner = nestedBuilder.build();
BooleanQuery.Builder builderMixed = new BooleanQuery.Builder()
.add(inner, BooleanClause.Occur.SHOULD);
builderMixed.setMinimumNumberShouldMatch(5);
for (int i = 0; i < 600; i++) {
builderMixed.add(new TermQuery(new Term("foo", "bar")), BooleanClause.Occur.SHOULD);
}
Query query = builderMixed.build();
expectThrows(IndexSearcher.TooManyClauses.class, () -> {
searcher.rewrite(query);
});
}
public void testLargeTermsNestedLast() throws IOException {
IndexSearcher searcher = newSearcher(new MultiReader());
BooleanQuery.Builder nestedBuilder = new BooleanQuery.Builder();
nestedBuilder.setMinimumNumberShouldMatch(5);
for(int i = 0; i < 600; i++) {
nestedBuilder.add(new TermQuery(new Term("foo", "bar-" + i)), BooleanClause.Occur.SHOULD);
}
Query inner = nestedBuilder.build();
BooleanQuery.Builder builderMixed = new BooleanQuery.Builder();
builderMixed.setMinimumNumberShouldMatch(5);
for (int i = 0; i < 600; i++) {
builderMixed.add(new TermQuery(new Term("foo", "bar")), BooleanClause.Occur.SHOULD);
}
builderMixed.add(inner, BooleanClause.Occur.SHOULD);
Query query = builderMixed.build();
expectThrows(IndexSearcher.TooManyClauses.class, () -> {
searcher.rewrite(query);
});
}
public void testLargeDisjunctionMaxQuery() throws IOException {
IndexSearcher searcher = newSearcher(new MultiReader());
Query[] clausesQueryArray = new Query[1050];
for(int i = 0; i < 1049; i++) {
clausesQueryArray[i] = new TermQuery(new Term("field", "a"));
}
PhraseQuery pq = new PhraseQuery("field", new String[0]);
clausesQueryArray[1049] = pq;
DisjunctionMaxQuery dmq = new DisjunctionMaxQuery(
Arrays.asList(clausesQueryArray),
0.5f);
expectThrows(IndexSearcher.TooManyClauses.class, () -> {
searcher.rewrite(dmq);
});
}
public void testMultiExactWithRepeats() throws IOException {
IndexSearcher searcher = newSearcher(new MultiReader());
MultiPhraseQuery.Builder qb = new MultiPhraseQuery.Builder();
for (int i = 0;i < 1050; i++) {
qb.add(new Term[]{new Term("foo", "bar-" + i), new Term("foo", "bar+" + i)}, 0);
}
expectThrows(IndexSearcher.TooManyClauses.class, () -> {
searcher.rewrite(qb.build());
});
}
}

View File

@ -220,33 +220,33 @@ public class TestMultiTermQueryRewrites extends LuceneTestCase {
} }
private void checkMaxClauseLimitation(MultiTermQuery.RewriteMethod method) throws Exception { private void checkMaxClauseLimitation(MultiTermQuery.RewriteMethod method) throws Exception {
int savedMaxClauseCount = BooleanQuery.getMaxClauseCount(); int savedMaxClauseCount = IndexSearcher.getMaxClauseCount();
BooleanQuery.setMaxClauseCount(3); IndexSearcher.setMaxClauseCount(3);
final MultiTermQuery mtq = TermRangeQuery.newStringRange("data", "2", "7", true, true); final MultiTermQuery mtq = TermRangeQuery.newStringRange("data", "2", "7", true, true);
mtq.setRewriteMethod(method); mtq.setRewriteMethod(method);
try { try {
BooleanQuery.TooManyClauses expected = expectThrows(BooleanQuery.TooManyClauses.class, () -> { IndexSearcher.TooManyClauses expected = expectThrows(IndexSearcher.TooManyClauses.class, () -> {
multiSearcherDupls.rewrite(mtq); multiSearcherDupls.rewrite(mtq);
}); });
// Maybe remove this assert in later versions, when internal API changes: // Maybe remove this assert in later versions, when internal API changes:
assertEquals("Should throw BooleanQuery.TooManyClauses with a stacktrace containing checkMaxClauseCount()", assertEquals("Should throw BooleanQuery.TooManyClauses with a stacktrace containing checkMaxClauseCount()",
"checkMaxClauseCount", expected.getStackTrace()[0].getMethodName()); "checkMaxClauseCount", expected.getStackTrace()[0].getMethodName());
} finally { } finally {
BooleanQuery.setMaxClauseCount(savedMaxClauseCount); IndexSearcher.setMaxClauseCount(savedMaxClauseCount);
} }
} }
private void checkNoMaxClauseLimitation(MultiTermQuery.RewriteMethod method) throws Exception { private void checkNoMaxClauseLimitation(MultiTermQuery.RewriteMethod method) throws Exception {
int savedMaxClauseCount = BooleanQuery.getMaxClauseCount(); int savedMaxClauseCount = IndexSearcher.getMaxClauseCount();
BooleanQuery.setMaxClauseCount(3); IndexSearcher.setMaxClauseCount(3);
final MultiTermQuery mtq = TermRangeQuery.newStringRange("data", "2", "7", true, true); final MultiTermQuery mtq = TermRangeQuery.newStringRange("data", "2", "7", true, true);
mtq.setRewriteMethod(method); mtq.setRewriteMethod(method);
try { try {
multiSearcherDupls.rewrite(mtq); multiSearcherDupls.rewrite(mtq);
} finally { } finally {
BooleanQuery.setMaxClauseCount(savedMaxClauseCount); IndexSearcher.setMaxClauseCount(savedMaxClauseCount);
} }
} }

View File

@ -131,12 +131,12 @@ public class TestTermRangeQuery extends LuceneTestCase {
TermRangeQuery query = TermRangeQuery.newStringRange("content", "B", "J", true, true); TermRangeQuery query = TermRangeQuery.newStringRange("content", "B", "J", true, true);
checkBooleanTerms(searcher, query, "B", "C", "D", "E", "F", "G", "H", "I", "J"); checkBooleanTerms(searcher, query, "B", "C", "D", "E", "F", "G", "H", "I", "J");
final int savedClauseCount = BooleanQuery.getMaxClauseCount(); final int savedClauseCount = IndexSearcher.getMaxClauseCount();
try { try {
BooleanQuery.setMaxClauseCount(3); IndexSearcher.setMaxClauseCount(3);
checkBooleanTerms(searcher, query, "B", "C", "D"); checkBooleanTerms(searcher, query, "B", "C", "D");
} finally { } finally {
BooleanQuery.setMaxClauseCount(savedClauseCount); IndexSearcher.setMaxClauseCount(savedClauseCount);
} }
reader.close(); reader.close();
} }

View File

@ -32,6 +32,7 @@ import org.apache.lucene.analysis.tokenattributes.PositionIncrementAttribute;
import org.apache.lucene.index.Term; import org.apache.lucene.index.Term;
import org.apache.lucene.search.BooleanClause; import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery; import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.MultiPhraseQuery; import org.apache.lucene.search.MultiPhraseQuery;
import org.apache.lucene.search.PhraseQuery; import org.apache.lucene.search.PhraseQuery;
import org.apache.lucene.search.Query; import org.apache.lucene.search.Query;
@ -497,13 +498,13 @@ public class TestQueryBuilder extends LuceneTestCase {
} }
QueryBuilder qb = new QueryBuilder(null); QueryBuilder qb = new QueryBuilder(null);
try (TokenStream ts = new CannedBinaryTokenStream(tokens)) { try (TokenStream ts = new CannedBinaryTokenStream(tokens)) {
expectThrows(BooleanQuery.TooManyClauses.class, () -> qb.analyzeGraphBoolean("", ts, BooleanClause.Occur.MUST)); expectThrows(IndexSearcher.TooManyClauses.class, () -> qb.analyzeGraphBoolean("", ts, BooleanClause.Occur.MUST));
} }
try (TokenStream ts = new CannedBinaryTokenStream(tokens)) { try (TokenStream ts = new CannedBinaryTokenStream(tokens)) {
expectThrows(BooleanQuery.TooManyClauses.class, () -> qb.analyzeGraphBoolean("", ts, BooleanClause.Occur.SHOULD)); expectThrows(IndexSearcher.TooManyClauses.class, () -> qb.analyzeGraphBoolean("", ts, BooleanClause.Occur.SHOULD));
} }
try (TokenStream ts = new CannedBinaryTokenStream(tokens)) { try (TokenStream ts = new CannedBinaryTokenStream(tokens)) {
expectThrows(BooleanQuery.TooManyClauses.class, () -> qb.analyzeGraphPhrase(ts, "", 0)); expectThrows(IndexSearcher.TooManyClauses.class, () -> qb.analyzeGraphPhrase(ts, "", 0));
} }
} }
} }

View File

@ -40,6 +40,7 @@ import org.apache.lucene.index.TermsEnum;
import org.apache.lucene.search.BooleanClause; import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery; import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.BoostQuery; import org.apache.lucene.search.BoostQuery;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query; import org.apache.lucene.search.Query;
import org.apache.lucene.search.TermQuery; import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.similarities.ClassicSimilarity; import org.apache.lucene.search.similarities.ClassicSimilarity;
@ -220,7 +221,7 @@ public final class MoreLikeThis {
/** /**
* Return a Query with no more than this many terms. * Return a Query with no more than this many terms.
* *
* @see BooleanQuery#getMaxClauseCount * @see IndexSearcher#getMaxClauseCount
* @see #getMaxQueryTerms * @see #getMaxQueryTerms
* @see #setMaxQueryTerms * @see #setMaxQueryTerms
*/ */
@ -635,7 +636,7 @@ public final class MoreLikeThis {
try { try {
query.add(tq, BooleanClause.Occur.SHOULD); query.add(tq, BooleanClause.Occur.SHOULD);
} }
catch (BooleanQuery.TooManyClauses ignore) { catch (IndexSearcher.TooManyClauses ignore) {
break; break;
} }
} }

View File

@ -29,7 +29,7 @@ import org.apache.lucene.queryparser.classic.QueryParser.Operator;
import org.apache.lucene.queryparser.flexible.standard.CommonQueryParserConfiguration; import org.apache.lucene.queryparser.flexible.standard.CommonQueryParserConfiguration;
import org.apache.lucene.search.*; import org.apache.lucene.search.*;
import org.apache.lucene.search.BooleanClause.Occur; import org.apache.lucene.search.BooleanClause.Occur;
import org.apache.lucene.search.BooleanQuery.TooManyClauses; import org.apache.lucene.search.IndexSearcher.TooManyClauses;
import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.BytesRefBuilder; import org.apache.lucene.util.BytesRefBuilder;
import org.apache.lucene.util.QueryBuilder; import org.apache.lucene.util.QueryBuilder;
@ -114,7 +114,7 @@ public abstract class QueryParserBase extends QueryBuilder implements CommonQuer
ParseException e = new ParseException("Cannot parse '" +query+ "': " + tme.getMessage()); ParseException e = new ParseException("Cannot parse '" +query+ "': " + tme.getMessage());
e.initCause(tme); e.initCause(tme);
throw e; throw e;
} catch (BooleanQuery.TooManyClauses tmc) { } catch (TooManyClauses tmc) {
ParseException e = new ParseException("Cannot parse '" +query+ "': too many boolean clauses"); ParseException e = new ParseException("Cannot parse '" +query+ "': too many boolean clauses");
e.initCause(tmc); e.initCause(tmc);
throw e; throw e;

View File

@ -27,7 +27,7 @@ import org.apache.lucene.queryparser.flexible.core.nodes.QueryNode;
import org.apache.lucene.search.BooleanClause; import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery; import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.Query; import org.apache.lucene.search.Query;
import org.apache.lucene.search.BooleanQuery.TooManyClauses; import org.apache.lucene.search.IndexSearcher.TooManyClauses;
/** /**
* Builds a BooleanQuery of SHOULD clauses, possibly with * Builds a BooleanQuery of SHOULD clauses, possibly with

View File

@ -28,8 +28,9 @@ import org.apache.lucene.queryparser.flexible.core.nodes.QueryNode;
import org.apache.lucene.queryparser.flexible.standard.parser.EscapeQuerySyntaxImpl; import org.apache.lucene.queryparser.flexible.standard.parser.EscapeQuerySyntaxImpl;
import org.apache.lucene.search.BooleanClause; import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery; import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query; import org.apache.lucene.search.Query;
import org.apache.lucene.search.BooleanQuery.TooManyClauses; import org.apache.lucene.search.IndexSearcher.TooManyClauses;
/** /**
* Builds a {@link BooleanQuery} object from a {@link BooleanQueryNode} object. * Builds a {@link BooleanQuery} object from a {@link BooleanQueryNode} object.
@ -67,7 +68,7 @@ public class BooleanQueryNodeBuilder implements StandardQueryBuilder {
} catch (TooManyClauses ex) { } catch (TooManyClauses ex) {
throw new QueryNodeException(new MessageImpl( throw new QueryNodeException(new MessageImpl(
QueryParserMessages.TOO_MANY_BOOLEAN_CLAUSES, BooleanQuery QueryParserMessages.TOO_MANY_BOOLEAN_CLAUSES, IndexSearcher
.getMaxClauseCount(), queryNode .getMaxClauseCount(), queryNode
.toQueryString(new EscapeQuerySyntaxImpl())), ex); .toQueryString(new EscapeQuerySyntaxImpl())), ex);

View File

@ -38,6 +38,7 @@ import org.apache.lucene.queryparser.util.QueryParserTestBase; // javadocs
import org.apache.lucene.search.BooleanQuery; import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.BoostQuery; import org.apache.lucene.search.BoostQuery;
import org.apache.lucene.search.FuzzyQuery; import org.apache.lucene.search.FuzzyQuery;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.MatchNoDocsQuery; import org.apache.lucene.search.MatchNoDocsQuery;
import org.apache.lucene.search.PhraseQuery; import org.apache.lucene.search.PhraseQuery;
import org.apache.lucene.search.PrefixQuery; import org.apache.lucene.search.PrefixQuery;
@ -141,7 +142,7 @@ public class TestPrecedenceQueryParser extends LuceneTestCase {
@Override @Override
public void setUp() throws Exception { public void setUp() throws Exception {
super.setUp(); super.setUp();
originalMaxClauses = BooleanQuery.getMaxClauseCount(); originalMaxClauses = IndexSearcher.getMaxClauseCount();
} }
public PrecedenceQueryParser getParser(Analyzer a) throws Exception { public PrecedenceQueryParser getParser(Analyzer a) throws Exception {
@ -572,7 +573,7 @@ public class TestPrecedenceQueryParser extends LuceneTestCase {
// ParseException expected due to too many boolean clauses // ParseException expected due to too many boolean clauses
public void testBooleanQuery() throws Exception { public void testBooleanQuery() throws Exception {
BooleanQuery.setMaxClauseCount(2); IndexSearcher.setMaxClauseCount(2);
expectThrows(QueryNodeException.class, () -> { expectThrows(QueryNodeException.class, () -> {
getParser(new MockAnalyzer(random(), MockTokenizer.WHITESPACE, false)).parse("one two three", "field"); getParser(new MockAnalyzer(random(), MockTokenizer.WHITESPACE, false)).parse("one two three", "field");
}); });
@ -639,7 +640,7 @@ public class TestPrecedenceQueryParser extends LuceneTestCase {
@Override @Override
public void tearDown() throws Exception { public void tearDown() throws Exception {
BooleanQuery.setMaxClauseCount(originalMaxClauses); IndexSearcher.setMaxClauseCount(originalMaxClauses);
super.tearDown(); super.tearDown();
} }

View File

@ -210,7 +210,7 @@ public class TestQPHelper extends LuceneTestCase {
@Override @Override
public void setUp() throws Exception { public void setUp() throws Exception {
super.setUp(); super.setUp();
originalMaxClauses = BooleanQuery.getMaxClauseCount(); originalMaxClauses = IndexSearcher.getMaxClauseCount();
} }
public StandardQueryParser getParser(Analyzer a) throws Exception { public StandardQueryParser getParser(Analyzer a) throws Exception {
@ -1017,7 +1017,7 @@ public class TestQPHelper extends LuceneTestCase {
// too many boolean clauses, so ParseException is expected // too many boolean clauses, so ParseException is expected
public void testBooleanQuery() throws Exception { public void testBooleanQuery() throws Exception {
BooleanQuery.setMaxClauseCount(2); IndexSearcher.setMaxClauseCount(2);
expectThrows(QueryNodeException.class, () -> { expectThrows(QueryNodeException.class, () -> {
StandardQueryParser qp = new StandardQueryParser(); StandardQueryParser qp = new StandardQueryParser();
qp.setAnalyzer(new MockAnalyzer(random(), MockTokenizer.WHITESPACE, false)); qp.setAnalyzer(new MockAnalyzer(random(), MockTokenizer.WHITESPACE, false));
@ -1248,7 +1248,7 @@ public class TestQPHelper extends LuceneTestCase {
@Override @Override
public void tearDown() throws Exception { public void tearDown() throws Exception {
BooleanQuery.setMaxClauseCount(originalMaxClauses); IndexSearcher.setMaxClauseCount(originalMaxClauses);
super.tearDown(); super.tearDown();
} }

View File

@ -138,7 +138,7 @@ public abstract class QueryParserTestBase extends LuceneTestCase {
@Override @Override
public void setUp() throws Exception { public void setUp() throws Exception {
super.setUp(); super.setUp();
originalMaxClauses = BooleanQuery.getMaxClauseCount(); originalMaxClauses = IndexSearcher.getMaxClauseCount();
} }
public abstract CommonQueryParserConfiguration getParserConfig(Analyzer a) throws Exception; public abstract CommonQueryParserConfiguration getParserConfig(Analyzer a) throws Exception;
@ -960,7 +960,7 @@ public abstract class QueryParserTestBase extends LuceneTestCase {
} }
public void testBooleanQuery() throws Exception { public void testBooleanQuery() throws Exception {
BooleanQuery.setMaxClauseCount(2); IndexSearcher.setMaxClauseCount(2);
Analyzer purWhitespaceAnalyzer = new MockAnalyzer(random(), MockTokenizer.WHITESPACE, false); Analyzer purWhitespaceAnalyzer = new MockAnalyzer(random(), MockTokenizer.WHITESPACE, false);
assertParseException("one two three", purWhitespaceAnalyzer); assertParseException("one two three", purWhitespaceAnalyzer);
} }
@ -1121,7 +1121,7 @@ public abstract class QueryParserTestBase extends LuceneTestCase {
@Override @Override
public void tearDown() throws Exception { public void tearDown() throws Exception {
BooleanQuery.setMaxClauseCount(originalMaxClauses); IndexSearcher.setMaxClauseCount(originalMaxClauses);
super.tearDown(); super.tearDown();
} }

View File

@ -104,8 +104,8 @@ public final class BM25FQuery extends Query {
* Adds a term to this builder. * Adds a term to this builder.
*/ */
public Builder addTerm(BytesRef term) { public Builder addTerm(BytesRef term) {
if (termsSet.size() > BooleanQuery.getMaxClauseCount()) { if (termsSet.size() > IndexSearcher.getMaxClauseCount()) {
throw new BooleanQuery.TooManyClauses(); throw new IndexSearcher.TooManyClauses();
} }
termsSet.add(term); termsSet.add(term);
return this; return this;
@ -116,8 +116,8 @@ public final class BM25FQuery extends Query {
*/ */
public BM25FQuery build() { public BM25FQuery build() {
int size = fieldAndWeights.size() * termsSet.size(); int size = fieldAndWeights.size() * termsSet.size();
if (size > BooleanQuery.getMaxClauseCount()) { if (size > IndexSearcher.getMaxClauseCount()) {
throw new BooleanQuery.TooManyClauses(); throw new IndexSearcher.TooManyClauses();
} }
BytesRef[] terms = termsSet.toArray(new BytesRef[0]); BytesRef[] terms = termsSet.toArray(new BytesRef[0]);
return new BM25FQuery(similarity, new TreeMap<>(fieldAndWeights), terms); return new BM25FQuery(similarity, new TreeMap<>(fieldAndWeights), terms);
@ -148,8 +148,8 @@ public final class BM25FQuery extends Query {
this.fieldAndWeights = fieldAndWeights; this.fieldAndWeights = fieldAndWeights;
this.terms = terms; this.terms = terms;
int numFieldTerms = fieldAndWeights.size() * terms.length; int numFieldTerms = fieldAndWeights.size() * terms.length;
if (numFieldTerms > BooleanQuery.getMaxClauseCount()) { if (numFieldTerms > IndexSearcher.getMaxClauseCount()) {
throw new BooleanQuery.TooManyClauses(); throw new IndexSearcher.TooManyClauses();
} }
this.fieldTerms = new Term[numFieldTerms]; this.fieldTerms = new Term[numFieldTerms];
Arrays.sort(terms); Arrays.sort(terms);

View File

@ -48,8 +48,8 @@ public final class CoveringQuery extends Query {
* do not match. * do not match.
*/ */
public CoveringQuery(Collection<Query> queries, LongValuesSource minimumNumberMatch) { public CoveringQuery(Collection<Query> queries, LongValuesSource minimumNumberMatch) {
if (queries.size() > BooleanQuery.getMaxClauseCount()) { if (queries.size() > IndexSearcher.getMaxClauseCount()) {
throw new BooleanQuery.TooManyClauses(); throw new IndexSearcher.TooManyClauses();
} }
if (minimumNumberMatch.needsScores()) { if (minimumNumberMatch.needsScores()) {
throw new IllegalArgumentException("The minimum number of matches may not depend on the score."); throw new IllegalArgumentException("The minimum number of matches may not depend on the score.");

View File

@ -23,7 +23,7 @@ import java.util.List;
import java.util.function.Function; import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.apache.lucene.search.BooleanQuery; import org.apache.lucene.search.IndexSearcher;
final class Disjunctions { final class Disjunctions {
@ -43,7 +43,7 @@ final class Disjunctions {
rewritten.forEach(l -> l.add(disjuncts.get(0))); rewritten.forEach(l -> l.add(disjuncts.get(0)));
} }
else { else {
if (rewritten.size() * disjuncts.size() > BooleanQuery.getMaxClauseCount()) { if (rewritten.size() * disjuncts.size() > IndexSearcher.getMaxClauseCount()) {
throw new IllegalArgumentException("Too many disjunctions to expand"); throw new IllegalArgumentException("Too many disjunctions to expand");
} }
List<List<IntervalsSource>> toAdd = new ArrayList<>(); List<List<IntervalsSource>> toAdd = new ArrayList<>();

View File

@ -16,7 +16,7 @@
*/ */
package org.apache.lucene.util; package org.apache.lucene.util;
import org.apache.lucene.search.BooleanQuery; import org.apache.lucene.search.IndexSearcher;
/** /**
* Prepares and restores {@link LuceneTestCase} at instance level * Prepares and restores {@link LuceneTestCase} at instance level
@ -27,11 +27,11 @@ final class TestRuleSetupAndRestoreInstanceEnv extends AbstractBeforeAfterRule {
@Override @Override
protected void before() { protected void before() {
savedBoolMaxClauseCount = BooleanQuery.getMaxClauseCount(); savedBoolMaxClauseCount = IndexSearcher.getMaxClauseCount();
} }
@Override @Override
protected void after() { protected void after() {
BooleanQuery.setMaxClauseCount(savedBoolMaxClauseCount); IndexSearcher.setMaxClauseCount(savedBoolMaxClauseCount);
} }
} }

View File

@ -45,7 +45,7 @@ import org.apache.http.client.CredentialsProvider;
import org.apache.http.config.Lookup; import org.apache.http.config.Lookup;
import org.apache.lucene.index.CorruptIndexException; import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.search.BooleanQuery; import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.store.Directory; import org.apache.lucene.store.Directory;
import org.apache.solr.client.solrj.SolrClient; import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.cloud.SolrCloudManager; import org.apache.solr.client.solrj.cloud.SolrCloudManager;
@ -326,7 +326,7 @@ public class CoreContainer {
containerHandlers.put(PublicKeyHandler.PATH, new PublicKeyHandler()); containerHandlers.put(PublicKeyHandler.PATH, new PublicKeyHandler());
this.cfg = requireNonNull(config); this.cfg = requireNonNull(config);
if (null != this.cfg.getBooleanQueryMaxClauseCount()) { if (null != this.cfg.getBooleanQueryMaxClauseCount()) {
BooleanQuery.setMaxClauseCount(this.cfg.getBooleanQueryMaxClauseCount()); IndexSearcher.setMaxClauseCount(this.cfg.getBooleanQueryMaxClauseCount());
} }
this.coresLocator = locator; this.coresLocator = locator;
this.containerProperties = new Properties(properties); this.containerProperties = new Properties(properties);

View File

@ -22,6 +22,7 @@ import java.util.HashSet;
import java.util.Properties; import java.util.Properties;
import java.util.Set; import java.util.Set;
import org.apache.lucene.search.IndexSearcher;
import org.apache.solr.common.SolrException; import org.apache.solr.common.SolrException;
import org.apache.solr.logging.LogWatcherConfig; import org.apache.solr.logging.LogWatcherConfig;
import org.apache.solr.update.UpdateShardHandlerConfig; import org.apache.solr.update.UpdateShardHandlerConfig;
@ -136,7 +137,7 @@ public class NodeConfig {
/** /**
* If null, the lucene default will not be overridden * If null, the lucene default will not be overridden
* *
* @see org.apache.lucene.search.BooleanQuery#setMaxClauseCount * @see IndexSearcher#setMaxClauseCount
*/ */
public Integer getBooleanQueryMaxClauseCount() { public Integer getBooleanQueryMaxClauseCount() {
return booleanQueryMaxClauseCount; return booleanQueryMaxClauseCount;

View File

@ -46,7 +46,7 @@ import java.util.regex.Pattern;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import org.apache.commons.io.FileUtils; import org.apache.commons.io.FileUtils;
import org.apache.lucene.index.IndexDeletionPolicy; import org.apache.lucene.index.IndexDeletionPolicy;
import org.apache.lucene.search.BooleanQuery; import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.util.Version; import org.apache.lucene.util.Version;
import org.apache.solr.client.solrj.io.stream.expr.Expressible; import org.apache.solr.client.solrj.io.stream.expr.Expressible;
import org.apache.solr.cloud.RecoveryStrategy; import org.apache.solr.cloud.RecoveryStrategy;
@ -234,10 +234,10 @@ public class SolrConfig extends XmlConfigFile implements MapSerializable {
// Parse indexConfig section, using mainIndex as backup in case old config is used // Parse indexConfig section, using mainIndex as backup in case old config is used
indexConfig = new SolrIndexConfig(this, "indexConfig", null); indexConfig = new SolrIndexConfig(this, "indexConfig", null);
booleanQueryMaxClauseCount = getInt("query/maxBooleanClauses", BooleanQuery.getMaxClauseCount()); booleanQueryMaxClauseCount = getInt("query/maxBooleanClauses", IndexSearcher.getMaxClauseCount());
if (BooleanQuery.getMaxClauseCount() < booleanQueryMaxClauseCount) { if (IndexSearcher.getMaxClauseCount() < booleanQueryMaxClauseCount) {
log.warn("solrconfig.xml: <maxBooleanClauses> of {} is greater than global limit of {} "+ log.warn("solrconfig.xml: <maxBooleanClauses> of {} is greater than global limit of {} "+
"and will have no effect", booleanQueryMaxClauseCount, BooleanQuery.getMaxClauseCount()); "and will have no effect", booleanQueryMaxClauseCount, IndexSearcher.getMaxClauseCount());
log.warn("set 'maxBooleanClauses' in solr.xml to increase global limit"); log.warn("set 'maxBooleanClauses' in solr.xml to increase global limit");
} }

View File

@ -36,6 +36,7 @@ import org.apache.lucene.search.BoostQuery;
import org.apache.lucene.search.ConstantScoreQuery; import org.apache.lucene.search.ConstantScoreQuery;
import org.apache.lucene.search.DisjunctionMaxQuery; import org.apache.lucene.search.DisjunctionMaxQuery;
import org.apache.lucene.search.FuzzyQuery; import org.apache.lucene.search.FuzzyQuery;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.MatchAllDocsQuery; import org.apache.lucene.search.MatchAllDocsQuery;
import org.apache.lucene.search.MultiPhraseQuery; import org.apache.lucene.search.MultiPhraseQuery;
import org.apache.lucene.search.MultiTermQuery; import org.apache.lucene.search.MultiTermQuery;
@ -263,7 +264,7 @@ public abstract class SolrQueryParserBase extends QueryBuilder {
} }
catch (ParseException | TokenMgrError tme) { catch (ParseException | TokenMgrError tme) {
throw new SyntaxError("Cannot parse '" +query+ "': " + tme.getMessage(), tme); throw new SyntaxError("Cannot parse '" +query+ "': " + tme.getMessage(), tme);
} catch (BooleanQuery.TooManyClauses tmc) { } catch (IndexSearcher.TooManyClauses tmc) {
throw new SyntaxError("Cannot parse '" +query+ "': too many boolean clauses", tmc); throw new SyntaxError("Cannot parse '" +query+ "': too many boolean clauses", tmc);
} }
} }

View File

@ -369,7 +369,7 @@ public final class SolrRangeQuery extends ExtendedQueryBase implements DocSetPro
*/ */
private long collectTerms(LeafReaderContext context, TermsEnum termsEnum, List<TermAndState> terms) throws IOException { private long collectTerms(LeafReaderContext context, TermsEnum termsEnum, List<TermAndState> terms) throws IOException {
long count = 0; long count = 0;
final int threshold = Math.min(BOOLEAN_REWRITE_TERM_COUNT_THRESHOLD, BooleanQuery.getMaxClauseCount()); final int threshold = Math.min(BOOLEAN_REWRITE_TERM_COUNT_THRESHOLD, IndexSearcher.getMaxClauseCount());
for (int i = 0; i < threshold; ++i) { for (int i = 0; i < threshold; ++i) {
final BytesRef term = termsEnum.next(); final BytesRef term = termsEnum.next();
if (term == null) { if (term == null) {

View File

@ -20,6 +20,7 @@ import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanClause.Occur; import org.apache.lucene.search.BooleanClause.Occur;
import org.apache.lucene.search.BooleanQuery; import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.BoostQuery; import org.apache.lucene.search.BoostQuery;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.MatchAllDocsQuery; import org.apache.lucene.search.MatchAllDocsQuery;
import org.apache.lucene.search.Query; import org.apache.lucene.search.Query;
import org.apache.solr.common.SolrException; import org.apache.solr.common.SolrException;
@ -132,7 +133,7 @@ public class QueryUtils {
/** @lucene.experimental throw exception if max boolean clauses are exceeded */ /** @lucene.experimental throw exception if max boolean clauses are exceeded */
public static BooleanQuery build(BooleanQuery.Builder builder, QParser parser) { public static BooleanQuery build(BooleanQuery.Builder builder, QParser parser) {
int configuredMax = parser != null ? parser.getReq().getCore().getSolrConfig().booleanQueryMaxClauseCount : BooleanQuery.getMaxClauseCount(); int configuredMax = parser != null ? parser.getReq().getCore().getSolrConfig().booleanQueryMaxClauseCount : IndexSearcher.getMaxClauseCount();
BooleanQuery bq = builder.build(); BooleanQuery bq = builder.build();
if (bq.clauses().size() > configuredMax) { if (bq.clauses().size() > configuredMax) {
throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, throw new SolrException(SolrException.ErrorCode.BAD_REQUEST,

View File

@ -23,7 +23,6 @@ import org.apache.lucene.document.Field;
import org.apache.lucene.index.DirectoryReader; import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.RandomIndexWriter; import org.apache.lucene.index.RandomIndexWriter;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.MultiTermQuery; import org.apache.lucene.search.MultiTermQuery;
import org.apache.lucene.search.Query; import org.apache.lucene.search.Query;
@ -139,7 +138,7 @@ public class TestNumericRangeQuery32 extends SolrTestCase {
super.setUp(); super.setUp();
// set the theoretical maximum term count for 8bit (see docs for the number) // set the theoretical maximum term count for 8bit (see docs for the number)
// super.tearDown will restore the default // super.tearDown will restore the default
BooleanQuery.setMaxClauseCount(3*255*2 + 255); IndexSearcher.setMaxClauseCount(3*255*2 + 255);
} }
/** test for both constant score and boolean query, the other tests only use the constant score mode */ /** test for both constant score and boolean query, the other tests only use the constant score mode */

View File

@ -23,7 +23,6 @@ import org.apache.lucene.document.Field;
import org.apache.lucene.index.DirectoryReader; import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.RandomIndexWriter; import org.apache.lucene.index.RandomIndexWriter;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.MultiTermQuery; import org.apache.lucene.search.MultiTermQuery;
import org.apache.lucene.search.Query; import org.apache.lucene.search.Query;
@ -148,7 +147,7 @@ public class TestNumericRangeQuery64 extends SolrTestCase {
super.setUp(); super.setUp();
// set the theoretical maximum term count for 8bit (see docs for the number) // set the theoretical maximum term count for 8bit (see docs for the number)
// super.tearDown will restore the default // super.tearDown will restore the default
BooleanQuery.setMaxClauseCount(7*255*2 + 255); IndexSearcher.setMaxClauseCount(7*255*2 + 255);
} }
/** test for constant score + boolean query + filter, the other tests only use the constant score mode */ /** test for constant score + boolean query + filter, the other tests only use the constant score mode */

View File

@ -28,6 +28,7 @@ import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery; import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.BoostQuery; import org.apache.lucene.search.BoostQuery;
import org.apache.lucene.search.ConstantScoreQuery; import org.apache.lucene.search.ConstantScoreQuery;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.PointInSetQuery; import org.apache.lucene.search.PointInSetQuery;
import org.apache.lucene.search.Query; import org.apache.lucene.search.Query;
import org.apache.lucene.search.TermInSetQuery; import org.apache.lucene.search.TermInSetQuery;
@ -367,7 +368,7 @@ public class TestSolrQueryParser extends SolrTestCaseJ4 {
@Test @Test
public void testManyClauses_Lucene() throws Exception { public void testManyClauses_Lucene() throws Exception {
final int numZ = BooleanQuery.getMaxClauseCount(); final int numZ = IndexSearcher.getMaxClauseCount();
final String a = "1 a 2 b 3 c 10 d 11 12 "; // 10 terms final String a = "1 a 2 b 3 c 10 d 11 12 "; // 10 terms
final StringBuilder sb = new StringBuilder("id:("); final StringBuilder sb = new StringBuilder("id:(");
@ -391,7 +392,7 @@ public class TestSolrQueryParser extends SolrTestCaseJ4 {
assertEquals(SyntaxError.class, e.getCause().getClass()); assertEquals(SyntaxError.class, e.getCause().getClass());
assertNotNull(e.getCause().getCause()); assertNotNull(e.getCause().getCause());
assertEquals(BooleanQuery.TooManyClauses.class, e.getCause().getCause().getClass()); assertEquals(IndexSearcher.TooManyClauses.class, e.getCause().getCause().getClass());
// but should still work as a filter query since TermsQuery can be used... // but should still work as a filter query since TermsQuery can be used...
assertJQ(req("q","*:*", "fq", way_too_long) assertJQ(req("q","*:*", "fq", way_too_long)