Add test cases for AND and OR.

This commit is contained in:
Harpreet Sangar 2023-03-21 12:56:53 +05:30
parent 647942b44d
commit 1b88b9afe3
3 changed files with 64 additions and 7 deletions

View File

@ -83,6 +83,7 @@ public:
/// operation.
void next();
/// Advances the iterator until the doc value is less than id. The iterator may become invalid during this operation.
/// Advances the iterator until the doc value reaches or just overshoots id. The iterator may become invalid during
/// this operation.
void skip_to(uint32_t id);
};

View File

@ -4,10 +4,10 @@
#include "filter.h"
void filter_result_iterator_t::and_filter_iterators() {
while (left_it->valid() && right_it->valid()) {
while (left_it->is_valid && right_it->is_valid) {
while (left_it->doc < right_it->doc) {
left_it->next();
if (!left_it->valid()) {
if (!left_it->is_valid) {
is_valid = false;
return;
}
@ -15,7 +15,7 @@ void filter_result_iterator_t::and_filter_iterators() {
while (left_it->doc > right_it->doc) {
right_it->next();
if (!right_it->valid()) {
if (!right_it->is_valid) {
is_valid = false;
return;
}
@ -40,7 +40,7 @@ void filter_result_iterator_t::and_filter_iterators() {
}
void filter_result_iterator_t::or_filter_iterators() {
if (left_it->valid() && right_it->valid()) {
if (left_it->is_valid && right_it->is_valid) {
if (left_it->doc < right_it->doc) {
doc = left_it->doc;
reference.clear();
@ -76,7 +76,7 @@ void filter_result_iterator_t::or_filter_iterators() {
return;
}
if (left_it->valid()) {
if (left_it->is_valid) {
doc = left_it->doc;
reference.clear();
@ -87,7 +87,7 @@ void filter_result_iterator_t::or_filter_iterators() {
return;
}
if (right_it->valid()) {
if (right_it->is_valid) {
doc = right_it->doc;
reference.clear();
@ -133,9 +133,21 @@ void filter_result_iterator_t::next() {
}
if (filter_node->isOperator) {
// Advance the subtrees and then apply operators to arrive at the next valid doc.
if (filter_node->filter_operator == AND) {
left_it->next();
right_it->next();
and_filter_iterators();
} else {
if (left_it->doc == doc && right_it->doc == doc) {
left_it->next();
right_it->next();
} else if (left_it->doc == doc) {
left_it->next();
} else {
right_it->next();
}
or_filter_iterators();
}

View File

@ -178,5 +178,49 @@ TEST_F(FilterTest, FilterTreeIterator) {
ASSERT_FALSE(iter_skip_test.valid());
ASSERT_TRUE(iter_op.ok());
delete filter_tree_root;
filter_tree_root = nullptr;
filter_op = filter::parse_filter_query("name: jeremy && tags: fine platinum", coll->get_schema(), store, doc_id_prefix,
filter_tree_root);
ASSERT_TRUE(filter_op.ok());
auto iter_and_test = filter_result_iterator_t(coll->get_name(), coll->_get_index(), filter_tree_root, iter_op);
ASSERT_TRUE(iter_and_test.valid());
ASSERT_EQ(1, iter_and_test.doc);
iter_and_test.next();
ASSERT_FALSE(iter_and_test.valid());
ASSERT_TRUE(iter_op.ok());
delete filter_tree_root;
filter_tree_root = nullptr;
filter_op = filter::parse_filter_query("name: James || tags: bronze", coll->get_schema(), store, doc_id_prefix,
filter_tree_root);
ASSERT_TRUE(filter_op.ok());
auto doc =
R"({
"name": "James Rowdy",
"age": 36,
"years": [2005, 2022],
"rating": 6.03,
"tags": ["copper"]
})"_json;
auto add_op = coll->add(doc.dump());
ASSERT_TRUE(add_op.ok());
auto iter_or_test = filter_result_iterator_t(coll->get_name(), coll->_get_index(), filter_tree_root, iter_op);
expected = {2, 4, 5};
for (auto const& i : expected) {
ASSERT_TRUE(iter_or_test.valid());
ASSERT_EQ(i, iter_or_test.doc);
iter_or_test.next();
}
ASSERT_FALSE(iter_or_test.valid());
ASSERT_TRUE(iter_op.ok());
delete filter_tree_root;
}