query: Fix limit:N clauses on strange iterators

If the underlying source didn't abort at the result limit count we
have to clip it manually ourselves higher up in the query processor.
I failed to use the limit:N value and instead clipped with the
default, resulting in larger result sets for certain queries.

Change-Id: Ibc68dde8631788ffa1e2ea23266bb736280abc04
Signed-off-by: Shawn O. Pearce <sop@google.com>
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java
index 834e866..1b9f051 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java
@@ -413,6 +413,11 @@
   }
 
   @SuppressWarnings("unchecked")
+  public int getLimit(Predicate<ChangeData> p) {
+    return ((IntPredicate) find(p, IntPredicate.class, FIELD_LIMIT)).intValue();
+  }
+
+  @SuppressWarnings("unchecked")
   public boolean hasSortKey(Predicate<ChangeData> p) {
     return find(p, SortKeyPredicate.class, "sortkey_after") != null
         || find(p, SortKeyPredicate.class, "sortkey_before") != null;
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/QueryProcessor.java b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/QueryProcessor.java
index 62d3bbd..3433fa9 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/QueryProcessor.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/QueryProcessor.java
@@ -140,8 +140,9 @@
           }
         });
 
-        if (defaultLimit < results.size()) {
-          results = results.subList(0, defaultLimit);
+        int limit = limit(s);
+        if (limit < results.size()) {
+          results = results.subList(0, limit);
         }
 
         for (ChangeData d : results) {
@@ -190,6 +191,10 @@
     }
   }
 
+  private int limit(Predicate<ChangeData> s) {
+    return queryBuilder.hasLimit(s) ? queryBuilder.getLimit(s) : defaultLimit;
+  }
+
   @SuppressWarnings("unchecked")
   private Predicate<ChangeData> compileQuery(String queryString,
       final Predicate<ChangeData> visibleToMe) throws QueryParseException {