diff --git a/gerrit-lucene/src/main/java/com/google/gerrit/lucene/LuceneChangeIndex.java b/gerrit-lucene/src/main/java/com/google/gerrit/lucene/LuceneChangeIndex.java index e8057c1f06..da116b719f 100644 --- a/gerrit-lucene/src/main/java/com/google/gerrit/lucene/LuceneChangeIndex.java +++ b/gerrit-lucene/src/main/java/com/google/gerrit/lucene/LuceneChangeIndex.java @@ -126,6 +126,14 @@ public class LuceneChangeIndex implements ChangeIndex { private static final String ID_SORT_FIELD = sortFieldName(ChangeField.LEGACY_ID); + static Term idTerm(ChangeData cd) { + return QueryBuilder.intTerm(LEGACY_ID.getName(), cd.getId().get()); + } + + static Term idTerm(Change.Id id) { + return QueryBuilder.intTerm(LEGACY_ID.getName(), id.get()); + } + private static String sortFieldName(FieldDef f) { return f.getName() + "_SORT"; } @@ -140,7 +148,7 @@ public class LuceneChangeIndex implements ChangeIndex { private final Provider db; private final ChangeData.Factory changeDataFactory; private final Schema schema; - private final QueryBuilder queryBuilder; + private final QueryBuilder queryBuilder; private final ChangeSubIndex openIndex; private final ChangeSubIndex closedIndex; @@ -165,7 +173,7 @@ public class LuceneChangeIndex implements ChangeIndex { GerritIndexWriterConfig closedConfig = new GerritIndexWriterConfig(cfg, "changes_closed"); - queryBuilder = new QueryBuilder(openConfig.getAnalyzer()); + queryBuilder = new QueryBuilder<>(schema, openConfig.getAnalyzer()); SearcherFactory searcherFactory = new SearcherFactory(); if (LuceneIndexModule.isInMemoryTest(cfg)) { @@ -207,7 +215,7 @@ public class LuceneChangeIndex implements ChangeIndex { @Override public void replace(ChangeData cd) throws IOException { - Term id = QueryBuilder.idTerm(cd); + Term id = LuceneChangeIndex.idTerm(cd); Document doc = toDocument(cd); try { if (cd.change().getStatus().isOpen()) { @@ -226,7 +234,7 @@ public class LuceneChangeIndex implements ChangeIndex { @Override public void delete(Change.Id id) throws IOException { - Term idTerm = QueryBuilder.idTerm(id); + Term idTerm = LuceneChangeIndex.idTerm(id); try { Futures.allAsList( openIndex.delete(idTerm), @@ -498,12 +506,12 @@ public class LuceneChangeIndex implements ChangeIndex { return result; } - private void add(Document doc, Values values) { + private static void add(Document doc, Values values) { String name = values.getField().getName(); FieldType type = values.getField().getType(); Store store = store(values.getField()); - FieldDef f = values.getField(); + FieldDef f = values.getField(); // Add separate DocValues fields for those fields needed for sorting. if (f == ChangeField.LEGACY_ID) { diff --git a/gerrit-lucene/src/main/java/com/google/gerrit/lucene/QueryBuilder.java b/gerrit-lucene/src/main/java/com/google/gerrit/lucene/QueryBuilder.java index 9897ded5d1..7e5177e692 100644 --- a/gerrit-lucene/src/main/java/com/google/gerrit/lucene/QueryBuilder.java +++ b/gerrit-lucene/src/main/java/com/google/gerrit/lucene/QueryBuilder.java @@ -14,24 +14,23 @@ package com.google.gerrit.lucene; -import static com.google.gerrit.server.index.change.ChangeField.LEGACY_ID; +import static com.google.common.base.Preconditions.checkArgument; import static org.apache.lucene.search.BooleanClause.Occur.MUST; import static org.apache.lucene.search.BooleanClause.Occur.MUST_NOT; import static org.apache.lucene.search.BooleanClause.Occur.SHOULD; import com.google.common.collect.Lists; -import com.google.gerrit.reviewdb.client.Change; import com.google.gerrit.server.index.FieldType; import com.google.gerrit.server.index.IndexPredicate; import com.google.gerrit.server.index.IntegerRangePredicate; import com.google.gerrit.server.index.RegexPredicate; +import com.google.gerrit.server.index.Schema; import com.google.gerrit.server.index.TimestampRangePredicate; import com.google.gerrit.server.query.AndPredicate; import com.google.gerrit.server.query.NotPredicate; import com.google.gerrit.server.query.OrPredicate; import com.google.gerrit.server.query.Predicate; import com.google.gerrit.server.query.QueryParseException; -import com.google.gerrit.server.query.change.ChangeData; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.index.Term; @@ -48,23 +47,22 @@ import org.apache.lucene.util.NumericUtils; import java.util.Date; import java.util.List; -public class QueryBuilder { - - public static Term idTerm(ChangeData cd) { - return intTerm(LEGACY_ID.getName(), cd.getId().get()); - } - - public static Term idTerm(Change.Id id) { - return intTerm(LEGACY_ID.getName(), id.get()); +public class QueryBuilder { + static Term intTerm(String name, int value) { + BytesRefBuilder builder = new BytesRefBuilder(); + NumericUtils.intToPrefixCodedBytes(value, 0, builder); + return new Term(name, builder.get()); } + private final Schema schema; private final org.apache.lucene.util.QueryBuilder queryBuilder; - public QueryBuilder(Analyzer analyzer) { + public QueryBuilder(Schema schema, Analyzer analyzer) { + this.schema = schema; queryBuilder = new org.apache.lucene.util.QueryBuilder(analyzer); } - public Query toQuery(Predicate p) throws QueryParseException { + public Query toQuery(Predicate p) throws QueryParseException { if (p instanceof AndPredicate) { return and(p); } else if (p instanceof OrPredicate) { @@ -72,13 +70,13 @@ public class QueryBuilder { } else if (p instanceof NotPredicate) { return not(p); } else if (p instanceof IndexPredicate) { - return fieldQuery((IndexPredicate) p); + return fieldQuery((IndexPredicate) p); } else { throw new QueryParseException("cannot create query for index: " + p); } } - private Query or(Predicate p) + private Query or(Predicate p) throws QueryParseException { try { BooleanQuery.Builder q = new BooleanQuery.Builder(); @@ -91,17 +89,17 @@ public class QueryBuilder { } } - private Query and(Predicate p) + private Query and(Predicate p) throws QueryParseException { try { BooleanQuery.Builder b = new BooleanQuery.Builder(); List not = Lists.newArrayListWithCapacity(p.getChildCount()); for (int i = 0; i < p.getChildCount(); i++) { - Predicate c = p.getChild(i); + Predicate c = p.getChild(i); if (c instanceof NotPredicate) { - Predicate n = c.getChild(0); + Predicate n = c.getChild(0); if (n instanceof TimestampRangePredicate) { - b.add(notTimestamp((TimestampRangePredicate) n), MUST); + b.add(notTimestamp((TimestampRangePredicate) n), MUST); } else { not.add(toQuery(n)); } @@ -118,11 +116,11 @@ public class QueryBuilder { } } - private Query not(Predicate p) + private Query not(Predicate p) throws QueryParseException { - Predicate n = p.getChild(0); + Predicate n = p.getChild(0); if (n instanceof TimestampRangePredicate) { - return notTimestamp((TimestampRangePredicate) n); + return notTimestamp((TimestampRangePredicate) n); } // Lucene does not support negation, start with all and subtract. @@ -132,8 +130,11 @@ public class QueryBuilder { .build(); } - private Query fieldQuery(IndexPredicate p) + private Query fieldQuery(IndexPredicate p) throws QueryParseException { + checkArgument(schema.hasField(p.getField()), + "field not in schema v%s: %s", schema.getVersion(), + p.getField().getName()); if (p.getType() == FieldType.INTEGER) { return intQuery(p); } else if (p.getType() == FieldType.INTEGER_RANGE) { @@ -151,13 +152,7 @@ public class QueryBuilder { } } - private static Term intTerm(String name, int value) { - BytesRefBuilder builder = new BytesRefBuilder(); - NumericUtils.intToPrefixCodedBytes(value, 0, builder); - return new Term(name, builder.get()); - } - - private Query intQuery(IndexPredicate p) + private Query intQuery(IndexPredicate p) throws QueryParseException { int value; try { @@ -170,11 +165,11 @@ public class QueryBuilder { return new TermQuery(intTerm(p.getField().getName(), value)); } - private Query intRangeQuery(IndexPredicate p) + private Query intRangeQuery(IndexPredicate p) throws QueryParseException { if (p instanceof IntegerRangePredicate) { - IntegerRangePredicate r = - (IntegerRangePredicate) p; + IntegerRangePredicate r = + (IntegerRangePredicate) p; int minimum = r.getMinimumValue(); int maximum = r.getMaximumValue(); if (minimum == maximum) { @@ -192,11 +187,11 @@ public class QueryBuilder { throw new QueryParseException("not an integer range: " + p); } - private Query timestampQuery(IndexPredicate p) + private Query timestampQuery(IndexPredicate p) throws QueryParseException { if (p instanceof TimestampRangePredicate) { - TimestampRangePredicate r = - (TimestampRangePredicate) p; + TimestampRangePredicate r = + (TimestampRangePredicate) p; return NumericRangeQuery.newLongRange( r.getField().getName(), r.getMinTimestamp().getTime(), @@ -206,7 +201,7 @@ public class QueryBuilder { throw new QueryParseException("not a timestamp: " + p); } - private Query notTimestamp(TimestampRangePredicate r) + private Query notTimestamp(TimestampRangePredicate r) throws QueryParseException { if (r.getMinTimestamp().getTime() == 0) { return NumericRangeQuery.newLongRange( @@ -218,7 +213,7 @@ public class QueryBuilder { throw new QueryParseException("cannot negate: " + r); } - private Query exactQuery(IndexPredicate p) { + private Query exactQuery(IndexPredicate p) { if (p instanceof RegexPredicate) { return regexQuery(p); } else { @@ -226,7 +221,7 @@ public class QueryBuilder { } } - private Query regexQuery(IndexPredicate p) { + private Query regexQuery(IndexPredicate p) { String re = p.getValue(); if (re.startsWith("^")) { re = re.substring(1); @@ -237,11 +232,11 @@ public class QueryBuilder { return new RegexpQuery(new Term(p.getField().getName(), re)); } - private Query prefixQuery(IndexPredicate p) { + private Query prefixQuery(IndexPredicate p) { return new PrefixQuery(new Term(p.getField().getName(), p.getValue())); } - private Query fullTextQuery(IndexPredicate p) + private Query fullTextQuery(IndexPredicate p) throws QueryParseException { String value = p.getValue(); if (value == null) {