Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 5e4ae44

Browse files
charlygaoCPWstatic
andauthored
FIND PATH sentence support REVERSELY/BIDIRECT and NOLOOP (vesoft-inc#2398)
Co-authored-by: cpw <[email protected]>
1 parent b9c1428 commit 5e4ae44

File tree

9 files changed

+718
-119
lines changed

9 files changed

+718
-119
lines changed

src/graph/FindPathExecutor.cpp

Lines changed: 159 additions & 60 deletions
Large diffs are not rendered by default.

src/graph/FindPathExecutor.h

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,12 @@ const std::vector<std::string> kReserveProps_ = {"_type", "_rank"};
2020
using Neighbor = std::tuple<VertexID, EdgeType, EdgeRanking>; /* dst, type, rank*/
2121
using Neighbors = std::vector<Neighbor>;
2222
using Frontiers =
23-
std::vector<
24-
std::pair<
25-
VertexID, /* start */
26-
Neighbors /* frontiers of vertex*/
27-
>
28-
>;
23+
std::vector<
24+
std::pair<
25+
VertexID, /* start */
26+
Neighbors /* frontiers of vertex*/
27+
>
28+
>;
2929

3030
using StepOut = std::tuple<VertexID, EdgeType, EdgeRanking>; /* src, type, rank*/
3131
using Path = std::list<StepOut*>;
@@ -50,6 +50,8 @@ class FindPathExecutor final : public TraverseExecutor {
5050

5151
static std::string buildPathString(const Path &path);
5252

53+
const std::string NEGATIVE_STR = "-";
54+
5355
cpp2::RowValue buildPathRow(const Path &path);
5456

5557
private:
@@ -78,22 +80,24 @@ class FindPathExecutor final : public TraverseExecutor {
7880

7981
inline void meetEvenPath(VertexID intersectId);
8082

81-
inline void updatePath(
82-
VertexID &src,
83-
std::multimap<VertexID, Path> &pathToSrc,
84-
Neighbor &neighbor,
85-
std::multimap<VertexID, Path> &pathToNeighbor,
86-
VisitedBy visitedBy);
83+
inline bool updatePath(
84+
VertexID &src,
85+
std::multimap<VertexID, Path> &pathToSrc,
86+
Neighbor &neighbor,
87+
std::multimap<VertexID, Path> &pathToNeighbor,
88+
VisitedBy visitedBy);
89+
90+
inline bool isPathAcceptable(Path path, Neighbor &neighbor, VisitedBy visitedBy);
8791

8892
Status setupVids();
8993

9094
Status setupVidsFromRef(Clause::Vertices &vertices);
9195

9296
Status doFilter(
93-
storage::StorageRpcResponse<storage::cpp2::QueryResponse> &&result,
94-
Expression *filter,
95-
bool isOutBound,
96-
Frontiers &frontiers);
97+
storage::StorageRpcResponse<storage::cpp2::QueryResponse> &&result,
98+
Expression *filter,
99+
bool isOutBound,
100+
Frontiers &frontiers);
97101

98102
StatusOr<std::vector<storage::cpp2::PropDef>> getStepOutProps(bool reversely);
99103

@@ -108,7 +112,9 @@ class FindPathExecutor final : public TraverseExecutor {
108112
Clause::Over over_;
109113
Clause::Step step_;
110114
Clause::Where where_;
115+
OverClause::Direction direction_{OverClause::Direction::kForward};
111116
bool shortest_{false};
117+
bool noLoop_{false};
112118
using SchemaPropIndex = std::unordered_map<std::pair<std::string, std::string>, int64_t>;
113119
SchemaPropIndex srcTagProps_;
114120
SchemaPropIndex dstTagProps_;

src/graph/test/FindPathTest.cpp

Lines changed: 466 additions & 34 deletions
Large diffs are not rendered by default.

src/graph/test/TraverseTestBase.h

Lines changed: 43 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -62,16 +62,19 @@ class TraverseTestBase : public TestBase {
6262

6363
auto rows = buildPathString(*resp.get_rows());
6464

65-
if (expected.size() != rows.size()) {
66-
return TestError() << "Rows' count not match: "
67-
<< rows.size() << " vs. " << expected.size();
68-
}
69-
7065
std::sort(rows.begin(), rows.end());
7166
std::sort(expected.begin(), expected.end());
7267

68+
std::string joinedRowString;
7369
for (decltype(rows.size()) i = 0; i < rows.size(); ++i) {
7470
VLOG(2) << rows[i];
71+
joinedRowString += rows[i] + "\n";
72+
}
73+
74+
if (expected.size() != rows.size()) {
75+
return TestError() << "Rows' count not match: "
76+
<< rows.size() << " vs. " << expected.size() << "\n"
77+
<< joinedRowString;
7578
}
7679

7780
for (decltype(rows.size()) i = 0; i < rows.size(); ++i) {
@@ -363,6 +366,15 @@ TraverseTestBase::VertexHolder<TraverseTestBase::Player> TraverseTestBase::playe
363366
Player{"Ben Simmons", 22},
364367
Player{"Luka Doncic", 20},
365368

369+
Player{"Jaylen Adams", 24},
370+
Player{"Steven Adams", 27},
371+
Player{"Bam Adebayo", 23},
372+
Player{"Kyle Alexander", 24},
373+
Player{"Grayson Allen", 25},
374+
Player{"Jarrett Allen", 22},
375+
Player{"Justin Anderson", 27},
376+
Player{"OG Anunoby", 23},
377+
366378
Player{"Nobody", 0},
367379
}
368380
};
@@ -781,6 +793,16 @@ AssertionResult TraverseTestBase::initData() {
781793
.like("Dirk Nowitzki", 90)
782794
.like("Kristaps Porzingis", 90)
783795
.like("James Harden", 80);
796+
797+
players_["Jaylen Adams"].like("Steven Adams", 95)
798+
.like("Bam Adebayo", 95);
799+
players_["Steven Adams"].like("Kyle Alexander", 95)
800+
.like("Bam Adebayo", 95);
801+
players_["Kyle Alexander"].like("Grayson Allen", 95);
802+
players_["Grayson Allen"].like("Jarrett Allen", 95);
803+
players_["Jarrett Allen"].like("Justin Anderson", 95);
804+
players_["Justin Anderson"].like("OG Anunoby", 95);
805+
players_["OG Anunoby"].like("Jarrett Allen", 95);
784806
return TestOK();
785807
}
786808

@@ -816,6 +838,7 @@ AssertionResult TraverseTestBase::insertData() {
816838
query += "),\n\t";
817839
}
818840
query.resize(query.size() - 3);
841+
LOG(INFO) << query;
819842
auto code = client_->execute(query, resp);
820843
if (code != cpp2::ErrorCode::SUCCEEDED) {
821844
return TestError() << "Insert `players' failed: "
@@ -841,6 +864,7 @@ AssertionResult TraverseTestBase::insertData() {
841864
query += "),\n\t";
842865
}
843866
query.resize(query.size() - 3);
867+
LOG(INFO) << query;
844868
auto code = client_->execute(query, resp);
845869
if (code != cpp2::ErrorCode::SUCCEEDED) {
846870
return TestError() << "Insert `players' failed: "
@@ -865,6 +889,7 @@ AssertionResult TraverseTestBase::insertData() {
865889
query += "),\n\t";
866890
}
867891
query.resize(query.size() - 3);
892+
LOG(INFO) << query;
868893
auto code = client_->execute(query, resp);
869894
if (code != cpp2::ErrorCode::SUCCEEDED) {
870895
return TestError() << "Insert `players' failed: "
@@ -890,6 +915,7 @@ AssertionResult TraverseTestBase::insertData() {
890915
query += "),\n\t";
891916
}
892917
query.resize(query.size() - 3);
918+
LOG(INFO) << query;
893919
auto code = client_->execute(query, resp);
894920
if (code != cpp2::ErrorCode::SUCCEEDED) {
895921
return TestError() << "Insert `players' failed: "
@@ -912,6 +938,7 @@ AssertionResult TraverseTestBase::insertData() {
912938
query += "),\n\t";
913939
}
914940
query.resize(query.size() - 3);
941+
LOG(INFO) << query;
915942
auto code = client_->execute(query, resp);
916943
if (code != cpp2::ErrorCode::SUCCEEDED) {
917944
return TestError() << "Insert `teams' failed: "
@@ -935,6 +962,7 @@ AssertionResult TraverseTestBase::insertData() {
935962
query += "),\n\t";
936963
}
937964
query.resize(query.size() - 3);
965+
LOG(INFO) << query;
938966
auto code = client_->execute(query, resp);
939967
if (code != cpp2::ErrorCode::SUCCEEDED) {
940968
return TestError() << "Insert `teams' failed: "
@@ -958,6 +986,7 @@ AssertionResult TraverseTestBase::insertData() {
958986
query += "),\n\t";
959987
}
960988
query.resize(query.size() - 3);
989+
LOG(INFO) << query;
961990
auto code = client_->execute(query, resp);
962991
if (code != cpp2::ErrorCode::SUCCEEDED) {
963992
return TestError() << "Insert `teams' failed: "
@@ -990,6 +1019,7 @@ AssertionResult TraverseTestBase::insertData() {
9901019
}
9911020
}
9921021
query.resize(query.size() - 3);
1022+
LOG(INFO) << query;
9931023
auto code = client_->execute(query, resp);
9941024
if (code != cpp2::ErrorCode::SUCCEEDED) {
9951025
return TestError() << "Insert `serve' failed: "
@@ -1022,6 +1052,7 @@ AssertionResult TraverseTestBase::insertData() {
10221052
}
10231053
}
10241054
query.resize(query.size() - 3);
1055+
LOG(INFO) << query;
10251056
auto code = client_->execute(query, resp);
10261057
if (code != cpp2::ErrorCode::SUCCEEDED) {
10271058
return TestError() << "Insert `serve' failed: "
@@ -1054,6 +1085,7 @@ AssertionResult TraverseTestBase::insertData() {
10541085
}
10551086
}
10561087
query.resize(query.size() - 3);
1088+
LOG(INFO) << query;
10571089
auto code = client_->execute(query, resp);
10581090
if (code != cpp2::ErrorCode::SUCCEEDED) {
10591091
return TestError() << "Insert `serve' failed: "
@@ -1080,6 +1112,7 @@ AssertionResult TraverseTestBase::insertData() {
10801112
}
10811113
}
10821114
query.resize(query.size() - 3);
1115+
LOG(INFO) << query;
10831116
auto code = client_->execute(query, resp);
10841117
if (code != cpp2::ErrorCode::SUCCEEDED) {
10851118
return TestError() << "Insert `like' failed: "
@@ -1107,6 +1140,7 @@ AssertionResult TraverseTestBase::insertData() {
11071140
}
11081141
}
11091142
query.resize(query.size() - 3);
1143+
LOG(INFO) << query;
11101144
auto code = client_->execute(query, resp);
11111145
if (code != cpp2::ErrorCode::SUCCEEDED) {
11121146
return TestError() << "Insert `like' failed: "
@@ -1134,6 +1168,7 @@ AssertionResult TraverseTestBase::insertData() {
11341168
}
11351169
}
11361170
query.resize(query.size() - 3);
1171+
LOG(INFO) << query;
11371172
auto code = client_->execute(query, resp);
11381173
if (code != cpp2::ErrorCode::SUCCEEDED) {
11391174
return TestError() << "Insert `like' failed: "
@@ -1158,6 +1193,7 @@ AssertionResult TraverseTestBase::insertData() {
11581193
}
11591194
}
11601195
query.resize(query.size() - 3);
1196+
LOG(INFO) << query;
11611197
auto code = client_->execute(query, resp);
11621198
if (code != cpp2::ErrorCode::SUCCEEDED) {
11631199
return TestError() << "Insert `teammate' failed: " << static_cast<int32_t>(code);
@@ -1185,6 +1221,7 @@ AssertionResult TraverseTestBase::insertData() {
11851221
}
11861222
}
11871223
query.resize(query.size() - 3);
1224+
LOG(INFO) << query;
11881225
auto code = client_->execute(query, resp);
11891226
if (code != cpp2::ErrorCode::SUCCEEDED) {
11901227
return TestError() << "Insert `teammate' failed: " << static_cast<int32_t>(code);
@@ -1212,6 +1249,7 @@ AssertionResult TraverseTestBase::insertData() {
12121249
}
12131250
}
12141251
query.resize(query.size() - 3);
1252+
LOG(INFO) << query;
12151253
auto code = client_->execute(query, resp);
12161254
if (code != cpp2::ErrorCode::SUCCEEDED) {
12171255
return TestError() << "Insert `teammate' failed: " << static_cast<int32_t>(code);

src/parser/TraverseSentences.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,8 @@ std::string FindPathSentence::toString() const {
280280
buf += "FIND ";
281281
if (isShortest_) {
282282
buf += "SHORTEST PATH ";
283+
} else if (isNoLoop_) {
284+
buf += "NOLOOP PATH ";
283285
} else {
284286
buf += "ALL PATH ";
285287
}

src/parser/TraverseSentences.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -486,9 +486,10 @@ class FetchEdgesSentence final : public Sentence {
486486

487487
class FindPathSentence final : public Sentence {
488488
public:
489-
explicit FindPathSentence(bool isShortest) {
489+
explicit FindPathSentence(bool isShortest, bool isNoLoop) {
490490
kind_ = Kind::kFindPath;
491491
isShortest_ = isShortest;
492+
isNoLoop_ = isNoLoop;
492493
}
493494

494495
void setFrom(FromClause *clause) {
@@ -535,10 +536,15 @@ class FindPathSentence final : public Sentence {
535536
return isShortest_;
536537
}
537538

539+
bool isNoLoop() const {
540+
return isNoLoop_;
541+
}
542+
538543
std::string toString() const override;
539544

540545
private:
541546
bool isShortest_;
547+
bool isNoLoop_;
542548
std::unique_ptr<FromClause> from_;
543549
std::unique_ptr<ToClause> to_;
544550
std::unique_ptr<OverClause> over_;

src/parser/parser.yy

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ static constexpr size_t MAX_ABS_INTEGER = 9223372036854775808ULL;
117117
%token KW_ORDER KW_ASC KW_LIMIT KW_OFFSET KW_GROUP
118118
%token KW_DISTINCT KW_ALL KW_OF
119119
%token KW_BALANCE KW_LEADER
120-
%token KW_SHORTEST KW_PATH
120+
%token KW_SHORTEST KW_PATH KW_NOLOOP
121121
%token KW_IS KW_NULL KW_DEFAULT
122122
%token KW_SNAPSHOT KW_SNAPSHOTS KW_LOOKUP
123123
%token KW_JOBS KW_JOB KW_RECOVER KW_FLUSH KW_COMPACT KW_SUBMIT
@@ -310,6 +310,7 @@ unreserved_keyword
310310
| KW_STORAGE { $$ = new std::string("storage"); }
311311
| KW_ALL { $$ = new std::string("all"); }
312312
| KW_SHORTEST { $$ = new std::string("shortest"); }
313+
| KW_NOLOOP { $$ = new std::string("noloop"); }
313314
| KW_COUNT_DISTINCT { $$ = new std::string("count_distinct"); }
314315
| KW_CONTAINS { $$ = new std::string("contains"); }
315316
;
@@ -945,7 +946,7 @@ fetch_sentence
945946
find_path_sentence
946947
: KW_FIND KW_ALL KW_PATH from_clause to_clause over_clause find_path_upto_clause
947948
/* where_clause */ {
948-
auto *s = new FindPathSentence(false);
949+
auto *s = new FindPathSentence(false, false);
949950
s->setFrom($4);
950951
s->setTo($5);
951952
s->setOver($6);
@@ -955,14 +956,24 @@ find_path_sentence
955956
}
956957
| KW_FIND KW_SHORTEST KW_PATH from_clause to_clause over_clause find_path_upto_clause
957958
/* where_clause */ {
958-
auto *s = new FindPathSentence(true);
959+
auto *s = new FindPathSentence(true, true);
959960
s->setFrom($4);
960961
s->setTo($5);
961962
s->setOver($6);
962963
s->setStep($7);
963964
/* s->setWhere($8); */
964965
$$ = s;
965966
}
967+
| KW_FIND KW_NOLOOP KW_PATH from_clause to_clause over_clause find_path_upto_clause
968+
/* where_clause */ {
969+
auto *s = new FindPathSentence(false, true);
970+
s->setFrom($4);
971+
s->setTo($5);
972+
s->setOver($6);
973+
s->setStep($7);
974+
/* s->setWhere($8); */
975+
$$ = s;
976+
}
966977
;
967978

968979
find_path_upto_clause

src/parser/scanner.lex

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ OF ([Oo][Ff])
132132
DATA ([Dd][Aa][Tt][Aa])
133133
STOP ([Ss][Tt][Oo][Pp])
134134
SHORTEST ([Ss][Hh][Oo][Rr][Tt][Ee][Ss][Tt])
135+
NOLOOP ([Nn][Oo][Ll][Oo][Oo][Pp])
135136
PATH ([Pp][Aa][Tt][Hh])
136137
LIMIT ([Ll][Ii][Mm][Ii][Tt])
137138
OFFSET ([Oo][Ff][Ff][Ss][Ee][Tt])
@@ -306,6 +307,7 @@ RECOVER ([Rr][Ee][Cc][Oo][Vv][Ee][Rr])
306307
{GRAPH} { return TokenType::KW_GRAPH; }
307308
{META} { return TokenType::KW_META; }
308309
{STORAGE} { return TokenType::KW_STORAGE; }
310+
{NOLOOP} { return TokenType::KW_NOLOOP; }
309311
{SHORTEST} { return TokenType::KW_SHORTEST; }
310312
{CONTAINS} { return TokenType::KW_CONTAINS; }
311313

src/parser/test/ScannerTest.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,9 @@ TEST(Scanner, Basic) {
459459
CHECK_SEMANTIC_TYPE("SHORTEST", TokenType::KW_SHORTEST),
460460
CHECK_SEMANTIC_TYPE("Shortest", TokenType::KW_SHORTEST),
461461
CHECK_SEMANTIC_TYPE("shortest", TokenType::KW_SHORTEST),
462+
CHECK_SEMANTIC_TYPE("NOLOOP", TokenType::KW_NOLOOP),
463+
CHECK_SEMANTIC_TYPE("noloop", TokenType::KW_NOLOOP),
464+
CHECK_SEMANTIC_TYPE("NoLoop", TokenType::KW_NOLOOP),
462465
CHECK_SEMANTIC_TYPE("GRAPH", TokenType::KW_GRAPH),
463466
CHECK_SEMANTIC_TYPE("Graph", TokenType::KW_GRAPH),
464467
CHECK_SEMANTIC_TYPE("graph", TokenType::KW_GRAPH),

0 commit comments

Comments
 (0)