diff --git a/src/cypher/execution_plan/ops/op_produce_results.h b/src/cypher/execution_plan/ops/op_produce_results.h index 30415146a4..ab413fe81c 100644 --- a/src/cypher/execution_plan/ops/op_produce_results.h +++ b/src/cypher/execution_plan/ops/op_produce_results.h @@ -106,8 +106,14 @@ static void RRecordToURecord( if (header_type == lgraph_api::LGraphType::RELATIONSHIP || header_type == lgraph_api::LGraphType::ANY) { auto uit = v.relationship->ItRef(); - auto uid = uit->GetUid(); - record.Insert(header[index].first, uid, txn); + if (uit->IsValid()) { + auto uid = uit->GetUid(); + record.Insert(header[index].first, uid, txn); + } else { + lgraph::EdgeUid euid; + euid.eid = -1; + record.InsertEdgeByID(header[index].first, euid); + } continue; } else { throw lgraph::CypherException( diff --git a/src/lgraph_api/lgraph_result.cpp b/src/lgraph_api/lgraph_result.cpp index b1ec4d8b8d..015fa4a9e5 100644 --- a/src/lgraph_api/lgraph_result.cpp +++ b/src/lgraph_api/lgraph_result.cpp @@ -186,6 +186,9 @@ void Record::Insert(const std::string &key, const lgraph_api::OutEdgeIterator &o void Record::Insert(const std::string &key, const int64_t vid, lgraph_api::Transaction *txn) { auto core_txn = txn->GetTxn().get(); auto vit = core_txn->GetVertexIterator(vid); + if (!vit.IsValid()) { + THROW_CODE(InternalError, "invalid vid {} for creating record", vid); + } lgraph_result::Node node; node.id = vid; node.label = core_txn->GetVertexLabel(vit); @@ -206,6 +209,9 @@ void Record::InsertVertexByID(const std::string &key, int64_t node_id) { void Record::Insert(const std::string &key, EdgeUid &uid, lgraph_api::Transaction *txn) { auto core_txn = txn->GetTxn().get(); auto eit = core_txn->GetOutEdgeIterator(uid, false); + if (!eit.IsValid()) { + THROW_CODE(InternalError, "invalid euid {} for creating record", uid.ToString()); + } lgraph_result::Relationship repl; repl.id = uid.eid; repl.src = uid.src; diff --git a/src/lgraph_api/result_element.cpp b/src/lgraph_api/result_element.cpp index 6abc2ab46e..4747576b48 100644 --- a/src/lgraph_api/result_element.cpp +++ b/src/lgraph_api/result_element.cpp @@ -52,6 +52,9 @@ bolt::Node Node::ToBolt() { } nlohmann::json Relationship::ToJson() { + if (id == -1) { + return json("__null__");; + } json result; std::map j_properties; result["identity"] = id; @@ -417,9 +420,17 @@ std::any ResultElement::ToBolt(int64_t* v_eid) { } return ret;*/ } else if (type_ == LGraphType::NODE) { - return v.node->ToBolt(); + if (v.node->id == -1) { + return {}; + } else { + return v.node->ToBolt(); + } } else if (type_ == LGraphType::RELATIONSHIP) { - return v.repl->ToBolt(v_eid); + if (v.repl->id == -1) { + return {}; + } else { + return v.repl->ToBolt(v_eid); + } } else if (type_ == LGraphType::PATH) { bolt::InternalPath path; for (size_t i = 0; i < v.path->size(); i++) { diff --git a/test/resource/cases/suite/cypher/base.result b/test/resource/cases/suite/cypher/base.result index 07a5c9c53a..4bad2e5bdc 100644 --- a/test/resource/cases/suite/cypher/base.result +++ b/test/resource/cases/suite/cypher/base.result @@ -7,3 +7,5 @@ with '123dfd\\fd45a\'bcd' as a return a; [{"a":"123dfd\\fd45a'bcd"}] with "123dfd\\fd\"45a'bcd" as a return a; [{"a":"123dfd\\fd\"45a'bcd"}] +optional MATCH (n:City {name:'London'})-[r]->(m) RETURN n.name,r,m; +[{"m":"__null__","n.name":null,"r":"__null__"}] diff --git a/test/resource/cases/suite/cypher/base.test b/test/resource/cases/suite/cypher/base.test index d764af3c77..986cf47455 100644 --- a/test/resource/cases/suite/cypher/base.test +++ b/test/resource/cases/suite/cypher/base.test @@ -3,4 +3,5 @@ RETURN s,r,r.weight,d ORDER BY r.weight LIMIT 2; with '123dfd\\fd45a\'bcd' as a return a; -with "123dfd\\fd\"45a'bcd" as a return a; \ No newline at end of file +with "123dfd\\fd\"45a'bcd" as a return a; +optional MATCH (n:City {name:'London'})-[r]->(m) RETURN n.name,r,m; \ No newline at end of file