diff --git a/src/query/frontend/ast/cypher_main_visitor.cpp b/src/query/frontend/ast/cypher_main_visitor.cpp index b2f261ca2..a6961ecbb 100644 --- a/src/query/frontend/ast/cypher_main_visitor.cpp +++ b/src/query/frontend/ast/cypher_main_visitor.cpp @@ -332,7 +332,14 @@ antlrcpp::Any CypherMainVisitor::visitSymbolicName( } return name; } - return std::string(ctx->getText()); + if (ctx->UnescapedSymbolicName() || ctx->HexLetter()) { + return std::string(ctx->getText()); + } + // Symbolic names are case sensitive. Since StrippedQuery lowercases all + // keywords there is no way to differentiate between differently cased + // symbolic names if they are equal to a keyword. + throw SemanticException( + fmt::format("Symbolic name can't be keyword {}", ctx->getText())); } antlrcpp::Any CypherMainVisitor::visitPattern( diff --git a/tests/unit/cypher_main_visitor.cpp b/tests/unit/cypher_main_visitor.cpp index 36506c91e..57ddb9b04 100644 --- a/tests/unit/cypher_main_visitor.cpp +++ b/tests/unit/cypher_main_visitor.cpp @@ -143,6 +143,23 @@ TYPED_TEST(CypherMainVisitorTest, EscapedLabel) { ElementsAre(ast_generator.db_accessor_->label("l-$\"'ab`e``l"))); } +TYPED_TEST(CypherMainVisitorTest, KeywordLabel) { + ASSERT_THROW(TypeParam("RETURN n:DEletE"), SemanticException); +} + +TYPED_TEST(CypherMainVisitorTest, HexLetterLabel) { + TypeParam ast_generator("RETURN n:a"); + auto *query = ast_generator.query_; + ASSERT_EQ(query->clauses_.size(), 1U); + auto *return_clause = dynamic_cast<Return *>(query->clauses_[0]); + auto *labels_test = dynamic_cast<LabelsTest *>( + return_clause->body_.named_expressions[0]->expression_); + auto identifier = dynamic_cast<Identifier *>(labels_test->expression_); + EXPECT_EQ(identifier->name_, "n"); + ASSERT_THAT(labels_test->labels_, + ElementsAre(ast_generator.db_accessor_->label("a"))); +} + TYPED_TEST(CypherMainVisitorTest, ReturnNoDistinctNoBagSemantics) { TypeParam ast_generator("RETURN x"); auto *query = ast_generator.query_;