Index change status in the secondary index

Change-Id: I4dd8a815c1886be4e955267b0d9d2e23d0e41a4b
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/change/Abandon.java b/gerrit-server/src/main/java/com/google/gerrit/server/change/Abandon.java
index f766297..20e7681 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/change/Abandon.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/change/Abandon.java
@@ -28,6 +28,7 @@
 import com.google.gerrit.server.ChangeUtil;
 import com.google.gerrit.server.IdentifiedUser;
 import com.google.gerrit.server.change.Abandon.Input;
+import com.google.gerrit.server.index.ChangeIndexer;
 import com.google.gerrit.server.mail.AbandonedSender;
 import com.google.gerrit.server.mail.ReplyToChangeSender;
 import com.google.gerrit.server.project.ChangeControl;
@@ -48,6 +49,7 @@
   private final AbandonedSender.Factory abandonedSenderFactory;
   private final Provider<ReviewDb> dbProvider;
   private final ChangeJson json;
+  private final ChangeIndexer indexer;
 
   public static class Input {
     @DefaultInput
@@ -58,11 +60,13 @@
   Abandon(ChangeHooks hooks,
       AbandonedSender.Factory abandonedSenderFactory,
       Provider<ReviewDb> dbProvider,
-      ChangeJson json) {
+      ChangeJson json,
+      ChangeIndexer indexer) {
     this.hooks = hooks;
     this.abandonedSenderFactory = abandonedSenderFactory;
     this.dbProvider = dbProvider;
     this.json = json;
+    this.indexer = indexer;
   }
 
   @Override
@@ -107,6 +111,7 @@
       db.rollback();
     }
 
+    indexer.index(change);
     try {
       ReplyToChangeSender cm = abandonedSenderFactory.create(change);
       cm.setFrom(caller.getAccountId());
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/change/Restore.java b/gerrit-server/src/main/java/com/google/gerrit/server/change/Restore.java
index afb58f9..001ed03 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/change/Restore.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/change/Restore.java
@@ -28,6 +28,7 @@
 import com.google.gerrit.server.ChangeUtil;
 import com.google.gerrit.server.IdentifiedUser;
 import com.google.gerrit.server.change.Restore.Input;
+import com.google.gerrit.server.index.ChangeIndexer;
 import com.google.gerrit.server.mail.ReplyToChangeSender;
 import com.google.gerrit.server.mail.RestoredSender;
 import com.google.gerrit.server.project.ChangeControl;
@@ -48,6 +49,7 @@
   private final RestoredSender.Factory restoredSenderFactory;
   private final Provider<ReviewDb> dbProvider;
   private final ChangeJson json;
+  private final ChangeIndexer indexer;
 
   public static class Input {
     @DefaultInput
@@ -58,11 +60,13 @@
   Restore(ChangeHooks hooks,
       RestoredSender.Factory restoredSenderFactory,
       Provider<ReviewDb> dbProvider,
-      ChangeJson json) {
+      ChangeJson json,
+      ChangeIndexer indexer) {
     this.hooks = hooks;
     this.restoredSenderFactory = restoredSenderFactory;
     this.dbProvider = dbProvider;
     this.json = json;
+    this.indexer = indexer;
   }
 
   @Override
@@ -98,6 +102,7 @@
         throw new ResourceConflictException("change is "
             + status(db.changes().get(req.getChange().getId())));
       }
+      indexer.index(change);
       message = newMessage(input, caller, change);
       db.changeMessages().insert(Collections.singleton(message));
       new ApprovalsUtil(db).syncChangeStatus(change);
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/change/Submit.java b/gerrit-server/src/main/java/com/google/gerrit/server/change/Submit.java
index 2b51b0a..e236abb 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/change/Submit.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/change/Submit.java
@@ -36,6 +36,7 @@
 import com.google.gerrit.server.change.Submit.Input;
 import com.google.gerrit.server.git.GitRepositoryManager;
 import com.google.gerrit.server.git.MergeQueue;
+import com.google.gerrit.server.index.ChangeIndexer;
 import com.google.gerrit.server.project.ChangeControl;
 import com.google.gwtorm.server.AtomicUpdate;
 import com.google.gwtorm.server.OrmException;
@@ -72,14 +73,17 @@
   private final Provider<ReviewDb> dbProvider;
   private final GitRepositoryManager repoManager;
   private final MergeQueue mergeQueue;
+  private final ChangeIndexer indexer;
 
   @Inject
   Submit(Provider<ReviewDb> dbProvider,
       GitRepositoryManager repoManager,
-      MergeQueue mergeQueue) {
+      MergeQueue mergeQueue,
+      ChangeIndexer indexer) {
     this.dbProvider = dbProvider;
     this.repoManager = repoManager;
     this.mergeQueue = mergeQueue;
+    this.indexer = indexer;
   }
 
   @Override
@@ -187,6 +191,7 @@
     } finally {
       db.rollback();
     }
+    indexer.index(change);
     return change;
   }
 
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/changedetail/PublishDraft.java b/gerrit-server/src/main/java/com/google/gerrit/server/changedetail/PublishDraft.java
index 22eae2d..6ece448 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/changedetail/PublishDraft.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/changedetail/PublishDraft.java
@@ -33,6 +33,7 @@
 import com.google.gerrit.server.IdentifiedUser;
 import com.google.gerrit.server.account.AccountResolver;
 import com.google.gerrit.server.git.GitRepositoryManager;
+import com.google.gerrit.server.index.ChangeIndexer;
 import com.google.gerrit.server.mail.CreateChangeSender;
 import com.google.gerrit.server.mail.MailUtil.MailRecipients;
 import com.google.gerrit.server.mail.ReplacePatchSetSender;
@@ -40,6 +41,7 @@
 import com.google.gerrit.server.patch.PatchSetInfoNotAvailableException;
 import com.google.gerrit.server.project.ChangeControl;
 import com.google.gerrit.server.project.NoSuchChangeException;
+import com.google.gerrit.server.util.RequestScopePropagator;
 import com.google.gwtorm.server.AtomicUpdate;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
@@ -75,6 +77,8 @@
   private final AccountResolver accountResolver;
   private final CreateChangeSender.Factory createChangeSenderFactory;
   private final ReplacePatchSetSender.Factory replacePatchSetFactory;
+  private final ChangeIndexer indexer;
+  private final RequestScopePropagator requestScopePropagator;
 
   private final PatchSet.Id patchSetId;
 
@@ -87,6 +91,8 @@
       final AccountResolver accountResolver,
       final CreateChangeSender.Factory createChangeSenderFactory,
       final ReplacePatchSetSender.Factory replacePatchSetFactory,
+      final ChangeIndexer indexer,
+      final RequestScopePropagator requestScopePropagator,
       @Assisted final PatchSet.Id patchSetId) {
     this.changeControlFactory = changeControlFactory;
     this.db = db;
@@ -97,6 +103,8 @@
     this.accountResolver = accountResolver;
     this.createChangeSenderFactory = createChangeSenderFactory;
     this.replacePatchSetFactory = replacePatchSetFactory;
+    this.indexer = indexer;
+    this.requestScopePropagator = requestScopePropagator;
 
     this.patchSetId = patchSetId;
   }
@@ -146,6 +154,7 @@
       });
 
       if (!updatedPatchSet.isDraft() || updatedChange.getStatus() == Change.Status.NEW) {
+        indexer.index(updatedChange, requestScopePropagator);
         hooks.doDraftPublishedHook(updatedChange, updatedPatchSet, db);
 
         sendNotifications(control.getChange().getStatus() == Change.Status.DRAFT,
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/changedetail/RebaseChange.java b/gerrit-server/src/main/java/com/google/gerrit/server/changedetail/RebaseChange.java
index 3b43fb0..0db8019 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/changedetail/RebaseChange.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/changedetail/RebaseChange.java
@@ -35,6 +35,7 @@
 import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
 import com.google.gerrit.server.git.GitRepositoryManager;
 import com.google.gerrit.server.git.MergeUtil;
+import com.google.gerrit.server.index.ChangeIndexer;
 import com.google.gerrit.server.mail.RebasedPatchSetSender;
 import com.google.gerrit.server.mail.ReplacePatchSetSender;
 import com.google.gerrit.server.patch.PatchSetInfoFactory;
@@ -75,6 +76,7 @@
   private final ChangeHookRunner hooks;
   private final MergeUtil.Factory mergeUtilFactory;
   private final ProjectCache projectCache;
+  private final ChangeIndexer indexer;
 
   @Inject
   RebaseChange(final ChangeControl.GenericFactory changeControlFactory,
@@ -85,7 +87,8 @@
       final RebasedPatchSetSender.Factory rebasedPatchSetSenderFactory,
       final ChangeHookRunner hooks,
       final MergeUtil.Factory mergeUtilFactory,
-      final ProjectCache projectCache) {
+      final ProjectCache projectCache,
+      final ChangeIndexer changeIndexer) {
     this.changeControlFactory = changeControlFactory;
     this.patchSetInfoFactory = patchSetInfoFactory;
     this.db = db;
@@ -96,6 +99,7 @@
     this.hooks = hooks;
     this.mergeUtilFactory = mergeUtilFactory;
     this.projectCache = projectCache;
+    this.indexer = changeIndexer;
   }
 
   /**
@@ -156,10 +160,10 @@
           uploader.newCommitterIdent(myIdent.getWhen(),
               myIdent.getTimeZone());
 
-      final PatchSet newPatchSet =
-          rebase(git, rw, inserter, patchSetId, change, uploader.getAccountId(), baseCommit,
-              mergeUtilFactory.create(
-                  changeControl.getProjectControl().getProjectState(), true), committerIdent);
+      final PatchSet newPatchSet = rebase(git, rw, inserter, patchSetId, change,
+          uploader.getAccountId(), baseCommit, mergeUtilFactory.create(
+              changeControl.getProjectControl().getProjectState(), true),
+          committerIdent, indexer);
 
       final Set<Account.Id> oldReviewers = Sets.newHashSet();
       final Set<Account.Id> oldCC = Sets.newHashSet();
@@ -301,6 +305,7 @@
    * @param uploader the user that creates the rebased patch set
    * @param baseCommit the commit that should be the new base
    * @param mergeUtil merge utilities for the destination project
+   * @param indexer helper for indexing the change
    * @return the new patch set which is based on the given base commit
    * @throws NoSuchChangeException thrown if the change to which the patch set
    *         belongs does not exist or is not visible to the user
@@ -311,7 +316,8 @@
   public PatchSet rebase(final Repository git, final RevWalk revWalk,
       final ObjectInserter inserter, final PatchSet.Id patchSetId,
       final Change chg, final Account.Id uploader, final RevCommit baseCommit,
-      final MergeUtil mergeUtil, PersonIdent committerIdent) throws NoSuchChangeException,
+      final MergeUtil mergeUtil, PersonIdent committerIdent,
+      final ChangeIndexer indexer) throws NoSuchChangeException,
       OrmException, IOException, InvalidChangeOperationException,
       PathConflictException {
     Change change = chg;
@@ -383,6 +389,7 @@
             "Change %s was modified", change.getId()));
       }
 
+      indexer.index(change);
       ApprovalsUtil.copyLabels(db, projectCache.get(change.getProject())
           .getLabelTypes(), patchSetId, change.currentPatchSetId());
 
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/MergeOp.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/MergeOp.java
index a59a216..bce3d37 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/MergeOp.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/MergeOp.java
@@ -15,6 +15,7 @@
 package com.google.gerrit.server.git;
 
 import static com.google.gerrit.server.git.MergeUtil.getSubmitter;
+
 import static java.util.concurrent.TimeUnit.DAYS;
 import static java.util.concurrent.TimeUnit.MILLISECONDS;
 import static java.util.concurrent.TimeUnit.MINUTES;
@@ -43,6 +44,7 @@
 import com.google.gerrit.server.account.AccountCache;
 import com.google.gerrit.server.config.AllProjectsName;
 import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
+import com.google.gerrit.server.index.ChangeIndexer;
 import com.google.gerrit.server.mail.MergeFailSender;
 import com.google.gerrit.server.mail.MergedSender;
 import com.google.gerrit.server.patch.PatchSetInfoFactory;
@@ -153,6 +155,7 @@
   private final WorkQueue workQueue;
   private final RequestScopePropagator requestScopePropagator;
   private final AllProjectsName allProjectsName;
+  private final ChangeIndexer indexer;
 
   @Inject
   MergeOp(final GitRepositoryManager grm, final SchemaFactory<ReviewDb> sf,
@@ -168,7 +171,8 @@
       final SubmoduleOp.Factory subOpFactory,
       final WorkQueue workQueue,
       final RequestScopePropagator requestScopePropagator,
-      final AllProjectsName allProjectsName) {
+      final AllProjectsName allProjectsName,
+      final ChangeIndexer indexer) {
     repoManager = grm;
     schemaFactory = sf;
     labelNormalizer = fs;
@@ -188,6 +192,7 @@
     this.workQueue = workQueue;
     this.requestScopePropagator = requestScopePropagator;
     this.allProjectsName = allProjectsName;
+    this.indexer = indexer;
     destBranch = branch;
     toMerge = ArrayListMultimap.create();
     potentiallyStillSubmittable = new ArrayList<CodeReviewCommit>();
@@ -758,6 +763,7 @@
       } catch (OrmException err) {
         log.warn("Error updating change status for " + c.getId(), err);
       }
+      indexer.index(c);
     }
   }
 
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/RebaseIfNecessary.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/RebaseIfNecessary.java
index 77c4863..0518349 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/RebaseIfNecessary.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/RebaseIfNecessary.java
@@ -80,7 +80,7 @@
                 rebaseChange.rebase(args.repo, args.rw, args.inserter,
                     n.patchsetId, n.change,
                     args.mergeUtil.getSubmitter(n.patchsetId).getAccountId(),
-                    newMergeTip, args.mergeUtil, committerIdent);
+                    newMergeTip, args.mergeUtil, committerIdent, args.indexer);
             List<PatchSetApproval> approvals = Lists.newArrayList();
             for (PatchSetApproval a : args.mergeUtil.getApprovalsForCommit(n)) {
               approvals.add(new PatchSetApproval(newPatchSet.getId(), a));
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/ReceiveCommits.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/ReceiveCommits.java
index 25cc6d4..8e4ba0c 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/ReceiveCommits.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/ReceiveCommits.java
@@ -74,6 +74,7 @@
 import com.google.gerrit.server.git.validators.CommitValidationException;
 import com.google.gerrit.server.git.validators.CommitValidationMessage;
 import com.google.gerrit.server.git.validators.CommitValidators;
+import com.google.gerrit.server.index.ChangeIndexer;
 import com.google.gerrit.server.mail.CreateChangeSender;
 import com.google.gerrit.server.mail.MailUtil.MailRecipients;
 import com.google.gerrit.server.mail.MergedSender;
@@ -263,6 +264,7 @@
   private final WorkQueue workQueue;
   private final ListeningExecutorService changeUpdateExector;
   private final RequestScopePropagator requestScopePropagator;
+  private final ChangeIndexer indexer;
   private final SshInfo sshInfo;
   private final AllProjectsName allProjectsName;
   private final ReceiveConfig receiveConfig;
@@ -323,6 +325,7 @@
       final WorkQueue workQueue,
       @ChangeUpdateExecutor ListeningExecutorService changeUpdateExector,
       final RequestScopePropagator requestScopePropagator,
+      final ChangeIndexer indexer,
       final SshInfo sshInfo,
       final AllProjectsName allProjectsName,
       ReceiveConfig config,
@@ -353,6 +356,7 @@
     this.workQueue = workQueue;
     this.changeUpdateExector = changeUpdateExector;
     this.requestScopePropagator = requestScopePropagator;
+    this.indexer = indexer;
     this.sshInfo = sshInfo;
     this.allProjectsName = allProjectsName;
     this.receiveConfig = config;
@@ -1905,6 +1909,7 @@
       if (cmd.getResult() == NOT_ATTEMPTED) {
         cmd.execute(rp);
       }
+      indexer.index(change, requestScopePropagator);
       gitRefUpdated.fire(project.getNameKey(), newPatchSet.getRefName(),
           ObjectId.zeroId(), newCommit);
       hooks.doPatchsetCreatedHook(change, newPatchSet, db);
@@ -2207,7 +2212,7 @@
 
   private void markChangeMergedByPush(final ReviewDb db,
       final ReplaceRequest result) throws OrmException {
-    final Change change = result.change;
+    Change change = result.change;
     final String mergedIntoRef = result.mergedIntoRef;
 
     change.setCurrentPatchSet(result.info);
@@ -2235,17 +2240,19 @@
 
     db.changeMessages().insert(Collections.singleton(msg));
 
-    db.changes().atomicUpdate(change.getId(), new AtomicUpdate<Change>() {
-      @Override
-      public Change update(Change change) {
-        if (change.getStatus().isOpen()) {
-          change.setCurrentPatchSet(result.info);
-          change.setStatus(Change.Status.MERGED);
-          ChangeUtil.updated(change);
-        }
-        return change;
-      }
-    });
+    change = db.changes().atomicUpdate(
+        change.getId(), new AtomicUpdate<Change>() {
+          @Override
+          public Change update(Change change) {
+            if (change.getStatus().isOpen()) {
+              change.setCurrentPatchSet(result.info);
+              change.setStatus(Change.Status.MERGED);
+              ChangeUtil.updated(change);
+            }
+            return change;
+          }
+        });
+    indexer.index(change, requestScopePropagator);
   }
 
   private void sendMergedEmail(final ReplaceRequest result) {
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/SubmitStrategy.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/SubmitStrategy.java
index 7c2ba86..9626e23 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/SubmitStrategy.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/SubmitStrategy.java
@@ -20,6 +20,7 @@
 import com.google.gerrit.reviewdb.client.Project.SubmitType;
 import com.google.gerrit.reviewdb.server.ReviewDb;
 import com.google.gerrit.server.IdentifiedUser;
+import com.google.gerrit.server.index.ChangeIndexer;
 
 import org.eclipse.jgit.lib.ObjectInserter;
 import org.eclipse.jgit.lib.PersonIdent;
@@ -55,13 +56,15 @@
     protected final Set<RevCommit> alreadyAccepted;
     protected final Branch.NameKey destBranch;
     protected final MergeUtil mergeUtil;
+    protected final ChangeIndexer indexer;
     protected final MergeSorter mergeSorter;
 
     Arguments(final IdentifiedUser.GenericFactory identifiedUserFactory,
         final PersonIdent myIdent, final ReviewDb db, final Repository repo,
         final RevWalk rw, final ObjectInserter inserter,
         final RevFlag canMergeFlag, final Set<RevCommit> alreadyAccepted,
-        final Branch.NameKey destBranch, final MergeUtil mergeUtil) {
+        final Branch.NameKey destBranch, final MergeUtil mergeUtil,
+        final ChangeIndexer indexer) {
       this.identifiedUserFactory = identifiedUserFactory;
       this.myIdent = myIdent;
       this.db = db;
@@ -73,6 +76,7 @@
       this.alreadyAccepted = alreadyAccepted;
       this.destBranch = destBranch;
       this.mergeUtil = mergeUtil;
+      this.indexer = indexer;
       this.mergeSorter = new MergeSorter(rw, alreadyAccepted, canMergeFlag);
     }
   }
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/SubmitStrategyFactory.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/SubmitStrategyFactory.java
index d43a756..845139d 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/SubmitStrategyFactory.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/SubmitStrategyFactory.java
@@ -22,6 +22,7 @@
 import com.google.gerrit.server.changedetail.RebaseChange;
 import com.google.gerrit.server.config.CanonicalWebUrl;
 import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
+import com.google.gerrit.server.index.ChangeIndexer;
 import com.google.gerrit.server.patch.PatchSetInfoFactory;
 import com.google.gerrit.server.project.NoSuchProjectException;
 import com.google.gerrit.server.project.ProjectCache;
@@ -54,6 +55,7 @@
   private final RebaseChange rebaseChange;
   private final ProjectCache projectCache;
   private final MergeUtil.Factory mergeUtilFactory;
+  private final ChangeIndexer indexer;
 
   @Inject
   SubmitStrategyFactory(
@@ -63,7 +65,8 @@
       @CanonicalWebUrl @Nullable final Provider<String> urlProvider,
       final GitReferenceUpdated gitRefUpdated, final RebaseChange rebaseChange,
       final ProjectCache projectCache,
-      final MergeUtil.Factory mergeUtilFactory) {
+      final MergeUtil.Factory mergeUtilFactory,
+      final ChangeIndexer indexer) {
     this.identifiedUserFactory = identifiedUserFactory;
     this.myIdent = myIdent;
     this.patchSetInfoFactory = patchSetInfoFactory;
@@ -71,6 +74,7 @@
     this.rebaseChange = rebaseChange;
     this.projectCache = projectCache;
     this.mergeUtilFactory = mergeUtilFactory;
+    this.indexer = indexer;
   }
 
   public SubmitStrategy create(final SubmitType submitType, final ReviewDb db,
@@ -82,7 +86,7 @@
     final SubmitStrategy.Arguments args =
         new SubmitStrategy.Arguments(identifiedUserFactory, myIdent, db, repo,
             rw, inserter, canMergeFlag, alreadyAccepted, destBranch,
-            mergeUtilFactory.create(project));
+            mergeUtilFactory.create(project), indexer);
     switch (submitType) {
       case CHERRY_PICK:
         return new CherryPick(args, patchSetInfoFactory, gitRefUpdated);
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/index/ChangeField.java b/gerrit-server/src/main/java/com/google/gerrit/server/index/ChangeField.java
index 602c59b..e52f80d 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/index/ChangeField.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/index/ChangeField.java
@@ -18,6 +18,7 @@
 import com.google.common.collect.Maps;
 import com.google.gerrit.server.query.change.ChangeData;
 import com.google.gerrit.server.query.change.ChangeQueryBuilder;
+import com.google.gerrit.server.query.change.ChangeStatusPredicate;
 import com.google.gwtorm.server.OrmException;
 
 import java.lang.reflect.Field;
@@ -49,6 +50,18 @@
         }
       };
 
+  /** Change status string, in the same format as {@code status:}. */
+  public static final FieldDef<ChangeData, String> STATUS =
+      new FieldDef.Single<ChangeData, String>(ChangeQueryBuilder.FIELD_STATUS,
+          FieldType.EXACT, false) {
+        @Override
+        public String get(ChangeData input, FillArgs args)
+            throws OrmException {
+          return ChangeStatusPredicate.VALUES.get(
+              input.change(args.db).getStatus());
+        }
+      };
+
   /** List of filenames modified in the current patch set. */
   public static final FieldDef<ChangeData, Iterable<String>> FILE =
       new FieldDef.Repeatable<ChangeData, String>(
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/ChangeStatusPredicate.java b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/ChangeStatusPredicate.java
index cb64801..6d08db0 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/ChangeStatusPredicate.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/ChangeStatusPredicate.java
@@ -19,7 +19,8 @@
 import com.google.common.collect.ImmutableBiMap;
 import com.google.gerrit.reviewdb.client.Change;
 import com.google.gerrit.reviewdb.server.ReviewDb;
-import com.google.gerrit.server.query.OperatorPredicate;
+import com.google.gerrit.server.index.ChangeField;
+import com.google.gerrit.server.index.IndexPredicate;
 import com.google.gerrit.server.query.Predicate;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Provider;
@@ -34,8 +35,8 @@
  * status:} but may also be {@code is:} to help do-what-i-meanery for end-users
  * searching for changes. Either operator name has the same meaning.
  */
-final class ChangeStatusPredicate extends OperatorPredicate<ChangeData> {
-  private static final ImmutableBiMap<Change.Status, String> VALUES;
+public final class ChangeStatusPredicate extends IndexPredicate<ChangeData> {
+  public static final ImmutableBiMap<Change.Status, String> VALUES;
 
   static {
     ImmutableBiMap.Builder<Change.Status, String> values =
@@ -70,14 +71,14 @@
   private final Change.Status status;
 
   ChangeStatusPredicate(Provider<ReviewDb> dbProvider, String value) {
-    super(ChangeQueryBuilder.FIELD_STATUS, value);
+    super(ChangeField.STATUS, value);
     this.dbProvider = dbProvider;
     status = VALUES.inverse().get(value);
     checkArgument(status != null, "invalid change status: %s", value);
   }
 
   ChangeStatusPredicate(Provider<ReviewDb> dbProvider, Change.Status status) {
-    super(ChangeQueryBuilder.FIELD_STATUS, VALUES.get(status));
+    super(ChangeField.STATUS, VALUES.get(status));
     this.dbProvider = dbProvider;
     this.status = status;
   }