cblp opened a new issue, #26222:
URL: https://github.com/apache/datafusion/issues/26222

   ### Describe the bug
   
   `sum` and `avg` of `Float64` over a sliding window frame (`ROWS BETWEEN n 
PRECEDING AND CURRENT ROW`) are not the sum and average of the values in the 
frame:
   
   - Once `Infinity`, `-Infinity` or `NaN` has been in the frame, every later 
frame returns `NaN`, even frames that contain only finite values.
   - Finite values lose precision: a frame can return a value that differs from 
the sum of its values by more than rounding.
   
   Both come from how values leaving the frame are removed: 
`SlidingSumAccumulator::retract_batch` 
(`datafusion/functions-aggregate/src/sum.rs`) and 
`AvgAccumulator::retract_batch` 
(`datafusion/functions-aggregate/src/average.rs`) subtract them from the 
running sum. `inf - inf` is `NaN`, and `NaN` never leaves the running sum. For 
finite values, a small value added to a large one is lost, and subtracting the 
large one does not bring it back.
   
   
   ### To Reproduce
   
   In `datafusion-cli`:
   
   ```sql
   SELECT i, x,
     sum(x) OVER (ORDER BY i ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) AS s,
     avg(x) OVER (ORDER BY i ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) AS a
   FROM (VALUES (1, 1.0), (2, 'Infinity'), (3, 2.0), (4, 3.0), (5, 'NaN'), (6, 
4.0), (7, 5.0)) AS t(i, x)
   ORDER BY i;
   ```
   
   ```
   +---+-----+-----+-----+
   | i | x   | s   | a   |
   +---+-----+-----+-----+
   | 1 | 1.0 | 1.0 | 1.0 |
   | 2 | inf | inf | inf |
   | 3 | 2.0 | inf | inf |
   | 4 | 3.0 | NaN | NaN |
   | 5 | NaN | NaN | NaN |
   | 6 | 4.0 | NaN | NaN |
   | 7 | 5.0 | NaN | NaN |
   +---+-----+-----+-----+
   ```
   
   Finite values only:
   
   ```sql
   SELECT i, x, sum(x) OVER (ORDER BY i ROWS BETWEEN 1 PRECEDING AND CURRENT 
ROW) AS s
   FROM (VALUES (1, 1e16), (2, 1.0), (3, 2.0)) AS t(i, x)
   ORDER BY i;
   ```
   
   ```
   +---+------+------+
   | i | x    | s    |
   +---+------+------+
   | 1 | 1e16 | 1e16 |
   | 2 | 1.0  | 1e16 |
   | 3 | 2.0  | 2.0  |
   +---+------+------+
   ```
   
   
   ### Expected behavior
   
   Each row returns the sum (average) of the values in its frame, as the same 
aggregate over just those values would:
   
   - first query: row 4 (frame `[2, 3]`) returns `5` and `2.5`, row 7 (frame 
`[4, 5]`) returns `9` and `4.5`; rows 5 and 6, whose frames contain `NaN`, 
return `NaN`;
   - second query: row 3 (frame `[1, 2]`) returns `3`.
   
   
   ### Additional context
   
   Reproduced on `main` at commit 6663e4348 (debug build of `datafusion-cli`).
   
   One way to fix it is to keep the running sum exact, so that removing a value 
is exact: for example an integer fixed-point accumulator that holds any `f64` 
sum exactly, with counts of `NaN`, `Infinity` and `-Infinity` in the frame 
instead of adding them to the sum.
   
   
   ### Willingness to contribute
   
   None


-- 
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]

Reply via email to