Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

push_down_ne #1469

Merged
merged 2 commits into from Sep 1, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
30 changes: 24 additions & 6 deletions common/models/src/predicate/domain.rs
Expand Up @@ -624,19 +624,30 @@ impl Range {
Self { low, high }
}
/// TODO Constructs a range of values not equal to scalar_value [scalar_value, scalar_value].
pub fn ne(data_type: &DataType, _scalar_value: &ScalarValue) -> Range {
let low = Marker {
pub fn ne(data_type: &DataType, scalar_value: &ScalarValue) -> Vec<Range> {
let low_1 = Marker::lower_unbound(data_type.clone());
let high_1 = Marker {
data_type: data_type.clone(),
value: None,
value: Some(scalar_value.clone()),
bound: Bound::Below,
};
let high = Marker {
let low_2 = Marker {
data_type: data_type.clone(),
value: None,
value: Some(scalar_value.clone()),
bound: Bound::Above,
};
let high_2 = Marker::upper_unbound(data_type.clone());

Self { low, high }
vec![
Self {
low: low_1,
high: high_1,
},
Self {
low: low_2,
high: high_2,
},
]
}
/// Construct a range of values greater than scalar_value (scalar_value, +∞).
pub fn gt(data_type: &DataType, scalar_value: &ScalarValue) -> Range {
Expand Down Expand Up @@ -692,6 +703,13 @@ impl Range {
fn overlaps(&self, other: &Self) -> Result<bool> {
self.check_type_compatibility(other)?;
if self.low <= other.high && other.low <= self.high {
// like (-∞, 2) and (2, +∞) is not overlap
if self.high == other.low
&& self.high.bound == Bound::Below
&& other.low.bound == Bound::Above
{
return Ok(false);
}
guojidan marked this conversation as resolved.
Show resolved Hide resolved
return Ok(true);
}
Ok(false)
Expand Down
30 changes: 15 additions & 15 deletions common/models/src/predicate/transformation.rs
Expand Up @@ -124,16 +124,18 @@ pub struct RowExpressionToDomainsVisitor<'a> {
ctx: &'a mut RowExpressionToDomainsVisitorContext,
}

type GetRangeFromDataTypeAndValue = fn(data_type: &DataType, scalar_value: &ScalarValue) -> Range;

/// Get the corresponding range constructor according to the comparison operator
fn get_get_range_fn(op: &Operator) -> Option<GetRangeFromDataTypeAndValue> {
fn get_range_fn(
op: &Operator,
data_type: &DataType,
scalar_value: &ScalarValue,
) -> Option<Vec<Range>> {
match op {
Operator::Eq => Some(Range::eq),
Operator::Lt => Some(Range::lt),
Operator::LtEq => Some(Range::le),
Operator::Gt => Some(Range::gt),
Operator::GtEq => Some(Range::ge),
Operator::Eq => Some(vec![Range::eq(data_type, scalar_value)]),
Operator::Lt => Some(vec![Range::lt(data_type, scalar_value)]),
Operator::LtEq => Some(vec![Range::le(data_type, scalar_value)]),
Operator::Gt => Some(vec![Range::gt(data_type, scalar_value)]),
Operator::GtEq => Some(vec![Range::ge(data_type, scalar_value)]),
Operator::NotEq => Some(Range::ne(data_type, scalar_value)),
_ => None,
}
}
Expand Down Expand Up @@ -281,13 +283,11 @@ impl RowExpressionToDomainsVisitor<'_> {
let col = &nsc.column;
let value = &nsc.value;
let op = &nsc.op;
// Get the function that constructs Range by dataType and ScalarValue.
// Get the Vec<range> by op dataType and ScalarValue.
// If op does not support it, it will return None, but it must be supported here (because op is obtained from nsc)
let val_set = get_get_range_fn(op)
// Construct Range
.map(|f| f(&value.get_datatype(), value))
// Construct ValueSet by Range, where of_ranges will not return an exception, because the parameter has only one range
.map(|r| Domain::of_ranges(&[r]).unwrap())
let val_set = get_range_fn(op, &value.get_datatype(), value)
// Construct ValueSet by Range
.map(|r| Domain::of_ranges(&r).unwrap())
// Normally this is not triggered (unless there is a bug), but returns ValueSet::All for safety
.unwrap_or(Domain::All);

Expand Down