Skip to content

Commit

Permalink
change the api of , add example of the usage
Browse files Browse the repository at this point in the history
  • Loading branch information
liukun4515 committed Aug 8, 2022
1 parent 5fae299 commit 39a19e1
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 9 deletions.
15 changes: 9 additions & 6 deletions arrow/src/array/array_decimal.rs
Expand Up @@ -57,7 +57,7 @@ use crate::util::decimal::{BasicDecimal, Decimal128, Decimal256};
/// // set precision and scale so values are interpreted
/// // as `8887.000000`, `Null`, and `-8887.000000`
/// let decimal_array = decimal_array
/// .with_precision_and_scale(23, 6)
/// .with_precision_and_scale(23, 6, true)
/// .unwrap();
///
/// assert_eq!(&DataType::Decimal128(23, 6), decimal_array.data_type());
Expand Down Expand Up @@ -253,11 +253,15 @@ pub trait BasicDecimalArray<T: BasicDecimal, U: From<ArrayData>>:
/// Returns a Decimal array with the same data as self, with the
/// specified precision.
///
/// If make sure that all values in this array are not out of ranges/bounds with the specified precision,
/// please set `need_validation` to `false, otherwise set to `true`.
///
/// Returns an Error if:
/// 1. `precision` is larger than [`Self::MAX_PRECISION`]
/// 2. `scale` is larger than [`Self::MAX_SCALE`];
/// 3. `scale` is > `precision`
fn with_precision_and_scale(self, precision: usize, scale: usize) -> Result<U>
/// 4. `need_validation` is `true`, but some values are out of ranges/bounds
fn with_precision_and_scale(self, precision: usize, scale: usize, need_validation: bool) -> Result<U>
where
Self: Sized,
{
Expand All @@ -282,10 +286,9 @@ pub trait BasicDecimalArray<T: BasicDecimal, U: From<ArrayData>>:
)));
}

// Ensure that all values are within the requested
// precision. For performance, only check if the precision is
// decreased
self.validate_decimal_precision(precision)?;
if need_validation {
self.validate_decimal_precision(precision)?;
}

let data_type = if Self::VALUE_LENGTH == 16 {
DataType::Decimal128(self.precision(), self.scale())
Expand Down
4 changes: 3 additions & 1 deletion parquet/src/arrow/array_reader/primitive_array.rs
Expand Up @@ -184,6 +184,8 @@ where
let a = arrow::compute::cast(&array, &ArrowType::Date32)?;
arrow::compute::cast(&a, &target_type)?
}
// In the parquet file, if the logical/converted type is decimal and the physical type
// is INT32 or INT64, don't need to do validation.
ArrowType::Decimal128(p, s) => {
let array = match array.data_type() {
ArrowType::Int32 => array
Expand All @@ -208,7 +210,7 @@ where
))
}
}
.with_precision_and_scale(p, s)?;
.with_precision_and_scale(p, s, false)?;

Arc::new(array) as ArrayRef
}
Expand Down
6 changes: 4 additions & 2 deletions parquet/src/arrow/buffer/converter.rs
Expand Up @@ -82,23 +82,25 @@ impl Converter<Vec<Option<FixedLenByteArray>>, Decimal128Array>
for DecimalArrayConverter
{
fn convert(&self, source: Vec<Option<FixedLenByteArray>>) -> Result<Decimal128Array> {
// In the parquet file, if the logical/converted type is decimal, don't need to do validation.
let array = source
.into_iter()
.map(|array| array.map(|array| from_bytes_to_i128(array.data())))
.collect::<Decimal128Array>()
.with_precision_and_scale(self.precision as usize, self.scale as usize)?;
.with_precision_and_scale(self.precision as usize, self.scale as usize, false)?;

Ok(array)
}
}

impl Converter<Vec<Option<ByteArray>>, Decimal128Array> for DecimalArrayConverter {
fn convert(&self, source: Vec<Option<ByteArray>>) -> Result<Decimal128Array> {
// In the parquet file, if the logical/converted type is decimal, don't need to do validation.
let array = source
.into_iter()
.map(|array| array.map(|array| from_bytes_to_i128(array.data())))
.collect::<Decimal128Array>()
.with_precision_and_scale(self.precision as usize, self.scale as usize)?;
.with_precision_and_scale(self.precision as usize, self.scale as usize, false)?;

Ok(array)
}
Expand Down

0 comments on commit 39a19e1

Please sign in to comment.