diff --git a/src/daemons/CMakeLists.txt b/src/daemons/CMakeLists.txt index fac9554ad419dc940c45293742a251faab1d68be..7059e007453ad19a55ce674d70beaf050117f3d6 100644 --- a/src/daemons/CMakeLists.txt +++ b/src/daemons/CMakeLists.txt @@ -4,27 +4,19 @@ nebula_add_executable( SOURCES GraphDaemon.cpp OBJECTS - $<TARGET_OBJECTS:meta_client> + $<TARGET_OBJECTS:filter_obj> $<TARGET_OBJECTS:graph_http_handler> - $<TARGET_OBJECTS:meta_thrift_obj> $<TARGET_OBJECTS:graph_obj> - $<TARGET_OBJECTS:base_obj> - $<TARGET_OBJECTS:graph_thrift_obj> - $<TARGET_OBJECTS:storage_thrift_obj> - $<TARGET_OBJECTS:common_thrift_obj> - $<TARGET_OBJECTS:meta_client> - $<TARGET_OBJECTS:meta_thrift_obj> - $<TARGET_OBJECTS:storage_client> - $<TARGET_OBJECTS:meta_thrift_obj> - $<TARGET_OBJECTS:time_obj> - $<TARGET_OBJECTS:fs_obj> $<TARGET_OBJECTS:http_client_obj> - $<TARGET_OBJECTS:stats_obj> - $<TARGET_OBJECTS:thread_obj> $<TARGET_OBJECTS:parser_obj> - $<TARGET_OBJECTS:filter_obj> $<TARGET_OBJECTS:network_obj> $<TARGET_OBJECTS:process_obj> + $<TARGET_OBJECTS:graph_thrift_obj> + $<TARGET_OBJECTS:storage_client> + $<TARGET_OBJECTS:storage_thrift_obj> + $<TARGET_OBJECTS:meta_client> + $<TARGET_OBJECTS:meta_thrift_obj> + $<TARGET_OBJECTS:common_thrift_obj> $<TARGET_OBJECTS:thrift_obj> $<TARGET_OBJECTS:schema_obj> $<TARGET_OBJECTS:ws_obj> @@ -32,6 +24,11 @@ nebula_add_executable( $<TARGET_OBJECTS:dataman_obj> $<TARGET_OBJECTS:meta_gflags_man_obj> $<TARGET_OBJECTS:gflags_man_obj> + $<TARGET_OBJECTS:stats_obj> + $<TARGET_OBJECTS:thread_obj> + $<TARGET_OBJECTS:time_obj> + $<TARGET_OBJECTS:fs_obj> + $<TARGET_OBJECTS:base_obj> LIBRARIES proxygenhttpserver proxygenlib @@ -46,34 +43,35 @@ nebula_add_executable( SOURCES StorageDaemon.cpp OBJECTS + $<TARGET_OBJECTS:filter_obj> $<TARGET_OBJECTS:storage_server> $<TARGET_OBJECTS:storage_service_handler> $<TARGET_OBJECTS:storage_http_handler> - $<TARGET_OBJECTS:storage_thrift_obj> $<TARGET_OBJECTS:kvstore_obj> - $<TARGET_OBJECTS:meta_client> - $<TARGET_OBJECTS:meta_thrift_obj> - $<TARGET_OBJECTS:common_thrift_obj> $<TARGET_OBJECTS:raftex_obj> $<TARGET_OBJECTS:raftex_thrift_obj> $<TARGET_OBJECTS:wal_obj> $<TARGET_OBJECTS:dataman_obj> $<TARGET_OBJECTS:schema_obj> $<TARGET_OBJECTS:hdfs_helper_obj> + $<TARGET_OBJECTS:storage_thrift_obj> $<TARGET_OBJECTS:http_client_obj> - $<TARGET_OBJECTS:filter_obj> - $<TARGET_OBJECTS:base_obj> + $<TARGET_OBJECTS:storage_client> + $<TARGET_OBJECTS:meta_client> + $<TARGET_OBJECTS:meta_thrift_obj> + $<TARGET_OBJECTS:common_thrift_obj> $<TARGET_OBJECTS:thrift_obj> - $<TARGET_OBJECTS:thread_obj> - $<TARGET_OBJECTS:time_obj> - $<TARGET_OBJECTS:fs_obj> - $<TARGET_OBJECTS:stats_obj> + $<TARGET_OBJECTS:meta_gflags_man_obj> + $<TARGET_OBJECTS:gflags_man_obj> $<TARGET_OBJECTS:network_obj> $<TARGET_OBJECTS:process_obj> $<TARGET_OBJECTS:ws_obj> $<TARGET_OBJECTS:ws_common_obj> - $<TARGET_OBJECTS:meta_gflags_man_obj> - $<TARGET_OBJECTS:gflags_man_obj> + $<TARGET_OBJECTS:thread_obj> + $<TARGET_OBJECTS:time_obj> + $<TARGET_OBJECTS:fs_obj> + $<TARGET_OBJECTS:stats_obj> + $<TARGET_OBJECTS:base_obj> LIBRARIES proxygenhttpserver proxygenlib @@ -93,27 +91,28 @@ nebula_add_executable( $<TARGET_OBJECTS:meta_http_handler> $<TARGET_OBJECTS:kvstore_obj> $<TARGET_OBJECTS:schema_obj> + $<TARGET_OBJECTS:wal_obj> + $<TARGET_OBJECTS:hdfs_helper_obj> + $<TARGET_OBJECTS:http_client_obj> + $<TARGET_OBJECTS:storage_client> + $<TARGET_OBJECTS:storage_thrift_obj> $<TARGET_OBJECTS:meta_client> $<TARGET_OBJECTS:meta_thrift_obj> - $<TARGET_OBJECTS:common_thrift_obj> - $<TARGET_OBJECTS:storage_thrift_obj> $<TARGET_OBJECTS:raftex_obj> $<TARGET_OBJECTS:raftex_thrift_obj> - $<TARGET_OBJECTS:wal_obj> - $<TARGET_OBJECTS:hdfs_helper_obj> - $<TARGET_OBJECTS:http_client_obj> - $<TARGET_OBJECTS:base_obj> + $<TARGET_OBJECTS:common_thrift_obj> $<TARGET_OBJECTS:thrift_obj> - $<TARGET_OBJECTS:network_obj> - $<TARGET_OBJECTS:thread_obj> - $<TARGET_OBJECTS:time_obj> - $<TARGET_OBJECTS:fs_obj> - $<TARGET_OBJECTS:stats_obj> $<TARGET_OBJECTS:process_obj> $<TARGET_OBJECTS:ws_obj> $<TARGET_OBJECTS:ws_common_obj> $<TARGET_OBJECTS:kv_gflags_man_obj> $<TARGET_OBJECTS:gflags_man_obj> + $<TARGET_OBJECTS:network_obj> + $<TARGET_OBJECTS:thread_obj> + $<TARGET_OBJECTS:stats_obj> + $<TARGET_OBJECTS:time_obj> + $<TARGET_OBJECTS:fs_obj> + $<TARGET_OBJECTS:base_obj> LIBRARIES proxygenhttpserver proxygenlib diff --git a/src/executor/DeleteVertexExecutor.cpp b/src/executor/DeleteVertexExecutor.cpp index f778d0143d6b50f59b216dbbafff8d805bfa7749..92e4552fe34ba6e7f40f84c18867a6b5028a8a95 100644 --- a/src/executor/DeleteVertexExecutor.cpp +++ b/src/executor/DeleteVertexExecutor.cpp @@ -28,7 +28,7 @@ Status DeleteVertexExecutor::prepare() { void DeleteVertexExecutor::execute() { GraphSpaceID space = ectx()->rctx()->session()->space(); // TODO(zlcook) Get edgeKes of a vertex by Go - auto future = ectx()->storage()->getEdgeKeys(space, vid_); + auto future = ectx()->getStorageClient()->getEdgeKeys(space, vid_); auto *runner = ectx()->rctx()->runner(); auto cb = [this] (auto &&resp) { if (!resp.ok()) { @@ -62,7 +62,7 @@ void DeleteVertexExecutor::execute() { void DeleteVertexExecutor::deleteEdges(std::vector<storage::cpp2::EdgeKey>* edges) { GraphSpaceID space = ectx()->rctx()->session()->space(); - auto future = ectx()->storage()->deleteEdges(space, *edges); + auto future = ectx()->getStorageClient()->deleteEdges(space, *edges); auto *runner = ectx()->rctx()->runner(); auto cb = [this] (auto &&resp) { auto completeness = resp.completeness(); @@ -86,7 +86,7 @@ void DeleteVertexExecutor::deleteEdges(std::vector<storage::cpp2::EdgeKey>* edge void DeleteVertexExecutor::deleteVertex() { GraphSpaceID space = ectx()->rctx()->session()->space(); - auto future = ectx()->storage()->deleteVertex(space, vid_); + auto future = ectx()->getStorageClient()->deleteVertex(space, vid_); auto *runner = ectx()->rctx()->runner(); auto cb = [this] (auto &&resp) { if (!resp.ok()) { diff --git a/src/executor/ExecutionContext.cpp b/src/executor/ExecutionContext.cpp index 2a56abd1c610f22596388c07af15bb960bcd34ed..03b0aaa4d7ed58feb0f0753bb0a6500cdba651d3 100644 --- a/src/executor/ExecutionContext.cpp +++ b/src/executor/ExecutionContext.cpp @@ -19,8 +19,8 @@ ExecutionContext::~ExecutionContext() { gflagsManager_ = nullptr; } - if (nullptr != storage_) { - storage_ = nullptr; + if (nullptr != storageClient_) { + storageClient_ = nullptr; } if (nullptr != metaClient_) { diff --git a/src/executor/ExecutionContext.h b/src/executor/ExecutionContext.h index d0200d864877254cda9d977b7f77e13b7fe989ab..56c5e19fea952e50e1f47225b9b2320d85506449 100644 --- a/src/executor/ExecutionContext.h +++ b/src/executor/ExecutionContext.h @@ -37,7 +37,7 @@ public: rctx_ = std::move(rctx); sm_ = sm; gflagsManager_ = gflagsManager; - storage_ = storage; + storageClient_ = storage; metaClient_ = metaClient; variableHolder_ = std::make_unique<VariableHolder>(); } @@ -56,8 +56,8 @@ public: return gflagsManager_; } - storage::StorageClient* storage() const { - return storage_; + storage::StorageClient* getStorageClient() const { + return storageClient_; } VariableHolder* variableHolder() const { @@ -72,7 +72,7 @@ private: RequestContextPtr rctx_; meta::SchemaManager *sm_{nullptr}; meta::ClientBasedGflagsManager *gflagsManager_{nullptr}; - storage::StorageClient *storage_{nullptr}; + storage::StorageClient *storageClient_{nullptr}; meta::MetaClient *metaClient_{nullptr}; std::unique_ptr<VariableHolder> variableHolder_; }; diff --git a/src/executor/FetchEdgesExecutor.cpp b/src/executor/FetchEdgesExecutor.cpp index bc4d32d473f08a2c74608a30ed3f7d8f74939a27..23725fd95fb3c767f8e6c0e9cd39de28043aafaf 100644 --- a/src/executor/FetchEdgesExecutor.cpp +++ b/src/executor/FetchEdgesExecutor.cpp @@ -28,6 +28,7 @@ Status FetchEdgesExecutor::prepareClauses() { break; } expCtx_ = std::make_unique<ExpressionContext>(); + expCtx_->setStorageClient(ectx()->getStorageClient()); spaceId_ = ectx()->rctx()->session()->space(); yieldClause_ = sentence_->yieldClause(); labelName_ = sentence_->edge(); @@ -196,12 +197,18 @@ Status FetchEdgesExecutor::setupEdgeKeysFromExpr() { if (distinct_) { uniq = std::make_unique<EdgeKeyHashSet>(256, hash_); } + auto edgeKeyExprs = sentence_->keys()->keys(); + expCtx_->setSpace(spaceId_); + for (auto *keyExpr : edgeKeyExprs) { auto *srcExpr = keyExpr->srcid(); + srcExpr->setContext(expCtx_.get()); + auto *dstExpr = keyExpr->dstid(); - auto rank = keyExpr->rank(); + dstExpr->setContext(expCtx_.get()); + auto rank = keyExpr->rank(); status = srcExpr->prepare(); if (!status.ok()) { break; @@ -258,7 +265,7 @@ void FetchEdgesExecutor::fetchEdges() { return; } - auto future = ectx()->storage()->getEdgeProps(spaceId_, edgeKeys_, std::move(props)); + auto future = ectx()->getStorageClient()->getEdgeProps(spaceId_, edgeKeys_, std::move(props)); auto *runner = ectx()->rctx()->runner(); auto cb = [this] (RpcResponse &&result) mutable { auto completeness = result.completeness(); @@ -361,5 +368,6 @@ void FetchEdgesExecutor::processResult(RpcResponse &&result) { finishExecution(std::move(rsWriter)); } + } // namespace graph } // namespace nebula diff --git a/src/executor/FetchEdgesExecutor.h b/src/executor/FetchEdgesExecutor.h index 82fee2e3b07c7a6c8ef36b4689f86f9bbabf1ba6..43b23bfd06a9689f02153eb99d43afe9eb5cc209 100644 --- a/src/executor/FetchEdgesExecutor.h +++ b/src/executor/FetchEdgesExecutor.h @@ -45,7 +45,6 @@ private: using RpcResponse = storage::StorageRpcResponse<storage::cpp2::EdgePropResponse>; void processResult(RpcResponse &&result); - using EdgeKeyHashSet = std::unordered_set< storage::cpp2::EdgeKey, std::function<size_t(const storage::cpp2::EdgeKey& key)>>; diff --git a/src/executor/FetchVerticesExecutor.cpp b/src/executor/FetchVerticesExecutor.cpp index 7e8a912118fc6020bf2fe19fe8bf5141de56de49..e1463a3f8af115c5efbe93406aa8366ab1c3dbb0 100644 --- a/src/executor/FetchVerticesExecutor.cpp +++ b/src/executor/FetchVerticesExecutor.cpp @@ -31,6 +31,8 @@ Status FetchVerticesExecutor::prepareClauses() { } expCtx_ = std::make_unique<ExpressionContext>(); + expCtx_->setStorageClient(ectx()->getStorageClient()); + spaceId_ = ectx()->rctx()->session()->space(); yieldClause_ = sentence_->yieldClause(); labelName_ = sentence_->tag(); @@ -117,7 +119,7 @@ void FetchVerticesExecutor::fetchVertices() { return; } - auto future = ectx()->storage()->getVertexProps(spaceId_, vids_, std::move(props)); + auto future = ectx()->getStorageClient()->getVertexProps(spaceId_, vids_, std::move(props)); auto *runner = ectx()->rctx()->runner(); auto cb = [this] (RpcResponse &&result) mutable { auto completeness = result.completeness(); @@ -247,8 +249,11 @@ Status FetchVerticesExecutor::setupVidsFromExpr() { if (distinct_) { uniqID = std::make_unique<std::unordered_set<VertexID>>(); } + + expCtx_->setSpace(spaceId_); auto vidList = sentence_->vidList(); for (auto *expr : vidList) { + expr->setContext(expCtx_.get()); status = expr->prepare(); if (!status.ok()) { break; @@ -304,6 +309,5 @@ Status FetchVerticesExecutor::setupVidsFromRef() { return Status::OK(); } - } // namespace graph } // namespace nebula diff --git a/src/executor/GoExecutor.cpp b/src/executor/GoExecutor.cpp index ba76d2a7dbe8e206241ae1a4c9f3176b3e9d0ce2..5ca5ffe00ee6ec77da8406070132619764800e97 100644 --- a/src/executor/GoExecutor.cpp +++ b/src/executor/GoExecutor.cpp @@ -33,6 +33,8 @@ Status GoExecutor::prepareClauses() { DCHECK(sentence_ != nullptr); Status status; expCtx_ = std::make_unique<ExpressionContext>(); + expCtx_->setStorageClient(ectx()->getStorageClient()); + do { status = checkIfGraphSpaceChosen(); if (!status.ok()) { @@ -156,8 +158,12 @@ Status GoExecutor::prepareFrom() { break; } + auto space = ectx()->rctx()->session()->space(); + expCtx_->setSpace(space); auto vidList = clause->vidList(); for (auto *expr : vidList) { + expr->setContext(expCtx_.get()); + status = expr->prepare(); if (!status.ok()) { break; @@ -388,11 +394,11 @@ void GoExecutor::stepOut() { return; } auto returns = status.value(); - auto future = ectx()->storage()->getNeighbors(spaceId, - starts_, - edgeTypes_, - "", - std::move(returns)); + auto future = ectx()->getStorageClient()->getNeighbors(spaceId, + starts_, + edgeTypes_, + "", + std::move(returns)); auto *runner = ectx()->rctx()->runner(); auto cb = [this] (auto &&result) { auto completeness = result.completeness(); @@ -630,7 +636,7 @@ void GoExecutor::fetchVertexProps(std::vector<VertexID> ids, RpcResponse &&rpcRe return; } auto returns = status.value(); - auto future = ectx()->storage()->getVertexProps(spaceId, ids, returns); + auto future = ectx()->getStorageClient()->getVertexProps(spaceId, ids, returns); auto *runner = ectx()->rctx()->runner(); auto cb = [this, stepOutResp = std::move(rpcResp)] (auto &&result) mutable { auto completeness = result.completeness(); @@ -903,6 +909,7 @@ bool GoExecutor::processFinalResult(RpcResponse &rpcResp, Callback cb) const { } return getPropFromInterim(vdata.get_vertex_id(), prop); }; + // Evaluate filter if (filter_ != nullptr) { auto value = filter_->eval(); @@ -1040,6 +1047,5 @@ SupportedType GoExecutor::getPropTypeFromInterim(const std::string &prop) const return index_->getColumnType(prop); } - } // namespace graph } // namespace nebula diff --git a/src/executor/InsertEdgeExecutor.cpp b/src/executor/InsertEdgeExecutor.cpp index 883cc15dab2a9316a4c66c9a5a4826c7df451a74..7b3cbc5b8f01993d646d4f1d2588a98250ae88ed 100644 --- a/src/executor/InsertEdgeExecutor.cpp +++ b/src/executor/InsertEdgeExecutor.cpp @@ -18,6 +18,8 @@ InsertEdgeExecutor::InsertEdgeExecutor(Sentence *sentence, Status InsertEdgeExecutor::prepare() { + expCtx_ = std::make_unique<ExpressionContext>(); + expCtx_->setStorageClient(ectx()->getStorageClient()); return Status::OK(); } @@ -41,6 +43,8 @@ Status InsertEdgeExecutor::check() { auto props = sentence_->properties(); rows_ = sentence_->rows(); + expCtx_->setStorageClient(ectx()->getStorageClient()); + schema_ = ectx()->schemaManager()->getEdgeSchema(spaceId, edgeType_); if (schema_ == nullptr) { status = Status::Error("No schema found for `%s'", sentence_->edge()->c_str()); @@ -68,11 +72,18 @@ Status InsertEdgeExecutor::check() { StatusOr<std::vector<storage::cpp2::Edge>> InsertEdgeExecutor::prepareEdges() { + expCtx_ = std::make_unique<ExpressionContext>(); + expCtx_->setStorageClient(ectx()->getStorageClient()); + + auto space = ectx()->rctx()->session()->space(); + expCtx_->setSpace(space); + std::vector<storage::cpp2::Edge> edges(rows_.size() * 2); // inbound and outbound auto index = 0; for (auto i = 0u; i < rows_.size(); i++) { auto *row = rows_[i]; auto sid = row->srcid(); + sid->setContext(expCtx_.get()); auto status = sid->prepare(); if (!status.ok()) { return status; @@ -89,6 +100,7 @@ StatusOr<std::vector<storage::cpp2::Edge>> InsertEdgeExecutor::prepareEdges() { auto src = Expression::asInt(v); auto did = row->dstid(); + did->setContext(expCtx_.get()); status = did->prepare(); if (!status.ok()) { return status; @@ -195,7 +207,9 @@ void InsertEdgeExecutor::execute() { return; } auto space = ectx()->rctx()->session()->space(); - auto future = ectx()->storage()->addEdges(space, std::move(result).value(), overwritable_); + auto future = ectx()->getStorageClient()->addEdges(space, + std::move(result).value(), + overwritable_); auto *runner = ectx()->rctx()->runner(); auto cb = [this] (auto &&resp) { diff --git a/src/executor/InsertEdgeExecutor.h b/src/executor/InsertEdgeExecutor.h index 026c226a2e663c2b80512410761fa9cfa1fe4b93..e3e332ad3c9d53ae58170fa5ec94c8801c328f65 100644 --- a/src/executor/InsertEdgeExecutor.h +++ b/src/executor/InsertEdgeExecutor.h @@ -32,6 +32,7 @@ private: private: using EdgeSchema = std::shared_ptr<const meta::SchemaProviderIf>; InsertEdgeSentence *sentence_{nullptr}; + std::unique_ptr<ExpressionContext> expCtx_; bool overwritable_{true}; EdgeType edgeType_{0}; EdgeSchema schema_; diff --git a/src/executor/InsertVertexExecutor.cpp b/src/executor/InsertVertexExecutor.cpp index 4507c69f57e301ac311c52cbd4dcdc415395d978..9788e461de3db97021667f9c6d04a9970aacf6d2 100644 --- a/src/executor/InsertVertexExecutor.cpp +++ b/src/executor/InsertVertexExecutor.cpp @@ -18,6 +18,8 @@ InsertVertexExecutor::InsertVertexExecutor(Sentence *sentence, Status InsertVertexExecutor::prepare() { + expCtx_ = std::make_unique<ExpressionContext>(); + expCtx_->setStorageClient(ectx()->getStorageClient()); return Status::OK(); } @@ -75,12 +77,16 @@ Status InsertVertexExecutor::check() { return Status::OK(); } - StatusOr<std::vector<storage::cpp2::Vertex>> InsertVertexExecutor::prepareVertices() { + expCtx_->setStorageClient(ectx()->getStorageClient()); + expCtx_->setSpace(spaceId_); + std::vector<storage::cpp2::Vertex> vertices(rows_.size()); for (auto i = 0u; i < rows_.size(); i++) { auto *row = rows_[i]; auto rid = row->id(); + rid->setContext(expCtx_.get()); + auto status = rid->prepare(); if (!status.ok()) { return status; @@ -182,9 +188,9 @@ void InsertVertexExecutor::execute() { onError_(std::move(result).status()); return; } - auto future = ectx()->storage()->addVertices(spaceId_, - std::move(result).value(), - overwritable_); + auto future = ectx()->getStorageClient()->addVertices(spaceId_, + std::move(result).value(), + overwritable_); auto *runner = ectx()->rctx()->runner(); auto cb = [this] (auto &&resp) { diff --git a/src/executor/InsertVertexExecutor.h b/src/executor/InsertVertexExecutor.h index 79b180ea4b12f6f5d8369fd3e121fd7712e876c5..ec1be0a6a2428ed2b1c0b1cb1442b53294515589 100644 --- a/src/executor/InsertVertexExecutor.h +++ b/src/executor/InsertVertexExecutor.h @@ -32,6 +32,7 @@ private: private: using TagSchema = std::shared_ptr<const meta::SchemaProviderIf>; InsertVertexSentence *sentence_{nullptr}; + std::unique_ptr<ExpressionContext> expCtx_; bool overwritable_{true}; std::vector<VertexRowItem*> rows_; std::vector<TagID> tagIds_; diff --git a/src/executor/UpdateEdgeExecutor.cpp b/src/executor/UpdateEdgeExecutor.cpp index 658e2b6debf565ba05f161c59922b3827e4afbd4..bf3ee975d92c4dab1709352c62e934288d9dc6e9 100644 --- a/src/executor/UpdateEdgeExecutor.cpp +++ b/src/executor/UpdateEdgeExecutor.cpp @@ -201,7 +201,7 @@ void UpdateEdgeExecutor::insertReverselyEdge(storage::cpp2::UpdateResponse &&rpc reverselyEdge.props = ""; edges.emplace_back(reverselyEdge); auto space = ectx()->rctx()->session()->space(); - auto future = ectx()->storage()->addEdges(space, std::move(edges), false); + auto future = ectx()->getStorageClient()->addEdges(space, std::move(edges), false); auto *runner = ectx()->rctx()->runner(); auto cb = [this, updateResp = std::move(rpcResp)] (auto &&resp) mutable { auto completeness = resp.completeness(); @@ -228,12 +228,12 @@ void UpdateEdgeExecutor::execute() { auto space = ectx()->rctx()->session()->space(); std::string filterStr = filter_ ? Expression::encode(filter_) : ""; auto returns = getReturnColumns(); - auto future = ectx()->storage()->updateEdge(space, - edge_, - filterStr, - std::move(updateItems_), - std::move(returns), - insertable_); + auto future = ectx()->getStorageClient()->updateEdge(space, + edge_, + filterStr, + std::move(updateItems_), + std::move(returns), + insertable_); auto *runner = ectx()->rctx()->runner(); auto cb = [this] (auto &&resp) { if (!resp.ok()) { diff --git a/src/executor/UpdateVertexExecutor.cpp b/src/executor/UpdateVertexExecutor.cpp index 402f280dcfff3eecdae4624e85ce84300096d1ad..44f9a3ed33f883a75d8d729018a9e3957d0784f1 100644 --- a/src/executor/UpdateVertexExecutor.cpp +++ b/src/executor/UpdateVertexExecutor.cpp @@ -179,12 +179,12 @@ void UpdateVertexExecutor::execute() { auto spaceId = ectx()->rctx()->session()->space(); std::string filterStr = filter_ ? Expression::encode(filter_) : ""; auto returns = getReturnColumns(); - auto future = ectx()->storage()->updateVertex(spaceId, - vertex_, - filterStr, - std::move(updateItems_), - std::move(returns), - insertable_); + auto future = ectx()->getStorageClient()->updateVertex(spaceId, + vertex_, + filterStr, + std::move(updateItems_), + std::move(returns), + insertable_); auto *runner = ectx()->rctx()->runner(); auto cb = [this] (auto &&resp) { if (!resp.ok()) { diff --git a/src/executor/test/CMakeLists.txt b/src/executor/test/CMakeLists.txt index 92b872a5853745b140d6ab382abbe02ff92d8a20..5a586e464b46c37ad3c77a5ff08c69a2b25a204e 100644 --- a/src/executor/test/CMakeLists.txt +++ b/src/executor/test/CMakeLists.txt @@ -2,6 +2,7 @@ set(GRAPH_TEST_LIBS $<TARGET_OBJECTS:graph_obj> $<TARGET_OBJECTS:graph_thrift_obj> $<TARGET_OBJECTS:storage_service_handler> + $<TARGET_OBJECTS:storage_client> $<TARGET_OBJECTS:storage_thrift_obj> $<TARGET_OBJECTS:common_thrift_obj> $<TARGET_OBJECTS:parser_obj> diff --git a/src/executor/test/DataTest.cpp b/src/executor/test/DataTest.cpp index bc38c9732ecac5e3548d575091c1fe27469d022b..b307ac4e1f9cdfe335c60a41585232bf2ac3156d 100644 --- a/src/executor/test/DataTest.cpp +++ b/src/executor/test/DataTest.cpp @@ -179,6 +179,12 @@ TEST_F(DataTest, InsertVertex) { auto code = client_->execute(cmd, resp); ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); } + { + cpp2::ExecutionResponse resp; + std::string cmd = "INSERT VERTEX person(name, age) VALUES uuid(\"Tom\"):(\"Tom\", 22)"; + auto code = client_->execute(cmd, resp); + ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); + } // One vertex multi tags { cpp2::ExecutionResponse resp; @@ -187,6 +193,13 @@ TEST_F(DataTest, InsertVertex) { auto code = client_->execute(cmd, resp); ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); } + { + cpp2::ExecutionResponse resp; + std::string cmd = "INSERT VERTEX person(name, age),student(grade, number) " + "VALUES uuid(\"Lucy\"):(\"Lucy\", 8, \"three\", 20190901001)"; + auto code = client_->execute(cmd, resp); + ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); + } // Multi vertices multi tags { cpp2::ExecutionResponse resp; @@ -196,6 +209,14 @@ TEST_F(DataTest, InsertVertex) { auto code = client_->execute(cmd, resp); ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); } + { + cpp2::ExecutionResponse resp; + std::string cmd = "INSERT VERTEX person(name, age),student(grade, number) " + "VALUES uuid(\"Laura\"):(\"Laura\", 8, \"three\", 20190901008)," + "uuid(\"Amber\"):(\"Amber\", 9, \"four\", 20180901003)"; + auto code = client_->execute(cmd, resp); + ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); + } // Multi vertices one tag { cpp2::ExecutionResponse resp; @@ -204,6 +225,13 @@ TEST_F(DataTest, InsertVertex) { auto code = client_->execute(cmd, resp); ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); } + { + cpp2::ExecutionResponse resp; + std::string cmd = "INSERT VERTEX person(name, age) " + "VALUES uuid(\"Kitty\"):(\"Kitty\", 8), uuid(\"Peter\"):(\"Peter\", 9)"; + auto code = client_->execute(cmd, resp); + ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); + } { cpp2::ExecutionResponse resp; std::string cmd = "INSERT EDGE schoolmate(likeness) VALUES " @@ -211,6 +239,13 @@ TEST_F(DataTest, InsertVertex) { auto code = client_->execute(cmd, resp); ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); } + { + cpp2::ExecutionResponse resp; + std::string cmd = "INSERT EDGE schoolmate(likeness) VALUES " + "uuid(\"Tom\")->uuid(\"Lucy\"):(85)"; + auto code = client_->execute(cmd, resp); + ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); + } // Insert multi edges { cpp2::ExecutionResponse resp; @@ -220,6 +255,14 @@ TEST_F(DataTest, InsertVertex) { auto code = client_->execute(cmd, resp); ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); } + { + cpp2::ExecutionResponse resp; + std::string cmd = "INSERT EDGE schoolmate(likeness) VALUES " + "uuid(\"Tom\")->uuid(\"Kitty\"):(81)," + "uuid(\"Tom\")->uuid(\"Peter\"):(83)"; + auto code = client_->execute(cmd, resp); + ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); + } // Get result { cpp2::ExecutionResponse resp; @@ -234,6 +277,19 @@ TEST_F(DataTest, InsertVertex) { }; ASSERT_TRUE(verifyResult(resp, expected)); } + { + cpp2::ExecutionResponse resp; + std::string cmd = "GO FROM uuid(\"Tom\") OVER schoolmate YIELD $^.person.name," + "schoolmate.likeness, $$.person.name"; + auto code = client_->execute(cmd, resp); + ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); + std::vector<std::tuple<std::string, int64_t, std::string>> expected = { + {"Tom", 85, "Lucy"}, + {"Tom", 81, "Kitty"}, + {"Tom", 83, "Peter"}, + }; + ASSERT_TRUE(verifyResult(resp, expected)); + } // Get multi tags { cpp2::ExecutionResponse resp; @@ -243,6 +299,14 @@ TEST_F(DataTest, InsertVertex) { auto code = client_->execute(cmd, resp); ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); } + { + cpp2::ExecutionResponse resp; + std::string cmd = "INSERT EDGE schoolmate(likeness) VALUES " + "uuid(\"Lucy\")->uuid(\"Laura\"):(90)," + "uuid(\"Lucy\")->uuid(\"Amber\"):(95)"; + auto code = client_->execute(cmd, resp); + ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); + } { cpp2::ExecutionResponse resp; std::string cmd = "GO FROM hash(\"Lucy\") OVER schoolmate YIELD " @@ -257,6 +321,20 @@ TEST_F(DataTest, InsertVertex) { }; ASSERT_TRUE(verifyResult(resp, expected)); } + { + cpp2::ExecutionResponse resp; + std::string cmd = "GO FROM uuid(\"Lucy\") OVER schoolmate YIELD " + "schoolmate.likeness, $$.person.name," + "$$.student.grade, $$.student.number"; + auto code = client_->execute(cmd, resp); + ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); + using valueType = std::tuple<int64_t, std::string, std::string, int64_t>; + std::vector<valueType> expected = { + {90, "Laura", "three", 20190901008}, + {95, "Amber", "four", 20180901003}, + }; + ASSERT_TRUE(verifyResult(resp, expected)); + } // Multi sentences to insert multi tags { cpp2::ExecutionResponse resp; @@ -267,6 +345,15 @@ TEST_F(DataTest, InsertVertex) { auto code = client_->execute(cmd, resp); ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); } + { + cpp2::ExecutionResponse resp; + std::string cmd = "INSERT VERTEX person(name, age)" + "VALUES uuid(\"Aero\"):(\"Aero\", 8);" + "INSERT VERTEX student(grade, number) " + "VALUES uuid(\"Aero\"):(\"four\", 20190901003)"; + auto code = client_->execute(cmd, resp); + ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); + } { cpp2::ExecutionResponse resp; std::string cmd = "INSERT EDGE schoolmate(likeness) VALUES " @@ -274,6 +361,13 @@ TEST_F(DataTest, InsertVertex) { auto code = client_->execute(cmd, resp); ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); } + { + cpp2::ExecutionResponse resp; + std::string cmd = "INSERT EDGE schoolmate(likeness) VALUES " + "uuid(\"Laura\")->uuid(\"Aero\"):(90)"; + auto code = client_->execute(cmd, resp); + ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); + } // Get result { cpp2::ExecutionResponse resp; @@ -287,6 +381,18 @@ TEST_F(DataTest, InsertVertex) { }; ASSERT_TRUE(verifyResult(resp, expected)); } + { + cpp2::ExecutionResponse resp; + std::string cmd = "GO FROM uuid(\"Laura\") OVER schoolmate " + "YIELD $$.student.number, $$.person.name"; + auto code = client_->execute(cmd, resp); + ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); + using valueType = std::tuple<int64_t, std::string>; + std::vector<valueType> expected{ + {20190901003, "Aero"}, + }; + ASSERT_TRUE(verifyResult(resp, expected)); + } // Test same prop name diff type in diff tags { cpp2::ExecutionResponse resp; @@ -296,6 +402,14 @@ TEST_F(DataTest, InsertVertex) { auto code = client_->execute(cmd, resp); ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); } + { + cpp2::ExecutionResponse resp; + std::string cmd = "INSERT VERTEX person(name, age),employee(name) " + "VALUES uuid(\"Joy\"):(\"Joy\", 18, 123)," + "uuid(\"Petter\"):(\"Petter\", 19, 456)"; + auto code = client_->execute(cmd, resp); + ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); + } { cpp2::ExecutionResponse resp; std::string cmd = "INSERT EDGE schoolmate(likeness) VALUES " @@ -303,6 +417,13 @@ TEST_F(DataTest, InsertVertex) { auto code = client_->execute(cmd, resp); ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); } + { + cpp2::ExecutionResponse resp; + std::string cmd = "INSERT EDGE schoolmate(likeness) VALUES " + "uuid(\"Joy\")->uuid(\"Petter\"):(90)"; + auto code = client_->execute(cmd, resp); + ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); + } { cpp2::ExecutionResponse resp; std::string cmd = "GO FROM hash(\"Joy\") OVER schoolmate YIELD $^.person.name," @@ -314,6 +435,17 @@ TEST_F(DataTest, InsertVertex) { }; ASSERT_TRUE(verifyResult(resp, expected)); } + { + cpp2::ExecutionResponse resp; + std::string cmd = "GO FROM uuid(\"Joy\") OVER schoolmate YIELD $^.person.name," + "schoolmate.likeness, $$.person.name, $$.person.age,$$.employee.name"; + auto code = client_->execute(cmd, resp); + ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); + std::vector<std::tuple<std::string, int64_t, std::string, int64_t, int64_t>> expected = { + {"Joy", 90, "Petter", 19, 456}, + }; + ASSERT_TRUE(verifyResult(resp, expected)); + } // Test same prop name same type in diff tags { cpp2::ExecutionResponse resp; @@ -322,6 +454,13 @@ TEST_F(DataTest, InsertVertex) { auto code = client_->execute(cmd, resp); ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); } + { + cpp2::ExecutionResponse resp; + std::string cmd = "INSERT VERTEX person(name, age),interest(name) " + "VALUES uuid(\"Bob\"):(\"Bob\", 19, \"basketball\")"; + auto code = client_->execute(cmd, resp); + ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); + } { cpp2::ExecutionResponse resp; std::string cmd = "INSERT EDGE schoolmate(likeness) VALUES " @@ -329,6 +468,13 @@ TEST_F(DataTest, InsertVertex) { auto code = client_->execute(cmd, resp); ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); } + { + cpp2::ExecutionResponse resp; + std::string cmd = "INSERT EDGE schoolmate(likeness) VALUES " + "uuid(\"Petter\")->uuid(\"Bob\"):(90)"; + auto code = client_->execute(cmd, resp); + ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); + } { cpp2::ExecutionResponse resp; std::string cmd = "GO FROM hash(\"Petter\") OVER schoolmate " @@ -343,6 +489,20 @@ TEST_F(DataTest, InsertVertex) { }; ASSERT_TRUE(verifyResult(resp, expected)); } + { + cpp2::ExecutionResponse resp; + std::string cmd = "GO FROM uuid(\"Petter\") OVER schoolmate " + "YIELD $^.person.name, $^.employee.name, " + "schoolmate.likeness, $$.person.name," + "$$.interest.name, $$.person.age"; + auto code = client_->execute(cmd, resp); + ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); + using type = std::tuple<std::string, int64_t, int64_t, std::string, std::string, int64_t>; + std::vector<type> expected = { + {"Petter", 456, 90, "Bob", "basketball", 19}, + }; + ASSERT_TRUE(verifyResult(resp, expected)); + } // Insert wrong type { cpp2::ExecutionResponse resp; @@ -392,6 +552,13 @@ TEST_F(DataTest, InsertVertex) { auto code = client_->execute(cmd, resp); ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); } + { + cpp2::ExecutionResponse resp; + std::string cmd = "INSERT VERTEX school(name, create_time) VALUES " + "uuid(\"sun_school\"):(\"sun_school\", \"2010-01-01 10:00:00\")"; + auto code = client_->execute(cmd, resp); + ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); + } { cpp2::ExecutionResponse resp; std::string cmd = "INSERT EDGE study(start_time, end_time) " @@ -400,6 +567,14 @@ TEST_F(DataTest, InsertVertex) { auto code = client_->execute(cmd, resp); ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); } + { + cpp2::ExecutionResponse resp; + std::string cmd = "INSERT EDGE study(start_time, end_time) " + "VALUES uuid(\"Laura\")->uuid(\"sun_school\"):" + "(\"2019-01-01 10:00:00\", now()+3600*24*365*3)"; + auto code = client_->execute(cmd, resp); + ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); + } { cpp2::ExecutionResponse resp; std::string cmd = "GO FROM hash(\"Laura\") OVER study " @@ -412,6 +587,18 @@ TEST_F(DataTest, InsertVertex) { }; ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); } + { + cpp2::ExecutionResponse resp; + std::string cmd = "GO FROM uuid(\"Laura\") OVER study " + "YIELD $$.school.name, study._dst, " + "$$.school.create_time, (string)study.start_time"; + auto code = client_->execute(cmd, resp); + ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); + std::vector<std::tuple<std::string, int64_t, int64_t, std::string>> expected = { + {"sun_school", std::hash<std::string>()("sun_school"), 1262311200, "1535760000"}, + }; + ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); + } { cpp2::ExecutionResponse resp; std::string cmd = "FETCH PROP ON school hash(\"sun_school\") ";; @@ -422,6 +609,16 @@ TEST_F(DataTest, InsertVertex) { }; ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); } + { + cpp2::ExecutionResponse resp; + std::string cmd = "FETCH PROP ON school uuid(\"sun_school\") ";; + auto code = client_->execute(cmd, resp); + ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); + std::vector<std::tuple<std::string, int64_t>> expected = { + {"sun_school", 1262311200}, + }; + ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); + } // TODO: Test insert multi tags, and delete one of them then check other existent } @@ -487,6 +684,68 @@ TEST_F(DataTest, InsertMultiVersionTest) { } } +TEST_F(DataTest, InsertMultiVersionWithUUIDTest) { + // Insert multi version vertex + { + cpp2::ExecutionResponse resp; + std::string cmd = "INSERT VERTEX person(name, age) VALUES " + "uuid(\"Tony\"):(\"Tony\", 18), " + "uuid(\"Mack\"):(\"Mack\", 19)"; + auto code = client_->execute(cmd, resp); + ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); + } + { + cpp2::ExecutionResponse resp; + std::string cmd = "INSERT VERTEX person(name, age) VALUES " + "uuid(\"Mack\"):(\"Mack\", 20)"; + auto code = client_->execute(cmd, resp); + ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); + } + { + cpp2::ExecutionResponse resp; + std::string cmd = "INSERT VERTEX person(name, age) VALUES " + "uuid(\"Mack\"):(\"Mack\", 21)"; + auto code = client_->execute(cmd, resp); + ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); + } + // Insert multi version edge + { + cpp2::ExecutionResponse resp; + std::string cmd = "INSERT EDGE schoolmate(likeness) VALUES " + "uuid(\"Tony\")->uuid(\"Mack\")@1:(1)"; + auto code = client_->execute(cmd, resp); + ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); + } + { + cpp2::ExecutionResponse resp; + std::string cmd = "INSERT EDGE schoolmate(likeness) VALUES " + "uuid(\"Tony\")->uuid(\"Mack\")@1:(2)"; + auto code = client_->execute(cmd, resp); + ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); + } + { + cpp2::ExecutionResponse resp; + std::string cmd = "INSERT EDGE schoolmate(likeness) VALUES " + "uuid(\"Tony\")->uuid(\"Mack\")@1:(3)"; + auto code = client_->execute(cmd, resp); + ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); + } + // Get result + { + cpp2::ExecutionResponse resp; + std::string cmd = "GO FROM uuid(\"Tony\") OVER schoolmate " + "YIELD $$.person.name, $$.person.age, schoolmate.likeness"; + auto code = client_->execute(cmd, resp); + ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); + using valueType = std::tuple<std::string, int64_t, int64_t>; + // Get the latest result + std::vector<valueType> expected{ + {"Mack", 21, 3}, + }; + ASSERT_TRUE(verifyResult(resp, expected)); + } +} + TEST_F(DataTest, FindTest) { { cpp2::ExecutionResponse resp; diff --git a/src/executor/test/FetchEdgesTest.cpp b/src/executor/test/FetchEdgesTest.cpp index efc4239d0b64be3e832f4907b3f8ef7ea77cac21..bb382890c386d901d730d3d95f1092ca567165b2 100644 --- a/src/executor/test/FetchEdgesTest.cpp +++ b/src/executor/test/FetchEdgesTest.cpp @@ -163,8 +163,23 @@ 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 hash(\"%s\")->hash(\"%s\")" - " YIELD serve.start_year, serve.end_year"; + auto *fmt = "FETCH PROP ON serve hash(\"%s\")->hash(\"%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); + 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)); + } + { + cpp2::ExecutionResponse resp; + 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\") " + "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); ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); @@ -236,6 +251,20 @@ TEST_F(FetchEdgesTest, noYield) { }; ASSERT_TRUE(verifyResult(resp, expected)); } + { + cpp2::ExecutionResponse resp; + 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 query = folly::stringPrintf(fmt, player.name().c_str(), team.name().c_str()); + 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)); + } } TEST_F(FetchEdgesTest, distinct) { @@ -347,22 +376,22 @@ TEST_F(FetchEdgesTest, noInput) { TEST_F(FetchEdgesTest, syntaxError) { { cpp2::ExecutionResponse resp; - auto query = "FETCH PROP ON serve hash(\"Boris Diaw\")->hash(\"Spurs\")" - " YIELD $^.serve.start_year"; + auto query = "FETCH PROP ON serve hash(\"Boris Diaw\")->hash(\"Spurs\") " + "YIELD $^.serve.start_year"; auto code = client_->execute(query, resp); ASSERT_EQ(cpp2::ErrorCode::E_SYNTAX_ERROR, code); } { cpp2::ExecutionResponse resp; - auto query = "FETCH PROP ON serve hash(\"Boris Diaw\")->hash(\"Spurs\")" - " YIELD $$.serve.start_year"; + auto query = "FETCH PROP ON serve hash(\"Boris Diaw\")->hash(\"Spurs\") " + "YIELD $$.serve.start_year"; auto code = client_->execute(query, resp); ASSERT_EQ(cpp2::ErrorCode::E_SYNTAX_ERROR, code); } { cpp2::ExecutionResponse resp; - auto query = "FETCH PROP ON serve hash(\"Boris Diaw\")->hash(\"Spurs\")" - " YIELD abc.start_year"; + auto query = "FETCH PROP ON serve hash(\"Boris Diaw\")->hash(\"Spurs\") " + "YIELD abc.start_year"; auto code = client_->execute(query, resp); ASSERT_EQ(cpp2::ErrorCode::E_SYNTAX_ERROR, code); } @@ -371,8 +400,16 @@ TEST_F(FetchEdgesTest, syntaxError) { TEST_F(FetchEdgesTest, nonExistEdge) { { cpp2::ExecutionResponse resp; - auto query = "FETCH PROP ON serve hash(\"Zion Williamson\")->hash(\"Spurs\")" - " YIELD serve.start_year"; + auto query = "FETCH PROP ON serve hash(\"Zion Williamson\")->hash(\"Spurs\") " + "YIELD serve.start_year"; + auto code = client_->execute(query, resp); + ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); + ASSERT_EQ(nullptr, resp.get_rows()); + } + { + cpp2::ExecutionResponse resp; + auto query = "FETCH PROP ON serve uuid(\"Zion Williamson\")->hash(\"Spurs\") " + "YIELD serve.start_year"; auto code = client_->execute(query, resp); ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); ASSERT_EQ(nullptr, resp.get_rows()); diff --git a/src/executor/test/FetchVerticesTest.cpp b/src/executor/test/FetchVerticesTest.cpp index 61f8220692b5a571fe342ec96cd5c8d3bdf9a1f2..713a2926bd2e7d7714f2ca521f2c322ce002c8bf 100644 --- a/src/executor/test/FetchVerticesTest.cpp +++ b/src/executor/test/FetchVerticesTest.cpp @@ -127,8 +127,8 @@ TEST_F(FetchVerticesTest, base) { { cpp2::ExecutionResponse resp; auto &player = players_["Boris Diaw"]; - auto *fmt = "FETCH PROP ON player hash(\"%s\")" - " YIELD player.name, player.age"; + auto *fmt = "FETCH PROP ON player hash(\"%s\") " + "YIELD player.name, player.age"; auto query = folly::stringPrintf(fmt, player.name().c_str()); auto code = client_->execute(query, resp); ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); @@ -143,6 +143,19 @@ TEST_F(FetchVerticesTest, base) { }; ASSERT_TRUE(verifyResult(resp, expected)); } + { + cpp2::ExecutionResponse resp; + auto &player = players_["Boris Diaw"]; + auto *fmt = "FETCH PROP ON player uuid(\"%s\") " + "YIELD player.name, player.age"; + auto query = folly::stringPrintf(fmt, player.name().c_str()); + 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)); + } } TEST_F(FetchVerticesTest, noYield) { @@ -182,6 +195,18 @@ TEST_F(FetchVerticesTest, noYield) { }; ASSERT_TRUE(verifyResult(resp, expected)); } + { + cpp2::ExecutionResponse resp; + auto &player = players_["Boris Diaw"]; + auto *fmt = "FETCH PROP ON player uuid(\"%s\")"; + auto query = folly::stringPrintf(fmt, player.name().c_str()); + 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)); + } } TEST_F(FetchVerticesTest, distinct) { diff --git a/src/executor/test/TraverseTestBase.h b/src/executor/test/TraverseTestBase.h index 4bc53d6914d55ad633d5a7a30b53ba6939d26ab7..94d75b2797eef176cd9236ea22f7f95e5f725586 100644 --- a/src/executor/test/TraverseTestBase.h +++ b/src/executor/test/TraverseTestBase.h @@ -675,6 +675,31 @@ AssertionResult TraverseTestBase::prepareData() { << static_cast<int32_t>(code); } } + { + // Insert vertices `player' with uuid + cpp2::ExecutionResponse resp; + std::string query; + query.reserve(1024); + query += "INSERT VERTEX player(name, age) VALUES "; + for (auto &player : players_) { + query += "uuid(\""; + query += player.name(); + query += "\"): "; + query += "("; + query += "\""; + query += player.name(); + query += "\""; + query += ","; + query += std::to_string(player.age()); + query += "),\n\t"; + } + query.resize(query.size() - 3); + auto code = client_->execute(query, resp); + if (code != cpp2::ErrorCode::SUCCEEDED) { + return TestError() << "Insert `players' failed: " + << static_cast<int32_t>(code); + } + } { // Insert vertices `team' cpp2::ExecutionResponse resp; @@ -702,7 +727,7 @@ AssertionResult TraverseTestBase::prepareData() { cpp2::ExecutionResponse resp; std::string query; query.reserve(1024); - query += "INSERT EDGE serve(start_year, end_year) VALUES"; + query += "INSERT EDGE serve(start_year, end_year) VALUES "; for (auto &player : players_) { for (auto &serve : player.serves()) { auto &team = std::get<0>(serve); @@ -726,6 +751,36 @@ AssertionResult TraverseTestBase::prepareData() { << static_cast<int32_t>(code); } } + { + // Insert edges `serve' with uuid + cpp2::ExecutionResponse resp; + std::string query; + query.reserve(1024); + query += "INSERT EDGE serve(start_year, end_year) VALUES "; + for (auto &player : players_) { + for (auto &serve : player.serves()) { + auto &team = std::get<0>(serve); + auto startYear = std::get<1>(serve); + auto endYear = std::get<2>(serve); + query += "uuid(\""; + query += player.name(); + query += "\") -> "; + query += std::to_string(teams_[team].vid()); + query += ": "; + query += "("; + query += std::to_string(startYear); + query += ", "; + query += std::to_string(endYear); + query += "),\n\t"; + } + } + query.resize(query.size() - 3); + auto code = client_->execute(query, resp); + if (code != cpp2::ErrorCode::SUCCEEDED) { + return TestError() << "Insert `serve' failed: " + << static_cast<int32_t>(code); + } + } { // Insert edges `like' cpp2::ExecutionResponse resp; @@ -752,6 +807,33 @@ AssertionResult TraverseTestBase::prepareData() { << static_cast<int32_t>(code); } } + { + // Insert edges `like' with uuid + cpp2::ExecutionResponse resp; + std::string query; + query.reserve(1024); + query += "INSERT EDGE like(likeness) VALUES "; + for (auto &player : players_) { + for (auto &like : player.likes()) { + auto &other = std::get<0>(like); + auto likeness = std::get<1>(like); + query += "uuid(\""; + query += player.name(); + query += "\") -> uuid(\""; + query += players_[other].name(); + query += "\"): "; + query += "("; + query += std::to_string(likeness); + query += "),\n\t"; + } + } + query.resize(query.size() - 3); + auto code = client_->execute(query, resp); + if (code != cpp2::ErrorCode::SUCCEEDED) { + return TestError() << "Insert `like' failed: " + << static_cast<int32_t>(code); + } + } return TestOK(); } diff --git a/src/parser/parser.yy b/src/parser/parser.yy index 47e90f650bfd3d8f61047fe62d0e1a5212bc06df..8499b549df6c582c2810df6541cd8eb1e9a754a4 100644 --- a/src/parser/parser.yy +++ b/src/parser/parser.yy @@ -98,7 +98,7 @@ class GraphScanner; %token KW_EDGE KW_EDGES KW_STEPS KW_OVER KW_UPTO KW_REVERSELY KW_SPACE KW_DELETE KW_FIND %token KW_INT KW_BIGINT KW_DOUBLE KW_STRING KW_BOOL KW_TAG KW_TAGS KW_UNION KW_INTERSECT KW_MINUS %token KW_NO KW_OVERWRITE KW_IN KW_DESCRIBE KW_DESC KW_SHOW KW_HOSTS KW_TIMESTAMP KW_ADD -%token KW_PARTITION_NUM KW_REPLICA_FACTOR KW_DROP KW_REMOVE KW_SPACES KW_INGEST +%token KW_PARTITION_NUM KW_REPLICA_FACTOR KW_DROP KW_REMOVE KW_SPACES KW_INGEST KW_UUID %token KW_IF KW_NOT KW_EXISTS KW_WITH KW_FIRSTNAME KW_LASTNAME KW_EMAIL KW_PHONE KW_USER KW_USERS %token KW_PASSWORD KW_CHANGE KW_ROLE KW_GOD KW_ADMIN KW_GUEST KW_GRANT KW_REVOKE KW_ON %token KW_ROLES KW_BY KW_DOWNLOAD KW_HDFS @@ -133,6 +133,7 @@ class GraphScanner; %type <expr> vid_ref_expression %type <expr> vid %type <expr> function_call_expression +%type <expr> uuid_expression %type <argument_list> argument_list %type <type> type_spec %type <step_clause> step_clause @@ -331,6 +332,12 @@ function_call_expression } ; +uuid_expression + : KW_UUID L_PAREN STRING R_PAREN { + $$ = new UUIDExpression($3); + } + ; + argument_list : %empty { $$ = nullptr; @@ -518,6 +525,9 @@ vid | function_call_expression { $$ = $1; } + | uuid_expression { + $$ = $1; + } ; unary_integer diff --git a/src/parser/scanner.lex b/src/parser/scanner.lex index d80d9c4e4395b0f68d4c4a4ee4f4ef968f4d2894..b6755139462e3b88d578c8323306e12c88dc5987 100644 --- a/src/parser/scanner.lex +++ b/src/parser/scanner.lex @@ -119,6 +119,7 @@ PROP ([Pp][Rr][Oo][Pp]) ALL ([Aa][Ll][Ll]) BALANCE ([Bb][Aa][Ll][Aa][Nn][Cc][Ee]) LEADER ([Ll][Ee][Aa][Dd][Ee][Rr]) +UUID ([Uu][Uu][Ii][Dd]) OF ([Oo][Ff]) DATA ([Dd][Aa][Tt][Aa]) @@ -230,6 +231,7 @@ IP_OCTET ([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]) {ALL} { return TokenType::KW_ALL; } {BALANCE} { return TokenType::KW_BALANCE; } {LEADER} { return TokenType::KW_LEADER; } +{UUID} { return TokenType::KW_UUID; } {DATA} { return TokenType::KW_DATA; } "." { return TokenType::DOT; } diff --git a/src/parser/test/CMakeLists.txt b/src/parser/test/CMakeLists.txt index 7783b23e8c6ac77d728815ccb8698e8a41760198..7a381d4f38afefed7348bd15d7580721dced826f 100644 --- a/src/parser/test/CMakeLists.txt +++ b/src/parser/test/CMakeLists.txt @@ -1,29 +1,38 @@ set(PARSER_TEST_LIBS $<TARGET_OBJECTS:parser_obj> $<TARGET_OBJECTS:filter_obj> - $<TARGET_OBJECTS:base_obj> $<TARGET_OBJECTS:network_obj> $<TARGET_OBJECTS:fs_obj> $<TARGET_OBJECTS:time_obj> + $<TARGET_OBJECTS:gflags_man_obj> + $<TARGET_OBJECTS:schema_obj> + $<TARGET_OBJECTS:meta_client> + $<TARGET_OBJECTS:meta_thrift_obj> + $<TARGET_OBJECTS:storage_client> + $<TARGET_OBJECTS:storage_thrift_obj> + $<TARGET_OBJECTS:common_thrift_obj> + $<TARGET_OBJECTS:thrift_obj> + $<TARGET_OBJECTS:thread_obj> + $<TARGET_OBJECTS:base_obj> ) nebula_add_test( NAME parser_test SOURCES ParserTest.cpp OBJECTS ${PARSER_TEST_LIBS} - LIBRARIES gtest gtest_main + LIBRARIES gtest gtest_main ${THRIFT_LIBRARIES} wangle ) nebula_add_test( NAME scanner_test SOURCES ScannerTest.cpp OBJECTS ${PARSER_TEST_LIBS} - LIBRARIES gtest gtest_main + LIBRARIES gtest gtest_main ${THRIFT_LIBRARIES} wangle ) nebula_add_executable( NAME parser_benchmark SOURCES ParserBenchmark.cpp OBJECTS ${PARSER_TEST_LIBS} - LIBRARIES follybenchmark boost_regex + LIBRARIES follybenchmark boost_regex ${THRIFT_LIBRARIES} wangle ) diff --git a/src/parser/test/ParserTest.cpp b/src/parser/test/ParserTest.cpp index 6b57bb700df5de771b201e86cb7a06a32b1d24d1..c22acc47e7cd75968ee24f71d41f6c450d4ea6f1 100644 --- a/src/parser/test/ParserTest.cpp +++ b/src/parser/test/ParserTest.cpp @@ -503,6 +503,20 @@ TEST(Parser, InsertVertex) { auto result = parser.parse(query); ASSERT_TRUE(result.ok()) << result.status(); } + { + GQLParser parser; + std::string query = "INSERT VERTEX person(name,age,married,salary,create_time) " + "VALUES hash(\"dutor\"):(\"dutor\", 30, true, 3.14, 1551331900)"; + auto result = parser.parse(query); + ASSERT_TRUE(result.ok()) << result.status(); + } + { + GQLParser parser; + std::string query = "INSERT VERTEX person(name,age,married,salary,create_time) " + "VALUES uuid(\"dutor\"):(\"dutor\", 30, true, 3.14, 1551331900)"; + auto result = parser.parse(query); + ASSERT_TRUE(result.ok()) << result.status(); + } // Test insert empty value { GQLParser parser; @@ -527,6 +541,20 @@ TEST(Parser, InsertVertex) { auto result = parser.parse(query); ASSERT_TRUE(result.status().isSyntaxError()); } + { + GQLParser parser; + std::string query = "INSERT VERTEX person(name, age) " + "VALUES hash(\"dutor\"):(\'dutor, 30)"; + auto result = parser.parse(query); + ASSERT_TRUE(result.status().isSyntaxError()); + } + { + GQLParser parser; + std::string query = "INSERT VERTEX person(name, age) " + "VALUES uuid(\"dutor\"):(\'dutor, 30)"; + auto result = parser.parse(query); + ASSERT_TRUE(result.status().isSyntaxError()); + } } TEST(Parser, UpdateVertex) { @@ -588,6 +616,20 @@ TEST(Parser, InsertEdge) { auto result = parser.parse(query); ASSERT_TRUE(result.ok()) << result.status(); } + { + GQLParser parser; + std::string query = "INSERT EDGE transfer(amount, time) " + "VALUES hash(\"from\")->hash(\"to\"):(3.75, 1537408527)"; + auto result = parser.parse(query); + ASSERT_TRUE(result.ok()) << result.status(); + } + { + GQLParser parser; + std::string query = "INSERT EDGE transfer(amount, time) " + "VALUES uuid(\"from\")->uuid(\"to\"):(3.75, 1537408527)"; + auto result = parser.parse(query); + ASSERT_TRUE(result.ok()) << result.status(); + } // multi edge { GQLParser parser; @@ -1040,6 +1082,12 @@ TEST(Parser, UnreservedKeywords) { auto result = parser.parse(query); ASSERT_TRUE(result.ok()) << result.status(); } + { + GQLParser parser; + std::string query = "GO FROM UUID(\"tom\") OVER guest WHERE $-.EMAIL"; + auto result = parser.parse(query); + ASSERT_TRUE(result.ok()) << result.status(); + } { GQLParser parser; std::string query = "GO FROM 123 OVER like YIELD $$.tag1.EMAIL, like.users," @@ -1048,12 +1096,26 @@ TEST(Parser, UnreservedKeywords) { auto result = parser.parse(query); ASSERT_TRUE(result.ok()) << result.status(); } + { + GQLParser parser; + std::string query = "GO FROM UUID(\"tom\") OVER like YIELD $$.tag1.EMAIL, like.users," + "like._src, like._dst, like.type, $^.tag2.SPACE " + "| ORDER BY $-.SPACE"; + auto result = parser.parse(query); + ASSERT_TRUE(result.ok()) << result.status(); + } { GQLParser parser; std::string query = "$var = GO FROM 123 OVER like;GO FROM $var.SPACE OVER like"; auto result = parser.parse(query); ASSERT_TRUE(result.ok()) << result.status(); } + { + GQLParser parser; + std::string query = "$var = GO FROM UUID(\"tom\") OVER like;GO FROM $var.SPACE OVER like"; + auto result = parser.parse(query); + ASSERT_TRUE(result.ok()) << result.status(); + } } TEST(Parser, Annotation) { diff --git a/src/parser/test/ScannerTest.cpp b/src/parser/test/ScannerTest.cpp index cc35e2b07a744d3357a5fdb0b601462dd4ceb1ed..aad3e44c2d9bda527224b70cd98eca3b74f225be 100644 --- a/src/parser/test/ScannerTest.cpp +++ b/src/parser/test/ScannerTest.cpp @@ -379,6 +379,12 @@ TEST(Scanner, Basic) { CHECK_SEMANTIC_TYPE("LEADER", TokenType::KW_LEADER), CHECK_SEMANTIC_TYPE("Leader", TokenType::KW_LEADER), CHECK_SEMANTIC_TYPE("leader", TokenType::KW_LEADER), + CHECK_SEMANTIC_TYPE("FETCH", TokenType::KW_FETCH), + CHECK_SEMANTIC_TYPE("Fetch", TokenType::KW_FETCH), + CHECK_SEMANTIC_TYPE("fetch", TokenType::KW_FETCH), + CHECK_SEMANTIC_TYPE("UUID", TokenType::KW_UUID), + CHECK_SEMANTIC_TYPE("Uuid", TokenType::KW_UUID), + CHECK_SEMANTIC_TYPE("uuid", TokenType::KW_UUID), CHECK_SEMANTIC_TYPE("OF", TokenType::KW_OF), CHECK_SEMANTIC_TYPE("Of", TokenType::KW_OF), CHECK_SEMANTIC_TYPE("of", TokenType::KW_OF),