Skip to content

Commit feff7dd

Browse files
Test coverage: persisted props, list/map fresh ids, sort-order reuse
- Pin that 'format-version' is not in replaced.metadata.properties. - Add list/map element_id/key_id/value_id reuse coverage for assign_fresh_schema_ids_for_replace. - Extend sort-order reuse test to cover reusing a non-zero sorted order_id from history. - Drop the stale HEAD (view-exists) reference in test_replace_table_issues_commit_post_immediately.
1 parent 08c5b2d commit feff7dd

3 files changed

Lines changed: 51 additions & 5 deletions

File tree

tests/catalog/test_catalog_behaviors.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -520,21 +520,26 @@ def test_replace_table_reuses_partition_spec_id(catalog: Catalog, test_table_ide
520520

521521
def test_replace_table_with_sort_order_changes(catalog: Catalog, test_table_identifier: Identifier) -> None:
522522
"""Replace can change the sort order. The new sort order is appended to the history and
523-
becomes the default; a follow-up replace back to unsorted reuses the unsorted order_id
524-
rather than appending a duplicate."""
523+
becomes the default; a follow-up replace back to a sort already in history reuses its
524+
order_id rather than appending a duplicate."""
525525
_, schema = _create_simple_table(catalog, test_table_identifier)
526526
sort = SortOrder(SortField(source_id=1, transform=IdentityTransform(), direction=SortDirection.ASC))
527527

528528
# unsorted → sorted: a new order is added and becomes the default.
529529
sorted_table = catalog.replace_table(test_table_identifier, schema=schema, sort_order=sort)
530530
assert sorted_table.sort_order().fields == sort.fields
531-
assert sorted_table.metadata.default_sort_order_id != 0
531+
sorted_order_id = sorted_table.metadata.default_sort_order_id
532+
assert sorted_order_id != 0
532533

533534
# sorted → unsorted: reuses the unsorted order_id 0 from history.
534535
unsorted_table = catalog.replace_table(test_table_identifier, schema=schema)
535536
assert unsorted_table.sort_order().is_unsorted
536537
assert unsorted_table.metadata.default_sort_order_id == 0
537538

539+
# unsorted → original sorted form: reuses the existing sorted order_id from history.
540+
replayed = catalog.replace_table(test_table_identifier, schema=schema, sort_order=sort)
541+
assert replayed.metadata.default_sort_order_id == sorted_order_id
542+
538543

539544
def test_replace_table_inherits_existing_location(catalog: Catalog, test_table_identifier: Identifier) -> None:
540545
"""`location=None` keeps the existing table's location."""
@@ -574,6 +579,8 @@ def test_replace_table_upgrades_format_version(catalog: Catalog, test_table_iden
574579
assert catalog.load_table(test_table_identifier).format_version == 1
575580
replaced = catalog.replace_table(test_table_identifier, schema=schema, properties={"format-version": "2"})
576581
assert replaced.format_version == 2
582+
# `format-version` is a control input, not a regular property — must not leak into persisted properties.
583+
assert "format-version" not in replaced.properties
577584

578585

579586
def test_replace_table_rejects_format_version_downgrade(catalog: Catalog, test_table_identifier: Identifier) -> None:

tests/catalog/test_rest.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3017,8 +3017,8 @@ def test_replace_table_issues_commit_post_immediately(
30173017
NestedField(field_id=2, name="data", field_type=StringType(), required=False),
30183018
)
30193019

3020-
# Baseline: opening the transaction alone makes the HEAD (view-exists) + GET (load) calls
3021-
# but no POST until the caller commits.
3020+
# Baseline: opening the transaction alone makes only the load GET call; no POST is
3021+
# issued until the caller commits.
30223022
catalog.replace_table_transaction(identifier=("fokko", "fokko2"), schema=new_schema)
30233023
methods_after_open = [r.method for r in rest_mock.request_history]
30243024
assert "POST" not in methods_after_open

tests/test_schema.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1888,3 +1888,42 @@ def test_assign_fresh_schema_ids_for_replace_with_nested_struct() -> None:
18881888
assert loc_fields[1].field_id == 4 # location.lon reused
18891889
assert loc_fields[2].field_id == 5 # location.alt is new
18901890
assert last_col_id == 5
1891+
1892+
1893+
def test_assign_fresh_schema_ids_for_replace_with_list_and_map() -> None:
1894+
"""`element_id`, `key_id`, and `value_id` are reused by name path (e.g. `tags.element`, `m.key`, `m.value`)."""
1895+
base_schema = Schema(
1896+
NestedField(
1897+
field_id=1,
1898+
name="tags",
1899+
field_type=ListType(element_id=2, element_type=StringType(), element_required=False),
1900+
required=False,
1901+
),
1902+
NestedField(
1903+
field_id=3,
1904+
name="m",
1905+
field_type=MapType(key_id=4, key_type=StringType(), value_id=5, value_type=IntegerType(), value_required=False),
1906+
required=False,
1907+
),
1908+
)
1909+
new_schema = Schema(
1910+
NestedField(
1911+
field_id=10,
1912+
name="tags",
1913+
field_type=ListType(element_id=20, element_type=StringType(), element_required=False),
1914+
required=False,
1915+
),
1916+
NestedField(
1917+
field_id=30,
1918+
name="m",
1919+
field_type=MapType(key_id=40, key_type=StringType(), value_id=50, value_type=IntegerType(), value_required=False),
1920+
required=False,
1921+
),
1922+
)
1923+
fresh, last_col_id = assign_fresh_schema_ids_for_replace(new_schema, base_schema, 5)
1924+
assert fresh.fields[0].field_id == 1
1925+
assert fresh.fields[0].field_type.element_id == 2
1926+
assert fresh.fields[1].field_id == 3
1927+
assert fresh.fields[1].field_type.key_id == 4
1928+
assert fresh.fields[1].field_type.value_id == 5
1929+
assert last_col_id == 5

0 commit comments

Comments
 (0)