Skip to content

Commit

Permalink
fix push down of rank(e)
Browse files Browse the repository at this point in the history
  • Loading branch information
jievince committed Dec 28, 2022
1 parent 1c6534f commit 75e272c
Show file tree
Hide file tree
Showing 6 changed files with 124 additions and 60 deletions.
41 changes: 26 additions & 15 deletions src/graph/optimizer/rule/PushFilterDownTraverseRule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ StatusOr<OptRule::TransformResult> PushFilterDownTraverseRule::transform(
auto* filterGroup = filterGroupNode->group();
auto* filter = static_cast<graph::Filter*>(filterGroupNode->node());
auto* condition = filter->condition();
LOG(ERROR) << "condition: " << condition->toString();

auto* avGroupNode = matched.dependencies[0].node;
auto* av = static_cast<graph::AppendVertices*>(avGroupNode->node());
Expand All @@ -67,26 +68,32 @@ StatusOr<OptRule::TransformResult> PushFilterDownTraverseRule::transform(
auto pool = qctx->objPool();

// Pick the expr looks like `$-.e[0].likeness
auto picker = [&edgeAlias](const Expression* e) -> bool {
// TODO(jie): Handle the strange exists expr. e.g. exists(e.likeness)
auto exprs = graph::ExpressionUtils::collectAll(e, {Expression::Kind::kPredicate});
for (auto* expr : exprs) {
if (static_cast<const PredicateExpression*>(expr)->name() == "exists") {
auto picker = [&edgeAlias](const Expression* expr) -> bool {
bool shouldNotPick = false;
auto finder = [&shouldNotPick, &edgeAlias](const Expression* e) -> bool {
if (e->kind() == Expression::Kind::kInputProperty ||
e->kind() == Expression::Kind::kVarProperty) {
shouldNotPick = true;
return false;
}

// TODO(jie): Handle the strange exists expr. e.g. exists(e.likeness)
if (e->kind() == Expression::Kind::kPredicate &&
static_cast<const PredicateExpression*>(e)->name() == "exists") {
shouldNotPick = true;
return false;
}
}

auto varProps = graph::ExpressionUtils::collectAll(
e, {Expression::Kind::kInputProperty, Expression::Kind::kVarProperty});
if (varProps.empty()) {
if (graph::ExpressionUtils::isOneStepEdgeProp(edgeAlias, e)) return true;
return false;
};
graph::FindVisitor visitor(finder, true, true);
const_cast<Expression*>(expr)->accept(&visitor);
if (shouldNotPick) return false;
if (!visitor.results().empty()) {
return true;
}
for (auto* expr : varProps) {
DCHECK(graph::ExpressionUtils::isPropertyExpr(expr));
auto& propName = static_cast<const PropertyExpression*>(expr)->prop();
if (propName != edgeAlias) return false;
}
return true;
return false;
};
Expression* filterPicked = nullptr;
Expression* filterUnpicked = nullptr;
Expand All @@ -97,10 +104,12 @@ StatusOr<OptRule::TransformResult> PushFilterDownTraverseRule::transform(
}
auto* newFilterPicked =
graph::ExpressionUtils::rewriteEdgePropertyFilter(pool, edgeAlias, filterPicked->clone());
LOG(ERROR) << "newFilterPicked: " << newFilterPicked->toString();

Filter* newFilter = nullptr;
OptGroupNode* newFilterGroupNode = nullptr;
if (filterUnpicked) {
LOG(ERROR) << "filterUnpicked: " << filterUnpicked->toString();
newFilter = Filter::make(qctx, nullptr, filterUnpicked);
newFilter->setOutputVar(filter->outputVar());
newFilter->setColNames(filter->colNames());
Expand All @@ -125,6 +134,8 @@ StatusOr<OptRule::TransformResult> PushFilterDownTraverseRule::transform(
? LogicalExpression::makeAnd(pool, newFilterPicked, eFilter->clone())
: newFilterPicked;

LOG(ERROR) << "newEFilter: " << newEFilter->toString();

auto* newTv = static_cast<graph::Traverse*>(tv->clone());
newAv->setInputVar(newTv->outputVar());
newTv->setEdgeFilter(newEFilter);
Expand Down
36 changes: 34 additions & 2 deletions src/graph/util/ExpressionUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,38 @@ Expression *ExpressionUtils::rewriteAttr2LabelTagProp(
return RewriteVisitor::transform(expr, std::move(matcher), std::move(rewriter));
}

// rewrite rank(e) to e._rank
Expression *ExpressionUtils::rewriteRankFunc2LabelAttribute(
const Expression *expr, const std::unordered_map<std::string, AliasType> &aliasTypeMap) {
ObjectPool *pool = expr->getObjPool();
auto matcher = [&aliasTypeMap](const Expression *e) -> bool {
if (e->kind() != Expression::Kind::kFunctionCall) return false;

auto *funcExpr = static_cast<const FunctionCallExpression *>(e);
auto funcName = funcExpr->name();
std::transform(funcName.begin(), funcName.end(), funcName.begin(), ::tolower);
if (funcName != "rank") return false;
auto args = funcExpr->args()->args();
if (args.size() != 1) return false;
if (args[0]->kind() != Expression::Kind::kLabel) return false;

auto &label = static_cast<const LabelExpression *>(args[0])->name();
auto iter = aliasTypeMap.find(label);
if (iter == aliasTypeMap.end() || iter->second != AliasType::kEdge) {
return false;
}
return true;
};
auto rewriter = [pool](const Expression *e) -> Expression * {
auto funcExpr = static_cast<const FunctionCallExpression *>(e);
auto args = funcExpr->args()->args();
return LabelAttributeExpression::make(
pool, static_cast<LabelExpression *>(args[0]), ConstantExpression::make(pool, "_rank"));
};

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

Expression *ExpressionUtils::rewriteLabelAttr2TagProp(const Expression *expr) {
ObjectPool *pool = expr->getObjPool();
auto matcher = [](const Expression *e) -> bool {
Expand Down Expand Up @@ -1518,7 +1550,7 @@ bool ExpressionUtils::checkExprDepth(const Expression *expr) {
}

/*static*/
bool ExpressionUtils::isSingleLenExpandExpr(const std::string &edgeAlias, const Expression *expr) {
bool ExpressionUtils::isOneStepEdgeProp(const std::string &edgeAlias, const Expression *expr) {
if (expr->kind() != Expression::Kind::kAttribute) {
return false;
}
Expand Down Expand Up @@ -1562,7 +1594,7 @@ bool ExpressionUtils::isSingleLenExpandExpr(const std::string &edgeAlias, const
const std::string &edgeAlias,
Expression *expr) {
graph::RewriteVisitor::Matcher matcher = [&edgeAlias](const Expression *e) -> bool {
return isSingleLenExpandExpr(edgeAlias, e);
return isOneStepEdgeProp(edgeAlias, e);
};
graph::RewriteVisitor::Rewriter rewriter = [pool](const Expression *e) -> Expression * {
DCHECK_EQ(e->kind(), Expression::Kind::kAttribute);
Expand Down
6 changes: 5 additions & 1 deletion src/graph/util/ExpressionUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ class ExpressionUtils {
static Expression* rewriteAttr2LabelTagProp(
const Expression* expr, const std::unordered_map<std::string, AliasType>& aliasTypeMap);

// rewrite rank(e) to e._rank
static Expression* rewriteRankFunc2LabelAttribute(
const Expression* expr, const std::unordered_map<std::string, AliasType>& aliasTypeMap);

// rewrite LabelAttr to tagProp
static Expression* rewriteLabelAttr2TagProp(const Expression* expr);

Expand Down Expand Up @@ -239,7 +243,7 @@ class ExpressionUtils {
static bool isVidPredication(const Expression* expr);

// Check if the expr looks like `$-.e[0].likeness`
static bool isSingleLenExpandExpr(const std::string& edgeAlias, const Expression* expr);
static bool isOneStepEdgeProp(const std::string& edgeAlias, const Expression* expr);

static Expression* rewriteEdgePropertyFilter(ObjectPool* pool,
const std::string& edgeAlias,
Expand Down
14 changes: 12 additions & 2 deletions src/graph/validator/MatchValidator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -333,13 +333,23 @@ Status MatchValidator::buildEdgeInfo(const MatchPath *path,
// Rewrite expression to fit semantic, check type and check used aliases.
Status MatchValidator::validateFilter(const Expression *filter,
WhereClauseContext &whereClauseCtx) {
LOG(ERROR) << "filter: " << filter->toString();
auto *newFilter = graph::ExpressionUtils::rewriteParameter(filter, qctx_);
LOG(ERROR) << "newFilter after rewriteParameter: " << newFilter->toString();
newFilter = graph::ExpressionUtils::rewriteInnerInExpr(filter);
LOG(ERROR) << "newFilter after rewriteInnerInExpr: " << newFilter->toString();
auto transformRes = ExpressionUtils::filterTransform(newFilter);
NG_RETURN_IF_ERROR(transformRes);
LOG(ERROR) << "transformRes after filterTransform: " << transformRes.value()->toString();
// rewrite Attribute to LabelTagProperty
whereClauseCtx.filter = ExpressionUtils::rewriteAttr2LabelTagProp(
transformRes.value(), whereClauseCtx.aliasesAvailable);
newFilter = ExpressionUtils::rewriteAttr2LabelTagProp(transformRes.value(),
whereClauseCtx.aliasesAvailable);
LOG(ERROR) << "newFilter after rewriteAttr2LabelTagProp: " << newFilter->toString();
newFilter =
ExpressionUtils::rewriteRankFunc2LabelAttribute(newFilter, whereClauseCtx.aliasesAvailable);
LOG(ERROR) << "newFilter after rewriteRankFunc2LabelAttribute: " << newFilter->toString();

whereClauseCtx.filter = newFilter;

auto typeStatus = deduceExprType(whereClauseCtx.filter);
NG_RETURN_IF_ERROR(typeStatus);
Expand Down
Loading

0 comments on commit 75e272c

Please sign in to comment.