|  | 
| 15 | 15 | // specific language governing permissions and limitations | 
| 16 | 16 | // under the License. | 
| 17 | 17 | 
 | 
|  | 18 | +use num::{BigInt, Num, ToPrimitive}; | 
| 18 | 19 | use std::fmt; | 
| 19 | 20 | 
 | 
| 20 | 21 | use serde_derive::{Deserialize, Serialize}; | 
| @@ -300,6 +301,49 @@ pub const MAX_DECIMAL_FOR_EACH_PRECISION: [i128; 38] = [ | 
| 300 | 301 |     99999999999999999999999999999999999999, | 
| 301 | 302 | ]; | 
| 302 | 303 | 
 | 
|  | 304 | +/// `MAX_DECIMAL_FOR_LARGER_PRECISION[p]` holds the maximum integer value | 
|  | 305 | +/// that can be stored in [DataType::Decimal256] value of precision `p` > 38 | 
|  | 306 | +pub const MAX_DECIMAL_FOR_LARGER_PRECISION: [&str; 38] = [ | 
|  | 307 | +    "99999999999999999999999999999999999999", | 
|  | 308 | +    "999999999999999999999999999999999999999", | 
|  | 309 | +    "9999999999999999999999999999999999999999", | 
|  | 310 | +    "99999999999999999999999999999999999999999", | 
|  | 311 | +    "999999999999999999999999999999999999999999", | 
|  | 312 | +    "9999999999999999999999999999999999999999999", | 
|  | 313 | +    "99999999999999999999999999999999999999999999", | 
|  | 314 | +    "999999999999999999999999999999999999999999999", | 
|  | 315 | +    "9999999999999999999999999999999999999999999999", | 
|  | 316 | +    "99999999999999999999999999999999999999999999999", | 
|  | 317 | +    "999999999999999999999999999999999999999999999999", | 
|  | 318 | +    "9999999999999999999999999999999999999999999999999", | 
|  | 319 | +    "99999999999999999999999999999999999999999999999999", | 
|  | 320 | +    "999999999999999999999999999999999999999999999999999", | 
|  | 321 | +    "9999999999999999999999999999999999999999999999999999", | 
|  | 322 | +    "99999999999999999999999999999999999999999999999999999", | 
|  | 323 | +    "999999999999999999999999999999999999999999999999999999", | 
|  | 324 | +    "9999999999999999999999999999999999999999999999999999999", | 
|  | 325 | +    "99999999999999999999999999999999999999999999999999999999", | 
|  | 326 | +    "999999999999999999999999999999999999999999999999999999999", | 
|  | 327 | +    "9999999999999999999999999999999999999999999999999999999999", | 
|  | 328 | +    "99999999999999999999999999999999999999999999999999999999999", | 
|  | 329 | +    "999999999999999999999999999999999999999999999999999999999999", | 
|  | 330 | +    "9999999999999999999999999999999999999999999999999999999999999", | 
|  | 331 | +    "99999999999999999999999999999999999999999999999999999999999999", | 
|  | 332 | +    "999999999999999999999999999999999999999999999999999999999999999", | 
|  | 333 | +    "9999999999999999999999999999999999999999999999999999999999999999", | 
|  | 334 | +    "99999999999999999999999999999999999999999999999999999999999999999", | 
|  | 335 | +    "999999999999999999999999999999999999999999999999999999999999999999", | 
|  | 336 | +    "9999999999999999999999999999999999999999999999999999999999999999999", | 
|  | 337 | +    "99999999999999999999999999999999999999999999999999999999999999999999", | 
|  | 338 | +    "999999999999999999999999999999999999999999999999999999999999999999999", | 
|  | 339 | +    "9999999999999999999999999999999999999999999999999999999999999999999999", | 
|  | 340 | +    "99999999999999999999999999999999999999999999999999999999999999999999999", | 
|  | 341 | +    "999999999999999999999999999999999999999999999999999999999999999999999999", | 
|  | 342 | +    "9999999999999999999999999999999999999999999999999999999999999999999999999", | 
|  | 343 | +    "99999999999999999999999999999999999999999999999999999999999999999999999999", | 
|  | 344 | +    "999999999999999999999999999999999999999999999999999999999999999999999999999", | 
|  | 345 | +]; | 
|  | 346 | + | 
| 303 | 347 | /// `MIN_DECIMAL_FOR_EACH_PRECISION[p]` holds the minimum `i128` value | 
| 304 | 348 | /// that can be stored in a [DataType::Decimal] value of precision `p` | 
| 305 | 349 | pub const MIN_DECIMAL_FOR_EACH_PRECISION: [i128; 38] = [ | 
| @@ -343,13 +387,62 @@ pub const MIN_DECIMAL_FOR_EACH_PRECISION: [i128; 38] = [ | 
| 343 | 387 |     -99999999999999999999999999999999999999, | 
| 344 | 388 | ]; | 
| 345 | 389 | 
 | 
|  | 390 | +/// `MIN_DECIMAL_FOR_LARGER_PRECISION[p]` holds the minimum integer value | 
|  | 391 | +/// that can be stored in a [DataType::Decimal256] value of precision `p` > 38 | 
|  | 392 | +pub const MIN_DECIMAL_FOR_LARGER_PRECISION: [&str; 38] = [ | 
|  | 393 | +    "-99999999999999999999999999999999999999", | 
|  | 394 | +    "-999999999999999999999999999999999999999", | 
|  | 395 | +    "-9999999999999999999999999999999999999999", | 
|  | 396 | +    "-99999999999999999999999999999999999999999", | 
|  | 397 | +    "-999999999999999999999999999999999999999999", | 
|  | 398 | +    "-9999999999999999999999999999999999999999999", | 
|  | 399 | +    "-99999999999999999999999999999999999999999999", | 
|  | 400 | +    "-999999999999999999999999999999999999999999999", | 
|  | 401 | +    "-9999999999999999999999999999999999999999999999", | 
|  | 402 | +    "-99999999999999999999999999999999999999999999999", | 
|  | 403 | +    "-999999999999999999999999999999999999999999999999", | 
|  | 404 | +    "-9999999999999999999999999999999999999999999999999", | 
|  | 405 | +    "-99999999999999999999999999999999999999999999999999", | 
|  | 406 | +    "-999999999999999999999999999999999999999999999999999", | 
|  | 407 | +    "-9999999999999999999999999999999999999999999999999999", | 
|  | 408 | +    "-99999999999999999999999999999999999999999999999999999", | 
|  | 409 | +    "-999999999999999999999999999999999999999999999999999999", | 
|  | 410 | +    "-9999999999999999999999999999999999999999999999999999999", | 
|  | 411 | +    "-99999999999999999999999999999999999999999999999999999999", | 
|  | 412 | +    "-999999999999999999999999999999999999999999999999999999999", | 
|  | 413 | +    "-9999999999999999999999999999999999999999999999999999999999", | 
|  | 414 | +    "-99999999999999999999999999999999999999999999999999999999999", | 
|  | 415 | +    "-999999999999999999999999999999999999999999999999999999999999", | 
|  | 416 | +    "-9999999999999999999999999999999999999999999999999999999999999", | 
|  | 417 | +    "-99999999999999999999999999999999999999999999999999999999999999", | 
|  | 418 | +    "-999999999999999999999999999999999999999999999999999999999999999", | 
|  | 419 | +    "-9999999999999999999999999999999999999999999999999999999999999999", | 
|  | 420 | +    "-99999999999999999999999999999999999999999999999999999999999999999", | 
|  | 421 | +    "-999999999999999999999999999999999999999999999999999999999999999999", | 
|  | 422 | +    "-9999999999999999999999999999999999999999999999999999999999999999999", | 
|  | 423 | +    "-99999999999999999999999999999999999999999999999999999999999999999999", | 
|  | 424 | +    "-999999999999999999999999999999999999999999999999999999999999999999999", | 
|  | 425 | +    "-9999999999999999999999999999999999999999999999999999999999999999999999", | 
|  | 426 | +    "-99999999999999999999999999999999999999999999999999999999999999999999999", | 
|  | 427 | +    "-999999999999999999999999999999999999999999999999999999999999999999999999", | 
|  | 428 | +    "-9999999999999999999999999999999999999999999999999999999999999999999999999", | 
|  | 429 | +    "-99999999999999999999999999999999999999999999999999999999999999999999999999", | 
|  | 430 | +    "-999999999999999999999999999999999999999999999999999999999999999999999999999", | 
|  | 431 | +]; | 
|  | 432 | + | 
| 346 | 433 | /// The maximum precision for [DataType::Decimal] values | 
| 347 | 434 | pub const DECIMAL_MAX_PRECISION: usize = 38; | 
| 348 | 435 | 
 | 
| 349 | 436 | /// The maximum scale for [DataType::Decimal] values | 
| 350 | 437 | pub const DECIMAL_MAX_SCALE: usize = 38; | 
| 351 | 438 | 
 | 
| 352 |  | -/// The default scale for [DataType::Decimal] values | 
|  | 439 | +/// The maximum precision for [DataType::Decimal256] values | 
|  | 440 | +pub const DECIMAL256_MAX_PRECISION: usize = 76; | 
|  | 441 | + | 
|  | 442 | +/// The maximum scale for [DataType::Decimal256] values | 
|  | 443 | +pub const DECIMAL256_MAX_SCALE: usize = 76; | 
|  | 444 | + | 
|  | 445 | +/// The default scale for [DataType::Decimal] and [DataType::Decimal256] values | 
| 353 | 446 | pub const DECIMAL_DEFAULT_SCALE: usize = 10; | 
| 354 | 447 | 
 | 
| 355 | 448 | /// Validates that the specified `i128` value can be properly | 
| @@ -379,6 +472,55 @@ pub(crate) fn validate_decimal_precision(value: i128, precision: usize) -> Resul | 
| 379 | 472 |     } | 
| 380 | 473 | } | 
| 381 | 474 | 
 | 
|  | 475 | +/// Validates that the specified string value can be properly | 
|  | 476 | +/// interpreted as a Decimal256 number with precision `precision` | 
|  | 477 | +#[inline] | 
|  | 478 | +pub(crate) fn validate_decimal256_precision( | 
|  | 479 | +    value: &str, | 
|  | 480 | +    precision: usize, | 
|  | 481 | +) -> Result<BigInt> { | 
|  | 482 | +    if precision > 38 { | 
|  | 483 | +        let max_str = MAX_DECIMAL_FOR_LARGER_PRECISION[precision - 38 - 1]; | 
|  | 484 | +        let min_str = MIN_DECIMAL_FOR_LARGER_PRECISION[precision - 38 - 1]; | 
|  | 485 | + | 
|  | 486 | +        let max = BigInt::from_str_radix(max_str, 10).unwrap(); | 
|  | 487 | +        let min = BigInt::from_str_radix(min_str, 10).unwrap(); | 
|  | 488 | + | 
|  | 489 | +        let value = BigInt::from_str_radix(value, 10).unwrap(); | 
|  | 490 | +        if value > max { | 
|  | 491 | +            Err(ArrowError::InvalidArgumentError(format!( | 
|  | 492 | +                "{} is too large to store in a Decimal256 of precision {}. Max is {}", | 
|  | 493 | +                value, precision, max | 
|  | 494 | +            ))) | 
|  | 495 | +        } else if value < min { | 
|  | 496 | +            Err(ArrowError::InvalidArgumentError(format!( | 
|  | 497 | +                "{} is too small to store in a Decimal256 of precision {}. Min is {}", | 
|  | 498 | +                value, precision, min | 
|  | 499 | +            ))) | 
|  | 500 | +        } else { | 
|  | 501 | +            Ok(value) | 
|  | 502 | +        } | 
|  | 503 | +    } else { | 
|  | 504 | +        let max = MAX_DECIMAL_FOR_EACH_PRECISION[precision - 1]; | 
|  | 505 | +        let min = MIN_DECIMAL_FOR_EACH_PRECISION[precision - 1]; | 
|  | 506 | +        let value = BigInt::from_str_radix(value, 10).unwrap(); | 
|  | 507 | + | 
|  | 508 | +        if value.to_i128().unwrap() > max { | 
|  | 509 | +            Err(ArrowError::InvalidArgumentError(format!( | 
|  | 510 | +                "{} is too large to store in a Decimal256 of precision {}. Max is {}", | 
|  | 511 | +                value, precision, max | 
|  | 512 | +            ))) | 
|  | 513 | +        } else if value.to_i128().unwrap() < min { | 
|  | 514 | +            Err(ArrowError::InvalidArgumentError(format!( | 
|  | 515 | +                "{} is too small to store in a Decimal256 of precision {}. Min is {}", | 
|  | 516 | +                value, precision, min | 
|  | 517 | +            ))) | 
|  | 518 | +        } else { | 
|  | 519 | +            Ok(value) | 
|  | 520 | +        } | 
|  | 521 | +    } | 
|  | 522 | +} | 
|  | 523 | + | 
| 382 | 524 | impl DataType { | 
| 383 | 525 |     /// Parse a data type from a JSON representation. | 
| 384 | 526 |     pub(crate) fn from(json: &Value) -> Result<DataType> { | 
|  | 
0 commit comments