|
45 | 45 | StartsWith, |
46 | 46 | ) |
47 | 47 | from pyiceberg.expressions.visitors import ( |
| 48 | + IN_PREDICATE_LIMIT, |
48 | 49 | ROWS_CANNOT_MATCH, |
49 | 50 | ROWS_MIGHT_MATCH, |
50 | 51 | ROWS_MIGHT_NOT_MATCH, |
@@ -674,6 +675,47 @@ def test_integer_in(schema_data_file: Schema, data_file: DataFile) -> None: |
674 | 675 | assert should_read, "Should read: large in expression" |
675 | 676 |
|
676 | 677 |
|
| 678 | +def test_integer_in_above_limit(schema_data_file: Schema, data_file: DataFile) -> None: |
| 679 | + below_lower = set(range(INT_MIN_VALUE - IN_PREDICATE_LIMIT - 1, INT_MIN_VALUE)) |
| 680 | + should_read = _InclusiveMetricsEvaluator(schema_data_file, In("id", below_lower)).eval(data_file) |
| 681 | + assert not should_read, "Should not read: id below lower bound (max 29 < 30)" |
| 682 | + |
| 683 | + above_upper = set(range(INT_MAX_VALUE + 1, INT_MAX_VALUE + IN_PREDICATE_LIMIT + 2)) |
| 684 | + should_read = _InclusiveMetricsEvaluator(schema_data_file, In("id", above_upper)).eval(data_file) |
| 685 | + assert not should_read, "Should not read: id above upper bound (min 80 > 79)" |
| 686 | + |
| 687 | + equal_lower = set(range(INT_MIN_VALUE - IN_PREDICATE_LIMIT, INT_MIN_VALUE + 1)) |
| 688 | + should_read = _InclusiveMetricsEvaluator(schema_data_file, In("id", equal_lower)).eval(data_file) |
| 689 | + assert should_read, "Should read: id equal to lower bound (max 30 == 30)" |
| 690 | + |
| 691 | + equal_upper = set(range(INT_MAX_VALUE, INT_MAX_VALUE + IN_PREDICATE_LIMIT + 1)) |
| 692 | + should_read = _InclusiveMetricsEvaluator(schema_data_file, In("id", equal_upper)).eval(data_file) |
| 693 | + assert should_read, "Should read: id equal to upper bound (min 79 == 79)" |
| 694 | + |
| 695 | + straddle = set(range(INT_MIN_VALUE - IN_PREDICATE_LIMIT, INT_MAX_VALUE + 2)) |
| 696 | + should_read = _InclusiveMetricsEvaluator(schema_data_file, In("id", straddle)).eval(data_file) |
| 697 | + assert should_read, "Should read: id range overlaps bounds" |
| 698 | + |
| 699 | + outside_both = {*range(INT_MIN_VALUE - IN_PREDICATE_LIMIT, INT_MIN_VALUE), INT_MAX_VALUE + 1} |
| 700 | + should_read = _InclusiveMetricsEvaluator(schema_data_file, In("id", outside_both)).eval(data_file) |
| 701 | + assert should_read, "Should read: id range covers bounds, values between min and max are not checked" |
| 702 | + |
| 703 | + should_read = _InclusiveMetricsEvaluator( |
| 704 | + schema_data_file, In("all_nulls", {str(i) for i in range(IN_PREDICATE_LIMIT + 1)}) |
| 705 | + ).eval(data_file) |
| 706 | + assert not should_read, "Should skip: in on all nulls column" |
| 707 | + |
| 708 | + |
| 709 | +def test_integer_in_at_limit(schema_data_file: Schema, data_file: DataFile) -> None: |
| 710 | + below_lower = set(range(INT_MIN_VALUE - IN_PREDICATE_LIMIT, INT_MIN_VALUE)) |
| 711 | + should_read = _InclusiveMetricsEvaluator(schema_data_file, In("id", below_lower)).eval(data_file) |
| 712 | + assert not should_read, "Should not read: id below lower bound (max 29 < 30)" |
| 713 | + |
| 714 | + outside_both = {*range(INT_MIN_VALUE - IN_PREDICATE_LIMIT + 1, INT_MIN_VALUE), INT_MAX_VALUE + 1} |
| 715 | + should_read = _InclusiveMetricsEvaluator(schema_data_file, In("id", outside_both)).eval(data_file) |
| 716 | + assert not should_read, "Should not read: no id between lower and upper bounds" |
| 717 | + |
| 718 | + |
677 | 719 | def test_integer_not_in(schema_data_file: Schema, data_file: DataFile) -> None: |
678 | 720 | should_read = _InclusiveMetricsEvaluator(schema_data_file, NotIn("id", {INT_MIN_VALUE - 25, INT_MIN_VALUE - 24})).eval( |
679 | 721 | data_file |
@@ -909,6 +951,34 @@ def test_inclusive_metrics_evaluator_in(schema_data_file_nan: Schema, data_file_ |
909 | 951 | assert should_read, "Should match: overlap with upper bounds" |
910 | 952 |
|
911 | 953 |
|
| 954 | +def test_inclusive_metrics_evaluator_in_above_limit(schema_data_file_nan: Schema, data_file_nan: DataFile) -> None: |
| 955 | + below_seven = {float(i) for i in range(-IN_PREDICATE_LIMIT, 1)} |
| 956 | + above_twenty_two = {float(i) for i in range(30, 30 + IN_PREDICATE_LIMIT + 1)} |
| 957 | + |
| 958 | + should_read = _InclusiveMetricsEvaluator(schema_data_file_nan, In("all_nan", below_seven)).eval(data_file_nan) |
| 959 | + assert not should_read, "Should not match: all nan column doesn't contain number" |
| 960 | + |
| 961 | + should_read = _InclusiveMetricsEvaluator(schema_data_file_nan, In("max_nan", below_seven)).eval(data_file_nan) |
| 962 | + assert not should_read, "Should not match: all values are smaller than lower bound" |
| 963 | + |
| 964 | + should_read = _InclusiveMetricsEvaluator(schema_data_file_nan, In("max_nan", above_twenty_two)).eval(data_file_nan) |
| 965 | + assert should_read, "Should match: upper bound is nan" |
| 966 | + |
| 967 | + should_read = _InclusiveMetricsEvaluator(schema_data_file_nan, In("min_max_nan", below_seven)).eval(data_file_nan) |
| 968 | + assert should_read, "Should match: no visibility" |
| 969 | + |
| 970 | + should_read = _InclusiveMetricsEvaluator(schema_data_file_nan, In("all_nan_null_bounds", below_seven)).eval(data_file_nan) |
| 971 | + assert not should_read, "Should not match: all nan column doesn't contain number" |
| 972 | + |
| 973 | + should_read = _InclusiveMetricsEvaluator(schema_data_file_nan, In("some_nan_correct_bounds", below_seven)).eval(data_file_nan) |
| 974 | + assert not should_read, "Should not match: all values are smaller than lower bound" |
| 975 | + |
| 976 | + should_read = _InclusiveMetricsEvaluator(schema_data_file_nan, In("some_nan_correct_bounds", above_twenty_two)).eval( |
| 977 | + data_file_nan |
| 978 | + ) |
| 979 | + assert not should_read, "Should not match: all values are larger than upper bound" |
| 980 | + |
| 981 | + |
912 | 982 | def test_inclusive_metrics_evaluator_not_in(schema_data_file_nan: Schema, data_file_nan: DataFile) -> None: |
913 | 983 | should_read = _InclusiveMetricsEvaluator(schema_data_file_nan, NotIn("all_nan", (1, 10, 30))).eval(data_file_nan) |
914 | 984 | assert should_read, "Should match: no visibility" |
|
0 commit comments