diff --git a/src/graph/executor/algo/BatchShortestPath.cpp b/src/graph/executor/algo/BatchShortestPath.cpp index 1ec6cd6204c..42d69f03bc8 100644 --- a/src/graph/executor/algo/BatchShortestPath.cpp +++ b/src/graph/executor/algo/BatchShortestPath.cpp @@ -16,6 +16,9 @@ namespace graph { folly::Future BatchShortestPath::execute(const HashSet& startVids, const HashSet& endVids, DataSet* result) { + if (maxStep_ == 0) { + return Status::OK(); + } // MemoryTrackerVerified size_t rowSize = init(startVids, endVids); std::vector> futures; diff --git a/src/graph/executor/algo/SingleShortestPath.cpp b/src/graph/executor/algo/SingleShortestPath.cpp index ed0d0cce4b6..90e1bfc9813 100644 --- a/src/graph/executor/algo/SingleShortestPath.cpp +++ b/src/graph/executor/algo/SingleShortestPath.cpp @@ -14,6 +14,9 @@ namespace graph { folly::Future SingleShortestPath::execute(const HashSet& startVids, const HashSet& endVids, DataSet* result) { + if (maxStep_ == 0) { + return Status::OK(); + } size_t rowSize = startVids.size() * endVids.size(); init(startVids, endVids, rowSize); std::vector> futures; diff --git a/src/graph/validator/MatchValidator.cpp b/src/graph/validator/MatchValidator.cpp index 561322b6aaa..d4517705809 100644 --- a/src/graph/validator/MatchValidator.cpp +++ b/src/graph/validator/MatchValidator.cpp @@ -165,10 +165,13 @@ Status MatchValidator::buildPathExpr(const MatchPath *path, return Status::SemanticError( "`shortestPath(...)' only support pattern like (start)-[edge*..hop]-(end)"); } - auto min = edgeInfos.front().range->min(); - if (min != 0 && min != 1) { - return Status::SemanticError( - "`shortestPath(...)' does not support a minimal length different from 0 or 1"); + auto *range = edgeInfos.front().range.get(); + if (range != nullptr) { + auto min = range->min(); + if (min != 0 && min != 1) { + return Status::SemanticError( + "The minimal number of steps for shortestPath() must be either 0 or 1."); + } } pathInfo.pathType = static_cast(pathType); } diff --git a/tests/tck/features/match/AllShortestPaths.feature b/tests/tck/features/match/AllShortestPaths.feature index 766156b7d16..563d90a371d 100644 --- a/tests/tck/features/match/AllShortestPaths.feature +++ b/tests/tck/features/match/AllShortestPaths.feature @@ -6,6 +6,110 @@ Feature: allShortestPaths Background: Given a graph with space named "nba" + Scenario: shortest path invalid step + When executing query: + """ + WITH ["Tim Duncan","Tony Parker"] as list1 + MATCH allShortestPaths((v1:player)-[e*2]-(v2:player)) + WHERE id(v1) in list1 AND id(v2) in list1 + RETURN e + """ + Then a SemanticError should be raised at runtime: The minimal number of steps for shortestPath() must be either 0 or 1. + When executing query: + """ + WITH ["Tim Duncan","Tony Parker"] as list1 + MATCH allShortestPaths((v1:player)-[e*2..4]-(v2:player)) + WHERE id(v1) in list1 AND id(v2) in list1 + RETURN e + """ + Then a SemanticError should be raised at runtime: The minimal number of steps for shortestPath() must be either 0 or 1. + When executing query: + """ + WITH ["Tim Duncan","Tony Parker"] as list1 + MATCH allShortestPaths((v1:player)-[e]->(b)--(v2:player)) + WHERE id(v1) in list1 AND id(v2) in list1 + RETURN e + """ + Then a SemanticError should be raised at runtime: `shortestPath(...)' only support pattern like (start)-[edge*..hop]-(end) + When executing query: + """ + WITH ["Tim Duncan","Tony Parker"] as list1 + MATCH allShortestPaths((v1:player)-[e]->(b)-[e2:like]-(v2:player)) + WHERE id(v1) in list1 AND id(v2) in list1 + RETURN e + """ + Then a SemanticError should be raised at runtime: `shortestPath(...)' only support pattern like (start)-[edge*..hop]-(end) + + Scenario: zero step shortest path + When executing query: + """ + WITH ["Tim Duncan","Tony Parker"] as list1 + MATCH allShortestPaths((v1:player)-[e*0]-(v2:player)) + WHERE id(v1) in list1 AND id(v2) in list1 + RETURN e + """ + Then the result should be, in any order, with relax comparison: + | e | + When executing query: + """ + MATCH allShortestPaths((v1:player{name:"Tim Duncan"})-[e*0]-(v2:player{name:"Tony Parker"})) + RETURN e + """ + Then the result should be, in any order, with relax comparison: + | e | + + Scenario: one step shortest path + When executing query: + """ + WITH ["Tim Duncan","Tony Parker"] as list1 + MATCH allShortestPaths((v1:player)-[e]-(v2:player)) + WHERE id(v1) in list1 AND id(v2) in list1 + RETURN e + """ + Then the result should be, in any order, with relax comparison: + | e | + | [:like "Tony Parker"->"Tim Duncan" @0 {likeness: 95}] | + | [:like "Tim Duncan"->"Tony Parker" @0 {likeness: 95}] | + | [:teammate "Tony Parker"->"Tim Duncan" @0 {end_year: 2016, start_year: 2001}] | + | [:teammate "Tim Duncan"->"Tony Parker" @0 {end_year: 2016, start_year: 2001}] | + | [:like "Tim Duncan"->"Tony Parker" @0 {likeness: 95}] | + | [:like "Tony Parker"->"Tim Duncan" @0 {likeness: 95}] | + | [:teammate "Tim Duncan"->"Tony Parker" @0 {end_year: 2016, start_year: 2001}] | + | [:teammate "Tony Parker"->"Tim Duncan" @0 {end_year: 2016, start_year: 2001}] | + When executing query: + """ + MATCH allShortestPaths((v1:player{name:"Tim Duncan"})-[e]-(v2:player{name:"Tony Parker"})) + RETURN e + """ + Then the result should be, in any order, with relax comparison: + | e | + | [:teammate "Tony Parker"->"Tim Duncan" @0 {end_year: 2016, start_year: 2001}] | + | [:teammate "Tim Duncan"->"Tony Parker" @0 {end_year: 2016, start_year: 2001}] | + | [:like "Tony Parker"->"Tim Duncan" @0 {likeness: 95}] | + | [:like "Tim Duncan"->"Tony Parker" @0 {likeness: 95}] | + When executing query: + """ + MATCH allShortestPaths((v1:player{name:"Tim Duncan"})-[e*1]-(v2:player{name:"Tony Parker"})) + RETURN e + """ + Then the result should be, in any order, with relax comparison: + | e | + | [[:teammate "Tony Parker"->"Tim Duncan" @0 {end_year: 2016, start_year: 2001}]] | + | [[:teammate "Tim Duncan"->"Tony Parker" @0 {end_year: 2016, start_year: 2001}]] | + | [[:like "Tony Parker"->"Tim Duncan" @0 {likeness: 95}]] | + | [[:like "Tim Duncan"->"Tony Parker" @0 {likeness: 95}]] | + When executing query: + """ + MATCH allShortestPaths((v1:player{name:"Tim Duncan"})-[e*1..1]-(v2:player{name:"Tony Parker"})) + RETURN e + """ + Then the result should be, in any order, with relax comparison: + | e | + | [[:teammate "Tony Parker"->"Tim Duncan" @0 {end_year: 2016, start_year: 2001}]] | + | [[:teammate "Tim Duncan"->"Tony Parker" @0 {end_year: 2016, start_year: 2001}]] | + | [[:like "Tony Parker"->"Tim Duncan" @0 {likeness: 95}]] | + | [[:like "Tim Duncan"->"Tony Parker" @0 {likeness: 95}]] | + Scenario: allShortestPaths1 When executing query: """ diff --git a/tests/tck/features/match/SingleShorestPath.feature b/tests/tck/features/match/SingleShorestPath.feature index b7e74473073..78ad83c1662 100644 --- a/tests/tck/features/match/SingleShorestPath.feature +++ b/tests/tck/features/match/SingleShorestPath.feature @@ -6,6 +6,58 @@ Feature: single shortestPath Background: Given a graph with space named "nba" + Scenario: shortest path invalid step + When executing query: + """ + WITH ["Tim Duncan","Tony Parker"] as list1 + MATCH shortestPath((v1:player)-[e*2]-(v2:player)) + WHERE id(v1) in list1 AND id(v2) in list1 + RETURN e + """ + Then a SemanticError should be raised at runtime: The minimal number of steps for shortestPath() must be either 0 or 1. + When executing query: + """ + WITH ["Tim Duncan","Tony Parker"] as list1 + MATCH shortestPath((v1:player)-[e*2..4]-(v2:player)) + WHERE id(v1) in list1 AND id(v2) in list1 + RETURN e + """ + Then a SemanticError should be raised at runtime: The minimal number of steps for shortestPath() must be either 0 or 1. + When executing query: + """ + WITH ["Tim Duncan","Tony Parker"] as list1 + MATCH shortestPath((v1:player)-[e]->(b)--(v2:player)) + WHERE id(v1) in list1 AND id(v2) in list1 + RETURN e + """ + Then a SemanticError should be raised at runtime: `shortestPath(...)' only support pattern like (start)-[edge*..hop]-(end) + When executing query: + """ + WITH ["Tim Duncan","Tony Parker"] as list1 + MATCH shortestPath((v1:player)-[e]->(b)-[e2:like]-(v2:player)) + WHERE id(v1) in list1 AND id(v2) in list1 + RETURN e + """ + Then a SemanticError should be raised at runtime: `shortestPath(...)' only support pattern like (start)-[edge*..hop]-(end) + + Scenario: zero step shortestpath + When executing query: + """ + WITH ["Tim Duncan","Tony Parker"] as list1 + MATCH shortestPath((v1:player)-[e*0]-(v2:player)) + WHERE id(v1) in list1 AND id(v2) in list1 + RETURN e + """ + Then the result should be, in any order, with relax comparison: + | e | + When executing query: + """ + MATCH shortestPath((v1:player{name:"Tim Duncan"})-[e*0]-(v2:player{name:"Tony Parker"})) + RETURN e + """ + Then the result should be, in any order, with relax comparison: + | e | + Scenario: single shortestPath1 When executing query: """