Separate query types in openCypher grammars

Summary: depends on D1640

Reviewers: teon.banek, llugovic

Reviewed By: teon.banek

Subscribers: pullbot

Differential Revision: https://phabricator.memgraph.io/D1643
This commit is contained in:
Marin Tomic 2018-10-09 15:03:45 +02:00
parent ca2106bb91
commit 695129f401
5 changed files with 55 additions and 48 deletions

View File

@ -33,6 +33,40 @@ antlrcpp::Any CypherMainVisitor::visitExplainQuery(
return query_; return query_;
} }
antlrcpp::Any CypherMainVisitor::visitCypherQuery(
MemgraphCypher::CypherQueryContext *ctx) {
query_ = storage_.query();
DCHECK(ctx->singleQuery()) << "Expected single query.";
query_->single_query_ = ctx->singleQuery()->accept(this).as<SingleQuery *>();
// Check that union and union all dont mix
bool has_union = false;
bool has_union_all = false;
for (auto *child : ctx->cypherUnion()) {
if (child->ALL()) {
has_union_all = true;
} else {
has_union = true;
}
if (has_union && has_union_all) {
throw SemanticException("Invalid combination of UNION and UNION ALL.");
}
query_->cypher_unions_.push_back(child->accept(this).as<CypherUnion *>());
}
return query_;
}
antlrcpp::Any CypherMainVisitor::visitIndexQuery(
MemgraphCypher::IndexQueryContext *ctx) {
query_ = storage_.query();
DCHECK(ctx->createIndex()) << "Expected CREATE INDEX";
query_->single_query_ = storage_.Create<SingleQuery>();
query_->single_query_->clauses_.emplace_back(
ctx->createIndex()->accept(this).as<CreateIndex *>());
return query_;
}
antlrcpp::Any CypherMainVisitor::visitAuthQuery( antlrcpp::Any CypherMainVisitor::visitAuthQuery(
MemgraphCypher::AuthQueryContext *ctx) { MemgraphCypher::AuthQueryContext *ctx) {
query_ = storage_.query(); query_ = storage_.query();
@ -67,30 +101,6 @@ antlrcpp::Any CypherMainVisitor::visitStreamQuery(
return query_; return query_;
} }
antlrcpp::Any CypherMainVisitor::visitRegularQuery(
MemgraphCypher::RegularQueryContext *ctx) {
query_ = storage_.query();
DCHECK(ctx->singleQuery()) << "Expected single query.";
query_->single_query_ = ctx->singleQuery()->accept(this).as<SingleQuery *>();
// Check that union and union all dont mix
bool has_union = false;
bool has_union_all = false;
for (auto *child : ctx->cypherUnion()) {
if (child->ALL()) {
has_union_all = true;
} else {
has_union = true;
}
if (has_union && has_union_all) {
throw SemanticException("Invalid combination of UNION and UNION ALL.");
}
query_->cypher_unions_.push_back(child->accept(this).as<CypherUnion *>());
}
return query_;
}
antlrcpp::Any CypherMainVisitor::visitCypherUnion( antlrcpp::Any CypherMainVisitor::visitCypherUnion(
MemgraphCypher::CypherUnionContext *ctx) { MemgraphCypher::CypherUnionContext *ctx) {
bool distinct = !ctx->ALL(); bool distinct = !ctx->ALL();
@ -227,10 +237,6 @@ antlrcpp::Any CypherMainVisitor::visitClause(
if (ctx->unwind()) { if (ctx->unwind()) {
return static_cast<Clause *>(ctx->unwind()->accept(this).as<Unwind *>()); return static_cast<Clause *>(ctx->unwind()->accept(this).as<Unwind *>());
} }
if (ctx->createIndex()) {
return static_cast<Clause *>(
ctx->createIndex()->accept(this).as<CreateIndex *>());
}
// TODO: implement other clauses. // TODO: implement other clauses.
throw utils::NotYetImplemented("clause '{}'", ctx->getText()); throw utils::NotYetImplemented("clause '{}'", ctx->getText());
return 0; return 0;

View File

@ -134,6 +134,18 @@ class CypherMainVisitor : public antlropencypher::MemgraphCypherBaseVisitor {
return expression; return expression;
} }
/**
* @return Query*
*/
antlrcpp::Any visitCypherQuery(
MemgraphCypher::CypherQueryContext *ctx) override;
/**
* @return Query*
*/
antlrcpp::Any visitIndexQuery(
MemgraphCypher::IndexQueryContext *ctx) override;
/** /**
* @return Query* * @return Query*
*/ */
@ -151,12 +163,6 @@ class CypherMainVisitor : public antlropencypher::MemgraphCypherBaseVisitor {
antlrcpp::Any visitStreamQuery( antlrcpp::Any visitStreamQuery(
MemgraphCypher::StreamQueryContext *ctx) override; MemgraphCypher::StreamQueryContext *ctx) override;
/**
* @return Query*
*/
antlrcpp::Any visitRegularQuery(
MemgraphCypher::RegularQueryContext *ctx) override;
/** /**
* @return CypherUnion* * @return CypherUnion*
*/ */

View File

@ -23,13 +23,16 @@ cypher : statement ';'? EOF ;
statement : query ; statement : query ;
query : regularQuery query : cypherQuery
| indexQuery
| explainQuery | explainQuery
; ;
explainQuery : EXPLAIN regularQuery ; explainQuery : EXPLAIN cypherQuery ;
regularQuery : singleQuery ( cypherUnion )* ; cypherQuery : singleQuery ( cypherUnion )* ;
indexQuery : createIndex ;
singleQuery : clause ( clause )* ; singleQuery : clause ( clause )* ;
@ -46,7 +49,6 @@ clause : cypherMatch
| remove | remove
| with | with
| cypherReturn | cypherReturn
| createIndex
; ;
cypherMatch : OPTIONAL? MATCH pattern where? ; cypherMatch : OPTIONAL? MATCH pattern where? ;

View File

@ -45,10 +45,11 @@ symbolicName : UnescapedSymbolicName
| memgraphCypherKeyword | memgraphCypherKeyword
; ;
query : regularQuery query : cypherQuery
| indexQuery
| explainQuery
| authQuery | authQuery
| streamQuery | streamQuery
| explainQuery
; ;
authQuery : createRole authQuery : createRole

View File

@ -1510,14 +1510,6 @@ TYPED_TEST(CypherMainVisitorTest, ClausesOrdering) {
SemanticException); SemanticException);
TypeParam("UNWIND [1,2,3] AS x CREATE (n) RETURN x"); TypeParam("UNWIND [1,2,3] AS x CREATE (n) RETURN x");
TypeParam("CREATE (n) WITH n UNWIND [1,2,3] AS x RETURN x"); TypeParam("CREATE (n) WITH n UNWIND [1,2,3] AS x RETURN x");
TypeParam("CREATE INDEX ON :a(b)");
ASSERT_THROW(TypeParam("CREATE INDEX ON :a(n) CREATE INDEX ON :b(c)"),
SemanticException);
ASSERT_THROW(TypeParam("CREATE (n) CREATE INDEX ON :a(n)"),
SemanticException);
ASSERT_THROW(TypeParam("CREATE INDEX ON :a(n) RETURN 2 + 2"),
SemanticException);
} }
TYPED_TEST(CypherMainVisitorTest, Merge) { TYPED_TEST(CypherMainVisitorTest, Merge) {