jayzhan211 opened a new issue, #26470:
URL: https://github.com/apache/datafusion/issues/26470
### Describe the bug
When a sliding window frame (one that does not start at `UNBOUNDED
PRECEDING`) contains only NULL values, `bit_xor` returns `0` instead of `NULL`.
This only happens after the frame has already seen a non-NULL value. The same
aggregate over a whole partition returns `NULL` correctly.
### To Reproduce
```sql
SELECT x,
bit_xor(x) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND CURRENT ROW) AS
sliding,
bit_xor(x) OVER (PARTITION BY i) AS whole
FROM (VALUES (1, 5), (2, NULL), (3, 6)) t(i, x)
ORDER BY i;
```
```
+------+---------+-------+
| x | sliding | whole |
+------+---------+-------+
| 5 | 5 | 5 |
| NULL | 0 | NULL |
| 6 | 6 | 6 |
+------+---------+-------+
```
### Expected behavior
`sliding` is `NULL` on the second row, as in `whole`. DuckDB returns `NULL`
there.
### Additional context
`BitXorAccumulator` keeps an `Option` that becomes `Some` on the first
non-NULL value. `retract_batch` XORs the leaving values back out, but the state
never goes back to `None`. So once every non-NULL value has left the frame,
`evaluate` returns `Some(0)`:
https://github.com/apache/datafusion/blob/3470bd0fbc/datafusion/functions-aggregate/src/bit_and_or_xor.rs#L455-L466
One way to fix it is to count the non-NULL values in the frame and return
NULL when the count is zero. `avg` had the same kind of problem in #22139.
### Willingness to contribute
Feel free to take it!
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]