From 3fd3c40b74de736da903b7cfa9e5282ecaf02a75 Mon Sep 17 00:00:00 2001 From: Stepan Bagritsevich <43710058+BagritsevichStepan@users.noreply.github.com> Date: Sat, 24 Aug 2024 10:58:16 +0200 Subject: [PATCH] fix(search_family): Fix query parsing for the integer tags in OR expression (#3544) fixes dragonflydb#3490 Signed-off-by: Stepan Bagritsevich --- src/core/search/parser.y | 12 ++++++++---- src/core/search/search_parser_test.cc | 4 ++++ src/server/search/search_family_test.cc | 16 ++++++++++++++++ 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/src/core/search/parser.y b/src/core/search/parser.y index 7a3cce413..38d327f9a 100644 --- a/src/core/search/parser.y +++ b/src/core/search/parser.y @@ -80,6 +80,7 @@ using namespace std; %nterm opt_lparen %nterm final_query filter search_expr search_unary_expr search_or_expr search_and_expr numeric_filter_expr %nterm field_cond field_cond_expr field_unary_expr field_or_expr field_and_expr tag_list +%nterm tag_list_element %nterm knn_query %nterm opt_knn_alias @@ -170,10 +171,13 @@ field_unary_expr: | UINT32 { $$ = AstTermNode(to_string($1)); } tag_list: - TERM { $$ = AstTagsNode(std::move($1)); } - | UINT32 { $$ = AstTagsNode(to_string($1)); } - | tag_list OR_OP TERM { $$ = AstTagsNode(std::move($1), std::move($3)); } - | tag_list OR_OP DOUBLE { $$ = AstTagsNode(std::move($1), to_string($3)); } + tag_list_element { $$ = AstTagsNode(std::move($1)); } + | tag_list OR_OP tag_list_element { $$ = AstTagsNode(std::move($1), std::move($3)); } + +tag_list_element: + TERM { $$ = std::move($1); } + | UINT32 { $$ = to_string($1); } + | DOUBLE { $$ = to_string($1); } %% diff --git a/src/core/search/search_parser_test.cc b/src/core/search/search_parser_test.cc index 032aecc85..2345a49bb 100644 --- a/src/core/search/search_parser_test.cc +++ b/src/core/search/search_parser_test.cc @@ -110,6 +110,10 @@ TEST_F(SearchParserTest, Parse) { EXPECT_EQ(0, Parse(" -(foo) @foo:bar @ss:[1 2]")); EXPECT_EQ(0, Parse("@foo:{ tag1 | tag2 }")); + EXPECT_EQ(0, Parse("@foo:{1|2}")); + EXPECT_EQ(0, Parse("@foo:{1|2.0|4|3.0}")); + EXPECT_EQ(0, Parse("@foo:{1|hello|3.0|world|4}")); + EXPECT_EQ(1, Parse(" -(foo ")); EXPECT_EQ(1, Parse(" foo:bar ")); EXPECT_EQ(1, Parse(" @foo:@bar ")); diff --git a/src/server/search/search_family_test.cc b/src/server/search/search_family_test.cc index 62d26319d..388eacb2d 100644 --- a/src/server/search/search_family_test.cc +++ b/src/server/search/search_family_test.cc @@ -395,6 +395,22 @@ TEST_F(SearchFamilyTest, TagOptions) { EXPECT_THAT(Run({"ft.search", "i1", "@color:{blue}"}), AreDocIds("d:2", "d:4")); } +TEST_F(SearchFamilyTest, TagNumbers) { + Run({"hset", "d:1", "number", "1"}); + Run({"hset", "d:2", "number", "2"}); + Run({"hset", "d:3", "number", "3"}); + + EXPECT_EQ(Run({"ft.create", "i1", "on", "hash", "schema", "number", "tag"}), "OK"); + + EXPECT_THAT(Run({"ft.search", "i1", "@number:{1}"}), AreDocIds("d:1")); + EXPECT_THAT(Run({"ft.search", "i1", "@number:{1|2}"}), AreDocIds("d:1", "d:2")); + EXPECT_THAT(Run({"ft.search", "i1", "@number:{1|2|3}"}), AreDocIds("d:1", "d:2", "d:3")); + + EXPECT_THAT(Run({"ft.search", "i1", "@number:{1.0|2|3.0}"}), AreDocIds("d:2")); + EXPECT_THAT(Run({"ft.search", "i1", "@number:{1|2|3.0}"}), AreDocIds("d:1", "d:2")); + EXPECT_THAT(Run({"ft.search", "i1", "@number:{1|hello|2}"}), AreDocIds("d:1", "d:2")); +} + TEST_F(SearchFamilyTest, Numbers) { for (unsigned i = 0; i <= 10; i++) { for (unsigned j = 0; j <= 10; j++) {