Repository navigation
CALL ... YIELD may null out variables carried in from WITH #3996
Description
ArcadeDB version
Observed on Docker images:
arcadedata/arcadedb:26.3.2arcadedata/arcadedb:26.4.1-SNAPSHOTarcadedata/arcadedb:26.4.2
Environment
- Host OS: Windows 10
- Architecture: x86_64
- Deployment: Docker
- ArcadeDB endpoint: HTTP
/api/v1/command/arcade - Request mode matches ArcadeDB Studio:
language: opencypherserializer: studio
- Differential comparison target: Neo4j Docker
neo4j:latest
Describe the bug
ArcadeDB may null out variables that were already bound by a preceding WITH once the query executes a procedure call with CALL ... YIELD ....
In the minimized repro below, Neo4j preserves the carried value x = 1 across every row yielded by db.labels().
ArcadeDB still yields labels, but x becomes null on every row.
The same issue also reproduces with aggregated values carried through WITH, so this does not appear to be limited to literals.
I also reproduced the same carried-variable loss with:
CALL db.relationshipTypes() YIELD relationshipTypeCALL db.propertyKeys() YIELD propertyKey
So this does not currently look specific to db.labels().
It looks more like a general problem preserving outer WITH bindings across procedure calls.
The exact rows returned by these procedures differ between engines, but that is not the bug here.
The bug is that the carried variables are lost.
To Reproduce
Setup:
CREATE (:Person {name:'Alice'});Query:
WITH 1 AS x
CALL db.labels() YIELD label
RETURN x, label
LIMIT 3;Expected behavior
The carried variable should remain bound:
1, <label>
1, <label>
1, <label>
Observed Neo4j result:
1, Person
1, Team
1, Product
The specific label values are not important here.
What matters is that x stays 1 on every row.
Actual behavior
ArcadeDB returns rows from db.labels(), but the carried variable is lost:
Latest observed result:
null, Meta
null, EmptyNode
null, Stop
Observed 26.3.2 result:
null, Company
null, User
null, Manager
So CALL ... YIELD ... appears to wipe out the variables that came from the outer WITH.
Control cases
The carried value is fine if the procedure call is removed:
WITH 1 AS x
RETURN x;Observed result on Neo4j and ArcadeDB:
1
The procedure itself also works when returned on its own:
CALL db.labels() YIELD label
RETURN label
LIMIT 3;Observed result on both engines:
- rows are returned successfully
So the problem is not that db.labels() is missing or failing.
The problem is specifically that variables carried into the procedure call come back as null.
The same loss also affects aggregated values:
MATCH (:Person)
WITH count(*) AS c
CALL db.labels() YIELD label
RETURN c, label
LIMIT 3;Observed Neo4j result:
1, Person
1, Team
1, Product
Observed ArcadeDB result:
null, Meta
null, EmptyNode
null, Stop
This makes the boundary clearer: the issue is with preserving carried variables across CALL db.labels(), not with literals or aggregates on their own.
The same carried-variable loss also happens with other procedures.
For example:
WITH 1 AS x
CALL db.relationshipTypes() YIELD relationshipType
RETURN x, relationshipType
LIMIT 3;Neo4j keeps x = 1, while ArcadeDB returns x = null.
Likewise:
WITH 1 AS x
CALL db.propertyKeys() YIELD propertyKey
RETURN x, propertyKey
LIMIT 3;again preserves x on Neo4j but returns x = null on ArcadeDB.
That makes the family look broader than db.labels() specifically.
Activity
#3996 fix(cypher): CALL...YIELD preserves variables carried in from W…
ArcadeData#3996 fix(cypher): CALL...YIELD preserves variables carried…
chore(deps): bump org.postgresql:postgresql from 42.7.10 to 42.7.11 […
#3996 fix(cypher): CALL...YIELD preserves variables carried in from W…
ArcadeData#3996 fix(cypher): CALL...YIELD preserves variables carried…
ArcadeData#3996 fix(cypher): CALL...YIELD preserves variables carried…
chore(deps): bump org.postgresql:postgresql from 42.7.10 to 42.7.11 […
ArcadeData#3996 fix(cypher): CALL...YIELD preserves variables carried…
chore(deps): bump the github-actions group with 4 updates [skip ci]