This is an automated email from the ASF dual-hosted git repository.
alamb pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/arrow-datafusion.git
The following commit(s) were added to refs/heads/master by this push:
new d082fa3 [Minor] Clean up DecimalArray API Usage (#1869)
d082fa3 is described below
commit d082fa3f66188ab2bbf913cde593026240c1fc0e
Author: Andrew Lamb <[email protected]>
AuthorDate: Sun Mar 6 07:11:41 2022 -0500
[Minor] Clean up DecimalArray API Usage (#1869)
* Clean up decimal array creation
* Refactor a bit more
* Update the next
!
* cleanup
* update
* port over min/max
* Update sum
* Use max scale / precision from arrow
* fmt
* Fixup
* clippy
---
datafusion-common/src/lib.rs | 4 +-
datafusion-common/src/scalar.rs | 45 ++------
.../src/coercion_rule/binary_rule.rs | 7 +-
.../src/expressions/average.rs | 47 ++++----
datafusion-physical-expr/src/expressions/cast.rs | 80 ++++++++-----
.../src/expressions/min_max.rs | 127 ++++++++++-----------
datafusion-physical-expr/src/expressions/sum.rs | 76 ++++++------
datafusion/src/physical_plan/hash_utils.rs | 16 +--
datafusion/src/scalar.rs | 4 +-
datafusion/src/sql/utils.rs | 6 +-
10 files changed, 198 insertions(+), 214 deletions(-)
diff --git a/datafusion-common/src/lib.rs b/datafusion-common/src/lib.rs
index fdcb7d4..d39020f 100644
--- a/datafusion-common/src/lib.rs
+++ b/datafusion-common/src/lib.rs
@@ -25,6 +25,4 @@ mod scalar;
pub use column::Column;
pub use dfschema::{DFField, DFSchema, DFSchemaRef, ExprSchema, ToDFSchema};
pub use error::{DataFusionError, Result};
-pub use scalar::{
- ScalarType, ScalarValue, MAX_PRECISION_FOR_DECIMAL128,
MAX_SCALE_FOR_DECIMAL128,
-};
+pub use scalar::{ScalarType, ScalarValue};
diff --git a/datafusion-common/src/scalar.rs b/datafusion-common/src/scalar.rs
index d7c6c6b..4a1dde1 100644
--- a/datafusion-common/src/scalar.rs
+++ b/datafusion-common/src/scalar.rs
@@ -26,6 +26,7 @@ use arrow::{
Float64Type, Int16Type, Int32Type, Int64Type, Int8Type, IntervalUnit,
TimeUnit,
TimestampMicrosecondType, TimestampMillisecondType,
TimestampNanosecondType,
TimestampSecondType, UInt16Type, UInt32Type, UInt64Type, UInt8Type,
+ DECIMAL_MAX_PRECISION,
},
};
use ordered_float::OrderedFloat;
@@ -34,11 +35,6 @@ use std::convert::{Infallible, TryInto};
use std::str::FromStr;
use std::{convert::TryFrom, fmt, iter::repeat, sync::Arc};
-// TODO may need to be moved to arrow-rs
-/// The max precision and scale for decimal128
-pub const MAX_PRECISION_FOR_DECIMAL128: usize = 38;
-pub const MAX_SCALE_FOR_DECIMAL128: usize = 38;
-
/// Represents a dynamically typed, nullable single value.
/// This is the single-valued counter-part of arrow’s `Array`.
#[derive(Clone)]
@@ -542,7 +538,7 @@ impl ScalarValue {
scale: usize,
) -> Result<Self> {
// make sure the precision and scale is valid
- if precision <= MAX_PRECISION_FOR_DECIMAL128 && scale <= precision {
+ if precision <= DECIMAL_MAX_PRECISION && scale <= precision {
return Ok(ScalarValue::Decimal128(Some(value), precision, scale));
}
return Err(DataFusionError::Internal(format!(
@@ -985,26 +981,15 @@ impl ScalarValue {
precision: &usize,
scale: &usize,
) -> Result<DecimalArray> {
- // collect the value as Option<i128>
let array = scalars
.into_iter()
.map(|element: ScalarValue| match element {
ScalarValue::Decimal128(v1, _, _) => v1,
_ => unreachable!(),
})
- .collect::<Vec<Option<i128>>>();
-
- // build the decimal array using the Decimal Builder
- let mut builder = DecimalBuilder::new(array.len(), *precision, *scale);
- array.iter().for_each(|element| match element {
- None => {
- builder.append_null().unwrap();
- }
- Some(v) => {
- builder.append_value(*v).unwrap();
- }
- });
- Ok(builder.finish())
+ .collect::<DecimalArray>()
+ .with_precision_and_scale(*precision, *scale)?;
+ Ok(array)
}
fn iter_to_array_list(
@@ -1080,21 +1065,11 @@ impl ScalarValue {
scale: &usize,
size: usize,
) -> DecimalArray {
- let mut builder = DecimalBuilder::new(size, *precision, *scale);
- match value {
- None => {
- for _i in 0..size {
- builder.append_null().unwrap();
- }
- }
- Some(v) => {
- let v = *v;
- for _i in 0..size {
- builder.append_value(v).unwrap();
- }
- }
- };
- builder.finish()
+ std::iter::repeat(value)
+ .take(size)
+ .collect::<DecimalArray>()
+ .with_precision_and_scale(*precision, *scale)
+ .unwrap()
}
/// Converts a scalar value into an array of `size` rows.
diff --git a/datafusion-physical-expr/src/coercion_rule/binary_rule.rs
b/datafusion-physical-expr/src/coercion_rule/binary_rule.rs
index 2207079..ac23f2b 100644
--- a/datafusion-physical-expr/src/coercion_rule/binary_rule.rs
+++ b/datafusion-physical-expr/src/coercion_rule/binary_rule.rs
@@ -17,10 +17,9 @@
//! Coercion rules for matching argument types for binary operators
-use arrow::datatypes::DataType;
+use arrow::datatypes::{DataType, DECIMAL_MAX_PRECISION, DECIMAL_MAX_SCALE};
use datafusion_common::DataFusionError;
use datafusion_common::Result;
-use datafusion_common::{MAX_PRECISION_FOR_DECIMAL128,
MAX_SCALE_FOR_DECIMAL128};
use datafusion_expr::Operator;
/// Coercion rules for all binary operators. Returns the output type
@@ -261,8 +260,8 @@ fn mathematics_numerical_coercion(
fn create_decimal_type(precision: usize, scale: usize) -> DataType {
DataType::Decimal(
- MAX_PRECISION_FOR_DECIMAL128.min(precision),
- MAX_SCALE_FOR_DECIMAL128.min(scale),
+ DECIMAL_MAX_PRECISION.min(precision),
+ DECIMAL_MAX_SCALE.min(scale),
)
}
diff --git a/datafusion-physical-expr/src/expressions/average.rs
b/datafusion-physical-expr/src/expressions/average.rs
index acdbf8b..8888ee9 100644
--- a/datafusion-physical-expr/src/expressions/average.rs
+++ b/datafusion-physical-expr/src/expressions/average.rs
@@ -23,15 +23,13 @@ use std::sync::Arc;
use crate::{AggregateExpr, PhysicalExpr};
use arrow::compute;
-use arrow::datatypes::DataType;
+use arrow::datatypes::{DataType, DECIMAL_MAX_PRECISION, DECIMAL_MAX_SCALE};
use arrow::{
array::{ArrayRef, UInt64Array},
datatypes::Field,
};
+use datafusion_common::ScalarValue;
use datafusion_common::{DataFusionError, Result};
-use datafusion_common::{
- ScalarValue, MAX_PRECISION_FOR_DECIMAL128, MAX_SCALE_FOR_DECIMAL128,
-};
use datafusion_expr::Accumulator;
use super::{format_state_name, sum};
@@ -50,8 +48,8 @@ pub fn avg_return_type(arg_type: &DataType) ->
Result<DataType> {
DataType::Decimal(precision, scale) => {
// in the spark, the result type is DECIMAL(min(38,precision+4),
min(38,scale+4)).
// ref:
https://github.com/apache/spark/blob/fcf636d9eb8d645c24be3db2d599aba2d7e2955a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/aggregate/Average.scala#L66
- let new_precision = MAX_PRECISION_FOR_DECIMAL128.min(*precision +
4);
- let new_scale = MAX_SCALE_FOR_DECIMAL128.min(*scale + 4);
+ let new_precision = DECIMAL_MAX_PRECISION.min(*precision + 4);
+ let new_scale = DECIMAL_MAX_SCALE.min(*scale + 4);
Ok(DataType::Decimal(new_precision, new_scale))
}
DataType::Int8
@@ -237,11 +235,12 @@ mod tests {
#[test]
fn avg_decimal() -> Result<()> {
// test agg
- let mut decimal_builder = DecimalBuilder::new(6, 10, 0);
- for i in 1..7 {
- decimal_builder.append_value(i as i128)?;
- }
- let array: ArrayRef = Arc::new(decimal_builder.finish());
+ let array: ArrayRef = Arc::new(
+ (1..7)
+ .map(Some)
+ .collect::<DecimalArray>()
+ .with_precision_and_scale(10, 0)?,
+ );
generic_test_op!(
array,
@@ -254,15 +253,12 @@ mod tests {
#[test]
fn avg_decimal_with_nulls() -> Result<()> {
- let mut decimal_builder = DecimalBuilder::new(5, 10, 0);
- for i in 1..6 {
- if i == 2 {
- decimal_builder.append_null()?;
- } else {
- decimal_builder.append_value(i)?;
- }
- }
- let array: ArrayRef = Arc::new(decimal_builder.finish());
+ let array: ArrayRef = Arc::new(
+ (1..6)
+ .map(|i| if i == 2 { None } else { Some(i) })
+ .collect::<DecimalArray>()
+ .with_precision_and_scale(10, 0)?,
+ );
generic_test_op!(
array,
DataType::Decimal(10, 0),
@@ -275,11 +271,12 @@ mod tests {
#[test]
fn avg_decimal_all_nulls() -> Result<()> {
// test agg
- let mut decimal_builder = DecimalBuilder::new(5, 10, 0);
- for _i in 1..6 {
- decimal_builder.append_null()?;
- }
- let array: ArrayRef = Arc::new(decimal_builder.finish());
+ let array: ArrayRef = Arc::new(
+ std::iter::repeat(None)
+ .take(6)
+ .collect::<DecimalArray>()
+ .with_precision_and_scale(10, 0)?,
+ );
generic_test_op!(
array,
DataType::Decimal(10, 0),
diff --git a/datafusion-physical-expr/src/expressions/cast.rs
b/datafusion-physical-expr/src/expressions/cast.rs
index 1b157e3..2870c9b 100644
--- a/datafusion-physical-expr/src/expressions/cast.rs
+++ b/datafusion-physical-expr/src/expressions/cast.rs
@@ -161,8 +161,8 @@ mod tests {
use crate::expressions::col;
use arrow::{
array::{
- Array, DecimalArray, DecimalBuilder, Float32Array, Float64Array,
Int16Array,
- Int32Array, Int64Array, Int8Array, StringArray,
Time64NanosecondArray,
+ Array, DecimalArray, Float32Array, Float64Array, Int16Array,
Int32Array,
+ Int64Array, Int8Array, StringArray, Time64NanosecondArray,
TimestampNanosecondArray, UInt32Array,
},
datatypes::*,
@@ -268,23 +268,16 @@ mod tests {
}};
}
- fn create_decimal_array(
- array: &[i128],
- precision: usize,
- scale: usize,
- ) -> Result<DecimalArray> {
- let mut decimal_builder = DecimalBuilder::new(array.len(), precision,
scale);
- for value in array {
- decimal_builder.append_value(*value)?
- }
- decimal_builder.append_null()?;
- Ok(decimal_builder.finish())
- }
-
#[test]
fn test_cast_decimal_to_decimal() -> Result<()> {
- let array: Vec<i128> = vec![1234, 2222, 3, 4000, 5000];
- let decimal_array = create_decimal_array(&array, 10, 3)?;
+ let array = vec![1234, 2222, 3, 4000, 5000];
+
+ let decimal_array = array
+ .iter()
+ .map(|v| Some(*v))
+ .collect::<DecimalArray>()
+ .with_precision_and_scale(10, 3)?;
+
generic_decimal_to_other_test_cast!(
decimal_array,
DataType::Decimal(10, 3),
@@ -301,7 +294,12 @@ mod tests {
DEFAULT_DATAFUSION_CAST_OPTIONS
);
- let decimal_array = create_decimal_array(&array, 10, 3)?;
+ let decimal_array = array
+ .iter()
+ .map(|v| Some(*v))
+ .collect::<DecimalArray>()
+ .with_precision_and_scale(10, 3)?;
+
generic_decimal_to_other_test_cast!(
decimal_array,
DataType::Decimal(10, 3),
@@ -323,9 +321,12 @@ mod tests {
#[test]
fn test_cast_decimal_to_numeric() -> Result<()> {
- let array: Vec<i128> = vec![1, 2, 3, 4, 5];
+ let array = vec![Some(1), Some(2), Some(3), Some(4), Some(5), None];
// decimal to i8
- let decimal_array = create_decimal_array(&array, 10, 0)?;
+ let decimal_array = array
+ .iter()
+ .collect::<DecimalArray>()
+ .with_precision_and_scale(10, 0)?;
generic_decimal_to_other_test_cast!(
decimal_array,
DataType::Decimal(10, 0),
@@ -341,8 +342,12 @@ mod tests {
],
DEFAULT_DATAFUSION_CAST_OPTIONS
);
+
// decimal to i16
- let decimal_array = create_decimal_array(&array, 10, 0)?;
+ let decimal_array = array
+ .iter()
+ .collect::<DecimalArray>()
+ .with_precision_and_scale(10, 0)?;
generic_decimal_to_other_test_cast!(
decimal_array,
DataType::Decimal(10, 0),
@@ -358,8 +363,12 @@ mod tests {
],
DEFAULT_DATAFUSION_CAST_OPTIONS
);
+
// decimal to i32
- let decimal_array = create_decimal_array(&array, 10, 0)?;
+ let decimal_array = array
+ .iter()
+ .collect::<DecimalArray>()
+ .with_precision_and_scale(10, 0)?;
generic_decimal_to_other_test_cast!(
decimal_array,
DataType::Decimal(10, 0),
@@ -375,8 +384,12 @@ mod tests {
],
DEFAULT_DATAFUSION_CAST_OPTIONS
);
+
// decimal to i64
- let decimal_array = create_decimal_array(&array, 10, 0)?;
+ let decimal_array = array
+ .iter()
+ .collect::<DecimalArray>()
+ .with_precision_and_scale(10, 0)?;
generic_decimal_to_other_test_cast!(
decimal_array,
DataType::Decimal(10, 0),
@@ -392,9 +405,20 @@ mod tests {
],
DEFAULT_DATAFUSION_CAST_OPTIONS
);
+
// decimal to float32
- let array: Vec<i128> = vec![1234, 2222, 3, 4000, 5000];
- let decimal_array = create_decimal_array(&array, 10, 3)?;
+ let array = vec![
+ Some(1234),
+ Some(2222),
+ Some(3),
+ Some(4000),
+ Some(5000),
+ None,
+ ];
+ let decimal_array = array
+ .iter()
+ .collect::<DecimalArray>()
+ .with_precision_and_scale(10, 3)?;
generic_decimal_to_other_test_cast!(
decimal_array,
DataType::Decimal(10, 3),
@@ -410,8 +434,12 @@ mod tests {
],
DEFAULT_DATAFUSION_CAST_OPTIONS
);
+
// decimal to float64
- let decimal_array = create_decimal_array(&array, 20, 6)?;
+ let decimal_array = array
+ .into_iter()
+ .collect::<DecimalArray>()
+ .with_precision_and_scale(20, 6)?;
generic_decimal_to_other_test_cast!(
decimal_array,
DataType::Decimal(20, 6),
diff --git a/datafusion-physical-expr/src/expressions/min_max.rs
b/datafusion-physical-expr/src/expressions/min_max.rs
index be3ea95..a599d65 100644
--- a/datafusion-physical-expr/src/expressions/min_max.rs
+++ b/datafusion-physical-expr/src/expressions/min_max.rs
@@ -556,7 +556,6 @@ mod tests {
use crate::expressions::col;
use crate::expressions::tests::aggregate;
use crate::generic_test_op;
- use arrow::array::DecimalBuilder;
use arrow::datatypes::*;
use arrow::record_batch::RecordBatch;
use datafusion_common::Result;
@@ -572,32 +571,33 @@ mod tests {
assert_eq!(result, left);
// min batch
- let mut decimal_builder = DecimalBuilder::new(5, 10, 0);
- for i in 1..6 {
- decimal_builder.append_value(i as i128)?;
- }
- let array: ArrayRef = Arc::new(decimal_builder.finish());
+ let array: ArrayRef = Arc::new(
+ (1..6)
+ .map(Some)
+ .collect::<DecimalArray>()
+ .with_precision_and_scale(10, 0)?,
+ );
let result = min_batch(&array)?;
assert_eq!(result, ScalarValue::Decimal128(Some(1), 10, 0));
- // min batch without values
- let mut decimal_builder = DecimalBuilder::new(5, 10, 0);
- let array: ArrayRef = Arc::new(decimal_builder.finish());
- let result = min_batch(&array)?;
- assert_eq!(ScalarValue::Decimal128(None, 10, 0), result);
- let mut decimal_builder = DecimalBuilder::new(0, 10, 0);
- let array: ArrayRef = Arc::new(decimal_builder.finish());
+ // min batch without values
+ let array: ArrayRef = Arc::new(
+ std::iter::repeat(None)
+ .take(0)
+ .collect::<DecimalArray>()
+ .with_precision_and_scale(10, 0)?,
+ );
let result = min_batch(&array)?;
assert_eq!(ScalarValue::Decimal128(None, 10, 0), result);
// min batch with agg
- let mut decimal_builder = DecimalBuilder::new(6, 10, 0);
- decimal_builder.append_null().unwrap();
- for i in 1..6 {
- decimal_builder.append_value(i as i128)?;
- }
- let array: ArrayRef = Arc::new(decimal_builder.finish());
+ let array: ArrayRef = Arc::new(
+ (1..6)
+ .map(Some)
+ .collect::<DecimalArray>()
+ .with_precision_and_scale(10, 0)?,
+ );
generic_test_op!(
array,
DataType::Decimal(10, 0),
@@ -610,11 +610,12 @@ mod tests {
#[test]
fn min_decimal_all_nulls() -> Result<()> {
// min batch all nulls
- let mut decimal_builder = DecimalBuilder::new(5, 10, 0);
- for _i in 1..6 {
- decimal_builder.append_null()?;
- }
- let array: ArrayRef = Arc::new(decimal_builder.finish());
+ let array: ArrayRef = Arc::new(
+ std::iter::repeat(None)
+ .take(6)
+ .collect::<DecimalArray>()
+ .with_precision_and_scale(10, 0)?,
+ );
generic_test_op!(
array,
DataType::Decimal(10, 0),
@@ -627,15 +628,13 @@ mod tests {
#[test]
fn min_decimal_with_nulls() -> Result<()> {
// min batch with nulls
- let mut decimal_builder = DecimalBuilder::new(5, 10, 0);
- for i in 1..6 {
- if i == 2 {
- decimal_builder.append_null()?;
- } else {
- decimal_builder.append_value(i as i128)?;
- }
- }
- let array: ArrayRef = Arc::new(decimal_builder.finish());
+ let array: ArrayRef = Arc::new(
+ (1..6)
+ .map(|i| if i == 2 { None } else { Some(i) })
+ .collect::<DecimalArray>()
+ .with_precision_and_scale(10, 0)?,
+ );
+
generic_test_op!(
array,
DataType::Decimal(10, 0),
@@ -662,30 +661,32 @@ mod tests {
assert_eq!(expect.to_string(), result.unwrap_err().to_string());
// max batch
- let mut decimal_builder = DecimalBuilder::new(5, 10, 5);
- for i in 1..6 {
- decimal_builder.append_value(i as i128)?;
- }
- let array: ArrayRef = Arc::new(decimal_builder.finish());
+ let array: ArrayRef = Arc::new(
+ (1..6)
+ .map(Some)
+ .collect::<DecimalArray>()
+ .with_precision_and_scale(10, 5)?,
+ );
let result = max_batch(&array)?;
assert_eq!(result, ScalarValue::Decimal128(Some(5), 10, 5));
+
// max batch without values
- let mut decimal_builder = DecimalBuilder::new(5, 10, 0);
- let array: ArrayRef = Arc::new(decimal_builder.finish());
+ let array: ArrayRef = Arc::new(
+ std::iter::repeat(None)
+ .take(0)
+ .collect::<DecimalArray>()
+ .with_precision_and_scale(10, 0)?,
+ );
let result = max_batch(&array)?;
assert_eq!(ScalarValue::Decimal128(None, 10, 0), result);
- let mut decimal_builder = DecimalBuilder::new(0, 10, 0);
- let array: ArrayRef = Arc::new(decimal_builder.finish());
- let result = max_batch(&array)?;
- assert_eq!(ScalarValue::Decimal128(None, 10, 0), result);
// max batch with agg
- let mut decimal_builder = DecimalBuilder::new(6, 10, 0);
- decimal_builder.append_null().unwrap();
- for i in 1..6 {
- decimal_builder.append_value(i as i128)?;
- }
- let array: ArrayRef = Arc::new(decimal_builder.finish());
+ let array: ArrayRef = Arc::new(
+ (1..6)
+ .map(Some)
+ .collect::<DecimalArray>()
+ .with_precision_and_scale(10, 0)?,
+ );
generic_test_op!(
array,
DataType::Decimal(10, 0),
@@ -697,15 +698,12 @@ mod tests {
#[test]
fn max_decimal_with_nulls() -> Result<()> {
- let mut decimal_builder = DecimalBuilder::new(5, 10, 0);
- for i in 1..6 {
- if i == 2 {
- decimal_builder.append_null()?;
- } else {
- decimal_builder.append_value(i as i128)?;
- }
- }
- let array: ArrayRef = Arc::new(decimal_builder.finish());
+ let array: ArrayRef = Arc::new(
+ (1..6)
+ .map(|i| if i == 2 { None } else { Some(i) })
+ .collect::<DecimalArray>()
+ .with_precision_and_scale(10, 0)?,
+ );
generic_test_op!(
array,
DataType::Decimal(10, 0),
@@ -717,11 +715,12 @@ mod tests {
#[test]
fn max_decimal_all_nulls() -> Result<()> {
- let mut decimal_builder = DecimalBuilder::new(5, 10, 0);
- for _i in 1..6 {
- decimal_builder.append_null()?;
- }
- let array: ArrayRef = Arc::new(decimal_builder.finish());
+ let array: ArrayRef = Arc::new(
+ std::iter::repeat(None)
+ .take(6)
+ .collect::<DecimalArray>()
+ .with_precision_and_scale(10, 0)?,
+ );
generic_test_op!(
array,
DataType::Decimal(10, 0),
diff --git a/datafusion-physical-expr/src/expressions/sum.rs
b/datafusion-physical-expr/src/expressions/sum.rs
index f2c19f5..9945620 100644
--- a/datafusion-physical-expr/src/expressions/sum.rs
+++ b/datafusion-physical-expr/src/expressions/sum.rs
@@ -23,7 +23,7 @@ use std::sync::Arc;
use crate::{AggregateExpr, PhysicalExpr};
use arrow::compute;
-use arrow::datatypes::DataType;
+use arrow::datatypes::{DataType, DECIMAL_MAX_PRECISION};
use arrow::{
array::{
ArrayRef, Float32Array, Float64Array, Int16Array, Int32Array,
Int64Array,
@@ -31,8 +31,7 @@ use arrow::{
},
datatypes::Field,
};
-use datafusion_common::{DataFusionError, Result};
-use datafusion_common::{ScalarValue, MAX_PRECISION_FOR_DECIMAL128};
+use datafusion_common::{DataFusionError, Result, ScalarValue};
use datafusion_expr::Accumulator;
use super::format_state_name;
@@ -63,7 +62,7 @@ pub fn sum_return_type(arg_type: &DataType) ->
Result<DataType> {
DataType::Decimal(precision, scale) => {
// in the spark, the result type is DECIMAL(min(38,precision+10),
s)
// ref:
https://github.com/apache/spark/blob/fcf636d9eb8d645c24be3db2d599aba2d7e2955a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/aggregate/Sum.scala#L66
- let new_precision = MAX_PRECISION_FOR_DECIMAL128.min(*precision +
10);
+ let new_precision = DECIMAL_MAX_PRECISION.min(*precision + 10);
Ok(DataType::Decimal(new_precision, *scale))
}
other => Err(DataFusionError::Plan(format!(
@@ -377,7 +376,6 @@ mod tests {
use super::*;
use crate::expressions::col;
use crate::generic_test_op;
- use arrow::array::DecimalBuilder;
use arrow::datatypes::*;
use arrow::record_batch::RecordBatch;
use datafusion_common::Result;
@@ -419,20 +417,22 @@ mod tests {
);
// test sum batch
- let mut decimal_builder = DecimalBuilder::new(5, 10, 0);
- for i in 1..6 {
- decimal_builder.append_value(i as i128)?;
- }
- let array: ArrayRef = Arc::new(decimal_builder.finish());
+ let array: ArrayRef = Arc::new(
+ (1..6)
+ .map(Some)
+ .collect::<DecimalArray>()
+ .with_precision_and_scale(10, 0)?,
+ );
let result = sum_batch(&array)?;
assert_eq!(ScalarValue::Decimal128(Some(15), 10, 0), result);
// test agg
- let mut decimal_builder = DecimalBuilder::new(5, 10, 0);
- for i in 1..6 {
- decimal_builder.append_value(i as i128)?;
- }
- let array: ArrayRef = Arc::new(decimal_builder.finish());
+ let array: ArrayRef = Arc::new(
+ (1..6)
+ .map(Some)
+ .collect::<DecimalArray>()
+ .with_precision_and_scale(10, 0)?,
+ );
generic_test_op!(
array,
@@ -452,28 +452,22 @@ mod tests {
assert_eq!(ScalarValue::Decimal128(Some(123), 10, 2), result);
// test with batch
- let mut decimal_builder = DecimalBuilder::new(5, 10, 0);
- for i in 1..6 {
- if i == 2 {
- decimal_builder.append_null()?;
- } else {
- decimal_builder.append_value(i)?;
- }
- }
- let array: ArrayRef = Arc::new(decimal_builder.finish());
+ let array: ArrayRef = Arc::new(
+ (1..6)
+ .map(|i| if i == 2 { None } else { Some(i) })
+ .collect::<DecimalArray>()
+ .with_precision_and_scale(10, 0)?,
+ );
let result = sum_batch(&array)?;
assert_eq!(ScalarValue::Decimal128(Some(13), 10, 0), result);
// test agg
- let mut decimal_builder = DecimalBuilder::new(5, 35, 0);
- for i in 1..6 {
- if i == 2 {
- decimal_builder.append_null()?;
- } else {
- decimal_builder.append_value(i)?;
- }
- }
- let array: ArrayRef = Arc::new(decimal_builder.finish());
+ let array: ArrayRef = Arc::new(
+ (1..6)
+ .map(|i| if i == 2 { None } else { Some(i) })
+ .collect::<DecimalArray>()
+ .with_precision_and_scale(35, 0)?,
+ );
generic_test_op!(
array,
DataType::Decimal(35, 0),
@@ -492,20 +486,16 @@ mod tests {
assert_eq!(ScalarValue::Decimal128(None, 10, 2), result);
// test with batch
- let mut decimal_builder = DecimalBuilder::new(5, 10, 0);
- for _i in 1..6 {
- decimal_builder.append_null()?;
- }
- let array: ArrayRef = Arc::new(decimal_builder.finish());
+ let array: ArrayRef = Arc::new(
+ std::iter::repeat(None)
+ .take(6)
+ .collect::<DecimalArray>()
+ .with_precision_and_scale(10, 0)?,
+ );
let result = sum_batch(&array)?;
assert_eq!(ScalarValue::Decimal128(None, 10, 0), result);
// test agg
- let mut decimal_builder = DecimalBuilder::new(5, 10, 0);
- for _i in 1..6 {
- decimal_builder.append_null()?;
- }
- let array: ArrayRef = Arc::new(decimal_builder.finish());
generic_test_op!(
array,
DataType::Decimal(10, 0),
diff --git a/datafusion/src/physical_plan/hash_utils.rs
b/datafusion/src/physical_plan/hash_utils.rs
index 00073a6..4e503b1 100644
--- a/datafusion/src/physical_plan/hash_utils.rs
+++ b/datafusion/src/physical_plan/hash_utils.rs
@@ -564,7 +564,6 @@ pub fn create_hashes<'a>(
#[cfg(test)]
mod tests {
use crate::from_slice::FromSlice;
- use arrow::array::DecimalBuilder;
use arrow::{array::DictionaryArray, datatypes::Int8Type};
use std::sync::Arc;
@@ -572,14 +571,15 @@ mod tests {
#[test]
fn create_hashes_for_decimal_array() -> Result<()> {
- let mut builder = DecimalBuilder::new(4, 20, 3);
- let array: Vec<i128> = vec![1, 2, 3, 4];
- for value in &array {
- builder.append_value(*value)?;
- }
- let array_ref = Arc::new(builder.finish());
+ let array = vec![1, 2, 3, 4]
+ .into_iter()
+ .map(Some)
+ .collect::<DecimalArray>()
+ .with_precision_and_scale(20, 3)
+ .unwrap();
+ let array_ref = Arc::new(array);
let random_state = RandomState::with_seeds(0, 0, 0, 0);
- let hashes_buff = &mut vec![0; array.len()];
+ let hashes_buff = &mut vec![0; array_ref.len()];
let hashes = create_hashes(&[array_ref], &random_state, hashes_buff)?;
assert_eq!(hashes.len(), 4);
Ok(())
diff --git a/datafusion/src/scalar.rs b/datafusion/src/scalar.rs
index 7dc9475..774b8eb 100644
--- a/datafusion/src/scalar.rs
+++ b/datafusion/src/scalar.rs
@@ -17,9 +17,7 @@
//! ScalarValue reimported from datafusion-common
-pub use datafusion_common::{
- ScalarType, ScalarValue, MAX_PRECISION_FOR_DECIMAL128,
MAX_SCALE_FOR_DECIMAL128,
-};
+pub use datafusion_common::{ScalarType, ScalarValue};
#[cfg(test)]
mod tests {
diff --git a/datafusion/src/sql/utils.rs b/datafusion/src/sql/utils.rs
index cbe40d6..8ec0a49 100644
--- a/datafusion/src/sql/utils.rs
+++ b/datafusion/src/sql/utils.rs
@@ -17,12 +17,12 @@
//! SQL Utility Functions
-use arrow::datatypes::DataType;
+use arrow::datatypes::{DataType, DECIMAL_MAX_PRECISION};
use sqlparser::ast::Ident;
use crate::logical_plan::ExprVisitable;
use crate::logical_plan::{Expr, LogicalPlan};
-use crate::scalar::{ScalarValue, MAX_PRECISION_FOR_DECIMAL128};
+use crate::scalar::ScalarValue;
use crate::{
error::{DataFusionError, Result},
logical_plan::{Column, ExpressionVisitor, Recursion},
@@ -522,7 +522,7 @@ pub(crate) fn make_decimal_type(
}
(Some(p), Some(s)) => {
// Arrow decimal is i128 meaning 38 maximum decimal digits
- if (p as usize) > MAX_PRECISION_FOR_DECIMAL128 || s > p {
+ if (p as usize) > DECIMAL_MAX_PRECISION || s > p {
return Err(DataFusionError::Internal(format!(
"For decimal(precision, scale) precision must be less than
or equal to 38 and scale can't be greater than precision. Got ({}, {})",
p, s