@@ -21,6 +21,7 @@ use vortex_array::compute::min_max;
2121use vortex_array:: compute:: take;
2222use vortex_array:: expr:: Expression ;
2323use vortex_array:: expr:: root;
24+ use vortex_array:: mask:: MaskExecutor ;
2425use vortex_array:: session:: ArraySessionExt ;
2526use vortex_dtype:: DType ;
2627use vortex_dtype:: FieldMask ;
@@ -183,35 +184,41 @@ impl LayoutReader for DictReader {
183184 MaskFuture :: new_true ( mask. len ( ) ) ,
184185 ) ?;
185186
187+ let session = self . session . clone ( ) ;
188+
186189 Ok ( MaskFuture :: new ( mask. len ( ) , async move {
187190 // Join on the I/O futures first, before the mask.
188191 let ( codes, values) = try_join ! ( codes_eval, values_eval. map_err( VortexError :: from) ) ?;
189192 let mask = mask. await ?;
190193
191- // Short-circuit when the values are all true/false.
192- if values. all_valid ( )
193- && let Some ( MinMaxResult { min, max } ) = min_max ( & values) ?
194- {
195- #[ expect( clippy:: bool_comparison, reason = "easy to follow" ) ]
196- if max. as_bool ( ) . value ( ) . vortex_expect ( "non null" ) == false {
197- // All values are false
198- return Ok ( Mask :: AllFalse ( mask. len ( ) ) ) ;
199- }
200- #[ expect( clippy:: bool_comparison, reason = "easy to follow" ) ]
201- if min. as_bool ( ) . value ( ) . vortex_expect ( "not null" ) == true {
202- // All values are true, but we still need to respect codes validity
203- return Ok ( mask. bitand ( & codes. validity_mask ( ) ) ) ;
194+ let dict_mask = if * USE_VORTEX_OPERATORS {
195+ values. take ( codes) ?. execute_mask_optimized ( & session) ?
196+ } else {
197+ // Short-circuit when the values are all true/false.
198+ if values. all_valid ( )
199+ && let Some ( MinMaxResult { min, max } ) = min_max ( & values) ?
200+ {
201+ #[ expect( clippy:: bool_comparison, reason = "easy to follow" ) ]
202+ if max. as_bool ( ) . value ( ) . vortex_expect ( "non null" ) == false {
203+ // All values are false
204+ return Ok ( Mask :: AllFalse ( mask. len ( ) ) ) ;
205+ }
206+ #[ expect( clippy:: bool_comparison, reason = "easy to follow" ) ]
207+ if min. as_bool ( ) . value ( ) . vortex_expect ( "not null" ) == true {
208+ // All values are true, but we still need to respect codes validity
209+ return Ok ( mask. bitand ( & codes. validity_mask ( ) ) ) ;
210+ }
204211 }
205- }
206212
207- // Creating a mask from the dict array would canonicalize it,
208- // it should be fine for now as long as values is already canonical,
209- // so different row ranges do not canonicalize to the same array
210- // multiple times.
211- // TODO(joe): fixme casting null to false is *VERY* unsound, if the expression in the filter
212- // can inspect nulls (e.g. `is_null`).
213- // See `FlatEvaluation` for more details.
214- let dict_mask = take ( & values, & codes) ?. try_to_mask_fill_null_false ( ) ?;
213+ // Creating a mask from the dict array would canonicalize it,
214+ // it should be fine for now as long as values is already canonical,
215+ // so different row ranges do not canonicalize to the same array
216+ // multiple times.
217+ // TODO(joe): fixme casting null to false is *VERY* unsound, if the expression in the filter
218+ // can inspect nulls (e.g. `is_null`).
219+ // See `FlatEvaluation` for more details.
220+ take ( & values, & codes) ?. try_to_mask_fill_null_false ( ) ?
221+ } ;
215222
216223 Ok ( mask. bitand ( & dict_mask) )
217224 } ) )
0 commit comments