| 179 | } |
| 180 | |
| 181 | fn invoke_with_args(&self, args: ScalarFunctionArgs) -> Result<ColumnarValue> { |
| 182 | let [first_arg, second_arg] = take_function_args(self.name(), &args.args)?; |
| 183 | if first_arg.data_type().is_null() { |
| 184 | // Always return null if the first argument is null |
| 185 | // i.e. array_has(null, element) -> null |
| 186 | return Ok(ColumnarValue::Scalar(ScalarValue::Boolean(None))); |
| 187 | } |
| 188 | |
| 189 | match &second_arg { |
| 190 | ColumnarValue::Array(array_needle) => { |
| 191 | // the needle is already an array, convert the haystack to an array of the same length |
| 192 | let haystack = first_arg.to_array(array_needle.len())?; |
| 193 | let array = array_has_inner_for_array(&haystack, array_needle)?; |
| 194 | Ok(ColumnarValue::Array(array)) |
| 195 | } |
| 196 | ColumnarValue::Scalar(scalar_needle) => { |
| 197 | // Always return null if the second argument is null |
| 198 | // i.e. array_has(array, null) -> null |
| 199 | if scalar_needle.is_null() { |
| 200 | return Ok(ColumnarValue::Scalar(ScalarValue::Boolean(None))); |
| 201 | } |
| 202 | |
| 203 | // since the needle is a scalar, convert it to an array of size 1 |
| 204 | let haystack = first_arg.to_array(1)?; |
| 205 | let needle = scalar_needle.to_array_of_size(1)?; |
| 206 | let needle = Scalar::new(needle); |
| 207 | let array = array_has_inner_for_scalar(&haystack, &needle)?; |
| 208 | if let ColumnarValue::Scalar(_) = &first_arg { |
| 209 | // If both inputs are scalar, keeps output as scalar |
| 210 | let scalar_value = ScalarValue::try_from_array(&array, 0)?; |
| 211 | Ok(ColumnarValue::Scalar(scalar_value)) |
| 212 | } else { |
| 213 | Ok(ColumnarValue::Array(array)) |
| 214 | } |
| 215 | } |
| 216 | } |
| 217 | } |
| 218 | |
| 219 | fn aliases(&self) -> &[String] { |
| 220 | &self.aliases |