Adds back float to decimal casts

pull/22/head
Tpt 5 years ago
parent 87f2823688
commit 4a2daeb739
  1. 42
      lib/src/model/xsd/decimal.rs
  2. 32
      lib/src/sparql/eval.rs

@ -19,6 +19,7 @@ pub struct Decimal {
} }
impl Decimal { impl Decimal {
#[inline]
pub fn from_le_bytes(bytes: [u8; 16]) -> Self { pub fn from_le_bytes(bytes: [u8; 16]) -> Self {
Self { Self {
value: i128::from_le_bytes(bytes), value: i128::from_le_bytes(bytes),
@ -27,6 +28,7 @@ impl Decimal {
} }
impl<I: Into<i64>> From<I> for Decimal { impl<I: Into<i64>> From<I> for Decimal {
#[inline]
fn from(value: I) -> Self { fn from(value: I) -> Self {
let value: i64 = value.into(); let value: i64 = value.into();
Self { Self {
@ -194,6 +196,7 @@ impl fmt::Display for Decimal {
impl Neg for Decimal { impl Neg for Decimal {
type Output = Self; type Output = Self;
#[inline]
fn neg(self) -> Self { fn neg(self) -> Self {
Self { Self {
value: self.value.neg(), value: self.value.neg(),
@ -206,11 +209,13 @@ impl Decimal {
(self.value / DECIMAL_PART_POW) as i64 (self.value / DECIMAL_PART_POW) as i64
}*/ }*/
#[inline]
pub fn to_le_bytes(&self) -> [u8; 16] { pub fn to_le_bytes(&self) -> [u8; 16] {
self.value.to_le_bytes() self.value.to_le_bytes()
} }
/// [op:numeric-add](https://www.w3.org/TR/xpath-functions/#func-numeric-add) /// [op:numeric-add](https://www.w3.org/TR/xpath-functions/#func-numeric-add)
#[inline]
pub fn checked_add(&self, rhs: Self) -> Option<Self> { pub fn checked_add(&self, rhs: Self) -> Option<Self> {
Some(Self { Some(Self {
value: self.value.checked_add(rhs.value)?, value: self.value.checked_add(rhs.value)?,
@ -218,6 +223,7 @@ impl Decimal {
} }
/// [op:numeric-subtract](https://www.w3.org/TR/xpath-functions/#func-numeric-subtract) /// [op:numeric-subtract](https://www.w3.org/TR/xpath-functions/#func-numeric-subtract)
#[inline]
pub fn checked_sub(&self, rhs: Self) -> Option<Self> { pub fn checked_sub(&self, rhs: Self) -> Option<Self> {
Some(Self { Some(Self {
value: self.value.checked_sub(rhs.value)?, value: self.value.checked_sub(rhs.value)?,
@ -225,6 +231,7 @@ impl Decimal {
} }
/// [op:numeric-multiply](https://www.w3.org/TR/xpath-functions/#func-numeric-multiply) /// [op:numeric-multiply](https://www.w3.org/TR/xpath-functions/#func-numeric-multiply)
#[inline]
pub fn checked_mul(&self, rhs: Self) -> Option<Self> { pub fn checked_mul(&self, rhs: Self) -> Option<Self> {
//TODO: better algorithm to keep precision //TODO: better algorithm to keep precision
Some(Self { Some(Self {
@ -236,6 +243,7 @@ impl Decimal {
} }
/// [op:numeric-divide](https://www.w3.org/TR/xpath-functions/#func-numeric-divide) /// [op:numeric-divide](https://www.w3.org/TR/xpath-functions/#func-numeric-divide)
#[inline]
pub fn checked_div(&self, rhs: Self) -> Option<Self> { pub fn checked_div(&self, rhs: Self) -> Option<Self> {
//TODO: better algorithm to keep precision //TODO: better algorithm to keep precision
Some(Self { Some(Self {
@ -248,6 +256,7 @@ impl Decimal {
} }
/// [fn:abs](https://www.w3.org/TR/xpath-functions/#func-abs) /// [fn:abs](https://www.w3.org/TR/xpath-functions/#func-abs)
#[inline]
pub fn abs(&self) -> Decimal { pub fn abs(&self) -> Decimal {
Self { Self {
value: self.value.abs(), value: self.value.abs(),
@ -255,6 +264,7 @@ impl Decimal {
} }
/// [fn:round](https://www.w3.org/TR/xpath-functions/#func-round) /// [fn:round](https://www.w3.org/TR/xpath-functions/#func-round)
#[inline]
pub fn round(&self) -> Decimal { pub fn round(&self) -> Decimal {
let value = self.value / DECIMAL_PART_POW_MINUS_ONE; let value = self.value / DECIMAL_PART_POW_MINUS_ONE;
Self { Self {
@ -267,6 +277,7 @@ impl Decimal {
} }
/// [fn:ceiling](https://www.w3.org/TR/xpath-functions/#func-ceiling) /// [fn:ceiling](https://www.w3.org/TR/xpath-functions/#func-ceiling)
#[inline]
pub fn ceil(&self) -> Decimal { pub fn ceil(&self) -> Decimal {
Self { Self {
value: if self.value >= 0 && self.value % DECIMAL_PART_POW != 0 { value: if self.value >= 0 && self.value % DECIMAL_PART_POW != 0 {
@ -278,6 +289,7 @@ impl Decimal {
} }
/// [fn:floor](https://www.w3.org/TR/xpath-functions/#func-floor) /// [fn:floor](https://www.w3.org/TR/xpath-functions/#func-floor)
#[inline]
pub fn floor(&self) -> Decimal { pub fn floor(&self) -> Decimal {
Self { Self {
value: if self.value >= 0 || self.value % DECIMAL_PART_POW == 0 { value: if self.value >= 0 || self.value % DECIMAL_PART_POW == 0 {
@ -288,14 +300,32 @@ impl Decimal {
} }
} }
pub fn to_f32(&self) -> Option<f32> { /// Creates a `Decimal` from a `f32` without taking care of precision
//TODO: precision? #[inline]
Some((self.value as f32) / (DECIMAL_PART_POW as f32)) pub fn from_f32(v: f32) -> Self {
Self {
value: (v * (DECIMAL_PART_POW as f32)) as i128,
}
}
/// Creates a `f32` from a `Decimal` without taking care of precision
#[inline]
pub fn to_f32(&self) -> f32 {
(self.value as f32) / (DECIMAL_PART_POW as f32)
}
/// Creates a `Decimal` from a `f64` without taking care of precision
#[inline]
pub fn from_f64(v: f64) -> Self {
Self {
value: (v * (DECIMAL_PART_POW as f64)) as i128,
}
} }
pub fn to_f64(&self) -> Option<f64> { /// Creates a `f64` from a `Decimal` without taking care of precision
//TODO: precision? #[inline]
Some((self.value as f64) / (DECIMAL_PART_POW as f64)) pub fn to_f64(&self) -> f64 {
(self.value as f64) / (DECIMAL_PART_POW as f64)
} }
} }

@ -1328,7 +1328,7 @@ impl<'a, S: StoreConnection + 'a> SimpleEvaluator<S> {
EncodedTerm::FloatLiteral(value) => Some(value.to_f64()?.into()), EncodedTerm::FloatLiteral(value) => Some(value.to_f64()?.into()),
EncodedTerm::DoubleLiteral(value) => Some(value.to_f64()?.into()), EncodedTerm::DoubleLiteral(value) => Some(value.to_f64()?.into()),
EncodedTerm::IntegerLiteral(value) => Some(value.to_f64()?.into()), EncodedTerm::IntegerLiteral(value) => Some(value.to_f64()?.into()),
EncodedTerm::DecimalLiteral(value) => Some(value.to_f64()?.into()), EncodedTerm::DecimalLiteral(value) => Some(value.to_f64().into()),
EncodedTerm::BooleanLiteral(value) => { EncodedTerm::BooleanLiteral(value) => {
Some(if value { 1. as f64 } else { 0. }.into()) Some(if value { 1. as f64 } else { 0. }.into())
} }
@ -1341,7 +1341,7 @@ impl<'a, S: StoreConnection + 'a> SimpleEvaluator<S> {
EncodedTerm::FloatLiteral(value) => Some(value.to_f32()?.into()), EncodedTerm::FloatLiteral(value) => Some(value.to_f32()?.into()),
EncodedTerm::DoubleLiteral(value) => Some(value.to_f32()?.into()), EncodedTerm::DoubleLiteral(value) => Some(value.to_f32()?.into()),
EncodedTerm::IntegerLiteral(value) => Some(value.to_f32()?.into()), EncodedTerm::IntegerLiteral(value) => Some(value.to_f32()?.into()),
EncodedTerm::DecimalLiteral(value) => Some(value.to_f32()?.into()), EncodedTerm::DecimalLiteral(value) => Some(value.to_f32().into()),
EncodedTerm::BooleanLiteral(value) => { EncodedTerm::BooleanLiteral(value) => {
Some(if value { 1. as f32 } else { 0. }.into()) Some(if value { 1. as f32 } else { 0. }.into())
} }
@ -1362,8 +1362,8 @@ impl<'a, S: StoreConnection + 'a> SimpleEvaluator<S> {
_ => None, _ => None,
}, },
PlanExpression::DecimalCast(e) => match self.eval_expression(e, tuple)? { PlanExpression::DecimalCast(e) => match self.eval_expression(e, tuple)? {
//TODO: code EncodedTerm::FloatLiteral(value) => Some(Decimal::from_f32(*value)?.into()), EncodedTerm::FloatLiteral(value) => Some(Decimal::from_f32(*value).into()),
//TODO: code EncodedTerm::DoubleLiteral(value) => Some(Decimal::from_f64(*value)?.into()), EncodedTerm::DoubleLiteral(value) => Some(Decimal::from_f64(*value).into()),
EncodedTerm::IntegerLiteral(value) => Some(Decimal::from(value).into()), EncodedTerm::IntegerLiteral(value) => Some(Decimal::from(value).into()),
EncodedTerm::DecimalLiteral(value) => Some(value.into()), EncodedTerm::DecimalLiteral(value) => Some(value.into()),
EncodedTerm::BooleanLiteral(value) => { EncodedTerm::BooleanLiteral(value) => {
@ -1653,7 +1653,7 @@ impl<'a, S: StoreConnection + 'a> SimpleEvaluator<S> {
EncodedTerm::FloatLiteral(b) => Some(a == b), EncodedTerm::FloatLiteral(b) => Some(a == b),
EncodedTerm::DoubleLiteral(b) => Some(a.to_f64()? == *b), EncodedTerm::DoubleLiteral(b) => Some(a.to_f64()? == *b),
EncodedTerm::IntegerLiteral(b) => Some(*a == b.to_f32()?), EncodedTerm::IntegerLiteral(b) => Some(*a == b.to_f32()?),
EncodedTerm::DecimalLiteral(b) => Some(*a == b.to_f32()?), EncodedTerm::DecimalLiteral(b) => Some(*a == b.to_f32()),
EncodedTerm::TypedLiteral { .. } => None, EncodedTerm::TypedLiteral { .. } => None,
_ => Some(false), _ => Some(false),
}, },
@ -1661,7 +1661,7 @@ impl<'a, S: StoreConnection + 'a> SimpleEvaluator<S> {
EncodedTerm::FloatLiteral(b) => Some(*a == b.to_f64()?), EncodedTerm::FloatLiteral(b) => Some(*a == b.to_f64()?),
EncodedTerm::DoubleLiteral(b) => Some(a == b), EncodedTerm::DoubleLiteral(b) => Some(a == b),
EncodedTerm::IntegerLiteral(b) => Some(*a == b.to_f64()?), EncodedTerm::IntegerLiteral(b) => Some(*a == b.to_f64()?),
EncodedTerm::DecimalLiteral(b) => Some(*a == b.to_f64()?), EncodedTerm::DecimalLiteral(b) => Some(*a == b.to_f64()),
EncodedTerm::TypedLiteral { .. } => None, EncodedTerm::TypedLiteral { .. } => None,
_ => Some(false), _ => Some(false),
}, },
@ -1674,8 +1674,8 @@ impl<'a, S: StoreConnection + 'a> SimpleEvaluator<S> {
_ => Some(false), _ => Some(false),
}, },
EncodedTerm::DecimalLiteral(a) => match b { EncodedTerm::DecimalLiteral(a) => match b {
EncodedTerm::FloatLiteral(b) => Some(a.to_f32()? == *b), EncodedTerm::FloatLiteral(b) => Some(a.to_f32() == *b),
EncodedTerm::DoubleLiteral(b) => Some(a.to_f64()? == *b), EncodedTerm::DoubleLiteral(b) => Some(a.to_f64() == *b),
EncodedTerm::IntegerLiteral(b) => Some(a == Decimal::from(b)), EncodedTerm::IntegerLiteral(b) => Some(a == Decimal::from(b)),
EncodedTerm::DecimalLiteral(b) => Some(a == b), EncodedTerm::DecimalLiteral(b) => Some(a == b),
EncodedTerm::TypedLiteral { .. } => None, EncodedTerm::TypedLiteral { .. } => None,
@ -1799,14 +1799,14 @@ impl<'a, S: StoreConnection + 'a> SimpleEvaluator<S> {
EncodedTerm::FloatLiteral(b) => (*a).partial_cmp(&*b), EncodedTerm::FloatLiteral(b) => (*a).partial_cmp(&*b),
EncodedTerm::DoubleLiteral(b) => a.to_f64()?.partial_cmp(&*b), EncodedTerm::DoubleLiteral(b) => a.to_f64()?.partial_cmp(&*b),
EncodedTerm::IntegerLiteral(b) => (*a).partial_cmp(&b.to_f32()?), EncodedTerm::IntegerLiteral(b) => (*a).partial_cmp(&b.to_f32()?),
EncodedTerm::DecimalLiteral(b) => (*a).partial_cmp(&b.to_f32()?), EncodedTerm::DecimalLiteral(b) => (*a).partial_cmp(&b.to_f32()),
_ => None, _ => None,
}, },
EncodedTerm::DoubleLiteral(a) => match b { EncodedTerm::DoubleLiteral(a) => match b {
EncodedTerm::FloatLiteral(b) => (*a).partial_cmp(&b.to_f64()?), EncodedTerm::FloatLiteral(b) => (*a).partial_cmp(&b.to_f64()?),
EncodedTerm::DoubleLiteral(b) => (*a).partial_cmp(&*b), EncodedTerm::DoubleLiteral(b) => (*a).partial_cmp(&*b),
EncodedTerm::IntegerLiteral(b) => (*a).partial_cmp(&b.to_f64()?), EncodedTerm::IntegerLiteral(b) => (*a).partial_cmp(&b.to_f64()?),
EncodedTerm::DecimalLiteral(b) => (*a).partial_cmp(&b.to_f64()?), EncodedTerm::DecimalLiteral(b) => (*a).partial_cmp(&b.to_f64()),
_ => None, _ => None,
}, },
EncodedTerm::IntegerLiteral(a) => match b { EncodedTerm::IntegerLiteral(a) => match b {
@ -1817,8 +1817,8 @@ impl<'a, S: StoreConnection + 'a> SimpleEvaluator<S> {
_ => None, _ => None,
}, },
EncodedTerm::DecimalLiteral(a) => match b { EncodedTerm::DecimalLiteral(a) => match b {
EncodedTerm::FloatLiteral(b) => a.to_f32()?.partial_cmp(&*b), EncodedTerm::FloatLiteral(b) => a.to_f32().partial_cmp(&*b),
EncodedTerm::DoubleLiteral(b) => a.to_f64()?.partial_cmp(&*b), EncodedTerm::DoubleLiteral(b) => a.to_f64().partial_cmp(&*b),
EncodedTerm::IntegerLiteral(b) => a.partial_cmp(&Decimal::from(b)), EncodedTerm::IntegerLiteral(b) => a.partial_cmp(&Decimal::from(b)),
EncodedTerm::DecimalLiteral(b) => a.partial_cmp(&b), EncodedTerm::DecimalLiteral(b) => a.partial_cmp(&b),
_ => None, _ => None,
@ -1894,7 +1894,7 @@ impl NumericBinaryOperands {
Some(NumericBinaryOperands::Float(*v1, v2.to_f32()?)) Some(NumericBinaryOperands::Float(*v1, v2.to_f32()?))
} }
(EncodedTerm::FloatLiteral(v1), EncodedTerm::DecimalLiteral(v2)) => { (EncodedTerm::FloatLiteral(v1), EncodedTerm::DecimalLiteral(v2)) => {
Some(NumericBinaryOperands::Float(*v1, v2.to_f32()?)) Some(NumericBinaryOperands::Float(*v1, v2.to_f32()))
} }
(EncodedTerm::DoubleLiteral(v1), EncodedTerm::FloatLiteral(v2)) => { (EncodedTerm::DoubleLiteral(v1), EncodedTerm::FloatLiteral(v2)) => {
Some(NumericBinaryOperands::Double(*v1, v2.to_f64()?)) Some(NumericBinaryOperands::Double(*v1, v2.to_f64()?))
@ -1906,7 +1906,7 @@ impl NumericBinaryOperands {
Some(NumericBinaryOperands::Double(*v1, v2.to_f64()?)) Some(NumericBinaryOperands::Double(*v1, v2.to_f64()?))
} }
(EncodedTerm::DoubleLiteral(v1), EncodedTerm::DecimalLiteral(v2)) => { (EncodedTerm::DoubleLiteral(v1), EncodedTerm::DecimalLiteral(v2)) => {
Some(NumericBinaryOperands::Double(*v1, v2.to_f64()?)) Some(NumericBinaryOperands::Double(*v1, v2.to_f64()))
} }
(EncodedTerm::IntegerLiteral(v1), EncodedTerm::FloatLiteral(v2)) => { (EncodedTerm::IntegerLiteral(v1), EncodedTerm::FloatLiteral(v2)) => {
Some(NumericBinaryOperands::Float(v1.to_f32()?, *v2)) Some(NumericBinaryOperands::Float(v1.to_f32()?, *v2))
@ -1921,10 +1921,10 @@ impl NumericBinaryOperands {
Some(NumericBinaryOperands::Decimal(Decimal::from(v1), v2)) Some(NumericBinaryOperands::Decimal(Decimal::from(v1), v2))
} }
(EncodedTerm::DecimalLiteral(v1), EncodedTerm::FloatLiteral(v2)) => { (EncodedTerm::DecimalLiteral(v1), EncodedTerm::FloatLiteral(v2)) => {
Some(NumericBinaryOperands::Float(v1.to_f32()?, *v2)) Some(NumericBinaryOperands::Float(v1.to_f32(), *v2))
} }
(EncodedTerm::DecimalLiteral(v1), EncodedTerm::DoubleLiteral(v2)) => { (EncodedTerm::DecimalLiteral(v1), EncodedTerm::DoubleLiteral(v2)) => {
Some(NumericBinaryOperands::Double(v1.to_f64()?, *v2)) Some(NumericBinaryOperands::Double(v1.to_f64(), *v2))
} }
(EncodedTerm::DecimalLiteral(v1), EncodedTerm::IntegerLiteral(v2)) => { (EncodedTerm::DecimalLiteral(v1), EncodedTerm::IntegerLiteral(v2)) => {
Some(NumericBinaryOperands::Decimal(v1, Decimal::from(v2))) Some(NumericBinaryOperands::Decimal(v1, Decimal::from(v2)))

Loading…
Cancel
Save