Open meido opened 8 months ago
Summary: Incorrect query result for MATCH/OPTIONAL MATCH combination.
Based on the provided information, the issue seems to be related to the handling of OPTIONAL MATCH
in the query execution engine of Kùzu. The expected behavior is that the query should return all V
nodes in the hierarchy of v1
and any related R
nodes, with nulls for R
when there is no related node. However, Kùzu's result is missing the (:R {id: "r12"})
related to v12
.
To address this issue, the following steps should be taken:
OPTIONAL MATCH
clause.OPTIONAL MATCH
does not find a match, it correctly returns null for the optional pattern instead of omitting the row.childof*
in the query.MATCH
and OPTIONAL MATCH
clauses is correctly implemented, as it should not filter out rows when the OPTIONAL MATCH
does not find a related node.OPTIONAL MATCH
is used in combination with variable length relationships and ensure that the expected behavior matches that of Neo4j.The provided Java and C++ test code snippets are primarily related to value retrieval and property access, and do not directly address the OPTIONAL MATCH
issue. Focus on the parts of the codebase that deal with query parsing, execution, and result construction.
tools/java_api/src/test/java/com/kuzudb/test/ValueTest.java
The Java API tests for relationship values might be relevant to the issue as they deal with relationship retrieval and properties, which could be related to the MATCH/OPTIONAL MATCH combination issue.
The C API tests for relationship values could be relevant since they involve relationship retrieval and properties, which might be connected to the MATCH/OPTIONAL MATCH combination issue.
CREATE NODE TABLE V (id STRING, PRIMARY KEY(id)); CREATE NODE TABLE R (id STRING, PRIMARY KEY(id)); CREATE REL TABLE childof (FROM V TO V); CREATE REL TABLE relatedto (FROM R TO V);
CREATE (v1:V {id:"v1"}),(v11:V {id:"v11"}),(v12:V {id:"v12"}),(v111:V {id:"v111"}), (r1:R {id:"r1"}), (r12:R {id:"r12"}), (v111)-[:childof]->(v11),(v11)-[:childof]->(v1),(v12)-[:childof]->(v1), (r1)-[:relatedto]->(v1), (r12)-[:relatedto]->(v12); MATCH (v1:V {id: "v1"}) WITH v1 MATCH (v:V)-[e:childof*]->(v1) OPTIONAL MATCH (r)-[:relatedto]->(v) RETURN r, v; screenshot
What Kuzu returns:
| r | v |
| | {_ID: 0:3, _LABEL: V, id: v111} |
| | {_ID: 0:2, _LABEL: V, id: v12} |
| | {_ID: 0:1, _LABEL: V, id: v11} |
(3 tuples) (2 columns) What Neo4j returns (and what is expected here):
╒════════════════╤═════════════════╕ │r │v │ ╞════════════════╪═════════════════╡ │null │(:V {id: "v11"}) │ ├────────────────┼─────────────────┤ │null │(:V {id: "v111"})│ ├────────────────┼─────────────────┤ │(:R {id: "r12"})│(:V {id: "v12"}) │ └────────────────┴─────────────────┘ Why does Kuzu omit the existing optional match (:R {id: "r12"}) for v12 here?