Skip to content

Commit 7f497b3

Browse files
authored
Add non-column expression equality tracking to filter exec (#9819)
* Add non-column expression equality tracking to filter exec * Minor changes
1 parent 09f5a54 commit 7f497b3

3 files changed

Lines changed: 44 additions & 25 deletions

File tree

datafusion/physical-plan/src/filter.rs

Lines changed: 23 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ use super::{
2929
};
3030
use crate::{
3131
metrics::{BaselineMetrics, ExecutionPlanMetricsSet, MetricsSet},
32-
Column, DisplayFormatType, ExecutionPlan,
32+
DisplayFormatType, ExecutionPlan,
3333
};
3434

3535
use arrow::compute::filter_record_batch;
@@ -192,9 +192,7 @@ impl FilterExec {
192192
let mut eq_properties = input.equivalence_properties().clone();
193193
let (equal_pairs, _) = collect_columns_from_predicate(predicate);
194194
for (lhs, rhs) in equal_pairs {
195-
let lhs_expr = Arc::new(lhs.clone()) as _;
196-
let rhs_expr = Arc::new(rhs.clone()) as _;
197-
eq_properties.add_equal_conditions(&lhs_expr, &rhs_expr)
195+
eq_properties.add_equal_conditions(lhs, rhs)
198196
}
199197
// Add the columns that have only one viable value (singleton) after
200198
// filtering to constants.
@@ -405,34 +403,33 @@ impl RecordBatchStream for FilterExecStream {
405403

406404
/// Return the equals Column-Pairs and Non-equals Column-Pairs
407405
fn collect_columns_from_predicate(predicate: &Arc<dyn PhysicalExpr>) -> EqualAndNonEqual {
408-
let mut eq_predicate_columns = Vec::<(&Column, &Column)>::new();
409-
let mut ne_predicate_columns = Vec::<(&Column, &Column)>::new();
406+
let mut eq_predicate_columns = Vec::<PhysicalExprPairRef>::new();
407+
let mut ne_predicate_columns = Vec::<PhysicalExprPairRef>::new();
410408

411409
let predicates = split_conjunction(predicate);
412410
predicates.into_iter().for_each(|p| {
413411
if let Some(binary) = p.as_any().downcast_ref::<BinaryExpr>() {
414-
if let (Some(left_column), Some(right_column)) = (
415-
binary.left().as_any().downcast_ref::<Column>(),
416-
binary.right().as_any().downcast_ref::<Column>(),
417-
) {
418-
match binary.op() {
419-
Operator::Eq => {
420-
eq_predicate_columns.push((left_column, right_column))
421-
}
422-
Operator::NotEq => {
423-
ne_predicate_columns.push((left_column, right_column))
424-
}
425-
_ => {}
412+
match binary.op() {
413+
Operator::Eq => {
414+
eq_predicate_columns.push((binary.left(), binary.right()))
415+
}
416+
Operator::NotEq => {
417+
ne_predicate_columns.push((binary.left(), binary.right()))
426418
}
419+
_ => {}
427420
}
428421
}
429422
});
430423

431424
(eq_predicate_columns, ne_predicate_columns)
432425
}
426+
427+
/// Pair of `Arc<dyn PhysicalExpr>`s
428+
pub type PhysicalExprPairRef<'a> = (&'a Arc<dyn PhysicalExpr>, &'a Arc<dyn PhysicalExpr>);
429+
433430
/// The equals Column-Pairs and Non-equals Column-Pairs in the Predicates
434431
pub type EqualAndNonEqual<'a> =
435-
(Vec<(&'a Column, &'a Column)>, Vec<(&'a Column, &'a Column)>);
432+
(Vec<PhysicalExprPairRef<'a>>, Vec<PhysicalExprPairRef<'a>>);
436433

437434
#[cfg(test)]
438435
mod tests {
@@ -482,14 +479,16 @@ mod tests {
482479
)?;
483480

484481
let (equal_pairs, ne_pairs) = collect_columns_from_predicate(&predicate);
482+
assert_eq!(2, equal_pairs.len());
483+
assert!(equal_pairs[0].0.eq(&col("c2", &schema)?));
484+
assert!(equal_pairs[0].1.eq(&lit(4u32)));
485485

486-
assert_eq!(1, equal_pairs.len());
487-
assert_eq!(equal_pairs[0].0.name(), "c2");
488-
assert_eq!(equal_pairs[0].1.name(), "c9");
486+
assert!(equal_pairs[1].0.eq(&col("c2", &schema)?));
487+
assert!(equal_pairs[1].1.eq(&col("c9", &schema)?));
489488

490489
assert_eq!(1, ne_pairs.len());
491-
assert_eq!(ne_pairs[0].0.name(), "c1");
492-
assert_eq!(ne_pairs[0].1.name(), "c13");
490+
assert!(ne_pairs[0].0.eq(&col("c1", &schema)?));
491+
assert!(ne_pairs[0].1.eq(&col("c13", &schema)?));
493492

494493
Ok(())
495494
}

datafusion/physical-plan/src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ use datafusion_common::config::ConfigOptions;
3333
use datafusion_common::utils::DataPtr;
3434
use datafusion_common::Result;
3535
use datafusion_execution::TaskContext;
36-
use datafusion_physical_expr::expressions::Column;
3736
use datafusion_physical_expr::{
3837
EquivalenceProperties, LexOrdering, PhysicalSortExpr, PhysicalSortRequirement,
3938
};

datafusion/sqllogictest/test_files/select.slt

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1386,6 +1386,27 @@ AggregateExec: mode=FinalPartitioned, gby=[c2@0 as c2], aggr=[COUNT(*)]
13861386
--------RepartitionExec: partitioning=RoundRobinBatch(2), input_partitions=1
13871387
----------CsvExec: file_groups={1 group: [[WORKSPACE_ROOT/testing/data/csv/aggregate_test_100.csv]]}, projection=[c2], has_header=true
13881388

1389+
# FilterExec can track equality of non-column expressions.
1390+
# plan below shouldn't have a SortExec because given column 'a' is ordered.
1391+
# 'CAST(ROUND(b) as INT)' is also ordered. After filter is applied.
1392+
query TT
1393+
EXPLAIN SELECT *
1394+
FROM annotated_data_finite2
1395+
WHERE CAST(ROUND(b) as INT) = a
1396+
ORDER BY CAST(ROUND(b) as INT);
1397+
----
1398+
logical_plan
1399+
Sort: CAST(round(CAST(annotated_data_finite2.b AS Float64)) AS Int32) ASC NULLS LAST
1400+
--Filter: CAST(round(CAST(annotated_data_finite2.b AS Float64)) AS Int32) = annotated_data_finite2.a
1401+
----TableScan: annotated_data_finite2 projection=[a0, a, b, c, d], partial_filters=[CAST(round(CAST(annotated_data_finite2.b AS Float64)) AS Int32) = annotated_data_finite2.a]
1402+
physical_plan
1403+
SortPreservingMergeExec: [CAST(round(CAST(b@2 AS Float64)) AS Int32) ASC NULLS LAST]
1404+
--CoalesceBatchesExec: target_batch_size=8192
1405+
----FilterExec: CAST(round(CAST(b@2 AS Float64)) AS Int32) = a@1
1406+
------RepartitionExec: partitioning=RoundRobinBatch(2), input_partitions=1
1407+
--------CsvExec: file_groups={1 group: [[WORKSPACE_ROOT/datafusion/core/tests/data/window_2.csv]]}, projection=[a0, a, b, c, d], output_ordering=[a@1 ASC NULLS LAST, b@2 ASC NULLS LAST, c@3 ASC NULLS LAST], has_header=true
1408+
1409+
13891410
statement ok
13901411
drop table annotated_data_finite2;
13911412

0 commit comments

Comments
 (0)