Skip to content

Commit

Permalink
Merge pull request #202 from FlameFactory/add_uint_256
Browse files Browse the repository at this point in the history
[u256/i256] add support for u256/i256
  • Loading branch information
suharev7 authored Nov 5, 2023
2 parents 069d8ca + 5b862b3 commit 61be8e5
Show file tree
Hide file tree
Showing 14 changed files with 372 additions and 4 deletions.
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

0 comments on commit 61be8e5

Please sign in to comment.