Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion vortex-file/src/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,13 @@ impl VortexFile {
let mut ctx = self.session.create_execution_ctx();
Ok(match applied.execute::<Columnar>(&mut ctx)? {
Columnar::Constant(s) => s.scalar().as_bool().value() == Some(true),
Columnar::Canonical(_) => false,
Columnar::Canonical(c) => {
c.into_array()
.execute_scalar(0, &mut ctx)?
.as_bool()
.value()
== Some(true)
}
})
}

Expand Down
37 changes: 37 additions & 0 deletions vortex-file/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ use vortex_array::dtype::PType::I32;
use vortex_array::dtype::StructFields;
use vortex_array::expr::and;
use vortex_array::expr::cast;
use vortex_array::expr::col;
use vortex_array::expr::eq;
use vortex_array::expr::get_item;
use vortex_array::expr::gt;
Expand Down Expand Up @@ -1953,3 +1954,39 @@ async fn test_segment_ordering_zonemaps_after_data() -> VortexResult<()> {

Ok(())
}

#[tokio::test]
#[cfg_attr(miri, ignore)]
async fn test_can_prune_composite_predicates() -> VortexResult<()> {
// Regression test for `can_prune` after `ScalarFnConstantRule` was removed
// (#7575): composite falsification trees no longer constant-fold during
// execution, so `can_prune` must read the one-row evaluated result instead
// of requiring a `Columnar::Constant`. `Eq` is affected too: its
// falsification is internally `or(min > lit, lit > max)`.
let st = StructArray::from_fields(&[
("age", buffer![15i32, 18, 22, 25].into_array()),
("price", buffer![120i32, 130, 140, 150].into_array()),
])?;
let mut buf = ByteBufferMut::empty();
SESSION
.write_options()
.write(&mut buf, st.into_array().to_array_stream())
.await?;
let file = SESSION.open_options().open_buffer(buf)?;

// Bare comparisons: falsified directly by min/max stats.
assert!(file.can_prune(&gt(col("age"), lit(30)))?);
assert!(file.can_prune(&lt(col("price"), lit(100)))?);

// Composite predicates whose falsifications are boolean trees.
assert!(file.can_prune(&and(gt(col("age"), lit(30)), lt(col("price"), lit(100))))?);
assert!(file.can_prune(&or(gt(col("age"), lit(30)), lt(col("age"), lit(10))))?);
assert!(file.can_prune(&eq(col("age"), lit(5)))?);

// Non-falsifiable controls: rows may match, so pruning must refuse.
assert!(!file.can_prune(&gt(col("age"), lit(20)))?);
assert!(!file.can_prune(&eq(col("age"), lit(18)))?);
assert!(!file.can_prune(&and(gt(col("age"), lit(20)), gt(col("price"), lit(100))))?);

Ok(())
}
Loading