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

Fermée
#321 0 commentaires 0 réactions 0 personnes assignées Voir sur GitHub

Les mainteneurs répondent en général sous 1 jour

Une pull request liée a déjà été fusionnée.

  • #322 par @jasperblues — fusionnée

Évaluation

Difficulté
3/5
Temps estimé
1-2 jours
Accessibilité débutants
56/100
Type d'issue
Bug
Clarté
Plutôt claire
Activité
Active
Stack technique
python
Domaine
databases

Piste de recherche

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.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Description

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".
Langage dominant
Python
Étoiles
1
Forks
0
Merge moyen
1 h 32 min
PR mergées (30 j)
149

Préparer son environnement

Ce projet ne fournit ni conteneur de développement, ni Dockerfile, ni guide de contribution : l'installation est à votre charge. Commencez par son README, et consultez notre guide de la première contribution pour les étapes générales.

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Autres issues de liberation-data/drivine-python

Toutes les issues de liberation-data/drivine-python

Issues similaires

Plus d'issues Python

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.