Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
jievince committed Dec 6, 2022
1 parent 5cf71d6 commit 2f8ad9f
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 54 deletions.
54 changes: 34 additions & 20 deletions src/graph/optimizer/rule/OptimizeLeftJoinPredicateRule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ OptimizeLeftJoinPredicateRule::OptimizeLeftJoinPredicateRule() {

const Pattern& OptimizeLeftJoinPredicateRule::pattern() const {
static Pattern pattern = Pattern::create(
PlanNode::Kind::kBiLeftJoin,
PlanNode::Kind::kHashLeftJoin,
{Pattern::create(PlanNode::Kind::kUnknown),
Pattern::create(PlanNode::Kind::kProject,
{Pattern::create(PlanNode::Kind::kAppendVertices,
Expand All @@ -38,7 +38,7 @@ StatusOr<OptRule::TransformResult> OptimizeLeftJoinPredicateRule::transform(
OptContext* octx, const MatchedResult& matched) const {
auto* leftJoinGroupNode = matched.node;
auto* leftJoinGroup = leftJoinGroupNode->group();
auto* leftJoin = static_cast<graph::BiLeftJoin*>(leftJoinGroupNode->node());
auto* leftJoin = static_cast<graph::HashLeftJoin*>(leftJoinGroupNode->node());

auto* projectGroupNode = matched.dependencies[1].node;
auto* projectGroup = projectGroupNode->group();
Expand Down Expand Up @@ -68,14 +68,14 @@ StatusOr<OptRule::TransformResult> OptimizeLeftJoinPredicateRule::transform(
auto& probeKeys = leftJoin->probeKeys();

// Use visitor to collect all function `id` in the hashKeys

std::vector<size_t> hashKeyIdx;
bool found = false;
size_t hashKeyIdx;
for (size_t i = 0; i < hashKeys.size(); ++i) {
auto* key = hashKeys[i];
if (key->kind() != Expression::Kind::kFunctionCall) {
auto* hashKey = hashKeys[i];
if (hashKey->kind() != Expression::Kind::kFunctionCall) {
continue;
}
auto* func = static_cast<FunctionCallExpression*>(key);
auto* func = static_cast<FunctionCallExpression*>(hashKey);
if (func->name() != "id" || func->name() != "_joinkey") {
continue;
}
Expand All @@ -87,66 +87,80 @@ StatusOr<OptRule::TransformResult> OptimizeLeftJoinPredicateRule::transform(
}
auto& alias = static_cast<InputPropertyExpression*>(arg)->prop();
if (alias != avNodeAlias) continue;
// FIXME(jie): Must check if probe keys contain the same key
hashKeyIdx.emplace_back(i);
// Must check if probe keys contain the same key
if (probeKeys[i] != hashKey) {
return TransformResult::noTransform();
}
if (found) {
return TransformResult::noTransform();
}
hashKeyIdx = i;
found = true;
}
if (hashKeyIdx.size() != 1) {
if (!found) {
return TransformResult::noTransform();
}

std::vector<size_t> prjIdx;
found = false;
size_t prjIdx;
for (size_t i = 0; i < project->columns()->size(); ++i) {
const auto* col = project->columns()->columns()[i];
if (col->expr()->kind() != Expression::Kind::kInputProperty) {
continue;
}
auto* inputProp = static_cast<InputPropertyExpression*>(col->expr());
if (inputProp->prop() != avNodeAlias) continue;
prjIdx.push_back(i);
if (found) {
return TransformResult::noTransform();
}
prjIdx = i;
found = true;
}
if (prjIdx.size() != 1) {
if (!found) {
return TransformResult::noTransform();
}

auto* pool = octx->qctx()->objPool();
// Let the new project generate expr `none_direct_dst($-.tvEdgeAlias)`, and let the new left join
// use it as hash key
// Let the new project generate expr `none_direct_dst($-.tvEdgeAlias)`,
// and let the new left join use it as hash key
auto* args = ArgumentList::make(pool);
args->addArgument(InputPropertyExpression::make(pool, tvEdgeAlias));
auto* newPrjExpr = FunctionCallExpression::make(pool, "none_direct_dst", args);

auto* newYieldColumns = pool->makeAndAdd<YieldColumns>();
for (size_t i = 0; i < project->columns()->size(); ++i) {
if (i == prjIdx[0]) {
if (i == prjIdx) {
newYieldColumns->addColumn(pool->makeAndAdd<YieldColumn>(newPrjExpr, newPrjExpr->toString()));
} else {
newYieldColumns->addColumn(project->columns()->columns()[i]);
}
}
auto* newProject = graph::Project::make(octx->qctx(), nullptr, newYieldColumns);

// $-.`none_direct_dst(tvEdgeAlias)`
auto* newHashExpr = InputPropertyExpression::make(pool, newPrjExpr->toString());
std::vector<Expression*> newHashKeys;
for (size_t i = 0; i < hashKeys.size(); ++i) {
if (i == hashKeyIdx[0]) {
if (i == hashKeyIdx) {
newHashKeys.emplace_back(newHashExpr);
} else {
newHashKeys.emplace_back(hashKeys[i]);
}
}
auto* newLeftJoin =
graph::BiLeftJoin::make(octx->qctx(), nullptr, nullptr, newHashKeys, probeKeys);
graph::HashLeftJoin::make(octx->qctx(), nullptr, nullptr, newHashKeys, probeKeys);

TransformResult result;
result.eraseAll = true;

newProject->setInputVar(appendVertices->inputVar());
newProject->setOutputVar(project->outputVar());
auto newProjectGroup = OptGroup::create(octx);
auto* newProjectGroupNode = newProjectGroup->makeGroupNode(newProject);
newProjectGroupNode->setDeps(projectGroupNode->dependencies());

newLeftJoin->setDep(1, newProject);
newLeftJoin->setLeftVar(leftJoin->leftInputVar());
newLeftJoin->setRightVar(newProject->outputVar());
newLeftJoin->setOutputVar(leftJoin->outputVar());
auto* newLeftJoinGroupNode = OptGroupNode::create(octx, newLeftJoin, leftJoinGroup);
newLeftJoinGroupNode->dependsOn(leftJoinGroupNode->dependencies()[0]);
newLeftJoinGroupNode->dependsOn(newProjectGroup);
Expand Down
34 changes: 18 additions & 16 deletions src/graph/optimizer/rule/OptimizeLeftJoinPredicateRule.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,24 @@ namespace nebula {
namespace opt {

/*
Before:
BiLeftJoin({id(v)}, id(v))
/ \
... Project
\
AppendVertices(v)
\
Traverse(e)
After:
BiLeftJoin({id(v)}, none_direct_dst(e))
/ \
... Project
\
Traverse(e)
*/
* Before:
* HashLeftJoin({id(v)}, {id(v)})
* / \
* ... Project
* / \
* AppendVertices(v) AppendVertices(v)
* / \
* ... Traverse(e)
*
* After:
* HashLeftJoin({id(v)}, {$-.`none_direct_dst(e)`})
* / \
* ... Project(none_direct_dst(e))
* / \
* AppendVertices(v) Traverse(e)
* /
* ...
*/
class OptimizeLeftJoinPredicateRule final : public OptRule {
public:
const Pattern &pattern() const override;
Expand Down
37 changes: 19 additions & 18 deletions tests/tck/features/optimizer/OptimizeLeftJoinPredicateRule.feature
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Copyright (c) 2021 vesoft inc. All rights reserved.
#
# This source code is licensed under Apache 2.0 License.
@jie
Feature: Optimize left join predicate

Background:
Expand Down Expand Up @@ -44,21 +45,21 @@ Feature: Optimize left join predicate
| "Heat" | "Heat" | 0 |
| "Jazz" | "Jazz" | 0 |
And the execution plan should be:
| id | name | dependencies | profiling data | operator info |
| 21 | TopN | 18 | | |
| 18 | Project | 17 | | |
| 17 | Aggregate | 16 | | |
| 16 | BiLeftJoin | 10,15 | | |
| 10 | Dedup | 28 | | |
| 28 | Project | 22 | | |
| 22 | Filter | 26 | | |
| 26 | AppendVertices | 25 | | |
| 25 | Traverse | 24 | | |
| 24 | Traverse | 2 | | |
| 2 | Dedup | 1 | | |
| 1 | PassThrough | 3 | | |
| 3 | Start | | | |
| 15 | Project | 14 | | |
| 14 | Traverse | 12 | | |
| 12 | Traverse | 11 | | |
| 11 | Argument | | | |
| id | name | dependencies | operator info |
| 21 | TopN | 18 | |
| 18 | Project | 17 | |
| 17 | Aggregate | 16 | |
| 16 | HashLeftJoin | 10,15 | {"probeKeys": ["_joinkey($-.friendTeam)", "_joinkey($-.friendTeam)"], "hashKeys": ["$-.none_direct_dst(__VAR_3)", "_joinkey($-.friendTeam)"]} |
| 10 | Dedup | 28 | |
| 28 | Project | 22 | |
| 22 | Filter | 26 | |
| 26 | AppendVertices | 25 | |
| 25 | Traverse | 24 | |
| 24 | Traverse | 2 | |
| 2 | Dedup | 1 | |
| 1 | PassThrough | 3 | |
| 3 | Start | | |
| 15 | Project | 14 | {"columns": ["$-.friend AS friend, $-.friend2 AS friend2, none_direct_dst(__VAR_3) AS none_direct_dst(__VAR_3)"]} |
| 14 | Traverse | 12 | |
| 12 | Traverse | 11 | |
| 11 | Argument | | |

0 comments on commit 2f8ad9f

Please sign in to comment.