Unary negation can eliminate a required sort at the signed minimum
- Dominant language
- Rust
- Stars
- 9.3k
- Forks
- 2.4k
- Avg merge
- 3d 7h
- Merged PRs (30d)
- 344
Description
### Describe the bug
`NegativeExpr::get_properties` always reverses its child ordering. Integer array negation uses wrapping arithmetic, so negating the minimum signed value returns the same value and is not monotonic across the full domain.
The incorrect ordering claim can remove a required `SortExec` and return rows in the wrong order.
### To Reproduce
```sql
SELECT i, -i AS n
FROM (
SELECT i
FROM (
VALUES
(CAST(-128 AS TINYINT)),
(CAST(-1 AS TINYINT)),
(CAST(0 AS TINYINT)),
(CAST(1 AS TINYINT))
) AS v(i)
ORDER BY i DESC
LIMIT 4
) AS t
ORDER BY n ASC;
```
Current result:
```text
1 -1
0 0
-1 1
-128 -128
```
Expected result:
```text
-128 -128
1 -1
0 0
-1 1
```
### Expected behavior
DataFusion should retain the outer sort unless it can prove that the signed minimum is outside the input range.
### Additional context
This is a pre-existing single-negation issue found while working on #24668. A fix should retain safe ordering for exact widening casts such as `Int32` to `Int64`, and for wrapping double negation on unbounded integer streams.
Contributor guide
Research direction
Start by locating NegativeExpr::get_properties and reproduce the provided SQL query to observe the incorrect ordering. Trace how unary negation reports child ordering, then verify the change preserves the outer sort for signed-minimum inputs while retaining safe ordering for exact widening casts and wrapping double negation.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- databases
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 68/100