Latest Results
feat(functions): add try_divide for PySpark parity (#7210)
## Summary
Adds a `try_divide` scalar function: true division that returns null
where the divisor is 0, instead of infinity, NaN, or an error. This
mirrors Spark's `try_divide` semantics, where a zero divisor yields null
for every numeric type.
## Why
Part of the PySpark function parity effort tracked in #3793. Daft's `/`
follows IEEE 754 (`1/0` gives `inf`, `0.0/0.0` gives `NaN`), and integer
floor division by zero currently panics a worker thread, so a
null-on-zero-divisor variant gives users a safe option that matches
Spark. Follows the `pmod` (#6801) pattern: a Rust `ScalarUDF` in
`src/daft-functions/src/numeric/` with a thin Python wrapper.
## Changes Made
- `src/daft-functions/src/numeric/try_divide.rs`: new `TryDivide`
ScalarUDF. Computes the quotient with Daft's existing `Series` division,
then nulls rows where the divisor equals zero via a broadcast comparison
and `if_else`. Return type comes from the same `InferDataType` division
inference used by the `/` operator (integer inputs produce `Float64`).
- `src/daft-functions/src/numeric/mod.rs`: register `TryDivide`.
- `daft/functions/numeric.py`: `try_divide(dividend, divisor)` wrapper.
- `daft/functions/__init__.py`: export `try_divide`.
- `tests/recordbatch/numeric/test_numeric.py`: 7 tests covering ints,
floats (including a `-0.0` divisor), unsigned ints, output dtype,
broadcasting in both directions, and the non-numeric error.
## Behavior
- `try_divide(1, 0)` returns null; `try_divide(6, 3)` returns `2.0`
(`Float64`, same inference as `/`).
- `try_divide(1.0, 0.0)`, `try_divide(-1.0, 0.0)`, and `try_divide(0.0,
-0.0)` all return null, matching Spark, where the regular operators
would give `inf`, `-inf`, and `NaN`. Daft's float equality is bitwise,
so the implementation adds zero to the divisor before comparing (`-0.0 +
0.0` is `+0.0` in IEEE 754) to catch negative zero.
- Nulls propagate; non-numeric inputs raise a `TypeError` at planning
time.
- Decimal inputs are rejected by the same `is_numeric` gate `pmod` uses
(Daft's `is_numeric` excludes `Decimal128`). Spark's `try_divide`
supports decimals; this can be lifted in a follow-up if decimal division
support is wanted here.
- Available in SQL through the function registry: `SELECT try_divide(1,
0)` returns null.
## Test Plan
- `pytest tests/recordbatch/numeric/test_numeric.py`: 392 passed (7 new)
- `pytest --doctest-modules daft/functions/numeric.py`: 5 passed
- `cargo check -p daft-functions --lib` clean
- `cargo fmt -p daft-functions --check` clean
- `cargo clippy -p daft-functions --lib --no-deps` clean
- End-to-end check through the DataFrame API and `daft.sql`
## Related Issues
Part of #3793. Latest Branches
0%
Lucas61000:fix-hdfs-write-port 0%
0%
cmirandavega:feat/rint-bround ยฉ 2026 CodSpeed Technology