diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index e3ac97aaa3b3fa1c1b9c6a267a315a519e7034a7..14562bcf74185d212bd2f5e8113f6c9b258eceef 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -7,16 +7,17 @@ on: - master - 'v[0-9]+.*' +defaults: + run: + shell: bash + jobs: lint: name: lint if: ${{ contains(github.event.pull_request.labels.*.name, 'ready-for-testing') }} runs-on: ubuntu-latest - defaults: - run: - shell: bash outputs: - num_source_files: ${{ steps.filter-source-files.outputs.num_source_files }} + has_source_files: ${{ steps.filter-source-files.outputs.has_source_files }} steps: - uses: actions/checkout@v2 with: @@ -29,17 +30,14 @@ jobs: id: filter-source-files run: | diff_commits=$(git log --oneline -n 1 | cut -d' ' -f1,5) - num_source_files=$(git --no-pager diff --name-only $diff_commits | grep '^src\|^CMakeLists.txt\|^cmake\|^.github/workflows' | wc -l) - echo "::set-output name=num_source_files::${num_source_files}" + source_files=$(git --no-pager diff --name-only $diff_commits | grep '^src\|^tests\|^CMakeLists.txt\|^cmake\|^.github/workflows') + echo "::set-output name=has_source_files::$([[ "$source_files" == "" ]] && echo 0 || echo 1)" build: name: build needs: lint - if: ${{ needs.lint.outputs.num_source_files != 0 }} + if: ${{ needs.lint.outputs.has_source_files != 0 }} runs-on: self-hosted - defaults: - run: - shell: bash strategy: fail-fast: false matrix: diff --git a/src/context/Result.h b/src/context/Result.h index 01ccbb0bffdb560c99e3a97d60123394520ea5d4..9dd78c32e24ca4ca0c99af9e7a48f347c58c89a5 100644 --- a/src/context/Result.h +++ b/src/context/Result.h @@ -42,6 +42,10 @@ public: return core_.state; } + size_t size() const { + return core_.iter->size(); + } + std::unique_ptr<Iterator> iter() const { return core_.iter->copy(); } diff --git a/src/context/test/CMakeLists.txt b/src/context/test/CMakeLists.txt index 4bc6f73fd5eca11340a87bba1661bbb7cc4e703f..bcbe73fd176908484f9b185497e9f015247b8108 100644 --- a/src/context/test/CMakeLists.txt +++ b/src/context/test/CMakeLists.txt @@ -5,12 +5,24 @@ SET(CONTEXT_TEST_LIBS $<TARGET_OBJECTS:common_datatypes_obj> + $<TARGET_OBJECTS:common_expression_obj> + $<TARGET_OBJECTS:common_function_manager_obj> + $<TARGET_OBJECTS:common_fs_obj> $<TARGET_OBJECTS:common_time_obj> $<TARGET_OBJECTS:common_base_obj> $<TARGET_OBJECTS:common_thread_obj> + $<TARGET_OBJECTS:common_conf_obj> + $<TARGET_OBJECTS:common_file_based_cluster_id_man_obj> + $<TARGET_OBJECTS:common_meta_obj> + $<TARGET_OBJECTS:common_meta_client_obj> + $<TARGET_OBJECTS:common_meta_thrift_obj> + $<TARGET_OBJECTS:common_thrift_obj> $<TARGET_OBJECTS:common_common_thrift_obj> $<TARGET_OBJECTS:common_graph_thrift_obj> + $<TARGET_OBJECTS:common_storage_thrift_obj> + $<TARGET_OBJECTS:util_obj> $<TARGET_OBJECTS:context_obj> + $<TARGET_OBJECTS:parser_obj> $<TARGET_OBJECTS:graph_flags_obj> $<TARGET_OBJECTS:session_obj> $<TARGET_OBJECTS:planner_obj> @@ -28,6 +40,9 @@ nebula_add_test( LIBRARIES ${THRIFT_LIBRARIES} gtest + wangle + proxygenhttpserver + proxygenlib ) nebula_add_executable( @@ -41,4 +56,7 @@ nebula_add_executable( follybenchmark boost_regex ${THRIFT_LIBRARIES} + wangle + proxygenhttpserver + proxygenlib ) diff --git a/src/exec/Executor.cpp b/src/exec/Executor.cpp index a69641fcd0d287bdbea70cc8ec4a952c15207fe6..b37e60c1f6eaebe2a19cd39669923546f4de3ba0 100644 --- a/src/exec/Executor.cpp +++ b/src/exec/Executor.cpp @@ -24,8 +24,8 @@ #include "exec/logic/StartExecutor.h" #include "exec/maintain/EdgeExecutor.h" #include "exec/maintain/TagExecutor.h" -#include "exec/mutate/InsertExecutor.h" #include "exec/mutate/DeleteExecutor.h" +#include "exec/mutate/InsertExecutor.h" #include "exec/mutate/UpdateExecutor.h" #include "exec/query/AggregateExecutor.h" #include "exec/query/DataCollectExecutor.h" @@ -465,17 +465,13 @@ folly::Future<Status> Executor::error(Status status) const { } Status Executor::finish(Result &&result) { + numRows_ = result.size(); ectx_->setResult(node()->varName(), std::move(result)); return Status::OK(); } Status Executor::finish(Value &&value) { - ectx_->setResult(node()->varName(), - ResultBuilder() - .value(std::move(value)) - .iter(Iterator::Kind::kDefault) - .finish()); - return Status::OK(); + return finish(ResultBuilder().value(std::move(value)).iter(Iterator::Kind::kDefault).finish()); } folly::Executor *Executor::runner() const { diff --git a/src/exec/query/ProjectExecutor.cpp b/src/exec/query/ProjectExecutor.cpp index 8c296cc41151d65466848a843b690fafe9ecb6e0..3b2caa1a23e270b494aa7dbb16952fe4232ff937 100644 --- a/src/exec/query/ProjectExecutor.cpp +++ b/src/exec/query/ProjectExecutor.cpp @@ -33,7 +33,6 @@ folly::Future<Status> ProjectExecutor::execute() { } ds.rows.emplace_back(std::move(row)); } - numRows_ = ds.rows.size(); return finish(ResultBuilder().value(Value(std::move(ds))).finish()); } diff --git a/src/parser/CMakeLists.txt b/src/parser/CMakeLists.txt index 544cde7b2a35b86f3196a255184b95b0f83d32da..de3b634dd7c46169929911cfe8ff3ea24bd60cff 100644 --- a/src/parser/CMakeLists.txt +++ b/src/parser/CMakeLists.txt @@ -20,6 +20,7 @@ nebula_add_library( ${FLEX_Scanner_OUTPUTS} ${BISON_Parser_OUTPUTS} Clauses.cpp + EdgeKey.cpp SequentialSentences.cpp MaintainSentences.cpp TraverseSentences.cpp diff --git a/src/parser/EdgeKey.cpp b/src/parser/EdgeKey.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1596e7922f1787262506057b97f29901e03ffc37 --- /dev/null +++ b/src/parser/EdgeKey.cpp @@ -0,0 +1,49 @@ +/* Copyright (c) 2020 vesoft inc. All rights reserved. + * + * This source code is licensed under Apache 2.0 License, + * attached with Common Clause Condition 1.0, found in the LICENSES directory. + */ + +#include "parser/EdgeKey.h" + +#include "common/expression/Expression.h" + +namespace nebula { + +std::string EdgeKey::toString() const { + return folly::stringPrintf( + "%s->%s@%ld", srcid_->toString().c_str(), dstid_->toString().c_str(), rank_); +} + +std::string EdgeKeys::toString() const { + std::string buf; + buf.reserve(256); + for (auto &key : keys_) { + buf += key->toString(); + buf += ","; + } + if (!buf.empty()) { + buf.resize(buf.size() - 1); + } + + return buf; +} + +std::string EdgeKeyRef::toString() const { + std::string buf; + buf.reserve(256); + if (srcid_ != nullptr) { + buf += srcid_->toString(); + } + if (dstid_ != nullptr) { + buf += "->"; + buf += dstid_->toString(); + } + if (rank_ != nullptr) { + buf += "@"; + buf += rank_->toString(); + } + return buf; +} + +} // namespace nebula diff --git a/src/parser/EdgeKey.h b/src/parser/EdgeKey.h new file mode 100644 index 0000000000000000000000000000000000000000..065275009f37079dc5da770ab160b986033d1173 --- /dev/null +++ b/src/parser/EdgeKey.h @@ -0,0 +1,119 @@ +/* Copyright (c) 2020 vesoft inc. All rights reserved. + * + * This source code is licensed under Apache 2.0 License, + * attached with Common Clause Condition 1.0, found in the LICENSES directory. + */ + +#ifndef PARSER_EDGEKEY_H_ +#define PARSER_EDGEKEY_H_ + +#include <algorithm> +#include <cstdint> +#include <memory> +#include <string> +#include <unordered_set> +#include <vector> + +#include "common/thrift/ThriftTypes.h" + +namespace nebula { + +class Expression; + +class EdgeKey final { +public: + EdgeKey(Expression *srcid, Expression *dstid, int64_t rank) { + srcid_.reset(srcid); + dstid_.reset(dstid); + rank_ = rank; + } + + Expression *srcid() const { + return srcid_.get(); + } + + Expression *dstid() const { + return dstid_.get(); + } + + int64_t rank() { + return rank_; + } + + std::string toString() const; + +private: + std::unique_ptr<Expression> srcid_; + std::unique_ptr<Expression> dstid_; + EdgeRanking rank_; +}; + +class EdgeKeys final { +public: + EdgeKeys() = default; + + void addEdgeKey(EdgeKey *key) { + keys_.emplace_back(key); + } + + std::vector<EdgeKey *> keys() const { + std::vector<EdgeKey *> result; + result.resize(keys_.size()); + auto get = [](const auto &key) { return key.get(); }; + std::transform(keys_.begin(), keys_.end(), result.begin(), get); + return result; + } + + std::string toString() const; + +private: + std::vector<std::unique_ptr<EdgeKey>> keys_; +}; + +class EdgeKeyRef final { +public: + EdgeKeyRef(Expression *srcid, Expression *dstid, Expression *rank, bool isInputExpr = true) { + srcid_.reset(srcid); + dstid_.reset(dstid); + rank_.reset(rank); + isInputExpr_ = isInputExpr; + } + + Expression *srcid() const { + return srcid_.get(); + } + + Expression *dstid() const { + return dstid_.get(); + } + + Expression *rank() const { + return rank_.get(); + } + + Expression *type() const { + return type_.get(); + } + + void setType(Expression *type) { + type_.reset(type); + } + + bool isInputExpr() const { + return isInputExpr_; + } + + std::string toString() const; + +private: + std::unique_ptr<Expression> srcid_; + std::unique_ptr<Expression> dstid_; + std::unique_ptr<Expression> rank_; + std::unique_ptr<Expression> type_; + std::unordered_set<std::string> uniqVar_; + bool isInputExpr_; +}; + +} // namespace nebula + +#endif // PARSER_EDGEKEY_H_ diff --git a/src/parser/MutateSentences.h b/src/parser/MutateSentences.h index 949412f12772224f564f27f79fbc353cd5bc2fe3..48fcc79703ee7caab5568197209e94e0e5126b43 100644 --- a/src/parser/MutateSentences.h +++ b/src/parser/MutateSentences.h @@ -9,6 +9,7 @@ #include "common/base/Base.h" #include "common/base/StatusOr.h" #include "parser/Clauses.h" +#include "parser/EdgeKey.h" #include "parser/Sentence.h" namespace nebula { diff --git a/src/parser/Sentence.h b/src/parser/Sentence.h index 3a40ad9192b139933a2a78bed62ce74ef59e3709..7e1f4b87cc7e828e8bfa3a980f63993eaedf1dc8 100644 --- a/src/parser/Sentence.h +++ b/src/parser/Sentence.h @@ -144,106 +144,6 @@ inline std::ostream& operator<<(std::ostream &os, Sentence::Kind kind) { return os << static_cast<uint32_t>(kind); } -class EdgeKey final { -public: - EdgeKey(Expression *srcid, Expression *dstid, int64_t rank) { - srcid_.reset(srcid); - dstid_.reset(dstid); - rank_ = rank; - } - - Expression* srcid() const { - return srcid_.get(); - } - - Expression* dstid() const { - return dstid_.get(); - } - - int64_t rank() { - return rank_; - } - - std::string toString() const; - -private: - std::unique_ptr<Expression> srcid_; - std::unique_ptr<Expression> dstid_; - EdgeRanking rank_; -}; - -class EdgeKeys final { -public: - EdgeKeys() = default; - - void addEdgeKey(EdgeKey *key) { - keys_.emplace_back(key); - } - - std::vector<EdgeKey*> keys() const { - std::vector<EdgeKey*> result; - result.resize(keys_.size()); - auto get = [](const auto&key) { return key.get(); }; - std::transform(keys_.begin(), keys_.end(), result.begin(), get); - return result; - } - - std::string toString() const; - -private: - std::vector<std::unique_ptr<EdgeKey>> keys_; -}; - -class EdgeKeyRef final { -public: - EdgeKeyRef( - Expression *srcid, - Expression *dstid, - Expression *rank, - bool isInputExpr = true) { - srcid_.reset(srcid); - dstid_.reset(dstid); - rank_.reset(rank); - isInputExpr_ = isInputExpr; - } - - StatusOr<std::string> varname() const; - - Expression* srcid() const { - return srcid_.get(); - } - - Expression* dstid() const { - return dstid_.get(); - } - - Expression* rank() const { - return rank_.get(); - } - - Expression* type() const { - return type_.get(); - } - - void setType(Expression *type) { - type_.reset(type); - } - - bool isInputExpr() const { - return isInputExpr_; - } - - std::string toString() const; - -private: - std::unique_ptr<Expression> srcid_; - std::unique_ptr<Expression> dstid_; - std::unique_ptr<Expression> rank_; - std::unique_ptr<Expression> type_; - std::unordered_set<std::string> uniqVar_; - bool isInputExpr_; -}; - } // namespace nebula #endif // PARSER_SENTENCE_H_ diff --git a/src/parser/TraverseSentences.cpp b/src/parser/TraverseSentences.cpp index 8041537773544187224a3eee522edf6163a7d6e4..fd51e2db613f20b8cc7a3b0f7d89c0e8397938ea 100644 --- a/src/parser/TraverseSentences.cpp +++ b/src/parser/TraverseSentences.cpp @@ -145,41 +145,6 @@ std::string FetchVerticesSentence::toString() const { return buf; } -std::string EdgeKey::toString() const { - return folly::stringPrintf("%s->%s@%ld,", - srcid_->toString().c_str(), dstid_->toString().c_str(), rank_); -} - -std::string EdgeKeys::toString() const { - std::string buf; - buf.reserve(256); - for (auto &key : keys_) { - buf += key->toString(); - } - if (!buf.empty()) { - buf.resize(buf.size() - 1); - } - - return buf; -} - -std::string EdgeKeyRef::toString() const { - std::string buf; - buf.reserve(256); - if (srcid_ != nullptr) { - buf += srcid_->toString(); - } - if (dstid_ != nullptr) { - buf += "->"; - buf += dstid_->toString(); - } - if (rank_ != nullptr) { - buf += "@"; - buf += rank_->toString(); - } - return buf; -} - std::string FetchEdgesSentence::toString() const { std::string buf; buf.reserve(256); diff --git a/src/parser/TraverseSentences.h b/src/parser/TraverseSentences.h index e9a06fad044dbfb13deebac916f66320b1927ae1..a9db4efc63a999c32499deb769ca358c14ea702d 100644 --- a/src/parser/TraverseSentences.h +++ b/src/parser/TraverseSentences.h @@ -7,13 +7,13 @@ #define PARSER_TRAVERSESENTENCES_H_ #include "common/base/Base.h" -#include "parser/Sentence.h" #include "parser/Clauses.h" +#include "parser/EdgeKey.h" #include "parser/MutateSentences.h" +#include "parser/Sentence.h" namespace nebula { - class GoSentence final : public Sentence { public: GoSentence() { diff --git a/src/parser/test/CMakeLists.txt b/src/parser/test/CMakeLists.txt index 203e067cdbf8482a07ead47c2cb7aa37a34d92da..ba1837af79fa1608d0c4bdb576a5ad9ffababec3 100644 --- a/src/parser/test/CMakeLists.txt +++ b/src/parser/test/CMakeLists.txt @@ -19,6 +19,7 @@ set(PARSER_TEST_LIBS $<TARGET_OBJECTS:common_function_manager_obj> $<TARGET_OBJECTS:common_meta_thrift_obj> $<TARGET_OBJECTS:common_graph_thrift_obj> + $<TARGET_OBJECTS:common_storage_thrift_obj> $<TARGET_OBJECTS:common_meta_obj> $<TARGET_OBJECTS:common_meta_client_obj> $<TARGET_OBJECTS:common_conf_obj> diff --git a/src/planner/Admin.cpp b/src/planner/Admin.cpp new file mode 100644 index 0000000000000000000000000000000000000000..796415bd98bd6bd6d915ec91d68bce148729d5eb --- /dev/null +++ b/src/planner/Admin.cpp @@ -0,0 +1,56 @@ + +/* Copyright (c) 2020 vesoft inc. All rights reserved. + * + * This source code is licensed under Apache 2.0 License, + * attached with Common Clause Condition 1.0, found in the LICENSES directory. + */ + +#include "planner/Admin.h" + +#include "common/interface/gen-cpp2/graph_types.h" +#include "util/ToJson.h" + +namespace nebula { +namespace graph { + +std::unique_ptr<cpp2::PlanNodeDescription> CreateSpace::explain() const { + auto desc = SingleInputNode::explain(); + addDescription("ifNotExists", folly::to<std::string>(ifNotExists_), desc.get()); + addDescription("spaceDesc", folly::toJson(util::toJson(props_)), desc.get()); + return desc; +} + +std::unique_ptr<cpp2::PlanNodeDescription> DropSpace::explain() const { + auto desc = SingleInputNode::explain(); + addDescription("spaceName", spaceName_, desc.get()); + addDescription("ifExists", folly::to<std::string>(ifExists_), desc.get()); + return desc; +} + +std::unique_ptr<cpp2::PlanNodeDescription> DescSpace::explain() const { + auto desc = SingleInputNode::explain(); + addDescription("spaceName", spaceName_, desc.get()); + return desc; +} + +std::unique_ptr<cpp2::PlanNodeDescription> ShowCreateSpace::explain() const { + auto desc = SingleInputNode::explain(); + addDescription("spaceName", spaceName_, desc.get()); + return desc; +} + +std::unique_ptr<cpp2::PlanNodeDescription> DropSnapshot::explain() const { + auto desc = SingleInputNode::explain(); + addDescription("snapshotName", snapshotName_, desc.get()); + return desc; +} + +std::unique_ptr<cpp2::PlanNodeDescription> ShowParts::explain() const { + auto desc = SingleInputNode::explain(); + addDescription("spaceId", folly::to<std::string>(spaceId_), desc.get()); + addDescription("partIds", folly::toJson(util::toJson(partIds_)), desc.get()); + return desc; +} + +} // namespace graph +} // namespace nebula diff --git a/src/planner/Admin.h b/src/planner/Admin.h index 188b3b1b32194658e790a7c5c86493bc2e7891d2..1b950233c97f0684ca04fc1e42b42477f48fa9a9 100644 --- a/src/planner/Admin.h +++ b/src/planner/Admin.h @@ -19,6 +19,7 @@ */ namespace nebula { namespace graph { + // TODO: All DDLs, DMLs and DQLs could be used in a single query // which would make them in a single and big execution plan @@ -29,10 +30,6 @@ public: return new ShowHosts(plan, dep); } - std::string explain() const override { - return "ShowHosts"; - } - private: explicit ShowHosts(ExecutionPlan* plan, PlanNode* dep) : SingleDependencyNode(plan, Kind::kShowHosts, dep) {} @@ -50,9 +47,7 @@ public: ifNotExists); } - std::string explain() const override { - return "CreateSpace"; - } + std::unique_ptr<cpp2::PlanNodeDescription> explain() const override; public: const meta::SpaceDesc& getSpaceDesc() const { @@ -73,7 +68,6 @@ private: ifNotExists_ = ifNotExists; } - private: meta::SpaceDesc props_; bool ifNotExists_; @@ -88,9 +82,7 @@ public: return new DropSpace(plan, input, std::move(spaceName), ifExists); } - std::string explain() const override { - return "DropSpace"; - } + std::unique_ptr<cpp2::PlanNodeDescription> explain() const override; const std::string& getSpaceName() const { return spaceName_; @@ -123,9 +115,7 @@ public: return new DescSpace(plan, input, std::move(spaceName)); } - std::string explain() const override { - return "DescSpace"; - } + std::unique_ptr<cpp2::PlanNodeDescription> explain() const override; const std::string& getSpaceName() const { return spaceName_; @@ -149,10 +139,6 @@ public: return new ShowSpaces(plan, input); } - std::string explain() const override { - return "ShowSpaces"; - } - private: explicit ShowSpaces(ExecutionPlan* plan, PlanNode* input) : SingleInputNode(plan, Kind::kShowSpaces, input) {} @@ -160,9 +146,6 @@ private: class Config final : public SingleInputNode { public: - std::string explain() const override { - return "Config"; - } }; class ShowCreateSpace final : public SingleInputNode { @@ -173,9 +156,7 @@ public: return new ShowCreateSpace(plan, input, std::move(spaceName)); } - std::string explain() const override { - return "ShowCreateSpace"; - } + std::unique_ptr<cpp2::PlanNodeDescription> explain() const override; const std::string& getSpaceName() const { return spaceName_; @@ -195,9 +176,6 @@ private: class Balance final : public SingleInputNode { public: - std::string explain() const override { - return "Balance"; - } }; class CreateSnapshot final : public SingleInputNode { @@ -206,10 +184,6 @@ public: return new CreateSnapshot(plan, input); } - std::string explain() const override { - return "CreateSnapshot"; - } - private: explicit CreateSnapshot(ExecutionPlan* plan, PlanNode* input) : SingleInputNode(plan, Kind::kCreateSnapshot, input) {} @@ -223,12 +197,10 @@ public: return new DropSnapshot(plan, input, std::move(snapshotName)); } - std::string explain() const override { - return "DropSnapshot"; - } + std::unique_ptr<cpp2::PlanNodeDescription> explain() const override; const std::string& getShapshotName() const { - return shapshotName_; + return snapshotName_; } private: @@ -236,11 +208,11 @@ private: PlanNode* input, std::string snapshotName) : SingleInputNode(plan, Kind::kDropSnapshot, input) { - shapshotName_ = std::move(snapshotName); + snapshotName_ = std::move(snapshotName); } private: - std::string shapshotName_; + std::string snapshotName_; }; class ShowSnapshots final : public SingleInputNode { @@ -249,10 +221,6 @@ public: return new ShowSnapshots(plan, input); } - std::string explain() const override { - return "ShowSnapshots"; - } - private: explicit ShowSnapshots(ExecutionPlan* plan, PlanNode* input) : SingleInputNode(plan, Kind::kShowSnapshots, input) {} @@ -260,16 +228,10 @@ private: class Download final : public SingleInputNode { public: - std::string explain() const override { - return "Download"; - } }; class Ingest final : public SingleInputNode { public: - std::string explain() const override { - return "Ingest"; - } }; class ShowParts final : public SingleInputNode { @@ -281,9 +243,7 @@ public: return new ShowParts(plan, input, spaceId, std::move(partIds)); } - std::string explain() const override { - return "ShowParts"; - } + std::unique_ptr<cpp2::PlanNodeDescription> explain() const override; GraphSpaceID getSpaceId() const { return spaceId_; @@ -307,6 +267,7 @@ private: GraphSpaceID spaceId_{-1}; std::vector<PartitionID> partIds_; }; + } // namespace graph } // namespace nebula #endif // PLANNER_ADMIN_H_ diff --git a/src/planner/CMakeLists.txt b/src/planner/CMakeLists.txt index 923bcbdfd67627f3d9100383943de16ef6008728..1485a8ea6f72d6eb67467f1c7c6a2cc2f567074a 100644 --- a/src/planner/CMakeLists.txt +++ b/src/planner/CMakeLists.txt @@ -7,9 +7,11 @@ nebula_add_library( planner_obj OBJECT PlanNode.cpp ExecutionPlan.cpp + Admin.cpp Logic.cpp Query.cpp - Mutate.h + Mutate.cpp + Maintain.cpp ) #nebula_add_subdirectory(test) diff --git a/src/planner/ExecutionPlan.cpp b/src/planner/ExecutionPlan.cpp index 90a3625fbae3dfef3776a6fb6afca6da0c9377c5..e2a5cbfc784c8c7edb643eceac92fbd51c4465d2 100644 --- a/src/planner/ExecutionPlan.cpp +++ b/src/planner/ExecutionPlan.cpp @@ -42,17 +42,9 @@ static size_t makePlanNodeDesc(const PlanNode* node, cpp2::PlanDescription* plan size_t planNodeDescPos = planDesc->plan_node_descs.size(); planDesc->node_index_map.emplace(node->id(), planNodeDescPos); - planDesc->plan_node_descs.emplace_back(cpp2::PlanNodeDescription{}); + planDesc->plan_node_descs.emplace_back(std::move(*node->explain())); auto& planNodeDesc = planDesc->plan_node_descs.back(); - planNodeDesc.set_id(node->id()); - planNodeDesc.set_name(PlanNode::toString(node->kind())); - planNodeDesc.set_output_var(node->varName()); - cpp2::Pair p; - p.set_key("description"); - p.set_value(node->explain()); - planNodeDesc.set_description({std::move(p)}); - switch (node->kind()) { case PlanNode::Kind::kStart: { break; @@ -61,7 +53,6 @@ static size_t makePlanNodeDesc(const PlanNode* node, cpp2::PlanDescription* plan case PlanNode::Kind::kIntersect: case PlanNode::Kind::kMinus: { auto bNode = static_cast<const BiInputNode*>(node); - planNodeDesc.set_dependencies({bNode->left()->id(), bNode->right()->id()}); makePlanNodeDesc(bNode->left(), planDesc); makePlanNodeDesc(bNode->right(), planDesc); break; @@ -96,7 +87,6 @@ static size_t makePlanNodeDesc(const PlanNode* node, cpp2::PlanDescription* plan default: { // Other plan nodes have single dependency auto singleDepNode = static_cast<const SingleDependencyNode*>(node); - planNodeDesc.set_dependencies({singleDepNode->dep()->id()}); makePlanNodeDesc(singleDepNode->dep(), planDesc); break; } diff --git a/src/planner/Logic.cpp b/src/planner/Logic.cpp index c92d43c659d86fb6a541b2ac6176d45d0d94112d..dcae2387cfe45698682f115fdfb3e1cdad92ccd0 100644 --- a/src/planner/Logic.cpp +++ b/src/planner/Logic.cpp @@ -6,19 +6,19 @@ #include "planner/Logic.h" +#include "common/interface/gen-cpp2/graph_types.h" + namespace nebula { namespace graph { -std::string Select::explain() const { - return "Select"; +std::unique_ptr<cpp2::PlanNodeDescription> BinarySelect::explain() const { + auto desc = SingleInputNode::explain(); + addDescription("condition", condition_ ? condition_->toString() : "", desc.get()); + return desc; } Loop::Loop(ExecutionPlan* plan, PlanNode* input, PlanNode* body, Expression* condition) : BinarySelect(plan, Kind::kLoop, input, condition), body_(body) {} -std::string Loop::explain() const { - return "Loop"; -} - } // namespace graph } // namespace nebula diff --git a/src/planner/Logic.h b/src/planner/Logic.h index 4b19c7db9b800a296a2e0f44e945f7b180daaa83..c32c65203e16fdca1f7f1a6941e65fb40366ef47 100644 --- a/src/planner/Logic.h +++ b/src/planner/Logic.h @@ -18,10 +18,6 @@ public: return new StartNode(plan); } - std::string explain() const override { - return "Start"; - } - private: explicit StartNode(ExecutionPlan* plan) : PlanNode(plan, Kind::kStart) {} }; @@ -32,6 +28,8 @@ public: return condition_; } + std::unique_ptr<cpp2::PlanNodeDescription> explain() const override; + protected: BinarySelect(ExecutionPlan* plan, Kind kind, PlanNode* input, Expression* condition) : SingleInputNode(plan, kind, input), condition_(condition) {} @@ -57,8 +55,6 @@ public: else_ = elseBranch; } - std::string explain() const override; - const PlanNode* then() const { return if_; } @@ -90,8 +86,6 @@ public: body_ = body; } - std::string explain() const override; - const PlanNode* body() const { return body_; } @@ -111,10 +105,6 @@ public: return new MultiOutputsNode(input, plan); } - std::string explain() const override { - return "MultiOutputsNode"; - } - private: MultiOutputsNode(PlanNode* input, ExecutionPlan* plan) : SingleInputNode(plan, Kind::kMultiOutputs, input) {} diff --git a/src/planner/Maintain.cpp b/src/planner/Maintain.cpp new file mode 100644 index 0000000000000000000000000000000000000000..744e5bc872e4b439c03c627e0cbfa3d5a6cd6f90 --- /dev/null +++ b/src/planner/Maintain.cpp @@ -0,0 +1,48 @@ +/* Copyright (c) 2020 vesoft inc. All rights reserved. + * + * This source code is licensed under Apache 2.0 License, + * attached with Common Clause Condition 1.0, found in the LICENSES directory. + */ + +#include "planner/Maintain.h" + +#include <sstream> + +#include "common/interface/gen-cpp2/graph_types.h" +#include "util/ToJson.h" + +namespace nebula { +namespace graph { + +std::unique_ptr<cpp2::PlanNodeDescription> CreateSchemaNode::explain() const { + auto desc = SingleInputNode::explain(); + addDescription("name", name_, desc.get()); + addDescription("ifNotExists", folly::to<std::string>(ifNotExists_), desc.get()); + addDescription("schema", folly::toJson(util::toJson(schema_)), desc.get()); + return desc; +} + +std::unique_ptr<cpp2::PlanNodeDescription> AlterSchemaNode::explain() const { + auto desc = SingleInputNode::explain(); + addDescription("space", folly::to<std::string>(space_), desc.get()); + addDescription("name", name_, desc.get()); + addDescription("schemaItems", folly::toJson(util::toJson(schemaItems_)), desc.get()); + addDescription("schemaProp", folly::toJson(util::toJson(schemaProp_)), desc.get()); + return desc; +} + +std::unique_ptr<cpp2::PlanNodeDescription> DescSchema::explain() const { + auto desc = SingleInputNode::explain(); + addDescription("name", name_, desc.get()); + return desc; +} + +std::unique_ptr<cpp2::PlanNodeDescription> DropSchema::explain() const { + auto desc = SingleInputNode::explain(); + addDescription("name", name_, desc.get()); + addDescription("ifExists", folly::to<std::string>(ifExists_), desc.get()); + return desc; +} + +} // namespace graph +} // namespace nebula diff --git a/src/planner/Maintain.h b/src/planner/Maintain.h index 940b2347d4c30afb23e5ee484fa49ce63e7cc8ec..d07ddee13c3e4ab81b851f564dad61e9d4c9f71f 100644 --- a/src/planner/Maintain.h +++ b/src/planner/Maintain.h @@ -13,6 +13,7 @@ namespace nebula { namespace graph { + // which would make them in a single and big execution plan class CreateSchemaNode : public SingleInputNode { protected: @@ -40,6 +41,8 @@ public: return ifNotExists_; } + std::unique_ptr<cpp2::PlanNodeDescription> explain() const override; + protected: std::string name_; meta::cpp2::Schema schema_; @@ -60,10 +63,6 @@ public: ifNotExists); } - std::string explain() const override { - return "CreateTag"; - } - private: CreateTag(ExecutionPlan* plan, PlanNode* input, @@ -93,10 +92,6 @@ public: ifNotExists); } - std::string explain() const override { - return "CreateEdge"; - } - private: CreateEdge(ExecutionPlan* plan, PlanNode* input, @@ -144,6 +139,8 @@ public: return space_; } + std::unique_ptr<cpp2::PlanNodeDescription> explain() const override; + protected: GraphSpaceID space_; std::string name_; @@ -167,10 +164,6 @@ public: std::move(schemaProp)); } - std::string explain() const override { - return "AlterTag"; - } - private: AlterTag(ExecutionPlan* plan, PlanNode* input, @@ -204,10 +197,6 @@ public: std::move(schemaProp)); } - std::string explain() const override { - return "AlterEdge"; - } - private: AlterEdge(ExecutionPlan* plan, PlanNode* input, @@ -240,6 +229,8 @@ public: return name_; } + std::unique_ptr<cpp2::PlanNodeDescription> explain() const override; + protected: std::string name_; }; @@ -252,10 +243,6 @@ public: return new DescTag(plan, input, std::move(tagName)); } - std::string explain() const override { - return "DescTag"; - } - private: DescTag(ExecutionPlan* plan, PlanNode* input, @@ -272,10 +259,6 @@ public: return new DescEdge(plan, input, std::move(edgeName)); } - std::string explain() const override { - return "DescEdge"; - } - private: DescEdge(ExecutionPlan* plan, PlanNode* input, @@ -292,10 +275,6 @@ public: return new ShowCreateTag(plan, input, std::move(name)); } - std::string explain() const override { - return "ShowCreateTag"; - } - private: ShowCreateTag(ExecutionPlan* plan, PlanNode* input, @@ -312,10 +291,6 @@ public: return new ShowCreateEdge(plan, input, std::move(name)); } - std::string explain() const override { - return "ShowCreateEdge"; - } - private: ShowCreateEdge(ExecutionPlan* plan, PlanNode* input, @@ -331,10 +306,6 @@ public: return new ShowTags(plan, input); } - std::string explain() const override { - return "ShowTags"; - } - private: ShowTags(ExecutionPlan* plan, PlanNode* input) @@ -349,10 +320,6 @@ public: return new ShowEdges(plan, input); } - std::string explain() const override { - return "ShowEdges"; - } - private: ShowEdges(ExecutionPlan* plan, PlanNode* input) @@ -380,6 +347,9 @@ public: return ifExists_; } + + std::unique_ptr<cpp2::PlanNodeDescription> explain() const override; + protected: std::string name_; bool ifExists_; @@ -394,10 +364,6 @@ public: return new DropTag(plan, input, std::move(name), ifExists); } - std::string explain() const override { - return "DropTag"; - } - private: DropTag(ExecutionPlan* plan, PlanNode* input, @@ -416,10 +382,6 @@ public: return new DropEdge(plan, input, std::move(name), ifExists); } - std::string explain() const override { - return "DropEdge"; - } - private: DropEdge(ExecutionPlan* plan, PlanNode* input, @@ -431,59 +393,36 @@ private: class CreateTagIndex final : public SingleInputNode { public: - std::string explain() const override { - return "CreateTagIndex"; - } }; class CreateEdgeIndex final : public SingleInputNode { public: - std::string explain() const override { - return "CreateEdgeIndex"; - } }; class DescribeTagIndex final : public SingleInputNode { public: - std::string explain() const override { - return "DescribeTagIndex"; - } }; class DescribeEdgeIndex final : public SingleInputNode { public: - std::string explain() const override { - return "DescribeEdgeIndex"; - } }; class DropTagIndex final : public SingleInputNode { public: - std::string explain() const override { - return "DropTagIndex"; - } }; class DropEdgeIndex final : public SingleInputNode { public: - std::string explain() const override { - return "DropEdgeIndex"; - } }; class BuildTagIndex final : public SingleInputNode { public: - std::string explain() const override { - return "BuildTagIndex"; - } }; class BuildEdgeIndex final : public SingleInputNode { public: - std::string explain() const override { - return "BuildEdgeIndex"; - } }; + } // namespace graph } // namespace nebula #endif // PLANNER_MAINTAIN_H_ diff --git a/src/planner/Mutate.cpp b/src/planner/Mutate.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2e18c04d88998e29e0ed29385cc9b849bcc8c42f --- /dev/null +++ b/src/planner/Mutate.cpp @@ -0,0 +1,85 @@ +/* Copyright (c) 2020 vesoft inc. All rights reserved. + * + * This source code is licensed under Apache 2.0 License, + * attached with Common Clause Condition 1.0, found in the LICENSES directory. + */ + +#include "planner/Mutate.h" + +#include "common/interface/gen-cpp2/graph_types.h" +#include "common/interface/gen-cpp2/storage_types.h" +#include "util/ToJson.h" + +namespace nebula { +namespace graph { + +std::unique_ptr<cpp2::PlanNodeDescription> InsertVertices::explain() const { + auto desc = SingleInputNode::explain(); + addDescription("spaceId", folly::to<std::string>(spaceId_), desc.get()); + addDescription("overwritable", folly::to<std::string>(overwritable_), desc.get()); + + folly::dynamic tagPropsArr = folly::dynamic::array(); + for (const auto &p : tagPropNames_) { + folly::dynamic obj = folly::dynamic::object(); + obj.insert("tagId", p.first); + obj.insert("props", util::toJson(p.second)); + tagPropsArr.push_back(obj); + } + addDescription("tagPropNames", folly::toJson(tagPropsArr), desc.get()); + addDescription("vertices", folly::toJson(util::toJson(vertices_)), desc.get()); + return desc; +} + +std::unique_ptr<cpp2::PlanNodeDescription> InsertEdges::explain() const { + auto desc = SingleInputNode::explain(); + addDescription("spaceId", folly::to<std::string>(spaceId_), desc.get()); + addDescription("overwritable", folly::to<std::string>(overwritable_), desc.get()); + addDescription("propNames", folly::toJson(util::toJson(propNames_)), desc.get()); + addDescription("edges", folly::toJson(util::toJson(edges_)), desc.get()); + return desc; +} + +std::unique_ptr<cpp2::PlanNodeDescription> Update::explain() const { + auto desc = SingleInputNode::explain(); + addDescription("spaceId", folly::to<std::string>(spaceId_), desc.get()); + addDescription("schemaName", schemaName_, desc.get()); + addDescription("insertable", folly::to<std::string>(insertable_), desc.get()); + addDescription("updatedProps", folly::toJson(util::toJson(updatedProps_)), desc.get()); + addDescription("returnProps", folly::toJson(util::toJson(returnProps_)), desc.get()); + addDescription("condition", condition_, desc.get()); + addDescription("yieldNames", folly::toJson(util::toJson(yieldNames_)), desc.get()); + return desc; +} + +std::unique_ptr<cpp2::PlanNodeDescription> UpdateVertex::explain() const { + auto desc = Update::explain(); + addDescription("vid", folly::to<std::string>(vId_), desc.get()); + addDescription("tagId", folly::to<std::string>(tagId_), desc.get()); + return desc; +} + +std::unique_ptr<cpp2::PlanNodeDescription> UpdateEdge::explain() const { + auto desc = Update::explain(); + addDescription("srcId", srcId_, desc.get()); + addDescription("dstId", dstId_, desc.get()); + addDescription("rank", folly::to<std::string>(rank_), desc.get()); + addDescription("edgeType", folly::to<std::string>(edgeType_), desc.get()); + return desc; +} + +std::unique_ptr<cpp2::PlanNodeDescription> DeleteVertices::explain() const { + auto desc = SingleInputNode::explain(); + addDescription("space", folly::to<std::string>(space_), desc.get()); + addDescription("vidRef", vidRef_ ? vidRef_->toString() : "", desc.get()); + return desc; +} + +std::unique_ptr<cpp2::PlanNodeDescription> DeleteEdges::explain() const { + auto desc = SingleInputNode::explain(); + addDescription("space", folly::to<std::string>(space_), desc.get()); + addDescription("edgeKeyRefs", folly::toJson(util::toJson(edgeKeyRefs_)), desc.get()); + return desc; +} + +} // namespace graph +} // namespace nebula diff --git a/src/planner/Mutate.h b/src/planner/Mutate.h index 2de152ea1a3ae58becea9941aff67bf483545858..fc49b6bb43e1cdc6dfe2baf65a678db96ed5cd31 100644 --- a/src/planner/Mutate.h +++ b/src/planner/Mutate.h @@ -34,9 +34,7 @@ public: overwritable); } - std::string explain() const override { - return "InsertVertices"; - } + std::unique_ptr<cpp2::PlanNodeDescription> explain() const override; const std::vector<storage::cpp2::NewVertex>& getVertices() const { return vertices_; @@ -91,9 +89,7 @@ public: overwritable); } - std::string explain() const override { - return "InsertEdges"; - } + std::unique_ptr<cpp2::PlanNodeDescription> explain() const override; const std::vector<std::string>& getPropNames() const { return propNames_; @@ -162,6 +158,8 @@ public: return schemaName_; } + std::unique_ptr<cpp2::PlanNodeDescription> explain() const override; + protected: Update(Kind kind, ExecutionPlan* plan, @@ -218,9 +216,7 @@ public: std::move(yieldNames)); } - std::string explain() const override { - return "UpdateVertex"; - } + std::unique_ptr<cpp2::PlanNodeDescription> explain() const override; const std::string& getVId() const { return vId_; @@ -290,9 +286,7 @@ public: std::move(yieldNames)); } - std::string explain() const override { - return "UpdateEdge"; - } + std::unique_ptr<cpp2::PlanNodeDescription> explain() const override; const std::string& getSrcId() const { return srcId_; @@ -363,9 +357,7 @@ public: vidRef_); } - std::string explain() const override { - return "DeleteVertices"; - } + std::unique_ptr<cpp2::PlanNodeDescription> explain() const override; GraphSpaceID getSpace() const { return space_; @@ -401,9 +393,7 @@ public: std::move(edgeKeyRefs)); } - std::string explain() const override { - return "DeleteEdges"; - } + std::unique_ptr<cpp2::PlanNodeDescription> explain() const override; GraphSpaceID getSpace() const { return space_; @@ -423,9 +413,10 @@ private: , edgeKeyRefs_(std::move(edgeKeyRefs)) {} private: - GraphSpaceID space_{-1}; - std::vector<EdgeKeyRef*> edgeKeyRefs_; + GraphSpaceID space_{-1}; + std::vector<EdgeKeyRef*> edgeKeyRefs_; }; + } // namespace graph } // namespace nebula #endif // PLANNER_MUTATE_H_ diff --git a/src/planner/PlanNode.cpp b/src/planner/PlanNode.cpp index ac94a51a01da17d5ecc3d55473cabd1a7f8c04c6..b52cbd9fe8d412eaf7185d586bc0bc624760ece0 100644 --- a/src/planner/PlanNode.cpp +++ b/src/planner/PlanNode.cpp @@ -5,6 +5,8 @@ */ #include "planner/PlanNode.h" + +#include "common/interface/gen-cpp2/graph_types.h" #include "planner/ExecutionPlan.h" namespace nebula { @@ -120,10 +122,53 @@ const char* PlanNode::toString(PlanNode::Kind kind) { LOG(FATAL) << "Impossible kind plan node " << static_cast<int>(kind); } +// static +void PlanNode::addDescription(std::string key, std::string value, cpp2::PlanNodeDescription* desc) { + if (!desc->__isset.description) { + desc->set_description({}); + } + cpp2::Pair kv; + kv.set_key(std::move(key)); + kv.set_value(std::move(value)); + desc->get_description()->emplace_back(std::move(kv)); +} + +std::unique_ptr<cpp2::PlanNodeDescription> PlanNode::explain() const { + auto desc = std::make_unique<cpp2::PlanNodeDescription>(); + desc->set_id(id_); + desc->set_name(toString(kind_)); + desc->set_output_var(outputVar_); + return desc; +} + std::ostream& operator<<(std::ostream& os, PlanNode::Kind kind) { os << PlanNode::toString(kind); return os; } +std::unique_ptr<cpp2::PlanNodeDescription> SingleDependencyNode::explain() const { + auto desc = PlanNode::explain(); + DCHECK(!desc->__isset.dependencies); + desc->set_dependencies({dependency_->id()}); + return desc; +} + +std::unique_ptr<cpp2::PlanNodeDescription> SingleInputNode::explain() const { + auto desc = SingleDependencyNode::explain(); + DCHECK(!desc->__isset.description); + addDescription("inputVar", inputVar_, desc.get()); + return desc; +} + +std::unique_ptr<cpp2::PlanNodeDescription> BiInputNode::explain() const { + auto desc = PlanNode::explain(); + DCHECK(!desc->__isset.dependencies); + desc->set_dependencies({left_->id(), right_->id()}); + DCHECK(!desc->__isset.description); + addDescription("leftVar", leftVar_, desc.get()); + addDescription("rightVar", rightVar_, desc.get()); + return desc; +} + } // namespace graph } // namespace nebula diff --git a/src/planner/PlanNode.h b/src/planner/PlanNode.h index dd97153bea7db509b816b4739db9e1dd2dff98c8..94119d67efd94d9ec831749c994de30ae811fb87 100644 --- a/src/planner/PlanNode.h +++ b/src/planner/PlanNode.h @@ -14,6 +14,10 @@ namespace nebula { namespace graph { +namespace cpp2 { +class PlanNodeDescription; +} // namespace cpp2 + class ExecutionPlan; /** @@ -78,10 +82,8 @@ public: virtual ~PlanNode() = default; - /** - * To explain how a query would be executed - */ - virtual std::string explain() const = 0; + // Describe plan node + virtual std::unique_ptr<cpp2::PlanNodeDescription> explain() const; Kind kind() const { return kind_; @@ -135,6 +137,8 @@ public: } protected: + static void addDescription(std::string key, std::string value, cpp2::PlanNodeDescription* desc); + Kind kind_{Kind::kUnknown}; int64_t id_{IdGenerator::INVALID_ID}; ExecutionPlan* plan_{nullptr}; @@ -163,6 +167,8 @@ protected: SingleDependencyNode(ExecutionPlan *plan, Kind kind, const PlanNode *dep) : PlanNode(plan, kind), dependency_(dep) {} + std::unique_ptr<cpp2::PlanNodeDescription> explain() const override; + const PlanNode *dependency_; }; @@ -176,6 +182,8 @@ public: return inputVar_; } + std::unique_ptr<cpp2::PlanNodeDescription> explain() const override; + protected: SingleInputNode(ExecutionPlan* plan, Kind kind, const PlanNode* dep) : SingleDependencyNode(plan, kind, dep) { @@ -219,9 +227,7 @@ public: return rightVar_; } - std::string explain() const override { - return ""; - } + std::unique_ptr<cpp2::PlanNodeDescription> explain() const override; protected: BiInputNode(ExecutionPlan* plan, Kind kind, PlanNode* left, PlanNode* right) diff --git a/src/planner/Query.cpp b/src/planner/Query.cpp index 5927c61f195a2ff7df141eaf602408e531fe85a9..bbeec0f4bb627014cb0e84339e2ef475c2920561 100644 --- a/src/planner/Query.cpp +++ b/src/planner/Query.cpp @@ -8,82 +8,129 @@ #include <folly/String.h> +#include "common/interface/gen-cpp2/graph_types.h" +#include "util/ToJson.h" + using folly::stringPrintf; namespace nebula { namespace graph { -std::string GetNeighbors::explain() const { - // TODO: - return "GetNeighbors"; -} -std::string GetVertices::explain() const { - // TODO: - return "GetVertices"; +std::unique_ptr<cpp2::PlanNodeDescription> Explore::explain() const { + auto desc = SingleInputNode::explain(); + addDescription("space", folly::to<std::string>(space_), desc.get()); + addDescription("dedup", folly::to<std::string>(dedup_), desc.get()); + addDescription("limit", folly::to<std::string>(limit_), desc.get()); + addDescription("filter", filter_, desc.get()); + addDescription("orderBy", folly::toJson(util::toJson(orderBy_)), desc.get()); + return desc; } -std::string GetEdges::explain() const { - // TODO: - return "GetEdges"; +std::unique_ptr<cpp2::PlanNodeDescription> GetNeighbors::explain() const { + auto desc = Explore::explain(); + addDescription("src", src_ ? src_->toString() : "", desc.get()); + addDescription("edgeTypes", folly::toJson(util::toJson(edgeTypes_)), desc.get()); + addDescription("edgeDirection", + storage::cpp2::_EdgeDirection_VALUES_TO_NAMES.at(edgeDirection_), + desc.get()); + addDescription( + "vertexProps", vertexProps_ ? folly::toJson(util::toJson(*vertexProps_)) : "", desc.get()); + addDescription( + "edgeProps", edgeProps_ ? folly::toJson(util::toJson(*edgeProps_)) : "", desc.get()); + addDescription( + "statProps", statProps_ ? folly::toJson(util::toJson(*statProps_)) : "", desc.get()); + addDescription("exprs", exprs_ ? folly::toJson(util::toJson(*exprs_)) : "", desc.get()); + addDescription("random", folly::to<std::string>(random_), desc.get()); + return desc; } -std::string IndexScan::explain() const { - // TODO: - return "IndexScan"; +std::unique_ptr<cpp2::PlanNodeDescription> GetVertices::explain() const { + auto desc = Explore::explain(); + addDescription("vertices", folly::toJson(util::toJson(vertices_)), desc.get()); + addDescription("src", src_ ? src_->toString() : "", desc.get()); + addDescription("props", folly::toJson(util::toJson(props_)), desc.get()); + addDescription("exprs", folly::toJson(util::toJson(exprs_)), desc.get()); + return desc; } -std::string Filter::explain() const { - // TODO: - return "Filter"; +std::unique_ptr<cpp2::PlanNodeDescription> GetEdges::explain() const { + auto desc = Explore::explain(); + addDescription("edges", folly::toJson(util::toJson(edges_)), desc.get()); + addDescription("src", src_ ? src_->toString() : "", desc.get()); + addDescription("type", util::toJson(type_), desc.get()); + addDescription("ranking", ranking_ ? ranking_->toString() : "", desc.get()); + addDescription("dst", dst_ ? dst_->toString() : "", desc.get()); + addDescription("props", folly::toJson(util::toJson(props_)), desc.get()); + addDescription("exprs", folly::toJson(util::toJson(exprs_)), desc.get()); + return desc; } -std::string Union::explain() const { - // TODO: - return "Union"; +std::unique_ptr<cpp2::PlanNodeDescription> IndexScan::explain() const { + auto desc = Explore::explain(); + // TODO + return desc; } -std::string Intersect::explain() const { - // TODO: - return "Intersect"; +std::unique_ptr<cpp2::PlanNodeDescription> Filter::explain() const { + auto desc = SingleInputNode::explain(); + addDescription("condition", condition_ ? condition_->toString() : "", desc.get()); + return desc; } -std::string Minus::explain() const { - // TODO: - return "Minus"; +std::unique_ptr<cpp2::PlanNodeDescription> Project::explain() const { + auto desc = SingleInputNode::explain(); + addDescription("columns", cols_ ? cols_->toString() : "", desc.get()); + return desc; } -std::string Project::explain() const { - // TODO: - return "Project"; +std::unique_ptr<cpp2::PlanNodeDescription> Sort::explain() const { + auto desc = SingleInputNode::explain(); + addDescription("factors", folly::toJson(util::toJson(factors_)), desc.get()); + return desc; } -std::string Sort::explain() const { - // TODO: - return "Sort"; +std::unique_ptr<cpp2::PlanNodeDescription> Limit::explain() const { + auto desc = SingleInputNode::explain(); + addDescription("offset", folly::to<std::string>(offset_), desc.get()); + addDescription("count", folly::to<std::string>(count_), desc.get()); + return desc; } -std::string Limit::explain() const { - std::string buf; - buf.reserve(256); - buf += "Limit: "; - buf += folly::stringPrintf("offset %ld, count %ld", offset_, count_); - return buf; +std::unique_ptr<cpp2::PlanNodeDescription> Aggregate::explain() const { + auto desc = SingleInputNode::explain(); + addDescription("groupKeys", folly::toJson(util::toJson(groupKeys_)), desc.get()); + folly::dynamic itemArr = folly::dynamic::array(); + for (const auto &item : groupItems_) { + folly::dynamic itemObj = folly::dynamic::object(); + itemObj.insert("distinct", item.distinct); + itemObj.insert("funcType", static_cast<uint8_t>(item.func)); + itemObj.insert("expr", item.expr ? item.expr->toString() : ""); + itemArr.push_back(itemObj); + } + addDescription("groupItems", folly::toJson(itemArr), desc.get()); + return desc; } - -std::string Aggregate::explain() const { - // TODO: - return "Aggregate"; -} -std::string SwitchSpace::explain() const { - return "SwitchSpace"; +std::unique_ptr<cpp2::PlanNodeDescription> SwitchSpace::explain() const { + auto desc = SingleInputNode::explain(); + addDescription("space", spaceName_, desc.get()); + return desc; } -std::string Dedup::explain() const { - return "Dedup"; +std::unique_ptr<cpp2::PlanNodeDescription> DataCollect::explain() const { + auto desc = SingleInputNode::explain(); + addDescription("vars", folly::toJson(util::toJson(vars_)), desc.get()); + addDescription("kind", collectKind_ == CollectKind::kSubgraph ? "subgraph" : "row", desc.get()); + return desc; } -std::string DataCollect::explain() const { - return "DataCollect"; +std::unique_ptr<cpp2::PlanNodeDescription> DataJoin::explain() const { + auto desc = SingleInputNode::explain(); + addDescription("leftVar", folly::toJson(util::toJson(leftVar_)), desc.get()); + addDescription("rightVar", folly::toJson(util::toJson(rightVar_)), desc.get()); + addDescription("hashKeys", folly::toJson(util::toJson(hashKeys_)), desc.get()); + addDescription("probeKeys", folly::toJson(util::toJson(probeKeys_)), desc.get()); + return desc; } -} // namespace graph -} // namespace nebula + +} // namespace graph +} // namespace nebula diff --git a/src/planner/Query.h b/src/planner/Query.h index 2b25b805c2cc0d932a1c8802cacdadb43afae227..0d2c026c20daf3df7a10b955373ced2cb54ae318 100644 --- a/src/planner/Query.h +++ b/src/planner/Query.h @@ -20,6 +20,7 @@ * All query-related nodes would be put in this file, * and they are derived from PlanNode. */ + namespace nebula { namespace graph { @@ -68,6 +69,8 @@ public: orderBy_ = std::move(orderBy); } + std::unique_ptr<cpp2::PlanNodeDescription> explain() const override; + protected: Explore(ExecutionPlan* plan, Kind kind, @@ -88,7 +91,7 @@ protected: : SingleInputNode(plan, kind, input), space_(space) {} protected: - GraphSpaceID space_; + GraphSpaceID space_; bool dedup_{false}; int64_t limit_{std::numeric_limits<int64_t>::max()}; std::string filter_; @@ -142,7 +145,7 @@ public: std::move(filter)); } - std::string explain() const override; + std::unique_ptr<cpp2::PlanNodeDescription> explain() const override; Expression* src() const { return src_; @@ -248,7 +251,7 @@ private: private: Expression* src_{nullptr}; std::vector<EdgeType> edgeTypes_; - storage::cpp2::EdgeDirection edgeDirection_; + storage::cpp2::EdgeDirection edgeDirection_{storage::cpp2::EdgeDirection::OUT_EDGE}; VertexProps vertexProps_; EdgeProps edgeProps_; StatProps statProps_; @@ -286,7 +289,7 @@ public: std::move(filter)); } - std::string explain() const override; + std::unique_ptr<cpp2::PlanNodeDescription> explain() const override; const std::vector<Row>& vertices() const { return vertices_; @@ -376,7 +379,7 @@ public: std::move(filter)); } - std::string explain() const override; + std::unique_ptr<cpp2::PlanNodeDescription> explain() const override; const std::vector<Row>& edges() const { return edges_; @@ -459,7 +462,7 @@ public: IndexScan(ExecutionPlan* plan, PlanNode* input, GraphSpaceID space) : Explore(plan, Kind::kIndexScan, input, space) {} - std::string explain() const override; + std::unique_ptr<cpp2::PlanNodeDescription> explain() const override; }; /** @@ -477,7 +480,7 @@ public: return condition_; } - std::string explain() const override; + std::unique_ptr<cpp2::PlanNodeDescription> explain() const override; private: Filter(ExecutionPlan* plan, PlanNode* input, Expression* condition) @@ -512,8 +515,6 @@ public: return new Union(plan, left, right); } - std::string explain() const override; - private: Union(ExecutionPlan* plan, PlanNode* left, PlanNode* right) : SetOp(plan, Kind::kUnion, left, right) {} @@ -528,8 +529,6 @@ public: return new Intersect(plan, left, right); } - std::string explain() const override; - private: Intersect(ExecutionPlan* plan, PlanNode* left, PlanNode* right) : SetOp(plan, Kind::kIntersect, left, right) {} @@ -544,7 +543,6 @@ public: return new Minus(plan, left, right); } - std::string explain() const override; private: Minus(ExecutionPlan* plan, PlanNode* left, PlanNode* right) @@ -562,7 +560,7 @@ public: return new Project(plan, input, cols); } - std::string explain() const override; + std::unique_ptr<cpp2::PlanNodeDescription> explain() const override; const YieldColumns* columns() const { return cols_; @@ -591,7 +589,7 @@ public: return factors_; } - std::string explain() const override; + std::unique_ptr<cpp2::PlanNodeDescription> explain() const override; private: Sort(ExecutionPlan* plan, @@ -625,7 +623,7 @@ public: return count_; } - std::string explain() const override; + std::unique_ptr<cpp2::PlanNodeDescription> explain() const override; private: Limit(ExecutionPlan* plan, PlanNode* input, int64_t offset, int64_t count) @@ -667,7 +665,7 @@ public: return groupItems_; } - std::string explain() const override; + std::unique_ptr<cpp2::PlanNodeDescription> explain() const override; private: Aggregate(ExecutionPlan* plan, @@ -696,7 +694,7 @@ public: return spaceName_; } - std::string explain() const override; + std::unique_ptr<cpp2::PlanNodeDescription> explain() const override; private: SwitchSpace(ExecutionPlan* plan, @@ -717,8 +715,6 @@ public: return new Dedup(plan, input); } - std::string explain() const override; - private: Dedup(ExecutionPlan* plan, PlanNode* input) @@ -748,6 +744,8 @@ public: return vars_; } + std::unique_ptr<cpp2::PlanNodeDescription> explain() const override; + private: DataCollect(ExecutionPlan* plan, PlanNode* input, @@ -758,8 +756,6 @@ private: vars_ = std::move(vars); } - std::string explain() const override; - private: CollectKind collectKind_; std::vector<std::string> vars_; @@ -781,10 +777,6 @@ public: std::move(probeKeys)); } - std::string explain() const override { - return "DataJoin"; - } - const std::pair<std::string, int64_t>& leftVar() const { return leftVar_; } @@ -801,6 +793,8 @@ public: return probeKeys_; } + std::unique_ptr<cpp2::PlanNodeDescription> explain() const override; + private: DataJoin(ExecutionPlan* plan, PlanNode* input, std::pair<std::string, int64_t> leftVar, @@ -821,10 +815,13 @@ private: }; class ProduceSemiShortestPath : public PlanNode { +public: }; class ConjunctPath : public PlanNode { +public: }; + } // namespace graph } // namespace nebula #endif // PLANNER_QUERY_H_ diff --git a/src/util/CMakeLists.txt b/src/util/CMakeLists.txt index e17d8e9e16d6c563eed5464d25df24f3ccfee68f..f333c400b835911d23f056624d3cd5b5e2c00e8b 100644 --- a/src/util/CMakeLists.txt +++ b/src/util/CMakeLists.txt @@ -7,6 +7,7 @@ nebula_add_library( util_obj OBJECT SchemaUtil.cpp + ToJson.cpp ) nebula_add_library( diff --git a/src/util/ToJson.cpp b/src/util/ToJson.cpp new file mode 100644 index 0000000000000000000000000000000000000000..cc0cfc7782965500c5e2c6e04315c611452f6fac --- /dev/null +++ b/src/util/ToJson.cpp @@ -0,0 +1,223 @@ +/* Copyright (c) 2020 vesoft inc. All rights reserved. + * + * This source code is licensed under Apache 2.0 License, + * attached with Common Clause Condition 1.0, found in the LICENSES directory. + */ + +#include "util/ToJson.h" + +#include "common/clients/meta/MetaClient.h" +#include "common/datatypes/Value.h" +#include "common/expression/Expression.h" +#include "parser/EdgeKey.h" + +#include "common/interface/gen-cpp2/meta_types.h" +#include "common/interface/gen-cpp2/storage_types.h" + +namespace nebula { +namespace util { + +std::string toJson(const std::string &str) { + return str; +} + +std::string toJson(int32_t i) { + return folly::to<std::string>(i); +} + +std::string toJson(int64_t i) { + return folly::to<std::string>(i); +} + +std::string toJson(const List &list) { + return list.toString(); +} + +std::string toJson(const Value &value) { + return value.toString(); +} + +std::string toJson(const EdgeKeyRef *ref) { + return ref->toString(); +} + +std::string toJson(const Expression *expr) { + return expr->toString(); +} + +folly::dynamic toJson(const meta::SpaceDesc &desc) { + folly::dynamic obj = folly::dynamic::object(); + obj.insert("name", desc.spaceName_); + obj.insert("partNum", desc.partNum_); + obj.insert("replicaFactor", desc.replicaFactor_); + obj.insert("charset", desc.charsetName_); + obj.insert("collate", desc.collationName_); + obj.insert("vidSize", desc.vidSize_); + return obj; +} + +folly::dynamic toJson(const meta::cpp2::ColumnDef &column) { + folly::dynamic obj = folly::dynamic::object(); + obj.insert("name", column.get_name()); + obj.insert("type", meta::cpp2::_PropertyType_VALUES_TO_NAMES.at(column.get_type())); + if (column.__isset.type_length) { + obj.insert("typeLength", folly::to<std::string>(*column.get_type_length())); + } + if (column.__isset.nullable) { + obj.insert("nullable", folly::to<std::string>(*column.get_nullable())); + } + if (column.__isset.default_value) { + obj.insert("defaultValue", column.get_default_value()->toString()); + } + return obj; +} + +folly::dynamic toJson(const meta::cpp2::Schema &schema) { + folly::dynamic json = folly::dynamic::object(); + if (schema.__isset.columns) { + json.insert("columns", toJson(schema.get_columns())); + } + if (schema.__isset.schema_prop) { + json.insert("prop", toJson(schema.get_schema_prop())); + } + return json; +} + +folly::dynamic toJson(const meta::cpp2::SchemaProp &prop) { + folly::dynamic object = folly::dynamic::object(); + if (prop.__isset.ttl_col) { + object.insert("ttlCol", *prop.get_ttl_col()); + } + if (prop.__isset.ttl_duration) { + object.insert("ttlDuration", *prop.get_ttl_duration()); + } + return object; +} + +folly::dynamic toJson(const meta::cpp2::AlterSchemaItem &item) { + folly::dynamic json = folly::dynamic::object(); + if (item.__isset.schema) { + json.insert("schema", toJson(item.get_schema())); + } + if (item.__isset.op) { + json.insert("op", meta::cpp2::_AlterSchemaOp_VALUES_TO_NAMES.at(item.get_op())); + } + return json; +} + +folly::dynamic toJson(const storage::cpp2::EdgeKey &edgeKey) { + folly::dynamic edgeKeyObj = folly::dynamic::object(); + if (edgeKey.__isset.src) { + edgeKeyObj.insert("src", edgeKey.get_src()); + } + if (edgeKey.__isset.dst) { + edgeKeyObj.insert("dst", edgeKey.get_dst()); + } + if (edgeKey.__isset.edge_type) { + edgeKeyObj.insert("edgeType", edgeKey.get_edge_type()); + } + if (edgeKey.__isset.ranking) { + edgeKeyObj.insert("ranking", edgeKey.get_ranking()); + } + return edgeKeyObj; +} + +folly::dynamic toJson(const storage::cpp2::NewTag &tag) { + folly::dynamic tagObj = folly::dynamic::object(); + if (tag.__isset.tag_id) { + tagObj.insert("tagId", tag.get_tag_id()); + } + if (tag.__isset.props) { + tagObj.insert("props", toJson(tag.get_props())); + } + return tagObj; +} + +folly::dynamic toJson(const storage::cpp2::NewVertex &vert) { + folly::dynamic vertObj = folly::dynamic::object(); + if (vert.__isset.id) { + vertObj.insert("id", vert.get_id()); + } + if (vert.__isset.tags) { + vertObj.insert("tags", util::toJson(vert.get_tags())); + } + return vertObj; +} + +folly::dynamic toJson(const storage::cpp2::NewEdge &edge) { + folly::dynamic edgeObj = folly::dynamic::object(); + if (edge.__isset.key) { + edgeObj.insert("key", toJson(edge.get_key())); + } + if (edge.__isset.props) { + edgeObj.insert("props", toJson(edge.get_props())); + } + return edgeObj; +} + +folly::dynamic toJson(const storage::cpp2::UpdatedProp &prop) { + return folly::dynamic::object("name", prop.get_name())("value", prop.get_value()); +} + +folly::dynamic toJson(const storage::cpp2::OrderBy &orderBy) { + folly::dynamic obj = folly::dynamic::object(); + if (orderBy.__isset.direction) { + auto dir = orderBy.get_direction(); + obj.insert("direction", storage::cpp2::_OrderDirection_VALUES_TO_NAMES.at(dir)); + } + if (orderBy.__isset.prop) { + obj.insert("prop", orderBy.get_prop()); + } + return obj; +} + +folly::dynamic toJson(const storage::cpp2::VertexProp &prop) { + folly::dynamic obj = folly::dynamic::object(); + if (prop.__isset.tag) { + auto tag = prop.get_tag(); + obj.insert("tagId", tag); + } + if (prop.__isset.props) { + obj.insert("props", toJson(prop.get_props())); + } + return obj; +} + +folly::dynamic toJson(const storage::cpp2::EdgeProp &prop) { + folly::dynamic obj = folly::dynamic::object(); + if (prop.__isset.type) { + obj.insert("type", toJson(prop.get_type())); + } + if (prop.__isset.props) { + obj.insert("props", toJson(prop.get_props())); + } + return obj; +} + +folly::dynamic toJson(const storage::cpp2::StatProp &prop) { + folly::dynamic obj = folly::dynamic::object(); + if (prop.__isset.alias) { + obj.insert("alias", prop.get_alias()); + } + if (prop.__isset.prop) { + obj.insert("prop", prop.get_prop()); + } + if (prop.__isset.stat) { + obj.insert("stat", storage::cpp2::_StatType_VALUES_TO_NAMES.at(prop.get_stat())); + } + return obj; +} + +folly::dynamic toJson(const storage::cpp2::Expr &expr) { + folly::dynamic obj = folly::dynamic::object(); + if (expr.__isset.alias) { + obj.insert("alias", expr.get_alias()); + } + if (expr.__isset.expr) { + obj.insert("expr", expr.get_expr()); + } + return obj; +} + +} // namespace util +} // namespace nebula diff --git a/src/util/ToJson.h b/src/util/ToJson.h new file mode 100644 index 0000000000000000000000000000000000000000..7c5ab017b697641164e7ee6f673b957863ac5918 --- /dev/null +++ b/src/util/ToJson.h @@ -0,0 +1,93 @@ +/* Copyright (c) 2020 vesoft inc. All rights reserved. + * + * This source code is licensed under Apache 2.0 License, + * attached with Common Clause Condition 1.0, found in the LICENSES directory. + */ +#ifndef UTIL_TOJSON_H_ +#define UTIL_TOJSON_H_ + +#include <iterator> +#include <string> +#include <utility> +#include <vector> + +#include <folly/dynamic.h> + +namespace nebula { + +class EdgeKeyRef; +class Expression; +struct List; +struct Value; + +namespace meta { +struct SpaceDesc; +namespace cpp2 { +class AlterSchemaItem; +class ColumnDef; +class Schema; +class SchemaProp; +} // namespace cpp2 +} // namespace meta + +namespace storage { +namespace cpp2 { +class EdgeKey; +class NewTag; +class NewEdge; +class NewVertex; +class UpdatedProp; +class OrderBy; +class VertexProp; +class EdgeProp; +class StatProp; +class Expr; +} // namespace cpp2 +} // namespace storage + +namespace util { + +template <typename T> +folly::dynamic toJson(const std::vector<T> &arr); + +std::string toJson(const std::string &str); +std::string toJson(int32_t i); +std::string toJson(int64_t i); + +std::string toJson(const List &list); +std::string toJson(const Value &value); +std::string toJson(const EdgeKeyRef *ref); +std::string toJson(const Expression *expr); +folly::dynamic toJson(const meta::SpaceDesc &desc); +folly::dynamic toJson(const meta::cpp2::ColumnDef &column); +folly::dynamic toJson(const meta::cpp2::Schema &schema); +folly::dynamic toJson(const meta::cpp2::SchemaProp &prop); +folly::dynamic toJson(const meta::cpp2::AlterSchemaItem &item); +folly::dynamic toJson(const storage::cpp2::EdgeKey &edgeKey); +folly::dynamic toJson(const storage::cpp2::NewTag &tag); +folly::dynamic toJson(const storage::cpp2::NewVertex &vert); +folly::dynamic toJson(const storage::cpp2::NewEdge &edge); +folly::dynamic toJson(const storage::cpp2::UpdatedProp &prop); +folly::dynamic toJson(const storage::cpp2::OrderBy &orderBy); +folly::dynamic toJson(const storage::cpp2::VertexProp &prop); +folly::dynamic toJson(const storage::cpp2::EdgeProp &prop); +folly::dynamic toJson(const storage::cpp2::StatProp &prop); +folly::dynamic toJson(const storage::cpp2::Expr &expr); + +template <typename K, typename V> +folly::dynamic toJson(const std::pair<K, V> &p) { + return folly::dynamic::object(toJson(p.first), toJson(p.second)); +} + +template <typename T> +folly::dynamic toJson(const std::vector<T> &arr) { + auto farr = folly::dynamic::array(); + std::transform( + arr.cbegin(), arr.cend(), std::back_inserter(farr), [](const T &t) { return toJson(t); }); + return farr; +} + +} // namespace util +} // namespace nebula + +#endif // UTIL_TOJSON_H_