apache / apache/datafusion

INTERSECT ALL returns wrong number of records from RHS

Aperta
#12,955 5 commenti 1 reazione 0 assegnatari Vedi su GitHub
bug
Lingua principale
Rust
Stelle
9.3k
Fork
2.4k
Merge medio
3g 11h
PR unite (30g)
362

Descrizione

### Describe the bug

According to the [SQL spec](https://www.contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt), when returning duplicate records from INTERSECT ALL the minimum number of copies from either input should be returned. Specifically:
```
b) If a set operator is specified, then the result of applying
the set operator is a table containing the following rows:

i) Let R be a row that is a duplicate of some row in T1 or of
some row in T2 or both. Let m be the number of duplicates
of R in T1 and let n be the number of duplicates of R in
T2, where m � 0 and n � 0.

...

iii) If ALL is specified, then

Case:

1) If UNION is specified, then the number of duplicates of
R that T contains is (m + n).

2) If EXCEPT is specified, then the number of duplicates of
R that T contains is the maximum of (m - n) and 0.

3) If INTERSECT is specified, then the number of duplicates
of R that T contains is the minimum of m and n.
```

DataFusion currently returns ALL copies of duplicated records from the RHS.

### To Reproduce

The following query
```sql
➜ ~ datafusion-cli
DataFusion CLI v42.0.0

> SELECT * FROM VALUES ('a'), ('b'), ('b'), ('c'), ('c'), ('c')
INTERSECT ALL
SELECT * FROM VALUES ('b'), ('b'), ('b'), ('c'), ('c');
+---------+
| column1 |
+---------+
| b |
| b |
| c |
| c |
| c |
+---------+
```

returns 3 copies of the record `('c')` which does not match the expected behaviour based on the spec.

Note that only 2 copies of `('b')` are returned, so this only appears to affect the RHS.

### Expected behavior

The above query should return 2 copies of the record `('c')`

### Additional context

See DB Fiddle for Postgres which showcases the expected behaviour:
https://www.db-fiddle.com/f/ja4BG5CfyEvak5ScoBwCZr/0

Guida per i contributori

Apri la guida per i contributori

Direzione di ricerca

Inizia riproducendo la query INTERSECT ALL segnalata in DataFusion e traccia il percorso di esecuzione che gestisce le righe duplicate nell’input di destra. Il lavoro è completato quando viene restituito il numero minimo di duplicati di entrambi gli input per ogni riga, con un test di regressione che copra l’esempio con b e c.

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à
Ferma
Chiarezza
Specificata chiaramente
Idoneità per principianti
45/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.