Skip to content

Commit

Permalink
Allow usage of aliases defined in previous matches. (#5021)
Browse files Browse the repository at this point in the history
* allow usage of aliases defined in previous matches.

* update tck

* add a tck

* fix tck format
  • Loading branch information
xtcyclist authored Dec 8, 2022
1 parent 42f5de3 commit 5057eeb
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 5 deletions.
9 changes: 6 additions & 3 deletions src/graph/validator/MatchValidator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,7 @@ Status MatchValidator::buildColumnsForAllNamedAliases(const std::vector<QueryPar
switch (boundary->kind) {
case CypherClauseKind::kUnwind: {
auto unwindCtx = static_cast<const UnwindClauseContext *>(boundary.get());
columns->addColumn(makeColumn(unwindCtx->alias));
columns->addColumn(makeColumn(unwindCtx->alias), true);
break;
}
case CypherClauseKind::kWith: {
Expand All @@ -390,7 +390,7 @@ Status MatchValidator::buildColumnsForAllNamedAliases(const std::vector<QueryPar
}
for (auto &col : yieldColumns->columns()) {
if (!col->alias().empty()) {
columns->addColumn(makeColumn(col->alias()));
columns->addColumn(makeColumn(col->alias()), true);
}
}
break;
Expand Down Expand Up @@ -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) {
Expand Down
22 changes: 21 additions & 1 deletion src/parser/Clauses.h
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,7 @@ class YieldColumn final {
explicit YieldColumn(Expression *expr, const std::string &alias = "") {
expr_ = expr;
alias_ = alias;
isMatched_ = false;
}

std::unique_ptr<YieldColumn> clone() const {
Expand Down Expand Up @@ -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);
Expand All @@ -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<YieldColumn *> columns() const {
Expand Down Expand Up @@ -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<std::unique_ptr<YieldColumn>> columns_;
};
Expand Down
28 changes: 27 additions & 1 deletion tests/tck/features/match/With.feature
Original file line number Diff line number Diff line change
Expand Up @@ -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 |
Expand All @@ -387,3 +387,29 @@ 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:
"""
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 |
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'

0 comments on commit 5057eeb

Please sign in to comment.