Negative `INTERVAL` offsets in RANGE window frames are accepted and panic at execution
- Lingua principale
- Rust
- Stelle
- 9.3k
- Fork
- 2.4k
- Merge medio
- 3g 11h
- PR unite (30g)
- 360
Descrizione
### Describe the bug
ROWS and GROUPS frame offsets are parsed as `UInt64`, so `ROWS BETWEEN -1 PRECEDING ...` is a planning error ("frame offsets for ROWS / GROUPS must be non negative integers"). RANGE offsets are kept as strings until `coerce_window_frame` (`datafusion/optimizer/src/analyzer/type_coercion.rs`) casts them to the ORDER BY type, and an interval literal such as `INTERVAL '-1 day'` carries its sign inside the string, so a negative RANGE offset is never rejected.
The frame then starts after it ends. The window execution code assumes `start <= end` and panics in debug builds:
### To Reproduce
Debug build of `datafusion-cli`:
```sql
SELECT count(*) OVER (ORDER BY x RANGE BETWEEN INTERVAL '-1 month' PRECEDING AND CURRENT ROW)
FROM (VALUES (arrow_cast(1, 'Timestamp(Second, None)')), (arrow_cast(2, 'Timestamp(Second, None)'))) t(x);
```
```text
thread 'main' panicked at datafusion/physical-expr/src/window/sliding_aggregate.rs:216:33:
attempt to subtract with overflow
```
```sql
SELECT count(*) OVER (ORDER BY x RANGE BETWEEN INTERVAL '-1 day' PRECEDING AND INTERVAL '-1 day' FOLLOWING)
FROM (VALUES (now()), (now())) t(x);
```
```text
thread 'main' panicked at datafusion/expr/src/window_state.rs:65:18:
attempt to subtract with overflow
```
In release builds the same queries do not panic but return wrong results (e.g. `count(*)` of 0 for every row over three consecutive dates with `INTERVAL '-1 day' PRECEDING`).
### Expected behavior
A planning error, consistent with ROWS / GROUPS (and with PostgreSQL, which rejects the frame with "frame starting offset must not be negative").
### Additional context
Found while running a corpus of extreme-value literals against a debug build of `datafusion-cli`.
Guida per i contributori
Apri la guida per i contributori
Direzione di ricerca
Riproduci le query con una build di debug di datafusion-cli, quindi esamina coerce_window_frame in datafusion/optimizer/src/analyzer/type_coercion.rs. Traccia il frame risultante attraverso datafusion/physical-expr/src/window/sliding_aggregate.rs e datafusion/expr/src/window_state.rs. Il lavoro è completato quando gli offset negativi di RANGE INTERVAL producono un errore di pianificazione come ROWS e GROUPS, invece di arrivare all'esecuzione o restituire risultati errati.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Valutazione
- Stack tecnologico
- rust, sql
- Ambito
- databases
- Tipo di issue
- Bug
- Difficoltà
- 3/5
- Tempo stimato
- 1-2 giorni
- Stato di attività
- Attiva
- Chiarezza
- Specificata chiaramente
- Idoneità per principianti
- 75/100