Skip to content

A unit CALL subquery that performs UNWIND and write operations may incorrectly multiply outer rows by the inner UNWIND cardinality. #3944

@Silence6666668

Description

@Silence6666668

ArcadeDB version

Observed on Docker images:

  • arcadedata/arcadedb:latest
  • arcadedata/arcadedb:26.4.1-SNAPSHOT

Environment

  • Docker on Windows host
  • ArcadeDB queried through the HTTP API: /api/v1/command/arcade
  • Requests sent in the same shape used by ArcadeDB Studio:
    • language: opencypher
    • serializer: studio

Describe the bug

A unit CALL subquery that performs UNWIND and write operations may incorrectly multiply outer rows by the inner UNWIND cardinality.

In Cypher, a unit subquery is a CALL subquery with no RETURN. Its internal writes should not change the outer row count.

In the repro below, the outer query has one row per Person, so the final result should have exactly three rows.
Neo4j returns one row for each person.
ArcadeDB returns each person twice, matching the inner UNWIND range(1, 2) cardinality.

To Reproduce

Setup

CREATE (:Person {name:'Alice'}),
       (:Person {name:'Bob'}),
       (:Person {name:'Charlie'});

Query

MATCH (p:Person)
CALL (p) {
  UNWIND range(1, 2) AS i
  CREATE (:Clone {name: p.name, id: i})
}
RETURN p.name AS person
ORDER BY person;

Expected behavior

Because the subquery is a unit subquery, it should preserve the outer row count:

Alice
Bob
Charlie

Actual behavior

ArcadeDB returns each outer row twice:

Alice
Alice
Bob
Bob
Charlie
Charlie

The outer row count is multiplied by the inner UNWIND cardinality.

Control cases

Control 1, without UNWIND, ArcadeDB behaves correctly:

MATCH (p:Person)
CALL (p) {
  CREATE (:Clone {name: p.name, id: 1})
}
RETURN p.name AS person, count(*) AS rowCount
ORDER BY person;

Observed result on both Neo4j and ArcadeDB:

Alice, 1
Bob, 1
Charlie, 1

Control 2, if the subquery explicitly returns the unwound rows, both engines intentionally multiply the outer rows:

MATCH (p:Person)
CALL (p) {
  UNWIND range(1, 2) AS i
  RETURN i
}
RETURN p.name AS person, count(*) AS rowCount
ORDER BY person;

Observed result on both Neo4j and ArcadeDB:

Alice, 2
Bob, 2
Charlie, 2

This suggests the issue is specifically tied to unit subqueries leaking internal UNWIND cardinality, not to UNWIND in general.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions