1use arrow_array::ArrowNativeTypeOp;
22use arrow_array::timezone::Tz;
23use arrow_array::types::*;
24use arrow_buffer::ArrowNativeType;
25use arrow_schema::ArrowError;
26use chrono::prelude::*;
27use half::f16;
28use std::str::FromStr;
29
30#[inline]
32fn parse_nanos<const N: usize, const O: u8>(digits: &[u8]) -> u32 {
33 digits[..N]
34 .iter()
35 .fold(0_u32, |acc, v| acc * 10 + v.wrapping_sub(O) as u32)
36 * 10_u32.pow((9 - N) as _)
37}
38
39struct TimestampParser {
41 digits: [u8; 32],
45 mask: u32,
47}
48
49impl TimestampParser {
50 fn new(bytes: &[u8]) -> Self {
51 let mut digits = [0; 32];
52 let mut mask = 0;
53
54 for (idx, (o, i)) in digits.iter_mut().zip(bytes).enumerate() {
56 *o = i.wrapping_sub(b'0');
57 mask |= ((*o < 10) as u32) << idx
58 }
59
60 Self { digits, mask }
61 }
62
63 fn test(&self, idx: usize, b: u8) -> bool {
65 self.digits[idx] == b.wrapping_sub(b'0')
66 }
67
68 fn date(&self) -> Option<NaiveDate> {
70 if self.mask & 0b1111111111 != 0b1101101111 || !self.test(4, b'-') || !self.test(7, b'-') {
71 return None;
72 }
73
74 let year = self.digits[0] as u16 * 1000
75 + self.digits[1] as u16 * 100
76 + self.digits[2] as u16 * 10
77 + self.digits[3] as u16;
78
79 let month = self.digits[5] * 10 + self.digits[6];
80 let day = self.digits[8] * 10 + self.digits[9];
81
82 NaiveDate::from_ymd_opt(year as _, month as _, day as _)
83 }
84
85 fn time(&self) -> Option<(NaiveTime, usize)> {
94 let time = |hour, min, sec, nano| match sec {
96 60 => {
97 let nano = 1_000_000_000 + nano;
98 NaiveTime::from_hms_nano_opt(hour as _, min as _, 59, nano)
99 }
100 _ => NaiveTime::from_hms_nano_opt(hour as _, min as _, sec as _, nano),
101 };
102
103 match (self.mask >> 11) & 0b11111111 {
104 0b11011011 if self.test(13, b':') && self.test(16, b':') => {
106 let hour = self.digits[11] * 10 + self.digits[12];
107 let minute = self.digits[14] * 10 + self.digits[15];
108 let second = self.digits[17] * 10 + self.digits[18];
109
110 match self.test(19, b'.') {
111 true => {
112 let digits = (self.mask >> 20).trailing_ones();
113 let nanos = match digits {
114 0 => return None,
115 1 => parse_nanos::<1, 0>(&self.digits[20..21]),
116 2 => parse_nanos::<2, 0>(&self.digits[20..22]),
117 3 => parse_nanos::<3, 0>(&self.digits[20..23]),
118 4 => parse_nanos::<4, 0>(&self.digits[20..24]),
119 5 => parse_nanos::<5, 0>(&self.digits[20..25]),
120 6 => parse_nanos::<6, 0>(&self.digits[20..26]),
121 7 => parse_nanos::<7, 0>(&self.digits[20..27]),
122 8 => parse_nanos::<8, 0>(&self.digits[20..28]),
123 _ => parse_nanos::<9, 0>(&self.digits[20..29]),
124 };
125 Some((time(hour, minute, second, nanos)?, 20 + digits as usize))
126 }
127 false => Some((time(hour, minute, second, 0)?, 19)),
128 }
129 }
130 0b111111 => {
132 let hour = self.digits[11] * 10 + self.digits[12];
133 let minute = self.digits[13] * 10 + self.digits[14];
134 let second = self.digits[15] * 10 + self.digits[16];
135 let time = time(hour, minute, second, 0)?;
136 Some((time, 17))
137 }
138 _ => None,
139 }
140 }
141}
142
143pub fn string_to_datetime<T: TimeZone>(timezone: &T, s: &str) -> Result<DateTime<T>, ArrowError> {
177 let err =
178 |ctx: &str| ArrowError::ParseError(format!("Error parsing timestamp from '{s}': {ctx}"));
179
180 let bytes = s.as_bytes();
181 if bytes.len() < 10 {
182 return Err(err("timestamp must contain at least 10 characters"));
183 }
184
185 let parser = TimestampParser::new(bytes);
186 let date = parser.date().ok_or_else(|| err("error parsing date"))?;
187 if bytes.len() == 10 {
188 let datetime = date.and_time(NaiveTime::MIN);
189 return timezone
190 .from_local_datetime(&datetime)
191 .single()
192 .ok_or_else(|| err("error computing timezone offset"));
193 }
194
195 if !parser.test(10, b'T') && !parser.test(10, b't') && !parser.test(10, b' ') {
196 return Err(err("invalid timestamp separator"));
197 }
198
199 let (time, mut tz_offset) = parser.time().ok_or_else(|| err("error parsing time"))?;
200 let datetime = date.and_time(time);
201
202 if tz_offset == 32 {
203 while tz_offset < bytes.len() && bytes[tz_offset].is_ascii_digit() {
205 tz_offset += 1;
206 }
207 }
208
209 if bytes.len() <= tz_offset {
210 return timezone
211 .from_local_datetime(&datetime)
212 .single()
213 .ok_or_else(|| err("error computing timezone offset"));
214 }
215
216 if (bytes[tz_offset] == b'z' || bytes[tz_offset] == b'Z') && tz_offset == bytes.len() - 1 {
217 return Ok(timezone.from_utc_datetime(&datetime));
218 }
219
220 let parsed_tz: Tz = s[tz_offset..].trim_start().parse()?;
222 let parsed = parsed_tz
223 .from_local_datetime(&datetime)
224 .single()
225 .ok_or_else(|| err("error computing timezone offset"))?;
226
227 Ok(parsed.with_timezone(timezone))
228}
229
230#[inline]
272pub fn string_to_timestamp_nanos(s: &str) -> Result<i64, ArrowError> {
273 to_timestamp_nanos(string_to_datetime(&Utc, s)?.naive_utc())
274}
275
276#[inline]
278fn to_timestamp_nanos(dt: NaiveDateTime) -> Result<i64, ArrowError> {
279 dt.and_utc()
280 .timestamp_nanos_opt()
281 .ok_or_else(|| ArrowError::ParseError(ERR_NANOSECONDS_NOT_SUPPORTED.to_string()))
282}
283
284pub fn string_to_time_nanoseconds(s: &str) -> Result<i64, ArrowError> {
300 let nt = string_to_time(s)
301 .ok_or_else(|| ArrowError::ParseError(format!("Failed to parse \'{s}\' as time")))?;
302 Ok(nt.num_seconds_from_midnight() as i64 * 1_000_000_000 + nt.nanosecond() as i64)
303}
304
305fn string_to_time(s: &str) -> Option<NaiveTime> {
306 let bytes = s.as_bytes();
307 if bytes.len() < 4 {
308 return None;
309 }
310
311 let (am, bytes) = match bytes.get(bytes.len() - 3..) {
312 Some(b" AM" | b" am" | b" Am" | b" aM") => (Some(true), &bytes[..bytes.len() - 3]),
313 Some(b" PM" | b" pm" | b" pM" | b" Pm") => (Some(false), &bytes[..bytes.len() - 3]),
314 _ => (None, bytes),
315 };
316
317 if bytes.len() < 4 {
318 return None;
319 }
320
321 let mut digits = [b'0'; 6];
322
323 let bytes = match (bytes[1], bytes[2]) {
325 (b':', _) => {
326 digits[1] = bytes[0];
327 &bytes[2..]
328 }
329 (_, b':') => {
330 digits[0] = bytes[0];
331 digits[1] = bytes[1];
332 &bytes[3..]
333 }
334 _ => return None,
335 };
336
337 if bytes.len() < 2 {
338 return None; }
340
341 digits[2] = bytes[0];
343 digits[3] = bytes[1];
344
345 let nanoseconds = match bytes.get(2) {
346 Some(b':') => {
347 if bytes.len() < 5 {
348 return None;
349 }
350
351 digits[4] = bytes[3];
353 digits[5] = bytes[4];
354
355 match bytes.get(5) {
357 Some(b'.') => {
358 let decimal = &bytes[6..];
359 if decimal.iter().any(|x| !x.is_ascii_digit()) {
360 return None;
361 }
362 match decimal.len() {
363 0 => return None,
364 1 => parse_nanos::<1, b'0'>(decimal),
365 2 => parse_nanos::<2, b'0'>(decimal),
366 3 => parse_nanos::<3, b'0'>(decimal),
367 4 => parse_nanos::<4, b'0'>(decimal),
368 5 => parse_nanos::<5, b'0'>(decimal),
369 6 => parse_nanos::<6, b'0'>(decimal),
370 7 => parse_nanos::<7, b'0'>(decimal),
371 8 => parse_nanos::<8, b'0'>(decimal),
372 _ => parse_nanos::<9, b'0'>(decimal),
373 }
374 }
375 Some(_) => return None,
376 None => 0,
377 }
378 }
379 Some(_) => return None,
380 None => 0,
381 };
382
383 digits.iter_mut().for_each(|x| *x = x.wrapping_sub(b'0'));
384 if digits.iter().any(|x| *x > 9) {
385 return None;
386 }
387
388 let hour = match (digits[0] * 10 + digits[1], am) {
389 (12, Some(true)) => 0, (h @ 1..=11, Some(true)) => h, (12, Some(false)) => 12, (h @ 1..=11, Some(false)) => h + 12, (_, Some(_)) => return None,
394 (h, None) => h,
395 };
396
397 let (second, nanoseconds) = match digits[4] * 10 + digits[5] {
399 60 => (59, nanoseconds + 1_000_000_000),
400 s => (s, nanoseconds),
401 };
402
403 NaiveTime::from_hms_nano_opt(
404 hour as _,
405 (digits[2] * 10 + digits[3]) as _,
406 second as _,
407 nanoseconds,
408 )
409}
410
411pub trait Parser: ArrowPrimitiveType {
435 fn parse(string: &str) -> Option<Self::Native>;
437
438 fn parse_formatted(string: &str, _format: &str) -> Option<Self::Native> {
442 Self::parse(string)
443 }
444}
445
446impl Parser for Float16Type {
447 fn parse(string: &str) -> Option<f16> {
448 if let Ok(raw_float) = lexical_core::parse(string.as_bytes()) {
449 return Some(f16::from_f32(raw_float));
450 }
451 let string = trim_pre_and_post_whitespace(string);
452 lexical_core::parse(string.as_bytes())
453 .ok()
454 .map(f16::from_f32)
455 }
456}
457
458impl Parser for Float32Type {
459 fn parse(string: &str) -> Option<f32> {
460 if let Ok(raw_float) = lexical_core::parse(string.as_bytes()) {
461 return Some(raw_float);
462 }
463 let string = trim_pre_and_post_whitespace(string);
464 lexical_core::parse(string.as_bytes()).ok()
465 }
466}
467
468impl Parser for Float64Type {
469 fn parse(string: &str) -> Option<f64> {
470 if let Ok(raw_float) = lexical_core::parse(string.as_bytes()) {
471 return Some(raw_float);
472 }
473 let string = trim_pre_and_post_whitespace(string);
474 lexical_core::parse(string.as_bytes()).ok()
475 }
476}
477
478#[inline]
480fn trim_pre_and_post_whitespace(string: &str) -> &str {
481 let bytes = string.as_bytes();
482 let prefix = bytes.first().is_some_and(|b| !b.is_ascii_digit());
483 let suffix = bytes.last().is_some_and(|b| !b.is_ascii_digit());
484 match (prefix, suffix) {
485 (false, false) => string,
486 (true, false) => string.trim_ascii_start(),
487 (false, true) => string.trim_ascii_end(),
488 (true, true) => string.trim_ascii(),
489 }
490}
491
492macro_rules! parser_primitive {
493 ($t:ty) => {
494 impl Parser for $t {
495 fn parse(string: &str) -> Option<Self::Native> {
496 let mut raw_bytes = string.as_bytes();
497 if !raw_bytes.last().is_some_and(|x| x.is_ascii_digit()) {
498 raw_bytes = raw_bytes.trim_ascii_end();
499 if !raw_bytes.last().is_some_and(|x| x.is_ascii_digit()) {
500 return None;
501 }
502 }
503 match atoi::FromRadix10SignedChecked::from_radix_10_signed_checked(raw_bytes) {
504 (Some(n), x) if x == raw_bytes.len() => Some(n),
505 _ => {
506 let trimmed = raw_bytes.trim_ascii_start();
507 match atoi::FromRadix10SignedChecked::from_radix_10_signed_checked(trimmed)
508 {
509 (Some(n), x) if x == trimmed.len() => Some(n),
510 _ => None,
511 }
512 }
513 }
514 }
515 }
516 };
517}
518parser_primitive!(UInt64Type);
519parser_primitive!(UInt32Type);
520parser_primitive!(UInt16Type);
521parser_primitive!(UInt8Type);
522parser_primitive!(Int64Type);
523parser_primitive!(Int32Type);
524parser_primitive!(Int16Type);
525parser_primitive!(Int8Type);
526parser_primitive!(DurationNanosecondType);
527parser_primitive!(DurationMicrosecondType);
528parser_primitive!(DurationMillisecondType);
529parser_primitive!(DurationSecondType);
530
531impl Parser for TimestampNanosecondType {
532 fn parse(string: &str) -> Option<i64> {
533 string_to_timestamp_nanos(string).ok()
534 }
535}
536
537impl Parser for TimestampMicrosecondType {
538 fn parse(string: &str) -> Option<i64> {
539 let nanos = string_to_timestamp_nanos(string).ok();
540 nanos.map(|x| x / 1000)
541 }
542}
543
544impl Parser for TimestampMillisecondType {
545 fn parse(string: &str) -> Option<i64> {
546 let nanos = string_to_timestamp_nanos(string).ok();
547 nanos.map(|x| x / 1_000_000)
548 }
549}
550
551impl Parser for TimestampSecondType {
552 fn parse(string: &str) -> Option<i64> {
553 let nanos = string_to_timestamp_nanos(string).ok();
554 nanos.map(|x| x / 1_000_000_000)
555 }
556}
557
558impl Parser for Time64NanosecondType {
559 fn parse(string: &str) -> Option<Self::Native> {
561 string_to_time_nanoseconds(string)
562 .ok()
563 .or_else(|| string.parse::<Self::Native>().ok())
564 }
565
566 fn parse_formatted(string: &str, format: &str) -> Option<Self::Native> {
567 let nt = NaiveTime::parse_from_str(string, format).ok()?;
568 Some(nt.num_seconds_from_midnight() as i64 * 1_000_000_000 + nt.nanosecond() as i64)
569 }
570}
571
572impl Parser for Time64MicrosecondType {
573 fn parse(string: &str) -> Option<Self::Native> {
575 string_to_time_nanoseconds(string)
576 .ok()
577 .map(|nanos| nanos / 1_000)
578 .or_else(|| string.parse::<Self::Native>().ok())
579 }
580
581 fn parse_formatted(string: &str, format: &str) -> Option<Self::Native> {
582 let nt = NaiveTime::parse_from_str(string, format).ok()?;
583 Some(nt.num_seconds_from_midnight() as i64 * 1_000_000 + nt.nanosecond() as i64 / 1_000)
584 }
585}
586
587impl Parser for Time32MillisecondType {
588 fn parse(string: &str) -> Option<Self::Native> {
590 string_to_time_nanoseconds(string)
591 .ok()
592 .map(|nanos| (nanos / 1_000_000) as i32)
593 .or_else(|| string.parse::<Self::Native>().ok())
594 }
595
596 fn parse_formatted(string: &str, format: &str) -> Option<Self::Native> {
597 let nt = NaiveTime::parse_from_str(string, format).ok()?;
598 Some(nt.num_seconds_from_midnight() as i32 * 1_000 + nt.nanosecond() as i32 / 1_000_000)
599 }
600}
601
602impl Parser for Time32SecondType {
603 fn parse(string: &str) -> Option<Self::Native> {
605 string_to_time_nanoseconds(string)
606 .ok()
607 .map(|nanos| (nanos / 1_000_000_000) as i32)
608 .or_else(|| string.parse::<Self::Native>().ok())
609 }
610
611 fn parse_formatted(string: &str, format: &str) -> Option<Self::Native> {
612 let nt = NaiveTime::parse_from_str(string, format).ok()?;
613 Some(nt.num_seconds_from_midnight() as i32 + nt.nanosecond() as i32 / 1_000_000_000)
614 }
615}
616
617const EPOCH_DAYS_FROM_CE: i32 = 719_163;
619
620const ERR_NANOSECONDS_NOT_SUPPORTED: &str = "The dates that can be represented as nanoseconds have to be between 1677-09-21T00:12:44.0 and 2262-04-11T23:47:16.854775804";
622
623fn parse_extended_ymd(string: &str) -> Option<(i32, u32, u32)> {
630 debug_assert!(string.starts_with('+') || string.starts_with('-'));
631 let rest = &string[1..];
634 let hyphen = rest.find('-')?;
635 if hyphen < 4 {
636 return None;
637 }
638 let year: i32 = string[..hyphen + 1].parse().ok()?;
641 let remainder = string[hyphen + 1..].strip_prefix('-')?;
643 let mut parts = remainder.splitn(2, '-');
644 let month: u32 = parts.next()?.parse().ok()?;
645 let day: u32 = parts.next()?.parse().ok()?;
646 Some((year, month, day))
647}
648
649fn parse_date(string: &str) -> Option<NaiveDate> {
650 if string.starts_with('+') || string.starts_with('-') {
658 let (year, month, day) = parse_extended_ymd(string)?;
659 return NaiveDate::from_ymd_opt(year, month, day);
660 }
661
662 if string.len() > 10 {
663 return string_to_datetime(&Utc, string)
665 .map(|dt| dt.date_naive())
666 .ok();
667 }
668 let mut digits = [0; 10];
669 let mut mask = 0;
670
671 for (idx, (o, i)) in digits.iter_mut().zip(string.bytes()).enumerate() {
673 *o = i.wrapping_sub(b'0');
674 mask |= ((*o < 10) as u16) << idx
675 }
676
677 const HYPHEN: u8 = b'-'.wrapping_sub(b'0');
678
679 if digits[4] != HYPHEN {
681 let (year, month, day) = match (mask, string.len()) {
682 (0b11111111, 8) => (
683 digits[0] as u16 * 1000
684 + digits[1] as u16 * 100
685 + digits[2] as u16 * 10
686 + digits[3] as u16,
687 digits[4] * 10 + digits[5],
688 digits[6] * 10 + digits[7],
689 ),
690 _ => return None,
691 };
692 return NaiveDate::from_ymd_opt(year as _, month as _, day as _);
693 }
694
695 let (month, day) = match mask {
696 0b1101101111 => {
697 if digits[7] != HYPHEN {
698 return None;
699 }
700 (digits[5] * 10 + digits[6], digits[8] * 10 + digits[9])
701 }
702 0b101101111 => {
703 if digits[7] != HYPHEN {
704 return None;
705 }
706 (digits[5] * 10 + digits[6], digits[8])
707 }
708 0b110101111 => {
709 if digits[6] != HYPHEN {
710 return None;
711 }
712 (digits[5], digits[7] * 10 + digits[8])
713 }
714 0b10101111 => {
715 if digits[6] != HYPHEN {
716 return None;
717 }
718 (digits[5], digits[7])
719 }
720 _ => return None,
721 };
722
723 let year =
724 digits[0] as u16 * 1000 + digits[1] as u16 * 100 + digits[2] as u16 * 10 + digits[3] as u16;
725
726 NaiveDate::from_ymd_opt(year as _, month as _, day as _)
727}
728
729fn parse_date_to_days(string: &str) -> Option<i32> {
738 if string.starts_with('+') || string.starts_with('-') {
739 let (year, month, day) = parse_extended_ymd(string)?;
740 let y = year as i64;
741 let era = y.div_euclid(400);
742 let yoe = y.rem_euclid(400) as i32;
743 let naive_date = NaiveDate::from_ymd_opt(yoe, month, day)?;
744 let in_era = (naive_date.num_days_from_ce() - EPOCH_DAYS_FROM_CE) as i64;
745 return i32::try_from(era * 146_097 + in_era).ok();
746 }
747 parse_date(string).map(|naive_date| naive_date.num_days_from_ce() - EPOCH_DAYS_FROM_CE)
748}
749
750impl Parser for Date32Type {
751 fn parse(string: &str) -> Option<i32> {
752 parse_date_to_days(string)
753 }
754
755 fn parse_formatted(string: &str, format: &str) -> Option<i32> {
756 let date = NaiveDate::parse_from_str(string, format).ok()?;
757 Some(date.num_days_from_ce() - EPOCH_DAYS_FROM_CE)
758 }
759}
760
761impl Parser for Date64Type {
762 fn parse(string: &str) -> Option<i64> {
763 if string.len() <= 10 {
764 let datetime = NaiveDateTime::new(parse_date(string)?, NaiveTime::default());
765 Some(datetime.and_utc().timestamp_millis())
766 } else {
767 let date_time = string_to_datetime(&Utc, string).ok()?;
768 Some(date_time.timestamp_millis())
769 }
770 }
771
772 fn parse_formatted(string: &str, format: &str) -> Option<i64> {
773 use chrono::format::Fixed;
774 use chrono::format::StrftimeItems;
775 let fmt = StrftimeItems::new(format);
776 let has_zone = fmt.into_iter().any(|item| match item {
777 chrono::format::Item::Fixed(fixed_item) => matches!(
778 fixed_item,
779 Fixed::RFC2822
780 | Fixed::RFC3339
781 | Fixed::TimezoneName
782 | Fixed::TimezoneOffsetColon
783 | Fixed::TimezoneOffsetColonZ
784 | Fixed::TimezoneOffset
785 | Fixed::TimezoneOffsetZ
786 ),
787 _ => false,
788 });
789 if has_zone {
790 let date_time = chrono::DateTime::parse_from_str(string, format).ok()?;
791 Some(date_time.timestamp_millis())
792 } else {
793 let date_time = NaiveDateTime::parse_from_str(string, format).ok()?;
794 Some(date_time.and_utc().timestamp_millis())
795 }
796 }
797}
798
799pub fn parse_decimal<T: DecimalType>(
832 s: &str,
833 precision: u8,
834 scale: i8,
835) -> Result<T::Native, ArrowError> {
836 parse_decimal_checked::<T>(s, precision, scale).map_err(|e| match e {
837 DecimalParseError::Overflow => ArrowError::ParseError(format!(
838 "{s:?} does not fit in {}({precision}, {scale})",
839 T::PREFIX
840 )),
841 DecimalParseError::InvalidFormat => {
842 ArrowError::ParseError(format!("Invalid decimal format: {s:?}"))
843 }
844 })
845}
846
847#[derive(Debug, Clone, Copy, PartialEq, Eq)]
849pub(crate) enum DecimalParseError {
850 InvalidFormat,
852 Overflow,
854}
855
856pub(crate) fn parse_decimal_checked<T: DecimalType>(
860 s: &str,
861 precision: u8,
862 scale: i8,
863) -> Result<T::Native, DecimalParseError> {
864 let (value, digits) = parse_decimal_native::<T>(s, scale)?;
865 let fits = precision <= T::MAX_PRECISION
868 && (digits <= precision as usize || T::is_valid_decimal_precision(value, precision));
869 if fits {
870 Ok(value)
871 } else {
872 Err(DecimalParseError::Overflow)
873 }
874}
875
876#[inline]
882fn parse_decimal_native<T: DecimalType>(
883 s: &str,
884 scale: i8,
885) -> Result<(T::Native, usize), DecimalParseError> {
886 let bytes = s.as_bytes().trim_ascii();
887 let (negative, mut mantissa) = split_sign(bytes);
888
889 let mut scale = scale as i64;
890 loop {
891 let exponent_at = match parse_decimal_mantissa::<T>(mantissa, negative, scale) {
892 Ok(result) => return Ok(result),
893 Err(MantissaError::InvalidFormat) => return Err(DecimalParseError::InvalidFormat),
894 Err(MantissaError::Exponent(index)) => index,
895 Err(MantissaError::Overflow) => mantissa
899 .iter()
900 .position(|b| matches!(b, b'e' | b'E'))
901 .ok_or(DecimalParseError::Overflow)?,
902 };
903
904 let exponent = parse_decimal_exponent(&mantissa[exponent_at + 1..])?;
908 scale = scale.saturating_add(exponent);
909
910 mantissa = &mantissa[..exponent_at];
912 }
913}
914
915enum MantissaError {
917 InvalidFormat,
919 Overflow,
921 Exponent(usize),
923}
924
925impl From<DecimalParseError> for MantissaError {
926 fn from(e: DecimalParseError) -> Self {
927 match e {
928 DecimalParseError::InvalidFormat => Self::InvalidFormat,
929 DecimalParseError::Overflow => Self::Overflow,
930 }
931 }
932}
933
934const MAX_CHUNK_DIGITS: usize = 18;
939
940#[inline]
947fn parse_decimal_mantissa<T: DecimalType>(
948 mantissa: &[u8],
949 negative: bool,
950 scale: i64,
951) -> Result<(T::Native, usize), MantissaError> {
952 let (int_keep, frac_keep, mut round) = if scale >= 0 {
957 (
958 usize::MAX,
959 usize::try_from(scale).unwrap_or(usize::MAX),
960 true,
961 )
962 } else {
963 let int_digits = mantissa.iter().take_while(|b| b.is_ascii_digit()).count();
964 match usize::try_from(int_digits as i64 + scale) {
965 Ok(keep) => (keep, 0, true),
966 Err(_) => (0, 0, false),
970 }
971 };
972
973 let mut acc = DecimalAccumulator::<T> {
974 value: T::Native::ZERO,
975 chunk: 0,
976 chunk_len: 0,
977 negative,
978 };
979 let mut int_kept = 0_usize;
980 let mut frac_kept = 0_usize;
981 let mut first_discarded_digit = None;
982
983 let mut index = 0;
985 while let Some(&b) = mantissa.get(index) {
986 if !b.is_ascii_digit() {
987 break;
988 }
989 if int_kept < int_keep {
990 int_kept += 1;
991 acc.push(b - b'0')?;
992 } else {
993 first_discarded_digit.get_or_insert(b - b'0');
994 }
995 index += 1;
996 }
997
998 if mantissa.get(index) == Some(&b'.') {
1000 index += 1;
1001 while let Some(&b) = mantissa.get(index) {
1002 if !b.is_ascii_digit() {
1003 break;
1004 }
1005 if frac_kept < frac_keep {
1006 frac_kept += 1;
1007 acc.push(b - b'0')?;
1008 } else {
1009 first_discarded_digit.get_or_insert(b - b'0');
1010 }
1011 index += 1;
1012 }
1013 }
1014
1015 match mantissa.get(index) {
1016 None => {}
1017 Some(b'e' | b'E') => return Err(MantissaError::Exponent(index)),
1018 Some(_) => return Err(MantissaError::InvalidFormat),
1019 }
1020
1021 if int_kept == 0 && frac_kept == 0 && first_discarded_digit.is_none() {
1022 return Err(MantissaError::InvalidFormat);
1023 }
1024
1025 let mut value = acc.finish()?;
1026
1027 let missing = scale - frac_kept as i64;
1031 if missing > 0 && !value.is_zero() {
1032 value = value
1033 .mul_checked(decimal_pow::<T>(missing)?)
1034 .map_err(|_| MantissaError::Overflow)?;
1035 }
1036
1037 round &= first_discarded_digit.is_some_and(|digit| digit >= 5);
1038 if round {
1039 value = if negative {
1040 value.sub_checked(T::Native::ONE)
1041 } else {
1042 value.add_checked(T::Native::ONE)
1043 }
1044 .map_err(|_| MantissaError::Overflow)?;
1045 }
1046
1047 let digits = usize::try_from(missing.max(0))
1048 .unwrap_or(usize::MAX)
1049 .saturating_add(int_kept + frac_kept + round as usize);
1050 Ok((value, digits))
1051}
1052
1053fn parse_decimal_exponent(exponent: &[u8]) -> Result<i64, DecimalParseError> {
1057 let (negative, digits) = split_sign(exponent);
1058 if digits.is_empty() {
1059 return Err(DecimalParseError::InvalidFormat);
1060 }
1061 let mut value = 0_i64;
1062 for &b in digits {
1063 if !b.is_ascii_digit() {
1064 return Err(DecimalParseError::InvalidFormat);
1065 }
1066 value = value.saturating_mul(10).saturating_add((b - b'0') as i64);
1067 }
1068 Ok(if negative { -value } else { value })
1069}
1070
1071#[inline]
1074fn split_sign(bytes: &[u8]) -> (bool, &[u8]) {
1075 match bytes.first() {
1076 Some(b'-') => (true, &bytes[1..]),
1077 Some(b'+') => (false, &bytes[1..]),
1078 _ => (false, bytes),
1079 }
1080}
1081
1082struct DecimalAccumulator<T: DecimalType> {
1085 value: T::Native,
1086 chunk: u64,
1087 chunk_len: usize,
1088 negative: bool,
1089}
1090
1091impl<T: DecimalType> DecimalAccumulator<T> {
1092 #[inline(always)]
1093 fn push(&mut self, digit: u8) -> Result<(), DecimalParseError> {
1094 self.chunk = self.chunk * 10 + digit as u64;
1097 self.chunk_len += 1;
1098 if self.chunk_len == MAX_CHUNK_DIGITS {
1099 self.value =
1100 fold_decimal_chunk::<T>(self.value, self.chunk, self.chunk_len, self.negative)?;
1101 self.chunk = 0;
1102 self.chunk_len = 0;
1103 }
1104 Ok(())
1105 }
1106
1107 #[inline]
1109 fn finish(self) -> Result<T::Native, DecimalParseError> {
1110 if self.chunk_len == 0 {
1111 return Ok(self.value);
1112 }
1113 fold_decimal_chunk::<T>(self.value, self.chunk, self.chunk_len, self.negative)
1114 }
1115}
1116
1117#[inline(always)]
1121fn fold_decimal_chunk<T: DecimalType>(
1122 value: T::Native,
1123 chunk: u64,
1124 chunk_len: usize,
1125 negative: bool,
1126) -> Result<T::Native, DecimalParseError> {
1127 let chunk = decimal_chunk_to_native::<T>(chunk, negative)?;
1128
1129 if value.is_zero() {
1133 return Ok(chunk);
1134 }
1135
1136 value
1137 .mul_checked(decimal_pow::<T>(chunk_len as i64)?)
1138 .map_err(|_| DecimalParseError::Overflow)?
1139 .add_checked(chunk)
1140 .map_err(|_| DecimalParseError::Overflow)
1141}
1142
1143#[inline]
1146fn decimal_chunk_to_native<T: DecimalType>(
1147 chunk: u64,
1148 negative: bool,
1149) -> Result<T::Native, DecimalParseError> {
1150 const HALF: u64 = 1_000_000_000;
1154 if chunk < HALF || (T::MAX_PRECISION as usize >= MAX_CHUNK_DIGITS && usize::BITS >= 64) {
1155 let chunk = T::Native::usize_as(chunk as usize);
1156 return Ok(if negative {
1160 T::Native::ZERO.sub_wrapping(chunk)
1161 } else {
1162 chunk
1163 });
1164 }
1165 let low = T::Native::usize_as((chunk % HALF) as usize);
1167 let high = T::Native::usize_as((chunk / HALF) as usize)
1168 .mul_checked(T::Native::usize_as(HALF as usize))
1169 .map_err(|_| DecimalParseError::Overflow)?;
1170 if negative {
1174 T::Native::ZERO
1175 .sub_checked(high)
1176 .map_err(|_| DecimalParseError::Overflow)?
1177 .sub_checked(low)
1178 .map_err(|_| DecimalParseError::Overflow)
1179 } else {
1180 high.add_checked(low)
1181 .map_err(|_| DecimalParseError::Overflow)
1182 }
1183}
1184
1185#[inline]
1188fn decimal_pow<T: DecimalType>(exp: i64) -> Result<T::Native, DecimalParseError> {
1189 usize::try_from(exp)
1193 .ok()
1194 .and_then(|exp| T::MAX_FOR_EACH_PRECISION.get(exp))
1195 .map(|max| max.add_wrapping(T::Native::ONE))
1196 .ok_or(DecimalParseError::Overflow)
1197}
1198
1199pub fn parse_interval_year_month(
1201 value: &str,
1202) -> Result<<IntervalYearMonthType as ArrowPrimitiveType>::Native, ArrowError> {
1203 let config = IntervalParseConfig::new(IntervalUnit::Year);
1204 let interval = Interval::parse(value, &config)?;
1205
1206 let months = interval.to_year_months().map_err(|_| {
1207 ArrowError::CastError(format!(
1208 "Cannot cast {value} to IntervalYearMonth. Only year and month fields are allowed."
1209 ))
1210 })?;
1211
1212 Ok(IntervalYearMonthType::make_value(0, months))
1213}
1214
1215pub fn parse_interval_day_time(
1217 value: &str,
1218) -> Result<<IntervalDayTimeType as ArrowPrimitiveType>::Native, ArrowError> {
1219 let config = IntervalParseConfig::new(IntervalUnit::Day);
1220 let interval = Interval::parse(value, &config)?;
1221
1222 let (days, millis) = interval.to_day_time().map_err(|_| ArrowError::CastError(format!(
1223 "Cannot cast {value} to IntervalDayTime because the nanos part isn't multiple of milliseconds"
1224 )))?;
1225
1226 Ok(IntervalDayTimeType::make_value(days, millis))
1227}
1228
1229pub fn parse_interval_month_day_nano_config(
1231 value: &str,
1232 config: IntervalParseConfig,
1233) -> Result<<IntervalMonthDayNanoType as ArrowPrimitiveType>::Native, ArrowError> {
1234 let interval = Interval::parse(value, &config)?;
1235
1236 let (months, days, nanos) = interval.to_month_day_nanos();
1237
1238 Ok(IntervalMonthDayNanoType::make_value(months, days, nanos))
1239}
1240
1241pub fn parse_interval_month_day_nano(
1243 value: &str,
1244) -> Result<<IntervalMonthDayNanoType as ArrowPrimitiveType>::Native, ArrowError> {
1245 parse_interval_month_day_nano_config(value, IntervalParseConfig::new(IntervalUnit::Month))
1246}
1247
1248const NANOS_PER_MILLIS: i64 = 1_000_000;
1249const NANOS_PER_SECOND: i64 = 1_000 * NANOS_PER_MILLIS;
1250const NANOS_PER_MINUTE: i64 = 60 * NANOS_PER_SECOND;
1251const NANOS_PER_HOUR: i64 = 60 * NANOS_PER_MINUTE;
1252#[cfg(test)]
1253const NANOS_PER_DAY: i64 = 24 * NANOS_PER_HOUR;
1254
1255#[derive(Debug, Clone)]
1259pub struct IntervalParseConfig {
1260 default_unit: IntervalUnit,
1263}
1264
1265impl IntervalParseConfig {
1266 pub fn new(default_unit: IntervalUnit) -> Self {
1268 Self { default_unit }
1269 }
1270}
1271
1272#[rustfmt::skip]
1273#[derive(Debug, Clone, Copy)]
1274#[repr(u16)]
1275pub enum IntervalUnit {
1278 Century = 0b_0000_0000_0001,
1280 Decade = 0b_0000_0000_0010,
1282 Year = 0b_0000_0000_0100,
1284 Month = 0b_0000_0000_1000,
1286 Week = 0b_0000_0001_0000,
1288 Day = 0b_0000_0010_0000,
1290 Hour = 0b_0000_0100_0000,
1292 Minute = 0b_0000_1000_0000,
1294 Second = 0b_0001_0000_0000,
1296 Millisecond = 0b_0010_0000_0000,
1298 Microsecond = 0b_0100_0000_0000,
1300 Nanosecond = 0b_1000_0000_0000,
1302}
1303
1304impl FromStr for IntervalUnit {
1309 type Err = ArrowError;
1310
1311 fn from_str(s: &str) -> Result<Self, ArrowError> {
1312 match s.to_lowercase().as_str() {
1313 "c" | "cent" | "cents" | "century" | "centuries" => Ok(Self::Century),
1314 "dec" | "decs" | "decade" | "decades" => Ok(Self::Decade),
1315 "y" | "yr" | "yrs" | "year" | "years" => Ok(Self::Year),
1316 "mon" | "mons" | "month" | "months" => Ok(Self::Month),
1317 "w" | "week" | "weeks" => Ok(Self::Week),
1318 "d" | "day" | "days" => Ok(Self::Day),
1319 "h" | "hr" | "hrs" | "hour" | "hours" => Ok(Self::Hour),
1320 "m" | "min" | "mins" | "minute" | "minutes" => Ok(Self::Minute),
1321 "s" | "sec" | "secs" | "second" | "seconds" => Ok(Self::Second),
1322 "ms" | "msec" | "msecs" | "msecond" | "mseconds" | "millisecond" | "milliseconds" => {
1323 Ok(Self::Millisecond)
1324 }
1325 "us" | "usec" | "usecs" | "usecond" | "useconds" | "microsecond" | "microseconds" => {
1326 Ok(Self::Microsecond)
1327 }
1328 "nanosecond" | "nanoseconds" => Ok(Self::Nanosecond),
1329 _ => Err(ArrowError::InvalidArgumentError(format!(
1330 "Unknown interval type: {s}"
1331 ))),
1332 }
1333 }
1334}
1335
1336impl IntervalUnit {
1337 fn from_str_or_config(
1338 s: Option<&str>,
1339 config: &IntervalParseConfig,
1340 ) -> Result<Self, ArrowError> {
1341 match s {
1342 Some(s) => s.parse(),
1343 None => Ok(config.default_unit),
1344 }
1345 }
1346}
1347
1348pub type MonthDayNano = (i32, i32, i64);
1350
1351const INTERVAL_PRECISION: u32 = 15;
1353
1354#[derive(Clone, Copy, Debug, PartialEq)]
1355struct IntervalAmount {
1356 integer: i64,
1358 frac: i64,
1360}
1361
1362#[cfg(test)]
1363impl IntervalAmount {
1364 fn new(integer: i64, frac: i64) -> Self {
1365 Self { integer, frac }
1366 }
1367}
1368
1369impl FromStr for IntervalAmount {
1370 type Err = ArrowError;
1371
1372 fn from_str(s: &str) -> Result<Self, Self::Err> {
1373 match s.split_once('.') {
1374 Some((integer, frac))
1375 if frac.len() <= INTERVAL_PRECISION as usize
1376 && !frac.is_empty()
1377 && !frac.starts_with('-') =>
1378 {
1379 let explicit_neg = integer.starts_with('-');
1382 let integer = if integer.is_empty() || integer == "-" {
1383 Ok(0)
1384 } else {
1385 integer.parse::<i64>().map_err(|_| {
1386 ArrowError::ParseError(format!("Failed to parse {s} as interval amount"))
1387 })
1388 }?;
1389
1390 let frac_unscaled = frac.parse::<i64>().map_err(|_| {
1391 ArrowError::ParseError(format!("Failed to parse {s} as interval amount"))
1392 })?;
1393
1394 let frac = frac_unscaled * 10_i64.pow(INTERVAL_PRECISION - frac.len() as u32);
1396
1397 let frac = if integer < 0 || explicit_neg {
1399 -frac
1400 } else {
1401 frac
1402 };
1403
1404 let result = Self { integer, frac };
1405
1406 Ok(result)
1407 }
1408 Some((_, frac)) if frac.starts_with('-') => Err(ArrowError::ParseError(format!(
1409 "Failed to parse {s} as interval amount"
1410 ))),
1411 Some((_, frac)) if frac.len() > INTERVAL_PRECISION as usize => {
1412 Err(ArrowError::ParseError(format!(
1413 "{s} exceeds the precision available for interval amount"
1414 )))
1415 }
1416 Some(_) | None => {
1417 let integer = s.parse::<i64>().map_err(|_| {
1418 ArrowError::ParseError(format!("Failed to parse {s} as interval amount"))
1419 })?;
1420
1421 let result = Self { integer, frac: 0 };
1422 Ok(result)
1423 }
1424 }
1425 }
1426}
1427
1428#[derive(Debug, Default, PartialEq)]
1429struct Interval {
1430 months: i32,
1431 days: i32,
1432 nanos: i64,
1433}
1434
1435impl Interval {
1436 fn new(months: i32, days: i32, nanos: i64) -> Self {
1437 Self {
1438 months,
1439 days,
1440 nanos,
1441 }
1442 }
1443
1444 fn to_year_months(&self) -> Result<i32, ArrowError> {
1445 match (self.months, self.days, self.nanos) {
1446 (months, days, nanos) if days == 0 && nanos == 0 => Ok(months),
1447 _ => Err(ArrowError::InvalidArgumentError(format!(
1448 "Unable to represent interval with days and nanos as year-months: {self:?}"
1449 ))),
1450 }
1451 }
1452
1453 fn to_day_time(&self) -> Result<(i32, i32), ArrowError> {
1454 let days = self.months.mul_checked(30)?.add_checked(self.days)?;
1455
1456 match self.nanos {
1457 nanos if nanos % NANOS_PER_MILLIS == 0 => {
1458 let millis = (self.nanos / 1_000_000).try_into().map_err(|_| {
1459 ArrowError::InvalidArgumentError(format!(
1460 "Unable to represent {} nanos as milliseconds in a signed 32-bit integer",
1461 self.nanos
1462 ))
1463 })?;
1464
1465 Ok((days, millis))
1466 }
1467 nanos => Err(ArrowError::InvalidArgumentError(format!(
1468 "Unable to represent {nanos} as milliseconds"
1469 ))),
1470 }
1471 }
1472
1473 fn to_month_day_nanos(&self) -> (i32, i32, i64) {
1474 (self.months, self.days, self.nanos)
1475 }
1476
1477 fn parse(value: &str, config: &IntervalParseConfig) -> Result<Self, ArrowError> {
1480 let components = parse_interval_components(value, config)?;
1481
1482 components
1483 .into_iter()
1484 .try_fold(Self::default(), |result, (amount, unit)| {
1485 result.add(amount, unit)
1486 })
1487 }
1488
1489 fn add(&self, amount: IntervalAmount, unit: IntervalUnit) -> Result<Self, ArrowError> {
1496 let result = match unit {
1497 IntervalUnit::Century => {
1498 let months_int = amount.integer.mul_checked(100)?.mul_checked(12)?;
1499 let month_frac = amount.frac * 12 / 10_i64.pow(INTERVAL_PRECISION - 2);
1500 let months = months_int
1501 .add_checked(month_frac)?
1502 .try_into()
1503 .map_err(|_| {
1504 ArrowError::ParseError(format!(
1505 "Unable to represent {} centuries as months in a signed 32-bit integer",
1506 amount.integer
1507 ))
1508 })?;
1509
1510 Self::new(self.months.add_checked(months)?, self.days, self.nanos)
1511 }
1512 IntervalUnit::Decade => {
1513 let months_int = amount.integer.mul_checked(10)?.mul_checked(12)?;
1514
1515 let month_frac = amount.frac * 12 / 10_i64.pow(INTERVAL_PRECISION - 1);
1516 let months = months_int
1517 .add_checked(month_frac)?
1518 .try_into()
1519 .map_err(|_| {
1520 ArrowError::ParseError(format!(
1521 "Unable to represent {} decades as months in a signed 32-bit integer",
1522 amount.integer
1523 ))
1524 })?;
1525
1526 Self::new(self.months.add_checked(months)?, self.days, self.nanos)
1527 }
1528 IntervalUnit::Year => {
1529 let months_int = amount.integer.mul_checked(12)?;
1530 let month_frac = amount.frac * 12 / 10_i64.pow(INTERVAL_PRECISION);
1531 let months = months_int
1532 .add_checked(month_frac)?
1533 .try_into()
1534 .map_err(|_| {
1535 ArrowError::ParseError(format!(
1536 "Unable to represent {} years as months in a signed 32-bit integer",
1537 amount.integer
1538 ))
1539 })?;
1540
1541 Self::new(self.months.add_checked(months)?, self.days, self.nanos)
1542 }
1543 IntervalUnit::Month => {
1544 let months = amount.integer.try_into().map_err(|_| {
1545 ArrowError::ParseError(format!(
1546 "Unable to represent {} months in a signed 32-bit integer",
1547 amount.integer
1548 ))
1549 })?;
1550
1551 let days = amount.frac * 3 / 10_i64.pow(INTERVAL_PRECISION - 1);
1552 let days = days.try_into().map_err(|_| {
1553 ArrowError::ParseError(format!(
1554 "Unable to represent {} months as days in a signed 32-bit integer",
1555 amount.frac / 10_i64.pow(INTERVAL_PRECISION)
1556 ))
1557 })?;
1558
1559 Self::new(
1560 self.months.add_checked(months)?,
1561 self.days.add_checked(days)?,
1562 self.nanos,
1563 )
1564 }
1565 IntervalUnit::Week => {
1566 let days = amount.integer.mul_checked(7)?.try_into().map_err(|_| {
1567 ArrowError::ParseError(format!(
1568 "Unable to represent {} weeks as days in a signed 32-bit integer",
1569 amount.integer
1570 ))
1571 })?;
1572
1573 let nanos = amount.frac * 7 * 24 * 6 * 6 / 10_i64.pow(INTERVAL_PRECISION - 11);
1574
1575 Self::new(
1576 self.months,
1577 self.days.add_checked(days)?,
1578 self.nanos.add_checked(nanos)?,
1579 )
1580 }
1581 IntervalUnit::Day => {
1582 let days = amount.integer.try_into().map_err(|_| {
1583 ArrowError::InvalidArgumentError(format!(
1584 "Unable to represent {} days in a signed 32-bit integer",
1585 amount.integer
1586 ))
1587 })?;
1588
1589 let nanos = amount.frac * 24 * 6 * 6 / 10_i64.pow(INTERVAL_PRECISION - 11);
1590
1591 Self::new(
1592 self.months,
1593 self.days.add_checked(days)?,
1594 self.nanos.add_checked(nanos)?,
1595 )
1596 }
1597 IntervalUnit::Hour => {
1598 let nanos_int = amount.integer.mul_checked(NANOS_PER_HOUR)?;
1599 let nanos_frac = amount.frac * 6 * 6 / 10_i64.pow(INTERVAL_PRECISION - 11);
1600 let nanos = nanos_int.add_checked(nanos_frac)?;
1601
1602 Interval::new(self.months, self.days, self.nanos.add_checked(nanos)?)
1603 }
1604 IntervalUnit::Minute => {
1605 let nanos_int = amount.integer.mul_checked(NANOS_PER_MINUTE)?;
1606 let nanos_frac = amount.frac * 6 / 10_i64.pow(INTERVAL_PRECISION - 10);
1607
1608 let nanos = nanos_int.add_checked(nanos_frac)?;
1609
1610 Interval::new(self.months, self.days, self.nanos.add_checked(nanos)?)
1611 }
1612 IntervalUnit::Second => {
1613 let nanos_int = amount.integer.mul_checked(NANOS_PER_SECOND)?;
1614 let nanos_frac = amount.frac / 10_i64.pow(INTERVAL_PRECISION - 9);
1615 let nanos = nanos_int.add_checked(nanos_frac)?;
1616
1617 Interval::new(self.months, self.days, self.nanos.add_checked(nanos)?)
1618 }
1619 IntervalUnit::Millisecond => {
1620 let nanos_int = amount.integer.mul_checked(NANOS_PER_MILLIS)?;
1621 let nanos_frac = amount.frac / 10_i64.pow(INTERVAL_PRECISION - 6);
1622 let nanos = nanos_int.add_checked(nanos_frac)?;
1623
1624 Interval::new(self.months, self.days, self.nanos.add_checked(nanos)?)
1625 }
1626 IntervalUnit::Microsecond => {
1627 let nanos_int = amount.integer.mul_checked(1_000)?;
1628 let nanos_frac = amount.frac / 10_i64.pow(INTERVAL_PRECISION - 3);
1629 let nanos = nanos_int.add_checked(nanos_frac)?;
1630
1631 Interval::new(self.months, self.days, self.nanos.add_checked(nanos)?)
1632 }
1633 IntervalUnit::Nanosecond => {
1634 let nanos_int = amount.integer;
1635 let nanos_frac = amount.frac / 10_i64.pow(INTERVAL_PRECISION);
1636 let nanos = nanos_int.add_checked(nanos_frac)?;
1637
1638 Interval::new(self.months, self.days, self.nanos.add_checked(nanos)?)
1639 }
1640 };
1641
1642 Ok(result)
1643 }
1644}
1645
1646fn parse_interval_components(
1648 value: &str,
1649 config: &IntervalParseConfig,
1650) -> Result<Vec<(IntervalAmount, IntervalUnit)>, ArrowError> {
1651 let raw_pairs = split_interval_components(value);
1652
1653 let Ok(pairs): Result<Vec<(IntervalAmount, IntervalUnit)>, ArrowError> = raw_pairs
1655 .iter()
1656 .map(|(a, u)| Ok((a.parse()?, IntervalUnit::from_str_or_config(*u, config)?)))
1657 .collect()
1658 else {
1659 return Err(ArrowError::ParseError(format!(
1660 "Invalid input syntax for type interval: {value:?}"
1661 )));
1662 };
1663
1664 let (amounts, units): (Vec<_>, Vec<_>) = pairs.into_iter().unzip();
1666
1667 let mut observed_interval_types = 0;
1669 for (unit, (_, raw_unit)) in units.iter().zip(raw_pairs) {
1670 if observed_interval_types & (*unit as u16) != 0 {
1671 return Err(ArrowError::ParseError(format!(
1672 "Invalid input syntax for type interval: {:?}. Repeated type '{}'",
1673 value,
1674 raw_unit.unwrap_or_default(),
1675 )));
1676 }
1677
1678 observed_interval_types |= *unit as u16;
1679 }
1680
1681 let result = amounts.iter().copied().zip(units.iter().copied());
1682
1683 Ok(result.collect::<Vec<_>>())
1684}
1685
1686fn split_interval_components(value: &str) -> Vec<(&str, Option<&str>)> {
1692 let mut result = vec![];
1693 let mut words = value.split(char::is_whitespace);
1694 while let Some(word) = words.next() {
1695 if let Some(split_word_at) = word.find(not_interval_amount) {
1696 let (amount, unit) = word.split_at(split_word_at);
1697 result.push((amount, Some(unit)));
1698 } else if let Some(unit) = words.next() {
1699 result.push((word, Some(unit)));
1700 } else {
1701 result.push((word, None));
1702 break;
1703 }
1704 }
1705 result
1706}
1707
1708fn not_interval_amount(c: char) -> bool {
1710 !c.is_ascii_digit() && c != '.' && c != '-'
1711}
1712
1713#[cfg(test)]
1714mod tests {
1715 use super::*;
1716 use arrow_array::temporal_conversions::date32_to_datetime;
1717 use arrow_buffer::i256;
1718
1719 fn parse_native<T: DecimalType>(s: &str, scale: i8) -> Result<T::Native, DecimalParseError> {
1721 parse_decimal_native::<T>(s, scale).map(|(value, _)| value)
1722 }
1723
1724 #[test]
1725 fn test_parse_nanos() {
1726 assert_eq!(parse_nanos::<3, 0>(&[1, 2, 3]), 123_000_000);
1727 assert_eq!(parse_nanos::<5, 0>(&[1, 2, 3, 4, 5]), 123_450_000);
1728 assert_eq!(parse_nanos::<6, b'0'>(b"123456"), 123_456_000);
1729 }
1730
1731 #[test]
1732 fn string_to_timestamp_timezone() {
1733 assert_eq!(
1735 1599572549190855000,
1736 parse_timestamp("2020-09-08T13:42:29.190855+00:00").unwrap()
1737 );
1738 assert_eq!(
1739 1599572549190855000,
1740 parse_timestamp("2020-09-08T13:42:29.190855Z").unwrap()
1741 );
1742 assert_eq!(
1743 1599572549000000000,
1744 parse_timestamp("2020-09-08T13:42:29Z").unwrap()
1745 ); assert_eq!(
1747 1599590549190855000,
1748 parse_timestamp("2020-09-08T13:42:29.190855-05:00").unwrap()
1749 );
1750 }
1751
1752 #[test]
1753 fn string_to_timestamp_timezone_space() {
1754 assert_eq!(
1756 1599572549190855000,
1757 parse_timestamp("2020-09-08 13:42:29.190855+00:00").unwrap()
1758 );
1759 assert_eq!(
1760 1599572549190855000,
1761 parse_timestamp("2020-09-08 13:42:29.190855Z").unwrap()
1762 );
1763 assert_eq!(
1764 1599572549000000000,
1765 parse_timestamp("2020-09-08 13:42:29Z").unwrap()
1766 ); assert_eq!(
1768 1599590549190855000,
1769 parse_timestamp("2020-09-08 13:42:29.190855-05:00").unwrap()
1770 );
1771 }
1772
1773 #[test]
1774 fn string_to_timestamp_no_timezone() {
1775 let naive_datetime = NaiveDateTime::new(
1779 NaiveDate::from_ymd_opt(2020, 9, 8).unwrap(),
1780 NaiveTime::from_hms_nano_opt(13, 42, 29, 190855000).unwrap(),
1781 );
1782
1783 assert_eq!(
1785 naive_datetime.and_utc().timestamp_nanos_opt().unwrap(),
1786 parse_timestamp("2020-09-08T13:42:29.190855").unwrap()
1787 );
1788
1789 assert_eq!(
1790 naive_datetime.and_utc().timestamp_nanos_opt().unwrap(),
1791 parse_timestamp("2020-09-08 13:42:29.190855").unwrap()
1792 );
1793
1794 let datetime_whole_secs = NaiveDateTime::new(
1797 NaiveDate::from_ymd_opt(2020, 9, 8).unwrap(),
1798 NaiveTime::from_hms_opt(13, 42, 29).unwrap(),
1799 )
1800 .and_utc();
1801
1802 assert_eq!(
1804 datetime_whole_secs.timestamp_nanos_opt().unwrap(),
1805 parse_timestamp("2020-09-08T13:42:29").unwrap()
1806 );
1807
1808 assert_eq!(
1809 datetime_whole_secs.timestamp_nanos_opt().unwrap(),
1810 parse_timestamp("2020-09-08 13:42:29").unwrap()
1811 );
1812
1813 let datetime_no_time = NaiveDateTime::new(
1817 NaiveDate::from_ymd_opt(2020, 9, 8).unwrap(),
1818 NaiveTime::from_hms_opt(0, 0, 0).unwrap(),
1819 )
1820 .and_utc();
1821
1822 assert_eq!(
1823 datetime_no_time.timestamp_nanos_opt().unwrap(),
1824 parse_timestamp("2020-09-08").unwrap()
1825 )
1826 }
1827
1828 #[test]
1829 fn string_to_timestamp_chrono() {
1830 let cases = [
1831 "2020-09-08T13:42:29Z",
1832 "1969-01-01T00:00:00.1Z",
1833 "2020-09-08T12:00:12.12345678+00:00",
1834 "2020-09-08T12:00:12+00:00",
1835 "2020-09-08T12:00:12.1+00:00",
1836 "2020-09-08T12:00:12.12+00:00",
1837 "2020-09-08T12:00:12.123+00:00",
1838 "2020-09-08T12:00:12.1234+00:00",
1839 "2020-09-08T12:00:12.12345+00:00",
1840 "2020-09-08T12:00:12.123456+00:00",
1841 "2020-09-08T12:00:12.1234567+00:00",
1842 "2020-09-08T12:00:12.12345678+00:00",
1843 "2020-09-08T12:00:12.123456789+00:00",
1844 "2020-09-08T12:00:12.12345678912z",
1845 "2020-09-08T12:00:12.123456789123Z",
1846 "2020-09-08T12:00:12.123456789123+02:00",
1847 "2020-09-08T12:00:12.12345678912345Z",
1848 "2020-09-08T12:00:12.1234567891234567+02:00",
1849 "2020-09-08T12:00:60Z",
1850 "2020-09-08T12:00:60.123Z",
1851 "2020-09-08T12:00:60.123456+02:00",
1852 "2020-09-08T12:00:60.1234567891234567+02:00",
1853 "2020-09-08T12:00:60.999999999+02:00",
1854 "2020-09-08t12:00:12.12345678+00:00",
1855 "2020-09-08t12:00:12+00:00",
1856 "2020-09-08t12:00:12Z",
1857 ];
1858
1859 for case in cases {
1860 let chrono = DateTime::parse_from_rfc3339(case).unwrap();
1861 let chrono_utc = chrono.with_timezone(&Utc);
1862
1863 let custom = string_to_datetime(&Utc, case).unwrap();
1864 assert_eq!(chrono_utc, custom)
1865 }
1866 }
1867
1868 #[test]
1869 fn string_to_timestamp_naive() {
1870 let cases = [
1871 "2018-11-13T17:11:10.011375885995",
1872 "2030-12-04T17:11:10.123",
1873 "2030-12-04T17:11:10.1234",
1874 "2030-12-04T17:11:10.123456",
1875 ];
1876 for case in cases {
1877 let chrono = NaiveDateTime::parse_from_str(case, "%Y-%m-%dT%H:%M:%S%.f").unwrap();
1878 let custom = string_to_datetime(&Utc, case).unwrap();
1879 assert_eq!(chrono, custom.naive_utc())
1880 }
1881 }
1882
1883 #[test]
1884 fn string_to_timestamp_invalid() {
1885 let cases = [
1887 ("", "timestamp must contain at least 10 characters"),
1888 ("SS", "timestamp must contain at least 10 characters"),
1889 ("Wed, 18 Feb 2015 23:16:09 GMT", "error parsing date"),
1890 ("1997-01-31H09:26:56.123Z", "invalid timestamp separator"),
1891 ("1997-01-31 09:26:56.123Z", "error parsing time"),
1892 ("1997:01:31T09:26:56.123Z", "error parsing date"),
1893 ("1997:1:31T09:26:56.123Z", "error parsing date"),
1894 ("1997-01-32T09:26:56.123Z", "error parsing date"),
1895 ("1997-13-32T09:26:56.123Z", "error parsing date"),
1896 ("1997-02-29T09:26:56.123Z", "error parsing date"),
1897 ("2015-02-30T17:35:20-08:00", "error parsing date"),
1898 ("1997-01-10T9:26:56.123Z", "error parsing time"),
1899 ("2015-01-20T25:35:20-08:00", "error parsing time"),
1900 ("1997-01-10T09:61:56.123Z", "error parsing time"),
1901 ("1997-01-10T09:61:90.123Z", "error parsing time"),
1902 ("1997-01-10T12:00:6.123Z", "error parsing time"),
1903 ("1997-01-31T092656.123Z", "error parsing time"),
1904 ("1997-01-10T12:00:06.", "error parsing time"),
1905 ("1997-01-10T12:00:06. ", "error parsing time"),
1906 ];
1907
1908 for (s, ctx) in cases {
1909 let expected = format!("Parser error: Error parsing timestamp from '{s}': {ctx}");
1910 let actual = string_to_datetime(&Utc, s).unwrap_err().to_string();
1911 assert_eq!(actual, expected)
1912 }
1913 }
1914
1915 fn parse_timestamp(s: &str) -> Result<i64, ArrowError> {
1917 let result = string_to_timestamp_nanos(s);
1918 if let Err(e) = &result {
1919 eprintln!("Error parsing timestamp '{s}': {e:?}");
1920 }
1921 result
1922 }
1923
1924 #[test]
1925 fn string_without_timezone_to_timestamp() {
1926 let naive_datetime = NaiveDateTime::new(
1929 NaiveDate::from_ymd_opt(2020, 9, 8).unwrap(),
1930 NaiveTime::from_hms_nano_opt(13, 42, 29, 190855000).unwrap(),
1931 );
1932
1933 assert_eq!(
1935 naive_datetime.and_utc().timestamp_nanos_opt().unwrap(),
1936 parse_timestamp("2020-09-08T13:42:29.190855").unwrap()
1937 );
1938
1939 assert_eq!(
1940 naive_datetime.and_utc().timestamp_nanos_opt().unwrap(),
1941 parse_timestamp("2020-09-08 13:42:29.190855").unwrap()
1942 );
1943
1944 let naive_datetime = NaiveDateTime::new(
1945 NaiveDate::from_ymd_opt(2020, 9, 8).unwrap(),
1946 NaiveTime::from_hms_nano_opt(13, 42, 29, 0).unwrap(),
1947 );
1948
1949 assert_eq!(
1951 naive_datetime.and_utc().timestamp_nanos_opt().unwrap(),
1952 parse_timestamp("2020-09-08T13:42:29").unwrap()
1953 );
1954
1955 assert_eq!(
1956 naive_datetime.and_utc().timestamp_nanos_opt().unwrap(),
1957 parse_timestamp("2020-09-08 13:42:29").unwrap()
1958 );
1959
1960 let tz: Tz = "+02:00".parse().unwrap();
1961 let date = string_to_datetime(&tz, "2020-09-08 13:42:29").unwrap();
1962 let utc = date.naive_utc().to_string();
1963 assert_eq!(utc, "2020-09-08 11:42:29");
1964 let local = date.naive_local().to_string();
1965 assert_eq!(local, "2020-09-08 13:42:29");
1966
1967 let date = string_to_datetime(&tz, "2020-09-08 13:42:29Z").unwrap();
1968 let utc = date.naive_utc().to_string();
1969 assert_eq!(utc, "2020-09-08 13:42:29");
1970 let local = date.naive_local().to_string();
1971 assert_eq!(local, "2020-09-08 15:42:29");
1972
1973 let dt =
1974 NaiveDateTime::parse_from_str("2020-09-08T13:42:29Z", "%Y-%m-%dT%H:%M:%SZ").unwrap();
1975 let local: Tz = "+08:00".parse().unwrap();
1976
1977 let date = string_to_datetime(&local, "2020-09-08T13:42:29Z").unwrap();
1979 assert_eq!(dt, date.naive_utc());
1980 assert_ne!(dt, date.naive_local());
1981
1982 let date = string_to_datetime(&local, "2020-09-08 13:42:29").unwrap();
1984 assert_eq!(dt, date.naive_local());
1985 assert_ne!(dt, date.naive_utc());
1986 }
1987
1988 #[test]
1989 fn parse_date32() {
1990 let cases = [
1991 "2020-09-08",
1992 "2020-9-8",
1993 "2020-09-8",
1994 "2020-9-08",
1995 "2020-12-1",
1996 "1690-2-5",
1997 "2020-09-08 01:02:03",
1998 ];
1999 for case in cases {
2000 let v = date32_to_datetime(Date32Type::parse(case).unwrap()).unwrap();
2001 let expected = NaiveDate::parse_from_str(case, "%Y-%m-%d")
2002 .or_else(|_| NaiveDate::parse_from_str(case, "%Y-%m-%d %H:%M:%S"))
2003 .unwrap();
2004 assert_eq!(v.date(), expected);
2005 }
2006
2007 let err_cases = [
2008 "",
2009 "80-01-01",
2010 "342",
2011 "Foo",
2012 "2020-09-08-03",
2013 "2020--04-03",
2014 "2020--",
2015 "2020-09-08 01",
2016 "2020-09-08 01:02",
2017 "2020-09-08 01-02-03",
2018 "2020-9-8 01:02:03",
2019 "2020-09-08 1:2:3",
2020 ];
2021 for case in err_cases {
2022 assert_eq!(Date32Type::parse(case), None);
2023 }
2024 }
2025
2026 #[test]
2027 fn parse_date32_extended_year() {
2028 let cases: &[(&str, i32)] = &[
2030 ("+1970-01-01", 0),
2031 ("+2024-01-01", 19_723),
2032 ("-0001-01-01", -719_893),
2033 ("+29349-01-26", 10_000_000),
2034 ("+2739877-01-03", 1_000_000_000),
2035 ("+5881580-07-11", i32::MAX),
2037 ("-5877641-06-23", i32::MIN),
2038 ];
2039 for (input, expected) in cases {
2040 assert_eq!(Date32Type::parse(input), Some(*expected), "input: {input}");
2041 }
2042
2043 assert_eq!(Date32Type::parse("+5881580-07-12"), None);
2045 assert_eq!(Date32Type::parse("-5877641-06-22"), None);
2046 assert_eq!(Date32Type::parse("+2739877-02-30"), None);
2048 assert_eq!(Date32Type::parse("+2739877-13-01"), None);
2049 assert_eq!(Date32Type::parse("-2739877-02-30"), None);
2050 }
2051
2052 #[test]
2053 fn parse_time64_nanos() {
2054 assert_eq!(
2055 Time64NanosecondType::parse("02:10:01.1234567899999999"),
2056 Some(7_801_123_456_789)
2057 );
2058 assert_eq!(
2059 Time64NanosecondType::parse("02:10:01.1234567"),
2060 Some(7_801_123_456_700)
2061 );
2062 assert_eq!(
2063 Time64NanosecondType::parse("2:10:01.1234567"),
2064 Some(7_801_123_456_700)
2065 );
2066 assert_eq!(
2067 Time64NanosecondType::parse("12:10:01.123456789 AM"),
2068 Some(601_123_456_789)
2069 );
2070 assert_eq!(
2071 Time64NanosecondType::parse("12:10:01.123456789 am"),
2072 Some(601_123_456_789)
2073 );
2074 assert_eq!(
2075 Time64NanosecondType::parse("2:10:01.12345678 PM"),
2076 Some(51_001_123_456_780)
2077 );
2078 assert_eq!(
2079 Time64NanosecondType::parse("2:10:01.12345678 pm"),
2080 Some(51_001_123_456_780)
2081 );
2082 assert_eq!(
2083 Time64NanosecondType::parse("02:10:01"),
2084 Some(7_801_000_000_000)
2085 );
2086 assert_eq!(
2087 Time64NanosecondType::parse("2:10:01"),
2088 Some(7_801_000_000_000)
2089 );
2090 assert_eq!(
2091 Time64NanosecondType::parse("12:10:01 AM"),
2092 Some(601_000_000_000)
2093 );
2094 assert_eq!(
2095 Time64NanosecondType::parse("12:10:01 am"),
2096 Some(601_000_000_000)
2097 );
2098 assert_eq!(
2099 Time64NanosecondType::parse("2:10:01 PM"),
2100 Some(51_001_000_000_000)
2101 );
2102 assert_eq!(
2103 Time64NanosecondType::parse("2:10:01 pm"),
2104 Some(51_001_000_000_000)
2105 );
2106 assert_eq!(
2107 Time64NanosecondType::parse("02:10"),
2108 Some(7_800_000_000_000)
2109 );
2110 assert_eq!(Time64NanosecondType::parse("2:10"), Some(7_800_000_000_000));
2111 assert_eq!(
2112 Time64NanosecondType::parse("12:10 AM"),
2113 Some(600_000_000_000)
2114 );
2115 assert_eq!(
2116 Time64NanosecondType::parse("12:10 am"),
2117 Some(600_000_000_000)
2118 );
2119 assert_eq!(
2120 Time64NanosecondType::parse("2:10 PM"),
2121 Some(51_000_000_000_000)
2122 );
2123 assert_eq!(
2124 Time64NanosecondType::parse("2:10 pm"),
2125 Some(51_000_000_000_000)
2126 );
2127
2128 assert_eq!(Time64NanosecondType::parse("1"), Some(1));
2130
2131 assert_eq!(
2133 Time64NanosecondType::parse("23:59:60"),
2134 Some(86_400_000_000_000)
2135 );
2136
2137 assert_eq!(
2139 Time64NanosecondType::parse_formatted("02 - 10 - 01 - .1234567", "%H - %M - %S - %.f"),
2140 Some(7_801_123_456_700)
2141 );
2142 }
2143
2144 #[test]
2145 fn parse_time64_micros() {
2146 assert_eq!(
2148 Time64MicrosecondType::parse("02:10:01.1234"),
2149 Some(7_801_123_400)
2150 );
2151 assert_eq!(
2152 Time64MicrosecondType::parse("2:10:01.1234"),
2153 Some(7_801_123_400)
2154 );
2155 assert_eq!(
2156 Time64MicrosecondType::parse("12:10:01.123456 AM"),
2157 Some(601_123_456)
2158 );
2159 assert_eq!(
2160 Time64MicrosecondType::parse("12:10:01.123456 am"),
2161 Some(601_123_456)
2162 );
2163 assert_eq!(
2164 Time64MicrosecondType::parse("2:10:01.12345 PM"),
2165 Some(51_001_123_450)
2166 );
2167 assert_eq!(
2168 Time64MicrosecondType::parse("2:10:01.12345 pm"),
2169 Some(51_001_123_450)
2170 );
2171 assert_eq!(
2172 Time64MicrosecondType::parse("02:10:01"),
2173 Some(7_801_000_000)
2174 );
2175 assert_eq!(Time64MicrosecondType::parse("2:10:01"), Some(7_801_000_000));
2176 assert_eq!(
2177 Time64MicrosecondType::parse("12:10:01 AM"),
2178 Some(601_000_000)
2179 );
2180 assert_eq!(
2181 Time64MicrosecondType::parse("12:10:01 am"),
2182 Some(601_000_000)
2183 );
2184 assert_eq!(
2185 Time64MicrosecondType::parse("2:10:01 PM"),
2186 Some(51_001_000_000)
2187 );
2188 assert_eq!(
2189 Time64MicrosecondType::parse("2:10:01 pm"),
2190 Some(51_001_000_000)
2191 );
2192 assert_eq!(Time64MicrosecondType::parse("02:10"), Some(7_800_000_000));
2193 assert_eq!(Time64MicrosecondType::parse("2:10"), Some(7_800_000_000));
2194 assert_eq!(Time64MicrosecondType::parse("12:10 AM"), Some(600_000_000));
2195 assert_eq!(Time64MicrosecondType::parse("12:10 am"), Some(600_000_000));
2196 assert_eq!(
2197 Time64MicrosecondType::parse("2:10 PM"),
2198 Some(51_000_000_000)
2199 );
2200 assert_eq!(
2201 Time64MicrosecondType::parse("2:10 pm"),
2202 Some(51_000_000_000)
2203 );
2204
2205 assert_eq!(Time64MicrosecondType::parse("1"), Some(1));
2207
2208 assert_eq!(
2210 Time64MicrosecondType::parse("23:59:60"),
2211 Some(86_400_000_000)
2212 );
2213
2214 assert_eq!(
2216 Time64MicrosecondType::parse_formatted("02 - 10 - 01 - .1234", "%H - %M - %S - %.f"),
2217 Some(7_801_123_400)
2218 );
2219 }
2220
2221 #[test]
2222 fn parse_time32_millis() {
2223 assert_eq!(Time32MillisecondType::parse("02:10:01.1"), Some(7_801_100));
2225 assert_eq!(Time32MillisecondType::parse("2:10:01.1"), Some(7_801_100));
2226 assert_eq!(
2227 Time32MillisecondType::parse("12:10:01.123 AM"),
2228 Some(601_123)
2229 );
2230 assert_eq!(
2231 Time32MillisecondType::parse("12:10:01.123 am"),
2232 Some(601_123)
2233 );
2234 assert_eq!(
2235 Time32MillisecondType::parse("2:10:01.12 PM"),
2236 Some(51_001_120)
2237 );
2238 assert_eq!(
2239 Time32MillisecondType::parse("2:10:01.12 pm"),
2240 Some(51_001_120)
2241 );
2242 assert_eq!(Time32MillisecondType::parse("02:10:01"), Some(7_801_000));
2243 assert_eq!(Time32MillisecondType::parse("2:10:01"), Some(7_801_000));
2244 assert_eq!(Time32MillisecondType::parse("12:10:01 AM"), Some(601_000));
2245 assert_eq!(Time32MillisecondType::parse("12:10:01 am"), Some(601_000));
2246 assert_eq!(Time32MillisecondType::parse("2:10:01 PM"), Some(51_001_000));
2247 assert_eq!(Time32MillisecondType::parse("2:10:01 pm"), Some(51_001_000));
2248 assert_eq!(Time32MillisecondType::parse("02:10"), Some(7_800_000));
2249 assert_eq!(Time32MillisecondType::parse("2:10"), Some(7_800_000));
2250 assert_eq!(Time32MillisecondType::parse("12:10 AM"), Some(600_000));
2251 assert_eq!(Time32MillisecondType::parse("12:10 am"), Some(600_000));
2252 assert_eq!(Time32MillisecondType::parse("2:10 PM"), Some(51_000_000));
2253 assert_eq!(Time32MillisecondType::parse("2:10 pm"), Some(51_000_000));
2254
2255 assert_eq!(Time32MillisecondType::parse("1"), Some(1));
2257
2258 assert_eq!(Time32MillisecondType::parse("23:59:60"), Some(86_400_000));
2260
2261 assert_eq!(
2263 Time32MillisecondType::parse_formatted("02 - 10 - 01 - .1", "%H - %M - %S - %.f"),
2264 Some(7_801_100)
2265 );
2266 }
2267
2268 #[test]
2269 fn parse_time32_secs() {
2270 assert_eq!(Time32SecondType::parse("02:10:01.1"), Some(7_801));
2272 assert_eq!(Time32SecondType::parse("02:10:01"), Some(7_801));
2273 assert_eq!(Time32SecondType::parse("2:10:01"), Some(7_801));
2274 assert_eq!(Time32SecondType::parse("12:10:01 AM"), Some(601));
2275 assert_eq!(Time32SecondType::parse("12:10:01 am"), Some(601));
2276 assert_eq!(Time32SecondType::parse("2:10:01 PM"), Some(51_001));
2277 assert_eq!(Time32SecondType::parse("2:10:01 pm"), Some(51_001));
2278 assert_eq!(Time32SecondType::parse("02:10"), Some(7_800));
2279 assert_eq!(Time32SecondType::parse("2:10"), Some(7_800));
2280 assert_eq!(Time32SecondType::parse("12:10 AM"), Some(600));
2281 assert_eq!(Time32SecondType::parse("12:10 am"), Some(600));
2282 assert_eq!(Time32SecondType::parse("2:10 PM"), Some(51_000));
2283 assert_eq!(Time32SecondType::parse("2:10 pm"), Some(51_000));
2284
2285 assert_eq!(Time32SecondType::parse("1"), Some(1));
2287
2288 assert_eq!(Time32SecondType::parse("23:59:60"), Some(86400));
2290
2291 assert_eq!(
2293 Time32SecondType::parse_formatted("02 - 10 - 01", "%H - %M - %S"),
2294 Some(7_801)
2295 );
2296 }
2297
2298 #[test]
2299 fn test_string_to_time_invalid() {
2300 let cases = [
2301 "25:00",
2302 "9:00:",
2303 "009:00",
2304 "09:0:00",
2305 "25:00:00",
2306 "13:00 AM",
2307 "13:00 PM",
2308 "12:00. AM",
2309 "09:0:00",
2310 "09:01:0",
2311 "09:01:1",
2312 "9:1:0",
2313 "09:01:0",
2314 "1:00.123",
2315 "1:00:00.123f",
2316 " 9:00:00",
2317 ":09:00",
2318 "T9:00:00",
2319 "AM",
2320 ];
2321 for case in cases {
2322 assert!(string_to_time(case).is_none(), "{case}");
2323 }
2324 }
2325
2326 #[test]
2327 fn test_string_to_time_chrono() {
2328 let cases = [
2329 ("1:00", "%H:%M"),
2330 ("12:00", "%H:%M"),
2331 ("13:00", "%H:%M"),
2332 ("24:00", "%H:%M"),
2333 ("1:00:00", "%H:%M:%S"),
2334 ("12:00:30", "%H:%M:%S"),
2335 ("13:00:59", "%H:%M:%S"),
2336 ("24:00:60", "%H:%M:%S"),
2337 ("09:00:00", "%H:%M:%S%.f"),
2338 ("0:00:30.123456", "%H:%M:%S%.f"),
2339 ("0:00 AM", "%I:%M %P"),
2340 ("1:00 AM", "%I:%M %P"),
2341 ("12:00 AM", "%I:%M %P"),
2342 ("13:00 AM", "%I:%M %P"),
2343 ("0:00 PM", "%I:%M %P"),
2344 ("1:00 PM", "%I:%M %P"),
2345 ("12:00 PM", "%I:%M %P"),
2346 ("13:00 PM", "%I:%M %P"),
2347 ("1:00 pM", "%I:%M %P"),
2348 ("1:00 Pm", "%I:%M %P"),
2349 ("1:00 aM", "%I:%M %P"),
2350 ("1:00 Am", "%I:%M %P"),
2351 ("1:00:30.123456 PM", "%I:%M:%S%.f %P"),
2352 ("1:00:30.123456789 PM", "%I:%M:%S%.f %P"),
2353 ("1:00:30.123456789123 PM", "%I:%M:%S%.f %P"),
2354 ("1:00:30.1234 PM", "%I:%M:%S%.f %P"),
2355 ("1:00:30.123456 PM", "%I:%M:%S%.f %P"),
2356 ("1:00:30.123456789123456789 PM", "%I:%M:%S%.f %P"),
2357 ("1:00:30.12F456 PM", "%I:%M:%S%.f %P"),
2358 ];
2359 for (s, format) in cases {
2360 let chrono = NaiveTime::parse_from_str(s, format).ok();
2361 let custom = string_to_time(s);
2362 assert_eq!(chrono, custom, "{s}");
2363 }
2364 }
2365
2366 #[test]
2367 fn test_parse_interval() {
2368 let config = IntervalParseConfig::new(IntervalUnit::Month);
2369
2370 assert_eq!(
2371 Interval::new(1i32, 0i32, 0i64),
2372 Interval::parse("1 month", &config).unwrap(),
2373 );
2374
2375 assert_eq!(
2376 Interval::new(2i32, 0i32, 0i64),
2377 Interval::parse("2 month", &config).unwrap(),
2378 );
2379
2380 assert_eq!(
2381 Interval::new(-1i32, -18i32, -(NANOS_PER_DAY / 5)),
2382 Interval::parse("-1.5 months -3.2 days", &config).unwrap(),
2383 );
2384
2385 assert_eq!(
2386 Interval::new(0i32, 15i32, 0),
2387 Interval::parse("0.5 months", &config).unwrap(),
2388 );
2389
2390 assert_eq!(
2391 Interval::new(0i32, 15i32, 0),
2392 Interval::parse(".5 months", &config).unwrap(),
2393 );
2394
2395 assert_eq!(
2396 Interval::new(0i32, -15i32, 0),
2397 Interval::parse("-0.5 months", &config).unwrap(),
2398 );
2399
2400 assert_eq!(
2401 Interval::new(0i32, -15i32, 0),
2402 Interval::parse("-.5 months", &config).unwrap(),
2403 );
2404
2405 assert_eq!(
2406 Interval::new(2i32, 10i32, 9 * NANOS_PER_HOUR),
2407 Interval::parse("2.1 months 7.25 days 3 hours", &config).unwrap(),
2408 );
2409
2410 assert_eq!(
2411 Interval::parse("1 centurys 1 month", &config)
2412 .unwrap_err()
2413 .to_string(),
2414 r#"Parser error: Invalid input syntax for type interval: "1 centurys 1 month""#
2415 );
2416
2417 assert_eq!(
2418 Interval::new(37i32, 0i32, 0i64),
2419 Interval::parse("3 year 1 month", &config).unwrap(),
2420 );
2421
2422 assert_eq!(
2423 Interval::new(35i32, 0i32, 0i64),
2424 Interval::parse("3 year -1 month", &config).unwrap(),
2425 );
2426
2427 assert_eq!(
2428 Interval::new(-37i32, 0i32, 0i64),
2429 Interval::parse("-3 year -1 month", &config).unwrap(),
2430 );
2431
2432 assert_eq!(
2433 Interval::new(-35i32, 0i32, 0i64),
2434 Interval::parse("-3 year 1 month", &config).unwrap(),
2435 );
2436
2437 assert_eq!(
2438 Interval::new(0i32, 5i32, 0i64),
2439 Interval::parse("5 days", &config).unwrap(),
2440 );
2441
2442 assert_eq!(
2443 Interval::new(0i32, 7i32, 3 * NANOS_PER_HOUR),
2444 Interval::parse("7 days 3 hours", &config).unwrap(),
2445 );
2446
2447 assert_eq!(
2448 Interval::new(0i32, 7i32, 5 * NANOS_PER_MINUTE),
2449 Interval::parse("7 days 5 minutes", &config).unwrap(),
2450 );
2451
2452 assert_eq!(
2453 Interval::new(0i32, 7i32, -5 * NANOS_PER_MINUTE),
2454 Interval::parse("7 days -5 minutes", &config).unwrap(),
2455 );
2456
2457 assert_eq!(
2458 Interval::new(0i32, -7i32, 5 * NANOS_PER_HOUR),
2459 Interval::parse("-7 days 5 hours", &config).unwrap(),
2460 );
2461
2462 assert_eq!(
2463 Interval::new(
2464 0i32,
2465 -7i32,
2466 -5 * NANOS_PER_HOUR - 5 * NANOS_PER_MINUTE - 5 * NANOS_PER_SECOND
2467 ),
2468 Interval::parse("-7 days -5 hours -5 minutes -5 seconds", &config).unwrap(),
2469 );
2470
2471 assert_eq!(
2472 Interval::new(12i32, 0i32, 25 * NANOS_PER_MILLIS),
2473 Interval::parse("1 year 25 millisecond", &config).unwrap(),
2474 );
2475
2476 assert_eq!(
2477 Interval::new(
2478 12i32,
2479 1i32,
2480 (NANOS_PER_SECOND as f64 * 0.000000001_f64) as i64
2481 ),
2482 Interval::parse("1 year 1 day 0.000000001 seconds", &config).unwrap(),
2483 );
2484
2485 assert_eq!(
2486 Interval::new(12i32, 1i32, NANOS_PER_MILLIS / 10),
2487 Interval::parse("1 year 1 day 0.1 milliseconds", &config).unwrap(),
2488 );
2489
2490 assert_eq!(
2491 Interval::new(12i32, 1i32, 1000i64),
2492 Interval::parse("1 year 1 day 1 microsecond", &config).unwrap(),
2493 );
2494
2495 assert_eq!(
2496 Interval::new(12i32, 1i32, 1i64),
2497 Interval::parse("1 year 1 day 1 nanoseconds", &config).unwrap(),
2498 );
2499
2500 assert_eq!(
2501 Interval::new(1i32, 0i32, -NANOS_PER_SECOND),
2502 Interval::parse("1 month -1 second", &config).unwrap(),
2503 );
2504
2505 assert_eq!(
2506 Interval::new(
2507 -13i32,
2508 -8i32,
2509 -NANOS_PER_HOUR
2510 - NANOS_PER_MINUTE
2511 - NANOS_PER_SECOND
2512 - (1.11_f64 * NANOS_PER_MILLIS as f64) as i64
2513 ),
2514 Interval::parse(
2515 "-1 year -1 month -1 week -1 day -1 hour -1 minute -1 second -1.11 millisecond",
2516 &config
2517 )
2518 .unwrap(),
2519 );
2520
2521 assert_eq!(
2523 Interval::new(1, 0, 0),
2524 Interval::parse("1", &config).unwrap()
2525 );
2526 assert_eq!(
2527 Interval::new(42, 0, 0),
2528 Interval::parse("42", &config).unwrap()
2529 );
2530 assert_eq!(
2531 Interval::new(0, 0, 42_000_000_000),
2532 Interval::parse("42", &IntervalParseConfig::new(IntervalUnit::Second)).unwrap()
2533 );
2534
2535 assert_eq!(
2537 Interval::new(1, 0, 0),
2538 Interval::parse("1 mon", &config).unwrap()
2539 );
2540 assert_eq!(
2541 Interval::new(1, 0, 0),
2542 Interval::parse("1 mons", &config).unwrap()
2543 );
2544 assert_eq!(
2545 Interval::new(0, 0, 1_000_000),
2546 Interval::parse("1 ms", &config).unwrap()
2547 );
2548 assert_eq!(
2549 Interval::new(0, 0, 1_000),
2550 Interval::parse("1 us", &config).unwrap()
2551 );
2552
2553 assert_eq!(
2555 Interval::new(0, 0, 1_000),
2556 Interval::parse("1us", &config).unwrap()
2557 );
2558 assert_eq!(
2559 Interval::new(0, 0, NANOS_PER_SECOND),
2560 Interval::parse("1s", &config).unwrap()
2561 );
2562 assert_eq!(
2563 Interval::new(1, 2, 10_864_000_000_000),
2564 Interval::parse("1mon 2days 3hr 1min 4sec", &config).unwrap()
2565 );
2566
2567 assert_eq!(
2568 Interval::new(
2569 -13i32,
2570 -8i32,
2571 -NANOS_PER_HOUR
2572 - NANOS_PER_MINUTE
2573 - NANOS_PER_SECOND
2574 - (1.11_f64 * NANOS_PER_MILLIS as f64) as i64
2575 ),
2576 Interval::parse(
2577 "-1year -1month -1week -1day -1 hour -1 minute -1 second -1.11millisecond",
2578 &config
2579 )
2580 .unwrap(),
2581 );
2582
2583 assert_eq!(
2584 Interval::parse("1h s", &config).unwrap_err().to_string(),
2585 r#"Parser error: Invalid input syntax for type interval: "1h s""#
2586 );
2587
2588 assert_eq!(
2589 Interval::parse("1XX", &config).unwrap_err().to_string(),
2590 r#"Parser error: Invalid input syntax for type interval: "1XX""#
2591 );
2592 }
2593
2594 #[test]
2595 fn test_duplicate_interval_type() {
2596 let config = IntervalParseConfig::new(IntervalUnit::Month);
2597
2598 let err = Interval::parse("1 month 1 second 1 second", &config)
2599 .expect_err("parsing interval should have failed");
2600 assert_eq!(
2601 r#"ParseError("Invalid input syntax for type interval: \"1 month 1 second 1 second\". Repeated type 'second'")"#,
2602 format!("{err:?}")
2603 );
2604
2605 let err = Interval::parse("1 century 2 centuries", &config)
2607 .expect_err("parsing interval should have failed");
2608 assert_eq!(
2609 r#"ParseError("Invalid input syntax for type interval: \"1 century 2 centuries\". Repeated type 'centuries'")"#,
2610 format!("{err:?}")
2611 );
2612 }
2613
2614 #[test]
2615 fn test_interval_amount_parsing() {
2616 let result = IntervalAmount::from_str("123").unwrap();
2618 let expected = IntervalAmount::new(123, 0);
2619
2620 assert_eq!(result, expected);
2621
2622 let result = IntervalAmount::from_str("0.3").unwrap();
2624 let expected = IntervalAmount::new(0, 3 * 10_i64.pow(INTERVAL_PRECISION - 1));
2625
2626 assert_eq!(result, expected);
2627
2628 let result = IntervalAmount::from_str("-3.5").unwrap();
2630 let expected = IntervalAmount::new(-3, -5 * 10_i64.pow(INTERVAL_PRECISION - 1));
2631
2632 assert_eq!(result, expected);
2633
2634 let result = IntervalAmount::from_str("3.");
2636 assert!(result.is_err());
2637
2638 let result = IntervalAmount::from_str("3.-5");
2640 assert!(result.is_err());
2641 }
2642
2643 #[test]
2644 fn test_interval_precision() {
2645 let config = IntervalParseConfig::new(IntervalUnit::Month);
2646
2647 let result = Interval::parse("100000.1 days", &config).unwrap();
2648 let expected = Interval::new(0_i32, 100_000_i32, NANOS_PER_DAY / 10);
2649
2650 assert_eq!(result, expected);
2651 }
2652
2653 #[test]
2654 fn test_interval_addition() {
2655 let start = Interval::new(1, 2, 3);
2657 let expected = Interval::new(4921, 2, 3);
2658
2659 let result = start
2660 .add(
2661 IntervalAmount::new(4, 10_i64.pow(INTERVAL_PRECISION - 1)),
2662 IntervalUnit::Century,
2663 )
2664 .unwrap();
2665
2666 assert_eq!(result, expected);
2667
2668 let start = Interval::new(1, 2, 3);
2670 let expected = Interval::new(1231, 2, 3);
2671
2672 let result = start
2673 .add(
2674 IntervalAmount::new(10, 25 * 10_i64.pow(INTERVAL_PRECISION - 2)),
2675 IntervalUnit::Decade,
2676 )
2677 .unwrap();
2678
2679 assert_eq!(result, expected);
2680
2681 let start = Interval::new(1, 2, 3);
2683 let expected = Interval::new(364, 2, 3);
2684
2685 let result = start
2686 .add(
2687 IntervalAmount::new(30, 3 * 10_i64.pow(INTERVAL_PRECISION - 1)),
2688 IntervalUnit::Year,
2689 )
2690 .unwrap();
2691
2692 assert_eq!(result, expected);
2693
2694 let start = Interval::new(1, 2, 3);
2696 let expected = Interval::new(2, 17, 3);
2697
2698 let result = start
2699 .add(
2700 IntervalAmount::new(1, 5 * 10_i64.pow(INTERVAL_PRECISION - 1)),
2701 IntervalUnit::Month,
2702 )
2703 .unwrap();
2704
2705 assert_eq!(result, expected);
2706
2707 let start = Interval::new(1, 25, 3);
2709 let expected = Interval::new(1, 11, 3);
2710
2711 let result = start
2712 .add(IntervalAmount::new(-2, 0), IntervalUnit::Week)
2713 .unwrap();
2714
2715 assert_eq!(result, expected);
2716
2717 let start = Interval::new(12, 15, 3);
2719 let expected = Interval::new(12, 17, 3 + 17_280 * NANOS_PER_SECOND);
2720
2721 let result = start
2722 .add(
2723 IntervalAmount::new(2, 2 * 10_i64.pow(INTERVAL_PRECISION - 1)),
2724 IntervalUnit::Day,
2725 )
2726 .unwrap();
2727
2728 assert_eq!(result, expected);
2729
2730 let start = Interval::new(1, 2, 3);
2732 let expected = Interval::new(1, 2, 3 + 45_000 * NANOS_PER_SECOND);
2733
2734 let result = start
2735 .add(
2736 IntervalAmount::new(12, 5 * 10_i64.pow(INTERVAL_PRECISION - 1)),
2737 IntervalUnit::Hour,
2738 )
2739 .unwrap();
2740
2741 assert_eq!(result, expected);
2742
2743 let start = Interval::new(0, 0, -3);
2745 let expected = Interval::new(0, 0, -90_000_000_000 - 3);
2746
2747 let result = start
2748 .add(
2749 IntervalAmount::new(-1, -5 * 10_i64.pow(INTERVAL_PRECISION - 1)),
2750 IntervalUnit::Minute,
2751 )
2752 .unwrap();
2753
2754 assert_eq!(result, expected);
2755 }
2756
2757 #[test]
2758 fn string_to_timestamp_old() {
2759 parse_timestamp("1677-06-14T07:29:01.256")
2760 .map_err(|e| assert!(e.to_string().ends_with(ERR_NANOSECONDS_NOT_SUPPORTED)))
2761 .unwrap_err();
2762 }
2763
2764 #[test]
2765 fn test_parse_decimal_with_parameter() {
2766 let tests = [
2767 ("0", 0i128),
2768 ("123.123", 123123i128),
2769 ("123.1234", 123123i128),
2770 ("123.1", 123100i128),
2771 ("123", 123000i128),
2772 ("-123.123", -123123i128),
2773 ("-123.1234", -123123i128),
2774 ("-123.1", -123100i128),
2775 ("-123", -123000i128),
2776 ("0.0000123", 0i128),
2777 ("12.", 12000i128),
2778 ("-12.", -12000i128),
2779 ("00.1", 100i128),
2780 ("-00.1", -100i128),
2781 ("12345678912345678.1234", 12345678912345678123i128),
2782 ("-12345678912345678.1234", -12345678912345678123i128),
2783 ("99999999999999999.999", 99999999999999999999i128),
2784 ("-99999999999999999.999", -99999999999999999999i128),
2785 (".123", 123i128),
2786 ("-.123", -123i128),
2787 ("123.", 123000i128),
2788 ("-123.", -123000i128),
2789 ];
2790 for (s, i) in tests {
2791 let result_128 = parse_decimal::<Decimal128Type>(s, 20, 3);
2792 assert_eq!(i, result_128.unwrap());
2793 let result_256 = parse_decimal::<Decimal256Type>(s, 20, 3);
2794 assert_eq!(i256::from_i128(i), result_256.unwrap());
2795 }
2796
2797 let e_notation_tests = [
2798 ("1.23e3", "1230.0", 2),
2799 ("5.6714e+2", "567.14", 4),
2800 ("5.6714e-2", "0.056714", 4),
2801 ("5.6714e-2", "0.056714", 3),
2802 ("5.6741214125e2", "567.41214125", 4),
2803 ("8.91E4", "89100.0", 2),
2804 ("3.14E+5", "314000.0", 2),
2805 ("2.718e0", "2.718", 2),
2806 ("9.999999e-1", "0.9999999", 4),
2807 ("1.23e+3", "1230", 2),
2808 ("1.234559e+3", "1234.559", 2),
2809 ("1.00E-10", "0.0000000001", 11),
2810 ("1.23e-4", "0.000123", 2),
2811 ("9.876e7", "98760000.0", 2),
2812 ("5.432E+8", "543200000.0", 10),
2813 ("1.234567e9", "1234567000.0", 2),
2814 ("1.234567e2", "123.45670000", 2),
2815 ("4749.3e-5", "0.047493", 10),
2816 ("4749.3e+5", "474930000", 10),
2817 ("4749.3e-5", "0.047493", 1),
2818 ("4749.3e+5", "474930000", 1),
2819 ("0E-8", "0", 10),
2820 ("0E+6", "0", 10),
2821 ("0e0", "0", 10),
2822 ("-0e0", "0", 10),
2823 ("00e48", "0", 10),
2824 ("1E-8", "0.00000001", 10),
2825 ("12E+6", "12000000", 10),
2826 ("12E-6", "0.000012", 10),
2827 ("0.1e-6", "0.0000001", 10),
2828 ("0.1e+6", "100000", 10),
2829 ("0.12e-6", "0.00000012", 10),
2830 ("0.12e+6", "120000", 10),
2831 ("000000000001e0", "000000000001", 3),
2832 ("000001.1034567002e0", "000001.1034567002", 3),
2833 ("1.234e16", "12340000000000000", 0),
2834 ("123.4e16", "1234000000000000000", 0),
2835 ("15e-1", "1.5", 0),
2836 ("1.25e1", "12.5", 0),
2837 ("1.5e-1", "0.15", 1),
2838 ];
2839 for (e, d, scale) in e_notation_tests {
2840 let result_128_e = parse_decimal::<Decimal128Type>(e, 20, scale);
2841 let result_128_d = parse_decimal::<Decimal128Type>(d, 20, scale);
2842 assert_eq!(result_128_e.unwrap(), result_128_d.unwrap(), "{e} vs {d}");
2843 let result_256_e = parse_decimal::<Decimal256Type>(e, 20, scale);
2844 let result_256_d = parse_decimal::<Decimal256Type>(d, 20, scale);
2845 assert_eq!(result_256_e.unwrap(), result_256_d.unwrap(), "{e} vs {d}");
2846 }
2847 let can_not_parse_tests = [
2848 "123,123",
2849 ".",
2850 "123.123.123",
2851 "",
2852 "+",
2853 "-",
2854 "e",
2855 "e5",
2856 "-.",
2857 "+e-11",
2858 "-.E+3",
2859 ".e5",
2860 "1.3e+e3",
2861 "5.6714ee-2",
2862 "4.11ee-+4",
2863 "4.11e++4",
2864 "1.1e.12",
2865 "1.23e+3.",
2866 "1.23e+3.1",
2867 "1e",
2868 "1e+",
2869 "1e-",
2870 "1e5e5",
2871 "1 000",
2872 "1_000",
2873 "- 1",
2874 "1.5 x",
2875 "0x10",
2876 "NaN",
2877 "inf",
2878 "\u{661}\u{662}",
2879 "\u{ff11}",
2880 ];
2881 for s in can_not_parse_tests {
2882 let result_128 = parse_decimal::<Decimal128Type>(s, 20, 3);
2883 assert_eq!(
2884 format!("Parser error: Invalid decimal format: {s:?}"),
2885 result_128.unwrap_err().to_string()
2886 );
2887 let result_256 = parse_decimal::<Decimal256Type>(s, 20, 3);
2888 assert_eq!(
2889 format!("Parser error: Invalid decimal format: {s:?}"),
2890 result_256.unwrap_err().to_string()
2891 );
2892 }
2893 let overflow_parse_tests = [
2894 ("12345678", 3),
2895 ("1.2345678e7", 3),
2896 ("12345678.9", 3),
2897 ("1.23456789e+7", 3),
2898 ("99999999.99", 3),
2899 ("9.999999999e7", 3),
2900 ("12345678908765.123456", 3),
2901 ("123456789087651234.56e-4", 3),
2902 ("1234560000000", 0),
2903 ("12345678900.0", 0),
2904 ("1.23456e12", 0),
2905 ("9999999.9995", 3),
2906 ("1e99999", 0),
2907 ("1e40", 0),
2908 ];
2909 for (s, scale) in overflow_parse_tests {
2910 let result_128 = parse_decimal::<Decimal128Type>(s, 10, scale);
2911 let expected_128 =
2912 format!("Parser error: {s:?} does not fit in Decimal128(10, {scale})");
2913 assert_eq!(result_128.unwrap_err().to_string(), expected_128);
2914
2915 let result_256 = parse_decimal::<Decimal256Type>(s, 10, scale);
2916 let expected_256 =
2917 format!("Parser error: {s:?} does not fit in Decimal256(10, {scale})");
2918 assert_eq!(result_256.unwrap_err().to_string(), expected_256);
2919 }
2920
2921 let edge_tests_128 = [
2922 (
2923 "99999999999999999999999999999999999999",
2924 99999999999999999999999999999999999999i128,
2925 0,
2926 ),
2927 (
2928 "999999999999999999999999999999999999.99",
2929 99999999999999999999999999999999999999i128,
2930 2,
2931 ),
2932 (
2933 "9999999999999999999999999.9999999999999",
2934 99999999999999999999999999999999999999i128,
2935 13,
2936 ),
2937 (
2938 "9999999999999999999999999",
2939 99999999999999999999999990000000000000i128,
2940 13,
2941 ),
2942 (
2943 "0.99999999999999999999999999999999999999",
2944 99999999999999999999999999999999999999i128,
2945 38,
2946 ),
2947 (
2948 "0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001016744",
2949 0i128,
2950 15,
2951 ),
2952 ("1.016744e-320", 0i128, 15),
2953 ("-1e3", -1000000000i128, 6),
2954 ("+1e3", 1000000000i128, 6),
2955 ("-1e31", -10000000000000000000000000000000000000i128, 6),
2956 ("10000000000000000000000000000000000000000e-39", 10i128, 0),
2958 (
2960 "99999999999999999999999999999999999994e-1",
2961 9999999999999999999999999999999999999i128,
2962 0,
2963 ),
2964 ];
2965 for (s, i, scale) in edge_tests_128 {
2966 let result_128 = parse_decimal::<Decimal128Type>(s, 38, scale);
2967 assert_eq!(i, result_128.unwrap(), "{s}");
2968 }
2969 assert!(
2971 parse_decimal::<Decimal128Type>("999999999999999999999999999999999999999e-1", 38, 0)
2972 .is_err()
2973 );
2974
2975 let edge_tests_256 = [
2976 (
2977 "9999999999999999999999999999999999999999999999999999999999999999999999999999",
2978 i256::from_string(
2979 "9999999999999999999999999999999999999999999999999999999999999999999999999999",
2980 )
2981 .unwrap(),
2982 0,
2983 ),
2984 (
2985 "999999999999999999999999999999999999999999999999999999999999999999999999.9999",
2986 i256::from_string(
2987 "9999999999999999999999999999999999999999999999999999999999999999999999999999",
2988 )
2989 .unwrap(),
2990 4,
2991 ),
2992 (
2993 "99999999999999999999999999999999999999999999999999.99999999999999999999999999",
2994 i256::from_string(
2995 "9999999999999999999999999999999999999999999999999999999999999999999999999999",
2996 )
2997 .unwrap(),
2998 26,
2999 ),
3000 (
3001 "9.999999999999999999999999999999999999999999999999999999999999999999999999999e49",
3002 i256::from_string(
3003 "9999999999999999999999999999999999999999999999999999999999999999999999999999",
3004 )
3005 .unwrap(),
3006 26,
3007 ),
3008 (
3009 "99999999999999999999999999999999999999999999999999",
3010 i256::from_string(
3011 "9999999999999999999999999999999999999999999999999900000000000000000000000000",
3012 )
3013 .unwrap(),
3014 26,
3015 ),
3016 (
3017 "9.9999999999999999999999999999999999999999999999999e+49",
3018 i256::from_string(
3019 "9999999999999999999999999999999999999999999999999900000000000000000000000000",
3020 )
3021 .unwrap(),
3022 26,
3023 ),
3024 ];
3025 for (s, i, scale) in edge_tests_256 {
3026 let result = parse_decimal::<Decimal256Type>(s, 76, scale);
3027 assert_eq!(i, result.unwrap());
3028 }
3029
3030 let zero_scale_tests = [
3031 (".123", 0, 3),
3032 ("0.123", 0, 3),
3033 ("1.0", 1, 3),
3034 ("1.2", 1, 3),
3035 ("1.00", 1, 3),
3036 ("1.23", 1, 3),
3037 ("1.000", 1, 3),
3038 ("1.123", 1, 3),
3039 ("1.5", 2, 3),
3040 ("1.9", 2, 3),
3041 ("123.0", 123, 3),
3042 ("123.4", 123, 3),
3043 ("123.00", 123, 3),
3044 ("123.45", 123, 3),
3045 ("123.5", 124, 3),
3046 ("123.000000000000000000004", 123, 3),
3047 ("0.123e2", 12, 3),
3048 ("0.123e4", 1230, 10),
3049 ("1.23e4", 12300, 10),
3050 ("12.3e4", 123000, 10),
3051 ("123e4", 1230000, 10),
3052 (
3053 "20000000000000000000000000000000000002.0",
3054 20000000000000000000000000000000000002,
3055 38,
3056 ),
3057 ];
3058 for (s, i, precision) in zero_scale_tests {
3059 let result_128 = parse_decimal::<Decimal128Type>(s, precision, 0).unwrap();
3060 assert_eq!(i, result_128, "{s}");
3061 }
3062
3063 let can_not_parse_zero_scale = [".", "blag", "", "+", "-", "e"];
3064 for s in can_not_parse_zero_scale {
3065 let result_128 = parse_decimal::<Decimal128Type>(s, 5, 0);
3066 assert_eq!(
3067 format!("Parser error: Invalid decimal format: {s:?}"),
3068 result_128.unwrap_err().to_string(),
3069 );
3070 }
3071 }
3072
3073 #[test]
3074 fn test_parse_decimal_rounds_half_away_from_zero() {
3075 let tests = [
3076 ("1.234", 2, 123),
3077 ("1.235", 2, 124),
3078 ("1.2350000", 2, 124),
3079 ("1.2349999", 2, 123),
3080 ("-1.234", 2, -123),
3081 ("-1.235", 2, -124),
3082 ("-0.004", 2, 0),
3083 ("-0.005", 2, -1),
3084 (".5", 0, 1),
3085 ("-.5", 0, -1),
3086 ("0.5", 0, 1),
3087 ("1.5", 0, 2),
3088 ("2.5", 0, 3),
3089 ("-2.5", 0, -3),
3090 ("1.99", 1, 20),
3091 ("0.995", 2, 100),
3092 ("9.99", 1, 100),
3093 ("123.4567891", 5, 12345679),
3094 ("123.45", 0, 123),
3095 ("0.0000123", 3, 0),
3096 ("12.", 2, 1200),
3097 (".12", 2, 12),
3098 ("+.12", 2, 12),
3099 ("-.12", 2, -12),
3100 ];
3101 for (s, scale, expected) in tests {
3102 assert_eq!(
3103 parse_decimal::<Decimal128Type>(s, 38, scale).unwrap(),
3104 expected,
3105 "{s} at scale {scale}"
3106 );
3107 assert_eq!(
3108 parse_decimal::<Decimal256Type>(s, 76, scale).unwrap(),
3109 i256::from_i128(expected),
3110 "{s} at scale {scale}"
3111 );
3112 }
3113 }
3114
3115 #[test]
3116 fn test_parse_decimal_rounding_overflow() {
3117 assert!(parse_decimal::<Decimal128Type>("99999.5", 5, 0).is_err());
3119 assert!(parse_decimal::<Decimal128Type>("9.995", 3, 2).is_err());
3120 assert_eq!(parse_decimal::<Decimal128Type>("9.994", 3, 2).unwrap(), 999);
3121 assert_eq!(parse_decimal::<Decimal128Type>("0.995", 3, 2).unwrap(), 100);
3122
3123 assert_eq!(
3125 parse_native::<Decimal32Type>("2147483647.5", 0),
3126 Err(DecimalParseError::Overflow)
3127 );
3128 assert_eq!(
3129 parse_native::<Decimal32Type>("-2147483648.5", 0),
3130 Err(DecimalParseError::Overflow)
3131 );
3132 assert_eq!(
3133 parse_native::<Decimal128Type>(&format!("{}.5", i128::MAX), 0),
3134 Err(DecimalParseError::Overflow)
3135 );
3136 assert_eq!(
3137 parse_native::<Decimal128Type>(&format!("{}.5", i128::MIN), 0),
3138 Err(DecimalParseError::Overflow)
3139 );
3140 assert_eq!(
3141 parse_native::<Decimal256Type>(&format!("{}.5", i256::MAX), 0),
3142 Err(DecimalParseError::Overflow)
3143 );
3144 assert_eq!(
3145 parse_native::<Decimal256Type>(&format!("{}.5", i256::MIN), 0),
3146 Err(DecimalParseError::Overflow)
3147 );
3148 }
3149
3150 #[test]
3151 fn test_parse_decimal_precision_by_digit_count() {
3152 assert_eq!(
3154 parse_decimal::<Decimal128Type>("99999.4", 5, 0).unwrap(),
3155 99999
3156 );
3157 assert!(parse_decimal::<Decimal128Type>("99999.5", 5, 0).is_err());
3158 assert!(parse_decimal::<Decimal128Type>("-99999.5", 5, 0).is_err());
3159 assert_eq!(
3160 parse_decimal::<Decimal128Type>("99999.5", 6, 0).unwrap(),
3161 100000
3162 );
3163 assert_eq!(
3166 parse_decimal::<Decimal128Type>("000000000000000000000001", 1, 0).unwrap(),
3167 1
3168 );
3169 assert_eq!(
3170 parse_decimal::<Decimal128Type>("0.000000000000000000001", 1, 21).unwrap(),
3171 1
3172 );
3173 assert!(parse_decimal::<Decimal128Type>("0.0000000000000000000012", 1, 22).is_err());
3174 assert_eq!(parse_decimal::<Decimal128Type>("1", 3, 2).unwrap(), 100);
3176 assert!(parse_decimal::<Decimal128Type>("1", 2, 2).is_err());
3177 assert!(parse_decimal::<Decimal128Type>("1e2", 2, 0).is_err());
3178 assert_eq!(parse_decimal::<Decimal32Type>("1e2", 3, 0).unwrap(), 100);
3179 assert_eq!(
3181 parse_decimal::<Decimal128Type>("123456", 2, -4).unwrap(),
3182 12
3183 );
3184 assert!(parse_decimal::<Decimal128Type>("123456", 1, -4).is_err());
3185 assert!(parse_decimal::<Decimal32Type>("1", 10, 0).is_err());
3187 assert!(parse_decimal::<Decimal32Type>("00000000001", 10, 0).is_err());
3188 assert!(parse_decimal::<Decimal128Type>("1", 39, 0).is_err());
3189 assert!(parse_decimal::<Decimal256Type>("1", 77, 0).is_err());
3190 }
3191
3192 #[test]
3193 fn test_parse_decimal_native_full_range() {
3194 assert_eq!(
3197 parse_native::<Decimal32Type>("-2147483648", 0),
3198 Ok(i32::MIN)
3199 );
3200 assert_eq!(
3201 parse_native::<Decimal32Type>("2147483648", 0),
3202 Err(DecimalParseError::Overflow)
3203 );
3204 assert_eq!(
3205 parse_native::<Decimal64Type>("-9223372036854775808", 0),
3206 Ok(i64::MIN)
3207 );
3208 assert_eq!(
3209 parse_native::<Decimal64Type>("9223372036854775808", 0),
3210 Err(DecimalParseError::Overflow)
3211 );
3212 assert_eq!(
3213 parse_native::<Decimal128Type>(&i128::MAX.to_string(), 0),
3214 Ok(i128::MAX)
3215 );
3216 assert_eq!(
3217 parse_native::<Decimal128Type>(&i128::MIN.to_string(), 0),
3218 Ok(i128::MIN)
3219 );
3220 assert_eq!(
3221 parse_native::<Decimal256Type>(&i256::MAX.to_string(), 0),
3222 Ok(i256::MAX)
3223 );
3224 assert_eq!(
3225 parse_native::<Decimal256Type>(&i256::MIN.to_string(), 0),
3226 Ok(i256::MIN)
3227 );
3228 let input = format!("{}.12345678901234567890123", "7".repeat(71));
3232 assert_eq!(
3233 parse_native::<Decimal256Type>(&input, 21),
3234 Err(DecimalParseError::Overflow)
3235 );
3236
3237 assert!(parse_decimal::<Decimal128Type>(&i128::MAX.to_string(), 38, 0).is_err());
3238 assert!(parse_decimal::<Decimal32Type>("-2147483648", 9, 0).is_err());
3239 }
3240
3241 #[test]
3242 fn test_parse_decimal_integer_widths() {
3243 assert_eq!(
3244 parse_decimal::<Decimal32Type>("123.45", 9, 2).unwrap(),
3245 12_345_i32
3246 );
3247 assert_eq!(
3248 parse_decimal::<Decimal32Type>("-9999999.994", 9, 2).unwrap(),
3249 -999_999_999_i32
3250 );
3251 assert!(parse_decimal::<Decimal32Type>("9999999.995", 9, 2).is_err());
3252 assert!(parse_decimal::<Decimal32Type>("-9999999.995", 9, 2).is_err());
3253 assert_eq!(
3254 parse_decimal::<Decimal64Type>("123.45", 18, 2).unwrap(),
3255 12_345_i64
3256 );
3257 assert_eq!(
3258 parse_decimal::<Decimal64Type>("9999999999999999.99", 18, 2).unwrap(),
3259 999_999_999_999_999_999_i64
3260 );
3261 assert!(parse_decimal::<Decimal64Type>("10000000000000000.00", 18, 2).is_err());
3262 assert_eq!(
3265 parse_decimal::<Decimal64Type>(&format!(".{}", "5".repeat(100)), 18, 4).unwrap(),
3266 5_556_i64
3267 );
3268 assert_eq!(
3269 parse_decimal::<Decimal128Type>(&format!(".{}", "1".repeat(100)), 38, 4).unwrap(),
3270 1_111_i128
3271 );
3272 }
3273
3274 #[test]
3275 fn test_parse_decimal_exponent() {
3276 let tests = [
3277 ("1e2", 0, 100),
3278 ("1E2", 0, 100),
3279 ("1e+2", 0, 100),
3280 ("1e+02", 0, 100),
3281 ("1.5e2", 0, 150),
3282 ("1.5e2", 2, 15000),
3283 ("1.5e-1", 1, 2),
3284 ("15e-1", 0, 2),
3285 ("1e-2", 1, 0),
3286 ("1e-3", 2, 0),
3287 ("0e0", 2, 0),
3288 ("-0e0", 2, 0),
3289 ("0E5", 2, 0),
3290 ("0e99999", 2, 0),
3291 ("00e48", 8, 0),
3292 ("+00.0E+41", 12, 0),
3293 ("1.25e1", 0, 13),
3294 ("1e-99999", 2, 0),
3295 ("1.5e-400", 2, 0),
3296 ("123456789e-9", 9, 123456789),
3297 ("0.000000001e9", 0, 1),
3298 ("5e-1", 0, 1),
3299 ("4e-1", 0, 0),
3300 ("-5e-1", 0, -1),
3301 ];
3302 for (s, scale, expected) in tests {
3303 assert_eq!(
3304 parse_decimal::<Decimal128Type>(s, 38, scale).unwrap(),
3305 expected,
3306 "{s} at scale {scale}"
3307 );
3308 assert_eq!(
3309 parse_decimal::<Decimal32Type>(s, 9, scale).unwrap(),
3310 expected as i32,
3311 "{s} at scale {scale}"
3312 );
3313 }
3314
3315 assert_eq!(
3317 parse_decimal::<Decimal32Type>("4825037936439135476.2609835314269495255615E-14", 9, 4)
3318 .unwrap(),
3319 482503794
3320 );
3321 assert_eq!(
3322 parse_decimal::<Decimal32Type>(
3323 "+18232335063972188138031550982650807591758238.0724251287782783777442440E-58",
3324 1,
3325 0
3326 )
3327 .unwrap(),
3328 0
3329 );
3330 assert_eq!(
3331 parse_decimal::<Decimal128Type>("4825037936439135476.2609835314269495255615E-14", 9, 1)
3332 .unwrap(),
3333 482504
3334 );
3335 assert!(
3336 parse_decimal::<Decimal128Type>("4825037936439135476.2609835314269495255615E-14", 5, 1)
3337 .is_err()
3338 );
3339 assert!(parse_decimal::<Decimal128Type>(&format!("1e{}", "9".repeat(30)), 38, 0).is_err());
3341 assert_eq!(
3342 parse_decimal::<Decimal128Type>(&format!("1e-{}", "9".repeat(30)), 38, 0).unwrap(),
3343 0
3344 );
3345 }
3346
3347 #[test]
3348 fn test_parse_decimal_negative_scale() {
3349 let tests = [
3350 ("1234.5", -2, 12),
3351 ("150", -2, 2),
3352 ("149", -2, 1),
3353 ("-150", -2, -2),
3354 ("-149", -2, -1),
3355 ("50", -2, 1),
3356 ("49", -2, 0),
3357 ("5", -1, 1),
3358 ("4", -1, 0),
3359 ("0.5", -1, 0),
3360 ("5.9", -1, 1),
3361 ("1e5", -2, 1000),
3362 ("1.5e5", -2, 1500),
3363 ("0.9e2", -1, 9),
3364 (".5e3", -2, 5),
3365 ("12345", -5, 0),
3366 ("12345", -4, 1),
3367 ("000123456", -3, 123),
3368 ("0", -5, 0),
3369 ("-0.0", -5, 0),
3370 ];
3371 for (s, scale, expected) in tests {
3372 assert_eq!(
3373 parse_decimal::<Decimal128Type>(s, 38, scale).unwrap(),
3374 expected,
3375 "{s} at scale {scale}"
3376 );
3377 assert_eq!(
3378 parse_decimal::<Decimal32Type>(s, 9, scale).unwrap(),
3379 expected as i32,
3380 "{s} at scale {scale}"
3381 );
3382 assert_eq!(
3383 parse_decimal::<Decimal256Type>(s, 76, scale).unwrap(),
3384 i256::from_i128(expected),
3385 "{s} at scale {scale}"
3386 );
3387 }
3388 assert_eq!(
3391 parse_decimal::<Decimal128Type>(&format!("1{}", "0".repeat(50)), 38, -40).unwrap(),
3392 10_000_000_000
3393 );
3394 assert_eq!(
3395 parse_decimal::<Decimal32Type>("123456789012", 9, -5).unwrap(),
3396 1234568
3397 );
3398 assert!(parse_decimal::<Decimal32Type>("123456789012", 9, -2).is_err());
3399 }
3400
3401 #[test]
3402 fn test_parse_decimal_whitespace_and_long_input() {
3403 for s in [" 1.5", "1.5 ", " 1.5 ", "\t1.5\n", "\r\n1.5\x0c"] {
3404 assert_eq!(
3405 parse_decimal::<Decimal128Type>(s, 38, 1).unwrap(),
3406 15,
3407 "{s:?}"
3408 );
3409 }
3410 assert!(parse_decimal::<Decimal128Type>("\u{a0}1.5", 38, 1).is_err());
3412 assert!(parse_decimal::<Decimal128Type>("1.5\u{2003}", 38, 1).is_err());
3413 assert!(parse_decimal::<Decimal128Type>(" ", 38, 1).is_err());
3414
3415 for s in [
3417 "1".repeat(255),
3418 "1".repeat(256),
3419 "1".repeat(300),
3420 format!("{}.5", "1".repeat(300)),
3421 format!("1e{}", "9".repeat(300)),
3422 ] {
3423 let err = parse_decimal::<Decimal128Type>(&s, 38, 0).unwrap_err();
3424 assert!(err.to_string().contains("does not fit"), "{err}");
3425 }
3426 assert_eq!(
3428 parse_decimal::<Decimal128Type>(&format!("0.{}", "0".repeat(200)), 38, 10).unwrap(),
3429 0
3430 );
3431 assert_eq!(
3432 parse_decimal::<Decimal128Type>(&format!("0.{}1", "0".repeat(200)), 38, 10).unwrap(),
3433 0
3434 );
3435 assert_eq!(
3436 parse_decimal::<Decimal128Type>(&format!("1.{}", "9".repeat(300)), 38, 2).unwrap(),
3437 200
3438 );
3439 assert_eq!(parse_decimal::<Decimal32Type>("0", 9, 10).unwrap(), 0);
3441 assert_eq!(parse_decimal::<Decimal32Type>("-0.0", 9, 10).unwrap(), 0);
3442 assert_eq!(parse_decimal::<Decimal64Type>("0", 18, 20).unwrap(), 0);
3443 assert_eq!(parse_decimal::<Decimal128Type>("0", 38, 40).unwrap(), 0);
3444 assert!(parse_decimal::<Decimal32Type>("1", 9, 10).is_err());
3445 }
3446
3447 #[test]
3448 #[cfg_attr(miri, ignore)] fn test_parse_decimal_matches_bigint_reference() {
3450 use num_bigint::BigInt;
3451 use rand::rngs::StdRng;
3452 use rand::{RngExt, SeedableRng};
3453
3454 fn check<T: DecimalType>(rng: &mut StdRng, iterations: usize)
3457 where
3458 T::Native: std::fmt::Display,
3459 {
3460 let random_digits = |rng: &mut StdRng, len: usize| -> String {
3461 (0..len)
3462 .map(|_| char::from(b'0' + rng.random_range(0..10u8)))
3463 .collect()
3464 };
3465 for _ in 0..iterations {
3466 let sign = ["", "+", "-"][rng.random_range(0..3)];
3467 let int_len = rng.random_range(0..=40);
3468 let frac_len = if rng.random_bool(0.3) {
3469 0
3470 } else {
3471 rng.random_range(0..=40)
3472 };
3473 if int_len == 0 && frac_len == 0 {
3474 continue;
3475 }
3476 let int = random_digits(rng, int_len);
3477 let frac = random_digits(rng, frac_len);
3478 let mut s = format!("{sign}{int}");
3479 if frac_len > 0 || rng.random_bool(0.2) {
3480 s.push('.');
3481 s.push_str(&frac);
3482 }
3483 let exponent: i64 = if rng.random_bool(0.3) {
3484 rng.random_range(-60..=60)
3485 } else {
3486 0
3487 };
3488 if exponent != 0 || rng.random_bool(0.1) {
3489 s.push(if rng.random_bool(0.5) { 'e' } else { 'E' });
3490 if exponent >= 0 && rng.random_bool(0.5) {
3491 s.push('+');
3492 }
3493 s.push_str(&exponent.to_string());
3494 }
3495 let precision = rng.random_range(1..=T::MAX_PRECISION);
3496 let scale = rng.random_range(-10..=T::MAX_SCALE.min(precision as i8));
3497
3498 let mantissa: BigInt = format!("{int}{frac}").parse().unwrap();
3501 let shift = exponent - frac_len as i64 + scale as i64;
3502 let mut expected = if shift >= 0 {
3503 mantissa * BigInt::from(10).pow(shift as u32)
3504 } else {
3505 let divisor = BigInt::from(10).pow((-shift) as u32);
3506 let quotient = &mantissa / &divisor;
3507 if (&mantissa % &divisor) * 2 >= divisor {
3508 quotient + 1
3509 } else {
3510 quotient
3511 }
3512 };
3513 if sign == "-" {
3514 expected = -expected;
3515 }
3516 let limit = BigInt::from(10).pow(precision as u32);
3517 let fits = expected < limit && expected > -limit;
3518
3519 match (fits, parse_decimal::<T>(&s, precision, scale)) {
3520 (true, Ok(actual)) => {
3521 let actual: BigInt = actual.to_string().parse().unwrap();
3522 assert_eq!(
3523 actual,
3524 expected,
3525 "{s:?} as {}({precision}, {scale})",
3526 T::PREFIX
3527 );
3528 }
3529 (false, Err(_)) => {}
3530 (true, Err(e)) => {
3531 panic!(
3532 "{s:?} as {}({precision}, {scale}): expected {expected}, got {e}",
3533 T::PREFIX
3534 )
3535 }
3536 (false, Ok(actual)) => panic!(
3537 "{s:?} as {}({precision}, {scale}): expected overflow, got {actual}",
3538 T::PREFIX
3539 ),
3540 }
3541 }
3542 }
3543
3544 let mut rng = StdRng::seed_from_u64(0xDEC1_3A15);
3545 check::<Decimal32Type>(&mut rng, 5_000);
3546 check::<Decimal64Type>(&mut rng, 5_000);
3547 check::<Decimal128Type>(&mut rng, 5_000);
3548 check::<Decimal256Type>(&mut rng, 5_000);
3549 }
3550
3551 #[test]
3552 fn test_parse_empty() {
3553 assert_eq!(Int32Type::parse(""), None);
3554 assert_eq!(Int64Type::parse(""), None);
3555 assert_eq!(UInt32Type::parse(""), None);
3556 assert_eq!(UInt64Type::parse(""), None);
3557 assert_eq!(Float32Type::parse(""), None);
3558 assert_eq!(Float64Type::parse(""), None);
3559 assert_eq!(Int32Type::parse("+"), None);
3560 assert_eq!(Int64Type::parse("+"), None);
3561 assert_eq!(UInt32Type::parse("+"), None);
3562 assert_eq!(UInt64Type::parse("+"), None);
3563 assert_eq!(Float32Type::parse("+"), None);
3564 assert_eq!(Float64Type::parse("+"), None);
3565 assert_eq!(TimestampNanosecondType::parse(""), None);
3566 assert_eq!(Date32Type::parse(""), None);
3567 }
3568
3569 #[test]
3570 fn test_parse_interval_month_day_nano_config() {
3571 let interval = parse_interval_month_day_nano_config(
3572 "1",
3573 IntervalParseConfig::new(IntervalUnit::Second),
3574 )
3575 .unwrap();
3576 assert_eq!(interval.months, 0);
3577 assert_eq!(interval.days, 0);
3578 assert_eq!(interval.nanoseconds, NANOS_PER_SECOND);
3579 }
3580 #[test]
3581 fn test_parse_prefix_white_space() {
3582 assert_eq!(Float64Type::parse(" 1.5"), Some(1.5));
3583 assert_eq!(Float64Type::parse("\t\n 20.54"), Some(20.54));
3584 assert_eq!(Float64Type::parse("\n2.5"), Some(2.5));
3585 assert_eq!(Float64Type::parse("\n-942.5423"), Some(-942.5423));
3586 assert_eq!(Float64Type::parse("\n\t\n\t\n40.5123"), Some(40.5123));
3587 assert_eq!(Float64Type::parse(" 1.5"), Some(1.5));
3588 assert_eq!(Float64Type::parse("\n\t\n\t\n-40.5123"), Some(-40.5123));
3589 assert_eq!(Float64Type::parse(" -1.5"), Some(-1.5));
3590 assert_eq!(Int32Type::parse(" 3"), Some(3));
3591 assert_eq!(Int32Type::parse(" 30"), Some(30));
3592 assert_eq!(Int32Type::parse("\n \n 100"), Some(100));
3593 assert_eq!(Int32Type::parse(" \n25"), Some(25));
3594 assert_eq!(Int32Type::parse("\t800"), Some(800));
3595 assert_eq!(Int32Type::parse("\t \n \t 851"), Some(851));
3596 assert_eq!(Int32Type::parse("\t\n\t\n\n\n\t1"), Some(1));
3597 assert_eq!(Int32Type::parse(" \n-25"), Some(-25));
3598 assert_eq!(Int32Type::parse("\t-800"), Some(-800));
3599
3600 assert_eq!(Float64Type::parse("1.5 "), Some(1.5));
3602 assert_eq!(Float64Type::parse("40.5123\n"), Some(40.5123));
3603 assert_eq!(Float64Type::parse("40.5123\n\t\n\t\n"), Some(40.5123));
3604 assert_eq!(Float64Type::parse("-942.5423\t"), Some(-942.5423));
3605 assert_eq!(Int32Type::parse("3 "), Some(3));
3606 assert_eq!(Int32Type::parse("30 "), Some(30));
3607 assert_eq!(Int32Type::parse("-25 \n"), Some(-25));
3608 assert_eq!(Int32Type::parse("800\t"), Some(800));
3609 assert_eq!(Float64Type::parse(" 1.5 "), Some(1.5));
3611 assert_eq!(Float64Type::parse("\t\n 20.54 \t"), Some(20.54));
3612 assert_eq!(Float64Type::parse("\n-942.5423\n"), Some(-942.5423));
3613 assert_eq!(Int32Type::parse(" 3 "), Some(3));
3614 assert_eq!(Int32Type::parse("\n \n 100 \n"), Some(100));
3615 assert_eq!(Int32Type::parse("\t-800\t\n"), Some(-800));
3616
3617 assert_eq!(Float64Type::parse("1.5abc"), None);
3619 assert_eq!(Float64Type::parse("40.5123x"), None);
3620 assert_eq!(Int32Type::parse("30x"), None);
3621 assert_eq!(Int32Type::parse("100px"), None);
3622 assert_eq!(Int32Type::parse("-25!"), None);
3623 assert_eq!(Int32Type::parse("3j"), None);
3624 assert_eq!(Int32Type::parse("3"), Some(3));
3625 }
3626}