Skip to content

Collected relationship list may drop all rows after a later variable-length match #3997

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 drop all rows when a relationship variable is first aggregated into a list with collect(...), and a later MATCH in the same query uses a variable-length relationship pattern from the same anchor node.

The failure is specific to collecting the relationship objects themselves.
Equivalent scalar aggregates such as count(r), collect(type(r)), and collect(r.since) behave normally.

To Reproduce

Setup:

CREATE (a:Person {name:'Alice', age:30}),
       (b:Person {name:'Bob', age:25}),
       (c:Person {name:'Charlie', age:35}),
       (a)-[:KNOWS {since:2020}]->(b),
       (b)-[:KNOWS {since:2019}]->(c);

Query:

MATCH (a:Person {name:'Alice'})-[r:KNOWS]->(b:Person)
WITH a, collect(r) AS rels
MATCH path = (a)-[:KNOWS*1..2]->(c:Person)
RETURN length(path) AS len, size(rels) AS relationCount
ORDER BY len;

Expected behavior
Neo4j returns:

len = 1, relationCount = 1
len = 2, relationCount = 1

ArcadeDB should return the same two rows.

Actual behavior
ArcadeDB returns:

0 rows

Control cases

If the earlier relationship binding is aggregated with count(r) instead of collect(r), ArcadeDB behaves correctly:

MATCH (a:Person {name:'Alice'})-[r:KNOWS]->(b:Person)
WITH a, count(r) AS rc
MATCH path = (a)-[:KNOWS*1..2]->(c:Person)
RETURN length(path) AS len, rc
ORDER BY len;

Observed result on both Neo4j and ArcadeDB:

len = 1, rc = 1
len = 2, rc = 1

If the earlier aggregation collects scalar values derived from the relationship rather than the relationship objects themselves, ArcadeDB also behaves correctly:

MATCH (a:Person {name:'Alice'})-[r:KNOWS]->(b:Person)
WITH a, collect(type(r)) AS relTypes
MATCH path = (a)-[:KNOWS*1..2]->(c:Person)
RETURN length(path) AS len, relTypes
ORDER BY len;

Observed result on both Neo4j and ArcadeDB:

len = 1, relTypes = ['KNOWS']
len = 2, relTypes = ['KNOWS']

This also works with:

collect(r.since)

So the problem appears to be tied specifically to carrying a collected list of relationship objects.

If the later match is fixed-length instead of variable-length, ArcadeDB behaves correctly again:

MATCH (a:Person {name:'Alice'})-[r:KNOWS]->(b:Person)
WITH a, collect(r) AS rels
MATCH path = (a)-[:KNOWS]->(c:Person)
RETURN length(path) AS len, size(rels) AS relationCount
ORDER BY len;

Observed result on both Neo4j and ArcadeDB:

len = 1, relationCount = 1

So the boundary is:

  • collect(r) or collect(DISTINCT r) is carried forward
  • a later MATCH uses a variable-length relationship pattern
  • ArcadeDB drops all rows

while:

  • count(r) works
  • collect(type(r)) works
  • collect(r.since) works
  • a fixed-length later match works

Stronger variant
The problem also appears when the earlier relationship comes from OPTIONAL MATCH:

MATCH (a:Person {name:'Alice'})
OPTIONAL MATCH (a)-[r:KNOWS]->(b:Person)
WITH a, collect(DISTINCT r) AS rels
MATCH path = (a)-[:KNOWS*1..2]->(c:Person)
RETURN length(path) AS len, size(rels) AS relationCount
ORDER BY len;

Observed Neo4j result:

len = 1, relationCount = 1
len = 2, relationCount = 1

Observed ArcadeDB result:

0 rows

So OPTIONAL MATCH is not required for the failure, but it does not avoid it either.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions