diff --git a/src/optimizer/OptGroup.cpp b/src/optimizer/OptGroup.cpp index c4da0182cbdc6f404c33292953763b65a62620e0..d8c4f6e7503781f6955babdae68b97b9cfc5a806 100644 --- a/src/optimizer/OptGroup.cpp +++ b/src/optimizer/OptGroup.cpp @@ -31,15 +31,15 @@ OptGroup::OptGroup(QueryContext *qctx) noexcept : qctx_(qctx) { DCHECK(qctx != nullptr); } -void OptGroup::addGroupExpr(OptGroupExpr *groupExpr) { - DCHECK(groupExpr != nullptr); - DCHECK(groupExpr->group() == this); - groupExprs_.emplace_back(groupExpr); +void OptGroup::addGroupNode(OptGroupNode *groupNode) { + DCHECK(groupNode != nullptr); + DCHECK(groupNode->group() == this); + groupNodes_.emplace_back(groupNode); } -OptGroupExpr *OptGroup::makeGroupExpr(QueryContext *qctx, PlanNode *node) { - groupExprs_.emplace_back(OptGroupExpr::create(qctx, node, this)); - return groupExprs_.back(); +OptGroupNode *OptGroup::makeGroupNode(QueryContext *qctx, PlanNode *node) { + groupNodes_.emplace_back(OptGroupNode::create(qctx, node, this)); + return groupNodes_.back(); } Status OptGroup::explore(const OptRule *rule) { @@ -48,18 +48,18 @@ Status OptGroup::explore(const OptRule *rule) { } setExplored(rule); - for (auto iter = groupExprs_.begin(); iter != groupExprs_.end();) { - auto groupExpr = *iter; - DCHECK(groupExpr != nullptr); - if (groupExpr->isExplored(rule)) { + for (auto iter = groupNodes_.begin(); iter != groupNodes_.end();) { + auto groupNode = *iter; + DCHECK(groupNode != nullptr); + if (groupNode->isExplored(rule)) { ++iter; continue; } // Bottom to up exploration - NG_RETURN_IF_ERROR(groupExpr->explore(rule)); + NG_RETURN_IF_ERROR(groupNode->explore(rule)); // Find more equivalents - auto status = rule->match(groupExpr); + auto status = rule->match(groupNode); if (!status.ok()) { ++iter; continue; @@ -69,23 +69,23 @@ Status OptGroup::explore(const OptRule *rule) { NG_RETURN_IF_ERROR(resStatus); auto result = std::move(resStatus).value(); if (result.eraseAll) { - groupExprs_.clear(); - for (auto nge : result.newGroupExprs) { - addGroupExpr(nge); + groupNodes_.clear(); + for (auto ngn : result.newGroupNodes) { + addGroupNode(ngn); } break; } - if (!result.newGroupExprs.empty()) { - for (auto nge : result.newGroupExprs) { - addGroupExpr(nge); + if (!result.newGroupNodes.empty()) { + for (auto ngn : result.newGroupNodes) { + addGroupNode(ngn); } setUnexplored(rule); } if (result.eraseCurr) { - iter = groupExprs_.erase(iter); + iter = groupNodes_.erase(iter); } else { ++iter; } @@ -107,40 +107,40 @@ Status OptGroup::exploreUntilMaxRound(const OptRule *rule) { return Status::OK(); } -std::pair<double, const OptGroupExpr *> OptGroup::findMinCostGroupExpr() const { +std::pair<double, const OptGroupNode *> OptGroup::findMinCostGroupNode() const { double minCost = std::numeric_limits<double>::max(); - const OptGroupExpr *minGroupExpr = nullptr; - for (auto &groupExpr : groupExprs_) { - double cost = groupExpr->getCost(); + const OptGroupNode *minGroupNode = nullptr; + for (auto &groupNode : groupNodes_) { + double cost = groupNode->getCost(); if (minCost > cost) { minCost = cost; - minGroupExpr = groupExpr; + minGroupNode = groupNode; } } - return std::make_pair(minCost, minGroupExpr); + return std::make_pair(minCost, minGroupNode); } double OptGroup::getCost() const { - return findMinCostGroupExpr().first; + return findMinCostGroupNode().first; } const PlanNode *OptGroup::getPlan() const { - const OptGroupExpr *minGroupExpr = findMinCostGroupExpr().second; - DCHECK(minGroupExpr != nullptr); - return minGroupExpr->getPlan(); + const OptGroupNode *minGroupNode = findMinCostGroupNode().second; + DCHECK(minGroupNode != nullptr); + return minGroupNode->getPlan(); } -OptGroupExpr *OptGroupExpr::create(QueryContext *qctx, PlanNode *node, const OptGroup *group) { - return qctx->objPool()->add(new OptGroupExpr(node, group)); +OptGroupNode *OptGroupNode::create(QueryContext *qctx, PlanNode *node, const OptGroup *group) { + return qctx->objPool()->add(new OptGroupNode(node, group)); } -OptGroupExpr::OptGroupExpr(PlanNode *node, const OptGroup *group) noexcept +OptGroupNode::OptGroupNode(PlanNode *node, const OptGroup *group) noexcept : node_(node), group_(group) { DCHECK(node != nullptr); DCHECK(group != nullptr); } -Status OptGroupExpr::explore(const OptRule *rule) { +Status OptGroupNode::explore(const OptRule *rule) { if (isExplored(rule)) { return Status::OK(); } @@ -158,11 +158,11 @@ Status OptGroupExpr::explore(const OptRule *rule) { return Status::OK(); } -double OptGroupExpr::getCost() const { +double OptGroupNode::getCost() const { return node_->cost(); } -const PlanNode *OptGroupExpr::getPlan() const { +const PlanNode *OptGroupNode::getPlan() const { switch (node_->dependencies().size()) { case 0: { DCHECK(dependencies_.empty()); diff --git a/src/optimizer/OptGroup.h b/src/optimizer/OptGroup.h index e1c4c4e359d7911c62ccdf20581eea7ba760045b..e7a15089a0f9d30b63e40f3d6f3d49de7e24d0a1 100644 --- a/src/optimizer/OptGroup.h +++ b/src/optimizer/OptGroup.h @@ -20,7 +20,7 @@ class QueryContext; namespace opt { -class OptGroupExpr; +class OptGroupNode; class OptRule; class OptGroup final { @@ -43,10 +43,10 @@ public: } } - void addGroupExpr(OptGroupExpr *groupExpr); - OptGroupExpr *makeGroupExpr(graph::QueryContext *qctx, graph::PlanNode *node); - const std::list<OptGroupExpr *> &groupExprs() const { - return groupExprs_; + void addGroupNode(OptGroupNode *groupNode); + OptGroupNode *makeGroupNode(graph::QueryContext *qctx, graph::PlanNode *node); + const std::list<OptGroupNode *> &groupNodes() const { + return groupNodes_; } Status explore(const OptRule *rule); @@ -59,16 +59,16 @@ private: static constexpr int16_t kMaxExplorationRound = 128; - std::pair<double, const OptGroupExpr *> findMinCostGroupExpr() const; + std::pair<double, const OptGroupNode *> findMinCostGroupNode() const; graph::QueryContext *qctx_{nullptr}; - std::list<OptGroupExpr *> groupExprs_; + std::list<OptGroupNode *> groupNodes_; std::vector<const OptRule *> exploredRules_; }; -class OptGroupExpr final { +class OptGroupNode final { public: - static OptGroupExpr *create(graph::QueryContext *qctx, + static OptGroupNode *create(graph::QueryContext *qctx, graph::PlanNode *node, const OptGroup *group); @@ -110,7 +110,7 @@ public: const graph::PlanNode *getPlan() const; private: - OptGroupExpr(graph::PlanNode *node, const OptGroup *group) noexcept; + OptGroupNode(graph::PlanNode *node, const OptGroup *group) noexcept; graph::PlanNode *node_{nullptr}; const OptGroup *group_{nullptr}; diff --git a/src/optimizer/OptRule.cpp b/src/optimizer/OptRule.cpp index e6253fcfc2b8e538907328bc7760736e1c50b822..fed3f0e67387c399cdd5024179cff5b3d8aef4da 100644 --- a/src/optimizer/OptRule.cpp +++ b/src/optimizer/OptRule.cpp @@ -21,24 +21,24 @@ Pattern Pattern::create(graph::PlanNode::Kind kind, std::initializer_list<Patter return pattern; } -StatusOr<MatchedResult> Pattern::match(const OptGroupExpr *groupExpr) const { - if (groupExpr->node()->kind() != kind_) { +StatusOr<MatchedResult> Pattern::match(const OptGroupNode *groupNode) const { + if (groupNode->node()->kind() != kind_) { return Status::Error(); } if (dependencies_.empty()) { - return MatchedResult{groupExpr, {}}; + return MatchedResult{groupNode, {}}; } - if (groupExpr->dependencies().size() != dependencies_.size()) { + if (groupNode->dependencies().size() != dependencies_.size()) { return Status::Error(); } MatchedResult result; - result.node = groupExpr; + result.node = groupNode; result.dependencies.reserve(dependencies_.size()); for (size_t i = 0; i < dependencies_.size(); ++i) { - auto group = groupExpr->dependencies()[i]; + auto group = groupNode->dependencies()[i]; const auto &pattern = dependencies_[i]; auto status = pattern.match(group); NG_RETURN_IF_ERROR(status); @@ -48,7 +48,7 @@ StatusOr<MatchedResult> Pattern::match(const OptGroupExpr *groupExpr) const { } StatusOr<MatchedResult> Pattern::match(const OptGroup *group) const { - for (auto node : group->groupExprs()) { + for (auto node : group->groupNodes()) { auto status = match(node); if (status.ok()) { return status; @@ -57,9 +57,9 @@ StatusOr<MatchedResult> Pattern::match(const OptGroup *group) const { return Status::Error(); } -StatusOr<MatchedResult> OptRule::match(const OptGroupExpr *groupExpr) const { +StatusOr<MatchedResult> OptRule::match(const OptGroupNode *groupNode) const { const auto &pattern = this->pattern(); - auto status = pattern.match(groupExpr); + auto status = pattern.match(groupNode); NG_RETURN_IF_ERROR(status); auto matched = std::move(status).value(); if (!this->match(matched)) { diff --git a/src/optimizer/OptRule.h b/src/optimizer/OptRule.h index fe616376dfa9f42162c4107631622b5ed8ce5faa..9041afead0b72f1a53e5f52affc71137d6768ae4 100644 --- a/src/optimizer/OptRule.h +++ b/src/optimizer/OptRule.h @@ -22,11 +22,11 @@ class QueryContext; namespace opt { -class OptGroupExpr; +class OptGroupNode; class OptGroup; struct MatchedResult { - const OptGroupExpr *node{nullptr}; + const OptGroupNode *node{nullptr}; std::vector<MatchedResult> dependencies; }; @@ -34,7 +34,7 @@ class Pattern final { public: static Pattern create(graph::PlanNode::Kind kind, std::initializer_list<Pattern> patterns = {}); - StatusOr<MatchedResult> match(const OptGroupExpr *groupNode) const; + StatusOr<MatchedResult> match(const OptGroupNode *groupNode) const; private: Pattern() = default; @@ -51,12 +51,13 @@ public: static TransformResult kNoTrans{false, false, {}}; return kNoTrans; } + bool eraseCurr{false}; bool eraseAll{false}; - std::vector<OptGroupExpr *> newGroupExprs; + std::vector<OptGroupNode *> newGroupNodes; }; - StatusOr<MatchedResult> match(const OptGroupExpr *groupExpr) const; + StatusOr<MatchedResult> match(const OptGroupNode *groupNode) const; virtual ~OptRule() = default; diff --git a/src/optimizer/Optimizer.cpp b/src/optimizer/Optimizer.cpp index 34e40b8685f13a6b6e8e650ba811aea841c45c72..0c35446e72009c6adc0fc3e1706bcadcf55011d0 100644 --- a/src/optimizer/Optimizer.cpp +++ b/src/optimizer/Optimizer.cpp @@ -60,7 +60,7 @@ OptGroup *Optimizer::convertToGroup(QueryContext *qctx, } auto group = OptGroup::create(qctx); - auto groupExpr = group->makeGroupExpr(qctx, node); + auto groupNode = group->makeGroupNode(qctx, node); switch (node->dependencies().size()) { case 0: { @@ -71,29 +71,29 @@ OptGroup *Optimizer::convertToGroup(QueryContext *qctx, if (node->kind() == PlanNode::Kind::kSelect) { auto select = static_cast<Select *>(node); auto then = convertToGroup(qctx, const_cast<PlanNode *>(select->then()), visited); - groupExpr->addBody(then); + groupNode->addBody(then); auto otherNode = const_cast<PlanNode *>(select->otherwise()); auto otherwise = convertToGroup(qctx, otherNode, visited); - groupExpr->addBody(otherwise); + groupNode->addBody(otherwise); } else if (node->kind() == PlanNode::Kind::kLoop) { auto loop = static_cast<Loop *>(node); auto body = convertToGroup(qctx, const_cast<PlanNode *>(loop->body()), visited); - groupExpr->addBody(body); + groupNode->addBody(body); } auto dep = static_cast<SingleDependencyNode *>(node)->dep(); DCHECK(dep != nullptr); auto depGroup = convertToGroup(qctx, const_cast<graph::PlanNode *>(dep), visited); - groupExpr->dependsOn(depGroup); + groupNode->dependsOn(depGroup); break; } case 2: { auto bNode = static_cast<BiInputNode *>(node); auto leftNode = const_cast<graph::PlanNode *>(bNode->left()); auto leftGroup = convertToGroup(qctx, leftNode, visited); - groupExpr->dependsOn(leftGroup); + groupNode->dependsOn(leftGroup); auto rightNode = const_cast<graph::PlanNode *>(bNode->right()); auto rightGroup = convertToGroup(qctx, rightNode, visited); - groupExpr->dependsOn(rightGroup); + groupNode->dependsOn(rightGroup); break; } default: { diff --git a/src/optimizer/Optimizer.h b/src/optimizer/Optimizer.h index c250106305c3a907cc53421828ff97dd7b8a4cde..176a7d86bedf80ba0d8bc75ed411c7f2e01a323f 100644 --- a/src/optimizer/Optimizer.h +++ b/src/optimizer/Optimizer.h @@ -20,7 +20,7 @@ class QueryContext; namespace opt { class OptGroup; -class OptGroupExpr; +class OptGroupNode; class RuleSet; class Optimizer final { diff --git a/src/optimizer/rule/IndexScanRule.cpp b/src/optimizer/rule/IndexScanRule.cpp index 136a883e21f70cb5c8db0c94a0e7d5fa7467c6d2..cf250255dcc6d48e38489c8d8534b96afa54dc10 100644 --- a/src/optimizer/rule/IndexScanRule.cpp +++ b/src/optimizer/rule/IndexScanRule.cpp @@ -14,6 +14,7 @@ using nebula::graph::IndexScan; namespace nebula { namespace opt { + std::unique_ptr<OptRule> IndexScanRule::kInstance = std::unique_ptr<IndexScanRule>(new IndexScanRule()); @@ -28,29 +29,27 @@ const Pattern& IndexScanRule::pattern() const { StatusOr<OptRule::TransformResult> IndexScanRule::transform(graph::QueryContext* qctx, const MatchedResult& matched) const { - auto groupExpr = matched.node; - auto filter = filterExpr(groupExpr); + auto groupNode = matched.node; + auto filter = filterExpr(groupNode); if (filter == nullptr) { return Status::SemanticError("WHERE clause error"); } FilterItems items; ScanKind kind; - auto ret = analyzeExpression(filter.get(), &items, &kind, isEdge(groupExpr)); - NG_RETURN_IF_ERROR(ret); + NG_RETURN_IF_ERROR(analyzeExpression(filter.get(), &items, &kind, isEdge(groupNode))); IndexQueryCtx iqctx = std::make_unique<std::vector<IndexQueryContext>>(); - ret = createIndexQueryCtx(iqctx, kind, items, qctx, groupExpr); - NG_RETURN_IF_ERROR(ret); + NG_RETURN_IF_ERROR(createIndexQueryCtx(iqctx, kind, items, qctx, groupNode)); - auto newIN = static_cast<const IndexScan*>(groupExpr->node())->clone(qctx); + auto newIN = static_cast<const IndexScan*>(groupNode->node())->clone(qctx); newIN->setIndexQueryContext(std::move(iqctx)); - auto newGroupExpr = OptGroupExpr::create(qctx, newIN, groupExpr->group()); - if (groupExpr->dependencies().size() != 1) { + auto newGroupNode = OptGroupNode::create(qctx, newIN, groupNode->group()); + if (groupNode->dependencies().size() != 1) { return Status::Error("Plan node dependencies error"); } - newGroupExpr->dependsOn(groupExpr->dependencies()[0]); + newGroupNode->dependsOn(groupNode->dependencies()[0]); TransformResult result; - result.newGroupExprs.emplace_back(newGroupExpr); + result.newGroupNodes.emplace_back(newGroupNode); result.eraseAll = true; return result; } @@ -63,17 +62,17 @@ Status IndexScanRule::createIndexQueryCtx(IndexQueryCtx &iqctx, ScanKind kind, const FilterItems& items, graph::QueryContext *qctx, - const OptGroupExpr *groupExpr) const { + const OptGroupNode *groupNode) const { return kind.isLogicalAnd() - ? createIQCWithLogicAnd(iqctx, items, qctx, groupExpr) - : createIQCWithLogicOR(iqctx, items, qctx, groupExpr); + ? createIQCWithLogicAnd(iqctx, items, qctx, groupNode) + : createIQCWithLogicOR(iqctx, items, qctx, groupNode); } Status IndexScanRule::createIQCWithLogicAnd(IndexQueryCtx &iqctx, const FilterItems& items, graph::QueryContext *qctx, - const OptGroupExpr *groupExpr) const { - auto index = findOptimalIndex(qctx, groupExpr, items); + const OptGroupNode *groupNode) const { + auto index = findOptimalIndex(qctx, groupNode, items); if (index == nullptr) { return Status::IndexNotFound("No valid index found"); } @@ -84,9 +83,9 @@ Status IndexScanRule::createIQCWithLogicAnd(IndexQueryCtx &iqctx, Status IndexScanRule::createIQCWithLogicOR(IndexQueryCtx &iqctx, const FilterItems& items, graph::QueryContext *qctx, - const OptGroupExpr *groupExpr) const { + const OptGroupNode *groupNode) const { for (auto const& item : items.items) { - auto index = findOptimalIndex(qctx, groupExpr, FilterItems({item})); + auto index = findOptimalIndex(qctx, groupNode, FilterItems({item})); if (index == nullptr) { return Status::IndexNotFound("No valid index found"); } @@ -121,8 +120,7 @@ Status IndexScanRule::appendIQCtx(const IndexItem& index, if (it != filterItems.items.end()) { break; } - auto ret = appendColHint(hints, filterItems, field); - NG_RETURN_IF_ERROR(ret); + NG_RETURN_IF_ERROR(appendColHint(hints, filterItems, field)); } ctx.set_index_id(index->get_index_id()); // TODO (sky) : rewrite expr and set filter @@ -156,8 +154,7 @@ Status IndexScanRule::appendColHint(std::vector<IndexColumnHint>& hints, begin = item.value_; break; } - auto ret = boundValue(item, col, begin, end); - NG_RETURN_IF_ERROR(ret); + NG_RETURN_IF_ERROR(boundValue(item, col, begin, end)); } if (isRangeScan) { @@ -238,24 +235,24 @@ Status IndexScanRule::boundValue(const FilterItem& item, return Status::OK(); } -bool IndexScanRule::isEdge(const OptGroupExpr *groupExpr) const { - auto in = static_cast<const IndexScan *>(groupExpr->node()); +bool IndexScanRule::isEdge(const OptGroupNode *groupNode) const { + auto in = static_cast<const IndexScan *>(groupNode->node()); return in->isEdge(); } -int32_t IndexScanRule::schemaId(const OptGroupExpr *groupExpr) const { - auto in = static_cast<const IndexScan *>(groupExpr->node()); +int32_t IndexScanRule::schemaId(const OptGroupNode *groupNode) const { + auto in = static_cast<const IndexScan *>(groupNode->node()); return in->schemaId(); } -GraphSpaceID IndexScanRule::spaceId(const OptGroupExpr *groupExpr) const { - auto in = static_cast<const IndexScan *>(groupExpr->node()); +GraphSpaceID IndexScanRule::spaceId(const OptGroupNode *groupNode) const { + auto in = static_cast<const IndexScan *>(groupNode->node()); return in->space(); } std::unique_ptr<Expression> -IndexScanRule::filterExpr(const OptGroupExpr *groupExpr) const { - auto in = static_cast<const IndexScan *>(groupExpr->node()); +IndexScanRule::filterExpr(const OptGroupNode *groupNode) const { + auto in = static_cast<const IndexScan *>(groupNode->node()); auto qct = in->queryContext(); // The initial IndexScan plan node has only one queryContext. // TODO(yee): Move this condition to match interface @@ -292,10 +289,8 @@ Status IndexScanRule::analyzeExpression(Expression* expr, Expression::encode(*expr).c_str()); return Status::NotSupported(errorMsg); } - auto ret = analyzeExpression(lExpr->left(), items, kind, isEdge); - NG_RETURN_IF_ERROR(ret); - ret = analyzeExpression(lExpr->right(), items, kind, isEdge); - NG_RETURN_IF_ERROR(ret); + NG_RETURN_IF_ERROR(analyzeExpression(lExpr->left(), items, kind, isEdge)); + NG_RETURN_IF_ERROR(analyzeExpression(lExpr->right(), items, kind, isEdge)); break; } case Expression::Kind::kRelLE: @@ -365,11 +360,11 @@ Expression::Kind IndexScanRule::reverseRelationalExprKind(Expression::Kind kind) } IndexItem IndexScanRule::findOptimalIndex(graph::QueryContext *qctx, - const OptGroupExpr *groupExpr, + const OptGroupNode *groupNode, const FilterItems& items) const { // The rule of priority is '==' --> '< > <= >=' --> '!=' // Step 1 : find out all valid indexes for where condition. - auto validIndexes = findValidIndex(qctx, groupExpr, items); + auto validIndexes = findValidIndex(qctx, groupNode, items); if (validIndexes.empty()) { LOG(ERROR) << "No valid index found"; return nullptr; @@ -389,10 +384,10 @@ IndexItem IndexScanRule::findOptimalIndex(graph::QueryContext *qctx, std::vector<IndexItem> IndexScanRule::allIndexesBySchema(graph::QueryContext *qctx, - const OptGroupExpr *groupExpr) const { - auto ret = isEdge(groupExpr) - ? qctx->getMetaClient()->getEdgeIndexesFromCache(spaceId(groupExpr)) - : qctx->getMetaClient()->getTagIndexesFromCache(spaceId(groupExpr)); + const OptGroupNode *groupNode) const { + auto ret = isEdge(groupNode) + ? qctx->getMetaClient()->getEdgeIndexesFromCache(spaceId(groupNode)) + : qctx->getMetaClient()->getTagIndexesFromCache(spaceId(groupNode)); if (!ret.ok()) { LOG(ERROR) << "No index was found"; return {}; @@ -400,10 +395,10 @@ IndexScanRule::allIndexesBySchema(graph::QueryContext *qctx, std::vector<IndexItem> indexes; for (auto& index : ret.value()) { // TODO (sky) : ignore rebuilding indexes - auto id = isEdge(groupExpr) + auto id = isEdge(groupNode) ? index->get_schema_id().get_edge_type() : index->get_schema_id().get_tag_id(); - if (id == schemaId(groupExpr)) { + if (id == schemaId(groupNode)) { indexes.emplace_back(index); } } @@ -416,9 +411,9 @@ IndexScanRule::allIndexesBySchema(graph::QueryContext *qctx, std::vector<IndexItem> IndexScanRule::findValidIndex(graph::QueryContext *qctx, - const OptGroupExpr *groupExpr, + const OptGroupNode *groupNode, const FilterItems& items) const { - auto indexes = allIndexesBySchema(qctx, groupExpr); + auto indexes = allIndexesBySchema(qctx, groupNode); if (indexes.empty()) { return indexes; } diff --git a/src/optimizer/rule/IndexScanRule.h b/src/optimizer/rule/IndexScanRule.h index a492342561acb07cacb1ea1cad41143037151a38..8ba09e34ac5521719a5cac76fadcf3140b539934 100644 --- a/src/optimizer/rule/IndexScanRule.h +++ b/src/optimizer/rule/IndexScanRule.h @@ -105,17 +105,17 @@ private: ScanKind kind, const FilterItems& items, graph::QueryContext *qctx, - const OptGroupExpr *groupExpr) const; + const OptGroupNode *groupNode) const; Status createIQCWithLogicAnd(IndexQueryCtx &iqctx, const FilterItems& items, graph::QueryContext *qctx, - const OptGroupExpr *groupExpr) const; + const OptGroupNode *groupNode) const; Status createIQCWithLogicOR(IndexQueryCtx &iqctx, const FilterItems& items, graph::QueryContext *qctx, - const OptGroupExpr *groupExpr) const; + const OptGroupNode *groupNode) const; Status appendIQCtx(const IndexItem& index, const FilterItems& items, @@ -129,13 +129,13 @@ private: const meta::cpp2::ColumnDef& col, Value& begin, Value& end) const; - bool isEdge(const OptGroupExpr *groupExpr) const; + bool isEdge(const OptGroupNode *groupNode) const; - int32_t schemaId(const OptGroupExpr *groupExpr) const; + int32_t schemaId(const OptGroupNode *groupNode) const; - GraphSpaceID spaceId(const OptGroupExpr *groupExpr) const; + GraphSpaceID spaceId(const OptGroupNode *groupNode) const; - std::unique_ptr<Expression> filterExpr(const OptGroupExpr *groupExpr) const; + std::unique_ptr<Expression> filterExpr(const OptGroupNode *groupNode) const; Status analyzeExpression(Expression* expr, FilterItems* items, ScanKind* kind, bool isEdge) const; @@ -148,14 +148,14 @@ private: Expression::Kind reverseRelationalExprKind(Expression::Kind kind) const; IndexItem findOptimalIndex(graph::QueryContext *qctx, - const OptGroupExpr *groupExpr, + const OptGroupNode *groupNode, const FilterItems& items) const; std::vector<IndexItem> - allIndexesBySchema(graph::QueryContext *qctx, const OptGroupExpr *groupExpr) const; + allIndexesBySchema(graph::QueryContext *qctx, const OptGroupNode *groupNode) const; std::vector<IndexItem> findValidIndex(graph::QueryContext *qctx, - const OptGroupExpr *groupExpr, + const OptGroupNode *groupNode, const FilterItems& items) const; std::vector<IndexItem> findIndexForEqualScan(const std::vector<IndexItem>& indexes, diff --git a/src/optimizer/rule/LimitPushDownRule.cpp b/src/optimizer/rule/LimitPushDownRule.cpp index e32859223ec6522f72e4d09431f23e9950e0b1f6..dadeae08fa1d7ee84fd0bad920ab921aa11f117a 100644 --- a/src/optimizer/rule/LimitPushDownRule.cpp +++ b/src/optimizer/rule/LimitPushDownRule.cpp @@ -44,13 +44,13 @@ const Pattern &LimitPushDownRule::pattern() const { StatusOr<OptRule::TransformResult> LimitPushDownRule::transform( QueryContext *qctx, const MatchedResult &matched) const { - auto limitExpr = matched.node; - auto projExpr = matched.dependencies.front().node; - auto gnExpr = matched.dependencies.front().dependencies.front().node; + auto limitGroupNode = matched.node; + auto projGroupNode = matched.dependencies.front().node; + auto gnGroupNode = matched.dependencies.front().dependencies.front().node; - const auto limit = static_cast<const Limit *>(limitExpr->node()); - const auto proj = static_cast<const Project *>(projExpr->node()); - const auto gn = static_cast<const GetNeighbors *>(gnExpr->node()); + const auto limit = static_cast<const Limit *>(limitGroupNode->node()); + const auto proj = static_cast<const Project *>(projGroupNode->node()); + const auto gn = static_cast<const GetNeighbors *>(gnGroupNode->node()); int64_t limitRows = limit->offset() + limit->count(); if (limitRows >= gn->limit()) { @@ -58,27 +58,26 @@ StatusOr<OptRule::TransformResult> LimitPushDownRule::transform( } auto newLimit = limit->clone(qctx); - auto newLimitExpr = OptGroupExpr::create(qctx, newLimit, limitExpr->group()); + auto newLimitGroupNode = OptGroupNode::create(qctx, newLimit, limitGroupNode->group()); auto newProj = proj->clone(qctx); auto newProjGroup = OptGroup::create(qctx); - auto newProjExpr = newProjGroup->makeGroupExpr(qctx, newProj); + auto newProjGroupNode = newProjGroup->makeGroupNode(qctx, newProj); auto newGn = gn->clone(qctx); newGn->setLimit(limitRows); auto newGnGroup = OptGroup::create(qctx); - auto newGnExpr = newGnGroup->makeGroupExpr(qctx, newGn); + auto newGnGroupNode = newGnGroup->makeGroupNode(qctx, newGn); - newLimitExpr->dependsOn(newProjGroup); - newProjExpr->dependsOn(newGnGroup); - for (auto dep : gnExpr->dependencies()) { - newGnExpr->dependsOn(dep); + newLimitGroupNode->dependsOn(newProjGroup); + newProjGroupNode->dependsOn(newGnGroup); + for (auto dep : gnGroupNode->dependencies()) { + newGnGroupNode->dependsOn(dep); } TransformResult result; result.eraseAll = true; - result.eraseCurr = true; - result.newGroupExprs.emplace_back(newLimitExpr); + result.newGroupNodes.emplace_back(newLimitGroupNode); return result; } diff --git a/src/optimizer/rule/PushFilterDownGetNbrsRule.cpp b/src/optimizer/rule/PushFilterDownGetNbrsRule.cpp index bb6f55298a7c28fd5cc8f51be038d87910374e41..8218afe600dfaace63705b66a95802c8902ea17f 100644 --- a/src/optimizer/rule/PushFilterDownGetNbrsRule.cpp +++ b/src/optimizer/rule/PushFilterDownGetNbrsRule.cpp @@ -41,10 +41,10 @@ const Pattern &PushFilterDownGetNbrsRule::pattern() const { StatusOr<OptRule::TransformResult> PushFilterDownGetNbrsRule::transform( QueryContext *qctx, const MatchedResult &matched) const { - auto filterGroupExpr = matched.node; - auto gnGroupExpr = matched.dependencies.front().node; - auto filter = static_cast<const Filter *>(filterGroupExpr->node()); - auto gn = static_cast<const GetNeighbors *>(gnGroupExpr->node()); + auto filterGroupNode = matched.node; + auto gnGroupNode = matched.dependencies.front().node; + auto filter = static_cast<const Filter *>(filterGroupNode->node()); + auto gn = static_cast<const GetNeighbors *>(gnGroupNode->node()); auto condition = filter->condition()->clone(); graph::ExtractFilterExprVisitor visitor; @@ -55,12 +55,12 @@ StatusOr<OptRule::TransformResult> PushFilterDownGetNbrsRule::transform( auto pool = qctx->objPool(); auto remainedExpr = std::move(visitor).remainedExpr(); - OptGroupExpr *newFilterGroupExpr = nullptr; + OptGroupNode *newFilterGroupNode = nullptr; if (remainedExpr != nullptr) { auto newFilter = Filter::make(qctx, nullptr, pool->add(remainedExpr.release())); newFilter->setOutputVar(filter->outputVar()); newFilter->setInputVar(filter->inputVar()); - newFilterGroupExpr = OptGroupExpr::create(qctx, newFilter, filterGroupExpr->group()); + newFilterGroupNode = OptGroupNode::create(qctx, newFilter, filterGroupNode->group()); } auto newGNFilter = condition->encode(); @@ -74,25 +74,25 @@ StatusOr<OptRule::TransformResult> PushFilterDownGetNbrsRule::transform( auto newGN = gn->clone(qctx); newGN->setFilter(newGNFilter); - OptGroupExpr *newGnGroupExpr = nullptr; - if (newFilterGroupExpr != nullptr) { - // Filter(A&&B)->GetNeighbors(C) => Filter(A)->GetNeighbors(B&&C) + OptGroupNode *newGnGroupNode = nullptr; + if (newFilterGroupNode != nullptr) { + // Filter(A&&B)<-GetNeighbors(C) => Filter(A)<-GetNeighbors(B&&C) auto newGroup = OptGroup::create(qctx); - newGnGroupExpr = newGroup->makeGroupExpr(qctx, newGN); - newFilterGroupExpr->dependsOn(newGroup); + newGnGroupNode = newGroup->makeGroupNode(qctx, newGN); + newFilterGroupNode->dependsOn(newGroup); } else { - // Filter(A)->GetNeighbors(C) => GetNeighbors(A&&C) - newGnGroupExpr = OptGroupExpr::create(qctx, newGN, filterGroupExpr->group()); + // Filter(A)<-GetNeighbors(C) => GetNeighbors(A&&C) + newGnGroupNode = OptGroupNode::create(qctx, newGN, filterGroupNode->group()); newGN->setOutputVar(filter->outputVar()); } - for (auto dep : gnGroupExpr->dependencies()) { - newGnGroupExpr->dependsOn(dep); + for (auto dep : gnGroupNode->dependencies()) { + newGnGroupNode->dependsOn(dep); } TransformResult result; result.eraseCurr = true; - result.newGroupExprs.emplace_back(newFilterGroupExpr ? newFilterGroupExpr : newGnGroupExpr); + result.newGroupNodes.emplace_back(newFilterGroupNode ? newFilterGroupNode : newGnGroupNode); return result; } diff --git a/src/optimizer/rule/TopNRule.cpp b/src/optimizer/rule/TopNRule.cpp index 1912d0962b0fa58803c4ec199e5454e5091a0dd0..b7886b0bd958e4d28abc46477a1ac39e0f775991 100644 --- a/src/optimizer/rule/TopNRule.cpp +++ b/src/optimizer/rule/TopNRule.cpp @@ -40,10 +40,10 @@ const Pattern &TopNRule::pattern() const { StatusOr<OptRule::TransformResult> TopNRule::transform(QueryContext *qctx, const MatchedResult &matched) const { - auto limitExpr = matched.node; - auto sortExpr = matched.dependencies.front().node; - auto limit = static_cast<const Limit *>(limitExpr->node()); - auto sort = static_cast<const Sort *>(sortExpr->node()); + auto limitGroupNode = matched.node; + auto sortGroupNode = matched.dependencies.front().node; + auto limit = static_cast<const Limit *>(limitGroupNode->node()); + auto sort = static_cast<const Sort *>(sortGroupNode->node()); // Currently, we cannot know the total amount of input data, // so only apply topn rule when offset of limit is 0 @@ -55,15 +55,14 @@ StatusOr<OptRule::TransformResult> TopNRule::transform(QueryContext *qctx, topn->setOutputVar(limit->outputVar()); topn->setInputVar(sort->inputVar()); topn->setColNames(sort->colNames()); - auto topnExpr = OptGroupExpr::create(qctx, topn, limitExpr->group()); - for (auto dep : sortExpr->dependencies()) { - topnExpr->dependsOn(dep); + auto topnNode = OptGroupNode::create(qctx, topn, limitGroupNode->group()); + for (auto dep : sortGroupNode->dependencies()) { + topnNode->dependsOn(dep); } TransformResult result; - result.newGroupExprs.emplace_back(topnExpr); + result.newGroupNodes.emplace_back(topnNode); result.eraseAll = true; - result.eraseCurr = true; return result; } diff --git a/tests/query/v2/test_optimizer.py b/tests/query/v2/test_optimizer.py index 580ad093e67d373e7ecde9eebf4647f562b1a4bb..fe4da2163dd6138e07e65ec7f4fb6c921c3a439f 100644 --- a/tests/query/v2/test_optimizer.py +++ b/tests/query/v2/test_optimizer.py @@ -218,6 +218,5 @@ class TestOptimizer(NebulaTestSuite): ] # expected_data = [[1998], [2004], [2009], [2010], [2011], [2014], [2017], [2018]] self.check_exec_plan(resp, expected_plan) - if resp.data is None: - assert False, 'resp.data is None' - assert len(resp.data.rows) == 4 \ No newline at end of file + assert resp.data is not None, 'resp.data is None' + assert len(resp.data.rows) == 4