rdf_fusion_functions/builtin/native/
int64_as_rdf_term.rs

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