Skip to content
Snippets Groups Projects
Unverified Commit c5270c6a authored by kyle.cao's avatar kyle.cao Committed by GitHub
Browse files

add combineFilter opt rule (#970)

parent 57eb81e9
No related branches found
No related tags found
No related merge requests found
......@@ -13,6 +13,7 @@ nebula_add_library(
OptContext.cpp
rule/PushFilterDownGetNbrsRule.cpp
rule/RemoveNoopProjectRule.cpp
rule/CombineFilterRule.cpp
rule/MergeGetVerticesAndDedupRule.cpp
rule/MergeGetVerticesAndProjectRule.cpp
rule/MergeGetNbrsAndDedupRule.cpp
......
/* Copyright (c) 2021 vesoft inc. All rights reserved.
*
* This source code is licensed under Apache 2.0 License,
* attached with Common Clause Condition 1.0, found in the LICENSES directory.
*/
#include "optimizer/rule/CombineFilterRule.h"
#include "optimizer/OptContext.h"
#include "optimizer/OptGroup.h"
#include "planner/PlanNode.h"
#include "planner/Query.h"
using nebula::graph::PlanNode;
using nebula::graph::QueryContext;
namespace nebula {
namespace opt {
std::unique_ptr<OptRule> CombineFilterRule::kInstance =
std::unique_ptr<CombineFilterRule>(new CombineFilterRule());
CombineFilterRule::CombineFilterRule() {
RuleSet::QueryRules().addRule(this);
}
const Pattern& CombineFilterRule::pattern() const {
static Pattern pattern = Pattern::create(graph::PlanNode::Kind::kFilter,
{Pattern::create(graph::PlanNode::Kind::kFilter)});
return pattern;
}
StatusOr<OptRule::TransformResult> CombineFilterRule::transform(
OptContext* octx,
const MatchedResult& matched) const {
const auto* filterGroupNode = matched.node;
const auto* filterAbove = filterGroupNode->node();
DCHECK_EQ(filterAbove->kind(), PlanNode::Kind::kFilter);
const auto* conditionAbove = static_cast<const graph::Filter*>(filterAbove)->condition();
const auto& deps = matched.dependencies;
const auto* filterGroup = filterGroupNode->group();
auto* qctx = octx->qctx();
TransformResult result;
result.eraseAll = true;
for (auto& dep : deps) {
const auto* groupNode = dep.node;
const auto* filterBelow = groupNode->node();
DCHECK_EQ(filterBelow->kind(), PlanNode::Kind::kFilter);
auto* newFilter = static_cast<graph::Filter*>(filterBelow->clone());
const auto* conditionBelow = newFilter->condition();
auto* conditionCombine =
qctx->objPool()->add(new LogicalExpression(Expression::Kind::kLogicalAnd,
conditionAbove->clone().release(),
conditionBelow->clone().release()));
newFilter->setCondition(conditionCombine);
newFilter->setOutputVar(filterAbove->outputVar());
auto* newGroupNode = OptGroupNode::create(octx, newFilter, filterGroup);
newGroupNode->setDeps(groupNode->dependencies());
result.newGroupNodes.emplace_back(newGroupNode);
}
return result;
}
bool CombineFilterRule::match(OptContext* octx, const MatchedResult& matched) const {
return OptRule::match(octx, matched);
}
std::string CombineFilterRule::toString() const {
return "CombineFilterRule";
}
} // namespace opt
} // namespace nebula
/* Copyright (c) 2021 vesoft inc. All rights reserved.
*
* This source code is licensed under Apache 2.0 License,
* attached with Common Clause Condition 1.0, found in the LICENSES directory.
*/
#ifndef OPTIMIZER_RULE_COMBINEFILTERRULE_H_
#define OPTIMIZER_RULE_COMBINEFILTERRULE_H_
#include <memory>
#include "optimizer/OptRule.h"
namespace nebula {
namespace opt {
class CombineFilterRule final : public OptRule {
public:
const Pattern &pattern() const override;
StatusOr<TransformResult> transform(OptContext *ctx,
const MatchedResult &matched) const override;
bool match(OptContext *ctx, const MatchedResult &matched) const override;
std::string toString() const override;
private:
CombineFilterRule();
static std::unique_ptr<OptRule> kInstance;
};
} // namespace opt
} // namespace nebula
#endif // OPTIMIZER_RULE_COMBINEFILTERRULE_H_
......@@ -97,12 +97,11 @@ Feature: UnaryExpression
| ("Shaquile O'Neal" :player{age: 47, name: "Shaquile O'Neal"}) |
And the execution plan should be:
| id | name | dependencies | operator info |
| 10 | Project | 9 | |
| 9 | Filter | 8 | |
| 8 | Filter | 7 | |
| 10 | Project | 12 | |
| 12 | Filter | 7 | |
| 7 | Project | 6 | |
| 6 | Project | 5 | |
| 5 | Filter | 13 | |
| 13 | GetVertices | 11 | |
| 5 | Filter | 14 | |
| 14 | GetVertices | 11 | |
| 11 | IndexScan | 0 | {"indexCtx": {"columnHints":{"scanType":"RANGE"}}} |
| 0 | Start | | |
# Copyright (c) 2021 vesoft inc. All rights reserved.
#
# This source code is licensed under Apache 2.0 License,
# attached with Common Clause Condition 1.0, found in the LICENSES directory.
Feature: combine filters
Background:
Given a graph with space named "nba"
Scenario: combine filters
When profiling query:
"""
MATCH (v:player)-[:like]->(n)
WHERE v.age>40 AND n.age>42
RETURN v, n
"""
Then the result should be, in any order:
| v | n |
| ("Steve Nash" :player{age: 45, name: "Steve Nash"}) | ("Jason Kidd" :player{age: 45, name: "Jason Kidd"}) |
| ("Vince Carter" :player{age: 42, name: "Vince Carter"}) | ("Jason Kidd" :player{age: 45, name: "Jason Kidd"}) |
| ("Jason Kidd" :player{age: 45, name: "Jason Kidd"}) | ("Steve Nash" :player{age: 45, name: "Steve Nash"}) |
And the execution plan should be:
| id | name | dependencies | operator info |
| 16 | Project | 18 | |
| 18 | Filter | 13 | {"condition" : "((($v.age>40) AND ($n.age>42)) AND !(hasSameEdgeInPath($-.__COL_0)))"} |
| 13 | Project | 12 | |
| 12 | InnerJoin | 11 | |
| 11 | Project | 20 | |
| 20 | GetVertices | 7 | |
| 7 | Filter | 6 | |
| 6 | Project | 5 | |
| 5 | Filter | 22 | |
| 22 | GetNeighbors | 17 | |
| 17 | IndexScan | 0 | |
| 0 | Start | | |
......@@ -19,11 +19,10 @@ Feature: merge get vertices, dedup and project rule
| "Tim Duncan" |
And the execution plan should be:
| id | name | dependencies | operator info |
| 0 | Project | 1 | |
| 1 | Filter | 2 | |
| 2 | Filter | 3 | |
| 3 | Project | 4 | |
| 4 | Project | 5 | |
| 5 | GetVertices | 6 | {"dedup": "true"} |
| 6 | PassThrough | 7 | |
| 7 | Start | | |
| 9 | Project | 10 | |
| 10 | Filter | 6 | |
| 6 | Project | 5 | |
| 5 | Project | 12 | |
| 12 | GetVertices | 1 | {"dedup": "true"} |
| 1 | PassThrough | 0 | |
| 0 | Start | | |
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment