Convert labels test from antlr to AST

Reviewers: florijan, teon.banek

Reviewed By: teon.banek

Subscribers: pullbot

Differential Revision: https://phabricator.memgraph.io/D346
This commit is contained in:
Mislav Bradac 2017-05-04 18:07:54 +02:00
parent 3b4e66e0e3
commit 72d4a67c4a
4 changed files with 47 additions and 14 deletions

View File

@ -600,7 +600,7 @@ antlrcpp::Any CypherMainVisitor::visitExpression3a(
antlrcpp::Any CypherMainVisitor::visitExpression3b(
CypherParser::Expression3bContext *ctx) {
Expression *expression = ctx->expression2()->accept(this);
Expression *expression = ctx->expression2a()->accept(this);
for (auto *list_op : ctx->listIndexingOrSlicing()) {
if (list_op->getTokens(kDotsTokenId).size() == 0U) {
// If there is no '..' then we need to create list indexing operator.
@ -631,13 +631,19 @@ antlrcpp::Any CypherMainVisitor::visitListIndexingOrSlicing(
return 0;
}
antlrcpp::Any CypherMainVisitor::visitExpression2(
CypherParser::Expression2Context *ctx) {
if (ctx->nodeLabels().size()) {
// TODO: Implement this. We don't currently support label checking in
// expresssion.
throw utils::NotYetImplemented();
antlrcpp::Any CypherMainVisitor::visitExpression2a(
CypherParser::Expression2aContext *ctx) {
Expression *expression = ctx->expression2b()->accept(this);
if (ctx->nodeLabels()) {
auto labels =
ctx->nodeLabels()->accept(this).as<std::vector<GraphDbTypes::Label>>();
expression = storage_.Create<LabelsTest>(expression, labels);
}
return expression;
}
antlrcpp::Any CypherMainVisitor::visitExpression2b(
CypherParser::Expression2bContext *ctx) {
Expression *expression = ctx->atom()->accept(this);
for (auto *lookup : ctx->propertyLookup()) {
auto property_lookup =

View File

@ -381,12 +381,20 @@ class CypherMainVisitor : public antlropencypher::CypherBaseVisitor {
CypherParser::ListIndexingOrSlicingContext *ctx) override;
/**
* Property lookup, test for node labels existence...
* Node labels test.
*
* @return Expression*
*/
antlrcpp::Any visitExpression2(
CypherParser::Expression2Context *ctx) override;
antlrcpp::Any visitExpression2a(
CypherParser::Expression2aContext *ctx) override;
/**
* Property lookup.
*
* @return Expression*
*/
antlrcpp::Any visitExpression2b(
CypherParser::Expression2bContext *ctx) override;
/**
* Literals, params, list comprehension...

View File

@ -153,15 +153,17 @@ expression5 : expression4 ( SP? '^' SP? expression4 )* ;
expression4 : ( ( '+' | '-' ) SP? )* expression3a ;
expression3a : expression3b ( ( ( ( SP? '=~' ) | ( SP IN ) | ( SP STARTS SP WITH ) | ( SP ENDS SP WITH ) | ( SP CONTAINS ) ) SP? expression2 ) | ( SP IS SP CYPHERNULL ) | ( SP IS SP NOT SP CYPHERNULL ) )* ;
expression3a : expression3b ( ( ( ( SP? '=~' ) | ( SP IN ) | ( SP STARTS SP WITH ) | ( SP ENDS SP WITH ) | ( SP CONTAINS ) ) SP? expression2a ) | ( SP IS SP CYPHERNULL ) | ( SP IS SP NOT SP CYPHERNULL ) )* ;
expression3b : expression2 ( SP? listIndexingOrSlicing )* ;
expression3b : expression2a ( SP? listIndexingOrSlicing )* ;
listIndexingOrSlicing : ( '[' SP? expression SP? ']' )
| ( '[' SP? lower_bound=expression? SP? '..' SP? upper_bound=expression? SP? ']' )
;
expression2 : atom ( SP? ( propertyLookup | nodeLabels ) )* ;
expression2a : expression2b ( SP? nodeLabels )? ;
expression2b : atom ( SP? propertyLookup )* ;
atom : literal
| parameter

View File

@ -19,8 +19,9 @@ namespace {
using namespace query;
using namespace query::frontend;
using query::TypedValue;
using testing::UnorderedElementsAre;
using testing::Pair;
using testing::ElementsAre;
using testing::UnorderedElementsAre;
class AstGenerator {
public:
@ -68,6 +69,22 @@ TEST(CypherMainVisitorTest, PropertyLookup) {
ast_generator.db_accessor_->property("x"));
}
TEST(CypherMainVisitorTest, LabelsTest) {
AstGenerator ast_generator("RETURN n:x:y");
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_);
ASSERT_TRUE(labels_test->expression_);
auto identifier = dynamic_cast<Identifier *>(labels_test->expression_);
ASSERT_TRUE(identifier);
ASSERT_EQ(identifier->name_, "n");
ASSERT_THAT(labels_test->labels_,
ElementsAre(ast_generator.db_accessor_->label("x"),
ast_generator.db_accessor_->label("y")));
}
TEST(CypherMainVisitorTest, ReturnNoDistinctNoBagSemantics) {
AstGenerator ast_generator("RETURN x");
auto *query = ast_generator.query_;