Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add code comments of validators. #3740

Merged
merged 8 commits into from
Feb 24, 2022
13 changes: 13 additions & 0 deletions src/graph/validator/AdminValidator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@

namespace nebula {
namespace graph {

// Validate options of create space sentence, and fill them into spaceDesc_
Status CreateSpaceValidator::validateImpl() {
auto sentence = static_cast<CreateSpaceSentence *>(sentence_);
ifNotExist_ = sentence->isIfNotExist();
Expand Down Expand Up @@ -150,6 +152,7 @@ Status CreateSpaceValidator::toPlan() {
return Status::OK();
}

// Validate sentence to create space by clone existed one. Just clone meta data, don't clone data.
Status CreateSpaceAsValidator::validateImpl() {
auto sentence = static_cast<CreateSpaceAsSentence *>(sentence_);
oldSpaceName_ = sentence->getOldSpaceName();
Expand All @@ -164,6 +167,7 @@ Status CreateSpaceAsValidator::toPlan() {
return Status::OK();
}

// Alter options of space: zone
Status AlterSpaceValidator::validateImpl() {
return Status::OK();
}
Expand Down Expand Up @@ -212,10 +216,13 @@ Status DropSpaceValidator::toPlan() {
return Status::OK();
}

// Show the sentence to create this space. It's created from options of space, so maybe is different
// from the origin sentence to create this space.
Status ShowCreateSpaceValidator::validateImpl() {
return Status::OK();
}

// Show create space need read permission on target space.
Status ShowCreateSpaceValidator::checkPermission() {
auto sentence = static_cast<ShowCreateSpaceSentence *>(sentence_);
auto spaceIdResult = qctx_->schemaMng()->toGraphSpaceID(*sentence->spaceName());
Expand Down Expand Up @@ -323,6 +330,7 @@ Status ShowListenerValidator::toPlan() {
return Status::OK();
}

// Register hosts, unregistered host won't be allowed to join cluster.
Status AddHostsValidator::validateImpl() {
auto sentence = static_cast<AddHostsSentence *>(sentence_);
auto hosts = sentence->hosts()->hosts();
Expand Down Expand Up @@ -527,6 +535,7 @@ Status ShowStatusValidator::validateImpl() {
return Status::OK();
}

// Plan to show stats of vertices and edges
Status ShowStatusValidator::toPlan() {
auto *node = ShowStats::make(qctx_, nullptr);
root_ = node;
Expand All @@ -538,6 +547,7 @@ Status ShowServiceClientsValidator::validateImpl() {
return Status::OK();
}

// Plan to show external service clients, e.g. Text Search client
Status ShowServiceClientsValidator::toPlan() {
auto sentence = static_cast<ShowServiceClientsSentence *>(sentence_);
auto type = sentence->getType();
Expand All @@ -551,6 +561,7 @@ Status SignInServiceValidator::validateImpl() {
return Status::OK();
}

// Plan to sign in external services, e.g. Text Search
Status SignInServiceValidator::toPlan() {
auto sentence = static_cast<SignInServiceSentence *>(sentence_);
std::vector<meta::cpp2::ServiceClient> clients;
Expand All @@ -568,6 +579,7 @@ Status SignOutServiceValidator::validateImpl() {
return Status::OK();
}

// Plan to sign out external services, e.g. Text Search
Status SignOutServiceValidator::toPlan() {
auto sentence = static_cast<SignOutServiceSentence *>(sentence_);
auto type = sentence->getType();
Expand Down Expand Up @@ -639,6 +651,7 @@ Status KillQueryValidator::validateImpl() {
return Status::OK();
}

// Plan to kill query by execution plan id
Status KillQueryValidator::toPlan() {
auto sentence = static_cast<KillQuerySentence *>(sentence_);
auto *node = KillQuery::make(qctx_, nullptr, sentence->sessionId(), sentence->epId());
Expand Down
1 change: 1 addition & 0 deletions src/graph/validator/AssignmentValidator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ Status AssignmentValidator::validateImpl() {
return Status::OK();
}

// Plan to process assignment in nGQL, e.g. $a = GO FROM <vid_list> OVER <edge_type> YIELD ...
Status AssignmentValidator::toPlan() {
root_ = validator_->root();
auto *var = qctx_->symTable()->newVariable(var_);
Expand Down
1 change: 1 addition & 0 deletions src/graph/validator/DownloadValidator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
namespace nebula {
namespace graph {

// Plan to download SST file from HDFS
Status DownloadValidator::toPlan() {
auto sentence = static_cast<DownloadSentence *>(sentence_);
if (sentence->host() == nullptr || sentence->port() == 0 || sentence->path() == nullptr) {
Expand Down
1 change: 1 addition & 0 deletions src/graph/validator/ExplainValidator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ ExplainValidator::ExplainValidator(Sentence* sentence, QueryContext* context)
}
}

// Check validity of format type string, and convert to lower case
static StatusOr<std::string> toExplainFormatType(const std::string& formatType) {
if (formatType.empty()) {
return kAllowedFmtType.front();
Expand Down
77 changes: 42 additions & 35 deletions src/graph/validator/FetchEdgesValidator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ Status FetchEdgesValidator::validateImpl() {
return Status::OK();
}

// Check validity of edge type specified in sentence
Status FetchEdgesValidator::validateEdgeName() {
auto &spaceID = space_.id;
auto status = qctx_->schemaMng()->toEdgeType(spaceID, edgeName_);
Expand All @@ -39,6 +40,8 @@ Status FetchEdgesValidator::validateEdgeName() {
return Status::OK();
}

// Check validity of edge key(src, type, rank, dst)
// from Input/Variable expression specified in sentence
StatusOr<std::string> FetchEdgesValidator::validateEdgeRef(const Expression *expr,
Value::Type type) {
const auto &kind = expr->kind();
Expand All @@ -62,11 +65,12 @@ StatusOr<std::string> FetchEdgesValidator::validateEdgeRef(const Expression *exp
return propExpr->sym();
}

// Check validity of edge key(src, type, rank, dst) from Variable/Constants specified in sentence
Status FetchEdgesValidator::validateEdgeKey() {
auto pool = qctx_->objPool();
auto *sentence = static_cast<FetchEdgesSentence *>(sentence_);
std::string inputVarName;
if (sentence->isRef()) {
if (sentence->isRef()) { // edge keys from Input/Variable
auto *srcExpr = sentence->ref()->srcid();
auto result = validateEdgeRef(srcExpr, vidType_);
NG_RETURN_IF_ERROR(result);
Expand Down Expand Up @@ -97,45 +101,48 @@ Status FetchEdgesValidator::validateEdgeKey() {
fetchCtx_->type = ConstantExpression::make(pool, edgeType_);
fetchCtx_->inputVarName = std::move(inputVarName);
return Status::OK();
}

DataSet edgeKeys{{kSrc, kRank, kDst}};
QueryExpressionContext ctx;
auto keys = sentence->keys()->keys();
edgeKeys.rows.reserve(keys.size());
for (const auto &key : keys) {
if (!ExpressionUtils::isEvaluableExpr(key->srcid(), qctx_)) {
return Status::SemanticError("`%s' is not evaluable.", key->srcid()->toString().c_str());
}
auto src = key->srcid()->eval(ctx);
if (src.type() != vidType_) {
std::stringstream ss;
ss << "the src should be type of " << vidType_ << ", but was`" << src.type() << "'";
return Status::SemanticError(ss.str());
}
auto ranking = key->rank();
} else { // Edge keys from constants
DataSet edgeKeys{{kSrc, kRank, kDst}};
QueryExpressionContext ctx;
auto keys = sentence->keys()->keys();
edgeKeys.rows.reserve(keys.size());
for (const auto &key : keys) {
if (!ExpressionUtils::isEvaluableExpr(key->srcid(), qctx_)) {
return Status::SemanticError("`%s' is not evaluable.", key->srcid()->toString().c_str());
}
auto src = key->srcid()->eval(ctx);
if (src.type() != vidType_) {
std::stringstream ss;
ss << "the src should be type of " << vidType_ << ", but was`" << src.type() << "'";
return Status::SemanticError(ss.str());
}
auto ranking = key->rank();

if (!ExpressionUtils::isEvaluableExpr(key->dstid(), qctx_)) {
return Status::SemanticError("`%s' is not evaluable.", key->dstid()->toString().c_str());
}
auto dst = key->dstid()->eval(ctx);
if (dst.type() != vidType_) {
std::stringstream ss;
ss << "the dst should be type of " << vidType_ << ", but was`" << dst.type() << "'";
return Status::SemanticError(ss.str());
if (!ExpressionUtils::isEvaluableExpr(key->dstid(), qctx_)) {
return Status::SemanticError("`%s' is not evaluable.", key->dstid()->toString().c_str());
}
auto dst = key->dstid()->eval(ctx);
if (dst.type() != vidType_) {
std::stringstream ss;
ss << "the dst should be type of " << vidType_ << ", but was`" << dst.type() << "'";
return Status::SemanticError(ss.str());
}
edgeKeys.emplace_back(nebula::Row({std::move(src), ranking, std::move(dst)}));
}
edgeKeys.emplace_back(nebula::Row({std::move(src), ranking, std::move(dst)}));
inputVarName = vctx_->anonVarGen()->getVar();
qctx_->ectx()->setResult(inputVarName,
ResultBuilder().value(Value(std::move(edgeKeys))).build());
fetchCtx_->src = ColumnExpression::make(pool, 0);
fetchCtx_->rank = ColumnExpression::make(pool, 1);
fetchCtx_->dst = ColumnExpression::make(pool, 2);
fetchCtx_->type = ConstantExpression::make(pool, edgeType_);
fetchCtx_->inputVarName = std::move(inputVarName);
return Status::OK();
}
inputVarName = vctx_->anonVarGen()->getVar();
qctx_->ectx()->setResult(inputVarName, ResultBuilder().value(Value(std::move(edgeKeys))).build());
fetchCtx_->src = ColumnExpression::make(pool, 0);
fetchCtx_->rank = ColumnExpression::make(pool, 1);
fetchCtx_->dst = ColumnExpression::make(pool, 2);
fetchCtx_->type = ConstantExpression::make(pool, edgeType_);
fetchCtx_->inputVarName = std::move(inputVarName);
return Status::OK();
}

// Validate columns of yield clause, rewrites expression to fit its sementic
// and disable some invalid expression types.
Status FetchEdgesValidator::validateYield(const YieldClause *yield) {
if (yield == nullptr) {
return Status::SemanticError("Missing yield clause.");
Expand Down
3 changes: 3 additions & 0 deletions src/graph/validator/FetchVerticesValidator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ Status FetchVerticesValidator::validateImpl() {
return Status::OK();
}

// Check validity of tags specified in sentence
Status FetchVerticesValidator::validateTag(const NameLabelList *nameLabels) {
if (nameLabels == nullptr) {
// all tag
Expand Down Expand Up @@ -50,6 +51,8 @@ Status FetchVerticesValidator::validateTag(const NameLabelList *nameLabels) {
return Status::OK();
}

// Validate columns of yield clause, rewrites expression to fit its sementic
// and disable some invalid expression types.
Status FetchVerticesValidator::validateYield(YieldClause *yield) {
if (yield == nullptr) {
return Status::SemanticError("Missing yield clause.");
Expand Down
3 changes: 3 additions & 0 deletions src/graph/validator/FindPathValidator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ Status FindPathValidator::validateImpl() {
return Status::OK();
}

// Check validity of filter expression, rewrites expression to fit its sementic,
// disable some invalid expression types, collect properties used in filter.
Status FindPathValidator::validateWhere(WhereClause* where) {
if (where == nullptr) {
return Status::OK();
Expand Down Expand Up @@ -62,6 +64,7 @@ Status FindPathValidator::validateWhere(WhereClause* where) {
return Status::OK();
}

// Check validity of yield columns
Status FindPathValidator::validateYield(YieldClause* yield) {
if (yield == nullptr) {
return Status::SemanticError("Missing yield clause.");
Expand Down
4 changes: 4 additions & 0 deletions src/graph/validator/GetSubgraphValidator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ Status GetSubgraphValidator::validateImpl() {
return Status::OK();
}

// Validate in-bound edge types
Status GetSubgraphValidator::validateInBound(InBoundClause* in) {
auto& edgeTypes = subgraphCtx_->edgeTypes;
if (in != nullptr) {
Expand All @@ -49,6 +50,7 @@ Status GetSubgraphValidator::validateInBound(InBoundClause* in) {
return Status::OK();
}

// Validate out-bound edge types
Status GetSubgraphValidator::validateOutBound(OutBoundClause* out) {
auto& edgeTypes = subgraphCtx_->edgeTypes;
if (out != nullptr) {
Expand All @@ -70,6 +72,7 @@ Status GetSubgraphValidator::validateOutBound(OutBoundClause* out) {
return Status::OK();
}

// Validate bidirectional(in-bound and out-bound) edge types
Status GetSubgraphValidator::validateBothInOutBound(BothInOutClause* out) {
auto& edgeTypes = subgraphCtx_->edgeTypes;
if (out != nullptr) {
Expand All @@ -93,6 +96,7 @@ Status GetSubgraphValidator::validateBothInOutBound(BothInOutClause* out) {
return Status::OK();
}

// Validate yield clause, which only supports YIELD vertices or edges
Status GetSubgraphValidator::validateYield(YieldClause* yield) {
if (yield == nullptr) {
return Status::SemanticError("Missing yield clause.");
Expand Down
12 changes: 12 additions & 0 deletions src/graph/validator/GoValidator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ Status GoValidator::validateImpl() {
return Status::SemanticError("$- must be referred in FROM before used in WHERE or YIELD");
}

// Only one variable allowed in whole sentence
if (!exprProps.varProps().empty()) {
if (goCtx_->from.fromType != kVariable) {
return Status::SemanticError(
Expand Down Expand Up @@ -60,6 +61,8 @@ Status GoValidator::validateImpl() {
return Status::OK();
}

// Validate filter expression, rewrites expression to fit sementic,
// deduce and check the type of expression, collect properties used in filter.
Status GoValidator::validateWhere(WhereClause* where) {
if (where == nullptr) {
return Status::OK();
Expand Down Expand Up @@ -87,6 +90,7 @@ Status GoValidator::validateWhere(WhereClause* where) {
return Status::OK();
}

// Validate the step sample/limit clause, which specify the sample/limit number for each steps.
Status GoValidator::validateTruncate(TruncateClause* truncate) {
if (truncate == nullptr) {
return Status::OK();
Expand Down Expand Up @@ -119,6 +123,8 @@ Status GoValidator::validateTruncate(TruncateClause* truncate) {
return Status::OK();
}

// Validate yield clause, disable the invalid expression types, rewrites expression to fit sementic,
// check expression type, collect properties used in yield.
Status GoValidator::validateYield(YieldClause* yield) {
if (yield == nullptr) {
return Status::SemanticError("Missing yield clause.");
Expand Down Expand Up @@ -156,6 +162,7 @@ Status GoValidator::validateYield(YieldClause* yield) {
return Status::OK();
}

// Get all tag IDs in the whole space
Status GoValidator::extractTagIds() {
auto tagStatus = qctx_->schemaMng()->getAllLatestVerTagSchema(space_.id);
NG_RETURN_IF_ERROR(tagStatus);
Expand All @@ -176,6 +183,8 @@ void GoValidator::extractPropExprs(const Expression* expr,
const_cast<Expression*>(expr)->accept(&visitor);
}

// Rewrites the property expression to corresponding Variable/Input expression
// which get related property from previous plan node.
Expression* GoValidator::rewrite2VarProp(const Expression* expr) {
auto matcher = [this](const Expression* e) -> bool {
return propExprColMap_.find(e->toString()) != propExprColMap_.end();
Expand All @@ -189,6 +198,9 @@ Expression* GoValidator::rewrite2VarProp(const Expression* expr) {
return RewriteVisitor::transform(expr, matcher, rewriter);
}

// Build the final output columns, collect the src/edge and dst properties used in the query,
// collect the input properties used in the query,
// rewrites output expression to Input/Variable expression to get properties from previous plan node
Status GoValidator::buildColumns() {
const auto& exprProps = goCtx_->exprProps;
const auto& dstTagProps = exprProps.dstTagProps();
Expand Down
8 changes: 8 additions & 0 deletions src/graph/validator/GroupByValidator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ Status GroupByValidator::validateImpl() {
return Status::OK();
}

// Validate the yield clause of group by.
// Check aggregate expression, and add Input/Variable expression for Project
Status GroupByValidator::validateYield(const YieldClause* yieldClause) {
std::vector<YieldColumn*> columns;
if (yieldClause != nullptr) {
Expand Down Expand Up @@ -78,6 +80,8 @@ Status GroupByValidator::validateYield(const YieldClause* yieldClause) {
return Status::OK();
}

// Validate group by expression.
// The expression must contains Input/Variable expression, and shouldn't contains some expressions.
Status GroupByValidator::validateGroup(const GroupClause* groupClause) {
if (!groupClause) return Status::OK();
std::vector<YieldColumn*> columns;
Expand Down Expand Up @@ -141,6 +145,10 @@ Status GroupByValidator::toPlan() {
return Status::OK();
}

// Check the correctness of group by clause and yield clause.
// Check expression type, disable invalid properties.
// Check group by expression and yield expression, variable expression in yield columns must
// contains in group by expressions too.
Status GroupByValidator::groupClauseSemanticCheck() {
// deduce group items and build outputs_
DCHECK_EQ(aggOutputColNames_.size(), groupItems_.size());
Expand Down
1 change: 1 addition & 0 deletions src/graph/validator/IngestValidator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
namespace nebula {
namespace graph {

// Plan to ingest SST file in server side
Status IngestValidator::toPlan() {
auto *doNode = Ingest::make(qctx_, nullptr);
root_ = doNode;
Expand Down
1 change: 1 addition & 0 deletions src/graph/validator/LimitValidator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

namespace nebula {
namespace graph {
// Validate limit number
Status LimitValidator::validateImpl() {
auto limitSentence = static_cast<LimitSentence *>(sentence_);
offset_ = limitSentence->offset();
Expand Down
Loading