Merge branch 'stable-2.14' into stable-2.15

* stable-2.14:
  Update git submodules
  WorkQueue.Executor#buildMetrics: Remove MetricMaker parameter
  ChangeQueryBuilder: Allow ownerin predicate to be evaluated by the index

Change-Id: Ie972385f045ff08640701f71a0f4c33f6fde9248
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/WorkQueue.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/WorkQueue.java
index bdd5e61..a9461a4 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/WorkQueue.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/WorkQueue.java
@@ -223,7 +223,7 @@
               );
       queueName = prefix;
       try {
-        buildMetrics(queueName, metrics);
+        buildMetrics(queueName);
       } catch (IllegalArgumentException e) {
         if (e.getMessage().contains("already")) {
           log.warn("Not creating metrics for queue '{}': already exists", queueName);
@@ -233,8 +233,8 @@
       }
     }
 
-    private void buildMetrics(String queueName, MetricMaker metric) {
-      metric.newCallbackMetric(
+    private void buildMetrics(String queueName) {
+      metrics.newCallbackMetric(
           getMetricName(queueName, "max_pool_size"),
           Long.class,
           new Description("Maximum allowed number of threads in the pool")
@@ -246,7 +246,7 @@
               return (long) getMaximumPoolSize();
             }
           });
-      metric.newCallbackMetric(
+      metrics.newCallbackMetric(
           getMetricName(queueName, "pool_size"),
           Long.class,
           new Description("Current number of threads in the pool").setGauge().setUnit("threads"),
@@ -256,7 +256,7 @@
               return (long) getPoolSize();
             }
           });
-      metric.newCallbackMetric(
+      metrics.newCallbackMetric(
           getMetricName(queueName, "active_threads"),
           Long.class,
           new Description("Number number of threads that are actively executing tasks")
@@ -268,7 +268,7 @@
               return (long) getActiveCount();
             }
           });
-      metric.newCallbackMetric(
+      metrics.newCallbackMetric(
           getMetricName(queueName, "scheduled_tasks"),
           Integer.class,
           new Description("Number of scheduled tasks in the queue").setGauge().setUnit("tasks"),
@@ -278,7 +278,7 @@
               return getQueue().size();
             }
           });
-      metric.newCallbackMetric(
+      metrics.newCallbackMetric(
           getMetricName(queueName, "total_scheduled_tasks_count"),
           Long.class,
           new Description("Total number of tasks that have been scheduled for execution")
@@ -290,7 +290,7 @@
               return (long) getTaskCount();
             }
           });
-      metric.newCallbackMetric(
+      metrics.newCallbackMetric(
           getMetricName(queueName, "total_completed_tasks_count"),
           Long.class,
           new Description("Total number of tasks that have completed execution")
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java
index bb6c06c..7f4b906 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java
@@ -25,6 +25,7 @@
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Lists;
 import com.google.common.primitives.Ints;
+import com.google.gerrit.common.data.GroupDescription;
 import com.google.gerrit.common.data.GroupReference;
 import com.google.gerrit.common.data.SubmitRecord;
 import com.google.gerrit.common.errors.NotSignedInException;
@@ -761,23 +762,8 @@
       }
     }
 
-    // expand a group predicate into multiple user predicates
     if (group != null) {
-      Set<Account.Id> allMembers =
-          args.listMembers
-              .get()
-              .setRecursive(true)
-              .apply(group)
-              .stream()
-              .map(a -> new Account.Id(a._accountId))
-              .collect(toSet());
-      int maxTerms = args.indexConfig.maxTerms();
-      if (allMembers.size() > maxTerms) {
-        // limit the number of query terms otherwise Gerrit will barf
-        accounts = ImmutableSet.copyOf(Iterables.limit(allMembers, maxTerms));
-      } else {
-        accounts = allMembers;
-      }
+      accounts = getMembers(group);
     }
 
     // If the vote piece looks like Code-Review=NEED with a valid non-numeric
@@ -961,12 +947,24 @@
   }
 
   @Operator
-  public Predicate<ChangeData> ownerin(String group) throws QueryParseException {
+  public Predicate<ChangeData> ownerin(String group) throws QueryParseException, OrmException {
     GroupReference g = GroupBackends.findBestSuggestion(args.groupBackend, group);
     if (g == null) {
       throw error("Group " + group + " not found");
     }
-    return new OwnerinPredicate(args.userFactory, g.getUUID());
+
+    AccountGroup.UUID groupId = g.getUUID();
+    GroupDescription.Basic groupDescription = args.groupBackend.get(groupId);
+    if (!(groupDescription instanceof GroupDescription.Internal)) {
+      return new OwnerinPredicate(args.userFactory, groupId);
+    }
+
+    Set<Account.Id> accounts = getMembers(groupId);
+    List<OwnerPredicate> p = Lists.newArrayListWithCapacity(accounts.size());
+    for (Account.Id id : accounts) {
+      p.add(new OwnerPredicate(id));
+    }
+    return Predicate.or(p);
   }
 
   @Operator
@@ -1237,6 +1235,26 @@
     return Predicate.and(predicates);
   }
 
+  private Set<Account.Id> getMembers(AccountGroup.UUID g) throws OrmException {
+    Set<Account.Id> accounts;
+    Set<Account.Id> allMembers =
+        args.listMembers
+            .get()
+            .setRecursive(true)
+            .apply(g)
+            .stream()
+            .map(a -> new Account.Id(a._accountId))
+            .collect(toSet());
+    int maxTerms = args.indexConfig.maxTerms();
+    if (allMembers.size() > maxTerms) {
+      // limit the number of query terms otherwise Gerrit will barf
+      accounts = ImmutableSet.copyOf(Iterables.limit(allMembers, maxTerms));
+    } else {
+      accounts = allMembers;
+    }
+    return accounts;
+  }
+
   private Set<Account.Id> parseAccount(String who)
       throws QueryParseException, OrmException, IOException, ConfigInvalidException {
     if (isSelf(who)) {