rdf_fusion_functions/builtin/native/
boolean_as_rdf_term.rs1use datafusion::arrow::array::{Array, as_boolean_array};
2use datafusion::arrow::datatypes::DataType;
3use datafusion::common::exec_err;
4use datafusion::logical_expr::{
5 ColumnarValue, ScalarFunctionArgs, ScalarUDF, ScalarUDFImpl, Signature,
6 TypeSignature, Volatility,
7};
8use rdf_fusion_encoding::typed_value::{TYPED_VALUE_ENCODING, TypedValueArrayBuilder};
9use rdf_fusion_encoding::{EncodingArray, TermEncoding};
10use rdf_fusion_extensions::functions::BuiltinName;
11use rdf_fusion_model::DFResult;
12use std::any::Any;
13use std::hash::{Hash, Hasher};
14
15pub fn native_boolean_as_term() -> ScalarUDF {
16 let udf_impl = NativeBooleanAsTerm::new();
17 ScalarUDF::new_from_impl(udf_impl)
18}
19
20#[derive(Debug, Eq)]
21struct NativeBooleanAsTerm {
22 name: String,
23 signature: Signature,
24}
25
26impl NativeBooleanAsTerm {
27 pub fn new() -> Self {
28 Self {
29 name: BuiltinName::NativeBooleanAsTerm.to_string(),
30 signature: Signature::new(
31 TypeSignature::Exact(vec![DataType::Boolean]),
32 Volatility::Immutable,
33 ),
34 }
35 }
36}
37
38impl ScalarUDFImpl for NativeBooleanAsTerm {
39 fn as_any(&self) -> &dyn Any {
40 self
41 }
42
43 fn name(&self) -> &str {
44 &self.name
45 }
46
47 fn signature(&self) -> &Signature {
48 &self.signature
49 }
50
51 fn return_type(&self, _arg_types: &[DataType]) -> DFResult<DataType> {
52 Ok(TYPED_VALUE_ENCODING.data_type())
53 }
54
55 fn invoke_with_args(&self, args: ScalarFunctionArgs) -> DFResult<ColumnarValue> {
56 if args.args.len() != 1 {
57 return exec_err!("Unexpected number of arguments");
58 }
59
60 let arg = &args.args[0];
61 if arg.data_type() != DataType::Boolean {
62 return exec_err!("Unexpected argument type: {:?}", arg.data_type());
63 }
64
65 let arg = arg.to_array(args.number_rows)?;
67 let arg = as_boolean_array(&arg);
68 let mut builder = TypedValueArrayBuilder::default();
69 for i in 0..args.number_rows {
70 if arg.is_null(i) {
71 builder.append_null()?;
72 } else {
73 builder.append_boolean(arg.value(i).into())?;
74 }
75 }
76
77 Ok(ColumnarValue::Array(builder.finish().into_array()))
78 }
79}
80
81impl Hash for NativeBooleanAsTerm {
82 fn hash<H: Hasher>(&self, state: &mut H) {
83 self.as_any().type_id().hash(state);
84 }
85}
86
87impl PartialEq for NativeBooleanAsTerm {
88 fn eq(&self, other: &Self) -> bool {
89 self.as_any().type_id() == other.as_any().type_id()
90 }
91}