fn evaluate()

in native/spark-expr/src/math_funcs/negative.rs [112:201]


    fn evaluate(&self, batch: &RecordBatch) -> Result<ColumnarValue> {
        let arg = self.arg.evaluate(batch)?;

        // overflow checks only apply in ANSI mode
        // datatypes supported are byte, short, integer, long, float, interval
        match arg {
            ColumnarValue::Array(array) => {
                if self.fail_on_error {
                    match array.data_type() {
                        DataType::Int8 => {
                            check_overflow!(array, arrow::array::Int8Array, i8::MIN, "byte")
                        }
                        DataType::Int16 => {
                            check_overflow!(array, arrow::array::Int16Array, i16::MIN, "short")
                        }
                        DataType::Int32 => {
                            check_overflow!(array, arrow::array::Int32Array, i32::MIN, "integer")
                        }
                        DataType::Int64 => {
                            check_overflow!(array, arrow::array::Int64Array, i64::MIN, "long")
                        }
                        DataType::Interval(value) => match value {
                            arrow::datatypes::IntervalUnit::YearMonth => check_overflow!(
                                array,
                                arrow::array::IntervalYearMonthArray,
                                i32::MIN,
                                "interval"
                            ),
                            arrow::datatypes::IntervalUnit::DayTime => check_overflow!(
                                array,
                                arrow::array::IntervalDayTimeArray,
                                IntervalDayTime::MIN,
                                "interval"
                            ),
                            arrow::datatypes::IntervalUnit::MonthDayNano => {
                                // Overflow checks are not supported
                            }
                        },
                        _ => {
                            // Overflow checks are not supported for other datatypes
                        }
                    }
                }
                let result = neg_wrapping(array.as_ref())?;
                Ok(ColumnarValue::Array(result))
            }
            ColumnarValue::Scalar(scalar) => {
                if self.fail_on_error {
                    match scalar {
                        ScalarValue::Int8(value) => {
                            if value == Some(i8::MIN) {
                                return Err(arithmetic_overflow_error(" caused").into());
                            }
                        }
                        ScalarValue::Int16(value) => {
                            if value == Some(i16::MIN) {
                                return Err(arithmetic_overflow_error(" caused").into());
                            }
                        }
                        ScalarValue::Int32(value) => {
                            if value == Some(i32::MIN) {
                                return Err(arithmetic_overflow_error("integer").into());
                            }
                        }
                        ScalarValue::Int64(value) => {
                            if value == Some(i64::MIN) {
                                return Err(arithmetic_overflow_error("long").into());
                            }
                        }
                        ScalarValue::IntervalDayTime(value) => {
                            let (days, ms) =
                                IntervalDayTimeType::to_parts(value.unwrap_or_default());
                            if days == i32::MIN || ms == i32::MIN {
                                return Err(arithmetic_overflow_error("interval").into());
                            }
                        }
                        ScalarValue::IntervalYearMonth(value) => {
                            if value == Some(i32::MIN) {
                                return Err(arithmetic_overflow_error("interval").into());
                            }
                        }
                        _ => {
                            // Overflow checks are not supported for other datatypes
                        }
                    }
                }
                Ok(ColumnarValue::Scalar((scalar.arithmetic_negate())?))
            }
        }
    }