Line data Source code
1 : // Copyright (C) 2021 The Android Open Source Project 2 : // 3 : // Licensed under the Apache License, Version 2.0 (the "License"); 4 : // you may not use this file except in compliance with the License. 5 : // You may obtain a copy of the License at 6 : // 7 : // http://www.apache.org/licenses/LICENSE-2.0 8 : // 9 : // Unless required by applicable law or agreed to in writing, software 10 : // distributed under the License is distributed on an "AS IS" BASIS, 11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 : // See the License for the specific language governing permissions and 13 : // limitations under the License. 14 : 15 : package com.google.gerrit.server.query.change; 16 : 17 : import com.google.gerrit.index.query.NotPredicate; 18 : import com.google.gerrit.index.query.Predicate; 19 : import com.google.gerrit.server.index.change.ChangeField; 20 : 21 : public class IsSubmittablePredicate extends BooleanPredicate { 22 : public IsSubmittablePredicate() { 23 5 : super(ChangeField.IS_SUBMITTABLE_SPEC); 24 5 : } 25 : 26 : /** 27 : * Rewrite the is:submittable predicate. 28 : * 29 : * <p>If we run a query with "is:submittable OR -is:submittable" the result should match all 30 : * changes. In Lucene, we keep separate sub-indexes for open and closed changes. The Lucene 31 : * backend inspects the input predicate and depending on all its child predicates decides if the 32 : * query should run against the open sub-index, closed sub-index or both. 33 : * 34 : * <p>The "is:submittable" operator is implemented as: 35 : * 36 : * <p>issubmittable:1 37 : * 38 : * <p>But we want to exclude closed changes from being matched by this query. For the normal case, 39 : * we rewrite the query as: 40 : * 41 : * <p>issubmittable:1 AND status:new 42 : * 43 : * <p>Hence Lucene will match the query against the open sub-index. For the negated case (i.e. 44 : * "-is:submittable"), we cannot just negate the previous query because it would result in: 45 : * 46 : * <p>-(issubmittable:1 AND status:new) 47 : * 48 : * <p>Lucene will conclude that it should look for changes that are <b>not</b> new and hence will 49 : * run the query against the closed sub-index, not matching with changes that are open but not 50 : * submittable. For this case, we need to rewrite the query to match with closed changes <b>or</b> 51 : * changes that are not submittable. 52 : */ 53 : public static Predicate<ChangeData> rewrite(Predicate<ChangeData> in) { 54 111 : if (in instanceof IsSubmittablePredicate) { 55 5 : return Predicate.and( 56 5 : new BooleanPredicate(ChangeField.IS_SUBMITTABLE_SPEC), ChangeStatusPredicate.open()); 57 : } 58 111 : if (in instanceof NotPredicate && in.getChild(0) instanceof IsSubmittablePredicate) { 59 4 : return Predicate.or( 60 4 : Predicate.not(new BooleanPredicate(ChangeField.IS_SUBMITTABLE_SPEC)), 61 4 : ChangeStatusPredicate.closed()); 62 : } 63 111 : return in; 64 : } 65 : }