diff --git a/core/src/main/java/org/apache/iceberg/view/ViewMetadata.java b/core/src/main/java/org/apache/iceberg/view/ViewMetadata.java index 68619ddb2292..433a48f889eb 100644 --- a/core/src/main/java/org/apache/iceberg/view/ViewMetadata.java +++ b/core/src/main/java/org/apache/iceberg/view/ViewMetadata.java @@ -321,17 +321,23 @@ private int reuseOrCreateNewViewVersionId(ViewVersion viewVersion) { /** * Checks whether the given view versions would behave the same while ignoring the view version - * id, the creation timestamp, and the summary. + * id, the creation timestamp, and the operation. * * @param one the view version to compare * @param two the view version to compare * @return true if the given view versions would behave the same */ private boolean sameViewVersion(ViewVersion one, ViewVersion two) { + // ignore the "operation" contained in the summary for the comparison + Map summaryOne = Maps.newHashMap(one.summary()); + Map summaryTwo = Maps.newHashMap(two.summary()); + summaryOne.remove("operation"); + summaryTwo.remove("operation"); return Objects.equals(one.representations(), two.representations()) && Objects.equals(one.defaultCatalog(), two.defaultCatalog()) && Objects.equals(one.defaultNamespace(), two.defaultNamespace()) - && one.schemaId() == two.schemaId(); + && one.schemaId() == two.schemaId() + && Objects.equals(summaryOne, summaryTwo); } public Builder addSchema(Schema schema) { diff --git a/core/src/test/java/org/apache/iceberg/view/TestViewMetadata.java b/core/src/test/java/org/apache/iceberg/view/TestViewMetadata.java index 7837d9405524..bf87b333a865 100644 --- a/core/src/test/java/org/apache/iceberg/view/TestViewMetadata.java +++ b/core/src/test/java/org/apache/iceberg/view/TestViewMetadata.java @@ -578,6 +578,46 @@ public void viewVersionDeduplication() { ImmutableViewVersion.builder().from(viewVersionThree).versionId(3).build()); } + @Test + public void viewVersionDeduplicationWithCustomSummary() { + // all view versions have the same ID + // additionally, there are duplicate view versions that only differ in the summary + ViewVersion viewVersionOne = newViewVersion(1, "select * from ns.tbl"); + ViewVersion viewVersionTwo = newViewVersion(1, "select count(*) from ns.tbl"); + ViewVersion viewVersionOneUpdated = + ImmutableViewVersion.builder() + .from(viewVersionTwo) + .summary(ImmutableMap.of("operation", "replace")) + .build(); + ViewVersion viewVersionTwoUpdated = + ImmutableViewVersion.builder() + .from(viewVersionTwo) + .summary(ImmutableMap.of("operation", "replace", "key", "val")) + .build(); + + ViewMetadata viewMetadata = + ViewMetadata.builder() + .setLocation("custom-location") + .addSchema(new Schema(Types.NestedField.required(1, "x", Types.LongType.get()))) + .addVersion(viewVersionOne) + .addVersion(viewVersionTwo) + .addVersion(viewVersionOneUpdated) + .addVersion(viewVersionTwoUpdated) + .setCurrentVersionId(3) + .build(); + + assertThat(viewMetadata.currentVersion()) + .isEqualTo(ImmutableViewVersion.builder().from(viewVersionTwoUpdated).versionId(3).build()); + + // IDs of the view versions should be re-assigned and view versions should be de-duplicated + assertThat(viewMetadata.versions()) + .hasSize(3) + .containsExactly( + viewVersionOne, + ImmutableViewVersion.builder().from(viewVersionTwo).versionId(2).build(), + ImmutableViewVersion.builder().from(viewVersionTwoUpdated).versionId(3).build()); + } + @Test public void schemaIDReassignment() { Schema schemaOne = new Schema(5, Types.NestedField.required(1, "x", Types.LongType.get()));