Skip to content

Commit c674fad

Browse files
committed
Reject conflicted source-id and source-ids fields
1 parent 1a87aa3 commit c674fad

4 files changed

Lines changed: 18 additions & 2 deletions

File tree

pyiceberg/partitioning.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,9 @@ def __init__(
109109
@classmethod
110110
def map_source_ids_onto_source_id(cls, data: Any) -> Any:
111111
if isinstance(data, dict):
112-
if "source-id" not in data and "source-ids" in data:
112+
if "source-ids" in data:
113+
if "source-id" in data:
114+
raise ValueError("source-id and source-ids are mutually exclusive")
113115
source_ids = data["source-ids"]
114116
if isinstance(source_ids, list):
115117
if len(source_ids) == 0:

pyiceberg/table/sorting.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,9 @@ def set_null_order(cls, values: dict[str, Any]) -> dict[str, Any]:
101101
@classmethod
102102
def map_source_ids_onto_source_id(cls, data: Any) -> Any:
103103
if isinstance(data, dict):
104-
if "source-id" not in data and "source-ids" in data:
104+
if "source-ids" in data:
105+
if "source-id" in data:
106+
raise ValueError("source-id and source-ids are mutually exclusive")
105107
source_ids = data["source-ids"]
106108
if isinstance(source_ids, list):
107109
if len(source_ids) == 0:

tests/table/test_partitioning.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,12 @@ def test_deserialize_partition_field_empty_source_ids_rejected() -> None:
273273
PartitionField.model_validate_json(json_partition_spec)
274274

275275

276+
def test_deserialize_partition_field_source_id_and_source_ids_rejected() -> None:
277+
json_partition_spec = """{"source-id": 5, "source-ids": [1, 2], "field-id": 1000, "transform": "bucket[4]", "name": "m"}"""
278+
with pytest.raises(Exception, match="source-id and source-ids are mutually exclusive"):
279+
PartitionField.model_validate_json(json_partition_spec)
280+
281+
276282
def test_incompatible_source_column_not_found() -> None:
277283
schema = Schema(NestedField(1, "foo", IntegerType()), NestedField(2, "bar", IntegerType()))
278284

tests/table/test_sorting.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,12 @@ def test_deserialize_sort_field_empty_source_ids_rejected() -> None:
144144
SortField.model_validate_json(payload)
145145

146146

147+
def test_deserialize_sort_field_source_id_and_source_ids_rejected() -> None:
148+
payload = '{"source-id":5,"source-ids":[19,20],"transform":"bucket[4]","direction":"asc","null-order":"nulls-first"}'
149+
with pytest.raises(Exception, match="source-id and source-ids are mutually exclusive"):
150+
SortField.model_validate_json(payload)
151+
152+
147153
def test_incompatible_source_column_not_found(sort_order: SortOrder) -> None:
148154
schema = Schema(NestedField(1, "foo", IntegerType()), NestedField(2, "bar", IntegerType()))
149155

0 commit comments

Comments
 (0)