andygrove opened a new issue, #6080:
URL: https://github.com/apache/datafusion-comet/issues/6080
### Describe the bug
`CometToUnixTimestamp` and `CometMakeTimestamp` both extend
`CometCodegenDispatch`, whose `convert` unconditionally emits
`CometScalaUDF.emitJvmCodegenDispatch`
(`spark/src/main/scala/org/apache/comet/serde/CometScalaUDF.scala:202-211`).
Neither expression has a native kernel at all. Both nevertheless return
`Incompatible` when an argument carries a non-default collation:
- `CometMakeTimestamp`,
`spark/src/main/scala/org/apache/comet/serde/datetime.scala:867-883`
- `CometToUnixTimestamp`,
`spark/src/main/scala/org/apache/comet/serde/datetime.scala:895-911`
That `Incompatible` has two user-visible effects, and both of them promise a
native implementation that does not exist.
In `EXPLAIN`, the `Incompatible` arm of `QueryPlanSerde.exprToProtoInternal`
tags the node with `withInfo(expr, NativeOptIn.message(...))` before routing it
through the dispatcher, so the user is told to set a flag that changes nothing.
In the generated compatibility guide, `getIncompatibleReasons()` is rendered
under the `nativeOptIn` header from `GenerateDocs.renderExpressionCompatNotes`:
"By default, `X` is evaluated in the JVM using Spark's own code-generated
implementation (run inside the Comet pipeline), which matches Spark exactly.
Set `...allowIncompatible=true` to opt into Comet's native implementation
instead, which has the following differences from Spark:". There is no native
implementation to opt into.
### Steps to reproduce
On Spark 4.0+, over a Parquet table `t(_1 string, _2 string, _3 string)`
holding `('2024-06-15', 'yyyy-MM-dd', 'America/Los_Angeles')`, with
`ConstantFolding` excluded, run each query twice, once with the expression's
`allowIncompatible` at `false` and once at `true`:
```sql
SELECT to_unix_timestamp(_1, _2 COLLATE UTF8_LCASE) FROM t
SELECT make_timestamp(2024, 6, 15, 12, 0, 0, _3 COLLATE UTF8_LCASE) FROM t
```
The routing is byte-identical across the two settings. Only the hint
disappears. On Spark 4.1.3:
```
ToUnixTimestamp allowIncompatible=false native=[] dispatched=[collate,
resolvedcollation, to_unix_timestamp]
CometProject [COMET-INFO: A native implementation of ToUnixTimestamp is
available.
Set spark.comet.expression.ToUnixTimestamp.allowIncompatible=true to
enable it. ...]
Accelerated expressions: 0 native, 3 codegen dispatch.
ToUnixTimestamp allowIncompatible=true native=[] dispatched=[collate,
resolvedcollation, to_unix_timestamp]
CometProject
Accelerated expressions: 0 native, 3 codegen dispatch.
MakeTimestamp allowIncompatible=false native=[] dispatched=[cast,
collate, make_timestamp, resolvedcollation]
CometProject [COMET-INFO: A native implementation of MakeTimestamp is
available.
Set spark.comet.expression.MakeTimestamp.allowIncompatible=true to
enable it. ...]
Accelerated expressions: 0 native, 4 codegen dispatch.
MakeTimestamp allowIncompatible=true native=[] dispatched=[cast,
collate, make_timestamp, resolvedcollation]
CometProject
Accelerated expressions: 0 native, 4 codegen dispatch.
```
### Expected behavior
Results are correct in every case, so this is about diagnostics and
documentation rather than answers.
A collated argument on an expression with no native path should not report
`Incompatible`, because `Incompatible` is the level that means "Comet has a
native implementation that differs from Spark, and you can opt into it". The
natural fix is to drop the collation gate from these two serdes entirely and
let them report `Compatible`, since `CometCodegenDispatch` always runs Spark's
own generated code and therefore already honours collation exactly. Reporting
`Unsupported` instead would also silence the hint, but it would misdescribe the
situation, because these expressions are fully supported.
Either way, `getIncompatibleReasons()` should go too, so the compatibility
page stops advertising a native opt-in for these two.
### Additional context
This surfaced while reviewing #5789, which makes the same correction for
`unix_timestamp`. That PR removes the collation gate from `CometUnixTimestamp`
on the grounds that Spark's `ToTimestamp` only reads the format argument in the
`StringType` branch, so the format's collation cannot change the answer for
date and timestamp inputs. `ToUnixTimestamp` is the same `ToTimestamp`
subclass, and neither it nor `MakeTimestamp` has a native path for the gate to
protect in the first place.
These are the only two serdes in the tree that combine
`CometCodegenDispatch` with a non-`Compatible` support level, so the fix is
contained. `CometMakeInterval` also reports `Incompatible`, but it is a plain
`CometExpressionSerde` with a real native path, so its opt-in hint is genuine
and should stay.
Existing coverage to keep green: the `to_unix_timestamp` and
`make_timestamp` cases in `routing_datetime_collation_enabled.sql` and
`routing_datetime_collation_disabled.sql` (added by #5950) assert the dispatch
and fallback routes, and `CometCollationSuite` on Spark 4.0 and 4.1 has a
`make_timestamp rejects non-UTF8_BINARY collated timezone` and a
`to_unix_timestamp rejects non-UTF8_BINARY collated format` test, both
asserting the fallback reason text that would go away.
--
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]