-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Add validation for Decimal256 #2113
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
21e8457
40473dc
6dfd0b0
b060eb2
1fff485
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -15,6 +15,7 @@ | |
| // specific language governing permissions and limitations | ||
| // under the License. | ||
|
|
||
| use num::{BigInt, Num, ToPrimitive}; | ||
| use std::fmt; | ||
|
|
||
| use serde_derive::{Deserialize, Serialize}; | ||
|
|
@@ -300,6 +301,49 @@ pub const MAX_DECIMAL_FOR_EACH_PRECISION: [i128; 38] = [ | |
| 99999999999999999999999999999999999999, | ||
| ]; | ||
|
|
||
| /// `MAX_DECIMAL_FOR_LARGER_PRECISION[p]` holds the maximum integer value | ||
| /// that can be stored in [DataType::Decimal256] value of precision `p` > 38 | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Depends on #2093 which adds
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So this causes doc failure in CI.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I took the liberty of merging the latest |
||
| pub const MAX_DECIMAL_FOR_LARGER_PRECISION: [&str; 38] = [ | ||
| "99999999999999999999999999999999999999", | ||
| "999999999999999999999999999999999999999", | ||
| "9999999999999999999999999999999999999999", | ||
| "99999999999999999999999999999999999999999", | ||
| "999999999999999999999999999999999999999999", | ||
| "9999999999999999999999999999999999999999999", | ||
| "99999999999999999999999999999999999999999999", | ||
| "999999999999999999999999999999999999999999999", | ||
| "9999999999999999999999999999999999999999999999", | ||
| "99999999999999999999999999999999999999999999999", | ||
| "999999999999999999999999999999999999999999999999", | ||
| "9999999999999999999999999999999999999999999999999", | ||
| "99999999999999999999999999999999999999999999999999", | ||
| "999999999999999999999999999999999999999999999999999", | ||
| "9999999999999999999999999999999999999999999999999999", | ||
| "99999999999999999999999999999999999999999999999999999", | ||
| "999999999999999999999999999999999999999999999999999999", | ||
| "9999999999999999999999999999999999999999999999999999999", | ||
| "99999999999999999999999999999999999999999999999999999999", | ||
| "999999999999999999999999999999999999999999999999999999999", | ||
| "9999999999999999999999999999999999999999999999999999999999", | ||
| "99999999999999999999999999999999999999999999999999999999999", | ||
| "999999999999999999999999999999999999999999999999999999999999", | ||
| "9999999999999999999999999999999999999999999999999999999999999", | ||
| "99999999999999999999999999999999999999999999999999999999999999", | ||
| "999999999999999999999999999999999999999999999999999999999999999", | ||
| "9999999999999999999999999999999999999999999999999999999999999999", | ||
| "99999999999999999999999999999999999999999999999999999999999999999", | ||
| "999999999999999999999999999999999999999999999999999999999999999999", | ||
| "9999999999999999999999999999999999999999999999999999999999999999999", | ||
| "99999999999999999999999999999999999999999999999999999999999999999999", | ||
| "999999999999999999999999999999999999999999999999999999999999999999999", | ||
| "9999999999999999999999999999999999999999999999999999999999999999999999", | ||
| "99999999999999999999999999999999999999999999999999999999999999999999999", | ||
| "999999999999999999999999999999999999999999999999999999999999999999999999", | ||
| "9999999999999999999999999999999999999999999999999999999999999999999999999", | ||
| "99999999999999999999999999999999999999999999999999999999999999999999999999", | ||
| "999999999999999999999999999999999999999999999999999999999999999999999999999", | ||
| ]; | ||
|
|
||
| /// `MIN_DECIMAL_FOR_EACH_PRECISION[p]` holds the minimum `i128` value | ||
| /// that can be stored in a [DataType::Decimal] value of precision `p` | ||
| pub const MIN_DECIMAL_FOR_EACH_PRECISION: [i128; 38] = [ | ||
|
|
@@ -343,13 +387,62 @@ pub const MIN_DECIMAL_FOR_EACH_PRECISION: [i128; 38] = [ | |
| -99999999999999999999999999999999999999, | ||
| ]; | ||
|
|
||
| /// `MIN_DECIMAL_FOR_LARGER_PRECISION[p]` holds the minimum integer value | ||
| /// that can be stored in a [DataType::Decimal256] value of precision `p` > 38 | ||
| pub const MIN_DECIMAL_FOR_LARGER_PRECISION: [&str; 38] = [ | ||
| "-99999999999999999999999999999999999999", | ||
| "-999999999999999999999999999999999999999", | ||
| "-9999999999999999999999999999999999999999", | ||
| "-99999999999999999999999999999999999999999", | ||
| "-999999999999999999999999999999999999999999", | ||
| "-9999999999999999999999999999999999999999999", | ||
| "-99999999999999999999999999999999999999999999", | ||
| "-999999999999999999999999999999999999999999999", | ||
| "-9999999999999999999999999999999999999999999999", | ||
| "-99999999999999999999999999999999999999999999999", | ||
| "-999999999999999999999999999999999999999999999999", | ||
| "-9999999999999999999999999999999999999999999999999", | ||
| "-99999999999999999999999999999999999999999999999999", | ||
| "-999999999999999999999999999999999999999999999999999", | ||
| "-9999999999999999999999999999999999999999999999999999", | ||
| "-99999999999999999999999999999999999999999999999999999", | ||
| "-999999999999999999999999999999999999999999999999999999", | ||
| "-9999999999999999999999999999999999999999999999999999999", | ||
| "-99999999999999999999999999999999999999999999999999999999", | ||
| "-999999999999999999999999999999999999999999999999999999999", | ||
| "-9999999999999999999999999999999999999999999999999999999999", | ||
| "-99999999999999999999999999999999999999999999999999999999999", | ||
| "-999999999999999999999999999999999999999999999999999999999999", | ||
| "-9999999999999999999999999999999999999999999999999999999999999", | ||
| "-99999999999999999999999999999999999999999999999999999999999999", | ||
| "-999999999999999999999999999999999999999999999999999999999999999", | ||
| "-9999999999999999999999999999999999999999999999999999999999999999", | ||
| "-99999999999999999999999999999999999999999999999999999999999999999", | ||
| "-999999999999999999999999999999999999999999999999999999999999999999", | ||
| "-9999999999999999999999999999999999999999999999999999999999999999999", | ||
| "-99999999999999999999999999999999999999999999999999999999999999999999", | ||
| "-999999999999999999999999999999999999999999999999999999999999999999999", | ||
| "-9999999999999999999999999999999999999999999999999999999999999999999999", | ||
| "-99999999999999999999999999999999999999999999999999999999999999999999999", | ||
| "-999999999999999999999999999999999999999999999999999999999999999999999999", | ||
| "-9999999999999999999999999999999999999999999999999999999999999999999999999", | ||
| "-99999999999999999999999999999999999999999999999999999999999999999999999999", | ||
| "-999999999999999999999999999999999999999999999999999999999999999999999999999", | ||
| ]; | ||
|
|
||
| /// The maximum precision for [DataType::Decimal] values | ||
| pub const DECIMAL_MAX_PRECISION: usize = 38; | ||
|
|
||
| /// The maximum scale for [DataType::Decimal] values | ||
| pub const DECIMAL_MAX_SCALE: usize = 38; | ||
|
|
||
| /// The default scale for [DataType::Decimal] values | ||
| /// The maximum precision for [DataType::Decimal256] values | ||
| pub const DECIMAL256_MAX_PRECISION: usize = 76; | ||
|
|
||
| /// The maximum scale for [DataType::Decimal256] values | ||
| pub const DECIMAL256_MAX_SCALE: usize = 76; | ||
|
|
||
| /// The default scale for [DataType::Decimal] and [DataType::Decimal256] values | ||
| pub const DECIMAL_DEFAULT_SCALE: usize = 10; | ||
|
|
||
| /// Validates that the specified `i128` value can be properly | ||
|
|
@@ -379,6 +472,55 @@ pub(crate) fn validate_decimal_precision(value: i128, precision: usize) -> Resul | |
| } | ||
| } | ||
|
|
||
| /// Validates that the specified string value can be properly | ||
| /// interpreted as a Decimal256 number with precision `precision` | ||
| #[inline] | ||
| pub(crate) fn validate_decimal256_precision( | ||
| value: &str, | ||
| precision: usize, | ||
| ) -> Result<BigInt> { | ||
| if precision > 38 { | ||
| let max_str = MAX_DECIMAL_FOR_LARGER_PRECISION[precision - 38 - 1]; | ||
| let min_str = MIN_DECIMAL_FOR_LARGER_PRECISION[precision - 38 - 1]; | ||
|
|
||
| let max = BigInt::from_str_radix(max_str, 10).unwrap(); | ||
| let min = BigInt::from_str_radix(min_str, 10).unwrap(); | ||
|
|
||
| let value = BigInt::from_str_radix(value, 10).unwrap(); | ||
| if value > max { | ||
| Err(ArrowError::InvalidArgumentError(format!( | ||
| "{} is too large to store in a Decimal256 of precision {}. Max is {}", | ||
| value, precision, max | ||
| ))) | ||
| } else if value < min { | ||
| Err(ArrowError::InvalidArgumentError(format!( | ||
| "{} is too small to store in a Decimal256 of precision {}. Min is {}", | ||
| value, precision, min | ||
| ))) | ||
| } else { | ||
| Ok(value) | ||
| } | ||
| } else { | ||
| let max = MAX_DECIMAL_FOR_EACH_PRECISION[precision - 1]; | ||
| let min = MIN_DECIMAL_FOR_EACH_PRECISION[precision - 1]; | ||
| let value = BigInt::from_str_radix(value, 10).unwrap(); | ||
|
|
||
| if value.to_i128().unwrap() > max { | ||
| Err(ArrowError::InvalidArgumentError(format!( | ||
| "{} is too large to store in a Decimal256 of precision {}. Max is {}", | ||
| value, precision, max | ||
| ))) | ||
| } else if value.to_i128().unwrap() < min { | ||
| Err(ArrowError::InvalidArgumentError(format!( | ||
| "{} is too small to store in a Decimal256 of precision {}. Min is {}", | ||
| value, precision, min | ||
| ))) | ||
| } else { | ||
| Ok(value) | ||
| } | ||
| } | ||
| } | ||
|
|
||
| impl DataType { | ||
| /// Parse a data type from a JSON representation. | ||
| pub(crate) fn from(json: &Value) -> Result<DataType> { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fix typo