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

Support properties in where clause #3443

Merged
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 2 additions & 20 deletions src/graph/validator/FetchEdgesValidator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,18 +136,6 @@ Status FetchEdgesValidator::validateEdgeKey() {
return Status::OK();
}

void FetchEdgesValidator::extractEdgeProp(ExpressionProps &exprProps) {
exprProps.insertEdgeProp(edgeType_, kSrc);
exprProps.insertEdgeProp(edgeType_, kDst);
exprProps.insertEdgeProp(edgeType_, kRank);
exprProps.insertEdgeProp(edgeType_, kType);

for (std::size_t i = 0; i < edgeSchema_->getNumFields(); ++i) {
const auto propName = edgeSchema_->getFieldName(i);
exprProps.insertEdgeProp(edgeType_, propName);
}
}

Status FetchEdgesValidator::validateYield(const YieldClause *yield) {
if (yield == nullptr) {
return Status::SemanticError("Missing yield clause.");
Expand All @@ -158,12 +146,6 @@ Status FetchEdgesValidator::validateYield(const YieldClause *yield) {
exprProps.insertEdgeProp(edgeType_, nebula::kDst);
exprProps.insertEdgeProp(edgeType_, nebula::kRank);

for (const auto &col : yield->columns()) {
if (ExpressionUtils::hasAny(col->expr(), {Expression::Kind::kEdge})) {
extractEdgeProp(exprProps);
break;
}
}
auto size = yield->columns().size();
outputs_.reserve(size);

Expand All @@ -182,8 +164,8 @@ Status FetchEdgesValidator::validateYield(const YieldClause *yield) {
NG_RETURN_IF_ERROR(typeStatus);
outputs_.emplace_back(col->name(), typeStatus.value());
newCols->addColumn(col->clone().release());

NG_RETURN_IF_ERROR(deduceProps(colExpr, exprProps));
std::vector<EdgeType> edgeTypes{edgeType_};
NG_RETURN_IF_ERROR(deduceProps(colExpr, exprProps, nullptr, &edgeTypes));
}

if (exprProps.hasInputVarProperty()) {
Expand Down
2 changes: 0 additions & 2 deletions src/graph/validator/FetchEdgesValidator.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@ class FetchEdgesValidator final : public Validator {

Status validateEdgeKey();

void extractEdgeProp(ExpressionProps& exprProps);

Status validateYield(const YieldClause* yieldClause);

AstContext* getAstContext() override { return fetchCtx_.get(); }
Expand Down
19 changes: 3 additions & 16 deletions src/graph/validator/FetchVerticesValidator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ Status FetchVerticesValidator::validateTag(const NameLabelList *nameLabels) {
NG_RETURN_IF_ERROR(tagStatus);
for (const auto &tag : tagStatus.value()) {
tagsSchema_.emplace(tag.first, tag.second);
tagIds_.emplace_back(tag.first);
}
} else {
auto labels = nameLabels->labels();
Expand All @@ -43,6 +44,7 @@ Status FetchVerticesValidator::validateTag(const NameLabelList *nameLabels) {
return Status::SemanticError("no schema found for `%s'", label->c_str());
}
tagsSchema_.emplace(tagID, tagSchema);
tagIds_.emplace_back(tagID);
}
}
return Status::OK();
Expand Down Expand Up @@ -76,12 +78,8 @@ Status FetchVerticesValidator::validateYield(YieldClause *yield) {
col->setAlias(col->name());
col->setExpr(InputPropertyExpression::make(pool, nebula::kVid));
}
if (ExpressionUtils::hasAny(colExpr, {Expression::Kind::kVertex})) {
extractVertexProp(exprProps);
}
newCols->addColumn(col->clone().release());

NG_RETURN_IF_ERROR(deduceProps(colExpr, exprProps));
NG_RETURN_IF_ERROR(deduceProps(colExpr, exprProps, &tagIds_));
}
if (exprProps.tagProps().empty()) {
for (const auto &tagSchema : tagsSchema_) {
Expand All @@ -105,16 +103,5 @@ Status FetchVerticesValidator::validateYield(YieldClause *yield) {
return Status::OK();
}

void FetchVerticesValidator::extractVertexProp(ExpressionProps &exprProps) {
for (const auto &tagSchema : tagsSchema_) {
auto tagID = tagSchema.first;
exprProps.insertTagProp(tagID, nebula::kTag);
for (std::size_t i = 0; i < tagSchema.second->getNumFields(); ++i) {
const auto propName = tagSchema.second->getFieldName(i);
exprProps.insertTagProp(tagID, propName);
}
}
}

} // namespace graph
} // namespace nebula
3 changes: 1 addition & 2 deletions src/graph/validator/FetchVerticesValidator.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,9 @@ class FetchVerticesValidator final : public Validator {

AstContext* getAstContext() override { return fetchCtx_.get(); }

void extractVertexProp(ExpressionProps& exprProps);

private:
std::map<TagID, std::shared_ptr<const meta::SchemaProviderIf>> tagsSchema_;
std::vector<TagID> tagIds_;

std::unique_ptr<FetchVerticesContext> fetchCtx_;
};
Expand Down
105 changes: 23 additions & 82 deletions src/graph/validator/GoValidator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,6 @@
namespace nebula {
namespace graph {

static const char* COLNAME_EDGE = "EDGE";
static const char* SRC_VERTEX = "$^";
static const char* DST_VERTEX = "$$";

Status GoValidator::validateImpl() {
auto* goSentence = static_cast<GoSentence*>(sentence_);
goCtx_ = getContext<GoContext>();
Expand All @@ -27,6 +23,7 @@ Status GoValidator::validateImpl() {
NG_RETURN_IF_ERROR(ValidateUtil::validateStep(goSentence->stepClause(), goCtx_->steps));
NG_RETURN_IF_ERROR(validateStarts(goSentence->fromClause(), goCtx_->from));
NG_RETURN_IF_ERROR(ValidateUtil::validateOver(qctx_, goSentence->overClause(), goCtx_->over));
NG_RETURN_IF_ERROR(extractTagIds());
NG_RETURN_IF_ERROR(validateWhere(goSentence->whereClause()));
NG_RETURN_IF_ERROR(validateYield(goSentence->yieldClause()));
NG_RETURN_IF_ERROR(validateTruncate(goSentence->truncateClause()));
Expand Down Expand Up @@ -90,7 +87,7 @@ Status GoValidator::validateWhere(WhereClause* where) {
return Status::SemanticError(ss.str());
}

NG_RETURN_IF_ERROR(deduceProps(filter, goCtx_->exprProps));
NG_RETURN_IF_ERROR(deduceProps(filter, goCtx_->exprProps, &tagIds_, &goCtx_->over.edgeTypes));
goCtx_->filter = filter;
return Status::OK();
}
Expand Down Expand Up @@ -140,32 +137,21 @@ Status GoValidator::validateYield(YieldClause* yield) {
return Status::SemanticError("`%s' is not support in go sentence.", col->toString().c_str());
}

const auto& vertexExprs = ExpressionUtils::collectAll(col->expr(), {Expression::Kind::kVertex});
for (const auto* expr : vertexExprs) {
const auto& colName = static_cast<const VertexExpression*>(expr)->name();
if (colName == SRC_VERTEX) {
NG_RETURN_IF_ERROR(extractVertexProp(exprProps, true));
} else if (colName == DST_VERTEX) {
NG_RETURN_IF_ERROR(extractVertexProp(exprProps, false));
} else {
return Status::SemanticError("`%s' is not support in go sentence.",
col->toString().c_str());
}
auto vertexExpr = ExpressionUtils::findAny(col->expr(), {Expression::Kind::kVertex});
if (vertexExpr != nullptr &&
static_cast<const VertexExpression*>(vertexExpr)->name() == "VERTEX") {
return Status::SemanticError("`%s' is not support in go sentence.", col->toString().c_str());
}

col->setExpr(ExpressionUtils::rewriteLabelAttr2EdgeProp(col->expr()));
NG_RETURN_IF_ERROR(ValidateUtil::invalidLabelIdentifiers(col->expr()));

auto* colExpr = col->expr();
if (ExpressionUtils::hasAny(colExpr, {Expression::Kind::kEdge})) {
extractEdgeProp(exprProps);
}

auto typeStatus = deduceExprType(colExpr);
NG_RETURN_IF_ERROR(typeStatus);
auto type = typeStatus.value();
outputs_.emplace_back(col->name(), type);
NG_RETURN_IF_ERROR(deduceProps(colExpr, exprProps));
NG_RETURN_IF_ERROR(deduceProps(colExpr, exprProps, &tagIds_, &goCtx_->over.edgeTypes));
}

const auto& over = goCtx_->over;
Expand All @@ -180,43 +166,23 @@ Status GoValidator::validateYield(YieldClause* yield) {
return Status::OK();
}

Status GoValidator::extractVertexProp(ExpressionProps& exprProps, bool isSrc) {
const auto tagStatus = qctx_->schemaMng()->getAllLatestVerTagSchema(space_.id);
Status GoValidator::extractTagIds() {
auto tagStatus = qctx_->schemaMng()->getAllLatestVerTagSchema(space_.id);
NG_RETURN_IF_ERROR(tagStatus);
for (const auto& tag : tagStatus.value()) {
auto tagID = tag.first;
const auto& tagSchema = tag.second;
if (isSrc) {
for (size_t i = 0; i < tagSchema->getNumFields(); ++i) {
exprProps.insertSrcTagProp(tagID, tagSchema->getFieldName(i));
}
} else {
for (size_t i = 0; i < tagSchema->getNumFields(); ++i) {
exprProps.insertDstTagProp(tagID, tagSchema->getFieldName(i));
}
}
tagIds_.emplace_back(tag.first);
}
return Status::OK();
}

Status GoValidator::extractEdgeProp(ExpressionProps& exprProps) {
const auto& edgeTypes = goCtx_->over.edgeTypes;
for (const auto& edgeType : edgeTypes) {
const auto& edgeSchema = qctx_->schemaMng()->getEdgeSchema(space_.id, std::abs(edgeType));
exprProps.insertEdgeProp(edgeType, kType);
exprProps.insertEdgeProp(edgeType, kSrc);
exprProps.insertEdgeProp(edgeType, kDst);
exprProps.insertEdgeProp(edgeType, kRank);
for (size_t i = 0; i < edgeSchema->getNumFields(); ++i) {
exprProps.insertEdgeProp(edgeType, edgeSchema->getFieldName(i));
}
}
return Status::OK();
}

void GoValidator::extractPropExprs(const Expression* expr) {
ExtractPropExprVisitor visitor(
vctx_, goCtx_->srcEdgePropsExpr, goCtx_->dstPropsExpr, inputPropCols_, propExprColMap_);
void GoValidator::extractPropExprs(const Expression* expr,
std::unordered_set<std::string>& uniqueExpr) {
ExtractPropExprVisitor visitor(vctx_,
goCtx_->srcEdgePropsExpr,
goCtx_->dstPropsExpr,
inputPropCols_,
propExprColMap_,
uniqueExpr);
const_cast<Expression*>(expr)->accept(&visitor);
}

Expand Down Expand Up @@ -258,42 +224,17 @@ Status GoValidator::buildColumns() {
inputPropCols_ = pool->add(new YieldColumns());
}

std::unordered_set<std::string> uniqueEdgeVertexExpr;
auto filter = goCtx_->filter;
if (filter != nullptr) {
extractPropExprs(filter);
auto newFilter = filter->clone();
goCtx_->filter = rewrite2VarProp(newFilter);
extractPropExprs(filter, uniqueEdgeVertexExpr);
goCtx_->filter = rewrite2VarProp(filter);
}

std::unordered_set<std::string> existExpr;
auto* newYieldExpr = pool->add(new YieldColumns());
for (auto* col : goCtx_->yieldExpr->columns()) {
const auto& vertexExprs = ExpressionUtils::collectAll(col->expr(), {Expression::Kind::kVertex});
auto existEdge = ExpressionUtils::hasAny(col->expr(), {Expression::Kind::kEdge});
if (!existEdge && vertexExprs.empty()) {
extractPropExprs(col->expr());
newYieldExpr->addColumn(new YieldColumn(rewrite2VarProp(col->expr()), col->alias()));
} else {
if (existEdge) {
if (existExpr.emplace(COLNAME_EDGE).second) {
goCtx_->srcEdgePropsExpr->addColumn(
new YieldColumn(EdgeExpression::make(pool), COLNAME_EDGE));
}
}
for (const auto* expr : vertexExprs) {
const auto& colName = static_cast<const VertexExpression*>(expr)->name();
if (existExpr.emplace(colName).second) {
if (colName == SRC_VERTEX) {
goCtx_->srcEdgePropsExpr->addColumn(
new YieldColumn(VertexExpression::make(pool), SRC_VERTEX));
} else {
goCtx_->dstPropsExpr->addColumn(
new YieldColumn(VertexExpression::make(pool), DST_VERTEX));
}
}
}
newYieldExpr->addColumn(col->clone().release());
}
extractPropExprs(col->expr(), uniqueEdgeVertexExpr);
newYieldExpr->addColumn(new YieldColumn(rewrite2VarProp(col->expr()), col->alias()));
}
goCtx_->yieldExpr = newYieldExpr;
return Status::OK();
Expand Down
9 changes: 4 additions & 5 deletions src/graph/validator/GoValidator.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,19 +32,18 @@ class GoValidator final : public Validator {

Status buildColumns();

void extractPropExprs(const Expression* expr);
Status extractTagIds();

Expression* rewrite2VarProp(const Expression* expr);

Status extractVertexProp(ExpressionProps& exprProps, bool isSrc);
void extractPropExprs(const Expression* expr, std::unordered_set<std::string>& uniqueCols);

Status extractEdgeProp(ExpressionProps& exprProps);
Expression* rewrite2VarProp(const Expression* expr);

private:
std::unique_ptr<GoContext> goCtx_;

YieldColumns* inputPropCols_{nullptr};
std::unordered_map<std::string, YieldColumn*> propExprColMap_;
std::vector<TagID> tagIds_;
};
} // namespace graph
} // namespace nebula
Expand Down
34 changes: 10 additions & 24 deletions src/graph/validator/LookupValidator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ Status LookupValidator::validateImpl() {
lookupCtx_ = getContext<LookupContext>();

NG_RETURN_IF_ERROR(validateFrom());
NG_RETURN_IF_ERROR(validateFilter());
NG_RETURN_IF_ERROR(validateWhere());
NG_RETURN_IF_ERROR(validateYield());
return Status::OK();
}
Expand All @@ -53,19 +53,7 @@ Status LookupValidator::validateFrom() {
NG_RETURN_IF_ERROR(ret);
lookupCtx_->isEdge = ret.value().first;
lookupCtx_->schemaId = ret.value().second;
return Status::OK();
}

Status LookupValidator::extractSchemaProp() {
shared_ptr<const NebulaSchemaProvider> schema;
NG_RETURN_IF_ERROR(getSchemaProvider(&schema));
for (std::size_t i = 0; i < schema->getNumFields(); ++i) {
const auto& propName = schema->getFieldName(i);
auto iter = std::find(idxReturnCols_.begin(), idxReturnCols_.end(), propName);
if (iter == idxReturnCols_.end()) {
idxReturnCols_.emplace_back(propName);
}
}
schemaIds_.emplace_back(ret.value().second);
return Status::OK();
}

Expand Down Expand Up @@ -107,9 +95,6 @@ Status LookupValidator::validateYieldEdge() {
{Expression::Kind::kAggregate, Expression::Kind::kVertex})) {
return Status::SemanticError("illegal yield clauses `%s'", col->toString().c_str());
}
if (ExpressionUtils::hasAny(col->expr(), {Expression::Kind::kEdge})) {
NG_RETURN_IF_ERROR(extractSchemaProp());
}
if (col->expr()->kind() == Expression::Kind::kLabelAttribute) {
const auto& schemaName = static_cast<LabelAttributeExpression*>(col->expr())->left()->name();
if (schemaName != sentence()->from()) {
Expand All @@ -124,7 +109,7 @@ Status LookupValidator::validateYieldEdge() {
NG_RETURN_IF_ERROR(typeStatus);
outputs_.emplace_back(col->name(), typeStatus.value());
yieldExpr->addColumn(col->clone().release());
NG_RETURN_IF_ERROR(deduceProps(colExpr, exprProps_));
NG_RETURN_IF_ERROR(deduceProps(colExpr, exprProps_, nullptr, &schemaIds_));
}
return Status::OK();
}
Expand All @@ -137,9 +122,6 @@ Status LookupValidator::validateYieldTag() {
{Expression::Kind::kAggregate, Expression::Kind::kEdge})) {
return Status::SemanticError("illegal yield clauses `%s'", col->toString().c_str());
}
if (ExpressionUtils::hasAny(col->expr(), {Expression::Kind::kVertex})) {
NG_RETURN_IF_ERROR(extractSchemaProp());
}
if (col->expr()->kind() == Expression::Kind::kLabelAttribute) {
const auto& schemaName = static_cast<LabelAttributeExpression*>(col->expr())->left()->name();
if (schemaName != sentence()->from()) {
Expand All @@ -154,7 +136,7 @@ Status LookupValidator::validateYieldTag() {
NG_RETURN_IF_ERROR(typeStatus);
outputs_.emplace_back(col->name(), typeStatus.value());
yieldExpr->addColumn(col->clone().release());
NG_RETURN_IF_ERROR(deduceProps(colExpr, exprProps_));
NG_RETURN_IF_ERROR(deduceProps(colExpr, exprProps_, &schemaIds_));
}
return Status::OK();
}
Expand Down Expand Up @@ -187,7 +169,7 @@ Status LookupValidator::validateYield() {
return Status::OK();
}

Status LookupValidator::validateFilter() {
Status LookupValidator::validateWhere() {
auto whereClause = sentence()->whereClause();
if (whereClause == nullptr) {
return Status::OK();
Expand All @@ -211,7 +193,11 @@ Status LookupValidator::validateFilter() {
// Make sure the type of the rewritted filter expr is right
NG_RETURN_IF_ERROR(deduceExprType(lookupCtx_->filter));
}
NG_RETURN_IF_ERROR(deduceProps(lookupCtx_->filter, exprProps_));
if (lookupCtx_->isEdge) {
NG_RETURN_IF_ERROR(deduceProps(lookupCtx_->filter, exprProps_, nullptr, &schemaIds_));
} else {
NG_RETURN_IF_ERROR(deduceProps(lookupCtx_->filter, exprProps_, &schemaIds_));
}
return Status::OK();
}

Expand Down
Loading