feat: impl Vector, DataType traits for decimal128 (#2727)

* feat: decimal128 vector

* feat: Decimal128Type in datatypes

* refactor: cast function

* feat: decimal128 type in ConcreteDataType

* chore: decimal

* chore: sql_data_type_to_concrete_data_type

* chore: cr comment

Co-authored-by: Dennis Zhuang <killme2008@gmail.com>
Co-authored-by: Yingwen <realevenyag@gmail.com>

* chore: fix finish()

* chore: add debug_assert to new decimal128

---------

Co-authored-by: Dennis Zhuang <killme2008@gmail.com>
Co-authored-by: Yingwen <realevenyag@gmail.com>
This commit is contained in:
Wei
2023-11-16 14:44:26 +08:00
committed by GitHub
parent 9bd10134dd
commit ae27fbc7f2
29 changed files with 961 additions and 82 deletions

View File

@@ -1,5 +1,5 @@
[package]
name = "decimal"
name = "common-decimal"
version.workspace = true
edition.workspace = true
license.workspace = true

View File

@@ -43,7 +43,7 @@ const BYTES_TO_OVERFLOW_RUST_DECIMAL: usize = 28;
/// **precision**: the total number of digits in the number, it's range is \[1, 38\].
///
/// **scale**: the number of digits to the right of the decimal point, it's range is \[0, precision\].
#[derive(Debug, Default, Eq, Copy, Clone, Serialize, Deserialize)]
#[derive(Debug, Eq, Copy, Clone, Serialize, Deserialize)]
pub struct Decimal128 {
value: i128,
precision: u8,
@@ -51,8 +51,18 @@ pub struct Decimal128 {
}
impl Decimal128 {
/// Create a new Decimal128 from i128, precision and scale.
pub fn new_unchecked(value: i128, precision: u8, scale: i8) -> Self {
/// Create a new Decimal128 from i128, precision and scale without any validation.
pub fn new(value: i128, precision: u8, scale: i8) -> Self {
// debug assert precision and scale is valid
debug_assert!(
precision > 0 && precision <= DECIMAL128_MAX_PRECISION,
"precision should be in [1, {}]",
DECIMAL128_MAX_PRECISION
);
debug_assert!(
scale >= 0 && scale <= precision as i8,
"scale should be in [0, precision]"
);
Self {
value,
precision,
@@ -60,6 +70,7 @@ impl Decimal128 {
}
}
/// Try new Decimal128 from i128, precision and scale with validation.
pub fn try_new(value: i128, precision: u8, scale: i8) -> error::Result<Self> {
// make sure the precision and scale is valid.
valid_precision_and_scale(precision, scale)?;
@@ -70,6 +81,7 @@ impl Decimal128 {
})
}
/// Return underlying value without precision and scale
pub fn val(&self) -> i128 {
self.value
}
@@ -90,6 +102,17 @@ impl Decimal128 {
}
}
/// The default value of Decimal128 is 0, and its precision is 1 and scale is 0.
impl Default for Decimal128 {
fn default() -> Self {
Self {
value: 0,
precision: 1,
scale: 0,
}
}
}
impl PartialEq for Decimal128 {
fn eq(&self, other: &Self) -> bool {
self.precision.eq(&other.precision)
@@ -270,7 +293,7 @@ mod tests {
#[test]
fn test_common_decimal128() {
let decimal = Decimal128::new_unchecked(123456789, 9, 3);
let decimal = Decimal128::new(123456789, 9, 3);
assert_eq!(decimal.to_string(), "123456.789");
let decimal = Decimal128::try_new(123456789, 9, 0);

View File

@@ -14,3 +14,5 @@
pub mod decimal128;
pub mod error;
pub use decimal128::Decimal128;

View File

@@ -71,7 +71,8 @@ macro_rules! convert_arrow_array_to_grpc_vals {
return Ok(vals);
},
)+
ConcreteDataType::Null(_) | ConcreteDataType::List(_) | ConcreteDataType::Dictionary(_) => unreachable!("Should not send {:?} in gRPC", $data_type),
// TODO(QuenKar): support gRPC for Decimal128
ConcreteDataType::Null(_) | ConcreteDataType::List(_) | ConcreteDataType::Dictionary(_) | ConcreteDataType::Decimal128(_) => unreachable!("Should not send {:?} in gRPC", $data_type),
}
}};
}