diff --git a/include/field.h b/include/field.h index 2f558129..090e1ebc 100644 --- a/include/field.h +++ b/include/field.h @@ -500,6 +500,7 @@ struct sort_by { exclude_radius = other.exclude_radius; geo_precision = other.geo_precision; missing_values = other.missing_values; + eval = other.eval; return *this; } }; diff --git a/include/index.h b/include/index.h index e91e7efb..61aaabe7 100644 --- a/include/index.h +++ b/include/index.h @@ -93,7 +93,7 @@ struct search_args { std::vector& facets; std::vector>& included_ids; std::vector excluded_ids; - std::vector sort_fields_std; + std::vector& sort_fields_std; facet_query_t facet_query; std::vector num_typos; size_t max_facet_values; @@ -133,7 +133,7 @@ struct search_args { search_args(std::vector field_query_tokens, std::vector search_fields, std::vector filters, std::vector& facets, std::vector>& included_ids, std::vector excluded_ids, - std::vector sort_fields_std, facet_query_t facet_query, const std::vector& num_typos, + std::vector& sort_fields_std, facet_query_t facet_query, const std::vector& num_typos, size_t max_facet_values, size_t max_hits, size_t per_page, size_t page, token_ordering token_order, const std::vector& prefixes, size_t drop_tokens_threshold, size_t typo_tokens_threshold, const std::vector& group_by_fields, size_t group_limit, diff --git a/src/collection.cpp b/src/collection.cpp index b8c04310..337f47de 100644 --- a/src/collection.cpp +++ b/src/collection.cpp @@ -38,6 +38,20 @@ struct match_index_t { } }; +struct sort_fields_guard_t { + std::vector sort_fields_std; + + ~sort_fields_guard_t() { + for(auto& sort_by_clause: sort_fields_std) { + if(sort_by_clause.eval.ids) { + delete [] sort_by_clause.eval.ids; + sort_by_clause.eval.ids = nullptr; + sort_by_clause.eval.size = 0; + } + } + } +}; + Collection::Collection(const std::string& name, const uint32_t collection_id, const uint64_t created_at, const uint32_t next_seq_id, Store *store, const std::vector &fields, const std::string& default_sorting_field, @@ -1039,7 +1053,8 @@ Option Collection::search(const std::string & raw_query, // validate sort fields and standardize - std::vector sort_fields_std; + sort_fields_guard_t sort_fields_guard; + std::vector& sort_fields_std = sort_fields_guard.sort_fields_std; if(curated_sort_by.empty()) { auto sort_validation_op = validate_and_standardize_sort_fields(sort_fields, sort_fields_std); diff --git a/test/collection_sorting_test.cpp b/test/collection_sorting_test.cpp index 4a7202ef..80755c93 100644 --- a/test/collection_sorting_test.cpp +++ b/test/collection_sorting_test.cpp @@ -1835,7 +1835,7 @@ TEST_F(CollectionSortingTest, OptionalFilteringViaSortingWildcard) { ASSERT_TRUE(coll1->add(doc.dump()).ok()); } - auto sort_fields = { + std::vector sort_fields = { sort_by("_eval(brand:nike)", "DESC"), sort_by("points", "DESC"), }; @@ -1844,7 +1844,7 @@ TEST_F(CollectionSortingTest, OptionalFilteringViaSortingWildcard) { ASSERT_EQ(5, results["hits"].size()); std::vector expected_ids = {"3", "0", "4", "2", "1"}; - for(size_t i = 0; i > expected_ids.size(); i++) { + for(size_t i = 0; i < expected_ids.size(); i++) { ASSERT_EQ(expected_ids[i], results["hits"][i]["document"]["id"].get()); } @@ -1858,7 +1858,7 @@ TEST_F(CollectionSortingTest, OptionalFilteringViaSortingWildcard) { ASSERT_EQ(5, results["hits"].size()); expected_ids = {"0", "4", "3", "2", "1"}; - for(size_t i = 0; i > expected_ids.size(); i++) { + for(size_t i = 0; i < expected_ids.size(); i++) { ASSERT_EQ(expected_ids[i], results["hits"][i]["document"]["id"].get()); } @@ -1872,7 +1872,7 @@ TEST_F(CollectionSortingTest, OptionalFilteringViaSortingWildcard) { ASSERT_EQ(5, results["hits"].size()); expected_ids = {"4", "3", "2", "1", "0"}; - for(size_t i = 0; i > expected_ids.size(); i++) { + for(size_t i = 0; i < expected_ids.size(); i++) { ASSERT_EQ(expected_ids[i], results["hits"][i]["document"]["id"].get()); } @@ -1933,7 +1933,7 @@ TEST_F(CollectionSortingTest, OptionalFilteringViaSortingSearch) { ASSERT_TRUE(coll1->add(doc.dump()).ok()); } - auto sort_fields = { + std::vector sort_fields = { sort_by("_eval(brand:nike)", "DESC"), sort_by("points", "DESC"), }; @@ -1942,7 +1942,7 @@ TEST_F(CollectionSortingTest, OptionalFilteringViaSortingSearch) { ASSERT_EQ(5, results["hits"].size()); std::vector expected_ids = {"3", "0", "4", "2", "1"}; - for(size_t i = 0; i > expected_ids.size(); i++) { + for(size_t i = 0; i < expected_ids.size(); i++) { ASSERT_EQ(expected_ids[i], results["hits"][i]["document"]["id"].get()); } @@ -1956,7 +1956,7 @@ TEST_F(CollectionSortingTest, OptionalFilteringViaSortingSearch) { ASSERT_EQ(5, results["hits"].size()); expected_ids = {"0", "4", "3", "2", "1"}; - for(size_t i = 0; i > expected_ids.size(); i++) { + for(size_t i = 0; i < expected_ids.size(); i++) { ASSERT_EQ(expected_ids[i], results["hits"][i]["document"]["id"].get()); } @@ -1970,7 +1970,7 @@ TEST_F(CollectionSortingTest, OptionalFilteringViaSortingSearch) { ASSERT_EQ(5, results["hits"].size()); expected_ids = {"4", "3", "2", "1", "0"}; - for(size_t i = 0; i > expected_ids.size(); i++) { + for(size_t i = 0; i < expected_ids.size(); i++) { ASSERT_EQ(expected_ids[i], results["hits"][i]["document"]["id"].get()); } @@ -2022,7 +2022,7 @@ TEST_F(CollectionSortingTest, OptionalFilteringViaSortingSecondThirdParams) { ASSERT_TRUE(coll1->add(doc.dump()).ok()); } - auto sort_fields = { + std::vector sort_fields = { sort_by("val", "DESC"), sort_by("_eval(brand:nike)", "DESC"), sort_by("points", "DESC"), @@ -2032,7 +2032,7 @@ TEST_F(CollectionSortingTest, OptionalFilteringViaSortingSecondThirdParams) { ASSERT_EQ(5, results["hits"].size()); std::vector expected_ids = {"3", "0", "4", "2", "1"}; - for(size_t i = 0; i > expected_ids.size(); i++) { + for(size_t i = 0; i < expected_ids.size(); i++) { ASSERT_EQ(expected_ids[i], results["hits"][i]["document"]["id"].get()); } @@ -2045,7 +2045,7 @@ TEST_F(CollectionSortingTest, OptionalFilteringViaSortingSecondThirdParams) { results = coll1->search("title", {"title"}, "", {}, sort_fields, {2}, 10, 1, FREQUENCY, {true}, 10).get(); ASSERT_EQ(5, results["hits"].size()); - for(size_t i = 0; i > expected_ids.size(); i++) { + for(size_t i = 0; i < expected_ids.size(); i++) { ASSERT_EQ(expected_ids[i], results["hits"][i]["document"]["id"].get()); } }