List predicate (`ALL`/`any`/`none`/`single`) over node values in a `WHERE` clause raises internal error `no relation entry for relid` (XX000)
- Dominant language
- C
- Stars
- 4.8k
- Forks
- 523
- Avg merge
- 1d 2h
- Merged PRs (30d)
- 9
Description
## Bug description
Putting a list predicate — `ALL`, `any`, `none`, or `single` — over a list of node or relationship values inside a `WHERE` clause makes AGE 1.8.0 fail with the PostgreSQL internal error `ERROR: XX000: no relation entry for relid 2`. The failure is at query-planning time, needs no data, and reproduces on an empty graph.
```pgsql
MATCH p = (a)-->(b) WHERE ALL(x IN nodes(p) WHERE true) RETURN 1
```
The predicate function name is irrelevant (`ALL`/`any`/`none`/`single` all reproduce) and the filter body is already reduced to `WHERE true` — the trigger is the list predicate over a node/relationship-valued list in `WHERE`.
## 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 p = (a)-->(b) WHERE ALL(x IN nodes(p) WHERE true) RETURN 1 $$) AS (c0 agtype);
```
```
ERROR: no relation entry for relid 2
```
(SQLSTATE `XX000`, internal error.) The failure is data-independent: it occurs both on an empty graph and when the graph already contains nodes and edges. Replacing `ALL` with `any`, `none`, or `single` produces the identical error.
The bug is specific to `WHERE` — the same predicate runs cleanly (0 rows, no error) when the list is projected through `WITH`, placed in `RETURN`, or the list holds plain integers:
```pgsql
-- works: list projected through WITH, then filtered
SELECT * FROM cypher('graph_test', $$ MATCH p = (a)-->(b) WITH nodes(p) AS L WHERE ALL(x IN L WHERE true) RETURN 1 $$) AS (c0 agtype);
-- works: predicate in RETURN clause
SELECT * FROM cypher('graph_test', $$ MATCH p = (a)-->(b) RETURN ALL(x IN nodes(p) WHERE true) $$) AS (c0 agtype);
-- works: list of plain integers in WHERE
SELECT * FROM cypher('graph_test', $$ MATCH (a)-[r]->(b) WHERE ALL(x IN [1] WHERE true) RETURN 1 $$) AS (c0 agtype);
```
## Expected behavior
`MATCH p = (a)-->(b) WHERE ALL(x IN nodes(p) WHERE true)` is valid standard Cypher (it executes in Neo4j). AGE should either run it and return rows, or raise a normal user-facing Cypher error — it must not leak a PostgreSQL internal error (`XX000`) caused by referencing a relation that was never registered.
## 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
Start by reproducing the failure with psql in the apache/age:1.8.0 Docker container using the cypher('graph_test', ...) entry point and the empty-graph setup. Compare the failing WHERE predicate with the working WITH, RETURN, and integer-list cases; done means the node/relationship-valued predicate no longer raises the PostgreSQL XX000 relation-entry error.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- c, postgresql
- Domain
- databases
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100