This is an automated email from the ASF dual-hosted git repository.

pvary pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/iceberg.git


The following commit(s) were added to refs/heads/main by this push:
     new b59c059430 Flink: Fix DynamicIcebergSink TableMetadataCache resolving 
retired field ids (#18517)
b59c059430 is described below

commit b59c059430d334d6a381c484fb73bb5094d00741
Author: Aditya Kumar <[email protected]>
AuthorDate: Thu Nov 5 16:12:24 2026 +0530

    Flink: Fix DynamicIcebergSink TableMetadataCache resolving retired field 
ids (#18517)
---
 docs/docs/flink-writes.md                          |   4 +
 .../flink/sink/dynamic/TableMetadataCache.java     | 102 ++++++++++--
 .../flink/sink/dynamic/TestDynamicIcebergSink.java |  33 ++++
 .../flink/sink/dynamic/TestTableMetadataCache.java | 176 +++++++++++++++++++++
 4 files changed, 302 insertions(+), 13 deletions(-)

diff --git a/docs/docs/flink-writes.md b/docs/docs/flink-writes.md
index 6e1a4ec095..deece55bb8 100644
--- a/docs/docs/flink-writes.md
+++ b/docs/docs/flink-writes.md
@@ -524,6 +524,8 @@ The dynamic sink tries to match the schema provided in 
`DynamicRecord` with the
 - If there is no direct match, DynamicSink tries to adapt the provided schema 
such that it matches one of table schemas. For example, if there is an 
additional optional column in the table schema, a null value will be added to 
the RowData provided via DynamicRecord.
 - Otherwise, we evolve the table schema to match the input schema, within the 
constraints described below.
 
+Schemas are matched by column name. The table schemas are checked starting 
with the current schema, then from newest to oldest. A table schema which 
matches the record exactly is preferred over one which needs a conversion (for 
example `Integer` to `Long`), so a record which has the shape of an older table 
schema is written with that schema, even if it would also fit the current one. 
The exceptions are older table schemas which use a column name that belongs to 
a different column in the  [...]
+
 The dynamic sink maintains an LRU cache for both table metadata and incoming 
schemas, with eviction based on size and time constraints. When a DynamicRecord 
contains a schema that is incompatible with the current table schema, a schema 
update is triggered. This update can occur either immediately or via a 
centralized executor, depending on the `immediateTableUpdate` configuration. 
While centralized updates reduce load on the Catalog, they may introduce 
backpressure on the sink.
 
 #### Supported schema updates
@@ -541,6 +543,8 @@ regular queries won't be able to reference the column. If 
the field was to re-ap
 entirely new column would be added, which apart from the name, has nothing in 
common with the old column, i.e. queries
 for the new column will never return data of the old column.
 
+Records which still carry the old column are written to the new column when 
their values can be converted to its type. If they cannot be converted (for 
example because the column was re-added with an incompatible type), they are 
still written using the older table schema.
+
 ##### Unsupported schema updates
 
 - Renaming columns
diff --git 
a/flink/v2.3/flink/src/main/java/org/apache/iceberg/flink/sink/dynamic/TableMetadataCache.java
 
b/flink/v2.3/flink/src/main/java/org/apache/iceberg/flink/sink/dynamic/TableMetadataCache.java
index 76f5909e65..9d836d56fb 100644
--- 
a/flink/v2.3/flink/src/main/java/org/apache/iceberg/flink/sink/dynamic/TableMetadataCache.java
+++ 
b/flink/v2.3/flink/src/main/java/org/apache/iceberg/flink/sink/dynamic/TableMetadataCache.java
@@ -19,6 +19,7 @@
 package org.apache.iceberg.flink.sink.dynamic;
 
 import java.time.Clock;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import org.apache.flink.annotation.Internal;
@@ -32,6 +33,12 @@ import org.apache.iceberg.catalog.TableIdentifier;
 import org.apache.iceberg.exceptions.NoSuchNamespaceException;
 import org.apache.iceberg.exceptions.NoSuchTableException;
 import org.apache.iceberg.flink.FlinkSchemaUtil;
+import org.apache.iceberg.relocated.com.google.common.base.Preconditions;
+import org.apache.iceberg.relocated.com.google.common.collect.ImmutableList;
+import org.apache.iceberg.relocated.com.google.common.collect.Lists;
+import org.apache.iceberg.relocated.com.google.common.collect.Maps;
+import org.apache.iceberg.types.TypeUtil;
+import org.apache.iceberg.types.Types;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -123,7 +130,10 @@ class TableMetadataCache {
             cacheRefreshClock.millis(),
             true,
             table.refs().keySet(),
-            table.schemas(),
+            schemaTiers(
+                orderSchemas(table.schemas(), table.schema().schemaId()),
+                table.schema(),
+                caseSensitive),
             table.specs(),
             inputSchemasPerTableCacheMaximumSize));
   }
@@ -177,15 +187,24 @@ class TableMetadataCache {
   private ResolvedSchemaInfo resolveSchema(
       TableIdentifier identifier, CacheItem cached, Schema input, boolean 
allowRefresh) {
     Schema compatible = null;
-    for (Schema tableSchema : cached.tableSchemas.values()) {
-      CompareSchemasVisitor.Result result =
-          CompareSchemasVisitor.visit(input, tableSchema, caseSensitive, 
dropUnusedColumns);
-      if (result == CompareSchemasVisitor.Result.SAME) {
-        return new ResolvedSchemaInfo(
-            tableSchema, CompareSchemasVisitor.Result.SAME, 
DataConverter.identity());
-      } else if (compatible == null
-          && result == CompareSchemasVisitor.Result.DATA_CONVERSION_NEEDED) {
-        compatible = tableSchema;
+    // The schemas of a tier are only used if no schema of the previous tiers 
matched the input.
+    // Within a tier, the first schema which is the same as the input wins, 
otherwise the first
+    // schema which the input can be converted to. See schemaTiers for the 
order of the schemas.
+    for (List<Schema> tableSchemas : cached.schemaTiers) {
+      for (Schema tableSchema : tableSchemas) {
+        CompareSchemasVisitor.Result result =
+            CompareSchemasVisitor.visit(input, tableSchema, caseSensitive, 
dropUnusedColumns);
+        if (result == CompareSchemasVisitor.Result.SAME) {
+          return new ResolvedSchemaInfo(
+              tableSchema, CompareSchemasVisitor.Result.SAME, 
DataConverter.identity());
+        } else if (compatible == null
+            && result == CompareSchemasVisitor.Result.DATA_CONVERSION_NEEDED) {
+          compatible = tableSchema;
+        }
+      }
+
+      if (compatible != null) {
+        break;
       }
     }
 
@@ -259,12 +278,69 @@ class TableMetadataCache {
     tableCache.remove(identifier);
   }
 
+  /**
+   * Orders the schemas with the current schema first, followed by the rest 
from newest to oldest.
+   * The current schema is not necessarily the one with the highest id, for 
example after a
+   * rollback.
+   */
+  static Map<Integer, Schema> orderSchemas(Map<Integer, Schema> tableSchemas, 
int currentSchemaId) {
+    Map<Integer, Schema> ordered = 
Maps.newLinkedHashMapWithExpectedSize(tableSchemas.size());
+    Schema current = tableSchemas.get(currentSchemaId);
+    Preconditions.checkArgument(current != null, "Current schema %s not 
found", currentSchemaId);
+    ordered.put(currentSchemaId, current);
+
+    tableSchemas.entrySet().stream()
+        .filter(e -> e.getKey() != currentSchemaId)
+        .sorted(Map.Entry.<Integer, Schema>comparingByKey().reversed())
+        .forEach(e -> ordered.put(e.getKey(), e.getValue()));
+    return ordered;
+  }
+
+  /**
+   * Splits the ordered schemas into two tiers, keeping their order within 
each tier.
+   *
+   * <p>The second tier holds the schemas which use a field name that belongs 
to a different field
+   * id in the current schema, for example after a column was dropped and 
added again, or renamed
+   * and its name reused. Data written with such a schema is stored under 
field ids which are not
+   * read through the current schema, so these schemas are only used when no 
schema of the first
+   * tier matches the input.
+   */
+  static List<List<Schema>> schemaTiers(
+      Map<Integer, Schema> orderedSchemas, Schema currentSchema, boolean 
caseSensitive) {
+    List<Schema> preferred = Lists.newArrayList();
+    List<Schema> fallback = Lists.newArrayList();
+    for (Schema schema : orderedSchemas.values()) {
+      if (reusesFieldNames(schema, currentSchema, caseSensitive)) {
+        fallback.add(schema);
+      } else {
+        preferred.add(schema);
+      }
+    }
+
+    return ImmutableList.of(preferred, fallback);
+  }
+
+  private static boolean reusesFieldNames(
+      Schema schema, Schema currentSchema, boolean caseSensitive) {
+    for (Map.Entry<Integer, String> field : 
TypeUtil.indexNameById(schema.asStruct()).entrySet()) {
+      Types.NestedField currentField =
+          caseSensitive
+              ? currentSchema.findField(field.getValue())
+              : currentSchema.caseInsensitiveFindField(field.getValue());
+      if (currentField != null && currentField.fieldId() != field.getKey()) {
+        return true;
+      }
+    }
+
+    return false;
+  }
+
   /** Handles timeout for missing items only. Caffeine performance causes 
noticeable delays. */
   static class CacheItem {
     private final long createdTimestampMillis;
     private final boolean tableExists;
     private final Set<String> branches;
-    private final Map<Integer, Schema> tableSchemas;
+    private final List<List<Schema>> schemaTiers;
     private final Map<Integer, PartitionSpec> specs;
     private final Map<Schema, ResolvedSchemaInfo> inputSchemas;
 
@@ -272,13 +348,13 @@ class TableMetadataCache {
         long createdTimestampMillis,
         boolean tableExists,
         Set<String> branches,
-        Map<Integer, Schema> tableSchemas,
+        List<List<Schema>> schemaTiers,
         Map<Integer, PartitionSpec> specs,
         int inputSchemaCacheMaximumSize) {
       this.createdTimestampMillis = createdTimestampMillis;
       this.tableExists = tableExists;
       this.branches = branches;
-      this.tableSchemas = tableSchemas;
+      this.schemaTiers = schemaTiers;
       this.specs = specs;
       this.inputSchemas =
           new LRUCache<>(inputSchemaCacheMaximumSize, 
CacheItem::inputSchemaEvictionListener);
diff --git 
a/flink/v2.3/flink/src/test/java/org/apache/iceberg/flink/sink/dynamic/TestDynamicIcebergSink.java
 
b/flink/v2.3/flink/src/test/java/org/apache/iceberg/flink/sink/dynamic/TestDynamicIcebergSink.java
index 5cdbab9087..69730d9adb 100644
--- 
a/flink/v2.3/flink/src/test/java/org/apache/iceberg/flink/sink/dynamic/TestDynamicIcebergSink.java
+++ 
b/flink/v2.3/flink/src/test/java/org/apache/iceberg/flink/sink/dynamic/TestDynamicIcebergSink.java
@@ -2110,6 +2110,39 @@ class TestDynamicIcebergSink extends 
TestFlinkIcebergSinkBase {
     }
   }
 
+  @Test
+  void testWriteOldShapeRecordAfterColumnReAddedWithWiderType() throws 
Exception {
+    Schema base =
+        new Schema(
+            Types.NestedField.optional(1, "id", Types.IntegerType.get()),
+            Types.NestedField.optional(2, "data", Types.StringType.get()));
+    Schema oldShape =
+        new Schema(
+            Types.NestedField.optional(1, "id", Types.IntegerType.get()),
+            Types.NestedField.optional(2, "data", Types.StringType.get()),
+            Types.NestedField.optional(3, "c", Types.IntegerType.get()));
+
+    Catalog catalog = CATALOG_EXTENSION.catalog();
+    TableIdentifier tableIdentifier = TableIdentifier.of(DATABASE, "t1");
+    Table table = catalog.createTable(tableIdentifier, base);
+    table.updateSchema().addColumn("c", Types.IntegerType.get()).commit();
+    table.updateSchema().deleteColumn("c").commit();
+    table.updateSchema().addColumn("c", Types.LongType.get()).commit();
+
+    DynamicIcebergDataImpl record =
+        new DynamicIcebergDataImpl(
+            oldShape, "t1", SnapshotRef.MAIN_BRANCH, 
PartitionSpec.unpartitioned());
+    record.rowProvided = Row.of(1, "a", 5);
+
+    executeDynamicSink(Lists.newArrayList(record), env, true, 1, null);
+
+    table.refresh();
+    List<Record> records = 
Lists.newArrayList(IcebergGenerics.read(table).build());
+    assertThat(records).hasSize(1);
+    assertThat(records.get(0).getField("data")).isEqualTo("a");
+    assertThat(records.get(0).getField("c")).isEqualTo(5L);
+  }
+
   private void runTest(List<DynamicIcebergDataImpl> dynamicData) throws 
Exception {
     runTest(dynamicData, this.env, 2);
   }
diff --git 
a/flink/v2.3/flink/src/test/java/org/apache/iceberg/flink/sink/dynamic/TestTableMetadataCache.java
 
b/flink/v2.3/flink/src/test/java/org/apache/iceberg/flink/sink/dynamic/TestTableMetadataCache.java
index bdf8045774..3bb62b45fb 100644
--- 
a/flink/v2.3/flink/src/test/java/org/apache/iceberg/flink/sink/dynamic/TestTableMetadataCache.java
+++ 
b/flink/v2.3/flink/src/test/java/org/apache/iceberg/flink/sink/dynamic/TestTableMetadataCache.java
@@ -24,6 +24,7 @@ import static org.assertj.core.api.Assertions.assertThat;
 import java.time.Clock;
 import java.time.Instant;
 import java.time.ZoneId;
+import java.util.Map;
 import org.apache.commons.lang3.SerializationUtils;
 import org.apache.iceberg.PartitionSpec;
 import org.apache.iceberg.Schema;
@@ -32,6 +33,7 @@ import org.apache.iceberg.Table;
 import org.apache.iceberg.catalog.Catalog;
 import org.apache.iceberg.catalog.TableIdentifier;
 import org.apache.iceberg.flink.sink.TestFlinkIcebergSinkBase;
+import org.apache.iceberg.relocated.com.google.common.collect.Maps;
 import org.apache.iceberg.types.Types;
 import org.junit.jupiter.api.Test;
 
@@ -239,4 +241,178 @@ public class TestTableMetadataCache extends 
TestFlinkIcebergSinkBase {
     assertThat(cache.schema(tableIdentifier, SCHEMA_MIXEDCASE))
         .isEqualTo(TableMetadataCache.NOT_FOUND);
   }
+
+  @Test
+  void testSchemaPrefersCurrentSchemaAfterDropAndReAddColumn() {
+    Catalog catalog = CATALOG_EXTENSION.catalog();
+    TableIdentifier tableIdentifier = TableIdentifier.parse("default.myTable");
+    Table table = catalog.createTable(tableIdentifier, SCHEMA);
+    table.updateSchema().addColumn("extra", Types.StringType.get()).commit();
+    int retiredFieldId = table.schema().findField("extra").fieldId();
+    table.updateSchema().deleteColumn("extra").commit();
+    table.updateSchema().addColumn("extra", Types.StringType.get()).commit();
+    int currentFieldId = table.schema().findField("extra").fieldId();
+    assertThat(currentFieldId).isNotEqualTo(retiredFieldId);
+
+    TableMetadataCache cache =
+        new TableMetadataCache(catalog, 10, Long.MAX_VALUE, 10, 
CASE_SENSITIVE, PRESERVE_COLUMNS);
+
+    Schema resolved = cache.schema(tableIdentifier, 
table.schema()).resolvedTableSchema();
+
+    
assertThat(resolved.findField("extra").fieldId()).isEqualTo(currentFieldId);
+  }
+
+  @Test
+  void testSchemaStillMatchesHistoricalSchemaWhenDroppedColumnIsNotReAdded() {
+    Catalog catalog = CATALOG_EXTENSION.catalog();
+    TableIdentifier tableIdentifier = TableIdentifier.parse("default.myTable");
+    Table table = catalog.createTable(tableIdentifier, SCHEMA);
+    table.updateSchema().addColumn("extra", Types.StringType.get()).commit();
+    Schema withExtra = table.schema();
+    table.updateSchema().deleteColumn("extra").commit();
+
+    TableMetadataCache cache =
+        new TableMetadataCache(catalog, 10, Long.MAX_VALUE, 10, 
CASE_SENSITIVE, PRESERVE_COLUMNS);
+
+    Schema resolved = cache.schema(tableIdentifier, 
withExtra).resolvedTableSchema();
+
+    assertThat(resolved.findField("extra").fieldId())
+        .isEqualTo(withExtra.findField("extra").fieldId());
+  }
+
+  @Test
+  void testSchemasAreOrderedCurrentFirstThenNewestToOldest() {
+    Map<Integer, Schema> schemas = Maps.newHashMap();
+    for (int id = 0; id < 4; id++) {
+      schemas.put(id, SCHEMA);
+    }
+
+    assertThat(TableMetadataCache.orderSchemas(schemas, 
3).keySet()).containsExactly(3, 2, 1, 0);
+
+    // after a rollback the current schema is not the one with the highest id
+    assertThat(TableMetadataCache.orderSchemas(schemas, 
1).keySet()).containsExactly(1, 3, 2, 0);
+  }
+
+  @Test
+  void testSchemaPrefersCurrentSchemaWhenColumnIsReAddedAfterAnotherChange() {
+    Catalog catalog = CATALOG_EXTENSION.catalog();
+    TableIdentifier tableIdentifier = TableIdentifier.parse("default.myTable");
+    Table table = catalog.createTable(tableIdentifier, SCHEMA);
+    table.updateSchema().addColumn("c", Types.StringType.get()).commit();
+    Schema oldShape = table.schema();
+    int retiredFieldId = oldShape.findField("c").fieldId();
+    table.updateSchema().deleteColumn("c").commit();
+    table.updateSchema().addColumn("d", Types.StringType.get()).commit();
+    table.updateSchema().addColumn("c", Types.StringType.get()).commit();
+    int currentFieldId = table.schema().findField("c").fieldId();
+    assertThat(currentFieldId).isNotEqualTo(retiredFieldId);
+
+    TableMetadataCache cache =
+        new TableMetadataCache(catalog, 10, Long.MAX_VALUE, 10, 
CASE_SENSITIVE, PRESERVE_COLUMNS);
+
+    Schema resolved = cache.schema(tableIdentifier, 
oldShape).resolvedTableSchema();
+
+    assertThat(resolved.findField("c").fieldId()).isEqualTo(currentFieldId);
+  }
+
+  @Test
+  void testSchemaPrefersCurrentSchemaWhenColumnIsReAddedWithWiderType() {
+    Catalog catalog = CATALOG_EXTENSION.catalog();
+    TableIdentifier tableIdentifier = TableIdentifier.parse("default.myTable");
+    Table table = catalog.createTable(tableIdentifier, SCHEMA);
+    table.updateSchema().addColumn("c", Types.IntegerType.get()).commit();
+    Schema oldShape = table.schema();
+    int retiredFieldId = oldShape.findField("c").fieldId();
+    table.updateSchema().deleteColumn("c").commit();
+    table.updateSchema().addColumn("c", Types.LongType.get()).commit();
+    int currentFieldId = table.schema().findField("c").fieldId();
+    assertThat(currentFieldId).isNotEqualTo(retiredFieldId);
+
+    TableMetadataCache cache =
+        new TableMetadataCache(catalog, 10, Long.MAX_VALUE, 10, 
CASE_SENSITIVE, PRESERVE_COLUMNS);
+
+    Schema resolved = cache.schema(tableIdentifier, 
oldShape).resolvedTableSchema();
+
+    assertThat(resolved.findField("c").fieldId()).isEqualTo(currentFieldId);
+    assertThat(resolved.findField("c").type()).isEqualTo(Types.LongType.get());
+  }
+
+  @Test
+  void testSchemaPrefersCurrentSchemaWhenFieldNameIsReusedAfterRename() {
+    Catalog catalog = CATALOG_EXTENSION.catalog();
+    TableIdentifier tableIdentifier = TableIdentifier.parse("default.myTable");
+    Table table = catalog.createTable(tableIdentifier, SCHEMA);
+    int renamedFieldId = table.schema().findField("data").fieldId();
+    table.updateSchema().renameColumn("data", "legacy").commit();
+    table.updateSchema().addColumn("data", Types.StringType.get()).commit();
+    int currentFieldId = table.schema().findField("data").fieldId();
+    assertThat(currentFieldId).isNotEqualTo(renamedFieldId);
+
+    TableMetadataCache cache =
+        new TableMetadataCache(catalog, 10, Long.MAX_VALUE, 10, 
CASE_SENSITIVE, PRESERVE_COLUMNS);
+
+    Schema resolved = cache.schema(tableIdentifier, 
SCHEMA).resolvedTableSchema();
+
+    assertThat(resolved.findField("data").fieldId()).isEqualTo(currentFieldId);
+  }
+
+  @Test
+  void testSchemaPrefersExactMatchOnOlderSchemaOverConversionToCurrentSchema() 
{
+    Catalog catalog = CATALOG_EXTENSION.catalog();
+    TableIdentifier tableIdentifier = TableIdentifier.parse("default.myTable");
+    Table table = catalog.createTable(tableIdentifier, SCHEMA);
+    Schema oldShape = table.schema();
+    table.updateSchema().updateColumn("id", Types.LongType.get()).commit();
+    
assertThat(table.schema().findField("id").type()).isEqualTo(Types.LongType.get());
+
+    TableMetadataCache cache =
+        new TableMetadataCache(catalog, 10, Long.MAX_VALUE, 10, 
CASE_SENSITIVE, PRESERVE_COLUMNS);
+
+    Schema resolved = cache.schema(tableIdentifier, 
oldShape).resolvedTableSchema();
+
+    
assertThat(resolved.findField("id").type()).isEqualTo(Types.IntegerType.get());
+  }
+
+  @Test
+  void 
testSchemaFallsBackToHistoricalSchemaWhenReAddedColumnTypeIsIncompatible() {
+    Catalog catalog = CATALOG_EXTENSION.catalog();
+    TableIdentifier tableIdentifier = TableIdentifier.parse("default.myTable");
+    Table table = catalog.createTable(tableIdentifier, SCHEMA);
+    table.updateSchema().addColumn("myfield", Types.StringType.get()).commit();
+    Schema oldShape = table.schema();
+    int retiredFieldId = oldShape.findField("myfield").fieldId();
+    table.updateSchema().deleteColumn("myfield").commit();
+    table.updateSchema().addColumn("myfield", Types.DoubleType.get()).commit();
+    
assertThat(table.schema().findField("myfield").fieldId()).isNotEqualTo(retiredFieldId);
+
+    TableMetadataCache cache =
+        new TableMetadataCache(catalog, 10, Long.MAX_VALUE, 10, 
CASE_SENSITIVE, PRESERVE_COLUMNS);
+
+    Schema resolved = cache.schema(tableIdentifier, 
oldShape).resolvedTableSchema();
+
+    
assertThat(resolved.findField("myfield").fieldId()).isEqualTo(retiredFieldId);
+    
assertThat(resolved.findField("myfield").type()).isEqualTo(Types.StringType.get());
+  }
+
+  @Test
+  void testSchemaMatchingOfReusedFieldNameHonorsCaseSensitivity() {
+    Catalog catalog = CATALOG_EXTENSION.catalog();
+    TableIdentifier tableIdentifier = TableIdentifier.parse("default.myTable");
+    Table table = catalog.createTable(tableIdentifier, SCHEMA);
+    int renamedFieldId = table.schema().findField("data").fieldId();
+    table.updateSchema().renameColumn("data", "legacy").commit();
+    table.updateSchema().addColumn("Data", Types.StringType.get()).commit();
+    int currentFieldId = table.schema().findField("Data").fieldId();
+    assertThat(currentFieldId).isNotEqualTo(renamedFieldId);
+
+    TableMetadataCache caseInsensitive =
+        new TableMetadataCache(catalog, 10, Long.MAX_VALUE, 10, 
CASE_INSENSITIVE, PRESERVE_COLUMNS);
+    Schema resolved = caseInsensitive.schema(tableIdentifier, 
SCHEMA).resolvedTableSchema();
+    
assertThat(resolved.caseInsensitiveFindField("data").fieldId()).isEqualTo(currentFieldId);
+
+    TableMetadataCache caseSensitive =
+        new TableMetadataCache(catalog, 10, Long.MAX_VALUE, 10, 
CASE_SENSITIVE, PRESERVE_COLUMNS);
+    resolved = caseSensitive.schema(tableIdentifier, 
SCHEMA).resolvedTableSchema();
+    assertThat(resolved.findField("data").fieldId()).isEqualTo(renamedFieldId);
+  }
 }

Reply via email to