Skip to content

Commit 47b7068

Browse files
committed
x
1 parent cafd206 commit 47b7068

1 file changed

Lines changed: 56 additions & 64 deletions

File tree

src/query/functions/src/scalars/comparison.rs

Lines changed: 56 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -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

525518
enum 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> {
536529
impl<'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

Comments
 (0)