Skip to content

Commit 01fe380

Browse files
authored
Core: Ensure reactivated view version uses correct timestamp (#12821)
1 parent ee70a53 commit 01fe380

File tree

3 files changed

+80
-4
lines changed

3 files changed

+80
-4
lines changed

core/src/main/java/org/apache/iceberg/view/ViewMetadata.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -249,9 +249,17 @@ public Builder setCurrentVersionId(int newVersionId) {
249249
changes.add(new MetadataUpdate.SetCurrentViewVersion(newVersionId));
250250
}
251251

252+
// Use the timestamp from the view version if it was added in current set of changes.
253+
// Otherwise, use the current system time. This handles cases where the view version
254+
// was set as current in the past and is being re-activated.
255+
boolean versionAddedInThisChange =
256+
changes(MetadataUpdate.AddViewVersion.class)
257+
.anyMatch(added -> added.viewVersion().versionId() == newVersionId);
258+
252259
this.historyEntry =
253260
ImmutableViewHistoryEntry.builder()
254-
.timestampMillis(version.timestampMillis())
261+
.timestampMillis(
262+
versionAddedInThisChange ? version.timestampMillis() : System.currentTimeMillis())
255263
.versionId(version.versionId())
256264
.build();
257265

core/src/test/java/org/apache/iceberg/view/TestViewMetadata.java

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,13 @@ private ViewVersion newViewVersion(int id, String sql) {
4242
}
4343

4444
private ViewVersion newViewVersion(int id, int schemaId, String sql) {
45+
return newViewVersion(id, schemaId, System.currentTimeMillis(), sql);
46+
}
47+
48+
private ViewVersion newViewVersion(int id, int schemaId, long timestampMillis, String sql) {
4549
return ImmutableViewVersion.builder()
4650
.versionId(id)
47-
.timestampMillis(System.currentTimeMillis())
51+
.timestampMillis(timestampMillis)
4852
.defaultCatalog("prod")
4953
.defaultNamespace(Namespace.of("default"))
5054
.putSummary("user", "some-user")
@@ -396,6 +400,70 @@ public void viewVersionHistoryIsCorrectlyRetained() {
396400
.hasMessage("Cannot set current version to unknown version: 1");
397401
}
398402

403+
@Test
404+
public void versionHistoryEntryMaintainCorrectTimeline() {
405+
ViewVersion viewVersionOne = newViewVersion(1, 0, 1000, "select * from ns.tbl");
406+
ViewVersion viewVersionTwo = newViewVersion(2, 0, 2000, "select count(*) from ns.tbl");
407+
ViewVersion viewVersionThree =
408+
newViewVersion(3, 0, 3000, "select count(*) as count from ns.tbl");
409+
410+
ViewMetadata viewMetadata =
411+
ViewMetadata.builder()
412+
.setLocation("location")
413+
.addSchema(new Schema(Types.NestedField.required(1, "x", Types.LongType.get())))
414+
.addVersion(viewVersionOne)
415+
.addVersion(viewVersionTwo)
416+
.setCurrentVersionId(1)
417+
.build();
418+
419+
// setting an existing view version as the new current should update the timestamp in the
420+
// history
421+
ViewMetadata updated = ViewMetadata.buildFrom(viewMetadata).setCurrentVersionId(2).build();
422+
423+
List<ViewHistoryEntry> history = updated.history();
424+
assertThat(history)
425+
.hasSize(2)
426+
.element(0)
427+
.isEqualTo(ImmutableViewHistoryEntry.builder().versionId(1).timestampMillis(1000).build());
428+
assertThat(history)
429+
.element(1)
430+
.satisfies(
431+
v -> {
432+
assertThat(v.versionId()).isEqualTo(2);
433+
assertThat(v.timestampMillis())
434+
.isGreaterThan(3000)
435+
.isLessThanOrEqualTo(System.currentTimeMillis());
436+
});
437+
438+
// adding a new view version and setting it as current should use the view version's timestamp
439+
// in the history (which has been set to a fixed value for testing)
440+
updated =
441+
ViewMetadata.buildFrom(updated).addVersion(viewVersionThree).setCurrentVersionId(3).build();
442+
List<ViewHistoryEntry> historyTwo = updated.history();
443+
assertThat(historyTwo)
444+
.hasSize(3)
445+
.containsAll(history)
446+
.element(2)
447+
.isEqualTo(ImmutableViewHistoryEntry.builder().versionId(3).timestampMillis(3000).build());
448+
449+
// setting an older view version as the new current (aka doing a rollback) should update the
450+
// timestamp in the history
451+
ViewMetadata reactiveOldViewVersion =
452+
ViewMetadata.buildFrom(updated).setCurrentVersionId(1).build();
453+
List<ViewHistoryEntry> historyThree = reactiveOldViewVersion.history();
454+
assertThat(historyThree)
455+
.hasSize(4)
456+
.containsAll(historyTwo)
457+
.element(3)
458+
.satisfies(
459+
v -> {
460+
assertThat(v.versionId()).isEqualTo(1);
461+
assertThat(v.timestampMillis())
462+
.isGreaterThan(3000)
463+
.isLessThanOrEqualTo(System.currentTimeMillis());
464+
});
465+
}
466+
399467
@Test
400468
public void versionsAddedInCurrentBuildAreRetained() {
401469
ViewVersion v1 = newViewVersion(1, "select 1 as count");

core/src/test/java/org/apache/iceberg/view/TestViewMetadataParser.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,14 +106,14 @@ public void readAndWriteValidViewMetadata() throws Exception {
106106
.assignUUID("fa6506c3-7681-40c8-86dc-e36561f83385")
107107
.addSchema(TEST_SCHEMA)
108108
.addVersion(version1)
109-
.addVersion(version2)
110109
.setLocation("s3://bucket/test/location")
111110
.setProperties(
112111
ImmutableMap.of(
113112
"some-key", "some-value", ViewProperties.COMMENT, "some-comment"))
114113
.setCurrentVersionId(1)
115114
.upgradeFormatVersion(1)
116115
.build())
116+
.addVersion(version2)
117117
.setCurrentVersionId(2)
118118
.build();
119119

@@ -222,7 +222,6 @@ public void viewMetadataWithMetadataLocation() throws Exception {
222222
.assignUUID("fa6506c3-7681-40c8-86dc-e36561f83385")
223223
.addSchema(TEST_SCHEMA)
224224
.addVersion(version1)
225-
.addVersion(version2)
226225
.setLocation("s3://bucket/test/location")
227226
.setProperties(
228227
ImmutableMap.of(
@@ -233,6 +232,7 @@ public void viewMetadataWithMetadataLocation() throws Exception {
233232
.setCurrentVersionId(1)
234233
.upgradeFormatVersion(1)
235234
.build())
235+
.addVersion(version2)
236236
.setCurrentVersionId(2)
237237
.build())
238238
.setMetadataLocation(metadataLocation)

0 commit comments

Comments
 (0)