Skip to content

CALL ... YIELD may null out variables carried in from WITH #3996

@Silence6666668

Description

@Silence6666668

ArcadeDB version
Observed on Docker images:

  • arcadedata/arcadedb:26.3.2
  • arcadedata/arcadedb:26.4.1-SNAPSHOT
  • arcadedata/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: opencypher
    • serializer: 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 relationshipType
  • CALL 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.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions