From a327bc7ab06b946a1d99cc3a011c83bfad8d0dbe Mon Sep 17 00:00:00 2001 From: xtcyclist <7731943+xtcyclist@users.noreply.github.com> Date: Wed, 7 Dec 2022 22:25:14 +0800 Subject: [PATCH 1/4] allow usage of aliases defined in previous matches. --- src/graph/validator/MatchValidator.cpp | 9 ++++++--- src/parser/Clauses.h | 22 +++++++++++++++++++++- tests/tck/features/match/With.feature | 13 +++++++++++++ 3 files changed, 40 insertions(+), 4 deletions(-) diff --git a/src/graph/validator/MatchValidator.cpp b/src/graph/validator/MatchValidator.cpp index eb5d998a374..8a359b7f2f1 100644 --- a/src/graph/validator/MatchValidator.cpp +++ b/src/graph/validator/MatchValidator.cpp @@ -379,7 +379,7 @@ Status MatchValidator::buildColumnsForAllNamedAliases(const std::vectorkind) { case CypherClauseKind::kUnwind: { auto unwindCtx = static_cast(boundary.get()); - columns->addColumn(makeColumn(unwindCtx->alias)); + columns->addColumn(makeColumn(unwindCtx->alias), true); break; } case CypherClauseKind::kWith: { @@ -390,7 +390,7 @@ Status MatchValidator::buildColumnsForAllNamedAliases(const std::vectorcolumns()) { if (!col->alias().empty()) { - columns->addColumn(makeColumn(col->alias())); + columns->addColumn(makeColumn(col->alias()), true); } } break; @@ -584,7 +584,10 @@ Status MatchValidator::validateWith(const WithClause *with, auto found = withClauseCtx.yield->aliasesAvailable.find(label); DCHECK(found != withClauseCtx.yield->aliasesAvailable.end()); if (!withClauseCtx.aliasesGenerated.emplace(col->alias(), found->second).second) { - return Status::SemanticError("`%s': Redefined alias", col->alias().c_str()); + auto columnFound = withClauseCtx.yield->yieldColumns->find(col->alias()); + if (!(columnFound != nullptr && columnFound->isMatched())) { + return Status::SemanticError("`%s': Redefined alias", col->alias().c_str()); + } } } else { if (!withClauseCtx.aliasesGenerated.emplace(col->alias(), aliasType).second) { diff --git a/src/parser/Clauses.h b/src/parser/Clauses.h index fd62eb20418..0d275996028 100644 --- a/src/parser/Clauses.h +++ b/src/parser/Clauses.h @@ -257,6 +257,7 @@ class YieldColumn final { explicit YieldColumn(Expression *expr, const std::string &alias = "") { expr_ = expr; alias_ = alias; + isMatched_ = false; } std::unique_ptr clone() const { @@ -285,9 +286,18 @@ class YieldColumn final { std::string toString() const; + void setMatched(bool isMatched) { + isMatched_ = isMatched; + } + + bool isMatched() const { + return isMatched_; + } + private: Expression *expr_{nullptr}; std::string alias_; + bool isMatched_; }; bool operator==(const YieldColumn &l, const YieldColumn &r); @@ -297,8 +307,9 @@ inline bool operator!=(const YieldColumn &l, const YieldColumn &r) { class YieldColumns final { public: - void addColumn(YieldColumn *field) { + void addColumn(YieldColumn *field, bool isMatched = false) { columns_.emplace_back(field); + field->setMatched(isMatched); } std::vector columns() const { @@ -346,6 +357,15 @@ class YieldColumns final { bool hasAgg() const; + YieldColumn *find(const std::string &name) const { + for (auto &col : columns_) { + if (name.compare(col->name()) == 0) { + return col.get(); + } + } + return nullptr; + } + private: std::vector> columns_; }; diff --git a/tests/tck/features/match/With.feature b/tests/tck/features/match/With.feature index 895853de8ba..c3905e8e5b5 100644 --- a/tests/tck/features/match/With.feature +++ b/tests/tck/features/match/With.feature @@ -387,3 +387,16 @@ Feature: With clause | [:teammate "Tim Duncan"->"Tony Parker" @0 {end_year: 2016, start_year: 2001}] | | [:like "Tim Duncan"->"Tony Parker" @0 {likeness: 95}] | | [:teammate "Tim Duncan"->"Danny Green" @0 {end_year: 2016, start_year: 2010}] | + + Scenario: with wildcard after multiple matches + When executing query: + """ + match (v0:player)--(v1:team) where v1.team.name == "Spurs" and v0.player.name == "Tim Duncan" + match (v:player) where v.player.name != "Tim Duncan" with v0 where v0.player.age > 0 + match (v0:player) + with * + return count(v0) + """ + Then the result should be, in order: + | count(v0) | + | 51 | From 8a889414ddec2a5342b66a96624127e85af5079b Mon Sep 17 00:00:00 2001 From: xtcyclist <7731943+xtcyclist@users.noreply.github.com> Date: Thu, 8 Dec 2022 09:56:37 +0800 Subject: [PATCH 2/4] update tck --- tests/tck/features/match/With.feature | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/tck/features/match/With.feature b/tests/tck/features/match/With.feature index c3905e8e5b5..a7172118722 100644 --- a/tests/tck/features/match/With.feature +++ b/tests/tck/features/match/With.feature @@ -378,7 +378,7 @@ Feature: With clause Scenario: with wildcard after unwind When executing query: """ - match p = (v0)-[e0]->(v1) where id(v0) in ["Tim Duncan"] unwind v0 as uv0 with * return e0 limit 5; + match p = (v0)-[e0]->(v1) where id(v0) in ["Tim Duncan"] unwind v0 as uv0 with * return e0; """ Then the result should be, in any order: | e0 | @@ -387,6 +387,8 @@ Feature: With clause | [:teammate "Tim Duncan"->"Tony Parker" @0 {end_year: 2016, start_year: 2001}] | | [:like "Tim Duncan"->"Tony Parker" @0 {likeness: 95}] | | [:teammate "Tim Duncan"->"Danny Green" @0 {end_year: 2016, start_year: 2010}] | + | [:teammate "Tim Duncan"->"Manu Ginobili" @0 {end_year: 2016, start_year: 2002}] | + | [:like "Tim Duncan"->"Manu Ginobili" @0 {likeness: 95}] | Scenario: with wildcard after multiple matches When executing query: From 9f1f348196c694fca7ff4e6ebebc211bd279ea20 Mon Sep 17 00:00:00 2001 From: xtcyclist <7731943+xtcyclist@users.noreply.github.com> Date: Thu, 8 Dec 2022 11:39:29 +0800 Subject: [PATCH 3/4] add a tck --- tests/tck/features/match/With.feature | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/tck/features/match/With.feature b/tests/tck/features/match/With.feature index a7172118722..98ed91f4c04 100644 --- a/tests/tck/features/match/With.feature +++ b/tests/tck/features/match/With.feature @@ -402,3 +402,14 @@ Feature: With clause Then the result should be, in order: | count(v0) | | 51 | + When executing query: + """ + match (v:player) + with v AS p + match (p) + with p AS v + match (v) + with * + return count (p) + """ + Then a SemanticError should be raised at runtime: Alias used but not defined: `p' \ No newline at end of file From 6602ea89461a95e3443a89edf28e6bb77f14ba6a Mon Sep 17 00:00:00 2001 From: xtcyclist <7731943+xtcyclist@users.noreply.github.com> Date: Thu, 8 Dec 2022 11:48:28 +0800 Subject: [PATCH 4/4] fix tck format --- tests/tck/features/match/With.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/tck/features/match/With.feature b/tests/tck/features/match/With.feature index 98ed91f4c04..7637c5b374f 100644 --- a/tests/tck/features/match/With.feature +++ b/tests/tck/features/match/With.feature @@ -412,4 +412,4 @@ Feature: With clause with * return count (p) """ - Then a SemanticError should be raised at runtime: Alias used but not defined: `p' \ No newline at end of file + Then a SemanticError should be raised at runtime: Alias used but not defined: `p'