Merge pull request #1107 from happy-san/v0.26-facets

Refactor
This commit is contained in:
Kishore Nallan 2023-07-21 13:42:10 +05:30 committed by GitHub
commit ae504338bf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 89 additions and 86 deletions

View File

@ -201,4 +201,7 @@ public:
Option<bool> upsert_preset(const std::string & preset_name, const nlohmann::json& preset_config);
Option<bool> delete_preset(const std::string & preset_name);
static void _get_reference_collection_names(const std::string& filter_query,
std::set<std::string>& reference_collection_names);
};

View File

@ -335,7 +335,4 @@ struct StringUtils {
static Option<bool> tokenize_filter_query(const std::string& filter_query, std::queue<std::string>& tokens);
static Option<bool> split_include_fields(const std::string& include_fields, std::vector<std::string>& tokens);
static void get_reference_collection_names(const std::string& filter_query,
std::set<std::string>& reference_collection_names);
};

View File

@ -676,13 +676,61 @@ Option<bool> add_unsigned_int_list_param(const std::string& param_name, const st
return Option<bool>(true);
}
void CollectionManager::_get_reference_collection_names(const std::string& filter_query,
std::set<std::string>& reference_collection_names) {
auto size = filter_query.size();
for (uint32_t i = 0; i < size;) {
auto c = filter_query[i];
if (c == ' ' || c == '(' || c == ')') {
i++;
} else if (c == '&' || c == '|') {
i += 2;
} else {
// Reference filter would start with $ symbol.
if (c == '$') {
auto open_paren_pos = filter_query.find('(', ++i);
if (open_paren_pos == std::string::npos) {
return;
}
auto reference_collection_name = filter_query.substr(i, open_paren_pos - i);
StringUtils::trim(reference_collection_name);
if (!reference_collection_name.empty()) {
reference_collection_names.insert(reference_collection_name);
}
i = open_paren_pos;
int parenthesis_count = 1;
while (++i < size && parenthesis_count > 0) {
if (filter_query[i] == '(') {
parenthesis_count++;
} else if (filter_query[i] == ')') {
parenthesis_count--;
}
}
} else {
while (filter_query[++i] != ':');
bool in_backtick = false;
do {
c = filter_query[++i];
if (c == '`') {
in_backtick = !in_backtick;
}
} while (i < size && (in_backtick || (c != '(' && c != ')' &&
!(c == '&' && filter_query[i + 1] == '&') &&
!(c == '|' && filter_query[i + 1] == '|'))));
}
}
}
}
void initialize_include_fields_vec(const std::string& filter_query, std::vector<std::string>& include_fields_vec) {
if (filter_query.empty()) {
return;
}
std::set<std::string> reference_collection_names;
StringUtils::get_reference_collection_names(filter_query, reference_collection_names);
CollectionManager::_get_reference_collection_names(filter_query, reference_collection_names);
if (reference_collection_names.empty()) {
return;
}

View File

@ -737,16 +737,16 @@ Option<bool> filter::parse_filter_query(const std::string& filter_query,
return tokenize_op;
}
if (tokens.size() > 100) {
return Option<bool>(400, "Filter expression is not valid.");
}
std::queue<std::string> postfix;
Option<bool> toPostfix_op = toPostfix(tokens, postfix);
if (!toPostfix_op.ok()) {
return toPostfix_op;
}
if (postfix.size() > 100) {
return Option<bool>(400, "`filter_by` has too many operations.");
}
Option<bool> toParseTree_op = toParseTree(postfix,
root,
search_schema,

View File

@ -1026,6 +1026,9 @@ void filter_result_iterator_t::init() {
std::vector<std::string> str_tokens;
while (tokenizer.next(str_token, token_index)) {
if (str_token.size() > 100) {
str_token.erase(100);
}
str_tokens.push_back(str_token);
art_leaf* leaf = (art_leaf *) art_search(t, (const unsigned char*) str_token.c_str(),

View File

@ -582,54 +582,6 @@ size_t StringUtils::split_facet(const std::string &s, std::vector<std::string> &
return std::min(end_index, s.size());
}
void StringUtils::get_reference_collection_names(const std::string& filter_query,
std::set<std::string>& reference_collection_names) {
auto size = filter_query.size();
for (uint32_t i = 0; i < size;) {
auto c = filter_query[i];
if (c == ' ' || c == '(' || c == ')') {
i++;
} else if (c == '&' || c == '|') {
i += 2;
} else {
// Reference filter would start with $ symbol.
if (c == '$') {
auto open_paren_pos = filter_query.find('(', ++i);
if (open_paren_pos == std::string::npos) {
return;
}
auto reference_collection_name = filter_query.substr(i, open_paren_pos - i);
StringUtils::trim(reference_collection_name);
if (!reference_collection_name.empty()) {
reference_collection_names.insert(reference_collection_name);
}
i = open_paren_pos;
int parenthesis_count = 1;
while (++i < size && parenthesis_count > 0) {
if (filter_query[i] == '(') {
parenthesis_count++;
} else if (filter_query[i] == ')') {
parenthesis_count--;
}
}
} else {
while (filter_query[++i] != ':');
bool in_backtick = false;
do {
c = filter_query[++i];
if (c == '`') {
in_backtick = !in_backtick;
}
} while (i < size && (in_backtick || (c != '(' && c != ')' &&
!(c == '&' && filter_query[i + 1] == '&') &&
!(c == '|' && filter_query[i + 1] == '|'))));
}
}
}
}
/*size_t StringUtils::unicode_length(const std::string& bytes) {
std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> utf8conv;
return utf8conv.from_bytes(bytes).size();

View File

@ -1245,3 +1245,33 @@ TEST_F(CollectionManagerTest, CloneCollection) {
ASSERT_EQ('-', coll2->get_token_separators().at(0));
ASSERT_EQ('?', coll2->get_token_separators().at(1));
}
TEST(StringUtilsTest, GetReferenceCollectionNames) {
std::string filter_query = "";
std::set<std::string> reference_collection_names;
CollectionManager::_get_reference_collection_names(filter_query, reference_collection_names);
ASSERT_TRUE(reference_collection_names.empty());
filter_query = "foo:bar";
CollectionManager::_get_reference_collection_names(filter_query, reference_collection_names);
ASSERT_TRUE(reference_collection_names.empty());
filter_query = "$foo(bar:baz)";
std::vector<std::string> result = {"foo"};
CollectionManager::_get_reference_collection_names(filter_query, reference_collection_names);
ASSERT_EQ(1, reference_collection_names.size());
for (const auto &item: result) {
ASSERT_EQ(1, reference_collection_names.count(item));
}
reference_collection_names.clear();
filter_query = "((age: <5 || age: >10) && category:= [shoes]) &&"
" $Customers(customer_id:=customer_a && (product_price:>100 && product_price:<200))";
result = {"Customers"};
CollectionManager::_get_reference_collection_names(filter_query, reference_collection_names);
ASSERT_EQ(1, reference_collection_names.size());
for (const auto &item: result) {
ASSERT_EQ(1, reference_collection_names.count(item));
}
reference_collection_names.clear();
}

View File

@ -420,33 +420,3 @@ TEST(StringUtilsTest, SplitIncludeFields) {
tokens = {"id", "$Collection(title, pref*)", "count"};
splitIncludeTestHelper(include_fields, tokens);
}
TEST(StringUtilsTest, GetReferenceCollectionNames) {
std::string filter_query = "";
std::set<std::string> reference_collection_names;
StringUtils::get_reference_collection_names(filter_query, reference_collection_names);
ASSERT_TRUE(reference_collection_names.empty());
filter_query = "foo:bar";
StringUtils::get_reference_collection_names(filter_query, reference_collection_names);
ASSERT_TRUE(reference_collection_names.empty());
filter_query = "$foo(bar:baz)";
std::vector<std::string> result = {"foo"};
StringUtils::get_reference_collection_names(filter_query, reference_collection_names);
ASSERT_EQ(1, reference_collection_names.size());
for (const auto &item: result) {
ASSERT_EQ(1, reference_collection_names.count(item));
}
reference_collection_names.clear();
filter_query = "((age: <5 || age: >10) && category:= [shoes]) &&"
" $Customers(customer_id:=customer_a && (product_price:>100 && product_price:<200))";
result = {"Customers"};
StringUtils::get_reference_collection_names(filter_query, reference_collection_names);
ASSERT_EQ(1, reference_collection_names.size());
for (const auto &item: result) {
ASSERT_EQ(1, reference_collection_names.count(item));
}
reference_collection_names.clear();
}