diff --git a/pyiceberg/expressions/__init__.py b/pyiceberg/expressions/__init__.py index ece0db82db..16e3aab753 100644 --- a/pyiceberg/expressions/__init__.py +++ b/pyiceberg/expressions/__init__.py @@ -915,11 +915,15 @@ def bind(self, schema: Schema, case_sensitive: bool = True) -> BoundLiteralPredi return AlwaysTrue() elif isinstance(self, (GreaterThan, GreaterThanOrEqual, EqualTo)): return AlwaysFalse() + else: + raise ValueError(f"Cannot bind {type(self).__name__} with AboveMax literal") elif isinstance(lit, BelowMin): if isinstance(self, (GreaterThan, GreaterThanOrEqual, NotEqualTo)): return AlwaysTrue() elif isinstance(self, (LessThan, LessThanOrEqual, EqualTo)): return AlwaysFalse() + else: + raise ValueError(f"Cannot bind {type(self).__name__} with BelowMin literal") return self.as_bound(bound_term, lit) # type: ignore diff --git a/tests/expressions/test_expressions.py b/tests/expressions/test_expressions.py index 8ce48a6897..5a33db254c 100644 --- a/tests/expressions/test_expressions.py +++ b/tests/expressions/test_expressions.py @@ -295,6 +295,20 @@ def test_empty_bind_not_in(table_schema_simple: Schema) -> None: assert bound == AlwaysTrue() +@pytest.mark.parametrize( + "expression, match", + [ + (StartsWith("bar", "2147483648"), "AboveMax"), + (NotStartsWith("bar", "2147483648"), "AboveMax"), + (StartsWith("bar", "-2147483649"), "BelowMin"), + (NotStartsWith("bar", "-2147483649"), "BelowMin"), + ], +) +def test_bind_starts_with_out_of_range_literal(table_schema_simple: Schema, expression: BooleanExpression, match: str) -> None: + with pytest.raises(ValueError, match=match): + expression.bind(table_schema_simple) + + def test_bind_not_in_equal_term(table_schema_simple: Schema) -> None: bound = BoundNotIn( BoundReference(table_schema_simple.find_field(1), table_schema_simple.accessor_for_field(1)), {literal("hello")}