Raise if MATCH is after OPTIONAL MATCH

Reviewers: florijan, mislav.bradac

Reviewed By: mislav.bradac

Subscribers: pullbot

Differential Revision: https://phabricator.memgraph.io/D383
This commit is contained in:
Teon Banek 2017-05-19 16:01:01 +02:00
parent 6a027ea3b2
commit 28fbeb8e9d
2 changed files with 18 additions and 2 deletions

View File

@ -41,11 +41,21 @@ antlrcpp::Any CypherMainVisitor::visitSingleQuery(
// consecutive SET clauses are undefined behaviour in neo4j.
bool has_update = false;
bool has_return = false;
bool has_optional_match = false;
for (Clause *clause : query_->clauses_) {
if (dynamic_cast<Match *>(clause) || dynamic_cast<Unwind *>(clause)) {
if (dynamic_cast<Unwind *>(clause)) {
if (has_update || has_return) {
throw SemanticException("Unwind can't be after return or update clause");
}
} else if (auto *match = dynamic_cast<Match *>(clause)) {
if (has_update || has_return) {
throw SemanticException("Match can't be after return or update clause");
}
if (match->optional_) {
has_optional_match = true;
} else if (has_optional_match) {
throw SemanticException("Match can't be after optional match");
}
} else if (dynamic_cast<Create *>(clause) ||
dynamic_cast<Delete *>(clause) ||
dynamic_cast<SetProperty *>(clause) ||
@ -67,7 +77,7 @@ antlrcpp::Any CypherMainVisitor::visitSingleQuery(
if (has_return) {
throw SemanticException("Return can't be before with");
}
has_update = has_return = false;
has_update = has_return = has_optional_match = false;
} else {
debug_assert(false, "Can't happen");
}

View File

@ -1095,6 +1095,12 @@ TEST(CypherMainVisitorTest, ClausesOrdering) {
ASSERT_THROW(AstGenerator("RETURN 1 AS n UNWIND n AS x RETURN x"),
SemanticException);
ASSERT_THROW(AstGenerator("OPTIONAL MATCH (n) MATCH (m) RETURN n, m"),
SemanticException);
AstGenerator("OPTIONAL MATCH (n) WITH n MATCH (m) RETURN n, m");
AstGenerator("OPTIONAL MATCH (n) OPTIONAL MATCH (m) RETURN n, m");
AstGenerator("MATCH (n) OPTIONAL MATCH (m) RETURN n, m");
AstGenerator("CREATE (n)");
ASSERT_THROW(AstGenerator("SET n:x MATCH (n) RETURN n"), SemanticException);
AstGenerator("REMOVE n.x SET n.x = 1");