Skip to content

Commit 57d4c88

Browse files
committed
Prune plan scans with zoned statistics
Signed-off-by: Joe Isaacs <joe.isaacs@live.co.uk>
1 parent 43bb342 commit 57d4c88

13 files changed

Lines changed: 815 additions & 95 deletions

File tree

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vortex-layout/src/layouts/zoned/mod.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,11 @@ impl ZonedLayout {
358358
}
359359

360360
impl ZonedData {
361-
fn aggregate_fns(&self) -> Arc<[AggregateFnRef]> {
361+
pub(crate) fn zone_len(&self) -> usize {
362+
self.zone_len
363+
}
364+
365+
pub(crate) fn aggregate_fns(&self) -> Arc<[AggregateFnRef]> {
362366
match &self.zone_map_schema {
363367
ZoneMapSchema::LegacyStats(stats) => stats
364368
.iter()

vortex-layout/src/layouts/zoned/zone_map.rs

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use vortex_array::aggregate_fn::fns::all_null::AllNull;
1717
use vortex_array::aggregate_fn::fns::bounded_max::BOUNDED_MAX_BOUND;
1818
use vortex_array::aggregate_fn::fns::bounded_max::BoundedMax;
1919
use vortex_array::aggregate_fn::fns::nan_count::NanCount;
20+
use vortex_array::arrays::BoolArray;
2021
use vortex_array::arrays::ConstantArray;
2122
use vortex_array::arrays::PrimitiveArray;
2223
use vortex_array::arrays::StructArray;
@@ -87,7 +88,7 @@ impl ZoneMap {
8788
Ok(unsafe { Self::new_unchecked(column_dtype, array, aggregate_fns, zone_len, row_count) })
8889
}
8990

90-
pub(super) unsafe fn new_unchecked(
91+
pub(crate) unsafe fn new_unchecked(
9192
column_dtype: DType,
9293
array: StructArray,
9394
aggregate_fns: Arc<[AggregateFnRef]>,
@@ -143,18 +144,34 @@ impl ZoneMap {
143144
/// only after the predicate has been lowered to the zone-map table.
144145
pub fn prune(&self, predicate: &Expression, session: &VortexSession) -> VortexResult<Mask> {
145146
let mut ctx = session.create_execution_ctx();
147+
self.applied_predicate(predicate)?
148+
.null_as_false()
149+
.execute(&mut ctx)
150+
}
151+
152+
/// Evaluate a pruning predicate while preserving unknown (null) proof values.
153+
pub(crate) fn evaluate(
154+
&self,
155+
predicate: &Expression,
156+
session: &VortexSession,
157+
) -> VortexResult<BoolArray> {
158+
let mut ctx = session.create_execution_ctx();
159+
self.applied_predicate(predicate)?
160+
.execute::<BoolArray>(&mut ctx)
161+
}
162+
163+
fn applied_predicate(&self, predicate: &Expression) -> VortexResult<ArrayRef> {
146164
let num_zones = self.array.len();
147165
let predicate = self.lower_stats(predicate.clone())?;
148166

149167
let applied = self.array.clone().into_array().apply(&predicate)?;
150-
151-
if !contains_row_count(&applied) {
152-
return applied.null_as_false().execute(&mut ctx);
153-
}
154-
155-
let row_count_array = row_count_array(self.zone_len, self.row_count, num_zones)?;
156-
let substituted = substitute_row_count(applied, &row_count_array)?;
157-
substituted.null_as_false().execute(&mut ctx)
168+
let applied = if contains_row_count(&applied) {
169+
let row_count_array = row_count_array(self.zone_len, self.row_count, num_zones)?;
170+
substitute_row_count(applied, &row_count_array)?
171+
} else {
172+
applied
173+
};
174+
Ok(applied)
158175
}
159176

160177
fn lower_stats(&self, predicate: Expression) -> VortexResult<Expression> {

vortex-layout/src/plan/display.rs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use std::fmt;
55

66
use super::ExpressionPlan;
77
use super::Plan;
8+
use super::ZonedPlan;
89

910
/// Context threaded through a plan tree traversal.
1011
pub struct PlanTreeContext {
@@ -110,7 +111,7 @@ impl PlanTreeExtractor for PlanSummaryExtractor {
110111
}
111112
}
112113

113-
/// Adds an expression annotation to [`ExpressionPlan`] nodes.
114+
/// Adds expression annotations to expression and zoned-pruning plans.
114115
pub struct PlanExpressionExtractor;
115116

116117
impl PlanTreeExtractor for PlanExpressionExtractor {
@@ -120,10 +121,16 @@ impl PlanTreeExtractor for PlanExpressionExtractor {
120121
_context: &PlanTreeContext,
121122
formatter: &mut fmt::Formatter<'_>,
122123
) -> fmt::Result {
123-
let Some(expression_plan) = plan.downcast_ref::<ExpressionPlan>() else {
124-
return Ok(());
125-
};
126-
write!(formatter, " expr={}", expression_plan.expression())
124+
if let Some(expression_plan) = plan.downcast_ref::<ExpressionPlan>() {
125+
return write!(formatter, " expr={}", expression_plan.expression());
126+
}
127+
if let Some(expression) = plan
128+
.downcast_ref::<ZonedPlan>()
129+
.and_then(ZonedPlan::pruning_expression)
130+
{
131+
return write!(formatter, " prune={expression}");
132+
}
133+
Ok(())
127134
}
128135
}
129136

vortex-layout/src/plan/optimizer/mod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,12 @@ use super::DictPlan;
1616
use super::PlanRef;
1717
use super::RowIdxPlan;
1818
use super::StructPlan;
19+
use super::ZonedPlan;
1920
use super::plans::ExpressionChunkedRule;
2021
use super::plans::ExpressionDictRule;
2122
use super::plans::ExpressionRowIdxRule;
2223
use super::plans::ExpressionStructRule;
24+
use super::plans::ExpressionZonedRule;
2325

2426
static EXPRESSION_CHUNKED_RULE: PlanParentReduceRuleAdapter<ChunkedPlan, ExpressionChunkedRule> =
2527
PlanParentReduceRuleAdapter::new(ExpressionChunkedRule);
@@ -29,12 +31,15 @@ static EXPRESSION_ROW_IDX_RULE: PlanParentReduceRuleAdapter<RowIdxPlan, Expressi
2931
PlanParentReduceRuleAdapter::new(ExpressionRowIdxRule);
3032
static EXPRESSION_STRUCT_RULE: PlanParentReduceRuleAdapter<StructPlan, ExpressionStructRule> =
3133
PlanParentReduceRuleAdapter::new(ExpressionStructRule);
34+
static EXPRESSION_ZONED_RULE: PlanParentReduceRuleAdapter<ZonedPlan, ExpressionZonedRule> =
35+
PlanParentReduceRuleAdapter::new(ExpressionZonedRule);
3236

3337
static PARENT_RULES: PlanParentRuleSet = PlanParentRuleSet::new(&[
3438
&EXPRESSION_CHUNKED_RULE,
3539
&EXPRESSION_DICT_RULE,
3640
&EXPRESSION_ROW_IDX_RULE,
3741
&EXPRESSION_STRUCT_RULE,
42+
&EXPRESSION_ZONED_RULE,
3843
]);
3944

4045
/// Attempts a static rewrite for `parent` and its child at `child_idx`.

vortex-layout/src/plan/plans/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,5 @@ pub use row_idx::RowIdxPlan;
2323
pub use row_idx::RowIdxValuesPlan;
2424
pub(crate) use struct_::ExpressionStructRule;
2525
pub use struct_::StructPlan;
26+
pub(crate) use zoned::ExpressionZonedRule;
2627
pub use zoned::ZonedPlan;

0 commit comments

Comments
 (0)