This is an automated email from the ASF dual-hosted git repository.
github-merge-queue[bot] pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/iceberg-python.git
The following commit(s) were added to refs/heads/main by this push:
new 59b7c1c6e Validate snapshot sequence numbers on v3 tables (#4125)
59b7c1c6e is described below
commit 59b7c1c6ef93c839bceff3e8a1739341b6586e47
Author: Bishop Kammeraad <[email protected]>
AuthorDate: Sat Oct 24 22:43:10 2026 +0000
Validate snapshot sequence numbers on v3 tables (#4125)
* fix(table): validate snapshot sequence numbers on v3 tables
The check that rejects a snapshot whose sequence number is not greater
than the table's last sequence number only ran for format version 2.
Java applies it to every format version after 1.
* test: derive expected sequence number from the fixture
The stale sequence-number test built the snapshot from the fixture's
last_sequence_number but hardcoded 34 in the expected error message.
Co-authored-by: Copilot App <[email protected]>
---------
Co-authored-by: Kevin Liu <[email protected]>
Co-authored-by: Copilot App <[email protected]>
---
pyiceberg/table/update/__init__.py | 2 +-
tests/table/test_init.py | 24 ++++++++++++++++++++++++
2 files changed, 25 insertions(+), 1 deletion(-)
diff --git a/pyiceberg/table/update/__init__.py
b/pyiceberg/table/update/__init__.py
index aaa4a51b7..aa1a09ebb 100644
--- a/pyiceberg/table/update/__init__.py
+++ b/pyiceberg/table/update/__init__.py
@@ -453,7 +453,7 @@ def _(update: AddSnapshotUpdate, base_metadata:
TableMetadata, context: _TableMe
elif base_metadata.snapshot_by_id(update.snapshot.snapshot_id) is not None:
raise ValueError(f"Snapshot with id {update.snapshot.snapshot_id}
already exists")
elif (
- base_metadata.format_version == 2
+ base_metadata.format_version >= 2
and update.snapshot.sequence_number is not None
and update.snapshot.sequence_number <=
base_metadata.last_sequence_number
and update.snapshot.parent_snapshot_id is not None
diff --git a/tests/table/test_init.py b/tests/table/test_init.py
index 20acc870a..f6b984f1a 100644
--- a/tests/table/test_init.py
+++ b/tests/table/test_init.py
@@ -2084,6 +2084,30 @@ def
test_add_snapshot_update_fails_with_smaller_first_row_id(table_v3: Table) ->
update_table_metadata(table_v3.metadata,
(AddSnapshotUpdate(snapshot=new_snapshot),))
[email protected]("table", [lf("table_v2"), lf("table_v3")])
+def test_add_snapshot_update_fails_with_stale_sequence_number(table: Table) ->
None:
+ last_sequence_number = table.metadata.last_sequence_number
+ new_snapshot = Snapshot(
+ snapshot_id=25,
+ parent_snapshot_id=3055729675574597004,
+ sequence_number=last_sequence_number,
+ timestamp_ms=1602638593590,
+ manifest_list="s3:/a/b/c.avro",
+ summary=Summary(Operation.APPEND),
+ schema_id=1,
+ first_row_id=2,
+ )
+
+ with pytest.raises(
+ ValueError,
+ match=(
+ f"Cannot add snapshot with sequence number {last_sequence_number} "
+ f"older than last sequence number {last_sequence_number}"
+ ),
+ ):
+ update_table_metadata(table.metadata,
(AddSnapshotUpdate(snapshot=new_snapshot),))
+
+
def test_add_snapshot_update_updates_next_row_id(table_v3: Table) -> None:
new_snapshot = Snapshot(
snapshot_id=25,