leangjonathan commented on code in PR #10861:
URL: https://github.com/apache/iceberg/pull/10861#discussion_r1710087155
##########
core/src/main/java/org/apache/iceberg/TableMetadata.java:
##########
@@ -1004,24 +1004,28 @@ private Builder setInitialFormatVersion(int
newFormatVersion) {
return this;
}
- public Builder upgradeFormatVersion(int newFormatVersion) {
+ public Builder upgradeFormatVersion(int targetFormatVersion) {
Preconditions.checkArgument(
- newFormatVersion <= SUPPORTED_TABLE_FORMAT_VERSION,
+ targetFormatVersion <= SUPPORTED_TABLE_FORMAT_VERSION,
"Cannot upgrade table to unsupported format version: v%s (supported:
v%s)",
- newFormatVersion,
+ targetFormatVersion,
SUPPORTED_TABLE_FORMAT_VERSION);
Preconditions.checkArgument(
- newFormatVersion >= formatVersion,
+ targetFormatVersion >= formatVersion,
"Cannot downgrade v%s table to v%s",
formatVersion,
- newFormatVersion);
+ targetFormatVersion);
- if (newFormatVersion == formatVersion) {
+ if (targetFormatVersion == formatVersion) {
return this;
}
- this.formatVersion = newFormatVersion;
- changes.add(new MetadataUpdate.UpgradeFormatVersion(newFormatVersion));
+ // register incremental version changes separately to ensure all upgrade
requirements are met
+ for (int version = formatVersion + 1; version <= targetFormatVersion;
version++) {
+ changes.add(new MetadataUpdate.UpgradeFormatVersion(version));
Review Comment:
The problem we are solving involves how we maintain different upgrade paths.
This stepwise internal upgrade is for future proofing version requirements.
@amogh-jahagirdar @RussellSpitzer correct me if I'm wrong.
In the logic for upgrade requirements we currently have the following
pattern:
```
public static List<UpdateRequirement> forUpdateTable(
TableMetadata base, List<MetadataUpdate> metadataUpdates) {
Preconditions.checkArgument(null != base, "Invalid table metadata:
null");
Preconditions.checkArgument(null != metadataUpdates, "Invalid metadata
updates: null");
Builder builder = new Builder(base, false);
builder.require(new UpdateRequirement.AssertTableUUID(base.uuid()));
metadataUpdates.forEach(builder::update);
return builder.build();
}
```
Where `metadataUpdates.forEach(builder::update);` will register
UpdateRequirements based on the specific metadata update into a list for later
processing.
Using the 1, 2, 3 example...
Let's say that V2 required some field XYZ to be populated and we register
that as an `UpdateRequirement` subclass.
```
class AssertXYZPopulated implements UpdateRequirement {
...
}
```
And we also fill in the appropriate builder logic to link
`MetadataUpdate.UpgradeFormatVersion(2)` to `AssertXYZPopulated`
For V1->V2 upgrades the original logic worked since we would have a
`MetadataUpdate.UpgradeFormatVersion(2)` instance registered and can thus
enforce `AssertXYZPopulated`.
However, for V1->V3 upgrades, the original logic would have only had
`MetadataUpdate.UpgradeFormatVersion(3)` (which does not have the mapping to
`AssertXYZPopulated`) and we would fail to enforce the V2 upgrade requirements.
By adding the stepwise logic we are ensuring future upgrade requirements are
always enforced version by version.
--
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]