Skip to content

Commit

Permalink
add rewrite attributeExpr to LabelTagPropertyExpr
Browse files Browse the repository at this point in the history
  • Loading branch information
nevermore3 committed Nov 11, 2021
1 parent 005d22a commit 28e8099
Show file tree
Hide file tree
Showing 7 changed files with 56 additions and 24 deletions.
6 changes: 3 additions & 3 deletions src/common/expression/LabelTagPropertyExpression.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,11 @@ class LabelTagPropertyExpression final : public Expression {
return LabelTagPropertyExpression::make(pool_, label_, tag_, prop_);
}

const std::string& prop() { return prop_; }
const std::string& prop() const { return prop_; }

const std::string& tag() { return tag_; }
const std::string& tag() const { return tag_; }

const std::string& label() { return label_; }
const std::string& label() const { return label_; }

private:
LabelTagPropertyExpression(ObjectPool* pool,
Expand Down
34 changes: 31 additions & 3 deletions src/graph/util/ExpressionUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,14 +106,44 @@ bool ExpressionUtils::isEvaluableExpr(const Expression *expr) {
return visitor.ok();
}

// rewrite Attribute to LabelTagProp
Expression *ExpressionUtils::rewriteAttr2LabelTagProp(const Expression *expr) {
ObjectPool *pool = expr->getObjPool();

auto matcher = [](const Expression *e) -> bool {
if (e->kind() == Expression::Kind::kAttribute) {
auto attrExpr = static_cast<const AttributeExpression *>(e);
if (attrExpr->left()->kind() == Expression::Kind::kLabelAttribute &&
attrExpr->right()->kind() == Expression::Kind::kLabel) {
return true;
}
}
return false;
};

auto rewriter = [pool](const Expression *e) -> Expression * {
auto attrExpr = static_cast<const AttributeExpression *>(e);
auto labelAttrExpr = static_cast<const LabelAttributeExpression *>(attrExpr->left());
auto labelExpr = const_cast<LabelExpression *>(labelAttrExpr->left());
auto tagExpr = const_cast<ConstantExpression *>(labelAttrExpr->right());
auto propExpr = static_cast<const LabelExpression *>(attrExpr->right());
QueryExpressionContext ctx(nullptr);
const auto &label = labelExpr->eval(ctx);
const auto &tag = tagExpr->eval(ctx);
const auto &prop = const_cast<LabelExpression *>(propExpr)->eval(ctx);
return LabelTagPropertyExpression::make(pool, label.getStr(), tag.getStr(), prop.getStr());
};

return RewriteVisitor::transform(expr, std::move(matcher), std::move(rewriter));
}

// rewrite LabelAttr to EdgeProp
Expression *ExpressionUtils::rewriteLabelAttr2EdgeProp(const Expression *expr) {
ObjectPool *pool = expr->getObjPool();
auto matcher = [](const Expression *e) -> bool {
return e->kind() == Expression::Kind::kLabelAttribute;
};
auto rewriter = [pool](const Expression *e) -> Expression * {
DCHECK_EQ(e->kind(), Expression::Kind::kLabelAttribute);
auto labelAttrExpr = static_cast<const LabelAttributeExpression *>(e);
auto leftName = labelAttrExpr->left()->name();
auto rightName = labelAttrExpr->right()->value().getStr();
Expand All @@ -130,7 +160,6 @@ Expression *ExpressionUtils::rewriteInnerVar(const Expression *expr, std::string
return e->kind() == Expression::Kind::kVarProperty;
};
auto rewriter = [pool, newVar](const Expression *e) -> Expression * {
DCHECK_EQ(e->kind(), Expression::Kind::kVarProperty);
auto varPropExpr = static_cast<const VariablePropertyExpression *>(e);
auto newProp = varPropExpr->prop();
return VariablePropertyExpression::make(pool, newVar, newProp);
Expand All @@ -146,7 +175,6 @@ Expression *ExpressionUtils::rewriteLabelAttr2TagProp(const Expression *expr) {
return e->kind() == Expression::Kind::kLabelAttribute;
};
auto rewriter = [pool](const Expression *e) -> Expression * {
DCHECK_EQ(e->kind(), Expression::Kind::kLabelAttribute);
auto labelAttrExpr = static_cast<const LabelAttributeExpression *>(e);
auto leftName = labelAttrExpr->left()->name();
auto rightName = labelAttrExpr->right()->value().getStr();
Expand Down
2 changes: 2 additions & 0 deletions src/graph/util/ExpressionUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ class ExpressionUtils {

static bool isEvaluableExpr(const Expression* expr);

static Expression* rewriteAttr2LabelTagProp(const Expression* expr);

static Expression* rewriteLabelAttr2TagProp(const Expression* expr);

static Expression* rewriteLabelAttr2EdgeProp(const Expression* expr);
Expand Down
35 changes: 17 additions & 18 deletions src/graph/validator/MatchValidator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,8 @@ Status MatchValidator::validateFilter(const Expression *filter,
WhereClauseContext &whereClauseCtx) const {
auto transformRes = ExpressionUtils::filterTransform(filter);
NG_RETURN_IF_ERROR(transformRes);
whereClauseCtx.filter = transformRes.value();
// rewrite Attribute to LabelTagProperty
whereClauseCtx.filter = ExpressionUtils::rewriteAttr2LabelTagProp(transformRes.value());

auto typeStatus = deduceExprType(whereClauseCtx.filter);
NG_RETURN_IF_ERROR(typeStatus);
Expand Down Expand Up @@ -396,6 +397,7 @@ Status MatchValidator::validateAliases(
const std::unordered_map<std::string, AliasType> *aliasesUsed) const {
static const std::unordered_set<Expression::Kind> kinds = {Expression::Kind::kLabel,
Expression::Kind::kLabelAttribute,
Expression::Kind::kLabelTagProperty,
// primitive props
Expression::Kind::kEdgeSrc,
Expression::Kind::kEdgeDst,
Expand Down Expand Up @@ -766,25 +768,28 @@ Status MatchValidator::checkAlias(
case Expression::Kind::kLabel: {
auto name = static_cast<const LabelExpression *>(refExpr)->name();
auto res = getAliasType(aliasesUsed, name);
if (!res.ok()) {
return res.status();
NG_RETURN_IF_ERROR(res);
return Status::OK();
}
case Expression::Kind::kLabelTagProperty: {
auto name = static_cast<const LabelTagPropertyExpression *>(refExpr)->label();
auto res = getAliasType(aliasesUsed, name);
NG_RETURN_IF_ERROR(res);
if (res.value() != AliasType::kNode) {
return Status::SemanticError("Alias: %s 's type must be vertex", name.c_str());
}
return Status::OK();
}
case Expression::Kind::kLabelAttribute: {
auto name = static_cast<const LabelAttributeExpression *>(refExpr)->left()->name();
auto res = getAliasType(aliasesUsed, name);
if (!res.ok()) {
return res.status();
}
NG_RETURN_IF_ERROR(res);
return Status::OK();
}
case Expression::Kind::kEdgeSrc: {
auto name = static_cast<const EdgeSrcIdExpression *>(refExpr)->sym();
auto res = getAliasType(aliasesUsed, name);
if (!res.ok()) {
return res.status();
}
NG_RETURN_IF_ERROR(res);
aliasType = res.value();
switch (aliasType) {
case AliasType::kNode:
Expand All @@ -802,9 +807,7 @@ Status MatchValidator::checkAlias(
case Expression::Kind::kEdgeDst: {
auto name = static_cast<const EdgeDstIdExpression *>(refExpr)->sym();
auto res = getAliasType(aliasesUsed, name);
if (!res.ok()) {
return res.status();
}
NG_RETURN_IF_ERROR(res);
aliasType = res.value();
switch (aliasType) {
case AliasType::kNode:
Expand All @@ -822,9 +825,7 @@ Status MatchValidator::checkAlias(
case Expression::Kind::kEdgeRank: {
auto name = static_cast<const EdgeRankExpression *>(refExpr)->sym();
auto res = getAliasType(aliasesUsed, name);
if (!res.ok()) {
return res.status();
}
NG_RETURN_IF_ERROR(res);
aliasType = res.value();
switch (aliasType) {
case AliasType::kNode:
Expand All @@ -844,9 +845,7 @@ Status MatchValidator::checkAlias(
case Expression::Kind::kEdgeType: {
auto name = static_cast<const EdgeTypeExpression *>(refExpr)->sym();
auto res = getAliasType(aliasesUsed, name);
if (!res.ok()) {
return res.status();
}
NG_RETURN_IF_ERROR(res);
aliasType = res.value();
switch (aliasType) {
case AliasType::kNode:
Expand Down
1 change: 1 addition & 0 deletions src/storage/ExprVisitorBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ void ExprVisitorBase::visit(SetExpression *expr) {
}
void ExprVisitorBase::visit(MapExpression *expr) { UNUSED(expr); }
// property Expression
void ExprVisitorBase::visit(LabelTagPropertyExpression *expr) { UNUSED(expr); }
void ExprVisitorBase::visit(TagPropertyExpression *expr) { UNUSED(expr); }
void ExprVisitorBase::visit(EdgePropertyExpression *expr) { UNUSED(expr); }
void ExprVisitorBase::visit(InputPropertyExpression *expr) { UNUSED(expr); }
Expand Down
1 change: 1 addition & 0 deletions src/storage/ExprVisitorBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class ExprVisitorBase : public ::nebula::ExprVisitor {
void visit(SetExpression *expr) override;
void visit(MapExpression *expr) override;
// property Expression
void visit(LabelTagPropertyExpression *expr) override;
void visit(TagPropertyExpression *expr) override;
void visit(EdgePropertyExpression *expr) override;
void visit(InputPropertyExpression *expr) override;
Expand Down
1 change: 1 addition & 0 deletions src/storage/exec/IndexSelectionNode.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ class SelectionExprVisitor : public ExprVisitorBase {
void visit(EdgeRankExpression *expr) override { requiredColumns_.insert(expr->prop()); }
void visit(EdgeDstIdExpression *expr) override { requiredColumns_.insert(expr->prop()); }
void visit(TagPropertyExpression *expr) override { requiredColumns_.insert(expr->prop()); }
void visit(LabelTagPropertyExpression *expr) override { requiredColumns_.insert(expr->prop()); }
void visit(EdgePropertyExpression *expr) override { requiredColumns_.insert(expr->prop()); }
const Set<std::string> &getRequiredColumns() { return requiredColumns_; }
::nebula::cpp2::ErrorCode getCode() { return code_; }
Expand Down

0 comments on commit 28e8099

Please sign in to comment.