Fix limit handling in QueryProcessor
This was a mess, and hasn't been working for a long time. The test for _more_changes added in this change does not pass prior to this change. The only way we ever communicated that extra results were present out of QueryProcessor was by including one more result. But different pieces of the code were rarely clear on whether they should be expecting an extra result or not. Moreover, there were three different limits that were considered, and they were all given unhelpful names like "limit" and "maxLimit." Improving this situation substantially requires doing something like what the end result is from the REST API: including for each list of results a boolean indicating whether there are more results available. Do this with a QueryResult class encapsulating these fields. This class also includes the original query string and rewritten predicate intermediates, which can help with debugging. After this change, the semantics of the limits should be more clear. The limit computation uses more helpful variable names, and enforces that we always request a limit of n+1 from the secondary index. However, this extra result never escapes to callers in a QueryResult from QueryProcessor. This also required changes to the query rewriter to replace all limit predicates within the query with a fixed value that is always different from any limit predicate in the original query. This may actually make IndexRewriteTest a little easier to understand, as prior to this change a different limit would appear in the IndexChangedQuery portions than at the top level. Change-Id: I4fcf7db0136fd77dbe91b20258ae80a9797a1af9
This commit is contained in:
@@ -97,7 +97,7 @@ public class IndexRewriteTest {
|
||||
parse("-status:abandoned (status:open OR status:merged)");
|
||||
assertEquals(
|
||||
query(parse("status:new OR status:submitted OR status:draft OR status:merged")),
|
||||
rewrite.rewrite(in, 0));
|
||||
rewrite.rewrite(in, 0, DEFAULT_MAX_QUERY_LIMIT));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -158,24 +158,26 @@ public class IndexRewriteTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLimit() throws Exception {
|
||||
Predicate<ChangeData> in = parse("file:a limit:3");
|
||||
Predicate<ChangeData> out = rewrite(in);
|
||||
public void testLimitArgumentOverridesAllLimitPredicates() throws Exception {
|
||||
Predicate<ChangeData> in = parse("limit:1 file:a limit:3");
|
||||
Predicate<ChangeData> out = rewrite(in, 5);
|
||||
assertSame(AndSource.class, out.getClass());
|
||||
assertEquals(ImmutableList.of(
|
||||
query(in.getChild(0), 3),
|
||||
in.getChild(1)),
|
||||
query(in.getChild(1), 5),
|
||||
parse("limit:5"),
|
||||
parse("limit:5")),
|
||||
out.getChildren());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStartIncreasesLimit() throws Exception {
|
||||
int n = 3;
|
||||
Predicate<ChangeData> f = parse("file:a");
|
||||
Predicate<ChangeData> l = parse("limit:3");
|
||||
Predicate<ChangeData> l = parse("limit:" + n);
|
||||
Predicate<ChangeData> in = and(f, l);
|
||||
assertEquals(and(query(f, 3), l), rewrite.rewrite(in, 0));
|
||||
assertEquals(and(query(f, 4), l), rewrite.rewrite(in, 1));
|
||||
assertEquals(and(query(f, 5), l), rewrite.rewrite(in, 2));
|
||||
assertEquals(and(query(f, 3), parse("limit:3")), rewrite.rewrite(in, 0, n));
|
||||
assertEquals(and(query(f, 4), parse("limit:4")), rewrite.rewrite(in, 1, n));
|
||||
assertEquals(and(query(f, 5), parse("limit:5")), rewrite.rewrite(in, 2, n));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -220,7 +222,12 @@ public class IndexRewriteTest {
|
||||
|
||||
private Predicate<ChangeData> rewrite(Predicate<ChangeData> in)
|
||||
throws QueryParseException {
|
||||
return rewrite.rewrite(in, 0);
|
||||
return rewrite.rewrite(in, 0, DEFAULT_MAX_QUERY_LIMIT);
|
||||
}
|
||||
|
||||
private Predicate<ChangeData> rewrite(Predicate<ChangeData> in, int limit)
|
||||
throws QueryParseException {
|
||||
return rewrite.rewrite(in, 0, limit);
|
||||
}
|
||||
|
||||
private IndexedChangeQuery query(Predicate<ChangeData> p)
|
||||
|
@@ -543,9 +543,22 @@ public abstract class AbstractQueryChangesTest {
|
||||
|
||||
List<ChangeInfo> results;
|
||||
for (int i = 1; i <= n + 2; i++) {
|
||||
int expectedSize;
|
||||
Boolean expectedMoreChanges;
|
||||
if (i < n) {
|
||||
expectedSize = i;
|
||||
expectedMoreChanges = true;
|
||||
} else {
|
||||
expectedSize = n;
|
||||
expectedMoreChanges = null;
|
||||
}
|
||||
results = query("status:new limit:" + i);
|
||||
assertThat(results).hasSize(Math.min(i, n));
|
||||
String msg = "i=" + i;
|
||||
assert_().withFailureMessage(msg).that(results).hasSize(expectedSize);
|
||||
assertResultEquals(last, results.get(0));
|
||||
assert_().withFailureMessage(msg)
|
||||
.that(results.get(results.size() - 1)._moreChanges)
|
||||
.isEqualTo(expectedMoreChanges);
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user