Skip to content

Commit c2e118b

Browse files
committed
fix: ad test and fix for logic bug in PageIndexEvaluator in-clause handler
1 parent eb82cac commit c2e118b

1 file changed

Lines changed: 55 additions & 10 deletions

File tree

crates/iceberg/src/expr/visitors/page_index_evaluator.rs

Lines changed: 55 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -719,18 +719,30 @@ impl BoundPredicateVisitor for PageIndexEvaluator<'_> {
719719
return Ok(false);
720720
}
721721

722-
if let Some(lower_bound) = min {
723-
if !literals.iter().any(|datum| datum.ge(&lower_bound)) {
724-
// if all values are less than lower bound, rows cannot match.
725-
return Ok(false);
722+
match (min, max) {
723+
(Some(min), Some(max)) => {
724+
if literals
725+
.iter()
726+
.all(|datum| datum.lt(&min) || datum.gt(&max))
727+
{
728+
// if all values are outside the bounds, rows cannot match.
729+
return Ok(false);
730+
}
726731
}
727-
}
728-
729-
if let Some(upper_bound) = max {
730-
if !literals.iter().any(|datum| datum.le(&upper_bound)) {
731-
// if all values are greater than upper bound, rows cannot match.
732-
return Ok(false);
732+
(Some(min), _) => {
733+
if !literals.iter().any(|datum| datum.ge(&min)) {
734+
// if none of the values are greater than the min bound, rows cant match
735+
return Ok(false);
736+
}
737+
}
738+
(_, Some(max)) => {
739+
if !literals.iter().any(|datum| datum.le(&max)) {
740+
// if all values are greater than upper bound, rows cannot match.
741+
return Ok(false);
742+
}
733743
}
744+
745+
_ => {}
734746
}
735747

736748
Ok(true)
@@ -1265,6 +1277,39 @@ mod tests {
12651277
Ok(())
12661278
}
12671279

1280+
#[test]
1281+
fn eval_in_valid_set_size_some_rows() -> Result<()> {
1282+
let row_group_metadata = create_row_group_metadata(4096, 1000, None, 1000, None)?;
1283+
let (column_index, offset_index) = create_page_index()?;
1284+
1285+
let (iceberg_schema_ref, field_id_map) = build_iceberg_schema_and_field_map()?;
1286+
1287+
let filter = Reference::new("col_string")
1288+
.is_in([Datum::string("AARDVARK"), Datum::string("ICEBERG")])
1289+
.bind(iceberg_schema_ref.clone(), false)?;
1290+
1291+
let result = PageIndexEvaluator::eval(
1292+
&filter,
1293+
&column_index,
1294+
&offset_index,
1295+
&row_group_metadata,
1296+
&field_id_map,
1297+
iceberg_schema_ref.as_ref(),
1298+
)?;
1299+
1300+
let expected = vec![
1301+
RowSelector::select(512),
1302+
RowSelector::skip(512),
1303+
RowSelector::select(2976),
1304+
RowSelector::skip(48),
1305+
RowSelector::select(48),
1306+
];
1307+
1308+
assert_eq!(result, expected);
1309+
1310+
Ok(())
1311+
}
1312+
12681313
fn build_iceberg_schema_and_field_map() -> Result<(Arc<Schema>, HashMap<i32, usize>)> {
12691314
let iceberg_schema = Schema::builder()
12701315
.with_fields([

0 commit comments

Comments
 (0)