Throw QueryParseException earlier from index queries In Ia839eb21 due to sort key predicate rewriting we pushed the call to ChangeIndex.getSource() to be lazy when reading the predicate. Wrapping a resulting QueryParseException means that exception text, which is intended to be user-visible, isn't. Instead, send the query to the secondary index implementation earlier, and just re-process the query if the sort key is rewritten. This change means it is definitively inappropriate to kick off searches in the background when getSource() is called as opposed to when read() is called on the resulting source; document this fact in the getSource() javadoc. Change-Id: I8fb2ab25aaadf4eb0eba44c9eb31351be0748c0e
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/index/ChangeIndex.java b/gerrit-server/src/main/java/com/google/gerrit/server/index/ChangeIndex.java index fd37cfb..397b044 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/index/ChangeIndex.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/index/ChangeIndex.java
@@ -125,6 +125,11 @@ /** * Convert the given operator predicate into a source searching the index and * returning only the documents matching that predicate. + * <p> + * This method may be called multiple times for variations on the same + * predicate or multiple predicate subtrees in the course of processing a + * single query, so it should not have any side effects (e.g. starting a + * search in the background). * * @param p the predicate to match. Must be a tree containing only AND, OR, * or NOT predicates as internal nodes, and {@link IndexPredicate}s as
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/index/IndexedChangeQuery.java b/gerrit-server/src/main/java/com/google/gerrit/server/index/IndexedChangeQuery.java index 2185af3..f915dad 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/index/IndexedChangeQuery.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/index/IndexedChangeQuery.java
@@ -91,8 +91,9 @@ Predicate<ChangeData> pred, int limit) throws QueryParseException { this.db = db; this.index = index; - this.pred = pred; this.limit = limit; + this.pred = pred; + this.source = index.getSource(pred, limit); } @Override @@ -131,14 +132,8 @@ @Override public ResultSet<ChangeData> read() throws OrmException { - final ChangeDataSource currSource; - try { - currSource = index.getSource(pred, limit); - } catch (QueryParseException e) { - throw new OrmException(e); - } - source = currSource; - final ResultSet<ChangeData> rs = source.read(); + final ChangeDataSource currSource = source; + final ResultSet<ChangeData> rs = currSource.read(); return new ResultSet<ChangeData>() { @Override @@ -174,6 +169,14 @@ @Override public ResultSet<ChangeData> restart(ChangeData last) throws OrmException { pred = replaceSortKeyPredicates(pred, last.change(db).getSortKey()); + try { + source = index.getSource(pred, limit); + } catch (QueryParseException e) { + // Don't need to show this exception to the user; the only thing that + // changed about pred was its SortKeyPredicates, and any other QPEs + // that might happen should have already thrown from the constructor. + throw new OrmException(e); + } return read(); }