diff --git a/core/src/ast/data_type.rs b/core/src/ast/data_type.rs index 7657c41b7..54ce7060c 100644 --- a/core/src/ast/data_type.rs +++ b/core/src/ast/data_type.rs @@ -14,6 +14,9 @@ pub enum DataType { Int128, Uint8, Uint16, + Uint32, + Uint64, + Uint128, Float, Text, Bytea, diff --git a/core/src/data/bigdecimal_ext.rs b/core/src/data/bigdecimal_ext.rs index 79206b579..5028455db 100644 --- a/core/src/data/bigdecimal_ext.rs +++ b/core/src/data/bigdecimal_ext.rs @@ -10,6 +10,7 @@ pub trait BigDecimalExt { fn to_u16(&self) -> Option; fn to_u32(&self) -> Option; fn to_u128(&self) -> Option; + fn to_u64(&self) -> Option; fn to_f64(&self) -> Option; } @@ -50,6 +51,10 @@ impl BigDecimalExt for BigDecimal { self.is_integer() .then(|| bigdecimal::ToPrimitive::to_u32(self))? } + fn to_u64(&self) -> Option { + self.is_integer() + .then(|| bigdecimal::ToPrimitive::to_u64(self))? + } fn to_u128(&self) -> Option { self.is_integer() .then(|| bigdecimal::ToPrimitive::to_u128(self))? diff --git a/core/src/data/interval/primitive.rs b/core/src/data/interval/primitive.rs index 729e110eb..26d2d33a0 100644 --- a/core/src/data/interval/primitive.rs +++ b/core/src/data/interval/primitive.rs @@ -79,6 +79,40 @@ impl Mul for Interval { } } } + +impl Mul for Interval { + type Output = Self; + + fn mul(self, rhs: u32) -> Self { + match self { + Interval::Month(v) => Interval::Month(((v as u32) * rhs) as i32), + Interval::Microsecond(v) => Interval::Microsecond(((v as u32) * rhs) as i64), + } + } +} + +impl Mul for Interval { + type Output = Self; + + fn mul(self, rhs: u64) -> Self { + match self { + Interval::Month(v) => Interval::Month(((v as u64) * rhs) as i32), + Interval::Microsecond(v) => Interval::Microsecond(((v as u64) * rhs) as i64), + } + } +} + +impl Mul for Interval { + type Output = Self; + + fn mul(self, rhs: u128) -> Self { + match self { + Interval::Month(v) => Interval::Month(((v as u128) * rhs) as i32), + Interval::Microsecond(v) => Interval::Microsecond(((v as u128) * rhs) as i64), + } + } +} + impl Mul for Interval { type Output = Self; @@ -146,6 +180,30 @@ impl Mul for u16 { } } +impl Mul for u32 { + type Output = Interval; + + fn mul(self, rhs: Interval) -> Interval { + rhs * self + } +} + +impl Mul for u64 { + type Output = Interval; + + fn mul(self, rhs: Interval) -> Interval { + rhs * self + } +} + +impl Mul for u128 { + type Output = Interval; + + fn mul(self, rhs: Interval) -> Interval { + rhs * self + } +} + impl Mul for f64 { type Output = Interval; @@ -231,6 +289,39 @@ impl Div for Interval { } } +impl Div for Interval { + type Output = Self; + + fn div(self, rhs: u32) -> Self { + match self { + Interval::Month(v) => Interval::Month(((v as u32) / rhs) as i32), + Interval::Microsecond(v) => Interval::Microsecond(((v as u32) / rhs) as i64), + } + } +} + +impl Div for Interval { + type Output = Self; + + fn div(self, rhs: u64) -> Self { + match self { + Interval::Month(v) => Interval::Month(((v as u64) / rhs) as i32), + Interval::Microsecond(v) => Interval::Microsecond(((v as u64) / rhs) as i64), + } + } +} + +impl Div for Interval { + type Output = Self; + + fn div(self, rhs: u128) -> Self { + match self { + Interval::Month(v) => Interval::Month(((v as u128) / rhs) as i32), + Interval::Microsecond(v) => Interval::Microsecond(((v as u128) / rhs) as i64), + } + } +} + impl Div for Interval { type Output = Self; @@ -318,6 +409,40 @@ impl Div for u16 { } } } + +impl Div for u32 { + type Output = Interval; + + fn div(self, rhs: Interval) -> Interval { + match rhs { + Interval::Month(v) => Interval::Month((self / (v as u32)) as i32), + Interval::Microsecond(v) => Interval::Microsecond((self / (v as u32)) as i64), + } + } +} + +impl Div for u64 { + type Output = Interval; + + fn div(self, rhs: Interval) -> Interval { + match rhs { + Interval::Month(v) => Interval::Month((self / (v as u64)) as i32), + Interval::Microsecond(v) => Interval::Microsecond((self / (v as u64)) as i64), + } + } +} + +impl Div for u128 { + type Output = Interval; + + fn div(self, rhs: Interval) -> Interval { + match rhs { + Interval::Month(v) => Interval::Month((self / (v as u128)) as i32), + Interval::Microsecond(v) => Interval::Microsecond((self / (v as u128)) as i64), + } + } +} + impl Div for f64 { type Output = Interval; @@ -358,6 +483,15 @@ mod tests { assert_eq!(Month(2) * 3_u16, Month(6)); assert_eq!(2_u16 * Month(3), Month(6)); + assert_eq!(Month(2) * 3_u32, Month(6)); + assert_eq!(2_u32 * Month(3), Month(6)); + + assert_eq!(Month(2) * 3_u64, Month(6)); + assert_eq!(2_u64 * Month(3), Month(6)); + + assert_eq!(Month(2) * 3_u128, Month(6)); + assert_eq!(2_u128 * Month(3), Month(6)); + assert_eq!(Month(2) * 3.0, Month(6)); assert_eq!(2.0 * Month(3), Month(6)); @@ -382,6 +516,15 @@ mod tests { assert_eq!(Month(6) / 3_u16, Month(2)); assert_eq!(6_u16 / Month(2), Month(3)); + assert_eq!(Month(6) / 3_u32, Month(2)); + assert_eq!(6_u32 / Month(2), Month(3)); + + assert_eq!(Month(6) / 3_u64, Month(2)); + assert_eq!(6_u64 / Month(2), Month(3)); + + assert_eq!(Month(6) / 3_u128, Month(2)); + assert_eq!(6_u128 / Month(2), Month(3)); + assert_eq!(Month(8) / 4.0, Month(2)); assert_eq!(8.0 / Month(4), Month(2)); @@ -406,6 +549,15 @@ mod tests { assert_eq!(Microsecond(2) * 3_u16, Microsecond(6)); assert_eq!(2_u16 * Microsecond(3), Microsecond(6)); + assert_eq!(Microsecond(2) * 3_u32, Microsecond(6)); + assert_eq!(2_u32 * Microsecond(3), Microsecond(6)); + + assert_eq!(Microsecond(2) * 3_u64, Microsecond(6)); + assert_eq!(2_u64 * Microsecond(3), Microsecond(6)); + + assert_eq!(Microsecond(2) * 3_u128, Microsecond(6)); + assert_eq!(2_u128 * Microsecond(3), Microsecond(6)); + assert_eq!(Microsecond(6) / 3_i8, Microsecond(2)); assert_eq!(6_i8 / Microsecond(2), Microsecond(3)); @@ -426,5 +578,14 @@ mod tests { assert_eq!(Microsecond(6) / 3_u16, Microsecond(2)); assert_eq!(6_u16 / Microsecond(2), Microsecond(3)); + + assert_eq!(Microsecond(6) / 3_u32, Microsecond(2)); + assert_eq!(6_u32 / Microsecond(2), Microsecond(3)); + + assert_eq!(Microsecond(6) / 3_u64, Microsecond(2)); + assert_eq!(6_u64 / Microsecond(2), Microsecond(3)); + + assert_eq!(Microsecond(6) / 3_u128, Microsecond(2)); + assert_eq!(6_u128 / Microsecond(2), Microsecond(3)); } } diff --git a/core/src/data/key.rs b/core/src/data/key.rs index e0f1b9164..0796301e5 100644 --- a/core/src/data/key.rs +++ b/core/src/data/key.rs @@ -32,6 +32,9 @@ pub enum Key { I128(i128), U8(u8), U16(u16), + U32(u32), + U64(u64), + U128(u128), F64(OrderedFloat), Decimal(Decimal), Bool(bool), @@ -56,6 +59,9 @@ impl Ord for Key { (Key::I128(l), Key::I128(r)) => l.cmp(r), (Key::U8(l), Key::U8(r)) => l.cmp(r), (Key::U16(l), Key::U16(r)) => l.cmp(r), + (Key::U32(l), Key::U32(r)) => l.cmp(r), + (Key::U64(l), Key::U64(r)) => l.cmp(r), + (Key::U128(l), Key::U128(r)) => l.cmp(r), (Key::F64(l), Key::F64(r)) => l.total_cmp(&r.0), (Key::Decimal(l), Key::Decimal(r)) => l.cmp(r), (Key::Bool(l), Key::Bool(r)) => l.cmp(r), @@ -78,6 +84,9 @@ impl Ord for Key { | (Key::I128(_), _) | (Key::U8(_), _) | (Key::U16(_), _) + | (Key::U32(_), _) + | (Key::U64(_), _) + | (Key::U128(_), _) | (Key::F64(_), _) | (Key::Decimal(_), _) | (Key::Bool(_), _) @@ -95,6 +104,28 @@ impl Ord for Key { impl PartialOrd for Key { fn partial_cmp(&self, other: &Self) -> Option { + match (self, other) { + (Key::I8(l), Key::I8(r)) => Some(l.cmp(r)), + (Key::I16(l), Key::I16(r)) => Some(l.cmp(r)), + (Key::I32(l), Key::I32(r)) => Some(l.cmp(r)), + (Key::I64(l), Key::I64(r)) => Some(l.cmp(r)), + (Key::U8(l), Key::U8(r)) => Some(l.cmp(r)), + (Key::U16(l), Key::U16(r)) => Some(l.cmp(r)), + (Key::U32(l), Key::U32(r)) => Some(l.cmp(r)), + (Key::U64(l), Key::U64(r)) => Some(l.cmp(r)), + (Key::U128(l), Key::U128(r)) => Some(l.cmp(r)), + (Key::Decimal(l), Key::Decimal(r)) => Some(l.cmp(r)), + (Key::Bool(l), Key::Bool(r)) => Some(l.cmp(r)), + (Key::Str(l), Key::Str(r)) => Some(l.cmp(r)), + (Key::Bytea(l), Key::Bytea(r)) => Some(l.cmp(r)), + (Key::Inet(l), Key::Inet(r)) => Some(l.cmp(r)), + (Key::Date(l), Key::Date(r)) => Some(l.cmp(r)), + (Key::Timestamp(l), Key::Timestamp(r)) => Some(l.cmp(r)), + (Key::Time(l), Key::Time(r)) => Some(l.cmp(r)), + (Key::Interval(l), Key::Interval(r)) => l.partial_cmp(r), + (Key::Uuid(l), Key::Uuid(r)) => Some(l.cmp(r)), + _ => None, + }; Some(self.cmp(other)) } } @@ -114,6 +145,9 @@ impl TryFrom for Key { I128(v) => Ok(Key::I128(v)), U8(v) => Ok(Key::U8(v)), U16(v) => Ok(Key::U16(v)), + U32(v) => Ok(Key::U32(v)), + U64(v) => Ok(Key::U64(v)), + U128(v) => Ok(Key::U128(v)), F64(v) => Ok(Key::F64(OrderedFloat(v))), Decimal(v) => Ok(Key::Decimal(v)), Str(v) => Ok(Key::Str(v)), @@ -150,6 +184,9 @@ impl From for Value { Key::I128(v) => Value::I128(v), Key::U8(v) => Value::U8(v), Key::U16(v) => Value::U16(v), + Key::U32(v) => Value::U32(v), + Key::U64(v) => Value::U64(v), + Key::U128(v) => Value::U128(v), Key::F64(v) => Value::F64(v.0), Key::Decimal(v) => Value::Decimal(v), Key::Str(v) => Value::Str(v), @@ -234,6 +271,21 @@ impl Key { .chain(v.to_be_bytes().iter()) .copied() .collect::>(), + Key::U32(v) => [VALUE, 1] + .iter() + .chain(v.to_be_bytes().iter()) + .copied() + .collect::>(), + Key::U64(v) => [VALUE, 1] + .iter() + .chain(v.to_be_bytes().iter()) + .copied() + .collect::>(), + Key::U128(v) => [VALUE, 1] + .iter() + .chain(v.to_be_bytes().iter()) + .copied() + .collect::>(), Key::F64(_) => { return Err(KeyError::FloatToCmpBigEndianNotSupported.into()); } @@ -351,6 +403,9 @@ mod tests { assert_eq!(convert("CAST(1024 AS INT128)"), Ok(Key::I128(1024))); assert_eq!(convert("CAST(11 AS UINT8)"), Ok(Key::U8(11))); assert_eq!(convert("CAST(11 AS UINT16)"), Ok(Key::U16(11))); + assert_eq!(convert("CAST(11 AS UINT32)"), Ok(Key::U32(11))); + assert_eq!(convert("CAST(11 AS UINT64)"), Ok(Key::U64(11))); + assert_eq!(convert("CAST(11 AS UINT128)"), Ok(Key::U128(11))); assert!(matches!(convert("12.03"), Ok(Key::F64(_)))); assert_eq!( @@ -438,6 +493,15 @@ mod tests { assert!(Key::U16(10) > Key::U16(3)); assert!(Key::U16(1) > Key::Decimal(dec("1"))); + assert!(Key::U32(10) > Key::U32(3)); + assert!(Key::U32(1) > Key::Decimal(dec("1"))); + + assert!(Key::U64(10) > Key::U64(3)); + assert!(Key::U64(1) > Key::Decimal(dec("1"))); + + assert!(Key::U128(10) > Key::U128(3)); + assert!(Key::U128(1) > Key::Decimal(dec("1"))); + assert!(Key::Decimal(dec("123.45")) > Key::Decimal(dec("0.11"))); assert!(Key::Decimal(dec("1")) > Key::Bool(true)); @@ -604,6 +668,33 @@ mod tests { assert_eq!(cmp(&n1, &n4), Ordering::Less); assert_eq!(cmp(&n3, &n4), Ordering::Equal); + let n1 = U32(0).to_cmp_be_bytes(); + let n2 = U32(3).to_cmp_be_bytes(); + let n3 = U32(20).to_cmp_be_bytes(); + let n4 = U32(20).to_cmp_be_bytes(); + assert_eq!(cmp(&n1, &n2), Ordering::Less); + assert_eq!(cmp(&n3, &n2), Ordering::Greater); + assert_eq!(cmp(&n1, &n4), Ordering::Less); + assert_eq!(cmp(&n3, &n4), Ordering::Equal); + + let n1 = U64(0).to_cmp_be_bytes(); + let n2 = U64(3).to_cmp_be_bytes(); + let n3 = U64(20).to_cmp_be_bytes(); + let n4 = U64(20).to_cmp_be_bytes(); + assert_eq!(cmp(&n1, &n2), Ordering::Less); + assert_eq!(cmp(&n3, &n2), Ordering::Greater); + assert_eq!(cmp(&n1, &n4), Ordering::Less); + assert_eq!(cmp(&n3, &n4), Ordering::Equal); + + let n1 = U128(0).to_cmp_be_bytes(); + let n2 = U128(3).to_cmp_be_bytes(); + let n3 = U128(20).to_cmp_be_bytes(); + let n4 = U128(20).to_cmp_be_bytes(); + assert_eq!(cmp(&n1, &n2), Ordering::Less); + assert_eq!(cmp(&n3, &n2), Ordering::Greater); + assert_eq!(cmp(&n1, &n4), Ordering::Less); + assert_eq!(cmp(&n3, &n4), Ordering::Equal); + let dec = |n| Decimal(rust_decimal::Decimal::from_str(n).unwrap()); let n1 = dec("-1200.345678").to_cmp_be_bytes(); let n2 = dec("-1.01").to_cmp_be_bytes(); @@ -730,6 +821,9 @@ mod tests { assert_eq!(Value::from(Key::I128(32)), Value::I128(32)); assert_eq!(Value::from(Key::U8(64)), Value::U8(64)); assert_eq!(Value::from(Key::U16(128)), Value::U16(128)); + assert_eq!(Value::from(Key::U32(128)), Value::U32(128)); + assert_eq!(Value::from(Key::U64(128)), Value::U64(128)); + assert_eq!(Value::from(Key::U128(128)), Value::U128(128)); assert_eq!(Value::from(Key::F64(1.0.into())), Value::F64(1.0)); assert_eq!( Value::from(Key::Decimal(Decimal::from_str("123.45").unwrap())), diff --git a/core/src/data/value/binary_op/decimal.rs b/core/src/data/value/binary_op/decimal.rs index dda2ff22a..0e4482724 100644 --- a/core/src/data/value/binary_op/decimal.rs +++ b/core/src/data/value/binary_op/decimal.rs @@ -19,6 +19,9 @@ impl PartialEq for Decimal { I128(other) => *self == Decimal::from(*other), U8(other) => *self == Decimal::from(*other), U16(other) => *self == Decimal::from(*other), + U32(other) => *self == Decimal::from(*other), + U64(other) => *self == Decimal::from(*other), + U128(other) => *self == Decimal::from(*other), F64(other) => Decimal::from_f64_retain(*other) .map(|x| *self == x) .unwrap_or(false), @@ -37,6 +40,9 @@ impl PartialOrd for Decimal { I128(rhs) => self.partial_cmp(&(Decimal::from(rhs))), U8(rhs) => self.partial_cmp(&(Decimal::from(rhs))), U16(rhs) => self.partial_cmp(&(Decimal::from(rhs))), + U32(rhs) => self.partial_cmp(&(Decimal::from(rhs))), + U64(rhs) => self.partial_cmp(&(Decimal::from(rhs))), + U128(rhs) => self.partial_cmp(&(Decimal::from(rhs))), F64(rhs) => Decimal::from_f64_retain(rhs) .map(|x| self.partial_cmp(&x)) .unwrap_or(None), @@ -119,6 +125,40 @@ impl TryBinaryOperator for Decimal { .into() }) .map(Decimal), + U32(rhs) => lhs + .checked_add(Decimal::from(rhs)) + .ok_or_else(|| { + ValueError::BinaryOperationOverflow { + lhs: Decimal(lhs), + rhs: U32(rhs), + operator: NumericBinaryOperator::Add, + } + .into() + }) + .map(Decimal), + U64(rhs) => lhs + .checked_add(Decimal::from(rhs)) + .ok_or_else(|| { + ValueError::BinaryOperationOverflow { + lhs: Decimal(lhs), + rhs: U64(rhs), + operator: NumericBinaryOperator::Add, + } + .into() + }) + .map(Decimal), + U128(rhs) => lhs + .checked_add(Decimal::from(rhs)) + .ok_or_else(|| { + ValueError::BinaryOperationOverflow { + lhs: Decimal(lhs), + rhs: U128(rhs), + operator: NumericBinaryOperator::Add, + } + .into() + }) + .map(Decimal), + F64(rhs) => Decimal::from_f64_retain(rhs) .map(|x| Ok(Decimal(lhs + x))) .unwrap_or_else(|| Err(ValueError::FloatToDecimalConversionFailure(rhs).into())), @@ -213,6 +253,40 @@ impl TryBinaryOperator for Decimal { .into() }) .map(Decimal), + U32(rhs) => lhs + .checked_sub(Decimal::from(rhs)) + .ok_or_else(|| { + ValueError::BinaryOperationOverflow { + lhs: Decimal(lhs), + rhs: U32(rhs), + operator: NumericBinaryOperator::Subtract, + } + .into() + }) + .map(Decimal), + U64(rhs) => lhs + .checked_sub(Decimal::from(rhs)) + .ok_or_else(|| { + ValueError::BinaryOperationOverflow { + lhs: Decimal(lhs), + rhs: U64(rhs), + operator: NumericBinaryOperator::Subtract, + } + .into() + }) + .map(Decimal), + U128(rhs) => lhs + .checked_sub(Decimal::from(rhs)) + .ok_or_else(|| { + ValueError::BinaryOperationOverflow { + lhs: Decimal(lhs), + rhs: U128(rhs), + operator: NumericBinaryOperator::Subtract, + } + .into() + }) + .map(Decimal), + F64(rhs) => Decimal::from_f64_retain(rhs) .map(|x| Ok(Decimal(lhs - x))) .unwrap_or_else(|| Err(ValueError::FloatToDecimalConversionFailure(rhs).into())), @@ -307,6 +381,40 @@ impl TryBinaryOperator for Decimal { .into() }) .map(Decimal), + U32(rhs) => lhs + .checked_mul(Decimal::from(rhs)) + .ok_or_else(|| { + ValueError::BinaryOperationOverflow { + lhs: Decimal(lhs), + rhs: U32(rhs), + operator: NumericBinaryOperator::Multiply, + } + .into() + }) + .map(Decimal), + U64(rhs) => lhs + .checked_mul(Decimal::from(rhs)) + .ok_or_else(|| { + ValueError::BinaryOperationOverflow { + lhs: Decimal(lhs), + rhs: U64(rhs), + operator: NumericBinaryOperator::Multiply, + } + .into() + }) + .map(Decimal), + U128(rhs) => lhs + .checked_mul(Decimal::from(rhs)) + .ok_or_else(|| { + ValueError::BinaryOperationOverflow { + lhs: Decimal(lhs), + rhs: U128(rhs), + operator: NumericBinaryOperator::Multiply, + } + .into() + }) + .map(Decimal), + F64(rhs) => Decimal::from_f64_retain(rhs) .map(|x| Ok(Decimal(lhs * x))) .unwrap_or_else(|| Err(ValueError::FloatToDecimalConversionFailure(rhs).into())), @@ -401,6 +509,40 @@ impl TryBinaryOperator for Decimal { .into() }) .map(Decimal), + U32(rhs) => lhs + .checked_div(Decimal::from(rhs)) + .ok_or_else(|| { + ValueError::BinaryOperationOverflow { + lhs: Decimal(lhs), + rhs: U32(rhs), + operator: NumericBinaryOperator::Divide, + } + .into() + }) + .map(Decimal), + U64(rhs) => lhs + .checked_div(Decimal::from(rhs)) + .ok_or_else(|| { + ValueError::BinaryOperationOverflow { + lhs: Decimal(lhs), + rhs: U64(rhs), + operator: NumericBinaryOperator::Divide, + } + .into() + }) + .map(Decimal), + U128(rhs) => lhs + .checked_div(Decimal::from(rhs)) + .ok_or_else(|| { + ValueError::BinaryOperationOverflow { + lhs: Decimal(lhs), + rhs: U128(rhs), + operator: NumericBinaryOperator::Divide, + } + .into() + }) + .map(Decimal), + F64(rhs) => Decimal::from_f64_retain(rhs) .map(|x| Ok(Decimal(lhs / x))) .unwrap_or_else(|| Err(ValueError::FloatToDecimalConversionFailure(rhs).into())), @@ -495,6 +637,40 @@ impl TryBinaryOperator for Decimal { .into() }) .map(Decimal), + U32(rhs) => lhs + .checked_rem(Decimal::from(rhs)) + .ok_or_else(|| { + ValueError::BinaryOperationOverflow { + lhs: Decimal(lhs), + rhs: U32(rhs), + operator: NumericBinaryOperator::Modulo, + } + .into() + }) + .map(Decimal), + U64(rhs) => lhs + .checked_rem(Decimal::from(rhs)) + .ok_or_else(|| { + ValueError::BinaryOperationOverflow { + lhs: Decimal(lhs), + rhs: U64(rhs), + operator: NumericBinaryOperator::Modulo, + } + .into() + }) + .map(Decimal), + U128(rhs) => lhs + .checked_rem(Decimal::from(rhs)) + .ok_or_else(|| { + ValueError::BinaryOperationOverflow { + lhs: Decimal(lhs), + rhs: U128(rhs), + operator: NumericBinaryOperator::Modulo, + } + .into() + }) + .map(Decimal), + F64(rhs) => match Decimal::from_f64_retain(rhs) { Some(x) => lhs .checked_rem(x) @@ -609,6 +785,34 @@ mod tests { } .into()) ); + assert_eq!( + Decimal::MAX.try_add(&U32(1)), + Err(ValueError::BinaryOperationOverflow { + lhs: Decimal(Decimal::MAX), + rhs: U32(1), + operator: NumericBinaryOperator::Add, + } + .into()) + ); + assert_eq!( + Decimal::MAX.try_add(&U64(1)), + Err(ValueError::BinaryOperationOverflow { + lhs: Decimal(Decimal::MAX), + rhs: U64(1), + operator: NumericBinaryOperator::Add, + } + .into()) + ); + assert_eq!( + Decimal::MAX.try_add(&U128(1)), + Err(ValueError::BinaryOperationOverflow { + lhs: Decimal(Decimal::MAX), + rhs: U128(1), + operator: NumericBinaryOperator::Add, + } + .into()) + ); + assert_eq!( Decimal::MIN.try_subtract(&I8(1)), Err(ValueError::BinaryOperationOverflow { @@ -663,6 +867,33 @@ mod tests { } .into()) ); + assert_eq!( + Decimal::MIN.try_subtract(&U32(1)), + Err(ValueError::BinaryOperationOverflow { + lhs: Decimal(Decimal::MIN), + rhs: U32(1), + operator: NumericBinaryOperator::Subtract, + } + .into()) + ); + assert_eq!( + Decimal::MIN.try_subtract(&U64(1)), + Err(ValueError::BinaryOperationOverflow { + lhs: Decimal(Decimal::MIN), + rhs: U64(1), + operator: NumericBinaryOperator::Subtract, + } + .into()) + ); + assert_eq!( + Decimal::MIN.try_subtract(&U128(1)), + Err(ValueError::BinaryOperationOverflow { + lhs: Decimal(Decimal::MIN), + rhs: U128(1), + operator: NumericBinaryOperator::Subtract, + } + .into()) + ); assert_eq!( Decimal::MIN.try_subtract(&Decimal(Decimal::ONE)), @@ -729,6 +960,34 @@ mod tests { .into()) ); + assert_eq!( + Decimal::MAX.try_multiply(&U32(2)), + Err(ValueError::BinaryOperationOverflow { + lhs: Decimal(Decimal::MAX), + rhs: U32(2), + operator: NumericBinaryOperator::Multiply, + } + .into()) + ); + assert_eq!( + Decimal::MAX.try_multiply(&U64(2)), + Err(ValueError::BinaryOperationOverflow { + lhs: Decimal(Decimal::MAX), + rhs: U64(2), + operator: NumericBinaryOperator::Multiply, + } + .into()) + ); + assert_eq!( + Decimal::MAX.try_multiply(&U128(2)), + Err(ValueError::BinaryOperationOverflow { + lhs: Decimal(Decimal::MAX), + rhs: U128(2), + operator: NumericBinaryOperator::Multiply, + } + .into()) + ); + assert_eq!( Decimal::MAX.try_multiply(&Decimal(Decimal::TWO)), Err(ValueError::BinaryOperationOverflow { @@ -796,6 +1055,34 @@ mod tests { } .into()) ); + assert_eq!( + base.try_divide(&U32(0)), + Err(ValueError::BinaryOperationOverflow { + lhs: Decimal(base), + rhs: U32(0), + operator: NumericBinaryOperator::Divide, + } + .into()) + ); + assert_eq!( + base.try_divide(&U64(0)), + Err(ValueError::BinaryOperationOverflow { + lhs: Decimal(base), + rhs: U64(0), + operator: NumericBinaryOperator::Divide, + } + .into()) + ); + assert_eq!( + base.try_divide(&U128(0)), + Err(ValueError::BinaryOperationOverflow { + lhs: Decimal(base), + rhs: U128(0), + operator: NumericBinaryOperator::Divide, + } + .into()) + ); + assert_eq!( base.try_divide(&Decimal(Decimal::ZERO)), Err(ValueError::BinaryOperationOverflow { @@ -863,6 +1150,33 @@ mod tests { } .into()) ); + assert_eq!( + base.try_modulo(&U32(0)), + Err(ValueError::BinaryOperationOverflow { + lhs: Decimal(base), + rhs: U32(0), + operator: NumericBinaryOperator::Modulo, + } + .into()) + ); + assert_eq!( + base.try_modulo(&U64(0)), + Err(ValueError::BinaryOperationOverflow { + lhs: Decimal(base), + rhs: U64(0), + operator: NumericBinaryOperator::Modulo, + } + .into()) + ); + assert_eq!( + base.try_modulo(&U128(0)), + Err(ValueError::BinaryOperationOverflow { + lhs: Decimal(base), + rhs: U128(0), + operator: NumericBinaryOperator::Modulo, + } + .into()) + ); assert_eq!( base.try_modulo(&Decimal(Decimal::ZERO)), @@ -885,6 +1199,9 @@ mod tests { assert_eq!(base, I128(1)); assert_eq!(base, U8(1)); assert_eq!(base, U16(1)); + assert_eq!(base, U32(1)); + assert_eq!(base, U64(1)); + assert_eq!(base, U128(1)); assert_eq!(base, F64(1.0)); assert_eq!(base, Decimal(Decimal::ONE)); @@ -901,6 +1218,9 @@ mod tests { assert_eq!(base.partial_cmp(&I128(1)), Some(Ordering::Equal)); assert_eq!(base.partial_cmp(&U8(1)), Some(Ordering::Equal)); assert_eq!(base.partial_cmp(&U16(1)), Some(Ordering::Equal)); + assert_eq!(base.partial_cmp(&U32(1)), Some(Ordering::Equal)); + assert_eq!(base.partial_cmp(&U64(1)), Some(Ordering::Equal)); + assert_eq!(base.partial_cmp(&U128(1)), Some(Ordering::Equal)); assert_eq!(base.partial_cmp(&F64(1.0)), Some(Ordering::Equal)); assert_eq!( base.partial_cmp(&Decimal(Decimal::ONE)), @@ -920,6 +1240,9 @@ mod tests { assert_eq!(base.try_add(&I128(1)), Ok(Decimal(Decimal::TWO))); assert_eq!(base.try_add(&U8(1)), Ok(Decimal(Decimal::TWO))); assert_eq!(base.try_add(&U16(1)), Ok(Decimal(Decimal::TWO))); + assert_eq!(base.try_add(&U32(1)), Ok(Decimal(Decimal::TWO))); + assert_eq!(base.try_add(&U64(1)), Ok(Decimal(Decimal::TWO))); + assert_eq!(base.try_add(&U128(1)), Ok(Decimal(Decimal::TWO))); assert_eq!(base.try_add(&F64(1.0)), Ok(Decimal(Decimal::TWO))); assert_eq!( base.try_add(&Decimal(Decimal::ONE)), @@ -947,6 +1270,9 @@ mod tests { assert_eq!(base.try_subtract(&I128(1)), Ok(Decimal(Decimal::ZERO))); assert_eq!(base.try_subtract(&U8(1)), Ok(Decimal(Decimal::ZERO))); assert_eq!(base.try_subtract(&U16(1)), Ok(Decimal(Decimal::ZERO))); + assert_eq!(base.try_subtract(&U32(1)), Ok(Decimal(Decimal::ZERO))); + assert_eq!(base.try_subtract(&U64(1)), Ok(Decimal(Decimal::ZERO))); + assert_eq!(base.try_subtract(&U128(1)), Ok(Decimal(Decimal::ZERO))); assert_eq!(base.try_subtract(&F64(1.0)), Ok(Decimal(Decimal::ZERO))); assert_eq!( base.try_subtract(&Decimal(Decimal::ONE)), @@ -974,6 +1300,9 @@ mod tests { assert_eq!(base.try_multiply(&I128(1)), Ok(Decimal(Decimal::ONE))); assert_eq!(base.try_multiply(&U8(1)), Ok(Decimal(Decimal::ONE))); assert_eq!(base.try_multiply(&U16(1)), Ok(Decimal(Decimal::ONE))); + assert_eq!(base.try_multiply(&U32(1)), Ok(Decimal(Decimal::ONE))); + assert_eq!(base.try_multiply(&U64(1)), Ok(Decimal(Decimal::ONE))); + assert_eq!(base.try_multiply(&U128(1)), Ok(Decimal(Decimal::ONE))); assert_eq!(base.try_multiply(&F64(1.0)), Ok(Decimal(Decimal::ONE))); assert_eq!( base.try_multiply(&Decimal(Decimal::ONE)), @@ -1001,6 +1330,9 @@ mod tests { assert_eq!(base.try_divide(&I128(1)), Ok(Decimal(Decimal::ONE))); assert_eq!(base.try_divide(&U8(1)), Ok(Decimal(Decimal::ONE))); assert_eq!(base.try_divide(&U16(1)), Ok(Decimal(Decimal::ONE))); + assert_eq!(base.try_divide(&U32(1)), Ok(Decimal(Decimal::ONE))); + assert_eq!(base.try_divide(&U64(1)), Ok(Decimal(Decimal::ONE))); + assert_eq!(base.try_divide(&U128(1)), Ok(Decimal(Decimal::ONE))); assert_eq!(base.try_divide(&F64(1.0)), Ok(Decimal(Decimal::ONE))); assert_eq!( base.try_divide(&Decimal(Decimal::ONE)), @@ -1028,6 +1360,9 @@ mod tests { assert_eq!(base.try_modulo(&I128(1)), Ok(Decimal(Decimal::ZERO))); assert_eq!(base.try_modulo(&U8(1)), Ok(Decimal(Decimal::ZERO))); assert_eq!(base.try_modulo(&U16(1)), Ok(Decimal(Decimal::ZERO))); + assert_eq!(base.try_modulo(&U32(1)), Ok(Decimal(Decimal::ZERO))); + assert_eq!(base.try_modulo(&U64(1)), Ok(Decimal(Decimal::ZERO))); + assert_eq!(base.try_modulo(&U128(1)), Ok(Decimal(Decimal::ZERO))); assert_eq!(base.try_modulo(&F64(1.0)), Ok(Decimal(Decimal::ZERO))); assert_eq!( base.try_modulo(&Decimal(Decimal::ONE)), diff --git a/core/src/data/value/binary_op/f64.rs b/core/src/data/value/binary_op/f64.rs index 287ac920c..a9419d17d 100644 --- a/core/src/data/value/binary_op/f64.rs +++ b/core/src/data/value/binary_op/f64.rs @@ -22,6 +22,9 @@ impl PartialEq for f64 { I128(rhs) => (lhs - (rhs as f64)).abs() < f64::EPSILON, U8(rhs) => (lhs - (rhs as f64)).abs() < f64::EPSILON, U16(rhs) => (lhs - (rhs as f64)).abs() < f64::EPSILON, + U32(rhs) => (lhs - (rhs as f64)).abs() < f64::EPSILON, + U64(rhs) => (lhs - (rhs as f64)).abs() < f64::EPSILON, + U128(rhs) => (lhs - (rhs as f64)).abs() < f64::EPSILON, F64(rhs) => (lhs - rhs).abs() < f64::EPSILON, Decimal(rhs) => Decimal::from_f64_retain(lhs) .map(|x| rhs == x) @@ -41,6 +44,9 @@ impl PartialOrd for f64 { I128(rhs) => self.partial_cmp(&(rhs as f64)), U8(rhs) => self.partial_cmp(&(rhs as f64)), U16(rhs) => self.partial_cmp(&(rhs as f64)), + U32(rhs) => self.partial_cmp(&(rhs as f64)), + U64(rhs) => self.partial_cmp(&(rhs as f64)), + U128(rhs) => self.partial_cmp(&(rhs as f64)), F64(rhs) => self.partial_cmp(&rhs), Decimal(rhs) => Decimal::from_f64_retain(*self) .map(|x| x.partial_cmp(&rhs)) @@ -64,6 +70,9 @@ impl TryBinaryOperator for f64 { I128(rhs) => Ok(F64(lhs + rhs as f64)), U8(rhs) => Ok(F64(lhs + rhs as f64)), U16(rhs) => Ok(F64(lhs + rhs as f64)), + U32(rhs) => Ok(F64(lhs + rhs as f64)), + U64(rhs) => Ok(F64(lhs + rhs as f64)), + U128(rhs) => Ok(F64(lhs + rhs as f64)), F64(rhs) => Ok(F64(lhs + rhs)), Decimal(rhs) => Decimal::from_f64_retain(lhs) .map(|x| Ok(Decimal(x + rhs))) @@ -89,6 +98,9 @@ impl TryBinaryOperator for f64 { I128(rhs) => Ok(F64(lhs - rhs as f64)), U8(rhs) => Ok(F64(lhs - rhs as f64)), U16(rhs) => Ok(F64(lhs - rhs as f64)), + U32(rhs) => Ok(F64(lhs - rhs as f64)), + U64(rhs) => Ok(F64(lhs - rhs as f64)), + U128(rhs) => Ok(F64(lhs - rhs as f64)), F64(rhs) => Ok(F64(lhs - rhs)), Decimal(rhs) => Decimal::from_f64_retain(lhs) .map(|x| Ok(Decimal(x - rhs))) @@ -114,6 +126,9 @@ impl TryBinaryOperator for f64 { I128(rhs) => Ok(F64(lhs * rhs as f64)), U8(rhs) => Ok(F64(lhs * rhs as f64)), U16(rhs) => Ok(F64(lhs * rhs as f64)), + U32(rhs) => Ok(F64(lhs * rhs as f64)), + U64(rhs) => Ok(F64(lhs * rhs as f64)), + U128(rhs) => Ok(F64(lhs * rhs as f64)), F64(rhs) => Ok(F64(lhs * rhs)), Interval(rhs) => Ok(Interval(lhs * rhs)), Decimal(rhs) => Decimal::from_f64_retain(lhs) @@ -140,6 +155,9 @@ impl TryBinaryOperator for f64 { I128(rhs) => Ok(F64(lhs / rhs as f64)), U8(rhs) => Ok(F64(lhs / rhs as f64)), U16(rhs) => Ok(F64(lhs / rhs as f64)), + U32(rhs) => Ok(F64(lhs / rhs as f64)), + U64(rhs) => Ok(F64(lhs / rhs as f64)), + U128(rhs) => Ok(F64(lhs / rhs as f64)), F64(rhs) => Ok(F64(lhs / rhs)), Decimal(rhs) => Decimal::from_f64_retain(lhs) .map(|x| Ok(Decimal(x * rhs))) @@ -165,6 +183,9 @@ impl TryBinaryOperator for f64 { I128(rhs) => Ok(F64(lhs % rhs as f64)), U8(rhs) => Ok(F64(lhs % rhs as f64)), U16(rhs) => Ok(F64(lhs % rhs as f64)), + U32(rhs) => Ok(F64(lhs % rhs as f64)), + U64(rhs) => Ok(F64(lhs % rhs as f64)), + U128(rhs) => Ok(F64(lhs % rhs as f64)), F64(rhs) => Ok(F64(lhs % rhs)), Decimal(rhs) => match Decimal::from_f64_retain(lhs) { Some(x) => x @@ -211,6 +232,9 @@ mod tests { assert_eq!(base, I128(1)); assert_eq!(base, U8(1)); assert_eq!(base, U16(1)); + assert_eq!(base, U32(1)); + assert_eq!(base, U64(1)); + assert_eq!(base, U128(1)); assert_eq!(base, F64(1.0)); assert_eq!(base, Decimal(Decimal::from(1))); @@ -228,6 +252,9 @@ mod tests { assert_eq!(base.partial_cmp(&I128(1)), Some(Ordering::Equal)); assert_eq!(base.partial_cmp(&U8(1)), Some(Ordering::Equal)); assert_eq!(base.partial_cmp(&U16(1)), Some(Ordering::Equal)); + assert_eq!(base.partial_cmp(&U32(1)), Some(Ordering::Equal)); + assert_eq!(base.partial_cmp(&U64(1)), Some(Ordering::Equal)); + assert_eq!(base.partial_cmp(&U128(1)), Some(Ordering::Equal)); assert_eq!(base.partial_cmp(&F64(1.0)), Some(Ordering::Equal)); assert_eq!( base.partial_cmp(&Decimal(Decimal::ONE)), @@ -248,6 +275,9 @@ mod tests { assert!(matches!(base.try_add(&I128(1)), Ok(F64(x)) if (x - 2.0).abs() < f64::EPSILON )); assert!(matches!(base.try_add(&U8(1)), Ok(F64(x)) if (x - 2.0).abs() < f64::EPSILON )); assert!(matches!(base.try_add(&U16(1)), Ok(F64(x)) if (x - 2.0).abs() < f64::EPSILON )); + assert!(matches!(base.try_add(&U32(1)),Ok(F64(x)) if (x-2.0).abs() < f64::EPSILON)); + assert!(matches!(base.try_add(&U64(1)),Ok(F64(x)) if (x-2.0).abs() < f64::EPSILON)); + assert!(matches!(base.try_add(&U128(1)),Ok(F64(x)) if (x-2.0).abs() $lhs + .$method($lhs_primitive::try_from($rhs)?) + .ok_or_else(|| { + ValueError::BinaryOperationOverflow { + lhs: $lhs_variant($lhs), + rhs: U32(rhs), + operator: $op, + } + .into() + }), + U64(rhs) => $lhs + .$method($lhs_primitive::try_from($rhs)?) + .ok_or_else(|| { + ValueError::BinaryOperationOverflow { + lhs: $lhs_variant($lhs), + rhs: U64(rhs), + operator: $op, + } + .into() + }), + U128(rhs) => $lhs + .$method($lhs_primitive::try_from($rhs)?) + .ok_or_else(|| { + ValueError::BinaryOperationOverflow { + lhs: $lhs_variant($lhs), + rhs: U128(rhs), + operator: $op, + } + .into() + }), F64(rhs) => $lhs .$method($lhs_primitive::try_from($rhs)?) .ok_or_else(|| { @@ -229,6 +259,18 @@ macro_rules! generate_binary_op_tests { $primitive::MAX.try_add(&U16(1)), overflow_err($variant($primitive::MAX), U16(1), Add) ); + assert_eq!( + $primitive::MAX.try_add(&U32(1)), + overflow_err($variant($primitive::MAX), U32(1), Add) + ); + assert_eq!( + $primitive::MAX.try_add(&U64(1)), + overflow_err($variant($primitive::MAX), U64(1), Add) + ); + assert_eq!( + $primitive::MAX.try_add(&U128(1)), + overflow_err($variant($primitive::MAX), U128(1), Add) + ); } #[test] @@ -273,6 +315,18 @@ macro_rules! generate_binary_op_tests { $primitive::MIN.try_subtract(&U16(1)), overflow_err($variant($primitive::MIN), U16(1), Subtract) ); + assert_eq!( + $primitive::MIN.try_subtract(&U32(1)), + overflow_err($variant($primitive::MIN), U32(1), Subtract) + ); + assert_eq!( + $primitive::MIN.try_subtract(&U64(1)), + overflow_err($variant($primitive::MIN), U64(1), Subtract) + ); + assert_eq!( + $primitive::MIN.try_subtract(&U128(1)), + overflow_err($variant($primitive::MIN), U128(1), Subtract) + ); } #[test] @@ -317,6 +371,18 @@ macro_rules! generate_binary_op_tests { $primitive::MAX.try_multiply(&U16(2)), overflow_err($variant($primitive::MAX), U16(2), Multiply) ); + assert_eq!( + $primitive::MAX.try_multiply(&U32(2)), + overflow_err($variant($primitive::MAX), U32(2), Multiply) + ); + assert_eq!( + $primitive::MAX.try_multiply(&U64(2)), + overflow_err($variant($primitive::MAX), U64(2), Multiply) + ); + assert_eq!( + $primitive::MAX.try_multiply(&U128(2)), + overflow_err($variant($primitive::MAX), U128(2), Multiply) + ); } #[test] @@ -357,6 +423,18 @@ macro_rules! generate_binary_op_tests { $primitive::MAX.try_divide(&U16(0)), overflow_err($variant($primitive::MAX), U16(0), Divide) ); + assert_eq!( + $primitive::MAX.try_divide(&U32(0)), + overflow_err($variant($primitive::MAX), U32(0), Divide) + ); + assert_eq!( + $primitive::MAX.try_divide(&U64(0)), + overflow_err($variant($primitive::MAX), U64(0), Divide) + ); + assert_eq!( + $primitive::MAX.try_divide(&U128(0)), + overflow_err($variant($primitive::MAX), U128(0), Divide) + ); } #[test] @@ -397,6 +475,18 @@ macro_rules! generate_binary_op_tests { $primitive::MAX.try_modulo(&U16(0)), overflow_err($variant($primitive::MAX), U16(0), Modulo) ); + assert_eq!( + $primitive::MAX.try_modulo(&U32(0)), + overflow_err($variant($primitive::MAX), U32(0), Modulo) + ); + assert_eq!( + $primitive::MAX.try_modulo(&U64(0)), + overflow_err($variant($primitive::MAX), U64(0), Modulo) + ); + assert_eq!( + $primitive::MAX.try_modulo(&U128(0)), + overflow_err($variant($primitive::MAX), U128(0), Modulo) + ); } #[test] @@ -412,6 +502,9 @@ macro_rules! generate_binary_op_tests { assert_eq!(base.try_add(&I128(1)), Ok($variant(2))); assert_eq!(base.try_add(&U8(1)), Ok($variant(2))); assert_eq!(base.try_add(&U16(1)), Ok($variant(2))); + assert_eq!(base.try_add(&U32(1)), Ok($variant(2))); + assert_eq!(base.try_add(&U64(1)), Ok($variant(2))); + assert_eq!(base.try_add(&U128(1)), Ok($variant(2))); assert_eq!( base.try_add(&Bool(true)), @@ -437,6 +530,9 @@ macro_rules! generate_binary_op_tests { assert_eq!(base.try_subtract(&I128(1)), Ok($variant(0))); assert_eq!(base.try_subtract(&U8(1)), Ok($variant(0))); assert_eq!(base.try_subtract(&U16(1)), Ok($variant(0))); + assert_eq!(base.try_subtract(&U32(1)), Ok($variant(0))); + assert_eq!(base.try_subtract(&U64(1)), Ok($variant(0))); + assert_eq!(base.try_subtract(&U128(1)), Ok($variant(0))); assert_eq!( base.try_subtract(&Bool(true)), @@ -462,6 +558,9 @@ macro_rules! generate_binary_op_tests { assert_eq!(base.try_multiply(&I128(2)), Ok($variant(6))); assert_eq!(base.try_multiply(&U8(2)), Ok($variant(6))); assert_eq!(base.try_multiply(&U16(2)), Ok($variant(6))); + assert_eq!(base.try_multiply(&U32(2)), Ok($variant(6))); + assert_eq!(base.try_multiply(&U64(2)), Ok($variant(6))); + assert_eq!(base.try_multiply(&U128(2)), Ok($variant(6))); assert_eq!( base.try_multiply(&Bool(true)), @@ -487,6 +586,9 @@ macro_rules! generate_binary_op_tests { assert_eq!(base.try_divide(&I128(2)), Ok($variant(3))); assert_eq!(base.try_divide(&U8(2)), Ok($variant(3))); assert_eq!(base.try_divide(&U16(2)), Ok($variant(3))); + assert_eq!(base.try_divide(&U32(2)), Ok($variant(3))); + assert_eq!(base.try_divide(&U64(2)), Ok($variant(3))); + assert_eq!(base.try_divide(&U128(2)), Ok($variant(3))); assert_eq!( base.try_divide(&Bool(true)), @@ -512,6 +614,9 @@ macro_rules! generate_binary_op_tests { assert_eq!(base.try_modulo(&I128(1)), Ok($variant(0))); assert_eq!(base.try_modulo(&U8(1)), Ok($variant(0))); assert_eq!(base.try_modulo(&U16(1)), Ok($variant(0))); + assert_eq!(base.try_modulo(&U32(1)), Ok($variant(0))); + assert_eq!(base.try_modulo(&U64(1)), Ok($variant(0))); + assert_eq!(base.try_modulo(&U128(1)), Ok($variant(0))); assert_eq!( base.try_modulo(&Bool(true)), @@ -584,6 +689,9 @@ macro_rules! generate_cmp_ord_tests { assert_eq!(base, I128(1)); assert_eq!(base, U8(1)); assert_eq!(base, U16(1)); + assert_eq!(base, U32(1)); + assert_eq!(base, U64(1)); + assert_eq!(base, U128(1)); assert_ne!(base, Bool(true)); } @@ -604,6 +712,9 @@ macro_rules! generate_cmp_ord_tests { assert_eq!(base.partial_cmp(&I128(0)), Some(Ordering::Greater)); assert_eq!(base.partial_cmp(&U8(0)), Some(Ordering::Greater)); assert_eq!(base.partial_cmp(&U16(0)), Some(Ordering::Greater)); + assert_eq!(base.partial_cmp(&U32(0)), Some(Ordering::Greater)); + assert_eq!(base.partial_cmp(&U64(0)), Some(Ordering::Greater)); + assert_eq!(base.partial_cmp(&U128(0)), Some(Ordering::Greater)); assert_eq!( base.partial_cmp(&Decimal(Decimal::ONE)), @@ -617,6 +728,9 @@ macro_rules! generate_cmp_ord_tests { assert_eq!(base.partial_cmp(&I128(1)), Some(Ordering::Equal)); assert_eq!(base.partial_cmp(&U8(1)), Some(Ordering::Equal)); assert_eq!(base.partial_cmp(&U16(1)), Some(Ordering::Equal)); + assert_eq!(base.partial_cmp(&U32(1)), Some(Ordering::Equal)); + assert_eq!(base.partial_cmp(&U64(1)), Some(Ordering::Equal)); + assert_eq!(base.partial_cmp(&U128(1)), Some(Ordering::Equal)); assert_eq!( base.partial_cmp(&Decimal(Decimal::TWO)), @@ -630,6 +744,9 @@ macro_rules! generate_cmp_ord_tests { assert_eq!(base.partial_cmp(&I128(2)), Some(Ordering::Less)); assert_eq!(base.partial_cmp(&U8(2)), Some(Ordering::Less)); assert_eq!(base.partial_cmp(&U16(2)), Some(Ordering::Less)); + assert_eq!(base.partial_cmp(&U32(2)), Some(Ordering::Less)); + assert_eq!(base.partial_cmp(&U64(2)), Some(Ordering::Less)); + assert_eq!(base.partial_cmp(&U128(2)), Some(Ordering::Less)); assert_eq!(base.partial_cmp(&Bool(true)), None); } diff --git a/core/src/data/value/binary_op/integer/mod.rs b/core/src/data/value/binary_op/integer/mod.rs index d35c84a4b..11a6b7efb 100644 --- a/core/src/data/value/binary_op/integer/mod.rs +++ b/core/src/data/value/binary_op/integer/mod.rs @@ -3,7 +3,10 @@ mod i16; mod i32; mod i64; mod i8; +mod u128; mod u16; +mod u32; +mod u64; mod u8; mod macros; diff --git a/core/src/data/value/binary_op/integer/u128.rs b/core/src/data/value/binary_op/integer/u128.rs new file mode 100644 index 000000000..f534eca3f --- /dev/null +++ b/core/src/data/value/binary_op/integer/u128.rs @@ -0,0 +1,9 @@ +use {crate::prelude::Value, std::cmp::Ordering}; + +super::macros::impl_try_binary_op!(U128, u128); +#[cfg(test)] +super::macros::generate_binary_op_tests!(U128, u128); + +super::macros::impl_partial_cmp_ord_method!(u128); +#[cfg(test)] +super::macros::generate_cmp_ord_tests!(u128); diff --git a/core/src/data/value/binary_op/integer/u32.rs b/core/src/data/value/binary_op/integer/u32.rs new file mode 100644 index 000000000..8ae4480be --- /dev/null +++ b/core/src/data/value/binary_op/integer/u32.rs @@ -0,0 +1,9 @@ +use {crate::prelude::Value, std::cmp::Ordering}; + +super::macros::impl_try_binary_op!(U32, u32); +#[cfg(test)] +super::macros::generate_binary_op_tests!(U32, u32); + +super::macros::impl_partial_cmp_ord_method!(u32); +#[cfg(test)] +super::macros::generate_cmp_ord_tests!(u32); diff --git a/core/src/data/value/binary_op/integer/u64.rs b/core/src/data/value/binary_op/integer/u64.rs new file mode 100644 index 000000000..8acfbf79d --- /dev/null +++ b/core/src/data/value/binary_op/integer/u64.rs @@ -0,0 +1,9 @@ +use {crate::prelude::Value, std::cmp::Ordering}; + +super::macros::impl_try_binary_op!(U64, u64); +#[cfg(test)] +super::macros::generate_binary_op_tests!(U64, u64); + +super::macros::impl_partial_cmp_ord_method!(u64); +#[cfg(test)] +super::macros::generate_cmp_ord_tests!(u64); diff --git a/core/src/data/value/convert.rs b/core/src/data/value/convert.rs index 003e0037b..e5a6c2f2c 100644 --- a/core/src/data/value/convert.rs +++ b/core/src/data/value/convert.rs @@ -27,6 +27,9 @@ impl From<&Value> for String { Value::I128(value) => value.to_string(), Value::U8(value) => value.to_string(), Value::U16(value) => value.to_string(), + Value::U32(value) => value.to_string(), + Value::U64(value) => value.to_string(), + Value::U128(value) => value.to_string(), Value::F64(value) => value.to_string(), Value::Date(value) => value.to_string(), Value::Timestamp(value) => value.to_string(), @@ -91,6 +94,21 @@ impl TryFrom<&Value> for bool { 0 => false, _ => return Err(ValueError::ImpossibleCast.into()), }, + Value::U32(value) => match value { + 1 => true, + 0 => false, + _ => return Err(ValueError::ImpossibleCast.into()), + }, + Value::U64(value) => match value { + 1 => true, + 0 => false, + _ => return Err(ValueError::ImpossibleCast.into()), + }, + Value::U128(value) => match value { + 1 => true, + 0 => false, + _ => return Err(ValueError::ImpossibleCast.into()), + }, Value::F64(value) => { if value.eq(&1.0) { true @@ -141,6 +159,9 @@ impl TryFrom<&Value> for i8 { Value::I128(value) => value.to_i8().ok_or(ValueError::ImpossibleCast)?, Value::U8(value) => value.to_i8().ok_or(ValueError::ImpossibleCast)?, Value::U16(value) => value.to_i8().ok_or(ValueError::ImpossibleCast)?, + Value::U32(value) => value.to_i8().ok_or(ValueError::ImpossibleCast)?, + Value::U64(value) => value.to_i8().ok_or(ValueError::ImpossibleCast)?, + Value::U128(value) => value.to_i8().ok_or(ValueError::ImpossibleCast)?, Value::F64(value) => value.to_i8().ok_or(ValueError::ImpossibleCast)?, Value::Str(value) => value .parse::() @@ -173,6 +194,9 @@ impl TryFrom<&Value> for i16 { Value::I128(value) => value.to_i16().ok_or(ValueError::ImpossibleCast)?, Value::U8(value) => value.to_i16().ok_or(ValueError::ImpossibleCast)?, Value::U16(value) => value.to_i16().ok_or(ValueError::ImpossibleCast)?, + Value::U32(value) => value.to_i16().ok_or(ValueError::ImpossibleCast)?, + Value::U64(value) => value.to_i16().ok_or(ValueError::ImpossibleCast)?, + Value::U128(value) => value.to_i16().ok_or(ValueError::ImpossibleCast)?, Value::F64(value) => value.to_i16().ok_or(ValueError::ImpossibleCast)?, Value::Str(value) => value .parse::() @@ -205,6 +229,9 @@ impl TryFrom<&Value> for i32 { Value::I128(value) => value.to_i32().ok_or(ValueError::ImpossibleCast)?, Value::U8(value) => value.to_i32().ok_or(ValueError::ImpossibleCast)?, Value::U16(value) => value.to_i32().ok_or(ValueError::ImpossibleCast)?, + Value::U32(value) => value.to_i32().ok_or(ValueError::ImpossibleCast)?, + Value::U64(value) => value.to_i32().ok_or(ValueError::ImpossibleCast)?, + Value::U128(value) => value.to_i32().ok_or(ValueError::ImpossibleCast)?, Value::F64(value) => value.to_i32().ok_or(ValueError::ImpossibleCast)?, Value::Str(value) => value .parse::() @@ -237,6 +264,9 @@ impl TryFrom<&Value> for i64 { Value::I128(value) => value.to_i64().ok_or(ValueError::ImpossibleCast)?, Value::U8(value) => value.to_i64().ok_or(ValueError::ImpossibleCast)?, Value::U16(value) => value.to_i64().ok_or(ValueError::ImpossibleCast)?, + Value::U32(value) => value.to_i64().ok_or(ValueError::ImpossibleCast)?, + Value::U64(value) => value.to_i64().ok_or(ValueError::ImpossibleCast)?, + Value::U128(value) => value.to_i64().ok_or(ValueError::ImpossibleCast)?, Value::F64(value) => value.to_i64().ok_or(ValueError::ImpossibleCast)?, Value::Str(value) => value .parse::() @@ -269,6 +299,9 @@ impl TryFrom<&Value> for i128 { Value::I128(value) => *value, Value::U8(value) => *value as i128, Value::U16(value) => *value as i128, + Value::U32(value) => value.to_i128().ok_or(ValueError::ImpossibleCast)?, + Value::U64(value) => value.to_i128().ok_or(ValueError::ImpossibleCast)?, + Value::U128(value) => value.to_i128().ok_or(ValueError::ImpossibleCast)?, Value::F64(value) => value.to_i128().ok_or(ValueError::ImpossibleCast)?, Value::Str(value) => value .parse::() @@ -301,6 +334,9 @@ impl TryFrom<&Value> for u8 { Value::I128(value) => value.to_u8().ok_or(ValueError::ImpossibleCast)?, Value::U8(value) => *value, Value::U16(value) => value.to_u8().ok_or(ValueError::ImpossibleCast)?, + Value::U32(value) => value.to_u8().ok_or(ValueError::ImpossibleCast)?, + Value::U64(value) => value.to_u8().ok_or(ValueError::ImpossibleCast)?, + Value::U128(value) => value.to_u8().ok_or(ValueError::ImpossibleCast)?, Value::F64(value) => value.to_u8().ok_or(ValueError::ImpossibleCast)?, Value::Str(value) => value .parse::() @@ -332,6 +368,9 @@ impl TryFrom<&Value> for u16 { Value::I128(value) => value.to_u16().ok_or(ValueError::ImpossibleCast)?, Value::U8(value) => value.to_u16().ok_or(ValueError::ImpossibleCast)?, Value::U16(value) => *value, + Value::U32(value) => value.to_u16().ok_or(ValueError::ImpossibleCast)?, + Value::U64(value) => value.to_u16().ok_or(ValueError::ImpossibleCast)?, + Value::U128(value) => value.to_u16().ok_or(ValueError::ImpossibleCast)?, Value::F64(value) => value.to_u16().ok_or(ValueError::ImpossibleCast)?, Value::Str(value) => value .parse::() @@ -351,6 +390,113 @@ impl TryFrom<&Value> for u16 { } } +impl TryFrom<&Value> for u32 { + type Error = Error; + + fn try_from(v: &Value) -> Result { + Ok(match v { + Value::Bool(value) => u32::from(*value), + Value::I8(value) => value.to_u32().ok_or(ValueError::ImpossibleCast)?, + Value::I16(value) => value.to_u32().ok_or(ValueError::ImpossibleCast)?, + Value::I32(value) => value.to_u32().ok_or(ValueError::ImpossibleCast)?, + Value::I64(value) => value.to_u32().ok_or(ValueError::ImpossibleCast)?, + Value::I128(value) => value.to_u32().ok_or(ValueError::ImpossibleCast)?, + Value::U8(value) => value.to_u32().ok_or(ValueError::ImpossibleCast)?, + Value::U16(value) => value.to_u32().ok_or(ValueError::ImpossibleCast)?, + Value::U32(value) => *value, + Value::U64(value) => value.to_u32().ok_or(ValueError::ImpossibleCast)?, + Value::U128(value) => value.to_u32().ok_or(ValueError::ImpossibleCast)?, + Value::F64(value) => value.to_u32().ok_or(ValueError::ImpossibleCast)?, + Value::Str(value) => value + .parse::() + .map_err(|_| ValueError::ImpossibleCast)?, + Value::Decimal(value) => value.to_u32().ok_or(ValueError::ImpossibleCast)?, + Value::Inet(IpAddr::V4(value)) => u32::from(*value), + Value::Date(_) + | Value::Timestamp(_) + | Value::Time(_) + | Value::Interval(_) + | Value::Uuid(_) + | Value::Inet(_) + | Value::Map(_) + | Value::List(_) + | Value::Bytea(_) + | Value::Null => return Err(ValueError::ImpossibleCast.into()), + }) + } +} + +impl TryFrom<&Value> for u64 { + type Error = Error; + + fn try_from(v: &Value) -> Result { + Ok(match v { + Value::Bool(value) => u64::from(*value), + Value::I8(value) => value.to_u64().ok_or(ValueError::ImpossibleCast)?, + Value::I16(value) => value.to_u64().ok_or(ValueError::ImpossibleCast)?, + Value::I32(value) => value.to_u64().ok_or(ValueError::ImpossibleCast)?, + Value::I64(value) => value.to_u64().ok_or(ValueError::ImpossibleCast)?, + Value::I128(value) => value.to_u64().ok_or(ValueError::ImpossibleCast)?, + Value::U8(value) => value.to_u64().ok_or(ValueError::ImpossibleCast)?, + Value::U16(value) => value.to_u64().ok_or(ValueError::ImpossibleCast)?, + Value::U32(value) => value.to_u64().ok_or(ValueError::ImpossibleCast)?, + Value::U64(value) => *value, + Value::U128(value) => value.to_u64().ok_or(ValueError::ImpossibleCast)?, + Value::F64(value) => value.to_u64().ok_or(ValueError::ImpossibleCast)?, + Value::Str(value) => value + .parse::() + .map_err(|_| ValueError::ImpossibleCast)?, + Value::Decimal(value) => value.to_u64().ok_or(ValueError::ImpossibleCast)?, + Value::Date(_) + | Value::Timestamp(_) + | Value::Time(_) + | Value::Interval(_) + | Value::Uuid(_) + | Value::Inet(_) + | Value::Map(_) + | Value::List(_) + | Value::Bytea(_) + | Value::Null => return Err(ValueError::ImpossibleCast.into()), + }) + } +} + +impl TryFrom<&Value> for u128 { + type Error = Error; + + fn try_from(v: &Value) -> Result { + Ok(match v { + Value::Bool(value) => u128::from(*value), + Value::I8(value) => value.to_u128().ok_or(ValueError::ImpossibleCast)?, + Value::I16(value) => value.to_u128().ok_or(ValueError::ImpossibleCast)?, + Value::I32(value) => value.to_u128().ok_or(ValueError::ImpossibleCast)?, + Value::I64(value) => value.to_u128().ok_or(ValueError::ImpossibleCast)?, + Value::I128(value) => value.to_u128().ok_or(ValueError::ImpossibleCast)?, + Value::U8(value) => value.to_u128().ok_or(ValueError::ImpossibleCast)?, + Value::U16(value) => value.to_u128().ok_or(ValueError::ImpossibleCast)?, + Value::U32(value) => value.to_u128().ok_or(ValueError::ImpossibleCast)?, + Value::U64(value) => value.to_u128().ok_or(ValueError::ImpossibleCast)?, + Value::U128(value) => *value, + Value::F64(value) => value.to_u128().ok_or(ValueError::ImpossibleCast)?, + Value::Str(value) => value + .parse::() + .map_err(|_| ValueError::ImpossibleCast)?, + Value::Decimal(value) => value.to_u128().ok_or(ValueError::ImpossibleCast)?, + Value::Inet(IpAddr::V6(v)) => u128::from(*v), + Value::Uuid(value) => *value, + Value::Date(_) + | Value::Timestamp(_) + | Value::Time(_) + | Value::Interval(_) + | Value::Map(_) + | Value::List(_) + | Value::Inet(IpAddr::V4(_)) + | Value::Bytea(_) + | Value::Null => return Err(ValueError::ImpossibleCast.into()), + }) + } +} + impl TryFrom<&Value> for f64 { type Error = Error; @@ -370,6 +516,9 @@ impl TryFrom<&Value> for f64 { Value::I128(value) => *value as f64, Value::U8(value) => value.to_f64().ok_or(ValueError::ImpossibleCast)?, Value::U16(value) => value.to_f64().ok_or(ValueError::ImpossibleCast)?, + Value::U32(value) => value.to_f64().ok_or(ValueError::ImpossibleCast)?, + Value::U64(value) => value.to_f64().ok_or(ValueError::ImpossibleCast)?, + Value::U128(value) => value.to_f64().ok_or(ValueError::ImpossibleCast)?, Value::F64(value) => *value, Value::Str(value) => value .parse::() @@ -402,6 +551,9 @@ impl TryFrom<&Value> for usize { Value::I128(value) => value.to_usize().ok_or(ValueError::ImpossibleCast)?, Value::U8(value) => value.to_usize().ok_or(ValueError::ImpossibleCast)?, Value::U16(value) => value.to_usize().ok_or(ValueError::ImpossibleCast)?, + Value::U32(value) => value.to_usize().ok_or(ValueError::ImpossibleCast)?, + Value::U64(value) => value.to_usize().ok_or(ValueError::ImpossibleCast)?, + Value::U128(value) => value.to_usize().ok_or(ValueError::ImpossibleCast)?, Value::F64(value) => value.to_usize().ok_or(ValueError::ImpossibleCast)?, Value::Str(value) => value .parse::() @@ -440,6 +592,9 @@ impl TryFrom<&Value> for Decimal { Value::I128(value) => Decimal::from_i128(*value).ok_or(ValueError::ImpossibleCast)?, Value::U8(value) => Decimal::from_u8(*value).ok_or(ValueError::ImpossibleCast)?, Value::U16(value) => Decimal::from_u16(*value).ok_or(ValueError::ImpossibleCast)?, + Value::U32(value) => Decimal::from_u32(*value).ok_or(ValueError::ImpossibleCast)?, + Value::U64(value) => Decimal::from_u64(*value).ok_or(ValueError::ImpossibleCast)?, + Value::U128(value) => Decimal::from_u128(*value).ok_or(ValueError::ImpossibleCast)?, Value::F64(value) => Decimal::from_f64(*value).ok_or(ValueError::ImpossibleCast)?, Value::Str(value) => { Decimal::from_str(value).map_err(|_| ValueError::ImpossibleCast)? @@ -472,7 +627,7 @@ macro_rules! try_from_owned_value { )*} } -try_from_owned_value!(bool, i8, i16, i32, i64, i128, f64, u8, u16, u128, usize, Decimal); +try_from_owned_value!(bool, i8, i16, i32, i64, i128, f64, u8, u16, u32, u64, u128, usize, Decimal); impl TryFrom<&Value> for NaiveDate { type Error = Error; @@ -525,32 +680,6 @@ impl TryFrom<&Value> for Interval { } } -impl TryFrom<&Value> for u32 { - type Error = Error; - - fn try_from(v: &Value) -> Result { - match v { - Value::Inet(IpAddr::V4(v)) => Ok(u32::from(*v)), - _ => Err(ValueError::ImpossibleCast.into()), - } - } -} - -impl TryFrom<&Value> for u128 { - type Error = Error; - - fn try_from(v: &Value) -> Result { - match v { - Value::Uuid(value) => Ok(*value), - Value::Str(value) => value - .parse::() - .map_err(|_| ValueError::FailedToParseNumber.into()), - Value::Inet(IpAddr::V6(v)) => Ok(u128::from(*v)), - _ => Err(ValueError::ImpossibleCast.into()), - } - } -} - impl TryFrom<&Value> for IpAddr { type Error = Error; @@ -611,6 +740,9 @@ mod tests { test!(Value::I128(1234567890), "1234567890"); test!(Value::U8(122), "122"); test!(Value::U16(122), "122"); + test!(Value::U32(122), "122"); + test!(Value::U64(122), "122"); + test!(Value::U128(122), "122"); test!(Value::F64(1234567890.0987), "1234567890.0987"); test!(Value::Date(date(2021, 11, 20)), "2021-11-20"); test!( @@ -654,6 +786,12 @@ mod tests { test!(Value::U8(2), Err(ValueError::ImpossibleCast.into())); test!(Value::U16(1), Ok(true)); test!(Value::U16(0), Ok(false)); + test!(Value::U32(1), Ok(true)); + test!(Value::U32(0), Ok(false)); + test!(Value::U64(1), Ok(true)); + test!(Value::U64(0), Ok(false)); + test!(Value::U128(1), Ok(true)); + test!(Value::U128(0), Ok(false)); test!(Value::U16(2), Err(ValueError::ImpossibleCast.into())); test!(Value::F64(1.0), Ok(true)); test!(Value::F64(0.0), Ok(false)); @@ -702,6 +840,11 @@ mod tests { test!(Value::I32(3), Err(ValueError::ImpossibleCast.into())); test!(Value::I64(3), Err(ValueError::ImpossibleCast.into())); test!(Value::I128(3), Err(ValueError::ImpossibleCast.into())); + test!(Value::U8(3), Err(ValueError::ImpossibleCast.into())); + test!(Value::U16(3), Err(ValueError::ImpossibleCast.into())); + test!(Value::U32(3), Err(ValueError::ImpossibleCast.into())); + test!(Value::U64(3), Err(ValueError::ImpossibleCast.into())); + test!(Value::U128(3), Err(ValueError::ImpossibleCast.into())); test!( Value::Inet(IpAddr::from_str("::1").unwrap()), Err(ValueError::ImpossibleCast.into()) @@ -726,6 +869,9 @@ mod tests { test!(Value::I128(122), Ok(122)); test!(Value::U8(122), Ok(122)); test!(Value::U16(122), Ok(122)); + test!(Value::U32(122), Ok(122)); + test!(Value::U64(122), Ok(122)); + test!(Value::U128(122), Ok(122)); test!(Value::F64(122.0), Ok(122)); test!(Value::F64(122.9), Ok(122)); test!(Value::Str("122".to_owned()), Ok(122)); @@ -767,6 +913,9 @@ mod tests { test!(Value::I128(128), Err(ValueError::ImpossibleCast.into())); test!(Value::U8(128), Err(ValueError::ImpossibleCast.into())); test!(Value::U16(128), Err(ValueError::ImpossibleCast.into())); + test!(Value::U32(128), Err(ValueError::ImpossibleCast.into())); + test!(Value::U64(128), Err(ValueError::ImpossibleCast.into())); + test!(Value::U128(128), Err(ValueError::ImpossibleCast.into())); test!(Value::F64(128.0), Err(ValueError::ImpossibleCast.into())); test!( Value::Inet(IpAddr::from_str("::1").unwrap()), @@ -792,6 +941,9 @@ mod tests { test!(Value::I128(122), Ok(122)); test!(Value::U8(122), Ok(122)); test!(Value::U16(122), Ok(122)); + test!(Value::U32(122), Ok(122)); + test!(Value::U64(122), Ok(122)); + test!(Value::U128(122), Ok(122)); test!(Value::F64(122.0), Ok(122)); test!(Value::F64(122.1), Ok(122)); test!(Value::Str("122".to_owned()), Ok(122)); @@ -849,6 +1001,9 @@ mod tests { test!(Value::I128(122), Ok(122)); test!(Value::U8(122), Ok(122)); test!(Value::U16(122), Ok(122)); + test!(Value::U32(122), Ok(122)); + test!(Value::U64(122), Ok(122)); + test!(Value::U128(122), Ok(122)); test!(Value::I64(1234567890), Ok(1234567890)); test!(Value::F64(1234567890.0), Ok(1234567890)); test!(Value::F64(1234567890.1), Ok(1234567890)); @@ -907,6 +1062,9 @@ mod tests { test!(Value::I128(122), Ok(122)); test!(Value::U8(122), Ok(122)); test!(Value::U16(122), Ok(122)); + test!(Value::U32(122), Ok(122)); + test!(Value::U64(122), Ok(122)); + test!(Value::U128(122), Ok(122)); test!(Value::I64(1234567890), Ok(1234567890)); test!(Value::F64(1234567890.0), Ok(1234567890)); test!(Value::F64(1234567890.1), Ok(1234567890)); @@ -965,6 +1123,9 @@ mod tests { test!(Value::I128(122), Ok(122)); test!(Value::U8(122), Ok(122)); test!(Value::U16(122), Ok(122)); + test!(Value::U32(122), Ok(122)); + test!(Value::U64(122), Ok(122)); + test!(Value::U128(122), Ok(122)); test!(Value::I64(1234567890), Ok(1234567890)); test!(Value::F64(1234567890.0), Ok(1234567890)); test!(Value::F64(1234567890.9), Ok(1234567890)); @@ -1023,6 +1184,9 @@ mod tests { test!(Value::I128(122), Ok(122)); test!(Value::U8(122), Ok(122)); test!(Value::U16(122), Ok(122)); + test!(Value::U32(122), Ok(122)); + test!(Value::U64(122), Ok(122)); + test!(Value::U128(122), Ok(122)); test!(Value::F64(122.0), Ok(122)); test!(Value::F64(122.9), Ok(122)); test!(Value::Str("122".to_owned()), Ok(122)); @@ -1092,6 +1256,129 @@ mod tests { test!(Value::I128(122), Ok(122)); test!(Value::U8(122), Ok(122)); test!(Value::U16(122), Ok(122)); + test!(Value::U32(122), Ok(122)); + test!(Value::U64(122), Ok(122)); + test!(Value::U128(122), Ok(122)); + test!(Value::F64(122.0), Ok(122)); + test!(Value::F64(122.1), Ok(122)); + test!(Value::Str("122".to_owned()), Ok(122)); + test!(Value::Decimal(Decimal::new(122, 0)), Ok(122)); + test!( + Value::Date(date(2021, 11, 20)), + Err(ValueError::ImpossibleCast.into()) + ); + test!( + Value::Timestamp(timestamp(2021, 11, 20, 10, 0, 0, 0)), + Err(ValueError::ImpossibleCast.into()) + ); + test!( + Value::Time(time(10, 0, 0, 0)), + Err(ValueError::ImpossibleCast.into()) + ); + test!( + Value::Interval(I::Month(1)), + Err(ValueError::ImpossibleCast.into()) + ); + test!( + Value::Uuid(195965723427462096757863453463987888808), + Err(ValueError::ImpossibleCast.into()) + ); + test!( + Value::Map(HashMap::new()), + Err(ValueError::ImpossibleCast.into()) + ); + test!( + Value::List(Vec::new()), + Err(ValueError::ImpossibleCast.into()) + ); + test!(Value::Null, Err(ValueError::ImpossibleCast.into())); + } + + #[test] + fn try_into_u32() { + macro_rules! test { + ($from: expr, $to: expr) => { + assert_eq!($from.try_into() as Result, $to); + assert_eq!(u32::try_from($from), $to); + }; + } + + test!(Value::Bool(true), Ok(1)); + test!(Value::Bool(false), Ok(0)); + test!(Value::I8(122), Ok(122)); + test!(Value::I16(122), Ok(122)); + test!(Value::I32(122), Ok(122)); + test!(Value::I64(122), Ok(122)); + test!(Value::I128(122), Ok(122)); + test!(Value::U8(122), Ok(122)); + test!(Value::U16(122), Ok(122)); + test!(Value::U32(122), Ok(122)); + test!(Value::U64(122), Ok(122)); + test!(Value::U128(122), Ok(122)); + test!(Value::F64(122.0), Ok(122)); + test!(Value::F64(122.1), Ok(122)); + test!(Value::Str("122".to_owned()), Ok(122)); + test!(Value::Decimal(Decimal::new(122, 0)), Ok(122)); + test!( + Value::Date(date(2021, 11, 20)), + Err(ValueError::ImpossibleCast.into()) + ); + test!( + Value::Timestamp(timestamp(2021, 11, 20, 10, 0, 0, 0)), + Err(ValueError::ImpossibleCast.into()) + ); + test!( + Value::Time(time(10, 0, 0, 0)), + Err(ValueError::ImpossibleCast.into()) + ); + test!( + Value::Interval(I::Month(1)), + Err(ValueError::ImpossibleCast.into()) + ); + test!( + Value::Uuid(195965723427462096757863453463987888808), + Err(ValueError::ImpossibleCast.into()) + ); + test!( + Value::Map(HashMap::new()), + Err(ValueError::ImpossibleCast.into()) + ); + test!( + Value::List(Vec::new()), + Err(ValueError::ImpossibleCast.into()) + ); + test!(Value::Null, Err(ValueError::ImpossibleCast.into())); + assert_eq!( + u32::try_from(&Value::Inet(IpAddr::from_str("0.0.0.0").unwrap())), + Ok(u32::from(Ipv4Addr::from(0))) + ); + assert_eq!( + u32::try_from(&Value::Inet(IpAddr::from_str("::0").unwrap())), + Err(ValueError::ImpossibleCast.into()) + ); + } + + #[test] + fn try_into_u64() { + macro_rules! test { + ($from: expr, $to: expr) => { + assert_eq!($from.try_into() as Result, $to); + assert_eq!(u64::try_from($from), $to); + }; + } + + test!(Value::Bool(true), Ok(1)); + test!(Value::Bool(false), Ok(0)); + test!(Value::I8(122), Ok(122)); + test!(Value::I16(122), Ok(122)); + test!(Value::I32(122), Ok(122)); + test!(Value::I64(122), Ok(122)); + test!(Value::I128(122), Ok(122)); + test!(Value::U8(122), Ok(122)); + test!(Value::U16(122), Ok(122)); + test!(Value::U32(122), Ok(122)); + test!(Value::U64(122), Ok(122)); + test!(Value::U128(122), Ok(122)); test!(Value::F64(122.0), Ok(122)); test!(Value::F64(122.1), Ok(122)); test!(Value::Str("122".to_owned()), Ok(122)); @@ -1131,6 +1418,72 @@ mod tests { ); } + #[test] + fn try_into_u128() { + macro_rules! test { + ($from: expr, $to: expr) => { + assert_eq!($from.try_into() as Result, $to); + assert_eq!(u128::try_from($from), $to); + }; + } + + test!(Value::Bool(true), Ok(1)); + test!(Value::Bool(false), Ok(0)); + test!(Value::I8(122), Ok(122)); + test!(Value::I16(122), Ok(122)); + test!(Value::I32(122), Ok(122)); + test!(Value::I64(122), Ok(122)); + test!(Value::I128(122), Ok(122)); + test!(Value::U8(122), Ok(122)); + test!(Value::U16(122), Ok(122)); + test!(Value::U32(122), Ok(122)); + test!(Value::U64(122), Ok(122)); + test!(Value::U128(122), Ok(122)); + test!(Value::F64(122.0), Ok(122)); + test!(Value::F64(122.1), Ok(122)); + test!(Value::Str("122".to_owned()), Ok(122)); + test!(Value::Decimal(Decimal::new(122, 0)), Ok(122)); + test!( + Value::Date(date(2021, 11, 20)), + Err(ValueError::ImpossibleCast.into()) + ); + test!( + Value::Timestamp(timestamp(2021, 11, 20, 10, 0, 0, 0)), + Err(ValueError::ImpossibleCast.into()) + ); + test!( + Value::Time(time(10, 0, 0, 0)), + Err(ValueError::ImpossibleCast.into()) + ); + test!( + Value::Interval(I::Month(1)), + Err(ValueError::ImpossibleCast.into()) + ); + test!( + Value::Map(HashMap::new()), + Err(ValueError::ImpossibleCast.into()) + ); + test!( + Value::List(Vec::new()), + Err(ValueError::ImpossibleCast.into()) + ); + test!(Value::Null, Err(ValueError::ImpossibleCast.into())); + let uuid = 195965723427462096757863453463987888808; + assert_eq!((&Value::Uuid(uuid)).try_into() as Result, Ok(uuid)); + assert_eq!(u128::try_from(&Value::Uuid(uuid)), Ok(uuid)); + + let ip = Ipv6Addr::from(9876543210); + assert_eq!( + u128::try_from(&Value::Inet(IpAddr::V6(ip))), + Ok(u128::from(ip)) + ); + + assert_eq!( + u128::try_from(&Value::Date(date(2021, 11, 20))), + Err(ValueError::ImpossibleCast.into()) + ); + } + #[test] fn try_into_f64() { macro_rules! test { @@ -1149,6 +1502,9 @@ mod tests { test!(Value::I128(122), Ok(122.0)); test!(Value::U8(122), Ok(122.0)); test!(Value::U16(122), Ok(122.0)); + test!(Value::U32(122), Ok(122.0)); + test!(Value::U64(122), Ok(122.0)); + test!(Value::U128(122), Ok(122.0)); test!(Value::I64(1234567890), Ok(1234567890.0)); test!(Value::F64(1234567890.1), Ok(1234567890.1)); test!(Value::Str("1234567890.1".to_owned()), Ok(1234567890.1)); @@ -1209,6 +1565,9 @@ mod tests { test!(Value::I128(122), Ok(122)); test!(Value::U8(122), Ok(122)); test!(Value::U16(122), Ok(122)); + test!(Value::U32(122), Ok(122)); + test!(Value::U64(122), Ok(122)); + test!(Value::U128(122), Ok(122)); test!(Value::I64(1234567890), Ok(1234567890)); test!(Value::F64(1234567890.0), Ok(1234567890)); test!(Value::F64(1234567890.1), Ok(1234567890)); @@ -1322,45 +1681,6 @@ mod tests { ); } - #[test] - fn try_into_u32() { - assert_eq!( - u32::try_from(&Value::Inet(IpAddr::from_str("0.0.0.0").unwrap())), - Ok(u32::from(Ipv4Addr::from(0))) - ); - assert_eq!( - u32::try_from(&Value::Inet(IpAddr::from_str("::0").unwrap())), - Err(ValueError::ImpossibleCast.into()) - ); - } - - #[test] - fn try_into_u128() { - let uuid = 195965723427462096757863453463987888808; - assert_eq!((&Value::Uuid(uuid)).try_into() as Result, Ok(uuid)); - assert_eq!(u128::try_from(&Value::Uuid(uuid)), Ok(uuid)); - - let ip = Ipv6Addr::from(9876543210); - assert_eq!( - u128::try_from(&Value::Inet(IpAddr::V6(ip))), - Ok(u128::from(ip)) - ); - let num = "340282366920938463463374607431768211455"; - assert_eq!( - u128::try_from(&Value::Str(num.to_owned())), - Ok(340282366920938463463374607431768211455) - ); - let uuid = "936DA01F9ABD4d9d80C702AF85C822A8"; - assert_eq!( - u128::try_from(&Value::Str(uuid.to_owned())), - Err(ValueError::FailedToParseNumber.into()) - ); - assert_eq!( - u128::try_from(&Value::Date(date(2021, 11, 20))), - Err(ValueError::ImpossibleCast.into()) - ); - } - #[test] fn try_into_ipaddr() { macro_rules! test { diff --git a/core/src/data/value/error.rs b/core/src/data/value/error.rs index f11199e25..9ed26b021 100644 --- a/core/src/data/value/error.rs +++ b/core/src/data/value/error.rs @@ -104,6 +104,15 @@ pub enum ValueError { #[error("literal cast failed from text to UINT16: {0}")] LiteralCastFromTextToUint16Failed(String), + #[error("literal cast failed from text to UINT32: {0}")] + LiteralCastFromTextToUint32Failed(String), + + #[error("literal cast failed from text to UINT64: {0}")] + LiteralCastFromTextToUint64Failed(String), + + #[error("literal cast failed from text to UINT128: {0}")] + LiteralCastFromTextToUint128Failed(String), + #[error("literal cast failed from text to float: {0}")] LiteralCastFromTextToFloatFailed(String), @@ -128,6 +137,15 @@ pub enum ValueError { #[error("literal cast failed to UINT16: {0}")] LiteralCastToUint16Failed(String), + #[error("literal cast failed to UNIT32: {0}")] + LiteralCastToUint32Failed(String), + + #[error("literal cast failed to UNIT64: {0}")] + LiteralCastToUint64Failed(String), + + #[error("literal cast failed to UNIT128: {0}")] + LiteralCastToUint128Failed(String), + #[error("literal cast failed to time: {0}")] LiteralCastToTimeFailed(String), diff --git a/core/src/data/value/expr.rs b/core/src/data/value/expr.rs index b212b73e6..ad8190c76 100644 --- a/core/src/data/value/expr.rs +++ b/core/src/data/value/expr.rs @@ -41,7 +41,15 @@ impl TryFrom for Expr { Value::U16(v) => Expr::Literal(AstLiteral::Number( BigDecimal::from_u16(v).ok_or(ValueToExprConversionFailure)?, )), - + Value::U32(v) => Expr::Literal(AstLiteral::Number( + BigDecimal::from_u32(v).ok_or(ValueToExprConversionFailure)?, + )), + Value::U64(v) => Expr::Literal(AstLiteral::Number( + BigDecimal::from_u64(v).ok_or(ValueToExprConversionFailure)?, + )), + Value::U128(v) => Expr::Literal(AstLiteral::Number( + BigDecimal::from_u128(v).ok_or(ValueToExprConversionFailure)?, + )), Value::F64(v) => Expr::Literal(AstLiteral::Number( BigDecimal::from_f64(v).ok_or(ValueToExprConversionFailure)?, )), @@ -167,6 +175,31 @@ mod tests { BigDecimal::from_u8(8).unwrap() ))) ); + assert_eq!( + Value::U16(16).try_into(), + Ok(Expr::Literal(AstLiteral::Number( + BigDecimal::from_u16(16).unwrap() + ))) + ); + assert_eq!( + Value::U32(32).try_into(), + Ok(Expr::Literal(AstLiteral::Number( + BigDecimal::from_u32(32).unwrap() + ))) + ); + assert_eq!( + Value::U64(64).try_into(), + Ok(Expr::Literal(AstLiteral::Number( + BigDecimal::from_u64(64).unwrap() + ))) + ); + assert_eq!( + Value::U128(128).try_into(), + Ok(Expr::Literal(AstLiteral::Number( + BigDecimal::from_u128(128).unwrap() + ))) + ); + assert_eq!( Value::F64(64.4).try_into(), Ok(Expr::Literal(AstLiteral::Number( diff --git a/core/src/data/value/json.rs b/core/src/data/value/json.rs index f934173d6..5ca4b45ec 100644 --- a/core/src/data/value/json.rs +++ b/core/src/data/value/json.rs @@ -65,6 +65,11 @@ impl TryFrom for JsonValue { .map_err(|_| ValueError::UnreachableJsonNumberParseFailure(v.to_string()).into()), Value::U8(v) => Ok(v.into()), Value::U16(v) => Ok(v.into()), + Value::U32(v) => Ok(v.into()), + Value::U64(v) => Ok(v.into()), + Value::U128(v) => JsonNumber::from_str(&v.to_string()) + .map(JsonValue::Number) + .map_err(|_| ValueError::UnreachableJsonNumberParseFailure(v.to_string()).into()), Value::F64(v) => Ok(v.into()), Value::Decimal(v) => JsonNumber::from_str(&v.to_string()) .map(JsonValue::Number) @@ -170,6 +175,18 @@ mod tests { Value::U16(100).try_into(), Ok(JsonValue::Number(100.into())) ); + assert_eq!( + Value::U32(100).try_into(), + Ok(JsonValue::Number(100.into())) + ); + assert_eq!( + Value::U64(100).try_into(), + Ok(JsonValue::Number(100.into())) + ); + assert_eq!( + Value::U128(100).try_into(), + Ok(JsonValue::Number(100.into())) + ); assert!(JsonValue::try_from(Value::I128(i128::MAX)).is_ok()); assert_eq!( diff --git a/core/src/data/value/literal.rs b/core/src/data/value/literal.rs index 9585cf676..1d257cf06 100644 --- a/core/src/data/value/literal.rs +++ b/core/src/data/value/literal.rs @@ -29,6 +29,9 @@ impl PartialEq> for Value { (Value::I128(l), Literal::Number(r)) => r.to_i128().map(|r| *l == r).unwrap_or(false), (Value::U8(l), Literal::Number(r)) => r.to_u8().map(|r| *l == r).unwrap_or(false), (Value::U16(l), Literal::Number(r)) => r.to_u16().map(|r| *l == r).unwrap_or(false), + (Value::U32(l), Literal::Number(r)) => r.to_u32().map(|r| *l == r).unwrap_or(false), + (Value::U64(l), Literal::Number(r)) => r.to_u64().map(|r| *l == r).unwrap_or(false), + (Value::U128(l), Literal::Number(r)) => r.to_u128().map(|r| *l == r).unwrap_or(false), (Value::F64(l), Literal::Number(r)) => r.to_f64().map(|r| *l == r).unwrap_or(false), (Value::Str(l), Literal::Text(r)) => l == r.as_ref(), (Value::Bytea(l), Literal::Bytea(r)) => l == r, @@ -87,6 +90,16 @@ impl PartialOrd> for Value { (Value::U16(l), Literal::Number(r)) => { r.to_u16().map(|r| l.partial_cmp(&r)).unwrap_or(None) } + (Value::U32(l), Literal::Number(r)) => { + r.to_u32().map(|r| l.partial_cmp(&r)).unwrap_or(None) + } + (Value::U64(l), Literal::Number(r)) => { + r.to_u64().map(|r| l.partial_cmp(&r)).unwrap_or(None) + } + (Value::U128(l), Literal::Number(r)) => { + r.to_u128().map(|r| l.partial_cmp(&r)).unwrap_or(None) + } + (Value::F64(l), Literal::Number(r)) => { r.to_f64().map(|r| l.partial_cmp(&r)).unwrap_or(None) } @@ -188,6 +201,18 @@ impl Value { .to_u16() .map(Value::U16) .ok_or_else(|| ValueError::FailedToParseNumber.into()), + (DataType::Uint32, Literal::Number(v)) => v + .to_u32() + .map(Value::U32) + .ok_or_else(|| ValueError::FailedToParseNumber.into()), + (DataType::Uint64, Literal::Number(v)) => v + .to_u64() + .map(Value::U64) + .ok_or_else(|| ValueError::FailedToParseNumber.into()), + (DataType::Uint128, Literal::Number(v)) => v + .to_u128() + .map(Value::U128) + .ok_or_else(|| ValueError::FailedToParseNumber.into()), (DataType::Float, Literal::Number(v)) => v .to_f64() .map(Value::F64) @@ -350,6 +375,48 @@ impl Value { Ok(Value::U16(v)) } + (DataType::Uint32, Literal::Text(v)) => v + .parse::() + .map(Value::U32) + .map_err(|_| ValueError::LiteralCastFromTextToUint32Failed(v.to_string()).into()), + (DataType::Uint32, Literal::Number(v)) => match v.to_u32() { + Some(x) => Ok(Value::U32(x)), + None => Err(ValueError::LiteralCastToUint32Failed(v.to_string()).into()), + }, + (DataType::Uint32, Literal::Boolean(v)) => { + let v = u32::from(*v); + + Ok(Value::U32(v)) + } + + (DataType::Uint64, Literal::Text(v)) => v + .parse::() + .map(Value::U64) + .map_err(|_| ValueError::LiteralCastFromTextToUint64Failed(v.to_string()).into()), + (DataType::Uint64, Literal::Number(v)) => match v.to_u64() { + Some(x) => Ok(Value::U64(x)), + None => Err(ValueError::LiteralCastToUint64Failed(v.to_string()).into()), + }, + (DataType::Uint64, Literal::Boolean(v)) => { + let v = u64::from(*v); + + Ok(Value::U64(v)) + } + + (DataType::Uint128, Literal::Text(v)) => v + .parse::() + .map(Value::U128) + .map_err(|_| ValueError::LiteralCastFromTextToUint128Failed(v.to_string()).into()), + (DataType::Uint128, Literal::Number(v)) => match v.to_u128() { + Some(x) => Ok(Value::U128(x)), + None => Err(ValueError::LiteralCastToUint128Failed(v.to_string()).into()), + }, + (DataType::Uint128, Literal::Boolean(v)) => { + let v = u128::from(*v); + + Ok(Value::U128(v)) + } + (DataType::Float, Literal::Text(v)) => v .parse::() .map(Value::F64) @@ -396,6 +463,9 @@ impl Value { | (DataType::Int128, Literal::Null) | (DataType::Uint8, Literal::Null) | (DataType::Uint16, Literal::Null) + | (DataType::Uint32, Literal::Null) + | (DataType::Uint64, Literal::Null) + | (DataType::Uint128, Literal::Null) | (DataType::Float, Literal::Null) | (DataType::Decimal, Literal::Null) | (DataType::Text, Literal::Null) => Ok(Value::Null), @@ -481,12 +551,16 @@ mod tests { assert_eq!(Value::Bool(true), Literal::Boolean(true)); assert_eq!(Value::I8(8), num!("8")); + assert_eq!(Value::I32(32), num!("32")); assert_eq!(Value::I16(16), num!("16")); assert_eq!(Value::I32(32), num!("32")); assert_eq!(Value::I64(64), num!("64")); assert_eq!(Value::I128(128), num!("128")); assert_eq!(Value::U8(7), num!("7")); assert_eq!(Value::U16(64), num!("64")); + assert_eq!(Value::U32(64), num!("64")); + assert_eq!(Value::U64(64), num!("64")); + assert_eq!(Value::U128(64), num!("64")); assert_eq!(Value::F64(7.123), num!("7.123")); assert_eq!(Value::Str("Hello".to_owned()), text!("Hello")); assert_eq!(Value::Bytea(bytea()), Literal::Bytea(bytea())); @@ -600,7 +674,9 @@ mod tests { test!(DataType::Int128, num!("64"), Value::I128(64)); test!(DataType::Uint8, num!("8"), Value::U8(8)); test!(DataType::Uint16, num!("64"), Value::U16(64)); - + test!(DataType::Uint32, num!("64"), Value::U32(64)); + test!(DataType::Uint64, num!("64"), Value::U64(64)); + test!(DataType::Uint128, num!("64"), Value::U128(64)); test!(DataType::Float, num!("123456789"), Value::F64(123456789.0)); test!( DataType::Text, @@ -824,6 +900,21 @@ mod tests { test!(DataType::Uint16, Literal::Boolean(true), Value::U16(1)); test!(DataType::Uint16, Literal::Boolean(false), Value::U16(0)); + test!(DataType::Uint32, text!("127"), Value::U32(127)); + test!(DataType::Uint32, num!("125"), Value::U32(125)); + test!(DataType::Uint32, Literal::Boolean(true), Value::U32(1)); + test!(DataType::Uint32, Literal::Boolean(false), Value::U32(0)); + + test!(DataType::Uint64, text!("127"), Value::U64(127)); + test!(DataType::Uint64, num!("125"), Value::U64(125)); + test!(DataType::Uint64, Literal::Boolean(true), Value::U64(1)); + test!(DataType::Uint64, Literal::Boolean(false), Value::U64(0)); + + test!(DataType::Uint128, text!("127"), Value::U128(127)); + test!(DataType::Uint128, num!("125"), Value::U128(125)); + test!(DataType::Uint128, Literal::Boolean(true), Value::U128(1)); + test!(DataType::Uint128, Literal::Boolean(false), Value::U128(0)); + test!(DataType::Float, text!("12345.6789"), Value::F64(12345.6789)); test!(DataType::Float, num!("123456.789"), Value::F64(123456.789)); test!(DataType::Float, Literal::Boolean(true), Value::F64(1.0)); @@ -859,6 +950,9 @@ mod tests { test_null!(DataType::Int8, Literal::Null); test_null!(DataType::Uint8, Literal::Null); test_null!(DataType::Uint16, Literal::Null); + test_null!(DataType::Uint32, Literal::Null); + test_null!(DataType::Uint64, Literal::Null); + test_null!(DataType::Uint128, Literal::Null); test_null!(DataType::Float, Literal::Null); test_null!(DataType::Text, Literal::Null); test!( diff --git a/core/src/data/value/mod.rs b/core/src/data/value/mod.rs index 13cacf84d..b68106a12 100644 --- a/core/src/data/value/mod.rs +++ b/core/src/data/value/mod.rs @@ -38,6 +38,9 @@ pub enum Value { I128(i128), U8(u8), U16(u16), + U32(u32), + U64(u64), + U128(u128), F64(f64), Decimal(Decimal), Str(String), @@ -63,6 +66,9 @@ impl PartialEq for Value { (Value::I128(l), _) => l == other, (Value::U8(l), _) => l == other, (Value::U16(l), _) => l == other, + (Value::U32(l), _) => l == other, + (Value::U64(l), _) => l == other, + (Value::U128(l), _) => l == other, (Value::F64(l), _) => l == other, (Value::Decimal(l), Value::Decimal(r)) => l == r, (Value::Bool(l), Value::Bool(r)) => l == r, @@ -99,6 +105,9 @@ impl PartialOrd for Value { (Value::I128(l), _) => l.partial_cmp(other), (Value::U8(l), _) => l.partial_cmp(other), (Value::U16(l), _) => l.partial_cmp(other), + (Value::U32(l), _) => l.partial_cmp(other), + (Value::U64(l), _) => l.partial_cmp(other), + (Value::U128(l), _) => l.partial_cmp(other), (Value::F64(l), _) => l.partial_cmp(other), (Value::Decimal(l), Value::Decimal(r)) => Some(l.cmp(r)), (Value::Bool(l), Value::Bool(r)) => Some(l.cmp(r)), @@ -131,6 +140,9 @@ impl Value { Value::I128(v) => *v == 0, Value::U8(v) => *v == 0, Value::U16(v) => *v == 0, + Value::U32(v) => *v == 0, + Value::U64(v) => *v == 0, + Value::U128(v) => *v == 0, Value::F64(v) => *v == 0.0, Value::Decimal(v) => *v == Decimal::ZERO, _ => false, @@ -146,6 +158,9 @@ impl Value { Value::I128(_) => Some(DataType::Int128), Value::U8(_) => Some(DataType::Uint8), Value::U16(_) => Some(DataType::Uint16), + Value::U32(_) => Some(DataType::Uint32), + Value::U64(_) => Some(DataType::Uint64), + Value::U128(_) => Some(DataType::Uint128), Value::F64(_) => Some(DataType::Float), Value::Decimal(_) => Some(DataType::Decimal), Value::Bool(_) => Some(DataType::Boolean), @@ -172,6 +187,9 @@ impl Value { Value::I128(_) => matches!(data_type, DataType::Int128), Value::U8(_) => matches!(data_type, DataType::Uint8), Value::U16(_) => matches!(data_type, DataType::Uint16), + Value::U32(_) => matches!(data_type, DataType::Uint32), + Value::U64(_) => matches!(data_type, DataType::Uint64), + Value::U128(_) => matches!(data_type, DataType::Uint128), Value::F64(_) => matches!(data_type, DataType::Float), Value::Decimal(_) => matches!(data_type, DataType::Decimal), Value::Bool(_) => matches!(data_type, DataType::Boolean), @@ -216,6 +234,9 @@ impl Value { | (DataType::Int128, Value::I128(_)) | (DataType::Uint8, Value::U8(_)) | (DataType::Uint16, Value::U16(_)) + | (DataType::Uint32, Value::U32(_)) + | (DataType::Uint64, Value::U64(_)) + | (DataType::Uint128, Value::U128(_)) | (DataType::Float, Value::F64(_)) | (DataType::Decimal, Value::Decimal(_)) | (DataType::Boolean, Value::Bool(_)) @@ -237,6 +258,9 @@ impl Value { (DataType::Int128, value) => value.try_into().map(Value::I128), (DataType::Uint8, value) => value.try_into().map(Value::U8), (DataType::Uint16, value) => value.try_into().map(Value::U16), + (DataType::Uint32, value) => value.try_into().map(Value::U32), + (DataType::Uint64, value) => value.try_into().map(Value::U64), + (DataType::Uint128, value) => value.try_into().map(Value::U128), (DataType::Float, value) => value.try_into().map(Value::F64), (DataType::Decimal, value) => value.try_into().map(Value::Decimal), (DataType::Text, value) => Ok(Value::Str(value.into())), @@ -274,6 +298,9 @@ impl Value { (I128(a), b) => a.try_add(b), (U8(a), b) => a.try_add(b), (U16(a), b) => a.try_add(b), + (U32(a), b) => a.try_add(b), + (U64(a), b) => a.try_add(b), + (U128(a), b) => a.try_add(b), (F64(a), b) => a.try_add(b), (Decimal(a), b) => a.try_add(b), (Date(a), Time(b)) => Ok(Timestamp(NaiveDateTime::new(*a, *b))), @@ -288,6 +315,9 @@ impl Value { | (Null, I128(_)) | (Null, U8(_)) | (Null, U16(_)) + | (Null, U32(_)) + | (Null, U64(_)) + | (Null, U128(_)) | (Null, F64(_)) | (Null, Decimal(_)) | (Null, Date(_)) @@ -318,6 +348,9 @@ impl Value { (I128(a), _) => a.try_subtract(other), (U8(a), _) => a.try_subtract(other), (U16(a), _) => a.try_subtract(other), + (U32(a), _) => a.try_subtract(other), + (U64(a), _) => a.try_subtract(other), + (U128(a), _) => a.try_subtract(other), (F64(a), _) => a.try_subtract(other), (Decimal(a), _) => a.try_subtract(other), (Date(a), Date(b)) => Ok(Interval(I::days((*a - *b).num_days() as i32))), @@ -346,6 +379,9 @@ impl Value { | (Null, I128(_)) | (Null, U8(_)) | (Null, U16(_)) + | (Null, U32(_)) + | (Null, U64(_)) + | (Null, U128(_)) | (Null, F64(_)) | (Null, Decimal(_)) | (Null, Date(_)) @@ -377,6 +413,9 @@ impl Value { (I128(a), _) => a.try_multiply(other), (U8(a), _) => a.try_multiply(other), (U16(a), _) => a.try_multiply(other), + (U32(a), _) => a.try_multiply(other), + (U64(a), _) => a.try_multiply(other), + (U128(a), _) => a.try_multiply(other), (F64(a), _) => a.try_multiply(other), (Decimal(a), _) => a.try_multiply(other), (Interval(a), I8(b)) => Ok(Interval(*a * *b)), @@ -392,6 +431,9 @@ impl Value { | (Null, I128(_)) | (Null, U8(_)) | (Null, U16(_)) + | (Null, U32(_)) + | (Null, U64(_)) + | (Null, U128(_)) | (Null, F64(_)) | (Null, Decimal(_)) | (Null, Interval(_)) @@ -421,6 +463,9 @@ impl Value { (I128(a), _) => a.try_divide(other), (U8(a), _) => a.try_divide(other), (U16(a), _) => a.try_divide(other), + (U32(a), _) => a.try_divide(other), + (U64(a), _) => a.try_divide(other), + (U128(a), _) => a.try_divide(other), (F64(a), _) => a.try_divide(other), (Decimal(a), _) => a.try_divide(other), (Interval(a), I8(b)) => Ok(Interval(*a / *b)), @@ -430,6 +475,9 @@ impl Value { (Interval(a), I128(b)) => Ok(Interval(*a / *b)), (Interval(a), U8(b)) => Ok(Interval(*a / *b)), (Interval(a), U16(b)) => Ok(Interval(*a / *b)), + (Interval(a), U32(b)) => Ok(Interval(*a / *b)), + (Interval(a), U64(b)) => Ok(Interval(*a / *b)), + (Interval(a), U128(b)) => Ok(Interval(*a / *b)), (Interval(a), F64(b)) => Ok(Interval(*a / *b)), (Null, I8(_)) | (Null, I16(_)) @@ -438,6 +486,9 @@ impl Value { | (Null, I128(_)) | (Null, U8(_)) | (Null, U16(_)) + | (Null, U32(_)) + | (Null, U64(_)) + | (Null, U128(_)) | (Null, F64(_)) | (Null, Decimal(_)) | (Interval(_), Null) @@ -466,6 +517,9 @@ impl Value { (I128(a), _) => a.try_modulo(other), (U8(a), _) => a.try_modulo(other), (U16(a), _) => a.try_modulo(other), + (U32(a), _) => a.try_modulo(other), + (U64(a), _) => a.try_modulo(other), + (U128(a), _) => a.try_modulo(other), (F64(a), _) => a.try_modulo(other), (Decimal(a), _) => a.try_modulo(other), (Null, I8(_)) @@ -475,6 +529,9 @@ impl Value { | (Null, I128(_)) | (Null, U8(_)) | (Null, U16(_)) + | (Null, U32(_)) + | (Null, U64(_)) + | (Null, U128(_)) | (Null, F64(_)) | (Null, Decimal(_)) | (Null, Null) => Ok(Null), @@ -495,8 +552,8 @@ impl Value { use Value::*; match self { - I8(_) | I16(_) | I32(_) | I64(_) | I128(_) | U8(_) | U16(_) | F64(_) | Interval(_) - | Decimal(_) => Ok(self.clone()), + I8(_) | I16(_) | I32(_) | I64(_) | I128(_) | U8(_) | U16(_) | U32(_) | U64(_) + | U128(_) | F64(_) | Interval(_) | Decimal(_) => Ok(self.clone()), Null => Ok(Null), _ => Err(ValueError::UnaryPlusOnNonNumeric.into()), } @@ -540,6 +597,9 @@ impl Value { I128(a) => factorial_function(*a).map(I128), U8(a) => factorial_function(*a as i128).map(I128), U16(a) => factorial_function(*a as i128).map(I128), + U32(a) => factorial_function(*a as i128).map(I128), + U64(a) => factorial_function(*a as i128).map(I128), + U128(a) => factorial_function(*a as i128).map(I128), F64(_) => Err(ValueError::FactorialOnNonInteger.into()), Null => Ok(Null), _ => Err(ValueError::FactorialOnNonNumeric.into()), @@ -592,7 +652,8 @@ impl Value { pub fn sqrt(&self) -> Result { use Value::*; match self { - I8(_) | I16(_) | I64(_) | I128(_) | U8(_) | U16(_) | F64(_) => { + I8(_) | I16(_) | I64(_) | I128(_) | U8(_) | U16(_) | U32(_) | U64(_) | U128(_) + | F64(_) => { let a: f64 = self.try_into()?; Ok(Value::F64(a.sqrt())) } @@ -708,6 +769,9 @@ mod tests { assert_eq!(I128(1), I128(1)); assert_eq!(U8(1), U8(1)); assert_eq!(U16(1), U16(1)); + assert_eq!(U32(1), U32(1)); + assert_eq!(U64(1), U64(1)); + assert_eq!(U128(1), U128(1)); assert_eq!(I64(1), F64(1.0)); assert_eq!(F64(1.0), I64(1)); assert_eq!(F64(6.11), F64(6.11)); @@ -834,6 +898,18 @@ mod tests { assert_eq!(U16(1).partial_cmp(&U16(0)), Some(Ordering::Greater)); assert_eq!(U16(0).partial_cmp(&U16(0)), Some(Ordering::Equal)); assert_eq!(U16(0).partial_cmp(&U16(1)), Some(Ordering::Less)); + + assert_eq!(U32(1).partial_cmp(&U32(0)), Some(Ordering::Greater)); + assert_eq!(U32(0).partial_cmp(&U32(0)), Some(Ordering::Equal)); + assert_eq!(U32(0).partial_cmp(&U32(1)), Some(Ordering::Less)); + + assert_eq!(U64(1).partial_cmp(&U64(0)), Some(Ordering::Greater)); + assert_eq!(U64(0).partial_cmp(&U64(0)), Some(Ordering::Equal)); + assert_eq!(U64(0).partial_cmp(&U64(1)), Some(Ordering::Less)); + + assert_eq!(U128(1).partial_cmp(&U128(0)), Some(Ordering::Greater)); + assert_eq!(U128(0).partial_cmp(&U128(0)), Some(Ordering::Equal)); + assert_eq!(U128(0).partial_cmp(&U128(1)), Some(Ordering::Less)); } #[test] @@ -849,6 +925,14 @@ mod tests { } assert!(U8(0).is_zero()); assert!(!U8(1).is_zero()); + assert!(U16(0).is_zero()); + assert!(!U16(1).is_zero()); + assert!(U32(0).is_zero()); + assert!(!U32(1).is_zero()); + assert!(U64(0).is_zero()); + assert!(!U64(1).is_zero()); + assert!(U128(0).is_zero()); + assert!(!U128(1).is_zero()); } #[test] @@ -940,6 +1024,36 @@ mod tests { test!(add U16(1), U8(2) => U16(3)); test!(add U16(1), F64(2.0) => F64(3.0)); + test!(add U32(1), I8(2) => U32(3)); + test!(add U32(1), I16(2) => U32(3)); + test!(add U32(1), I32(2) => U32(3)); + test!(add U32(1), I64(2) => U32(3)); + test!(add U32(1), I128(2) => U32(3)); + test!(add U32(1), U8(2) => U32(3)); + test!(add U32(1), U16(2) => U32(3)); + test!(add U32(1), U32(2) => U32(3)); + test!(add U32(1), F64(2.0) => F64(3.0)); + + test!(add U64(1), I8(2) => U64(3)); + test!(add U64(1), I16(2) => U64(3)); + test!(add U64(1), I32(2) => U64(3)); + test!(add U64(1), I64(2) => U64(3)); + test!(add U64(1), I128(2) => U64(3)); + test!(add U64(1), U8(2) => U64(3)); + test!(add U64(1), U16(2) => U64(3)); + test!(add U64(1), U32(2) => U64(3)); + test!(add U64(1), F64(2.0) => F64(3.0)); + + test!(add U128(1), I8(2) => U128(3)); + test!(add U128(1), I16(2) => U128(3)); + test!(add U128(1), I32(2) => U128(3)); + test!(add U128(1), I64(2) => U128(3)); + test!(add U128(1), I128(2) => U128(3)); + test!(add U128(1), U8(2) => U128(3)); + test!(add U128(1), U16(2) => U128(3)); + test!(add U128(1), U32(2) => U128(3)); + test!(add U128(1), F64(2.0) => F64(3.0)); + test!(add F64(1.0), F64(2.0) => F64(3.0)); test!(add F64(1.0), I8(2) => F64(3.0)); test!(add F64(1.0), I32(2) => F64(3.0)); @@ -1024,6 +1138,30 @@ mod tests { test!(subtract U16(3), U8(2) => U16(1)); test!(subtract U16(3), F64(2.0) => F64(1.0)); + test!(subtract U32(3), I8(2) => U32(1)); + test!(subtract U32(3), I16(2) => U32(1)); + test!(subtract U32(3), I32(2) => U32(1)); + test!(subtract U32(3), I64(2) => U32(1)); + test!(subtract U32(3), I128(2) => U32(1)); + test!(subtract U32(3), U8(2) => U32(1)); + test!(subtract U32(3), F64(2.0) => F64(1.0)); + + test!(subtract U64(3), I8(2) => U64(1)); + test!(subtract U64(3), I16(2) => U64(1)); + test!(subtract U64(3), I32(2) => U64(1)); + test!(subtract U64(3), I64(2) => U64(1)); + test!(subtract U64(3), I128(2) => U64(1)); + test!(subtract U64(3), U8(2) => U64(1)); + test!(subtract U64(3), F64(2.0) => F64(1.0)); + + test!(subtract U128(3), I8(2) => U128(1)); + test!(subtract U128(3), I16(2) => U128(1)); + test!(subtract U128(3), I32(2) => U128(1)); + test!(subtract U128(3), I64(2) => U128(1)); + test!(subtract U128(3), I128(2) => U128(1)); + test!(subtract U128(3), U8(2) => U128(1)); + test!(subtract U128(3), F64(2.0) => F64(1.0)); + test!(subtract I8(3), F64(2.0) => F64(1.0)); test!(subtract I32(3), F64(2.0) => F64(1.0)); test!(subtract I64(3), F64(2.0) => F64(1.0)); @@ -1133,6 +1271,30 @@ mod tests { test!(multiply U16(3), U8(2) => U16(6)); test!(multiply U16(3), F64(2.0) => F64(6.0)); + test!(multiply U32(3), I8(2) => U32(6)); + test!(multiply U32(3), I16(2) => U32(6)); + test!(multiply U32(3), I32(2) => U32(6)); + test!(multiply U32(3), I64(2) => U32(6)); + test!(multiply U32(3), I128(2) => U32(6)); + test!(multiply U32(3), U8(2) => U32(6)); + test!(multiply U32(3), F64(2.0) => F64(6.0)); + + test!(multiply U64(3), I8(2) => U64(6)); + test!(multiply U64(3), I16(2) => U64(6)); + test!(multiply U64(3), I32(2) => U64(6)); + test!(multiply U64(3), I64(2) => U64(6)); + test!(multiply U64(3), I128(2) => U64(6)); + test!(multiply U64(3), U8(2) => U64(6)); + test!(multiply U64(3), F64(2.0) => F64(6.0)); + + test!(multiply U128(3), I8(2) => U128(6)); + test!(multiply U128(3), I16(2) => U128(6)); + test!(multiply U128(3), I32(2) => U128(6)); + test!(multiply U128(3), I64(2) => U128(6)); + test!(multiply U128(3), I128(2) => U128(6)); + test!(multiply U128(3), U8(2) => U128(6)); + test!(multiply U128(3), F64(2.0) => F64(6.0)); + test!(multiply F64(3.0), F64(2.0) => F64(6.0)); test!(multiply F64(3.0), I8(2) => F64(6.0)); test!(multiply F64(3.0), I32(2) => F64(6.0)); @@ -1208,6 +1370,30 @@ mod tests { test!(divide U16(6), U8(2) => U16(3)); test!(divide U16(6), F64(2.0) => F64(3.0)); + test!(divide U32(6), I8(2) => U32(3)); + test!(divide U32(6), I16(2) => U32(3)); + test!(divide U32(6), I32(2) => U32(3)); + test!(divide U32(6), I64(2) => U32(3)); + test!(divide U32(6), I128(2) => U32(3)); + test!(divide U32(6), U8(2) => U32(3)); + test!(divide U32(6), F64(2.0) => F64(3.0)); + + test!(divide U64(6), I8(2) => U64(3)); + test!(divide U64(6), I16(2) => U64(3)); + test!(divide U64(6), I32(2) => U64(3)); + test!(divide U64(6), I64(2) => U64(3)); + test!(divide U64(6), I128(2) => U64(3)); + test!(divide U64(6), U8(2) => U64(3)); + test!(divide U64(6), F64(2.0) => F64(3.0)); + + test!(divide U128(6), I8(2) => U128(3)); + test!(divide U128(6), I16(2) => U128(3)); + test!(divide U128(6), I32(2) => U128(3)); + test!(divide U128(6), I64(2) => U128(3)); + test!(divide U128(6), I128(2) => U128(3)); + test!(divide U128(6), U8(2) => U128(3)); + test!(divide U128(6), F64(2.0) => F64(3.0)); + test!(divide I8(6), F64(2.0) => F64(3.0)); test!(divide I32(6), F64(2.0) => F64(3.0)); test!(divide I64(6), F64(2.0) => F64(3.0)); @@ -1227,6 +1413,10 @@ mod tests { test!(divide mon!(6), I64(2) => mon!(3)); test!(divide mon!(6), I128(2) => mon!(3)); test!(divide mon!(6), U8(2) => mon!(3)); + test!(divide mon!(6), U16(2) => mon!(3)); + test!(divide mon!(6), U32(2) => mon!(3)); + test!(divide mon!(6), U64(2) => mon!(3)); + test!(divide mon!(6), U128(2) => mon!(3)); test!(divide mon!(6), F64(2.0) => mon!(3)); test!(modulo I8(6), I8(4) => I8(2)); @@ -1291,6 +1481,9 @@ mod tests { null_test!(add I128(1), Null); null_test!(add U8(1), Null); null_test!(add U16(1), Null); + null_test!(add U32(1), Null); + null_test!(add U64(1), Null); + null_test!(add U128(1), Null); null_test!(add F64(1.0), Null); null_test!(add decimal(1), Null); null_test!(add date(), Null); @@ -1304,6 +1497,9 @@ mod tests { null_test!(subtract I128(1), Null); null_test!(subtract U8(1), Null); null_test!(subtract U16(1), Null); + null_test!(subtract U32(1), Null); + null_test!(subtract U64(1), Null); + null_test!(subtract U128(1), Null); null_test!(subtract F64(1.0), Null); null_test!(subtract decimal(1), Null); null_test!(subtract date(), Null); @@ -1317,6 +1513,9 @@ mod tests { null_test!(multiply I128(1), Null); null_test!(multiply U8(1), Null); null_test!(multiply U16(1), Null); + null_test!(multiply U32(1), Null); + null_test!(multiply U64(1), Null); + null_test!(multiply U128(1), Null); null_test!(multiply F64(1.0), Null); null_test!(multiply decimal(1), Null); null_test!(multiply mon!(1), Null); @@ -1327,6 +1526,9 @@ mod tests { null_test!(divide I128(1), Null); null_test!(divide U8(1), Null); null_test!(divide U16(1), Null); + null_test!(divide U32(1), Null); + null_test!(divide U64(1), Null); + null_test!(divide U128(1), Null); null_test!(divide F64(1.0), Null); null_test!(divide decimal(1), Null); null_test!(divide mon!(1), Null); @@ -1337,6 +1539,9 @@ mod tests { null_test!(modulo I128(1), Null); null_test!(modulo U8(1), Null); null_test!(modulo U16(1), Null); + null_test!(modulo U32(1), Null); + null_test!(modulo U64(1), Null); + null_test!(modulo U128(1), Null); null_test!(modulo F64(1.0), Null); null_test!(modulo decimal(1), Null); @@ -1347,6 +1552,9 @@ mod tests { null_test!(add Null, I128(1)); null_test!(add Null, U8(1)); null_test!(add Null, U16(1)); + null_test!(add Null, U32(1)); + null_test!(add Null, U64(1)); + null_test!(add Null, U128(1)); null_test!(add Null, F64(1.0)); null_test!(add Null, decimal(1)); null_test!(add Null, mon!(1)); @@ -1359,6 +1567,9 @@ mod tests { null_test!(subtract Null, I128(1)); null_test!(subtract Null, U8(1)); null_test!(subtract Null, U16(1)); + null_test!(subtract Null, U32(1)); + null_test!(subtract Null, U64(1)); + null_test!(subtract Null, U128(1)); null_test!(subtract Null, F64(1.0)); null_test!(subtract Null, decimal(1)); null_test!(subtract Null, date()); @@ -1372,6 +1583,9 @@ mod tests { null_test!(multiply Null, I128(1)); null_test!(multiply Null, U8(1)); null_test!(multiply Null, U16(1)); + null_test!(multiply Null, U32(1)); + null_test!(multiply Null, U64(1)); + null_test!(multiply Null, U128(1)); null_test!(multiply Null, F64(1.0)); null_test!(multiply Null, decimal(1)); null_test!(divide Null, I8(1)); @@ -1381,6 +1595,9 @@ mod tests { null_test!(divide Null, I128(1)); null_test!(divide Null, U8(1)); null_test!(divide Null, U16(1)); + null_test!(divide Null, U32(1)); + null_test!(divide Null, U64(1)); + null_test!(divide Null, U128(1)); null_test!(divide Null, F64(1.0)); null_test!(divide Null, decimal(1)); null_test!(modulo Null, I8(1)); @@ -1389,6 +1606,9 @@ mod tests { null_test!(modulo Null, I128(1)); null_test!(modulo Null, U8(1)); null_test!(modulo Null, U16(1)); + null_test!(modulo Null, U32(1)); + null_test!(modulo Null, U64(1)); + null_test!(modulo Null, U128(1)); null_test!(modulo Null, F64(1.0)); null_test!(modulo Null, decimal(1)); @@ -1434,6 +1654,9 @@ mod tests { cast!(I128(1) => Int128 , I128(1)); cast!(U8(1) => Uint8 , U8(1)); cast!(U16(1) => Uint16 , U16(1)); + cast!(U32(1) => Uint32 , U32(1)); + cast!(U64(1) => Uint64 , U64(1)); + cast!(U128(1) => Uint128 , U128(1)); cast!(F64(1.0) => Float , F64(1.0)); cast!(Value::Uuid(123) => Uuid , Value::Uuid(123)); @@ -1453,6 +1676,12 @@ mod tests { cast!(U8(0) => Boolean, Bool(false)); cast!(U16(1) => Boolean, Bool(true)); cast!(U16(0) => Boolean, Bool(false)); + cast!(U32(1) => Boolean, Bool(true)); + cast!(U32(1) => Boolean, Bool(true)); + cast!(U64(1) => Boolean, Bool(true)); + cast!(U64(0) => Boolean, Bool(false)); + cast!(U128(0) => Boolean, Bool(false)); + cast!(U128(0) => Boolean, Bool(false)); cast!(F64(1.0) => Boolean, Bool(true)); cast!(F64(0.0) => Boolean, Bool(false)); cast!(Null => Boolean, Null); @@ -1488,6 +1717,30 @@ mod tests { cast!(Str("11".to_owned()) => Uint8, U8(11)); cast!(Null => Uint8, Null); + cast!(Bool(true) => Uint16, U16(1)); + cast!(Bool(false) => Uint16, U16(0)); + cast!(F64(1.1) => Uint16, U16(1)); + cast!(Str("11".to_owned()) => Uint16, U16(11)); + cast!(Null => Uint16, Null); + + cast!(Bool(true) => Uint32, U32(1)); + cast!(Bool(false) => Uint32, U32(0)); + cast!(F64(1.1) => Uint32, U32(1)); + cast!(Str("11".to_owned()) => Uint32, U32(11)); + cast!(Null => Uint32, Null); + + cast!(Bool(true) => Uint64, U64(1)); + cast!(Bool(false) => Uint64, U64(0)); + cast!(F64(1.1) => Uint64, U64(1)); + cast!(Str("11".to_owned()) => Uint64, U64(11)); + cast!(Null => Uint64, Null); + + cast!(Bool(true) => Uint128, U128(1)); + cast!(Bool(false) => Uint128, U128(0)); + cast!(F64(1.1) => Uint128, U128(1)); + cast!(Str("11".to_owned()) => Uint128, U128(11)); + cast!(Null => Uint128, Null); + // Float cast!(Bool(true) => Float, F64(1.0)); cast!(Bool(false) => Float, F64(0.0)); @@ -1498,6 +1751,9 @@ mod tests { cast!(I128(1) => Float, F64(1.0)); cast!(U8(1) => Float, F64(1.0)); cast!(U16(1) => Float, F64(1.0)); + cast!(U32(1) => Float, F64(1.0)); + cast!(U64(1) => Float, F64(1.0)); + cast!(U128(1) => Float, F64(1.0)); cast!(Str("11".to_owned()) => Float, F64(11.0)); cast!(Null => Float, Null); @@ -1511,6 +1767,9 @@ mod tests { cast!(I128(11) => Text, Str("11".to_owned())); cast!(U8(11) => Text, Str("11".to_owned())); cast!(U16(11) => Text, Str("11".to_owned())); + cast!(U32(11) => Text, Str("11".to_owned())); + cast!(U64(11) => Text, Str("11".to_owned())); + cast!(U128(11) => Text, Str("11".to_owned())); cast!(F64(1.0) => Text, Str("1".to_owned())); cast!(inet("::1") => Text, Str("::1".to_owned())); @@ -1584,6 +1843,9 @@ mod tests { assert_eq!(Str("A".to_owned()).concat(I128(1)), Str("A1".to_owned())); assert_eq!(Str("A".to_owned()).concat(U8(1)), Str("A1".to_owned())); assert_eq!(Str("A".to_owned()).concat(U16(1)), Str("A1".to_owned())); + assert_eq!(Str("A".to_owned()).concat(U32(1)), Str("A1".to_owned())); + assert_eq!(Str("A".to_owned()).concat(U64(1)), Str("A1".to_owned())); + assert_eq!(Str("A".to_owned()).concat(U128(1)), Str("A1".to_owned())); assert_eq!(Str("A".to_owned()).concat(F64(1.0)), Str("A1".to_owned())); assert_eq!( List(vec![I64(1)]).concat(List(vec![I64(2)])), @@ -1631,6 +1893,12 @@ mod tests { assert!(U8(1).validate_type(&D::Text).is_err()); assert!(U16(1).validate_type(&D::Uint16).is_ok()); assert!(U16(1).validate_type(&D::Text).is_err()); + assert!(U32(1).validate_type(&D::Uint32).is_ok()); + assert!(U32(1).validate_type(&D::Text).is_err()); + assert!(U64(1).validate_type(&D::Uint64).is_ok()); + assert!(U64(1).validate_type(&D::Text).is_err()); + assert!(U128(1).validate_type(&D::Uint128).is_ok()); + assert!(U128(1).validate_type(&D::Text).is_err()); assert!(F64(1.0).validate_type(&D::Float).is_ok()); assert!(F64(1.0).validate_type(&D::Int).is_err()); assert!(Decimal(rust_decimal::Decimal::ONE) @@ -1709,6 +1977,9 @@ mod tests { assert_eq!(I128(5).unary_factorial(), Ok(I128(120))); assert_eq!(U8(5).unary_factorial(), Ok(I128(120))); assert_eq!(U16(5).unary_factorial(), Ok(I128(120))); + assert_eq!(U32(5).unary_factorial(), Ok(I128(120))); + assert_eq!(U64(5).unary_factorial(), Ok(I128(120))); + assert_eq!(U128(5).unary_factorial(), Ok(I128(120))); assert_eq!( F64(5.0).unary_factorial(), Err(ValueError::FactorialOnNonInteger.into()) @@ -1728,6 +1999,9 @@ mod tests { assert_eq!(I128(9).sqrt(), Ok(F64(3.0))); assert_eq!(U8(9).sqrt(), Ok(F64(3.0))); assert_eq!(U16(9).sqrt(), Ok(F64(3.0))); + assert_eq!(U32(9).sqrt(), Ok(F64(3.0))); + assert_eq!(U64(9).sqrt(), Ok(F64(3.0))); + assert_eq!(U128(9).sqrt(), Ok(F64(3.0))); assert_eq!(F64(9.0).sqrt(), Ok(F64(3.0))); assert!(Null.sqrt().unwrap().is_null()); assert_eq!( @@ -1789,6 +2063,9 @@ mod tests { assert_eq!(I128(1).get_type(), Some(D::Int128)); assert_eq!(U8(1).get_type(), Some(D::Uint8)); assert_eq!(U16(1).get_type(), Some(D::Uint16)); + assert_eq!(U32(1).get_type(), Some(D::Uint32)); + assert_eq!(U64(1).get_type(), Some(D::Uint64)); + assert_eq!(U128(1).get_type(), Some(D::Uint128)); assert_eq!(F64(1.1).get_type(), Some(D::Float)); assert_eq!(decimal.get_type(), Some(D::Decimal)); assert_eq!(Bool(true).get_type(), Some(D::Boolean)); diff --git a/core/src/translate/data_type.rs b/core/src/translate/data_type.rs index dc7139ff2..1ba2e8fa2 100644 --- a/core/src/translate/data_type.rs +++ b/core/src/translate/data_type.rs @@ -32,6 +32,9 @@ pub fn translate_data_type(sql_data_type: &SqlDataType) -> Result { Some("INT128") => Ok(DataType::Int128), Some("UINT8") => Ok(DataType::Uint8), Some("UINT16") => Ok(DataType::Uint16), + Some("UINT32") => Ok(DataType::Uint32), + Some("UINT64") => Ok(DataType::Uint64), + Some("UINT128") => Ok(DataType::Uint128), Some("INET") => Ok(DataType::Inet), _ => Err(TranslateError::UnsupportedDataType(sql_data_type.to_string()).into()), diff --git a/test-suite/src/data_type/uint128.rs b/test-suite/src/data_type/uint128.rs new file mode 100644 index 000000000..7c206eb5d --- /dev/null +++ b/test-suite/src/data_type/uint128.rs @@ -0,0 +1,47 @@ +use { + crate::*, + gluesql_core::{data::ValueError, prelude::Value::*}, +}; + +test_case!(uint128, async move { + run!( + "CREATE TABLE Item ( + field_one UINT128, + field_two UINT128, + );" + ); + run!(r#"INSERT INTO Item VALUES (1, 1), (2, 2), (3, 3), (4, 4);"#); + + test!( + "INSERT INTO Item VALUES (327689,327689);", + Err(ValueError::FailedToParseNumber.into()) + ); + + test!( + "INSERT INTO Item VALUES (-32769, -32769);", + Err(ValueError::FailedToParseNumber.into()) + ); + test!( + "SELECT field_one, field_two FROM Item", + Ok(select!( + field_one | field_two + U128 | U128; + 1 1; + 2 2; + 3 3; + 4 4 + )) + ); + test!( + "SELECT field_one FROM Item WHERE field_one > 0", + Ok(select!(field_one U128; 1; 2;3;4)) + ); + test!( + "SELECT field_one FROM Item WHERE field_one >= 0", + Ok(select!(field_one U128; 1; 2;3;4)) + ); + test!( + "SELECT field_one FROM Item WHERE field_one = 2", + Ok(select!(field_one U128; 2)) + ); +}); diff --git a/test-suite/src/data_type/uint32.rs b/test-suite/src/data_type/uint32.rs new file mode 100644 index 000000000..56a713488 --- /dev/null +++ b/test-suite/src/data_type/uint32.rs @@ -0,0 +1,47 @@ +use { + crate::*, + gluesql_core::{data::ValueError, prelude::Value::*}, +}; + +test_case!(uint32, async move { + run!( + "CREATE TABLE Item ( + field_one UINT32, + field_two UINT32, + );" + ); + run!(r#"INSERT INTO Item VALUES (1, 1), (2, 2), (3, 3), (4, 4);"#); + + test!( + "INSERT INTO Item VALUES (327689,327689);", + Err(ValueError::FailedToParseNumber.into()) + ); + + test!( + "INSERT INTO Item VALUES (-32769, -32769);", + Err(ValueError::FailedToParseNumber.into()) + ); + test!( + "SELECT field_one, field_two FROM Item", + Ok(select!( + field_one | field_two + U32 | U32; + 1 1; + 2 2; + 3 3; + 4 4 + )) + ); + test!( + "SELECT field_one FROM Item WHERE field_one > 0", + Ok(select!(field_one U32; 1; 2;3;4)) + ); + test!( + "SELECT field_one FROM Item WHERE field_one >= 0", + Ok(select!(field_one U32; 1; 2;3;4)) + ); + test!( + "SELECT field_one FROM Item WHERE field_one = 2", + Ok(select!(field_one U32; 2)) + ); +}); diff --git a/test-suite/src/data_type/uint64.rs b/test-suite/src/data_type/uint64.rs new file mode 100644 index 000000000..a69398785 --- /dev/null +++ b/test-suite/src/data_type/uint64.rs @@ -0,0 +1,47 @@ +use { + crate::*, + gluesql_core::{data::ValueError, prelude::Value::*}, +}; + +test_case!(uint64, async move { + run!( + "CREATE TABLE Item ( + field_one UINT64, + field_two UINT64, + );" + ); + run!(r#"INSERT INTO Item VALUES (1, 1), (2, 2), (3, 3), (4, 4);"#); + + test!( + "INSERT INTO Item VALUES (327689,327689);", + Err(ValueError::FailedToParseNumber.into()) + ); + + test!( + "INSERT INTO Item VALUES (-32769, -32769);", + Err(ValueError::FailedToParseNumber.into()) + ); + test!( + "SELECT field_one, field_two FROM Item", + Ok(select!( + field_one | field_two + U64 | U64; + 1 1; + 2 2; + 3 3; + 4 4 + )) + ); + test!( + "SELECT field_one FROM Item WHERE field_one > 0", + Ok(select!(field_one U64; 1; 2;3;4)) + ); + test!( + "SELECT field_one FROM Item WHERE field_one >= 0", + Ok(select!(field_one U64; 1; 2;3;4)) + ); + test!( + "SELECT field_one FROM Item WHERE field_one = 2", + Ok(select!(field_one U64; 2)) + ); +});