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::from_hms_opt(0, 0, 0).unwrap());
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 let string = truncate_white_space(string);
449 lexical_core::parse(string.as_bytes())
450 .ok()
451 .map(f16::from_f32)
452 }
453}
454
455impl Parser for Float32Type {
456 fn parse(string: &str) -> Option<f32> {
457 let string = truncate_white_space(string);
458 lexical_core::parse(string.as_bytes()).ok()
459 }
460}
461
462impl Parser for Float64Type {
463 fn parse(string: &str) -> Option<f64> {
464 let string = truncate_white_space(string);
465 lexical_core::parse(string.as_bytes()).ok()
466 }
467}
468#[inline]
469fn truncate_white_space(string: &str) -> &str {
470 if string
471 .as_bytes()
472 .first()
473 .is_some_and(|first_byte| !first_byte.is_ascii_digit())
474 {
475 string.trim_ascii_start()
476 } else {
477 string
478 }
479}
480
481macro_rules! parser_primitive {
482 ($t:ty) => {
483 impl Parser for $t {
484 fn parse(mut string: &str) -> Option<Self::Native> {
485 if !string.as_bytes().last().is_some_and(|x| x.is_ascii_digit()) {
486 return None;
487 }
488 if string
489 .as_bytes()
490 .first()
491 .is_some_and(|first| !first.is_ascii_digit())
492 {
493 string = string.trim_ascii_start();
494 };
495 match atoi::FromRadix10SignedChecked::from_radix_10_signed_checked(
496 string.as_bytes(),
497 ) {
498 (Some(n), x) if x == string.len() => Some(n),
499 _ => None,
500 }
501 }
502 }
503 };
504}
505parser_primitive!(UInt64Type);
506parser_primitive!(UInt32Type);
507parser_primitive!(UInt16Type);
508parser_primitive!(UInt8Type);
509parser_primitive!(Int64Type);
510parser_primitive!(Int32Type);
511parser_primitive!(Int16Type);
512parser_primitive!(Int8Type);
513parser_primitive!(DurationNanosecondType);
514parser_primitive!(DurationMicrosecondType);
515parser_primitive!(DurationMillisecondType);
516parser_primitive!(DurationSecondType);
517
518impl Parser for TimestampNanosecondType {
519 fn parse(string: &str) -> Option<i64> {
520 string_to_timestamp_nanos(string).ok()
521 }
522}
523
524impl Parser for TimestampMicrosecondType {
525 fn parse(string: &str) -> Option<i64> {
526 let nanos = string_to_timestamp_nanos(string).ok();
527 nanos.map(|x| x / 1000)
528 }
529}
530
531impl Parser for TimestampMillisecondType {
532 fn parse(string: &str) -> Option<i64> {
533 let nanos = string_to_timestamp_nanos(string).ok();
534 nanos.map(|x| x / 1_000_000)
535 }
536}
537
538impl Parser for TimestampSecondType {
539 fn parse(string: &str) -> Option<i64> {
540 let nanos = string_to_timestamp_nanos(string).ok();
541 nanos.map(|x| x / 1_000_000_000)
542 }
543}
544
545impl Parser for Time64NanosecondType {
546 fn parse(string: &str) -> Option<Self::Native> {
548 string_to_time_nanoseconds(string)
549 .ok()
550 .or_else(|| string.parse::<Self::Native>().ok())
551 }
552
553 fn parse_formatted(string: &str, format: &str) -> Option<Self::Native> {
554 let nt = NaiveTime::parse_from_str(string, format).ok()?;
555 Some(nt.num_seconds_from_midnight() as i64 * 1_000_000_000 + nt.nanosecond() as i64)
556 }
557}
558
559impl Parser for Time64MicrosecondType {
560 fn parse(string: &str) -> Option<Self::Native> {
562 string_to_time_nanoseconds(string)
563 .ok()
564 .map(|nanos| nanos / 1_000)
565 .or_else(|| string.parse::<Self::Native>().ok())
566 }
567
568 fn parse_formatted(string: &str, format: &str) -> Option<Self::Native> {
569 let nt = NaiveTime::parse_from_str(string, format).ok()?;
570 Some(nt.num_seconds_from_midnight() as i64 * 1_000_000 + nt.nanosecond() as i64 / 1_000)
571 }
572}
573
574impl Parser for Time32MillisecondType {
575 fn parse(string: &str) -> Option<Self::Native> {
577 string_to_time_nanoseconds(string)
578 .ok()
579 .map(|nanos| (nanos / 1_000_000) as i32)
580 .or_else(|| string.parse::<Self::Native>().ok())
581 }
582
583 fn parse_formatted(string: &str, format: &str) -> Option<Self::Native> {
584 let nt = NaiveTime::parse_from_str(string, format).ok()?;
585 Some(nt.num_seconds_from_midnight() as i32 * 1_000 + nt.nanosecond() as i32 / 1_000_000)
586 }
587}
588
589impl Parser for Time32SecondType {
590 fn parse(string: &str) -> Option<Self::Native> {
592 string_to_time_nanoseconds(string)
593 .ok()
594 .map(|nanos| (nanos / 1_000_000_000) as i32)
595 .or_else(|| string.parse::<Self::Native>().ok())
596 }
597
598 fn parse_formatted(string: &str, format: &str) -> Option<Self::Native> {
599 let nt = NaiveTime::parse_from_str(string, format).ok()?;
600 Some(nt.num_seconds_from_midnight() as i32 + nt.nanosecond() as i32 / 1_000_000_000)
601 }
602}
603
604const EPOCH_DAYS_FROM_CE: i32 = 719_163;
606
607const 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";
609
610fn parse_extended_ymd(string: &str) -> Option<(i32, u32, u32)> {
617 debug_assert!(string.starts_with('+') || string.starts_with('-'));
618 let rest = &string[1..];
621 let hyphen = rest.find('-')?;
622 if hyphen < 4 {
623 return None;
624 }
625 let year: i32 = string[..hyphen + 1].parse().ok()?;
628 let remainder = string[hyphen + 1..].strip_prefix('-')?;
630 let mut parts = remainder.splitn(2, '-');
631 let month: u32 = parts.next()?.parse().ok()?;
632 let day: u32 = parts.next()?.parse().ok()?;
633 Some((year, month, day))
634}
635
636fn parse_date(string: &str) -> Option<NaiveDate> {
637 if string.starts_with('+') || string.starts_with('-') {
645 let (year, month, day) = parse_extended_ymd(string)?;
646 return NaiveDate::from_ymd_opt(year, month, day);
647 }
648
649 if string.len() > 10 {
650 return string_to_datetime(&Utc, string)
652 .map(|dt| dt.date_naive())
653 .ok();
654 };
655 let mut digits = [0; 10];
656 let mut mask = 0;
657
658 for (idx, (o, i)) in digits.iter_mut().zip(string.bytes()).enumerate() {
660 *o = i.wrapping_sub(b'0');
661 mask |= ((*o < 10) as u16) << idx
662 }
663
664 const HYPHEN: u8 = b'-'.wrapping_sub(b'0');
665
666 if digits[4] != HYPHEN {
668 let (year, month, day) = match (mask, string.len()) {
669 (0b11111111, 8) => (
670 digits[0] as u16 * 1000
671 + digits[1] as u16 * 100
672 + digits[2] as u16 * 10
673 + digits[3] as u16,
674 digits[4] * 10 + digits[5],
675 digits[6] * 10 + digits[7],
676 ),
677 _ => return None,
678 };
679 return NaiveDate::from_ymd_opt(year as _, month as _, day as _);
680 }
681
682 let (month, day) = match mask {
683 0b1101101111 => {
684 if digits[7] != HYPHEN {
685 return None;
686 }
687 (digits[5] * 10 + digits[6], digits[8] * 10 + digits[9])
688 }
689 0b101101111 => {
690 if digits[7] != HYPHEN {
691 return None;
692 }
693 (digits[5] * 10 + digits[6], digits[8])
694 }
695 0b110101111 => {
696 if digits[6] != HYPHEN {
697 return None;
698 }
699 (digits[5], digits[7] * 10 + digits[8])
700 }
701 0b10101111 => {
702 if digits[6] != HYPHEN {
703 return None;
704 }
705 (digits[5], digits[7])
706 }
707 _ => return None,
708 };
709
710 let year =
711 digits[0] as u16 * 1000 + digits[1] as u16 * 100 + digits[2] as u16 * 10 + digits[3] as u16;
712
713 NaiveDate::from_ymd_opt(year as _, month as _, day as _)
714}
715
716fn parse_date_to_days(string: &str) -> Option<i32> {
725 if string.starts_with('+') || string.starts_with('-') {
726 let (year, month, day) = parse_extended_ymd(string)?;
727 let y = year as i64;
728 let era = y.div_euclid(400);
729 let yoe = y.rem_euclid(400) as i32;
730 let nd = NaiveDate::from_ymd_opt(yoe, month, day)?;
731 let in_era = (nd.num_days_from_ce() - EPOCH_DAYS_FROM_CE) as i64;
732 return i32::try_from(era * 146_097 + in_era).ok();
733 }
734 parse_date(string).map(|nd| nd.num_days_from_ce() - EPOCH_DAYS_FROM_CE)
735}
736
737impl Parser for Date32Type {
738 fn parse(string: &str) -> Option<i32> {
739 parse_date_to_days(string)
740 }
741
742 fn parse_formatted(string: &str, format: &str) -> Option<i32> {
743 let date = NaiveDate::parse_from_str(string, format).ok()?;
744 Some(date.num_days_from_ce() - EPOCH_DAYS_FROM_CE)
745 }
746}
747
748impl Parser for Date64Type {
749 fn parse(string: &str) -> Option<i64> {
750 if string.len() <= 10 {
751 let datetime = NaiveDateTime::new(parse_date(string)?, NaiveTime::default());
752 Some(datetime.and_utc().timestamp_millis())
753 } else {
754 let date_time = string_to_datetime(&Utc, string).ok()?;
755 Some(date_time.timestamp_millis())
756 }
757 }
758
759 fn parse_formatted(string: &str, format: &str) -> Option<i64> {
760 use chrono::format::Fixed;
761 use chrono::format::StrftimeItems;
762 let fmt = StrftimeItems::new(format);
763 let has_zone = fmt.into_iter().any(|item| match item {
764 chrono::format::Item::Fixed(fixed_item) => matches!(
765 fixed_item,
766 Fixed::RFC2822
767 | Fixed::RFC3339
768 | Fixed::TimezoneName
769 | Fixed::TimezoneOffsetColon
770 | Fixed::TimezoneOffsetColonZ
771 | Fixed::TimezoneOffset
772 | Fixed::TimezoneOffsetZ
773 ),
774 _ => false,
775 });
776 if has_zone {
777 let date_time = chrono::DateTime::parse_from_str(string, format).ok()?;
778 Some(date_time.timestamp_millis())
779 } else {
780 let date_time = NaiveDateTime::parse_from_str(string, format).ok()?;
781 Some(date_time.and_utc().timestamp_millis())
782 }
783 }
784}
785
786fn parse_e_notation<T: DecimalType>(
787 s: &str,
788 mut digits: u16,
789 mut fractionals: i16,
790 mut result: T::Native,
791 index: usize,
792 precision: u16,
793 scale: i16,
794) -> Result<T::Native, ArrowError> {
795 let mut exp: i16 = 0;
796 let base = T::Native::usize_as(10);
797
798 let mut pos_shift_direction: bool = true;
800
801 let mut bs = s.as_bytes().iter().skip(index + fractionals as usize);
803
804 for b in bs.by_ref() {
810 match b {
811 b'0'..=b'9' => {
812 result = result.mul_wrapping(base);
813 result = result.add_wrapping(T::Native::usize_as((b - b'0') as usize));
814 fractionals += 1;
815 digits += 1;
816 }
817 b'e' | b'E' => {
818 break;
819 }
820 _ => {
821 return Err(ArrowError::ParseError(format!(
822 "can't parse the string value {s} to decimal"
823 )));
824 }
825 };
826 }
827
828 let mut signed = false;
830 for b in bs {
831 match b {
832 b'-' if !signed => {
833 pos_shift_direction = false;
834 signed = true;
835 }
836 b'+' if !signed => {
837 pos_shift_direction = true;
838 signed = true;
839 }
840 b if b.is_ascii_digit() => {
841 exp *= 10;
842 exp += (b - b'0') as i16;
843 }
844 _ => {
845 return Err(ArrowError::ParseError(format!(
846 "can't parse the string value {s} to decimal"
847 )));
848 }
849 }
850 }
851
852 if digits == 0 && fractionals == 0 && exp == 0 {
853 return Err(ArrowError::ParseError(format!(
854 "can't parse the string value {s} to decimal"
855 )));
856 }
857
858 if !pos_shift_direction {
859 if exp - (digits as i16 + scale) > 0 {
862 return Ok(T::Native::usize_as(0));
863 }
864 exp *= -1;
865 }
866
867 exp = fractionals - exp;
869 if !pos_shift_direction && exp > digits as i16 {
871 digits = exp as u16;
872 }
873 exp = scale - exp;
875
876 if (digits as i16 + exp) as u16 > precision {
877 return Err(ArrowError::ParseError(format!(
878 "parse decimal overflow ({s})"
879 )));
880 }
881
882 if exp < 0 {
883 result = result.div_wrapping(base.pow_wrapping(-exp as _));
884 } else {
885 result = result.mul_wrapping(base.pow_wrapping(exp as _));
886 }
887
888 Ok(result)
889}
890
891pub fn parse_decimal<T: DecimalType>(
898 s: &str,
899 precision: u8,
900 scale: i8,
901) -> Result<T::Native, ArrowError> {
902 let mut result = T::Native::usize_as(0);
903 let mut fractionals: i8 = 0;
904 let mut digits: u8 = 0;
905 let base = T::Native::usize_as(10);
906
907 let bs = s.as_bytes();
908
909 if !bs
910 .last()
911 .is_some_and(|b| b.is_ascii_digit() || (b == &b'.' && s.len() > 1))
912 {
913 return Err(ArrowError::ParseError(format!(
916 "can't parse the string value {s} to decimal"
917 )));
918 }
919
920 let (signed, negative) = match bs.first() {
921 Some(b'-') => (true, true),
922 Some(b'+') => (true, false),
923 _ => (false, false),
924 };
925
926 let mut bs = bs.iter().enumerate().skip(signed as usize);
928
929 let mut is_e_notation = false;
930
931 while let Some((index, b)) = bs.next() {
934 match b {
935 b'0'..=b'9' => {
936 if digits == 0 && *b == b'0' {
937 continue;
939 }
940 digits += 1;
941 result = result.mul_wrapping(base);
942 result = result.add_wrapping(T::Native::usize_as((b - b'0') as usize));
943 }
944 b'.' => {
945 let point_index = index;
946
947 for (_, b) in bs.by_ref() {
948 if !b.is_ascii_digit() {
949 if *b == b'e' || *b == b'E' {
950 result = parse_e_notation::<T>(
951 s,
952 digits as u16,
953 fractionals as i16,
954 result,
955 point_index + 1,
956 precision as u16,
957 scale as i16,
958 )?;
959
960 is_e_notation = true;
961
962 break;
963 }
964 return Err(ArrowError::ParseError(format!(
965 "can't parse the string value {s} to decimal"
966 )));
967 }
968 if fractionals == scale {
969 continue;
973 }
974 fractionals += 1;
975 digits += 1;
976 result = result.mul_wrapping(base);
977 result = result.add_wrapping(T::Native::usize_as((b - b'0') as usize));
978 }
979
980 if is_e_notation {
981 break;
982 }
983 }
984 b'e' | b'E' => {
985 result = parse_e_notation::<T>(
986 s,
987 digits as u16,
988 fractionals as i16,
989 result,
990 index,
991 precision as u16,
992 scale as i16,
993 )?;
994
995 is_e_notation = true;
996
997 break;
998 }
999 _ => {
1000 return Err(ArrowError::ParseError(format!(
1001 "can't parse the string value {s} to decimal"
1002 )));
1003 }
1004 }
1005 }
1006
1007 if !is_e_notation {
1008 if fractionals < scale {
1009 let exp = scale - fractionals;
1010 if exp as u8 + digits > precision {
1011 return Err(ArrowError::ParseError(format!(
1012 "parse decimal overflow ({s})"
1013 )));
1014 }
1015 let mul = base.pow_wrapping(exp as _);
1016 result = result.mul_wrapping(mul);
1017 } else if digits > precision {
1018 return Err(ArrowError::ParseError(format!(
1019 "parse decimal overflow ({s})"
1020 )));
1021 }
1022 }
1023
1024 Ok(if negative {
1025 result.neg_wrapping()
1026 } else {
1027 result
1028 })
1029}
1030
1031pub fn parse_interval_year_month(
1033 value: &str,
1034) -> Result<<IntervalYearMonthType as ArrowPrimitiveType>::Native, ArrowError> {
1035 let config = IntervalParseConfig::new(IntervalUnit::Year);
1036 let interval = Interval::parse(value, &config)?;
1037
1038 let months = interval.to_year_months().map_err(|_| {
1039 ArrowError::CastError(format!(
1040 "Cannot cast {value} to IntervalYearMonth. Only year and month fields are allowed."
1041 ))
1042 })?;
1043
1044 Ok(IntervalYearMonthType::make_value(0, months))
1045}
1046
1047pub fn parse_interval_day_time(
1049 value: &str,
1050) -> Result<<IntervalDayTimeType as ArrowPrimitiveType>::Native, ArrowError> {
1051 let config = IntervalParseConfig::new(IntervalUnit::Day);
1052 let interval = Interval::parse(value, &config)?;
1053
1054 let (days, millis) = interval.to_day_time().map_err(|_| ArrowError::CastError(format!(
1055 "Cannot cast {value} to IntervalDayTime because the nanos part isn't multiple of milliseconds"
1056 )))?;
1057
1058 Ok(IntervalDayTimeType::make_value(days, millis))
1059}
1060
1061pub fn parse_interval_month_day_nano_config(
1063 value: &str,
1064 config: IntervalParseConfig,
1065) -> Result<<IntervalMonthDayNanoType as ArrowPrimitiveType>::Native, ArrowError> {
1066 let interval = Interval::parse(value, &config)?;
1067
1068 let (months, days, nanos) = interval.to_month_day_nanos();
1069
1070 Ok(IntervalMonthDayNanoType::make_value(months, days, nanos))
1071}
1072
1073pub fn parse_interval_month_day_nano(
1075 value: &str,
1076) -> Result<<IntervalMonthDayNanoType as ArrowPrimitiveType>::Native, ArrowError> {
1077 parse_interval_month_day_nano_config(value, IntervalParseConfig::new(IntervalUnit::Month))
1078}
1079
1080const NANOS_PER_MILLIS: i64 = 1_000_000;
1081const NANOS_PER_SECOND: i64 = 1_000 * NANOS_PER_MILLIS;
1082const NANOS_PER_MINUTE: i64 = 60 * NANOS_PER_SECOND;
1083const NANOS_PER_HOUR: i64 = 60 * NANOS_PER_MINUTE;
1084#[cfg(test)]
1085const NANOS_PER_DAY: i64 = 24 * NANOS_PER_HOUR;
1086
1087#[derive(Debug, Clone)]
1091pub struct IntervalParseConfig {
1092 default_unit: IntervalUnit,
1095}
1096
1097impl IntervalParseConfig {
1098 pub fn new(default_unit: IntervalUnit) -> Self {
1100 Self { default_unit }
1101 }
1102}
1103
1104#[rustfmt::skip]
1105#[derive(Debug, Clone, Copy)]
1106#[repr(u16)]
1107pub enum IntervalUnit {
1110 Century = 0b_0000_0000_0001,
1112 Decade = 0b_0000_0000_0010,
1114 Year = 0b_0000_0000_0100,
1116 Month = 0b_0000_0000_1000,
1118 Week = 0b_0000_0001_0000,
1120 Day = 0b_0000_0010_0000,
1122 Hour = 0b_0000_0100_0000,
1124 Minute = 0b_0000_1000_0000,
1126 Second = 0b_0001_0000_0000,
1128 Millisecond = 0b_0010_0000_0000,
1130 Microsecond = 0b_0100_0000_0000,
1132 Nanosecond = 0b_1000_0000_0000,
1134}
1135
1136impl FromStr for IntervalUnit {
1141 type Err = ArrowError;
1142
1143 fn from_str(s: &str) -> Result<Self, ArrowError> {
1144 match s.to_lowercase().as_str() {
1145 "c" | "cent" | "cents" | "century" | "centuries" => Ok(Self::Century),
1146 "dec" | "decs" | "decade" | "decades" => Ok(Self::Decade),
1147 "y" | "yr" | "yrs" | "year" | "years" => Ok(Self::Year),
1148 "mon" | "mons" | "month" | "months" => Ok(Self::Month),
1149 "w" | "week" | "weeks" => Ok(Self::Week),
1150 "d" | "day" | "days" => Ok(Self::Day),
1151 "h" | "hr" | "hrs" | "hour" | "hours" => Ok(Self::Hour),
1152 "m" | "min" | "mins" | "minute" | "minutes" => Ok(Self::Minute),
1153 "s" | "sec" | "secs" | "second" | "seconds" => Ok(Self::Second),
1154 "ms" | "msec" | "msecs" | "msecond" | "mseconds" | "millisecond" | "milliseconds" => {
1155 Ok(Self::Millisecond)
1156 }
1157 "us" | "usec" | "usecs" | "usecond" | "useconds" | "microsecond" | "microseconds" => {
1158 Ok(Self::Microsecond)
1159 }
1160 "nanosecond" | "nanoseconds" => Ok(Self::Nanosecond),
1161 _ => Err(ArrowError::InvalidArgumentError(format!(
1162 "Unknown interval type: {s}"
1163 ))),
1164 }
1165 }
1166}
1167
1168impl IntervalUnit {
1169 fn from_str_or_config(
1170 s: Option<&str>,
1171 config: &IntervalParseConfig,
1172 ) -> Result<Self, ArrowError> {
1173 match s {
1174 Some(s) => s.parse(),
1175 None => Ok(config.default_unit),
1176 }
1177 }
1178}
1179
1180pub type MonthDayNano = (i32, i32, i64);
1182
1183const INTERVAL_PRECISION: u32 = 15;
1185
1186#[derive(Clone, Copy, Debug, PartialEq)]
1187struct IntervalAmount {
1188 integer: i64,
1190 frac: i64,
1192}
1193
1194#[cfg(test)]
1195impl IntervalAmount {
1196 fn new(integer: i64, frac: i64) -> Self {
1197 Self { integer, frac }
1198 }
1199}
1200
1201impl FromStr for IntervalAmount {
1202 type Err = ArrowError;
1203
1204 fn from_str(s: &str) -> Result<Self, Self::Err> {
1205 match s.split_once('.') {
1206 Some((integer, frac))
1207 if frac.len() <= INTERVAL_PRECISION as usize
1208 && !frac.is_empty()
1209 && !frac.starts_with('-') =>
1210 {
1211 let explicit_neg = integer.starts_with('-');
1214 let integer = if integer.is_empty() || integer == "-" {
1215 Ok(0)
1216 } else {
1217 integer.parse::<i64>().map_err(|_| {
1218 ArrowError::ParseError(format!("Failed to parse {s} as interval amount"))
1219 })
1220 }?;
1221
1222 let frac_unscaled = frac.parse::<i64>().map_err(|_| {
1223 ArrowError::ParseError(format!("Failed to parse {s} as interval amount"))
1224 })?;
1225
1226 let frac = frac_unscaled * 10_i64.pow(INTERVAL_PRECISION - frac.len() as u32);
1228
1229 let frac = if integer < 0 || explicit_neg {
1231 -frac
1232 } else {
1233 frac
1234 };
1235
1236 let result = Self { integer, frac };
1237
1238 Ok(result)
1239 }
1240 Some((_, frac)) if frac.starts_with('-') => Err(ArrowError::ParseError(format!(
1241 "Failed to parse {s} as interval amount"
1242 ))),
1243 Some((_, frac)) if frac.len() > INTERVAL_PRECISION as usize => {
1244 Err(ArrowError::ParseError(format!(
1245 "{s} exceeds the precision available for interval amount"
1246 )))
1247 }
1248 Some(_) | None => {
1249 let integer = s.parse::<i64>().map_err(|_| {
1250 ArrowError::ParseError(format!("Failed to parse {s} as interval amount"))
1251 })?;
1252
1253 let result = Self { integer, frac: 0 };
1254 Ok(result)
1255 }
1256 }
1257 }
1258}
1259
1260#[derive(Debug, Default, PartialEq)]
1261struct Interval {
1262 months: i32,
1263 days: i32,
1264 nanos: i64,
1265}
1266
1267impl Interval {
1268 fn new(months: i32, days: i32, nanos: i64) -> Self {
1269 Self {
1270 months,
1271 days,
1272 nanos,
1273 }
1274 }
1275
1276 fn to_year_months(&self) -> Result<i32, ArrowError> {
1277 match (self.months, self.days, self.nanos) {
1278 (months, days, nanos) if days == 0 && nanos == 0 => Ok(months),
1279 _ => Err(ArrowError::InvalidArgumentError(format!(
1280 "Unable to represent interval with days and nanos as year-months: {self:?}"
1281 ))),
1282 }
1283 }
1284
1285 fn to_day_time(&self) -> Result<(i32, i32), ArrowError> {
1286 let days = self.months.mul_checked(30)?.add_checked(self.days)?;
1287
1288 match self.nanos {
1289 nanos if nanos % NANOS_PER_MILLIS == 0 => {
1290 let millis = (self.nanos / 1_000_000).try_into().map_err(|_| {
1291 ArrowError::InvalidArgumentError(format!(
1292 "Unable to represent {} nanos as milliseconds in a signed 32-bit integer",
1293 self.nanos
1294 ))
1295 })?;
1296
1297 Ok((days, millis))
1298 }
1299 nanos => Err(ArrowError::InvalidArgumentError(format!(
1300 "Unable to represent {nanos} as milliseconds"
1301 ))),
1302 }
1303 }
1304
1305 fn to_month_day_nanos(&self) -> (i32, i32, i64) {
1306 (self.months, self.days, self.nanos)
1307 }
1308
1309 fn parse(value: &str, config: &IntervalParseConfig) -> Result<Self, ArrowError> {
1312 let components = parse_interval_components(value, config)?;
1313
1314 components
1315 .into_iter()
1316 .try_fold(Self::default(), |result, (amount, unit)| {
1317 result.add(amount, unit)
1318 })
1319 }
1320
1321 fn add(&self, amount: IntervalAmount, unit: IntervalUnit) -> Result<Self, ArrowError> {
1328 let result = match unit {
1329 IntervalUnit::Century => {
1330 let months_int = amount.integer.mul_checked(100)?.mul_checked(12)?;
1331 let month_frac = amount.frac * 12 / 10_i64.pow(INTERVAL_PRECISION - 2);
1332 let months = months_int
1333 .add_checked(month_frac)?
1334 .try_into()
1335 .map_err(|_| {
1336 ArrowError::ParseError(format!(
1337 "Unable to represent {} centuries as months in a signed 32-bit integer",
1338 amount.integer
1339 ))
1340 })?;
1341
1342 Self::new(self.months.add_checked(months)?, self.days, self.nanos)
1343 }
1344 IntervalUnit::Decade => {
1345 let months_int = amount.integer.mul_checked(10)?.mul_checked(12)?;
1346
1347 let month_frac = amount.frac * 12 / 10_i64.pow(INTERVAL_PRECISION - 1);
1348 let months = months_int
1349 .add_checked(month_frac)?
1350 .try_into()
1351 .map_err(|_| {
1352 ArrowError::ParseError(format!(
1353 "Unable to represent {} decades as months in a signed 32-bit integer",
1354 amount.integer
1355 ))
1356 })?;
1357
1358 Self::new(self.months.add_checked(months)?, self.days, self.nanos)
1359 }
1360 IntervalUnit::Year => {
1361 let months_int = amount.integer.mul_checked(12)?;
1362 let month_frac = amount.frac * 12 / 10_i64.pow(INTERVAL_PRECISION);
1363 let months = months_int
1364 .add_checked(month_frac)?
1365 .try_into()
1366 .map_err(|_| {
1367 ArrowError::ParseError(format!(
1368 "Unable to represent {} years as months in a signed 32-bit integer",
1369 amount.integer
1370 ))
1371 })?;
1372
1373 Self::new(self.months.add_checked(months)?, self.days, self.nanos)
1374 }
1375 IntervalUnit::Month => {
1376 let months = amount.integer.try_into().map_err(|_| {
1377 ArrowError::ParseError(format!(
1378 "Unable to represent {} months in a signed 32-bit integer",
1379 amount.integer
1380 ))
1381 })?;
1382
1383 let days = amount.frac * 3 / 10_i64.pow(INTERVAL_PRECISION - 1);
1384 let days = days.try_into().map_err(|_| {
1385 ArrowError::ParseError(format!(
1386 "Unable to represent {} months as days in a signed 32-bit integer",
1387 amount.frac / 10_i64.pow(INTERVAL_PRECISION)
1388 ))
1389 })?;
1390
1391 Self::new(
1392 self.months.add_checked(months)?,
1393 self.days.add_checked(days)?,
1394 self.nanos,
1395 )
1396 }
1397 IntervalUnit::Week => {
1398 let days = amount.integer.mul_checked(7)?.try_into().map_err(|_| {
1399 ArrowError::ParseError(format!(
1400 "Unable to represent {} weeks as days in a signed 32-bit integer",
1401 amount.integer
1402 ))
1403 })?;
1404
1405 let nanos = amount.frac * 7 * 24 * 6 * 6 / 10_i64.pow(INTERVAL_PRECISION - 11);
1406
1407 Self::new(
1408 self.months,
1409 self.days.add_checked(days)?,
1410 self.nanos.add_checked(nanos)?,
1411 )
1412 }
1413 IntervalUnit::Day => {
1414 let days = amount.integer.try_into().map_err(|_| {
1415 ArrowError::InvalidArgumentError(format!(
1416 "Unable to represent {} days in a signed 32-bit integer",
1417 amount.integer
1418 ))
1419 })?;
1420
1421 let nanos = amount.frac * 24 * 6 * 6 / 10_i64.pow(INTERVAL_PRECISION - 11);
1422
1423 Self::new(
1424 self.months,
1425 self.days.add_checked(days)?,
1426 self.nanos.add_checked(nanos)?,
1427 )
1428 }
1429 IntervalUnit::Hour => {
1430 let nanos_int = amount.integer.mul_checked(NANOS_PER_HOUR)?;
1431 let nanos_frac = amount.frac * 6 * 6 / 10_i64.pow(INTERVAL_PRECISION - 11);
1432 let nanos = nanos_int.add_checked(nanos_frac)?;
1433
1434 Interval::new(self.months, self.days, self.nanos.add_checked(nanos)?)
1435 }
1436 IntervalUnit::Minute => {
1437 let nanos_int = amount.integer.mul_checked(NANOS_PER_MINUTE)?;
1438 let nanos_frac = amount.frac * 6 / 10_i64.pow(INTERVAL_PRECISION - 10);
1439
1440 let nanos = nanos_int.add_checked(nanos_frac)?;
1441
1442 Interval::new(self.months, self.days, self.nanos.add_checked(nanos)?)
1443 }
1444 IntervalUnit::Second => {
1445 let nanos_int = amount.integer.mul_checked(NANOS_PER_SECOND)?;
1446 let nanos_frac = amount.frac / 10_i64.pow(INTERVAL_PRECISION - 9);
1447 let nanos = nanos_int.add_checked(nanos_frac)?;
1448
1449 Interval::new(self.months, self.days, self.nanos.add_checked(nanos)?)
1450 }
1451 IntervalUnit::Millisecond => {
1452 let nanos_int = amount.integer.mul_checked(NANOS_PER_MILLIS)?;
1453 let nanos_frac = amount.frac / 10_i64.pow(INTERVAL_PRECISION - 6);
1454 let nanos = nanos_int.add_checked(nanos_frac)?;
1455
1456 Interval::new(self.months, self.days, self.nanos.add_checked(nanos)?)
1457 }
1458 IntervalUnit::Microsecond => {
1459 let nanos_int = amount.integer.mul_checked(1_000)?;
1460 let nanos_frac = amount.frac / 10_i64.pow(INTERVAL_PRECISION - 3);
1461 let nanos = nanos_int.add_checked(nanos_frac)?;
1462
1463 Interval::new(self.months, self.days, self.nanos.add_checked(nanos)?)
1464 }
1465 IntervalUnit::Nanosecond => {
1466 let nanos_int = amount.integer;
1467 let nanos_frac = amount.frac / 10_i64.pow(INTERVAL_PRECISION);
1468 let nanos = nanos_int.add_checked(nanos_frac)?;
1469
1470 Interval::new(self.months, self.days, self.nanos.add_checked(nanos)?)
1471 }
1472 };
1473
1474 Ok(result)
1475 }
1476}
1477
1478fn parse_interval_components(
1480 value: &str,
1481 config: &IntervalParseConfig,
1482) -> Result<Vec<(IntervalAmount, IntervalUnit)>, ArrowError> {
1483 let raw_pairs = split_interval_components(value);
1484
1485 let Ok(pairs): Result<Vec<(IntervalAmount, IntervalUnit)>, ArrowError> = raw_pairs
1487 .iter()
1488 .map(|(a, u)| Ok((a.parse()?, IntervalUnit::from_str_or_config(*u, config)?)))
1489 .collect()
1490 else {
1491 return Err(ArrowError::ParseError(format!(
1492 "Invalid input syntax for type interval: {value:?}"
1493 )));
1494 };
1495
1496 let (amounts, units): (Vec<_>, Vec<_>) = pairs.into_iter().unzip();
1498
1499 let mut observed_interval_types = 0;
1501 for (unit, (_, raw_unit)) in units.iter().zip(raw_pairs) {
1502 if observed_interval_types & (*unit as u16) != 0 {
1503 return Err(ArrowError::ParseError(format!(
1504 "Invalid input syntax for type interval: {:?}. Repeated type '{}'",
1505 value,
1506 raw_unit.unwrap_or_default(),
1507 )));
1508 }
1509
1510 observed_interval_types |= *unit as u16;
1511 }
1512
1513 let result = amounts.iter().copied().zip(units.iter().copied());
1514
1515 Ok(result.collect::<Vec<_>>())
1516}
1517
1518fn split_interval_components(value: &str) -> Vec<(&str, Option<&str>)> {
1524 let mut result = vec![];
1525 let mut words = value.split(char::is_whitespace);
1526 while let Some(word) = words.next() {
1527 if let Some(split_word_at) = word.find(not_interval_amount) {
1528 let (amount, unit) = word.split_at(split_word_at);
1529 result.push((amount, Some(unit)));
1530 } else if let Some(unit) = words.next() {
1531 result.push((word, Some(unit)));
1532 } else {
1533 result.push((word, None));
1534 break;
1535 }
1536 }
1537 result
1538}
1539
1540fn not_interval_amount(c: char) -> bool {
1542 !c.is_ascii_digit() && c != '.' && c != '-'
1543}
1544
1545#[cfg(test)]
1546mod tests {
1547 use super::*;
1548 use arrow_array::temporal_conversions::date32_to_datetime;
1549 use arrow_buffer::i256;
1550
1551 #[test]
1552 fn test_parse_nanos() {
1553 assert_eq!(parse_nanos::<3, 0>(&[1, 2, 3]), 123_000_000);
1554 assert_eq!(parse_nanos::<5, 0>(&[1, 2, 3, 4, 5]), 123_450_000);
1555 assert_eq!(parse_nanos::<6, b'0'>(b"123456"), 123_456_000);
1556 }
1557
1558 #[test]
1559 fn string_to_timestamp_timezone() {
1560 assert_eq!(
1562 1599572549190855000,
1563 parse_timestamp("2020-09-08T13:42:29.190855+00:00").unwrap()
1564 );
1565 assert_eq!(
1566 1599572549190855000,
1567 parse_timestamp("2020-09-08T13:42:29.190855Z").unwrap()
1568 );
1569 assert_eq!(
1570 1599572549000000000,
1571 parse_timestamp("2020-09-08T13:42:29Z").unwrap()
1572 ); assert_eq!(
1574 1599590549190855000,
1575 parse_timestamp("2020-09-08T13:42:29.190855-05:00").unwrap()
1576 );
1577 }
1578
1579 #[test]
1580 fn string_to_timestamp_timezone_space() {
1581 assert_eq!(
1583 1599572549190855000,
1584 parse_timestamp("2020-09-08 13:42:29.190855+00:00").unwrap()
1585 );
1586 assert_eq!(
1587 1599572549190855000,
1588 parse_timestamp("2020-09-08 13:42:29.190855Z").unwrap()
1589 );
1590 assert_eq!(
1591 1599572549000000000,
1592 parse_timestamp("2020-09-08 13:42:29Z").unwrap()
1593 ); assert_eq!(
1595 1599590549190855000,
1596 parse_timestamp("2020-09-08 13:42:29.190855-05:00").unwrap()
1597 );
1598 }
1599
1600 #[test]
1601 #[cfg_attr(miri, ignore)] fn string_to_timestamp_no_timezone() {
1603 let naive_datetime = NaiveDateTime::new(
1607 NaiveDate::from_ymd_opt(2020, 9, 8).unwrap(),
1608 NaiveTime::from_hms_nano_opt(13, 42, 29, 190855000).unwrap(),
1609 );
1610
1611 assert_eq!(
1613 naive_datetime.and_utc().timestamp_nanos_opt().unwrap(),
1614 parse_timestamp("2020-09-08T13:42:29.190855").unwrap()
1615 );
1616
1617 assert_eq!(
1618 naive_datetime.and_utc().timestamp_nanos_opt().unwrap(),
1619 parse_timestamp("2020-09-08 13:42:29.190855").unwrap()
1620 );
1621
1622 let datetime_whole_secs = NaiveDateTime::new(
1625 NaiveDate::from_ymd_opt(2020, 9, 8).unwrap(),
1626 NaiveTime::from_hms_opt(13, 42, 29).unwrap(),
1627 )
1628 .and_utc();
1629
1630 assert_eq!(
1632 datetime_whole_secs.timestamp_nanos_opt().unwrap(),
1633 parse_timestamp("2020-09-08T13:42:29").unwrap()
1634 );
1635
1636 assert_eq!(
1637 datetime_whole_secs.timestamp_nanos_opt().unwrap(),
1638 parse_timestamp("2020-09-08 13:42:29").unwrap()
1639 );
1640
1641 let datetime_no_time = NaiveDateTime::new(
1645 NaiveDate::from_ymd_opt(2020, 9, 8).unwrap(),
1646 NaiveTime::from_hms_opt(0, 0, 0).unwrap(),
1647 )
1648 .and_utc();
1649
1650 assert_eq!(
1651 datetime_no_time.timestamp_nanos_opt().unwrap(),
1652 parse_timestamp("2020-09-08").unwrap()
1653 )
1654 }
1655
1656 #[test]
1657 fn string_to_timestamp_chrono() {
1658 let cases = [
1659 "2020-09-08T13:42:29Z",
1660 "1969-01-01T00:00:00.1Z",
1661 "2020-09-08T12:00:12.12345678+00:00",
1662 "2020-09-08T12:00:12+00:00",
1663 "2020-09-08T12:00:12.1+00:00",
1664 "2020-09-08T12:00:12.12+00:00",
1665 "2020-09-08T12:00:12.123+00:00",
1666 "2020-09-08T12:00:12.1234+00:00",
1667 "2020-09-08T12:00:12.12345+00:00",
1668 "2020-09-08T12:00:12.123456+00:00",
1669 "2020-09-08T12:00:12.1234567+00:00",
1670 "2020-09-08T12:00:12.12345678+00:00",
1671 "2020-09-08T12:00:12.123456789+00:00",
1672 "2020-09-08T12:00:12.12345678912z",
1673 "2020-09-08T12:00:12.123456789123Z",
1674 "2020-09-08T12:00:12.123456789123+02:00",
1675 "2020-09-08T12:00:12.12345678912345Z",
1676 "2020-09-08T12:00:12.1234567891234567+02:00",
1677 "2020-09-08T12:00:60Z",
1678 "2020-09-08T12:00:60.123Z",
1679 "2020-09-08T12:00:60.123456+02:00",
1680 "2020-09-08T12:00:60.1234567891234567+02:00",
1681 "2020-09-08T12:00:60.999999999+02:00",
1682 "2020-09-08t12:00:12.12345678+00:00",
1683 "2020-09-08t12:00:12+00:00",
1684 "2020-09-08t12:00:12Z",
1685 ];
1686
1687 for case in cases {
1688 let chrono = DateTime::parse_from_rfc3339(case).unwrap();
1689 let chrono_utc = chrono.with_timezone(&Utc);
1690
1691 let custom = string_to_datetime(&Utc, case).unwrap();
1692 assert_eq!(chrono_utc, custom)
1693 }
1694 }
1695
1696 #[test]
1697 fn string_to_timestamp_naive() {
1698 let cases = [
1699 "2018-11-13T17:11:10.011375885995",
1700 "2030-12-04T17:11:10.123",
1701 "2030-12-04T17:11:10.1234",
1702 "2030-12-04T17:11:10.123456",
1703 ];
1704 for case in cases {
1705 let chrono = NaiveDateTime::parse_from_str(case, "%Y-%m-%dT%H:%M:%S%.f").unwrap();
1706 let custom = string_to_datetime(&Utc, case).unwrap();
1707 assert_eq!(chrono, custom.naive_utc())
1708 }
1709 }
1710
1711 #[test]
1712 fn string_to_timestamp_invalid() {
1713 let cases = [
1715 ("", "timestamp must contain at least 10 characters"),
1716 ("SS", "timestamp must contain at least 10 characters"),
1717 ("Wed, 18 Feb 2015 23:16:09 GMT", "error parsing date"),
1718 ("1997-01-31H09:26:56.123Z", "invalid timestamp separator"),
1719 ("1997-01-31 09:26:56.123Z", "error parsing time"),
1720 ("1997:01:31T09:26:56.123Z", "error parsing date"),
1721 ("1997:1:31T09:26:56.123Z", "error parsing date"),
1722 ("1997-01-32T09:26:56.123Z", "error parsing date"),
1723 ("1997-13-32T09:26:56.123Z", "error parsing date"),
1724 ("1997-02-29T09:26:56.123Z", "error parsing date"),
1725 ("2015-02-30T17:35:20-08:00", "error parsing date"),
1726 ("1997-01-10T9:26:56.123Z", "error parsing time"),
1727 ("2015-01-20T25:35:20-08:00", "error parsing time"),
1728 ("1997-01-10T09:61:56.123Z", "error parsing time"),
1729 ("1997-01-10T09:61:90.123Z", "error parsing time"),
1730 ("1997-01-10T12:00:6.123Z", "error parsing time"),
1731 ("1997-01-31T092656.123Z", "error parsing time"),
1732 ("1997-01-10T12:00:06.", "error parsing time"),
1733 ("1997-01-10T12:00:06. ", "error parsing time"),
1734 ];
1735
1736 for (s, ctx) in cases {
1737 let expected = format!("Parser error: Error parsing timestamp from '{s}': {ctx}");
1738 let actual = string_to_datetime(&Utc, s).unwrap_err().to_string();
1739 assert_eq!(actual, expected)
1740 }
1741 }
1742
1743 fn parse_timestamp(s: &str) -> Result<i64, ArrowError> {
1745 let result = string_to_timestamp_nanos(s);
1746 if let Err(e) = &result {
1747 eprintln!("Error parsing timestamp '{s}': {e:?}");
1748 }
1749 result
1750 }
1751
1752 #[test]
1753 fn string_without_timezone_to_timestamp() {
1754 let naive_datetime = NaiveDateTime::new(
1757 NaiveDate::from_ymd_opt(2020, 9, 8).unwrap(),
1758 NaiveTime::from_hms_nano_opt(13, 42, 29, 190855000).unwrap(),
1759 );
1760
1761 assert_eq!(
1763 naive_datetime.and_utc().timestamp_nanos_opt().unwrap(),
1764 parse_timestamp("2020-09-08T13:42:29.190855").unwrap()
1765 );
1766
1767 assert_eq!(
1768 naive_datetime.and_utc().timestamp_nanos_opt().unwrap(),
1769 parse_timestamp("2020-09-08 13:42:29.190855").unwrap()
1770 );
1771
1772 let naive_datetime = NaiveDateTime::new(
1773 NaiveDate::from_ymd_opt(2020, 9, 8).unwrap(),
1774 NaiveTime::from_hms_nano_opt(13, 42, 29, 0).unwrap(),
1775 );
1776
1777 assert_eq!(
1779 naive_datetime.and_utc().timestamp_nanos_opt().unwrap(),
1780 parse_timestamp("2020-09-08T13:42:29").unwrap()
1781 );
1782
1783 assert_eq!(
1784 naive_datetime.and_utc().timestamp_nanos_opt().unwrap(),
1785 parse_timestamp("2020-09-08 13:42:29").unwrap()
1786 );
1787
1788 let tz: Tz = "+02:00".parse().unwrap();
1789 let date = string_to_datetime(&tz, "2020-09-08 13:42:29").unwrap();
1790 let utc = date.naive_utc().to_string();
1791 assert_eq!(utc, "2020-09-08 11:42:29");
1792 let local = date.naive_local().to_string();
1793 assert_eq!(local, "2020-09-08 13:42:29");
1794
1795 let date = string_to_datetime(&tz, "2020-09-08 13:42:29Z").unwrap();
1796 let utc = date.naive_utc().to_string();
1797 assert_eq!(utc, "2020-09-08 13:42:29");
1798 let local = date.naive_local().to_string();
1799 assert_eq!(local, "2020-09-08 15:42:29");
1800
1801 let dt =
1802 NaiveDateTime::parse_from_str("2020-09-08T13:42:29Z", "%Y-%m-%dT%H:%M:%SZ").unwrap();
1803 let local: Tz = "+08:00".parse().unwrap();
1804
1805 let date = string_to_datetime(&local, "2020-09-08T13:42:29Z").unwrap();
1807 assert_eq!(dt, date.naive_utc());
1808 assert_ne!(dt, date.naive_local());
1809
1810 let date = string_to_datetime(&local, "2020-09-08 13:42:29").unwrap();
1812 assert_eq!(dt, date.naive_local());
1813 assert_ne!(dt, date.naive_utc());
1814 }
1815
1816 #[test]
1817 fn parse_date32() {
1818 let cases = [
1819 "2020-09-08",
1820 "2020-9-8",
1821 "2020-09-8",
1822 "2020-9-08",
1823 "2020-12-1",
1824 "1690-2-5",
1825 "2020-09-08 01:02:03",
1826 ];
1827 for case in cases {
1828 let v = date32_to_datetime(Date32Type::parse(case).unwrap()).unwrap();
1829 let expected = NaiveDate::parse_from_str(case, "%Y-%m-%d")
1830 .or(NaiveDate::parse_from_str(case, "%Y-%m-%d %H:%M:%S"))
1831 .unwrap();
1832 assert_eq!(v.date(), expected);
1833 }
1834
1835 let err_cases = [
1836 "",
1837 "80-01-01",
1838 "342",
1839 "Foo",
1840 "2020-09-08-03",
1841 "2020--04-03",
1842 "2020--",
1843 "2020-09-08 01",
1844 "2020-09-08 01:02",
1845 "2020-09-08 01-02-03",
1846 "2020-9-8 01:02:03",
1847 "2020-09-08 1:2:3",
1848 ];
1849 for case in err_cases {
1850 assert_eq!(Date32Type::parse(case), None);
1851 }
1852 }
1853
1854 #[test]
1855 fn parse_date32_extended_year() {
1856 let cases: &[(&str, i32)] = &[
1858 ("+1970-01-01", 0),
1859 ("+2024-01-01", 19_723),
1860 ("-0001-01-01", -719_893),
1861 ("+29349-01-26", 10_000_000),
1862 ("+2739877-01-03", 1_000_000_000),
1863 ("+5881580-07-11", i32::MAX),
1865 ("-5877641-06-23", i32::MIN),
1866 ];
1867 for (input, expected) in cases {
1868 assert_eq!(Date32Type::parse(input), Some(*expected), "input: {input}");
1869 }
1870
1871 assert_eq!(Date32Type::parse("+5881580-07-12"), None);
1873 assert_eq!(Date32Type::parse("-5877641-06-22"), None);
1874 assert_eq!(Date32Type::parse("+2739877-02-30"), None);
1876 assert_eq!(Date32Type::parse("+2739877-13-01"), None);
1877 assert_eq!(Date32Type::parse("-2739877-02-30"), None);
1878 }
1879
1880 #[test]
1881 fn parse_time64_nanos() {
1882 assert_eq!(
1883 Time64NanosecondType::parse("02:10:01.1234567899999999"),
1884 Some(7_801_123_456_789)
1885 );
1886 assert_eq!(
1887 Time64NanosecondType::parse("02:10:01.1234567"),
1888 Some(7_801_123_456_700)
1889 );
1890 assert_eq!(
1891 Time64NanosecondType::parse("2:10:01.1234567"),
1892 Some(7_801_123_456_700)
1893 );
1894 assert_eq!(
1895 Time64NanosecondType::parse("12:10:01.123456789 AM"),
1896 Some(601_123_456_789)
1897 );
1898 assert_eq!(
1899 Time64NanosecondType::parse("12:10:01.123456789 am"),
1900 Some(601_123_456_789)
1901 );
1902 assert_eq!(
1903 Time64NanosecondType::parse("2:10:01.12345678 PM"),
1904 Some(51_001_123_456_780)
1905 );
1906 assert_eq!(
1907 Time64NanosecondType::parse("2:10:01.12345678 pm"),
1908 Some(51_001_123_456_780)
1909 );
1910 assert_eq!(
1911 Time64NanosecondType::parse("02:10:01"),
1912 Some(7_801_000_000_000)
1913 );
1914 assert_eq!(
1915 Time64NanosecondType::parse("2:10:01"),
1916 Some(7_801_000_000_000)
1917 );
1918 assert_eq!(
1919 Time64NanosecondType::parse("12:10:01 AM"),
1920 Some(601_000_000_000)
1921 );
1922 assert_eq!(
1923 Time64NanosecondType::parse("12:10:01 am"),
1924 Some(601_000_000_000)
1925 );
1926 assert_eq!(
1927 Time64NanosecondType::parse("2:10:01 PM"),
1928 Some(51_001_000_000_000)
1929 );
1930 assert_eq!(
1931 Time64NanosecondType::parse("2:10:01 pm"),
1932 Some(51_001_000_000_000)
1933 );
1934 assert_eq!(
1935 Time64NanosecondType::parse("02:10"),
1936 Some(7_800_000_000_000)
1937 );
1938 assert_eq!(Time64NanosecondType::parse("2:10"), Some(7_800_000_000_000));
1939 assert_eq!(
1940 Time64NanosecondType::parse("12:10 AM"),
1941 Some(600_000_000_000)
1942 );
1943 assert_eq!(
1944 Time64NanosecondType::parse("12:10 am"),
1945 Some(600_000_000_000)
1946 );
1947 assert_eq!(
1948 Time64NanosecondType::parse("2:10 PM"),
1949 Some(51_000_000_000_000)
1950 );
1951 assert_eq!(
1952 Time64NanosecondType::parse("2:10 pm"),
1953 Some(51_000_000_000_000)
1954 );
1955
1956 assert_eq!(Time64NanosecondType::parse("1"), Some(1));
1958
1959 assert_eq!(
1961 Time64NanosecondType::parse("23:59:60"),
1962 Some(86_400_000_000_000)
1963 );
1964
1965 assert_eq!(
1967 Time64NanosecondType::parse_formatted("02 - 10 - 01 - .1234567", "%H - %M - %S - %.f"),
1968 Some(7_801_123_456_700)
1969 );
1970 }
1971
1972 #[test]
1973 fn parse_time64_micros() {
1974 assert_eq!(
1976 Time64MicrosecondType::parse("02:10:01.1234"),
1977 Some(7_801_123_400)
1978 );
1979 assert_eq!(
1980 Time64MicrosecondType::parse("2:10:01.1234"),
1981 Some(7_801_123_400)
1982 );
1983 assert_eq!(
1984 Time64MicrosecondType::parse("12:10:01.123456 AM"),
1985 Some(601_123_456)
1986 );
1987 assert_eq!(
1988 Time64MicrosecondType::parse("12:10:01.123456 am"),
1989 Some(601_123_456)
1990 );
1991 assert_eq!(
1992 Time64MicrosecondType::parse("2:10:01.12345 PM"),
1993 Some(51_001_123_450)
1994 );
1995 assert_eq!(
1996 Time64MicrosecondType::parse("2:10:01.12345 pm"),
1997 Some(51_001_123_450)
1998 );
1999 assert_eq!(
2000 Time64MicrosecondType::parse("02:10:01"),
2001 Some(7_801_000_000)
2002 );
2003 assert_eq!(Time64MicrosecondType::parse("2:10:01"), Some(7_801_000_000));
2004 assert_eq!(
2005 Time64MicrosecondType::parse("12:10:01 AM"),
2006 Some(601_000_000)
2007 );
2008 assert_eq!(
2009 Time64MicrosecondType::parse("12:10:01 am"),
2010 Some(601_000_000)
2011 );
2012 assert_eq!(
2013 Time64MicrosecondType::parse("2:10:01 PM"),
2014 Some(51_001_000_000)
2015 );
2016 assert_eq!(
2017 Time64MicrosecondType::parse("2:10:01 pm"),
2018 Some(51_001_000_000)
2019 );
2020 assert_eq!(Time64MicrosecondType::parse("02:10"), Some(7_800_000_000));
2021 assert_eq!(Time64MicrosecondType::parse("2:10"), Some(7_800_000_000));
2022 assert_eq!(Time64MicrosecondType::parse("12:10 AM"), Some(600_000_000));
2023 assert_eq!(Time64MicrosecondType::parse("12:10 am"), Some(600_000_000));
2024 assert_eq!(
2025 Time64MicrosecondType::parse("2:10 PM"),
2026 Some(51_000_000_000)
2027 );
2028 assert_eq!(
2029 Time64MicrosecondType::parse("2:10 pm"),
2030 Some(51_000_000_000)
2031 );
2032
2033 assert_eq!(Time64MicrosecondType::parse("1"), Some(1));
2035
2036 assert_eq!(
2038 Time64MicrosecondType::parse("23:59:60"),
2039 Some(86_400_000_000)
2040 );
2041
2042 assert_eq!(
2044 Time64MicrosecondType::parse_formatted("02 - 10 - 01 - .1234", "%H - %M - %S - %.f"),
2045 Some(7_801_123_400)
2046 );
2047 }
2048
2049 #[test]
2050 fn parse_time32_millis() {
2051 assert_eq!(Time32MillisecondType::parse("02:10:01.1"), Some(7_801_100));
2053 assert_eq!(Time32MillisecondType::parse("2:10:01.1"), Some(7_801_100));
2054 assert_eq!(
2055 Time32MillisecondType::parse("12:10:01.123 AM"),
2056 Some(601_123)
2057 );
2058 assert_eq!(
2059 Time32MillisecondType::parse("12:10:01.123 am"),
2060 Some(601_123)
2061 );
2062 assert_eq!(
2063 Time32MillisecondType::parse("2:10:01.12 PM"),
2064 Some(51_001_120)
2065 );
2066 assert_eq!(
2067 Time32MillisecondType::parse("2:10:01.12 pm"),
2068 Some(51_001_120)
2069 );
2070 assert_eq!(Time32MillisecondType::parse("02:10:01"), Some(7_801_000));
2071 assert_eq!(Time32MillisecondType::parse("2:10:01"), Some(7_801_000));
2072 assert_eq!(Time32MillisecondType::parse("12:10:01 AM"), Some(601_000));
2073 assert_eq!(Time32MillisecondType::parse("12:10:01 am"), Some(601_000));
2074 assert_eq!(Time32MillisecondType::parse("2:10:01 PM"), Some(51_001_000));
2075 assert_eq!(Time32MillisecondType::parse("2:10:01 pm"), Some(51_001_000));
2076 assert_eq!(Time32MillisecondType::parse("02:10"), Some(7_800_000));
2077 assert_eq!(Time32MillisecondType::parse("2:10"), Some(7_800_000));
2078 assert_eq!(Time32MillisecondType::parse("12:10 AM"), Some(600_000));
2079 assert_eq!(Time32MillisecondType::parse("12:10 am"), Some(600_000));
2080 assert_eq!(Time32MillisecondType::parse("2:10 PM"), Some(51_000_000));
2081 assert_eq!(Time32MillisecondType::parse("2:10 pm"), Some(51_000_000));
2082
2083 assert_eq!(Time32MillisecondType::parse("1"), Some(1));
2085
2086 assert_eq!(Time32MillisecondType::parse("23:59:60"), Some(86_400_000));
2088
2089 assert_eq!(
2091 Time32MillisecondType::parse_formatted("02 - 10 - 01 - .1", "%H - %M - %S - %.f"),
2092 Some(7_801_100)
2093 );
2094 }
2095
2096 #[test]
2097 fn parse_time32_secs() {
2098 assert_eq!(Time32SecondType::parse("02:10:01.1"), Some(7_801));
2100 assert_eq!(Time32SecondType::parse("02:10:01"), Some(7_801));
2101 assert_eq!(Time32SecondType::parse("2:10:01"), Some(7_801));
2102 assert_eq!(Time32SecondType::parse("12:10:01 AM"), Some(601));
2103 assert_eq!(Time32SecondType::parse("12:10:01 am"), Some(601));
2104 assert_eq!(Time32SecondType::parse("2:10:01 PM"), Some(51_001));
2105 assert_eq!(Time32SecondType::parse("2:10:01 pm"), Some(51_001));
2106 assert_eq!(Time32SecondType::parse("02:10"), Some(7_800));
2107 assert_eq!(Time32SecondType::parse("2:10"), Some(7_800));
2108 assert_eq!(Time32SecondType::parse("12:10 AM"), Some(600));
2109 assert_eq!(Time32SecondType::parse("12:10 am"), Some(600));
2110 assert_eq!(Time32SecondType::parse("2:10 PM"), Some(51_000));
2111 assert_eq!(Time32SecondType::parse("2:10 pm"), Some(51_000));
2112
2113 assert_eq!(Time32SecondType::parse("1"), Some(1));
2115
2116 assert_eq!(Time32SecondType::parse("23:59:60"), Some(86400));
2118
2119 assert_eq!(
2121 Time32SecondType::parse_formatted("02 - 10 - 01", "%H - %M - %S"),
2122 Some(7_801)
2123 );
2124 }
2125
2126 #[test]
2127 fn test_string_to_time_invalid() {
2128 let cases = [
2129 "25:00",
2130 "9:00:",
2131 "009:00",
2132 "09:0:00",
2133 "25:00:00",
2134 "13:00 AM",
2135 "13:00 PM",
2136 "12:00. AM",
2137 "09:0:00",
2138 "09:01:0",
2139 "09:01:1",
2140 "9:1:0",
2141 "09:01:0",
2142 "1:00.123",
2143 "1:00:00.123f",
2144 " 9:00:00",
2145 ":09:00",
2146 "T9:00:00",
2147 "AM",
2148 ];
2149 for case in cases {
2150 assert!(string_to_time(case).is_none(), "{case}");
2151 }
2152 }
2153
2154 #[test]
2155 fn test_string_to_time_chrono() {
2156 let cases = [
2157 ("1:00", "%H:%M"),
2158 ("12:00", "%H:%M"),
2159 ("13:00", "%H:%M"),
2160 ("24:00", "%H:%M"),
2161 ("1:00:00", "%H:%M:%S"),
2162 ("12:00:30", "%H:%M:%S"),
2163 ("13:00:59", "%H:%M:%S"),
2164 ("24:00:60", "%H:%M:%S"),
2165 ("09:00:00", "%H:%M:%S%.f"),
2166 ("0:00:30.123456", "%H:%M:%S%.f"),
2167 ("0:00 AM", "%I:%M %P"),
2168 ("1:00 AM", "%I:%M %P"),
2169 ("12:00 AM", "%I:%M %P"),
2170 ("13:00 AM", "%I:%M %P"),
2171 ("0:00 PM", "%I:%M %P"),
2172 ("1:00 PM", "%I:%M %P"),
2173 ("12:00 PM", "%I:%M %P"),
2174 ("13:00 PM", "%I:%M %P"),
2175 ("1:00 pM", "%I:%M %P"),
2176 ("1:00 Pm", "%I:%M %P"),
2177 ("1:00 aM", "%I:%M %P"),
2178 ("1:00 Am", "%I:%M %P"),
2179 ("1:00:30.123456 PM", "%I:%M:%S%.f %P"),
2180 ("1:00:30.123456789 PM", "%I:%M:%S%.f %P"),
2181 ("1:00:30.123456789123 PM", "%I:%M:%S%.f %P"),
2182 ("1:00:30.1234 PM", "%I:%M:%S%.f %P"),
2183 ("1:00:30.123456 PM", "%I:%M:%S%.f %P"),
2184 ("1:00:30.123456789123456789 PM", "%I:%M:%S%.f %P"),
2185 ("1:00:30.12F456 PM", "%I:%M:%S%.f %P"),
2186 ];
2187 for (s, format) in cases {
2188 let chrono = NaiveTime::parse_from_str(s, format).ok();
2189 let custom = string_to_time(s);
2190 assert_eq!(chrono, custom, "{s}");
2191 }
2192 }
2193
2194 #[test]
2195 fn test_parse_interval() {
2196 let config = IntervalParseConfig::new(IntervalUnit::Month);
2197
2198 assert_eq!(
2199 Interval::new(1i32, 0i32, 0i64),
2200 Interval::parse("1 month", &config).unwrap(),
2201 );
2202
2203 assert_eq!(
2204 Interval::new(2i32, 0i32, 0i64),
2205 Interval::parse("2 month", &config).unwrap(),
2206 );
2207
2208 assert_eq!(
2209 Interval::new(-1i32, -18i32, -(NANOS_PER_DAY / 5)),
2210 Interval::parse("-1.5 months -3.2 days", &config).unwrap(),
2211 );
2212
2213 assert_eq!(
2214 Interval::new(0i32, 15i32, 0),
2215 Interval::parse("0.5 months", &config).unwrap(),
2216 );
2217
2218 assert_eq!(
2219 Interval::new(0i32, 15i32, 0),
2220 Interval::parse(".5 months", &config).unwrap(),
2221 );
2222
2223 assert_eq!(
2224 Interval::new(0i32, -15i32, 0),
2225 Interval::parse("-0.5 months", &config).unwrap(),
2226 );
2227
2228 assert_eq!(
2229 Interval::new(0i32, -15i32, 0),
2230 Interval::parse("-.5 months", &config).unwrap(),
2231 );
2232
2233 assert_eq!(
2234 Interval::new(2i32, 10i32, 9 * NANOS_PER_HOUR),
2235 Interval::parse("2.1 months 7.25 days 3 hours", &config).unwrap(),
2236 );
2237
2238 assert_eq!(
2239 Interval::parse("1 centurys 1 month", &config)
2240 .unwrap_err()
2241 .to_string(),
2242 r#"Parser error: Invalid input syntax for type interval: "1 centurys 1 month""#
2243 );
2244
2245 assert_eq!(
2246 Interval::new(37i32, 0i32, 0i64),
2247 Interval::parse("3 year 1 month", &config).unwrap(),
2248 );
2249
2250 assert_eq!(
2251 Interval::new(35i32, 0i32, 0i64),
2252 Interval::parse("3 year -1 month", &config).unwrap(),
2253 );
2254
2255 assert_eq!(
2256 Interval::new(-37i32, 0i32, 0i64),
2257 Interval::parse("-3 year -1 month", &config).unwrap(),
2258 );
2259
2260 assert_eq!(
2261 Interval::new(-35i32, 0i32, 0i64),
2262 Interval::parse("-3 year 1 month", &config).unwrap(),
2263 );
2264
2265 assert_eq!(
2266 Interval::new(0i32, 5i32, 0i64),
2267 Interval::parse("5 days", &config).unwrap(),
2268 );
2269
2270 assert_eq!(
2271 Interval::new(0i32, 7i32, 3 * NANOS_PER_HOUR),
2272 Interval::parse("7 days 3 hours", &config).unwrap(),
2273 );
2274
2275 assert_eq!(
2276 Interval::new(0i32, 7i32, 5 * NANOS_PER_MINUTE),
2277 Interval::parse("7 days 5 minutes", &config).unwrap(),
2278 );
2279
2280 assert_eq!(
2281 Interval::new(0i32, 7i32, -5 * NANOS_PER_MINUTE),
2282 Interval::parse("7 days -5 minutes", &config).unwrap(),
2283 );
2284
2285 assert_eq!(
2286 Interval::new(0i32, -7i32, 5 * NANOS_PER_HOUR),
2287 Interval::parse("-7 days 5 hours", &config).unwrap(),
2288 );
2289
2290 assert_eq!(
2291 Interval::new(
2292 0i32,
2293 -7i32,
2294 -5 * NANOS_PER_HOUR - 5 * NANOS_PER_MINUTE - 5 * NANOS_PER_SECOND
2295 ),
2296 Interval::parse("-7 days -5 hours -5 minutes -5 seconds", &config).unwrap(),
2297 );
2298
2299 assert_eq!(
2300 Interval::new(12i32, 0i32, 25 * NANOS_PER_MILLIS),
2301 Interval::parse("1 year 25 millisecond", &config).unwrap(),
2302 );
2303
2304 assert_eq!(
2305 Interval::new(
2306 12i32,
2307 1i32,
2308 (NANOS_PER_SECOND as f64 * 0.000000001_f64) as i64
2309 ),
2310 Interval::parse("1 year 1 day 0.000000001 seconds", &config).unwrap(),
2311 );
2312
2313 assert_eq!(
2314 Interval::new(12i32, 1i32, NANOS_PER_MILLIS / 10),
2315 Interval::parse("1 year 1 day 0.1 milliseconds", &config).unwrap(),
2316 );
2317
2318 assert_eq!(
2319 Interval::new(12i32, 1i32, 1000i64),
2320 Interval::parse("1 year 1 day 1 microsecond", &config).unwrap(),
2321 );
2322
2323 assert_eq!(
2324 Interval::new(12i32, 1i32, 1i64),
2325 Interval::parse("1 year 1 day 1 nanoseconds", &config).unwrap(),
2326 );
2327
2328 assert_eq!(
2329 Interval::new(1i32, 0i32, -NANOS_PER_SECOND),
2330 Interval::parse("1 month -1 second", &config).unwrap(),
2331 );
2332
2333 assert_eq!(
2334 Interval::new(
2335 -13i32,
2336 -8i32,
2337 -NANOS_PER_HOUR
2338 - NANOS_PER_MINUTE
2339 - NANOS_PER_SECOND
2340 - (1.11_f64 * NANOS_PER_MILLIS as f64) as i64
2341 ),
2342 Interval::parse(
2343 "-1 year -1 month -1 week -1 day -1 hour -1 minute -1 second -1.11 millisecond",
2344 &config
2345 )
2346 .unwrap(),
2347 );
2348
2349 assert_eq!(
2351 Interval::new(1, 0, 0),
2352 Interval::parse("1", &config).unwrap()
2353 );
2354 assert_eq!(
2355 Interval::new(42, 0, 0),
2356 Interval::parse("42", &config).unwrap()
2357 );
2358 assert_eq!(
2359 Interval::new(0, 0, 42_000_000_000),
2360 Interval::parse("42", &IntervalParseConfig::new(IntervalUnit::Second)).unwrap()
2361 );
2362
2363 assert_eq!(
2365 Interval::new(1, 0, 0),
2366 Interval::parse("1 mon", &config).unwrap()
2367 );
2368 assert_eq!(
2369 Interval::new(1, 0, 0),
2370 Interval::parse("1 mons", &config).unwrap()
2371 );
2372 assert_eq!(
2373 Interval::new(0, 0, 1_000_000),
2374 Interval::parse("1 ms", &config).unwrap()
2375 );
2376 assert_eq!(
2377 Interval::new(0, 0, 1_000),
2378 Interval::parse("1 us", &config).unwrap()
2379 );
2380
2381 assert_eq!(
2383 Interval::new(0, 0, 1_000),
2384 Interval::parse("1us", &config).unwrap()
2385 );
2386 assert_eq!(
2387 Interval::new(0, 0, NANOS_PER_SECOND),
2388 Interval::parse("1s", &config).unwrap()
2389 );
2390 assert_eq!(
2391 Interval::new(1, 2, 10_864_000_000_000),
2392 Interval::parse("1mon 2days 3hr 1min 4sec", &config).unwrap()
2393 );
2394
2395 assert_eq!(
2396 Interval::new(
2397 -13i32,
2398 -8i32,
2399 -NANOS_PER_HOUR
2400 - NANOS_PER_MINUTE
2401 - NANOS_PER_SECOND
2402 - (1.11_f64 * NANOS_PER_MILLIS as f64) as i64
2403 ),
2404 Interval::parse(
2405 "-1year -1month -1week -1day -1 hour -1 minute -1 second -1.11millisecond",
2406 &config
2407 )
2408 .unwrap(),
2409 );
2410
2411 assert_eq!(
2412 Interval::parse("1h s", &config).unwrap_err().to_string(),
2413 r#"Parser error: Invalid input syntax for type interval: "1h s""#
2414 );
2415
2416 assert_eq!(
2417 Interval::parse("1XX", &config).unwrap_err().to_string(),
2418 r#"Parser error: Invalid input syntax for type interval: "1XX""#
2419 );
2420 }
2421
2422 #[test]
2423 fn test_duplicate_interval_type() {
2424 let config = IntervalParseConfig::new(IntervalUnit::Month);
2425
2426 let err = Interval::parse("1 month 1 second 1 second", &config)
2427 .expect_err("parsing interval should have failed");
2428 assert_eq!(
2429 r#"ParseError("Invalid input syntax for type interval: \"1 month 1 second 1 second\". Repeated type 'second'")"#,
2430 format!("{err:?}")
2431 );
2432
2433 let err = Interval::parse("1 century 2 centuries", &config)
2435 .expect_err("parsing interval should have failed");
2436 assert_eq!(
2437 r#"ParseError("Invalid input syntax for type interval: \"1 century 2 centuries\". Repeated type 'centuries'")"#,
2438 format!("{err:?}")
2439 );
2440 }
2441
2442 #[test]
2443 fn test_interval_amount_parsing() {
2444 let result = IntervalAmount::from_str("123").unwrap();
2446 let expected = IntervalAmount::new(123, 0);
2447
2448 assert_eq!(result, expected);
2449
2450 let result = IntervalAmount::from_str("0.3").unwrap();
2452 let expected = IntervalAmount::new(0, 3 * 10_i64.pow(INTERVAL_PRECISION - 1));
2453
2454 assert_eq!(result, expected);
2455
2456 let result = IntervalAmount::from_str("-3.5").unwrap();
2458 let expected = IntervalAmount::new(-3, -5 * 10_i64.pow(INTERVAL_PRECISION - 1));
2459
2460 assert_eq!(result, expected);
2461
2462 let result = IntervalAmount::from_str("3.");
2464 assert!(result.is_err());
2465
2466 let result = IntervalAmount::from_str("3.-5");
2468 assert!(result.is_err());
2469 }
2470
2471 #[test]
2472 fn test_interval_precision() {
2473 let config = IntervalParseConfig::new(IntervalUnit::Month);
2474
2475 let result = Interval::parse("100000.1 days", &config).unwrap();
2476 let expected = Interval::new(0_i32, 100_000_i32, NANOS_PER_DAY / 10);
2477
2478 assert_eq!(result, expected);
2479 }
2480
2481 #[test]
2482 fn test_interval_addition() {
2483 let start = Interval::new(1, 2, 3);
2485 let expected = Interval::new(4921, 2, 3);
2486
2487 let result = start
2488 .add(
2489 IntervalAmount::new(4, 10_i64.pow(INTERVAL_PRECISION - 1)),
2490 IntervalUnit::Century,
2491 )
2492 .unwrap();
2493
2494 assert_eq!(result, expected);
2495
2496 let start = Interval::new(1, 2, 3);
2498 let expected = Interval::new(1231, 2, 3);
2499
2500 let result = start
2501 .add(
2502 IntervalAmount::new(10, 25 * 10_i64.pow(INTERVAL_PRECISION - 2)),
2503 IntervalUnit::Decade,
2504 )
2505 .unwrap();
2506
2507 assert_eq!(result, expected);
2508
2509 let start = Interval::new(1, 2, 3);
2511 let expected = Interval::new(364, 2, 3);
2512
2513 let result = start
2514 .add(
2515 IntervalAmount::new(30, 3 * 10_i64.pow(INTERVAL_PRECISION - 1)),
2516 IntervalUnit::Year,
2517 )
2518 .unwrap();
2519
2520 assert_eq!(result, expected);
2521
2522 let start = Interval::new(1, 2, 3);
2524 let expected = Interval::new(2, 17, 3);
2525
2526 let result = start
2527 .add(
2528 IntervalAmount::new(1, 5 * 10_i64.pow(INTERVAL_PRECISION - 1)),
2529 IntervalUnit::Month,
2530 )
2531 .unwrap();
2532
2533 assert_eq!(result, expected);
2534
2535 let start = Interval::new(1, 25, 3);
2537 let expected = Interval::new(1, 11, 3);
2538
2539 let result = start
2540 .add(IntervalAmount::new(-2, 0), IntervalUnit::Week)
2541 .unwrap();
2542
2543 assert_eq!(result, expected);
2544
2545 let start = Interval::new(12, 15, 3);
2547 let expected = Interval::new(12, 17, 3 + 17_280 * NANOS_PER_SECOND);
2548
2549 let result = start
2550 .add(
2551 IntervalAmount::new(2, 2 * 10_i64.pow(INTERVAL_PRECISION - 1)),
2552 IntervalUnit::Day,
2553 )
2554 .unwrap();
2555
2556 assert_eq!(result, expected);
2557
2558 let start = Interval::new(1, 2, 3);
2560 let expected = Interval::new(1, 2, 3 + 45_000 * NANOS_PER_SECOND);
2561
2562 let result = start
2563 .add(
2564 IntervalAmount::new(12, 5 * 10_i64.pow(INTERVAL_PRECISION - 1)),
2565 IntervalUnit::Hour,
2566 )
2567 .unwrap();
2568
2569 assert_eq!(result, expected);
2570
2571 let start = Interval::new(0, 0, -3);
2573 let expected = Interval::new(0, 0, -90_000_000_000 - 3);
2574
2575 let result = start
2576 .add(
2577 IntervalAmount::new(-1, -5 * 10_i64.pow(INTERVAL_PRECISION - 1)),
2578 IntervalUnit::Minute,
2579 )
2580 .unwrap();
2581
2582 assert_eq!(result, expected);
2583 }
2584
2585 #[test]
2586 fn string_to_timestamp_old() {
2587 parse_timestamp("1677-06-14T07:29:01.256")
2588 .map_err(|e| assert!(e.to_string().ends_with(ERR_NANOSECONDS_NOT_SUPPORTED)))
2589 .unwrap_err();
2590 }
2591
2592 #[test]
2593 fn test_parse_decimal_with_parameter() {
2594 let tests = [
2595 ("0", 0i128),
2596 ("123.123", 123123i128),
2597 ("123.1234", 123123i128),
2598 ("123.1", 123100i128),
2599 ("123", 123000i128),
2600 ("-123.123", -123123i128),
2601 ("-123.1234", -123123i128),
2602 ("-123.1", -123100i128),
2603 ("-123", -123000i128),
2604 ("0.0000123", 0i128),
2605 ("12.", 12000i128),
2606 ("-12.", -12000i128),
2607 ("00.1", 100i128),
2608 ("-00.1", -100i128),
2609 ("12345678912345678.1234", 12345678912345678123i128),
2610 ("-12345678912345678.1234", -12345678912345678123i128),
2611 ("99999999999999999.999", 99999999999999999999i128),
2612 ("-99999999999999999.999", -99999999999999999999i128),
2613 (".123", 123i128),
2614 ("-.123", -123i128),
2615 ("123.", 123000i128),
2616 ("-123.", -123000i128),
2617 ];
2618 for (s, i) in tests {
2619 let result_128 = parse_decimal::<Decimal128Type>(s, 20, 3);
2620 assert_eq!(i, result_128.unwrap());
2621 let result_256 = parse_decimal::<Decimal256Type>(s, 20, 3);
2622 assert_eq!(i256::from_i128(i), result_256.unwrap());
2623 }
2624
2625 let e_notation_tests = [
2626 ("1.23e3", "1230.0", 2),
2627 ("5.6714e+2", "567.14", 4),
2628 ("5.6714e-2", "0.056714", 4),
2629 ("5.6714e-2", "0.056714", 3),
2630 ("5.6741214125e2", "567.41214125", 4),
2631 ("8.91E4", "89100.0", 2),
2632 ("3.14E+5", "314000.0", 2),
2633 ("2.718e0", "2.718", 2),
2634 ("9.999999e-1", "0.9999999", 4),
2635 ("1.23e+3", "1230", 2),
2636 ("1.234559e+3", "1234.559", 2),
2637 ("1.00E-10", "0.0000000001", 11),
2638 ("1.23e-4", "0.000123", 2),
2639 ("9.876e7", "98760000.0", 2),
2640 ("5.432E+8", "543200000.0", 10),
2641 ("1.234567e9", "1234567000.0", 2),
2642 ("1.234567e2", "123.45670000", 2),
2643 ("4749.3e-5", "0.047493", 10),
2644 ("4749.3e+5", "474930000", 10),
2645 ("4749.3e-5", "0.047493", 1),
2646 ("4749.3e+5", "474930000", 1),
2647 ("0E-8", "0", 10),
2648 ("0E+6", "0", 10),
2649 ("1E-8", "0.00000001", 10),
2650 ("12E+6", "12000000", 10),
2651 ("12E-6", "0.000012", 10),
2652 ("0.1e-6", "0.0000001", 10),
2653 ("0.1e+6", "100000", 10),
2654 ("0.12e-6", "0.00000012", 10),
2655 ("0.12e+6", "120000", 10),
2656 ("000000000001e0", "000000000001", 3),
2657 ("000001.1034567002e0", "000001.1034567002", 3),
2658 ("1.234e16", "12340000000000000", 0),
2659 ("123.4e16", "1234000000000000000", 0),
2660 ];
2661 for (e, d, scale) in e_notation_tests {
2662 let result_128_e = parse_decimal::<Decimal128Type>(e, 20, scale);
2663 let result_128_d = parse_decimal::<Decimal128Type>(d, 20, scale);
2664 assert_eq!(result_128_e.unwrap(), result_128_d.unwrap());
2665 let result_256_e = parse_decimal::<Decimal256Type>(e, 20, scale);
2666 let result_256_d = parse_decimal::<Decimal256Type>(d, 20, scale);
2667 assert_eq!(result_256_e.unwrap(), result_256_d.unwrap());
2668 }
2669 let can_not_parse_tests = [
2670 "123,123",
2671 ".",
2672 "123.123.123",
2673 "",
2674 "+",
2675 "-",
2676 "e",
2677 "1.3e+e3",
2678 "5.6714ee-2",
2679 "4.11ee-+4",
2680 "4.11e++4",
2681 "1.1e.12",
2682 "1.23e+3.",
2683 "1.23e+3.1",
2684 "1e",
2685 "1e+",
2686 "1e-",
2687 ];
2688 for s in can_not_parse_tests {
2689 let result_128 = parse_decimal::<Decimal128Type>(s, 20, 3);
2690 assert_eq!(
2691 format!("Parser error: can't parse the string value {s} to decimal"),
2692 result_128.unwrap_err().to_string()
2693 );
2694 let result_256 = parse_decimal::<Decimal256Type>(s, 20, 3);
2695 assert_eq!(
2696 format!("Parser error: can't parse the string value {s} to decimal"),
2697 result_256.unwrap_err().to_string()
2698 );
2699 }
2700 let overflow_parse_tests = [
2701 ("12345678", 3),
2702 ("1.2345678e7", 3),
2703 ("12345678.9", 3),
2704 ("1.23456789e+7", 3),
2705 ("99999999.99", 3),
2706 ("9.999999999e7", 3),
2707 ("12345678908765.123456", 3),
2708 ("123456789087651234.56e-4", 3),
2709 ("1234560000000", 0),
2710 ("12345678900.0", 0),
2711 ("1.23456e12", 0),
2712 ];
2713 for (s, scale) in overflow_parse_tests {
2714 let result_128 = parse_decimal::<Decimal128Type>(s, 10, scale);
2715 let expected_128 = "Parser error: parse decimal overflow";
2716 let actual_128 = result_128.unwrap_err().to_string();
2717
2718 assert!(
2719 actual_128.contains(expected_128),
2720 "actual: '{actual_128}', expected: '{expected_128}'"
2721 );
2722
2723 let result_256 = parse_decimal::<Decimal256Type>(s, 10, scale);
2724 let expected_256 = "Parser error: parse decimal overflow";
2725 let actual_256 = result_256.unwrap_err().to_string();
2726
2727 assert!(
2728 actual_256.contains(expected_256),
2729 "actual: '{actual_256}', expected: '{expected_256}'"
2730 );
2731 }
2732
2733 let edge_tests_128 = [
2734 (
2735 "99999999999999999999999999999999999999",
2736 99999999999999999999999999999999999999i128,
2737 0,
2738 ),
2739 (
2740 "999999999999999999999999999999999999.99",
2741 99999999999999999999999999999999999999i128,
2742 2,
2743 ),
2744 (
2745 "9999999999999999999999999.9999999999999",
2746 99999999999999999999999999999999999999i128,
2747 13,
2748 ),
2749 (
2750 "9999999999999999999999999",
2751 99999999999999999999999990000000000000i128,
2752 13,
2753 ),
2754 (
2755 "0.99999999999999999999999999999999999999",
2756 99999999999999999999999999999999999999i128,
2757 38,
2758 ),
2759 (
2760 "0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001016744",
2761 0i128,
2762 15,
2763 ),
2764 ("1.016744e-320", 0i128, 15),
2765 ("-1e3", -1000000000i128, 6),
2766 ("+1e3", 1000000000i128, 6),
2767 ("-1e31", -10000000000000000000000000000000000000i128, 6),
2768 ];
2769 for (s, i, scale) in edge_tests_128 {
2770 let result_128 = parse_decimal::<Decimal128Type>(s, 38, scale);
2771 assert_eq!(i, result_128.unwrap());
2772 }
2773 let edge_tests_256 = [
2774 (
2775 "9999999999999999999999999999999999999999999999999999999999999999999999999999",
2776 i256::from_string(
2777 "9999999999999999999999999999999999999999999999999999999999999999999999999999",
2778 )
2779 .unwrap(),
2780 0,
2781 ),
2782 (
2783 "999999999999999999999999999999999999999999999999999999999999999999999999.9999",
2784 i256::from_string(
2785 "9999999999999999999999999999999999999999999999999999999999999999999999999999",
2786 )
2787 .unwrap(),
2788 4,
2789 ),
2790 (
2791 "99999999999999999999999999999999999999999999999999.99999999999999999999999999",
2792 i256::from_string(
2793 "9999999999999999999999999999999999999999999999999999999999999999999999999999",
2794 )
2795 .unwrap(),
2796 26,
2797 ),
2798 (
2799 "9.999999999999999999999999999999999999999999999999999999999999999999999999999e49",
2800 i256::from_string(
2801 "9999999999999999999999999999999999999999999999999999999999999999999999999999",
2802 )
2803 .unwrap(),
2804 26,
2805 ),
2806 (
2807 "99999999999999999999999999999999999999999999999999",
2808 i256::from_string(
2809 "9999999999999999999999999999999999999999999999999900000000000000000000000000",
2810 )
2811 .unwrap(),
2812 26,
2813 ),
2814 (
2815 "9.9999999999999999999999999999999999999999999999999e+49",
2816 i256::from_string(
2817 "9999999999999999999999999999999999999999999999999900000000000000000000000000",
2818 )
2819 .unwrap(),
2820 26,
2821 ),
2822 ];
2823 for (s, i, scale) in edge_tests_256 {
2824 let result = parse_decimal::<Decimal256Type>(s, 76, scale);
2825 assert_eq!(i, result.unwrap());
2826 }
2827
2828 let zero_scale_tests = [
2829 (".123", 0, 3),
2830 ("0.123", 0, 3),
2831 ("1.0", 1, 3),
2832 ("1.2", 1, 3),
2833 ("1.00", 1, 3),
2834 ("1.23", 1, 3),
2835 ("1.000", 1, 3),
2836 ("1.123", 1, 3),
2837 ("123.0", 123, 3),
2838 ("123.4", 123, 3),
2839 ("123.00", 123, 3),
2840 ("123.45", 123, 3),
2841 ("123.000000000000000000004", 123, 3),
2842 ("0.123e2", 12, 3),
2843 ("0.123e4", 1230, 10),
2844 ("1.23e4", 12300, 10),
2845 ("12.3e4", 123000, 10),
2846 ("123e4", 1230000, 10),
2847 (
2848 "20000000000000000000000000000000000002.0",
2849 20000000000000000000000000000000000002,
2850 38,
2851 ),
2852 ];
2853 for (s, i, precision) in zero_scale_tests {
2854 let result_128 = parse_decimal::<Decimal128Type>(s, precision, 0).unwrap();
2855 assert_eq!(i, result_128);
2856 }
2857
2858 let can_not_parse_zero_scale = [".", "blag", "", "+", "-", "e"];
2859 for s in can_not_parse_zero_scale {
2860 let result_128 = parse_decimal::<Decimal128Type>(s, 5, 0);
2861 assert_eq!(
2862 format!("Parser error: can't parse the string value {s} to decimal"),
2863 result_128.unwrap_err().to_string(),
2864 );
2865 }
2866 }
2867
2868 #[test]
2869 fn test_parse_empty() {
2870 assert_eq!(Int32Type::parse(""), None);
2871 assert_eq!(Int64Type::parse(""), None);
2872 assert_eq!(UInt32Type::parse(""), None);
2873 assert_eq!(UInt64Type::parse(""), None);
2874 assert_eq!(Float32Type::parse(""), None);
2875 assert_eq!(Float64Type::parse(""), None);
2876 assert_eq!(Int32Type::parse("+"), None);
2877 assert_eq!(Int64Type::parse("+"), None);
2878 assert_eq!(UInt32Type::parse("+"), None);
2879 assert_eq!(UInt64Type::parse("+"), None);
2880 assert_eq!(Float32Type::parse("+"), None);
2881 assert_eq!(Float64Type::parse("+"), None);
2882 assert_eq!(TimestampNanosecondType::parse(""), None);
2883 assert_eq!(Date32Type::parse(""), None);
2884 }
2885
2886 #[test]
2887 fn test_parse_interval_month_day_nano_config() {
2888 let interval = parse_interval_month_day_nano_config(
2889 "1",
2890 IntervalParseConfig::new(IntervalUnit::Second),
2891 )
2892 .unwrap();
2893 assert_eq!(interval.months, 0);
2894 assert_eq!(interval.days, 0);
2895 assert_eq!(interval.nanoseconds, NANOS_PER_SECOND);
2896 }
2897 #[test]
2898 fn test_parse_prefix_white_space() {
2899 assert_eq!(Float64Type::parse(" 1.5"), Some(1.5));
2900 assert_eq!(Float64Type::parse("\t\n 20.54"), Some(20.54));
2901 assert_eq!(Float64Type::parse("\n2.5"), Some(2.5));
2902 assert_eq!(Float64Type::parse("\n-942.5423"), Some(-942.5423));
2903 assert_eq!(Float64Type::parse("\n\t\n\t\n40.5123"), Some(40.5123));
2904 assert_eq!(Float64Type::parse(" 1.5"), Some(1.5));
2905 assert_eq!(Float64Type::parse("\n\t\n\t\n-40.5123"), Some(-40.5123));
2906 assert_eq!(Float64Type::parse(" -1.5"), Some(-1.5));
2907 assert_eq!(Int32Type::parse(" 3"), Some(3));
2908 assert_eq!(Int32Type::parse(" 30"), Some(30));
2909 assert_eq!(Int32Type::parse("\n \n 100"), Some(100));
2910 assert_eq!(Int32Type::parse(" \n25"), Some(25));
2911 assert_eq!(Int32Type::parse("\t800"), Some(800));
2912 assert_eq!(Int32Type::parse("\t \n \t 851"), Some(851));
2913 assert_eq!(Int32Type::parse("\t\n\t\n\n\n\t1"), Some(1));
2914 assert_eq!(Int32Type::parse(" \n-25"), Some(-25));
2915 assert_eq!(Int32Type::parse("\t-800"), Some(-800));
2916 }
2917}