Bugfix - error on integer overflow in SurrealQL. (#1983)

This commit is contained in:
Finn Bear 2023-05-12 16:55:52 -07:00 committed by GitHub
parent df745bb3a5
commit 10f29fbb26
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 31 additions and 9 deletions

View file

@ -347,23 +347,23 @@ pub enum Error {
into: Cow<'static, str>,
},
/// The requested function does not exist
/// Cannot perform addition
#[error("Cannot perform addition with '{0}' and '{1}'")]
TryAdd(String, String),
/// The requested function does not exist
/// Cannot perform subtraction
#[error("Cannot perform subtraction with '{0}' and '{1}'")]
TrySub(String, String),
/// The requested function does not exist
/// Cannot perform multiplication
#[error("Cannot perform multiplication with '{0}' and '{1}'")]
TryMul(String, String),
/// The requested function does not exist
/// Cannot perform division
#[error("Cannot perform division with '{0}' and '{1}'")]
TryDiv(String, String),
/// The requested function does not exist
/// Cannot perform power
#[error("Cannot raise the value '{0}' with '{1}'")]
TryPow(String, String),

View file

@ -2003,7 +2003,12 @@ impl TryAdd for Value {
type Output = Self;
fn try_add(self, other: Self) -> Result<Self, Error> {
match (self, other) {
(Value::Number(v), Value::Number(w)) => Ok(Value::Number(v + w)),
(Value::Number(v), Value::Number(w)) => match (v, w) {
(Number::Int(v), Number::Int(w)) if v.checked_add(w).is_none() => {
Err(Error::TryAdd(v.to_string(), w.to_string()))
}
(v, w) => Ok(Value::Number(v + w)),
},
(Value::Strand(v), Value::Strand(w)) => Ok(Value::Strand(v + w)),
(Value::Datetime(v), Value::Duration(w)) => Ok(Value::Datetime(w + v)),
(Value::Duration(v), Value::Datetime(w)) => Ok(Value::Datetime(v + w)),
@ -2024,7 +2029,12 @@ impl TrySub for Value {
type Output = Self;
fn try_sub(self, other: Self) -> Result<Self, Error> {
match (self, other) {
(Value::Number(v), Value::Number(w)) => Ok(Value::Number(v - w)),
(Value::Number(v), Value::Number(w)) => match (v, w) {
(Number::Int(v), Number::Int(w)) if v.checked_sub(w).is_none() => {
Err(Error::TrySub(v.to_string(), w.to_string()))
}
(v, w) => Ok(Value::Number(v - w)),
},
(Value::Datetime(v), Value::Datetime(w)) => Ok(Value::Duration(v - w)),
(Value::Datetime(v), Value::Duration(w)) => Ok(Value::Datetime(w - v)),
(Value::Duration(v), Value::Datetime(w)) => Ok(Value::Datetime(v - w)),
@ -2045,7 +2055,12 @@ impl TryMul for Value {
type Output = Self;
fn try_mul(self, other: Self) -> Result<Self, Error> {
match (self, other) {
(Value::Number(v), Value::Number(w)) => Ok(Value::Number(v * w)),
(Value::Number(v), Value::Number(w)) => match (v, w) {
(Number::Int(v), Number::Int(w)) if v.checked_mul(w).is_none() => {
Err(Error::TryMul(v.to_string(), w.to_string()))
}
(v, w) => Ok(Value::Number(v * w)),
},
(v, w) => Err(Error::TryMul(v.to_raw_string(), w.to_raw_string())),
}
}
@ -2082,7 +2097,14 @@ impl TryPow for Value {
type Output = Self;
fn try_pow(self, other: Self) -> Result<Self, Error> {
match (self, other) {
(Value::Number(v), Value::Number(w)) => Ok(Value::Number(v.pow(w))),
(Value::Number(v), Value::Number(w)) => match (v, w) {
(Number::Int(v), Number::Int(w))
if w.try_into().ok().and_then(|w| v.checked_pow(w)).is_none() =>
{
Err(Error::TryPow(v.to_string(), w.to_string()))
}
(v, w) => Ok(Value::Number(v.pow(w))),
},
(v, w) => Err(Error::TryPow(v.to_raw_string(), w.to_raw_string())),
}
}