diff --git a/src/exec/Executor.cpp b/src/exec/Executor.cpp
index 1cd74c43be6f614c1a0094cb58c1142358387623..a955a054e28fb983b685a18a862123d3cc3cadd3 100644
--- a/src/exec/Executor.cpp
+++ b/src/exec/Executor.cpp
@@ -72,72 +72,72 @@ Executor *Executor::makeExecutor(const PlanNode *node,
     switch (node->kind()) {
         case PlanNode::Kind::kMultiOutputs: {
             auto mout = asNode<MultiOutputsNode>(node);
-            auto input = makeExecutor(mout->input(), qctx, visited);
+            auto dep = makeExecutor(mout->dep(), qctx, visited);
             exec = new MultiOutputsExecutor(mout, qctx);
-            exec->addDependent(input);
+            exec->addDependent(dep);
             break;
         }
         case PlanNode::Kind::kAggregate: {
             auto agg = asNode<Aggregate>(node);
-            auto input = makeExecutor(agg->input(), qctx, visited);
+            auto dep = makeExecutor(agg->dep(), qctx, visited);
             exec = new AggregateExecutor(agg, qctx);
-            exec->addDependent(input);
+            exec->addDependent(dep);
             break;
         }
         case PlanNode::Kind::kSort: {
             auto sort = asNode<Sort>(node);
-            auto input = makeExecutor(sort->input(), qctx, visited);
+            auto dep = makeExecutor(sort->dep(), qctx, visited);
             exec = new SortExecutor(sort, qctx);
-            exec->addDependent(input);
+            exec->addDependent(dep);
             break;
         }
         case PlanNode::Kind::kFilter: {
             auto filter = asNode<Filter>(node);
-            auto input = makeExecutor(filter->input(), qctx, visited);
+            auto dep = makeExecutor(filter->dep(), qctx, visited);
             exec = new FilterExecutor(filter, qctx);
-            exec->addDependent(input);
+            exec->addDependent(dep);
             break;
         }
         case PlanNode::Kind::kGetEdges: {
             auto ge = asNode<GetEdges>(node);
-            auto input = makeExecutor(ge->input(), qctx, visited);
+            auto dep = makeExecutor(ge->dep(), qctx, visited);
             exec = new GetEdgesExecutor(ge, qctx);
-            exec->addDependent(input);
+            exec->addDependent(dep);
             break;
         }
         case PlanNode::Kind::kGetVertices: {
             auto gv = asNode<GetVertices>(node);
-            auto input = makeExecutor(gv->input(), qctx, visited);
+            auto dep = makeExecutor(gv->dep(), qctx, visited);
             exec = new GetVerticesExecutor(gv, qctx);
-            exec->addDependent(input);
+            exec->addDependent(dep);
             break;
         }
         case PlanNode::Kind::kGetNeighbors: {
             auto gn = asNode<GetNeighbors>(node);
-            auto input = makeExecutor(gn->input(), qctx, visited);
+            auto dep = makeExecutor(gn->dep(), qctx, visited);
             exec = new GetNeighborsExecutor(gn, qctx);
-            exec->addDependent(input);
+            exec->addDependent(dep);
             break;
         }
         case PlanNode::Kind::kLimit: {
             auto limit = asNode<Limit>(node);
-            auto input = makeExecutor(limit->input(), qctx, visited);
+            auto dep = makeExecutor(limit->dep(), qctx, visited);
             exec = new LimitExecutor(limit, qctx);
-            exec->addDependent(input);
+            exec->addDependent(dep);
             break;
         }
         case PlanNode::Kind::kProject: {
             auto project = asNode<Project>(node);
-            auto input = makeExecutor(project->input(), qctx, visited);
+            auto dep = makeExecutor(project->dep(), qctx, visited);
             exec = new ProjectExecutor(project, qctx);
-            exec->addDependent(input);
+            exec->addDependent(dep);
             break;
         }
         case PlanNode::Kind::kReadIndex: {
             auto readIndex = asNode<ReadIndex>(node);
-            auto input = makeExecutor(readIndex->input(), qctx, visited);
+            auto dep = makeExecutor(readIndex->dep(), qctx, visited);
             exec = new ReadIndexExecutor(readIndex, qctx);
-            exec->addDependent(input);
+            exec->addDependent(dep);
             break;
         }
         case PlanNode::Kind::kStart: {
@@ -170,110 +170,110 @@ Executor *Executor::makeExecutor(const PlanNode *node,
         }
         case PlanNode::Kind::kLoop: {
             auto loop = asNode<Loop>(node);
-            auto input = makeExecutor(loop->input(), qctx, visited);
+            auto dep = makeExecutor(loop->dep(), qctx, visited);
             auto body = makeExecutor(loop->body(), qctx, visited);
             exec = new LoopExecutor(loop, qctx, body);
-            exec->addDependent(input);
+            exec->addDependent(dep);
             break;
         }
         case PlanNode::Kind::kSelect: {
             auto select = asNode<Select>(node);
-            auto input = makeExecutor(select->input(), qctx, visited);
+            auto dep = makeExecutor(select->dep(), qctx, visited);
             auto then = makeExecutor(select->then(), qctx, visited);
             auto els = makeExecutor(select->otherwise(), qctx, visited);
             exec = new SelectExecutor(select, qctx, then, els);
-            exec->addDependent(input);
+            exec->addDependent(dep);
             break;
         }
         case PlanNode::Kind::kDedup: {
             auto dedup = asNode<Dedup>(node);
-            auto input = makeExecutor(dedup->input(), qctx, visited);
+            auto dep = makeExecutor(dedup->dep(), qctx, visited);
             exec = new DedupExecutor(dedup, qctx);
-            exec->addDependent(input);
+            exec->addDependent(dep);
             break;
         }
         case PlanNode::Kind::kSwitchSpace: {
             auto switchSpace = asNode<SwitchSpace>(node);
-            auto input = makeExecutor(switchSpace->input(), qctx, visited);
+            auto dep = makeExecutor(switchSpace->dep(), qctx, visited);
             exec = new SwitchSpaceExecutor(switchSpace, qctx);
-            exec->addDependent(input);
+            exec->addDependent(dep);
             break;
         }
         case PlanNode::Kind::kCreateSpace: {
             auto createSpace = asNode<CreateSpace>(node);
-            auto input = makeExecutor(createSpace->input(), qctx, visited);
+            auto dep = makeExecutor(createSpace->dep(), qctx, visited);
             exec = new CreateSpaceExecutor(createSpace, qctx);
-            exec->addDependent(input);
+            exec->addDependent(dep);
             break;
         }
         case PlanNode::Kind::kDescSpace: {
             auto descSpace = asNode<DescSpace>(node);
-            auto input = makeExecutor(descSpace->input(), qctx, visited);
+            auto dep = makeExecutor(descSpace->dep(), qctx, visited);
             exec = new DescSpaceExecutor(descSpace, qctx);
-            exec->addDependent(input);
+            exec->addDependent(dep);
             break;
         }
         case PlanNode::Kind::kCreateTag: {
             auto createTag = asNode<CreateTag>(node);
-            auto input = makeExecutor(createTag->input(), qctx, visited);
+            auto dep = makeExecutor(createTag->dep(), qctx, visited);
             exec = new CreateTagExecutor(createTag, qctx);
-            exec->addDependent(input);
+            exec->addDependent(dep);
             break;
         }
         case PlanNode::Kind::kDescTag: {
             auto descTag = asNode<DescTag>(node);
-            auto input = makeExecutor(descTag->input(), qctx, visited);
+            auto dep = makeExecutor(descTag->dep(), qctx, visited);
             exec = new DescTagExecutor(descTag, qctx);
-            exec->addDependent(input);
+            exec->addDependent(dep);
             break;
         }
         case PlanNode::Kind::kAlterTag: {
             auto alterTag = asNode<AlterTag>(node);
-            auto input = makeExecutor(alterTag->input(), qctx, visited);
+            auto dep = makeExecutor(alterTag->dep(), qctx, visited);
             exec = new AlterTagExecutor(alterTag, qctx);
-            exec->addDependent(input);
+            exec->addDependent(dep);
             break;
         }
         case PlanNode::Kind::kCreateEdge: {
             auto createEdge = asNode<CreateEdge>(node);
-            auto input = makeExecutor(createEdge->input(), qctx, visited);
+            auto dep = makeExecutor(createEdge->dep(), qctx, visited);
             exec = new CreateEdgeExecutor(createEdge, qctx);
-            exec->addDependent(input);
+            exec->addDependent(dep);
             break;
         }
         case PlanNode::Kind::kDescEdge: {
             auto descEdge = asNode<DescEdge>(node);
-            auto input = makeExecutor(descEdge->input(), qctx, visited);
+            auto dep = makeExecutor(descEdge->dep(), qctx, visited);
             exec = new DescEdgeExecutor(descEdge, qctx);
-            exec->addDependent(input);
+            exec->addDependent(dep);
             break;
         }
         case PlanNode::Kind::kAlterEdge: {
             auto alterEdge = asNode<AlterEdge>(node);
-            auto input = makeExecutor(alterEdge->input(), qctx, visited);
+            auto dep = makeExecutor(alterEdge->dep(), qctx, visited);
             exec = new AlterEdgeExecutor(alterEdge, qctx);
-            exec->addDependent(input);
+            exec->addDependent(dep);
             break;
         }
         case PlanNode::Kind::kInsertVertices: {
             auto insertV = asNode<InsertVertices>(node);
-            auto input = makeExecutor(insertV->input(), qctx, visited);
+            auto dep = makeExecutor(insertV->dep(), qctx, visited);
             exec = new InsertVerticesExecutor(insertV, qctx);
-            exec->addDependent(input);
+            exec->addDependent(dep);
             break;
         }
         case PlanNode::Kind::kInsertEdges: {
             auto insertE = asNode<InsertEdges>(node);
-            auto input = makeExecutor(insertE->input(), qctx, visited);
+            auto dep = makeExecutor(insertE->dep(), qctx, visited);
             exec = new InsertEdgesExecutor(insertE, qctx);
-            exec->addDependent(input);
+            exec->addDependent(dep);
             break;
         }
         case PlanNode::Kind::kDataCollect: {
             auto dc = asNode<DataCollect>(node);
-            auto input = makeExecutor(dc->input(), qctx, visited);
+            auto dep = makeExecutor(dc->dep(), qctx, visited);
             exec = new DataCollectExecutor(dc, qctx);
-            exec->addDependent(input);
+            exec->addDependent(dep);
             break;
         }
         case PlanNode::Kind::kUnknown:
diff --git a/src/planner/Query.h b/src/planner/Query.h
index 62d4074f90f2548df3ea5885baab5f5d12decdfa..72e8a23522a47dbb4d732c4825614a95f892973f 100644
--- a/src/planner/Query.h
+++ b/src/planner/Query.h
@@ -37,16 +37,30 @@ private:
     }
 };
 
-class SingleInputNode : public PlanNode {
+// Dependencies will cover the inputs, For example bi input require bi dependencies as least,
+// but single dependencies may don't need any inputs (I.E admin plan node)
+
+// Single dependecy without input
+// It's useful for addmin plan node
+class SingleDependencyNode : public PlanNode {
 public:
-    const PlanNode* input() const {
-        return input_;
+    const PlanNode* dep() const {
+        return dependency_;
     }
 
-    void setInput(PlanNode* input) {
-        input_ = input;
+    void setDep(PlanNode *dep) {
+        dependency_ = DCHECK_NOTNULL(dep);
     }
 
+protected:
+    SingleDependencyNode(ExecutionPlan *plan, Kind kind, const PlanNode *dep)
+        : PlanNode(plan, kind), dependency_(dep) {}
+
+    const PlanNode *dependency_;
+};
+
+class SingleInputNode : public SingleDependencyNode {
+public:
     void setInputVar(std::string inputVar) {
         inputVar_ = std::move(inputVar);
     }
@@ -56,11 +70,10 @@ public:
     }
 
 protected:
-    SingleInputNode(ExecutionPlan* plan, Kind kind, PlanNode* input)
-        : PlanNode(plan, kind), input_(input) {
+    SingleInputNode(ExecutionPlan* plan, Kind kind, const PlanNode* dep)
+        : SingleDependencyNode(plan, kind, dep) {
     }
 
-    PlanNode* input_{nullptr};
     // Datasource for this node.
     std::string inputVar_;
 };
diff --git a/src/validator/Validator.cpp b/src/validator/Validator.cpp
index 25b2ec7f9104c3aed704e19baa0dcb674cce2572..60fe86b174c538e9c811d213a48ecc4d3dc13346 100644
--- a/src/validator/Validator.cpp
+++ b/src/validator/Validator.cpp
@@ -95,7 +95,7 @@ Status Validator::appendPlan(PlanNode* node, PlanNode* appended) {
         case PlanNode::Kind::kGetNeighbors:
         case PlanNode::Kind::kAlterTag:
         case PlanNode::Kind::kAlterEdge: {
-            static_cast<SingleInputNode*>(node)->setInput(appended);
+            static_cast<SingleDependencyNode*>(node)->setDep(appended);
             break;
         }
         default: {
diff --git a/src/validator/test/ValidatorTestBase.h b/src/validator/test/ValidatorTestBase.h
index dd04203653c7708eeb6d18f026e364eed19514f0..fb1a56ed13490e511454039ed6e80a5e0d60ee7f 100644
--- a/src/validator/test/ValidatorTestBase.h
+++ b/src/validator/test/ValidatorTestBase.h
@@ -126,7 +126,7 @@ protected:
                 case PlanNode::Kind::kInsertVertices:
                 case PlanNode::Kind::kInsertEdges: {
                     auto* current = static_cast<const SingleInputNode*>(node);
-                    queue.emplace(current->input());
+                    queue.emplace(current->dep());
                     break;
                 }
                 case PlanNode::Kind::kUnion:
@@ -139,7 +139,7 @@ protected:
                 }
                 case PlanNode::Kind::kSelect: {
                     auto* current = static_cast<const Select*>(node);
-                    queue.emplace(current->input());
+                    queue.emplace(current->dep());
                     queue.emplace(current->then());
                     if (current->otherwise() != nullptr) {
                         queue.emplace(current->otherwise());
@@ -148,7 +148,7 @@ protected:
                 }
                 case PlanNode::Kind::kLoop: {
                     auto* current = static_cast<const Loop*>(node);
-                    queue.emplace(current->input());
+                    queue.emplace(current->dep());
                     queue.emplace(current->body());
                     break;
                 }