apache / apache/datafusion

Unary negation can eliminate a required sort at the signed minimum

Open
#24,683 0 comments 0 reactions 0 assignees View on GitHub
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.