Skip to content

Commit

Permalink
Followup Support NULL literals in where clause
Browse files Browse the repository at this point in the history
  • Loading branch information
xinlifoobar committed Jul 16, 2024
1 parent 8c82c46 commit 4ca1b69
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 3 deletions.
2 changes: 1 addition & 1 deletion datafusion/expr/src/logical_plan/plan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2091,7 +2091,7 @@ impl Filter {
// construction (such as with correlated subqueries) so we make a best effort here and
// ignore errors resolving the expression against the schema.
if let Ok(predicate_type) = predicate.get_type(input.schema()) {
if predicate_type != DataType::Boolean {
if predicate_type != DataType::Boolean && predicate_type != DataType::Null {
return plan_err!(
"Cannot create filter with non-boolean predicate '{predicate}' returning {predicate_type}"
);
Expand Down
17 changes: 15 additions & 2 deletions datafusion/optimizer/src/analyzer/type_coercion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,9 @@ use datafusion_expr::type_coercion::{is_datetime, is_utf8_or_large_utf8};
use datafusion_expr::utils::merge_schema;
use datafusion_expr::{
is_false, is_not_false, is_not_true, is_not_unknown, is_true, is_unknown, not,
type_coercion, AggregateFunction, AggregateUDF, Expr, ExprSchemable, LogicalPlan,
Operator, ScalarUDF, Signature, WindowFrame, WindowFrameBound, WindowFrameUnits,
type_coercion, AggregateFunction, AggregateUDF, Expr, ExprSchemable, Filter,
LogicalPlan, Operator, ScalarUDF, Signature, WindowFrame, WindowFrameBound,
WindowFrameUnits,
};

use crate::analyzer::AnalyzerRule;
Expand Down Expand Up @@ -86,6 +87,18 @@ fn analyze_internal(
external_schema: &DFSchema,
plan: LogicalPlan,
) -> Result<Transformed<LogicalPlan>> {
if let LogicalPlan::Filter(Filter {
predicate, input, ..
}) = &plan
{
if predicate == &Expr::Literal(ScalarValue::Null) {
return Ok(Transformed::yes(LogicalPlan::Filter(Filter::try_new(
Expr::Literal(ScalarValue::Boolean(Some(false))),
Arc::clone(input),
)?)));
}
}

// get schema representing all available input fields. This is used for data type
// resolution only, so order does not matter here
let mut schema = merge_schema(plan.inputs());
Expand Down
13 changes: 13 additions & 0 deletions datafusion/sqllogictest/test_files/misc.slt
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,16 @@ query TT?
select 'foo', '', NULL
----
foo (empty) NULL

query I
select 1 where NULL
----

query I
select 1 where NULL and 1 = 1
----

query I
select 1 where NULL or 1 = 1
----
1

0 comments on commit 4ca1b69

Please sign in to comment.