Skip to content

exists() ignores relationship inline property filter {prop: value} — non-matching values still return true #5109

Description

@shulei5831sl

ArcadeDB version

Observed on local Docker image:

docker inspect arcadedb -> arcadedata/arcadedb:latest
docker exec arcadedb find /home/arcadedb/lib -name 'arcadedb-server-*.jar'
/home/arcadedb/lib/arcadedb-server-26.7.2-SNAPSHOT.jar

Endpoint:
http://127.0.0.1:2480/api/v1/command/test

If needed, I can also provide the startup banner / build hash from the server log. The JAR path only reports 26.7.2-SNAPSHOT.

Environment

  • Host OS: Linux

  • Deployment: Docker

  • Query interface: HTTP /api/v1/command/test

  • Query language: Cypher

  • Differential comparison target:

    • Neo4j Community 5.26.28

Description

ArcadeDB appears to ignore relationship inline property filters inside an exists() pattern.

For example:

WHERE exists((a)-[:R {w: 999}]->(:X))

returns true even when no outgoing :R relationship with w = 999 exists.

The equivalent MATCH form works correctly on this build:

MATCH (a)-[r:R {w: 999}]->(b)

This suggests the issue is not the parser or the general inline relationship-property syntax itself. The failure appears specific to the exists() pattern path.

exists() without a property filter also returns the correct boolean for plain relationship existence.

This looks related to #5093, but in a different query context.

To reproduce

Run from a clean database.

1. Clean database

MATCH (n) DETACH DELETE n;

2. Create test data

CREATE
  (a:X {name: 'Alice'}),
  (b:X {name: 'Bob'}),
  (d:X {name: 'Dave'}),
  (a)-[:R {w: 3}]->(b),
  (a)-[:R {w: 5}]->(d);

Alice has two outgoing :R relationships:

Alice -[:R {w: 3}]-> Bob
Alice -[:R {w: 5}]-> Dave

There is no outgoing :R relationship from Alice with w = 999.

3. Truth-table diagnostic

MATCH (a:X {name: 'Alice'})
RETURN
  exists((a)-[:R]->(:X))            AS any_R,
  exists((a)-[:R {w: 3}]->(:X))    AS has_w3,
  exists((a)-[:R {w: 5}]->(:X))    AS has_w5,
  exists((a)-[:R {w: 999}]->(:X))  AS has_w999;

4. Failing query

MATCH (a:X {name: 'Alice'})
WHERE exists((a)-[:R {w: 999}]->(:X))
RETURN a.name AS name;

Expected behavior

No relationship with w = 999 exists, so the exists() predicate should return false.

Expected truth table:

any_R    = true
has_w3   = true
has_w5   = true
has_w999 = false

Expected result for the failing query:

(empty)

Neo4j 5.26.28 returns this expected result.

Actual behavior

ArcadeDB truth table:

any_R    = true
has_w3   = true
has_w5   = true
has_w999 = true

has_w999 = true is wrong. It looks as if the {w: 999} filter is ignored and exists() only checks that some outgoing :R relationship exists.

The failing query returns:

Alice

Sanity checks

MATCH with non-matching inline relationship property filter

MATCH (a:X {name: 'Alice'})-[r:R {w: 999}]->(b:X)
RETURN b.name;

ArcadeDB result:

(empty)

The filter works in the regular MATCH context.

MATCH with explicit relationship property predicate

MATCH (a:X {name: 'Alice'})-[r:R]->(b:X)
WHERE r.w = 999
RETURN b.name;

ArcadeDB result:

(empty)

The explicit property predicate also works.

exists() without relationship property filter

MATCH (a:X {name: 'Alice'})
WHERE exists((a)-[:R]->(:X))
RETURN a.name;

ArcadeDB result:

Alice

This is expected because Alice does have outgoing :R relationships.

The truth-table query above is the strongest diagnostic: has_w999 = true when no w = 999 relationship exists directly shows that the inline property filter is not being enforced inside exists().

Cross-engine comparison

Truth-table query:

Engine any_R has_w3 has_w5 has_w999
Neo4j 5.26.28 true true true false
ArcadeDB 26.7.2-SNAPSHOT true true true true

Failing query:

Engine Result
Neo4j 5.26.28 (empty)
ArcadeDB 26.7.2-SNAPSHOT Alice

Summary

Form Syntax Expected ArcadeDB
exists() + non-matching relationship property exists((a)-[:R {w:999}]->(:X)) false true
exists() + no property filter exists((a)-[:R]->(:X)) true true
MATCH + non-matching inline property filter (a)-[r:R {w:999}]->(b) empty empty
MATCH + explicit property predicate (a)-[r:R]->(b) WHERE r.w = 999 empty empty

Hypothesis

The inline relationship property map may be parsed but not translated into an equality condition in the exists() pattern path.

The regular MATCH path appears to handle the same inline property filter correctly on this build, so the missing constraint seems specific to exists() pattern evaluation.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions