@@ -33,6 +33,7 @@ use std::mem::{size_of, size_of_val};
3333use std:: str:: FromStr ;
3434use std:: sync:: Arc ;
3535
36+ use crate :: assert_or_internal_err;
3637use crate :: cast:: {
3738 as_binary_array, as_binary_view_array, as_boolean_array, as_date32_array,
3839 as_date64_array, as_decimal128_array, as_decimal256_array, as_decimal32_array,
@@ -78,8 +79,8 @@ use arrow::compute::kernels::numeric::{
7879use arrow:: datatypes:: {
7980 i256, validate_decimal_precision_and_scale, ArrowDictionaryKeyType , ArrowNativeType ,
8081 ArrowTimestampType , DataType , Date32Type , Decimal128Type , Decimal256Type ,
81- Decimal32Type , Decimal64Type , Field , Float32Type , Int16Type , Int32Type , Int64Type ,
82- Int8Type , IntervalDayTime , IntervalDayTimeType , IntervalMonthDayNano ,
82+ Decimal32Type , Decimal64Type , DecimalType , Field , Float32Type , Int16Type , Int32Type ,
83+ Int64Type , Int8Type , IntervalDayTime , IntervalDayTimeType , IntervalMonthDayNano ,
8384 IntervalMonthDayNanoType , IntervalUnit , IntervalYearMonthType , TimeUnit ,
8485 TimestampMicrosecondType , TimestampMillisecondType , TimestampNanosecondType ,
8586 TimestampSecondType , UInt16Type , UInt32Type , UInt64Type , UInt8Type , UnionFields ,
@@ -1578,12 +1579,10 @@ impl ScalarValue {
15781579 DataType :: Float32 => ScalarValue :: Float32 ( Some ( 1.0 ) ) ,
15791580 DataType :: Float64 => ScalarValue :: Float64 ( Some ( 1.0 ) ) ,
15801581 DataType :: Decimal32 ( precision, scale) => {
1581- validate_decimal_precision_and_scale :: < Decimal32Type > (
1582+ Self :: validate_decimal_or_internal_err :: < Decimal32Type > (
15821583 * precision, * scale,
15831584 ) ?;
1584- if * scale < 0 {
1585- return _internal_err ! ( "Negative scale is not supported" ) ;
1586- }
1585+ assert_or_internal_err ! ( * scale >= 0 , "Negative scale is not supported" ) ;
15871586 match 10_i32 . checked_pow ( * scale as u32 ) {
15881587 Some ( value) => {
15891588 ScalarValue :: Decimal32 ( Some ( value) , * precision, * scale)
@@ -1592,12 +1591,10 @@ impl ScalarValue {
15921591 }
15931592 }
15941593 DataType :: Decimal64 ( precision, scale) => {
1595- validate_decimal_precision_and_scale :: < Decimal64Type > (
1594+ Self :: validate_decimal_or_internal_err :: < Decimal64Type > (
15961595 * precision, * scale,
15971596 ) ?;
1598- if * scale < 0 {
1599- return _internal_err ! ( "Negative scale is not supported" ) ;
1600- }
1597+ assert_or_internal_err ! ( * scale >= 0 , "Negative scale is not supported" ) ;
16011598 match i64:: from ( 10 ) . checked_pow ( * scale as u32 ) {
16021599 Some ( value) => {
16031600 ScalarValue :: Decimal64 ( Some ( value) , * precision, * scale)
@@ -1606,12 +1603,10 @@ impl ScalarValue {
16061603 }
16071604 }
16081605 DataType :: Decimal128 ( precision, scale) => {
1609- validate_decimal_precision_and_scale :: < Decimal128Type > (
1606+ Self :: validate_decimal_or_internal_err :: < Decimal128Type > (
16101607 * precision, * scale,
16111608 ) ?;
1612- if * scale < 0 {
1613- return _internal_err ! ( "Negative scale is not supported" ) ;
1614- }
1609+ assert_or_internal_err ! ( * scale >= 0 , "Negative scale is not supported" ) ;
16151610 match i128:: from ( 10 ) . checked_pow ( * scale as u32 ) {
16161611 Some ( value) => {
16171612 ScalarValue :: Decimal128 ( Some ( value) , * precision, * scale)
@@ -1620,12 +1615,10 @@ impl ScalarValue {
16201615 }
16211616 }
16221617 DataType :: Decimal256 ( precision, scale) => {
1623- validate_decimal_precision_and_scale :: < Decimal256Type > (
1618+ Self :: validate_decimal_or_internal_err :: < Decimal256Type > (
16241619 * precision, * scale,
16251620 ) ?;
1626- if * scale < 0 {
1627- return _internal_err ! ( "Negative scale is not supported" ) ;
1628- }
1621+ assert_or_internal_err ! ( * scale >= 0 , "Negative scale is not supported" ) ;
16291622 match i256:: from ( 10 ) . checked_pow ( * scale as u32 ) {
16301623 Some ( value) => {
16311624 ScalarValue :: Decimal256 ( Some ( value) , * precision, * scale)
@@ -1652,12 +1645,10 @@ impl ScalarValue {
16521645 DataType :: Float32 => ScalarValue :: Float32 ( Some ( -1.0 ) ) ,
16531646 DataType :: Float64 => ScalarValue :: Float64 ( Some ( -1.0 ) ) ,
16541647 DataType :: Decimal32 ( precision, scale) => {
1655- validate_decimal_precision_and_scale :: < Decimal32Type > (
1648+ Self :: validate_decimal_or_internal_err :: < Decimal32Type > (
16561649 * precision, * scale,
16571650 ) ?;
1658- if * scale < 0 {
1659- return _internal_err ! ( "Negative scale is not supported" ) ;
1660- }
1651+ assert_or_internal_err ! ( * scale >= 0 , "Negative scale is not supported" ) ;
16611652 match 10_i32 . checked_pow ( * scale as u32 ) {
16621653 Some ( value) => {
16631654 ScalarValue :: Decimal32 ( Some ( -value) , * precision, * scale)
@@ -1666,12 +1657,10 @@ impl ScalarValue {
16661657 }
16671658 }
16681659 DataType :: Decimal64 ( precision, scale) => {
1669- validate_decimal_precision_and_scale :: < Decimal64Type > (
1660+ Self :: validate_decimal_or_internal_err :: < Decimal64Type > (
16701661 * precision, * scale,
16711662 ) ?;
1672- if * scale < 0 {
1673- return _internal_err ! ( "Negative scale is not supported" ) ;
1674- }
1663+ assert_or_internal_err ! ( * scale >= 0 , "Negative scale is not supported" ) ;
16751664 match i64:: from ( 10 ) . checked_pow ( * scale as u32 ) {
16761665 Some ( value) => {
16771666 ScalarValue :: Decimal64 ( Some ( -value) , * precision, * scale)
@@ -1680,12 +1669,10 @@ impl ScalarValue {
16801669 }
16811670 }
16821671 DataType :: Decimal128 ( precision, scale) => {
1683- validate_decimal_precision_and_scale :: < Decimal128Type > (
1672+ Self :: validate_decimal_or_internal_err :: < Decimal128Type > (
16841673 * precision, * scale,
16851674 ) ?;
1686- if * scale < 0 {
1687- return _internal_err ! ( "Negative scale is not supported" ) ;
1688- }
1675+ assert_or_internal_err ! ( * scale >= 0 , "Negative scale is not supported" ) ;
16891676 match i128:: from ( 10 ) . checked_pow ( * scale as u32 ) {
16901677 Some ( value) => {
16911678 ScalarValue :: Decimal128 ( Some ( -value) , * precision, * scale)
@@ -1694,12 +1681,10 @@ impl ScalarValue {
16941681 }
16951682 }
16961683 DataType :: Decimal256 ( precision, scale) => {
1697- validate_decimal_precision_and_scale :: < Decimal256Type > (
1684+ Self :: validate_decimal_or_internal_err :: < Decimal256Type > (
16981685 * precision, * scale,
16991686 ) ?;
1700- if * scale < 0 {
1701- return _internal_err ! ( "Negative scale is not supported" ) ;
1702- }
1687+ assert_or_internal_err ! ( * scale >= 0 , "Negative scale is not supported" ) ;
17031688 match i256:: from ( 10 ) . checked_pow ( * scale as u32 ) {
17041689 Some ( value) => {
17051690 ScalarValue :: Decimal256 ( Some ( -value) , * precision, * scale)
@@ -1729,14 +1714,10 @@ impl ScalarValue {
17291714 DataType :: Float32 => ScalarValue :: Float32 ( Some ( 10.0 ) ) ,
17301715 DataType :: Float64 => ScalarValue :: Float64 ( Some ( 10.0 ) ) ,
17311716 DataType :: Decimal32 ( precision, scale) => {
1732- if let Err ( err ) = validate_decimal_precision_and_scale :: < Decimal32Type > (
1717+ Self :: validate_decimal_or_internal_err :: < Decimal32Type > (
17331718 * precision, * scale,
1734- ) {
1735- return _internal_err ! ( "Invalid precision and scale {err}" ) ;
1736- }
1737- if * scale < 0 {
1738- return _internal_err ! ( "Negative scale is not supported" ) ;
1739- }
1719+ ) ?;
1720+ assert_or_internal_err ! ( * scale >= 0 , "Negative scale is not supported" ) ;
17401721 match 10_i32 . checked_pow ( ( * scale + 1 ) as u32 ) {
17411722 Some ( value) => {
17421723 ScalarValue :: Decimal32 ( Some ( value) , * precision, * scale)
@@ -1745,14 +1726,10 @@ impl ScalarValue {
17451726 }
17461727 }
17471728 DataType :: Decimal64 ( precision, scale) => {
1748- if let Err ( err ) = validate_decimal_precision_and_scale :: < Decimal64Type > (
1729+ Self :: validate_decimal_or_internal_err :: < Decimal64Type > (
17491730 * precision, * scale,
1750- ) {
1751- return _internal_err ! ( "Invalid precision and scale {err}" ) ;
1752- }
1753- if * scale < 0 {
1754- return _internal_err ! ( "Negative scale is not supported" ) ;
1755- }
1731+ ) ?;
1732+ assert_or_internal_err ! ( * scale >= 0 , "Negative scale is not supported" ) ;
17561733 match i64:: from ( 10 ) . checked_pow ( ( * scale + 1 ) as u32 ) {
17571734 Some ( value) => {
17581735 ScalarValue :: Decimal64 ( Some ( value) , * precision, * scale)
@@ -1761,14 +1738,10 @@ impl ScalarValue {
17611738 }
17621739 }
17631740 DataType :: Decimal128 ( precision, scale) => {
1764- if let Err ( err ) = validate_decimal_precision_and_scale :: < Decimal128Type > (
1741+ Self :: validate_decimal_or_internal_err :: < Decimal128Type > (
17651742 * precision, * scale,
1766- ) {
1767- return _internal_err ! ( "Invalid precision and scale {err}" ) ;
1768- }
1769- if * scale < 0 {
1770- return _internal_err ! ( "Negative scale is not supported" ) ;
1771- }
1743+ ) ?;
1744+ assert_or_internal_err ! ( * scale >= 0 , "Negative scale is not supported" ) ;
17721745 match i128:: from ( 10 ) . checked_pow ( ( * scale + 1 ) as u32 ) {
17731746 Some ( value) => {
17741747 ScalarValue :: Decimal128 ( Some ( value) , * precision, * scale)
@@ -1777,14 +1750,10 @@ impl ScalarValue {
17771750 }
17781751 }
17791752 DataType :: Decimal256 ( precision, scale) => {
1780- if let Err ( err ) = validate_decimal_precision_and_scale :: < Decimal256Type > (
1753+ Self :: validate_decimal_or_internal_err :: < Decimal256Type > (
17811754 * precision, * scale,
1782- ) {
1783- return _internal_err ! ( "Invalid precision and scale {err}" ) ;
1784- }
1785- if * scale < 0 {
1786- return _internal_err ! ( "Negative scale is not supported" ) ;
1787- }
1755+ ) ?;
1756+ assert_or_internal_err ! ( * scale >= 0 , "Negative scale is not supported" ) ;
17881757 match i256:: from ( 10 ) . checked_pow ( ( * scale + 1 ) as u32 ) {
17891758 Some ( value) => {
17901759 ScalarValue :: Decimal256 ( Some ( value) , * precision, * scale)
@@ -4354,6 +4323,20 @@ impl ScalarValue {
43544323 _ => None ,
43554324 }
43564325 }
4326+
4327+ /// A thin wrapper on Arrow's validation that throws internal error if validation
4328+ /// fails.
4329+ fn validate_decimal_or_internal_err < T : DecimalType > (
4330+ precision : u8 ,
4331+ scale : i8 ,
4332+ ) -> Result < ( ) > {
4333+ validate_decimal_precision_and_scale :: < T > ( precision, scale) . map_err ( |err| {
4334+ _internal_datafusion_err ! (
4335+ "Decimal precision/scale invariant violated \
4336+ (precision={precision}, scale={scale}): {err}"
4337+ )
4338+ } )
4339+ }
43574340}
43584341
43594342/// Compacts the data of an `ArrayData` into a new `ArrayData`.
0 commit comments