vortex_array/scalar_fn/
foreign.rs1use std::fmt;
5use std::fmt::Display;
6use std::fmt::Formatter;
7
8use vortex_error::VortexResult;
9use vortex_error::vortex_bail;
10use vortex_session::VortexSession;
11
12use crate::ArrayRef;
13use crate::ExecutionCtx;
14use crate::dtype::DType;
15use crate::dtype::Nullability;
16use crate::expr::Expression;
17use crate::scalar_fn::Arity;
18use crate::scalar_fn::ChildName;
19use crate::scalar_fn::ExecutionArgs;
20use crate::scalar_fn::ScalarFn;
21use crate::scalar_fn::ScalarFnId;
22use crate::scalar_fn::ScalarFnRef;
23use crate::scalar_fn::ScalarFnVTable;
24
25#[derive(Clone, Debug, PartialEq, Eq, Hash)]
27pub struct ForeignScalarFnOptions {
28 metadata: Vec<u8>,
29 arity: usize,
30}
31
32impl ForeignScalarFnOptions {
33 pub fn new(metadata: Vec<u8>, arity: usize) -> Self {
34 Self { metadata, arity }
35 }
36}
37
38impl Display for ForeignScalarFnOptions {
39 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
40 write!(
41 f,
42 "foreign(arity={}, metadata={}B)",
43 self.arity,
44 self.metadata.len()
45 )
46 }
47}
48
49#[derive(Clone, Debug)]
51pub struct ForeignScalarFnVTable {
52 id: ScalarFnId,
53}
54
55impl ForeignScalarFnVTable {
56 pub fn new(id: ScalarFnId) -> Self {
57 Self { id }
58 }
59
60 pub fn make_scalar_fn(id: ScalarFnId, metadata: Vec<u8>, arity: usize) -> ScalarFnRef {
61 ScalarFn::new(Self::new(id), ForeignScalarFnOptions::new(metadata, arity)).erased()
62 }
63}
64
65impl ScalarFnVTable for ForeignScalarFnVTable {
66 type Options = ForeignScalarFnOptions;
67
68 fn id(&self) -> ScalarFnId {
69 self.id.clone()
70 }
71
72 fn serialize(&self, options: &Self::Options) -> VortexResult<Option<Vec<u8>>> {
73 Ok(Some(options.metadata.clone()))
74 }
75
76 fn deserialize(
77 &self,
78 metadata: &[u8],
79 _session: &VortexSession,
80 ) -> VortexResult<Self::Options> {
81 Ok(ForeignScalarFnOptions::new(metadata.to_vec(), 0))
82 }
83
84 fn arity(&self, options: &Self::Options) -> Arity {
85 Arity::Exact(options.arity)
86 }
87
88 fn child_name(&self, _options: &Self::Options, child_idx: usize) -> ChildName {
89 ChildName::new_arc(format!("arg{child_idx}").into())
90 }
91
92 fn fmt_sql(
93 &self,
94 _options: &Self::Options,
95 expr: &Expression,
96 f: &mut Formatter<'_>,
97 ) -> fmt::Result {
98 write!(f, "{}(", self.id)?;
99 for i in 0..expr.children().len() {
100 if i > 0 {
101 write!(f, ", ")?;
102 }
103 expr.child(i).fmt_sql(f)?;
104 }
105 write!(f, ")")
106 }
107
108 fn return_dtype(&self, _options: &Self::Options, _args: &[DType]) -> VortexResult<DType> {
109 Ok(DType::Variant(Nullability::Nullable))
110 }
111
112 fn execute(
113 &self,
114 _options: &Self::Options,
115 _args: &dyn ExecutionArgs,
116 _ctx: &mut ExecutionCtx,
117 ) -> VortexResult<ArrayRef> {
118 vortex_bail!("Cannot execute unknown scalar function '{}'", self.id);
119 }
120}