From 20f2c885c868e87bb98acfafe7d834a55b31a87a Mon Sep 17 00:00:00 2001 From: Teon Banek Date: Thu, 20 Jul 2017 15:31:20 +0200 Subject: [PATCH] Test grammar for variable length with filters Summary: Update Cypher grammar to pickup properties after range Reviewers: mislav.bradac, florijan Reviewed By: mislav.bradac Subscribers: pullbot Differential Revision: https://phabricator.memgraph.io/D578 --- .../frontend/opencypher/grammar/Cypher.g4 | 6 ++- tests/unit/cypher_main_visitor.cpp | 51 +++++++++++++++++++ 2 files changed, 55 insertions(+), 2 deletions(-) diff --git a/src/query/frontend/opencypher/grammar/Cypher.g4 b/src/query/frontend/opencypher/grammar/Cypher.g4 index 6d7dd18e6..eda75ffa0 100644 --- a/src/query/frontend/opencypher/grammar/Cypher.g4 +++ b/src/query/frontend/opencypher/grammar/Cypher.g4 @@ -116,7 +116,9 @@ relationshipPattern : ( leftArrowHead SP? dash SP? relationshipDetail? SP? dash | ( dash SP? relationshipDetail? SP? dash ) ; -relationshipDetail : '[' SP? ( variable SP? )? ( relationshipTypes SP? )? rangeLiteral? ( properties SP? )? ']' ; +relationshipDetail : '[' SP? ( variable SP? )? ( relationshipTypes SP? )? ( rangeLiteral SP? )? properties SP? ']' + | '[' SP? ( variable SP? )? ( relationshipTypes SP? )? ( rangeLiteral SP? )? ( properties SP? )? ']' + ; properties : mapLiteral | parameter @@ -128,7 +130,7 @@ nodeLabels : nodeLabel ( SP? nodeLabel )* ; nodeLabel : ':' SP? labelName ; -rangeLiteral : '*' SP? ( expression SP? )? ( '..' SP? ( expression SP? )? )? ; +rangeLiteral : '*' SP? ( expression SP? )? ( '..' ( SP? expression )? )? ; labelName : symbolicName ; diff --git a/tests/unit/cypher_main_visitor.cpp b/tests/unit/cypher_main_visitor.cpp index 950890189..201b7f05e 100644 --- a/tests/unit/cypher_main_visitor.cpp +++ b/tests/unit/cypher_main_visitor.cpp @@ -985,6 +985,57 @@ TYPED_TEST(CypherMainVisitorTest, RelationshipPatternFloatingUpperBound) { EXPECT_EQ(upper_bound->value_.Value(), 0.2); } +TYPED_TEST(CypherMainVisitorTest, RelationshipPatternUnboundedWithProperty) { + TypeParam ast_generator("MATCH ()-[r* {prop: 42}]->() RETURN r"); + auto *query = ast_generator.query_; + auto *match = dynamic_cast(query->clauses_[0]); + EdgeAtom *edge = nullptr; + AssertMatchSingleEdgeAtom(match, edge); + EXPECT_EQ(edge->direction_, EdgeAtom::Direction::OUT); + EXPECT_TRUE(edge->has_range_); + EXPECT_EQ(edge->lower_bound_, nullptr); + EXPECT_EQ(edge->upper_bound_, nullptr); + auto prop = ast_generator.db_accessor_->property("prop"); + auto prop_literal = dynamic_cast(edge->properties_[prop]); + EXPECT_EQ(prop_literal->value_.Value(), 42); +} + +TYPED_TEST(CypherMainVisitorTest, + RelationshipPatternDotsUnboundedWithEdgeTypeProperty) { + TypeParam ast_generator("MATCH ()-[r:edge_type*..{prop: 42}]->() RETURN r"); + auto *query = ast_generator.query_; + auto *match = dynamic_cast(query->clauses_[0]); + EdgeAtom *edge = nullptr; + AssertMatchSingleEdgeAtom(match, edge); + EXPECT_EQ(edge->direction_, EdgeAtom::Direction::OUT); + EXPECT_TRUE(edge->has_range_); + EXPECT_EQ(edge->lower_bound_, nullptr); + EXPECT_EQ(edge->upper_bound_, nullptr); + auto prop = ast_generator.db_accessor_->property("prop"); + auto prop_literal = dynamic_cast(edge->properties_[prop]); + EXPECT_EQ(prop_literal->value_.Value(), 42); + ASSERT_EQ(edge->edge_types_.size(), 1U); + auto edge_type = ast_generator.db_accessor_->edge_type("edge_type"); + EXPECT_EQ(edge->edge_types_[0], edge_type); +} + +TYPED_TEST(CypherMainVisitorTest, RelationshipPatternUpperBoundedWithProperty) { + TypeParam ast_generator("MATCH ()-[r*..2{prop: 42}]->() RETURN r"); + auto *query = ast_generator.query_; + auto *match = dynamic_cast(query->clauses_[0]); + EdgeAtom *edge = nullptr; + AssertMatchSingleEdgeAtom(match, edge); + EXPECT_EQ(edge->direction_, EdgeAtom::Direction::OUT); + EXPECT_TRUE(edge->has_range_); + EXPECT_EQ(edge->lower_bound_, nullptr); + auto upper_bound = dynamic_cast(edge->upper_bound_); + ASSERT_TRUE(upper_bound); + EXPECT_EQ(upper_bound->value_.Value(), 2); + auto prop = ast_generator.db_accessor_->property("prop"); + auto prop_literal = dynamic_cast(edge->properties_[prop]); + EXPECT_EQ(prop_literal->value_.Value(), 42); +} + // // PatternPart with variable. // TYPED_TEST(CypherMainVisitorTest, PatternPartVariable) { // ParserTables parser("CREATE var=()--()");