Admitted Subset¶
CypherGlot is intentionally narrow. It accepts a small Cypher surface and rejects broader grammar families clearly at validation time.
Practical Coverage¶
CypherGlot's current practical coverage should be understood from the admitted, documented, and regression-tested subset in this guide rather than from parser breadth alone.
For mainstream onboarding, the current surface is best described as a strong single-hop, read-heavy Neo4j-style subset rather than full Cypher parity. Neo4j is the practical reference engine for this admitted surface: queries in the subset should ideally be valid there unchanged, while other Cypher runtimes may require small compatibility rewrites around the same core shapes. That includes:
- ordinary
MATCH ... RETURNreads over one connected pattern - narrow standalone
OPTIONAL MATCH ... RETURN - narrow
MATCH ... WITH ... RETURNrebinding flows - narrow standalone
UNWIND ... RETURN - grouped
count(...),count(*),sum(...),avg(...),min(...), andmax(...)aggregation slices - common projection families over admitted field, scalar-binding, or literal
inputs:
size(...),id(...),type(...), searchedCASE,properties(...),labels(...),keys(...),startNode(...),endNode(...), string rewrite functions, numeric functions, conversion functions, and predicate outputs - one-hop relationship-property reads across those same admitted projection and predicate families
- bounded read-side variable-length relationship reads, including syntactic
relationship aliases that are not referenced downstream, for
ordinary
MATCH ... RETURNand narrowMATCH ... WITH ... RETURN - optional final-
RETURNaliases for common admitted introspection, aggregate, unary computed, and narrow multi-argument computed outputs
That is the current strong onboarding/read-heavy target: a practical mainstream subset for paste-in read queries that stay within simple connected patterns and narrow projection flows, plus the narrow write and bounded traversal families documented below. It is not a claim of broad Neo4j parity or of coverage for most Neo4j users overall. It is also not a claim that every runtime in the benchmark matrix accepts the exact same raw query text unchanged; Neo4j anchors the subset, and some other engines may need light adaptation at execution time.
Read subset¶
CypherGlot currently admits:
MATCH ... RETURN- narrow standalone
OPTIONAL MATCH ... RETURN - narrow
MATCH ... WITH ... RETURN - narrow standalone
UNWIND ... RETURN - a single connected
MATCHpattern - at most one relationship hop in the matched pattern
- bounded non-negative-length variable-length relationship reads in ordinary
MATCH ... RETURNand narrowMATCH ... WITH ... RETURN, including syntactic relationship aliases that are not referenced in downstreamRETURN,WITH, or predicate surfaces - traversal-backed
MATCH ... CREATEandMATCH ... MERGEwith exactly one reused matched node alias plus at most one fresh endpoint node, whether that fresh endpoint is labeled or unlabeled - narrow
WHEREpredicates over admitted entity fields, plus admittedid(alias) OP literal_or_parameter; for relationship bindings, admittedtype(rel_alias) = literal_or_parameter - that same ordinary-read and narrow-optional
WHEREslice also admits field string predicatesSTARTS WITH,ENDS WITH, andCONTAINS, plus field null predicatesIS NULLandIS NOT NULL; in admitted one-hop relationship reads, those same field string/null predicates also apply to relationship property fields such asr.note - that same ordinary-read and narrow-optional
WHEREslice also admits narrow nestedsize(...)field predicates over compile-safe property inputs:size(alias.field) OP literal_or_parameter,size(alias.field) IS NULL, andsize(alias.field) IS NOT NULL; in admitted one-hop relationship reads, those same nestedsize(...)filters also apply to relationship property fields such assize(r.note) ORDER BY,SKIP, andLIMITon admittedRETURNqueries- optional
AS output_aliason ordinaryMATCHand narrowOPTIONAL MATCHfield projections such asRETURN u.name AS name - whole-entity pass-through returns on ordinary
MATCHand narrowOPTIONAL MATCH, such asRETURN u,RETURN u AS user, or in one-hopMATCHqueriesRETURN r AS rel - a narrow standalone aggregation slice on ordinary
MATCH:count(bound_alias)orcount(*), each with optionalAS output_alias, optionally alongside grouped field or whole-entity projections - a first narrow scalar-expression slice on ordinary
MATCH: scalar literals or named parameters with explicit aliases such asRETURN 'tag' AS tagorRETURN $value AS value - a first narrow computed-expression slice on ordinary
MATCHand narrowOPTIONAL MATCH:size(...)over admitted field projections, with optionalAS output_alias; scalar literal/parameter inputs still require explicit aliases. This same slice also admits nestedid(alias)andtype(rel_alias)outputs undersize(...) - a narrow unary string-function slice on ordinary
MATCHand narrowOPTIONAL MATCH:lower(alias.field),upper(alias.field),trim(alias.field),ltrim(alias.field),rtrim(alias.field), andreverse(alias.field), each with optionalAS output_alias, plus scalar literal/parameter inputs such aslower('tag') AS lower_tag,upper($value) AS upper_value,trim(' tag ') AS trimmed,ltrim(' tag') AS left_trimmed,rtrim('tag ') AS right_trimmed, orreverse('tag') AS reversed_tag - in admitted one-hop relationship reads, those same field-projection families
also apply to relationship property fields such as
r.note - a narrow null-fallback slice on ordinary
MATCHand narrowOPTIONAL MATCH:coalesce(alias.field, literal_or_parameter)with optionalAS output_alias - a narrow replace slice on ordinary
MATCHand narrowOPTIONAL MATCH:replace(admitted_input, literal_or_parameter, literal_or_parameter)with optionalAS output_aliasover admitted field projections plus scalar literal/parameter inputs - a narrow left/right slice on ordinary
MATCHand narrowOPTIONAL MATCH:left(admitted_input, literal_or_parameter)andright(admitted_input, literal_or_parameter)with optionalAS output_aliasover admitted field projections plus scalar literal/parameter inputs - a narrow split slice on ordinary
MATCHand narrowOPTIONAL MATCH:split(admitted_input, literal_or_parameter)with optionalAS output_aliasover admitted field projections plus scalar literal/parameter inputs - a narrow substring slice on ordinary
MATCHand narrowOPTIONAL MATCH:substring(admitted_input, literal_or_parameter)andsubstring(admitted_input, literal_or_parameter, literal_or_parameter)with optionalAS output_aliasover admitted field projections plus scalar literal/parameter inputs - a narrow numeric-function slice on ordinary
MATCHand narrowOPTIONAL MATCH:abs(alias.field)with optionalAS output_alias, plus scalar literal/parameter inputs such asabs(-3) AS magnitude - a narrow sign-function slice on ordinary
MATCHand narrowOPTIONAL MATCH:sign(alias.field)with optionalAS output_alias, plus scalar literal/parameter inputs such assign(-3.2) AS age_sign - a narrow rounding-function slice on ordinary
MATCHand narrowOPTIONAL MATCH:round(alias.field) AS output_alias, plus scalar literal/parameter inputs such asround(-3.2) AS value - a narrow ceiling-function slice on ordinary
MATCHand narrowOPTIONAL MATCH:ceil(alias.field) AS output_alias, plus scalar literal/parameter inputs such asceil(-3.2) AS value - a narrow floor-function slice on ordinary
MATCHand narrowOPTIONAL MATCH:floor(alias.field) AS output_alias, plus scalar literal/parameter inputs such asfloor(-3.2) AS value - a narrow square-root-function slice on ordinary
MATCHand narrowOPTIONAL MATCH:sqrt(alias.field) AS output_alias, plus scalar literal/parameter inputs such assqrt(-3.2) AS value - a narrow exponential-function slice on ordinary
MATCHand narrowOPTIONAL MATCH:exp(alias.field) AS output_alias, plus scalar literal/parameter inputs such asexp(-3.2) AS value - a narrow sine-function slice on ordinary
MATCHand narrowOPTIONAL MATCH:sin(alias.field) AS output_alias, plus scalar literal/parameter inputs such assin(-3.2) AS value - a narrow cosine-function slice on ordinary
MATCHand narrowOPTIONAL MATCH:cos(alias.field) AS output_alias, plus scalar literal/parameter inputs such ascos(-3.2) AS value - a narrow tangent-function slice on ordinary
MATCHand narrowOPTIONAL MATCH:tan(alias.field) AS output_alias, plus scalar literal/parameter inputs such astan(-3.2) AS value - a narrow string-conversion slice on ordinary
MATCHand narrowOPTIONAL MATCH:toString(alias.field)with optionalAS output_alias, plus scalar literal/parameter inputs such astoString(-3) AS text - a narrow integer-conversion slice on ordinary
MATCHand narrowOPTIONAL MATCH:toInteger(alias.field)with optionalAS output_alias, plus scalar literal/parameter inputs such astoInteger(-3.2) AS age_int - a narrow float-conversion slice on ordinary
MATCHand narrowOPTIONAL MATCH:toFloat(alias.field)with optionalAS output_alias, plus scalar literal/parameter inputs such astoFloat(-3) AS age_float - a narrow boolean-conversion slice on ordinary
MATCHand narrowOPTIONAL MATCH:toBoolean(alias.field)with optionalAS output_alias, plus scalar literal/parameter inputs such astoBoolean(true) AS is_active - in admitted one-hop relationship reads, those same numeric and conversion
families also apply to relationship property fields such as
r.weight,r.score, andr.active, including forms such assqrt(r.score) AS sqrt_score,exp(r.score) AS exp_score, andsin(r.score) AS sin_score - a first narrow predicate-return slice on ordinary
MATCHand narrowOPTIONAL MATCH:alias.field OP literal_or_parameter AS output_alias, plus admitted string predicatesalias.field STARTS WITH literal_or_parameter,alias.field ENDS WITH literal_or_parameter, andalias.field CONTAINS literal_or_parameter, plus admittedid(alias) OP literal_or_parameter AS output_aliasandtype(rel_alias) OP literal_or_parameter AS output_alias, plus admittedsize(alias.field) OP literal_or_parameter AS output_alias,size(id(alias)) OP literal_or_parameter AS output_alias, andsize(type(rel_alias)) OP literal_or_parameter AS output_alias - a narrow null-predicate slice on ordinary
MATCHand narrowOPTIONAL MATCH:alias.field IS NULL AS output_alias,alias.field IS NOT NULL AS output_alias,size(alias.field) IS NULL AS output_alias, andsize(alias.field) IS NOT NULL AS output_alias - in admitted one-hop relationship reads, those same predicate families also
apply to relationship property fields such as
r.weightandr.note, including nestedsize(r.note) OP literal_or_parameter - a first narrow built-in function alias slice on ordinary
MATCHand narrowOPTIONAL MATCH:id(alias)andtype(rel_alias), each with optionalAS output_alias - a narrow graph-introspection projection slice on ordinary
MATCHand narrowOPTIONAL MATCH:properties(entity_alias),labels(node_alias),keys(entity_alias),startNode(rel_alias),endNode(rel_alias), and the admittedstartNode(rel_alias).field/endNode(rel_alias).fieldforms, each with optionalAS output_alias ORDER BY projected_aliasfor admitted ordinary field, whole-entity, aggregate, scalar,size(...), predicate,id(...), andtype(...)outputs
The admitted WITH slice is currently narrow:
- one
MATCHclause beforeWITH - one
WITHclause with passthrough variable items such asWITH uorWITH u AS person, plus simple scalar rebinding such asWITH u.name AS name - an optional narrow
WHEREafterWITH, usingscalar_alias OP valueorentity_alias.field OP value, plus admittedid(entity_alias) OP valueandtype(rel_alias) OP value - that same narrow
WITH WHEREslice also admitsscalar_alias IS NULL,scalar_alias IS NOT NULL,entity_alias.field IS NULL, andentity_alias.field IS NOT NULL WITH WHEREalso admits narrow string predicates over compile-safe scalar and entity-field inputs:scalar_alias STARTS WITH value,scalar_alias ENDS WITH value,scalar_alias CONTAINS value,entity_alias.field STARTS WITH value,entity_alias.field ENDS WITH value, andentity_alias.field CONTAINS value; in admitted one-hop relationship reads, those sameWITH WHEREstring/null field predicates also apply to relationship bindings such asrel.noteWITH WHEREalso admits narrow nestedsize(...)predicates over compile-safe scalar and entity-field inputs:size(scalar_alias) OP value,size(scalar_alias) IS NULL,size(scalar_alias) IS NOT NULL,size(entity_alias.field) OP value,size(entity_alias.field) IS NULL, andsize(entity_alias.field) IS NOT NULL; in admitted one-hop relationship reads, those same nestedsize(...)filters also apply to relationship bindings such assize(rel.note)- one final
RETURNclause afterWITH - final projections shaped as
RETURN alias.fieldfor entity bindings,RETURN entity_aliasfor pass-through entity bindings, orRETURN scalar_aliasfor scalar bindings - optional
AS output_aliason admitted finalRETURNprojection items - a first aggregation slice:
count(binding_alias)orcount(*), each with optionalAS output_alias, optionally alongside grouped scalar or entity pass-through return items - a narrow built-in function alias slice in the final
RETURNof admittedMATCH ... WITH ... RETURN:id(entity_alias)andtype(rel_alias), each with optionalAS output_alias - a narrow graph-introspection projection slice in the final
RETURNof admittedMATCH ... WITH ... RETURN:properties(entity_alias),labels(node_alias),keys(entity_alias),startNode(rel_alias),endNode(rel_alias), and the admittedstartNode(rel_alias).field/endNode(rel_alias).fieldforms, each with optionalAS output_alias - a narrow computed-expression slice in the final
RETURNof admittedMATCH ... WITH ... RETURN:size(entity_alias.field),size(scalar_alias),size(id(entity_alias)), andsize(type(rel_alias)), each with optionalAS output_alias; scalar literal/parameter inputs such assize('tag') AS tag_lenorsize($value) AS value_lenstill require aliases - a narrow unary string-function slice in the final
RETURNof admittedMATCH ... WITH ... RETURN:lower(entity_alias.field),upper(entity_alias.field),lower(scalar_alias),upper(scalar_alias),trim(entity_alias.field),trim(scalar_alias),ltrim(entity_alias.field),ltrim(scalar_alias),rtrim(entity_alias.field),rtrim(scalar_alias),reverse(entity_alias.field), andreverse(scalar_alias), each with optionalAS output_alias, plus scalar literal/parameter inputs such aslower('tag') AS lower_tag,upper($value) AS upper_value,trim(' tag ') AS trimmed,ltrim(' tag') AS left_trimmed,rtrim('tag ') AS right_trimmed, orreverse('tag') AS reversed_tag - in admitted
MATCH ... WITH ... RETURNflows, those same entity-field families also apply to relationship bindings such asrel.note - a narrow null-fallback slice in the final
RETURNof admittedMATCH ... WITH ... RETURN:coalesce(entity_alias.field, literal_or_parameter)andcoalesce(scalar_alias, literal_or_parameter)with optionalAS output_alias - a narrow replace slice in the final
RETURNof admittedMATCH ... WITH ... RETURN:replace(admitted_input, literal_or_parameter, literal_or_parameter)with optionalAS output_aliasover admitted entity-field projections, scalar bindings, and scalar literal/parameter primary inputs - a narrow left/right slice in the final
RETURNof admittedMATCH ... WITH ... RETURN:left(admitted_input, literal_or_parameter)andright(admitted_input, literal_or_parameter)with optionalAS output_aliasover admitted entity-field projections, scalar bindings, and scalar literal/parameter primary inputs - a narrow split slice in the final
RETURNof admittedMATCH ... WITH ... RETURN:split(admitted_input, literal_or_parameter)with optionalAS output_aliasover admitted entity-field projections, scalar bindings, and scalar literal/parameter primary inputs - a narrow substring slice in the final
RETURNof admittedMATCH ... WITH ... RETURN:substring(admitted_input, literal_or_parameter)andsubstring(admitted_input, literal_or_parameter, literal_or_parameter)with optionalAS output_aliasover admitted entity-field projections, scalar bindings, and scalar literal/parameter primary inputs - a narrow numeric-function slice in the final
RETURNof admittedMATCH ... WITH ... RETURN:abs(entity_alias.field) AS output_aliasandabs(scalar_alias) AS output_alias, plus scalar literal/parameter inputs such asabs(-3) AS magnitude - a narrow sign-function slice in the final
RETURNof admittedMATCH ... WITH ... RETURN:sign(entity_alias.field) AS output_aliasandsign(scalar_alias) AS output_alias, plus scalar literal/parameter inputs such assign(-3.2) AS age_sign - a narrow rounding-function slice in the final
RETURNof admittedMATCH ... WITH ... RETURN:round(entity_alias.field) AS output_aliasandround(scalar_alias) AS output_alias, plus scalar literal/parameter inputs such asround(-3.2) AS value - a narrow ceiling-function slice in the final
RETURNof admittedMATCH ... WITH ... RETURN:ceil(entity_alias.field) AS output_aliasandceil(scalar_alias) AS output_alias, plus scalar literal/parameter inputs such asceil(-3.2) AS value - a narrow floor-function slice in the final
RETURNof admittedMATCH ... WITH ... RETURN:floor(entity_alias.field) AS output_aliasandfloor(scalar_alias) AS output_alias, plus scalar literal/parameter inputs such asfloor(-3.2) AS value - a narrow square-root-function slice in the final
RETURNof admittedMATCH ... WITH ... RETURN:sqrt(entity_alias.field) AS output_aliasandsqrt(scalar_alias) AS output_alias, plus scalar literal/parameter inputs such assqrt(-3.2) AS value - a narrow exponential-function slice in the final
RETURNof admittedMATCH ... WITH ... RETURN:exp(entity_alias.field) AS output_aliasandexp(scalar_alias) AS output_alias, plus scalar literal/parameter inputs such asexp(-3.2) AS value - a narrow sine-function slice in the final
RETURNof admittedMATCH ... WITH ... RETURN:sin(entity_alias.field) AS output_aliasandsin(scalar_alias) AS output_alias, plus scalar literal/parameter inputs such assin(-3.2) AS value - a narrow cosine-function slice in the final
RETURNof admittedMATCH ... WITH ... RETURN:cos(entity_alias.field) AS output_aliasandcos(scalar_alias) AS output_alias, plus scalar literal/parameter inputs such ascos(-3.2) AS value - a narrow tangent-function slice in the final
RETURNof admittedMATCH ... WITH ... RETURN:tan(entity_alias.field) AS output_aliasandtan(scalar_alias) AS output_alias, plus scalar literal/parameter inputs such astan(-3.2) AS value - a narrow string-conversion slice in the final
RETURNof admittedMATCH ... WITH ... RETURN:toString(entity_alias.field)andtoString(scalar_alias), each with optionalAS output_alias, plus scalar literal/parameter inputs such astoString(-3) AS text - a narrow integer-conversion slice in the final
RETURNof admittedMATCH ... WITH ... RETURN:toInteger(entity_alias.field) AS output_aliasandtoInteger(scalar_alias) AS output_alias, plus scalar literal/parameter inputs such astoInteger(-3.2) AS age_int - a narrow float-conversion slice in the final
RETURNof admittedMATCH ... WITH ... RETURN:toFloat(entity_alias.field) AS output_aliasandtoFloat(scalar_alias) AS output_alias, plus scalar literal/parameter inputs such astoFloat(-3) AS age_float - a narrow boolean-conversion slice in the final
RETURNof admittedMATCH ... WITH ... RETURN:toBoolean(entity_alias.field) AS output_aliasandtoBoolean(scalar_alias) AS output_alias, plus scalar literal/parameter inputs such astoBoolean(true) AS is_active - in admitted
MATCH ... WITH ... RETURNflows, those same numeric and conversion families also apply to relationship bindings such asrel.weight,rel.score, and rebound scalar aliases likeactive, including forms such assqrt(rel.score) AS sqrt_scoreandexp(score) AS exp_score, andsin(rel.score) AS sin_score - a narrow scalar-expression slice in the final
RETURNof admittedMATCH ... WITH ... RETURN: scalar literals or named parameters with explicit aliases such asRETURN 'tag' AS tagorRETURN $value AS value - a narrow predicate-return slice in the final
RETURNof admittedMATCH ... WITH ... RETURN:scalar_alias OP literal_or_parameter AS output_aliasorentity_alias.field OP literal_or_parameter AS output_alias, including admitted string predicatesentity_alias.field STARTS WITH literal_or_parameter,entity_alias.field ENDS WITH literal_or_parameter,entity_alias.field CONTAINS literal_or_parameter,scalar_alias CONTAINS literal_or_parameter,scalar_alias ENDS WITH literal_or_parameter, and plus admittedid(entity_alias) OP literal_or_parameter AS output_aliasandtype(rel_alias) OP literal_or_parameter AS output_alias, plus admittedsize(scalar_alias) OP literal_or_parameter AS output_alias,size(entity_alias.field) OP literal_or_parameter AS output_alias,size(id(entity_alias)) OP literal_or_parameter AS output_alias, andsize(type(rel_alias)) OP literal_or_parameter AS output_alias - a narrow null-predicate slice in the final
RETURNof admittedMATCH ... WITH ... RETURN:scalar_alias IS NULL AS output_alias,scalar_alias IS NOT NULL AS output_alias,entity_alias.field IS NULL AS output_alias,entity_alias.field IS NOT NULL AS output_alias,size(scalar_alias) IS NULL AS output_alias, andsize(entity_alias.field) IS NOT NULL AS output_alias - in admitted
MATCH ... WITH ... RETURNflows, those same predicate families also apply to relationship bindings such asrel.weight,rel.note, and rebound scalar aliases likenote, including nestedsize(rel.note) OP literal_or_parameterandsize(note) OP literal_or_parameter - matching
ORDER BY alias.field,ORDER BY scalar_alias,ORDER BY entity_alias, andORDER BY aggregate_alias ORDER BY projected_aliasfor admitted scalar, field, aggregate,id(...),type(...), whole-entity,size(...), scalar literal/parameter outputs, and predicate outputs produced by the finalRETURN
Whole-entity pass-through returns on the strict relational product path do not
compile to packed object values anymore. Where whole-entity slices remain
admitted, they are expected to expand into stable typed dotted columns such as
user.id, user.name, rel.id, or endpoint-field projections; list- or
object-shaped packaging is not part of the emitted-SQL contract.
The admitted UNWIND slice is currently narrow:
- standalone
UNWIND list_literal AS x RETURN x - optional
AS output_aliason admitted scalar unwind projections ORDER BYon the unwind alias or projected scalar aliasSKIPorOFFSET, andLIMIT
The admitted OPTIONAL MATCH slice is currently narrow:
- standalone single-node
OPTIONAL MATCH (n[:Label]) RETURN ... - the same shape with admitted node-property and
id(alias)WHEREpredicates - ordinary node-field projection, optional
AS output_alias,ORDER BY,SKIPorOFFSET, andLIMIT - narrow scalar literal or parameter outputs with explicit aliases such as
RETURN 'tag' AS tagorRETURN $value AS value - the same narrow
size(...), predicate-return, andid(...)slices admitted in ordinary single-node reads, plus the same narrowlower(...),upper(...),trim(...),ltrim(...),rtrim(...),reverse(...),coalesce(...),replace(...),left(...),right(...),split(...),substring(...),abs(...),sign(...),round(...),ceil(...),floor(...),sqrt(...),exp(...),sin(...),cos(...),tan(...),toInteger(...),toFloat(...), andtoBoolean(...)output slice - whole-node pass-through returns such as
RETURN norRETURN n AS item - the same narrow
count(bound_alias)orcount(*)aggregation slice, each with optionalAS output_alias, as ordinaryMATCH, including grouped field or whole-entity projections - null-preserving lowering through a left-join-style compiled shape for unmatched rows
CypherGlot does not yet admit broader WITH semantics such as WITH DISTINCT,
broader aggregation forms beyond narrow admitted count(binding_alias) and count(*), broader expression projections beyond narrow admitted id(...), type(...), lower(...), upper(...), trim(...), ltrim(...), rtrim(...), reverse(...), coalesce(...), replace(...), left(...), right(...), split(...), abs(...), sign(...), round(...), ceil(...), floor(...), sqrt(...), exp(...), sin(...), cos(...), tan(...), toString(...), toInteger(...), toFloat(...), and toBoolean(...) outputs in the
final RETURN, broader ordinary-read expression projections beyond narrow admitted literal, parameter, size(...), lower(...), upper(...), trim(...), ltrim(...), rtrim(...), reverse(...), coalesce(...), replace(...), left(...), right(...), split(...), two-arg or three-arg substring(...), abs(...), sign(...), round(...), ceil(...), floor(...), sqrt(...), exp(...), sin(...), cos(...), tan(...), toString(...), toInteger(...), toFloat(...), toBoolean(...), simple predicate, id(...), and type(...) outputs, broader WITH final-RETURN expression projections beyond narrow admitted scalar literal/parameter, predicate, size(...), lower(...), upper(...), trim(...), ltrim(...), rtrim(...), reverse(...), coalesce(...), replace(...), left(...), right(...), split(...), two-arg or three-arg substring(...), abs(...), sign(...), round(...), ceil(...), floor(...), sqrt(...), exp(...), sin(...), cos(...), tan(...), toString(...), toInteger(...), toFloat(...), toBoolean(...), id(...), and type(...) outputs, or
multi-stage WITH ... WITH ... flows.
Mixed read-write subset¶
CypherGlot currently admits:
MATCH ... SETMATCH ... DELETE- narrow
MATCH ... CREATE - narrow
MATCH ... MERGE
The admitted MATCH ... CREATE shapes are:
- one matched node pattern before
CREATE - or two disconnected matched node patterns before
CREATE - or one matched directed relationship pattern / fixed-length directed chain
before
CREATE, when theCREATErelationship endpoints reuse already matched node aliases exactly, or reuse one matched node alias plus one fresh labeled endpoint node - no named paths, no broader variable-length relationships beyond the bounded read-side subset, and no multi-hop traversals in the matched portion
The admitted MATCH ... MERGE shape is:
- exactly two disconnected matched node patterns before
MERGE - or one matched directed relationship pattern / fixed-length directed chain
before
MERGE, when theMERGErelationship endpoints reuse already matched node aliases exactly, or reuse one matched node alias plus one fresh labeled endpoint node - one directed relationship pattern in the
MERGEclause that reuses those two matched aliases exactly - no
ON CREATE/ON MATCHactions, no fresh endpoint nodes outside the narrow one-fresh-endpoint traversal-backed subset, no named paths, no broader variable-length relationships, and no multi-hop traversals in the matched portion
Bounded variable-length read subset¶
CypherGlot now admits a narrow bounded variable-length read form for ordinary
MATCH ... RETURN and MATCH ... WITH ... RETURN:
- one directed relationship pattern such as
-[:KNOWS*1..2]->or-[:KNOWS*..2]-> - non-negative numeric bounds with a finite upper bound
- endpoint node aliases and endpoint node predicates/projections over the matched endpoints
- lowering to a finite union of fixed-hop plans under the hood
This bounded subset still excludes:
- open-ended ranges such as
[:KNOWS*]or[:KNOWS*2..] - relationship aliases on variable-length patterns
- relationship properties on variable-length patterns
- broader aggregate forms beyond direct bounded variable-length returns built
from endpoint field projections plus
count(*),count(endpoint_alias), andaggregate(endpoint.field) - grouped or non-count aggregate
MATCH ... RETURNdirectly over a variable-length pattern; useMATCH ... WITH ... RETURNinstead when broader aggregation is needed - broader write-side traversal semantics
Traversal-backed write subset¶
CypherGlot now admits a narrow traversal-backed write form for MATCH ... CREATE
and MATCH ... MERGE:
- the matched side may be one directed relationship pattern or one fixed-length directed relationship chain
- the write-side relationship must either reuse already matched node aliases
exactly or, for narrow
MATCH ... CREATE/MATCH ... MERGE, reuse one matched node alias plus one fresh labeled endpoint node - no
ON CREATE/ON MATCHactions
Write subset¶
CypherGlot currently admits narrow CREATE and MERGE statements used by the
compiler and rendering contract.
Some admitted CREATE forms lower to a single SQLGlot expression. Others, plus
the admitted standalone MERGE forms, lower to a small compiled program with
multiple SQLGlot-backed statements.
The admitted standalone MERGE shapes are:
- one labeled node pattern, matched-or-created idempotently
- or one directed relationship pattern whose endpoint node patterns are both labeled, matched-or-created idempotently as one guarded pattern
- no
ON CREATE/ON MATCHactions and no broader full-patternMERGEsemantics beyond that narrow subset
Deferred clause families¶
CypherGlot currently rejects these families explicitly:
- broader
OPTIONAL MATCHsemantics beyond the narrow admitted subset - named path patterns such as
MATCH p = (...) - broader variable-length relationships such as
[:KNOWS*],[:KNOWS*2..], aliased variable-length relationships, and variable-length relationships with relationship property constraints - multi-hop pattern chains outside the admitted fixed-length directed read and
MATCH ... WITH ... RETURNsubset - broader traversal-backed write shapes beyond reusing already matched node
aliases in narrow
MATCH ... CREATEandMATCH ... MERGE, plus the narrow one-fresh-endpointMATCH ... CREATEsubset - disconnected multi-pattern
MATCHclauses outside the narrowMATCH ... CREATEsubset - broader
WITHsemantics beyond the narrow admitted subset - broader
UNWINDsemantics beyond the narrow admitted subset - broader
MERGEsemantics beyond the narrow admitted subset - broader multi-part queries
Narrow vector-aware subset¶
CypherGlot now admits one narrow vector-aware read shape:
CALL db.index.vector.queryNodes('index_name', integer_top_k, $query) YIELD node, score RETURN node.id, score- the same procedure call followed by one admitted
MATCH ...candidate-filter clause beforeRETURN - or the same procedure call with admitted
YIELD node, score WHERE ...filtering beforeRETURN
That vector-aware shape is normalized into structured metadata plus an admitted
Cypher candidate query. The normalized handoff carries the vector index name,
query-parameter name, normalized top_k, one admitted normalized candidate
query, explicit return_items, and order_by items. CypherGlot does
not compile that procedure call into ordinary SQLGlot output yet. Host runtimes
such as HumemDB are still responsible for vector planning and execution.
Why the boundary is strict¶
CypherGlot uses SQLGlot as the structural SQL backend, but it still owns the Cypher-side language boundary. Keeping the unsupported families rejected in validation makes the contract explicit and keeps later normalization and compilation stages honest.