Skip to content

Commit cdb52ca

Browse files
committed
fix: defer multi-scan filter binding errors
Signed-off-by: Joe Isaacs <joe.isaacs@live.co.uk>
1 parent deba451 commit cdb52ca

1 file changed

Lines changed: 31 additions & 5 deletions

File tree

‎vortex-layout/src/scan/multi.rs‎

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ use vortex_array::stats::StatsSet;
4343
use vortex_array::stream::ArrayStreamAdapter;
4444
use vortex_array::stream::ArrayStreamExt;
4545
use vortex_array::stream::SendableArrayStream;
46+
use vortex_error::SharedVortexResult;
4647
use vortex_error::VortexResult;
4748
use vortex_error::vortex_bail;
4849
use vortex_error::vortex_err;
@@ -326,7 +327,7 @@ impl DataSource for MultiLayoutDataSource {
326327
#[derive(Clone)]
327328
struct BoundScanRequest {
328329
projection: BoundExpression,
329-
filter: Option<BoundExpression>,
330+
filter: SharedVortexResult<Option<BoundExpression>>,
330331
row_range: Option<Range<u64>>,
331332
selection: Selection,
332333
partition_selection: Selection,
@@ -352,7 +353,8 @@ impl BoundScanRequest {
352353
projection: optimize_and_bind(projection, dtype)?,
353354
filter: filter
354355
.map(|expr| optimize_and_bind(expr, dtype))
355-
.transpose()?,
356+
.transpose()
357+
.map_err(Arc::new),
356358
row_range,
357359
selection,
358360
partition_selection,
@@ -503,7 +505,7 @@ fn reader_partition(
503505

504506
// Check file-level pruning: if the filter can be proven false for the entire row range
505507
// using file-level statistics, skip this reader entirely.
506-
if let Some(filter) = &request.filter {
508+
if let Ok(Some(filter)) = &request.filter {
507509
let mask_len = usize::try_from(row_range.end - row_range.start).unwrap_or(usize::MAX);
508510
let mask = Mask::new_true(mask_len);
509511
if let Ok(pruning_future) = reader.pruning_evaluation(&row_range, filter, mask)
@@ -559,7 +561,11 @@ impl Partition for MultiLayoutPartition {
559561
.limit
560562
.map_or(row_count, |limit| row_count.min(limit));
561563

562-
if self.request.filter.is_some() {
564+
let has_filter = match &self.request.filter {
565+
Ok(filter) => filter.is_some(),
566+
Err(_) => true,
567+
};
568+
if has_filter {
563569
Precision::inexact(row_count)
564570
} else {
565571
Precision::exact(row_count)
@@ -572,10 +578,11 @@ impl Partition for MultiLayoutPartition {
572578

573579
fn execute(self: Box<Self>) -> VortexResult<SendableArrayStream> {
574580
let request = self.request;
581+
let filter = request.filter?;
575582
let mut builder = ScanBuilder::new(self.session, self.reader)
576583
.with_selection(request.selection)
577584
.with_projection(request.projection)
578-
.with_some_filter(request.filter)
585+
.with_some_filter(filter)
579586
.with_some_limit(request.limit)
580587
.with_ordered(request.ordered);
581588

@@ -596,6 +603,10 @@ impl Partition for MultiLayoutPartition {
596603
mod tests {
597604
use rstest::rstest;
598605
use vortex_array::dtype::Nullability;
606+
use vortex_array::dtype::PType;
607+
use vortex_array::expr::eq;
608+
use vortex_array::expr::lit;
609+
use vortex_array::expr::root;
599610

600611
use super::*;
601612
use crate::scan::test::new_session;
@@ -630,4 +641,19 @@ mod tests {
630641
fn byte_size_precision(#[case] sizes: Vec<Option<u64>>, #[case] expected: Precision<u64>) {
631642
assert_eq!(deferred_source(sizes).byte_size(), expected);
632643
}
644+
645+
#[test]
646+
fn filter_binding_errors_are_deferred() -> VortexResult<()> {
647+
let dtype = DType::Primitive(PType::U8, Nullability::NonNullable);
648+
let request = ScanRequest {
649+
filter: Some(eq(root(), lit(67_i32))),
650+
..ScanRequest::default()
651+
};
652+
653+
let request = BoundScanRequest::try_new(request, &dtype)?;
654+
655+
assert_eq!(request.projection.dtype(), &dtype);
656+
assert!(request.filter.is_err());
657+
Ok(())
658+
}
633659
}

0 commit comments

Comments
 (0)