diff --git a/pyiceberg/expressions/literals.py b/pyiceberg/expressions/literals.py index b502b43539..65569fc6f0 100644 --- a/pyiceberg/expressions/literals.py +++ b/pyiceberg/expressions/literals.py @@ -595,7 +595,7 @@ def _(self, type_var: IntegerType) -> Literal[int]: return IntAboveMax() elif IntegerType.min > number: return IntBelowMin() - return LongLiteral(int(number)) + return LongLiteral(_to_integral(number, type_var)) except (ArithmeticError, OverflowError, ValueError) as e: raise ValueError(f"Could not convert {self.value} into a {type_var}") from e @@ -608,7 +608,7 @@ def _(self, type_var: LongType) -> Literal[int]: elif LongType.min > long_value: return LongBelowMin() else: - return LongLiteral(int(long_value)) + return LongLiteral(_to_integral(long_value, type_var)) except (ArithmeticError, OverflowError, TypeError, ValueError) as e: raise ValueError(f"Could not convert {self.value} into a {type_var}") from e diff --git a/tests/expressions/test_literals.py b/tests/expressions/test_literals.py index 9c4252e57d..506dc69d89 100644 --- a/tests/expressions/test_literals.py +++ b/tests/expressions/test_literals.py @@ -325,9 +325,6 @@ def test_string_literal() -> None: pi_string_lit = StringLiteral("3.141") pi_double_lit = literal(3.141).to(DoubleType()) - assert literal("3.141").to(IntegerType()) == literal(3) - assert literal("3.141").to(LongType()) == literal(3) - assert sqrt2 != pi assert pi != pi_double_lit assert pi == pi_string_lit @@ -946,6 +943,14 @@ def test_fractional_decimal_to_integral_type_raises() -> None: _ = DecimalLiteral(Decimal(value)).to(target_type) +def test_fractional_string_to_integral_type_raises() -> None: + # Rounding would change the predicate, e.g. x < "2.6" would become x < 2 and drop x = 2 + for target_type in [IntegerType(), LongType()]: + for value in ["2.5", "2.6", "-2.5", "0.1"]: + with pytest.raises(ValueError, match=f"Could not convert {value} into a {target_type}"): + _ = literal(value).to(target_type) + + def test_integral_decimal_to_integral_type() -> None: # A decimal literal without a fractional part, such as 2.0, still converts exactly for target_type in [IntegerType(), LongType()]: