Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions pyiceberg/conversions.py
Original file line number Diff line number Diff line change
Expand Up @@ -310,9 +310,11 @@ def _(primitive_type: DecimalType, value: Decimal) -> bytes:
bytes: The byte representation of `value`.
"""
_, digits, exponent = value.as_tuple()
exponent = abs(int(exponent))
if exponent != primitive_type.scale:
raise ValueError(f"Cannot serialize value, scale of value does not match type {primitive_type}: {exponent}")
# A Decimal carries the negated scale as its exponent, so a value with a negative
# scale (1E+2) must not be read as if it had the matching positive one
value_scale = -int(exponent)
if value_scale != primitive_type.scale:
raise ValueError(f"Cannot serialize value, scale of value does not match type {primitive_type}: {value_scale}")
elif len(digits) > primitive_type.precision:
raise ValueError(
f"Cannot serialize value, precision of value is greater than precision of type {primitive_type}: {len(digits)}"
Expand Down
7 changes: 7 additions & 0 deletions tests/test_conversions.py
Original file line number Diff line number Diff line change
Expand Up @@ -510,6 +510,13 @@ def __repr__(self) -> str:
"primitive_type, value, expected_error_message",
[
(DecimalType(7, 3), Decimal("123.4567"), "Cannot serialize value, scale of value does not match type decimal(7, 3): 4"),
# A Decimal with a negative scale must not pass as its positive counterpart
(DecimalType(10, 2), Decimal("1E+2"), "Cannot serialize value, scale of value does not match type decimal(10, 2): -2"),
(
DecimalType(10, 2),
Decimal("100").normalize(),
"Cannot serialize value, scale of value does not match type decimal(10, 2): -2",
),
(
DecimalType(18, 8),
Decimal("123456789.123456789"),
Expand Down
Loading