Compiled Cypher: a CALL's UNION ALL keeps its null and list marks from the first part only (port of drivine4j#512)

Geschlossen
#321 0 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Maintainer antworten meist innerhalb von 1 Tag

Ein zugehöriger Pull Request wurde bereits gemerged.

  • #322 von @jasperblues — gemerged

Bewertung

Schwierigkeit
3/5
Geschätzter Aufwand
1-2 Tage
Anfängerfreundlichkeit
56/100
Issue-Typ
Bug
Klarheit
Größtenteils klar
Aktivitätsstatus
Aktiv
Tech-Stack
python
Bereich
databases

Rechercherichtung

Start at _called_union in drivine/cypher/sql/sql_cypher_compiler.py, especially the merge loop around line 1874, and compare how it combines marks across UNION ALL parts. Port the named cases from CypherQueryCrossEngineTest.kt and the two steps from spec v0.20.0. Done means the null and list marks merge as described and the regression cases match the expected Neo4j behavior.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Beschreibung

bug

Port of liberation-data/drivine4j#512 (fixed by liberation-data/drivine4j#514). This adds to the note already in #314.

What happens here now: _called_union (drivine/cypher/sql/sql_cypher_compiler.py:1834, merge loop at ~1874) builds each merged column with dataclasses.replace(projected[0]'s value, …). It recomputes only row_keys, from_list, temporal, items, item_items, temporals, text, texts and known across the parts. Every other mark comes from the first part only: JSON's-null (#314's note), and the marks for a list, a list of lists, and a flat list. So when parts differ in kind, the merged column sorts and compares by the first part's kind.

drivine4j's wrong rows before its fix:

  • CALL { RETURN [10] AS v UNION ALL RETURN 10 AS v } RETURN v ORDER BY v gave [10, [10]]; Neo4j gives [[10], 10].
  • v < 2 over [1] ∪ 1 gave [null, null]; Neo4j gives [null, true].
  • v = [1] and v IN [[1], 1] over [1] ∪ [null] gave [true, false]; Neo4j gives [true, null].
  • UNWIND v over [[1]] ∪ [1], then ORDER BY, gave [1, [1]]; Neo4j gives [[1], 1].
  • CALL { RETURN {}.a AS v UNION ALL RETURN [null][0] AS v } RETURN DISTINCT v gave two nulls; Neo4j gives one.

What the fix does: in calledUnion, the JSON's-null mark is set if any part has it. The list, list-of-lists and flat marks are kept only where every part has them, like text/texts.

Tests to port:

  • drivine4j CypherQueryCrossEngineTest.kt: "a CALL's UNION ALL whose later part gives a list's null keeps it one null with a missing key", and "a CALL's UNION ALL whose first part gives a list and a later one a number or a map sorts each by its kind". The second skips Postgres (#307 there) and compares rows without ORDER BY as a multiset.
  • Spec v0.20.0 (drivine-cypher-spec #45): two steps in "A null in a map and a missing key are one null".
Vorherrschende Sprache
Python
Sterne
1
Forks
0
Ø Merge
1 Std. 32 Min.
Gemergte PRs (30 T.)
149

Entwicklungsumgebung

Dieses Projekt bietet weder Dev-Container noch Dockerfile noch Beitragsleitfaden – die Einrichtung liegt bei Ihnen. Beginnen Sie mit der README; die allgemeinen Schritte stehen in unserem Leitfaden für den ersten Beitrag.

Erste Schritte

  1. Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
  3. Forken Sie das Repository und arbeiten Sie in einem Branch.
  4. Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.

Mehr aus liberation-data/drivine-python

Alle Issues in liberation-data/drivine-python

Ähnliche Issues

Weitere Issues zu Python

Neue Issues direkt in Ihr Postfach

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