From e4c96cc3b95030b5a1a9820a2e0758e83f0f0a98 Mon Sep 17 00:00:00 2001 From: yaphet <darion.wang@vesoft.com> Date: Thu, 10 Oct 2019 15:31:53 +0800 Subject: [PATCH] Support uuid in delete and update sentence (#1031) --- src/executor/DeleteVertexExecutor.cpp | 18 +++-- src/executor/DeleteVertexExecutor.h | 6 +- src/executor/UpdateEdgeExecutor.cpp | 27 ++++--- src/executor/UpdateEdgeExecutor.h | 2 + src/executor/UpdateVertexExecutor.cpp | 15 +++- src/executor/UpdateVertexExecutor.h | 2 + src/executor/test/DeleteVertexTest.cpp | 56 ++++++++++++- src/executor/test/FetchEdgesTest.cpp | 6 +- src/executor/test/TraverseTestBase.h | 29 ++++++- src/executor/test/UpdateTest.cpp | 106 +++++++++++++++++++++++++ src/executor/test/UpdateTestBase.h | 55 +++++++++++++ 11 files changed, 291 insertions(+), 31 deletions(-) diff --git a/src/executor/DeleteVertexExecutor.cpp b/src/executor/DeleteVertexExecutor.cpp index 92e4552f..b9d21af6 100644 --- a/src/executor/DeleteVertexExecutor.cpp +++ b/src/executor/DeleteVertexExecutor.cpp @@ -16,7 +16,14 @@ DeleteVertexExecutor::DeleteVertexExecutor(Sentence *sentence, } Status DeleteVertexExecutor::prepare() { - auto ovalue = sentence_->vid()->eval(); + spaceId_ = ectx()->rctx()->session()->space(); + expCtx_ = std::make_unique<ExpressionContext>(); + expCtx_->setSpace(spaceId_); + expCtx_->setStorageClient(ectx()->getStorageClient()); + + auto vid = sentence_->vid(); + vid->setContext(expCtx_.get()); + auto ovalue = vid->eval(); auto v = ovalue.value(); if (!Expression::isInt(v)) { return Status::Error("Vertex ID should be of type integer"); @@ -26,9 +33,8 @@ Status DeleteVertexExecutor::prepare() { } void DeleteVertexExecutor::execute() { - GraphSpaceID space = ectx()->rctx()->session()->space(); // TODO(zlcook) Get edgeKes of a vertex by Go - auto future = ectx()->getStorageClient()->getEdgeKeys(space, vid_); + auto future = ectx()->getStorageClient()->getEdgeKeys(spaceId_, vid_); auto *runner = ectx()->rctx()->runner(); auto cb = [this] (auto &&resp) { if (!resp.ok()) { @@ -61,8 +67,7 @@ void DeleteVertexExecutor::execute() { } void DeleteVertexExecutor::deleteEdges(std::vector<storage::cpp2::EdgeKey>* edges) { - GraphSpaceID space = ectx()->rctx()->session()->space(); - auto future = ectx()->getStorageClient()->deleteEdges(space, *edges); + auto future = ectx()->getStorageClient()->deleteEdges(spaceId_, *edges); auto *runner = ectx()->rctx()->runner(); auto cb = [this] (auto &&resp) { auto completeness = resp.completeness(); @@ -85,8 +90,7 @@ void DeleteVertexExecutor::deleteEdges(std::vector<storage::cpp2::EdgeKey>* edge } void DeleteVertexExecutor::deleteVertex() { - GraphSpaceID space = ectx()->rctx()->session()->space(); - auto future = ectx()->getStorageClient()->deleteVertex(space, vid_); + auto future = ectx()->getStorageClient()->deleteVertex(spaceId_, vid_); auto *runner = ectx()->rctx()->runner(); auto cb = [this] (auto &&resp) { if (!resp.ok()) { diff --git a/src/executor/DeleteVertexExecutor.h b/src/executor/DeleteVertexExecutor.h index 577a6709..d6dd8549 100644 --- a/src/executor/DeleteVertexExecutor.h +++ b/src/executor/DeleteVertexExecutor.h @@ -30,8 +30,10 @@ private: void deleteVertex(); private: - DeleteVertexSentence *sentence_{nullptr}; - VertexID vid_; + DeleteVertexSentence *sentence_{nullptr}; + std::unique_ptr<ExpressionContext> expCtx_; + VertexID vid_; + GraphSpaceID spaceId_{-1}; }; } // namespace graph diff --git a/src/executor/UpdateEdgeExecutor.cpp b/src/executor/UpdateEdgeExecutor.cpp index bf3ee975..87a570f3 100644 --- a/src/executor/UpdateEdgeExecutor.cpp +++ b/src/executor/UpdateEdgeExecutor.cpp @@ -26,28 +26,38 @@ UpdateEdgeExecutor::UpdateEdgeExecutor(Sentence *sentence, Status UpdateEdgeExecutor::prepare() { DCHECK(sentence_ != nullptr); Status status = Status::OK(); + + spaceId_ = ectx()->rctx()->session()->space(); + expCtx_ = std::make_unique<ExpressionContext>(); + expCtx_->setSpace(spaceId_); + expCtx_->setStorageClient(ectx()->getStorageClient()); + do { status = checkIfGraphSpaceChosen(); if (!status.ok()) { break; } insertable_ = sentence_->getInsertable(); - status = sentence_->getSrcId()->prepare(); + auto sid = sentence_->getSrcId(); + sid->setContext(expCtx_.get()); + status = sid->prepare(); if (!status.ok()) { break; } - auto src = sentence_->getSrcId()->eval(); + auto src = sid->eval(); if (!src.ok() || !Expression::isInt(src.value())) { status = Status::Error("SRC Vertex ID should be of type integer"); break; } edge_.set_src(Expression::asInt(src.value())); - status = sentence_->getDstId()->prepare(); + auto did = sentence_->getDstId(); + did->setContext(expCtx_.get()); + status = did->prepare(); if (!status.ok()) { break; } - auto dst = sentence_->getDstId()->eval(); + auto dst = did->eval(); if (!dst.ok() || !Expression::isInt(dst.value())) { status = Status::Error("DST Vertex ID should be of type integer"); break; @@ -55,9 +65,8 @@ Status UpdateEdgeExecutor::prepare() { edge_.set_dst(Expression::asInt(dst.value())); edge_.set_ranking(sentence_->getRank()); - auto spaceId = ectx()->rctx()->session()->space(); edgeTypeName_ = sentence_->getEdgeType(); - auto edgeStatus = ectx()->schemaManager()->toEdgeType(spaceId, *edgeTypeName_); + auto edgeStatus = ectx()->schemaManager()->toEdgeType(spaceId_, *edgeTypeName_); if (!edgeStatus.ok()) { status = edgeStatus.status(); break; @@ -200,8 +209,7 @@ void UpdateEdgeExecutor::insertReverselyEdge(storage::cpp2::UpdateResponse &&rpc reverselyEdge.key.set_edge_type(-edge_.edge_type); reverselyEdge.props = ""; edges.emplace_back(reverselyEdge); - auto space = ectx()->rctx()->session()->space(); - auto future = ectx()->getStorageClient()->addEdges(space, std::move(edges), false); + auto future = ectx()->getStorageClient()->addEdges(spaceId_, std::move(edges), false); auto *runner = ectx()->rctx()->runner(); auto cb = [this, updateResp = std::move(rpcResp)] (auto &&resp) mutable { auto completeness = resp.completeness(); @@ -225,10 +233,9 @@ void UpdateEdgeExecutor::insertReverselyEdge(storage::cpp2::UpdateResponse &&rpc void UpdateEdgeExecutor::execute() { FLOG_INFO("Executing UpdateEdge: %s", sentence_->toString().c_str()); - auto space = ectx()->rctx()->session()->space(); std::string filterStr = filter_ ? Expression::encode(filter_) : ""; auto returns = getReturnColumns(); - auto future = ectx()->getStorageClient()->updateEdge(space, + auto future = ectx()->getStorageClient()->updateEdge(spaceId_, edge_, filterStr, std::move(updateItems_), diff --git a/src/executor/UpdateEdgeExecutor.h b/src/executor/UpdateEdgeExecutor.h index d084eb5e..c4262284 100644 --- a/src/executor/UpdateEdgeExecutor.h +++ b/src/executor/UpdateEdgeExecutor.h @@ -62,6 +62,8 @@ private: std::vector<storage::cpp2::UpdateItem> updateItems_; Expression *filter_{nullptr}; std::vector<YieldColumn*> yields_; + std::unique_ptr<ExpressionContext> expCtx_; + GraphSpaceID spaceId_{-1}; }; } // namespace graph diff --git a/src/executor/UpdateVertexExecutor.cpp b/src/executor/UpdateVertexExecutor.cpp index 44f9a3ed..b96311db 100644 --- a/src/executor/UpdateVertexExecutor.cpp +++ b/src/executor/UpdateVertexExecutor.cpp @@ -24,6 +24,12 @@ UpdateVertexExecutor::UpdateVertexExecutor(Sentence *sentence, Status UpdateVertexExecutor::prepare() { DCHECK(sentence_ != nullptr); + + spaceId_ = ectx()->rctx()->session()->space(); + expCtx_ = std::make_unique<ExpressionContext>(); + expCtx_->setSpace(spaceId_); + expCtx_->setStorageClient(ectx()->getStorageClient()); + Status status = Status::OK(); do { status = checkIfGraphSpaceChosen(); @@ -31,11 +37,13 @@ Status UpdateVertexExecutor::prepare() { break; } insertable_ = sentence_->getInsertable(); - status = sentence_->getVid()->prepare(); + auto id = sentence_->getVid(); + id->setContext(expCtx_.get()); + status = id->prepare(); if (!status.ok()) { break; } - auto vid = sentence_->getVid()->eval(); + auto vid = id->eval(); if (!vid.ok() || !Expression::isInt(vid.value())) { status = Status::Error("Get Vertex ID failure!"); break; @@ -176,10 +184,9 @@ void UpdateVertexExecutor::finishExecution(storage::cpp2::UpdateResponse &&rpcRe void UpdateVertexExecutor::execute() { FLOG_INFO("Executing UpdateVertex: %s", sentence_->toString().c_str()); - auto spaceId = ectx()->rctx()->session()->space(); std::string filterStr = filter_ ? Expression::encode(filter_) : ""; auto returns = getReturnColumns(); - auto future = ectx()->getStorageClient()->updateVertex(spaceId, + auto future = ectx()->getStorageClient()->updateVertex(spaceId_, vertex_, filterStr, std::move(updateItems_), diff --git a/src/executor/UpdateVertexExecutor.h b/src/executor/UpdateVertexExecutor.h index 13fa5a2d..6c6e83ad 100644 --- a/src/executor/UpdateVertexExecutor.h +++ b/src/executor/UpdateVertexExecutor.h @@ -57,6 +57,8 @@ private: std::vector<storage::cpp2::UpdateItem> updateItems_; Expression *filter_{nullptr}; std::vector<YieldColumn*> yields_; + std::unique_ptr<ExpressionContext> expCtx_; + GraphSpaceID spaceId_{-1}; }; } // namespace graph diff --git a/src/executor/test/DeleteVertexTest.cpp b/src/executor/test/DeleteVertexTest.cpp index a2c15e59..9bddff72 100644 --- a/src/executor/test/DeleteVertexTest.cpp +++ b/src/executor/test/DeleteVertexTest.cpp @@ -102,8 +102,8 @@ TEST_F(DeleteVertexTest, base) { auto &player = players_["Tony Parker"]; auto &serve = player.serves()[0]; auto &team = teams_[std::get<0>(serve)]; - auto *fmt = "FETCH PROP ON serve %ld->%ld" - " YIELD serve.start_year, serve.end_year"; + auto *fmt = "FETCH PROP ON serve %ld->%ld " + "YIELD serve.start_year, serve.end_year"; auto query = folly::stringPrintf(fmt, player.vid(), team.vid()); auto code = client_->execute(query, resp); ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); @@ -111,6 +111,58 @@ TEST_F(DeleteVertexTest, base) { }; ASSERT_TRUE(verifyResult(resp, expected)); } + { + cpp2::ExecutionResponse resp; + auto &player = players_["Tony Parker"]; + auto query = "FETCH PROP ON player uuid(\"Tony Parker\") " + "YIELD player.name, player.age"; + auto code = client_->execute(query, resp); + ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); + std::vector<std::tuple<std::string, int64_t>> expected = { + {player.name(), player.age()}, + }; + ASSERT_TRUE(verifyResult(resp, expected)); + } + { + cpp2::ExecutionResponse resp; + auto &player = players_["Tony Parker"]; + auto &serve = player.serves()[0]; + auto query = "FETCH PROP ON serve uuid(\"Tony Parker\")->uuid(\"Spurs\") " + "YIELD serve.start_year, serve.end_year"; + auto code = client_->execute(query, resp); + ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); + std::vector<std::tuple<int64_t, int64_t>> expected = { + {std::get<1>(serve), std::get<2>(serve)}, + }; + ASSERT_TRUE(verifyResult(resp, expected)); + } + // Delete vertex + { + cpp2::ExecutionResponse resp; + auto query = "DELETE VERTEX uuid(\"Tony Parker\")"; + auto code = client_->execute(query, resp); + ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); + } + { + cpp2::ExecutionResponse resp; + auto query = "FETCH PROP ON player uuid(\"Tony Parker\") " + "YIELD player.name, player.age"; + auto code = client_->execute(query, resp); + ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); + std::vector<std::tuple<std::string, int64_t>> expected = { + }; + ASSERT_TRUE(verifyResult(resp, expected)); + } + { + cpp2::ExecutionResponse resp; + auto query = "FETCH PROP ON serve uuid(\"Tony Parker\")->uuid(\"Spurs\") " + "YIELD serve.start_year, serve.end_year"; + auto code = client_->execute(query, resp); + ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); + std::vector<std::tuple<int64_t, int64_t>> expected = { + }; + ASSERT_TRUE(verifyResult(resp, expected)); + } } } // namespace graph diff --git a/src/executor/test/FetchEdgesTest.cpp b/src/executor/test/FetchEdgesTest.cpp index bb382890..d74c5b89 100644 --- a/src/executor/test/FetchEdgesTest.cpp +++ b/src/executor/test/FetchEdgesTest.cpp @@ -178,7 +178,7 @@ TEST_F(FetchEdgesTest, base) { auto &player = players_["Boris Diaw"]; auto &serve = player.serves()[0]; auto &team = teams_[std::get<0>(serve)]; - auto *fmt = "FETCH PROP ON serve uuid(\"%s\")->hash(\"%s\") " + auto *fmt = "FETCH PROP ON serve uuid(\"%s\")->uuid(\"%s\") " "YIELD serve.start_year, serve.end_year"; auto query = folly::stringPrintf(fmt, player.name().c_str(), team.name().c_str()); auto code = client_->execute(query, resp); @@ -256,7 +256,7 @@ TEST_F(FetchEdgesTest, noYield) { auto &player = players_["Boris Diaw"]; auto &serve = player.serves()[0]; auto &team = teams_[std::get<0>(serve)]; - auto *fmt = "FETCH PROP ON serve uuid(\"%s\")->hash(\"%s\")"; + auto *fmt = "FETCH PROP ON serve uuid(\"%s\")->uuid(\"%s\")"; auto query = folly::stringPrintf(fmt, player.name().c_str(), team.name().c_str()); auto code = client_->execute(query, resp); ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); @@ -408,7 +408,7 @@ TEST_F(FetchEdgesTest, nonExistEdge) { } { cpp2::ExecutionResponse resp; - auto query = "FETCH PROP ON serve uuid(\"Zion Williamson\")->hash(\"Spurs\") " + auto query = "FETCH PROP ON serve uuid(\"Zion Williamson\")->uuid(\"Spurs\") " "YIELD serve.start_year"; auto code = client_->execute(query, resp); ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); diff --git a/src/executor/test/TraverseTestBase.h b/src/executor/test/TraverseTestBase.h index 94d75b27..021dcae5 100644 --- a/src/executor/test/TraverseTestBase.h +++ b/src/executor/test/TraverseTestBase.h @@ -722,6 +722,29 @@ AssertionResult TraverseTestBase::prepareData() { << static_cast<int32_t>(code); } } + { + // Insert vertices `team' with uuid + cpp2::ExecutionResponse resp; + std::string query; + query.reserve(1024); + query += "INSERT VERTEX team(name) VALUES "; + for (auto &team : teams_) { + query += "uuid(\""; + query += team.name(); + query += "\"): "; + query += "("; + query += "\""; + query += team.name(); + query += "\""; + query += "),\n\t"; + } + query.resize(query.size() - 3); + auto code = client_->execute(query, resp); + if (code != cpp2::ErrorCode::SUCCEEDED) { + return TestError() << "Insert `teams' failed: " + << static_cast<int32_t>(code); + } + } { // Insert edges `serve' cpp2::ExecutionResponse resp; @@ -764,9 +787,9 @@ AssertionResult TraverseTestBase::prepareData() { auto endYear = std::get<2>(serve); query += "uuid(\""; query += player.name(); - query += "\") -> "; - query += std::to_string(teams_[team].vid()); - query += ": "; + query += "\") -> uuid(\""; + query += teams_[team].name(); + query += "\"): "; query += "("; query += std::to_string(startYear); query += ", "; diff --git a/src/executor/test/UpdateTest.cpp b/src/executor/test/UpdateTest.cpp index 7539a944..cb7f223d 100644 --- a/src/executor/test/UpdateTest.cpp +++ b/src/executor/test/UpdateTest.cpp @@ -38,6 +38,13 @@ TEST_F(UpdateTest, UpdateVertex) { auto code = client_->execute(query, resp); ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); } + { + cpp2::ExecutionResponse resp; + auto query = "UPDATE VERTEX uuid(\"Math\") " + "SET course.credits = $^.course.credits + 1, building.name = \"No6\" "; + auto code = client_->execute(query, resp); + ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); + } { // SetFilter cpp2::ExecutionResponse resp; auto query = "UPDATE VERTEX 101 " @@ -46,6 +53,14 @@ TEST_F(UpdateTest, UpdateVertex) { auto code = client_->execute(query, resp); ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); } + { + cpp2::ExecutionResponse resp; + auto query = "UPDATE VERTEX uuid(\"Math\") " + "SET course.credits = $^.course.credits + 1, building.name = \"No7\" " + "WHEN $^.course.name == \"Math\" && $^.course.credits > 2"; + auto code = client_->execute(query, resp); + ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); + } { // SetYield cpp2::ExecutionResponse resp; auto query = "UPDATE VERTEX 101 " @@ -58,6 +73,18 @@ TEST_F(UpdateTest, UpdateVertex) { }; ASSERT_TRUE(verifyResult(resp, expected)); } + { + cpp2::ExecutionResponse resp; + auto query = "UPDATE VERTEX uuid(\"Math\") " + "SET course.credits = $^.course.credits + 1, building.name = \"No8\" " + "YIELD $^.course.name AS Name, $^.course.credits AS Credits, $^.building.name"; + auto code = client_->execute(query, resp); + ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); + std::vector<std::tuple<std::string, int64_t, std::string>> expected = { + {"Math", 6, "No8"}, + }; + ASSERT_TRUE(verifyResult(resp, expected)); + } { // SetFilterYield cpp2::ExecutionResponse resp; auto query = "UPDATE VERTEX 101 " @@ -71,6 +98,19 @@ TEST_F(UpdateTest, UpdateVertex) { }; ASSERT_TRUE(verifyResult(resp, expected)); } + { + cpp2::ExecutionResponse resp; + auto query = "UPDATE VERTEX uuid(\"Math\") " + "SET course.credits = $^.course.credits + 1, building.name = \"No9\" " + "WHEN $^.course.name == \"Math\" && $^.course.credits > 2 " + "YIELD $^.course.name AS Name, $^.course.credits AS Credits, $^.building.name"; + auto code = client_->execute(query, resp); + ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); + std::vector<std::tuple<std::string, int64_t, std::string>> expected = { + {"Math", 7, "No9"}, + }; + ASSERT_TRUE(verifyResult(resp, expected)); + } { // Insertable: vertex 103 ("CS", 5) --> ("CS", 6, "No10") cpp2::ExecutionResponse resp; auto query = "UPSERT VERTEX 103 " @@ -84,6 +124,19 @@ TEST_F(UpdateTest, UpdateVertex) { }; ASSERT_TRUE(verifyResult(resp, expected)); } + { + cpp2::ExecutionResponse resp; + auto query = "UPSERT VERTEX uuid(\"CS\") " + "SET course.credits = $^.course.credits + 1, building.name = \"No10\" " + "WHEN $^.course.name == \"CS\" && $^.course.credits > 2 " + "YIELD $^.course.name AS Name, $^.course.credits AS Credits, $^.building.name"; + auto code = client_->execute(query, resp); + ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); + std::vector<std::tuple<std::string, int64_t, std::string>> expected = { + {"CS", 6, "No10"}, + }; + ASSERT_TRUE(verifyResult(resp, expected)); + } } @@ -96,6 +149,13 @@ TEST_F(UpdateTest, UpdateEdge) { auto code = client_->execute(query, resp); ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); } + { + cpp2::ExecutionResponse resp; + auto query = "UPDATE EDGE uuid(\"Monica\") -> uuid(\"Math\")@0 OF select " + "SET grade = select.grade + 1, year = 2000"; + auto code = client_->execute(query, resp); + ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); + } { // SetFilter cpp2::ExecutionResponse resp; auto query = "UPDATE EDGE 200 -> 101@0 OF select " @@ -104,6 +164,14 @@ TEST_F(UpdateTest, UpdateEdge) { auto code = client_->execute(query, resp); ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); } + { + cpp2::ExecutionResponse resp; + auto query = "UPDATE EDGE uuid(\"Monica\") -> uuid(\"Math\")@0 OF select " + "SET grade = select.grade + 1, year = 2000 " + "WHEN select.grade > 4 && $^.student.age > 15"; + auto code = client_->execute(query, resp); + ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); + } { // SetYield cpp2::ExecutionResponse resp; auto query = "UPDATE EDGE 200 -> 101@0 OF select " @@ -116,6 +184,18 @@ TEST_F(UpdateTest, UpdateEdge) { }; ASSERT_TRUE(verifyResult(resp, expected)); } + { + cpp2::ExecutionResponse resp; + auto query = "UPDATE EDGE uuid(\"Monica\") -> uuid(\"Math\")@0 OF select " + "SET grade = select.grade + 1, year = 2018 " + "YIELD $^.student.name AS Name, select.grade AS Grade, select.year AS Year"; + auto code = client_->execute(query, resp); + ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); + std::vector<std::tuple<std::string, int64_t, int64_t>> expected = { + {"Monica", 8, 2018}, + }; + ASSERT_TRUE(verifyResult(resp, expected)); + } { // SetFilterYield cpp2::ExecutionResponse resp; auto query = "UPDATE EDGE 200 -> 101@0 OF select " @@ -129,6 +209,19 @@ TEST_F(UpdateTest, UpdateEdge) { }; ASSERT_TRUE(verifyResult(resp, expected)); } + { + cpp2::ExecutionResponse resp; + auto query = "UPDATE EDGE uuid(\"Monica\") -> uuid(\"Math\")@0 OF select " + "SET grade = select.grade + 1, year = 2019 " + "WHEN select.grade > 4 && $^.student.age > 15 " + "YIELD $^.student.name AS Name, select.grade AS Grade, select.year AS Year"; + auto code = client_->execute(query, resp); + ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); + std::vector<std::tuple<std::string, int64_t, int64_t>> expected = { + {"Monica", 9, 2019}, + }; + ASSERT_TRUE(verifyResult(resp, expected)); + } { // Insertable cpp2::ExecutionResponse resp; auto query = "UPSERT EDGE 201 -> 101@0 OF select " @@ -142,6 +235,19 @@ TEST_F(UpdateTest, UpdateEdge) { }; ASSERT_TRUE(verifyResult(resp, expected)); } + { + cpp2::ExecutionResponse resp; + auto query = "UPSERT EDGE uuid(\"Mike\") -> uuid(\"Math\")@0 OF select " + "SET grade = 3, year = 2019 " + "WHEN $^.student.age > 15 && $^.student.gender == \"male\" " + "YIELD select.grade AS Grade, select.year AS Year"; + auto code = client_->execute(query, resp); + ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); + std::vector<std::tuple<int64_t, int64_t>> expected = { + {3, 2019}, + }; + ASSERT_TRUE(verifyResult(resp, expected)); + } } } // namespace graph diff --git a/src/executor/test/UpdateTestBase.h b/src/executor/test/UpdateTestBase.h index d6e1341d..3b5feba3 100644 --- a/src/executor/test/UpdateTestBase.h +++ b/src/executor/test/UpdateTestBase.h @@ -174,6 +174,36 @@ AssertionResult UpdateTestBase::prepareData() { << static_cast<int32_t>(code); } } + { // Insert vertices 'student' with uuid + cpp2::ExecutionResponse resp; + std::string query; + query.reserve(1024); + query = "INSERT VERTEX student(name, age, gender) VALUES " + "uuid(\"Monica\"):(\"Monica\", 16, \"female\"), " + "uuid(\"Mike\"):(\"Mike\", 18, \"male\"), " + "uuid(\"Jane\"):(\"Jane\", 17, \"female\")"; + auto code = client_->execute(query, resp); + if (code != cpp2::ErrorCode::SUCCEEDED) { + return TestError() << "Insert 'student' failed: " + << static_cast<int32_t>(code); + } + query.clear(); + query = "INSERT VERTEX course(name, credits),building(name) VALUES " + "uuid(\"Math\"):(\"Math\", 3, \"No5\"), " + "uuid(\"English\"):(\"English\", 6, \"No11\")"; + code = client_->execute(query, resp); + if (code != cpp2::ErrorCode::SUCCEEDED) { + return TestError() << "Insert 'course' and 'building' failed: " + << static_cast<int32_t>(code); + } + query.clear(); + query = "INSERT VERTEX course(name, credits) VALUES uuid(\"CS\"):(\"CS\", 5)"; + code = client_->execute(query, resp); + if (code != cpp2::ErrorCode::SUCCEEDED) { + return TestError() << "Insert 'course' failed: " + << static_cast<int32_t>(code); + } + } { // Insert edges 'select' and 'like' cpp2::ExecutionResponse resp; std::string query; @@ -199,6 +229,31 @@ AssertionResult UpdateTestBase::prepareData() { << static_cast<int32_t>(code); } } + { // Insert edges 'select' and 'like' with uuid + cpp2::ExecutionResponse resp; + std::string query; + query.reserve(1024); + query = "INSERT EDGE select(grade, year) VALUES " + "uuid(\"Monica\") -> uuid(\"Math\")@0:(5, 2018), " + "uuid(\"Monica\") -> uuid(\"English\")@0:(3, 2018), " + "uuid(\"Mike\") -> uuid(\"English\")@0:(3, 2019), " + "uuid(\"Jane\") -> uuid(\"English\")@0:(3, 2019)"; + auto code = client_->execute(query, resp); + if (code != cpp2::ErrorCode::SUCCEEDED) { + return TestError() << "Insert 'select' failed: " + << static_cast<int32_t>(code); + } + query.clear(); + query = "INSERT EDGE like(likeness) VALUES " + "uuid(\"Monica\") -> uuid(\"Mike\")@0:(92.5), " + "uuid(\"Mike\") -> uuid(\"Monica\")@0:(85.6), " + "uuid(\"Mike\") -> uuid(\"Jane\")@0:(93.2)"; + code = client_->execute(query, resp); + if (code != cpp2::ErrorCode::SUCCEEDED) { + return TestError() << "Insert 'like' failed: " + << static_cast<int32_t>(code); + } + } return TestOK(); } -- GitLab