diff --git a/src/executor/logic/LoopExecutor.h b/src/executor/logic/LoopExecutor.h index 231feea87762d0d6a8596384a3f9c44aba756504..7e27834adf2b779fd224bae7569efeb218635c41 100644 --- a/src/executor/logic/LoopExecutor.h +++ b/src/executor/logic/LoopExecutor.h @@ -4,8 +4,8 @@ * attached with Common Clause Condition 1.0, found in the LICENSES directory. */ -#ifndef EXECUTOR_QUERY_LOOPEXECUTOR_H_ -#define EXECUTOR_QUERY_LOOPEXECUTOR_H_ +#ifndef EXECUTOR_LOGIC_LOOPEXECUTOR_H_ +#define EXECUTOR_LOGIC_LOOPEXECUTOR_H_ #include "executor/Executor.h" @@ -30,4 +30,4 @@ private: } // namespace graph } // namespace nebula -#endif // EXECUTOR_QUERY_LOOPEXECUTOR_H_ +#endif // EXECUTOR_LOGIC_LOOPEXECUTOR_H_ diff --git a/src/executor/logic/PassThroughExecutor.h b/src/executor/logic/PassThroughExecutor.h index 640dc8c37e15d3e3bb0c4af180e68ee44d7d298b..6007b73422d770de0a2ac6aaaf0804a54e08eb7f 100644 --- a/src/executor/logic/PassThroughExecutor.h +++ b/src/executor/logic/PassThroughExecutor.h @@ -4,13 +4,8 @@ * attached with Common Clause Condition 1.0, found in the LICENSES directory. */ -#ifndef EXEC_QUERY_PASSTHROUGHEXECUTOR_H_ -#define EXEC_QUERY_PASSTHROUGHEXECUTOR_H_ - -#include <unordered_map> - -#include <folly/SpinLock.h> -#include <folly/futures/SharedPromise.h> +#ifndef EXECUTOR_LOGIC_PASSTHROUGHEXECUTOR_H_ +#define EXECUTOR_LOGIC_PASSTHROUGHEXECUTOR_H_ #include "executor/Executor.h" @@ -19,7 +14,7 @@ namespace graph { class PassThroughExecutor final : public Executor { public: - PassThroughExecutor(const PlanNode *node, QueryContext* qctx) + PassThroughExecutor(const PlanNode* node, QueryContext* qctx) : Executor("PassThroughExecutor", node, qctx) {} folly::Future<Status> execute() override; @@ -28,4 +23,4 @@ public: } // namespace graph } // namespace nebula -#endif // EXEC_QUERY_PASSTHROUGHEXECUTOR_H_ +#endif // EXECUTOR_LOGIC_PASSTHROUGHEXECUTOR_H_ diff --git a/src/executor/logic/SelectExecutor.h b/src/executor/logic/SelectExecutor.h index d9f628026a576e1a4d50244ae0d1d7291c5d533f..8ff4e1cb21be5f8b61668878356259a8e3615e7c 100644 --- a/src/executor/logic/SelectExecutor.h +++ b/src/executor/logic/SelectExecutor.h @@ -4,8 +4,8 @@ * attached with Common Clause Condition 1.0, found in the LICENSES directory. */ -#ifndef EXECUTOR_QUERY_SELECTEXECUTOR_H_ -#define EXECUTOR_QUERY_SELECTEXECUTOR_H_ +#ifndef EXECUTOR_LOGIC_SELECTEXECUTOR_H_ +#define EXECUTOR_LOGIC_SELECTEXECUTOR_H_ #include "executor/Executor.h" @@ -34,4 +34,4 @@ private: } // namespace graph } // namespace nebula -#endif // EXECUTOR_QUERY_SELECTEXECUTOR_H_ +#endif // EXECUTOR_LOGIC_SELECTEXECUTOR_H_ diff --git a/src/executor/logic/StartExecutor.h b/src/executor/logic/StartExecutor.h index da429ce22aa1deae92d700db82e42546aee9f4c1..b643cd718344ea0e05a5b086f2700c6b1ffe7bc5 100644 --- a/src/executor/logic/StartExecutor.h +++ b/src/executor/logic/StartExecutor.h @@ -4,8 +4,8 @@ * attached with Common Clause Condition 1.0, found in the LICENSES directory. */ -#ifndef EXECUTOR_QUERY_STARTEXECUTOR_H_ -#define EXECUTOR_QUERY_STARTEXECUTOR_H_ +#ifndef EXECUTOR_LOGIC_STARTEXECUTOR_H_ +#define EXECUTOR_LOGIC_STARTEXECUTOR_H_ #include "executor/Executor.h" @@ -23,4 +23,4 @@ public: } // namespace graph } // namespace nebula -#endif // EXECUTOR_QUERY_STARTEXECUTOR_H_ +#endif // EXECUTOR_LOGIC_STARTEXECUTOR_H_ diff --git a/src/planner/PlanNode.cpp b/src/planner/PlanNode.cpp index 347af8311a9fbfbe830088f9653565fd4d4229d9..b25ad81fbaffd94aa35efb8095196699e6037521 100644 --- a/src/planner/PlanNode.cpp +++ b/src/planner/PlanNode.cpp @@ -191,7 +191,7 @@ std::ostream& operator<<(std::ostream& os, PlanNode::Kind kind) { std::unique_ptr<cpp2::PlanNodeDescription> SingleDependencyNode::explain() const { auto desc = PlanNode::explain(); DCHECK(!desc->__isset.dependencies); - desc->set_dependencies({dependency_->id()}); + desc->set_dependencies({dep()->id()}); return desc; } @@ -204,7 +204,7 @@ std::unique_ptr<cpp2::PlanNodeDescription> SingleInputNode::explain() const { std::unique_ptr<cpp2::PlanNodeDescription> BiInputNode::explain() const { auto desc = PlanNode::explain(); DCHECK(!desc->__isset.dependencies); - desc->set_dependencies({left_->id(), right_->id()}); + desc->set_dependencies({left()->id(), right()->id()}); addDescription("leftVar", leftVar_, desc.get()); addDescription("rightVar", rightVar_, desc.get()); return desc; diff --git a/src/planner/PlanNode.h b/src/planner/PlanNode.h index b678ce44ed67ec8aab6adf4292ba2da8cfc0737a..7af43b8deac96bdfc5ef86c2ddc93df5b2a59042 100644 --- a/src/planner/PlanNode.h +++ b/src/planner/PlanNode.h @@ -138,6 +138,20 @@ public: colNames_ = cols; } + const PlanNode* dep(size_t index = 0) const { + DCHECK_LT(index, dependencies_.size()); + return dependencies_.at(index); + } + + void setDep(size_t index, const PlanNode* dep) { + DCHECK_LT(index, dependencies_.size()); + dependencies_[index] = DCHECK_NOTNULL(dep); + } + + const std::vector<const PlanNode*>& dependencies() const { + return dependencies_; + } + static const char* toString(Kind kind); protected: @@ -147,6 +161,7 @@ protected: int64_t id_{-1}; std::string outputVar_; std::vector<std::string> colNames_; + std::vector<const PlanNode*> dependencies_; }; std::ostream& operator<<(std::ostream& os, PlanNode::Kind kind); @@ -157,21 +172,17 @@ std::ostream& operator<<(std::ostream& os, PlanNode::Kind kind); // It's useful for admin plan node class SingleDependencyNode : public PlanNode { public: - const PlanNode* dep() const { - return dependency_; - } - - void dependsOn(PlanNode *dep) { - dependency_ = DCHECK_NOTNULL(dep); + void dependsOn(const PlanNode* dep) { + setDep(0, dep); } protected: SingleDependencyNode(int64_t id, Kind kind, const PlanNode* dep) - : PlanNode(id, kind), dependency_(dep) {} + : PlanNode(id, kind) { + dependencies_.emplace_back(dep); + } std::unique_ptr<cpp2::PlanNodeDescription> explain() const override; - - const PlanNode *dependency_; }; class SingleInputNode : public SingleDependencyNode { @@ -198,11 +209,11 @@ protected: class BiInputNode : public PlanNode { public: void setLeft(const PlanNode* left) { - left_ = left; + setDep(0, left); } void setRight(const PlanNode* right) { - right_ = right; + setDep(1, right); } void setLeftVar(std::string leftVar) { @@ -214,11 +225,11 @@ public: } const PlanNode* left() const { - return left_; + return dep(0); } const PlanNode* right() const { - return right_; + return dep(1); } const std::string& leftInputVar() const { @@ -233,11 +244,11 @@ public: protected: BiInputNode(int64_t id, Kind kind, PlanNode* left, PlanNode* right) - : PlanNode(id, kind), left_(left), right_(right) { + : PlanNode(id, kind) { + dependencies_.emplace_back(DCHECK_NOTNULL(left)); + dependencies_.emplace_back(DCHECK_NOTNULL(right)); } - const PlanNode* left_{nullptr}; - const PlanNode* right_{nullptr}; // Datasource for this node. std::string leftVar_; std::string rightVar_; diff --git a/src/validator/Validator.cpp b/src/validator/Validator.cpp index 1b98c50e005c3fe4bdd08391311091e52cf4885d..d33c949ed49a4a5b5ece47fa2894bca1e64b8060 100644 --- a/src/validator/Validator.cpp +++ b/src/validator/Validator.cpp @@ -210,79 +210,18 @@ Status Validator::validate(Sentence* sentence, QueryContext* qctx) { } Status Validator::appendPlan(PlanNode* node, PlanNode* appended) { - switch (DCHECK_NOTNULL(node)->kind()) { - case PlanNode::Kind::kShowHosts: - case PlanNode::Kind::kFilter: - case PlanNode::Kind::kProject: - case PlanNode::Kind::kSort: - case PlanNode::Kind::kLimit: - case PlanNode::Kind::kAggregate: - case PlanNode::Kind::kSelect: - case PlanNode::Kind::kLoop: - case PlanNode::Kind::kCreateUser: - case PlanNode::Kind::kDropUser: - case PlanNode::Kind::kUpdateUser: - case PlanNode::Kind::kGrantRole: - case PlanNode::Kind::kRevokeRole: - case PlanNode::Kind::kChangePassword: - case PlanNode::Kind::kListUserRoles: - case PlanNode::Kind::kListUsers: - case PlanNode::Kind::kListRoles: - case PlanNode::Kind::kPassThrough: - case PlanNode::Kind::kSwitchSpace: - case PlanNode::Kind::kGetEdges: - case PlanNode::Kind::kGetVertices: - case PlanNode::Kind::kCreateSpace: - case PlanNode::Kind::kCreateTag: - case PlanNode::Kind::kCreateEdge: - case PlanNode::Kind::kDescSpace: - case PlanNode::Kind::kDescTag: - case PlanNode::Kind::kDescEdge: - case PlanNode::Kind::kInsertVertices: - case PlanNode::Kind::kInsertEdges: - case PlanNode::Kind::kGetNeighbors: - case PlanNode::Kind::kAlterTag: - case PlanNode::Kind::kAlterEdge: - case PlanNode::Kind::kShowCreateSpace: - case PlanNode::Kind::kShowCreateTag: - case PlanNode::Kind::kShowCreateEdge: - case PlanNode::Kind::kDropSpace: - case PlanNode::Kind::kDropTag: - case PlanNode::Kind::kDropEdge: - case PlanNode::Kind::kShowSpaces: - case PlanNode::Kind::kShowTags: - case PlanNode::Kind::kShowEdges: - case PlanNode::Kind::kCreateSnapshot: - case PlanNode::Kind::kDropSnapshot: - case PlanNode::Kind::kSubmitJob: - case PlanNode::Kind::kShowSnapshots: - case PlanNode::Kind::kBalanceLeaders: - case PlanNode::Kind::kBalance: - case PlanNode::Kind::kStopBalance: - case PlanNode::Kind::kShowBalance: - case PlanNode::Kind::kDeleteVertices: - case PlanNode::Kind::kDeleteEdges: - case PlanNode::Kind::kUpdateVertex: - case PlanNode::Kind::kUpdateEdge: - case PlanNode::Kind::kShowParts: - case PlanNode::Kind::kShowCharset: - case PlanNode::Kind::kShowCollation: - case PlanNode::Kind::kShowConfigs: - case PlanNode::Kind::kSetConfig: - case PlanNode::Kind::kGetConfig: { - static_cast<SingleDependencyNode*>(node)->dependsOn(appended); - break; - } - default: { - return Status::SemanticError("%s not support to append an input.", - PlanNode::toString(node->kind())); - } + DCHECK(node != nullptr); + DCHECK(appended != nullptr); + if (node->dependencies().size() != 1) { + return Status::SemanticError("%s not support to append an input.", + PlanNode::toString(node->kind())); } + static_cast<SingleDependencyNode*>(node)->dependsOn(appended); return Status::OK(); } Status Validator::appendPlan(PlanNode* root) { - return appendPlan(tail_, DCHECK_NOTNULL(root)); + return appendPlan(tail_, root); } Status Validator::validate() { @@ -1021,4 +960,3 @@ void ExpressionProps::unionProps(ExpressionProps exprProps) { } } // namespace graph } // namespace nebula - diff --git a/src/validator/test/ValidatorTestBase.cpp b/src/validator/test/ValidatorTestBase.cpp index 0c2bf43e418f4cebe2ce8932f03374d835e729d5..525c0a887422dcd347702749be4b98c8a9c4094a 100644 --- a/src/validator/test/ValidatorTestBase.cpp +++ b/src/validator/test/ValidatorTestBase.cpp @@ -36,89 +36,32 @@ void ValidatorTestBase::bfsTraverse(const PlanNode *root, std::vector<PlanNode:: visited.emplace(node->id()); result.emplace_back(node->kind()); - switch (node->kind()) { - case PlanNode::Kind::kUnknown: - ASSERT_TRUE(false) << "Unknown Plan Node."; - case PlanNode::Kind::kStart: { - break; - } - case PlanNode::Kind::kCreateUser: - case PlanNode::Kind::kDropUser: - case PlanNode::Kind::kUpdateUser: - case PlanNode::Kind::kGrantRole: - case PlanNode::Kind::kRevokeRole: - case PlanNode::Kind::kChangePassword: - case PlanNode::Kind::kListUserRoles: - case PlanNode::Kind::kListUsers: - case PlanNode::Kind::kListRoles: - case PlanNode::Kind::kShowHosts: - case PlanNode::Kind::kGetNeighbors: - case PlanNode::Kind::kGetVertices: - case PlanNode::Kind::kGetEdges: - case PlanNode::Kind::kIndexScan: - case PlanNode::Kind::kFilter: - case PlanNode::Kind::kProject: - case PlanNode::Kind::kSort: - case PlanNode::Kind::kLimit: - case PlanNode::Kind::kAggregate: - case PlanNode::Kind::kSwitchSpace: - case PlanNode::Kind::kPassThrough: - case PlanNode::Kind::kDedup: - case PlanNode::Kind::kDataCollect: - case PlanNode::Kind::kCreateSpace: - case PlanNode::Kind::kCreateTag: - case PlanNode::Kind::kCreateEdge: - case PlanNode::Kind::kDescSpace: - case PlanNode::Kind::kDescTag: - case PlanNode::Kind::kDescEdge: - case PlanNode::Kind::kInsertVertices: - case PlanNode::Kind::kInsertEdges: - case PlanNode::Kind::kShowCreateSpace: - case PlanNode::Kind::kShowCreateTag: - case PlanNode::Kind::kShowCreateEdge: - case PlanNode::Kind::kDropSpace: - case PlanNode::Kind::kDropTag: - case PlanNode::Kind::kDropEdge: - case PlanNode::Kind::kShowSpaces: - case PlanNode::Kind::kShowTags: - case PlanNode::Kind::kShowEdges: - case PlanNode::Kind::kCreateSnapshot: - case PlanNode::Kind::kDropSnapshot: - case PlanNode::Kind::kShowSnapshots: - case PlanNode::Kind::kDataJoin: - case PlanNode::Kind::kDeleteVertices: - case PlanNode::Kind::kDeleteEdges: - case PlanNode::Kind::kUpdateVertex: - case PlanNode::Kind::kUpdateEdge: { - auto *current = static_cast<const SingleDependencyNode *>(node); - queue.emplace(current->dep()); + if (node->kind() == PlanNode::Kind::kUnknown) { + ASSERT_TRUE(false) << "Unknown Plan Node."; + } + + switch (node->dependencies().size()) { + case 1: { + auto *sNode = static_cast<const SingleDependencyNode *>(node); + queue.emplace(sNode->dep()); + if (node->kind() == PlanNode::Kind::kSelect) { + auto *current = static_cast<const Select *>(node); + queue.emplace(current->then()); + if (current->otherwise() != nullptr) { + queue.emplace(current->otherwise()); + } + } else if (node->kind() == PlanNode::Kind::kLoop) { + auto *current = static_cast<const Loop *>(node); + queue.emplace(current->body()); + } break; } - case PlanNode::Kind::kUnion: - case PlanNode::Kind::kIntersect: - case PlanNode::Kind::kMinus: { + case 2: { auto *current = static_cast<const BiInputNode *>(node); queue.emplace(current->left()); queue.emplace(current->right()); break; } - case PlanNode::Kind::kSelect: { - auto *current = static_cast<const Select *>(node); - queue.emplace(current->dep()); - queue.emplace(current->then()); - if (current->otherwise() != nullptr) { - queue.emplace(current->otherwise()); - } - break; - } - case PlanNode::Kind::kLoop: { - auto *current = static_cast<const Loop *>(node); - queue.emplace(current->dep()); - queue.emplace(current->body()); - break; - } - default: - LOG(FATAL) << "Unknown PlanNode: " << static_cast<int64_t>(node->kind()); } } }