diff --git a/pyiceberg/types.py b/pyiceberg/types.py index 3c98215366..8c33b1aa21 100644 --- a/pyiceberg/types.py +++ b/pyiceberg/types.py @@ -324,6 +324,9 @@ class DecimalType(PrimitiveType): root: tuple[int, int] def __init__(self, precision: int, scale: int) -> None: + if precision < 1 or precision > 38: + raise ValidationError(f"Decimal precision must be between 1 and 38: {precision}") + super().__init__(root=(precision, scale)) @model_serializer diff --git a/tests/test_schema.py b/tests/test_schema.py index 93ddc16202..aacdbc7d5e 100644 --- a/tests/test_schema.py +++ b/tests/test_schema.py @@ -67,7 +67,7 @@ FloatType(), DoubleType(), DecimalType(10, 2), - DecimalType(100, 2), + DecimalType(38, 2), StringType(), DateType(), TimeType(), diff --git a/tests/test_types.py b/tests/test_types.py index 5e95687ba2..375fb9cdb6 100644 --- a/tests/test_types.py +++ b/tests/test_types.py @@ -920,3 +920,18 @@ def test_nested_field_geography_with_params_as_string() -> None: assert isinstance(field.field_type, GeographyType) assert field.field_type.crs == "EPSG:4326" assert field.field_type.algorithm == "planar" + + +def test_decimal_precision_validation() -> None: + """Test that DecimalType rejects precision outside the [1, 38] range.""" + decimal_type = DecimalType(38, 2) + assert decimal_type.precision == 38 + + with pytest.raises(ValidationError, match="Decimal precision must be between 1 and 38"): + DecimalType(39, 2) + + with pytest.raises(ValidationError, match="Decimal precision must be between 1 and 38"): + DecimalType(0, 2) + + with pytest.raises(ValidationError, match="Decimal precision must be between 1 and 38"): + DecimalType(-5, 2)