From ad355b58e9f649555826233316c4d9c40b6d6821 Mon Sep 17 00:00:00 2001 From: jimingquan <mingquan.ji@vesoft.com> Date: Fri, 2 Apr 2021 15:23:52 +0800 Subject: [PATCH] Remove redundant project&dedup in findpath & fix path error (#912) * remove redundant project&dedup in findpath * fix path error & add testcase * add testcase Co-authored-by: Yee <2520865+yixinglu@users.noreply.github.com> --- .gitignore | 3 + src/executor/algo/ConjunctPathExecutor.cpp | 33 +-- src/executor/algo/ConjunctPathExecutor.h | 10 +- src/validator/FindPathValidator.cpp | 103 +++------ src/validator/FindPathValidator.h | 12 +- src/validator/test/FindPathValidatorTest.cpp | 204 +++--------------- .../features/path/ShortestPath.IntVid.feature | 38 +++- tests/tck/features/path/ShortestPath.feature | 38 +++- 8 files changed, 148 insertions(+), 293 deletions(-) diff --git a/.gitignore b/.gitignore index c895fcef..6a89523d 100644 --- a/.gitignore +++ b/.gitignore @@ -58,3 +58,6 @@ workspace.* *.py[co] __pycache__ venv/ + +#lock +*.lock diff --git a/src/executor/algo/ConjunctPathExecutor.cpp b/src/executor/algo/ConjunctPathExecutor.cpp index c12879fd..2ccbaf97 100644 --- a/src/executor/algo/ConjunctPathExecutor.cpp +++ b/src/executor/algo/ConjunctPathExecutor.cpp @@ -33,6 +33,9 @@ folly::Future<Status> ConjunctPathExecutor::bfsShortestPath() { << " right input: " << conjunct->rightInputVar(); DCHECK(!!lIter); + auto steps = conjunct->steps(); + count_++; + DataSet ds; ds.colNames = conjunct->colNames(); @@ -62,14 +65,16 @@ folly::Future<Status> ConjunctPathExecutor::bfsShortestPath() { } } - auto latest = rHist.back().iter(); - isLatest = true; - backward_.emplace_back(); - VLOG(1) << "Find even length path."; - auto rows = findBfsShortestPath(latest.get(), isLatest, forward_.back()); - if (!rows.empty()) { - VLOG(1) << "Meet even length path."; - ds.rows = std::move(rows); + if (count_ * 2 <= steps) { + auto latest = rHist.back().iter(); + isLatest = true; + backward_.emplace_back(); + VLOG(1) << "Find even length path."; + auto rows = findBfsShortestPath(latest.get(), isLatest, forward_.back()); + if (!rows.empty()) { + VLOG(1) << "Meet even length path."; + ds.rows = std::move(rows); + } } return finish(ResultBuilder().value(Value(std::move(ds))).finish()); } @@ -77,7 +82,7 @@ folly::Future<Status> ConjunctPathExecutor::bfsShortestPath() { std::vector<Row> ConjunctPathExecutor::findBfsShortestPath( Iterator* iter, bool isLatest, - std::multimap<Value, const Edge*>& table) { + std::unordered_multimap<Value, const Edge*>& table) { std::unordered_set<Value> meets; for (; iter->valid(); iter->next()) { auto& dst = iter->getColumn(kVid); @@ -118,10 +123,10 @@ std::vector<Row> ConjunctPathExecutor::findBfsShortestPath( return rows; } -std::multimap<Value, Path> ConjunctPathExecutor::buildBfsInterimPath( +std::unordered_multimap<Value, Path> ConjunctPathExecutor::buildBfsInterimPath( std::unordered_set<Value>& meets, - std::vector<std::multimap<Value, const Edge*>>& hists) { - std::multimap<Value, Path> results; + std::vector<std::unordered_multimap<Value, const Edge*>>& hists) { + std::unordered_multimap<Value, Path> results; for (auto& v : meets) { VLOG(1) << "Meet at: " << v; Path start; @@ -205,7 +210,7 @@ folly::Future<Status> ConjunctPathExecutor::floydShortestPath() { findPath(previous.get(), forwardCostPathMap, ds); } - if (count_ * 2 < steps) { + if (count_ * 2 <= steps) { VLOG(1) << "Find even length path."; auto latest = rHist.back().iter(); findPath(latest.get(), forwardCostPathMap, ds); @@ -224,7 +229,7 @@ Status ConjunctPathExecutor::conjunctPath(const List& forwardPaths, } for (auto& j : backwardPaths.values) { if (!j.isPath()) { - return Status::Error("Forward Path Type Error"); + return Status::Error("Backward Path Type Error"); } Row row; auto forward = i.getPath(); diff --git a/src/executor/algo/ConjunctPathExecutor.h b/src/executor/algo/ConjunctPathExecutor.h index c2ddabbd..ac866174 100644 --- a/src/executor/algo/ConjunctPathExecutor.h +++ b/src/executor/algo/ConjunctPathExecutor.h @@ -33,11 +33,11 @@ private: std::vector<Row> findBfsShortestPath(Iterator* iter, bool isLatest, - std::multimap<Value, const Edge*>& table); + std::unordered_multimap<Value, const Edge*>& table); - std::multimap<Value, Path> buildBfsInterimPath( + std::unordered_multimap<Value, Path> buildBfsInterimPath( std::unordered_set<Value>& meets, - std::vector<std::multimap<Value, const Edge*>>& hist); + std::vector<std::unordered_multimap<Value, const Edge*>>& hist); folly::Future<Status> floydShortestPath(); @@ -54,8 +54,8 @@ private: void delPathFromConditionalVar(const Value& start, const Value& end); private: - std::vector<std::multimap<Value, const Edge*>> forward_; - std::vector<std::multimap<Value, const Edge*>> backward_; + std::vector<std::unordered_multimap<Value, const Edge*>> forward_; + std::vector<std::unordered_multimap<Value, const Edge*>> backward_; size_t count_{0}; // startVid : {endVid, cost} std::unordered_map<Value, std::unordered_map<Value, Value>> historyCostMap_; diff --git a/src/validator/FindPathValidator.cpp b/src/validator/FindPathValidator.cpp index e7e9cc5c..8e70eb40 100644 --- a/src/validator/FindPathValidator.cpp +++ b/src/validator/FindPathValidator.cpp @@ -56,18 +56,14 @@ Status FindPathValidator::singlePairPlan() { auto* bodyStart = StartNode::make(qctx_); auto* passThrough = PassThroughNode::make(qctx_, bodyStart); - std::string fromPathVar; - auto* forward = bfs(passThrough, from_, fromPathVar, false); - VLOG(1) << "forward: " << fromPathVar; + auto* forward = bfs(passThrough, from_, false); + VLOG(1) << "forward: " << forward->outputVar(); - std::string toPathVar; - auto* backward = bfs(passThrough, to_, toPathVar, true); - VLOG(1) << "backward: " << toPathVar; + auto* backward = bfs(passThrough, to_, true); + VLOG(1) << "backward: " << backward->outputVar(); auto* conjunct = ConjunctPath::make(qctx_, forward, backward, ConjunctPath::PathKind::kBiBFS, steps_.steps); - conjunct->setLeftVar(fromPathVar); - conjunct->setRightVar(toPathVar); conjunct->setColNames({"_path"}); auto* loop = Loop::make( @@ -82,45 +78,28 @@ Status FindPathValidator::singlePairPlan() { return Status::OK(); } -PlanNode* FindPathValidator::bfs(PlanNode* dep, - Starts& starts, - std::string& pathVar, - bool reverse) { +PlanNode* FindPathValidator::bfs(PlanNode* dep, Starts& starts, bool reverse) { std::string startVidsVar; buildConstantInput(starts, startVidsVar); - auto* gn = GetNeighbors::make(qctx_, dep, space_.id); gn->setSrc(starts.src); gn->setEdgeProps(buildEdgeKey(reverse)); + gn->setDedup(); gn->setInputVar(startVidsVar); auto* bfs = BFSShortestPath::make(qctx_, gn); - bfs->setColNames({"_vid", "edge"}); - pathVar = bfs->outputVar(); - - auto* columns = qctx_->objPool()->add(new YieldColumns()); - auto* column = - new YieldColumn(new VariablePropertyExpression(new std::string("*"), new std::string(kVid)), - new std::string(kVid)); - columns->addColumn(column); - auto* project = Project::make(qctx_, bfs, columns); - project->setColNames(deduceColNames(columns)); - - auto* dedup = Dedup::make(qctx_, project); - auto* startVidsVarPtr = qctx_->symTable()->getVar(startVidsVar); - startVidsVarPtr->colNames = project->colNames(); - dedup->setOutputVar(startVidsVar); - + bfs->setOutputVar(startVidsVar); + bfs->setColNames({nebula::kVid, "edge"}); DataSet ds; - ds.colNames = {"_vid", "edge"}; + ds.colNames = {nebula::kVid, "edge"}; Row row; row.values.emplace_back(starts.vids.front()); row.values.emplace_back(Value::kEmpty); ds.rows.emplace_back(std::move(row)); - qctx_->ectx()->setResult(pathVar, ResultBuilder().value(Value(std::move(ds))).finish()); + qctx_->ectx()->setResult(startVidsVar, ResultBuilder().value(Value(std::move(ds))).finish()); - return dedup; + return bfs; } Expression* FindPathValidator::buildBfsLoopCondition(uint32_t steps, const std::string& pathVar) { @@ -186,9 +165,7 @@ GetNeighbors::EdgeProps FindPathValidator::buildEdgeKey(bool reverse) { return edgeProps; } -PlanNode* FindPathValidator::buildAllPairFirstDataSet(PlanNode* dep, - const std::string& inputVar, - const std::string& outputVar) { +PlanNode* FindPathValidator::buildAllPairFirstDataSet(PlanNode* dep, const std::string& inputVar) { auto* vid = new YieldColumn(new VariablePropertyExpression(new std::string("*"), new std::string(kVid)), new std::string(kVid)); @@ -206,9 +183,9 @@ PlanNode* FindPathValidator::buildAllPairFirstDataSet(PlanNode* dep, auto* project = Project::make(qctx_, dep, columns); project->setInputVar(inputVar); - auto* outputVarPtr = qctx_->symTable()->getVar(outputVar); - outputVarPtr->colNames = {kVid, "path"}; - project->setOutputVar(outputVar); + auto* outputVarPtr = qctx_->symTable()->getVar(inputVar); + outputVarPtr->colNames = {nebula::kVid, "path"}; + project->setOutputVar(inputVar); return project; } @@ -218,28 +195,25 @@ Status FindPathValidator::allPairPaths() { std::string fromStartVidsVar; buildStart(from_, fromStartVidsVar, false); - std::string fromPathVar; - auto* forward = allPaths(passThrough, from_, fromStartVidsVar, fromPathVar, false); - VLOG(1) << "forward: " << fromPathVar; + + auto* forward = allPaths(passThrough, from_, fromStartVidsVar, false); + VLOG(1) << "forward: " << forward->outputVar(); std::string toStartVidsVar; buildStart(to_, toStartVidsVar, true); - std::string toPathVar; - auto* backward = allPaths(passThrough, to_, toStartVidsVar, toPathVar, true); - VLOG(1) << "backward: " << toPathVar; + auto* backward = allPaths(passThrough, to_, toStartVidsVar, true); + VLOG(1) << "backward: " << backward->outputVar(); auto* conjunct = ConjunctPath::make( qctx_, forward, backward, ConjunctPath::PathKind::kAllPaths, steps_.steps); - conjunct->setLeftVar(fromPathVar); - conjunct->setRightVar(toPathVar); conjunct->setColNames({"_path"}); conjunct->setNoLoop(noLoop_); PlanNode* projectFromDep = nullptr; linkLoopDepFromTo(projectFromDep); - auto* projectFrom = buildAllPairFirstDataSet(projectFromDep, fromStartVidsVar, fromPathVar); - auto* projectTo = buildAllPairFirstDataSet(projectFrom, toStartVidsVar, toPathVar); + auto* projectFrom = buildAllPairFirstDataSet(projectFromDep, fromStartVidsVar); + auto* projectTo = buildAllPairFirstDataSet(projectFrom, toStartVidsVar); auto* loop = Loop::make(qctx_, projectTo, conjunct, buildAllPathsLoopCondition(steps_.steps)); @@ -256,31 +230,17 @@ Status FindPathValidator::allPairPaths() { PlanNode* FindPathValidator::allPaths(PlanNode* dep, Starts& starts, std::string& startVidsVar, - std::string& pathVar, bool reverse) { auto* gn = GetNeighbors::make(qctx_, dep, space_.id); gn->setSrc(starts.src); gn->setEdgeProps(buildEdgeKey(reverse)); gn->setInputVar(startVidsVar); + gn->setDedup(); auto* allPaths = ProduceAllPaths::make(qctx_, gn); - allPaths->setColNames({kVid, "path"}); - pathVar = allPaths->outputVar(); - - auto* columns = qctx_->objPool()->add(new YieldColumns()); - auto* column = - new YieldColumn(new VariablePropertyExpression(new std::string("*"), new std::string(kVid)), - new std::string(kVid)); - columns->addColumn(column); - auto* project = Project::make(qctx_, allPaths, columns); - project->setColNames(deduceColNames(columns)); - - auto* dedup = Dedup::make(qctx_, project); - auto* startVidsVarPtr = qctx_->symTable()->getVar(startVidsVar); - startVidsVarPtr->colNames = project->colNames(); - dedup->setOutputVar(startVidsVar); - - return dedup; + allPaths->setOutputVar(startVidsVar); + allPaths->setColNames({nebula::kVid, "path"}); + return allPaths; } Expression* FindPathValidator::buildAllPathsLoopCondition(uint32_t steps) { @@ -419,9 +379,10 @@ PlanNode* FindPathValidator::multiPairShortestPath(PlanNode* dep, gn->setSrc(starts.src); gn->setEdgeProps(buildEdgeKey(reverse)); gn->setInputVar(startVidsVar); + gn->setDedup(); auto* pssp = ProduceSemiShortestPath::make(qctx_, gn); - pssp->setColNames({kDst, kSrc, "cost", "paths"}); + pssp->setColNames({nebula::kDst, nebula::kSrc, "cost", "paths"}); pathVar = pssp->outputVar(); auto* columns = qctx_->objPool()->add(new YieldColumns()); @@ -430,14 +391,10 @@ PlanNode* FindPathValidator::multiPairShortestPath(PlanNode* dep, new std::string(kVid)); columns->addColumn(column); auto* project = Project::make(qctx_, pssp, columns); + project->setOutputVar(startVidsVar); project->setColNames(deduceColNames(columns)); - auto* dedup = Dedup::make(qctx_, project); - auto* startVidsVarPtr = qctx_->symTable()->getVar(startVidsVar); - startVidsVarPtr->colNames = project->colNames(); - dedup->setOutputVar(startVidsVar); - - return dedup; + return project; } Expression* FindPathValidator::buildMultiPairLoopCondition(uint32_t steps, diff --git a/src/validator/FindPathValidator.h b/src/validator/FindPathValidator.h index 07b45b64..6a6b06c3 100644 --- a/src/validator/FindPathValidator.h +++ b/src/validator/FindPathValidator.h @@ -28,20 +28,14 @@ private: void linkLoopDepFromTo(PlanNode*& projectDep); // bfs Status singlePairPlan(); - PlanNode* bfs(PlanNode* dep, Starts& starts, std::string& pathVar, bool reverse); + PlanNode* bfs(PlanNode* dep, Starts& starts, bool reverse); Expression* buildBfsLoopCondition(uint32_t steps, const std::string& pathVar); // allPath Status allPairPaths(); - PlanNode* allPaths(PlanNode* dep, - Starts& starts, - std::string& startVidsVar, - std::string& pathVar, - bool reverse); + PlanNode* allPaths(PlanNode* dep, Starts& starts, std::string& startVidsVar, bool reverse); Expression* buildAllPathsLoopCondition(uint32_t steps); - PlanNode* buildAllPairFirstDataSet(PlanNode* dep, - const std::string& inputVar, - const std::string& outputVar); + PlanNode* buildAllPairFirstDataSet(PlanNode* dep, const std::string& inputVar); // multi-pair Status multiPairPlan(); diff --git a/src/validator/test/FindPathValidatorTest.cpp b/src/validator/test/FindPathValidatorTest.cpp index 69f74dd2..127f9609 100644 --- a/src/validator/test/FindPathValidatorTest.cpp +++ b/src/validator/test/FindPathValidatorTest.cpp @@ -27,10 +27,6 @@ TEST_F(FindPathValidatorTest, SinglePairPath) { PK::kLoop, PK::kStart, PK::kConjunctPath, - PK::kDedup, - PK::kDedup, - PK::kProject, - PK::kProject, PK::kBFSShortest, PK::kBFSShortest, PK::kGetNeighbors, @@ -47,30 +43,6 @@ TEST_F(FindPathValidatorTest, SinglePairPath) { PK::kLoop, PK::kStart, PK::kConjunctPath, - PK::kDedup, - PK::kDedup, - PK::kProject, - PK::kProject, - PK::kBFSShortest, - PK::kBFSShortest, - PK::kGetNeighbors, - PK::kGetNeighbors, - PK::kPassThrough, - PK::kStart, - }; - EXPECT_TRUE(checkResult(query, expected)); - } - { - std::string query = "FIND SHORTEST PATH FROM \"1\" TO \"2\" OVER * UPTO 5 STEPS"; - std::vector<PlanNode::Kind> expected = { - PK::kDataCollect, - PK::kLoop, - PK::kStart, - PK::kConjunctPath, - PK::kDedup, - PK::kDedup, - PK::kProject, - PK::kProject, PK::kBFSShortest, PK::kBFSShortest, PK::kGetNeighbors, @@ -91,37 +63,12 @@ TEST_F(FindPathValidatorTest, MultiPairPath) { PK::kCartesianProduct, PK::kConjunctPath, PK::kProject, - PK::kDedup, - PK::kDedup, PK::kProject, PK::kProject, PK::kProject, - PK::kStart, PK::kProduceSemiShortestPath, PK::kProduceSemiShortestPath, - PK::kGetNeighbors, - PK::kGetNeighbors, - PK::kPassThrough, PK::kStart, - }; - EXPECT_TRUE(checkResult(query, expected)); - } - { - std::string query = "FIND SHORTEST PATH FROM \"1\" TO \"2\",\"3\" OVER *"; - std::vector<PlanNode::Kind> expected = { - PK::kDataCollect, - PK::kLoop, - PK::kCartesianProduct, - PK::kConjunctPath, - PK::kProject, - PK::kDedup, - PK::kDedup, - PK::kProject, - PK::kProject, - PK::kProject, - PK::kStart, - PK::kProduceSemiShortestPath, - PK::kProduceSemiShortestPath, PK::kGetNeighbors, PK::kGetNeighbors, PK::kPassThrough, @@ -138,14 +85,12 @@ TEST_F(FindPathValidatorTest, MultiPairPath) { PK::kCartesianProduct, PK::kConjunctPath, PK::kProject, - PK::kDedup, - PK::kDedup, PK::kProject, PK::kProject, PK::kProject, - PK::kStart, PK::kProduceSemiShortestPath, PK::kProduceSemiShortestPath, + PK::kStart, PK::kGetNeighbors, PK::kGetNeighbors, PK::kPassThrough, @@ -164,35 +109,9 @@ TEST_F(FindPathValidatorTest, ALLPath) { PK::kProject, PK::kConjunctPath, PK::kProject, - PK::kDedup, - PK::kDedup, - PK::kStart, - PK::kProject, - PK::kProject, PK::kProduceAllPaths, PK::kProduceAllPaths, - PK::kGetNeighbors, - PK::kGetNeighbors, - PK::kPassThrough, PK::kStart, - }; - EXPECT_TRUE(checkResult(query, expected)); - } - { - std::string query = "FIND ALL PATH FROM \"1\" TO \"2\",\"3\" OVER like UPTO 5 STEPS"; - std::vector<PlanNode::Kind> expected = { - PK::kDataCollect, - PK::kLoop, - PK::kProject, - PK::kConjunctPath, - PK::kProject, - PK::kDedup, - PK::kDedup, - PK::kStart, - PK::kProject, - PK::kProject, - PK::kProduceAllPaths, - PK::kProduceAllPaths, PK::kGetNeighbors, PK::kGetNeighbors, PK::kPassThrough, @@ -201,42 +120,16 @@ TEST_F(FindPathValidatorTest, ALLPath) { EXPECT_TRUE(checkResult(query, expected)); } { - std::string query = "FIND ALL PATH FROM \"1\",\"2\" TO \"3\",\"4\" OVER like UPTO 5 STEPS"; + std::string query = "FIND ALL PATH FROM \"1\" TO \"2\",\"3\" OVER like UPTO 5 STEPS"; std::vector<PlanNode::Kind> expected = { PK::kDataCollect, PK::kLoop, PK::kProject, PK::kConjunctPath, PK::kProject, - PK::kDedup, - PK::kDedup, - PK::kStart, - PK::kProject, - PK::kProject, PK::kProduceAllPaths, PK::kProduceAllPaths, - PK::kGetNeighbors, - PK::kGetNeighbors, - PK::kPassThrough, - PK::kStart, - }; - EXPECT_TRUE(checkResult(query, expected)); - } - { - std::string query = "FIND ALL PATH FROM \"1\" TO \"2\" OVER like, serve UPTO 5 STEPS"; - std::vector<PlanNode::Kind> expected = { - PK::kDataCollect, - PK::kLoop, - PK::kProject, - PK::kConjunctPath, - PK::kProject, - PK::kDedup, - PK::kDedup, PK::kStart, - PK::kProject, - PK::kProject, - PK::kProduceAllPaths, - PK::kProduceAllPaths, PK::kGetNeighbors, PK::kGetNeighbors, PK::kPassThrough, @@ -257,22 +150,20 @@ TEST_F(FindPathValidatorTest, RunTimePath) { PK::kCartesianProduct, PK::kConjunctPath, PK::kProject, - PK::kDedup, - PK::kDedup, PK::kProject, PK::kProject, PK::kProject, - PK::kDedup, PK::kProduceSemiShortestPath, PK::kProduceSemiShortestPath, - PK::kProject, + PK::kDedup, PK::kGetNeighbors, PK::kGetNeighbors, - PK::kDedup, - PK::kPassThrough, PK::kProject, + PK::kPassThrough, + PK::kDedup, PK::kStart, PK::kProject, + PK::kProject, PK::kGetNeighbors, PK::kStart, }; @@ -288,12 +179,6 @@ TEST_F(FindPathValidatorTest, RunTimePath) { PK::kProject, PK::kConjunctPath, PK::kProject, - PK::kDedup, - PK::kDedup, - PK::kDedup, - PK::kProject, - PK::kProject, - PK::kProject, PK::kProduceAllPaths, PK::kProduceAllPaths, PK::kDedup, @@ -301,8 +186,10 @@ TEST_F(FindPathValidatorTest, RunTimePath) { PK::kGetNeighbors, PK::kProject, PK::kPassThrough, - PK::kProject, + PK::kDedup, PK::kStart, + PK::kProject, + PK::kProject, PK::kGetNeighbors, PK::kStart, }; @@ -318,21 +205,19 @@ TEST_F(FindPathValidatorTest, RunTimePath) { PK::kCartesianProduct, PK::kConjunctPath, PK::kProject, - PK::kDedup, - PK::kDedup, PK::kProject, PK::kProject, PK::kProject, - PK::kDedup, PK::kProduceSemiShortestPath, PK::kProduceSemiShortestPath, - PK::kProject, + PK::kDedup, PK::kGetNeighbors, PK::kGetNeighbors, PK::kProject, PK::kPassThrough, - PK::kGetNeighbors, + PK::kProject, PK::kStart, + PK::kGetNeighbors, PK::kStart, }; EXPECT_TRUE(checkResult(query, expected)); @@ -347,51 +232,18 @@ TEST_F(FindPathValidatorTest, RunTimePath) { PK::kCartesianProduct, PK::kConjunctPath, PK::kProject, - PK::kDedup, - PK::kDedup, PK::kProject, PK::kProject, PK::kProject, - PK::kDedup, PK::kProduceSemiShortestPath, PK::kProduceSemiShortestPath, - PK::kProject, - PK::kGetNeighbors, - PK::kGetNeighbors, - PK::kProject, - PK::kPassThrough, - PK::kGetNeighbors, - PK::kStart, - PK::kStart, - }; - EXPECT_TRUE(checkResult(query, expected)); - } - { - std::string query = - "$a = GO FROM \"1\" OVER like YIELD like._src AS src, like._dst AS dst; " - "FIND SHORTEST PATH FROM $a.src TO $a.dst OVER like, serve UPTO 5 STEPS"; - std::vector<PlanNode::Kind> expected = { - PK::kDataCollect, - PK::kLoop, - PK::kCartesianProduct, - PK::kConjunctPath, - PK::kProject, - PK::kDedup, - PK::kDedup, - PK::kProject, - PK::kProject, - PK::kProject, PK::kDedup, - PK::kProduceSemiShortestPath, - PK::kProduceSemiShortestPath, - PK::kProject, PK::kGetNeighbors, PK::kGetNeighbors, - PK::kDedup, + PK::kProject, PK::kPassThrough, PK::kProject, PK::kStart, - PK::kProject, PK::kGetNeighbors, PK::kStart, }; @@ -407,22 +259,20 @@ TEST_F(FindPathValidatorTest, RunTimePath) { PK::kCartesianProduct, PK::kConjunctPath, PK::kProject, - PK::kDedup, - PK::kDedup, PK::kProject, PK::kProject, PK::kProject, - PK::kDedup, PK::kProduceSemiShortestPath, PK::kProduceSemiShortestPath, - PK::kProject, + PK::kDedup, PK::kGetNeighbors, PK::kGetNeighbors, - PK::kDedup, - PK::kPassThrough, PK::kProject, + PK::kPassThrough, + PK::kDedup, PK::kStart, PK::kProject, + PK::kProject, PK::kGetNeighbors, PK::kProject, PK::kGetNeighbors, @@ -440,22 +290,20 @@ TEST_F(FindPathValidatorTest, RunTimePath) { PK::kCartesianProduct, PK::kConjunctPath, PK::kProject, - PK::kDedup, - PK::kDedup, PK::kProject, PK::kProject, PK::kProject, - PK::kDedup, PK::kProduceSemiShortestPath, PK::kProduceSemiShortestPath, - PK::kProject, + PK::kDedup, PK::kGetNeighbors, PK::kGetNeighbors, - PK::kDedup, - PK::kPassThrough, PK::kProject, + PK::kPassThrough, + PK::kDedup, PK::kStart, PK::kProject, + PK::kProject, PK::kStart, }; EXPECT_TRUE(checkResult(query, expected)); @@ -469,12 +317,6 @@ TEST_F(FindPathValidatorTest, RunTimePath) { PK::kProject, PK::kConjunctPath, PK::kProject, - PK::kDedup, - PK::kDedup, - PK::kDedup, - PK::kProject, - PK::kProject, - PK::kProject, PK::kProduceAllPaths, PK::kProduceAllPaths, PK::kDedup, @@ -482,8 +324,10 @@ TEST_F(FindPathValidatorTest, RunTimePath) { PK::kGetNeighbors, PK::kProject, PK::kPassThrough, - PK::kProject, + PK::kDedup, PK::kStart, + PK::kProject, + PK::kProject, PK::kStart, }; EXPECT_TRUE(checkResult(query, expected)); diff --git a/tests/tck/features/path/ShortestPath.IntVid.feature b/tests/tck/features/path/ShortestPath.IntVid.feature index 7cd51bb7..a2f410b8 100644 --- a/tests/tck/features/path/ShortestPath.IntVid.feature +++ b/tests/tck/features/path/ShortestPath.IntVid.feature @@ -1,4 +1,4 @@ -# Copyright (c) 2020 vesoft inc. All rights reserved. +# Copyright (c) 2021 vesoft inc. All rights reserved. # # This source code is licensed under Apache 2.0 License, # attached with Common Clause Condition 1.0, found in the LICENSES directory. @@ -52,6 +52,21 @@ Feature: Integer Vid Shortest Path | path | | <("Tiago Splitter")-[:like]->("Tim Duncan")-[:teammate]->("LaMarcus Aldridge")> | + Scenario: Integer Vid [6] SinglePair Shortest Path limit steps + When executing query: + """ + FIND SHORTEST PATH FROM hash("Tiago Splitter") TO hash("Tony Parker") OVER * UPTO 1 STEPS + """ + Then the result should be, in any order, with relax comparison: + | path | + When executing query: + """ + FIND SHORTEST PATH FROM hash("Tiago Splitter") TO hash("Tim Duncan") OVER * UPTO 1 STEPS + """ + Then the result should be, in any order, with relax comparison: + | path | + | <("Tiago Splitter")-[:like]->("Tim Duncan")> | + Scenario: Integer Vid [1] MultiPair Shortest Path When executing query: """ @@ -104,6 +119,15 @@ Feature: Integer Vid Shortest Path | <("Tony Parker")-[:like]->("Manu Ginobili")> | | <("Tony Parker")-[:teammate]->("Manu Ginobili")> | | <("Tony Parker")-[:serve]->("Spurs")> | + When executing query: + """ + FIND SHORTEST PATH FROM hash("Yao Ming") TO hash("Tim Duncan"), hash("Spurs"), hash("Lakers") OVER * UPTO 2 STEPS + """ + Then the result should be, in any order, with relax comparison: + | path | + | <("Yao Ming")-[:like]->("Shaquile O'Neal")-[:like]->("Tim Duncan")> | + | <("Yao Ming")-[:like]->("Tracy McGrady")-[:serve]->("Spurs")> | + | <("Yao Ming")-[:like]->("Shaquile O'Neal")-[:serve]->("Lakers")> | Scenario: Integer Vid [5] MultiPair Shortest Path When executing query: @@ -390,11 +414,13 @@ Feature: Integer Vid Shortest Path FIND SHORTEST PATH FROM hash("Tony Parker"), hash("Yao Ming") TO hash("Manu Ginobili"), hash("Spurs"), hash("Lakers") OVER * BIDIRECT UPTO 2 STEPS """ Then the result should be, in any order, with relax comparison: - | path | - | <("Tony Parker")-[:serve]->("Spurs")> | - | <("Tony Parker")<-[:teammate]-("Manu Ginobili")> | - | <("Tony Parker")-[:like]->("Manu Ginobili")> | - | <("Tony Parker")-[:teammate]->("Manu Ginobili")> | + | path | + | <("Yao Ming")-[:like]->("Tracy McGrady")-[:serve]->("Spurs")> | + | <("Yao Ming")-[:like]->("Shaquile O'Neal")-[:serve]->("Lakers")> | + | <("Tony Parker")-[:serve]->("Spurs")> | + | <("Tony Parker")<-[:teammate]-("Manu Ginobili")> | + | <("Tony Parker")-[:like]->("Manu Ginobili")> | + | <("Tony Parker")-[:teammate]->("Manu Ginobili")> | Scenario: Integer Vid [3] Shortest Path BIDIRECT When executing query: diff --git a/tests/tck/features/path/ShortestPath.feature b/tests/tck/features/path/ShortestPath.feature index 35892b1c..db87d135 100644 --- a/tests/tck/features/path/ShortestPath.feature +++ b/tests/tck/features/path/ShortestPath.feature @@ -1,4 +1,4 @@ -# Copyright (c) 2020 vesoft inc. All rights reserved. +# Copyright (c) 2021 vesoft inc. All rights reserved. # # This source code is licensed under Apache 2.0 License, # attached with Common Clause Condition 1.0, found in the LICENSES directory. @@ -52,6 +52,21 @@ Feature: Shortest Path | path | | <("Tiago Splitter")-[:like]->("Tim Duncan")-[:teammate]->("LaMarcus Aldridge")> | + Scenario: [6] SinglePair Shortest Path limit steps + When executing query: + """ + FIND SHORTEST PATH FROM "Tiago Splitter" TO "Tony Parker" OVER * UPTO 1 STEPS + """ + Then the result should be, in any order, with relax comparison: + | path | + When executing query: + """ + FIND SHORTEST PATH FROM "Tiago Splitter" TO "Tim Duncan" OVER * UPTO 1 STEPS + """ + Then the result should be, in any order, with relax comparison: + | path | + | <("Tiago Splitter")-[:like]->("Tim Duncan")> | + Scenario: [1] MultiPair Shortest Path When executing query: """ @@ -104,6 +119,15 @@ Feature: Shortest Path | <("Tony Parker")-[:like]->("Manu Ginobili")> | | <("Tony Parker")-[:teammate]->("Manu Ginobili")> | | <("Tony Parker")-[:serve]->("Spurs")> | + When executing query: + """ + FIND SHORTEST PATH FROM "Yao Ming" TO "Tim Duncan", "Spurs", "Lakers" OVER * UPTO 2 STEPS + """ + Then the result should be, in any order, with relax comparison: + | path | + | <("Yao Ming")-[:like]->("Shaquile O'Neal")-[:like]->("Tim Duncan")> | + | <("Yao Ming")-[:like]->("Tracy McGrady")-[:serve]->("Spurs")> | + | <("Yao Ming")-[:like]->("Shaquile O'Neal")-[:serve]->("Lakers")> | Scenario: [5] MultiPair Shortest Path When executing query: @@ -390,11 +414,13 @@ Feature: Shortest Path FIND SHORTEST PATH FROM "Tony Parker", "Yao Ming" TO "Manu Ginobili", "Spurs", "Lakers" OVER * BIDIRECT UPTO 2 STEPS """ Then the result should be, in any order, with relax comparison: - | path | - | <("Tony Parker")-[:serve]->("Spurs")> | - | <("Tony Parker")<-[:teammate]-("Manu Ginobili")> | - | <("Tony Parker")-[:like]->("Manu Ginobili")> | - | <("Tony Parker")-[:teammate]->("Manu Ginobili")> | + | path | + | <("Yao Ming")-[:like]->("Tracy McGrady")-[:serve]->("Spurs")> | + | <("Yao Ming")-[:like]->("Shaquile O'Neal")-[:serve]->("Lakers")> | + | <("Tony Parker")-[:serve]->("Spurs")> | + | <("Tony Parker")<-[:teammate]-("Manu Ginobili")> | + | <("Tony Parker")-[:like]->("Manu Ginobili")> | + | <("Tony Parker")-[:teammate]->("Manu Ginobili")> | Scenario: [3] Shortest Path BIDIRECT When executing query: -- GitLab