diff options
Diffstat (limited to 'searchlib/src/tests/query/streaming_query_test.cpp')
-rw-r--r-- | searchlib/src/tests/query/streaming_query_test.cpp | 205 |
1 files changed, 148 insertions, 57 deletions
diff --git a/searchlib/src/tests/query/streaming_query_test.cpp b/searchlib/src/tests/query/streaming_query_test.cpp index 306456518b7..7c4b7555158 100644 --- a/searchlib/src/tests/query/streaming_query_test.cpp +++ b/searchlib/src/tests/query/streaming_query_test.cpp @@ -6,6 +6,7 @@ #include <vespa/searchlib/query/streaming/in_term.h> #include <vespa/searchlib/query/streaming/query.h> #include <vespa/searchlib/query/streaming/nearest_neighbor_query_node.h> +#include <vespa/searchlib/query/streaming/wand_term.h> #include <vespa/searchlib/query/tree/querybuilder.h> #include <vespa/searchlib/query/tree/simplequery.h> #include <vespa/searchlib/query/tree/stackdumpcreator.h> @@ -27,6 +28,7 @@ void assertHit(const Hit & h, size_t expWordpos, size_t expContext, int32_t weig EXPECT_EQ(h.weight(), weight); } + TEST(StreamingQueryTest, test_query_language) { QueryNodeResultFactory factory; @@ -38,7 +40,7 @@ TEST(StreamingQueryTest, test_query_language) EXPECT_TRUE(q.getAsIntegerTerm(ia, ib)); EXPECT_EQ(ia, 7); EXPECT_EQ(ib, 7); - EXPECT_TRUE(q.getAsDoubleTerm(da, db)); + EXPECT_TRUE(q.getAsFloatTerm(da, db)); EXPECT_EQ(da, 7); EXPECT_EQ(db, 7); } @@ -48,15 +50,24 @@ TEST(StreamingQueryTest, test_query_language) EXPECT_TRUE(q.getAsIntegerTerm(ia, ib)); EXPECT_EQ(ia, -7); EXPECT_EQ(ib, -7); - EXPECT_TRUE(q.getAsDoubleTerm(da, db)); + EXPECT_TRUE(q.getAsFloatTerm(da, db)); EXPECT_EQ(da, -7); EXPECT_EQ(db, -7); } + { + QueryTerm q(factory.create(), "+7", "index", TermType::WORD); + EXPECT_TRUE(q.getAsIntegerTerm(ia, ib)); + EXPECT_EQ(ia, 7); + EXPECT_EQ(ib, 7); + EXPECT_TRUE(q.getAsFloatTerm(da, db)); + EXPECT_EQ(da, 7); + EXPECT_EQ(db, 7); + } { QueryTerm q(factory.create(), "7.5", "index", TermType::WORD); EXPECT_TRUE(!q.getAsIntegerTerm(ia, ib)); - EXPECT_TRUE(q.getAsDoubleTerm(da, db)); + EXPECT_TRUE(q.getAsFloatTerm(da, db)); EXPECT_EQ(da, 7.5); EXPECT_EQ(db, 7.5); } @@ -64,7 +75,7 @@ TEST(StreamingQueryTest, test_query_language) { QueryTerm q(factory.create(), "-7.5", "index", TermType::WORD); EXPECT_TRUE(!q.getAsIntegerTerm(ia, ib)); - EXPECT_TRUE(q.getAsDoubleTerm(da, db)); + EXPECT_TRUE(q.getAsFloatTerm(da, db)); EXPECT_EQ(da, -7.5); EXPECT_EQ(db, -7.5); } @@ -74,8 +85,8 @@ TEST(StreamingQueryTest, test_query_language) EXPECT_TRUE(q.getAsIntegerTerm(ia, ib)); EXPECT_EQ(ia, std::numeric_limits<int64_t>::min()); EXPECT_EQ(ib, 6); - EXPECT_TRUE(q.getAsDoubleTerm(da, db)); - EXPECT_EQ(da, -std::numeric_limits<double>::max()); + EXPECT_TRUE(q.getAsFloatTerm(da, db)); + EXPECT_EQ(da, -std::numeric_limits<double>::infinity()); EXPECT_LT(db, 7); EXPECT_GT(db, 6.99); } @@ -85,8 +96,8 @@ TEST(StreamingQueryTest, test_query_language) EXPECT_TRUE(q.getAsIntegerTerm(ia, ib)); EXPECT_EQ(ia, std::numeric_limits<int64_t>::min()); EXPECT_EQ(ib, 7); - EXPECT_TRUE(q.getAsDoubleTerm(da, db)); - EXPECT_EQ(da, -std::numeric_limits<double>::max()); + EXPECT_TRUE(q.getAsFloatTerm(da, db)); + EXPECT_EQ(da, -std::numeric_limits<double>::infinity()); EXPECT_EQ(db, 7); } @@ -95,10 +106,10 @@ TEST(StreamingQueryTest, test_query_language) EXPECT_TRUE(q.getAsIntegerTerm(ia, ib)); EXPECT_EQ(ia, 8); EXPECT_EQ(ib, std::numeric_limits<int64_t>::max()); - EXPECT_TRUE(q.getAsDoubleTerm(da, db)); + EXPECT_TRUE(q.getAsFloatTerm(da, db)); EXPECT_GT(da, 7); EXPECT_LT(da, 7.01); - EXPECT_EQ(db, std::numeric_limits<double>::max()); + EXPECT_EQ(db, std::numeric_limits<double>::infinity()); } { @@ -106,9 +117,9 @@ TEST(StreamingQueryTest, test_query_language) EXPECT_TRUE(q.getAsIntegerTerm(ia, ib)); EXPECT_EQ(ia, 7); EXPECT_EQ(ib, std::numeric_limits<int64_t>::max()); - EXPECT_TRUE(q.getAsDoubleTerm(da, db)); + EXPECT_TRUE(q.getAsFloatTerm(da, db)); EXPECT_EQ(da, 7); - EXPECT_EQ(db, std::numeric_limits<double>::max()); + EXPECT_EQ(db, std::numeric_limits<double>::infinity()); } { @@ -116,7 +127,7 @@ TEST(StreamingQueryTest, test_query_language) EXPECT_TRUE(q.getAsIntegerTerm(ia, ib)); EXPECT_EQ(ia, -7); EXPECT_EQ(ib, 7); - EXPECT_TRUE(q.getAsDoubleTerm(da, db)); + EXPECT_TRUE(q.getAsFloatTerm(da, db)); EXPECT_EQ(da, -7); EXPECT_EQ(db, 7); } @@ -126,7 +137,7 @@ TEST(StreamingQueryTest, test_query_language) EXPECT_FALSE(q.getAsIntegerTerm(ia, ib)); // This is dubious and perhaps a regression. EXPECT_EQ(ia, std::numeric_limits<int64_t>::min()); EXPECT_EQ(ib, std::numeric_limits<int64_t>::max()); - EXPECT_TRUE(q.getAsDoubleTerm(da, db)); + EXPECT_TRUE(q.getAsFloatTerm(da, db)); EXPECT_EQ(da, -7.1); EXPECT_EQ(db, 7.1); } @@ -136,7 +147,7 @@ TEST(StreamingQueryTest, test_query_language) EXPECT_FALSE(q.getAsIntegerTerm(ia, ib)); // This is dubious and perhaps a regression. EXPECT_EQ(ia, std::numeric_limits<int64_t>::min()); EXPECT_EQ(ib, std::numeric_limits<int64_t>::max()); - EXPECT_TRUE(q.getAsDoubleTerm(da, db)); + EXPECT_TRUE(q.getAsFloatTerm(da, db)); EXPECT_EQ(da, 500.0); EXPECT_EQ(db, std::numeric_limits<double>::max()); } @@ -147,8 +158,8 @@ TEST(StreamingQueryTest, test_query_language) EXPECT_TRUE(q.getAsIntegerTerm(ia, ib)); EXPECT_EQ(ia, -6); EXPECT_EQ(ib, 7); - EXPECT_TRUE(q.getAsDoubleTerm(da, db)); - EXPECT_EQ(da, std::nextafterf(minusSeven, seven)); + EXPECT_TRUE(q.getAsFloatTerm(da, db)); + EXPECT_EQ(da, std::nextafter(minusSeven, seven)); EXPECT_EQ(db, seven); } @@ -157,9 +168,9 @@ TEST(StreamingQueryTest, test_query_language) EXPECT_TRUE(q.getAsIntegerTerm(ia, ib)); EXPECT_EQ(ia, -6); EXPECT_EQ(ib, 6); - EXPECT_TRUE(q.getAsDoubleTerm(da, db)); - EXPECT_EQ(da, std::nextafterf(minusSeven, seven)); - EXPECT_EQ(db, std::nextafterf(seven, minusSeven)); + EXPECT_TRUE(q.getAsFloatTerm(da, db)); + EXPECT_EQ(da, std::nextafter(minusSeven, seven)); + EXPECT_EQ(db, std::nextafter(seven, minusSeven)); } { @@ -174,9 +185,9 @@ TEST(StreamingQueryTest, test_query_language) EXPECT_TRUE(q.getAsIntegerTerm(ia, ib)); EXPECT_EQ(ia, -7); EXPECT_EQ(ib, 6); - EXPECT_TRUE(q.getAsDoubleTerm(da, db)); + EXPECT_TRUE(q.getAsFloatTerm(da, db)); EXPECT_EQ(da, minusSeven); - EXPECT_EQ(db, std::nextafterf(seven, minusSeven)); + EXPECT_EQ(db, std::nextafter(seven, minusSeven)); } { @@ -184,8 +195,8 @@ TEST(StreamingQueryTest, test_query_language) EXPECT_TRUE(q.getAsIntegerTerm(ia, ib)); EXPECT_EQ(ia, std::numeric_limits<int64_t>::min()); EXPECT_EQ(ib, -8); - EXPECT_TRUE(q.getAsDoubleTerm(da, db)); - EXPECT_EQ(da, -std::numeric_limits<double>::max()); + EXPECT_TRUE(q.getAsFloatTerm(da, db)); + EXPECT_EQ(da, -std::numeric_limits<double>::infinity()); EXPECT_LT(db, -7); EXPECT_GT(db, -7.01); } @@ -195,8 +206,8 @@ TEST(StreamingQueryTest, test_query_language) EXPECT_TRUE(q.getAsIntegerTerm(ia, ib)); EXPECT_EQ(ia, std::numeric_limits<int64_t>::min()); EXPECT_EQ(ib, -7); - EXPECT_TRUE(q.getAsDoubleTerm(da, db)); - EXPECT_EQ(da, -std::numeric_limits<double>::max()); + EXPECT_TRUE(q.getAsFloatTerm(da, db)); + EXPECT_EQ(da, -std::numeric_limits<double>::infinity()); EXPECT_EQ(db, -7); } @@ -205,8 +216,8 @@ TEST(StreamingQueryTest, test_query_language) EXPECT_TRUE(q.getAsIntegerTerm(ia, ib)); EXPECT_EQ(ia, std::numeric_limits<int64_t>::min()); EXPECT_EQ(ib, -7); - EXPECT_TRUE(q.getAsDoubleTerm(da, db)); - EXPECT_EQ(da, -std::numeric_limits<double>::max()); + EXPECT_TRUE(q.getAsFloatTerm(da, db)); + EXPECT_EQ(da, -std::numeric_limits<double>::infinity()); EXPECT_EQ(db, -7); } @@ -215,10 +226,10 @@ TEST(StreamingQueryTest, test_query_language) EXPECT_TRUE(q.getAsIntegerTerm(ia, ib)); EXPECT_EQ(ia, -6); EXPECT_EQ(ib, std::numeric_limits<int64_t>::max()); - EXPECT_TRUE(q.getAsDoubleTerm(da, db)); + EXPECT_TRUE(q.getAsFloatTerm(da, db)); EXPECT_GT(da, -7); EXPECT_LT(da, -6.99); - EXPECT_EQ(db, std::numeric_limits<double>::max()); + EXPECT_EQ(db, std::numeric_limits<double>::infinity()); } { @@ -226,9 +237,9 @@ TEST(StreamingQueryTest, test_query_language) EXPECT_TRUE(q.getAsIntegerTerm(ia, ib)); EXPECT_EQ(ia, -7); EXPECT_EQ(ib, std::numeric_limits<int64_t>::max()); - EXPECT_TRUE(q.getAsDoubleTerm(da, db)); + EXPECT_TRUE(q.getAsFloatTerm(da, db)); EXPECT_EQ(da, -7); - EXPECT_EQ(db, std::numeric_limits<double>::max()); + EXPECT_EQ(db, std::numeric_limits<double>::infinity()); } { @@ -236,15 +247,15 @@ TEST(StreamingQueryTest, test_query_language) EXPECT_TRUE(q.getAsIntegerTerm(ia, ib)); EXPECT_EQ(ia, -7); EXPECT_EQ(ib, std::numeric_limits<int64_t>::max()); - EXPECT_TRUE(q.getAsDoubleTerm(da, db)); + EXPECT_TRUE(q.getAsFloatTerm(da, db)); EXPECT_EQ(da, -7); - EXPECT_EQ(db, std::numeric_limits<double>::max()); + EXPECT_EQ(db, std::numeric_limits<double>::infinity()); } { QueryTerm q(factory.create(), "a", "index", TermType::WORD); EXPECT_TRUE(!q.getAsIntegerTerm(ia, ib)); - EXPECT_TRUE(!q.getAsDoubleTerm(da, db)); + EXPECT_TRUE(!q.getAsFloatTerm(da, db)); } { @@ -287,7 +298,10 @@ TEST(StreamingQueryTest, test_query_language) class AllowRewrite : public QueryNodeResultFactory { public: - virtual bool getRewriteFloatTerms() const override { return true; } + explicit AllowRewrite(vespalib::stringref index) noexcept : _allowedIndex(index) {} + bool allow_float_terms_rewrite(vespalib::stringref index) const noexcept override { return index == _allowedIndex; } +private: + vespalib::string _allowedIndex; }; const char TERM_UNIQ = static_cast<char>(ParseItem::ITEM_TERM) | static_cast<char>(ParseItem::IF_UNIQUEID); @@ -297,12 +311,12 @@ TEST(StreamingQueryTest, e_is_not_rewritten_even_if_allowed) const char term[6] = {TERM_UNIQ, 3, 1, 'c', 1, 'e'}; vespalib::stringref stackDump(term, sizeof(term)); EXPECT_EQ(6u, stackDump.size()); - AllowRewrite allowRewrite; + AllowRewrite allowRewrite("c"); const Query q(allowRewrite, stackDump); EXPECT_TRUE(q.valid()); const QueryNode & root = q.getRoot(); EXPECT_TRUE(dynamic_cast<const QueryTerm *>(&root) != nullptr); - const QueryTerm & qt = static_cast<const QueryTerm &>(root); + const auto & qt = static_cast<const QueryTerm &>(root); EXPECT_EQ("c", qt.index()); EXPECT_EQ(vespalib::stringref("e"), qt.getTerm()); EXPECT_EQ(3u, qt.uniqueId()); @@ -313,12 +327,12 @@ TEST(StreamingQueryTest, onedot0e_is_not_rewritten_by_default) const char term[9] = {TERM_UNIQ, 3, 1, 'c', 4, '1', '.', '0', 'e'}; vespalib::stringref stackDump(term, sizeof(term)); EXPECT_EQ(9u, stackDump.size()); - QueryNodeResultFactory empty; + AllowRewrite empty("nix"); const Query q(empty, stackDump); EXPECT_TRUE(q.valid()); const QueryNode & root = q.getRoot(); EXPECT_TRUE(dynamic_cast<const QueryTerm *>(&root) != nullptr); - const QueryTerm & qt = static_cast<const QueryTerm &>(root); + const auto & qt = static_cast<const QueryTerm &>(root); EXPECT_EQ("c", qt.index()); EXPECT_EQ(vespalib::stringref("1.0e"), qt.getTerm()); EXPECT_EQ(3u, qt.uniqueId()); @@ -329,34 +343,34 @@ TEST(StreamingQueryTest, onedot0e_is_rewritten_if_allowed_too) const char term[9] = {TERM_UNIQ, 3, 1, 'c', 4, '1', '.', '0', 'e'}; vespalib::stringref stackDump(term, sizeof(term)); EXPECT_EQ(9u, stackDump.size()); - AllowRewrite empty; + AllowRewrite empty("c"); const Query q(empty, stackDump); EXPECT_TRUE(q.valid()); const QueryNode & root = q.getRoot(); EXPECT_TRUE(dynamic_cast<const EquivQueryNode *>(&root) != nullptr); - const EquivQueryNode & equiv = static_cast<const EquivQueryNode &>(root); + const auto & equiv = static_cast<const EquivQueryNode &>(root); EXPECT_EQ(2u, equiv.size()); EXPECT_TRUE(dynamic_cast<const QueryTerm *>(equiv[0].get()) != nullptr); { - const QueryTerm & qt = static_cast<const QueryTerm &>(*equiv[0]); + const auto & qt = static_cast<const QueryTerm &>(*equiv[0]); EXPECT_EQ("c", qt.index()); EXPECT_EQ(vespalib::stringref("1.0e"), qt.getTerm()); EXPECT_EQ(3u, qt.uniqueId()); } EXPECT_TRUE(dynamic_cast<const PhraseQueryNode *>(equiv[1].get()) != nullptr); { - const PhraseQueryNode & phrase = static_cast<const PhraseQueryNode &>(*equiv[1]); + const auto & phrase = static_cast<const PhraseQueryNode &>(*equiv[1]); EXPECT_EQ(2u, phrase.size()); EXPECT_TRUE(dynamic_cast<const QueryTerm *>(phrase[0].get()) != nullptr); { - const QueryTerm & qt = static_cast<const QueryTerm &>(*phrase[0]); + const auto & qt = static_cast<const QueryTerm &>(*phrase[0]); EXPECT_EQ("c", qt.index()); EXPECT_EQ(vespalib::stringref("1"), qt.getTerm()); EXPECT_EQ(0u, qt.uniqueId()); } EXPECT_TRUE(dynamic_cast<const QueryTerm *>(phrase[1].get()) != nullptr); { - const QueryTerm & qt = static_cast<const QueryTerm &>(*phrase[1]); + const auto & qt = static_cast<const QueryTerm &>(*phrase[1]); EXPECT_EQ("c", qt.index()); EXPECT_EQ(vespalib::stringref("0e"), qt.getTerm()); EXPECT_EQ(0u, qt.uniqueId()); @@ -460,7 +474,7 @@ TEST(StreamingQueryTest, test_phrase_evaluate) terms[1]->add(1, 5, 0, 1); terms[2]->add(0, 5, 0, 1); HitList hits; - PhraseQueryNode * p = static_cast<PhraseQueryNode *>(phrases[0]); + auto * p = static_cast<PhraseQueryNode *>(phrases[0]); p->evaluateHits(hits); ASSERT_EQ(3u, hits.size()); EXPECT_EQ(hits[0].wordpos(), 2u); @@ -522,6 +536,7 @@ void assertInt64Range(const std::string &term, bool expAdjusted, int64_t expLow, EXPECT_EQ(expHigh, (int64_t)res.high); } + TEST(StreamingQueryTest, require_that_int8_limits_are_enforced) { //std::numeric_limits<int8_t>::min() -> -128 @@ -607,6 +622,20 @@ TEST(StreamingQueryTest, require_that_we_can_take_floating_point_values_in_range assertInt64Range("[1.7976931348623157E308;-1.7976931348623157E308]", false, std::numeric_limits<int64_t>::max(), std::numeric_limits<int64_t>::min()); } +void assertIllegalRangeQueries(const QueryTermSimple & qt) { + QueryTermSimple::RangeResult<int64_t> ires = qt.getRange<int64_t>(); + EXPECT_EQ(false, ires.valid); + QueryTermSimple::RangeResult<double> fres = qt.getRange<double>(); + EXPECT_EQ(false, fres.valid); +} + +TEST(StreamingQueryTest, require_safe_parsing_of_illegal_ranges) { + // The 2 below are created when naively splitting numeric terms by dot. + // T=A.B => T EQUIV PHRASE(A, B) + assertIllegalRangeQueries(QueryTermSimple("[1", TermType::WORD)); + assertIllegalRangeQueries(QueryTermSimple(".1;2.1]", TermType::WORD)); +} + TEST(StreamingQueryTest, require_that_we_handle_empty_range_as_expected) { assertInt64Range("[1;1]", false, 1, 1); @@ -627,11 +656,11 @@ TEST(StreamingQueryTest, require_that_ascending_range_can_be_specified_with_limi QueryTerm ascending_query(eqnr.create(), "[;;500]", "index", TermType::WORD); EXPECT_TRUE(ascending_query.getAsIntegerTerm(low_integer, high_integer)); - EXPECT_TRUE(ascending_query.getAsDoubleTerm(low_double, high_double)); + EXPECT_TRUE(ascending_query.getAsFloatTerm(low_double, high_double)); EXPECT_EQ(std::numeric_limits<int64_t>::min(), low_integer); EXPECT_EQ(std::numeric_limits<int64_t>::max(), high_integer); - EXPECT_EQ(-std::numeric_limits<double>::max(), low_double); - EXPECT_EQ(std::numeric_limits<double>::max(), high_double); + EXPECT_EQ(-std::numeric_limits<double>::infinity(), low_double); + EXPECT_EQ(std::numeric_limits<double>::infinity(), high_double); EXPECT_EQ(500, ascending_query.getRangeLimit()); } @@ -646,11 +675,11 @@ TEST(StreamingQueryTest, require_that_descending_range_can_be_specified_with_lim QueryTerm descending_query(eqnr.create(), "[;;-500]", "index", TermType::WORD); EXPECT_TRUE(descending_query.getAsIntegerTerm(low_integer, high_integer)); - EXPECT_TRUE(descending_query.getAsDoubleTerm(low_double, high_double)); + EXPECT_TRUE(descending_query.getAsFloatTerm(low_double, high_double)); EXPECT_EQ(std::numeric_limits<int64_t>::min(), low_integer); EXPECT_EQ(std::numeric_limits<int64_t>::max(), high_integer); - EXPECT_EQ(-std::numeric_limits<double>::max(), low_double); - EXPECT_EQ(std::numeric_limits<double>::max(), high_double); + EXPECT_EQ(-std::numeric_limits<double>::infinity(), low_double); + EXPECT_EQ(std::numeric_limits<double>::infinity(), high_double); EXPECT_EQ(-500, descending_query.getRangeLimit()); } @@ -735,7 +764,7 @@ TEST(StreamingQueryTest, require_that_incorrectly_specified_diversity_can_be_par TEST(StreamingQueryTest, require_that_we_do_not_break_the_stack_on_bad_query) { - QueryTermSimple term("<form><iframe+	 +src=\\\"javascript:alert(1)\\\" 	;>", TermType::WORD); + QueryTermSimple term(R"(<form><iframe+	 +src=\"javascript:alert(1)\" 	;>)", TermType::WORD); EXPECT_FALSE(term.isValid()); } @@ -744,7 +773,7 @@ TEST(StreamingQueryTest, a_unhandled_sameElement_stack) const char * stack = "\022\002\026xyz_abcdefghij_xyzxyzxQ\001\vxxxxxx_name\034xxxxxx_xxxx_xxxxxxx_xxxxxxxxE\002\005delta\b<0.00393"; vespalib::stringref stackDump(stack); EXPECT_EQ(85u, stackDump.size()); - AllowRewrite empty; + AllowRewrite empty(""); const Query q(empty, stackDump); EXPECT_TRUE(q.valid()); const QueryNode & root = q.getRoot(); @@ -778,7 +807,7 @@ TEST(StreamingQueryTest, test_same_element_evaluate) vespalib::string stackDump = StackDumpCreator::create(*node); QueryNodeResultFactory empty; Query q(empty, stackDump); - SameElementQueryNode * sameElem = dynamic_cast<SameElementQueryNode *>(&q.getRoot()); + auto * sameElem = dynamic_cast<SameElementQueryNode *>(&q.getRoot()); EXPECT_TRUE(sameElem != nullptr); EXPECT_EQ("field", sameElem->getIndex()); EXPECT_EQ(3u, sameElem->size()); @@ -878,7 +907,7 @@ TEST(StreamingQueryTest, test_in_term) { auto term_vector = std::make_unique<StringTermVector>(1); term_vector->addTerm("7"); - search::streaming::InTerm term({}, "index", std::move(term_vector)); + search::streaming::InTerm term({}, "index", std::move(term_vector), Normalizing::NONE); SimpleTermData td; td.addField(10); td.addField(11); @@ -929,6 +958,68 @@ TEST(StreamingQueryTest, dot_product_term) EXPECT_EQ(-17 * 27 + 9 * 2, tmd1->getRawScore()); } +namespace { + +constexpr double exp_wand_score_field_12 = 13 * 27 + 4 * 2; +constexpr double exp_wand_score_field_11 = 17 * 27 + 9 * 2; + +void +check_wand_term(double limit, const vespalib::string& label) +{ + SCOPED_TRACE(label); + search::streaming::WandTerm term({}, "index", 2); + term.add_term(std::make_unique<QueryTerm>(std::unique_ptr<QueryNodeResultBase>(), "7", "", QueryTermSimple::Type::WORD)); + term.get_terms().back()->setWeight(Weight(27)); + term.add_term(std::make_unique<QueryTerm>(std::unique_ptr<QueryNodeResultBase>(), "9", "", QueryTermSimple::Type::WORD)); + term.get_terms().back()->setWeight(Weight(2)); + EXPECT_EQ(2, term.get_terms().size()); + term.set_score_threshold(limit); + SimpleTermData td; + /* + * Search in fields 10, 11 and 12 (cf. fieldset in schema). + * Fields 11 and 12 have content for doc containing the keys. + * Fields 10 and 12 have valid handles and can be used for ranking. + * Field 11 does not have a valid handle, thus no associated match data. + */ + td.addField(10); + td.addField(11); + td.addField(12); + td.lookupField(10)->setHandle(0); + td.lookupField(12)->setHandle(1); + EXPECT_FALSE(term.evaluate()); + auto& q0 = *term.get_terms()[0]; + q0.add(0, 11, 0, 17); + q0.add(0, 12, 0, 13); + auto& q1 = *term.get_terms()[1]; + q1.add(0, 11, 0, 9); + q1.add(0, 12, 0, 4); + EXPECT_EQ(limit < exp_wand_score_field_11, term.evaluate()); + MatchData md(MatchData::params().numTermFields(2)); + term.unpack_match_data(23, td, md); + auto tmd0 = md.resolveTermField(0); + EXPECT_NE(23, tmd0->getDocId()); + auto tmd1 = md.resolveTermField(1); + if (limit < exp_wand_score_field_12) { + EXPECT_EQ(23, tmd1->getDocId()); + EXPECT_EQ(exp_wand_score_field_12, tmd1->getRawScore()); + } else { + EXPECT_NE(23, tmd1->getDocId()); + } +} + +} + +TEST(StreamingQueryTest, wand_term) +{ + check_wand_term(0.0, "no limit"); + check_wand_term(exp_wand_score_field_12 - 1, "score above limit"); + check_wand_term(exp_wand_score_field_12, "score at limit"); + check_wand_term(exp_wand_score_field_12 + 1, "score below limit"); + check_wand_term(exp_wand_score_field_11 - 1, "hidden score above limit"); + check_wand_term(exp_wand_score_field_11, "hidden score at limit"); + check_wand_term(exp_wand_score_field_11 + 1, "hidden score below limit"); +} + TEST(StreamingQueryTest, control_the_size_of_query_terms) { EXPECT_EQ(112u, sizeof(QueryTermSimple)); |