datafusion_comet_spark_expr/predicate_funcs/
is_nan.rs1use arrow::array::{Array, BooleanArray};
19use arrow::array::{Float32Array, Float64Array};
20use arrow::datatypes::DataType;
21use datafusion::common::{DataFusionError, ScalarValue};
22use datafusion::physical_plan::ColumnarValue;
23use std::sync::Arc;
24
25pub fn spark_isnan(args: &[ColumnarValue]) -> Result<ColumnarValue, DataFusionError> {
27 fn set_nulls_to_false(is_nan: BooleanArray) -> ColumnarValue {
28 match is_nan.nulls() {
29 Some(nulls) => {
30 let is_not_null = nulls.inner();
31 ColumnarValue::Array(Arc::new(BooleanArray::new(
32 is_nan.values() & is_not_null,
33 None,
34 )))
35 }
36 None => ColumnarValue::Array(Arc::new(is_nan)),
37 }
38 }
39 let value = &args[0];
40 match value {
41 ColumnarValue::Array(array) => match array.data_type() {
42 DataType::Float64 => {
43 let array = array.as_any().downcast_ref::<Float64Array>().unwrap();
44 let is_nan = BooleanArray::from_unary(array, |x| x.is_nan());
45 Ok(set_nulls_to_false(is_nan))
46 }
47 DataType::Float32 => {
48 let array = array.as_any().downcast_ref::<Float32Array>().unwrap();
49 let is_nan = BooleanArray::from_unary(array, |x| x.is_nan());
50 Ok(set_nulls_to_false(is_nan))
51 }
52 other => Err(DataFusionError::Internal(format!(
53 "Unsupported data type {other:?} for function isnan",
54 ))),
55 },
56 ColumnarValue::Scalar(a) => match a {
57 ScalarValue::Float64(a) => Ok(ColumnarValue::Scalar(ScalarValue::Boolean(Some(
58 a.map(|x| x.is_nan()).unwrap_or(false),
59 )))),
60 ScalarValue::Float32(a) => Ok(ColumnarValue::Scalar(ScalarValue::Boolean(Some(
61 a.map(|x| x.is_nan()).unwrap_or(false),
62 )))),
63 _ => Err(DataFusionError::Internal(format!(
64 "Unsupported data type {:?} for function isnan",
65 value.data_type(),
66 ))),
67 },
68 }
69}