andygrove opened a new issue, #5366:
URL: https://github.com/apache/datafusion-comet/issues/5366

   ## Describe the bug
   
   Comet's native `to_time` / `try_to_time` parser 
(`native/spark-expr/src/datetime_funcs/to_time.rs`) diverges from Spark 4.1's 
`SparkDateTimeUtils.stringToTime` on three inputs that have nothing to do with 
whitespace trimming. In the first two cases Spark returns a value and Comet 
raises `The input string '...' cannot be parsed to a TIME value` (or returns 
`NULL` for `try_to_time`), so enabling Comet turns a succeeding query into a 
failing one.
   
   These were found while reviewing #5364, which fixes a separate 
whitespace-trimming divergence in the same function. They are pre-existing and 
are not caused by that PR.
   
   ### 1. `T`-prefixed hour with no minute component
   
   ```sql
   SELECT to_time('T12');    -- Spark: 12:00:00   Comet: error
   SELECT to_time('T1');     -- Spark: 01:00:00   Comet: error
   SELECT to_time('T12 AM'); -- Spark: 00:00:00   Comet: error
   ```
   
   In `parseTimestampString`, the `T` branch (`j == 0 && b == 'T'`) sets 
`justTime = true` and advances `i += 3`, so the following digits are 
accumulated directly into `segments(3)` (the hour). The loop then ends and 
`isValidDigits(3, 2)` passes, giving `hr = 12, min = 0, sec = 0`.
   
   Comet's `parse_time_components` skips an optional leading `T` but then 
unconditionally requires a `:` after the hour:
   
   
https://github.com/apache/datafusion-comet/blob/main/native/spark-expr/src/datetime_funcs/to_time.rs#L188-L190
   
   ### 2. Trailing `.` with no fractional digits
   
   ```sql
   SELECT to_time('12:30:45.'); -- Spark: 12:30:45   Comet: error
   ```
   
   Spark's `isValidDigits` short-circuits on `segment == 6`, so the 
fractional-second segment is allowed to have zero digits. Comet's 
`parse_fractional` returns `None` when `count == 0`.
   
   ### 3. Fractional digits 7 through 9 are dropped
   
   ```sql
   SELECT to_time('12:30:45.1234567');
   ```
   
   Spark keeps fractional digits 7-9 as a sub-microsecond remainder in 
`segments(9)` and folds them into `nanoOfSecond`, storing `45045123456700` 
nanos. Comet's `parse_fractional` truncates at 6 digits and stores 
`45045123456000`.
   
   This one may not be user-observable: `to_time` produces `TIME(6)`, and the 
existing test at 
`spark/src/test/resources/sql-tests/expressions/datetime/to_time.sql` (`SELECT 
to_time('00:00:00.1234567')`) passes today because `TIME(6)` formatting 
truncates the difference away. It needs a check for whether a widening cast or 
`extract(second from ...)` can expose the stored nanos before deciding whether 
to fix it.
   
   ## Steps to reproduce
   
   Requires Spark 4.1 with `spark.sql.timeType.enabled=true`.
   
   ```sql
   SELECT to_time('T12'), to_time('12:30:45.');
   ```
   
   ## Expected behavior
   
   Comet should return the same values Spark does.
   
   ## Additional context
   
   Found with a differential harness that ports Spark 4.1's `stringToTime` and 
`parseTimestampString` to Rust and compares them against `string_to_time` over 
~107k generated inputs (30 core time strings crossed with all 34 `trimAll` 
bytes and seven Unicode whitespace codepoints in leading, trailing, doubled, 
interior and pre-suffix positions). After #5364 lands, these three are the only 
remaining divergence classes in that corpus.
   


-- 
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]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to