Skip to content

Support for UInt256 #48

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Open
gd87429 opened this issue Nov 12, 2022 · 6 comments
Open

Support for UInt256 #48

gd87429 opened this issue Nov 12, 2022 · 6 comments
Labels
data-types enhancement New feature or request

Comments

@gd87429
Copy link

gd87429 commented Nov 12, 2022

  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 Insert a DateTime Type #1. Any interest in supporting chrono or time instead of u32?

@loyd
Copy link
Collaborator

loyd commented Nov 14, 2022

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.

@gd87429
Copy link
Author

gd87429 commented Nov 14, 2022

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!

@loyd loyd changed the title Support for U256 and DateTime? Support for UInt256 and DateTime Nov 22, 2022
@loyd loyd changed the title Support for UInt256 and DateTime Support for UInt256 Nov 22, 2022
@gd87429
Copy link
Author

gd87429 commented Nov 25, 2022

Closing since 0.11.1 has been released! Thank you.

@gd87429 gd87429 closed this as completed Nov 25, 2022
@loyd
Copy link
Collaborator

loyd commented Nov 25, 2022

Reopened, because the issue is about UInt256

@loyd loyd reopened this Nov 25, 2022
@slvrtrn slvrtrn added enhancement New feature or request data-types labels Jul 29, 2024
@slvrtrn slvrtrn mentioned this issue Jul 30, 2024
11 tasks
@nstylo
Copy link

nstylo commented Jan 24, 2025

What's the status on this one. We are dealing with UInt256/Int256 data types. There should be a better way of handling this. Using the workaround above currently.

@nstylo
Copy link

nstylo commented Jan 25, 2025

For anyone who is using ruint directly or the alloy-rs re-export of it, this is how I am doing serde:

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

    /// evm U256 is represented in big-endian, but ClickHouse expects little-endian
    pub fn serialize<S: Serializer>(u: &U256, serializer: S) -> Result<S::Ok, S::Error> {
        let buf: [u8; 32] = u.to_le_bytes();
        buf.serialize(serializer)
    }

    /// ClickHouse stores U256 in little-endian
    pub fn deserialize<'de, D>(deserializer: D) -> Result<U256, D::Error>
    where
        D: Deserializer<'de>,
    {
        let buf: [u8; 32] = Deserialize::deserialize(deserializer)?;
        Ok(U256::from_le_bytes(buf))
    }
}

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
data-types enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

4 participants