Skip to content

Commit

Permalink
feat: impl UNSIGNED INTEGER and UNSIGNED BIGINT
Browse files Browse the repository at this point in the history
  • Loading branch information
laysakura committed Jun 20, 2022
1 parent 6576119 commit f4245cb
Show file tree
Hide file tree
Showing 8 changed files with 162 additions and 6 deletions.
2 changes: 1 addition & 1 deletion springql-core/src/pipeline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ pub use pump_model::{
};
pub use relation::{
ColumnConstraint, ColumnDataType, ColumnDefinition, F32LooseType, I64LooseType,
NumericComparableType, SqlType, StringComparableLoseType,
NumericComparableType, SqlType, StringComparableLoseType, U64LooseType,
};
pub use sink_writer_model::{SinkWriterModel, SinkWriterType};
pub use source_reader_model::{SourceReaderModel, SourceReaderType};
Expand Down
1 change: 1 addition & 0 deletions springql-core/src/pipeline/relation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ mod sql_type;
pub use column::{ColumnConstraint, ColumnDataType, ColumnDefinition};
pub use sql_type::{
F32LooseType, I64LooseType, NumericComparableType, SqlType, StringComparableLoseType,
U64LooseType,
};
27 changes: 27 additions & 0 deletions springql-core/src/pipeline/relation/sql_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,19 @@ impl SqlType {
SqlType::NumericComparable(NumericComparableType::I64Loose(I64LooseType::BigInt))
}

/// Constructor of Integer
pub fn unsigned_integer() -> SqlType {
SqlType::NumericComparable(NumericComparableType::U64Loose(
U64LooseType::UnsignedInteger,
))
}
/// Constructor of unsigned BigInt
pub fn unsigned_big_int() -> SqlType {
SqlType::NumericComparable(NumericComparableType::U64Loose(
U64LooseType::UnsignedBigInt,
))
}

/// Constructor of Float
pub fn float() -> SqlType {
SqlType::NumericComparable(NumericComparableType::F32Loose(F32LooseType::Float))
Expand Down Expand Up @@ -74,11 +87,15 @@ impl SqlType {
}

/// Numeric types (comparable).
#[allow(clippy::enum_variant_names)]
#[derive(Clone, Eq, PartialEq, Hash, Debug)]
pub enum NumericComparableType {
/// Loosely typed as i64
I64Loose(I64LooseType),

/// Loosely typed as u64
U64Loose(U64LooseType),

/// Loosely typed as f32
F32Loose(F32LooseType),
}
Expand All @@ -96,6 +113,16 @@ pub enum I64LooseType {
BigInt,
}

/// Unsigned integer types (loosely typed as u64).
#[derive(Clone, Eq, PartialEq, Hash, Debug)]
pub enum U64LooseType {
/// 4-byte unsigned integer.
UnsignedInteger,

/// 8-byte unsigned integer.
UnsignedBigInt,
}

/// Float types (loosely typed as f64).
#[derive(Clone, Eq, PartialEq, Hash, Debug)]
pub enum F32LooseType {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ keyword = {
| ^"TIMESTAMP"
| ^"TRUE"
| ^"TYPE"
| ^"UNSIGNED"
| ^"WINDOW"
| ^"WRITER"
}
Expand Down Expand Up @@ -320,9 +321,11 @@ data_type = {
*/

integer_type = {
^"SMALLINT"
| ^"INTEGER"
| ^"BIGINT"
^"UNSIGNED"? ~ (
^"SMALLINT"
| ^"INTEGER"
| ^"BIGINT"
)
}

/*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1106,6 +1106,7 @@ impl PestParserImpl {
let s = self_as_str(&mut params);
match s.to_ascii_uppercase().as_str() {
"INTEGER" => Ok(SqlType::integer()),
"UNSIGNED INTEGER" => Ok(SqlType::unsigned_integer()),
x => {
eprintln!("Unexpected data type parsed: {}", x);
unreachable!();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,30 @@ pub trait SpringValue: Sized {
Self::default_err("i64")
}

/// # Failures
///
/// - `SpringError::Sql` when:
/// - the type implementing SqlConvertible is not convertible from u16
fn try_from_u16(_: &u16) -> Result<Self> {
Self::default_err("u16")
}

/// # Failures
///
/// - `SpringError::Sql` when:
/// - the type implementing SqlConvertible is not convertible from u32
fn try_from_u32(_: &u32) -> Result<Self> {
Self::default_err("u32")
}

/// # Failures
///
/// - `SpringError::Sql` when:
/// - the type implementing SqlConvertible is not convertible from u64
fn try_from_u64(_: &u64) -> Result<Self> {
Self::default_err("u64")
}

/// # Failures
///
/// - `SpringError::Sql` when:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,46 @@ impl ToNnSqlValue for i64 {
}
}

impl SpringValue for u32 {
fn try_from_u16(v: &u16) -> Result<Self> {
Ok(*v as u32)
}

fn try_from_u32(v: &u32) -> Result<Self> {
Ok(*v)
}

fn try_from_u64(v: &u64) -> Result<Self> {
u32::try_from(*v)
.with_context(|| format!("cannot convert u64 value ({}) into u32", v))
.map_err(SpringError::Sql)
}
}
impl ToNnSqlValue for u32 {
fn into_sql_value(self) -> NnSqlValue {
NnSqlValue::UnsignedInteger(self)
}
}

impl SpringValue for u64 {
fn try_from_u16(v: &u16) -> Result<Self> {
Ok(*v as u64)
}

fn try_from_u32(v: &u32) -> Result<Self> {
Ok(*v as u64)
}

fn try_from_u64(v: &u64) -> Result<Self> {
Ok(*v)
}
}
impl ToNnSqlValue for u64 {
fn into_sql_value(self) -> NnSqlValue {
NnSqlValue::UnsignedBigInt(self)
}
}

#[cfg(test)]
mod tests_i32 {
use crate::{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use crate::{
mem_size::MemSize,
pipeline::{
F32LooseType, I64LooseType, NumericComparableType, SqlType, StringComparableLoseType,
U64LooseType,
},
stream_engine::{
autonomous_executor::row::value::{
Expand All @@ -35,6 +36,11 @@ pub enum NnSqlValue {
/// BIGINT
BigInt(i64),

/// UNSIGNED INTEGER
UnsignedInteger(u32),
/// UNSIGNED BIGINT
UnsignedBigInt(u64),

/// FLOAT
Float(
// to implement Hash
Expand Down Expand Up @@ -64,6 +70,9 @@ impl MemSize for NnSqlValue {
NnSqlValue::Integer(_) => size_of::<i32>(),
NnSqlValue::BigInt(_) => size_of::<i64>(),

NnSqlValue::UnsignedInteger(_) => size_of::<u32>(),
NnSqlValue::UnsignedBigInt(_) => size_of::<u64>(),

NnSqlValue::Float(_) => size_of::<f32>(),

NnSqlValue::Text(s) => s.capacity(),
Expand Down Expand Up @@ -93,12 +102,16 @@ impl MemSize for NnSqlValue {
///
/// does not work properly with closures which capture &mut environments.
macro_rules! for_all_loose_types {
( $nn_sql_value:expr, $closure_i64:expr, $closure_ordered_float:expr, $closure_string:expr, $closure_blob:expr, $closure_bool:expr, $closure_timestamp:expr, $closure_duration:expr ) => {{
( $nn_sql_value:expr, $closure_i64:expr, $closure_u64:expr, $closure_ordered_float:expr, $closure_string:expr, $closure_blob:expr, $closure_bool:expr, $closure_timestamp:expr, $closure_duration:expr ) => {{
match &$nn_sql_value {
NnSqlValue::SmallInt(_) | NnSqlValue::Integer(_) | NnSqlValue::BigInt(_) => {
let v = $nn_sql_value.unpack::<i64>().unwrap();
$closure_i64(v)
}
NnSqlValue::UnsignedInteger(_) | NnSqlValue::UnsignedBigInt(_) => {
let v = $nn_sql_value.unpack::<u64>().unwrap();
$closure_u64(v)
}
NnSqlValue::Float(_) => {
let v = $nn_sql_value.unpack::<f32>().unwrap();
$closure_ordered_float(OrderedFloat(v))
Expand Down Expand Up @@ -128,6 +141,9 @@ impl Hash for NnSqlValue {
|i: i64| {
i.hash(state);
},
|u: u64| {
u.hash(state);
},
|f: OrderedFloat<f32>| {
f.hash(state);
},
Expand All @@ -149,6 +165,7 @@ impl Display for NnSqlValue {
let s: String = for_all_loose_types!(
self,
|i: i64| i.to_string(),
|u: u64| u.to_string(),
|f: OrderedFloat<f32>| f.to_string(),
|s: String| format!(r#""{}""#, s),
|v: Vec<u8>| format!("{:?}", v),
Expand Down Expand Up @@ -178,6 +195,8 @@ impl NnSqlValue {
NnSqlValue::SmallInt(i16_) => T::try_from_i16(i16_),
NnSqlValue::Integer(i32_) => T::try_from_i32(i32_),
NnSqlValue::BigInt(i64_) => T::try_from_i64(i64_),
NnSqlValue::UnsignedInteger(u32_) => T::try_from_u32(u32_),
NnSqlValue::UnsignedBigInt(u64_) => T::try_from_u64(u64_),
NnSqlValue::Float(f32_) => T::try_from_f32(f32_),
NnSqlValue::Text(string) => T::try_from_string(string),
NnSqlValue::Blob(blob) => T::try_from_blob(blob),
Expand All @@ -193,6 +212,8 @@ impl NnSqlValue {
NnSqlValue::SmallInt(_) => SqlType::small_int(),
NnSqlValue::Integer(_) => SqlType::integer(),
NnSqlValue::BigInt(_) => SqlType::big_int(),
NnSqlValue::UnsignedInteger(_) => SqlType::unsigned_integer(),
NnSqlValue::UnsignedBigInt(_) => SqlType::unsigned_big_int(),
NnSqlValue::Float(_) => SqlType::float(),
NnSqlValue::Text(_) => SqlType::text(),
NnSqlValue::Blob(_) => SqlType::blob(),
Expand Down Expand Up @@ -220,6 +241,14 @@ impl NnSqlValue {
I64LooseType::Integer => self.unpack::<i32>().map(|v| v.into_sql_value()),
I64LooseType::BigInt => self.unpack::<i64>().map(|v| v.into_sql_value()),
},
NumericComparableType::U64Loose(u) => match u {
U64LooseType::UnsignedInteger => {
self.unpack::<u32>().map(|v| v.into_sql_value())
}
U64LooseType::UnsignedBigInt => {
self.unpack::<u64>().map(|v| v.into_sql_value())
}
},
NumericComparableType::F32Loose(f) => match f {
F32LooseType::Float => self.unpack::<f32>().map(|v| v.into_sql_value()),
},
Expand Down Expand Up @@ -248,6 +277,10 @@ impl NnSqlValue {
let (self_i64, other_i64) = (self.unpack::<i64>()?, other.unpack::<i64>()?);
Ok(SqlCompareResult::from(self_i64.cmp(&other_i64)))
}
(NumericComparableType::U64Loose(_), NumericComparableType::U64Loose(_)) => {
let (self_u64, other_u64) = (self.unpack::<u64>()?, other.unpack::<u64>()?);
Ok(SqlCompareResult::from(self_u64.cmp(&other_u64)))
}
(NumericComparableType::F32Loose(_), NumericComparableType::F32Loose(_)) => {
let (self_f32, other_f32) = (self.unpack::<f32>()?, other.unpack::<f32>()?);
Ok(SqlCompareResult::from(self_f32.partial_cmp(&other_f32)))
Expand Down Expand Up @@ -297,7 +330,10 @@ impl NnSqlValue {
NnSqlValue::Integer(v) => Ok(Self::Integer(-v)),
NnSqlValue::BigInt(v) => Ok(Self::BigInt(-v)),
NnSqlValue::Float(v) => Ok(Self::Float(-v)),
NnSqlValue::Text(_)

NnSqlValue::UnsignedInteger(_)
| NnSqlValue::UnsignedBigInt(_)
| NnSqlValue::Text(_)
| NnSqlValue::Blob(_)
| NnSqlValue::Boolean(_)
| NnSqlValue::Timestamp(_)
Expand All @@ -312,6 +348,8 @@ impl From<NnSqlValue> for serde_json::Value {
NnSqlValue::SmallInt(i) => serde_json::Value::from(i),
NnSqlValue::Integer(i) => serde_json::Value::from(i),
NnSqlValue::BigInt(i) => serde_json::Value::from(i),
NnSqlValue::UnsignedInteger(u) => serde_json::Value::from(u),
NnSqlValue::UnsignedBigInt(u) => serde_json::Value::from(u),
NnSqlValue::Float(f) => serde_json::Value::from(f.into_inner()),
NnSqlValue::Text(s) => serde_json::Value::from(s),
NnSqlValue::Boolean(b) => serde_json::Value::from(b),
Expand All @@ -335,6 +373,10 @@ impl Add for NnSqlValue {
let (self_i64, rhs_i64) = (self.unpack::<i64>()?, rhs.unpack::<i64>()?);
Ok(Self::BigInt(self_i64 + rhs_i64))
}
(NumericComparableType::U64Loose(_), NumericComparableType::U64Loose(_)) => {
let (self_u64, rhs_u64) = (self.unpack::<u64>()?, rhs.unpack::<u64>()?);
Ok(Self::UnsignedBigInt(self_u64 + rhs_u64))
}
(NumericComparableType::F32Loose(_), NumericComparableType::F32Loose(_)) => {
let (self_f32, rhs_f32) = (self.unpack::<f32>()?, rhs.unpack::<f32>()?);
Ok(Self::Float(OrderedFloat(self_f32 + rhs_f32)))
Expand Down Expand Up @@ -365,6 +407,10 @@ impl Mul for NnSqlValue {
let (self_i64, rhs_i64) = (self.unpack::<i64>()?, rhs.unpack::<i64>()?);
Ok(Self::BigInt(self_i64 * rhs_i64))
}
(NumericComparableType::U64Loose(_), NumericComparableType::U64Loose(_)) => {
let (self_u64, rhs_u64) = (self.unpack::<u64>()?, rhs.unpack::<u64>()?);
Ok(Self::UnsignedBigInt(self_u64 * rhs_u64))
}
(NumericComparableType::F32Loose(_), NumericComparableType::F32Loose(_)) => {
let (self_f32, rhs_f32) = (self.unpack::<f32>()?, rhs.unpack::<f32>()?);
Ok(Self::Float(OrderedFloat(self_f32 * rhs_f32)))
Expand Down Expand Up @@ -403,6 +449,20 @@ mod tests {
assert_eq!(NnSqlValue::BigInt(-1).unpack::<i32>()?, -1);
assert_eq!(NnSqlValue::BigInt(-1).unpack::<i64>()?, -1);

assert_eq!(
NnSqlValue::UnsignedInteger(u16::MAX as u32).unpack::<u32>()?,
u16::MAX as u32
);
assert_eq!(
NnSqlValue::UnsignedInteger(u16::MAX as u32).unpack::<u64>()?,
u16::MAX as u64
);

assert_eq!(
NnSqlValue::UnsignedBigInt(u16::MAX as u64).unpack::<u64>()?,
u16::MAX as u64
);

assert_eq!(
NnSqlValue::Text("🚔".to_string()).unpack::<String>()?,
"🚔".to_string()
Expand Down

0 comments on commit f4245cb

Please sign in to comment.