diff --git a/CHANGELOG.md b/CHANGELOG.md index 15ac752bc..53d76d452 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,7 @@ TODO ### Bug Fixes and Other Changes -TODO +* List indexing supported with preceeding IN (for example in query `RETURN 1 IN [[1,2]][0]`) ## Build 825 diff --git a/src/query/frontend/ast/cypher_main_visitor.cpp b/src/query/frontend/ast/cypher_main_visitor.cpp index a24b85b99..002860920 100644 --- a/src/query/frontend/ast/cypher_main_visitor.cpp +++ b/src/query/frontend/ast/cypher_main_visitor.cpp @@ -604,7 +604,7 @@ antlrcpp::Any CypherMainVisitor::visitExpression3a( storage_.Create<IsNullOperator>(expression)); } else if (op->IN()) { expression = static_cast<Expression *>(storage_.Create<InListOperator>( - expression, op->expression2a()->accept(this))); + expression, op->expression3b()->accept(this))); } else { throw utils::NotYetImplemented(); } diff --git a/src/query/frontend/opencypher/grammar/Cypher.g4 b/src/query/frontend/opencypher/grammar/Cypher.g4 index 2f2f14c16..cf107039e 100644 --- a/src/query/frontend/opencypher/grammar/Cypher.g4 +++ b/src/query/frontend/opencypher/grammar/Cypher.g4 @@ -155,7 +155,7 @@ expression4 : ( ( '+' | '-' ) SP? )* expression3a ; expression3a : expression3b ( stringAndNullOperators )* ; -stringAndNullOperators : ( ( ( ( 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 ) ) ; +stringAndNullOperators : ( ( ( ( SP? '=~' ) | ( SP IN ) | ( SP STARTS SP WITH ) | ( SP ENDS SP WITH ) | ( SP CONTAINS ) ) SP? expression3b) | ( SP IS SP CYPHERNULL ) | ( SP IS SP NOT SP CYPHERNULL ) ) ; expression3b : expression2a ( SP? listIndexingOrSlicing )* ; diff --git a/tests/unit/cypher_main_visitor.cpp b/tests/unit/cypher_main_visitor.cpp index 29f51b044..443cdb387 100644 --- a/tests/unit/cypher_main_visitor.cpp +++ b/tests/unit/cypher_main_visitor.cpp @@ -432,6 +432,25 @@ TEST(CypherMainVisitorTest, InListOperator) { ASSERT_TRUE(list); } +TEST(CypherMainVisitorTest, InWithListIndexing) { + AstGenerator ast_generator("RETURN 1 IN [[1,2]][0]"); + auto *query = ast_generator.query_; + auto *return_clause = dynamic_cast<Return *>(query->clauses_[0]); + auto *in_list_operator = dynamic_cast<InListOperator *>( + return_clause->body_.named_expressions[0]->expression_); + ASSERT_TRUE(in_list_operator); + auto *literal = + dynamic_cast<PrimitiveLiteral *>(in_list_operator->expression1_); + ASSERT_TRUE(literal); + EXPECT_EQ(literal->value_.Value<int64_t>(), 1); + auto *list_indexing = dynamic_cast<ListIndexingOperator *>(in_list_operator->expression2_); + ASSERT_TRUE(list_indexing); + auto *list = dynamic_cast<ListLiteral *>(list_indexing->expression1_); + EXPECT_TRUE(list); + auto *list_index = dynamic_cast<PrimitiveLiteral *>(list_indexing->expression2_); + EXPECT_TRUE(list_index); +} + TEST(CypherMainVisitorTest, IsNull) { AstGenerator ast_generator("RETURN 2 iS NulL"); auto *query = ast_generator.query_;