apache / apache/datafusion

Negative `INTERVAL` offsets in RANGE window frames are accepted and panic at execution

Aperta
#24,902 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub
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

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.