diff --git a/src/executor/DeleteVertexExecutor.cpp b/src/executor/DeleteVertexExecutor.cpp index 92e4552fe34ba6e7f40f84c18867a6b5028a8a95..b9d21af6388f0beba579bfbc90ca54827e1faea9 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 577a6709c9005ab6fdf28cb849afbe896d4ddeee..d6dd85492863d4cbf7cd74c8f234d3fc20d8169b 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 bf3ee975d92c4dab1709352c62e934288d9dc6e9..87a570f306e2a0baaf196d9a1ccb0b3ed417c553 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 d084eb5eef539aaf8b016c09ff486836ccf24134..c426228428f6d3fb394228f1d3a075fbffc807d2 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 44f9a3ed33f883a75d8d729018a9e3957d0784f1..b96311db7dd6c3642dd895c9eb349c9071be8971 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 13fa5a2dbc7f809e335e8a5b91c20c5b5a7ac952..6c6e83adb94ed121c8fd24d3dc17175e72a5322f 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 a2c15e59c44d91a3c5c998b4b5e27f829aab2311..9bddff72f059d9ddc3f6a465ec37f7787c8da71a 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 bb382890c386d901d730d3d95f1092ca567165b2..d74c5b89dcf50bfad67d0402f0a5f9dd4205a235 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 94d75b2797eef176cd9236ea22f7f95e5f725586..021dcae532a7ceb15e7be9925d2a8e7f3866d882 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 7539a94445ec2c825869cee8ada84eec56b3a238..cb7f223d6999bed6ab13fd495d3cbf2d15e271c2 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 d6e1341d0896aaf9acba3f68088cb58bfe8f7e0f..3b5feba36ed4c918f917e0555eb9d00e3d1a0d60 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(); }