vortex_array/scalar_fn/
erased.rs1use std::any::type_name;
7use std::fmt::Debug;
8use std::fmt::Display;
9use std::fmt::Formatter;
10use std::hash::Hash;
11use std::hash::Hasher;
12use std::sync::Arc;
13
14use vortex_error::VortexExpect;
15use vortex_error::VortexResult;
16use vortex_error::vortex_err;
17use vortex_utils::debug_with::DebugWith;
18
19use crate::ArrayRef;
20use crate::ExecutionCtx;
21use crate::dtype::DType;
22use crate::expr::BoundExpression;
23use crate::expr::display::ExprDisplay;
24use crate::scalar_fn::ArrayReduceNode;
25use crate::scalar_fn::ExecutionArgs;
26use crate::scalar_fn::ExpressionReduceNode;
27use crate::scalar_fn::ReduceNodeValidity;
28use crate::scalar_fn::ScalarFnId;
29use crate::scalar_fn::ScalarFnVTable;
30use crate::scalar_fn::options::ScalarFnOptions;
31use crate::scalar_fn::signature::ScalarFnSignature;
32use crate::scalar_fn::typed::DynScalarFn;
33use crate::scalar_fn::typed::TypedScalarFnInstance;
34
35#[derive(Clone)]
43pub struct ScalarFnRef(pub(super) Arc<dyn DynScalarFn>);
44
45impl ScalarFnRef {
46 pub fn id(&self) -> ScalarFnId {
48 self.0.id()
49 }
50
51 pub fn is<V: ScalarFnVTable>(&self) -> bool {
53 self.0.as_any().is::<TypedScalarFnInstance<V>>()
54 }
55
56 pub fn as_opt<V: ScalarFnVTable>(&self) -> Option<&V::Options> {
58 self.0
59 .as_any()
60 .downcast_ref::<TypedScalarFnInstance<V>>()
61 .map(|sf| sf.options())
62 }
63
64 pub fn as_<V: ScalarFnVTable>(&self) -> &V::Options {
70 self.as_opt::<V>()
71 .vortex_expect("Expression options type mismatch")
72 }
73
74 pub fn try_downcast<V: ScalarFnVTable>(
78 self,
79 ) -> Result<Arc<TypedScalarFnInstance<V>>, ScalarFnRef> {
80 if self.0.as_any().is::<TypedScalarFnInstance<V>>() {
81 let ptr = Arc::into_raw(self.0) as *const TypedScalarFnInstance<V>;
82 Ok(unsafe { Arc::from_raw(ptr) })
83 } else {
84 Err(self)
85 }
86 }
87
88 pub fn downcast<V: ScalarFnVTable>(self) -> Arc<TypedScalarFnInstance<V>> {
94 self.try_downcast::<V>()
95 .map_err(|this| {
96 vortex_err!(
97 "Failed to downcast ScalarFnRef {} to {}",
98 this.0.id(),
99 type_name::<V>(),
100 )
101 })
102 .vortex_expect("Failed to downcast ScalarFnRef")
103 }
104
105 pub fn downcast_ref<V: ScalarFnVTable>(&self) -> Option<&TypedScalarFnInstance<V>> {
107 self.0.as_any().downcast_ref::<TypedScalarFnInstance<V>>()
108 }
109
110 pub fn options(&self) -> ScalarFnOptions<'_> {
112 ScalarFnOptions { inner: &*self.0 }
113 }
114
115 pub fn signature(&self) -> ScalarFnSignature<'_> {
117 ScalarFnSignature { inner: &*self.0 }
118 }
119
120 pub fn return_dtype(&self, arg_types: &[DType]) -> VortexResult<DType> {
122 self.0.return_dtype(arg_types)
123 }
124
125 pub(crate) fn validity_expression<'a>(
127 &self,
128 node: &ExpressionReduceNode<'a>,
129 ) -> VortexResult<ReduceNodeValidity<ExpressionReduceNode<'a>>> {
130 self.0.validity_expression(node)
131 }
132
133 pub(crate) fn validity_array<'a>(
135 &self,
136 node: &ArrayReduceNode<'a>,
137 ) -> VortexResult<ReduceNodeValidity<ArrayReduceNode<'a>>> {
138 self.0.validity_array(node)
139 }
140
141 pub fn execute(
143 &self,
144 args: &dyn ExecutionArgs,
145 ctx: &mut ExecutionCtx,
146 ) -> VortexResult<ArrayRef> {
147 self.0.execute(args, ctx)
148 }
149
150 pub fn reduce_expression<'a>(
152 &self,
153 node: &ExpressionReduceNode<'a>,
154 ) -> VortexResult<Option<ExpressionReduceNode<'a>>> {
155 self.0.reduce_expression(node)
156 }
157
158 pub fn reduce_array<'a>(
160 &self,
161 node: &ArrayReduceNode<'a>,
162 ) -> VortexResult<Option<ArrayReduceNode<'a>>> {
163 self.0.reduce_array(node)
164 }
165
166 pub(crate) fn fmt_sql(
172 &self,
173 expr: &dyn ExprDisplay,
174 f: &mut Formatter<'_>,
175 ) -> std::fmt::Result {
176 self.0.fmt_sql(expr, f)
177 }
178
179 pub(crate) fn simplify(&self, expr: &BoundExpression) -> VortexResult<Option<BoundExpression>> {
181 self.0.simplify(expr)
182 }
183}
184
185impl Debug for ScalarFnRef {
186 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
187 f.debug_struct("ScalarFnRef")
188 .field("vtable", &self.0.id())
189 .field("options", &DebugWith(|fmt| self.0.options_debug(fmt)))
190 .finish()
191 }
192}
193
194impl Display for ScalarFnRef {
195 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
196 write!(f, "{}(", self.0.id())?;
197 self.0.options_display(f)?;
198 write!(f, ")")
199 }
200}
201
202impl PartialEq for ScalarFnRef {
203 fn eq(&self, other: &Self) -> bool {
204 self.0.id() == other.0.id() && self.0.options_eq(other.0.options_any())
205 }
206}
207impl Eq for ScalarFnRef {}
208
209impl Hash for ScalarFnRef {
210 fn hash<H: Hasher>(&self, state: &mut H) {
211 self.0.id().hash(state);
212 self.0.options_hash(state);
213 }
214}