Skip to content

Commit

Permalink
Add INT(16) data type (gluesql#632)
Browse files Browse the repository at this point in the history
yujonglee authored Jul 12, 2022
1 parent 36e156e commit 24319b0
Showing 19 changed files with 1,780 additions and 12 deletions.
1 change: 1 addition & 0 deletions core/src/ast/data_type.rs
Original file line number Diff line number Diff line change
@@ -6,6 +6,7 @@ use strum_macros::Display;
pub enum DataType {
Boolean,
Int8,
Int16,
Int32,
Int,
Int128,
5 changes: 5 additions & 0 deletions core/src/data/bigdecimal_ext.rs
Original file line number Diff line number Diff line change
@@ -2,6 +2,7 @@ use bigdecimal::BigDecimal;

pub trait BigDecimalExt {
fn to_i8(&self) -> Option<i8>;
fn to_i16(&self) -> Option<i16>;
fn to_i32(&self) -> Option<i32>;
fn to_i64(&self) -> Option<i64>;
fn to_i128(&self) -> Option<i128>;
@@ -13,6 +14,10 @@ impl BigDecimalExt for BigDecimal {
self.is_integer()
.then(|| bigdecimal::ToPrimitive::to_i8(self))?
}
fn to_i16(&self) -> Option<i16> {
self.is_integer()
.then(|| bigdecimal::ToPrimitive::to_i16(self))?
}
fn to_i32(&self) -> Option<i32> {
self.is_integer()
.then(|| bigdecimal::ToPrimitive::to_i32(self))?
53 changes: 53 additions & 0 deletions core/src/data/interval/primitive.rs
Original file line number Diff line number Diff line change
@@ -14,6 +14,17 @@ impl Mul<i8> for Interval {
}
}

impl Mul<i16> for Interval {
type Output = Self;

fn mul(self, rhs: i16) -> Self {
match self {
Interval::Month(v) => Interval::Month(v * rhs as i32),
Interval::Microsecond(v) => Interval::Microsecond(v * rhs as i64),
}
}
}

impl Mul<i32> for Interval {
type Output = Self;

@@ -66,6 +77,14 @@ impl Mul<Interval> for i8 {
}
}

impl Mul<Interval> for i16 {
type Output = Interval;

fn mul(self, rhs: Interval) -> Interval {
rhs * self
}
}

impl Mul<Interval> for i32 {
type Output = Interval;

@@ -109,6 +128,17 @@ impl Div<i8> for Interval {
}
}

impl Div<i16> for Interval {
type Output = Self;

fn div(self, rhs: i16) -> Self {
match self {
Interval::Month(v) => Interval::Month(v / rhs as i32),
Interval::Microsecond(v) => Interval::Microsecond(v / rhs as i64),
}
}
}

impl Div<i32> for Interval {
type Output = Self;

@@ -164,6 +194,17 @@ impl Div<Interval> for i8 {
}
}

impl Div<Interval> for i16 {
type Output = Interval;

fn div(self, rhs: Interval) -> Interval {
match rhs {
Interval::Month(v) => Interval::Month(self as i32 / v),
Interval::Microsecond(v) => Interval::Microsecond(self as i64 / v),
}
}
}

impl Div<Interval> for i32 {
type Output = Interval;

@@ -219,6 +260,9 @@ mod tests {
assert_eq!(Month(2) * 3_i8, Month(6));
assert_eq!(2_i8 * Month(3), Month(6));

assert_eq!(Month(2) * 3_i16, Month(6));
assert_eq!(2_i16 * Month(3), Month(6));

assert_eq!(Month(2) * 3_i32, Month(6));
assert_eq!(2_i32 * Month(3), Month(6));

@@ -234,6 +278,9 @@ mod tests {
assert_eq!(Month(6) / 3_i8, Month(2));
assert_eq!(6_i8 / Month(2), Month(3));

assert_eq!(Month(6) / 3_i16, Month(2));
assert_eq!(6_i16 / Month(2), Month(3));

assert_eq!(Month(6) / 3_i32, Month(2));
assert_eq!(6_i32 / Month(2), Month(3));

@@ -249,6 +296,9 @@ mod tests {
assert_eq!(Microsecond(2) * 3_i8, Microsecond(6));
assert_eq!(2_i8 * Microsecond(3), Microsecond(6));

assert_eq!(Microsecond(2) * 3_i16, Microsecond(6));
assert_eq!(2_i16 * Microsecond(3), Microsecond(6));

assert_eq!(Microsecond(2) * 3_i32, Microsecond(6));
assert_eq!(2_i32 * Microsecond(3), Microsecond(6));

@@ -261,6 +311,9 @@ mod tests {
assert_eq!(Microsecond(6) / 3_i8, Microsecond(2));
assert_eq!(6_i8 / Microsecond(2), Microsecond(3));

assert_eq!(Microsecond(6) / 3_i16, Microsecond(2));
assert_eq!(6_i16 / Microsecond(2), Microsecond(3));

assert_eq!(Microsecond(6) / 3_i32, Microsecond(2));
assert_eq!(6_i32 / Microsecond(2), Microsecond(3));

28 changes: 28 additions & 0 deletions core/src/data/key.rs
Original file line number Diff line number Diff line change
@@ -25,6 +25,7 @@ pub enum KeyError {
#[derive(PartialEq, Eq, Hash, Clone, Debug, Serialize, Deserialize)]
pub enum Key {
I8(i8),
I16(i16),
I32(i32),
I64(i64),
I128(i128),
@@ -44,6 +45,7 @@ impl PartialOrd for Key {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
match (self, other) {
(Key::I8(l), Key::I8(r)) => Some(l.cmp(r)),
(Key::I16(l), Key::I16(r)) => Some(l.cmp(r)),
(Key::I32(l), Key::I32(r)) => Some(l.cmp(r)),
(Key::I64(l), Key::I64(r)) => Some(l.cmp(r)),
(Key::Bool(l), Key::Bool(r)) => Some(l.cmp(r)),
@@ -69,6 +71,7 @@ impl TryFrom<Value> for Key {
match value {
Bool(v) => Ok(Key::Bool(v)),
I8(v) => Ok(Key::I8(v)),
I16(v) => Ok(Key::I16(v)),
I32(v) => Ok(Key::I32(v)),
I64(v) => Ok(Key::I64(v)),
I128(v) => Ok(Key::I128(v)),
@@ -119,6 +122,15 @@ impl Key {
.copied()
.collect::<Vec<_>>()
}
Key::I16(v) => {
let sign = if *v >= 0 { 1 } else { 0 };

[VALUE, sign]
.iter()
.chain(v.to_be_bytes().iter())
.copied()
.collect::<Vec<_>>()
}
Key::I32(v) => {
let sign = if *v >= 0 { 1 } else { 0 };

@@ -232,6 +244,7 @@ mod tests {
// Some
assert_eq!(convert("True"), Ok(Key::Bool(true)));
assert_eq!(convert("CAST(11 AS INT(8))"), Ok(Key::I8(11)));
assert_eq!(convert("CAST(11 AS INT(16))"), Ok(Key::I16(11)));
assert_eq!(convert("CAST(11 AS INT(32))"), Ok(Key::I32(11)));
assert_eq!(convert("2048"), Ok(Key::I64(2048)));
assert_eq!(
@@ -318,6 +331,21 @@ mod tests {
assert_eq!(cmp(&n6, &n4), Ordering::Greater);
assert_eq!(cmp(&n4, &null), Ordering::Less);

let n1 = I16(-100).to_cmp_be_bytes();
let n2 = I16(-10).to_cmp_be_bytes();
let n3 = I16(0).to_cmp_be_bytes();
let n4 = I16(3).to_cmp_be_bytes();
let n5 = I16(20).to_cmp_be_bytes();
let n6 = I16(100).to_cmp_be_bytes();

assert_eq!(cmp(&n1, &n2), Ordering::Less);
assert_eq!(cmp(&n3, &n2), Ordering::Greater);
assert_eq!(cmp(&n1, &n6), Ordering::Less);
assert_eq!(cmp(&n5, &n5), Ordering::Equal);
assert_eq!(cmp(&n4, &n5), Ordering::Less);
assert_eq!(cmp(&n6, &n4), Ordering::Greater);
assert_eq!(cmp(&n4, &null), Ordering::Less);

let n1 = I32(-100).to_cmp_be_bytes();
let n2 = I32(-10).to_cmp_be_bytes();
let n3 = I32(0).to_cmp_be_bytes();
18 changes: 18 additions & 0 deletions core/src/data/value/binary_op/f64.rs
Original file line number Diff line number Diff line change
@@ -16,6 +16,7 @@ impl PartialEq<Value> for f64 {

match *other {
I8(rhs) => (lhs - (rhs as f64)).abs() < f64::EPSILON,
I16(rhs) => (lhs - (rhs as f64)).abs() < f64::EPSILON,
I32(rhs) => (lhs - (rhs as f64)).abs() < f64::EPSILON,
I64(rhs) => (lhs - (rhs as f64)).abs() < f64::EPSILON,
I128(rhs) => (lhs - (rhs as f64)).abs() < f64::EPSILON,
@@ -32,6 +33,7 @@ impl PartialOrd<Value> for f64 {
fn partial_cmp(&self, other: &Value) -> Option<Ordering> {
match *other {
I8(rhs) => self.partial_cmp(&(rhs as f64)),
I16(rhs) => self.partial_cmp(&(rhs as f64)),
I32(rhs) => self.partial_cmp(&(rhs as f64)),
I64(rhs) => self.partial_cmp(&(rhs as f64)),
I128(rhs) => self.partial_cmp(&(rhs as f64)),
@@ -52,6 +54,7 @@ impl TryBinaryOperator for f64 {

match *rhs {
I8(rhs) => Ok(F64(lhs + rhs as f64)),
I16(rhs) => Ok(F64(lhs + rhs as f64)),
I32(rhs) => Ok(F64(lhs + rhs as f64)),
I64(rhs) => Ok(F64(lhs + rhs as f64)),
I128(rhs) => Ok(F64(lhs + rhs as f64)),
@@ -74,6 +77,7 @@ impl TryBinaryOperator for f64 {

match *rhs {
I8(rhs) => Ok(F64(lhs - rhs as f64)),
I16(rhs) => Ok(F64(lhs - rhs as f64)),
I32(rhs) => Ok(F64(lhs - rhs as f64)),
I64(rhs) => Ok(F64(lhs - rhs as f64)),
I128(rhs) => Ok(F64(lhs - rhs as f64)),
@@ -96,6 +100,7 @@ impl TryBinaryOperator for f64 {

match *rhs {
I8(rhs) => Ok(F64(lhs * rhs as f64)),
I16(rhs) => Ok(F64(lhs * rhs as f64)),
I32(rhs) => Ok(F64(lhs * rhs as f64)),
I64(rhs) => Ok(F64(lhs * rhs as f64)),
I128(rhs) => Ok(F64(lhs * rhs as f64)),
@@ -119,6 +124,7 @@ impl TryBinaryOperator for f64 {

match *rhs {
I8(rhs) => Ok(F64(lhs / rhs as f64)),
I16(rhs) => Ok(F64(lhs / rhs as f64)),
I32(rhs) => Ok(F64(lhs / rhs as f64)),
I64(rhs) => Ok(F64(lhs / rhs as f64)),
I128(rhs) => Ok(F64(lhs / rhs as f64)),
@@ -141,6 +147,7 @@ impl TryBinaryOperator for f64 {

match *rhs {
I8(rhs) => Ok(F64(lhs % rhs as f64)),
I16(rhs) => Ok(F64(lhs % rhs as f64)),
I32(rhs) => Ok(F64(lhs % rhs as f64)),
I64(rhs) => Ok(F64(lhs % rhs as f64)),
I128(rhs) => Ok(F64(lhs % rhs as f64)),
@@ -184,6 +191,7 @@ mod tests {
let base = 1.0_f64;

assert_eq!(base, I8(1));
assert_eq!(base, I16(1));
assert_eq!(base, I32(1));
assert_eq!(base, I64(1));
assert_eq!(base, I128(1));
@@ -198,6 +206,7 @@ mod tests {
let base = 1.0_f64;

assert_eq!(base.partial_cmp(&I8(1)), Some(Ordering::Equal));
assert_eq!(base.partial_cmp(&I16(1)), Some(Ordering::Equal));
assert_eq!(base.partial_cmp(&I32(1)), Some(Ordering::Equal));
assert_eq!(base.partial_cmp(&I64(1)), Some(Ordering::Equal));
assert_eq!(base.partial_cmp(&I128(1)), Some(Ordering::Equal));
@@ -215,6 +224,7 @@ mod tests {
let base = 1.0_f64;

assert!(matches!(base.try_add(&I8(1)), Ok(F64(x)) if (x - 2.0).abs() < f64::EPSILON ));
assert!(matches!(base.try_add(&I16(1)), Ok(F64(x)) if (x - 2.0).abs() < f64::EPSILON ));
assert!(matches!(base.try_add(&I32(1)), Ok(F64(x)) if (x - 2.0).abs() < f64::EPSILON ));
assert!(matches!(base.try_add(&I64(1)), Ok(F64(x)) if (x - 2.0).abs() < f64::EPSILON ));
assert!(matches!(base.try_add(&I128(1)), Ok(F64(x)) if (x - 2.0).abs() < f64::EPSILON ));
@@ -239,6 +249,9 @@ mod tests {
let base = 1.0_f64;

assert!(matches!(base.try_subtract(&I8(1)), Ok(F64(x)) if (x - 0.0).abs() < f64::EPSILON ));
assert!(
matches!(base.try_subtract(&I16(1)), Ok(F64(x)) if (x - 0.0).abs() < f64::EPSILON )
);
assert!(
matches!(base.try_subtract(&I32(1)), Ok(F64(x)) if (x - 0.0).abs() < f64::EPSILON )
);
@@ -271,6 +284,9 @@ mod tests {
let base = 1.0_f64;

assert!(matches!(base.try_multiply(&I8(1)), Ok(F64(x)) if (x - 1.0).abs() < f64::EPSILON ));
assert!(
matches!(base.try_multiply(&I16(1)), Ok(F64(x)) if (x - 1.0).abs() < f64::EPSILON )
);
assert!(
matches!(base.try_multiply(&I32(1)), Ok(F64(x)) if (x - 1.0).abs() < f64::EPSILON )
);
@@ -303,6 +319,7 @@ mod tests {
let base = 1.0_f64;

assert!(matches!(base.try_divide(&I8(1)), Ok(F64(x)) if (x - 1.0).abs() < f64::EPSILON ));
assert!(matches!(base.try_divide(&I16(1)), Ok(F64(x)) if (x - 1.0).abs() < f64::EPSILON ));
assert!(matches!(base.try_divide(&I32(1)), Ok(F64(x)) if (x - 1.0).abs() < f64::EPSILON ));
assert!(matches!(base.try_divide(&I64(1)), Ok(F64(x)) if (x - 1.0).abs() < f64::EPSILON ));
assert!(matches!(base.try_divide(&I128(1)), Ok(F64(x)) if (x - 1.0).abs() < f64::EPSILON ));
@@ -329,6 +346,7 @@ mod tests {
let base = 1.0_f64;

assert!(matches!(base.try_modulo(&I8(1)), Ok(F64(x)) if (x - 0.0).abs() < f64::EPSILON ));
assert!(matches!(base.try_modulo(&I16(1)), Ok(F64(x)) if (x - 0.0).abs() < f64::EPSILON ));
assert!(matches!(base.try_modulo(&I32(1)), Ok(F64(x)) if (x - 0.0).abs() < f64::EPSILON ));
assert!(matches!(base.try_modulo(&I64(1)), Ok(F64(x)) if (x - 0.0).abs() < f64::EPSILON ));
assert!(matches!(base.try_modulo(&I128(1)), Ok(F64(x)) if (x - 0.0).abs() < f64::EPSILON ));
Loading
Oops, something went wrong.

0 comments on commit 24319b0

Please sign in to comment.