|
@@ -19,6 +19,11 @@
|
|
|
|
|
|
package org.elasticsearch.index.query;
|
|
|
|
|
|
+import org.apache.lucene.analysis.Analyzer;
|
|
|
+import org.apache.lucene.analysis.CannedBinaryTokenStream;
|
|
|
+import org.apache.lucene.analysis.MockTokenizer;
|
|
|
+import org.apache.lucene.analysis.TokenStream;
|
|
|
+import org.apache.lucene.analysis.Tokenizer;
|
|
|
import org.apache.lucene.index.Term;
|
|
|
import org.apache.lucene.queries.ExtendedCommonTermsQuery;
|
|
|
import org.apache.lucene.search.BooleanClause;
|
|
@@ -30,6 +35,7 @@ import org.apache.lucene.search.MatchNoDocsQuery;
|
|
|
import org.apache.lucene.search.PointRangeQuery;
|
|
|
import org.apache.lucene.search.Query;
|
|
|
import org.apache.lucene.search.TermQuery;
|
|
|
+import org.apache.lucene.util.BytesRef;
|
|
|
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest;
|
|
|
import org.elasticsearch.common.ParsingException;
|
|
|
import org.elasticsearch.common.Strings;
|
|
@@ -46,6 +52,8 @@ import org.elasticsearch.test.AbstractQueryTestCase;
|
|
|
import org.hamcrest.Matcher;
|
|
|
|
|
|
import java.io.IOException;
|
|
|
+import java.io.Reader;
|
|
|
+import java.util.ArrayList;
|
|
|
import java.util.HashMap;
|
|
|
import java.util.List;
|
|
|
import java.util.Locale;
|
|
@@ -392,4 +400,72 @@ public class MatchQueryBuilderTests extends AbstractQueryTestCase<MatchQueryBuil
|
|
|
assertThat(query.toString(),
|
|
|
containsString("field:[string_no_pos] was indexed without position data; cannot run PhraseQuery"));
|
|
|
}
|
|
|
+
|
|
|
+ public void testMaxBooleanClause() {
|
|
|
+ MatchQuery query = new MatchQuery(createShardContext());
|
|
|
+ query.setAnalyzer(new MockGraphAnalyzer(createGiantGraph(40)));
|
|
|
+ expectThrows(BooleanQuery.TooManyClauses.class, () -> query.parse(Type.PHRASE, STRING_FIELD_NAME, ""));
|
|
|
+ query.setAnalyzer(new MockGraphAnalyzer(createGiantGraphMultiTerms()));
|
|
|
+ expectThrows(BooleanQuery.TooManyClauses.class, () -> query.parse(Type.PHRASE, STRING_FIELD_NAME, ""));
|
|
|
+ }
|
|
|
+
|
|
|
+ private static class MockGraphAnalyzer extends Analyzer {
|
|
|
+ final CannedBinaryTokenStream.BinaryToken[] tokens;
|
|
|
+
|
|
|
+ private MockGraphAnalyzer(CannedBinaryTokenStream.BinaryToken[] tokens ) {
|
|
|
+ this.tokens = tokens;
|
|
|
+ }
|
|
|
+ @Override
|
|
|
+ protected TokenStreamComponents createComponents(String fieldName) {
|
|
|
+ Tokenizer tokenizer = new MockTokenizer(MockTokenizer.SIMPLE, true);
|
|
|
+ return new TokenStreamComponents(tokenizer) {
|
|
|
+ @Override
|
|
|
+ public TokenStream getTokenStream() {
|
|
|
+ return new CannedBinaryTokenStream(tokens);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ protected void setReader(final Reader reader) {
|
|
|
+ }
|
|
|
+ };
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Creates a graph token stream with 2 side paths at each position.
|
|
|
+ **/
|
|
|
+ private static CannedBinaryTokenStream.BinaryToken[] createGiantGraph(int numPos) {
|
|
|
+ List<CannedBinaryTokenStream.BinaryToken> tokens = new ArrayList<>();
|
|
|
+ BytesRef term1 = new BytesRef("foo");
|
|
|
+ BytesRef term2 = new BytesRef("bar");
|
|
|
+ for (int i = 0; i < numPos;) {
|
|
|
+ if (i % 2 == 0) {
|
|
|
+ tokens.add(new CannedBinaryTokenStream.BinaryToken(term2, 1, 1));
|
|
|
+ tokens.add(new CannedBinaryTokenStream.BinaryToken(term1, 0, 2));
|
|
|
+ i += 2;
|
|
|
+ } else {
|
|
|
+ tokens.add(new CannedBinaryTokenStream.BinaryToken(term2, 1, 1));
|
|
|
+ i++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return tokens.toArray(new CannedBinaryTokenStream.BinaryToken[0]);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Creates a graph token stream with {@link BooleanQuery#getMaxClauseCount()}
|
|
|
+ * expansions at the last position.
|
|
|
+ **/
|
|
|
+ private static CannedBinaryTokenStream.BinaryToken[] createGiantGraphMultiTerms() {
|
|
|
+ List<CannedBinaryTokenStream.BinaryToken> tokens = new ArrayList<>();
|
|
|
+ BytesRef term1 = new BytesRef("foo");
|
|
|
+ BytesRef term2 = new BytesRef("bar");
|
|
|
+ tokens.add(new CannedBinaryTokenStream.BinaryToken(term2, 1, 1));
|
|
|
+ tokens.add(new CannedBinaryTokenStream.BinaryToken(term1, 0, 2));
|
|
|
+ tokens.add(new CannedBinaryTokenStream.BinaryToken(term2, 1, 1));
|
|
|
+ tokens.add(new CannedBinaryTokenStream.BinaryToken(term2, 1, 1));
|
|
|
+ for (int i = 0; i < BooleanQuery.getMaxClauseCount(); i++) {
|
|
|
+ tokens.add(new CannedBinaryTokenStream.BinaryToken(term1, 0, 1));
|
|
|
+ }
|
|
|
+ return tokens.toArray(new CannedBinaryTokenStream.BinaryToken[0]);
|
|
|
+ }
|
|
|
}
|