Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions core/src/main/java/org/apache/iceberg/TableMetadata.java
Original file line number Diff line number Diff line change
Expand Up @@ -1327,6 +1327,10 @@ public Builder setRef(String name, SnapshotRef ref) {
Snapshot snapshot = snapshotsById.get(snapshotId);
ValidationException.check(
snapshot != null, "Cannot set %s to unknown snapshot: %s", name, snapshotId);
ValidationException.check(
!SnapshotRef.MAIN_BRANCH.equals(name) || ref.isBranch(),
"Cannot set %s to a tag, it must be a branch",
SnapshotRef.MAIN_BRANCH);

if (SnapshotRef.MAIN_BRANCH.equals(name)) {
this.currentSnapshotId = ref.snapshotId();
Expand Down
19 changes: 19 additions & 0 deletions core/src/test/java/org/apache/iceberg/TestSnapshotManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,25 @@ public void testCreateTagFailsWhenRefAlreadyExists() {
.hasMessage("Ref tag2 already exists");
}

@TestTemplate
public void testCreateTagNamedMainFails() {
// stage a snapshot so that the table has a snapshot but no main branch ref yet
table.newAppend().appendFile(FILE_A).stageOnly().commit();
Snapshot stagedSnapshot = Iterables.getOnlyElement(table.snapshots());

assertThatThrownBy(
() ->
table
.manageSnapshots()
.createTag(SnapshotRef.MAIN_BRANCH, stagedSnapshot.snapshotId())
.commit())
.isInstanceOf(ValidationException.class)
.hasMessage("Cannot set main to a tag, it must be a branch");

// the failed commit must not have created the main ref
assertThat(table.ops().refresh().ref(SnapshotRef.MAIN_BRANCH)).isNull();
}

@TestTemplate
public void testRemoveBranch() {
table.newAppend().appendFile(FILE_A).commit();
Expand Down
38 changes: 38 additions & 0 deletions core/src/test/java/org/apache/iceberg/TestTableMetadata.java
Original file line number Diff line number Diff line change
Expand Up @@ -2148,4 +2148,42 @@ public void testAddSnapshotWithStaleFirstRowIdIsRetryable() {
.isInstanceOf(RetryableValidationException.class)
.hasMessageContaining("Cannot add a snapshot, first-row-id is behind table next-row-id");
}

@Test
public void testSetRefRejectsTagForMainBranch() {
TableMetadata base =
TableMetadata.newTableMetadata(
TEST_SCHEMA, PartitionSpec.unpartitioned(), "location", ImmutableMap.of());

Snapshot snapshot =
new BaseSnapshot(
1,
1L,
null,
System.currentTimeMillis(),
null,
null,
null,
"file:/s1.avro",
null,
null,
null);
TableMetadata withSnapshot = TableMetadata.buildFrom(base).addSnapshot(snapshot).build();

assertThatThrownBy(
() ->
TableMetadata.buildFrom(withSnapshot)
.setRef(
SnapshotRef.MAIN_BRANCH,
SnapshotRef.tagBuilder(snapshot.snapshotId()).build()))
.isInstanceOf(ValidationException.class)
.hasMessage("Cannot set main to a tag, it must be a branch");

// any other ref name can still be a tag
TableMetadata withTag =
TableMetadata.buildFrom(withSnapshot)
.setRef("tag1", SnapshotRef.tagBuilder(snapshot.snapshotId()).build())
.build();
assertThat(withTag.ref("tag1").isTag()).isTrue();
}
}