Skip to content

Commit

Permalink
Teach a negative NULL expression to return NULL instead of an error (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
drrtuy authored Oct 10, 2022
1 parent 8022827 commit c02e9d4
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 2 deletions.
18 changes: 18 additions & 0 deletions datafusion/core/tests/sql/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -646,6 +646,24 @@ async fn test_not_expressions() -> Result<()> {
Ok(())
}

#[tokio::test]
async fn test_negative_expressions() -> Result<()> {
let ctx = SessionContext::new();

let sql = "SELECT null, -null";
let actual = execute_to_batches(&ctx, sql).await;
let expected = vec![
"+------+----------+",
"| NULL | (- NULL) |",
"+------+----------+",
"| | |",
"+------+----------+",
];

assert_batches_eq!(expected, &actual);
Ok(())
}

#[tokio::test]
async fn test_boolean_expressions() -> Result<()> {
test_expression!("true", "true");
Expand Down
5 changes: 5 additions & 0 deletions datafusion/expr/src/type_coercion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ pub fn is_signed_numeric(dt: &DataType) -> bool {
)
}

// Determine if a DataType is Null or not
pub fn is_null(dt: &DataType) -> bool {
*dt == DataType::Null
}

/// Determine if a DataType is numeric or not
pub fn is_numeric(dt: &DataType) -> bool {
is_signed_numeric(dt)
Expand Down
9 changes: 7 additions & 2 deletions datafusion/physical-expr/src/expressions/negative.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,10 @@ use arrow::{

use crate::PhysicalExpr;
use datafusion_common::{DataFusionError, Result};
use datafusion_expr::{type_coercion::is_signed_numeric, ColumnarValue};
use datafusion_expr::{
type_coercion::{is_null, is_signed_numeric},
ColumnarValue,
};

/// Invoke a compute kernel on array(s)
macro_rules! compute_op {
Expand Down Expand Up @@ -119,7 +122,9 @@ pub fn negative(
input_schema: &Schema,
) -> Result<Arc<dyn PhysicalExpr>> {
let data_type = arg.data_type(input_schema)?;
if !is_signed_numeric(&data_type) {
if is_null(&data_type) {
Ok(arg)
} else if !is_signed_numeric(&data_type) {
Err(DataFusionError::Internal(
format!("Can't create negative physical expr for (- '{:?}'), the type of child expr is {}, not signed numeric", arg, data_type),
))
Expand Down

0 comments on commit c02e9d4

Please sign in to comment.