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

View File

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

View File

@ -15,17 +15,11 @@
* limitations under the License.
*/
/*
* 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 ;
parser grammar Cypher;
options { tokenVocab=CypherLexer; }
cypher : statement ;
cypher : statement ';'? EOF ;
statement : query ;
@ -49,14 +43,6 @@ clause : cypherMatch
| with
| cypherReturn
| createIndex
| modifyUser
| dropUser
| createStream
| dropStream
| showStreams
| startStopStream
| startStopAllStreams
| testStream
;
cypherMatch : OPTIONAL? MATCH pattern where? ;
@ -249,9 +235,7 @@ idInColl : variable IN expression ;
functionInvocation : functionName '(' ( DISTINCT )? ( expression ( ',' expression )* )? ')' ;
functionName : UnescapedSymbolicName
| EscapedSymbolicName
| COUNT ;
functionName : symbolicName ;
listComprehension : '[' filterExpression ( '|' expression )? ']' ;
@ -284,109 +268,64 @@ integerLiteral : DecimalLiteral
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 ;
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
| EscapedSymbolicName
| UNION
| 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
| cypherKeyword
;

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 ;
import UnicodeCategories ;
@ -33,6 +39,7 @@ COMMA : ',' ;
DOT : '.' ;
DOTS : '..' ;
COLON : ':' ;
SEMICOLON : ';' ;
DOLLAR : '$' ;
PIPE : '|' ;
@ -62,15 +69,11 @@ DashPart : '­' | '' | '' | '' | '' | '—' | '―'
/* Cypher reserved words. */
ALL : A L L ;
ALTER : A L T E R ;
AND : A N D ;
ANY : A N Y ;
AS : A S ;
ASC : A S C ;
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 ;
BY : B Y ;
CASE : C A S E ;
@ -78,13 +81,11 @@ CONTAINS : C O N T A I N S ;
COUNT : C O U N T ;
CREATE : C R E A T E ;
CYPHERNULL : N U L L ;
DATA : D A T A ;
DELETE : D E L E T E ;
DESC : D E S C ;
DESCENDING : D E S C E N D I N G ;
DETACH : D E T A C H ;
DISTINCT : D I S T I N C T ;
DROP : D R O P ;
ELSE : E L S E ;
END : E N D ;
ENDS : E N D S ;
@ -94,10 +95,7 @@ FILTER : F I L T E R ;
IN : I N ;
INDEX : I N D E X ;
IS : I S ;
KAFKA : K A F K A ;
K_TEST : T E S T ;
LIMIT : L I M I T ;
LOAD : L O A D ;
L_SKIP : S K I P ;
MATCH : M A T C H ;
MERGE : M E R G E ;
@ -107,25 +105,17 @@ ON : O N ;
OPTIONAL : O P T I O N A L ;
OR : O R ;
ORDER : O R D E R ;
PASSWORD : P A S S W O R D ;
REDUCE : R E D U C E ;
REMOVE : R E M O V E ;
RETURN : R E T U R N ;
SET : S E T ;
SHOW : S H O W ;
SINGLE : S I N G L E ;
START : S T A R T ;
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 ;
TOPIC : T O P I C ;
TRANSFORM : T R A N S F O R M ;
TRUE : T R U E ;
UNION : U N I O N ;
UNWIND : U N W I N D ;
USER : U S E R ;
WHEN : W H E N ;
WHERE : W H E R E ;
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 "query/exceptions.hpp"
#include "query/frontend/opencypher/generated/CypherLexer.h"
#include "query/frontend/opencypher/generated/CypherParser.h"
#include "query/frontend/opencypher/generated/MemgraphCypher.h"
#include "query/frontend/opencypher/generated/MemgraphCypherLexer.h"
namespace query {
namespace frontend {
@ -51,11 +51,11 @@ class Parser {
FirstMessageErrorListener error_listener_;
std::string query_;
antlr4::ANTLRInputStream input_{query_.c_str()};
antlropencypher::CypherLexer lexer_{&input_};
antlropencypher::MemgraphCypherLexer lexer_{&input_};
antlr4::CommonTokenStream tokens_{&lexer_};
// generate ast
antlropencypher::CypherParser parser_{&tokens_};
antlropencypher::MemgraphCypher parser_{&tokens_};
antlr4::tree::ParseTree *tree_ = nullptr;
};
} // namespace opencypher

View File

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

View File

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

View File

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

View File

@ -240,7 +240,8 @@ TYPED_TEST(CypherMainVisitorTest, EscapedLabel) {
}
TYPED_TEST(CypherMainVisitorTest, KeywordLabel) {
TypeParam ast_generator("RETURN n:DEletE");
for (const auto &label : {"DeLete", "UsER"}) {
TypeParam ast_generator(fmt::format("RETURN n:{}", label));
auto *query = ast_generator.query_;
ASSERT_TRUE(query->single_query_);
auto *single_query = query->single_query_;
@ -251,7 +252,8 @@ TYPED_TEST(CypherMainVisitorTest, KeywordLabel) {
auto identifier = dynamic_cast<Identifier *>(labels_test->expression_);
ASSERT_EQ(identifier->name_, "n");
ASSERT_THAT(labels_test->labels_,
ElementsAre(ast_generator.db_accessor_->Label("DEletE")));
ElementsAre(ast_generator.db_accessor_->Label(label)));
}
}
TYPED_TEST(CypherMainVisitorTest, HexLetterLabel) {
@ -779,21 +781,6 @@ TYPED_TEST(CypherMainVisitorTest, UndefinedFunction) {
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) {
TypeParam ast_generator("RETURN abs(n, 2)");
auto *query = ast_generator.query_;
@ -2023,40 +2010,40 @@ TYPED_TEST(CypherMainVisitorTest, CreateStream) {
check_create_stream(
"CreaTE StreaM strim AS LOad daTA KAFKA 'localhost' "
"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,
std::experimental::nullopt);
check_create_stream(
"CreaTE StreaM strim AS LOad daTA KAFKA 'localhost' "
"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",
std::experimental::nullopt, 17);
check_create_stream(
"CreaTE StreaM strim AS LOad daTA KAFKA 'localhost' "
"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);
EXPECT_THROW(check_create_stream(
"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,
std::experimental::nullopt),
SyntaxException);
EXPECT_THROW(check_create_stream(
"CREATE STREAM strim AS LOAD DATA KAFKA 'localhost' "
"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",
std::experimental::nullopt, 17),
SyntaxException);
EXPECT_THROW(check_create_stream(
"CREATE STREAM 123 AS LOAD DATA KAFKA 'localhost' "
"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,
std::experimental::nullopt),
SyntaxException);
@ -2070,14 +2057,14 @@ TYPED_TEST(CypherMainVisitorTest, CreateStream) {
EXPECT_THROW(check_create_stream(
"CREATE STREAM strim AS LOAD DATA KAFKA 'localhost' "
"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,
std::experimental::nullopt),
SyntaxException);
EXPECT_THROW(check_create_stream(
"CREATE STREAM strim AS LOAD DATA KAFKA 'localhost' "
"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,
std::experimental::nullopt),
SyntaxException);