datafusion_comet_spark_expr/predicate_funcs/
is_nan.rs1use arrow::array::{Float32Array, Float64Array};
19use arrow_array::{Array, BooleanArray};
20use arrow_schema::DataType;
21use datafusion::physical_plan::ColumnarValue;
22use datafusion_common::{DataFusionError, ScalarValue};
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 {:?} for function isnan",
54 other,
55 ))),
56 },
57 ColumnarValue::Scalar(a) => match a {
58 ScalarValue::Float64(a) => Ok(ColumnarValue::Scalar(ScalarValue::Boolean(Some(
59 a.map(|x| x.is_nan()).unwrap_or(false),
60 )))),
61 ScalarValue::Float32(a) => Ok(ColumnarValue::Scalar(ScalarValue::Boolean(Some(
62 a.map(|x| x.is_nan()).unwrap_or(false),
63 )))),
64 _ => Err(DataFusionError::Internal(format!(
65 "Unsupported data type {:?} for function isnan",
66 value.data_type(),
67 ))),
68 },
69 }
70}