rdf_fusion_functions/scalar/terms/
bnode.rs

1use crate::scalar::dispatch::dispatch_unary_typed_value;
2use crate::scalar::sparql_op_impl::{
3    ScalarSparqlOpImpl, create_typed_value_sparql_op_impl,
4};
5use crate::scalar::{ScalarSparqlOp, ScalarSparqlOpSignature, SparqlOpArity};
6use datafusion::logical_expr::{ColumnarValue, Volatility};
7use rdf_fusion_encoding::EncodingArray;
8use rdf_fusion_encoding::typed_value::{TypedValueArrayBuilder, TypedValueEncoding};
9use rdf_fusion_extensions::functions::BuiltinName;
10use rdf_fusion_extensions::functions::FunctionName;
11use rdf_fusion_model::{BlankNode, BlankNodeRef, ThinError, TypedValueRef};
12
13#[derive(Debug, Hash, PartialEq, Eq)]
14pub struct BNodeSparqlOp;
15
16impl Default for BNodeSparqlOp {
17    fn default() -> Self {
18        Self::new()
19    }
20}
21
22impl BNodeSparqlOp {
23    const NAME: FunctionName = FunctionName::Builtin(BuiltinName::BNode);
24
25    pub fn new() -> Self {
26        Self {}
27    }
28}
29
30impl ScalarSparqlOp for BNodeSparqlOp {
31    fn name(&self) -> &FunctionName {
32        &Self::NAME
33    }
34
35    fn signature(&self) -> ScalarSparqlOpSignature {
36        ScalarSparqlOpSignature {
37            volatility: Volatility::Volatile,
38            arity: SparqlOpArity::OneOf(vec![
39                SparqlOpArity::Nullary,
40                SparqlOpArity::Fixed(1),
41            ]),
42        }
43    }
44
45    fn typed_value_encoding_op(
46        &self,
47    ) -> Option<Box<dyn ScalarSparqlOpImpl<TypedValueEncoding>>> {
48        Some(create_typed_value_sparql_op_impl(|args| {
49            match args.args.len() {
50                0 => {
51                    let mut builder = TypedValueArrayBuilder::default();
52                    for _ in 0..args.number_rows {
53                        builder.append_blank_node(BlankNode::default().as_ref())?;
54                    }
55                    Ok(ColumnarValue::Array(builder.finish().into_array()))
56                }
57                1 => dispatch_unary_typed_value(
58                    &args.args[0],
59                    |value| match value {
60                        TypedValueRef::SimpleLiteral(value) => {
61                            let bnode = BlankNodeRef::new(value.value)?;
62                            Ok(TypedValueRef::BlankNode(bnode))
63                        }
64                        _ => ThinError::expected(),
65                    },
66                    ThinError::expected,
67                ),
68                _ => unreachable!("Invalid number of arguments"),
69            }
70        }))
71    }
72}