diff --git a/datafusion/optimizer/src/analyzer/type_coercion.rs b/datafusion/optimizer/src/analyzer/type_coercion.rs index 8c4e907e67342..c0dad2ef40063 100644 --- a/datafusion/optimizer/src/analyzer/type_coercion.rs +++ b/datafusion/optimizer/src/analyzer/type_coercion.rs @@ -44,7 +44,7 @@ use datafusion_expr::type_coercion::other::{ 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, + is_false, is_not_false, is_not_true, is_not_unknown, is_true, is_unknown, not, type_coercion, AggregateFunction, BuiltinScalarFunction, Expr, ExprSchemable, LogicalPlan, Operator, Projection, ScalarFunctionDefinition, Signature, WindowFrame, WindowFrameBound, WindowFrameUnits, @@ -176,6 +176,10 @@ impl TreeNodeRewriter for TypeCoercionRewriter { negated, ))) } + Expr::Not(expr) => { + let expr = not(get_casted_expr_for_bool_op(&expr, &self.schema)?); + Ok(expr) + } Expr::IsTrue(expr) => { let expr = is_true(get_casted_expr_for_bool_op(&expr, &self.schema)?); Ok(expr) diff --git a/datafusion/physical-expr/src/expressions/not.rs b/datafusion/physical-expr/src/expressions/not.rs index 4ceccc6932fe4..f17df73e30708 100644 --- a/datafusion/physical-expr/src/expressions/not.rs +++ b/datafusion/physical-expr/src/expressions/not.rs @@ -26,9 +26,7 @@ use crate::physical_expr::down_cast_any_ref; use crate::PhysicalExpr; use arrow::datatypes::{DataType, Schema}; use arrow::record_batch::RecordBatch; -use datafusion_common::{ - cast::as_boolean_array, internal_err, DataFusionError, Result, ScalarValue, -}; +use datafusion_common::{cast::as_boolean_array, Result, ScalarValue}; use datafusion_expr::ColumnarValue; /// Not expression @@ -83,13 +81,6 @@ impl PhysicalExpr for NotExpr { if scalar.is_null() { return Ok(ColumnarValue::Scalar(ScalarValue::Boolean(None))); } - let value_type = scalar.data_type(); - if value_type != DataType::Boolean { - return internal_err!( - "NOT '{:?}' can't be evaluated because the expression's type is {:?}, not boolean or NULL", - self.arg, value_type - ); - } let bool_value: bool = scalar.try_into()?; Ok(ColumnarValue::Scalar(ScalarValue::Boolean(Some( !bool_value, diff --git a/datafusion/sqllogictest/test_files/scalar.slt b/datafusion/sqllogictest/test_files/scalar.slt index 3e8ebe54c09c6..5b3ecab5fd769 100644 --- a/datafusion/sqllogictest/test_files/scalar.slt +++ b/datafusion/sqllogictest/test_files/scalar.slt @@ -1527,7 +1527,7 @@ SELECT not(true), not(false) ---- false true -query error +query error type_coercion\ncaused by\nError during planning: Cannot infer common argument type for comparison operation Int64 IS DISTINCT FROM Boolean SELECT not(1), not(0) query ?B @@ -1535,7 +1535,7 @@ SELECT null, not(null) ---- NULL NULL -query error +query error type_coercion\ncaused by\nError during planning: Cannot infer common argument type for comparison operation Utf8 IS DISTINCT FROM Boolean SELECT NOT('hi') # test_negative_expressions()