Separate auth/stream queries from rest of cypher

Summary: first step for a cleaner query front end that might be easier to open source

Reviewers: teon.banek

Reviewed By: teon.banek

Subscribers: pullbot

Differential Revision: https://phabricator.memgraph.io/D1511
This commit is contained in:
Marin Tomic 2018-07-27 13:29:16 +02:00
parent 2ecb660790
commit 9a6801cb98
12 changed files with 521 additions and 487 deletions

View File

@ -160,15 +160,15 @@ include_directories(SYSTEM ${LIBRDKAFKA_INCLUDE_DIR})
# openCypher parser ----------------------------------------------------------- # openCypher parser -----------------------------------------------------------
set(opencypher_frontend ${CMAKE_SOURCE_DIR}/src/query/frontend/opencypher) set(opencypher_frontend ${CMAKE_SOURCE_DIR}/src/query/frontend/opencypher)
set(opencypher_generated ${opencypher_frontend}/generated) set(opencypher_generated ${opencypher_frontend}/generated)
set(opencypher_lexer_grammar ${opencypher_frontend}/grammar/CypherLexer.g4) set(opencypher_lexer_grammar ${opencypher_frontend}/grammar/MemgraphCypherLexer.g4)
set(opencypher_parser_grammar ${opencypher_frontend}/grammar/CypherParser.g4) set(opencypher_parser_grammar ${opencypher_frontend}/grammar/MemgraphCypher.g4)
# enumerate all files that are generated from antlr # enumerate all files that are generated from antlr
set(antlr_opencypher_generated_src set(antlr_opencypher_generated_src
${opencypher_generated}/CypherLexer.cpp ${opencypher_generated}/MemgraphCypherLexer.cpp
${opencypher_generated}/CypherParser.cpp ${opencypher_generated}/MemgraphCypher.cpp
${opencypher_generated}/CypherParserBaseVisitor.cpp ${opencypher_generated}/MemgraphCypherBaseVisitor.cpp
${opencypher_generated}/CypherParserVisitor.cpp ${opencypher_generated}/MemgraphCypherVisitor.cpp
) )
# Provide a command to generate sources if missing. If this were a # Provide a command to generate sources if missing. If this were a

View File

@ -24,8 +24,45 @@ namespace query::frontend {
const std::string CypherMainVisitor::kAnonPrefix = "anon"; const std::string CypherMainVisitor::kAnonPrefix = "anon";
antlrcpp::Any CypherMainVisitor::visitAuthQuery(
MemgraphCypher::AuthQueryContext *ctx) {
query_ = storage_.query();
query_->single_query_ = storage_.Create<SingleQuery>();
Clause *clause = nullptr;
if (ctx->modifyUser()) {
clause = ctx->modifyUser()->accept(this).as<ModifyUser *>();
} else if (ctx->dropUser()) {
clause = ctx->dropUser()->accept(this).as<DropUser *>();
}
query_->single_query_->clauses_ = {clause};
return query_;
}
antlrcpp::Any CypherMainVisitor::visitStreamQuery(
MemgraphCypher::StreamQueryContext *ctx) {
query_ = storage_.query();
query_->single_query_ = storage_.Create<SingleQuery>();
Clause *clause = nullptr;
if (ctx->createStream()) {
clause = ctx->createStream()->accept(this).as<CreateStream *>();
} else if (ctx->dropStream()) {
clause = ctx->dropStream()->accept(this).as<DropStream *>();
} else if (ctx->showStreams()) {
clause = ctx->showStreams()->accept(this).as<ShowStreams *>();
} else if (ctx->startStopStream()) {
clause = ctx->startStopStream()->accept(this).as<StartStopStream *>();
} else if (ctx->startStopAllStreams()) {
clause =
ctx->startStopAllStreams()->accept(this).as<StartStopAllStreams *>();
} else if (ctx->testStream()) {
clause = ctx->testStream()->accept(this).as<TestStream *>();
}
query_->single_query_->clauses_ = {clause};
return query_;
}
antlrcpp::Any CypherMainVisitor::visitRegularQuery( antlrcpp::Any CypherMainVisitor::visitRegularQuery(
CypherParser::RegularQueryContext *ctx) { MemgraphCypher::RegularQueryContext *ctx) {
query_ = storage_.query(); query_ = storage_.query();
DCHECK(ctx->singleQuery()) << "Expected single query."; DCHECK(ctx->singleQuery()) << "Expected single query.";
query_->single_query_ = ctx->singleQuery()->accept(this).as<SingleQuery *>(); query_->single_query_ = ctx->singleQuery()->accept(this).as<SingleQuery *>();
@ -49,7 +86,7 @@ antlrcpp::Any CypherMainVisitor::visitRegularQuery(
} }
antlrcpp::Any CypherMainVisitor::visitCypherUnion( antlrcpp::Any CypherMainVisitor::visitCypherUnion(
CypherParser::CypherUnionContext *ctx) { MemgraphCypher::CypherUnionContext *ctx) {
bool distinct = !ctx->ALL(); bool distinct = !ctx->ALL();
auto *cypher_union = storage_.Create<CypherUnion>(distinct); auto *cypher_union = storage_.Create<CypherUnion>(distinct);
DCHECK(ctx->singleQuery()) << "Expected single query."; DCHECK(ctx->singleQuery()) << "Expected single query.";
@ -59,7 +96,7 @@ antlrcpp::Any CypherMainVisitor::visitCypherUnion(
} }
antlrcpp::Any CypherMainVisitor::visitSingleQuery( antlrcpp::Any CypherMainVisitor::visitSingleQuery(
CypherParser::SingleQueryContext *ctx) { MemgraphCypher::SingleQueryContext *ctx) {
auto *single_query = storage_.Create<SingleQuery>(); auto *single_query = storage_.Create<SingleQuery>();
for (auto *child : ctx->clause()) { for (auto *child : ctx->clause()) {
antlrcpp::Any got = child->accept(this); antlrcpp::Any got = child->accept(this);
@ -81,8 +118,6 @@ antlrcpp::Any CypherMainVisitor::visitSingleQuery(
bool has_return = false; bool has_return = false;
bool has_optional_match = false; bool has_optional_match = false;
bool has_create_index = false; bool has_create_index = false;
bool has_modify_user = false;
bool has_stream_clause = false;
for (Clause *clause : single_query->clauses_) { for (Clause *clause : single_query->clauses_) {
if (dynamic_cast<Unwind *>(clause)) { if (dynamic_cast<Unwind *>(clause)) {
@ -128,34 +163,11 @@ antlrcpp::Any CypherMainVisitor::visitSingleQuery(
"CreateIndex must be only clause in the query."); "CreateIndex must be only clause in the query.");
} }
has_create_index = true; has_create_index = true;
} else if (dynamic_cast<ModifyUser *>(clause)) {
has_modify_user = true;
if (single_query->clauses_.size() != 1U) {
throw SemanticException("ModifyUser must be only clause in the query.");
}
} else if (dynamic_cast<DropUser *>(clause)) {
has_modify_user = true;
if (single_query->clauses_.size() != 1U) {
throw SemanticException("DropUser must be only clause in the query.");
}
} else if (dynamic_cast<CreateStream *>(clause) ||
dynamic_cast<DropStream *>(clause) ||
dynamic_cast<ShowStreams *>(clause) ||
dynamic_cast<StartStopStream *>(clause) ||
dynamic_cast<StartStopAllStreams *>(clause) ||
dynamic_cast<TestStream *>(clause)) {
// If there is stream clause then there shouldn't be anything else.
if (single_query->clauses_.size() != 1U) {
throw SemanticException(
"Stream clause must be the only clause in the query.");
}
has_stream_clause = true;
} else { } else {
DLOG(FATAL) << "Can't happen"; DLOG(FATAL) << "Can't happen";
} }
} }
if (!has_update && !has_return && !has_create_index && !has_modify_user && if (!has_update && !has_return && !has_create_index) {
!has_stream_clause) {
throw SemanticException( throw SemanticException(
"Query should either create or update something, or return results!"); "Query should either create or update something, or return results!");
} }
@ -174,7 +186,8 @@ antlrcpp::Any CypherMainVisitor::visitSingleQuery(
return single_query; return single_query;
} }
antlrcpp::Any CypherMainVisitor::visitClause(CypherParser::ClauseContext *ctx) { antlrcpp::Any CypherMainVisitor::visitClause(
MemgraphCypher::ClauseContext *ctx) {
if (ctx->cypherReturn()) { if (ctx->cypherReturn()) {
return static_cast<Clause *>( return static_cast<Clause *>(
ctx->cypherReturn()->accept(this).as<Return *>()); ctx->cypherReturn()->accept(this).as<Return *>());
@ -211,45 +224,13 @@ antlrcpp::Any CypherMainVisitor::visitClause(CypherParser::ClauseContext *ctx) {
return static_cast<Clause *>( return static_cast<Clause *>(
ctx->createIndex()->accept(this).as<CreateIndex *>()); ctx->createIndex()->accept(this).as<CreateIndex *>());
} }
if (ctx->modifyUser()) {
return static_cast<Clause *>(
ctx->modifyUser()->accept(this).as<ModifyUser *>());
}
if (ctx->dropUser()) {
return static_cast<Clause *>(
ctx->dropUser()->accept(this).as<DropUser *>());
}
if (ctx->createStream()) {
return static_cast<Clause *>(
ctx->createStream()->accept(this).as<CreateStream *>());
}
if (ctx->dropStream()) {
return static_cast<Clause *>(
ctx->dropStream()->accept(this).as<DropStream *>());
}
if (ctx->showStreams()) {
return static_cast<Clause *>(
ctx->showStreams()->accept(this).as<ShowStreams *>());
}
if (ctx->startStopStream()) {
return static_cast<Clause *>(
ctx->startStopStream()->accept(this).as<StartStopStream *>());
}
if (ctx->startStopAllStreams()) {
return static_cast<Clause *>(
ctx->startStopAllStreams()->accept(this).as<StartStopAllStreams *>());
}
if (ctx->testStream()) {
return static_cast<Clause *>(
ctx->testStream()->accept(this).as<TestStream *>());
}
// TODO: implement other clauses. // TODO: implement other clauses.
throw utils::NotYetImplemented("clause '{}'", ctx->getText()); throw utils::NotYetImplemented("clause '{}'", ctx->getText());
return 0; return 0;
} }
antlrcpp::Any CypherMainVisitor::visitCypherMatch( antlrcpp::Any CypherMainVisitor::visitCypherMatch(
CypherParser::CypherMatchContext *ctx) { MemgraphCypher::CypherMatchContext *ctx) {
auto *match = storage_.Create<Match>(); auto *match = storage_.Create<Match>();
match->optional_ = !!ctx->OPTIONAL(); match->optional_ = !!ctx->OPTIONAL();
if (ctx->where()) { if (ctx->where()) {
@ -259,7 +240,8 @@ antlrcpp::Any CypherMainVisitor::visitCypherMatch(
return match; return match;
} }
antlrcpp::Any CypherMainVisitor::visitCreate(CypherParser::CreateContext *ctx) { antlrcpp::Any CypherMainVisitor::visitCreate(
MemgraphCypher::CreateContext *ctx) {
auto *create = storage_.Create<Create>(); auto *create = storage_.Create<Create>();
create->patterns_ = ctx->pattern()->accept(this).as<std::vector<Pattern *>>(); create->patterns_ = ctx->pattern()->accept(this).as<std::vector<Pattern *>>();
return create; return create;
@ -269,7 +251,7 @@ antlrcpp::Any CypherMainVisitor::visitCreate(CypherParser::CreateContext *ctx) {
* @return CreateIndex* * @return CreateIndex*
*/ */
antlrcpp::Any CypherMainVisitor::visitCreateIndex( antlrcpp::Any CypherMainVisitor::visitCreateIndex(
CypherParser::CreateIndexContext *ctx) { MemgraphCypher::CreateIndexContext *ctx) {
std::pair<std::string, storage::Property> key = std::pair<std::string, storage::Property> key =
ctx->propertyKeyName()->accept(this); ctx->propertyKeyName()->accept(this);
return storage_.Create<CreateIndex>( return storage_.Create<CreateIndex>(
@ -280,10 +262,10 @@ antlrcpp::Any CypherMainVisitor::visitCreateIndex(
* @return ModifyUser* * @return ModifyUser*
*/ */
antlrcpp::Any CypherMainVisitor::visitModifyUser( antlrcpp::Any CypherMainVisitor::visitModifyUser(
CypherParser::ModifyUserContext *ctx) { MemgraphCypher::ModifyUserContext *ctx) {
std::string username(ctx->userName()->getText()); std::string username(ctx->userName->getText());
Expression *password = nullptr; Expression *password = nullptr;
bool is_create = static_cast<bool>(ctx->createUser()); bool is_create = static_cast<bool>(ctx->CREATE());
for (auto option : ctx->modifyUserOption()) { for (auto option : ctx->modifyUserOption()) {
if (option->passwordOption()) { if (option->passwordOption()) {
if (password) { if (password) {
@ -301,7 +283,7 @@ antlrcpp::Any CypherMainVisitor::visitModifyUser(
* @return Expression* * @return Expression*
*/ */
antlrcpp::Any CypherMainVisitor::visitPasswordOption( antlrcpp::Any CypherMainVisitor::visitPasswordOption(
CypherParser::PasswordOptionContext *ctx) { MemgraphCypher::PasswordOptionContext *ctx) {
if (!ctx->literal()->StringLiteral() && !ctx->literal()->CYPHERNULL()) { if (!ctx->literal()->StringLiteral() && !ctx->literal()->CYPHERNULL()) {
throw SyntaxException("password should be a string literal or NULL"); throw SyntaxException("password should be a string literal or NULL");
} }
@ -312,9 +294,9 @@ antlrcpp::Any CypherMainVisitor::visitPasswordOption(
* @return DropUser* * @return DropUser*
*/ */
antlrcpp::Any CypherMainVisitor::visitDropUser( antlrcpp::Any CypherMainVisitor::visitDropUser(
CypherParser::DropUserContext *ctx) { MemgraphCypher::DropUserContext *ctx) {
std::vector<std::string> usernames; std::vector<std::string> usernames;
for (auto username_ptr : ctx->userName()) for (auto username_ptr : ctx->userName)
usernames.emplace_back(username_ptr->getText()); usernames.emplace_back(username_ptr->getText());
return storage_.Create<DropUser>(usernames); return storage_.Create<DropUser>(usernames);
} }
@ -323,7 +305,7 @@ antlrcpp::Any CypherMainVisitor::visitDropUser(
* @return CreateStream* * @return CreateStream*
*/ */
antlrcpp::Any CypherMainVisitor::visitCreateStream( antlrcpp::Any CypherMainVisitor::visitCreateStream(
CypherParser::CreateStreamContext *ctx) { MemgraphCypher::CreateStreamContext *ctx) {
std::string stream_name(ctx->streamName()->getText()); std::string stream_name(ctx->streamName()->getText());
if (!ctx->streamUri->StringLiteral()) { if (!ctx->streamUri->StringLiteral()) {
throw SyntaxException("Stream URI should be a string literal!"); throw SyntaxException("Stream URI should be a string literal!");
@ -359,7 +341,7 @@ antlrcpp::Any CypherMainVisitor::visitCreateStream(
* @return Expression* * @return Expression*
*/ */
antlrcpp::Any CypherMainVisitor::visitBatchIntervalOption( antlrcpp::Any CypherMainVisitor::visitBatchIntervalOption(
CypherParser::BatchIntervalOptionContext *ctx) { MemgraphCypher::BatchIntervalOptionContext *ctx) {
if (!ctx->literal()->numberLiteral() || if (!ctx->literal()->numberLiteral() ||
!ctx->literal()->numberLiteral()->integerLiteral()) { !ctx->literal()->numberLiteral()->integerLiteral()) {
throw SyntaxException("Batch interval should be an integer literal!"); throw SyntaxException("Batch interval should be an integer literal!");
@ -371,7 +353,7 @@ antlrcpp::Any CypherMainVisitor::visitBatchIntervalOption(
* @return Expression* * @return Expression*
*/ */
antlrcpp::Any CypherMainVisitor::visitBatchSizeOption( antlrcpp::Any CypherMainVisitor::visitBatchSizeOption(
CypherParser::BatchSizeOptionContext *ctx) { MemgraphCypher::BatchSizeOptionContext *ctx) {
if (!ctx->literal()->numberLiteral() || if (!ctx->literal()->numberLiteral() ||
!ctx->literal()->numberLiteral()->integerLiteral()) { !ctx->literal()->numberLiteral()->integerLiteral()) {
throw SyntaxException("Batch size should be an integer literal!"); throw SyntaxException("Batch size should be an integer literal!");
@ -383,7 +365,7 @@ antlrcpp::Any CypherMainVisitor::visitBatchSizeOption(
* @return DropStream* * @return DropStream*
*/ */
antlrcpp::Any CypherMainVisitor::visitDropStream( antlrcpp::Any CypherMainVisitor::visitDropStream(
CypherParser::DropStreamContext *ctx) { MemgraphCypher::DropStreamContext *ctx) {
return storage_.Create<DropStream>(std::string(ctx->streamName()->getText())); return storage_.Create<DropStream>(std::string(ctx->streamName()->getText()));
} }
@ -391,7 +373,7 @@ antlrcpp::Any CypherMainVisitor::visitDropStream(
* @return ShowStreams* * @return ShowStreams*
*/ */
antlrcpp::Any CypherMainVisitor::visitShowStreams( antlrcpp::Any CypherMainVisitor::visitShowStreams(
CypherParser::ShowStreamsContext *ctx) { MemgraphCypher::ShowStreamsContext *ctx) {
return storage_.Create<ShowStreams>(); return storage_.Create<ShowStreams>();
} }
@ -399,7 +381,7 @@ antlrcpp::Any CypherMainVisitor::visitShowStreams(
* @return StartStopStream* * @return StartStopStream*
*/ */
antlrcpp::Any CypherMainVisitor::visitStartStopStream( antlrcpp::Any CypherMainVisitor::visitStartStopStream(
CypherParser::StartStopStreamContext *ctx) { MemgraphCypher::StartStopStreamContext *ctx) {
std::string stream_name(std::string(ctx->streamName()->getText())); std::string stream_name(std::string(ctx->streamName()->getText()));
bool is_start = static_cast<bool>(ctx->START()); bool is_start = static_cast<bool>(ctx->START());
Expression *limit_batches = nullptr; Expression *limit_batches = nullptr;
@ -418,7 +400,7 @@ antlrcpp::Any CypherMainVisitor::visitStartStopStream(
* @return Expression* * @return Expression*
*/ */
antlrcpp::Any CypherMainVisitor::visitLimitBatchesOption( antlrcpp::Any CypherMainVisitor::visitLimitBatchesOption(
CypherParser::LimitBatchesOptionContext *ctx) { MemgraphCypher::LimitBatchesOptionContext *ctx) {
if (!ctx->literal()->numberLiteral() || if (!ctx->literal()->numberLiteral() ||
!ctx->literal()->numberLiteral()->integerLiteral()) { !ctx->literal()->numberLiteral()->integerLiteral()) {
throw SyntaxException("Batch limit should be an integer literal!"); throw SyntaxException("Batch limit should be an integer literal!");
@ -430,13 +412,13 @@ antlrcpp::Any CypherMainVisitor::visitLimitBatchesOption(
* @return StartStopAllStreams* * @return StartStopAllStreams*
*/ */
antlrcpp::Any CypherMainVisitor::visitStartStopAllStreams( antlrcpp::Any CypherMainVisitor::visitStartStopAllStreams(
CypherParser::StartStopAllStreamsContext *ctx) { MemgraphCypher::StartStopAllStreamsContext *ctx) {
bool is_start = static_cast<bool>(ctx->START()); bool is_start = static_cast<bool>(ctx->START());
return storage_.Create<StartStopAllStreams>(is_start); return storage_.Create<StartStopAllStreams>(is_start);
} }
antlrcpp::Any CypherMainVisitor::visitCypherReturn( antlrcpp::Any CypherMainVisitor::visitCypherReturn(
CypherParser::CypherReturnContext *ctx) { MemgraphCypher::CypherReturnContext *ctx) {
auto *return_clause = storage_.Create<Return>(); auto *return_clause = storage_.Create<Return>();
return_clause->body_ = ctx->returnBody()->accept(this); return_clause->body_ = ctx->returnBody()->accept(this);
if (ctx->DISTINCT()) { if (ctx->DISTINCT()) {
@ -449,7 +431,7 @@ antlrcpp::Any CypherMainVisitor::visitCypherReturn(
* @return TestStream* * @return TestStream*
*/ */
antlrcpp::Any CypherMainVisitor::visitTestStream( antlrcpp::Any CypherMainVisitor::visitTestStream(
CypherParser::TestStreamContext *ctx) { MemgraphCypher::TestStreamContext *ctx) {
std::string stream_name(std::string(ctx->streamName()->getText())); std::string stream_name(std::string(ctx->streamName()->getText()));
Expression *limit_batches = nullptr; Expression *limit_batches = nullptr;
@ -461,7 +443,7 @@ antlrcpp::Any CypherMainVisitor::visitTestStream(
} }
antlrcpp::Any CypherMainVisitor::visitReturnBody( antlrcpp::Any CypherMainVisitor::visitReturnBody(
CypherParser::ReturnBodyContext *ctx) { MemgraphCypher::ReturnBodyContext *ctx) {
ReturnBody body; ReturnBody body;
if (ctx->order()) { if (ctx->order()) {
body.order_by = ctx->order() body.order_by = ctx->order()
@ -482,17 +464,17 @@ antlrcpp::Any CypherMainVisitor::visitReturnBody(
} }
antlrcpp::Any CypherMainVisitor::visitReturnItems( antlrcpp::Any CypherMainVisitor::visitReturnItems(
CypherParser::ReturnItemsContext *ctx) { MemgraphCypher::ReturnItemsContext *ctx) {
std::vector<NamedExpression *> named_expressions; std::vector<NamedExpression *> named_expressions;
for (auto *item : ctx->returnItem()) { for (auto *item : ctx->returnItem()) {
named_expressions.push_back(item->accept(this)); named_expressions.push_back(item->accept(this));
} }
return std::pair<bool, std::vector<NamedExpression *>>( return std::pair<bool, std::vector<NamedExpression *>>(
ctx->getTokens(CypherParser::ASTERISK).size(), named_expressions); ctx->getTokens(MemgraphCypher::ASTERISK).size(), named_expressions);
} }
antlrcpp::Any CypherMainVisitor::visitReturnItem( antlrcpp::Any CypherMainVisitor::visitReturnItem(
CypherParser::ReturnItemContext *ctx) { MemgraphCypher::ReturnItemContext *ctx) {
auto *named_expr = storage_.Create<NamedExpression>(); auto *named_expr = storage_.Create<NamedExpression>();
named_expr->expression_ = ctx->expression()->accept(this); named_expr->expression_ = ctx->expression()->accept(this);
if (ctx->variable()) { if (ctx->variable()) {
@ -509,7 +491,7 @@ antlrcpp::Any CypherMainVisitor::visitReturnItem(
return named_expr; return named_expr;
} }
antlrcpp::Any CypherMainVisitor::visitOrder(CypherParser::OrderContext *ctx) { antlrcpp::Any CypherMainVisitor::visitOrder(MemgraphCypher::OrderContext *ctx) {
std::vector<std::pair<Ordering, Expression *>> order_by; std::vector<std::pair<Ordering, Expression *>> order_by;
for (auto *sort_item : ctx->sortItem()) { for (auto *sort_item : ctx->sortItem()) {
order_by.push_back(sort_item->accept(this)); order_by.push_back(sort_item->accept(this));
@ -518,14 +500,14 @@ antlrcpp::Any CypherMainVisitor::visitOrder(CypherParser::OrderContext *ctx) {
} }
antlrcpp::Any CypherMainVisitor::visitSortItem( antlrcpp::Any CypherMainVisitor::visitSortItem(
CypherParser::SortItemContext *ctx) { MemgraphCypher::SortItemContext *ctx) {
return std::pair<Ordering, Expression *>( return std::pair<Ordering, Expression *>(
ctx->DESC() || ctx->DESCENDING() ? Ordering::DESC : Ordering::ASC, ctx->DESC() || ctx->DESCENDING() ? Ordering::DESC : Ordering::ASC,
ctx->expression()->accept(this)); ctx->expression()->accept(this));
} }
antlrcpp::Any CypherMainVisitor::visitNodePattern( antlrcpp::Any CypherMainVisitor::visitNodePattern(
CypherParser::NodePatternContext *ctx) { MemgraphCypher::NodePatternContext *ctx) {
auto *node = storage_.Create<NodeAtom>(); auto *node = storage_.Create<NodeAtom>();
if (ctx->variable()) { if (ctx->variable()) {
std::string variable = ctx->variable()->accept(this); std::string variable = ctx->variable()->accept(this);
@ -549,7 +531,7 @@ antlrcpp::Any CypherMainVisitor::visitNodePattern(
} }
antlrcpp::Any CypherMainVisitor::visitNodeLabels( antlrcpp::Any CypherMainVisitor::visitNodeLabels(
CypherParser::NodeLabelsContext *ctx) { MemgraphCypher::NodeLabelsContext *ctx) {
std::vector<storage::Label> labels; std::vector<storage::Label> labels;
for (auto *node_label : ctx->nodeLabel()) { for (auto *node_label : ctx->nodeLabel()) {
labels.push_back(ctx_.db_accessor_.Label(node_label->accept(this))); labels.push_back(ctx_.db_accessor_.Label(node_label->accept(this)));
@ -558,7 +540,7 @@ antlrcpp::Any CypherMainVisitor::visitNodeLabels(
} }
antlrcpp::Any CypherMainVisitor::visitProperties( antlrcpp::Any CypherMainVisitor::visitProperties(
CypherParser::PropertiesContext *ctx) { MemgraphCypher::PropertiesContext *ctx) {
if (!ctx->mapLiteral()) { if (!ctx->mapLiteral()) {
// If child is not mapLiteral that means child is params. At the moment // If child is not mapLiteral that means child is params. At the moment
// we don't support properties to be a param because we can generate // we don't support properties to be a param because we can generate
@ -571,7 +553,7 @@ antlrcpp::Any CypherMainVisitor::visitProperties(
} }
antlrcpp::Any CypherMainVisitor::visitMapLiteral( antlrcpp::Any CypherMainVisitor::visitMapLiteral(
CypherParser::MapLiteralContext *ctx) { MemgraphCypher::MapLiteralContext *ctx) {
std::unordered_map<std::pair<std::string, storage::Property>, Expression *> std::unordered_map<std::pair<std::string, storage::Property>, Expression *>
map; map;
for (int i = 0; i < static_cast<int>(ctx->propertyKeyName().size()); ++i) { for (int i = 0; i < static_cast<int>(ctx->propertyKeyName().size()); ++i) {
@ -586,7 +568,7 @@ antlrcpp::Any CypherMainVisitor::visitMapLiteral(
} }
antlrcpp::Any CypherMainVisitor::visitListLiteral( antlrcpp::Any CypherMainVisitor::visitListLiteral(
CypherParser::ListLiteralContext *ctx) { MemgraphCypher::ListLiteralContext *ctx) {
std::vector<Expression *> expressions; std::vector<Expression *> expressions;
for (auto expr_ctx_ptr : ctx->expression()) for (auto expr_ctx_ptr : ctx->expression())
expressions.push_back(expr_ctx_ptr->accept(this)); expressions.push_back(expr_ctx_ptr->accept(this));
@ -594,13 +576,13 @@ antlrcpp::Any CypherMainVisitor::visitListLiteral(
} }
antlrcpp::Any CypherMainVisitor::visitPropertyKeyName( antlrcpp::Any CypherMainVisitor::visitPropertyKeyName(
CypherParser::PropertyKeyNameContext *ctx) { MemgraphCypher::PropertyKeyNameContext *ctx) {
const std::string key_name = visitChildren(ctx); const std::string key_name = visitChildren(ctx);
return std::make_pair(key_name, ctx_.db_accessor_.Property(key_name)); return std::make_pair(key_name, ctx_.db_accessor_.Property(key_name));
} }
antlrcpp::Any CypherMainVisitor::visitSymbolicName( antlrcpp::Any CypherMainVisitor::visitSymbolicName(
CypherParser::SymbolicNameContext *ctx) { MemgraphCypher::SymbolicNameContext *ctx) {
if (ctx->EscapedSymbolicName()) { if (ctx->EscapedSymbolicName()) {
auto quoted_name = ctx->getText(); auto quoted_name = ctx->getText();
DCHECK(quoted_name.size() >= 2U && quoted_name[0] == '`' && DCHECK(quoted_name.size() >= 2U && quoted_name[0] == '`' &&
@ -635,7 +617,7 @@ antlrcpp::Any CypherMainVisitor::visitSymbolicName(
} }
antlrcpp::Any CypherMainVisitor::visitPattern( antlrcpp::Any CypherMainVisitor::visitPattern(
CypherParser::PatternContext *ctx) { MemgraphCypher::PatternContext *ctx) {
std::vector<Pattern *> patterns; std::vector<Pattern *> patterns;
for (auto *pattern_part : ctx->patternPart()) { for (auto *pattern_part : ctx->patternPart()) {
patterns.push_back(pattern_part->accept(this)); patterns.push_back(pattern_part->accept(this));
@ -644,7 +626,7 @@ antlrcpp::Any CypherMainVisitor::visitPattern(
} }
antlrcpp::Any CypherMainVisitor::visitPatternPart( antlrcpp::Any CypherMainVisitor::visitPatternPart(
CypherParser::PatternPartContext *ctx) { MemgraphCypher::PatternPartContext *ctx) {
Pattern *pattern = ctx->anonymousPatternPart()->accept(this); Pattern *pattern = ctx->anonymousPatternPart()->accept(this);
if (ctx->variable()) { if (ctx->variable()) {
std::string variable = ctx->variable()->accept(this); std::string variable = ctx->variable()->accept(this);
@ -657,7 +639,7 @@ antlrcpp::Any CypherMainVisitor::visitPatternPart(
} }
antlrcpp::Any CypherMainVisitor::visitPatternElement( antlrcpp::Any CypherMainVisitor::visitPatternElement(
CypherParser::PatternElementContext *ctx) { MemgraphCypher::PatternElementContext *ctx) {
if (ctx->patternElement()) { if (ctx->patternElement()) {
return ctx->patternElement()->accept(this); return ctx->patternElement()->accept(this);
} }
@ -673,14 +655,14 @@ antlrcpp::Any CypherMainVisitor::visitPatternElement(
} }
antlrcpp::Any CypherMainVisitor::visitPatternElementChain( antlrcpp::Any CypherMainVisitor::visitPatternElementChain(
CypherParser::PatternElementChainContext *ctx) { MemgraphCypher::PatternElementChainContext *ctx) {
return std::pair<PatternAtom *, PatternAtom *>( return std::pair<PatternAtom *, PatternAtom *>(
ctx->relationshipPattern()->accept(this).as<EdgeAtom *>(), ctx->relationshipPattern()->accept(this).as<EdgeAtom *>(),
ctx->nodePattern()->accept(this).as<NodeAtom *>()); ctx->nodePattern()->accept(this).as<NodeAtom *>());
} }
antlrcpp::Any CypherMainVisitor::visitRelationshipPattern( antlrcpp::Any CypherMainVisitor::visitRelationshipPattern(
CypherParser::RelationshipPatternContext *ctx) { MemgraphCypher::RelationshipPatternContext *ctx) {
auto *edge = storage_.Create<EdgeAtom>(); auto *edge = storage_.Create<EdgeAtom>();
auto relationshipDetail = ctx->relationshipDetail(); auto relationshipDetail = ctx->relationshipDetail();
@ -808,19 +790,19 @@ antlrcpp::Any CypherMainVisitor::visitRelationshipPattern(
} }
antlrcpp::Any CypherMainVisitor::visitRelationshipDetail( antlrcpp::Any CypherMainVisitor::visitRelationshipDetail(
CypherParser::RelationshipDetailContext *) { MemgraphCypher::RelationshipDetailContext *) {
DLOG(FATAL) << "Should never be called. See documentation in hpp."; DLOG(FATAL) << "Should never be called. See documentation in hpp.";
return 0; return 0;
} }
antlrcpp::Any CypherMainVisitor::visitRelationshipLambda( antlrcpp::Any CypherMainVisitor::visitRelationshipLambda(
CypherParser::RelationshipLambdaContext *) { MemgraphCypher::RelationshipLambdaContext *) {
DLOG(FATAL) << "Should never be called. See documentation in hpp."; DLOG(FATAL) << "Should never be called. See documentation in hpp.";
return 0; return 0;
} }
antlrcpp::Any CypherMainVisitor::visitRelationshipTypes( antlrcpp::Any CypherMainVisitor::visitRelationshipTypes(
CypherParser::RelationshipTypesContext *ctx) { MemgraphCypher::RelationshipTypesContext *ctx) {
std::vector<storage::EdgeType> types; std::vector<storage::EdgeType> types;
for (auto *edge_type : ctx->relTypeName()) { for (auto *edge_type : ctx->relTypeName()) {
types.push_back(ctx_.db_accessor_.EdgeType(edge_type->accept(this))); types.push_back(ctx_.db_accessor_.EdgeType(edge_type->accept(this)));
@ -829,14 +811,14 @@ antlrcpp::Any CypherMainVisitor::visitRelationshipTypes(
} }
antlrcpp::Any CypherMainVisitor::visitVariableExpansion( antlrcpp::Any CypherMainVisitor::visitVariableExpansion(
CypherParser::VariableExpansionContext *ctx) { MemgraphCypher::VariableExpansionContext *ctx) {
DCHECK(ctx->expression().size() <= 2U) DCHECK(ctx->expression().size() <= 2U)
<< "Expected 0, 1 or 2 bounds in range literal."; << "Expected 0, 1 or 2 bounds in range literal.";
EdgeAtom::Type edge_type = EdgeAtom::Type::DEPTH_FIRST; EdgeAtom::Type edge_type = EdgeAtom::Type::DEPTH_FIRST;
if (!ctx->getTokens(CypherParser::BFS).empty()) if (!ctx->getTokens(MemgraphCypher::BFS).empty())
edge_type = EdgeAtom::Type::BREADTH_FIRST; edge_type = EdgeAtom::Type::BREADTH_FIRST;
else if (!ctx->getTokens(CypherParser::WSHORTEST).empty()) else if (!ctx->getTokens(MemgraphCypher::WSHORTEST).empty())
edge_type = EdgeAtom::Type::WEIGHTED_SHORTEST_PATH; edge_type = EdgeAtom::Type::WEIGHTED_SHORTEST_PATH;
Expression *lower = nullptr; Expression *lower = nullptr;
Expression *upper = nullptr; Expression *upper = nullptr;
@ -844,7 +826,7 @@ antlrcpp::Any CypherMainVisitor::visitVariableExpansion(
if (ctx->expression().size() == 0U) { if (ctx->expression().size() == 0U) {
// Case -[*]- // Case -[*]-
} else if (ctx->expression().size() == 1U) { } else if (ctx->expression().size() == 1U) {
auto dots_tokens = ctx->getTokens(CypherParser::DOTS); auto dots_tokens = ctx->getTokens(MemgraphCypher::DOTS);
Expression *bound = ctx->expression()[0]->accept(this); Expression *bound = ctx->expression()[0]->accept(this);
if (!dots_tokens.size()) { if (!dots_tokens.size()) {
// Case -[*bound]- // Case -[*bound]-
@ -870,43 +852,43 @@ antlrcpp::Any CypherMainVisitor::visitVariableExpansion(
} }
antlrcpp::Any CypherMainVisitor::visitExpression( antlrcpp::Any CypherMainVisitor::visitExpression(
CypherParser::ExpressionContext *ctx) { MemgraphCypher::ExpressionContext *ctx) {
return static_cast<Expression *>(ctx->expression12()->accept(this)); return static_cast<Expression *>(ctx->expression12()->accept(this));
} }
// OR. // OR.
antlrcpp::Any CypherMainVisitor::visitExpression12( antlrcpp::Any CypherMainVisitor::visitExpression12(
CypherParser::Expression12Context *ctx) { MemgraphCypher::Expression12Context *ctx) {
return LeftAssociativeOperatorExpression(ctx->expression11(), ctx->children, return LeftAssociativeOperatorExpression(ctx->expression11(), ctx->children,
{CypherParser::OR}); {MemgraphCypher::OR});
} }
// XOR. // XOR.
antlrcpp::Any CypherMainVisitor::visitExpression11( antlrcpp::Any CypherMainVisitor::visitExpression11(
CypherParser::Expression11Context *ctx) { MemgraphCypher::Expression11Context *ctx) {
return LeftAssociativeOperatorExpression(ctx->expression10(), ctx->children, return LeftAssociativeOperatorExpression(ctx->expression10(), ctx->children,
{CypherParser::XOR}); {MemgraphCypher::XOR});
} }
// AND. // AND.
antlrcpp::Any CypherMainVisitor::visitExpression10( antlrcpp::Any CypherMainVisitor::visitExpression10(
CypherParser::Expression10Context *ctx) { MemgraphCypher::Expression10Context *ctx) {
return LeftAssociativeOperatorExpression(ctx->expression9(), ctx->children, return LeftAssociativeOperatorExpression(ctx->expression9(), ctx->children,
{CypherParser::AND}); {MemgraphCypher::AND});
} }
// NOT. // NOT.
antlrcpp::Any CypherMainVisitor::visitExpression9( antlrcpp::Any CypherMainVisitor::visitExpression9(
CypherParser::Expression9Context *ctx) { MemgraphCypher::Expression9Context *ctx) {
return PrefixUnaryOperator(ctx->expression8(), ctx->children, return PrefixUnaryOperator(ctx->expression8(), ctx->children,
{CypherParser::NOT}); {MemgraphCypher::NOT});
} }
// Comparisons. // Comparisons.
// Expresion 1 < 2 < 3 is converted to 1 < 2 && 2 < 3 and then binary operator // Expresion 1 < 2 < 3 is converted to 1 < 2 && 2 < 3 and then binary operator
// ast node is constructed for each operator. // ast node is constructed for each operator.
antlrcpp::Any CypherMainVisitor::visitExpression8( antlrcpp::Any CypherMainVisitor::visitExpression8(
CypherParser::Expression8Context *ctx) { MemgraphCypher::Expression8Context *ctx) {
if (!ctx->partialComparisonExpression().size()) { if (!ctx->partialComparisonExpression().size()) {
// There is no comparison operators. We generate expression7. // There is no comparison operators. We generate expression7.
return ctx->expression7()->accept(this); return ctx->expression7()->accept(this);
@ -962,30 +944,31 @@ antlrcpp::Any CypherMainVisitor::visitExpression8(
} }
antlrcpp::Any CypherMainVisitor::visitPartialComparisonExpression( antlrcpp::Any CypherMainVisitor::visitPartialComparisonExpression(
CypherParser::PartialComparisonExpressionContext *) { MemgraphCypher::PartialComparisonExpressionContext *) {
DLOG(FATAL) << "Should never be called. See documentation in hpp."; DLOG(FATAL) << "Should never be called. See documentation in hpp.";
return 0; return 0;
} }
// Addition and subtraction. // Addition and subtraction.
antlrcpp::Any CypherMainVisitor::visitExpression7( antlrcpp::Any CypherMainVisitor::visitExpression7(
CypherParser::Expression7Context *ctx) { MemgraphCypher::Expression7Context *ctx) {
return LeftAssociativeOperatorExpression( return LeftAssociativeOperatorExpression(
ctx->expression6(), ctx->children, ctx->expression6(), ctx->children,
{CypherParser::PLUS, CypherParser::MINUS}); {MemgraphCypher::PLUS, MemgraphCypher::MINUS});
} }
// Multiplication, division, modding. // Multiplication, division, modding.
antlrcpp::Any CypherMainVisitor::visitExpression6( antlrcpp::Any CypherMainVisitor::visitExpression6(
CypherParser::Expression6Context *ctx) { MemgraphCypher::Expression6Context *ctx) {
return LeftAssociativeOperatorExpression( return LeftAssociativeOperatorExpression(
ctx->expression5(), ctx->children, ctx->expression5(), ctx->children,
{CypherParser::ASTERISK, CypherParser::SLASH, CypherParser::PERCENT}); {MemgraphCypher::ASTERISK, MemgraphCypher::SLASH,
MemgraphCypher::PERCENT});
} }
// Power. // Power.
antlrcpp::Any CypherMainVisitor::visitExpression5( antlrcpp::Any CypherMainVisitor::visitExpression5(
CypherParser::Expression5Context *ctx) { MemgraphCypher::Expression5Context *ctx) {
if (ctx->expression4().size() > 1U) { if (ctx->expression4().size() > 1U) {
// TODO: implement power operator. In neo4j power is left associative and // TODO: implement power operator. In neo4j power is left associative and
// int^int -> float. // int^int -> float.
@ -996,14 +979,14 @@ antlrcpp::Any CypherMainVisitor::visitExpression5(
// Unary minus and plus. // Unary minus and plus.
antlrcpp::Any CypherMainVisitor::visitExpression4( antlrcpp::Any CypherMainVisitor::visitExpression4(
CypherParser::Expression4Context *ctx) { MemgraphCypher::Expression4Context *ctx) {
return PrefixUnaryOperator(ctx->expression3a(), ctx->children, return PrefixUnaryOperator(ctx->expression3a(), ctx->children,
{CypherParser::PLUS, CypherParser::MINUS}); {MemgraphCypher::PLUS, MemgraphCypher::MINUS});
} }
// IS NULL, IS NOT NULL, STARTS WITH, .. // IS NULL, IS NOT NULL, STARTS WITH, ..
antlrcpp::Any CypherMainVisitor::visitExpression3a( antlrcpp::Any CypherMainVisitor::visitExpression3a(
CypherParser::Expression3aContext *ctx) { MemgraphCypher::Expression3aContext *ctx) {
Expression *expression = ctx->expression3b()->accept(this); Expression *expression = ctx->expression3b()->accept(this);
for (auto *op : ctx->stringAndNullOperators()) { for (auto *op : ctx->stringAndNullOperators()) {
@ -1036,16 +1019,16 @@ antlrcpp::Any CypherMainVisitor::visitExpression3a(
return expression; return expression;
} }
antlrcpp::Any CypherMainVisitor::visitStringAndNullOperators( antlrcpp::Any CypherMainVisitor::visitStringAndNullOperators(
CypherParser::StringAndNullOperatorsContext *) { MemgraphCypher::StringAndNullOperatorsContext *) {
DLOG(FATAL) << "Should never be called. See documentation in hpp."; DLOG(FATAL) << "Should never be called. See documentation in hpp.";
return 0; return 0;
} }
antlrcpp::Any CypherMainVisitor::visitExpression3b( antlrcpp::Any CypherMainVisitor::visitExpression3b(
CypherParser::Expression3bContext *ctx) { MemgraphCypher::Expression3bContext *ctx) {
Expression *expression = ctx->expression2a()->accept(this); Expression *expression = ctx->expression2a()->accept(this);
for (auto *list_op : ctx->listIndexingOrSlicing()) { for (auto *list_op : ctx->listIndexingOrSlicing()) {
if (list_op->getTokens(CypherParser::DOTS).size() == 0U) { if (list_op->getTokens(MemgraphCypher::DOTS).size() == 0U) {
// If there is no '..' then we need to create list indexing operator. // If there is no '..' then we need to create list indexing operator.
expression = storage_.Create<SubscriptOperator>( expression = storage_.Create<SubscriptOperator>(
expression, list_op->expression()[0]->accept(this)); expression, list_op->expression()[0]->accept(this));
@ -1069,13 +1052,13 @@ antlrcpp::Any CypherMainVisitor::visitExpression3b(
} }
antlrcpp::Any CypherMainVisitor::visitListIndexingOrSlicing( antlrcpp::Any CypherMainVisitor::visitListIndexingOrSlicing(
CypherParser::ListIndexingOrSlicingContext *) { MemgraphCypher::ListIndexingOrSlicingContext *) {
DLOG(FATAL) << "Should never be called. See documentation in hpp."; DLOG(FATAL) << "Should never be called. See documentation in hpp.";
return 0; return 0;
} }
antlrcpp::Any CypherMainVisitor::visitExpression2a( antlrcpp::Any CypherMainVisitor::visitExpression2a(
CypherParser::Expression2aContext *ctx) { MemgraphCypher::Expression2aContext *ctx) {
Expression *expression = ctx->expression2b()->accept(this); Expression *expression = ctx->expression2b()->accept(this);
if (ctx->nodeLabels()) { if (ctx->nodeLabels()) {
auto labels = auto labels =
@ -1086,7 +1069,7 @@ antlrcpp::Any CypherMainVisitor::visitExpression2a(
} }
antlrcpp::Any CypherMainVisitor::visitExpression2b( antlrcpp::Any CypherMainVisitor::visitExpression2b(
CypherParser::Expression2bContext *ctx) { MemgraphCypher::Expression2bContext *ctx) {
Expression *expression = ctx->atom()->accept(this); Expression *expression = ctx->atom()->accept(this);
for (auto *lookup : ctx->propertyLookup()) { for (auto *lookup : ctx->propertyLookup()) {
std::pair<std::string, storage::Property> key = lookup->accept(this); std::pair<std::string, storage::Property> key = lookup->accept(this);
@ -1097,7 +1080,7 @@ antlrcpp::Any CypherMainVisitor::visitExpression2b(
return expression; return expression;
} }
antlrcpp::Any CypherMainVisitor::visitAtom(CypherParser::AtomContext *ctx) { antlrcpp::Any CypherMainVisitor::visitAtom(MemgraphCypher::AtomContext *ctx) {
if (ctx->literal()) { if (ctx->literal()) {
return ctx->literal()->accept(this); return ctx->literal()->accept(this);
} else if (ctx->parameter()) { } else if (ctx->parameter()) {
@ -1175,12 +1158,12 @@ antlrcpp::Any CypherMainVisitor::visitAtom(CypherParser::AtomContext *ctx) {
} }
antlrcpp::Any CypherMainVisitor::visitParameter( antlrcpp::Any CypherMainVisitor::visitParameter(
CypherParser::ParameterContext *ctx) { MemgraphCypher::ParameterContext *ctx) {
return storage_.Create<ParameterLookup>(ctx->getStart()->getTokenIndex()); return storage_.Create<ParameterLookup>(ctx->getStart()->getTokenIndex());
} }
antlrcpp::Any CypherMainVisitor::visitLiteral( antlrcpp::Any CypherMainVisitor::visitLiteral(
CypherParser::LiteralContext *ctx) { MemgraphCypher::LiteralContext *ctx) {
if (ctx->CYPHERNULL() || ctx->StringLiteral() || ctx->booleanLiteral() || if (ctx->CYPHERNULL() || ctx->StringLiteral() || ctx->booleanLiteral() ||
ctx->numberLiteral()) { ctx->numberLiteral()) {
int token_position = ctx->getStart()->getTokenIndex(); int token_position = ctx->getStart()->getTokenIndex();
@ -1221,12 +1204,12 @@ antlrcpp::Any CypherMainVisitor::visitLiteral(
} }
antlrcpp::Any CypherMainVisitor::visitParenthesizedExpression( antlrcpp::Any CypherMainVisitor::visitParenthesizedExpression(
CypherParser::ParenthesizedExpressionContext *ctx) { MemgraphCypher::ParenthesizedExpressionContext *ctx) {
return static_cast<Expression *>(ctx->expression()->accept(this)); return static_cast<Expression *>(ctx->expression()->accept(this));
} }
antlrcpp::Any CypherMainVisitor::visitNumberLiteral( antlrcpp::Any CypherMainVisitor::visitNumberLiteral(
CypherParser::NumberLiteralContext *ctx) { MemgraphCypher::NumberLiteralContext *ctx) {
if (ctx->integerLiteral()) { if (ctx->integerLiteral()) {
return TypedValue(ctx->integerLiteral()->accept(this).as<int64_t>()); return TypedValue(ctx->integerLiteral()->accept(this).as<int64_t>());
} else if (ctx->doubleLiteral()) { } else if (ctx->doubleLiteral()) {
@ -1240,7 +1223,7 @@ antlrcpp::Any CypherMainVisitor::visitNumberLiteral(
} }
antlrcpp::Any CypherMainVisitor::visitFunctionInvocation( antlrcpp::Any CypherMainVisitor::visitFunctionInvocation(
CypherParser::FunctionInvocationContext *ctx) { MemgraphCypher::FunctionInvocationContext *ctx) {
if (ctx->DISTINCT()) { if (ctx->DISTINCT()) {
throw utils::NotYetImplemented("DISTINCT function call"); throw utils::NotYetImplemented("DISTINCT function call");
} }
@ -1289,17 +1272,17 @@ antlrcpp::Any CypherMainVisitor::visitFunctionInvocation(
} }
antlrcpp::Any CypherMainVisitor::visitFunctionName( antlrcpp::Any CypherMainVisitor::visitFunctionName(
CypherParser::FunctionNameContext *ctx) { MemgraphCypher::FunctionNameContext *ctx) {
return utils::ToUpperCase(ctx->getText()); return utils::ToUpperCase(ctx->getText());
} }
antlrcpp::Any CypherMainVisitor::visitDoubleLiteral( antlrcpp::Any CypherMainVisitor::visitDoubleLiteral(
CypherParser::DoubleLiteralContext *ctx) { MemgraphCypher::DoubleLiteralContext *ctx) {
return ParseDoubleLiteral(ctx->getText()); return ParseDoubleLiteral(ctx->getText());
} }
antlrcpp::Any CypherMainVisitor::visitIntegerLiteral( antlrcpp::Any CypherMainVisitor::visitIntegerLiteral(
CypherParser::IntegerLiteralContext *ctx) { MemgraphCypher::IntegerLiteralContext *ctx) {
return ParseIntegerLiteral(ctx->getText()); return ParseIntegerLiteral(ctx->getText());
} }
@ -1309,11 +1292,11 @@ antlrcpp::Any CypherMainVisitor::visitStringLiteral(
} }
antlrcpp::Any CypherMainVisitor::visitBooleanLiteral( antlrcpp::Any CypherMainVisitor::visitBooleanLiteral(
CypherParser::BooleanLiteralContext *ctx) { MemgraphCypher::BooleanLiteralContext *ctx) {
if (ctx->getTokens(CypherParser::TRUE).size()) { if (ctx->getTokens(MemgraphCypher::TRUE).size()) {
return true; return true;
} }
if (ctx->getTokens(CypherParser::FALSE).size()) { if (ctx->getTokens(MemgraphCypher::FALSE).size()) {
return false; return false;
} }
DLOG(FATAL) << "Shouldn't happend"; DLOG(FATAL) << "Shouldn't happend";
@ -1321,7 +1304,7 @@ antlrcpp::Any CypherMainVisitor::visitBooleanLiteral(
} }
antlrcpp::Any CypherMainVisitor::visitCypherDelete( antlrcpp::Any CypherMainVisitor::visitCypherDelete(
CypherParser::CypherDeleteContext *ctx) { MemgraphCypher::CypherDeleteContext *ctx) {
auto *del = storage_.Create<Delete>(); auto *del = storage_.Create<Delete>();
if (ctx->DETACH()) { if (ctx->DETACH()) {
del->detach_ = true; del->detach_ = true;
@ -1332,13 +1315,13 @@ antlrcpp::Any CypherMainVisitor::visitCypherDelete(
return del; return del;
} }
antlrcpp::Any CypherMainVisitor::visitWhere(CypherParser::WhereContext *ctx) { antlrcpp::Any CypherMainVisitor::visitWhere(MemgraphCypher::WhereContext *ctx) {
auto *where = storage_.Create<Where>(); auto *where = storage_.Create<Where>();
where->expression_ = ctx->expression()->accept(this); where->expression_ = ctx->expression()->accept(this);
return where; return where;
} }
antlrcpp::Any CypherMainVisitor::visitSet(CypherParser::SetContext *ctx) { antlrcpp::Any CypherMainVisitor::visitSet(MemgraphCypher::SetContext *ctx) {
std::vector<Clause *> set_items; std::vector<Clause *> set_items;
for (auto *set_item : ctx->setItem()) { for (auto *set_item : ctx->setItem()) {
set_items.push_back(set_item->accept(this)); set_items.push_back(set_item->accept(this));
@ -1347,7 +1330,7 @@ antlrcpp::Any CypherMainVisitor::visitSet(CypherParser::SetContext *ctx) {
} }
antlrcpp::Any CypherMainVisitor::visitSetItem( antlrcpp::Any CypherMainVisitor::visitSetItem(
CypherParser::SetItemContext *ctx) { MemgraphCypher::SetItemContext *ctx) {
// SetProperty // SetProperty
if (ctx->propertyExpression()) { if (ctx->propertyExpression()) {
auto *set_property = storage_.Create<SetProperty>(); auto *set_property = storage_.Create<SetProperty>();
@ -1357,13 +1340,13 @@ antlrcpp::Any CypherMainVisitor::visitSetItem(
} }
// SetProperties either assignment or update // SetProperties either assignment or update
if (ctx->getTokens(CypherParser::EQ).size() || if (ctx->getTokens(MemgraphCypher::EQ).size() ||
ctx->getTokens(CypherParser::PLUS_EQ).size()) { ctx->getTokens(MemgraphCypher::PLUS_EQ).size()) {
auto *set_properties = storage_.Create<SetProperties>(); auto *set_properties = storage_.Create<SetProperties>();
set_properties->identifier_ = storage_.Create<Identifier>( set_properties->identifier_ = storage_.Create<Identifier>(
ctx->variable()->accept(this).as<std::string>()); ctx->variable()->accept(this).as<std::string>());
set_properties->expression_ = ctx->expression()->accept(this); set_properties->expression_ = ctx->expression()->accept(this);
if (ctx->getTokens(CypherParser::PLUS_EQ).size()) { if (ctx->getTokens(MemgraphCypher::PLUS_EQ).size()) {
set_properties->update_ = true; set_properties->update_ = true;
} }
return static_cast<Clause *>(set_properties); return static_cast<Clause *>(set_properties);
@ -1378,7 +1361,8 @@ antlrcpp::Any CypherMainVisitor::visitSetItem(
return static_cast<Clause *>(set_labels); return static_cast<Clause *>(set_labels);
} }
antlrcpp::Any CypherMainVisitor::visitRemove(CypherParser::RemoveContext *ctx) { antlrcpp::Any CypherMainVisitor::visitRemove(
MemgraphCypher::RemoveContext *ctx) {
std::vector<Clause *> remove_items; std::vector<Clause *> remove_items;
for (auto *remove_item : ctx->removeItem()) { for (auto *remove_item : ctx->removeItem()) {
remove_items.push_back(remove_item->accept(this)); remove_items.push_back(remove_item->accept(this));
@ -1387,7 +1371,7 @@ antlrcpp::Any CypherMainVisitor::visitRemove(CypherParser::RemoveContext *ctx) {
} }
antlrcpp::Any CypherMainVisitor::visitRemoveItem( antlrcpp::Any CypherMainVisitor::visitRemoveItem(
CypherParser::RemoveItemContext *ctx) { MemgraphCypher::RemoveItemContext *ctx) {
// RemoveProperty // RemoveProperty
if (ctx->propertyExpression()) { if (ctx->propertyExpression()) {
auto *remove_property = storage_.Create<RemoveProperty>(); auto *remove_property = storage_.Create<RemoveProperty>();
@ -1405,7 +1389,7 @@ antlrcpp::Any CypherMainVisitor::visitRemoveItem(
} }
antlrcpp::Any CypherMainVisitor::visitPropertyExpression( antlrcpp::Any CypherMainVisitor::visitPropertyExpression(
CypherParser::PropertyExpressionContext *ctx) { MemgraphCypher::PropertyExpressionContext *ctx) {
Expression *expression = ctx->atom()->accept(this); Expression *expression = ctx->atom()->accept(this);
for (auto *lookup : ctx->propertyLookup()) { for (auto *lookup : ctx->propertyLookup()) {
std::pair<std::string, storage::Property> key = lookup->accept(this); std::pair<std::string, storage::Property> key = lookup->accept(this);
@ -1418,7 +1402,7 @@ antlrcpp::Any CypherMainVisitor::visitPropertyExpression(
} }
antlrcpp::Any CypherMainVisitor::visitCaseExpression( antlrcpp::Any CypherMainVisitor::visitCaseExpression(
CypherParser::CaseExpressionContext *ctx) { MemgraphCypher::CaseExpressionContext *ctx) {
Expression *test_expression = Expression *test_expression =
ctx->test ? ctx->test->accept(this).as<Expression *>() : nullptr; ctx->test ? ctx->test->accept(this).as<Expression *>() : nullptr;
auto alternatives = ctx->caseAlternatives(); auto alternatives = ctx->caseAlternatives();
@ -1442,12 +1426,12 @@ antlrcpp::Any CypherMainVisitor::visitCaseExpression(
} }
antlrcpp::Any CypherMainVisitor::visitCaseAlternatives( antlrcpp::Any CypherMainVisitor::visitCaseAlternatives(
CypherParser::CaseAlternativesContext *) { MemgraphCypher::CaseAlternativesContext *) {
DLOG(FATAL) << "Should never be called. See documentation in hpp."; DLOG(FATAL) << "Should never be called. See documentation in hpp.";
return 0; return 0;
} }
antlrcpp::Any CypherMainVisitor::visitWith(CypherParser::WithContext *ctx) { antlrcpp::Any CypherMainVisitor::visitWith(MemgraphCypher::WithContext *ctx) {
auto *with = storage_.Create<With>(); auto *with = storage_.Create<With>();
in_with_ = true; in_with_ = true;
with->body_ = ctx->returnBody()->accept(this); with->body_ = ctx->returnBody()->accept(this);
@ -1461,7 +1445,7 @@ antlrcpp::Any CypherMainVisitor::visitWith(CypherParser::WithContext *ctx) {
return with; return with;
} }
antlrcpp::Any CypherMainVisitor::visitMerge(CypherParser::MergeContext *ctx) { antlrcpp::Any CypherMainVisitor::visitMerge(MemgraphCypher::MergeContext *ctx) {
auto *merge = storage_.Create<Merge>(); auto *merge = storage_.Create<Merge>();
merge->pattern_ = ctx->patternPart()->accept(this); merge->pattern_ = ctx->patternPart()->accept(this);
for (auto &merge_action : ctx->mergeAction()) { for (auto &merge_action : ctx->mergeAction()) {
@ -1476,7 +1460,8 @@ antlrcpp::Any CypherMainVisitor::visitMerge(CypherParser::MergeContext *ctx) {
return merge; return merge;
} }
antlrcpp::Any CypherMainVisitor::visitUnwind(CypherParser::UnwindContext *ctx) { antlrcpp::Any CypherMainVisitor::visitUnwind(
MemgraphCypher::UnwindContext *ctx) {
auto *named_expr = storage_.Create<NamedExpression>(); auto *named_expr = storage_.Create<NamedExpression>();
named_expr->expression_ = ctx->expression()->accept(this); named_expr->expression_ = ctx->expression()->accept(this);
named_expr->name_ = named_expr->name_ =
@ -1485,7 +1470,7 @@ antlrcpp::Any CypherMainVisitor::visitUnwind(CypherParser::UnwindContext *ctx) {
} }
antlrcpp::Any CypherMainVisitor::visitFilterExpression( antlrcpp::Any CypherMainVisitor::visitFilterExpression(
CypherParser::FilterExpressionContext *) { MemgraphCypher::FilterExpressionContext *) {
LOG(FATAL) << "Should never be called. See documentation in hpp."; LOG(FATAL) << "Should never be called. See documentation in hpp.";
return 0; return 0;
} }

View File

@ -9,16 +9,16 @@
#include "query/context.hpp" #include "query/context.hpp"
#include "query/frontend/ast/ast.hpp" #include "query/frontend/ast/ast.hpp"
#include "query/frontend/opencypher/generated/CypherParserBaseVisitor.h" #include "query/frontend/opencypher/generated/MemgraphCypherBaseVisitor.h"
#include "utils/exceptions.hpp" #include "utils/exceptions.hpp"
namespace query { namespace query {
namespace frontend { namespace frontend {
using antlropencypher::CypherParser; using antlropencypher::MemgraphCypher;
using query::Context; using query::Context;
class CypherMainVisitor : public antlropencypher::CypherParserBaseVisitor { class CypherMainVisitor : public antlropencypher::MemgraphCypherBaseVisitor {
public: public:
explicit CypherMainVisitor(Context &ctx) : ctx_(ctx) {} explicit CypherMainVisitor(Context &ctx) : ctx_(ctx) {}
@ -26,34 +26,34 @@ class CypherMainVisitor : public antlropencypher::CypherParserBaseVisitor {
Expression *CreateBinaryOperatorByToken(size_t token, Expression *e1, Expression *CreateBinaryOperatorByToken(size_t token, Expression *e1,
Expression *e2) { Expression *e2) {
switch (token) { switch (token) {
case CypherParser::OR: case MemgraphCypher::OR:
return storage_.Create<OrOperator>(e1, e2); return storage_.Create<OrOperator>(e1, e2);
case CypherParser::XOR: case MemgraphCypher::XOR:
return storage_.Create<XorOperator>(e1, e2); return storage_.Create<XorOperator>(e1, e2);
case CypherParser::AND: case MemgraphCypher::AND:
return storage_.Create<AndOperator>(e1, e2); return storage_.Create<AndOperator>(e1, e2);
case CypherParser::PLUS: case MemgraphCypher::PLUS:
return storage_.Create<AdditionOperator>(e1, e2); return storage_.Create<AdditionOperator>(e1, e2);
case CypherParser::MINUS: case MemgraphCypher::MINUS:
return storage_.Create<SubtractionOperator>(e1, e2); return storage_.Create<SubtractionOperator>(e1, e2);
case CypherParser::ASTERISK: case MemgraphCypher::ASTERISK:
return storage_.Create<MultiplicationOperator>(e1, e2); return storage_.Create<MultiplicationOperator>(e1, e2);
case CypherParser::SLASH: case MemgraphCypher::SLASH:
return storage_.Create<DivisionOperator>(e1, e2); return storage_.Create<DivisionOperator>(e1, e2);
case CypherParser::PERCENT: case MemgraphCypher::PERCENT:
return storage_.Create<ModOperator>(e1, e2); return storage_.Create<ModOperator>(e1, e2);
case CypherParser::EQ: case MemgraphCypher::EQ:
return storage_.Create<EqualOperator>(e1, e2); return storage_.Create<EqualOperator>(e1, e2);
case CypherParser::NEQ1: case MemgraphCypher::NEQ1:
case CypherParser::NEQ2: case MemgraphCypher::NEQ2:
return storage_.Create<NotEqualOperator>(e1, e2); return storage_.Create<NotEqualOperator>(e1, e2);
case CypherParser::LT: case MemgraphCypher::LT:
return storage_.Create<LessOperator>(e1, e2); return storage_.Create<LessOperator>(e1, e2);
case CypherParser::GT: case MemgraphCypher::GT:
return storage_.Create<GreaterOperator>(e1, e2); return storage_.Create<GreaterOperator>(e1, e2);
case CypherParser::LTE: case MemgraphCypher::LTE:
return storage_.Create<LessEqualOperator>(e1, e2); return storage_.Create<LessEqualOperator>(e1, e2);
case CypherParser::GTE: case MemgraphCypher::GTE:
return storage_.Create<GreaterEqualOperator>(e1, e2); return storage_.Create<GreaterEqualOperator>(e1, e2);
default: default:
throw utils::NotYetImplemented("binary operator"); throw utils::NotYetImplemented("binary operator");
@ -62,11 +62,11 @@ class CypherMainVisitor : public antlropencypher::CypherParserBaseVisitor {
Expression *CreateUnaryOperatorByToken(size_t token, Expression *e) { Expression *CreateUnaryOperatorByToken(size_t token, Expression *e) {
switch (token) { switch (token) {
case CypherParser::NOT: case MemgraphCypher::NOT:
return storage_.Create<NotOperator>(e); return storage_.Create<NotOperator>(e);
case CypherParser::PLUS: case MemgraphCypher::PLUS:
return storage_.Create<UnaryPlusOperator>(e); return storage_.Create<UnaryPlusOperator>(e);
case CypherParser::MINUS: case MemgraphCypher::MINUS:
return storage_.Create<UnaryMinusOperator>(e); return storage_.Create<UnaryMinusOperator>(e);
default: default:
throw utils::NotYetImplemented("unary operator"); throw utils::NotYetImplemented("unary operator");
@ -132,112 +132,127 @@ class CypherMainVisitor : public antlropencypher::CypherParserBaseVisitor {
return expression; return expression;
} }
/**
* @return Query*
*/
antlrcpp::Any visitAuthQuery(MemgraphCypher::AuthQueryContext *ctx) override;
/**
* @return Query*
*/
antlrcpp::Any visitStreamQuery(
MemgraphCypher::StreamQueryContext *ctx) override;
/** /**
* @return Query* * @return Query*
*/ */
antlrcpp::Any visitRegularQuery( antlrcpp::Any visitRegularQuery(
CypherParser::RegularQueryContext *ctx) override; MemgraphCypher::RegularQueryContext *ctx) override;
/** /**
* @return CypherUnion* * @return CypherUnion*
*/ */
antlrcpp::Any visitCypherUnion( antlrcpp::Any visitCypherUnion(
CypherParser::CypherUnionContext *ctx) override; MemgraphCypher::CypherUnionContext *ctx) override;
/** /**
* @return SingleQuery* * @return SingleQuery*
*/ */
antlrcpp::Any visitSingleQuery( antlrcpp::Any visitSingleQuery(
CypherParser::SingleQueryContext *ctx) override; MemgraphCypher::SingleQueryContext *ctx) override;
/** /**
* @return Clause* or vector<Clause*>!!! * @return Clause* or vector<Clause*>!!!
*/ */
antlrcpp::Any visitClause(CypherParser::ClauseContext *ctx) override; antlrcpp::Any visitClause(MemgraphCypher::ClauseContext *ctx) override;
/** /**
* @return Match* * @return Match*
*/ */
antlrcpp::Any visitCypherMatch( antlrcpp::Any visitCypherMatch(
CypherParser::CypherMatchContext *ctx) override; MemgraphCypher::CypherMatchContext *ctx) override;
/** /**
* @return Create* * @return Create*
*/ */
antlrcpp::Any visitCreate(CypherParser::CreateContext *ctx) override; antlrcpp::Any visitCreate(MemgraphCypher::CreateContext *ctx) override;
/** /**
* @return CreateIndex* * @return CreateIndex*
*/ */
antlrcpp::Any visitCreateIndex( antlrcpp::Any visitCreateIndex(
CypherParser::CreateIndexContext *ctx) override; MemgraphCypher::CreateIndexContext *ctx) override;
/** /**
* @return ModifyUser* * @return ModifyUser*
*/ */
antlrcpp::Any visitModifyUser(CypherParser::ModifyUserContext *ctx) override; antlrcpp::Any visitModifyUser(
MemgraphCypher::ModifyUserContext *ctx) override;
antlrcpp::Any visitPasswordOption( antlrcpp::Any visitPasswordOption(
CypherParser::PasswordOptionContext *ctx) override; MemgraphCypher::PasswordOptionContext *ctx) override;
/** /**
* @return DropUser* * @return DropUser*
*/ */
antlrcpp::Any visitDropUser(CypherParser::DropUserContext *ctx) override; antlrcpp::Any visitDropUser(MemgraphCypher::DropUserContext *ctx) override;
/** /**
* @return CreateStream* * @return CreateStream*
*/ */
antlrcpp::Any visitCreateStream( antlrcpp::Any visitCreateStream(
CypherParser::CreateStreamContext *ctx) override; MemgraphCypher::CreateStreamContext *ctx) override;
antlrcpp::Any visitBatchIntervalOption( antlrcpp::Any visitBatchIntervalOption(
CypherParser::BatchIntervalOptionContext *ctx) override; MemgraphCypher::BatchIntervalOptionContext *ctx) override;
antlrcpp::Any visitBatchSizeOption( antlrcpp::Any visitBatchSizeOption(
CypherParser::BatchSizeOptionContext *ctx) override; MemgraphCypher::BatchSizeOptionContext *ctx) override;
/** /**
* @return DropStream* * @return DropStream*
*/ */
antlrcpp::Any visitDropStream(CypherParser::DropStreamContext *ctx) override; antlrcpp::Any visitDropStream(
MemgraphCypher::DropStreamContext *ctx) override;
/** /**
* @return ShowStreams* * @return ShowStreams*
*/ */
antlrcpp::Any visitShowStreams( antlrcpp::Any visitShowStreams(
CypherParser::ShowStreamsContext *ctx) override; MemgraphCypher::ShowStreamsContext *ctx) override;
/** /**
* @return StartStopStream* * @return StartStopStream*
*/ */
antlrcpp::Any visitStartStopStream( antlrcpp::Any visitStartStopStream(
CypherParser::StartStopStreamContext *ctx) override; MemgraphCypher::StartStopStreamContext *ctx) override;
/** /**
* @return StartStopAllStreams* * @return StartStopAllStreams*
*/ */
antlrcpp::Any visitStartStopAllStreams( antlrcpp::Any visitStartStopAllStreams(
CypherParser::StartStopAllStreamsContext *ctx) override; MemgraphCypher::StartStopAllStreamsContext *ctx) override;
antlrcpp::Any visitLimitBatchesOption( antlrcpp::Any visitLimitBatchesOption(
CypherParser::LimitBatchesOptionContext *ctx) override; MemgraphCypher::LimitBatchesOptionContext *ctx) override;
/** /**
* @return TestStream* * @return TestStream*
*/ */
antlrcpp::Any visitTestStream(CypherParser::TestStreamContext *ctx) override; antlrcpp::Any visitTestStream(
MemgraphCypher::TestStreamContext *ctx) override;
/** /**
* @return Return* * @return Return*
*/ */
antlrcpp::Any visitCypherReturn( antlrcpp::Any visitCypherReturn(
CypherParser::CypherReturnContext *ctx) override; MemgraphCypher::CypherReturnContext *ctx) override;
/** /**
* @return Return* * @return Return*
*/ */
antlrcpp::Any visitReturnBody(CypherParser::ReturnBodyContext *ctx) override; antlrcpp::Any visitReturnBody(
MemgraphCypher::ReturnBodyContext *ctx) override;
/** /**
* @return pair<bool, vector<NamedExpression*>> first member is true if * @return pair<bool, vector<NamedExpression*>> first member is true if
@ -245,123 +260,128 @@ class CypherMainVisitor : public antlropencypher::CypherParserBaseVisitor {
* expressions. * expressions.
*/ */
antlrcpp::Any visitReturnItems( antlrcpp::Any visitReturnItems(
CypherParser::ReturnItemsContext *ctx) override; MemgraphCypher::ReturnItemsContext *ctx) override;
/** /**
* @return vector<NamedExpression*> * @return vector<NamedExpression*>
*/ */
antlrcpp::Any visitReturnItem(CypherParser::ReturnItemContext *ctx) override; antlrcpp::Any visitReturnItem(
MemgraphCypher::ReturnItemContext *ctx) override;
/** /**
* @return vector<pair<Ordering, Expression*>> * @return vector<pair<Ordering, Expression*>>
*/ */
antlrcpp::Any visitOrder(CypherParser::OrderContext *ctx) override; antlrcpp::Any visitOrder(MemgraphCypher::OrderContext *ctx) override;
/** /**
* @return pair<Ordering, Expression*> * @return pair<Ordering, Expression*>
*/ */
antlrcpp::Any visitSortItem(CypherParser::SortItemContext *ctx) override; antlrcpp::Any visitSortItem(MemgraphCypher::SortItemContext *ctx) override;
/** /**
* @return NodeAtom* * @return NodeAtom*
*/ */
antlrcpp::Any visitNodePattern( antlrcpp::Any visitNodePattern(
CypherParser::NodePatternContext *ctx) override; MemgraphCypher::NodePatternContext *ctx) override;
/** /**
* @return vector<storage::Label> * @return vector<storage::Label>
*/ */
antlrcpp::Any visitNodeLabels(CypherParser::NodeLabelsContext *ctx) override; antlrcpp::Any visitNodeLabels(
MemgraphCypher::NodeLabelsContext *ctx) override;
/** /**
* @return unordered_map<storage::Property, Expression*> * @return unordered_map<storage::Property, Expression*>
*/ */
antlrcpp::Any visitProperties(CypherParser::PropertiesContext *ctx) override; antlrcpp::Any visitProperties(
MemgraphCypher::PropertiesContext *ctx) override;
/** /**
* @return map<std::string, Expression*> * @return map<std::string, Expression*>
*/ */
antlrcpp::Any visitMapLiteral(CypherParser::MapLiteralContext *ctx) override; antlrcpp::Any visitMapLiteral(
MemgraphCypher::MapLiteralContext *ctx) override;
/** /**
* @return vector<Expression*> * @return vector<Expression*>
*/ */
antlrcpp::Any visitListLiteral( antlrcpp::Any visitListLiteral(
CypherParser::ListLiteralContext *ctx) override; MemgraphCypher::ListLiteralContext *ctx) override;
/** /**
* @return storage::Property * @return storage::Property
*/ */
antlrcpp::Any visitPropertyKeyName( antlrcpp::Any visitPropertyKeyName(
CypherParser::PropertyKeyNameContext *ctx) override; MemgraphCypher::PropertyKeyNameContext *ctx) override;
/** /**
* @return string * @return string
*/ */
antlrcpp::Any visitSymbolicName( antlrcpp::Any visitSymbolicName(
CypherParser::SymbolicNameContext *ctx) override; MemgraphCypher::SymbolicNameContext *ctx) override;
/** /**
* @return vector<Pattern*> * @return vector<Pattern*>
*/ */
antlrcpp::Any visitPattern(CypherParser::PatternContext *ctx) override; antlrcpp::Any visitPattern(MemgraphCypher::PatternContext *ctx) override;
/** /**
* @return Pattern* * @return Pattern*
*/ */
antlrcpp::Any visitPatternPart( antlrcpp::Any visitPatternPart(
CypherParser::PatternPartContext *ctx) override; MemgraphCypher::PatternPartContext *ctx) override;
/** /**
* @return Pattern* * @return Pattern*
*/ */
antlrcpp::Any visitPatternElement( antlrcpp::Any visitPatternElement(
CypherParser::PatternElementContext *ctx) override; MemgraphCypher::PatternElementContext *ctx) override;
/** /**
* @return vector<pair<EdgeAtom*, NodeAtom*>> * @return vector<pair<EdgeAtom*, NodeAtom*>>
*/ */
antlrcpp::Any visitPatternElementChain( antlrcpp::Any visitPatternElementChain(
CypherParser::PatternElementChainContext *ctx) override; MemgraphCypher::PatternElementChainContext *ctx) override;
/** /**
*@return EdgeAtom* *@return EdgeAtom*
*/ */
antlrcpp::Any visitRelationshipPattern( antlrcpp::Any visitRelationshipPattern(
CypherParser::RelationshipPatternContext *ctx) override; MemgraphCypher::RelationshipPatternContext *ctx) override;
/** /**
* This should never be called. Everything is done directly in * This should never be called. Everything is done directly in
* visitRelationshipPattern. * visitRelationshipPattern.
*/ */
antlrcpp::Any visitRelationshipDetail( antlrcpp::Any visitRelationshipDetail(
CypherParser::RelationshipDetailContext *ctx) override; MemgraphCypher::RelationshipDetailContext *ctx) override;
/** /**
* This should never be called. Everything is done directly in * This should never be called. Everything is done directly in
* visitRelationshipPattern. * visitRelationshipPattern.
*/ */
antlrcpp::Any visitRelationshipLambda( antlrcpp::Any visitRelationshipLambda(
CypherParser::RelationshipLambdaContext *ctx) override; MemgraphCypher::RelationshipLambdaContext *ctx) override;
/** /**
* @return vector<storage::EdgeType> * @return vector<storage::EdgeType>
*/ */
antlrcpp::Any visitRelationshipTypes( antlrcpp::Any visitRelationshipTypes(
CypherParser::RelationshipTypesContext *ctx) override; MemgraphCypher::RelationshipTypesContext *ctx) override;
/** /**
* @return std::tuple<EdgeAtom::Type, int64_t, int64_t>. * @return std::tuple<EdgeAtom::Type, int64_t, int64_t>.
*/ */
antlrcpp::Any visitVariableExpansion( antlrcpp::Any visitVariableExpansion(
CypherParser::VariableExpansionContext *ctx) override; MemgraphCypher::VariableExpansionContext *ctx) override;
/** /**
* Top level expression, does nothing. * Top level expression, does nothing.
* *
* @return Expression* * @return Expression*
*/ */
antlrcpp::Any visitExpression(CypherParser::ExpressionContext *ctx) override; antlrcpp::Any visitExpression(
MemgraphCypher::ExpressionContext *ctx) override;
/** /**
* OR. * OR.
@ -369,7 +389,7 @@ class CypherMainVisitor : public antlropencypher::CypherParserBaseVisitor {
* @return Expression* * @return Expression*
*/ */
antlrcpp::Any visitExpression12( antlrcpp::Any visitExpression12(
CypherParser::Expression12Context *ctx) override; MemgraphCypher::Expression12Context *ctx) override;
/** /**
* XOR. * XOR.
@ -377,7 +397,7 @@ class CypherMainVisitor : public antlropencypher::CypherParserBaseVisitor {
* @return Expression* * @return Expression*
*/ */
antlrcpp::Any visitExpression11( antlrcpp::Any visitExpression11(
CypherParser::Expression11Context *ctx) override; MemgraphCypher::Expression11Context *ctx) override;
/** /**
* AND. * AND.
@ -385,7 +405,7 @@ class CypherMainVisitor : public antlropencypher::CypherParserBaseVisitor {
* @return Expression* * @return Expression*
*/ */
antlrcpp::Any visitExpression10( antlrcpp::Any visitExpression10(
CypherParser::Expression10Context *ctx) override; MemgraphCypher::Expression10Context *ctx) override;
/** /**
* NOT. * NOT.
@ -393,7 +413,7 @@ class CypherMainVisitor : public antlropencypher::CypherParserBaseVisitor {
* @return Expression* * @return Expression*
*/ */
antlrcpp::Any visitExpression9( antlrcpp::Any visitExpression9(
CypherParser::Expression9Context *ctx) override; MemgraphCypher::Expression9Context *ctx) override;
/** /**
* Comparisons. * Comparisons.
@ -401,14 +421,14 @@ class CypherMainVisitor : public antlropencypher::CypherParserBaseVisitor {
* @return Expression* * @return Expression*
*/ */
antlrcpp::Any visitExpression8( antlrcpp::Any visitExpression8(
CypherParser::Expression8Context *ctx) override; MemgraphCypher::Expression8Context *ctx) override;
/** /**
* Never call this. Everything related to generating code for comparison * Never call this. Everything related to generating code for comparison
* operators should be done in visitExpression8. * operators should be done in visitExpression8.
*/ */
antlrcpp::Any visitPartialComparisonExpression( antlrcpp::Any visitPartialComparisonExpression(
CypherParser::PartialComparisonExpressionContext *ctx) override; MemgraphCypher::PartialComparisonExpressionContext *ctx) override;
/** /**
* Addition and subtraction. * Addition and subtraction.
@ -416,7 +436,7 @@ class CypherMainVisitor : public antlropencypher::CypherParserBaseVisitor {
* @return Expression* * @return Expression*
*/ */
antlrcpp::Any visitExpression7( antlrcpp::Any visitExpression7(
CypherParser::Expression7Context *ctx) override; MemgraphCypher::Expression7Context *ctx) override;
/** /**
* Multiplication, division, modding. * Multiplication, division, modding.
@ -424,7 +444,7 @@ class CypherMainVisitor : public antlropencypher::CypherParserBaseVisitor {
* @return Expression* * @return Expression*
*/ */
antlrcpp::Any visitExpression6( antlrcpp::Any visitExpression6(
CypherParser::Expression6Context *ctx) override; MemgraphCypher::Expression6Context *ctx) override;
/** /**
* Power. * Power.
@ -432,7 +452,7 @@ class CypherMainVisitor : public antlropencypher::CypherParserBaseVisitor {
* @return Expression* * @return Expression*
*/ */
antlrcpp::Any visitExpression5( antlrcpp::Any visitExpression5(
CypherParser::Expression5Context *ctx) override; MemgraphCypher::Expression5Context *ctx) override;
/** /**
* Unary minus and plus. * Unary minus and plus.
@ -440,7 +460,7 @@ class CypherMainVisitor : public antlropencypher::CypherParserBaseVisitor {
* @return Expression* * @return Expression*
*/ */
antlrcpp::Any visitExpression4( antlrcpp::Any visitExpression4(
CypherParser::Expression4Context *ctx) override; MemgraphCypher::Expression4Context *ctx) override;
/** /**
* IS NULL, IS NOT NULL, STARTS WITH, END WITH, =~, ... * IS NULL, IS NOT NULL, STARTS WITH, END WITH, =~, ...
@ -448,7 +468,7 @@ class CypherMainVisitor : public antlropencypher::CypherParserBaseVisitor {
* @return Expression* * @return Expression*
*/ */
antlrcpp::Any visitExpression3a( antlrcpp::Any visitExpression3a(
CypherParser::Expression3aContext *ctx) override; MemgraphCypher::Expression3aContext *ctx) override;
/** /**
* Does nothing, everything is done in visitExpression3a. * Does nothing, everything is done in visitExpression3a.
@ -456,7 +476,7 @@ class CypherMainVisitor : public antlropencypher::CypherParserBaseVisitor {
* @return Expression* * @return Expression*
*/ */
antlrcpp::Any visitStringAndNullOperators( antlrcpp::Any visitStringAndNullOperators(
CypherParser::StringAndNullOperatorsContext *ctx) override; MemgraphCypher::StringAndNullOperatorsContext *ctx) override;
/** /**
* List indexing and slicing. * List indexing and slicing.
@ -464,13 +484,13 @@ class CypherMainVisitor : public antlropencypher::CypherParserBaseVisitor {
* @return Expression* * @return Expression*
*/ */
antlrcpp::Any visitExpression3b( antlrcpp::Any visitExpression3b(
CypherParser::Expression3bContext *ctx) override; MemgraphCypher::Expression3bContext *ctx) override;
/** /**
* Does nothing, everything is done in visitExpression3b. * Does nothing, everything is done in visitExpression3b.
*/ */
antlrcpp::Any visitListIndexingOrSlicing( antlrcpp::Any visitListIndexingOrSlicing(
CypherParser::ListIndexingOrSlicingContext *ctx) override; MemgraphCypher::ListIndexingOrSlicingContext *ctx) override;
/** /**
* Node labels test. * Node labels test.
@ -478,7 +498,7 @@ class CypherMainVisitor : public antlropencypher::CypherParserBaseVisitor {
* @return Expression* * @return Expression*
*/ */
antlrcpp::Any visitExpression2a( antlrcpp::Any visitExpression2a(
CypherParser::Expression2aContext *ctx) override; MemgraphCypher::Expression2aContext *ctx) override;
/** /**
* Property lookup. * Property lookup.
@ -486,42 +506,42 @@ class CypherMainVisitor : public antlropencypher::CypherParserBaseVisitor {
* @return Expression* * @return Expression*
*/ */
antlrcpp::Any visitExpression2b( antlrcpp::Any visitExpression2b(
CypherParser::Expression2bContext *ctx) override; MemgraphCypher::Expression2bContext *ctx) override;
/** /**
* Literals, params, list comprehension... * Literals, params, list comprehension...
* *
* @return Expression* * @return Expression*
*/ */
antlrcpp::Any visitAtom(CypherParser::AtomContext *ctx) override; antlrcpp::Any visitAtom(MemgraphCypher::AtomContext *ctx) override;
/** /**
* @return ParameterLookup* * @return ParameterLookup*
*/ */
antlrcpp::Any visitParameter(CypherParser::ParameterContext *ctx) override; antlrcpp::Any visitParameter(MemgraphCypher::ParameterContext *ctx) override;
/** /**
* @return Expression* * @return Expression*
*/ */
antlrcpp::Any visitParenthesizedExpression( antlrcpp::Any visitParenthesizedExpression(
CypherParser::ParenthesizedExpressionContext *ctx) override; MemgraphCypher::ParenthesizedExpressionContext *ctx) override;
/** /**
* @return Expression* * @return Expression*
*/ */
antlrcpp::Any visitFunctionInvocation( antlrcpp::Any visitFunctionInvocation(
CypherParser::FunctionInvocationContext *ctx) override; MemgraphCypher::FunctionInvocationContext *ctx) override;
/** /**
* @return string - uppercased * @return string - uppercased
*/ */
antlrcpp::Any visitFunctionName( antlrcpp::Any visitFunctionName(
CypherParser::FunctionNameContext *ctx) override; MemgraphCypher::FunctionNameContext *ctx) override;
/** /**
* @return Expression* * @return Expression*
*/ */
antlrcpp::Any visitLiteral(CypherParser::LiteralContext *ctx) override; antlrcpp::Any visitLiteral(MemgraphCypher::LiteralContext *ctx) override;
/** /**
* Convert escaped string from a query to unescaped utf8 string. * Convert escaped string from a query to unescaped utf8 string.
@ -534,97 +554,98 @@ class CypherMainVisitor : public antlropencypher::CypherParserBaseVisitor {
* @return bool * @return bool
*/ */
antlrcpp::Any visitBooleanLiteral( antlrcpp::Any visitBooleanLiteral(
CypherParser::BooleanLiteralContext *ctx) override; MemgraphCypher::BooleanLiteralContext *ctx) override;
/** /**
* @return TypedValue with either double or int * @return TypedValue with either double or int
*/ */
antlrcpp::Any visitNumberLiteral( antlrcpp::Any visitNumberLiteral(
CypherParser::NumberLiteralContext *ctx) override; MemgraphCypher::NumberLiteralContext *ctx) override;
/** /**
* @return int64_t * @return int64_t
*/ */
antlrcpp::Any visitIntegerLiteral( antlrcpp::Any visitIntegerLiteral(
CypherParser::IntegerLiteralContext *ctx) override; MemgraphCypher::IntegerLiteralContext *ctx) override;
/** /**
* @return double * @return double
*/ */
antlrcpp::Any visitDoubleLiteral( antlrcpp::Any visitDoubleLiteral(
CypherParser::DoubleLiteralContext *ctx) override; MemgraphCypher::DoubleLiteralContext *ctx) override;
/** /**
* @return Delete* * @return Delete*
*/ */
antlrcpp::Any visitCypherDelete( antlrcpp::Any visitCypherDelete(
CypherParser::CypherDeleteContext *ctx) override; MemgraphCypher::CypherDeleteContext *ctx) override;
/** /**
* @return Where* * @return Where*
*/ */
antlrcpp::Any visitWhere(CypherParser::WhereContext *ctx) override; antlrcpp::Any visitWhere(MemgraphCypher::WhereContext *ctx) override;
/** /**
* return vector<Clause*> * return vector<Clause*>
*/ */
antlrcpp::Any visitSet(CypherParser::SetContext *ctx) override; antlrcpp::Any visitSet(MemgraphCypher::SetContext *ctx) override;
/** /**
* @return Clause* * @return Clause*
*/ */
antlrcpp::Any visitSetItem(CypherParser::SetItemContext *ctx) override; antlrcpp::Any visitSetItem(MemgraphCypher::SetItemContext *ctx) override;
/** /**
* return vector<Clause*> * return vector<Clause*>
*/ */
antlrcpp::Any visitRemove(CypherParser::RemoveContext *ctx) override; antlrcpp::Any visitRemove(MemgraphCypher::RemoveContext *ctx) override;
/** /**
* @return Clause* * @return Clause*
*/ */
antlrcpp::Any visitRemoveItem(CypherParser::RemoveItemContext *ctx) override; antlrcpp::Any visitRemoveItem(
MemgraphCypher::RemoveItemContext *ctx) override;
/** /**
* @return PropertyLookup* * @return PropertyLookup*
*/ */
antlrcpp::Any visitPropertyExpression( antlrcpp::Any visitPropertyExpression(
CypherParser::PropertyExpressionContext *ctx) override; MemgraphCypher::PropertyExpressionContext *ctx) override;
/** /**
* @return IfOperator* * @return IfOperator*
*/ */
antlrcpp::Any visitCaseExpression( antlrcpp::Any visitCaseExpression(
CypherParser::CaseExpressionContext *ctx) override; MemgraphCypher::CaseExpressionContext *ctx) override;
/** /**
* Never call this. Ast generation for this production is done in * Never call this. Ast generation for this production is done in
* @c visitCaseExpression. * @c visitCaseExpression.
*/ */
antlrcpp::Any visitCaseAlternatives( antlrcpp::Any visitCaseAlternatives(
CypherParser::CaseAlternativesContext *ctx) override; MemgraphCypher::CaseAlternativesContext *ctx) override;
/** /**
* @return With* * @return With*
*/ */
antlrcpp::Any visitWith(CypherParser::WithContext *ctx) override; antlrcpp::Any visitWith(MemgraphCypher::WithContext *ctx) override;
/** /**
* @return Merge* * @return Merge*
*/ */
antlrcpp::Any visitMerge(CypherParser::MergeContext *ctx) override; antlrcpp::Any visitMerge(MemgraphCypher::MergeContext *ctx) override;
/** /**
* @return Unwind* * @return Unwind*
*/ */
antlrcpp::Any visitUnwind(CypherParser::UnwindContext *ctx) override; antlrcpp::Any visitUnwind(MemgraphCypher::UnwindContext *ctx) override;
/** /**
* Never call this. Ast generation for these expressions should be done by * Never call this. Ast generation for these expressions should be done by
* explicitly visiting the members of @c FilterExpressionContext. * explicitly visiting the members of @c FilterExpressionContext.
*/ */
antlrcpp::Any visitFilterExpression( antlrcpp::Any visitFilterExpression(
CypherParser::FilterExpressionContext *) override; MemgraphCypher::FilterExpressionContext *) override;
public: public:
Query *query() { return query_; } Query *query() { return query_; }

View File

@ -1,13 +1,13 @@
/* /*
* Copyright (c) 2015-2016 "Neo Technology," * Copyright (c) 2015-2016 "Neo Technology,"
* Network Engine for Objects in Lund AB [http://neotechnology.com] * Network Engine for Objects in Lund AB [http://neotechnology.com]
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -15,17 +15,11 @@
* limitations under the License. * limitations under the License.
*/ */
/* parser grammar Cypher;
* When changing this grammar make sure to update constants in
* src/query/frontend/stripped_lexer_constants.hpp (kKeywords, kSpecialTokens
* and bitsets) if needed.
*/
parser grammar CypherParser ;
options { tokenVocab=CypherLexer; } options { tokenVocab=CypherLexer; }
cypher : statement ; cypher : statement ';'? EOF ;
statement : query ; statement : query ;
@ -49,14 +43,6 @@ clause : cypherMatch
| with | with
| cypherReturn | cypherReturn
| createIndex | createIndex
| modifyUser
| dropUser
| createStream
| dropStream
| showStreams
| startStopStream
| startStopAllStreams
| testStream
; ;
cypherMatch : OPTIONAL? MATCH pattern where? ; cypherMatch : OPTIONAL? MATCH pattern where? ;
@ -249,9 +235,7 @@ idInColl : variable IN expression ;
functionInvocation : functionName '(' ( DISTINCT )? ( expression ( ',' expression )* )? ')' ; functionInvocation : functionName '(' ( DISTINCT )? ( expression ( ',' expression )* )? ')' ;
functionName : UnescapedSymbolicName functionName : symbolicName ;
| EscapedSymbolicName
| COUNT ;
listComprehension : '[' filterExpression ( '|' expression )? ']' ; listComprehension : '[' filterExpression ( '|' expression )? ']' ;
@ -281,112 +265,67 @@ integerLiteral : DecimalLiteral
| OctalLiteral | OctalLiteral
| HexadecimalLiteral | HexadecimalLiteral
; ;
createIndex : CREATE INDEX ON ':' labelName '(' propertyKeyName ')' ; createIndex : CREATE INDEX ON ':' labelName '(' propertyKeyName ')' ;
userName : UnescapedSymbolicName ;
createUser : CREATE USER ;
alterUser : ALTER USER ;
modifyUser : ( createUser | alterUser ) userName ( WITH ( modifyUserOption )+ )? ;
modifyUserOption : passwordOption ;
passwordOption : PASSWORD literal;
dropUser : DROP USER userName ( ',' userName )* ;
streamName : UnescapedSymbolicName ;
createStream : CREATE STREAM streamName AS LOAD DATA KAFKA
streamUri=literal WITH TOPIC streamTopic=literal WITH TRANSFORM
transformUri=literal ( batchIntervalOption )? (batchSizeOption )? ;
batchIntervalOption : BATCH_INTERVAL literal ;
batchSizeOption : BATCH_SIZE literal ;
dropStream : DROP STREAM streamName ;
showStreams : SHOW STREAMS ;
startStopStream : ( START | STOP ) STREAM streamName ( limitBatchesOption )? ;
limitBatchesOption : LIMIT limitBatches=literal BATCHES ;
startStopAllStreams : ( START | STOP ) ALL STREAMS ;
testStream : K_TEST STREAM streamName ( limitBatchesOption )? ;
doubleLiteral : FloatingLiteral ; doubleLiteral : FloatingLiteral ;
cypherKeyword : ALL
| AND
| ANY
| AS
| ASC
| ASCENDING
| BFS
| BY
| CASE
| CONTAINS
| COUNT
| CREATE
| CYPHERNULL
| DELETE
| DESC
| DESCENDING
| DETACH
| DISTINCT
| ELSE
| END
| ENDS
| EXTRACT
| FALSE
| FILTER
| IN
| INDEX
| IS
| LIMIT
| L_SKIP
| MATCH
| MERGE
| NONE
| NOT
| ON
| OPTIONAL
| OR
| ORDER
| REDUCE
| REMOVE
| RETURN
| SET
| SHOW
| SINGLE
| STARTS
| THEN
| TRUE
| UNION
| UNWIND
| WHEN
| WHERE
| WITH
| WSHORTEST
| XOR
;
symbolicName : UnescapedSymbolicName symbolicName : UnescapedSymbolicName
| EscapedSymbolicName | EscapedSymbolicName
| UNION | cypherKeyword
| ALL
| REDUCE
| OPTIONAL
| MATCH
| UNWIND
| AS
| MERGE
| ON
| CREATE
| SET
| DETACH
| DELETE
| REMOVE
| WITH
| DISTINCT
| RETURN
| ORDER
| BY
| L_SKIP
| LIMIT
| ASCENDING
| ASC
| DESCENDING
| DESC
| WHERE
| OR
| XOR
| AND
| NOT
| IN
| STARTS
| ENDS
| CONTAINS
| IS
| CYPHERNULL
| CASE
| WHEN
| THEN
| ELSE
| END
| COUNT
| FILTER
| EXTRACT
| ANY
| NONE
| SINGLE
| TRUE
| FALSE
| USER
| PASSWORD
| ALTER
| DROP
| STREAM
| STREAMS
| LOAD
| DATA
| KAFKA
| TRANSFORM
| BATCH_SIZE
| BATCH_INTERVAL
| SHOW
| START
| STOP
; ;

View File

@ -1,3 +1,9 @@
/*
* When changing this grammar make sure to update constants in
* src/query/frontend/stripped_lexer_constants.hpp (kKeywords, kSpecialTokens
* and bitsets) if needed.
*/
lexer grammar CypherLexer ; lexer grammar CypherLexer ;
import UnicodeCategories ; import UnicodeCategories ;
@ -22,36 +28,37 @@ fragment Comment : '/*' .*? '*/'
; ;
/* Special symbols. */ /* Special symbols. */
LPAREN : '(' ; LPAREN : '(' ;
RPAREN : ')' ; RPAREN : ')' ;
LBRACK : '[' ; LBRACK : '[' ;
RBRACK : ']' ; RBRACK : ']' ;
LBRACE : '{' ; LBRACE : '{' ;
RBRACE : '}' ; RBRACE : '}' ;
COMMA : ',' ; COMMA : ',' ;
DOT : '.' ; DOT : '.' ;
DOTS : '..' ; DOTS : '..' ;
COLON : ':' ; COLON : ':' ;
DOLLAR : '$' ; SEMICOLON : ';' ;
PIPE : '|' ; DOLLAR : '$' ;
PIPE : '|' ;
EQ : '=' ; EQ : '=' ;
LT : '<' ; LT : '<' ;
GT : '>' ; GT : '>' ;
LTE : '<=' ; LTE : '<=' ;
GTE : '>=' ; GTE : '>=' ;
NEQ1 : '<>' ; NEQ1 : '<>' ;
NEQ2 : '!=' ; NEQ2 : '!=' ;
SIM : '=~' ; SIM : '=~' ;
PLUS : '+' ; PLUS : '+' ;
MINUS : '-' ; MINUS : '-' ;
ASTERISK : '*' ; ASTERISK : '*' ;
SLASH : '/' ; SLASH : '/' ;
PERCENT : '%' ; PERCENT : '%' ;
CARET : '^' ; CARET : '^' ;
PLUS_EQ : '+=' ; PLUS_EQ : '+=' ;
/* Some random unicode characters that can be used to draw arrows. */ /* Some random unicode characters that can be used to draw arrows. */
LeftArrowHeadPart : '⟨' | '〈' | '﹤' | '' ; LeftArrowHeadPart : '⟨' | '〈' | '﹤' | '' ;
@ -62,15 +69,11 @@ DashPart : '­' | '' | '' | '' | '' | '—' | '―'
/* Cypher reserved words. */ /* Cypher reserved words. */
ALL : A L L ; ALL : A L L ;
ALTER : A L T E R ;
AND : A N D ; AND : A N D ;
ANY : A N Y ; ANY : A N Y ;
AS : A S ; AS : A S ;
ASC : A S C ; ASC : A S C ;
ASCENDING : A S C E N D I N G ; ASCENDING : A S C E N D I N G ;
BATCHES : B A T C H E S ;
BATCH_INTERVAL : B A T C H '_' I N T E R V A L ;
BATCH_SIZE : B A T C H '_' S I Z E ;
BFS : B F S ; BFS : B F S ;
BY : B Y ; BY : B Y ;
CASE : C A S E ; CASE : C A S E ;
@ -78,13 +81,11 @@ CONTAINS : C O N T A I N S ;
COUNT : C O U N T ; COUNT : C O U N T ;
CREATE : C R E A T E ; CREATE : C R E A T E ;
CYPHERNULL : N U L L ; CYPHERNULL : N U L L ;
DATA : D A T A ;
DELETE : D E L E T E ; DELETE : D E L E T E ;
DESC : D E S C ; DESC : D E S C ;
DESCENDING : D E S C E N D I N G ; DESCENDING : D E S C E N D I N G ;
DETACH : D E T A C H ; DETACH : D E T A C H ;
DISTINCT : D I S T I N C T ; DISTINCT : D I S T I N C T ;
DROP : D R O P ;
ELSE : E L S E ; ELSE : E L S E ;
END : E N D ; END : E N D ;
ENDS : E N D S ; ENDS : E N D S ;
@ -94,10 +95,7 @@ FILTER : F I L T E R ;
IN : I N ; IN : I N ;
INDEX : I N D E X ; INDEX : I N D E X ;
IS : I S ; IS : I S ;
KAFKA : K A F K A ;
K_TEST : T E S T ;
LIMIT : L I M I T ; LIMIT : L I M I T ;
LOAD : L O A D ;
L_SKIP : S K I P ; L_SKIP : S K I P ;
MATCH : M A T C H ; MATCH : M A T C H ;
MERGE : M E R G E ; MERGE : M E R G E ;
@ -107,25 +105,17 @@ ON : O N ;
OPTIONAL : O P T I O N A L ; OPTIONAL : O P T I O N A L ;
OR : O R ; OR : O R ;
ORDER : O R D E R ; ORDER : O R D E R ;
PASSWORD : P A S S W O R D ;
REDUCE : R E D U C E ; REDUCE : R E D U C E ;
REMOVE : R E M O V E ; REMOVE : R E M O V E ;
RETURN : R E T U R N ; RETURN : R E T U R N ;
SET : S E T ; SET : S E T ;
SHOW : S H O W ; SHOW : S H O W ;
SINGLE : S I N G L E ; SINGLE : S I N G L E ;
START : S T A R T ;
STARTS : S T A R T S ; STARTS : S T A R T S ;
STOP : S T O P ;
STREAM : S T R E A M ;
STREAMS : S T R E A M S ;
THEN : T H E N ; THEN : T H E N ;
TOPIC : T O P I C ;
TRANSFORM : T R A N S F O R M ;
TRUE : T R U E ; TRUE : T R U E ;
UNION : U N I O N ; UNION : U N I O N ;
UNWIND : U N W I N D ; UNWIND : U N W I N D ;
USER : U S E R ;
WHEN : W H E N ; WHEN : W H E N ;
WHERE : W H E R E ; WHERE : W H E R E ;
WITH : W I T H ; WITH : W I T H ;

View File

@ -0,0 +1,82 @@
/* Memgraph specific part of Cypher grammar. */
parser grammar MemgraphCypher ;
options { tokenVocab=MemgraphCypherLexer; }
import Cypher ;
memgraphCypherKeyword : cypherKeyword
| ALTER
| BATCH
| BATCHES
| DATA
| DROP
| INTERVAL
| K_TEST
| KAFKA
| LOAD
| PASSWORD
| SIZE
| START
| STOP
| STREAM
| STREAMS
| TOPIC
| TRANSFORM
| USER
;
symbolicName : UnescapedSymbolicName
| EscapedSymbolicName
| memgraphCypherKeyword
;
query : regularQuery
| authQuery
| streamQuery
;
authQuery : modifyUser
| dropUser
;
modifyUser : ( CREATE | ALTER ) USER userName=UnescapedSymbolicName
( WITH ( modifyUserOption )+ )? ;
modifyUserOption : passwordOption ;
passwordOption : PASSWORD literal;
dropUser : DROP USER userName+=UnescapedSymbolicName
( ',' userName+=UnescapedSymbolicName )* ;
streamQuery : createStream
| dropStream
| showStreams
| startStopStream
| startStopAllStreams
| testStream
;
streamName : UnescapedSymbolicName ;
createStream : CREATE STREAM streamName AS LOAD DATA KAFKA
streamUri=literal WITH TOPIC streamTopic=literal WITH TRANSFORM
transformUri=literal ( batchIntervalOption )? ( batchSizeOption )? ;
batchIntervalOption : BATCH INTERVAL literal ;
batchSizeOption : BATCH SIZE literal ;
dropStream : DROP STREAM streamName ;
showStreams : SHOW STREAMS ;
startStopStream : ( START | STOP ) STREAM streamName ( limitBatchesOption )? ;
limitBatchesOption : LIMIT limitBatches=literal BATCHES ;
startStopAllStreams : ( START | STOP ) ALL STREAMS ;
testStream : K_TEST STREAM streamName ( limitBatchesOption )? ;

View File

@ -0,0 +1,30 @@
/* Memgraph specific Cypher reserved words. */
/*
* When changing this grammar make sure to update constants in
* src/query/frontend/stripped_lexer_constants.hpp (kKeywords, kSpecialTokens
* and bitsets) if needed.
*/
lexer grammar MemgraphCypherLexer ;
import CypherLexer ;
ALTER : A L T E R ;
BATCH : B A T C H ;
BATCHES : B A T C H E S ;
DATA : D A T A ;
DROP : D R O P ;
INTERVAL : I N T E R V A L ;
K_TEST : T E S T ;
KAFKA : K A F K A ;
LOAD : L O A D ;
PASSWORD : P A S S W O R D ;
SIZE : S I Z E ;
START : S T A R T ;
STOP : S T O P ;
STREAM : S T R E A M ;
STREAMS : S T R E A M S ;
TOPIC : T O P I C ;
TRANSFORM : T R A N S F O R M ;
USER : U S E R ;

View File

@ -4,8 +4,8 @@
#include "antlr4-runtime.h" #include "antlr4-runtime.h"
#include "query/exceptions.hpp" #include "query/exceptions.hpp"
#include "query/frontend/opencypher/generated/CypherLexer.h" #include "query/frontend/opencypher/generated/MemgraphCypher.h"
#include "query/frontend/opencypher/generated/CypherParser.h" #include "query/frontend/opencypher/generated/MemgraphCypherLexer.h"
namespace query { namespace query {
namespace frontend { namespace frontend {
@ -51,11 +51,11 @@ class Parser {
FirstMessageErrorListener error_listener_; FirstMessageErrorListener error_listener_;
std::string query_; std::string query_;
antlr4::ANTLRInputStream input_{query_.c_str()}; antlr4::ANTLRInputStream input_{query_.c_str()};
antlropencypher::CypherLexer lexer_{&input_}; antlropencypher::MemgraphCypherLexer lexer_{&input_};
antlr4::CommonTokenStream tokens_{&lexer_}; antlr4::CommonTokenStream tokens_{&lexer_};
// generate ast // generate ast
antlropencypher::CypherParser parser_{&tokens_}; antlropencypher::MemgraphCypher parser_{&tokens_};
antlr4::tree::ParseTree *tree_ = nullptr; antlr4::tree::ParseTree *tree_ = nullptr;
}; };
} // namespace opencypher } // namespace opencypher

View File

@ -10,9 +10,9 @@
#include "query/common.hpp" #include "query/common.hpp"
#include "query/exceptions.hpp" #include "query/exceptions.hpp"
#include "query/frontend/opencypher/generated/CypherLexer.h" #include "query/frontend/opencypher/generated/MemgraphCypher.h"
#include "query/frontend/opencypher/generated/CypherParser.h" #include "query/frontend/opencypher/generated/MemgraphCypherBaseVisitor.h"
#include "query/frontend/opencypher/generated/CypherParserBaseVisitor.h" #include "query/frontend/opencypher/generated/MemgraphCypherLexer.h"
#include "query/frontend/stripped_lexer_constants.hpp" #include "query/frontend/stripped_lexer_constants.hpp"
#include "utils/hashing/fnv.hpp" #include "utils/hashing/fnv.hpp"
#include "utils/string.hpp" #include "utils/string.hpp"

View File

@ -1,8 +1,8 @@
#include <iostream> #include <iostream>
#include "antlr4-runtime.h" #include "antlr4-runtime.h"
#include "query/frontend/opencypher/generated/CypherLexer.h" #include "query/frontend/opencypher/generated/MemgraphCypher.h"
#include "query/frontend/opencypher/generated/CypherParser.h" #include "query/frontend/opencypher/generated/MemgraphCypherLexer.h"
using namespace antlropencypher; using namespace antlropencypher;
using namespace antlr4; using namespace antlr4;
@ -11,7 +11,7 @@ int main(int, const char **a) {
const char *query = a[1]; const char *query = a[1];
ANTLRInputStream input(query); ANTLRInputStream input(query);
CypherLexer lexer(&input); MemgraphCypherLexer lexer(&input);
CommonTokenStream tokens(&lexer); CommonTokenStream tokens(&lexer);
const auto &vocabulary = lexer.getVocabulary(); const auto &vocabulary = lexer.getVocabulary();
@ -22,7 +22,7 @@ int main(int, const char **a) {
<< "; STRING: " << token->toString() << std::endl; << "; STRING: " << token->toString() << std::endl;
} }
CypherParser parser(&tokens); MemgraphCypher parser(&tokens);
tree::ParseTree *tree = parser.cypher(); tree::ParseTree *tree = parser.cypher();
std::cout << tree->toStringTree(&parser) << std::endl << std::endl; std::cout << tree->toStringTree(&parser) << std::endl << std::endl;

View File

@ -5,8 +5,8 @@
#include <string> #include <string>
#include "antlr4-runtime.h" #include "antlr4-runtime.h"
#include "query/frontend/opencypher/generated/CypherLexer.h" #include "query/frontend/opencypher/generated/MemgraphCypher.h"
#include "query/frontend/opencypher/generated/CypherParser.h" #include "query/frontend/opencypher/generated/MemgraphCypherLexer.h"
using namespace antlropencypher; using namespace antlropencypher;
using namespace antlr4; using namespace antlr4;
@ -22,10 +22,10 @@ std::string ReadAllInput() {
return results; return results;
} }
int main(int, const char**) { int main(int, const char **) {
std::string input_string = ReadAllInput(); std::string input_string = ReadAllInput();
ANTLRInputStream input(input_string); ANTLRInputStream input(input_string);
CypherLexer lexer(&input); MemgraphCypherLexer lexer(&input);
CommonTokenStream tokens(&lexer); CommonTokenStream tokens(&lexer);
tokens.fill(); tokens.fill();
@ -33,8 +33,8 @@ int main(int, const char**) {
std::cout << token->toString() << std::endl; std::cout << token->toString() << std::endl;
} }
CypherParser parser(&tokens); MemgraphCypher parser(&tokens);
tree::ParseTree* tree = parser.cypher(); tree::ParseTree *tree = parser.cypher();
// Print tree indented. This is a hacky implementation and not very correct. // Print tree indented. This is a hacky implementation and not very correct.
std::string indent; std::string indent;

View File

@ -240,18 +240,20 @@ TYPED_TEST(CypherMainVisitorTest, EscapedLabel) {
} }
TYPED_TEST(CypherMainVisitorTest, KeywordLabel) { TYPED_TEST(CypherMainVisitorTest, KeywordLabel) {
TypeParam ast_generator("RETURN n:DEletE"); for (const auto &label : {"DeLete", "UsER"}) {
auto *query = ast_generator.query_; TypeParam ast_generator(fmt::format("RETURN n:{}", label));
ASSERT_TRUE(query->single_query_); auto *query = ast_generator.query_;
auto *single_query = query->single_query_; ASSERT_TRUE(query->single_query_);
ASSERT_EQ(single_query->clauses_.size(), 1U); auto *single_query = query->single_query_;
auto *return_clause = dynamic_cast<Return *>(single_query->clauses_[0]); ASSERT_EQ(single_query->clauses_.size(), 1U);
auto *labels_test = dynamic_cast<LabelsTest *>( auto *return_clause = dynamic_cast<Return *>(single_query->clauses_[0]);
return_clause->body_.named_expressions[0]->expression_); auto *labels_test = dynamic_cast<LabelsTest *>(
auto identifier = dynamic_cast<Identifier *>(labels_test->expression_); return_clause->body_.named_expressions[0]->expression_);
ASSERT_EQ(identifier->name_, "n"); auto identifier = dynamic_cast<Identifier *>(labels_test->expression_);
ASSERT_THAT(labels_test->labels_, ASSERT_EQ(identifier->name_, "n");
ElementsAre(ast_generator.db_accessor_->Label("DEletE"))); ASSERT_THAT(labels_test->labels_,
ElementsAre(ast_generator.db_accessor_->Label(label)));
}
} }
TYPED_TEST(CypherMainVisitorTest, HexLetterLabel) { TYPED_TEST(CypherMainVisitorTest, HexLetterLabel) {
@ -779,21 +781,6 @@ TYPED_TEST(CypherMainVisitorTest, UndefinedFunction) {
SemanticException); SemanticException);
} }
TYPED_TEST(CypherMainVisitorTest, FunctionSpecialCase) {
// For some reason parsing of function calls with single letter name in a-f
// range would fail, so here's a test for that (also see D1464).
TypeParam ast_generator("RETURN e()");
auto *query = ast_generator.query_;
ASSERT_TRUE(query->single_query_);
auto *single_query = query->single_query_;
auto *return_clause = dynamic_cast<Return *>(single_query->clauses_[0]);
ASSERT_EQ(return_clause->body_.named_expressions.size(), 1);
auto *function = dynamic_cast<Function *>(
return_clause->body_.named_expressions[0]->expression_);
ASSERT_TRUE(function);
ASSERT_TRUE(function->function());
}
TYPED_TEST(CypherMainVisitorTest, Function) { TYPED_TEST(CypherMainVisitorTest, Function) {
TypeParam ast_generator("RETURN abs(n, 2)"); TypeParam ast_generator("RETURN abs(n, 2)");
auto *query = ast_generator.query_; auto *query = ast_generator.query_;
@ -2023,40 +2010,40 @@ TYPED_TEST(CypherMainVisitorTest, CreateStream) {
check_create_stream( check_create_stream(
"CreaTE StreaM strim AS LOad daTA KAFKA 'localhost' " "CreaTE StreaM strim AS LOad daTA KAFKA 'localhost' "
"WitH TopIC 'tropika' " "WitH TopIC 'tropika' "
"WITH TRAnsFORM 'localhost/test.py' bAtCH_inTErvAL 168", "WITH TRAnsFORM 'localhost/test.py' bAtCH inTErvAL 168",
"strim", "localhost", "tropika", "localhost/test.py", 168, "strim", "localhost", "tropika", "localhost/test.py", 168,
std::experimental::nullopt); std::experimental::nullopt);
check_create_stream( check_create_stream(
"CreaTE StreaM strim AS LOad daTA KAFKA 'localhost' " "CreaTE StreaM strim AS LOad daTA KAFKA 'localhost' "
"WITH TopIC 'tropika' " "WITH TopIC 'tropika' "
"WITH TRAnsFORM 'localhost/test.py' bAtCH_SizE 17", "WITH TRAnsFORM 'localhost/test.py' bAtCH SizE 17",
"strim", "localhost", "tropika", "localhost/test.py", "strim", "localhost", "tropika", "localhost/test.py",
std::experimental::nullopt, 17); std::experimental::nullopt, 17);
check_create_stream( check_create_stream(
"CreaTE StreaM strim AS LOad daTA KAFKA 'localhost' " "CreaTE StreaM strim AS LOad daTA KAFKA 'localhost' "
"WitH TOPic 'tropika' " "WitH TOPic 'tropika' "
"WITH TRAnsFORM 'localhost/test.py' bAtCH_inTErvAL 168 Batch_SIze 17", "WITH TRAnsFORM 'localhost/test.py' bAtCH inTErvAL 168 Batch SIze 17",
"strim", "localhost", "tropika", "localhost/test.py", 168, 17); "strim", "localhost", "tropika", "localhost/test.py", 168, 17);
EXPECT_THROW(check_create_stream( EXPECT_THROW(check_create_stream(
"CREATE STREAM strim AS LOAD DATA KAFKA 'localhost' " "CREATE STREAM strim AS LOAD DATA KAFKA 'localhost' "
"WITH TRANSFORM 'localhost/test.py' BATCH_INTERVAL 'jedan' ", "WITH TRANSFORM 'localhost/test.py' BATCH INTERVAL 'jedan' ",
"strim", "localhost", "tropika", "localhost/test.py", 168, "strim", "localhost", "tropika", "localhost/test.py", 168,
std::experimental::nullopt), std::experimental::nullopt),
SyntaxException); SyntaxException);
EXPECT_THROW(check_create_stream( EXPECT_THROW(check_create_stream(
"CREATE STREAM strim AS LOAD DATA KAFKA 'localhost' " "CREATE STREAM strim AS LOAD DATA KAFKA 'localhost' "
"WITH TOPIC 'tropika' " "WITH TOPIC 'tropika' "
"WITH TRANSFORM 'localhost/test.py' BATCH_SIZE 'jedan' ", "WITH TRANSFORM 'localhost/test.py' BATCH SIZE 'jedan' ",
"strim", "localhost", "tropika", "localhost/test.py", "strim", "localhost", "tropika", "localhost/test.py",
std::experimental::nullopt, 17), std::experimental::nullopt, 17),
SyntaxException); SyntaxException);
EXPECT_THROW(check_create_stream( EXPECT_THROW(check_create_stream(
"CREATE STREAM 123 AS LOAD DATA KAFKA 'localhost' " "CREATE STREAM 123 AS LOAD DATA KAFKA 'localhost' "
"WITH TOPIC 'tropika' " "WITH TOPIC 'tropika' "
"WITH TRANSFORM 'localhost/test.py' BATCH_INTERVAL 168 ", "WITH TRANSFORM 'localhost/test.py' BATCH INTERVAL 168 ",
"strim", "localhost", "tropika", "localhost/test.py", 168, "strim", "localhost", "tropika", "localhost/test.py", 168,
std::experimental::nullopt), std::experimental::nullopt),
SyntaxException); SyntaxException);
@ -2070,14 +2057,14 @@ TYPED_TEST(CypherMainVisitorTest, CreateStream) {
EXPECT_THROW(check_create_stream( EXPECT_THROW(check_create_stream(
"CREATE STREAM strim AS LOAD DATA KAFKA 'localhost' " "CREATE STREAM strim AS LOAD DATA KAFKA 'localhost' "
"WITH TOPIC 2" "WITH TOPIC 2"
"WITH TRANSFORM localhost/test.py BATCH_INTERVAL 168 ", "WITH TRANSFORM localhost/test.py BATCH INTERVAL 168 ",
"strim", "localhost", "tropika", "localhost/test.py", 168, "strim", "localhost", "tropika", "localhost/test.py", 168,
std::experimental::nullopt), std::experimental::nullopt),
SyntaxException); SyntaxException);
EXPECT_THROW(check_create_stream( EXPECT_THROW(check_create_stream(
"CREATE STREAM strim AS LOAD DATA KAFKA 'localhost' " "CREATE STREAM strim AS LOAD DATA KAFKA 'localhost' "
"WITH TOPIC 'tropika'" "WITH TOPIC 'tropika'"
"WITH TRANSFORM localhost/test.py BATCH_INTERVAL 168 ", "WITH TRANSFORM localhost/test.py BATCH INTERVAL 168 ",
"strim", "localhost", "tropika", "localhost/test.py", 168, "strim", "localhost", "tropika", "localhost/test.py", 168,
std::experimental::nullopt), std::experimental::nullopt),
SyntaxException); SyntaxException);