Skip to content

Commit b42ae87

Browse files
committed
Add MemGQL v0.13.0 release docs
1 parent 86841b5 commit b42ae87

2 files changed

Lines changed: 82 additions & 14 deletions

File tree

‎pages/memgraph-zero/memgql/changelog.mdx‎

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,38 @@ description: MemGQL release notes
55

66
# MemGQL Changelog
77

8+
## MemGQL v0.13.0 - unreleased
9+
10+
### 🍃 New features & Improvements
11+
12+
- **Multi-label vertex mappings.** A vertex may declare
13+
`"labels": ["Cat", "Animal"]` instead of a single `label`. The first label
14+
identifies the mapping; the others may be shared with other mappings. A
15+
pattern on a shared label (`MATCH (a:Animal)`) reads every table that
16+
carries it as one `UNION` inside the connector, resolving shared property
17+
names through each table's own columns and returning `null` for a property
18+
only some of them declare. Returned nodes carry all of their labels. See
19+
[Vertices](/memgraph-zero/memgql/schema-file#vertices).
20+
- **Join edges within one connector.** `mappedJoinSource` now also links two
21+
tables in the same relational connector — the case where a row carries the
22+
target's *business key* rather than a foreign key into its `metaFields.id`,
23+
which a table-backed edge cannot express. The traversal is pushed down as a
24+
single `JOIN`, so aggregates across it work and no federated join is
25+
involved. See
26+
[Cross-connector edges](/memgraph-zero/memgql/schema-file#cross-connector-edges).
27+
28+
### ⚠️ Behavior changes
29+
30+
- **A label the mapping does not declare now matches nothing.**
31+
`MATCH (p:Person:Vip)` on a `Person` table that does not carry `Vip` returns
32+
no rows. Previously the second label was ignored and every `Person` came
33+
back.
34+
35+
### 🐞 Bug fixes
36+
37+
- `SHOW STATS CONNECTORS` missed queries that routed by label to a single
38+
connector; only federated and `USE`-qualified queries were counted.
39+
840
## MemGQL v0.12.0 - September 14th, 2026
941

1042
### ⚠️ Breaking changes

‎pages/memgraph-zero/memgql/schema-file.mdx‎

Lines changed: 50 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -245,8 +245,39 @@ A vertex maps a **label** to a backend source. Exactly one source kind is set:
245245
}
246246
```
247247

248+
A table whose rows should carry **more than one label** lists them under
249+
`labels` instead of `label`. The first label identifies the mapping and must be
250+
unique in the graph; the others may be shared with other mappings:
251+
252+
```json
253+
{
254+
"labels": ["Cat", "Animal"],
255+
"mappedTableSource": {
256+
"connector": "pg",
257+
"table": "cats",
258+
"metaFields": { "id": "cat_id" }
259+
},
260+
"attributes": [
261+
{ "name": "id", "column": "cat_id" },
262+
{ "name": "name" }
263+
]
264+
}
265+
```
266+
267+
With a second mapping `["Dog", "Animal"]` over a `dogs` table keyed by
268+
`dog_id`, `MATCH (a:Cat)` reads one table, `MATCH (a:Dog:Animal)` the other,
269+
and `MATCH (a:Animal)` both — as one `UNION` statement inside the connector.
270+
Shared property names resolve through each table's own columns, a property
271+
only one table declares is `null` on the other's rows, and returned nodes
272+
carry all of their labels (`(:Cat:Animal)`). Attributes that two carriers of a shared
273+
label both declare must have the same `type`. A traversal or an `INSERT` has to
274+
start from one table, so on a shared label both are refused with a pointer to
275+
the identifying label. A label no mapping carries together with the others
276+
matches nothing.
277+
248278
| Field | Source kind | Description |
249279
|-------|-------------|-------------|
280+
| `label` / `labels` | both | The node label, or a list of labels whose first entry identifies the mapping (unique per graph) and whose others may be shared with other mappings. |
250281
| `mappedTableSource.connector` | relational | Connector name (alias `catalog`). |
251282
| `mappedTableSource.schema` | relational | Optional middle namespace (PostgreSQL schema, etc.). |
252283
| `mappedTableSource.database` | relational | Optional outer namespace for backends with three-part names; on SQL Server it renders `database.schema.table`, so one connection can reach views in other databases. |
@@ -318,9 +349,11 @@ labels; the traversal is resolved by the backend.
318349

319350
#### Cross-connector edges
320351

321-
A third source kind, `mappedJoinSource`, declares an edge whose two endpoints
322-
live in **different connectors**. It has no backing table anywhere: the
323-
relationship *is* equality between one property on each endpoint.
352+
A third source kind, `mappedJoinSource`, declares an edge with **no backing
353+
table anywhere**: the relationship *is* equality between one property on each
354+
endpoint. It is how a traversal crosses into a **different connector**, and
355+
also how two tables in the **same** connector are linked by a business key
356+
rather than by a foreign key into the target's `metaFields.id`.
324357

325358
```json
326359
{
@@ -361,19 +394,22 @@ don't collide.
361394
**Rules and limits** (each is refused with a message saying what to write
362395
instead):
363396

364-
- Both endpoints must live in different connectors — within one connector use
365-
`mappedTableSource` with `metaFields.from` / `to`.
366-
- Each key must be a declared `attribute` of its endpoint vertex (native-graph
367-
vertices are exempt, since the query passes through).
368-
- The edge must be traversed **in a direction**: `-[:R]->` or `<-[:R]-`, not
369-
`-[:R]-`.
370-
- No variable-length traversal, no `OPTIONAL MATCH`, and one `MATCH` with one
371-
path pattern per query.
397+
- Each key must be a declared `attribute` of its endpoint vertex, backed by a
398+
plain scalar column (native-graph vertices are exempt, since the query passes
399+
through). The edge declares no `attributes`.
372400
- The edge carries no properties, so it cannot be filtered — filter the
373401
endpoints instead.
374-
- Every node in the pattern needs a label, so each side can be routed.
375-
- Aggregating *across* the join (for example `count()` over both sides) is not
376-
supported yet; return the rows and count client-side.
402+
- Across connectors: the edge must be traversed **in a direction** (`-[:R]->`
403+
or `<-[:R]-`, not `-[:R]-`); no variable-length traversal, no
404+
`OPTIONAL MATCH`, one `MATCH` with one path pattern per query; every node in
405+
the pattern needs a label, so each side can be routed; aggregating *across*
406+
the join (`count()` over both sides) is not supported yet.
407+
- Within one relational connector the edge is pushed down as a single `JOIN`
408+
on the two key columns, so those limits do not apply: aggregates work, and an
409+
undirected step is accepted when the two endpoint labels differ. A
410+
variable-length step over it is refused. Both endpoints on a Memgraph or
411+
Neo4j connector are refused — that backend stores its own relationships, so
412+
declare `mappedGraphSource`.
377413

378414
A **table-backed** edge whose endpoints sit in different connectors is still
379415
skipped at load time with a warning pointing at `mappedJoinSource`.

0 commit comments

Comments
 (0)