Allow only one relation in EXISTS()

This commit is contained in:
Andreja Tonev 2024-03-04 15:26:58 +01:00
parent f316f7db87
commit f1edc456ab
3 changed files with 32 additions and 8 deletions

View File

@ -2058,6 +2058,18 @@ antlrcpp::Any CypherMainVisitor::visitPatternPart(MemgraphCypher::PatternPartCon
return pattern;
}
antlrcpp::Any CypherMainVisitor::visitForcePatternPart(MemgraphCypher::ForcePatternPartContext *ctx) {
auto *pattern = std::any_cast<Pattern *>(ctx->relationshipsPattern()->accept(this));
if (ctx->variable()) {
auto variable = std::any_cast<std::string>(ctx->variable()->accept(this));
pattern->identifier_ = storage_->Create<Identifier>(variable);
users_identifiers.insert(variable);
} else {
anonymous_identifiers.push_back(&pattern->identifier_);
}
return pattern;
}
antlrcpp::Any CypherMainVisitor::visitPatternElement(MemgraphCypher::PatternElementContext *ctx) {
if (ctx->patternElement()) {
return ctx->patternElement()->accept(this);
@ -2510,6 +2522,8 @@ antlrcpp::Any CypherMainVisitor::visitAtom(MemgraphCypher::AtomContext *ctx) {
auto variable = std::any_cast<std::string>(ctx->variable()->accept(this));
users_identifiers.insert(variable);
return static_cast<Expression *>(storage_->Create<Identifier>(variable));
} else if (ctx->existsExpression()) {
return std::any_cast<Expression *>(ctx->existsExpression()->accept(this));
} else if (ctx->functionInvocation()) {
return std::any_cast<Expression *>(ctx->functionInvocation()->accept(this));
} else if (ctx->COALESCE()) {
@ -2521,7 +2535,7 @@ antlrcpp::Any CypherMainVisitor::visitAtom(MemgraphCypher::AtomContext *ctx) {
} else if (ctx->COUNT()) {
// Here we handle COUNT(*). COUNT(expression) is handled in
// visitFunctionInvocation with other aggregations. This is visible in
// functionInvocation and atom producions in opencypher grammar.
// functionInvocation and atom production in opencypher grammar.
return static_cast<Expression *>(storage_->Create<Aggregation>(nullptr, nullptr, Aggregation::Op::COUNT, false));
} else if (ctx->ALL()) {
auto *ident = storage_->Create<Identifier>(
@ -2576,8 +2590,6 @@ antlrcpp::Any CypherMainVisitor::visitAtom(MemgraphCypher::AtomContext *ctx) {
auto *list = std::any_cast<Expression *>(ctx->extractExpression()->idInColl()->expression()->accept(this));
auto *expr = std::any_cast<Expression *>(ctx->extractExpression()->expression()->accept(this));
return static_cast<Expression *>(storage_->Create<Extract>(ident, list, expr));
} else if (ctx->existsExpression()) {
return std::any_cast<Expression *>(ctx->existsExpression()->accept(this));
} else if (ctx->patternComprehension()) {
return std::any_cast<Expression *>(ctx->patternComprehension()->accept(this));
}
@ -2631,10 +2643,13 @@ antlrcpp::Any CypherMainVisitor::visitLiteral(MemgraphCypher::LiteralContext *ct
antlrcpp::Any CypherMainVisitor::visitExistsExpression(MemgraphCypher::ExistsExpressionContext *ctx) {
auto *exists = storage_->Create<Exists>();
exists->pattern_ = std::any_cast<Pattern *>(ctx->patternPart()->accept(this));
if (exists->pattern_->identifier_) {
throw SyntaxException("Identifiers are not supported in exists(...).");
if (ctx->forcePatternPart()) {
exists->pattern_ = std::any_cast<Pattern *>(ctx->forcePatternPart()->accept(this));
if (exists->pattern_->identifier_) {
throw SyntaxException("Identifiers are not supported in exists(...).");
}
} else {
throw SyntaxException("EXISTS supports only a single relation as its input.");
}
return static_cast<Expression *>(exists);

View File

@ -709,6 +709,11 @@ class CypherMainVisitor : public antlropencypher::MemgraphCypherBaseVisitor {
*/
antlrcpp::Any visitPatternPart(MemgraphCypher::PatternPartContext *ctx) override;
/**
* @return Pattern*
*/
antlrcpp::Any visitForcePatternPart(MemgraphCypher::ForcePatternPartContext *ctx) override;
/**
* @return Pattern*
*/

View File

@ -286,7 +286,11 @@ reduceExpression : accumulator=variable '=' initial=expression ',' idInColl '|'
extractExpression : idInColl '|' expression ;
existsExpression : patternPart ;
existsExpression : forcePatternPart | .* ;
forcePatternPart : ( variable '=' relationshipsPattern )
| relationshipsPattern
;
idInColl : variable IN expression ;