Skip to content

fix(cypher): translate collect() to json_group_array with typed decode - #29

Merged
ManSio merged 1 commit into
mainfrom
fix/cypher-collect-aggregate
Sep 8, 2026
Merged

ManSio merged 1 commit into
mainfrom
fix/cypher-collect-aggregate

Conversation

@ManSio

@ManSio ManSio commented Sep 8, 2026

Copy link
Copy Markdown
Owner

Summary

  • collect() in the Cypher SQL translator now lowers to json_group_array(expr) FILTER (WHERE expr IS NOT NULL) — Neo4j semantics: null-ignored, empty match → [].
  • collect(*) and nested collect raise explicit ValueError; DISTINCT inside collect is rejected by the parser layer.
  • Translator marks collect columns (collect_cols); cypher_executor decodes json.loads only for marked string columns — collision-safe (a collected string that looks like JSON stays a string), warning-only on decode failure.

Evidence

  • 13 new SQL/E2E/error tests incl. decode-collision guard: file 93 passed.
  • Full pytest: 1663 passed / 6 skipped / 91 deselected (verified 5×, incl. a sanitized-env replica of the gate-zero run).
  • ruff clean; verify_diary 16 ✅ / 0 ❌; negative controls: stale_detector PROVEN (after reverting a stray stale_config.json edit that broke gate-zero + negative controls — root-caused and reverted).
  • Red Team 5/5 attacks covered: empty match, nulls, unicode/quotes, DISTINCT, nested/*.
  • Experiments G1/G2 raw-verified on sqlite 3.50.4 / Python 3.14.3: FILTER semantics and empty→[] confirmed.

Notes

  • Known hook-environment issue documented: pre-commit hook launched under a non-venv interpreter (no pytest) made gate-zero fail with an empty summary; commits require venv-first PATH until the hook resolves sys.executable explicitly (follow-up).
  • Refs KNOWN_ISSUES 2026-09-07: collect() open → fixed.

fixes the collect() item tracked in KNOWN_ISSUES; closes #23 follow-up not included (LSP wrong-root stays open).

COLLECT(expr) now lowers to json_group_array(expr) FILTER (WHERE expr IS NOT NULL): Neo4j semantics (null-ignored, empty match -> []). collect(*) and nested collect raise explicit ValueError; DISTINCT is rejected by the parser layer. Translator marks collect columns (collect_cols); cypher_executor decodes json.loads only for marked string columns (collision-safe, warning-only on decode failure).

13 new SQL/E2E/error tests incl. decode-collision guard; full pytest 1663 passed / 6 skipped / 91 deselected (verified 5x incl. sanitized-env gate-zero replica); ruff clean; verify_diary 16/0; negative controls: stale_detector PROVEN. Red Team 5/5. Experiments G1/G2 raw-verified on sqlite 3.50.4.

Refs KNOWN_ISSUES 2026-09-07 (collect open -> fixed).
@coderabbitai

coderabbitai Bot commented Sep 8, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Advanced

Run ID: 05d62007-6cb0-4c05-badc-e412c0981d34


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@ManSio
ManSio merged commit 6e63f85 into main Sep 8, 2026
12 of 13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

LSP tools resolve project root from process CWD instead of per-call workdir (multi-window wrong-root risk)

1 participant