Skip to content

Commit e1f24c1

Browse files
authored
Chore: Add AboveMax and BelowMin (#820)
And add some nice `.to` conversions.
1 parent 74a85e7 commit e1f24c1

File tree

2 files changed

+383
-1
lines changed

2 files changed

+383
-1
lines changed

crates/iceberg/src/expr/predicate.rs

Lines changed: 152 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ use serde::{Deserialize, Serialize};
2929

3030
use crate::error::Result;
3131
use crate::expr::{Bind, BoundReference, PredicateOperator, Reference};
32-
use crate::spec::{Datum, SchemaRef};
32+
use crate::spec::{Datum, PrimitiveLiteral, SchemaRef};
3333
use crate::{Error, ErrorKind};
3434

3535
/// Logical expression, such as `AND`, `OR`, `NOT`.
@@ -400,6 +400,37 @@ impl Bind for Predicate {
400400
Predicate::Binary(expr) => {
401401
let bound_expr = expr.bind(schema, case_sensitive)?;
402402
let bound_literal = bound_expr.literal.to(&bound_expr.term.field().field_type)?;
403+
404+
match bound_literal.literal() {
405+
PrimitiveLiteral::AboveMax => match &bound_expr.op {
406+
&PredicateOperator::LessThan
407+
| &PredicateOperator::LessThanOrEq
408+
| &PredicateOperator::NotEq => {
409+
return Ok(BoundPredicate::AlwaysTrue);
410+
}
411+
&PredicateOperator::GreaterThan
412+
| &PredicateOperator::GreaterThanOrEq
413+
| &PredicateOperator::Eq => {
414+
return Ok(BoundPredicate::AlwaysFalse);
415+
}
416+
_ => {}
417+
},
418+
PrimitiveLiteral::BelowMin => match &bound_expr.op {
419+
&PredicateOperator::GreaterThan
420+
| &PredicateOperator::GreaterThanOrEq
421+
| &PredicateOperator::NotEq => {
422+
return Ok(BoundPredicate::AlwaysTrue);
423+
}
424+
&PredicateOperator::LessThan
425+
| &PredicateOperator::LessThanOrEq
426+
| &PredicateOperator::Eq => {
427+
return Ok(BoundPredicate::AlwaysFalse);
428+
}
429+
_ => {}
430+
},
431+
_ => {}
432+
}
433+
403434
Ok(BoundPredicate::Binary(BinaryExpression::new(
404435
bound_expr.op,
405436
bound_expr.term,
@@ -1086,6 +1117,126 @@ mod tests {
10861117
test_bound_predicate_serialize_diserialize(bound_expr);
10871118
}
10881119

1120+
#[test]
1121+
fn test_bind_equal_to_above_max() {
1122+
let schema = table_schema_simple();
1123+
// int32 can hold up to 2147483647
1124+
let expr = Reference::new("bar").equal_to(Datum::long(2147483648i64));
1125+
let bound_expr = expr.bind(schema, true).unwrap();
1126+
assert_eq!(&format!("{bound_expr}"), "False");
1127+
test_bound_predicate_serialize_diserialize(bound_expr);
1128+
}
1129+
1130+
#[test]
1131+
fn test_bind_equal_to_below_min() {
1132+
let schema = table_schema_simple();
1133+
// int32 can hold up to -2147483647
1134+
let expr = Reference::new("bar").equal_to(Datum::long(-2147483649i64));
1135+
let bound_expr = expr.bind(schema, true).unwrap();
1136+
assert_eq!(&format!("{bound_expr}"), "False");
1137+
test_bound_predicate_serialize_diserialize(bound_expr);
1138+
}
1139+
1140+
#[test]
1141+
fn test_bind_not_equal_to_above_max() {
1142+
let schema = table_schema_simple();
1143+
// int32 can hold up to 2147483647
1144+
let expr = Reference::new("bar").not_equal_to(Datum::long(2147483648i64));
1145+
let bound_expr = expr.bind(schema, true).unwrap();
1146+
assert_eq!(&format!("{bound_expr}"), "True");
1147+
test_bound_predicate_serialize_diserialize(bound_expr);
1148+
}
1149+
1150+
#[test]
1151+
fn test_bind_not_equal_to_below_min() {
1152+
let schema = table_schema_simple();
1153+
// int32 can hold up to -2147483647
1154+
let expr = Reference::new("bar").not_equal_to(Datum::long(-2147483649i64));
1155+
let bound_expr = expr.bind(schema, true).unwrap();
1156+
assert_eq!(&format!("{bound_expr}"), "True");
1157+
test_bound_predicate_serialize_diserialize(bound_expr);
1158+
}
1159+
1160+
#[test]
1161+
fn test_bind_less_than_above_max() {
1162+
let schema = table_schema_simple();
1163+
// int32 can hold up to 2147483647
1164+
let expr = Reference::new("bar").less_than(Datum::long(2147483648i64));
1165+
let bound_expr = expr.bind(schema, true).unwrap();
1166+
assert_eq!(&format!("{bound_expr}"), "True");
1167+
test_bound_predicate_serialize_diserialize(bound_expr);
1168+
}
1169+
1170+
#[test]
1171+
fn test_bind_less_than_below_min() {
1172+
let schema = table_schema_simple();
1173+
// int32 can hold up to -2147483647
1174+
let expr = Reference::new("bar").less_than(Datum::long(-2147483649i64));
1175+
let bound_expr = expr.bind(schema, true).unwrap();
1176+
assert_eq!(&format!("{bound_expr}"), "False");
1177+
test_bound_predicate_serialize_diserialize(bound_expr);
1178+
}
1179+
1180+
#[test]
1181+
fn test_bind_less_than_or_equal_to_above_max() {
1182+
let schema = table_schema_simple();
1183+
// int32 can hold up to 2147483647
1184+
let expr = Reference::new("bar").less_than_or_equal_to(Datum::long(2147483648i64));
1185+
let bound_expr = expr.bind(schema, true).unwrap();
1186+
assert_eq!(&format!("{bound_expr}"), "True");
1187+
test_bound_predicate_serialize_diserialize(bound_expr);
1188+
}
1189+
1190+
#[test]
1191+
fn test_bind_less_than_or_equal_to_below_min() {
1192+
let schema = table_schema_simple();
1193+
// int32 can hold up to -2147483647
1194+
let expr = Reference::new("bar").less_than_or_equal_to(Datum::long(-2147483649i64));
1195+
let bound_expr = expr.bind(schema, true).unwrap();
1196+
assert_eq!(&format!("{bound_expr}"), "False");
1197+
test_bound_predicate_serialize_diserialize(bound_expr);
1198+
}
1199+
1200+
#[test]
1201+
fn test_bind_great_than_above_max() {
1202+
let schema = table_schema_simple();
1203+
// int32 can hold up to 2147483647
1204+
let expr = Reference::new("bar").greater_than(Datum::long(2147483648i64));
1205+
let bound_expr = expr.bind(schema, true).unwrap();
1206+
assert_eq!(&format!("{bound_expr}"), "False");
1207+
test_bound_predicate_serialize_diserialize(bound_expr);
1208+
}
1209+
1210+
#[test]
1211+
fn test_bind_great_than_below_min() {
1212+
let schema = table_schema_simple();
1213+
// int32 can hold up to -2147483647
1214+
let expr = Reference::new("bar").greater_than(Datum::long(-2147483649i64));
1215+
let bound_expr = expr.bind(schema, true).unwrap();
1216+
assert_eq!(&format!("{bound_expr}"), "True");
1217+
test_bound_predicate_serialize_diserialize(bound_expr);
1218+
}
1219+
1220+
#[test]
1221+
fn test_bind_great_than_or_equal_to_above_max() {
1222+
let schema = table_schema_simple();
1223+
// int32 can hold up to 2147483647
1224+
let expr = Reference::new("bar").greater_than_or_equal_to(Datum::long(2147483648i64));
1225+
let bound_expr = expr.bind(schema, true).unwrap();
1226+
assert_eq!(&format!("{bound_expr}"), "False");
1227+
test_bound_predicate_serialize_diserialize(bound_expr);
1228+
}
1229+
1230+
#[test]
1231+
fn test_bind_great_than_or_equal_to_below_min() {
1232+
let schema = table_schema_simple();
1233+
// int32 can hold up to -2147483647
1234+
let expr = Reference::new("bar").greater_than_or_equal_to(Datum::long(-2147483649i64));
1235+
let bound_expr = expr.bind(schema, true).unwrap();
1236+
assert_eq!(&format!("{bound_expr}"), "True");
1237+
test_bound_predicate_serialize_diserialize(bound_expr);
1238+
}
1239+
10891240
#[test]
10901241
fn test_bind_equal_to_wrong_type() {
10911242
let schema = table_schema_simple();

0 commit comments

Comments
 (0)