Skip to content

Commit 5f33a5b

Browse files
commit
1 parent 9da72f5 commit 5f33a5b

2 files changed

Lines changed: 87 additions & 13 deletions

File tree

packages/rs-drive/src/query/conditions.rs

Lines changed: 63 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ impl WhereOperator {
193193
Between => match right_value {
194194
Value::Array(bounds) if bounds.len() == 2 => {
195195
match bounds[0].partial_cmp(&bounds[1]) {
196-
Some(Ordering::Less) | Some(Ordering::Equal) => {
196+
Some(Ordering::Less) => {
197197
left_value >= &bounds[0] && left_value <= &bounds[1]
198198
}
199199
_ => false,
@@ -204,9 +204,7 @@ impl WhereOperator {
204204
BetweenExcludeBounds => match right_value {
205205
Value::Array(bounds) if bounds.len() == 2 => {
206206
match bounds[0].partial_cmp(&bounds[1]) {
207-
Some(Ordering::Less) | Some(Ordering::Equal) => {
208-
left_value > &bounds[0] && left_value < &bounds[1]
209-
}
207+
Some(Ordering::Less) => left_value > &bounds[0] && left_value < &bounds[1],
210208
_ => false,
211209
}
212210
}
@@ -215,9 +213,7 @@ impl WhereOperator {
215213
BetweenExcludeLeft => match right_value {
216214
Value::Array(bounds) if bounds.len() == 2 => {
217215
match bounds[0].partial_cmp(&bounds[1]) {
218-
Some(Ordering::Less) | Some(Ordering::Equal) => {
219-
left_value > &bounds[0] && left_value <= &bounds[1]
220-
}
216+
Some(Ordering::Less) => left_value > &bounds[0] && left_value <= &bounds[1],
221217
_ => false,
222218
}
223219
}
@@ -226,9 +222,7 @@ impl WhereOperator {
226222
BetweenExcludeRight => match right_value {
227223
Value::Array(bounds) if bounds.len() == 2 => {
228224
match bounds[0].partial_cmp(&bounds[1]) {
229-
Some(Ordering::Less) | Some(Ordering::Equal) => {
230-
left_value >= &bounds[0] && left_value < &bounds[1]
231-
}
225+
Some(Ordering::Less) => left_value >= &bounds[0] && left_value < &bounds[1],
232226
_ => false,
233227
}
234228
}
@@ -1462,11 +1456,11 @@ impl<'a> WhereClause {
14621456
if let Value::Array(bounds) = &self.value {
14631457
if bounds.len() == 2 {
14641458
match bounds[0].partial_cmp(&bounds[1]) {
1465-
Some(Ordering::Less) | Some(Ordering::Equal) => {}
1459+
Some(Ordering::Less) => {}
14661460
_ => {
14671461
return QuerySyntaxSimpleValidationResult::new_with_error(
14681462
QuerySyntaxError::InvalidBetweenClause(
1469-
"when using between operator bounds must be ascending",
1463+
"when using between operator bounds must be strictly ascending",
14701464
),
14711465
);
14721466
}
@@ -1709,7 +1703,8 @@ mod tests {
17091703
use crate::error::query::QuerySyntaxError;
17101704
use crate::query::conditions::WhereClause;
17111705
use crate::query::conditions::{
1712-
Equal, GreaterThan, GreaterThanOrEquals, In, LessThan, LessThanOrEquals,
1706+
Between, BetweenExcludeBounds, BetweenExcludeLeft, BetweenExcludeRight, Equal, GreaterThan,
1707+
GreaterThanOrEquals, In, LessThan, LessThanOrEquals, ValueClause,
17131708
};
17141709
use crate::query::InternalClauses;
17151710
use dpp::data_contract::accessors::v0::DataContractV0Getters;
@@ -1988,6 +1983,61 @@ mod tests {
19881983
assert!(res.is_valid());
19891984
}
19901985

1986+
#[test]
1987+
fn validate_rejects_between_variants_with_equal_bounds() {
1988+
let fixture = get_data_contract_fixture(None, 0, LATEST_PLATFORM_VERSION.protocol_version);
1989+
let contract = fixture.data_contract_owned();
1990+
let doc_type = contract
1991+
.document_type_for_name("uniqueDates")
1992+
.expect("doc type exists");
1993+
1994+
for operator in [
1995+
Between,
1996+
BetweenExcludeBounds,
1997+
BetweenExcludeLeft,
1998+
BetweenExcludeRight,
1999+
] {
2000+
let clause = WhereClause {
2001+
field: "$createdAt".to_string(),
2002+
operator,
2003+
value: Value::Array(vec![Value::U64(1000), Value::U64(1000)]),
2004+
};
2005+
2006+
let res = clause.validate_against_schema(doc_type);
2007+
assert!(
2008+
res.is_err(),
2009+
"{operator:?} should reject equal bounds during validation"
2010+
);
2011+
assert!(matches!(
2012+
res.first_error(),
2013+
Some(QuerySyntaxError::InvalidBetweenClause(_))
2014+
));
2015+
}
2016+
}
2017+
2018+
#[test]
2019+
fn value_clause_between_variants_do_not_match_equal_bounds() {
2020+
let equal_bounds = Value::Array(vec![Value::U64(1000), Value::U64(1000)]);
2021+
let value_to_test = Value::U64(1000);
2022+
2023+
for operator in [
2024+
Between,
2025+
BetweenExcludeBounds,
2026+
BetweenExcludeLeft,
2027+
BetweenExcludeRight,
2028+
] {
2029+
let clause = ValueClause {
2030+
operator,
2031+
value: equal_bounds.clone(),
2032+
};
2033+
2034+
assert!(
2035+
!clause.matches_value(&value_to_test),
2036+
"{operator:?} should not match when bounds are equal"
2037+
);
2038+
}
2039+
}
2040+
19912041
#[test]
19922042
fn validate_rejects_meta_revision_float_equality() {
19932043
let fixture = get_data_contract_fixture(None, 0, LATEST_PLATFORM_VERSION.protocol_version);

packages/rs-drive/src/query/filter.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1642,6 +1642,30 @@ mod tests {
16421642
},
16431643
};
16441644
assert!(filter.validate().is_err());
1645+
1646+
// Price Between variants must reject equal bounds
1647+
for operator in [
1648+
WhereOperator::Between,
1649+
WhereOperator::BetweenExcludeBounds,
1650+
WhereOperator::BetweenExcludeLeft,
1651+
WhereOperator::BetweenExcludeRight,
1652+
] {
1653+
let filter = DriveDocumentQueryFilter {
1654+
contract: &contract,
1655+
document_type_name: "niceDocument".to_string(),
1656+
action_clauses: DocumentActionMatchClauses::UpdatePrice {
1657+
original_document_clauses: InternalClauses::default(),
1658+
price_clause: Some(ValueClause {
1659+
operator,
1660+
value: Value::Array(vec![Value::U64(10), Value::U64(10)]),
1661+
}),
1662+
},
1663+
};
1664+
assert!(
1665+
filter.validate().is_err(),
1666+
"{operator:?} should reject equal price bounds"
1667+
);
1668+
}
16451669
}
16461670

16471671
#[test]

0 commit comments

Comments
 (0)