peterxcli opened a new pull request, #5682:
URL: https://github.com/apache/datafusion-comet/pull/5682

   ## Which issue does this PR close?
   
   Closes #5674.
   
   ## Rationale for this change
   
   Comet's string→timestamp parser is a table of anchored regexes plus an 
offset-suffix fallback, while Spark's `SparkDateTimeUtils.parseTimestampString` 
is a segment scanner with per-segment digit rules (`isValidDigits`). They 
disagreed in four ways on the default-on path, for both `TIMESTAMP` and 
`TIMESTAMP_NTZ`:
   
   | input | Spark | Comet before |
   |---|---|---|
   | `2020-1-1`, `2020-01-01 12:34:5` | value (1–2 digit segments) | NULL / 
ANSI error |
   | `2020-01-01 12:34:56.` | value (empty fraction) | NULL / ANSI error |
   | `2020-10-01Z`, `2020-01-01+05:30`, `2020-10-01 UTC` | NULL (zone only 
after seconds) | value |
   | `0002020-01-01 00:00:00` | NULL (timestamp years ≤ 6 digits) | value |
   
   ## What changes are included in this PR?
   
   - Relax the shape regexes to Spark's `isValidDigits` rules: year `\d{4,6}` 
(only `stringToDate`, ported by `date_parser`, allows 7 — `CAST(... AS DATE)` 
is unchanged), month/day/hour/minute/second `\d{1,2}`, fraction `\.\d*`.
   - Add `ends_with_seconds_segment()` and only honour a stripped zone suffix 
when the remainder ends in a seconds or fraction segment, in both 
`timestamp_parser` and `timestamp_ntz_parser`. Any other suffix placement falls 
through with the unstripped value and is reported as malformed (NULL, or 
`CAST_INVALID_INPUT` under ANSI).
   - Previously accepted inputs keep bit-identical values; the common path is 
unchanged (a direct match still skips suffix extraction; the gate only runs on 
the fallback path).
   
   Note for #5130 (single-scan classifier): the regex edits are digit-count 
changes to the same 14 shapes, and the gate is a predicate on the classified 
shape of the stripped remainder, so it should rebase onto the classifier as a 
one-line `matches!` check.
   
   Observed but left out of scope: `timestamp_parser` (TZ only) still returns 
NULL for `'2021-11-22 10:54:27 +08:00'` (space before a bare offset) because it 
does not `trim_end()` the remainder the way the NTZ parser does; Spark accepts 
it. Worth a follow-up issue.
   
   ## How are these changes tested?
   
   - Rust: `timestamp_parser_spark_segment_rules_test`, 
`timestamp_ntz_parser_spark_segment_rules_test` and 
`test_cast_string_to_timestamp_spark_segment_rules_array` cover every case in 
the issue table in legacy/try/ANSI modes, regression values for previously 
accepted shapes (zone forms `Z`, `+05:30`, ` UTC`, ` America/Los_Angeles` after 
a time, negative year), 6-digit valid vs 7-digit invalid years, and 
`date_parser` still accepting a 7-digit year. `cargo test -p 
datafusion-comet-spark-expr`: 662 passed; `cargo clippy --all-targets 
--workspace -- -D warnings` clean.
   - Scala: `cast StringType to TimestampType - Spark segment rules` and the 
`TimestampNTZType` counterpart in `CometNativeCastSuite` compare against Spark 
in legacy, try and ANSI modes, with each malformed string in its own query so 
every ANSI error is checked. `CometNativeCastSuite` on Spark 4.1.3: 170 passed, 
0 failed.
   


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