Skip to content

Commit cafd206

Browse files
committed
x
1 parent 0d21a60 commit cafd206

8 files changed

Lines changed: 504 additions & 404 deletions

File tree

src/query/expression/src/function.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ use crate::types::nullable::NullableDomain;
5151
use crate::types::*;
5252
use crate::values::Value;
5353

54+
pub mod comparison;
5455
pub mod function_builder;
5556
pub mod function_factory;
5657
pub mod function_stat;

src/query/expression/src/comparison.rs renamed to src/query/expression/src/function/comparison.rs

Lines changed: 72 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@
1414

1515
use std::cmp::Ordering;
1616

17-
use databend_common_exception::ErrorCode;
18-
use databend_common_exception::Result;
19-
17+
use crate::Scalar;
18+
use crate::stat_distribution::ArgStat;
2019
use crate::stat_distribution::Ndv;
20+
use crate::stat_distribution::StatBinaryArg;
2121
use crate::stat_distribution::StatEstimate;
2222

2323
pub trait StatComparisonOp {
@@ -109,6 +109,75 @@ impl StatComparisonOp for GteOp {
109109
const INCLUDE_EQUAL: bool = true;
110110
}
111111

112+
pub struct ConstantComparison<'s, 'a> {
113+
pub stat: &'s ArgStat<'a>,
114+
pub constant: Scalar,
115+
pub cardinality: f64,
116+
}
117+
118+
impl<'s, 'a> ConstantComparison<'s, 'a> {
119+
pub fn from_equality_args(stat: &'s StatBinaryArg<'a>) -> Option<Self> {
120+
Self::from_right_constant(stat).or_else(|| Self::from_left_constant(stat))
121+
}
122+
123+
pub fn from_right_constant(stat: &'s StatBinaryArg<'a>) -> Option<Self> {
124+
Some(Self {
125+
stat: &stat.args[0],
126+
constant: stat.args[1].singleton()?,
127+
cardinality: stat.cardinality,
128+
})
129+
}
130+
131+
pub fn from_left_constant(stat: &'s StatBinaryArg<'a>) -> Option<Self> {
132+
Some(Self {
133+
stat: &stat.args[1],
134+
constant: stat.args[0].singleton()?,
135+
cardinality: stat.cardinality,
136+
})
137+
}
138+
139+
pub fn equality_true_count(
140+
&self,
141+
not_eq: bool,
142+
compare: impl Fn(&Scalar, &Scalar) -> Option<Ordering>,
143+
) -> Option<StatEstimate> {
144+
let Some((min, max)) = self.stat.value_minmax() else {
145+
return Some(StatEstimate::exact(if not_eq {
146+
self.cardinality
147+
} else {
148+
0.0
149+
}));
150+
};
151+
if compare(&self.constant, &min)? == Ordering::Less
152+
|| compare(&self.constant, &max)? == Ordering::Greater
153+
{
154+
return Some(StatEstimate::exact(if not_eq {
155+
self.cardinality
156+
} else {
157+
0.0
158+
}));
159+
}
160+
161+
Some(estimate_ndv_true_count(
162+
self.stat.ndv,
163+
not_eq,
164+
self.cardinality,
165+
))
166+
}
167+
168+
pub fn minmax_range_true_count<Op: StatComparisonOp>(
169+
&self,
170+
compare: impl Fn(&Scalar, &Scalar) -> Option<Ordering>,
171+
) -> Option<StatEstimate> {
172+
try {
173+
let (min, max) = self.stat.value_minmax()?;
174+
let cmp_min = compare(&self.constant, &min)?;
175+
let cmp_max = compare(&self.constant, &max)?;
176+
Op::estimate_minmax_range_true_count(self.stat.ndv, self.cardinality, cmp_min, cmp_max)?
177+
}
178+
}
179+
}
180+
112181
pub fn estimate_ndv_true_count(ndv: Ndv, not_eq: bool, cardinality: f64) -> StatEstimate {
113182
let value = ndv.value();
114183
let selectivity = if value == 0.0 {

src/query/expression/src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ mod block;
5555

5656
pub mod aggregate;
5757
mod block_vec;
58-
pub mod comparison;
5958
mod constant_folder;
6059
pub mod converts;
6160
mod evaluator;

0 commit comments

Comments
 (0)