From ad8d66142045ee2d707a28015523340eec8459c8 Mon Sep 17 00:00:00 2001 From: shylock <33566796+Shylock-Hg@users.noreply.github.com> Date: Wed, 13 Apr 2022 19:40:56 +0800 Subject: [PATCH] Refactor the process of symbols in optimizer. (#4146) * Refactor the process of symbols in optimizer. * Fix variable shadowing. * Collect boundary from MatchResult directly. * Check variable in TransformResult don't referenced by outside plan nodes. Co-authored-by: Sophie <84560950+Sophie-Xie@users.noreply.github.com> --- src/graph/context/Symbols.cpp | 1 + src/graph/optimizer/OptGroup.cpp | 15 ++++++ src/graph/optimizer/OptGroup.h | 5 ++ src/graph/optimizer/OptRule.cpp | 52 +++++++++++++++++++ src/graph/optimizer/OptRule.h | 7 +++ .../optimizer/rule/CollapseProjectRule.cpp | 1 + .../optimizer/rule/GetEdgesTransformRule.cpp | 1 + src/graph/optimizer/rule/IndexScanRule.cpp | 1 + .../rule/MergeGetNbrsAndDedupRule.cpp | 1 + .../rule/MergeGetNbrsAndProjectRule.cpp | 1 + .../rule/MergeGetVerticesAndDedupRule.cpp | 1 + .../rule/MergeGetVerticesAndProjectRule.cpp | 1 + .../rule/PushFilterDownGetNbrsRule.cpp | 5 +- .../rule/PushFilterDownProjectRule.cpp | 3 ++ .../rule/PushFilterDownScanVerticesRule.cpp | 5 +- .../rule/PushLimitDownGetNeighborsRule.cpp | 2 + .../rule/PushLimitDownIndexScanRule.cpp | 2 + .../rule/PushLimitDownProjectRule.cpp | 6 +-- .../PushLimitDownScanAppendVerticesRule.cpp | 3 ++ ...shLimitDownScanEdgesAppendVerticesRule.cpp | 4 ++ .../PushStepLimitDownGetNeighborsRule.cpp | 2 + .../PushStepSampleDownGetNeighborsRule.cpp | 2 + .../rule/PushTopNDownIndexScanRule.cpp | 3 ++ .../rule/PushVFilterDownScanVerticesRule.cpp | 2 +- src/graph/planner/plan/PlanNode.cpp | 23 ++++---- src/graph/planner/plan/PlanNode.h | 20 +++---- .../AsyncMsgNotifyBasedScheduler.cpp | 1 + .../scheduler/AsyncMsgNotifyBasedScheduler.h | 2 + 28 files changed, 139 insertions(+), 33 deletions(-) diff --git a/src/graph/context/Symbols.cpp b/src/graph/context/Symbols.cpp index d80b123545e..f09bcd6d1d4 100644 --- a/src/graph/context/Symbols.cpp +++ b/src/graph/context/Symbols.cpp @@ -41,6 +41,7 @@ SymbolTable::SymbolTable(ObjectPool* objPool) { Variable* SymbolTable::newVariable(std::string name) { VLOG(1) << "New variable for: " << name; + DCHECK(vars_.find(name) == vars_.end()); auto* variable = objPool_->makeAndAdd(name); addVar(std::move(name), variable); return variable; diff --git a/src/graph/optimizer/OptGroup.cpp b/src/graph/optimizer/OptGroup.cpp index eb73f9d4472..40ebea88a53 100644 --- a/src/graph/optimizer/OptGroup.cpp +++ b/src/graph/optimizer/OptGroup.cpp @@ -44,11 +44,21 @@ OptGroup::OptGroup(OptContext *ctx) noexcept : ctx_(ctx) { void OptGroup::addGroupNode(OptGroupNode *groupNode) { DCHECK(groupNode != nullptr); DCHECK(groupNode->group() == this); + if (outputVar_.empty()) { + outputVar_ = groupNode->node()->outputVar(); + } else { + DCHECK_EQ(outputVar_, groupNode->node()->outputVar()); + } groupNodes_.emplace_back(groupNode); groupNode->node()->updateSymbols(); } OptGroupNode *OptGroup::makeGroupNode(PlanNode *node) { + if (outputVar_.empty()) { + outputVar_ = node->outputVar(); + } else { + DCHECK_EQ(outputVar_, node->outputVar()); + } groupNodes_.emplace_back(OptGroupNode::create(ctx_, node, this)); return groupNodes_.back(); } @@ -70,6 +80,7 @@ Status OptGroup::explore(const OptRule *rule) { NG_RETURN_IF_ERROR(groupNode->explore(rule)); // Find more equivalents + std::vector boundary; auto status = rule->match(ctx_, groupNode); if (!status.ok()) { ++iter; @@ -77,9 +88,13 @@ Status OptGroup::explore(const OptRule *rule) { } ctx_->setChanged(true); auto matched = std::move(status).value(); + matched.collectBoundary(boundary); auto resStatus = rule->transform(ctx_, matched); NG_RETURN_IF_ERROR(resStatus); auto result = std::move(resStatus).value(); + DLOG_IF(WARNING, !result.checkDataFlow(boundary)) + << "Plan of transfromed result should keep input variable same with dependencies in rule " + << rule->toString(); if (result.eraseAll) { for (auto gnode : groupNodes_) { gnode->node()->releaseSymbols(); diff --git a/src/graph/optimizer/OptGroup.h b/src/graph/optimizer/OptGroup.h index 7164dd6246a..04ec946a4aa 100644 --- a/src/graph/optimizer/OptGroup.h +++ b/src/graph/optimizer/OptGroup.h @@ -43,6 +43,9 @@ class OptGroup final { Status exploreUntilMaxRound(const OptRule *rule); double getCost() const; const graph::PlanNode *getPlan() const; + const std::string &outputVar() const { + return outputVar_; + } private: explicit OptGroup(OptContext *ctx) noexcept; @@ -54,6 +57,8 @@ class OptGroup final { OptContext *ctx_{nullptr}; std::list groupNodes_; std::vector exploredRules_; + // The output variable should be same across the whole group. + std::string outputVar_; }; class OptGroupNode final { diff --git a/src/graph/optimizer/OptRule.cpp b/src/graph/optimizer/OptRule.cpp index ae71eb34413..1b7eab7ecc9 100644 --- a/src/graph/optimizer/OptRule.cpp +++ b/src/graph/optimizer/OptRule.cpp @@ -31,6 +31,16 @@ const PlanNode *MatchedResult::planNode(const std::vector &pos) const { return DCHECK_NOTNULL(result->node)->node(); } +void MatchedResult::collectBoundary(std::vector &boundary) const { + if (dependencies.empty()) { + boundary.insert(boundary.end(), node->dependencies().begin(), node->dependencies().end()); + } else { + for (const auto &dep : dependencies) { + dep.collectBoundary(boundary); + } + } +} + Pattern Pattern::create(graph::PlanNode::Kind kind, std::initializer_list patterns) { return Pattern(kind, std::move(patterns)); } @@ -76,6 +86,48 @@ StatusOr Pattern::match(const OptGroup *group) const { return Status::Error(); } +bool OptRule::TransformResult::checkDataFlow(const std::vector &boundary) { + return std::all_of( + newGroupNodes.begin(), newGroupNodes.end(), [&boundary](const OptGroupNode *groupNode) { + return checkDataFlow(groupNode, boundary); + }); +} + +/*static*/ bool OptRule::TransformResult::checkDataFlow(const OptGroupNode *groupNode, + const std::vector &boundary) { + const auto &deps = groupNode->dependencies(); + // reach the boundary + if (std::all_of(deps.begin(), deps.end(), [&boundary](OptGroup *dep) { + return std::find(boundary.begin(), boundary.end(), dep) != boundary.end(); + })) { + return true; + } + const auto *group = groupNode->group(); + if (std::find(boundary.begin(), boundary.end(), group) != boundary.end()) { + return true; + } + // Check dataflow + const auto *node = groupNode->node(); + if (node->inputVars().size() == deps.size()) { + // Don't check when count of dependencies is different from count of input variables + for (std::size_t i = 0; i < deps.size(); i++) { + const OptGroup *dep = deps[i]; + if (node->inputVar(i) != dep->outputVar()) { + return false; + } + // Only use by father plan node + if (node->inputVars()[i]->readBy.size() != 1) { + return false; + } + return std::all_of( + dep->groupNodes().begin(), dep->groupNodes().end(), [&boundary](const OptGroupNode *gn) { + return checkDataFlow(gn, boundary); + }); + } + } + return true; +} + StatusOr OptRule::match(OptContext *ctx, const OptGroupNode *groupNode) const { const auto &pattern = this->pattern(); auto status = pattern.match(groupNode); diff --git a/src/graph/optimizer/OptRule.h b/src/graph/optimizer/OptRule.h index f7a429d798b..c9379499dec 100644 --- a/src/graph/optimizer/OptRule.h +++ b/src/graph/optimizer/OptRule.h @@ -40,6 +40,8 @@ struct MatchedResult { // {0, 1, 0} | this->dependencies[1].dependencies[0] // {0, 1, 0, 1} | this->dependencies[1].dependencies[0].dependencies[1] const graph::PlanNode *planNode(const std::vector &pos = {}) const; + + void collectBoundary(std::vector &boundary) const; }; // Match plan node by trait or kind of plan node. @@ -86,6 +88,11 @@ class OptRule { return kNoTrans; } + // The plan of result should keep dataflow same as dependencies + bool checkDataFlow(const std::vector &boundary); + static bool checkDataFlow(const OptGroupNode *groupNode, + const std::vector &boundary); + bool eraseCurr{false}; bool eraseAll{false}; std::vector newGroupNodes; diff --git a/src/graph/optimizer/rule/CollapseProjectRule.cpp b/src/graph/optimizer/rule/CollapseProjectRule.cpp index 39da3ef888b..726ef22c6ff 100644 --- a/src/graph/optimizer/rule/CollapseProjectRule.cpp +++ b/src/graph/optimizer/rule/CollapseProjectRule.cpp @@ -109,6 +109,7 @@ StatusOr CollapseProjectRule::transform( // 4. rebuild OptGroupNode newProj->setInputVar(projBelow->inputVar()); + newProj->setOutputVar(projAbove->outputVar()); auto* newGroupNode = OptGroupNode::create(octx, newProj, projGroup); newGroupNode->setDeps(groupNodeBelow->dependencies()); diff --git a/src/graph/optimizer/rule/GetEdgesTransformRule.cpp b/src/graph/optimizer/rule/GetEdgesTransformRule.cpp index 7d65179a641..e1182ef194f 100644 --- a/src/graph/optimizer/rule/GetEdgesTransformRule.cpp +++ b/src/graph/optimizer/rule/GetEdgesTransformRule.cpp @@ -68,6 +68,7 @@ StatusOr GetEdgesTransformRule::transform( auto newAppendVertices = appendVertices->clone(); auto colSize = appendVertices->colNames().size(); + newAppendVertices->setOutputVar(appendVertices->outputVar()); newAppendVertices->setColNames( {appendVertices->colNames()[colSize - 2], appendVertices->colNames()[colSize - 1]}); auto newAppendVerticesGroupNode = diff --git a/src/graph/optimizer/rule/IndexScanRule.cpp b/src/graph/optimizer/rule/IndexScanRule.cpp index ffabf7e51e1..add9a7a76cd 100644 --- a/src/graph/optimizer/rule/IndexScanRule.cpp +++ b/src/graph/optimizer/rule/IndexScanRule.cpp @@ -81,6 +81,7 @@ StatusOr IndexScanRule::transform(OptContext* ctx, const auto* oldIN = groupNode->node(); DCHECK_EQ(oldIN->kind(), graph::PlanNode::Kind::kIndexScan); auto* newIN = static_cast(oldIN->clone()); + newIN->setOutputVar(oldIN->outputVar()); newIN->setIndexQueryContext(std::move(iqctx)); auto newGroupNode = OptGroupNode::create(ctx, newIN, groupNode->group()); if (groupNode->dependencies().size() != 1) { diff --git a/src/graph/optimizer/rule/MergeGetNbrsAndDedupRule.cpp b/src/graph/optimizer/rule/MergeGetNbrsAndDedupRule.cpp index 4549367a440..2168c16ab87 100644 --- a/src/graph/optimizer/rule/MergeGetNbrsAndDedupRule.cpp +++ b/src/graph/optimizer/rule/MergeGetNbrsAndDedupRule.cpp @@ -44,6 +44,7 @@ StatusOr MergeGetNbrsAndDedupRule::transform( newGN->setDedup(); } newGN->setInputVar(dedup->inputVar()); + newGN->setOutputVar(gn->outputVar()); auto newOptGV = OptGroupNode::create(octx, newGN, optGN->group()); for (auto dep : optDedup->dependencies()) { newOptGV->dependsOn(dep); diff --git a/src/graph/optimizer/rule/MergeGetNbrsAndProjectRule.cpp b/src/graph/optimizer/rule/MergeGetNbrsAndProjectRule.cpp index f2d6732773f..352c6b4a1d5 100644 --- a/src/graph/optimizer/rule/MergeGetNbrsAndProjectRule.cpp +++ b/src/graph/optimizer/rule/MergeGetNbrsAndProjectRule.cpp @@ -66,6 +66,7 @@ StatusOr MergeGetNbrsAndProjectRule::transform( auto srcExpr = column->expr()->clone(); newGN->setSrc(srcExpr); newGN->setInputVar(project->inputVar()); + newGN->setOutputVar(gn->outputVar()); auto newOptGV = OptGroupNode::create(ctx, newGN, optGN->group()); for (auto dep : optProj->dependencies()) { newOptGV->dependsOn(dep); diff --git a/src/graph/optimizer/rule/MergeGetVerticesAndDedupRule.cpp b/src/graph/optimizer/rule/MergeGetVerticesAndDedupRule.cpp index bbbc2ce4d47..ccf6f0da8e2 100644 --- a/src/graph/optimizer/rule/MergeGetVerticesAndDedupRule.cpp +++ b/src/graph/optimizer/rule/MergeGetVerticesAndDedupRule.cpp @@ -43,6 +43,7 @@ StatusOr MergeGetVerticesAndDedupRule::transform( newGV->setDedup(); } newGV->setInputVar(dedup->inputVar()); + newGV->setOutputVar(gv->outputVar()); auto newOptGV = OptGroupNode::create(ctx, newGV, optGV->group()); for (auto dep : optDedup->dependencies()) { newOptGV->dependsOn(dep); diff --git a/src/graph/optimizer/rule/MergeGetVerticesAndProjectRule.cpp b/src/graph/optimizer/rule/MergeGetVerticesAndProjectRule.cpp index 132065a0db0..07d4fb7e350 100644 --- a/src/graph/optimizer/rule/MergeGetVerticesAndProjectRule.cpp +++ b/src/graph/optimizer/rule/MergeGetVerticesAndProjectRule.cpp @@ -65,6 +65,7 @@ StatusOr MergeGetVerticesAndProjectRule::transform( auto srcExpr = column->expr()->clone(); newGV->setSrc(srcExpr); newGV->setInputVar(project->inputVar()); + newGV->setOutputVar(gv->outputVar()); auto newOptGV = OptGroupNode::create(ctx, newGV, optGV->group()); for (auto dep : optProj->dependencies()) { newOptGV->dependsOn(dep); diff --git a/src/graph/optimizer/rule/PushFilterDownGetNbrsRule.cpp b/src/graph/optimizer/rule/PushFilterDownGetNbrsRule.cpp index 7da272caf8b..c1580855408 100644 --- a/src/graph/optimizer/rule/PushFilterDownGetNbrsRule.cpp +++ b/src/graph/optimizer/rule/PushFilterDownGetNbrsRule.cpp @@ -63,10 +63,10 @@ StatusOr PushFilterDownGetNbrsRule::transform( auto remainedExpr = std::move(visitor).remainedExpr(); OptGroupNode *newFilterGroupNode = nullptr; + PlanNode *newFilter = nullptr; if (remainedExpr != nullptr) { - auto newFilter = Filter::make(qctx, nullptr, remainedExpr); + newFilter = Filter::make(qctx, nullptr, remainedExpr); newFilter->setOutputVar(filter->outputVar()); - newFilter->setInputVar(filter->inputVar()); newFilterGroupNode = OptGroupNode::create(ctx, newFilter, filterGroupNode->group()); } @@ -84,6 +84,7 @@ StatusOr PushFilterDownGetNbrsRule::transform( // Filter(A&&B)<-GetNeighbors(C) => Filter(A)<-GetNeighbors(B&&C) auto newGroup = OptGroup::create(ctx); newGnGroupNode = newGroup->makeGroupNode(newGN); + newFilter->setInputVar(newGN->outputVar()); newFilterGroupNode->dependsOn(newGroup); } else { // Filter(A)<-GetNeighbors(C) => GetNeighbors(A&&C) diff --git a/src/graph/optimizer/rule/PushFilterDownProjectRule.cpp b/src/graph/optimizer/rule/PushFilterDownProjectRule.cpp index 770883016ea..69ea357e248 100644 --- a/src/graph/optimizer/rule/PushFilterDownProjectRule.cpp +++ b/src/graph/optimizer/rule/PushFilterDownProjectRule.cpp @@ -132,12 +132,15 @@ StatusOr PushFilterDownProjectRule::transform( auto newProjGroup = OptGroup::create(octx); auto newProjGroupNode = newProjGroup->makeGroupNode(newProjNode); newProjGroupNode->setDeps({newBelowFilterGroup}); + newProjNode->setInputVar(newBelowFilterNode->outputVar()); newAboveFilterGroupNode->setDeps({newProjGroup}); + newAboveFilterNode->setInputVar(newProjNode->outputVar()); result.newGroupNodes.emplace_back(newAboveFilterGroupNode); } else { newProjNode->setOutputVar(oldFilterNode->outputVar()); auto newProjGroupNode = OptGroupNode::create(octx, newProjNode, filterGroupNode->group()); newProjGroupNode->setDeps({newBelowFilterGroup}); + newProjNode->setInputVar(newBelowFilterNode->outputVar()); result.newGroupNodes.emplace_back(newProjGroupNode); } diff --git a/src/graph/optimizer/rule/PushFilterDownScanVerticesRule.cpp b/src/graph/optimizer/rule/PushFilterDownScanVerticesRule.cpp index 6bc600c9440..cd6aca4ec07 100644 --- a/src/graph/optimizer/rule/PushFilterDownScanVerticesRule.cpp +++ b/src/graph/optimizer/rule/PushFilterDownScanVerticesRule.cpp @@ -53,8 +53,9 @@ StatusOr PushFilterDownScanVerticesRule::transform( auto remainedExpr = std::move(visitor).remainedExpr(); OptGroupNode *newFilterGroupNode = nullptr; + PlanNode *newFilter = nullptr; if (remainedExpr != nullptr) { - auto newFilter = Filter::make(qctx, nullptr, remainedExpr); + newFilter = Filter::make(qctx, nullptr, remainedExpr); newFilter->setOutputVar(filter->outputVar()); newFilter->setInputVar(filter->inputVar()); newFilterGroupNode = OptGroupNode::create(ctx, newFilter, filterGroupNode->group()); @@ -72,8 +73,10 @@ StatusOr PushFilterDownScanVerticesRule::transform( OptGroupNode *newSvGroupNode = nullptr; if (newFilterGroupNode != nullptr) { // Filter(A&&B)<-ScanVertices(C) => Filter(A)<-ScanVertices(B&&C) + // newSV->regenerateOutputVar(); auto newGroup = OptGroup::create(ctx); newSvGroupNode = newGroup->makeGroupNode(newSV); + newFilter->setInputVar(newSV->outputVar()); newFilterGroupNode->dependsOn(newGroup); } else { // Filter(A)<-ScanVertices(C) => ScanVertices(A&&C) diff --git a/src/graph/optimizer/rule/PushLimitDownGetNeighborsRule.cpp b/src/graph/optimizer/rule/PushLimitDownGetNeighborsRule.cpp index 0b3fba2244f..707acae093f 100644 --- a/src/graph/optimizer/rule/PushLimitDownGetNeighborsRule.cpp +++ b/src/graph/optimizer/rule/PushLimitDownGetNeighborsRule.cpp @@ -50,6 +50,7 @@ StatusOr PushLimitDownGetNeighborsRule::transform( } auto newLimit = static_cast(limit->clone()); + newLimit->setOutputVar(limit->outputVar()); auto newLimitGroupNode = OptGroupNode::create(octx, newLimit, limitGroupNode->group()); auto newGn = static_cast(gn->clone()); @@ -58,6 +59,7 @@ StatusOr PushLimitDownGetNeighborsRule::transform( auto newGnGroupNode = newGnGroup->makeGroupNode(newGn); newLimitGroupNode->dependsOn(newGnGroup); + newLimit->setInputVar(newGn->outputVar()); for (auto dep : gnGroupNode->dependencies()) { newGnGroupNode->dependsOn(dep); } diff --git a/src/graph/optimizer/rule/PushLimitDownIndexScanRule.cpp b/src/graph/optimizer/rule/PushLimitDownIndexScanRule.cpp index dda53f79835..8035694b221 100644 --- a/src/graph/optimizer/rule/PushLimitDownIndexScanRule.cpp +++ b/src/graph/optimizer/rule/PushLimitDownIndexScanRule.cpp @@ -58,6 +58,7 @@ StatusOr PushLimitDownIndexScanRule::transform( } auto newLimit = static_cast(limit->clone()); + newLimit->setOutputVar(limit->outputVar()); auto newLimitGroupNode = OptGroupNode::create(octx, newLimit, limitGroupNode->group()); auto newIndexScan = static_cast(indexScan->clone()); @@ -66,6 +67,7 @@ StatusOr PushLimitDownIndexScanRule::transform( auto newIndexScanGroupNode = newIndexScanGroup->makeGroupNode(newIndexScan); newLimitGroupNode->dependsOn(newIndexScanGroup); + newLimit->setInputVar(newIndexScan->outputVar()); for (auto dep : indexScanGroupNode->dependencies()) { newIndexScanGroupNode->dependsOn(dep); } diff --git a/src/graph/optimizer/rule/PushLimitDownProjectRule.cpp b/src/graph/optimizer/rule/PushLimitDownProjectRule.cpp index 2805e215ee6..550896060a9 100644 --- a/src/graph/optimizer/rule/PushLimitDownProjectRule.cpp +++ b/src/graph/optimizer/rule/PushLimitDownProjectRule.cpp @@ -42,18 +42,18 @@ StatusOr PushLimitDownProjectRule::transform( auto newLimit = static_cast(limit->clone()); auto newLimitGroup = OptGroup::create(octx); - auto newLimitGroupNode = newLimitGroup->makeGroupNode(newLimit); auto projInputVar = proj->inputVar(); - newLimit->setOutputVar(proj->outputVar()); + // newLimit->regenerateOutputVar(); newLimit->setInputVar(projInputVar); auto *varPtr = octx->qctx()->symTable()->getVar(projInputVar); DCHECK(!!varPtr); newLimit->setColNames(varPtr->colNames); + auto newLimitGroupNode = newLimitGroup->makeGroupNode(newLimit); auto newProj = static_cast(proj->clone()); - auto newProjGroupNode = OptGroupNode::create(octx, newProj, limitGroupNode->group()); newProj->setOutputVar(limit->outputVar()); newProj->setInputVar(newLimit->outputVar()); + auto newProjGroupNode = OptGroupNode::create(octx, newProj, limitGroupNode->group()); newProjGroupNode->dependsOn(const_cast(newLimitGroupNode->group())); for (auto dep : projGroupNode->dependencies()) { diff --git a/src/graph/optimizer/rule/PushLimitDownScanAppendVerticesRule.cpp b/src/graph/optimizer/rule/PushLimitDownScanAppendVerticesRule.cpp index 26c4d0d1440..1969c571035 100644 --- a/src/graph/optimizer/rule/PushLimitDownScanAppendVerticesRule.cpp +++ b/src/graph/optimizer/rule/PushLimitDownScanAppendVerticesRule.cpp @@ -73,6 +73,7 @@ StatusOr PushLimitDownScanAppendVerticesRule::transfor } auto newLimit = static_cast(limit->clone()); + newLimit->setOutputVar(limit->outputVar()); auto newLimitGroupNode = OptGroupNode::create(octx, newLimit, limitGroupNode->group()); auto newAppendVertices = static_cast(appendVertices->clone()); @@ -85,7 +86,9 @@ StatusOr PushLimitDownScanAppendVerticesRule::transfor auto newScanVerticesGroupNode = newScanVerticesGroup->makeGroupNode(newScanVertices); newLimitGroupNode->dependsOn(newAppendVerticesGroup); + newLimit->setInputVar(newAppendVertices->outputVar()); newAppendVerticesGroupNode->dependsOn(newScanVerticesGroup); + newAppendVertices->setInputVar(newScanVertices->outputVar()); for (auto dep : scanVerticesGroupNode->dependencies()) { newScanVerticesGroupNode->dependsOn(dep); } diff --git a/src/graph/optimizer/rule/PushLimitDownScanEdgesAppendVerticesRule.cpp b/src/graph/optimizer/rule/PushLimitDownScanEdgesAppendVerticesRule.cpp index 4f249ab001d..4934be86a5b 100644 --- a/src/graph/optimizer/rule/PushLimitDownScanEdgesAppendVerticesRule.cpp +++ b/src/graph/optimizer/rule/PushLimitDownScanEdgesAppendVerticesRule.cpp @@ -77,6 +77,7 @@ StatusOr PushLimitDownScanEdgesAppendVerticesRule::tra } auto newLimit = static_cast(limit->clone()); + newLimit->setOutputVar(limit->outputVar()); auto newLimitGroupNode = OptGroupNode::create(octx, newLimit, limitGroupNode->group()); auto newAppendVertices = static_cast(appendVertices->clone()); @@ -93,8 +94,11 @@ StatusOr PushLimitDownScanEdgesAppendVerticesRule::tra auto newScanEdgesGroupNode = newScanEdgesGroup->makeGroupNode(newScanEdges); newLimitGroupNode->dependsOn(newAppendVerticesGroup); + newLimit->setInputVar(newAppendVertices->outputVar()); newAppendVerticesGroupNode->dependsOn(newProjGroup); + newAppendVertices->setInputVar(newProj->outputVar()); newProjGroupNode->dependsOn(newScanEdgesGroup); + newProj->setInputVar(newScanEdges->outputVar()); for (auto dep : scanEdgesGroupNode->dependencies()) { newScanEdgesGroupNode->dependsOn(dep); } diff --git a/src/graph/optimizer/rule/PushStepLimitDownGetNeighborsRule.cpp b/src/graph/optimizer/rule/PushStepLimitDownGetNeighborsRule.cpp index 9fd4d486eae..369b5430bd9 100644 --- a/src/graph/optimizer/rule/PushStepLimitDownGetNeighborsRule.cpp +++ b/src/graph/optimizer/rule/PushStepLimitDownGetNeighborsRule.cpp @@ -51,6 +51,7 @@ StatusOr PushStepLimitDownGetNeighborsRule::transform( } auto newLimit = static_cast(limit->clone()); + newLimit->setOutputVar(limit->outputVar()); auto newLimitGroupNode = OptGroupNode::create(octx, newLimit, limitGroupNode->group()); auto newGn = static_cast(gn->clone()); @@ -59,6 +60,7 @@ StatusOr PushStepLimitDownGetNeighborsRule::transform( auto newGnGroupNode = newGnGroup->makeGroupNode(newGn); newLimitGroupNode->dependsOn(newGnGroup); + newLimit->setInputVar(newGn->outputVar()); for (auto dep : gnGroupNode->dependencies()) { newGnGroupNode->dependsOn(dep); } diff --git a/src/graph/optimizer/rule/PushStepSampleDownGetNeighborsRule.cpp b/src/graph/optimizer/rule/PushStepSampleDownGetNeighborsRule.cpp index bc271ff09ac..cacd4a0be5e 100644 --- a/src/graph/optimizer/rule/PushStepSampleDownGetNeighborsRule.cpp +++ b/src/graph/optimizer/rule/PushStepSampleDownGetNeighborsRule.cpp @@ -49,6 +49,7 @@ StatusOr PushStepSampleDownGetNeighborsRule::transform } auto newSample = static_cast(sample->clone()); + newSample->setOutputVar(sample->outputVar()); auto newSampleGroupNode = OptGroupNode::create(octx, newSample, sampleGroupNode->group()); auto newGn = static_cast(gn->clone()); @@ -58,6 +59,7 @@ StatusOr PushStepSampleDownGetNeighborsRule::transform auto newGnGroupNode = newGnGroup->makeGroupNode(newGn); newSampleGroupNode->dependsOn(newGnGroup); + newSample->setInputVar(newGn->outputVar()); for (auto dep : gnGroupNode->dependencies()) { newGnGroupNode->dependsOn(dep); } diff --git a/src/graph/optimizer/rule/PushTopNDownIndexScanRule.cpp b/src/graph/optimizer/rule/PushTopNDownIndexScanRule.cpp index 8320d7e5013..840e6172ed3 100644 --- a/src/graph/optimizer/rule/PushTopNDownIndexScanRule.cpp +++ b/src/graph/optimizer/rule/PushTopNDownIndexScanRule.cpp @@ -92,6 +92,7 @@ StatusOr PushTopNDownIndexScanRule::transform( } auto newTopN = static_cast(topN->clone()); + newTopN->setOutputVar(topN->outputVar()); auto newtopNGroupNode = OptGroupNode::create(octx, newTopN, topNGroupNode->group()); auto newProject = static_cast(project->clone()); @@ -105,7 +106,9 @@ StatusOr PushTopNDownIndexScanRule::transform( auto newIndexScanGroupNode = newIndexScanGroup->makeGroupNode(newIndexScan); newtopNGroupNode->dependsOn(newProjectGroup); + newTopN->setInputVar(newProject->outputVar()); newProjectGroupNode->dependsOn(newIndexScanGroup); + newProject->setInputVar(newIndexScan->outputVar()); for (auto dep : indexScanGroupNode->dependencies()) { newIndexScanGroupNode->dependsOn(dep); } diff --git a/src/graph/optimizer/rule/PushVFilterDownScanVerticesRule.cpp b/src/graph/optimizer/rule/PushVFilterDownScanVerticesRule.cpp index c335bc38238..f8adf045135 100644 --- a/src/graph/optimizer/rule/PushVFilterDownScanVerticesRule.cpp +++ b/src/graph/optimizer/rule/PushVFilterDownScanVerticesRule.cpp @@ -91,7 +91,6 @@ StatusOr PushVFilterDownScanVerticesRule::transform( auto newAppendVertices = appendVertices->clone(); newAppendVertices->setVertexFilter(remainedExpr); newAppendVertices->setOutputVar(appendVertices->outputVar()); - newAppendVertices->setInputVar(appendVertices->inputVar()); newAppendVerticesGroupNode = OptGroupNode::create(ctx, newAppendVertices, appendVerticesGroupNode->group()); @@ -107,6 +106,7 @@ StatusOr PushVFilterDownScanVerticesRule::transform( auto newGroup = OptGroup::create(ctx); auto newSvGroupNode = newGroup->makeGroupNode(newSV); newAppendVerticesGroupNode->dependsOn(newGroup); + newAppendVertices->setInputVar(newSV->outputVar()); for (auto dep : svGroupNode->dependencies()) { newSvGroupNode->dependsOn(dep); diff --git a/src/graph/planner/plan/PlanNode.cpp b/src/graph/planner/plan/PlanNode.cpp index f39847295d1..7fcadd038b7 100644 --- a/src/graph/planner/plan/PlanNode.cpp +++ b/src/graph/planner/plan/PlanNode.cpp @@ -25,7 +25,7 @@ PlanNode::PlanNode(QueryContext* qctx, Kind kind) : qctx_(qctx), kind_(kind) { auto varName = folly::stringPrintf("__%s_%ld", toString(kind_), id_); auto* variable = qctx_->symTable()->newVariable(varName); VLOG(1) << "New variable: " << varName; - outputVars_.emplace_back(variable); + outputVar_ = variable; qctx_->symTable()->writtenBy(varName, this); } @@ -330,11 +330,10 @@ void PlanNode::calcCost() { } void PlanNode::setOutputVar(const std::string& var) { - DCHECK_EQ(1, outputVars_.size()); auto* outputVarPtr = qctx_->symTable()->getVar(var); DCHECK(outputVarPtr != nullptr); - auto oldVar = outputVars_[0]->name; - outputVars_[0] = outputVarPtr; + auto oldVar = outputVar_->name; + outputVar_ = outputVarPtr; qctx_->symTable()->updateWrittenBy(oldVar, var, this); } @@ -355,7 +354,7 @@ std::unique_ptr PlanNode::explain() const { auto desc = std::make_unique(); desc->id = id_; desc->name = toString(kind_); - desc->outputVar = folly::toJson(util::toJson(outputVars_)); + desc->outputVar = folly::toJson(util::toJson(outputVar_)); return desc; } @@ -368,17 +367,13 @@ void PlanNode::releaseSymbols() { for (auto in : inputVars_) { in && symTbl->deleteReadBy(in->name, this); } - for (auto out : outputVars_) { - out && symTbl->deleteWrittenBy(out->name, this); - } + outputVar_ && symTbl->deleteWrittenBy(outputVar_->name, this); } void PlanNode::updateSymbols() { auto symTbl = qctx_->symTable(); - for (auto out : outputVars_) { - if (out != nullptr) { - symTbl->updateWrittenBy(out->name, out->name, this); - } + if (outputVar_ != nullptr) { + symTbl->updateWrittenBy(outputVar_->name, outputVar_->name, this); } } @@ -440,8 +435,8 @@ std::unique_ptr VariableDependencyNode::explain() const { } void PlanNode::setColNames(std::vector cols) { - qctx_->symTable()->setAliasGeneratedBy(cols, outputVarPtr(0)->name); - outputVarPtr(0)->colNames = std::move(cols); + qctx_->symTable()->setAliasGeneratedBy(cols, outputVarPtr()->name); + outputVarPtr()->colNames = std::move(cols); } } // namespace graph } // namespace nebula diff --git a/src/graph/planner/plan/PlanNode.h b/src/graph/planner/plan/PlanNode.h index d182d6fc9fe..e882a42fbf0 100644 --- a/src/graph/planner/plan/PlanNode.h +++ b/src/graph/planner/plan/PlanNode.h @@ -216,21 +216,16 @@ class PlanNode { void setOutputVar(const std::string& var); - const std::string& outputVar(size_t index = 0) const { - return outputVarPtr(index)->name; + const std::string& outputVar() const { + return outputVarPtr()->name; } - Variable* outputVarPtr(size_t index = 0) const { - DCHECK_LT(index, outputVars_.size()); - return outputVars_[index]; - } - - const std::vector& outputVars() const { - return outputVars_; + Variable* outputVarPtr() const { + return outputVar_; } const std::vector& colNames() const { - return outputVarPtr(0)->colNames; + return outputVarPtr()->colNames; } void setId(int64_t id) { @@ -314,7 +309,8 @@ class PlanNode { void cloneMembers(const PlanNode& node) { // TODO maybe shall copy cost_ and dependencies_ too inputVars_ = node.inputVars_; - outputVars_ = node.outputVars_; + // OutputVar will generated in constructor + setColNames(node.colNames()); } QueryContext* qctx_{nullptr}; @@ -323,7 +319,7 @@ class PlanNode { double cost_{0.0}; std::vector dependencies_; std::vector inputVars_; - std::vector outputVars_; + Variable* outputVar_; // nested loop layers of current node std::size_t loopLayers_{0}; bool deleted_{false}; diff --git a/src/graph/scheduler/AsyncMsgNotifyBasedScheduler.cpp b/src/graph/scheduler/AsyncMsgNotifyBasedScheduler.cpp index b2e1b878384..3bb81af59f8 100644 --- a/src/graph/scheduler/AsyncMsgNotifyBasedScheduler.cpp +++ b/src/graph/scheduler/AsyncMsgNotifyBasedScheduler.cpp @@ -12,6 +12,7 @@ namespace graph { AsyncMsgNotifyBasedScheduler::AsyncMsgNotifyBasedScheduler(QueryContext* qctx) : Scheduler() { qctx_ = qctx; + query_ = qctx->rctx()->query(); } folly::Future AsyncMsgNotifyBasedScheduler::schedule() { diff --git a/src/graph/scheduler/AsyncMsgNotifyBasedScheduler.h b/src/graph/scheduler/AsyncMsgNotifyBasedScheduler.h index 5698d2fcce3..b6d3cd88f02 100644 --- a/src/graph/scheduler/AsyncMsgNotifyBasedScheduler.h +++ b/src/graph/scheduler/AsyncMsgNotifyBasedScheduler.h @@ -63,6 +63,8 @@ class AsyncMsgNotifyBasedScheduler final : public Scheduler { folly::Future execute(Executor* executor) const; QueryContext* qctx_{nullptr}; + // used for debugging when core on runtime + std::string query_; }; } // namespace graph } // namespace nebula