common_function/scalars/expression/
is_null.rs1use std::fmt;
16use std::fmt::Display;
17use std::sync::Arc;
18
19use common_query::error;
20use common_query::error::{ArrowComputeSnafu, InvalidFuncArgsSnafu};
21use common_query::prelude::{Signature, Volatility};
22use datafusion::arrow::array::ArrayRef;
23use datafusion::arrow::compute::is_null;
24use datatypes::data_type::ConcreteDataType;
25use datatypes::prelude::VectorRef;
26use datatypes::vectors::Helper;
27use snafu::{ensure, ResultExt};
28
29use crate::function::{Function, FunctionContext};
30
31const NAME: &str = "isnull";
32
33#[derive(Clone, Debug, Default)]
35pub struct IsNullFunction;
36
37impl Display for IsNullFunction {
38 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
39 write!(f, "{}", NAME.to_ascii_uppercase())
40 }
41}
42
43impl Function for IsNullFunction {
44 fn name(&self) -> &str {
45 NAME
46 }
47
48 fn return_type(&self, _: &[ConcreteDataType]) -> common_query::error::Result<ConcreteDataType> {
49 Ok(ConcreteDataType::boolean_datatype())
50 }
51
52 fn signature(&self) -> Signature {
53 Signature::any(1, Volatility::Immutable)
54 }
55
56 fn eval(
57 &self,
58 _func_ctx: &FunctionContext,
59 columns: &[VectorRef],
60 ) -> common_query::error::Result<VectorRef> {
61 ensure!(
62 columns.len() == 1,
63 InvalidFuncArgsSnafu {
64 err_msg: format!(
65 "The length of the args is not correct, expect exactly one, have: {}",
66 columns.len()
67 ),
68 }
69 );
70 let values = &columns[0];
71 let arrow_array = &values.to_arrow_array();
72 let result = is_null(arrow_array).context(ArrowComputeSnafu)?;
73
74 Helper::try_into_vector(Arc::new(result) as ArrayRef).context(error::FromArrowArraySnafu)
75 }
76}
77
78#[cfg(test)]
79mod tests {
80 use std::sync::Arc;
81
82 use common_query::prelude::TypeSignature;
83 use datatypes::scalars::ScalarVector;
84 use datatypes::vectors::{BooleanVector, Float32Vector};
85
86 use super::*;
87 #[test]
88 fn test_is_null_function() {
89 let is_null = IsNullFunction;
90 assert_eq!("isnull", is_null.name());
91 assert_eq!(
92 ConcreteDataType::boolean_datatype(),
93 is_null.return_type(&[]).unwrap()
94 );
95 assert_eq!(
96 is_null.signature(),
97 Signature {
98 type_signature: TypeSignature::Any(1),
99 volatility: Volatility::Immutable
100 }
101 );
102 let values = vec![None, Some(3.0), None];
103
104 let args: Vec<VectorRef> = vec![Arc::new(Float32Vector::from(values))];
105 let vector = is_null.eval(&FunctionContext::default(), &args).unwrap();
106 let expect: VectorRef = Arc::new(BooleanVector::from_vec(vec![true, false, true]));
107 assert_eq!(expect, vector);
108 }
109}