Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

[u256/i256] add support for u256/i256 #202

Merged
merged 1 commit into from
Nov 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ combine = "^4.6"
percent-encoding = "^2.3"
either = "^1.6"
cfg-if = "1.0.0"
ethnum = "^1.5.0"

[dependencies.futures-util]
version = "^0.3"
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ clickhouse-rs = "*"
* Decimal(P, S)
* Float32, Float64
* String, FixedString(N)
* UInt8, UInt16, UInt32, UInt64, UInt128, Int8, Int16, Int32, Int64, Int128
* UInt8, UInt16, UInt32, UInt64, UInt128, UInt256, Int8, Int16, Int32, Int64, Int128, UInt256
* Nullable(T)
* Array(UInt/Int/Float/String/Date/DateTime)
* SimpleAggregateFunction(F, T)
Expand Down
5 changes: 4 additions & 1 deletion src/types/block/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use std::{
use byteorder::{LittleEndian, WriteBytesExt};
use chrono_tz::Tz;
use clickhouse_rs_cityhash_sys::city_hash_128;
use ethnum::{i256, u256};
use lz4::liblz4::{LZ4_compressBound, LZ4_compress_default};

use crate::{
Expand Down Expand Up @@ -64,12 +65,14 @@ sliceable! {
u32: UInt32,
u64: UInt64,
u128: UInt128,
u256: UInt256,

i8: Int8,
i16: Int16,
i32: Int32,
i64: Int64,
i128: Int128
i128: Int128,
i256: Int256
}

/// Represents Clickhouse Block
Expand Down
5 changes: 5 additions & 0 deletions src/types/column/factory.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use chrono_tz::Tz;
use ethnum::{i256, u256};

use combine::{
any, choice,
Expand Down Expand Up @@ -67,11 +68,13 @@ impl dyn ColumnData {
"UInt32" => W::wrap(VectorColumnData::<u32>::load(reader, size)?),
"UInt64" => W::wrap(VectorColumnData::<u64>::load(reader, size)?),
"UInt128" => W::wrap(VectorColumnData::<u128>::load(reader, size)?),
"UInt256" => W::wrap(VectorColumnData::<u256>::load(reader, size)?),
"Int8" | "TinyInt" => W::wrap(VectorColumnData::<i8>::load(reader, size)?),
"Int16" | "SmallInt" => W::wrap(VectorColumnData::<i16>::load(reader, size)?),
"Int32" | "Int" | "Integer" => W::wrap(VectorColumnData::<i32>::load(reader, size)?),
"Int64" | "BigInt" => W::wrap(VectorColumnData::<i64>::load(reader, size)?),
"Int128" => W::wrap(VectorColumnData::<i128>::load(reader, size)?),
"Int256" => W::wrap(VectorColumnData::<i256>::load(reader, size)?),
"Float32" | "Float" => W::wrap(VectorColumnData::<f32>::load(reader, size)?),
"Float64" | "Double" => W::wrap(VectorColumnData::<f64>::load(reader, size)?),
"String" | "Char" | "Varchar" | "Text" | "TinyText" | "MediumText" | "LongText" | "Blob" | "TinyBlob" | "MediumBlob" | "LongBlob" => W::wrap(StringColumnData::load(reader, size)?),
Expand Down Expand Up @@ -124,11 +127,13 @@ impl dyn ColumnData {
SqlType::UInt32 => W::wrap(VectorColumnData::<u32>::with_capacity(capacity)),
SqlType::UInt64 => W::wrap(VectorColumnData::<u64>::with_capacity(capacity)),
SqlType::UInt128 => W::wrap(VectorColumnData::<u128>::with_capacity(capacity)),
SqlType::UInt256 => W::wrap(VectorColumnData::<u256>::with_capacity(capacity)),
SqlType::Int8 => W::wrap(VectorColumnData::<i8>::with_capacity(capacity)),
SqlType::Int16 => W::wrap(VectorColumnData::<i16>::with_capacity(capacity)),
SqlType::Int32 => W::wrap(VectorColumnData::<i32>::with_capacity(capacity)),
SqlType::Int64 => W::wrap(VectorColumnData::<i64>::with_capacity(capacity)),
SqlType::Int128 => W::wrap(VectorColumnData::<i128>::with_capacity(capacity)),
SqlType::Int256 => W::wrap(VectorColumnData::<i256>::with_capacity(capacity)),
SqlType::String => W::wrap(StringColumnData::with_capacity(capacity)),
SqlType::FixedString(len) => {
W::wrap(FixedStringColumnData::with_capacity(capacity, len))
Expand Down
6 changes: 5 additions & 1 deletion src/types/column/iter/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

use chrono::prelude::*;
use chrono_tz::Tz;
use ethnum::{i256, u256};
use std::{
collections::HashMap,
hash::Hash,
Expand Down Expand Up @@ -78,7 +79,10 @@ simple_num_iterable! {
f64: Float64,

i128: Int128,
u128: UInt128
u128: UInt128,

i256: Int256,
u256: UInt256
}

macro_rules! iterator {
Expand Down
2 changes: 2 additions & 0 deletions src/types/column/numeric.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,12 +205,14 @@ where
Value::UInt32(x) => ValueRef::UInt32(x),
Value::UInt64(x) => ValueRef::UInt64(x),
Value::UInt128(x) => ValueRef::UInt128(x),
Value::UInt256(x) => ValueRef::UInt256(x),

Value::Int8(x) => ValueRef::Int8(x),
Value::Int16(x) => ValueRef::Int16(x),
Value::Int32(x) => ValueRef::Int32(x),
Value::Int64(x) => ValueRef::Int64(x),
Value::Int128(x) => ValueRef::Int128(x),
Value::Int256(x) => ValueRef::Int256(x),

Value::Float32(x) => ValueRef::Float32(x),
Value::Float64(x) => ValueRef::Float64(x),
Expand Down
5 changes: 5 additions & 0 deletions src/types/from_sql.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use chrono::{prelude::*, Duration};
use chrono_tz::Tz;
use either::Either;
use ethnum::{i256, u256};
use std::collections::HashMap;
use std::hash::Hash;
use std::net::{Ipv4Addr, Ipv6Addr};
Expand Down Expand Up @@ -262,11 +263,13 @@ from_sql_vec_impl! {
i32: Int32,
i64: Int64,
i128: Int128,
i256: Int256,

u16: UInt16,
u32: UInt32,
u64: UInt64,
u128: UInt128,
u256: UInt256,

f32: Float32,
f64: Float64
Expand Down Expand Up @@ -343,12 +346,14 @@ from_sql_impl! {
u32: UInt32,
u64: UInt64,
u128: UInt128,
u256: UInt256,

i8: Int8,
i16: Int16,
i32: Int32,
i64: Int64,
i128: Int128,
i256: Int256,

f32: Float32,
f64: Float64
Expand Down
47 changes: 47 additions & 0 deletions src/types/marshal.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use ethnum::{i256, u256};

pub trait Marshal {
fn marshal(&self, scratch: &mut [u8]);
}
Expand Down Expand Up @@ -62,6 +64,13 @@ impl Marshal for u128 {
}
}

impl Marshal for u256 {
fn marshal(&self, scratch: &mut [u8]) {
self.low().marshal(&mut scratch[0..]);
self.high().marshal(&mut scratch[16..]);
}
}

impl Marshal for i8 {
fn marshal(&self, scratch: &mut [u8]) {
scratch[0] = *self as u8;
Expand Down Expand Up @@ -122,6 +131,13 @@ impl Marshal for i128 {
}
}

impl Marshal for i256 {
fn marshal(&self, scratch: &mut [u8]) {
self.low().marshal(&mut scratch[0..]);
self.high().marshal(&mut scratch[16..]);
}
}

impl Marshal for f32 {
fn marshal(&self, scratch: &mut [u8]) {
let bits = self.to_bits();
Expand Down Expand Up @@ -157,6 +173,7 @@ mod test {
use std::fmt;

use crate::types::{Marshal, StatBuffer, Unmarshal};
use ethnum::{i256, u256};
use rand::distributions::{Distribution, Standard};
use rand::random;

Expand Down Expand Up @@ -201,6 +218,21 @@ mod test {
test_some::<u128>()
}

#[test]
fn test_u256() {
for _ in 0..100 {
let mut buffer = u256::buffer();
let v1 = random::<u128>();
let v2 = random::<u128>();
let v = u256::from_words(v1, v2);

v.marshal(buffer.as_mut());
let u = u256::unmarshal(buffer.as_ref());

assert_eq!(v, u);
}
}

#[test]
fn test_i8() {
test_some::<i8>()
Expand All @@ -226,6 +258,21 @@ mod test {
test_some::<i128>()
}

#[test]
fn test_i256() {
for _ in 0..100 {
let mut buffer = i256::buffer();
let v1 = random::<i128>();
let v2 = random::<i128>();
let v = i256::from_words(v1, v2);

v.marshal(buffer.as_mut());
let u = i256::unmarshal(buffer.as_ref());

assert_eq!(v, u);
}
}

#[test]
fn test_f32() {
test_some::<f32>()
Expand Down
7 changes: 7 additions & 0 deletions src/types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use std::{borrow::Cow, collections::HashMap, fmt, mem, pin::Pin, str::FromStr, s

use chrono::prelude::*;
use chrono_tz::Tz;
use ethnum::{i256, u256};
use hostname::get;

use lazy_static::lazy_static;
Expand Down Expand Up @@ -207,11 +208,13 @@ has_sql_type! {
u32: SqlType::UInt32,
u64: SqlType::UInt64,
u128: SqlType::UInt128,
u256: SqlType::UInt256,
i8: SqlType::Int8,
i16: SqlType::Int16,
i32: SqlType::Int32,
i64: SqlType::Int64,
i128: SqlType::Int128,
i256: SqlType::Int256,
&str: SqlType::String,
String: SqlType::String,
f32: SqlType::Float32,
Expand Down Expand Up @@ -314,11 +317,13 @@ pub enum SqlType {
UInt32,
UInt64,
UInt128,
UInt256,
Int8,
Int16,
Int32,
Int64,
Int128,
Int256,
String,
FixedString(usize),
Float32,
Expand Down Expand Up @@ -382,11 +387,13 @@ impl SqlType {
SqlType::UInt32 => "UInt32".into(),
SqlType::UInt64 => "UInt64".into(),
SqlType::UInt128 => "UInt128".into(),
SqlType::UInt256 => "UInt256".into(),
SqlType::Int8 => "Int8".into(),
SqlType::Int16 => "Int16".into(),
SqlType::Int32 => "Int32".into(),
SqlType::Int64 => "Int64".into(),
SqlType::Int128 => "Int128".into(),
SqlType::Int256 => "Int256".into(),
SqlType::String => "String".into(),
SqlType::FixedString(str_len) => format!("FixedString({str_len})").into(),
SqlType::Float32 => "Float32".into(),
Expand Down
25 changes: 25 additions & 0 deletions src/types/stat_buffer.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::types::SqlType;
use ethnum::{i256, u256};

pub trait StatBuffer {
type Buffer: AsMut<[u8]> + AsRef<[u8]> + Copy + Sync;
Expand Down Expand Up @@ -66,6 +67,18 @@ impl StatBuffer for u128 {
}
}

impl StatBuffer for u256 {
type Buffer = [u8; 32];

fn buffer() -> Self::Buffer {
[0; 32]
}

fn sql_type() -> SqlType {
SqlType::UInt256
}
}

impl StatBuffer for i8 {
type Buffer = [u8; 1];

Expand Down Expand Up @@ -126,6 +139,18 @@ impl StatBuffer for i128 {
}
}

impl StatBuffer for i256 {
type Buffer = [u8; 32];

fn buffer() -> Self::Buffer {
[0; 32]
}

fn sql_type() -> SqlType {
SqlType::Int256
}
}

impl StatBuffer for f32 {
type Buffer = [u8; 4];

Expand Down
20 changes: 20 additions & 0 deletions src/types/unmarshal.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use ethnum::{i256, u256};

pub trait Unmarshal<T: Copy> {
fn unmarshal(scratch: &[u8]) -> T;
}
Expand Down Expand Up @@ -57,6 +59,15 @@ impl Unmarshal<u128> for u128 {
}
}

impl Unmarshal<u256> for u256 {
fn unmarshal(scratch: &[u8]) -> Self {
Self::from_words(
u128::unmarshal(&scratch[16..]),
u128::unmarshal(&scratch[0..]),
)
}
}

impl Unmarshal<i8> for i8 {
fn unmarshal(scratch: &[u8]) -> Self {
scratch[0] as Self
Expand Down Expand Up @@ -112,6 +123,15 @@ impl Unmarshal<i128> for i128 {
}
}

impl Unmarshal<i256> for i256 {
fn unmarshal(scratch: &[u8]) -> Self {
Self::from_words(
i128::unmarshal(&scratch[16..]),
i128::unmarshal(&scratch[0..]),
)
}
}

impl Unmarshal<f32> for f32 {
fn unmarshal(scratch: &[u8]) -> Self {
let bits = u32::from(scratch[0])
Expand Down
Loading