From 2f0de3b17fb24a45d684fd6cad47415f3361045b Mon Sep 17 00:00:00 2001 From: shylock <33566796+Shylock-Hg@users.noreply.github.com> Date: Fri, 28 Jan 2022 16:55:49 +0800 Subject: [PATCH] Feature/optimizer trait match (#3769) * Add trait for pattern match. * Implement match plan by trait and reduce some reduncant rules. * Remove unused header. * Fix warning. * Let optimize rule decide collection of matched nodes. Co-authored-by: kyle.cao Co-authored-by: Sophie <84560950+Sophie-Xie@users.noreply.github.com> --- src/graph/optimizer/CMakeLists.txt | 12 -- src/graph/optimizer/OptRule.cpp | 14 +-- src/graph/optimizer/OptRule.h | 26 +++- .../PushLimitDownEdgeIndexFullScanRule.cpp | 74 ------------ .../rule/PushLimitDownEdgeIndexFullScanRule.h | 29 ----- .../PushLimitDownEdgeIndexPrefixScanRule.cpp | 76 ------------ .../PushLimitDownEdgeIndexPrefixScanRule.h | 29 ----- .../PushLimitDownEdgeIndexRangeScanRule.cpp | 74 ------------ .../PushLimitDownEdgeIndexRangeScanRule.h | 29 ----- .../rule/PushLimitDownIndexScanRule.cpp | 17 ++- .../rule/PushLimitDownIndexScanRule.h | 4 + .../PushLimitDownTagIndexFullScanRule.cpp | 72 ----------- .../rule/PushLimitDownTagIndexFullScanRule.h | 29 ----- .../PushLimitDownTagIndexPrefixScanRule.cpp | 73 ------------ .../PushLimitDownTagIndexPrefixScanRule.h | 29 ----- .../PushLimitDownTagIndexRangeScanRule.cpp | 73 ------------ .../rule/PushLimitDownTagIndexRangeScanRule.h | 29 ----- .../PushTopNDownEdgeIndexFullScanRule.cpp | 110 ----------------- .../rule/PushTopNDownEdgeIndexFullScanRule.h | 29 ----- .../PushTopNDownEdgeIndexPrefixScanRule.cpp | 110 ----------------- .../PushTopNDownEdgeIndexPrefixScanRule.h | 29 ----- .../PushTopNDownEdgeIndexRangeScanRule.cpp | 110 ----------------- .../rule/PushTopNDownEdgeIndexRangeScanRule.h | 29 ----- .../rule/PushTopNDownIndexScanRule.cpp | 20 +++- .../rule/PushTopNDownIndexScanRule.h | 3 + .../rule/PushTopNDownTagIndexFullScanRule.cpp | 110 ----------------- .../rule/PushTopNDownTagIndexFullScanRule.h | 29 ----- .../PushTopNDownTagIndexPrefixScanRule.cpp | 110 ----------------- .../rule/PushTopNDownTagIndexPrefixScanRule.h | 29 ----- .../PushTopNDownTagIndexRangeScanRule.cpp | 112 ------------------ .../rule/PushTopNDownTagIndexRangeScanRule.h | 29 ----- src/graph/planner/plan/PlanNode.h | 7 ++ 32 files changed, 74 insertions(+), 1481 deletions(-) delete mode 100644 src/graph/optimizer/rule/PushLimitDownEdgeIndexFullScanRule.cpp delete mode 100644 src/graph/optimizer/rule/PushLimitDownEdgeIndexFullScanRule.h delete mode 100644 src/graph/optimizer/rule/PushLimitDownEdgeIndexPrefixScanRule.cpp delete mode 100644 src/graph/optimizer/rule/PushLimitDownEdgeIndexPrefixScanRule.h delete mode 100644 src/graph/optimizer/rule/PushLimitDownEdgeIndexRangeScanRule.cpp delete mode 100644 src/graph/optimizer/rule/PushLimitDownEdgeIndexRangeScanRule.h delete mode 100644 src/graph/optimizer/rule/PushLimitDownTagIndexFullScanRule.cpp delete mode 100644 src/graph/optimizer/rule/PushLimitDownTagIndexFullScanRule.h delete mode 100644 src/graph/optimizer/rule/PushLimitDownTagIndexPrefixScanRule.cpp delete mode 100644 src/graph/optimizer/rule/PushLimitDownTagIndexPrefixScanRule.h delete mode 100644 src/graph/optimizer/rule/PushLimitDownTagIndexRangeScanRule.cpp delete mode 100644 src/graph/optimizer/rule/PushLimitDownTagIndexRangeScanRule.h delete mode 100644 src/graph/optimizer/rule/PushTopNDownEdgeIndexFullScanRule.cpp delete mode 100644 src/graph/optimizer/rule/PushTopNDownEdgeIndexFullScanRule.h delete mode 100644 src/graph/optimizer/rule/PushTopNDownEdgeIndexPrefixScanRule.cpp delete mode 100644 src/graph/optimizer/rule/PushTopNDownEdgeIndexPrefixScanRule.h delete mode 100644 src/graph/optimizer/rule/PushTopNDownEdgeIndexRangeScanRule.cpp delete mode 100644 src/graph/optimizer/rule/PushTopNDownEdgeIndexRangeScanRule.h delete mode 100644 src/graph/optimizer/rule/PushTopNDownTagIndexFullScanRule.cpp delete mode 100644 src/graph/optimizer/rule/PushTopNDownTagIndexFullScanRule.h delete mode 100644 src/graph/optimizer/rule/PushTopNDownTagIndexPrefixScanRule.cpp delete mode 100644 src/graph/optimizer/rule/PushTopNDownTagIndexPrefixScanRule.h delete mode 100644 src/graph/optimizer/rule/PushTopNDownTagIndexRangeScanRule.cpp delete mode 100644 src/graph/optimizer/rule/PushTopNDownTagIndexRangeScanRule.h diff --git a/src/graph/optimizer/CMakeLists.txt b/src/graph/optimizer/CMakeLists.txt index 6b7d61af23b..c6a6bc992bb 100644 --- a/src/graph/optimizer/CMakeLists.txt +++ b/src/graph/optimizer/CMakeLists.txt @@ -40,24 +40,12 @@ nebula_add_library( rule/TagIndexFullScanRule.cpp rule/EdgeIndexFullScanRule.cpp rule/PushLimitDownIndexScanRule.cpp - rule/PushLimitDownTagIndexFullScanRule.cpp - rule/PushLimitDownTagIndexPrefixScanRule.cpp - rule/PushLimitDownTagIndexRangeScanRule.cpp - rule/PushLimitDownEdgeIndexFullScanRule.cpp - rule/PushLimitDownEdgeIndexPrefixScanRule.cpp - rule/PushLimitDownEdgeIndexRangeScanRule.cpp rule/PushLimitDownProjectRule.cpp rule/EliminateRowCollectRule.cpp rule/PushLimitDownScanAppendVerticesRule.cpp rule/GetEdgesTransformRule.cpp rule/PushLimitDownScanEdgesAppendVerticesRule.cpp rule/PushTopNDownIndexScanRule.cpp - rule/PushTopNDownTagIndexFullScanRule.cpp - rule/PushTopNDownTagIndexPrefixScanRule.cpp - rule/PushTopNDownTagIndexRangeScanRule.cpp - rule/PushTopNDownEdgeIndexFullScanRule.cpp - rule/PushTopNDownEdgeIndexPrefixScanRule.cpp - rule/PushTopNDownEdgeIndexRangeScanRule.cpp ) nebula_add_subdirectory(test) diff --git a/src/graph/optimizer/OptRule.cpp b/src/graph/optimizer/OptRule.cpp index 908c7ebc14a..24de9a9715e 100644 --- a/src/graph/optimizer/OptRule.cpp +++ b/src/graph/optimizer/OptRule.cpp @@ -32,16 +32,16 @@ const PlanNode *MatchedResult::planNode(const std::vector &pos) const { } Pattern Pattern::create(graph::PlanNode::Kind kind, std::initializer_list patterns) { - Pattern pattern; - pattern.kind_ = kind; - for (auto &p : patterns) { - pattern.dependencies_.emplace_back(p); - } - return pattern; + return Pattern(kind, std::move(patterns)); +} + +/*static*/ Pattern Pattern::create(std::initializer_list kinds, + std::initializer_list patterns) { + return Pattern(std::move(kinds), std::move(patterns)); } StatusOr Pattern::match(const OptGroupNode *groupNode) const { - if (groupNode->node()->kind() != kind_) { + if (!node_.match(groupNode->node())) { return Status::Error(); } diff --git a/src/graph/optimizer/OptRule.h b/src/graph/optimizer/OptRule.h index 041c9419551..f7a429d798b 100644 --- a/src/graph/optimizer/OptRule.h +++ b/src/graph/optimizer/OptRule.h @@ -42,17 +42,39 @@ struct MatchedResult { const graph::PlanNode *planNode(const std::vector &pos = {}) const; }; +// Match plan node by trait or kind of plan node. +class MatchNode { + public: + explicit MatchNode(graph::PlanNode::Kind kind) : node_({kind}) {} + explicit MatchNode(std::initializer_list kinds) + : node_(std::move(kinds)) {} + + bool match(const graph::PlanNode *node) const { + auto find = node_.find(node->kind()); + return find != node_.end(); + } + + private: + std::unordered_set node_; +}; + class Pattern final { public: static Pattern create(graph::PlanNode::Kind kind, std::initializer_list patterns = {}); + static Pattern create(std::initializer_list kinds, + std::initializer_list patterns = {}); StatusOr match(const OptGroupNode *groupNode) const; private: - Pattern() = default; + explicit Pattern(graph::PlanNode::Kind kind, std::initializer_list patterns = {}) + : node_(kind), dependencies_(patterns) {} + explicit Pattern(std::initializer_list kinds, + std::initializer_list patterns = {}) + : node_(std::move(kinds)), dependencies_(patterns) {} StatusOr match(const OptGroup *group) const; - graph::PlanNode::Kind kind_; + MatchNode node_; std::vector dependencies_; }; diff --git a/src/graph/optimizer/rule/PushLimitDownEdgeIndexFullScanRule.cpp b/src/graph/optimizer/rule/PushLimitDownEdgeIndexFullScanRule.cpp deleted file mode 100644 index c6d488da165..00000000000 --- a/src/graph/optimizer/rule/PushLimitDownEdgeIndexFullScanRule.cpp +++ /dev/null @@ -1,74 +0,0 @@ -/* Copyright (c) 2021 vesoft inc. All rights reserved. - * - * This source code is licensed under Apache 2.0 License. - */ - -#include "graph/optimizer/rule/PushLimitDownEdgeIndexFullScanRule.h" - -#include "graph/optimizer/OptContext.h" -#include "graph/optimizer/OptGroup.h" -#include "graph/planner/plan/PlanNode.h" -#include "graph/planner/plan/Scan.h" -#include "graph/visitor/ExtractFilterExprVisitor.h" - -using nebula::graph::EdgeIndexFullScan; -using nebula::graph::Limit; -using nebula::graph::PlanNode; -using nebula::graph::QueryContext; - -namespace nebula { -namespace opt { - -std::unique_ptr PushLimitDownEdgeIndexFullScanRule::kInstance = - std::unique_ptr(new PushLimitDownEdgeIndexFullScanRule()); - -PushLimitDownEdgeIndexFullScanRule::PushLimitDownEdgeIndexFullScanRule() { - RuleSet::QueryRules().addRule(this); -} - -const Pattern &PushLimitDownEdgeIndexFullScanRule::pattern() const { - static Pattern pattern = Pattern::create( - graph::PlanNode::Kind::kLimit, {Pattern::create(graph::PlanNode::Kind::kEdgeIndexFullScan)}); - return pattern; -} - -StatusOr PushLimitDownEdgeIndexFullScanRule::transform( - OptContext *octx, const MatchedResult &matched) const { - auto *qctx = octx->qctx(); - auto limitGroupNode = matched.node; - auto indexScanGroupNode = matched.dependencies.front().node; - - const auto limit = static_cast(limitGroupNode->node()); - const auto indexScan = static_cast(indexScanGroupNode->node()); - - int64_t limitRows = limit->offset() + limit->count(qctx); - if (indexScan->limit(qctx) >= 0 && limitRows >= indexScan->limit(qctx)) { - return TransformResult::noTransform(); - } - - auto newLimit = static_cast(limit->clone()); - auto newLimitGroupNode = OptGroupNode::create(octx, newLimit, limitGroupNode->group()); - - auto newEdgeIndexFullScan = static_cast(indexScan->clone()); - newEdgeIndexFullScan->setLimit(limitRows); - auto newEdgeIndexFullScanGroup = OptGroup::create(octx); - auto newEdgeIndexFullScanGroupNode = - newEdgeIndexFullScanGroup->makeGroupNode(newEdgeIndexFullScan); - - newLimitGroupNode->dependsOn(newEdgeIndexFullScanGroup); - for (auto dep : indexScanGroupNode->dependencies()) { - newEdgeIndexFullScanGroupNode->dependsOn(dep); - } - - TransformResult result; - result.eraseAll = true; - result.newGroupNodes.emplace_back(newLimitGroupNode); - return result; -} - -std::string PushLimitDownEdgeIndexFullScanRule::toString() const { - return "PushLimitDownEdgeIndexFullScanRule"; -} - -} // namespace opt -} // namespace nebula diff --git a/src/graph/optimizer/rule/PushLimitDownEdgeIndexFullScanRule.h b/src/graph/optimizer/rule/PushLimitDownEdgeIndexFullScanRule.h deleted file mode 100644 index 4e55ff6eb8a..00000000000 --- a/src/graph/optimizer/rule/PushLimitDownEdgeIndexFullScanRule.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright (c) 2021 vesoft inc. All rights reserved. - * - * This source code is licensed under Apache 2.0 License. - */ - -#pragma once - -#include "graph/optimizer/OptRule.h" - -namespace nebula { -namespace opt { - -class PushLimitDownEdgeIndexFullScanRule final : public OptRule { - public: - const Pattern &pattern() const override; - - StatusOr transform(OptContext *ctx, - const MatchedResult &matched) const override; - - std::string toString() const override; - - private: - PushLimitDownEdgeIndexFullScanRule(); - - static std::unique_ptr kInstance; -}; - -} // namespace opt -} // namespace nebula diff --git a/src/graph/optimizer/rule/PushLimitDownEdgeIndexPrefixScanRule.cpp b/src/graph/optimizer/rule/PushLimitDownEdgeIndexPrefixScanRule.cpp deleted file mode 100644 index f34980bc979..00000000000 --- a/src/graph/optimizer/rule/PushLimitDownEdgeIndexPrefixScanRule.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/* Copyright (c) 2021 vesoft inc. All rights reserved. - * - * This source code is licensed under Apache 2.0 License. - */ - -#include "graph/optimizer/rule/PushLimitDownEdgeIndexPrefixScanRule.h" - -#include "graph/optimizer/OptContext.h" -#include "graph/optimizer/OptGroup.h" -#include "graph/planner/plan/PlanNode.h" -#include "graph/planner/plan/Scan.h" -#include "graph/visitor/ExtractFilterExprVisitor.h" - -using nebula::graph::EdgeIndexPrefixScan; -using nebula::graph::Limit; -using nebula::graph::PlanNode; -using nebula::graph::QueryContext; - -namespace nebula { -namespace opt { - -std::unique_ptr PushLimitDownEdgeIndexPrefixScanRule::kInstance = - std::unique_ptr( - new PushLimitDownEdgeIndexPrefixScanRule()); - -PushLimitDownEdgeIndexPrefixScanRule::PushLimitDownEdgeIndexPrefixScanRule() { - RuleSet::QueryRules().addRule(this); -} - -const Pattern &PushLimitDownEdgeIndexPrefixScanRule::pattern() const { - static Pattern pattern = - Pattern::create(graph::PlanNode::Kind::kLimit, - {Pattern::create(graph::PlanNode::Kind::kEdgeIndexPrefixScan)}); - return pattern; -} - -StatusOr PushLimitDownEdgeIndexPrefixScanRule::transform( - OptContext *octx, const MatchedResult &matched) const { - auto *qctx = octx->qctx(); - auto limitGroupNode = matched.node; - auto indexScanGroupNode = matched.dependencies.front().node; - - const auto limit = static_cast(limitGroupNode->node()); - const auto indexScan = static_cast(indexScanGroupNode->node()); - - int64_t limitRows = limit->offset() + limit->count(qctx); - if (indexScan->limit(qctx) >= 0 && limitRows >= indexScan->limit(qctx)) { - return TransformResult::noTransform(); - } - - auto newLimit = static_cast(limit->clone()); - auto newLimitGroupNode = OptGroupNode::create(octx, newLimit, limitGroupNode->group()); - - auto newEdgeIndexPrefixScan = static_cast(indexScan->clone()); - newEdgeIndexPrefixScan->setLimit(limitRows); - auto newEdgeIndexPrefixScanGroup = OptGroup::create(octx); - auto newEdgeIndexPrefixScanGroupNode = - newEdgeIndexPrefixScanGroup->makeGroupNode(newEdgeIndexPrefixScan); - - newLimitGroupNode->dependsOn(newEdgeIndexPrefixScanGroup); - for (auto dep : indexScanGroupNode->dependencies()) { - newEdgeIndexPrefixScanGroupNode->dependsOn(dep); - } - - TransformResult result; - result.eraseAll = true; - result.newGroupNodes.emplace_back(newLimitGroupNode); - return result; -} - -std::string PushLimitDownEdgeIndexPrefixScanRule::toString() const { - return "PushLimitDownEdgeIndexPrefixScanRule"; -} - -} // namespace opt -} // namespace nebula diff --git a/src/graph/optimizer/rule/PushLimitDownEdgeIndexPrefixScanRule.h b/src/graph/optimizer/rule/PushLimitDownEdgeIndexPrefixScanRule.h deleted file mode 100644 index 648a80288bb..00000000000 --- a/src/graph/optimizer/rule/PushLimitDownEdgeIndexPrefixScanRule.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright (c) 2021 vesoft inc. All rights reserved. - * - * This source code is licensed under Apache 2.0 License. - */ - -#pragma once - -#include "graph/optimizer/OptRule.h" - -namespace nebula { -namespace opt { - -class PushLimitDownEdgeIndexPrefixScanRule final : public OptRule { - public: - const Pattern &pattern() const override; - - StatusOr transform(OptContext *ctx, - const MatchedResult &matched) const override; - - std::string toString() const override; - - private: - PushLimitDownEdgeIndexPrefixScanRule(); - - static std::unique_ptr kInstance; -}; - -} // namespace opt -} // namespace nebula diff --git a/src/graph/optimizer/rule/PushLimitDownEdgeIndexRangeScanRule.cpp b/src/graph/optimizer/rule/PushLimitDownEdgeIndexRangeScanRule.cpp deleted file mode 100644 index 8dd8dc3f2ab..00000000000 --- a/src/graph/optimizer/rule/PushLimitDownEdgeIndexRangeScanRule.cpp +++ /dev/null @@ -1,74 +0,0 @@ -/* Copyright (c) 2021 vesoft inc. All rights reserved. - * - * This source code is licensed under Apache 2.0 License. - */ - -#include "graph/optimizer/rule/PushLimitDownEdgeIndexRangeScanRule.h" - -#include "graph/optimizer/OptContext.h" -#include "graph/optimizer/OptGroup.h" -#include "graph/planner/plan/PlanNode.h" -#include "graph/planner/plan/Scan.h" -#include "graph/visitor/ExtractFilterExprVisitor.h" - -using nebula::graph::EdgeIndexRangeScan; -using nebula::graph::Limit; -using nebula::graph::PlanNode; -using nebula::graph::QueryContext; - -namespace nebula { -namespace opt { - -std::unique_ptr PushLimitDownEdgeIndexRangeScanRule::kInstance = - std::unique_ptr(new PushLimitDownEdgeIndexRangeScanRule()); - -PushLimitDownEdgeIndexRangeScanRule::PushLimitDownEdgeIndexRangeScanRule() { - RuleSet::QueryRules().addRule(this); -} - -const Pattern &PushLimitDownEdgeIndexRangeScanRule::pattern() const { - static Pattern pattern = Pattern::create( - graph::PlanNode::Kind::kLimit, {Pattern::create(graph::PlanNode::Kind::kEdgeIndexRangeScan)}); - return pattern; -} - -StatusOr PushLimitDownEdgeIndexRangeScanRule::transform( - OptContext *octx, const MatchedResult &matched) const { - auto *qctx = octx->qctx(); - auto limitGroupNode = matched.node; - auto indexScanGroupNode = matched.dependencies.front().node; - - const auto limit = static_cast(limitGroupNode->node()); - const auto indexScan = static_cast(indexScanGroupNode->node()); - - int64_t limitRows = limit->offset() + limit->count(qctx); - if (indexScan->limit(qctx) >= 0 && limitRows >= indexScan->limit(qctx)) { - return TransformResult::noTransform(); - } - - auto newLimit = static_cast(limit->clone()); - auto newLimitGroupNode = OptGroupNode::create(octx, newLimit, limitGroupNode->group()); - - auto newEdgeIndexRangeScan = static_cast(indexScan->clone()); - newEdgeIndexRangeScan->setLimit(limitRows); - auto newEdgeIndexRangeScanGroup = OptGroup::create(octx); - auto newEdgeIndexRangeScanGroupNode = - newEdgeIndexRangeScanGroup->makeGroupNode(newEdgeIndexRangeScan); - - newLimitGroupNode->dependsOn(newEdgeIndexRangeScanGroup); - for (auto dep : indexScanGroupNode->dependencies()) { - newEdgeIndexRangeScanGroupNode->dependsOn(dep); - } - - TransformResult result; - result.eraseAll = true; - result.newGroupNodes.emplace_back(newLimitGroupNode); - return result; -} - -std::string PushLimitDownEdgeIndexRangeScanRule::toString() const { - return "PushLimitDownEdgeIndexRangeScanRule"; -} - -} // namespace opt -} // namespace nebula diff --git a/src/graph/optimizer/rule/PushLimitDownEdgeIndexRangeScanRule.h b/src/graph/optimizer/rule/PushLimitDownEdgeIndexRangeScanRule.h deleted file mode 100644 index c7678790474..00000000000 --- a/src/graph/optimizer/rule/PushLimitDownEdgeIndexRangeScanRule.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright (c) 2021 vesoft inc. All rights reserved. - * - * This source code is licensed under Apache 2.0 License. - */ - -#pragma once - -#include "graph/optimizer/OptRule.h" - -namespace nebula { -namespace opt { - -class PushLimitDownEdgeIndexRangeScanRule final : public OptRule { - public: - const Pattern &pattern() const override; - - StatusOr transform(OptContext *ctx, - const MatchedResult &matched) const override; - - std::string toString() const override; - - private: - PushLimitDownEdgeIndexRangeScanRule(); - - static std::unique_ptr kInstance; -}; - -} // namespace opt -} // namespace nebula diff --git a/src/graph/optimizer/rule/PushLimitDownIndexScanRule.cpp b/src/graph/optimizer/rule/PushLimitDownIndexScanRule.cpp index f434c35d32d..dda53f79835 100644 --- a/src/graph/optimizer/rule/PushLimitDownIndexScanRule.cpp +++ b/src/graph/optimizer/rule/PushLimitDownIndexScanRule.cpp @@ -19,6 +19,17 @@ using nebula::graph::QueryContext; namespace nebula { namespace opt { +/*static*/ const std::initializer_list + PushLimitDownIndexScanRule::kIndexScanKinds{ + graph::PlanNode::Kind::kIndexScan, + graph::PlanNode::Kind::kTagIndexFullScan, + graph::PlanNode::Kind::kTagIndexRangeScan, + graph::PlanNode::Kind::kTagIndexPrefixScan, + graph::PlanNode::Kind::kEdgeIndexFullScan, + graph::PlanNode::Kind::kEdgeIndexRangeScan, + graph::PlanNode::Kind::kEdgeIndexPrefixScan, + }; + std::unique_ptr PushLimitDownIndexScanRule::kInstance = std::unique_ptr(new PushLimitDownIndexScanRule()); @@ -27,8 +38,8 @@ PushLimitDownIndexScanRule::PushLimitDownIndexScanRule() { } const Pattern &PushLimitDownIndexScanRule::pattern() const { - static Pattern pattern = Pattern::create(graph::PlanNode::Kind::kLimit, - {Pattern::create(graph::PlanNode::Kind::kIndexScan)}); + static Pattern pattern = + Pattern::create(graph::PlanNode::Kind::kLimit, {Pattern::create(kIndexScanKinds)}); return pattern; } @@ -39,7 +50,7 @@ StatusOr PushLimitDownIndexScanRule::transform( auto indexScanGroupNode = matched.dependencies.front().node; const auto limit = static_cast(limitGroupNode->node()); - const auto indexScan = static_cast(indexScanGroupNode->node()); + const auto indexScan = indexScanGroupNode->node()->asNode(); int64_t limitRows = limit->offset() + limit->count(qctx); if (indexScan->limit(qctx) >= 0 && limitRows >= indexScan->limit(qctx)) { diff --git a/src/graph/optimizer/rule/PushLimitDownIndexScanRule.h b/src/graph/optimizer/rule/PushLimitDownIndexScanRule.h index 56bda90c366..5daa5b906e2 100644 --- a/src/graph/optimizer/rule/PushLimitDownIndexScanRule.h +++ b/src/graph/optimizer/rule/PushLimitDownIndexScanRule.h @@ -5,6 +5,8 @@ #pragma once +#include + #include "graph/optimizer/OptRule.h" namespace nebula { @@ -23,6 +25,8 @@ class PushLimitDownIndexScanRule final : public OptRule { PushLimitDownIndexScanRule(); static std::unique_ptr kInstance; + + static const std::initializer_list kIndexScanKinds; }; } // namespace opt diff --git a/src/graph/optimizer/rule/PushLimitDownTagIndexFullScanRule.cpp b/src/graph/optimizer/rule/PushLimitDownTagIndexFullScanRule.cpp deleted file mode 100644 index c48defaaede..00000000000 --- a/src/graph/optimizer/rule/PushLimitDownTagIndexFullScanRule.cpp +++ /dev/null @@ -1,72 +0,0 @@ -/* Copyright (c) 2021 vesoft inc. All rights reserved. - * - * This source code is licensed under Apache 2.0 License. - */ - -#include "graph/optimizer/rule/PushLimitDownTagIndexFullScanRule.h" - -#include "graph/optimizer/OptContext.h" -#include "graph/optimizer/OptGroup.h" -#include "graph/planner/plan/PlanNode.h" -#include "graph/planner/plan/Scan.h" - -using nebula::graph::Limit; -using nebula::graph::PlanNode; -using nebula::graph::QueryContext; -using nebula::graph::TagIndexFullScan; - -namespace nebula { -namespace opt { - -std::unique_ptr PushLimitDownTagIndexFullScanRule::kInstance = - std::unique_ptr(new PushLimitDownTagIndexFullScanRule()); - -PushLimitDownTagIndexFullScanRule::PushLimitDownTagIndexFullScanRule() { - RuleSet::QueryRules().addRule(this); -} - -const Pattern &PushLimitDownTagIndexFullScanRule::pattern() const { - static Pattern pattern = Pattern::create( - graph::PlanNode::Kind::kLimit, {Pattern::create(graph::PlanNode::Kind::kTagIndexFullScan)}); - return pattern; -} - -StatusOr PushLimitDownTagIndexFullScanRule::transform( - OptContext *octx, const MatchedResult &matched) const { - auto *qctx = octx->qctx(); - auto limitGroupNode = matched.node; - auto indexScanGroupNode = matched.dependencies.front().node; - - const auto limit = static_cast(limitGroupNode->node()); - const auto indexScan = static_cast(indexScanGroupNode->node()); - - int64_t limitRows = limit->offset() + limit->count(qctx); - if (indexScan->limit(qctx) >= 0 && limitRows >= indexScan->limit(qctx)) { - return TransformResult::noTransform(); - } - - auto newLimit = static_cast(limit->clone()); - auto newLimitGroupNode = OptGroupNode::create(octx, newLimit, limitGroupNode->group()); - - auto newTagIndexFullScan = static_cast(indexScan->clone()); - newTagIndexFullScan->setLimit(limitRows); - auto newTagIndexFullScanGroup = OptGroup::create(octx); - auto newTagIndexFullScanGroupNode = newTagIndexFullScanGroup->makeGroupNode(newTagIndexFullScan); - - newLimitGroupNode->dependsOn(newTagIndexFullScanGroup); - for (auto dep : indexScanGroupNode->dependencies()) { - newTagIndexFullScanGroupNode->dependsOn(dep); - } - - TransformResult result; - result.eraseAll = true; - result.newGroupNodes.emplace_back(newLimitGroupNode); - return result; -} - -std::string PushLimitDownTagIndexFullScanRule::toString() const { - return "PushLimitDownTagIndexFullScanRule"; -} - -} // namespace opt -} // namespace nebula diff --git a/src/graph/optimizer/rule/PushLimitDownTagIndexFullScanRule.h b/src/graph/optimizer/rule/PushLimitDownTagIndexFullScanRule.h deleted file mode 100644 index b3c5297d1c7..00000000000 --- a/src/graph/optimizer/rule/PushLimitDownTagIndexFullScanRule.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright (c) 2021 vesoft inc. All rights reserved. - * - * This source code is licensed under Apache 2.0 License. - */ - -#pragma once - -#include "graph/optimizer/OptRule.h" - -namespace nebula { -namespace opt { - -class PushLimitDownTagIndexFullScanRule final : public OptRule { - public: - const Pattern &pattern() const override; - - StatusOr transform(OptContext *ctx, - const MatchedResult &matched) const override; - - std::string toString() const override; - - private: - PushLimitDownTagIndexFullScanRule(); - - static std::unique_ptr kInstance; -}; - -} // namespace opt -} // namespace nebula diff --git a/src/graph/optimizer/rule/PushLimitDownTagIndexPrefixScanRule.cpp b/src/graph/optimizer/rule/PushLimitDownTagIndexPrefixScanRule.cpp deleted file mode 100644 index 905492d3632..00000000000 --- a/src/graph/optimizer/rule/PushLimitDownTagIndexPrefixScanRule.cpp +++ /dev/null @@ -1,73 +0,0 @@ -/* Copyright (c) 2021 vesoft inc. All rights reserved. - * - * This source code is licensed under Apache 2.0 License. - */ - -#include "graph/optimizer/rule/PushLimitDownTagIndexPrefixScanRule.h" - -#include "graph/optimizer/OptContext.h" -#include "graph/optimizer/OptGroup.h" -#include "graph/planner/plan/PlanNode.h" -#include "graph/planner/plan/Scan.h" - -using nebula::graph::Limit; -using nebula::graph::PlanNode; -using nebula::graph::QueryContext; -using nebula::graph::TagIndexPrefixScan; - -namespace nebula { -namespace opt { - -std::unique_ptr PushLimitDownTagIndexPrefixScanRule::kInstance = - std::unique_ptr(new PushLimitDownTagIndexPrefixScanRule()); - -PushLimitDownTagIndexPrefixScanRule::PushLimitDownTagIndexPrefixScanRule() { - RuleSet::QueryRules().addRule(this); -} - -const Pattern &PushLimitDownTagIndexPrefixScanRule::pattern() const { - static Pattern pattern = Pattern::create( - graph::PlanNode::Kind::kLimit, {Pattern::create(graph::PlanNode::Kind::kTagIndexPrefixScan)}); - return pattern; -} - -StatusOr PushLimitDownTagIndexPrefixScanRule::transform( - OptContext *octx, const MatchedResult &matched) const { - auto *qctx = octx->qctx(); - auto limitGroupNode = matched.node; - auto indexScanGroupNode = matched.dependencies.front().node; - - const auto limit = static_cast(limitGroupNode->node()); - const auto indexScan = static_cast(indexScanGroupNode->node()); - - int64_t limitRows = limit->offset() + limit->count(qctx); - if (indexScan->limit(qctx) >= 0 && limitRows >= indexScan->limit(qctx)) { - return TransformResult::noTransform(); - } - - auto newLimit = static_cast(limit->clone()); - auto newLimitGroupNode = OptGroupNode::create(octx, newLimit, limitGroupNode->group()); - - auto newTagIndexPrefixScan = static_cast(indexScan->clone()); - newTagIndexPrefixScan->setLimit(limitRows); - auto newTagIndexPrefixScanGroup = OptGroup::create(octx); - auto newTagIndexPrefixScanGroupNode = - newTagIndexPrefixScanGroup->makeGroupNode(newTagIndexPrefixScan); - - newLimitGroupNode->dependsOn(newTagIndexPrefixScanGroup); - for (auto dep : indexScanGroupNode->dependencies()) { - newTagIndexPrefixScanGroupNode->dependsOn(dep); - } - - TransformResult result; - result.eraseAll = true; - result.newGroupNodes.emplace_back(newLimitGroupNode); - return result; -} - -std::string PushLimitDownTagIndexPrefixScanRule::toString() const { - return "PushLimitDownTagIndexPrefixScanRule"; -} - -} // namespace opt -} // namespace nebula diff --git a/src/graph/optimizer/rule/PushLimitDownTagIndexPrefixScanRule.h b/src/graph/optimizer/rule/PushLimitDownTagIndexPrefixScanRule.h deleted file mode 100644 index 1c5064e2243..00000000000 --- a/src/graph/optimizer/rule/PushLimitDownTagIndexPrefixScanRule.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright (c) 2021 vesoft inc. All rights reserved. - * - * This source code is licensed under Apache 2.0 License. - */ - -#pragma once - -#include "graph/optimizer/OptRule.h" - -namespace nebula { -namespace opt { - -class PushLimitDownTagIndexPrefixScanRule final : public OptRule { - public: - const Pattern &pattern() const override; - - StatusOr transform(OptContext *ctx, - const MatchedResult &matched) const override; - - std::string toString() const override; - - private: - PushLimitDownTagIndexPrefixScanRule(); - - static std::unique_ptr kInstance; -}; - -} // namespace opt -} // namespace nebula diff --git a/src/graph/optimizer/rule/PushLimitDownTagIndexRangeScanRule.cpp b/src/graph/optimizer/rule/PushLimitDownTagIndexRangeScanRule.cpp deleted file mode 100644 index 7642108f715..00000000000 --- a/src/graph/optimizer/rule/PushLimitDownTagIndexRangeScanRule.cpp +++ /dev/null @@ -1,73 +0,0 @@ -/* Copyright (c) 2021 vesoft inc. All rights reserved. - * - * This source code is licensed under Apache 2.0 License. - */ - -#include "graph/optimizer/rule/PushLimitDownTagIndexRangeScanRule.h" - -#include "graph/optimizer/OptContext.h" -#include "graph/optimizer/OptGroup.h" -#include "graph/planner/plan/PlanNode.h" -#include "graph/planner/plan/Scan.h" - -using nebula::graph::Limit; -using nebula::graph::PlanNode; -using nebula::graph::QueryContext; -using nebula::graph::TagIndexRangeScan; - -namespace nebula { -namespace opt { - -std::unique_ptr PushLimitDownTagIndexRangeScanRule::kInstance = - std::unique_ptr(new PushLimitDownTagIndexRangeScanRule()); - -PushLimitDownTagIndexRangeScanRule::PushLimitDownTagIndexRangeScanRule() { - RuleSet::QueryRules().addRule(this); -} - -const Pattern &PushLimitDownTagIndexRangeScanRule::pattern() const { - static Pattern pattern = Pattern::create( - graph::PlanNode::Kind::kLimit, {Pattern::create(graph::PlanNode::Kind::kTagIndexRangeScan)}); - return pattern; -} - -StatusOr PushLimitDownTagIndexRangeScanRule::transform( - OptContext *octx, const MatchedResult &matched) const { - auto *qctx = octx->qctx(); - auto limitGroupNode = matched.node; - auto indexScanGroupNode = matched.dependencies.front().node; - - const auto limit = static_cast(limitGroupNode->node()); - const auto indexScan = static_cast(indexScanGroupNode->node()); - - int64_t limitRows = limit->offset() + limit->count(qctx); - if (indexScan->limit(qctx) >= 0 && limitRows >= indexScan->limit(qctx)) { - return TransformResult::noTransform(); - } - - auto newLimit = static_cast(limit->clone()); - auto newLimitGroupNode = OptGroupNode::create(octx, newLimit, limitGroupNode->group()); - - auto newTagIndexRangeScan = static_cast(indexScan->clone()); - newTagIndexRangeScan->setLimit(limitRows); - auto newTagIndexRangeScanGroup = OptGroup::create(octx); - auto newTagIndexRangeScanGroupNode = - newTagIndexRangeScanGroup->makeGroupNode(newTagIndexRangeScan); - - newLimitGroupNode->dependsOn(newTagIndexRangeScanGroup); - for (auto dep : indexScanGroupNode->dependencies()) { - newTagIndexRangeScanGroupNode->dependsOn(dep); - } - - TransformResult result; - result.eraseAll = true; - result.newGroupNodes.emplace_back(newLimitGroupNode); - return result; -} - -std::string PushLimitDownTagIndexRangeScanRule::toString() const { - return "PushLimitDownTagIndexRangeScanRule"; -} - -} // namespace opt -} // namespace nebula diff --git a/src/graph/optimizer/rule/PushLimitDownTagIndexRangeScanRule.h b/src/graph/optimizer/rule/PushLimitDownTagIndexRangeScanRule.h deleted file mode 100644 index 2e42c47298b..00000000000 --- a/src/graph/optimizer/rule/PushLimitDownTagIndexRangeScanRule.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright (c) 2021 vesoft inc. All rights reserved. - * - * This source code is licensed under Apache 2.0 License. - */ - -#pragma once - -#include "graph/optimizer/OptRule.h" - -namespace nebula { -namespace opt { - -class PushLimitDownTagIndexRangeScanRule final : public OptRule { - public: - const Pattern &pattern() const override; - - StatusOr transform(OptContext *ctx, - const MatchedResult &matched) const override; - - std::string toString() const override; - - private: - PushLimitDownTagIndexRangeScanRule(); - - static std::unique_ptr kInstance; -}; - -} // namespace opt -} // namespace nebula diff --git a/src/graph/optimizer/rule/PushTopNDownEdgeIndexFullScanRule.cpp b/src/graph/optimizer/rule/PushTopNDownEdgeIndexFullScanRule.cpp deleted file mode 100644 index a64c2ae4767..00000000000 --- a/src/graph/optimizer/rule/PushTopNDownEdgeIndexFullScanRule.cpp +++ /dev/null @@ -1,110 +0,0 @@ -/* Copyright (c) 2021 vesoft inc. All rights reserved. - * - * This source code is licensed under Apache 2.0 License. - */ - -#include "graph/optimizer/rule/PushTopNDownEdgeIndexFullScanRule.h" - -#include "graph/optimizer/OptContext.h" -#include "graph/optimizer/OptGroup.h" -#include "graph/planner/plan/PlanNode.h" -#include "graph/planner/plan/Query.h" -#include "graph/planner/plan/Scan.h" - -using nebula::graph::EdgeIndexFullScan; -using nebula::graph::PlanNode; -using nebula::graph::Project; -using nebula::graph::QueryContext; -using nebula::graph::TopN; - -namespace nebula { -namespace opt { - -std::unique_ptr PushTopNDownEdgeIndexFullScanRule::kInstance = - std::unique_ptr(new PushTopNDownEdgeIndexFullScanRule()); - -PushTopNDownEdgeIndexFullScanRule::PushTopNDownEdgeIndexFullScanRule() { - RuleSet::QueryRules().addRule(this); -} - -const Pattern &PushTopNDownEdgeIndexFullScanRule::pattern() const { - static Pattern pattern = Pattern::create( - graph::PlanNode::Kind::kTopN, - {Pattern::create(graph::PlanNode::Kind::kProject, - {Pattern::create(graph::PlanNode::Kind::kEdgeIndexFullScan)})}); - return pattern; -} - -StatusOr PushTopNDownEdgeIndexFullScanRule::transform( - OptContext *octx, const MatchedResult &matched) const { - auto topNGroupNode = matched.node; - auto projectGroupNode = matched.dependencies.front().node; - auto indexScanGroupNode = matched.dependencies.front().dependencies.front().node; - - const auto topN = static_cast(topNGroupNode->node()); - const auto project = static_cast(projectGroupNode->node()); - const auto indexScan = static_cast(indexScanGroupNode->node()); - - int64_t limitRows = topN->offset() + topN->count(); - - auto &factors = topN->factors(); - auto projColNames = project->colNames(); - const auto &yieldColumns = indexScan->yieldColumns(); - - std::unordered_map namesMap; - for (auto yieldColumn : yieldColumns->columns()) { - if (yieldColumn->expr()->kind() == Expression::Kind::kEdgeProperty) { - const auto &propName = static_cast(yieldColumn->expr())->prop(); - namesMap[yieldColumn->name()] = propName; - continue; - } - return TransformResult::noTransform(); - } - std::vector orderBys; - orderBys.reserve(factors.size()); - - for (auto factor : factors) { - auto colName = projColNames[factor.first]; - auto found = namesMap.find(colName); - if (found == namesMap.end()) { - return Status::Error(); - } - storage::cpp2::OrderBy orderBy; - orderBy.prop_ref() = found->second; - orderBy.direction_ref() = factor.second == OrderFactor::OrderType::ASCEND - ? storage::cpp2::OrderDirection::ASCENDING - : storage::cpp2::OrderDirection::DESCENDING; - orderBys.emplace_back(orderBy); - } - - auto newTopN = static_cast(topN->clone()); - auto newtopNGroupNode = OptGroupNode::create(octx, newTopN, topNGroupNode->group()); - - auto newProject = static_cast(project->clone()); - auto newProjectGroup = OptGroup::create(octx); - auto newProjectGroupNode = newProjectGroup->makeGroupNode(newProject); - - auto newIndexScan = static_cast(indexScan->clone()); - newIndexScan->setLimit(limitRows); - newIndexScan->setOrderBy(orderBys); - auto newIndexScanGroup = OptGroup::create(octx); - auto newIndexScanGroupNode = newIndexScanGroup->makeGroupNode(newIndexScan); - - newtopNGroupNode->dependsOn(newProjectGroup); - newProjectGroupNode->dependsOn(newIndexScanGroup); - for (auto dep : indexScanGroupNode->dependencies()) { - newIndexScanGroupNode->dependsOn(dep); - } - - TransformResult result; - result.eraseAll = true; - result.newGroupNodes.emplace_back(newtopNGroupNode); - return result; -} - -std::string PushTopNDownEdgeIndexFullScanRule::toString() const { - return "PushTopNDownEdgeIndexFullScanRule"; -} - -} // namespace opt -} // namespace nebula diff --git a/src/graph/optimizer/rule/PushTopNDownEdgeIndexFullScanRule.h b/src/graph/optimizer/rule/PushTopNDownEdgeIndexFullScanRule.h deleted file mode 100644 index 271d1045ac0..00000000000 --- a/src/graph/optimizer/rule/PushTopNDownEdgeIndexFullScanRule.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright (c) 2021 vesoft inc. All rights reserved. - * - * This source code is licensed under Apache 2.0 License. - */ - -#pragma once - -#include "graph/optimizer/OptRule.h" - -namespace nebula { -namespace opt { - -class PushTopNDownEdgeIndexFullScanRule final : public OptRule { - public: - const Pattern &pattern() const override; - - StatusOr transform(OptContext *ctx, - const MatchedResult &matched) const override; - - std::string toString() const override; - - private: - PushTopNDownEdgeIndexFullScanRule(); - - static std::unique_ptr kInstance; -}; - -} // namespace opt -} // namespace nebula diff --git a/src/graph/optimizer/rule/PushTopNDownEdgeIndexPrefixScanRule.cpp b/src/graph/optimizer/rule/PushTopNDownEdgeIndexPrefixScanRule.cpp deleted file mode 100644 index 305a3f3844d..00000000000 --- a/src/graph/optimizer/rule/PushTopNDownEdgeIndexPrefixScanRule.cpp +++ /dev/null @@ -1,110 +0,0 @@ -/* Copyright (c) 2021 vesoft inc. All rights reserved. - * - * This source code is licensed under Apache 2.0 License. - */ - -#include "graph/optimizer/rule/PushTopNDownEdgeIndexPrefixScanRule.h" - -#include "graph/optimizer/OptContext.h" -#include "graph/optimizer/OptGroup.h" -#include "graph/planner/plan/PlanNode.h" -#include "graph/planner/plan/Query.h" -#include "graph/planner/plan/Scan.h" - -using nebula::graph::EdgeIndexPrefixScan; -using nebula::graph::PlanNode; -using nebula::graph::Project; -using nebula::graph::QueryContext; -using nebula::graph::TopN; - -namespace nebula { -namespace opt { - -std::unique_ptr PushTopNDownEdgeIndexPrefixScanRule::kInstance = - std::unique_ptr(new PushTopNDownEdgeIndexPrefixScanRule()); - -PushTopNDownEdgeIndexPrefixScanRule::PushTopNDownEdgeIndexPrefixScanRule() { - RuleSet::QueryRules().addRule(this); -} - -const Pattern &PushTopNDownEdgeIndexPrefixScanRule::pattern() const { - static Pattern pattern = Pattern::create( - graph::PlanNode::Kind::kTopN, - {Pattern::create(graph::PlanNode::Kind::kProject, - {Pattern::create(graph::PlanNode::Kind::kEdgeIndexPrefixScan)})}); - return pattern; -} - -StatusOr PushTopNDownEdgeIndexPrefixScanRule::transform( - OptContext *octx, const MatchedResult &matched) const { - auto topNGroupNode = matched.node; - auto projectGroupNode = matched.dependencies.front().node; - auto indexScanGroupNode = matched.dependencies.front().dependencies.front().node; - - const auto topN = static_cast(topNGroupNode->node()); - const auto project = static_cast(projectGroupNode->node()); - const auto indexScan = static_cast(indexScanGroupNode->node()); - - int64_t limitRows = topN->offset() + topN->count(); - - auto &factors = topN->factors(); - auto projColNames = project->colNames(); - const auto &yieldColumns = indexScan->yieldColumns(); - - std::unordered_map namesMap; - for (auto yieldColumn : yieldColumns->columns()) { - if (yieldColumn->expr()->kind() == Expression::Kind::kEdgeProperty) { - const auto &propName = static_cast(yieldColumn->expr())->prop(); - namesMap[yieldColumn->name()] = propName; - continue; - } - return TransformResult::noTransform(); - } - std::vector orderBys; - orderBys.reserve(factors.size()); - - for (auto factor : factors) { - auto colName = projColNames[factor.first]; - auto found = namesMap.find(colName); - if (found == namesMap.end()) { - return Status::Error(); - } - storage::cpp2::OrderBy orderBy; - orderBy.prop_ref() = found->second; - orderBy.direction_ref() = factor.second == OrderFactor::OrderType::ASCEND - ? storage::cpp2::OrderDirection::ASCENDING - : storage::cpp2::OrderDirection::DESCENDING; - orderBys.emplace_back(orderBy); - } - - auto newTopN = static_cast(topN->clone()); - auto newtopNGroupNode = OptGroupNode::create(octx, newTopN, topNGroupNode->group()); - - auto newProject = static_cast(project->clone()); - auto newProjectGroup = OptGroup::create(octx); - auto newProjectGroupNode = newProjectGroup->makeGroupNode(newProject); - - auto newIndexScan = static_cast(indexScan->clone()); - newIndexScan->setLimit(limitRows); - newIndexScan->setOrderBy(orderBys); - auto newIndexScanGroup = OptGroup::create(octx); - auto newIndexScanGroupNode = newIndexScanGroup->makeGroupNode(newIndexScan); - - newtopNGroupNode->dependsOn(newProjectGroup); - newProjectGroupNode->dependsOn(newIndexScanGroup); - for (auto dep : indexScanGroupNode->dependencies()) { - newIndexScanGroupNode->dependsOn(dep); - } - - TransformResult result; - result.eraseAll = true; - result.newGroupNodes.emplace_back(newtopNGroupNode); - return result; -} - -std::string PushTopNDownEdgeIndexPrefixScanRule::toString() const { - return "PushTopNDownEdgeIndexPrefixScanRule"; -} - -} // namespace opt -} // namespace nebula diff --git a/src/graph/optimizer/rule/PushTopNDownEdgeIndexPrefixScanRule.h b/src/graph/optimizer/rule/PushTopNDownEdgeIndexPrefixScanRule.h deleted file mode 100644 index 11fae1deb3d..00000000000 --- a/src/graph/optimizer/rule/PushTopNDownEdgeIndexPrefixScanRule.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright (c) 2021 vesoft inc. All rights reserved. - * - * This source code is licensed under Apache 2.0 License. - */ - -#pragma once - -#include "graph/optimizer/OptRule.h" - -namespace nebula { -namespace opt { - -class PushTopNDownEdgeIndexPrefixScanRule final : public OptRule { - public: - const Pattern &pattern() const override; - - StatusOr transform(OptContext *ctx, - const MatchedResult &matched) const override; - - std::string toString() const override; - - private: - PushTopNDownEdgeIndexPrefixScanRule(); - - static std::unique_ptr kInstance; -}; - -} // namespace opt -} // namespace nebula diff --git a/src/graph/optimizer/rule/PushTopNDownEdgeIndexRangeScanRule.cpp b/src/graph/optimizer/rule/PushTopNDownEdgeIndexRangeScanRule.cpp deleted file mode 100644 index 58a668885af..00000000000 --- a/src/graph/optimizer/rule/PushTopNDownEdgeIndexRangeScanRule.cpp +++ /dev/null @@ -1,110 +0,0 @@ -/* Copyright (c) 2021 vesoft inc. All rights reserved. - * - * This source code is licensed under Apache 2.0 License. - */ - -#include "graph/optimizer/rule/PushTopNDownEdgeIndexRangeScanRule.h" - -#include "graph/optimizer/OptContext.h" -#include "graph/optimizer/OptGroup.h" -#include "graph/planner/plan/PlanNode.h" -#include "graph/planner/plan/Query.h" -#include "graph/planner/plan/Scan.h" - -using nebula::graph::EdgeIndexRangeScan; -using nebula::graph::PlanNode; -using nebula::graph::Project; -using nebula::graph::QueryContext; -using nebula::graph::TopN; - -namespace nebula { -namespace opt { - -std::unique_ptr PushTopNDownEdgeIndexRangeScanRule::kInstance = - std::unique_ptr(new PushTopNDownEdgeIndexRangeScanRule()); - -PushTopNDownEdgeIndexRangeScanRule::PushTopNDownEdgeIndexRangeScanRule() { - RuleSet::QueryRules().addRule(this); -} - -const Pattern &PushTopNDownEdgeIndexRangeScanRule::pattern() const { - static Pattern pattern = Pattern::create( - graph::PlanNode::Kind::kTopN, - {Pattern::create(graph::PlanNode::Kind::kProject, - {Pattern::create(graph::PlanNode::Kind::kEdgeIndexRangeScan)})}); - return pattern; -} - -StatusOr PushTopNDownEdgeIndexRangeScanRule::transform( - OptContext *octx, const MatchedResult &matched) const { - auto topNGroupNode = matched.node; - auto projectGroupNode = matched.dependencies.front().node; - auto indexScanGroupNode = matched.dependencies.front().dependencies.front().node; - - const auto topN = static_cast(topNGroupNode->node()); - const auto project = static_cast(projectGroupNode->node()); - const auto indexScan = static_cast(indexScanGroupNode->node()); - - int64_t limitRows = topN->offset() + topN->count(); - - auto &factors = topN->factors(); - auto projColNames = project->colNames(); - const auto &yieldColumns = indexScan->yieldColumns(); - - std::unordered_map namesMap; - for (auto yieldColumn : yieldColumns->columns()) { - if (yieldColumn->expr()->kind() == Expression::Kind::kEdgeProperty) { - const auto &propName = static_cast(yieldColumn->expr())->prop(); - namesMap[yieldColumn->name()] = propName; - continue; - } - return TransformResult::noTransform(); - } - std::vector orderBys; - orderBys.reserve(factors.size()); - - for (auto factor : factors) { - auto colName = projColNames[factor.first]; - auto found = namesMap.find(colName); - if (found == namesMap.end()) { - return Status::Error(); - } - storage::cpp2::OrderBy orderBy; - orderBy.prop_ref() = found->second; - orderBy.direction_ref() = factor.second == OrderFactor::OrderType::ASCEND - ? storage::cpp2::OrderDirection::ASCENDING - : storage::cpp2::OrderDirection::DESCENDING; - orderBys.emplace_back(orderBy); - } - - auto newTopN = static_cast(topN->clone()); - auto newtopNGroupNode = OptGroupNode::create(octx, newTopN, topNGroupNode->group()); - - auto newProject = static_cast(project->clone()); - auto newProjectGroup = OptGroup::create(octx); - auto newProjectGroupNode = newProjectGroup->makeGroupNode(newProject); - - auto newIndexScan = static_cast(indexScan->clone()); - newIndexScan->setLimit(limitRows); - newIndexScan->setOrderBy(orderBys); - auto newIndexScanGroup = OptGroup::create(octx); - auto newIndexScanGroupNode = newIndexScanGroup->makeGroupNode(newIndexScan); - - newtopNGroupNode->dependsOn(newProjectGroup); - newProjectGroupNode->dependsOn(newIndexScanGroup); - for (auto dep : indexScanGroupNode->dependencies()) { - newIndexScanGroupNode->dependsOn(dep); - } - - TransformResult result; - result.eraseAll = true; - result.newGroupNodes.emplace_back(newtopNGroupNode); - return result; -} - -std::string PushTopNDownEdgeIndexRangeScanRule::toString() const { - return "PushTopNDownEdgeIndexRangeScanRule"; -} - -} // namespace opt -} // namespace nebula diff --git a/src/graph/optimizer/rule/PushTopNDownEdgeIndexRangeScanRule.h b/src/graph/optimizer/rule/PushTopNDownEdgeIndexRangeScanRule.h deleted file mode 100644 index 781487d9b4a..00000000000 --- a/src/graph/optimizer/rule/PushTopNDownEdgeIndexRangeScanRule.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright (c) 2021 vesoft inc. All rights reserved. - * - * This source code is licensed under Apache 2.0 License. - */ - -#pragma once - -#include "graph/optimizer/OptRule.h" - -namespace nebula { -namespace opt { - -class PushTopNDownEdgeIndexRangeScanRule final : public OptRule { - public: - const Pattern &pattern() const override; - - StatusOr transform(OptContext *ctx, - const MatchedResult &matched) const override; - - std::string toString() const override; - - private: - PushTopNDownEdgeIndexRangeScanRule(); - - static std::unique_ptr kInstance; -}; - -} // namespace opt -} // namespace nebula diff --git a/src/graph/optimizer/rule/PushTopNDownIndexScanRule.cpp b/src/graph/optimizer/rule/PushTopNDownIndexScanRule.cpp index 1589917682f..8320d7e5013 100644 --- a/src/graph/optimizer/rule/PushTopNDownIndexScanRule.cpp +++ b/src/graph/optimizer/rule/PushTopNDownIndexScanRule.cpp @@ -19,6 +19,17 @@ using nebula::graph::TopN; namespace nebula { namespace opt { +/*static*/ const std::initializer_list + PushTopNDownIndexScanRule::kIndexScanKinds{ + graph::PlanNode::Kind::kIndexScan, + graph::PlanNode::Kind::kTagIndexFullScan, + graph::PlanNode::Kind::kTagIndexRangeScan, + graph::PlanNode::Kind::kTagIndexPrefixScan, + graph::PlanNode::Kind::kEdgeIndexFullScan, + graph::PlanNode::Kind::kEdgeIndexRangeScan, + graph::PlanNode::Kind::kEdgeIndexPrefixScan, + }; + std::unique_ptr PushTopNDownIndexScanRule::kInstance = std::unique_ptr(new PushTopNDownIndexScanRule()); @@ -27,10 +38,9 @@ PushTopNDownIndexScanRule::PushTopNDownIndexScanRule() { } const Pattern &PushTopNDownIndexScanRule::pattern() const { - static Pattern pattern = - Pattern::create(graph::PlanNode::Kind::kTopN, - {Pattern::create(graph::PlanNode::Kind::kProject, - {Pattern::create(graph::PlanNode::Kind::kIndexScan)})}); + static Pattern pattern = Pattern::create( + graph::PlanNode::Kind::kTopN, + {Pattern::create(graph::PlanNode::Kind::kProject, {Pattern::create(kIndexScanKinds)})}); return pattern; } @@ -42,7 +52,7 @@ StatusOr PushTopNDownIndexScanRule::transform( const auto topN = static_cast(topNGroupNode->node()); const auto project = static_cast(projectGroupNode->node()); - const auto indexScan = static_cast(indexScanGroupNode->node()); + const auto indexScan = indexScanGroupNode->node()->asNode(); int64_t limitRows = topN->offset() + topN->count(); diff --git a/src/graph/optimizer/rule/PushTopNDownIndexScanRule.h b/src/graph/optimizer/rule/PushTopNDownIndexScanRule.h index 7787320592c..a21f459ff7b 100644 --- a/src/graph/optimizer/rule/PushTopNDownIndexScanRule.h +++ b/src/graph/optimizer/rule/PushTopNDownIndexScanRule.h @@ -5,6 +5,8 @@ #pragma once +#include + #include "graph/optimizer/OptRule.h" namespace nebula { @@ -23,6 +25,7 @@ class PushTopNDownIndexScanRule final : public OptRule { PushTopNDownIndexScanRule(); static std::unique_ptr kInstance; + static const std::initializer_list kIndexScanKinds; }; } // namespace opt diff --git a/src/graph/optimizer/rule/PushTopNDownTagIndexFullScanRule.cpp b/src/graph/optimizer/rule/PushTopNDownTagIndexFullScanRule.cpp deleted file mode 100644 index 46b1eeba520..00000000000 --- a/src/graph/optimizer/rule/PushTopNDownTagIndexFullScanRule.cpp +++ /dev/null @@ -1,110 +0,0 @@ -/* Copyright (c) 2021 vesoft inc. All rights reserved. - * - * This source code is licensed under Apache 2.0 License. - */ - -#include "graph/optimizer/rule/PushTopNDownTagIndexFullScanRule.h" - -#include "graph/optimizer/OptContext.h" -#include "graph/optimizer/OptGroup.h" -#include "graph/planner/plan/PlanNode.h" -#include "graph/planner/plan/Query.h" -#include "graph/planner/plan/Scan.h" - -using nebula::graph::PlanNode; -using nebula::graph::Project; -using nebula::graph::QueryContext; -using nebula::graph::TagIndexFullScan; -using nebula::graph::TopN; - -namespace nebula { -namespace opt { - -std::unique_ptr PushTopNDownTagIndexFullScanRule::kInstance = - std::unique_ptr(new PushTopNDownTagIndexFullScanRule()); - -PushTopNDownTagIndexFullScanRule::PushTopNDownTagIndexFullScanRule() { - RuleSet::QueryRules().addRule(this); -} - -const Pattern &PushTopNDownTagIndexFullScanRule::pattern() const { - static Pattern pattern = Pattern::create( - graph::PlanNode::Kind::kTopN, - {Pattern::create(graph::PlanNode::Kind::kProject, - {Pattern::create(graph::PlanNode::Kind::kTagIndexFullScan)})}); - return pattern; -} - -StatusOr PushTopNDownTagIndexFullScanRule::transform( - OptContext *octx, const MatchedResult &matched) const { - auto topNGroupNode = matched.node; - auto projectGroupNode = matched.dependencies.front().node; - auto indexScanGroupNode = matched.dependencies.front().dependencies.front().node; - - const auto topN = static_cast(topNGroupNode->node()); - const auto project = static_cast(projectGroupNode->node()); - const auto indexScan = static_cast(indexScanGroupNode->node()); - - int64_t limitRows = topN->offset() + topN->count(); - - auto &factors = topN->factors(); - auto projColNames = project->colNames(); - const auto &yieldColumns = indexScan->yieldColumns(); - - std::unordered_map namesMap; - for (auto yieldColumn : yieldColumns->columns()) { - if (yieldColumn->expr()->kind() == Expression::Kind::kTagProperty) { - const auto &propName = static_cast(yieldColumn->expr())->prop(); - namesMap[yieldColumn->name()] = propName; - continue; - } - return TransformResult::noTransform(); - } - std::vector orderBys; - orderBys.reserve(factors.size()); - - for (auto factor : factors) { - auto colName = projColNames[factor.first]; - auto found = namesMap.find(colName); - if (found == namesMap.end()) { - return Status::Error(); - } - storage::cpp2::OrderBy orderBy; - orderBy.prop_ref() = found->second; - orderBy.direction_ref() = factor.second == OrderFactor::OrderType::ASCEND - ? storage::cpp2::OrderDirection::ASCENDING - : storage::cpp2::OrderDirection::DESCENDING; - orderBys.emplace_back(orderBy); - } - - auto newTopN = static_cast(topN->clone()); - auto newtopNGroupNode = OptGroupNode::create(octx, newTopN, topNGroupNode->group()); - - auto newProject = static_cast(project->clone()); - auto newProjectGroup = OptGroup::create(octx); - auto newProjectGroupNode = newProjectGroup->makeGroupNode(newProject); - - auto newIndexScan = static_cast(indexScan->clone()); - newIndexScan->setLimit(limitRows); - newIndexScan->setOrderBy(orderBys); - auto newIndexScanGroup = OptGroup::create(octx); - auto newIndexScanGroupNode = newIndexScanGroup->makeGroupNode(newIndexScan); - - newtopNGroupNode->dependsOn(newProjectGroup); - newProjectGroupNode->dependsOn(newIndexScanGroup); - for (auto dep : indexScanGroupNode->dependencies()) { - newIndexScanGroupNode->dependsOn(dep); - } - - TransformResult result; - result.eraseAll = true; - result.newGroupNodes.emplace_back(newtopNGroupNode); - return result; -} - -std::string PushTopNDownTagIndexFullScanRule::toString() const { - return "PushTopNDownTagIndexFullScanRule"; -} - -} // namespace opt -} // namespace nebula diff --git a/src/graph/optimizer/rule/PushTopNDownTagIndexFullScanRule.h b/src/graph/optimizer/rule/PushTopNDownTagIndexFullScanRule.h deleted file mode 100644 index 763b7fbf1f8..00000000000 --- a/src/graph/optimizer/rule/PushTopNDownTagIndexFullScanRule.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright (c) 2021 vesoft inc. All rights reserved. - * - * This source code is licensed under Apache 2.0 License. - */ - -#pragma once - -#include "graph/optimizer/OptRule.h" - -namespace nebula { -namespace opt { - -class PushTopNDownTagIndexFullScanRule final : public OptRule { - public: - const Pattern &pattern() const override; - - StatusOr transform(OptContext *ctx, - const MatchedResult &matched) const override; - - std::string toString() const override; - - private: - PushTopNDownTagIndexFullScanRule(); - - static std::unique_ptr kInstance; -}; - -} // namespace opt -} // namespace nebula diff --git a/src/graph/optimizer/rule/PushTopNDownTagIndexPrefixScanRule.cpp b/src/graph/optimizer/rule/PushTopNDownTagIndexPrefixScanRule.cpp deleted file mode 100644 index 044ac20b3f1..00000000000 --- a/src/graph/optimizer/rule/PushTopNDownTagIndexPrefixScanRule.cpp +++ /dev/null @@ -1,110 +0,0 @@ -/* Copyright (c) 2021 vesoft inc. All rights reserved. - * - * This source code is licensed under Apache 2.0 License. - */ - -#include "graph/optimizer/rule/PushTopNDownTagIndexPrefixScanRule.h" - -#include "graph/optimizer/OptContext.h" -#include "graph/optimizer/OptGroup.h" -#include "graph/planner/plan/PlanNode.h" -#include "graph/planner/plan/Query.h" -#include "graph/planner/plan/Scan.h" - -using nebula::graph::PlanNode; -using nebula::graph::Project; -using nebula::graph::QueryContext; -using nebula::graph::TagIndexPrefixScan; -using nebula::graph::TopN; - -namespace nebula { -namespace opt { - -std::unique_ptr PushTopNDownTagIndexPrefixScanRule::kInstance = - std::unique_ptr(new PushTopNDownTagIndexPrefixScanRule()); - -PushTopNDownTagIndexPrefixScanRule::PushTopNDownTagIndexPrefixScanRule() { - RuleSet::QueryRules().addRule(this); -} - -const Pattern &PushTopNDownTagIndexPrefixScanRule::pattern() const { - static Pattern pattern = Pattern::create( - graph::PlanNode::Kind::kTopN, - {Pattern::create(graph::PlanNode::Kind::kProject, - {Pattern::create(graph::PlanNode::Kind::kTagIndexPrefixScan)})}); - return pattern; -} - -StatusOr PushTopNDownTagIndexPrefixScanRule::transform( - OptContext *octx, const MatchedResult &matched) const { - auto topNGroupNode = matched.node; - auto projectGroupNode = matched.dependencies.front().node; - auto indexScanGroupNode = matched.dependencies.front().dependencies.front().node; - - const auto topN = static_cast(topNGroupNode->node()); - const auto project = static_cast(projectGroupNode->node()); - const auto indexScan = static_cast(indexScanGroupNode->node()); - - int64_t limitRows = topN->offset() + topN->count(); - - auto &factors = topN->factors(); - auto projColNames = project->colNames(); - const auto &yieldColumns = indexScan->yieldColumns(); - - std::unordered_map namesMap; - for (auto yieldColumn : yieldColumns->columns()) { - if (yieldColumn->expr()->kind() == Expression::Kind::kTagProperty) { - const auto &propName = static_cast(yieldColumn->expr())->prop(); - namesMap[yieldColumn->name()] = propName; - continue; - } - return TransformResult::noTransform(); - } - std::vector orderBys; - orderBys.reserve(factors.size()); - - for (auto factor : factors) { - auto colName = projColNames[factor.first]; - auto found = namesMap.find(colName); - if (found == namesMap.end()) { - return Status::Error(); - } - storage::cpp2::OrderBy orderBy; - orderBy.prop_ref() = found->second; - orderBy.direction_ref() = factor.second == OrderFactor::OrderType::ASCEND - ? storage::cpp2::OrderDirection::ASCENDING - : storage::cpp2::OrderDirection::DESCENDING; - orderBys.emplace_back(orderBy); - } - - auto newTopN = static_cast(topN->clone()); - auto newtopNGroupNode = OptGroupNode::create(octx, newTopN, topNGroupNode->group()); - - auto newProject = static_cast(project->clone()); - auto newProjectGroup = OptGroup::create(octx); - auto newProjectGroupNode = newProjectGroup->makeGroupNode(newProject); - - auto newIndexScan = static_cast(indexScan->clone()); - newIndexScan->setLimit(limitRows); - newIndexScan->setOrderBy(orderBys); - auto newIndexScanGroup = OptGroup::create(octx); - auto newIndexScanGroupNode = newIndexScanGroup->makeGroupNode(newIndexScan); - - newtopNGroupNode->dependsOn(newProjectGroup); - newProjectGroupNode->dependsOn(newIndexScanGroup); - for (auto dep : indexScanGroupNode->dependencies()) { - newIndexScanGroupNode->dependsOn(dep); - } - - TransformResult result; - result.eraseAll = true; - result.newGroupNodes.emplace_back(newtopNGroupNode); - return result; -} - -std::string PushTopNDownTagIndexPrefixScanRule::toString() const { - return "PushTopNDownTagIndexPrefixScanRule"; -} - -} // namespace opt -} // namespace nebula diff --git a/src/graph/optimizer/rule/PushTopNDownTagIndexPrefixScanRule.h b/src/graph/optimizer/rule/PushTopNDownTagIndexPrefixScanRule.h deleted file mode 100644 index b449504cd8e..00000000000 --- a/src/graph/optimizer/rule/PushTopNDownTagIndexPrefixScanRule.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright (c) 2021 vesoft inc. All rights reserved. - * - * This source code is licensed under Apache 2.0 License. - */ - -#pragma once - -#include "graph/optimizer/OptRule.h" - -namespace nebula { -namespace opt { - -class PushTopNDownTagIndexPrefixScanRule final : public OptRule { - public: - const Pattern &pattern() const override; - - StatusOr transform(OptContext *ctx, - const MatchedResult &matched) const override; - - std::string toString() const override; - - private: - PushTopNDownTagIndexPrefixScanRule(); - - static std::unique_ptr kInstance; -}; - -} // namespace opt -} // namespace nebula diff --git a/src/graph/optimizer/rule/PushTopNDownTagIndexRangeScanRule.cpp b/src/graph/optimizer/rule/PushTopNDownTagIndexRangeScanRule.cpp deleted file mode 100644 index fb9733dbce7..00000000000 --- a/src/graph/optimizer/rule/PushTopNDownTagIndexRangeScanRule.cpp +++ /dev/null @@ -1,112 +0,0 @@ -/* Copyright (c) 2021 vesoft inc. All rights reserved. - * - * This source code is licensed under Apache 2.0 License. - */ - -#include "graph/optimizer/rule/PushTopNDownTagIndexRangeScanRule.h" - -#include "common/expression/AttributeExpression.h" -#include "graph/optimizer/OptContext.h" -#include "graph/optimizer/OptGroup.h" -#include "graph/planner/plan/PlanNode.h" -#include "graph/planner/plan/Query.h" -#include "graph/planner/plan/Scan.h" - -using nebula::graph::PlanNode; -using nebula::graph::Project; -using nebula::graph::QueryContext; -using nebula::graph::TagIndexRangeScan; -using nebula::graph::TopN; - -namespace nebula { -namespace opt { - -std::unique_ptr PushTopNDownTagIndexRangeScanRule::kInstance = - std::unique_ptr(new PushTopNDownTagIndexRangeScanRule()); - -PushTopNDownTagIndexRangeScanRule::PushTopNDownTagIndexRangeScanRule() { - RuleSet::QueryRules().addRule(this); -} - -const Pattern &PushTopNDownTagIndexRangeScanRule::pattern() const { - static Pattern pattern = Pattern::create( - graph::PlanNode::Kind::kTopN, - {Pattern::create(graph::PlanNode::Kind::kProject, - {Pattern::create(graph::PlanNode::Kind::kTagIndexRangeScan)})}); - return pattern; -} - -StatusOr PushTopNDownTagIndexRangeScanRule::transform( - OptContext *octx, const MatchedResult &matched) const { - auto topNGroupNode = matched.node; - auto projectGroupNode = matched.dependencies.front().node; - auto indexScanGroupNode = matched.dependencies.front().dependencies.front().node; - - const auto topN = static_cast(topNGroupNode->node()); - const auto project = static_cast(projectGroupNode->node()); - const auto indexScan = static_cast(indexScanGroupNode->node()); - - int64_t limitRows = topN->offset() + topN->count(); - - auto &factors = topN->factors(); - auto projColNames = project->colNames(); - const auto *yieldColumns = indexScan->yieldColumns(); - - std::unordered_map namesMap; - for (auto yieldColumn : yieldColumns->columns()) { - LOG(INFO) << "yieldColumn->expr()->kind()=" << yieldColumn->expr()->kind(); - if (yieldColumn->expr()->kind() == Expression::Kind::kTagProperty) { - const auto &propName = static_cast(yieldColumn->expr())->prop(); - namesMap[yieldColumn->name()] = propName; - continue; - } - return TransformResult::noTransform(); - } - std::vector orderBys; - orderBys.reserve(factors.size()); - - for (auto factor : factors) { - auto colName = projColNames[factor.first]; - auto found = namesMap.find(colName); - if (found == namesMap.end()) { - return Status::Error(); - } - storage::cpp2::OrderBy orderBy; - orderBy.prop_ref() = found->second; - orderBy.direction_ref() = factor.second == OrderFactor::OrderType::ASCEND - ? storage::cpp2::OrderDirection::ASCENDING - : storage::cpp2::OrderDirection::DESCENDING; - orderBys.emplace_back(orderBy); - } - - auto newTopN = static_cast(topN->clone()); - auto newtopNGroupNode = OptGroupNode::create(octx, newTopN, topNGroupNode->group()); - - auto newProject = static_cast(project->clone()); - auto newProjectGroup = OptGroup::create(octx); - auto newProjectGroupNode = newProjectGroup->makeGroupNode(newProject); - - auto newIndexScan = static_cast(indexScan->clone()); - newIndexScan->setLimit(limitRows); - newIndexScan->setOrderBy(orderBys); - auto newIndexScanGroup = OptGroup::create(octx); - auto newIndexScanGroupNode = newIndexScanGroup->makeGroupNode(newIndexScan); - - newtopNGroupNode->dependsOn(newProjectGroup); - newProjectGroupNode->dependsOn(newIndexScanGroup); - for (auto dep : indexScanGroupNode->dependencies()) { - newIndexScanGroupNode->dependsOn(dep); - } - - TransformResult result; - result.eraseAll = true; - result.newGroupNodes.emplace_back(newtopNGroupNode); - return result; -} - -std::string PushTopNDownTagIndexRangeScanRule::toString() const { - return "PushTopNDownTagIndexRangeScanRule"; -} - -} // namespace opt -} // namespace nebula diff --git a/src/graph/optimizer/rule/PushTopNDownTagIndexRangeScanRule.h b/src/graph/optimizer/rule/PushTopNDownTagIndexRangeScanRule.h deleted file mode 100644 index a5512fffafb..00000000000 --- a/src/graph/optimizer/rule/PushTopNDownTagIndexRangeScanRule.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright (c) 2021 vesoft inc. All rights reserved. - * - * This source code is licensed under Apache 2.0 License. - */ - -#pragma once - -#include "graph/optimizer/OptRule.h" - -namespace nebula { -namespace opt { - -class PushTopNDownTagIndexRangeScanRule final : public OptRule { - public: - const Pattern &pattern() const override; - - StatusOr transform(OptContext *ctx, - const MatchedResult &matched) const override; - - std::string toString() const override; - - private: - PushTopNDownTagIndexRangeScanRule(); - - static std::unique_ptr kInstance; -}; - -} // namespace opt -} // namespace nebula diff --git a/src/graph/planner/plan/PlanNode.h b/src/graph/planner/plan/PlanNode.h index 4948c473a3c..5d50b3ac4e4 100644 --- a/src/graph/planner/plan/PlanNode.h +++ b/src/graph/planner/plan/PlanNode.h @@ -282,6 +282,13 @@ class PlanNode { return cost_; } + template + const T* asNode() const { + static_assert(std::is_base_of::value, "T must be a subclass of PlanNode"); + DCHECK(dynamic_cast(this) != nullptr); + return static_cast(this); + } + protected: PlanNode(QueryContext* qctx, Kind kind);