`id(n)` after rebinding the same variable across a `WITH` errors with `age_id(_ag_label_vertex) does not exist`
- Dominant language
- C
- Stars
- 4.8k
- Forks
- 523
- Avg merge
- 1d 2h
- Merged PRs (30d)
- 9
Description
## Bug description
Rebinding the same variable name in a new `MATCH` after a `WITH` clause that drops that variable, and then referencing `id(n)` in a `WHERE` clause, makes AGE 1.8.0 generate SQL that passes the raw `_ag_label_vertex` composite row — instead of an `agtype` — to the `age_id()` function, whose only overload is `age_id(agtype)`. The query fails with `ERROR: 42883: function ag_catalog.age_id(graph_test._ag_label_vertex) does not exist` instead of executing normally.
The error is raised at SQL-generation/parse time, so it fires even on an empty graph, and no data setup is required.
## Access method
- Command line via `psql`, inside the official Docker container `apache/age:1.8.0`
## Data setup
No data is required — the error reproduces on an empty graph. Only the graph itself must exist:
```pgsql
CREATE EXTENSION IF NOT EXISTS age;
LOAD 'age';
SET search_path = ag_catalog, "$user", public;
SELECT create_graph('graph_test');
```
## Configuration
- None beyond the stock AGE extension. No additional modules (no PostGIS, etc.), default `search_path` handling as shown above.
## Command that triggers the error
```pgsql
SELECT * FROM cypher('graph_test', $$ MATCH (n) WITH 1 AS v MATCH (n) WHERE id(n) = v RETURN 1 $$) AS (c0 agtype);
```
```
ERROR: function ag_catalog.age_id(graph_test._ag_label_vertex) does not exist
LINE 1: ...test', $$ MATCH (n) WITH 1 AS v MATCH (n) WHERE id(n) = v RE...
^
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
```
The trigger needs three ingredients, all present above:
1. `n` is bound by the first `MATCH (n)`;
2. `WITH 1 AS v` drops it (the `WITH` does not project `n`);
3. a second `MATCH (n)` rebinds the same name to an untyped vertex, and the following `WHERE id(n) = v` translates `id(n)` to `age_id(n)` where `n` is the whole `_ag_label_vertex` row — no matching overload exists.
Changing any one ingredient removes the error. All of the following variants run normally (return 0 rows or a row):
- Different variable names: `MATCH (x) WITH 1 AS v MATCH (y) WHERE id(y) = v RETURN 1`
- No `WITH` between the two `MATCH` clauses: `MATCH (n) MATCH (n) WHERE id(n) = 1 RETURN 1`
- `WITH` passes `n` through instead of dropping it: `MATCH (n) WITH n MATCH (n) WHERE id(n) = 1 RETURN 1`
- `id(n)` used in `RETURN` instead of `WHERE`: `MATCH (n) WITH 1 AS v MATCH (n) RETURN id(n)`
- No rebinding at all: `MATCH (n) WHERE id(n) = 1 RETURN 1`
## Expected behavior
Rebinding a variable in a new scope after a `WITH` is standard Cypher. The query is legal and should either execute normally (returning the rows matching `id(n) = v`) or raise a normal error — it must not fail with a function-signature error about the internal `_ag_label_vertex` row type.
## Environment
- Version: 1.8.0 (official `apache/age:1.8.0` Docker image)
- PostgreSQL: 18.1 (Debian 18.1-1.pgdg13+2), x86_64
Contributor guide
Research direction
Reproduce the query in the official apache/age:1.8.0 Docker container with psql on an empty graph. Trace SQL generation for a variable rebound after WITH and for id(n) in WHERE, then verify the query no longer raises the age_id(_ag_label_vertex) signature error and that the listed variants still run normally.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- postgresql
- Domain
- databases
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 68/100