apache / apache/datafusion

INTERSECT ALL returns wrong number of records from RHS

Offen
#12,955 5 Kommentare 1 Reaktion 0 zugewiesene Personen Auf GitHub ansehen
bug
Vorherrschende Sprache
Rust
Sterne
9.3k
Forks
2.4k
Ø Merge
3 T. 11 Std.
Gemergte PRs (30 T.)
362

Beschreibung

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

Beitragsleitfaden

Beitragsleitfaden öffnen

Rechercherichtung

Beginne damit, die gemeldete INTERSECT ALL-Abfrage in DataFusion zu reproduzieren, und verfolge den Ausführungspfad, der doppelte Zeilen in der Eingabe auf der rechten Seite verarbeitet. Als erledigt gilt dies, wenn für jede Zeile die minimale Anzahl von Duplikaten aus beiden Eingaben zurückgegeben wird und ein Regressionstest das Beispiel mit b und c abdeckt.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
rust, sql
Bereich
databases
Issue-Typ
Bug
Schwierigkeit
3/5
Geschätzter Aufwand
1-2 Tage
Aktivitätsstatus
Veraltet
Klarheit
Klar beschrieben
Anfängerfreundlichkeit
45/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.