@@ -47,7 +47,7 @@ pub trait StatBinder {
4747 /// then call [`Self::missing_stat`] with the dtype expected from the
4848 /// original `vortex.stat` expression.
4949 fn bind_stat (
50- & mut self ,
50+ & self ,
5151 input : & Expression ,
5252 stat : Stat ,
5353 stat_dtype : & DType ,
@@ -59,7 +59,7 @@ pub trait StatBinder {
5959 /// [`Stat`] slots. Binders that store richer aggregate stats can override
6060 /// this method without extending the generic stats binding walker.
6161 fn bind_aggregate (
62- & mut self ,
62+ & self ,
6363 input : & Expression ,
6464 aggregate_fn : & AggregateFnRef ,
6565 stat_dtype : & DType ,
@@ -68,11 +68,7 @@ pub trait StatBinder {
6868 }
6969
7070 /// Bind one of the legacy stat slots for `input`.
71- fn bind_legacy_stat (
72- & mut self ,
73- input : & Expression ,
74- stat : Stat ,
75- ) -> VortexResult < Option < Expression > > {
71+ fn bind_legacy_stat ( & self , input : & Expression , stat : Stat ) -> VortexResult < Option < Expression > > {
7672 let input_dtype = input. return_dtype ( self . scope ( ) ) ?;
7773 let Some ( stat_dtype) = stat. dtype ( & input_dtype) else {
7874 return Ok ( None ) ;
@@ -84,7 +80,7 @@ pub trait StatBinder {
8480 ///
8581 /// The default is a nullable null literal, which preserves three-valued
8682 /// pruning semantics for stats-table execution.
87- fn missing_stat ( & mut self , dtype : DType ) -> VortexResult < Expression > {
83+ fn missing_stat ( & self , dtype : DType ) -> VortexResult < Expression > {
8884 Ok ( null_expr ( dtype) )
8985 }
9086}
@@ -94,7 +90,10 @@ pub trait StatBinder {
9490/// The predicate is usually the output of a stats rewrite rule. Rewrite rules
9591/// are responsible for expressing stat semantics; binding maps aggregate-backed
9692/// stat requests to the concrete stats representation supported by the binder.
97- pub fn bind_stats ( predicate : Expression , binder : & mut impl StatBinder ) -> VortexResult < Expression > {
93+ pub fn bind_stats < B : StatBinder + ?Sized > (
94+ predicate : Expression ,
95+ binder : & B ,
96+ ) -> VortexResult < Expression > {
9897 let scope = binder. scope ( ) . clone ( ) ;
9998 let lowered = predicate
10099 . transform_down ( |expr| {
@@ -120,7 +119,7 @@ pub fn bind_stats(predicate: Expression, binder: &mut impl StatBinder) -> Vortex
120119/// This is an opt-in helper for stats backends that materialize `NaNCount` and
121120/// `NullCount`, but do not materialize aggregate boolean stats directly.
122121pub fn bind_legacy_count_aggregate < B : StatBinder + ?Sized > (
123- binder : & mut B ,
122+ binder : & B ,
124123 input : & Expression ,
125124 aggregate_fn : & AggregateFnRef ,
126125) -> VortexResult < Option < Expression > > {
@@ -157,7 +156,7 @@ pub fn bind_legacy_count_aggregate<B: StatBinder + ?Sized>(
157156
158157/// Bind an aggregate function that has a direct legacy [`Stat`] slot.
159158pub fn bind_direct_aggregate_stat < B : StatBinder + ?Sized > (
160- binder : & mut B ,
159+ binder : & B ,
161160 input : & Expression ,
162161 aggregate_fn : & AggregateFnRef ,
163162 stat_dtype : & DType ,
@@ -174,7 +173,7 @@ pub fn bind_direct_aggregate_stat<B: StatBinder + ?Sized>(
174173/// `NaNCount` and `NullCount`, then fall back to direct aggregate-to-stat
175174/// mappings.
176175pub fn bind_legacy_count_or_direct_aggregate < B : StatBinder + ?Sized > (
177- binder : & mut B ,
176+ binder : & B ,
178177 input : & Expression ,
179178 aggregate_fn : & AggregateFnRef ,
180179 stat_dtype : & DType ,
@@ -189,7 +188,7 @@ pub fn bind_legacy_count_or_direct_aggregate<B: StatBinder + ?Sized>(
189188fn bind_stat_fn (
190189 expr : & Expression ,
191190 scope : & DType ,
192- binder : & mut impl StatBinder ,
191+ binder : & ( impl StatBinder + ? Sized ) ,
193192) -> VortexResult < Option < Expression > > {
194193 let options = expr. as_ :: < StatFn > ( ) ;
195194 let aggregate_fn = options. aggregate_fn ( ) ;
@@ -258,7 +257,7 @@ mod tests {
258257 }
259258
260259 fn bind_stat (
261- & mut self ,
260+ & self ,
262261 _input : & Expression ,
263262 stat : Stat ,
264263 _stat_dtype : & DType ,
@@ -271,7 +270,7 @@ mod tests {
271270 }
272271
273272 fn bind_aggregate (
274- & mut self ,
273+ & self ,
275274 input : & Expression ,
276275 aggregate_fn : & AggregateFnRef ,
277276 stat_dtype : & DType ,
@@ -282,33 +281,33 @@ mod tests {
282281
283282 #[ test]
284283 fn all_non_nan_binds_to_nan_count_zero ( ) -> VortexResult < ( ) > {
285- let mut binder = TestBinder :: new ( true ) ;
284+ let binder = TestBinder :: new ( true ) ;
286285
287- let bound = bind_stats ( all_non_nan ( col ( "f" ) ) , & mut binder) ?;
286+ let bound = bind_stats ( all_non_nan ( col ( "f" ) ) , & binder) ?;
288287
289288 assert_eq ! ( bound, eq( col( "f_nan_count" ) , lit( 0u64 ) ) ) ;
290289 Ok ( ( ) )
291290 }
292291
293292 #[ test]
294293 fn all_non_nan_lowers_to_null_when_nan_count_is_missing ( ) -> VortexResult < ( ) > {
295- let mut binder = TestBinder :: new ( false ) ;
294+ let binder = TestBinder :: new ( false ) ;
296295
297- let bound = bind_stats ( all_non_nan ( col ( "f" ) ) , & mut binder) ?;
296+ let bound = bind_stats ( all_non_nan ( col ( "f" ) ) , & binder) ?;
298297
299298 assert_eq ! ( bound, lit( Scalar :: null( DType :: Bool ( Nullability :: Nullable ) ) ) ) ;
300299 Ok ( ( ) )
301300 }
302301
303302 #[ test]
304303 fn missing_stats_fold_when_kleene_semantics_allow_it ( ) -> VortexResult < ( ) > {
305- let mut binder = TestBinder :: new ( false ) ;
304+ let binder = TestBinder :: new ( false ) ;
306305
307- let bound = bind_stats ( and ( lit ( false ) , all_non_nan ( col ( "f" ) ) ) , & mut binder) ?;
306+ let bound = bind_stats ( and ( lit ( false ) , all_non_nan ( col ( "f" ) ) ) , & binder) ?;
308307
309308 assert_eq ! ( bound, lit( false ) ) ;
310309
311- let bound = bind_stats ( or ( lit ( true ) , all_non_nan ( col ( "f" ) ) ) , & mut binder) ?;
310+ let bound = bind_stats ( or ( lit ( true ) , all_non_nan ( col ( "f" ) ) ) , & binder) ?;
312311
313312 assert_eq ! ( bound, lit( true ) ) ;
314313 Ok ( ( ) )
@@ -328,7 +327,7 @@ mod tests {
328327 }
329328
330329 fn bind_stat (
331- & mut self ,
330+ & self ,
332331 input : & Expression ,
333332 stat : Stat ,
334333 stat_dtype : & DType ,
@@ -337,19 +336,19 @@ mod tests {
337336 }
338337 }
339338
340- let mut binder = DefaultBinder ( TestBinder :: new ( true ) ) ;
339+ let binder = DefaultBinder ( TestBinder :: new ( true ) ) ;
341340
342- let bound = bind_stats ( all_non_nan ( col ( "f" ) ) , & mut binder) ?;
341+ let bound = bind_stats ( all_non_nan ( col ( "f" ) ) , & binder) ?;
343342
344343 assert_eq ! ( bound, lit( Scalar :: null( DType :: Bool ( Nullability :: Nullable ) ) ) ) ;
345344 Ok ( ( ) )
346345 }
347346
348347 #[ test]
349348 fn unrelated_expressions_do_not_request_nan_count ( ) -> VortexResult < ( ) > {
350- let mut binder = TestBinder :: new ( false ) ;
349+ let binder = TestBinder :: new ( false ) ;
351350
352- let bound = bind_stats ( is_null ( col ( "f" ) ) , & mut binder) ?;
351+ let bound = bind_stats ( is_null ( col ( "f" ) ) , & binder) ?;
353352
354353 assert_eq ! ( bound, is_null( col( "f" ) ) ) ;
355354 Ok ( ( ) )
0 commit comments