diff options
Diffstat (limited to 'container-search/src/main/java/com/yahoo')
-rw-r--r-- | container-search/src/main/java/com/yahoo/prelude/query/QueryCanonicalizer.java | 18 | ||||
-rw-r--r-- | container-search/src/main/java/com/yahoo/search/query/QueryTree.java | 20 |
2 files changed, 36 insertions, 2 deletions
diff --git a/container-search/src/main/java/com/yahoo/prelude/query/QueryCanonicalizer.java b/container-search/src/main/java/com/yahoo/prelude/query/QueryCanonicalizer.java index 1f30833b3db..14e316c1877 100644 --- a/container-search/src/main/java/com/yahoo/prelude/query/QueryCanonicalizer.java +++ b/container-search/src/main/java/com/yahoo/prelude/query/QueryCanonicalizer.java @@ -1,6 +1,7 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.prelude.query; +import com.yahoo.processing.request.CompoundName; import com.yahoo.search.Query; import com.yahoo.search.query.QueryTree; @@ -19,6 +20,8 @@ public class QueryCanonicalizer { /** The name of the operation performed by this, for use in search chain ordering */ public static final String queryCanonicalization = "queryCanonicalization"; + private static final CompoundName MAX_QUERY_ITEMS = new CompoundName("maxQueryItems"); + /** * Validates this query and carries out possible operations on this query * which simplifies it without changing its semantics. @@ -26,7 +29,17 @@ public class QueryCanonicalizer { * @return null if the query is valid, an error message if it is invalid */ public static String canonicalize(Query query) { - return canonicalize(query.getModel().getQueryTree()); + Integer maxQueryItems = query.properties().getInteger(MAX_QUERY_ITEMS, Integer.MAX_VALUE); + return canonicalize(query.getModel().getQueryTree(), maxQueryItems); + } + + /** + * Canonicalizes this query, allowing any query tree size + * + * @return null if the query is valid, an error message if it is invalid + */ + public static String canonicalize(QueryTree queryTree) { + return canonicalize(queryTree, Integer.MAX_VALUE); } /** @@ -34,10 +47,11 @@ public class QueryCanonicalizer { * * @return null if the query is valid, an error message if it is invalid */ - public static String canonicalize(QueryTree query) { + private static String canonicalize(QueryTree query, Integer maxQueryItems) { ListIterator<Item> rootItemIterator = query.getItemIterator(); CanonicalizationResult result = recursivelyCanonicalize(rootItemIterator.next(), rootItemIterator); if (query.isEmpty() && ! result.isError()) result = CanonicalizationResult.error("No query"); + if (query.getTreeSize() > maxQueryItems) result = CanonicalizationResult.error("Query tree exceeds allowed item count"); return result.error().orElse(null); // preserve old API, unfortunately } diff --git a/container-search/src/main/java/com/yahoo/search/query/QueryTree.java b/container-search/src/main/java/com/yahoo/search/query/QueryTree.java index 2fb16ef503f..dab481dc842 100644 --- a/container-search/src/main/java/com/yahoo/search/query/QueryTree.java +++ b/container-search/src/main/java/com/yahoo/search/query/QueryTree.java @@ -7,6 +7,7 @@ import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import java.util.ListIterator; /** * The root node of a query tree. This is always present above the actual semantic root to ease query manipulation, @@ -179,4 +180,23 @@ public class QueryTree extends CompositeItem { } } + /** + * @return The total number of items in this query tree + */ + public int getTreeSize() { + if (isEmpty()) return 0; + return(countItemsRecursively(getItemIterator().next())); + } + + private int countItemsRecursively(Item item) { + int children = 0; + if (item instanceof CompositeItem) { + CompositeItem composite = (CompositeItem)item; + for (ListIterator<Item> i = composite.getItemIterator(); i.hasNext(); ) { + children += countItemsRecursively(i.next()); + } + } + return children + 1; + } + } |