diff --git a/datafusion/expr/src/type_coercion/binary.rs b/datafusion/expr/src/type_coercion/binary.rs index 45510cb03e0ed..911874fb09ba2 100644 --- a/datafusion/expr/src/type_coercion/binary.rs +++ b/datafusion/expr/src/type_coercion/binary.rs @@ -98,8 +98,12 @@ pub fn coerce_types( | Operator::BitwiseShiftRight | Operator::BitwiseShiftLeft => bitwise_coercion(lhs_type, rhs_type), Operator::And | Operator::Or => match (lhs_type, rhs_type) { - // logical binary boolean operators can only be evaluated in bools + // logical binary boolean operators can only be evaluated in bools or nulls (DataType::Boolean, DataType::Boolean) => Some(DataType::Boolean), + (DataType::Null, DataType::Null) => Some(DataType::Null), + (DataType::Boolean, DataType::Null) | (DataType::Null, DataType::Boolean) => { + Some(DataType::Boolean) + } _ => None, }, // logical comparison operators have their own rules, and always return a boolean @@ -1022,6 +1026,42 @@ mod tests { Operator::Or, DataType::Boolean ); + test_coercion_binary_rule!( + DataType::Boolean, + DataType::Null, + Operator::And, + DataType::Boolean + ); + test_coercion_binary_rule!( + DataType::Boolean, + DataType::Null, + Operator::Or, + DataType::Boolean + ); + test_coercion_binary_rule!( + DataType::Null, + DataType::Null, + Operator::Or, + DataType::Null + ); + test_coercion_binary_rule!( + DataType::Null, + DataType::Null, + Operator::And, + DataType::Null + ); + test_coercion_binary_rule!( + DataType::Null, + DataType::Boolean, + Operator::And, + DataType::Boolean + ); + test_coercion_binary_rule!( + DataType::Null, + DataType::Boolean, + Operator::Or, + DataType::Boolean + ); Ok(()) } }