@@ -348,16 +348,13 @@ impl<Op: StatComparisonOp> HistogramComparison<'_, Op> {
348348 Scalar :: Timestamp ( v) => * v,
349349 _ => return Err ( unexpected_histogram_constant ( "Int" , self . constant ) ) ,
350350 } ;
351- Ok (
352- self . typed_selectivity ( histogram, & constant, |bucket, constant| {
353- HistogramBucketComparison :: < _ , Op > {
354- bucket,
355- constant,
356- _op : PhantomData ,
357- }
358- . number_selectivity ( )
359- } ) ,
360- )
351+ Ok ( TypedHistogramScan :: < _ , Op > {
352+ histogram,
353+ constant : & constant,
354+ selected : 0.0 ,
355+ _op : PhantomData ,
356+ }
357+ . selectivity ( HistogramBucketComparison :: number_selectivity) )
361358 }
362359 Histogram :: UInt ( histogram) => {
363360 let constant = match self . constant {
@@ -367,72 +364,68 @@ impl<Op: StatComparisonOp> HistogramComparison<'_, Op> {
367364 Scalar :: Number ( NumberScalar :: UInt64 ( n) ) => * n,
368365 _ => return Err ( unexpected_histogram_constant ( "UInt" , self . constant ) ) ,
369366 } ;
370- Ok (
371- self . typed_selectivity ( histogram, & constant, |bucket, constant| {
372- HistogramBucketComparison :: < _ , Op > {
373- bucket,
374- constant,
375- _op : PhantomData ,
376- }
377- . number_selectivity ( )
378- } ) ,
379- )
367+ Ok ( TypedHistogramScan :: < _ , Op > {
368+ histogram,
369+ constant : & constant,
370+ selected : 0.0 ,
371+ _op : PhantomData ,
372+ }
373+ . selectivity ( HistogramBucketComparison :: number_selectivity) )
380374 }
381375 Histogram :: Float ( histogram) => {
382376 let constant = scalar_number_value ( self . constant )
383377 . ok_or_else ( || unexpected_histogram_constant ( "Float" , self . constant ) ) ?;
384- Ok (
385- self . typed_selectivity ( histogram, & constant, |bucket, constant| {
386- HistogramBucketComparison :: < _ , Op > {
387- bucket,
388- constant,
389- _op : PhantomData ,
390- }
391- . number_selectivity ( )
392- } ) ,
393- )
378+ Ok ( TypedHistogramScan :: < _ , Op > {
379+ histogram,
380+ constant : & constant,
381+ selected : 0.0 ,
382+ _op : PhantomData ,
383+ }
384+ . selectivity ( HistogramBucketComparison :: number_selectivity) )
394385 }
395386 Histogram :: Bytes ( histogram) => {
396387 let constant = scalar_bytes_value ( self . constant )
397388 . ok_or_else ( || unexpected_histogram_constant ( "Bytes" , self . constant ) ) ?;
398- Ok (
399- self . typed_selectivity ( histogram, & constant, |bucket, constant| {
400- HistogramBucketComparison :: < _ , Op > {
401- bucket,
402- constant,
403- _op : PhantomData ,
404- }
405- . bytes_selectivity ( )
406- } ) ,
407- )
389+ Ok ( TypedHistogramScan :: < _ , Op > {
390+ histogram,
391+ constant : & constant,
392+ selected : 0.0 ,
393+ _op : PhantomData ,
394+ }
395+ . selectivity ( HistogramBucketComparison :: bytes_selectivity) )
408396 }
409397 }
410398 }
399+ }
411400
412- fn typed_selectivity < T : Ord > (
413- & self ,
414- histogram : & TypedHistogram < T > ,
415- constant : & T ,
416- estimate_partial_bucket : impl Fn ( & TypedHistogramBucket < T > , & T ) -> f64 ,
401+ struct TypedHistogramScan < ' a , T , Op > {
402+ histogram : & ' a TypedHistogram < T > ,
403+ constant : & ' a T ,
404+ selected : f64 ,
405+ _op : PhantomData < fn ( Op ) > ,
406+ }
407+
408+ impl < ' a , T : Ord , Op : StatComparisonOp > TypedHistogramScan < ' a , T , Op > {
409+ fn selectivity (
410+ mut self ,
411+ estimate_partial_bucket : impl Fn ( & HistogramBucketComparison < ' a , T , Op > ) -> f64 ,
417412 ) -> f64 {
418- let mut selected = 0.0 ;
419- for bucket in & histogram. buckets {
420- let bucket_comparison = HistogramBucketComparison :: < _ , Op > {
413+ for bucket in & self . histogram . buckets {
414+ let bucket = HistogramBucketComparison :: < _ , Op > {
421415 bucket,
422- constant,
416+ constant : self . constant ,
423417 _op : PhantomData ,
424418 } ;
425- match bucket_comparison . overlap ( ) {
419+ match bucket . overlap ( ) {
426420 HistogramBucketOverlap :: None => { }
427- HistogramBucketOverlap :: Complete => selected += bucket. num_values ( ) ,
421+ HistogramBucketOverlap :: Complete => self . selected += bucket . bucket . num_values ( ) ,
428422 HistogramBucketOverlap :: Partial => {
429- let selectivity = estimate_partial_bucket ( bucket, constant) ;
430- selected += bucket. num_values ( ) * selectivity;
423+ self . selected += bucket. bucket . num_values ( ) * estimate_partial_bucket ( & bucket) ;
431424 }
432425 }
433426 }
434427
435- selected / histogram. num_values ( )
428+ self . selected / self . histogram . num_values ( )
436429 }
437430}
438431
@@ -523,7 +516,7 @@ impl<T: StatNumberValue, Op: StatComparisonOp> HistogramBucketComparison<'_, T,
523516}
524517
525518enum IntegerRangeComparison < ' s , ' a > {
526- Empty ,
519+ MissingMinMax ,
527520 Bounded {
528521 stat : & ' s ArgStat < ' a > ,
529522 min : F64 ,
@@ -536,7 +529,7 @@ enum IntegerRangeComparison<'s, 'a> {
536529impl < ' s , ' a > IntegerRangeComparison < ' s , ' a > {
537530 fn from_input ( input : & ConstantComparison < ' s , ' a > ) -> Option < Self > {
538531 let Some ( ( min, max) ) = input. stat . value_minmax ( ) else {
539- return Some ( Self :: Empty ) ;
532+ return Some ( Self :: MissingMinMax ) ;
540533 } ;
541534
542535 Some ( Self :: Bounded {
@@ -1983,22 +1976,21 @@ mod tests {
19831976 } ) ;
19841977 let constant = Scalar :: Number ( NumberScalar :: Int64 ( 10 ) ) ;
19851978
1986- let gte_selectivity = HistogramComparison :: < GteOp > {
1979+ let gte_input = HistogramComparison :: < GteOp > {
19871980 histogram : & histogram,
19881981 constant : & constant,
19891982 cardinality : 1.0 ,
19901983 _op : PhantomData ,
1991- }
1992- . selectivity ( )
1993- . unwrap ( ) ;
1994- let lt_selectivity = HistogramComparison :: < LtOp > {
1984+ } ;
1985+ let lt_input = HistogramComparison :: < LtOp > {
19951986 histogram : & histogram,
19961987 constant : & constant,
19971988 cardinality : 1.0 ,
19981989 _op : PhantomData ,
1999- }
2000- . selectivity ( )
2001- . unwrap ( ) ;
1990+ } ;
1991+
1992+ let gte_selectivity = gte_input. selectivity ( ) . unwrap ( ) ;
1993+ let lt_selectivity = lt_input. selectivity ( ) . unwrap ( ) ;
20021994
20031995 assert ! ( ( gte_selectivity - 0.1 ) . abs( ) < 1e-9 ) ;
20041996 assert ! ( ( lt_selectivity - 0.9 ) . abs( ) < 1e-9 ) ;
0 commit comments