andygrove commented on issue #4959:
URL: 
https://github.com/apache/datafusion-comet/issues/4959#issuecomment-5133903339

   I dug into the "Scope" note above and the divergence turns out to be 
considerably wider than boolean, so I've opened #5149 as an epic and I'd 
suggest closing this one in favour of it.
   
   Short version of what the audit found:
   
   - **7 of the 8 string cast targets diverge**, not just boolean. Only 
`CAST(string AS date)` is correct, because `date_parser`'s local 
`is_whitespace_or_iso_control` happens to compute exactly Spark's `trimAll` set.
   - **There is a second, unreported direction.** `str::trim` also trims 
non-ASCII Unicode whitespace (`U+0085`, `U+00A0`, `U+1680`, `U+2000`-`U+200A`, 
`U+2028`, `U+2029`, `U+202F`, `U+205F`, `U+3000`), which Spark never trims for 
any cast target. So `CAST(' true' AS boolean)` returns `true` in Comet and 
`NULL` in Spark, and under ANSI Comet silently succeeds where Spark throws. 
That's a silent-wrong-result path, arguably worse than the 
NULL-instead-of-value direction described here.
   - **Spark has two trim regimes, not one.** boolean / byte / short / int / 
long / date / timestamp / timestamp_ntz use the `trimAll` set (bytes 
`0x00`-`0x20` **and `0x7F`**), but float / double / decimal go through Java 
`String.trim`, which is chars `U+0000`-`U+0020` and **does not** include 
`0x7F`. So a single shared trim helper applied uniformly would fix boolean and 
integrals while introducing a *new* divergence in float and decimal.
   - One extra byte to watch: Rust's `u8::is_ascii_whitespace` excludes `0x0B` 
(vertical tab) whereas `str::trim` includes it, so the integral and decimal 
paths (which use `trim_ascii` / `is_ascii_whitespace`) fail on `0x0B` as well.
   
   Verified empirically in both directions: Spark ground truth via a Java probe 
against the 3.5.5 jars exercising the exact primitives each cast target uses 
(`UTF8String.trimAll`, `UTF8String.toInt`/`toLong`, `Double.parseDouble`, `new 
BigDecimal(String.trim)`, `DateTimeUtils.stringToDate`/`stringToTimestamp`), 
and Comet via the same 25-codepoint matrix through `spark_cast` in legacy and 
ANSI mode. The Spark code paths are identical in 3.5.8 and 4.1.1. Full matrix 
is in #5149.
   
   On the "mark cast(string to boolean) as incompatible" suggestion: I'd lean 
against it as the resolution here, since it would leave the other six targets 
silently wrong while singling out the one that was noticed first. All of them 
are `Compatible()` in `CometCast.canCastFromString` today. #5149 breaks the 
work down per target, and the two trim helpers it proposes should make each one 
a small change.
   


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