This is an automated email from the ASF dual-hosted git repository.
yangsiyu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/master by this push:
new e901d759989 [fix](inverted index) Handle minimum_should_match when no
should clauses exist (#60150)
e901d759989 is described below
commit e901d759989a961527061158bf85d3decef4ac07
Author: zzzxl <[email protected]>
AuthorDate: Tue Jan 27 11:03:12 2026 +0800
[fix](inverted index) Handle minimum_should_match when no should clauses
exist (#60150)
---
.../boolean_query/occur_boolean_weight.cpp | 8 +--
.../query_v2/occur_boolean_query_test.cpp | 80 ++++++++++++++++++++++
2 files changed, 83 insertions(+), 5 deletions(-)
diff --git
a/be/src/olap/rowset/segment_v2/inverted_index/query_v2/boolean_query/occur_boolean_weight.cpp
b/be/src/olap/rowset/segment_v2/inverted_index/query_v2/boolean_query/occur_boolean_weight.cpp
index 844d578338c..20ce9f15172 100644
---
a/be/src/olap/rowset/segment_v2/inverted_index/query_v2/boolean_query/occur_boolean_weight.cpp
+++
b/be/src/olap/rowset/segment_v2/inverted_index/query_v2/boolean_query/occur_boolean_weight.cpp
@@ -96,10 +96,6 @@ template <typename CombinerT>
std::optional<CombinationMethod>
OccurBooleanWeight<ScoreCombinerPtrT>::build_should_opt(
std::vector<ScorerPtr>& must_scorers, std::vector<ScorerPtr>
should_scorers,
CombinerT combiner, size_t num_all_scorers) {
- if (should_scorers.empty()) {
- return Ignored {};
- }
-
size_t adjusted_minimum = _minimum_number_should_match > num_all_scorers
? _minimum_number_should_match -
num_all_scorers
: 0;
@@ -109,7 +105,9 @@ std::optional<CombinationMethod>
OccurBooleanWeight<ScoreCombinerPtrT>::build_sh
return std::nullopt;
}
- if (adjusted_minimum == 0) {
+ if (adjusted_minimum == 0 && num_of_should_scorers == 0) {
+ return Ignored {};
+ } else if (adjusted_minimum == 0) {
return Optional {scorer_union(std::move(should_scorers), combiner)};
} else if (adjusted_minimum == 1) {
return Required {scorer_union(std::move(should_scorers), combiner)};
diff --git
a/be/test/olap/rowset/segment_v2/inverted_index/query_v2/occur_boolean_query_test.cpp
b/be/test/olap/rowset/segment_v2/inverted_index/query_v2/occur_boolean_query_test.cpp
index bcffa0d7082..9ed08a1385c 100644
---
a/be/test/olap/rowset/segment_v2/inverted_index/query_v2/occur_boolean_query_test.cpp
+++
b/be/test/olap/rowset/segment_v2/inverted_index/query_v2/occur_boolean_query_test.cpp
@@ -704,4 +704,84 @@ TEST_F(OccurBooleanQueryTest, OnlyMustNotClausesEmpty) {
EXPECT_EQ(scorer->doc(), TERMINATED);
}
+TEST_F(OccurBooleanQueryTest,
MinimumShouldMatchExceedsShouldClausesReturnsEmpty) {
+ {
+ auto must_docs1 = generate_range_docs(0, 100);
+ auto must_docs2 = generate_range_docs(50, 150);
+ std::vector<std::pair<Occur, QueryPtr>> clauses;
+ clauses.emplace_back(Occur::MUST,
std::make_shared<MockQuery>(must_docs1));
+ clauses.emplace_back(Occur::MUST,
std::make_shared<MockQuery>(must_docs2));
+
+ OccurBooleanQuery query(std::move(clauses), 2);
+ auto weight = query.weight(false);
+ auto scorer = weight->scorer(_ctx);
+
+ EXPECT_EQ(scorer->doc(), TERMINATED);
+ }
+
+ {
+ auto must_docs = generate_range_docs(0, 100);
+ auto should_docs = generate_range_docs(0, 100);
+ std::vector<std::pair<Occur, QueryPtr>> clauses;
+ clauses.emplace_back(Occur::MUST,
std::make_shared<MockQuery>(must_docs));
+ clauses.emplace_back(Occur::SHOULD,
std::make_shared<MockQuery>(should_docs));
+
+ OccurBooleanQuery query(std::move(clauses), 2);
+ auto weight = query.weight(false);
+ auto scorer = weight->scorer(_ctx);
+
+ EXPECT_EQ(scorer->doc(), TERMINATED);
+ }
+
+ {
+ auto should_docs1 = generate_range_docs(0, 100);
+ auto should_docs2 = generate_range_docs(50, 150);
+ auto expected = set_intersection(should_docs1, should_docs2);
+
+ std::vector<std::pair<Occur, QueryPtr>> clauses;
+ clauses.emplace_back(Occur::SHOULD,
std::make_shared<MockQuery>(should_docs1));
+ clauses.emplace_back(Occur::SHOULD,
std::make_shared<MockQuery>(should_docs2));
+
+ OccurBooleanQuery query(std::move(clauses), 2);
+ auto weight = query.weight(false);
+ auto scorer = weight->scorer(_ctx);
+ auto result = collect_docs(scorer);
+
+ EXPECT_EQ(result.size(), expected.size());
+ EXPECT_EQ(to_set(result), to_set(expected));
+ }
+
+ {
+ auto must_docs = generate_range_docs(0, 100);
+ auto must_not_docs = generate_range_docs(50, 150);
+
+ std::vector<std::pair<Occur, QueryPtr>> clauses;
+ clauses.emplace_back(Occur::MUST,
std::make_shared<MockQuery>(must_docs));
+ clauses.emplace_back(Occur::MUST_NOT,
std::make_shared<MockQuery>(must_not_docs));
+
+ OccurBooleanQuery query(std::move(clauses), 2);
+ auto weight = query.weight(false);
+ auto scorer = weight->scorer(_ctx);
+
+ EXPECT_EQ(scorer->doc(), TERMINATED);
+ }
+}
+
+TEST_F(OccurBooleanQueryTest,
MinimumShouldMatchZeroWithNoShouldClausesReturnsIgnored) {
+ auto must_docs1 = generate_range_docs(0, 100);
+ auto must_docs2 = generate_range_docs(50, 150);
+ auto expected = set_intersection(must_docs1, must_docs2);
+
+ std::vector<std::pair<Occur, QueryPtr>> clauses;
+ clauses.emplace_back(Occur::MUST, std::make_shared<MockQuery>(must_docs1));
+ clauses.emplace_back(Occur::MUST, std::make_shared<MockQuery>(must_docs2));
+
+ OccurBooleanQuery query(std::move(clauses), 0);
+ auto weight = query.weight(false);
+ auto scorer = weight->scorer(_ctx);
+ auto result = collect_docs(scorer);
+
+ EXPECT_EQ(result, expected);
+}
+
} // namespace doris::segment_v2::inverted_index::query_v2
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]