Describe the bug
try_mod (Spark 4.0+) is RuntimeReplaceable and rewrites to Remainder(left, right, EvalMode.TRY). Comet's CometRemainder serde explicitly rejects EvalMode.TRY with withInfo(expr, "Eval mode TRY is not supported") and returns None, so the enclosing plan falls back to Spark.
The sibling arithmetic serdes (CometAdd, CometSubtract, CometMultiply, CometDivide, CometIntegralDivide) all accept EvalMode.TRY by propagating the mode through evalModeToProto, and the Rust spark_modulo UDF already takes a fail_on_error: bool flag, so there is no semantic obstacle to letting EvalMode.TRY through.
Surfaced by the math-expressions audit (collection PR queue).
Steps to reproduce
SELECT try_mod(10, 0); -- Spark 4.0+ returns NULL; Comet falls back
Expected behavior
CometRemainder should accept EvalMode.TRY the same way the other arithmetic serdes do (TRY currently behaves identically to LEGACY at the Rust layer, returning NULL on divide-by-zero).
Additional context
- Comet serde:
CometRemainder in spark/src/main/scala/org/apache/comet/serde/arithmetic.scala
- Rust impl:
native/spark-expr/src/math_funcs/modulo_expr.rs::spark_modulo
- Spark reference:
TryMod in org.apache.spark.sql.catalyst.expressions.tryArithmetic.scala
Describe the bug
try_mod(Spark 4.0+) isRuntimeReplaceableand rewrites toRemainder(left, right, EvalMode.TRY). Comet'sCometRemainderserde explicitly rejectsEvalMode.TRYwithwithInfo(expr, "Eval mode TRY is not supported")and returnsNone, so the enclosing plan falls back to Spark.The sibling arithmetic serdes (
CometAdd,CometSubtract,CometMultiply,CometDivide,CometIntegralDivide) all acceptEvalMode.TRYby propagating the mode throughevalModeToProto, and the Rustspark_moduloUDF already takes afail_on_error: boolflag, so there is no semantic obstacle to lettingEvalMode.TRYthrough.Surfaced by the math-expressions audit (collection PR queue).
Steps to reproduce
Expected behavior
CometRemaindershould acceptEvalMode.TRYthe same way the other arithmetic serdes do (TRY currently behaves identically to LEGACY at the Rust layer, returning NULL on divide-by-zero).Additional context
CometRemainderinspark/src/main/scala/org/apache/comet/serde/arithmetic.scalanative/spark-expr/src/math_funcs/modulo_expr.rs::spark_moduloTryModinorg.apache.spark.sql.catalyst.expressions.tryArithmetic.scala