Last Updated: May 2, 2026
For fixed issues and release history, see CHANGELOG.md.
Status: Performance limitation
Error: MEMORY_LIMIT_EXCEEDED or query timeout
Cause: Recursive CTE-based shortest path explores all paths. Dense graphs cause exponential explosion.
Workaround: Use bounded path length: shortestPath((a)-[:FOLLOWS*1..5]->(b))
Status: By design (v0.6.7+)
Cause: ClickHouse server's lightweight UPDATE/DELETE path differs from chdb in maturity and concurrency semantics. ClickGraph's write_guard rejects writes against any executor that isn't EmbeddedChdb (server / remote / sql_only modes) and against any node/edge backed by a source: URI in the schema YAML.
Workaround: For server / remote workloads, perform writes via the ClickHouse SQL interface directly, then query through ClickGraph as normal.
Status: Pending Phase 5 (MERGE) and Phase 5+ (write extensions)
Affected: MERGE, CREATE … RETURN, relationship CREATE, DELETE r for an edge alias, SET a += {…} map-merge, REMOVE a:Label. Each case is rejected with an explicit error in the write pipeline rather than silently falling through.
Workaround: Issue a separate MATCH … RETURN after a CREATE to read back. For relationship CREATE today, use Connection::create_edges() (direct API). For edge deletion, Connection::delete_edges().
Status: chdb limitation
Cause: chdb's lightweight write path doesn't return affected-row counts, so ClickGraph attributes one to the relevant counter per write op (Insert, Update, Delete).
Workaround: Issue a MATCH … RETURN count(*) before/after the write for an exact count.
Fix: Commit 734d65f - Unified aggregation logic
- ClickHouse aggregations now properly return 1 row with default values (count=0, etc.)
- Made
extract_select_items()aggregation-aware - Unified WITH and RETURN aggregation code paths
Tests:
test_aggregation_empty_result,test_count_empty_resultexpecting 1 row with count=0
Fix: PR #64 (commit 6755d22) - Full WebSocket Bolt transport
- Added
websocket.rswith WebSocketBoltAdapter implementing AsyncRead/AsyncWrite - Server detects HTTP GET/POST requests on Bolt port → WebSocket handshake
- Neo4j Desktop and NeoDash now connect successfully via Bolt WebSocket
Location:
src/server/bolt_protocol/websocket.rs+ integration insrc/server/mod.rs
Fix: Commit f144108 - Full implementation with CTE+JOIN
- Added target_label/target_property extraction from pattern AST
- Fixed aggregation type detection (collect() → GroupArray)
- Generated INNER JOIN to target node table
- Fixed relationship name matching and JOIN conditions
Tests:
tests/integration/test_pattern_comprehensions.pypassing
Fix: Commits e5ca181 + b3697e2
- Empty plans now use
FROM system.one WHERE falsefor valid SQL - RETURN-only queries (e.g.,
RETURN 1) properly handled - Column references in Empty plans replaced with typed defaults
Location:
src/render_plan/plan_builder.rslines 2301-2400
Fix: PR #104 - Branch-specific label extraction
- Extract single label from each UNION branch's GraphNode
- Temporarily override plan_ctx during projection tagging
- Tightened VLP detection with
is_cte_reference()check Tests:tests/integration/test_labels_untyped_nodes.pywith 7 test cases
ClickGraph is primarily an analytical query engine. Limited write support exists in embedded mode (v0.6.7+); the rest stays out of scope:
- ✅ Cypher writes (
CREATE,SET,DELETE,REMOVE) in embedded mode only, against ClickGraph-managed (non-source:) tables — see Active Issues #2 / #3 for caveats - ❌ Cypher writes in server / remote / sql_only modes
- ❌
MERGEclause (planned for v0.7.x) - ❌ Schema DDL (
CREATE INDEX,CREATE CONSTRAINT) - ❌ Transaction management (
BEGIN,COMMIT,ROLLBACK) - ❌ Stored procedures (APOC/GDS) — only built-in
db.*procedures
| Issue | Fix | PR |
|---|---|---|
| Unlabeled nodes + labeled rel invalid UNION branches (#6) | Phase 0 Case 5 in TypeInference | path-direction-fix |
| Property filtering on unlabeled nodes invalid branches (#7) | Phase 2 property-based candidate filtering | path-direction-fix |
| Relationship property access fails with CTE structure (#8) | pattern_union CTE exposes direct columns | path-direction-fix |
| Query-level UNION fails plan context merge (#9) | Fixed branch pruning for TypeInference placeholders | path-direction-fix |
count(n) on untyped nodes returns wrong value |
Aggregation placed above UNION, not inside branches | path-direction-fix |
| FOLLOWS self-join returns empty | from_node/to_node aliases for same-table JOINs | path-direction-fix |
| JSON column order alphabetical instead of query order | serde_json preserve_order feature |
path-direction-fix |
UNION __label__ injection not projection-guided |
returns_whole_entity() checks Projection items |
path-direction-fix |
| UNWIND crash with collect(DISTINCT) | Fixed infinite WITH iteration + DISTINCT handling | #91 |
| Cross-session ID leakage between tenants | IdMapper scoped by schema + tenant | #85 |
| Query cache ignores tenant_id | Cache key includes tenant_id + view_parameters | main |
| PackStream arrays/objects not encoded | Recursive PackStream encoding | #83 |
| UNION column mismatch (literal + aggregate) | Extracted helper, fixed branch construction | #84 |
| Browser click-to-expand failures (5 schema types) | CTE naming, JOIN fixes, VLP rendering | #70–#82 |
| Browser EXPLAIN probe noise | EXPLAIN handler returns empty SUCCESS | #85 |
| Session commands not working in browser | ConnectionState::Streaming fix | #85 |