Skip to content

Commit d91a03f

Browse files
authored
Move handlign of NULL literals in where clause to type coercion pass (#11491)
* Revert "Support `NULL` literals in where clause (#11266)" This reverts commit fa01917. * Followup Support NULL literals in where clause * misc err change * adopt comparison_coercion * Fix comments * Fix comments
1 parent 1b9b35c commit d91a03f

File tree

2 files changed

+20
-31
lines changed

2 files changed

+20
-31
lines changed

datafusion/optimizer/src/analyzer/type_coercion.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ impl AnalyzerRule for TypeCoercion {
8484
/// Assumes that children have already been optimized
8585
fn analyze_internal(
8686
external_schema: &DFSchema,
87-
plan: LogicalPlan,
87+
mut plan: LogicalPlan,
8888
) -> Result<Transformed<LogicalPlan>> {
8989
// get schema representing all available input fields. This is used for data type
9090
// resolution only, so order does not matter here
@@ -103,6 +103,16 @@ fn analyze_internal(
103103
// select t2.c2 from t1 where t1.c1 in (select t2.c1 from t2 where t2.c2=t1.c3)
104104
schema.merge(external_schema);
105105

106+
if let LogicalPlan::Filter(filter) = &mut plan {
107+
if let Ok(new_predicate) = filter
108+
.predicate
109+
.clone()
110+
.cast_to(&DataType::Boolean, filter.input.schema())
111+
{
112+
filter.predicate = new_predicate;
113+
}
114+
}
115+
106116
let mut expr_rewrite = TypeCoercionRewriter::new(&schema);
107117

108118
let name_preserver = NamePreserver::new(&plan);

datafusion/physical-plan/src/filter.rs

Lines changed: 9 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,11 @@ use crate::{
2828
metrics::{BaselineMetrics, ExecutionPlanMetricsSet, MetricsSet},
2929
DisplayFormatType, ExecutionPlan,
3030
};
31+
3132
use arrow::compute::filter_record_batch;
3233
use arrow::datatypes::{DataType, SchemaRef};
3334
use arrow::record_batch::RecordBatch;
34-
use arrow_array::{Array, BooleanArray};
35-
use datafusion_common::cast::{as_boolean_array, as_null_array};
35+
use datafusion_common::cast::as_boolean_array;
3636
use datafusion_common::stats::Precision;
3737
use datafusion_common::{internal_err, plan_err, DataFusionError, Result};
3838
use datafusion_execution::TaskContext;
@@ -81,19 +81,6 @@ impl FilterExec {
8181
cache,
8282
})
8383
}
84-
DataType::Null => {
85-
let default_selectivity = 0;
86-
let cache =
87-
Self::compute_properties(&input, &predicate, default_selectivity)?;
88-
89-
Ok(Self {
90-
predicate,
91-
input: Arc::clone(&input),
92-
metrics: ExecutionPlanMetricsSet::new(),
93-
default_selectivity,
94-
cache,
95-
})
96-
}
9784
other => {
9885
plan_err!("Filter predicate must return BOOLEAN values, got {other:?}")
9986
}
@@ -367,23 +354,15 @@ pub(crate) fn batch_filter(
367354
.evaluate(batch)
368355
.and_then(|v| v.into_array(batch.num_rows()))
369356
.and_then(|array| {
370-
let filter_array = match as_boolean_array(&array) {
371-
Ok(boolean_array) => Ok(boolean_array.to_owned()),
357+
Ok(match as_boolean_array(&array) {
358+
// apply filter array to record batch
359+
Ok(filter_array) => filter_record_batch(batch, filter_array)?,
372360
Err(_) => {
373-
let Ok(null_array) = as_null_array(&array) else {
374-
return internal_err!(
375-
"Cannot create filter_array from non-boolean predicates"
376-
);
377-
};
378-
379-
// if the predicate is null, then the result is also null
380-
Ok::<BooleanArray, DataFusionError>(BooleanArray::new_null(
381-
null_array.len(),
382-
))
361+
return internal_err!(
362+
"Cannot create filter_array from non-boolean predicates"
363+
);
383364
}
384-
}?;
385-
386-
Ok(filter_record_batch(batch, &filter_array)?)
365+
})
387366
})
388367
}
389368

0 commit comments

Comments
 (0)