Skip to content

Conversation

@SamWheating
Copy link

Closes: #14953 - see this issue for a larger description and reproduction.

Its assumed that wap.id will be unique among snapshots, but this doesn't appear to be enforced anywhere which can lead to unexpected results when only the first write is actually published.

This PR updates the publish_changes procedure to fail when multiple matching snapshots are identified.

If this change is approved I will backport it to the other spark versions.

@SamWheating SamWheating force-pushed the sw-fail-publish-changes-on-duplicate-wap-id branch from 0699a5f to 7ed4b84 Compare January 2, 2026 22:27
@github-actions github-actions bot added the spark label Jan 2, 2026
@SamWheating SamWheating changed the title Fail publish_changes procedure if there's more than one matching snapshot Spark: Fail publish_changes procedure if there's more than one matching snapshot Jan 2, 2026
Comment on lines +116 to +117
throw new ValidationException(
"Cannot apply non-unique WAP ID. Found %d snapshots with WAP ID '%s'",
numMatchingSnapshots, wapId);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we should not allow this situation like 2 snapshots with same wap id to happen in the first place, during the snapshot creating time ?

Copy link
Author

@SamWheating SamWheating Jan 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't have a strong opinion here, but this might be considered a more significant / potentially breaking change? Technically having a duplicate WAP ID doesn't cause any problems until they are cherry-picked into main.

Do you think there might be legitimate uses for staging multiple changes under the same WAP ID? For example:

  • staging multiple changes, evaluating all of them separately and then deleting all but one before committing.
  • creating staged snapshots which are never intended to be published (for testing / evaluation / etc)

I am not super familiar with the original designs behind WAP in iceberg, I'll look through older commits to see if there's any mention of a uniqueness constraint.

Comment on lines +100 to +101
Iterable<Snapshot> wapSnapshots =
Iterables.filter(
table.snapshots(), snapshot -> wapId.equals(WapUtil.stagedWapId(snapshot)));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how about a case where a wap id is reused ? but at a given there is only staged wap-id ? prev snapshot with that wap id was published ?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will still fail with a DuplicateWAPCommitException during the cherry pick operation, originating from here:

/**
* Check if a given staged snapshot's associated wap-id was already published. Does not fail for
* non-WAP workflows.
*
* @param current the current {@link TableMetadata metadata} for the target table
* @param wapSnapshotId a snapshot id which could have been staged and is associated with a wap id
* @return the WAP ID that will be published, if the snapshot has one
*/
public static String validateWapPublish(TableMetadata current, long wapSnapshotId) {
Snapshot cherryPickSnapshot = current.snapshot(wapSnapshotId);
String wapId = stagedWapId(cherryPickSnapshot);
if (wapId != null && !wapId.isEmpty()) {
if (WapUtil.isWapIdPublished(current, wapId)) {
throw new DuplicateWAPCommitException(wapId);
}
}
return wapId;
}

@SamWheating SamWheating force-pushed the sw-fail-publish-changes-on-duplicate-wap-id branch from 7ed4b84 to df314e9 Compare January 3, 2026 00:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

publish_changes spark procedure only cherry-picks a single snapshot when there are multiple with the same wap.id

2 participants