diff --git a/scylla-cql/src/types/deserialize/value.rs b/scylla-cql/src/types/deserialize/value.rs index 8ca6d1260f..a2f30e76a6 100644 --- a/scylla-cql/src/types/deserialize/value.rs +++ b/scylla-cql/src/types/deserialize/value.rs @@ -1776,9 +1776,7 @@ pub(super) mod tests { use std::fmt::Debug; use std::net::{IpAddr, Ipv6Addr}; - use crate::frame::response::cql_to_rust::FromCqlVal; use crate::frame::response::result::{deser_cql_value, ColumnType, CqlValue}; - use crate::frame::types; use crate::frame::value::{ Counter, CqlDate, CqlDecimal, CqlDuration, CqlTime, CqlTimestamp, CqlTimeuuid, CqlVarint, }; @@ -1911,286 +1909,6 @@ pub(super) mod tests { assert_eq!(decoded_int, Some(MaybeEmpty::Empty)); } - #[test] - fn test_from_cql_value_compatibility() { - // This test should have a sub-case for each type - // that implements FromCqlValue - - // fixed size integers - for i in 0..7 { - let v: i8 = 1 << i; - compat_check::(&ColumnType::TinyInt, make_bytes(&v.to_be_bytes())); - compat_check::(&ColumnType::TinyInt, make_bytes(&(-v).to_be_bytes())); - } - for i in 0..15 { - let v: i16 = 1 << i; - compat_check::(&ColumnType::SmallInt, make_bytes(&v.to_be_bytes())); - compat_check::(&ColumnType::SmallInt, make_bytes(&(-v).to_be_bytes())); - } - for i in 0..31 { - let v: i32 = 1 << i; - compat_check::(&ColumnType::Int, make_bytes(&v.to_be_bytes())); - compat_check::(&ColumnType::Int, make_bytes(&(-v).to_be_bytes())); - } - for i in 0..63 { - let v: i64 = 1 << i; - compat_check::(&ColumnType::BigInt, make_bytes(&v.to_be_bytes())); - compat_check::(&ColumnType::BigInt, make_bytes(&(-v).to_be_bytes())); - } - - // bool - compat_check::(&ColumnType::Boolean, make_bytes(&[0])); - compat_check::(&ColumnType::Boolean, make_bytes(&[1])); - - // fixed size floating point types - compat_check::(&ColumnType::Float, make_bytes(&123f32.to_be_bytes())); - compat_check::(&ColumnType::Float, make_bytes(&(-123f32).to_be_bytes())); - compat_check::(&ColumnType::Double, make_bytes(&123f64.to_be_bytes())); - compat_check::(&ColumnType::Double, make_bytes(&(-123f64).to_be_bytes())); - - // big integers - const PI_STR: &[u8] = b"3.1415926535897932384626433832795028841971693993751058209749445923"; - let num1 = &PI_STR[2..]; - let num2 = [b'-'] - .into_iter() - .chain(PI_STR[2..].iter().copied()) - .collect::>(); - let num3 = &b"0"[..]; - - // native - CqlVarint - { - let num1 = CqlVarint::from_signed_bytes_be_slice(num1); - let num2 = CqlVarint::from_signed_bytes_be_slice(&num2); - let num3 = CqlVarint::from_signed_bytes_be_slice(num3); - compat_check_serialized::(&ColumnType::Varint, &num1); - compat_check_serialized::(&ColumnType::Varint, &num2); - compat_check_serialized::(&ColumnType::Varint, &num3); - } - - #[cfg(feature = "num-bigint-03")] - { - use num_bigint_03::BigInt; - - let num1 = BigInt::parse_bytes(num1, 10).unwrap(); - let num2 = BigInt::parse_bytes(&num2, 10).unwrap(); - let num3 = BigInt::parse_bytes(num3, 10).unwrap(); - compat_check_serialized::(&ColumnType::Varint, &num1); - compat_check_serialized::(&ColumnType::Varint, &num2); - compat_check_serialized::(&ColumnType::Varint, &num3); - } - - #[cfg(feature = "num-bigint-04")] - { - use num_bigint_04::BigInt; - - let num1 = BigInt::parse_bytes(num1, 10).unwrap(); - let num2 = BigInt::parse_bytes(&num2, 10).unwrap(); - let num3 = BigInt::parse_bytes(num3, 10).unwrap(); - compat_check_serialized::(&ColumnType::Varint, &num1); - compat_check_serialized::(&ColumnType::Varint, &num2); - compat_check_serialized::(&ColumnType::Varint, &num3); - } - - // big decimals - { - let scale1 = 0; - let scale2 = -42; - let scale3 = 2137; - let num1 = CqlDecimal::from_signed_be_bytes_slice_and_exponent(num1, scale1); - let num2 = CqlDecimal::from_signed_be_bytes_and_exponent(num2, scale2); - let num3 = CqlDecimal::from_signed_be_bytes_slice_and_exponent(num3, scale3); - compat_check_serialized::(&ColumnType::Decimal, &num1); - compat_check_serialized::(&ColumnType::Decimal, &num2); - compat_check_serialized::(&ColumnType::Decimal, &num3); - } - - // native - CqlDecimal - - #[cfg(feature = "bigdecimal-04")] - { - use bigdecimal_04::BigDecimal; - - let num1 = PI_STR.to_vec(); - let num2 = vec![b'-'] - .into_iter() - .chain(PI_STR.iter().copied()) - .collect::>(); - let num3 = b"0.0".to_vec(); - - let num1 = BigDecimal::parse_bytes(&num1, 10).unwrap(); - let num2 = BigDecimal::parse_bytes(&num2, 10).unwrap(); - let num3 = BigDecimal::parse_bytes(&num3, 10).unwrap(); - compat_check_serialized::(&ColumnType::Decimal, &num1); - compat_check_serialized::(&ColumnType::Decimal, &num2); - compat_check_serialized::(&ColumnType::Decimal, &num3); - } - - // blob - compat_check::>(&ColumnType::Blob, make_bytes(&[])); - compat_check::>(&ColumnType::Blob, make_bytes(&[1, 9, 2, 8, 3, 7, 4, 6, 5])); - - // text types - for typ in &[ColumnType::Ascii, ColumnType::Text] { - compat_check::(typ, make_bytes("".as_bytes())); - compat_check::(typ, make_bytes("foo".as_bytes())); - compat_check::(typ, make_bytes("superfragilisticexpialidocious".as_bytes())); - } - - // counters - for i in 0..63 { - let v: i64 = 1 << i; - compat_check::(&ColumnType::Counter, make_bytes(&v.to_be_bytes())); - } - - // duration - let duration1 = CqlDuration { - days: 123, - months: 456, - nanoseconds: 789, - }; - let duration2 = CqlDuration { - days: 987, - months: 654, - nanoseconds: 321, - }; - compat_check_serialized::(&ColumnType::Duration, &duration1); - compat_check_serialized::(&ColumnType::Duration, &duration2); - - // date - let date1 = (2u32.pow(31)).to_be_bytes(); - let date2 = (2u32.pow(31) - 30).to_be_bytes(); - let date3 = (2u32.pow(31) + 30).to_be_bytes(); - - compat_check::(&ColumnType::Date, make_bytes(&date1)); - compat_check::(&ColumnType::Date, make_bytes(&date2)); - compat_check::(&ColumnType::Date, make_bytes(&date3)); - - #[cfg(feature = "chrono")] - { - compat_check::(&ColumnType::Date, make_bytes(&date1)); - compat_check::(&ColumnType::Date, make_bytes(&date2)); - compat_check::(&ColumnType::Date, make_bytes(&date3)); - } - - #[cfg(feature = "time")] - { - compat_check::(&ColumnType::Date, make_bytes(&date1)); - compat_check::(&ColumnType::Date, make_bytes(&date2)); - compat_check::(&ColumnType::Date, make_bytes(&date3)); - } - - // time - let time1 = CqlTime(0); - let time2 = CqlTime(123456789); - let time3 = CqlTime(86399999999999); // maximum allowed - - compat_check_serialized::(&ColumnType::Time, &time1); - compat_check_serialized::(&ColumnType::Time, &time2); - compat_check_serialized::(&ColumnType::Time, &time3); - - #[cfg(feature = "chrono")] - { - compat_check_serialized::(&ColumnType::Time, &time1); - compat_check_serialized::(&ColumnType::Time, &time2); - compat_check_serialized::(&ColumnType::Time, &time3); - } - - #[cfg(feature = "time")] - { - compat_check_serialized::(&ColumnType::Time, &time1); - compat_check_serialized::(&ColumnType::Time, &time2); - compat_check_serialized::(&ColumnType::Time, &time3); - } - - // timestamp - let timestamp1 = CqlTimestamp(0); - let timestamp2 = CqlTimestamp(123456789); - let timestamp3 = CqlTimestamp(98765432123456); - - compat_check_serialized::(&ColumnType::Timestamp, ×tamp1); - compat_check_serialized::(&ColumnType::Timestamp, ×tamp2); - compat_check_serialized::(&ColumnType::Timestamp, ×tamp3); - - #[cfg(feature = "chrono")] - { - compat_check_serialized::>( - &ColumnType::Timestamp, - ×tamp1, - ); - compat_check_serialized::>( - &ColumnType::Timestamp, - ×tamp2, - ); - compat_check_serialized::>( - &ColumnType::Timestamp, - ×tamp3, - ); - } - - #[cfg(feature = "time")] - { - compat_check_serialized::(&ColumnType::Timestamp, ×tamp1); - compat_check_serialized::(&ColumnType::Timestamp, ×tamp2); - compat_check_serialized::(&ColumnType::Timestamp, ×tamp3); - } - - // inet - let ipv4 = IpAddr::from([127u8, 0, 0, 1]); - let ipv6: IpAddr = Ipv6Addr::LOCALHOST.into(); - compat_check::(&ColumnType::Inet, make_ip_address(ipv4)); - compat_check::(&ColumnType::Inet, make_ip_address(ipv6)); - - // uuid and timeuuid - // new_v4 generates random UUIDs, so these are different cases - for uuid in std::iter::repeat_with(Uuid::new_v4).take(3) { - compat_check_serialized::(&ColumnType::Uuid, &uuid); - compat_check_serialized::(&ColumnType::Timeuuid, &CqlTimeuuid::from(uuid)); - } - - // empty values - // ...are implemented via MaybeEmpty and are handled in other tests - - // nulls, represented via Option - compat_check_serialized::>(&ColumnType::Int, &123i32); - compat_check::>(&ColumnType::Int, make_null()); - - // collections - let mut list = BytesMut::new(); - list.put_i32(3); - append_bytes(&mut list, &123i32.to_be_bytes()); - append_bytes(&mut list, &456i32.to_be_bytes()); - append_bytes(&mut list, &789i32.to_be_bytes()); - let list = make_bytes(&list); - let list_type = ColumnType::List(Box::new(ColumnType::Int)); - compat_check::>(&list_type, list.clone()); - // Support for deserialization List -> {Hash,BTree}Set was removed not to cause confusion. - // Such deserialization would be lossy, which is unwanted. - - let mut set = BytesMut::new(); - set.put_i32(3); - append_bytes(&mut set, &123i32.to_be_bytes()); - append_bytes(&mut set, &456i32.to_be_bytes()); - append_bytes(&mut set, &789i32.to_be_bytes()); - let set = make_bytes(&set); - let set_type = ColumnType::Set(Box::new(ColumnType::Int)); - compat_check::>(&set_type, set.clone()); - compat_check::>(&set_type, set.clone()); - compat_check::>(&set_type, set); - - let mut map = BytesMut::new(); - map.put_i32(3); - append_bytes(&mut map, &123i32.to_be_bytes()); - append_bytes(&mut map, "quick".as_bytes()); - append_bytes(&mut map, &456i32.to_be_bytes()); - append_bytes(&mut map, "brown".as_bytes()); - append_bytes(&mut map, &789i32.to_be_bytes()); - append_bytes(&mut map, "fox".as_bytes()); - let map = make_bytes(&map); - let map_type = ColumnType::Map(Box::new(ColumnType::Int), Box::new(ColumnType::Text)); - compat_check::>(&map_type, map.clone()); - compat_check::>(&map_type, map); - } - #[test] fn test_maybe_empty() { let empty = make_bytes(&[]); @@ -2352,37 +2070,6 @@ pub(super) mod tests { assert_eq!(tup, SwappedPair("foo", 42)); } - // Checks that both new and old serialization framework - // produces the same results in this case - fn compat_check(typ: &ColumnType, raw: Bytes) - where - T: for<'f> DeserializeValue<'f>, - T: FromCqlVal>, - T: Debug + PartialEq, - { - let mut slice = raw.as_ref(); - let mut cell = types::read_bytes_opt(&mut slice).unwrap(); - let old = T::from_cql( - cell.as_mut() - .map(|c| deser_cql_value(typ, c)) - .transpose() - .unwrap(), - ) - .unwrap(); - let new = deserialize::(typ, &raw).unwrap(); - assert_eq!(old, new); - } - - fn compat_check_serialized(typ: &ColumnType, val: &dyn SerializeValue) - where - T: for<'f> DeserializeValue<'f>, - T: FromCqlVal>, - T: Debug + PartialEq, - { - let raw = serialize(typ, val); - compat_check::(typ, raw); - } - fn deserialize<'frame, T>( typ: &'frame ColumnType, bytes: &'frame Bytes,