Repository navigation
Commit 484183d
fix: preserve negative zero in trunc (#25732)
## Which issue does this PR close?
- Closes #25702.
## Rationale for this change
@jonasdedden reported that trunc(column) changes -0.0 to 0.0 on the
array path, while scalar trunc(-0.0) and trunc(column, 0) keep the sign.
That makes the one-argument column form behave differently from the
scalar form and from the explicit precision form.
After this change, the one-argument Float32 and Float64 array paths use
the native trunc() result directly, so the SQL path keeps the sign of
negative zero.
## What changes are included in this PR?
The Float32 and Float64 one-argument array implementation now matches
Rust's trunc() behavior for zero values, so trunc(column) keeps the sign
like the scalar and explicit precision forms.
## What is the testing strategy for this PR?
The reported behavior is shown below for Float32 and Float64 columns, on
upstream main and on this branch.
## Testing Done
A unit test in trunc.rs checks the Float32 and Float64 results directly,
and math.slt checks the same values through SQL. The reported behavior
is also reproducible with a small program.
Put the source below in src/main.rs of a new crate, add these
dependencies to its Cargo.toml with the path pointing at a checkout, and
pass the two queries as arguments to cargo run.
```toml
[dependencies]
datafusion = { path = "../datafusion/datafusion/core", default-features = false, features = ["sql", "math_expressions"] }
tokio = { version = "1", features = ["rt-multi-thread", "macros"] }
```
```bash
cargo run -q -- \
"SELECT 1.0 / trunc(column1), 1.0 / trunc(column1, 0) FROM (VALUES (CAST(-0.0 AS REAL)))" \
"SELECT 1.0 / trunc(column1), 1.0 / trunc(column1, 0) FROM (VALUES (CAST(-0.0 AS DOUBLE)))"
```
Before, on upstream main
(91cd7ff).
The one-argument form returns inf, the explicit precision form returns
-inf:
```text
SELECT 1.0 / trunc(column1), 1.0 / trunc(column1, 0) FROM (VALUES (CAST(-0.0 AS REAL)))
+-----------------------------+--------------------------------------+
| Float64(1) / trunc(column1) | Float64(1) / trunc(column1,Int64(0)) |
+-----------------------------+--------------------------------------+
| inf | -inf |
+-----------------------------+--------------------------------------+
SELECT 1.0 / trunc(column1), 1.0 / trunc(column1, 0) FROM (VALUES (CAST(-0.0 AS DOUBLE)))
+-----------------------------+--------------------------------------+
| Float64(1) / trunc(column1) | Float64(1) / trunc(column1,Int64(0)) |
+-----------------------------+--------------------------------------+
| inf | -inf |
+-----------------------------+--------------------------------------+
```
After, on this branch. Both forms return -inf:
```text
SELECT 1.0 / trunc(column1), 1.0 / trunc(column1, 0) FROM (VALUES (CAST(-0.0 AS REAL)))
+-----------------------------+--------------------------------------+
| Float64(1) / trunc(column1) | Float64(1) / trunc(column1,Int64(0)) |
+-----------------------------+--------------------------------------+
| -inf | -inf |
+-----------------------------+--------------------------------------+
SELECT 1.0 / trunc(column1), 1.0 / trunc(column1, 0) FROM (VALUES (CAST(-0.0 AS DOUBLE)))
+-----------------------------+--------------------------------------+
| Float64(1) / trunc(column1) | Float64(1) / trunc(column1,Int64(0)) |
+-----------------------------+--------------------------------------+
| -inf | -inf |
+-----------------------------+--------------------------------------+
```
<details><summary>Reproducer source: main.rs</summary>
```rust
use datafusion::error::Result;
use datafusion::prelude::SessionContext;
#[tokio::main]
async fn main() -> Result<()> {
let ctx = SessionContext::new();
for sql in std::env::args().skip(1) {
println!("{sql}");
ctx.sql(&sql).await?.show().await?;
}
Ok(())
}
```
</details>
## Are there any user-facing changes?
Yes. trunc(column) now preserves the sign of -0.0 for Float32 and
Float64 inputs.
---------
Signed-off-by: 1fanwang <[email protected]>
Co-authored-by: kosiew <[email protected]>1 parent 5f21582 commit 484183d
2 files changed
Lines changed: 39 additions & 22 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
162 | 162 | | |
163 | 163 | | |
164 | 164 | | |
165 | | - | |
166 | | - | |
167 | | - | |
168 | | - | |
169 | 165 | | |
170 | 166 | | |
171 | 167 | | |
| |||
305 | 301 | | |
306 | 302 | | |
307 | 303 | | |
308 | | - | |
309 | | - | |
310 | | - | |
311 | | - | |
312 | | - | |
313 | | - | |
314 | | - | |
315 | | - | |
316 | | - | |
| 304 | + | |
| 305 | + | |
| 306 | + | |
| 307 | + | |
| 308 | + | |
317 | 309 | | |
318 | 310 | | |
319 | 311 | | |
| |||
327 | 319 | | |
328 | 320 | | |
329 | 321 | | |
330 | | - | |
331 | | - | |
332 | | - | |
333 | | - | |
334 | | - | |
335 | | - | |
336 | | - | |
337 | | - | |
338 | | - | |
| 322 | + | |
| 323 | + | |
| 324 | + | |
| 325 | + | |
| 326 | + | |
339 | 327 | | |
340 | 328 | | |
341 | 329 | | |
| |||
555 | 543 | | |
556 | 544 | | |
557 | 545 | | |
| 546 | + | |
| 547 | + | |
| 548 | + | |
| 549 | + | |
| 550 | + | |
| 551 | + | |
| 552 | + | |
| 553 | + | |
| 554 | + | |
| 555 | + | |
| 556 | + | |
| 557 | + | |
| 558 | + | |
| 559 | + | |
| 560 | + | |
| 561 | + | |
| 562 | + | |
| 563 | + | |
| 564 | + | |
558 | 565 | | |
559 | 566 | | |
560 | 567 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
88 | 88 | | |
89 | 89 | | |
90 | 90 | | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
91 | 101 | | |
92 | 102 | | |
93 | 103 | | |
| |||
0 commit comments