This is an automated email from the ASF dual-hosted git repository.

github-merge-queue[bot] pushed a commit to branch 
gh-readonly-queue/main/pr-4125-d37149c8b5d1b737da0eb9fdcb585bc3ef3bac69
in repository https://gitbox.apache.org/repos/asf/iceberg-python.git

commit c4cd028cac22249da4b24eca32de28cc7831492c
Author: Bishop Kammeraad <[email protected]>
AuthorDate: Thu Oct 22 18:52:45 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.
---
 pyiceberg/table/update/__init__.py |  2 +-
 tests/table/test_init.py           | 20 ++++++++++++++++++++
 2 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/pyiceberg/table/update/__init__.py 
b/pyiceberg/table/update/__init__.py
index 64838b0bd..c93916327 100644
--- a/pyiceberg/table/update/__init__.py
+++ b/pyiceberg/table/update/__init__.py
@@ -435,7 +435,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 3d160781e..1c0904714 100644
--- a/tests/table/test_init.py
+++ b/tests/table/test_init.py
@@ -1966,6 +1966,26 @@ 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:
+    new_snapshot = Snapshot(
+        snapshot_id=25,
+        parent_snapshot_id=3055729675574597004,
+        sequence_number=table.metadata.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="Cannot add snapshot with sequence number 34 older than last 
sequence number 34",
+    ):
+        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,

Reply via email to