This is an automated email from the ASF dual-hosted git repository.

tustvold pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-rs.git


The following commit(s) were added to refs/heads/main by this push:
     new d6fa07874c Expose min/max values for Decimal128/256 and improve docs 
(#6992)
d6fa07874c is described below

commit d6fa07874c20e82d43cc556287353ab0875ac637
Author: Andrew Lamb <[email protected]>
AuthorDate: Sat Jan 25 10:22:01 2025 -0500

    Expose min/max values for Decimal128/256 and improve docs (#6992)
    
    * Expose min/max values for Decimal128/256 and improve docs
    
    * fix test
---
 arrow-data/src/decimal.rs | 142 +++++++++++++++++++++++++++++++++++-----------
 1 file changed, 108 insertions(+), 34 deletions(-)

diff --git a/arrow-data/src/decimal.rs b/arrow-data/src/decimal.rs
index fe19db6412..5453fb120d 100644
--- a/arrow-data/src/decimal.rs
+++ b/arrow-data/src/decimal.rs
@@ -15,10 +15,13 @@
 // specific language governing permissions and limitations
 // under the License.
 
-//! Defines maximum and minimum values for `decimal256` and `decimal128` types 
for varying precisions.
+//! Maximum and minimum values for [`Decimal256`] and [`Decimal128`].
 //!
-//! Also provides functions to validate if a given decimal value is within the 
valid range of the decimal type.
-
+//! Also provides functions to validate if a given decimal value is within
+//! the valid range of the decimal type.
+//!
+//! [`Decimal128`]: arrow_schema::DataType::Decimal128
+//! [`Decimal256`]: arrow_schema::DataType::Decimal256
 use arrow_buffer::i256;
 use arrow_schema::ArrowError;
 
@@ -27,12 +30,27 @@ pub use arrow_schema::{
     DECIMAL_DEFAULT_SCALE,
 };
 
-/// MAX decimal256 value of little-endian format for each precision.
-/// Each element is the max value of signed 256-bit integer for the specified 
precision which
-/// is encoded to the 32-byte width format of little-endian.
+/// `MAX_DECIMAL256_FOR_EACH_PRECISION[p]` holds the maximum [`i256`] value 
that can
+/// be stored in a [`Decimal256`] value of precision `p`.
+///
+/// # Notes
+///
+/// Each element is the max value of signed 256-bit integer for the specified
+/// precision which is encoded to the 32-byte width format of little-endian.
+///
 /// The first element is unused and is inserted so that we can look up using
 /// precision as the index without the need to subtract 1 first.
-pub(crate) const MAX_DECIMAL_BYTES_FOR_LARGER_EACH_PRECISION: [i256; 77] = [
+///
+/// # Example
+/// ```
+/// # use arrow_buffer::i256;
+/// # use arrow_data::decimal::MAX_DECIMAL256_FOR_EACH_PRECISION;
+/// assert_eq!(MAX_DECIMAL256_FOR_EACH_PRECISION[3], i256::from(999));
+/// ```
+///
+/// [`Decimal256`]: arrow_schema::DataType::Decimal256
+/// [`i256`]: arrow_buffer::i256
+pub const MAX_DECIMAL256_FOR_EACH_PRECISION: [i256; 77] = [
     i256::from_i128(0_i128), // unused first element
     i256::from_le_bytes([
         9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0,
@@ -340,12 +358,26 @@ pub(crate) const 
MAX_DECIMAL_BYTES_FOR_LARGER_EACH_PRECISION: [i256; 77] = [
     ]),
 ];
 
-/// MIN decimal256 value of little-endian format for each precision.
+/// `MIN_DECIMAL256_FOR_EACH_PRECISION[p]` holds the minimum [`i256`] value 
that can
+/// be stored in a [`Decimal256`] value of precision `p`.
+///
+/// # Notes
+///
 /// Each element is the min value of signed 256-bit integer for the specified 
precision which
 /// is encoded to the 76-byte width format of little-endian.
+///
 /// The first element is unused and is inserted so that we can look up using
 /// precision as the index without the need to subtract 1 first.
-pub(crate) const MIN_DECIMAL_BYTES_FOR_LARGER_EACH_PRECISION: [i256; 77] = [
+/// # Example
+/// ```
+/// # use arrow_buffer::i256;
+/// # use arrow_data::decimal::MIN_DECIMAL256_FOR_EACH_PRECISION;
+/// assert_eq!(MIN_DECIMAL256_FOR_EACH_PRECISION[3], i256::from(-999));
+/// ```
+///
+/// [`i256`]: arrow_buffer::i256
+/// [`Decimal256`]: arrow_schema::DataType::Decimal256
+pub const MIN_DECIMAL256_FOR_EACH_PRECISION: [i256; 77] = [
     i256::from_i128(0_i128), // unused first element
     i256::from_le_bytes([
         247, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 
255, 255, 255, 255,
@@ -654,7 +686,13 @@ pub(crate) const 
MIN_DECIMAL_BYTES_FOR_LARGER_EACH_PRECISION: [i256; 77] = [
 ];
 
 /// `MAX_DECIMAL_FOR_EACH_PRECISION[p-1]` holds the maximum `i128` value that 
can
-/// be stored in [arrow_schema::DataType::Decimal128] value of precision `p`
+/// be stored in a [`Decimal128`] value of precision `p`
+///
+/// [`Decimal128`]: arrow_schema::DataType::Decimal128
+#[deprecated(
+    since = "54.1.0",
+    note = "Use MAX_DECIMAL128_FOR_EACH_PRECISION (note indexes are different)"
+)]
 #[allow(dead_code)] // no longer used but is part of our public API
 pub const MAX_DECIMAL_FOR_EACH_PRECISION: [i128; 38] = [
     9,
@@ -698,8 +736,14 @@ pub const MAX_DECIMAL_FOR_EACH_PRECISION: [i128; 38] = [
 ];
 
 /// `MIN_DECIMAL_FOR_EACH_PRECISION[p-1]` holds the minimum `i128` value that 
can
-/// be stored in a [arrow_schema::DataType::Decimal128] value of precision `p`
+/// be stored in a [`Decimal128`] value of precision `p`
+///
+/// [`Decimal128`]: arrow_schema::DataType::Decimal128
 #[allow(dead_code)] // no longer used but is part of our public API
+#[deprecated(
+    since = "54.1.0",
+    note = "Use MIN_DECIMAL_FOR_EACH_PRECISION (note indexes are different)"
+)]
 pub const MIN_DECIMAL_FOR_EACH_PRECISION: [i128; 38] = [
     -9,
     -99,
@@ -741,11 +785,22 @@ pub const MIN_DECIMAL_FOR_EACH_PRECISION: [i128; 38] = [
     -99999999999999999999999999999999999999,
 ];
 
-/// `MAX_DECIMAL_FOR_EACH_PRECISION_ONE_BASED[p]` holds the maximum `i128` 
value that can
-/// be stored in [arrow_schema::DataType::Decimal128] value of precision `p`.
+/// `MAX_DECIMAL128_FOR_EACH_PRECISION[p]` holds the maximum `i128` value that 
can
+/// be stored in [`Decimal128`] value of precision `p`.
+///
+/// # Notes
+///
 /// The first element is unused and is inserted so that we can look up using
 /// precision as the index without the need to subtract 1 first.
-pub(crate) const MAX_DECIMAL_FOR_EACH_PRECISION_ONE_BASED: [i128; 39] = [
+///
+/// # Example
+/// ```
+/// # use arrow_data::decimal::MAX_DECIMAL128_FOR_EACH_PRECISION;
+/// assert_eq!(MAX_DECIMAL128_FOR_EACH_PRECISION[3], 999);
+/// ```
+///
+/// [`Decimal128`]: arrow_schema::DataType::Decimal128
+pub const MAX_DECIMAL128_FOR_EACH_PRECISION: [i128; 39] = [
     0, // unused first element
     9,
     99,
@@ -788,10 +843,21 @@ pub(crate) const 
MAX_DECIMAL_FOR_EACH_PRECISION_ONE_BASED: [i128; 39] = [
 ];
 
 /// `MIN_DECIMAL_FOR_EACH_PRECISION[p]` holds the minimum `i128` value that can
-/// be stored in a [arrow_schema::DataType::Decimal128] value of precision `p`.
+/// be stored in a [`Decimal128`] value of precision `p`.
+///
+/// # Notes
+///
 /// The first element is unused and is inserted so that we can look up using
 /// precision as the index without the need to subtract 1 first.
-pub(crate) const MIN_DECIMAL_FOR_EACH_PRECISION_ONE_BASED: [i128; 39] = [
+///
+/// # Example
+/// ```
+/// # use arrow_data::decimal::MIN_DECIMAL128_FOR_EACH_PRECISION;
+/// assert_eq!(MIN_DECIMAL128_FOR_EACH_PRECISION[3], -999);
+/// ```
+///
+/// [`Decimal128`]: arrow_schema::DataType::Decimal128
+pub const MIN_DECIMAL128_FOR_EACH_PRECISION: [i128; 39] = [
     0, // unused first element
     -9,
     -99,
@@ -834,7 +900,9 @@ pub(crate) const MIN_DECIMAL_FOR_EACH_PRECISION_ONE_BASED: 
[i128; 39] = [
 ];
 
 /// Validates that the specified `i128` value can be properly
-/// interpreted as a Decimal number with precision `precision`
+/// interpreted as a [`Decimal128`] number with precision `precision`
+///
+/// [`Decimal128`]: arrow_schema::DataType::Decimal128
 #[inline]
 pub fn validate_decimal_precision(value: i128, precision: u8) -> Result<(), 
ArrowError> {
     if precision > DECIMAL128_MAX_PRECISION {
@@ -842,32 +910,36 @@ pub fn validate_decimal_precision(value: i128, precision: 
u8) -> Result<(), Arro
             "Max precision of a Decimal128 is {DECIMAL128_MAX_PRECISION}, but 
got {precision}",
         )));
     }
-    if value > MAX_DECIMAL_FOR_EACH_PRECISION_ONE_BASED[precision as usize] {
+    if value > MAX_DECIMAL128_FOR_EACH_PRECISION[precision as usize] {
         Err(ArrowError::InvalidArgumentError(format!(
             "{value} is too large to store in a Decimal128 of precision 
{precision}. Max is {}",
-            MAX_DECIMAL_FOR_EACH_PRECISION_ONE_BASED[precision as usize]
+            MAX_DECIMAL128_FOR_EACH_PRECISION[precision as usize]
         )))
-    } else if value < MIN_DECIMAL_FOR_EACH_PRECISION_ONE_BASED[precision as 
usize] {
+    } else if value < MIN_DECIMAL128_FOR_EACH_PRECISION[precision as usize] {
         Err(ArrowError::InvalidArgumentError(format!(
             "{value} is too small to store in a Decimal128 of precision 
{precision}. Min is {}",
-            MIN_DECIMAL_FOR_EACH_PRECISION_ONE_BASED[precision as usize]
+            MIN_DECIMAL128_FOR_EACH_PRECISION[precision as usize]
         )))
     } else {
         Ok(())
     }
 }
 
-/// Determines whether the specified `i128` value can be properly
-/// interpreted as a Decimal number with precision `precision`
+/// Returns true if the specified `i128` value can be properly
+/// interpreted as a [`Decimal128`] number with precision `precision`
+///
+/// [`Decimal128`]: arrow_schema::DataType::Decimal128
 #[inline]
 pub fn is_validate_decimal_precision(value: i128, precision: u8) -> bool {
     precision <= DECIMAL128_MAX_PRECISION
-        && value >= MIN_DECIMAL_FOR_EACH_PRECISION_ONE_BASED[precision as 
usize]
-        && value <= MAX_DECIMAL_FOR_EACH_PRECISION_ONE_BASED[precision as 
usize]
+        && value >= MIN_DECIMAL128_FOR_EACH_PRECISION[precision as usize]
+        && value <= MAX_DECIMAL128_FOR_EACH_PRECISION[precision as usize]
 }
 
 /// Validates that the specified `i256` of value can be properly
-/// interpreted as a Decimal256 number with precision `precision`
+/// interpreted as a [`Decimal256`] number with precision `precision`
+///
+/// [`Decimal256`]: arrow_schema::DataType::Decimal256
 #[inline]
 pub fn validate_decimal256_precision(value: i256, precision: u8) -> Result<(), 
ArrowError> {
     if precision > DECIMAL256_MAX_PRECISION {
@@ -875,26 +947,28 @@ pub fn validate_decimal256_precision(value: i256, 
precision: u8) -> Result<(), A
             "Max precision of a Decimal256 is {DECIMAL256_MAX_PRECISION}, but 
got {precision}",
         )));
     }
-    if value > MAX_DECIMAL_BYTES_FOR_LARGER_EACH_PRECISION[precision as usize] 
{
+    if value > MAX_DECIMAL256_FOR_EACH_PRECISION[precision as usize] {
         Err(ArrowError::InvalidArgumentError(format!(
             "{value:?} is too large to store in a Decimal256 of precision 
{precision}. Max is {:?}",
-            MAX_DECIMAL_BYTES_FOR_LARGER_EACH_PRECISION[precision as usize]
+            MAX_DECIMAL256_FOR_EACH_PRECISION[precision as usize]
         )))
-    } else if value < MIN_DECIMAL_BYTES_FOR_LARGER_EACH_PRECISION[precision as 
usize] {
+    } else if value < MIN_DECIMAL256_FOR_EACH_PRECISION[precision as usize] {
         Err(ArrowError::InvalidArgumentError(format!(
             "{value:?} is too small to store in a Decimal256 of precision 
{precision}. Min is {:?}",
-            MIN_DECIMAL_BYTES_FOR_LARGER_EACH_PRECISION[precision as usize]
+            MIN_DECIMAL256_FOR_EACH_PRECISION[precision as usize]
         )))
     } else {
         Ok(())
     }
 }
 
-/// Determines whether the specified `i256` value can be properly
-/// interpreted as a Decimal256 number with precision `precision`
+/// Return true if the specified `i256` value can be properly
+/// interpreted as a [`Decimal256`] number with precision `precision`
+///
+/// [`Decimal256`]: arrow_schema::DataType::Decimal256
 #[inline]
 pub fn is_validate_decimal256_precision(value: i256, precision: u8) -> bool {
     precision <= DECIMAL256_MAX_PRECISION
-        && value >= MIN_DECIMAL_BYTES_FOR_LARGER_EACH_PRECISION[precision as 
usize]
-        && value <= MAX_DECIMAL_BYTES_FOR_LARGER_EACH_PRECISION[precision as 
usize]
+        && value >= MIN_DECIMAL256_FOR_EACH_PRECISION[precision as usize]
+        && value <= MAX_DECIMAL256_FOR_EACH_PRECISION[precision as usize]
 }

Reply via email to