vortex_array/expr/functions/
scalar.rs1use std::any::Any;
5use std::fmt::Debug;
6use std::fmt::Display;
7use std::fmt::Formatter;
8use std::hash::Hash;
9use std::hash::Hasher;
10
11use vortex_dtype::DType;
12use vortex_error::VortexResult;
13use vortex_utils::debug_with::DebugWith;
14use vortex_vector::Datum;
15
16use crate::expr::Expression;
17use crate::expr::StatsCatalog;
18use crate::expr::functions::ArgName;
19use crate::expr::functions::Arity;
20use crate::expr::functions::FunctionId;
21use crate::expr::functions::NullHandling;
22use crate::expr::functions::ScalarFnVTable;
23use crate::expr::functions::VTable;
24use crate::expr::functions::execution::ExecutionArgs;
25use crate::expr::stats::Stat;
26
27pub struct ScalarFn {
29 vtable: ScalarFnVTable,
30 options: Box<dyn Any + Send + Sync>,
31}
32
33impl ScalarFn {
34 pub fn new<V: VTable>(vtable: V, options: V::Options) -> ScalarFn {
36 let vtable = ScalarFnVTable::new::<V>(vtable);
37 let options = Box::new(options);
38 ScalarFn { vtable, options }
39 }
40
41 pub fn new_static<V: VTable>(vtable: &'static V, options: V::Options) -> ScalarFn {
43 let vtable = ScalarFnVTable::new_static(vtable);
44 let options = Box::new(options);
45 ScalarFn { vtable, options }
46 }
47
48 pub(crate) unsafe fn new_unchecked(
54 vtable: ScalarFnVTable,
55 options: Box<dyn Any + Send + Sync>,
56 ) -> Self {
57 Self { vtable, options }
58 }
59
60 pub fn id(&self) -> FunctionId {
62 self.vtable.id()
63 }
64
65 pub fn vtable(&self) -> &ScalarFnVTable {
67 &self.vtable
68 }
69
70 pub fn options(&self) -> ScalarFnOptions<'_> {
72 ScalarFnOptions {
73 vtable: &self.vtable,
74 options: self.options.as_ref(),
75 }
76 }
77
78 pub fn signature(&self) -> ScalarFnSignature<'_> {
80 ScalarFnSignature {
81 vtable: &self.vtable,
82 options: self.options.as_ref(),
83 }
84 }
85
86 pub fn stat_falsification(
87 &self,
88 expr: &Expression,
89 catalog: &dyn StatsCatalog,
90 ) -> Option<Expression> {
91 self.vtable
92 .as_dyn()
93 .stat_falsification(self.options.as_ref(), expr, catalog)
94 }
95
96 pub fn stat_expression(
97 &self,
98 expr: &Expression,
99 stat: Stat,
100 catalog: &dyn StatsCatalog,
101 ) -> Option<Expression> {
102 self.vtable
103 .as_dyn()
104 .stat_expression(self.options.as_ref(), expr, stat, catalog)
105 }
106
107 pub fn return_dtype(&self, arg_types: &[DType]) -> VortexResult<DType> {
108 self.vtable
109 .as_dyn()
110 .return_dtype(self.options.as_ref(), arg_types)
111 }
112
113 pub fn execute(&self, args: &ExecutionArgs) -> VortexResult<Datum> {
114 self.vtable.as_dyn().execute(self.options.as_ref(), args)
115 }
116}
117
118impl Clone for ScalarFn {
119 fn clone(&self) -> Self {
120 Self {
121 vtable: self.vtable.clone(),
122 options: self.vtable.as_dyn().options_clone(self.options.as_ref()),
123 }
124 }
125}
126
127impl Debug for ScalarFn {
128 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
129 f.debug_struct("ScalarFn")
130 .field("id", &self.vtable.id())
131 .field(
132 "options",
133 &DebugWith(|fmt| {
134 self.vtable
135 .as_dyn()
136 .options_debug(self.options.as_ref(), fmt)
137 }),
138 )
139 .finish()
140 }
141}
142
143impl Display for ScalarFn {
144 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
145 write!(f, "{}(", self.vtable.id())?;
146 self.vtable
147 .as_dyn()
148 .options_display(self.options.as_ref(), f)?;
149 write!(f, ")")
150 }
151}
152
153impl PartialEq for ScalarFn {
154 fn eq(&self, other: &Self) -> bool {
155 self.vtable.id() == other.vtable.id()
156 && self
157 .vtable
158 .as_dyn()
159 .options_eq(self.options.as_ref(), other.options.as_ref())
160 }
161}
162impl Eq for ScalarFn {}
163
164impl Hash for ScalarFn {
165 fn hash<H: Hasher>(&self, state: &mut H) {
166 self.vtable.id().hash(state);
167 self.vtable
168 .as_dyn()
169 .options_hash(self.options.as_ref(), state);
170 }
171}
172
173pub struct ScalarFnSignature<'a> {
175 pub(crate) vtable: &'a ScalarFnVTable,
176 pub(crate) options: &'a dyn Any,
177}
178
179impl ScalarFnSignature<'_> {
180 pub fn arity(&self) -> Arity {
181 self.vtable.as_dyn().arity(self.options)
182 }
183
184 pub fn null_handling(&self) -> NullHandling {
185 self.vtable.as_dyn().null_handling(self.options)
186 }
187
188 pub fn arg_name(&self, arg_idx: usize) -> ArgName {
189 self.vtable.as_dyn().arg_name(self.options, arg_idx)
190 }
191}
192
193pub struct ScalarFnOptions<'a> {
195 pub(crate) vtable: &'a ScalarFnVTable,
196 pub(crate) options: &'a dyn Any,
197}
198
199impl<'a> ScalarFnOptions<'a> {
200 pub fn as_any(&self) -> &'a dyn Any {
202 self.options
203 }
204}
205
206impl Display for ScalarFnOptions<'_> {
207 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
208 self.vtable.as_dyn().options_display(self.options, f)
209 }
210}
211
212impl Debug for ScalarFnOptions<'_> {
213 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
214 self.vtable.as_dyn().options_debug(self.options, f)
215 }
216}
217
218impl ScalarFnOptions<'_> {
219 pub fn serialize(&self) -> VortexResult<Option<Vec<u8>>> {
221 self.vtable.as_dyn().options_serialize(self.options)
222 }
223}