33
44use std:: any:: Any ;
55use std:: cell:: RefCell ;
6- use std:: ops:: Deref ;
76use std:: sync:: Arc ;
87
98use itertools:: Itertools ;
@@ -13,12 +12,15 @@ use vortex_utils::aliases::hash_map::HashMap;
1312
1413use crate :: dtype:: DType ;
1514use crate :: expr:: Expression ;
15+ use crate :: expr:: expression:: ExprReturnInfo ;
16+ use crate :: expr:: expression:: expr_return_dtype_info;
1617use crate :: expr:: transform:: match_between:: find_between;
1718use crate :: scalar_fn:: ReduceCtx ;
1819use crate :: scalar_fn:: ReduceNode ;
1920use crate :: scalar_fn:: ReduceNodeRef ;
2021use crate :: scalar_fn:: ScalarFnRef ;
2122use crate :: scalar_fn:: SimplifyCtx ;
23+ use crate :: scalar_fn:: fns:: literal:: Literal ;
2224use crate :: scalar_fn:: fns:: root:: Root ;
2325
2426impl Expression {
@@ -206,27 +208,34 @@ impl Expression {
206208
207209struct SimplifyCache < ' a > {
208210 scope : & ' a DType ,
209- dtype_cache : RefCell < HashMap < Expression , DType > > ,
211+ dtype_cache : RefCell < HashMap < Expression , ExprReturnInfo > > ,
210212}
211213
212- impl SimplifyCtx for SimplifyCache < ' _ > {
213- fn return_dtype ( & self , expr : & Expression ) -> VortexResult < DType > {
214- // If the expression is "root", return the scope dtype
214+ impl SimplifyCache < ' _ > {
215+ fn return_dtype_info ( & self , expr : & Expression ) -> VortexResult < ExprReturnInfo > {
215216 if expr. is :: < Root > ( ) {
216- return Ok ( self . scope . clone ( ) ) ;
217+ return Ok ( ExprReturnInfo :: storage_chain_repr_wrapper (
218+ self . scope . clone ( ) ,
219+ ) ) ;
220+ }
221+
222+ if let Some ( literal) = expr. as_opt :: < Literal > ( ) {
223+ return Ok ( ExprReturnInfo :: storage_chain_repr_wrapper (
224+ literal. dtype ( ) . clone ( ) ,
225+ ) ) ;
217226 }
218227
219228 if let Some ( dtype) = self . dtype_cache . borrow ( ) . get ( expr) {
220229 return Ok ( dtype. clone ( ) ) ;
221230 }
222231
223232 // Otherwise, compute dtype from children
224- let input_dtypes: Vec < _ > = expr
233+ let mut input_dtypes: Vec < _ > = expr
225234 . children ( )
226235 . iter ( )
227- . map ( |c| self . return_dtype ( c) )
236+ . map ( |c| self . return_dtype_info ( c) )
228237 . try_collect ( ) ?;
229- let dtype = expr. deref ( ) . return_dtype ( & input_dtypes) ?;
238+ let dtype = expr_return_dtype_info ( expr. scalar_fn ( ) , & mut input_dtypes) ?;
230239 self . dtype_cache
231240 . borrow_mut ( )
232241 . insert ( expr. clone ( ) , dtype. clone ( ) ) ;
@@ -235,6 +244,12 @@ impl SimplifyCtx for SimplifyCache<'_> {
235244 }
236245}
237246
247+ impl SimplifyCtx for SimplifyCache < ' _ > {
248+ fn return_dtype ( & self , expr : & Expression ) -> VortexResult < DType > {
249+ Ok ( self . return_dtype_info ( expr) ?. dtype )
250+ }
251+ }
252+
238253struct ExpressionReduceNode {
239254 expression : Expression ,
240255 scope : DType ,
@@ -294,3 +309,43 @@ impl ReduceCtx for ExpressionReduceCtx {
294309 } ) )
295310 }
296311}
312+
313+ #[ cfg( test) ]
314+ mod tests {
315+ use crate :: dtype:: DType ;
316+ use crate :: dtype:: Nullability ;
317+ use crate :: dtype:: PType ;
318+ use crate :: dtype:: extension:: ExtDType ;
319+ use crate :: expr:: checked_add;
320+ use crate :: expr:: fill_null;
321+ use crate :: expr:: lit;
322+ use crate :: expr:: root;
323+ use crate :: extension:: tests:: divisible_int:: DivisibleInt ;
324+ use crate :: extension:: tests:: divisible_int:: Divisor ;
325+
326+ fn divisible_int_dtype ( divisor : u64 ) -> DType {
327+ DType :: Extension (
328+ ExtDType :: < DivisibleInt > :: try_new (
329+ Divisor ( divisor) ,
330+ DType :: Primitive ( PType :: U64 , Nullability :: NonNullable ) ,
331+ )
332+ . unwrap ( )
333+ . erased ( ) ,
334+ )
335+ }
336+
337+ #[ test]
338+ fn optimize_recursive_uses_refinement_fallback_for_typed_simplify ( ) {
339+ let scope = divisible_int_dtype ( 3 ) ;
340+ let add = checked_add ( root ( ) , root ( ) ) ;
341+ let expr = fill_null ( add. clone ( ) , lit ( 0u64 ) ) ;
342+
343+ let optimized = expr. optimize_recursive ( & scope) . unwrap ( ) ;
344+
345+ assert_eq ! ( optimized, add) ;
346+ assert_eq ! (
347+ optimized. return_dtype( & scope) . unwrap( ) ,
348+ DType :: Primitive ( PType :: U64 , Nullability :: NonNullable ) ,
349+ ) ;
350+ }
351+ }
0 commit comments