|
30 | 30 | Summary, |
31 | 31 | ancestors_between, |
32 | 32 | ancestors_of, |
| 33 | + latest_ancestor_before_timestamp, |
33 | 34 | update_snapshot_summaries, |
34 | 35 | ) |
35 | 36 | from pyiceberg.transforms import IdentityTransform |
@@ -456,3 +457,79 @@ def test_ancestors_between(table_v2_with_extensive_snapshots: Table) -> None: |
456 | 457 | ) |
457 | 458 | == 2000 |
458 | 459 | ) |
| 460 | + |
| 461 | + |
| 462 | +def test_latest_ancestor_before_timestamp() -> None: |
| 463 | + from pyiceberg.table.metadata import TableMetadataV2 |
| 464 | + |
| 465 | + # Create metadata with 4 snapshots at ordered timestamps |
| 466 | + metadata = TableMetadataV2( |
| 467 | + **{ |
| 468 | + "format-version": 2, |
| 469 | + "table-uuid": "9c12d441-03fe-4693-9a96-a0705ddf69c1", |
| 470 | + "location": "s3://bucket/test/location", |
| 471 | + "last-sequence-number": 4, |
| 472 | + "last-updated-ms": 1602638573590, |
| 473 | + "last-column-id": 1, |
| 474 | + "current-schema-id": 0, |
| 475 | + "schemas": [{"type": "struct", "schema-id": 0, "fields": [{"id": 1, "name": "x", "required": True, "type": "long"}]}], |
| 476 | + "default-spec-id": 0, |
| 477 | + "partition-specs": [{"spec-id": 0, "fields": []}], |
| 478 | + "last-partition-id": 999, |
| 479 | + "default-sort-order-id": 0, |
| 480 | + "sort-orders": [{"order-id": 0, "fields": []}], |
| 481 | + "current-snapshot-id": 4, |
| 482 | + "snapshots": [ |
| 483 | + { |
| 484 | + "snapshot-id": 1, |
| 485 | + "timestamp-ms": 1000, |
| 486 | + "sequence-number": 1, |
| 487 | + "summary": {"operation": "append"}, |
| 488 | + "manifest-list": "s3://a/1.avro", |
| 489 | + }, |
| 490 | + { |
| 491 | + "snapshot-id": 2, |
| 492 | + "parent-snapshot-id": 1, |
| 493 | + "timestamp-ms": 2000, |
| 494 | + "sequence-number": 2, |
| 495 | + "summary": {"operation": "append"}, |
| 496 | + "manifest-list": "s3://a/2.avro", |
| 497 | + }, |
| 498 | + { |
| 499 | + "snapshot-id": 3, |
| 500 | + "parent-snapshot-id": 2, |
| 501 | + "timestamp-ms": 3000, |
| 502 | + "sequence-number": 3, |
| 503 | + "summary": {"operation": "append"}, |
| 504 | + "manifest-list": "s3://a/3.avro", |
| 505 | + }, |
| 506 | + { |
| 507 | + "snapshot-id": 4, |
| 508 | + "parent-snapshot-id": 3, |
| 509 | + "timestamp-ms": 4000, |
| 510 | + "sequence-number": 4, |
| 511 | + "summary": {"operation": "append"}, |
| 512 | + "manifest-list": "s3://a/4.avro", |
| 513 | + }, |
| 514 | + ], |
| 515 | + } |
| 516 | + ) |
| 517 | + |
| 518 | + result = latest_ancestor_before_timestamp(metadata, 3500) |
| 519 | + assert result is not None |
| 520 | + assert result.snapshot_id == 3 |
| 521 | + |
| 522 | + result = latest_ancestor_before_timestamp(metadata, 2500) |
| 523 | + assert result is not None |
| 524 | + assert result.snapshot_id == 2 |
| 525 | + |
| 526 | + result = latest_ancestor_before_timestamp(metadata, 5000) |
| 527 | + assert result is not None |
| 528 | + assert result.snapshot_id == 4 |
| 529 | + |
| 530 | + result = latest_ancestor_before_timestamp(metadata, 3000) |
| 531 | + assert result is not None |
| 532 | + assert result.snapshot_id == 2 |
| 533 | + |
| 534 | + result = latest_ancestor_before_timestamp(metadata, 1000) |
| 535 | + assert result is None |
0 commit comments