Browse Source

Make "too many clauses" throw IllegalArgumentException to avoid 500s (#112678)

* Make "too many clauses" throw IllegalArgumentException to avoid 500s
Stanislav Malyshev 1 year ago
parent
commit
383a4c2f46

+ 6 - 0
docs/changelog/112678.yaml

@@ -0,0 +1,6 @@
+pr: 112678
+summary: Make "too many clauses" throw IllegalArgumentException to avoid 500s
+area: Search
+type: bug
+issues:
+ - 112177

+ 2 - 0
server/src/main/java/org/elasticsearch/search/internal/ContextIndexSearcher.java

@@ -202,6 +202,8 @@ public class ContextIndexSearcher extends IndexSearcher implements Releasable {
         } catch (TimeExceededException e) {
             timeExceeded = true;
             return new MatchNoDocsQuery("rewrite timed out");
+        } catch (TooManyClauses e) {
+            throw new IllegalArgumentException("Query rewrite failed: too many clauses", e);
         } finally {
             if (profiler != null) {
                 profiler.stopAndAddRewriteTime(rewriteTimer);

+ 17 - 0
server/src/test/java/org/elasticsearch/search/query/QueryPhaseTests.java

@@ -29,6 +29,7 @@ import org.apache.lucene.index.NoMergePolicy;
 import org.apache.lucene.index.Term;
 import org.apache.lucene.queries.spans.SpanNearQuery;
 import org.apache.lucene.queries.spans.SpanTermQuery;
+import org.apache.lucene.search.BooleanClause;
 import org.apache.lucene.search.BooleanClause.Occur;
 import org.apache.lucene.search.BooleanQuery;
 import org.apache.lucene.search.Collector;
@@ -1105,6 +1106,22 @@ public class QueryPhaseTests extends IndexShardTestCase {
         );
     }
 
+    public void testTooManyClauses() throws Exception {
+        indexDocs();
+        var oldCount = IndexSearcher.getMaxClauseCount();
+        try {
+            var query = new BooleanQuery.Builder().add(new BooleanClause(new MatchAllDocsQuery(), Occur.SHOULD))
+                .add(new MatchAllDocsQuery(), Occur.SHOULD)
+                .build();
+            try (TestSearchContext context = createContext(newContextSearcher(reader), query)) {
+                IndexSearcher.setMaxClauseCount(1);
+                expectThrows(IllegalArgumentException.class, context::rewrittenQuery);
+            }
+        } finally {
+            IndexSearcher.setMaxClauseCount(oldCount);
+        }
+    }
+
     private static ContextIndexSearcher noCollectionContextSearcher(IndexReader reader) throws IOException {
         return earlyTerminationContextSearcher(reader, 0);
     }