Saltearse al contenido

Subset soportado

La capa de consulta de NamiDB implementa un subset estricto de Cypher 25 / openCypher 9 / GQL ISO/IEC 39075:2024, alcanzado para que las consultas LDBC SNB Interactive Complex Read IC01–IC14 parseen, planifiquen y se ejecuten de extremo a extremo. El subset es deliberadamente menor que el de Neo4j Community 5.x o Kùzu; el compromiso es “lo que el parser acepta corre o devuelve un error tipado — nunca un warning silencioso que cambia la semántica.”

Ante la duda, una feature no soportada produce un error explícito UnsupportedFeature que apunta a la RFC donde aterrizará.

Referencia del estándar

  • Estándar base: GQL ISO/IEC 39075:2024 más openCypher 9.
  • Cypher 25 (Neo4j) se usa como referencia de naming pero no se implementa nada exclusivo de Neo4j (ni db.* functions, ni APOC).
  • Cuando GQL y openCypher entran en conflicto, gana GQL.

Consulta RFC-004 para el documento completo de scope.

Cláusulas

CláusulaSoportadaNotas
MATCHPatrones fijos y de longitud variable.
OPTIONAL MATCHSemántica de left-outer-join.
WHEREPredicados arbitrarios sobre el scope visible.
RETURNLista de proyección con alias AS. DISTINCT soportado.
RETURN *Todos los alias bindeados.
WITHPipe que reabre el scope. Soporta WHERE interior y AS.
WITH *Todos los alias bindeados (pass-through del pipeline).
ORDER BYMúltiples claves ASC / DESC.
SKIP / LIMITLiterales o $param; sin expresiones.
UNWINDLista → filas.
CREATENodos y aristas con properties literales o $param.
MERGECon ON CREATE SET / ON MATCH SET. Una sola pattern part por MERGE (sin multi-label).
SETAsignación de property, reemplazo (=), merge (+=), agregar label.
DELETE / DETACH DELETEUn binding por delete. DELETE sin DETACH falla si el nodo tiene edges.
REMOVEQuitar property, quitar label.
UNION / UNION ALLMisma arity y mismos alias en ambos lados.
shortestPath(...)Forma envuelta MATCH p = shortestPath((a)-[*..N]-(b)). Path binding obligatorio, single hop, upper bound finito.
allShortestPaths(...)Mismo shape que shortestPath; emite cada path distinto de longitud mínima.

Patrones

ElementoSoportadoNotas
(a:Label {prop: val})Multi-label (a:A:B). Filtro inline de map de properties.
-[r:TYPE]->Direcciones -->, <--, --.
Alternación de tipo de relación -[r:A|B|C]->Unión sobre los tipos listados (RFC-024).
Variable-length -[r:KNOWS*1..3]->Bounds finitos obligatorios. *..M es atajo para *1..M.
Cadena de patrones (a)-[]-(b)-[]-(c)
Patrón multi-parte MATCH (a), (b)
Variable anónima (), []

Expresiones

CategoríaSoportado
Literales: int, float, string, bool, null, list [1,2,3], map {k: v}
Parámetros $name
Referencia a variable a, acceso a property a.prop
Aritmética + - * / % ^
String + (concat), =~ (regex)
Booleanos AND OR NOT XOR
Comparación = <> < > <= >=
IS NULL / IS NOT NULL
IN (membership en lista)
STARTS WITH, ENDS WITH, CONTAINS
CASE WHEN … THEN … ELSE END (simple y multi-branch)
List comprehension [x IN list WHERE pred | expr]
Pattern comprehension [(a)-[]->(b) | b.name]
Pattern predicate WHERE (a)-[]->(b) / EXISTS { ... }

Tipos

INTEGER (64-bit signed), FLOAT (64-bit), STRING, BOOLEAN, NULL, LIST<T> (heterogénea permitida, typecheck en runtime), MAP<STRING, T>, NODE, RELATIONSHIP, PATH, DATE, DATETIME (UTC, microsegundos), DURATION, VECTOR(Vec<f32>).

Fuera de scope en v0: BYTES, POINT, LOCALDATETIME, ZONEDDATETIME, LOCALTIME, TIME.

Semántica de NULL

Lógica de tres valores:

  • NULL = NULLNULL (no true).
  • NULL AND falsefalse; NULL AND trueNULL.
  • WHERE rechaza filas cuyo predicado evalúa a NULL (tratado como false).
  • IS NULL / IS NOT NULL son las únicas formas que testean NULL.

Cobertura LDBC SNB Interactive Complex

Consultav0
IC1 — Friends by name (transitive)
IC2 — Recent messages by friends
IC3 — Friends in two countries
IC4 — New topics on friend posts
IC5 — New groups (membership count)
IC6 — Tag co-occurrence
IC7 — Recent likers
IC8 — Recent replies
IC9 — Recent messages by friends-of-friends
IC10 — Friend recommendation
IC11 — Job referral
IC12 — Expert search by tag class
IC13 — Single shortest pathsí (RFC-023)
IC14 — All shortest paths weightedsí (RFC-023)

Las 14 consultas IC parsean, bajan a plan y se ejecutan end-to-end en el branch main actual.

Fuera de scope (v0)

Cualquier cosa que no esté listada arriba está explícitamente fuera de scope y produce un error de parse / lower tipado. Exclusiones destacadas:

FeaturePor qué afueraDónde aterriza
CALL { ... } (subqueries)El scoping de subqueries es sutil; no necesario para LDBC IC.RFC futura
CALL procedure.name(...)No hay procedure registry. APOC explícitamente excluido.RFC futura
FOREACHImperativo; raramente útil en práctica.RFC futura
USE databaseConsultas cross-database; un solo namespace por sesión.RFC para Cloud
LOAD CSVBulk-load pasa por WriterSession / merge_nodes.Nunca vía Cypher en v0.
CREATE INDEX / CREATE CONSTRAINTDDL la maneja la schema API, no Cypher.RFC futura
EXPLAIN / PROFILE (como prefijo Cypher)Disponible vía la CLI namidb explain.RFC futura
Transacciones explícitas (BEGIN/COMMIT/ROLLBACK en Cypher)Auto-commit por consulta en v0.Nunca vía Cypher en v0.
Variable-length sin upper bound (*1..)Blowup no acotado; rechazado explícitamente.Posible con WCOJ.
Patrones de longitud cero (*0..n)Semántica sobre auto-loops no finalizada.RFC futura
MATCH p = (a)-[*]->(b) RETURN p (path bindings var-len)Materialización de path diferida.RFC futura
Tipos POINT, TIME, ZONEDDATETIMENo necesarios para LDBC SNB Interactive.RFC futura
Namespaces db.* / apoc.*Vendor-specific Neo4j; no portables.Nunca

Read-your-own-writes

En v0, una consulta que escribe y luego lee no ve sus propias escrituras. Ejemplo:

CREATE (a:Person {name: 'Ada'})
MATCH (p:Person) RETURN p.name

El MATCH ve el snapshot fijado antes del CREATE. La nueva Ada aparece en la siguiente consulta. Workaround: ejecuta escrituras y lecturas en dos statements separados (o dos llamadas distintas a Client.cypher — las escrituras Cypher hacen auto-commit al final de cada statement).

Consulta RFC-009 para el razonamiento.

Siguientes pasos