miguelcorderopamphile commented on code in PR #11572:
URL: https://github.com/apache/arrow-rs/pull/11572#discussion_r4396026346
##########
arrow-cast/src/cast/string.rs:
##########
@@ -132,6 +136,111 @@ fn parse_string_iter<
Ok(Arc::new(array) as ArrayRef)
}
+/// Parse a string to a duration, accepting integer strings (interpreted
+/// in the target unit) and interval strings with units, such as
+/// `"1 hour 10 minutes"`.
+fn parse_duration<D>(string: &str) -> Result<i64, ArrowError>
+where
+ D: ArrowTemporalType<Native = i64> + Parser,
+{
+ if let Some(duration) = D::parse(string) {
+ return Ok(duration);
+ }
+
+ let (unit, scale) = match D::DATA_TYPE {
+ DataType::Duration(TimeUnit::Second) => (IntervalParseUnit::Second,
1_000_000_000),
+ DataType::Duration(TimeUnit::Millisecond) =>
(IntervalParseUnit::Millisecond, 1_000_000),
+ DataType::Duration(TimeUnit::Microsecond) =>
(IntervalParseUnit::Microsecond, 1_000),
+ DataType::Duration(TimeUnit::Nanosecond) =>
(IntervalParseUnit::Nanosecond, 1),
+ _ => unreachable!(),
+ };
+
+ let interval = parse_interval_month_day_nano_config(string,
IntervalParseConfig::new(unit))
Review Comment:
Yes. `Interval::add` accumulates nanoseconds in `i64`, so `10000000000
seconds` is `1e19` ns > `i64::MAX`: it returns `ArithmeticOverflow` and the
cast surfaces a `CastError`. It fails rather than wrapping.
I measured the boundary for `Duration(s)` with a local test (not committed):
- `9223372036 seconds` -> `9_223_372_036`
- `9223372037 seconds` -> error
- `10000000000 seconds` -> error
The limit is ~292 years for any string that goes through the interval
parser, even when the target is `Duration(s)`/`Duration(ms)` and the value
would fit, because `MonthDayNano` stores nanoseconds as `i64`. A wider
intermediate in `parse_duration` can't fix that; it needs a duration-specific
parse path.
I'd keep this PR scoped: add a regression test for the bound and follow up
with the duration-specific parser. If you'd rather have the parser change here,
say so.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]