Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 34 additions & 14 deletions datafusion/common/src/scalar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -710,24 +710,26 @@ impl ScalarValue {
}

/// Calculate arithmetic negation for a scalar value
pub fn arithmetic_negate(&self) -> Self {
pub fn arithmetic_negate(&self) -> Result<Self> {
match self {
ScalarValue::Boolean(None)
| ScalarValue::Int8(None)
ScalarValue::Int8(None)
| ScalarValue::Int16(None)
| ScalarValue::Int32(None)
| ScalarValue::Int64(None)
| ScalarValue::Float32(None) => self.clone(),
ScalarValue::Float64(Some(v)) => ScalarValue::Float64(Some(-v)),
ScalarValue::Float32(Some(v)) => ScalarValue::Float32(Some(-v)),
ScalarValue::Int8(Some(v)) => ScalarValue::Int8(Some(-v)),
ScalarValue::Int16(Some(v)) => ScalarValue::Int16(Some(-v)),
ScalarValue::Int32(Some(v)) => ScalarValue::Int32(Some(-v)),
ScalarValue::Int64(Some(v)) => ScalarValue::Int64(Some(-v)),
| ScalarValue::Float32(None) => Ok(self.clone()),
ScalarValue::Float64(Some(v)) => Ok(ScalarValue::Float64(Some(-v))),
ScalarValue::Float32(Some(v)) => Ok(ScalarValue::Float32(Some(-v))),
ScalarValue::Int8(Some(v)) => Ok(ScalarValue::Int8(Some(-v))),
ScalarValue::Int16(Some(v)) => Ok(ScalarValue::Int16(Some(-v))),
ScalarValue::Int32(Some(v)) => Ok(ScalarValue::Int32(Some(-v))),
ScalarValue::Int64(Some(v)) => Ok(ScalarValue::Int64(Some(-v))),
ScalarValue::Decimal128(Some(v), precision, scale) => {
ScalarValue::Decimal128(Some(-v), *precision, *scale)
Ok(ScalarValue::Decimal128(Some(-v), *precision, *scale))
}
_ => panic!("Cannot run arithmetic negate on scalar value: {:?}", self),
value => Err(DataFusionError::Internal(format!(
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

replace the panic with the error
cc @andygrove

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

"Can not run arithmetic negative on scalar value {:?}",
value
))),
}
}

Expand Down Expand Up @@ -2173,13 +2175,13 @@ mod tests {
use std::sync::Arc;

#[test]
fn scalar_decimal_test() {
fn scalar_decimal_test() -> Result<()> {
let decimal_value = ScalarValue::Decimal128(Some(123), 10, 1);
assert_eq!(DataType::Decimal128(10, 1), decimal_value.get_datatype());
let try_into_value: i128 = decimal_value.clone().try_into().unwrap();
assert_eq!(123_i128, try_into_value);
assert!(!decimal_value.is_null());
let neg_decimal_value = decimal_value.arithmetic_negate();
let neg_decimal_value = decimal_value.arithmetic_negate()?;
match neg_decimal_value {
ScalarValue::Decimal128(v, _, _) => {
assert_eq!(-123, v.unwrap());
Expand Down Expand Up @@ -2267,6 +2269,8 @@ mod tests {
ScalarValue::Decimal128(None, 10, 2),
ScalarValue::try_from_array(&array, 4).unwrap()
);

Ok(())
}

#[test]
Expand Down Expand Up @@ -3392,4 +3396,20 @@ mod tests {
// The datatype should be "Dictionary" but is actually Utf8!!!
assert_eq!(array.data_type(), &desired_type)
}

#[test]
fn test_scalar_negative() -> Result<()> {
// positive test
let value = ScalarValue::Int32(Some(12));
assert_eq!(ScalarValue::Int32(Some(-12)), value.arithmetic_negate()?);
let value = ScalarValue::Int32(None);
assert_eq!(ScalarValue::Int32(None), value.arithmetic_negate()?);

// negative test
let value = ScalarValue::UInt8(Some(12));
assert!(value.arithmetic_negate().is_err());
let value = ScalarValue::Boolean(None);
assert!(value.arithmetic_negate().is_err());
Ok(())
}
}
7 changes: 2 additions & 5 deletions datafusion/physical-expr/src/expressions/negative.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ impl PhysicalExpr for NegativeExpr {
result.map(|a| ColumnarValue::Array(a))
}
ColumnarValue::Scalar(scalar) => {
Ok(ColumnarValue::Scalar(scalar.arithmetic_negate()))
Ok(ColumnarValue::Scalar(scalar.arithmetic_negate()?))
}
}
}
Expand All @@ -121,10 +121,7 @@ pub fn negative(
let data_type = arg.data_type(input_schema)?;
if !is_signed_numeric(&data_type) {
Err(DataFusionError::Internal(
format!(
"(- '{:?}') can't be evaluated because the expression's type is {:?}, not signed numeric",
arg, data_type,
),
format!("Can't create negative physical expr for (- '{:?}'), the type of child expr is {}, not signed numeric", arg, data_type),
))
} else {
Ok(Arc::new(NegativeExpr::new(arg)))
Expand Down