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

Skip to content

Commit 8fff4aa

Browse files
authored
Fix dup alias in MATCH (vesoft-inc#4940)
* Fix dup alias in MATCH * Fix UT * Fix edge case
1 parent 4731ed9 commit 8fff4aa

File tree

3 files changed

+92
-12
lines changed

3 files changed

+92
-12
lines changed

src/graph/planner/match/MatchPathPlanner.cpp

Lines changed: 35 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -254,10 +254,12 @@ Status MatchPathPlanner::leftExpandFromNode(
254254
for (size_t i = startIndex; i > 0; --i) {
255255
auto& node = nodeInfos[i];
256256
auto& dst = nodeInfos[i - 1];
257-
bool expandInto = nodeAliasesSeenInPattern.find(dst.alias) != nodeAliasesSeenInPattern.end();
257+
258258
if (!node.anonymous) {
259259
nodeAliasesSeenInPattern.emplace(node.alias);
260260
}
261+
bool expandInto = nodeAliasesSeenInPattern.find(dst.alias) != nodeAliasesSeenInPattern.end();
262+
261263
auto& edge = edgeInfos[i - 1];
262264
auto traverse = Traverse::make(qctx, subplan.root, spaceId);
263265
traverse->setSrc(nextTraverseStart);
@@ -292,19 +294,26 @@ Status MatchPathPlanner::leftExpandFromNode(
292294
}
293295
}
294296

295-
auto& node = nodeInfos.front();
296-
if (!node.anonymous) {
297-
nodeAliasesSeenInPattern.emplace(node.alias);
297+
auto& lastNode = nodeInfos.front();
298+
299+
bool duppedLastAlias =
300+
nodeAliasesSeenInPattern.find(lastNode.alias) != nodeAliasesSeenInPattern.end() &&
301+
nodeAliasesSeenInPattern.size() > 1;
302+
// If the the last alias has been presented in the pattern, we could emit the AppendVertices node
303+
// because the same alias always presents in the same entity.
304+
if (duppedLastAlias) {
305+
return Status::OK();
298306
}
307+
299308
auto appendV = AppendVertices::make(qctx, subplan.root, spaceId);
300309
auto vertexProps = SchemaUtil::getAllVertexProp(qctx, spaceId, true);
301310
NG_RETURN_IF_ERROR(vertexProps);
302311
appendV->setVertexProps(std::move(vertexProps).value());
303312
appendV->setSrc(nextTraverseStart);
304-
appendV->setVertexFilter(genVertexFilter(node));
313+
appendV->setVertexFilter(genVertexFilter(lastNode));
305314
appendV->setDedup();
306315
appendV->setTrackPrevPath(!edgeInfos.empty());
307-
appendV->setColNames(genAppendVColNames(subplan.root->colNames(), node, !edgeInfos.empty()));
316+
appendV->setColNames(genAppendVColNames(subplan.root->colNames(), lastNode, !edgeInfos.empty()));
308317
subplan.root = appendV;
309318

310319
return Status::OK();
@@ -324,10 +333,12 @@ Status MatchPathPlanner::rightExpandFromNode(
324333
for (size_t i = startIndex; i < edgeInfos.size(); ++i) {
325334
auto& node = nodeInfos[i];
326335
auto& dst = nodeInfos[i + 1];
327-
bool expandInto = nodeAliasesSeenInPattern.find(dst.alias) != nodeAliasesSeenInPattern.end();
336+
328337
if (!node.anonymous) {
329338
nodeAliasesSeenInPattern.emplace(node.alias);
330339
}
340+
bool expandInto = nodeAliasesSeenInPattern.find(dst.alias) != nodeAliasesSeenInPattern.end();
341+
331342
auto& edge = edgeInfos[i];
332343
auto traverse = Traverse::make(qctx, subplan.root, spaceId);
333344
traverse->setSrc(nextTraverseStart);
@@ -355,19 +366,31 @@ Status MatchPathPlanner::rightExpandFromNode(
355366
}
356367
}
357368

358-
auto& node = nodeInfos.back();
359-
if (!node.anonymous) {
360-
nodeAliasesSeenInPattern.emplace(node.alias);
369+
auto& lastNode = nodeInfos.back();
370+
371+
bool duppedLastAlias =
372+
nodeAliasesSeenInPattern.find(lastNode.alias) != nodeAliasesSeenInPattern.end() &&
373+
nodeAliasesSeenInPattern.size() > 1;
374+
375+
if (!lastNode.anonymous) {
376+
nodeAliasesSeenInPattern.emplace(lastNode.alias);
361377
}
378+
379+
// If the the last alias has been presented in the pattern, we could emit the AppendVertices node
380+
// because the same alias always presents in the same entity.
381+
if (duppedLastAlias) {
382+
return Status::OK();
383+
}
384+
362385
auto appendV = AppendVertices::make(qctx, subplan.root, spaceId);
363386
auto vertexProps = SchemaUtil::getAllVertexProp(qctx, spaceId, true);
364387
NG_RETURN_IF_ERROR(vertexProps);
365388
appendV->setVertexProps(std::move(vertexProps).value());
366389
appendV->setSrc(nextTraverseStart);
367-
appendV->setVertexFilter(genVertexFilter(node));
390+
appendV->setVertexFilter(genVertexFilter(lastNode));
368391
appendV->setDedup();
369392
appendV->setTrackPrevPath(!edgeInfos.empty());
370-
appendV->setColNames(genAppendVColNames(subplan.root->colNames(), node, !edgeInfos.empty()));
393+
appendV->setColNames(genAppendVColNames(subplan.root->colNames(), lastNode, !edgeInfos.empty()));
371394
subplan.root = appendV;
372395

373396
return Status::OK();

src/graph/validator/test/MatchValidatorTest.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -535,6 +535,18 @@ TEST_F(MatchValidatorTest, validateAlias) {
535535
std::string(result.message()),
536536
"SemanticError: keywords: vertex and edge are not supported in return clause `EDGE AS b'");
537537
}
538+
// Duplicate alias at the end of the pattern
539+
{
540+
std::string query = "MATCH (v :person{name:\"Tim Duncan\"})-[e]->(v2)-[]->(v2) RETURN e";
541+
std::vector<PlanNode::Kind> expected = {PlanNode::Kind::kProject,
542+
PlanNode::Kind::kProject,
543+
PlanNode::Kind::kFilter,
544+
PlanNode::Kind::kTraverse,
545+
PlanNode::Kind::kTraverse,
546+
PlanNode::Kind::kIndexScan,
547+
PlanNode::Kind::kStart};
548+
EXPECT_TRUE(checkResult(query, expected));
549+
}
538550
}
539551

540552
} // namespace graph
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# Copyright (c) 2022 vesoft inc. All rights reserved.
2+
#
3+
# This source code is licensed under Apache 2.0 License.
4+
# Issue link: https://github.com/vesoft-inc/nebula-ent/issues/1605
5+
Feature: Duplicate alias in MATCH
6+
7+
Background:
8+
Given a graph with space named "nba"
9+
10+
Scenario: Duplicate node alias
11+
# expand from left to right
12+
When executing query:
13+
"""
14+
MATCH (n0)-[]->(n1)-[]->(n1) WHERE (id(n0) == "Tim Duncan") RETURN n1
15+
"""
16+
Then the result should be, in any order:
17+
| n1 |
18+
# expand from right to left
19+
When executing query:
20+
"""
21+
MATCH (n1)<-[]-(n1)<-[]-(n0) WHERE (id(n0) == "Tim Duncan") RETURN n1
22+
"""
23+
Then the result should be, in any order:
24+
| n1 |
25+
When executing query:
26+
"""
27+
MATCH (n0)-[]->(n1)-[]->(n1)-[]->(n1) WHERE (id(n0) == "Tim Duncan") RETURN n1
28+
"""
29+
Then the result should be, in any order:
30+
| n1 |
31+
When executing query:
32+
"""
33+
MATCH (n0)-[]->(n1)-[]->(n1)-[]->(n1)-[]->(n1) WHERE (id(n0) == "Tim Duncan") RETURN n1
34+
"""
35+
Then the result should be, in any order:
36+
| n1 |
37+
38+
Scenario: Duplicate node alias expand both direction
39+
# expand from middle to both sides
40+
When executing query:
41+
"""
42+
MATCH (n1)-[]->(n0)-[]->(n1)-[]->(n1)-[]->(n1) WHERE (id(n0) == "Tim Duncan") RETURN n1
43+
"""
44+
Then the result should be, in any order:
45+
| n1 |

0 commit comments

Comments
 (0)