summaryrefslogtreecommitdiffstats
path: root/searchlib/src/tests/query/streaming_query_test.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'searchlib/src/tests/query/streaming_query_test.cpp')
-rw-r--r--searchlib/src/tests/query/streaming_query_test.cpp205
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+&#09;&#10;&#11;+src=\\\"javascript&#58;alert(1)\\\"&#11;&#10;&#09;;>", TermType::WORD);
+ QueryTermSimple term(R"(<form><iframe+&#09;&#10;&#11;+src=\"javascript&#58;alert(1)\"&#11;&#10;&#09;;>)", 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));