gaborkaszab commented on code in PR #18073:
URL: https://github.com/apache/iceberg/pull/18073#discussion_r4442445933


##########
core/src/main/java/org/apache/iceberg/SnapshotProducer.java:
##########
@@ -685,7 +691,10 @@ protected ManifestReader<DeleteFile> 
newDeleteManifestReader(ManifestFile manife
   protected long snapshotId() {
     if (snapshotId == null) {
       synchronized (this) {
-        while (snapshotId == null || ops.current().snapshot(snapshotId) != 
null) {
+        // only check ids that are already loaded: with lazily loaded 
snapshots, a collision with

Review Comment:
   I believe this code is needed because a `snapshot(id)` call would load the 
missing snapshots. The contract for `SnapshotProducer.snapshotId()` function is 
to get a snapshot Id that doesn't collide with any of the current snapshots. 
The current change breaks this and puts responsibility to other parts of the 
code.
   Maybe even in REFS mode keep a set of taken snapshot IDs in `TableMetadata`? 
We'd still need another API through `TableMetadata` to query if the ID is 
taken, instead of calling `snapshot(id)`, but we'd keep the contract of this 
function intact.



##########
core/src/main/java/org/apache/iceberg/rest/RESTTableOperations.java:
##########
@@ -286,17 +312,48 @@ private static Long 
expectedSnapshotIdIfSnapshotAddOnly(List<MetadataUpdate> upd
   }
 
   private TableMetadata updateCurrentMetadata(LoadTableResponse response) {
+    return updateCurrentMetadata(response, false);
+  }
+
+  private TableMetadata updateCurrentMetadata(
+      LoadTableResponse response, boolean reinstallSnapshotsSupplier) {
     // LoadTableResponse is used to deserialize the response, but config is 
not allowed by the REST
     // spec so it can be
     // safely ignored. there is no requirement to update config on refresh or 
commit.
     if (current == null
         || !Objects.equals(current.metadataFileLocation(), 
response.metadataLocation())) {
-      this.current = checkUUID(current, response.tableMetadata());
+      TableMetadata refreshed = checkUUID(current, response.tableMetadata());
+      if (reinstallSnapshotsSupplier) {

Review Comment:
   This seems redundant code with the same in `RESTSessionCatalog`. Change one 
has the risk of forgetting to change the other. Would be nice to have a unified 
way to add snapshot supplier to the table metadata. Maybe using a utility class 
that can do that for us?



##########
core/src/main/java/org/apache/iceberg/TableMetadata.java:
##########
@@ -1000,18 +1034,27 @@ private Builder(TableMetadata base) {
       this.sortOrders = Lists.newArrayList(base.sortOrders);
       this.properties = Maps.newHashMap(base.properties);
       this.currentSnapshotId = base.currentSnapshotId;
-      this.snapshots = Lists.newArrayList(base.snapshots());
+
+      // copy the snapshot state as-is: when base loads snapshots lazily, 
carry the supplier over

Review Comment:
   If I don't get this wrong, the motivation of this part of the change is that 
we want to avoid doing a full snapshot load when creating a new `TableMetadata` 
from a base. I think that the PR is solving multiple problems, one is this and 
the other is the REST ops related part. You might want to consider splitting 
the PR by that boundary.



##########
core/src/main/java/org/apache/iceberg/TableMetadata.java:
##########
@@ -548,6 +559,19 @@ private synchronized void ensureSnapshotsLoaded() {
       List<Snapshot> loadedSnapshots = 
Lists.newArrayList(snapshotsSupplier.get());
       loadedSnapshots.removeIf(s -> s.sequenceNumber() > lastSequenceNumber);
 
+      // retain snapshots that were added to this metadata but are unknown to 
the supplier, such

Review Comment:
   Not sure I follow why the below change is needed. Is this because previously 
when we added a new snapshot we also did a full snapshot load and we put the 
new snapshot on top? Do I get it right that previously when we had a 
`MetadataUpdate.AddSnapshot` in `changes` we didn't reach this code because 
`snapshotsLoaded` was true, and this changes now?
   
   I feel that this part of the PR is not really intuitive and prone to 
confusion.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to