clickhouse.rs icon indicating copy to clipboard operation
clickhouse.rs copied to clipboard

Support for `UInt256`

Open gd87429 opened this issue 1 year ago • 4 comments

  1. Regarding U256, not sure if there is one, what should we use? Something like this would be nice.

  2. I saw a previous discussion about DateTime in #1. Any interest in supporting chrono or time instead of u32?

gd87429 avatar Nov 12 '22 13:11 gd87429

Hi, thanks for the questions!

U256

Now there is no default way to do it in this crate because I don't know one good crate for it. For instance,primitive_types doesn't provide i256 (only u256), so support will be incomplete.

However, you can implement ser/de for primitives_types::U256 on your own. For instance:

mod u256 {
    use primitive_types::U256;
    use serde::{
        de::{Deserialize, Deserializer},
        ser::{Serialize, Serializer},
    };

    pub fn serialize<S: Serializer>(u: &U256, serializer: S) -> Result<S::Ok, S::Error> {
        u.0.serialize(serializer)
    }

    pub fn deserialize<'de, D>(deserializer: D) -> Result<U256, D::Error>
    where
        D: Deserializer<'de>,
    {
        let u: [u64; 4] = Deserialize::deserialize(deserializer)?;
        Ok(U256(u))
    }
}

#[derive(Debug, Row, Serialize, Deserialize)]
struct MyRow {
    #[serde(with = "u256")]
    u: U256,
}

I'm not sure it works correctly on big-endian machines, because I believe the documentation lies that it's LE.

So, a more reliable way to do ser/de is

    pub fn serialize<S: Serializer>(u: &U256, serializer: S) -> Result<S::Ok, S::Error> {
        let mut buf: [u8; 32] = [0; 32];
        u.to_little_endian(&mut buf);
        buf.serialize(serializer)
    }

    pub fn deserialize<'de, D>(deserializer: D) -> Result<U256, D::Error>
    where
        D: Deserializer<'de>,
    {
        let u: [u8; 32] = Deserialize::deserialize(deserializer)?;
        Ok(U256::from_little_endian(&u))
    }

DateTime

time::OffsetDateTime is supported now in master by using serde(with = "clickhouse::serde::time::datetime") (and datetime64::{secs,millis,micros,nanos} for DateTime64(_)). It will be published soon with corresponding documentation.

loyd avatar Nov 14 '22 04:11 loyd

Thank you so much for the very detailed answer. This is great 👍 I'll use the implementation you suggested for U256 and wait for datetime to be released. Thank you!

gd87429 avatar Nov 14 '22 13:11 gd87429

Closing since 0.11.1 has been released! Thank you.

gd87429 avatar Nov 25 '22 11:11 gd87429

Reopened, because the issue is about UInt256

loyd avatar Nov 25 '22 13:11 loyd