Skip to content

Commit

Permalink
Finish the bug in validator with good Executor Framework (#4574)
Browse files Browse the repository at this point in the history
* Add validator and fix executor

* change some small issues
  • Loading branch information
peter-rich authored Aug 23, 2022
1 parent c594a10 commit 8bac443
Show file tree
Hide file tree
Showing 13 changed files with 148 additions and 22 deletions.
1 change: 1 addition & 0 deletions src/graph/executor/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ nebula_add_library(
algo/ShortestPathBase.cpp
algo/SingleShortestPath.cpp
algo/BatchShortestPath.cpp
algo/IsomorExecutor.cpp
admin/AddHostsExecutor.cpp
admin/DropHostsExecutor.cpp
admin/SwitchSpaceExecutor.cpp
Expand Down
8 changes: 5 additions & 3 deletions src/graph/executor/Executor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
#include "graph/executor/algo/ProduceAllPathsExecutor.h"
#include "graph/executor/algo/ShortestPathExecutor.h"
#include "graph/executor/algo/SubgraphExecutor.h"
#include "graph/executor/algo/IsomorExecutor.h"
#include "graph/executor/logic/ArgumentExecutor.h"
#include "graph/executor/logic/LoopExecutor.h"
#include "graph/executor/logic/PassThroughExecutor.h"
Expand Down Expand Up @@ -460,6 +461,10 @@ Executor *Executor::makeExecutor(QueryContext *qctx, const PlanNode *node) {
case PlanNode::Kind::kSubgraph: {
return pool->makeAndAdd<SubgraphExecutor>(node, qctx);
}
case PlanNode::Kind::kIsomor: {
// return pool->makeAndAdd<SubgraphExecutor>(node, qctx);
return pool->makeAndAdd<IsomorExecutor>(node, qctx);
}
case PlanNode::Kind::kAddHosts: {
return pool->makeAndAdd<AddHostsExecutor>(node, qctx);
}
Expand Down Expand Up @@ -550,9 +555,6 @@ Executor *Executor::makeExecutor(QueryContext *qctx, const PlanNode *node) {
case PlanNode::Kind::kShortestPath: {
return pool->makeAndAdd<ShortestPathExecutor>(node, qctx);
}
// case PlanNode::Kind::kIsomor: {
// return pool->makeAndAdd<SomeIsomorExecutor>(node, qctx);
// }
case PlanNode::Kind::kUnknown: {
LOG(FATAL) << "Unknown plan node kind " << static_cast<int32_t>(node->kind());
break;
Expand Down
88 changes: 88 additions & 0 deletions src/graph/executor/algo/IsomorExecutor.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
// Copyright (c) 2020 vesoft inc. All rights reserved.
//
// This source code is licensed under Apache 2.0 License.

#include "graph/executor/algo/IsomorExecutor.h"

#include "graph/planner/plan/Algo.h"

namespace nebula {
namespace graph {

folly::Future<Status> IsomorExecutor::execute() {
// TODO: Replace the following codes with subgraph matching. Return type.
SCOPED_TIMER(&execTime_);
auto* subgraph = asNode<Subgraph>(node());
DataSet ds;
ds.colNames = subgraph->colNames();

uint32_t steps = subgraph->steps();
const auto& currentStepVal = ectx_->getValue(subgraph->currentStepVar());
DCHECK(currentStepVal.isInt());
auto currentStep = currentStepVal.getInt();
auto resultVar = subgraph->resultVar();

auto iter = ectx_->getResult(subgraph->inputVar()).iter();
auto gnSize = iter->size();

ResultBuilder builder;
builder.value(iter->valuePtr());

std::unordered_map<Value, int64_t> currentVids;
currentVids.reserve(gnSize);
historyVids_.reserve(historyVids_.size() + gnSize);
if (currentStep == 1) {
for (; iter->valid(); iter->next()) {
const auto& src = iter->getColumn(nebula::kVid);
currentVids.emplace(src, 0);
}
iter->reset();
}
auto& biDirectEdgeTypes = subgraph->biDirectEdgeTypes();
while (iter->valid()) {
const auto& dst = iter->getEdgeProp("*", nebula::kDst);
auto findIter = historyVids_.find(dst);
if (findIter != historyVids_.end()) {
if (biDirectEdgeTypes.empty()) {
iter->next();
} else {
const auto& typeVal = iter->getEdgeProp("*", nebula::kType);
if (UNLIKELY(!typeVal.isInt())) {
iter->erase();
continue;
}
auto type = typeVal.getInt();
if (biDirectEdgeTypes.find(type) != biDirectEdgeTypes.end()) {
if (type < 0 || findIter->second + 2 == currentStep) {
iter->erase();
} else {
iter->next();
}
} else {
iter->next();
}
}
} else {
if (currentStep == steps) {
iter->erase();
continue;
}
if (currentVids.emplace(dst, currentStep).second) {
Row row;
row.values.emplace_back(std::move(dst));
ds.rows.emplace_back(std::move(row));
}
iter->next();
}
}
iter->reset();
builder.iter(std::move(iter));
ectx_->setResult(resultVar, builder.build());
// update historyVids
historyVids_.insert(std::make_move_iterator(currentVids.begin()),
std::make_move_iterator(currentVids.end()));
return finish(ResultBuilder().value(Value(std::move(ds))).build());
}

} // namespace graph
} // namespace nebula
26 changes: 26 additions & 0 deletions src/graph/executor/algo/IsomorExecutor.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright (c) 2020 vesoft inc. All rights reserved.
//
// This source code is licensed under Apache 2.0 License.

#ifndef GRAPH_EXECUTOR_ALGO_ISOMOREXECUTOR_H_
#define GRAPH_EXECUTOR_ALGO_ISOMOREXECUTOR_H_

#include "graph/executor/Executor.h"

namespace nebula {
namespace graph {
class IsomorExecutor : public Executor {
public:
IsomorExecutor(const PlanNode* node, QueryContext* qctx)
: Executor("IsomorExecutor", node, qctx) {}

folly::Future<Status> execute() override;

private:
std::unordered_map<Value, int64_t> historyVids_;
};

} // namespace graph
} // namespace nebula

#endif // GRAPH_EXECUTOR_ALGO_ISOMOREXECUTOR_H_
6 changes: 3 additions & 3 deletions src/graph/planner/plan/PlanNode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,8 @@ const char* PlanNode::toString(PlanNode::Kind kind) {
return "CartesianProduct";
case Kind::kSubgraph:
return "Subgraph";
case Kind::kIsomor:
return "Isomor";
case Kind::kAddHosts:
return "AddHosts";
case Kind::kDropHosts:
Expand Down Expand Up @@ -300,9 +302,7 @@ const char* PlanNode::toString(PlanNode::Kind kind) {
return "Argument";
case Kind::kRollUpApply:
return "RollUpApply";
case Kind::kIsomor:
return "Isomor";
// no default so the compiler will warning when lack
// no default so the compiler will warning when lack
}
LOG(FATAL) << "Impossible kind plan node " << static_cast<int>(kind);
}
Expand Down
4 changes: 4 additions & 0 deletions src/graph/planner/plan/Query.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -562,6 +562,10 @@ std::unique_ptr<PlanNodeDescription> DataCollect::explain() const {
addDescription("kind", "SUBGRAPH", desc.get());
break;
}
case DCKind::kIsomor: {
addDescription("kind", "ISOMOR", desc.get());
break;
}
case DCKind::kRowBasedMove: {
addDescription("kind", "ROW", desc.get());
break;
Expand Down
1 change: 1 addition & 0 deletions src/graph/planner/plan/Query.h
Original file line number Diff line number Diff line change
Expand Up @@ -1166,6 +1166,7 @@ class DataCollect final : public VariableDependencyNode {
public:
enum class DCKind : uint8_t {
kSubgraph,
kIsomor,
kRowBasedMove,
kMToN,
kBFSShortest,
Expand Down
1 change: 1 addition & 0 deletions src/graph/service/PermissionCheck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ namespace graph {
case Sentence::Kind::kFetchVertices:
case Sentence::Kind::kFetchEdges:
case Sentence::Kind::kFindPath:
case Sentence::Kind::kIsomor:
case Sentence::Kind::kGetSubgraph:
case Sentence::Kind::kLimit:
case Sentence::Kind::kGroupBy:
Expand Down
11 changes: 6 additions & 5 deletions src/graph/validator/IsomorValidator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,16 @@ namespace graph {
Status IsomorValidator::validateImpl() {
auto *fSentence = static_cast<IsomorSentence *>(sentence_);
fetchCtx_ = getContext<IsomorContext>();
NG_RETURN_IF_ERROR(validateTag(fSentence->tags()));
NG_RETURN_IF_ERROR(validateTag(fSentence->graphs()));
return Status::OK();
}
// Check validity of tags specified in sentence
Status IsomorValidator::validateTag(const NameLabelList *nameLabels) {
if (nameLabels == nullptr) {
// Wthether Found Tag in the storage? --> need the coorperation of the storage section.
} else {
}
auto graphs = nameLabels->labels();

// The first graph is query graph and the second graph is the data graph
fetchCtx_->querySpace = qctx_->schemaMng()->toGraphSpaceID(*graphs[0]);
fetchCtx_->dataSpace = qctx_->schemaMng()->toGraphSpaceID(*graphs[1]);
return Status::OK();
}
} // namespace graph
Expand Down
6 changes: 3 additions & 3 deletions src/graph/validator/IsomorValidator.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
* This source code is licensed under Apache 2.0 License.
*/

#ifndef _VALIDATOR_FETCH_VERTICES_VALIDATOR_H_
#define _VALIDATOR_FETCH_VERTICES_VALIDATOR_H_
#ifndef _VALIDATOR_ISOMOR_VALIDATOR_H_
#define _VALIDATOR_ISOMOR_VALIDATOR_H_

#include "graph/context/ast/QueryAstContext.h"
#include "graph/validator/Validator.h"
Expand Down Expand Up @@ -36,4 +36,4 @@ class IsomorValidator final : public Validator {
} // namespace graph
} // namespace nebula

#endif // _VALIDATOR_FETCH_VERTICES_VALIDATOR_H_
#endif // _VALIDATOR_ISOMOR_VALIDATOR_H_
3 changes: 3 additions & 0 deletions src/graph/validator/Validator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include "graph/visitor/DeduceTypeVisitor.h"
#include "graph/visitor/EvaluableExprVisitor.h"
#include "parser/Sentence.h"
#include "graph/validator/IsomorValidator.h"

namespace nebula {
namespace graph {
Expand Down Expand Up @@ -103,6 +104,8 @@ std::unique_ptr<Validator> Validator::makeValidator(Sentence* sentence, QueryCon
return std::make_unique<DropSpaceValidator>(sentence, context);
case Sentence::Kind::kDropTag:
return std::make_unique<DropTagValidator>(sentence, context);
case Sentence::Kind::kIsomor:
return std::make_unique<IsomorValidator>(sentence, context);
case Sentence::Kind::kDropEdge:
return std::make_unique<DropEdgeValidator>(sentence, context);
case Sentence::Kind::kShowCreateSpace:
Expand Down
4 changes: 2 additions & 2 deletions src/parser/TraverseSentences.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ std::string IsomorSentence::toString() const {
buf.reserve(256);
buf += "ISOMOR";
buf += " ";
if (tags_->empty()) {
if (graphs_->empty()) {
buf += "*";
} else {
buf += tags_->toString();
buf += graphs_->toString();
}
printf("Here is the string: %s \n", buf.c_str());
return buf;
Expand Down
11 changes: 5 additions & 6 deletions src/parser/TraverseSentences.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,16 @@ namespace nebula {

class IsomorSentence final : public Sentence {
public:
explicit IsomorSentence(NameLabelList* tags) {
tags_.reset(tags);
explicit IsomorSentence(NameLabelList* graphs) {
graphs_.reset(graphs);
}
const NameLabelList* tags() const {
return tags_->empty() ? nullptr : tags_.get();
const NameLabelList* graphs() const {
return graphs_->empty() ? nullptr : graphs_.get();
}
std::string toString() const override;
~IsomorSentence();

private:
std::unique_ptr<NameLabelList> tags_;
std::unique_ptr<NameLabelList> graphs_;
};

class GoSentence final : public Sentence {
Expand Down

0 comments on commit 8bac443

Please sign in to comment.