Introduce change number in secondary index

The only information contained in the index concerning
change number is the virtual id, stored in the `legacy_id_str`
field.

The virtual id is a combination of server Id + change number
(I7b9acabb).

Not having change number, but only virtual id in the index
prevents a lookup by change number for imported changes from
other servers.

This restriction doesn't allow command execution on
imported changes.

Added `changenum` in the secondary index to allow lookups
by change number.

Bug: Issue 320946495
Release-Notes: Introduce change number in secondary index
Forward-Compatible: checked
Change-Id: If141b0b10e150736d2934ff0ef5316725f669026
diff --git a/java/com/google/gerrit/server/index/change/ChangeField.java b/java/com/google/gerrit/server/index/change/ChangeField.java
index 3ca536c..045482a 100644
--- a/java/com/google/gerrit/server/index/change/ChangeField.java
+++ b/java/com/google/gerrit/server/index/change/ChangeField.java
@@ -17,6 +17,7 @@
 import static com.google.common.base.MoreObjects.firstNonNull;
 import static com.google.common.collect.ImmutableList.toImmutableList;
 import static com.google.common.collect.ImmutableSet.toImmutableSet;
+import static com.google.gerrit.server.query.change.ChangeQueryBuilder.FIELD_CHANGE_NUMBER;
 import static com.google.gerrit.server.util.AttentionSetUtil.additionsOnly;
 import static java.nio.charset.StandardCharsets.UTF_8;
 import static java.util.stream.Collectors.joining;
@@ -133,6 +134,15 @@
   public static final IndexedField<ChangeData, String>.SearchSpec NUMERIC_ID_STR_SPEC =
       NUMERIC_ID_STR_FIELD.exact("legacy_id_str");
 
+  public static final IndexedField<ChangeData, Integer> CHANGENUM_FIELD =
+      IndexedField.<ChangeData>integerBuilder("ChangeNumber")
+          .stored()
+          .required()
+          .build(cd -> cd.getId().get());
+
+  public static final IndexedField<ChangeData, Integer>.SearchSpec CHANGENUM_SPEC =
+      CHANGENUM_FIELD.integer(FIELD_CHANGE_NUMBER);
+
   /** Newer style Change-Id key. */
   public static final IndexedField<ChangeData, String> CHANGE_ID_FIELD =
       IndexedField.<ChangeData>stringBuilder("ChangeId")
diff --git a/java/com/google/gerrit/server/index/change/ChangeSchemaDefinitions.java b/java/com/google/gerrit/server/index/change/ChangeSchemaDefinitions.java
index 3d48907..4921b3f 100644
--- a/java/com/google/gerrit/server/index/change/ChangeSchemaDefinitions.java
+++ b/java/com/google/gerrit/server/index/change/ChangeSchemaDefinitions.java
@@ -259,8 +259,15 @@
           .build();
 
   /** Upgrade Lucene to 9.x requires reindexing. */
-  @SuppressWarnings("deprecation")
-  static final Schema<ChangeData> V85 = schema(V84);
+  @Deprecated static final Schema<ChangeData> V85 = schema(V84);
+
+  /** Add ChangeNumber field */
+  static final Schema<ChangeData> V86 =
+      new Schema.Builder<ChangeData>()
+          .add(V85)
+          .addIndexedFields(ChangeField.CHANGENUM_FIELD)
+          .addSearchSpecs(ChangeField.CHANGENUM_SPEC)
+          .build();
 
   /**
    * Name of the change index to be used when contacting index backends or loading configurations.
diff --git a/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java b/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java
index a64b68d..030db1b 100644
--- a/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java
+++ b/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java
@@ -166,6 +166,7 @@
 
   public static final String FIELD_CHANGE = "change";
   public static final String FIELD_CHANGE_ID = "change_id";
+  public static final String FIELD_CHANGE_NUMBER = "changenumber";
   public static final String FIELD_COMMENT = "comment";
   public static final String FIELD_COMMENTBY = "commentby";
   public static final String FIELD_COMMIT = "commit";