Skip to content

Docs Feedback modules/ROOT/pages/appendix/gql-conformance/index.adoc (ref: cypher-25) #1488

@averdeny

Description

@averdeny

Hi Cypher team,

I'm working on a Python library for parsing and transpiling GQL/Cypher. While building our Neo4j dialect I relied heavily on the conformance documentation. Here are a few things I ran into, plus some features that seem to be missing from the docs.

1. Questions and potential issues

SELECT: Select statements (e.g. SELECT 1) are rejected by Neo4j but I don't see it mentioned on the unsupported mandatory page.

GV39 temporal literals: The type support works, but the GQL literal form DATE '2026-01-01' is rejected (the Cypher constructor date('2026-01-01') works fine). A note on the GV39 entry would help clarify this for implementers.

STDDEV_SAMP / STDDEV_POP: The analogous Cypher page (GF10) spells these STDEV_SAMP / STDEV_POP (single D). The GQL standard uses STDDEV_SAMP / STDDEV_POP (double D). Looks like a typo.

MOD(): GQL defines MOD() for modulus; Cypher uses % instead and rejects MOD(). Not mentioned on any conformance page.

Trailing decimal: RETURN 3. (no fractional digits) is rejected; RETURN 3.0 works. Minor edge case.

DOUBLE vs FLOAT64: The analogous page maps both to Cypher's FLOAT. In the GQL standard FLOAT64 is exactly IEEE 754 binary64 while DOUBLE has implementation-defined precision (>= FLOAT). Since Cypher's FLOAT is 64-bit IEEE 754, the FLOAT64 mapping is precise, but the DOUBLE mapping could use a clarifying note.

2. Possibly undocumented optional features

Through integration testing (parse GQL, generate Cypher, execute against Neo4j 2026 community) I found several optional GQL features that work but don't appear on any of the three conformance pages.

Feature Description Test query Notes
G005 Path search prefix in a path pattern MATCH SHORTEST 2 (a)-[:KNOWS]->{1,5}(b) RETURN b.name Prerequisite for G016-G020 which are all listed; likely just missing from the docs
G044 Basic abbreviated edge patterns MATCH (a)-->(:Person) RETURN a.name GQL -> / <- / - vs Cypher --> / <-- / --
G111 IS LABELED predicate MATCH (n) WHERE n:Person RETURN n.name GQL n IS LABELED Person vs Cypher n:Person
GA05 Cast specification RETURN toFloat(42) GQL CAST(x AS FLOAT) vs Cypher toFloat(x) etc.
GB03 Double solidus comments // comment Same syntax
GD02 Graph label set changes MATCH (n) SET n:Intern RETURN n.name Same syntax
GD04 DELETE with simple expression MATCH ()-[r:LIKES]->() DELETE r Same syntax
GE07 Boolean XOR WHERE n.active = TRUE XOR n.age > 30 Same syntax
GF20 Aggregate functions in sort keys ORDER BY COUNT(m) DESC Same syntax
GL01 Hexadecimal literals RETURN 0xFF Same syntax
GL02 Octal literals RETURN 0o77 Same syntax
GL04 Exact number in common notation RETURN 3.14 Same syntax (trailing-dot 3. fails)
GP02 Inline procedure: implicit scope CALL { RETURN 42 AS x } RETURN x Same syntax
GQ12 OFFSET clause ORDER BY n.name SKIP 3 GQL OFFSET n vs Cypher SKIP n
GQ14 Complex expressions in sort keys ORDER BY n.age * -1 Same syntax
GQ16 Pre-projection aliases in sort keys ORDER BY person_name Same syntax
GQ22 EXISTS predicate: multiple MATCH WHERE EXISTS { MATCH ... MATCH ... } Same syntax
GV41 Duration types RETURN duration('P1Y') GQL DURATION 'P1Y' literal vs Cypher duration(...) constructor
GV48 Nested record types RETURN {a: {b: 'hello'}}.a.b Same syntax

Additionally, G043 (complete full edge patterns) and G045 (complete abbreviated edge patterns) are partially supported. Neo4j handles the directed forms (<-[r]-> for G043, <--> for G045) but rejects the tilde forms (~[r]~, <~[r]~, ~[r]~> for G043 and ~, <~, ~> for G045). Since Cypher only has directed edges, this is expected. Whether these count as supported probably depends on how strictly partial conformance is interpreted.

3. What's working well

Overall the conformance documentation has been genuinely useful for our implementation. The analogous Cypher page in particular: explicit function-name mappings like COLLECT_LIST -> collect and PATH_LENGTH -> length saved us a lot of guesswork, and every mapping we tested works correctly.

Thanks for maintaining these docs.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions