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áusula | Soportada | Notas |
|---|---|---|
MATCH | sí | Patrones fijos y de longitud variable. |
OPTIONAL MATCH | sí | Semántica de left-outer-join. |
WHERE | sí | Predicados arbitrarios sobre el scope visible. |
RETURN | sí | Lista de proyección con alias AS. DISTINCT soportado. |
RETURN * | sí | Todos los alias bindeados. |
WITH | sí | Pipe que reabre el scope. Soporta WHERE interior y AS. |
WITH * | sí | Todos los alias bindeados (pass-through del pipeline). |
ORDER BY | sí | Múltiples claves ASC / DESC. |
SKIP / LIMIT | sí | Literales o $param; sin expresiones. |
UNWIND | sí | Lista → filas. |
CREATE | sí | Nodos y aristas con properties literales o $param. |
MERGE | sí | Con ON CREATE SET / ON MATCH SET. Una sola pattern part por MERGE (sin multi-label). |
SET | sí | Asignación de property, reemplazo (=), merge (+=), agregar label. |
DELETE / DETACH DELETE | sí | Un binding por delete. DELETE sin DETACH falla si el nodo tiene edges. |
REMOVE | sí | Quitar property, quitar label. |
UNION / UNION ALL | sí | Misma arity y mismos alias en ambos lados. |
shortestPath(...) | sí | Forma envuelta MATCH p = shortestPath((a)-[*..N]-(b)). Path binding obligatorio, single hop, upper bound finito. |
allShortestPaths(...) | sí | Mismo shape que shortestPath; emite cada path distinto de longitud mínima. |
Patrones
| Elemento | Soportado | Notas |
|---|---|---|
(a:Label {prop: val}) | sí | Multi-label (a:A:B). Filtro inline de map de properties. |
-[r:TYPE]-> | sí | Direcciones -->, <--, --. |
Alternación de tipo de relación -[r:A|B|C]-> | sí | Unión sobre los tipos listados (RFC-024). |
Variable-length -[r:KNOWS*1..3]-> | sí | Bounds finitos obligatorios. *..M es atajo para *1..M. |
Cadena de patrones (a)-[]-(b)-[]-(c) | sí | |
Patrón multi-parte MATCH (a), (b) | sí | |
Variable anónima (), [] | sí |
Expresiones
| Categoría | Soportado |
|---|---|
Literales: int, float, string, bool, null, list [1,2,3], map {k: v} | sí |
Parámetros $name | sí |
Referencia a variable a, acceso a property a.prop | sí |
Aritmética + - * / % ^ | sí |
String + (concat), =~ (regex) | sí |
Booleanos AND OR NOT XOR | sí |
Comparación = <> < > <= >= | sí |
IS NULL / IS NOT NULL | sí |
IN (membership en lista) | sí |
STARTS WITH, ENDS WITH, CONTAINS | sí |
CASE WHEN … THEN … ELSE END (simple y multi-branch) | sí |
List comprehension [x IN list WHERE pred | expr] | sí |
Pattern comprehension [(a)-[]->(b) | b.name] | sí |
Pattern predicate WHERE (a)-[]->(b) / EXISTS { ... } | sí |
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 = NULL→NULL(notrue).NULL AND false→false;NULL AND true→NULL.WHERErechaza filas cuyo predicado evalúa aNULL(tratado comofalse).IS NULL/IS NOT NULLson las únicas formas que testeanNULL.
Cobertura LDBC SNB Interactive Complex
| Consulta | v0 |
|---|---|
| IC1 — Friends by name (transitive) | sí |
| IC2 — Recent messages by friends | sí |
| IC3 — Friends in two countries | sí |
| IC4 — New topics on friend posts | sí |
| IC5 — New groups (membership count) | sí |
| IC6 — Tag co-occurrence | sí |
| IC7 — Recent likers | sí |
| IC8 — Recent replies | sí |
| IC9 — Recent messages by friends-of-friends | sí |
| IC10 — Friend recommendation | sí |
| IC11 — Job referral | sí |
| IC12 — Expert search by tag class | sí |
| IC13 — Single shortest path | sí (RFC-023) |
| IC14 — All shortest paths weighted | sí (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:
| Feature | Por qué afuera | Dó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 |
FOREACH | Imperativo; raramente útil en práctica. | RFC futura |
USE database | Consultas cross-database; un solo namespace por sesión. | RFC para Cloud |
LOAD CSV | Bulk-load pasa por WriterSession / merge_nodes. | Nunca vía Cypher en v0. |
CREATE INDEX / CREATE CONSTRAINT | DDL 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, ZONEDDATETIME | No 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.nameEl 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
- Leer datos — cláusulas de lectura con ejemplos.
- Escribir datos — cláusulas de escritura y el modelo de auto-commit.
- Operadores y funciones — catálogo completo de operadores y funciones integradas.