After a multi-row path `CREATE`, `WITH * CREATE (...) DELETE ...` changes cardinality instead of preserving the incoming rows.
- Dominant language
- C
- Stars
- 4.8k
- Forks
- 523
- Avg merge
- 1d 2h
- Merged PRs (30d)
- 9
Description
**Environment**
Apache AGE `1.8.0` on PostgreSQL `18.6`, Docker image
`apache/age:release_PG18_1.8.0`.
**Setup**
Run this setup separately on two fresh graphs, one named
`age_issue_case20_left` and one named `age_issue_case20_right`:
```sql
LOAD 'age';
SET search_path = ag_catalog, public;
SELECT ag_catalog.create_graph('age_issue_case20_left');
SELECT *
FROM ag_catalog.cypher('age_issue_case20_left', $$
CREATE (a {id: 46}),
(b1 {k7: -1, k6: 2}),
(b2 {k7: -1, k6: 2}),
(c:l1 {k6: 3, klist: [4]}),
(n1:l0 {id: 10}),
(n0 {k4: [1]}),
(a)<-[:rt10 {k8: 2147483647}]-(b1),
(a)<-[:rt10 {k8: 2147483647}]-(b2),
(b1)<-[:R {k6: 3, klist: [4]}]-(c),
(b2)<-[:R {k6: 3, klist: [4]}]-(c),
(c)-[:X]->(n1)-[:Y]->(n0)
$$) AS (v agtype);
```
For the right graph, replace both graph-name occurrences above with
`age_issue_case20_right`.
**Baseline query** (run on the left graph)
```sql
SELECT *
FROM ag_catalog.cypher('age_issue_case20_left', $$
MATCH p = ({id: 46})<-[:rt10 {k8: 2147483647}]-({k7: -1, k6: 2})
<-[r1 {k6: 3, klist: [4]}]-(:l1)-[]->(n1:l0)
-[r0]->(n0 {k4: [1]})
WHERE size(n0.k4) >= 0
CREATE (n1)-[:rt5 {id: 421}]->(n0)-[:rt4 {id: 422}]->(:l1 {id: 128})
RETURN count(*) AS rows
$$) AS (rows agtype);
```
**Barrier query** (run on the right graph)
Use the same query, but insert the following clauses before the final return:
```cypher
WITH *
CREATE (__dinkel_n0)
DELETE __dinkel_n0
WITH n1, n0, r1, r0, p
```
**Expected**
Both queries preserve the two input rows and return `2`.
**Actual**
On Apache AGE `1.8.0` / PostgreSQL `18.6`, the baseline returns `2`, while
the barrier query returns `4`. The result rows include duplicated bindings;
the barrier also creates twice as many path-write entities. A read-only
`WITH *` control preserves the two rows. This is a real AGE cardinality
defect, not an outer-column-definition, JDBC, probe, or fingerprint issue.
Contributor guide
Research direction
Start by running the setup separately on the two fresh graphs, then compare the baseline and barrier queries through ag_catalog.cypher. The defect is fixed when both queries preserve two rows, the barrier produces no duplicate bindings or extra path-write entities, and the read-only WITH * control still preserves cardinality.
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
- 45/100