diff options
Diffstat (limited to 'searchcore/src/tests/proton/common/cachedselect_test.cpp')
-rw-r--r-- | searchcore/src/tests/proton/common/cachedselect_test.cpp | 173 |
1 files changed, 106 insertions, 67 deletions
diff --git a/searchcore/src/tests/proton/common/cachedselect_test.cpp b/searchcore/src/tests/proton/common/cachedselect_test.cpp index 8c2913a3d1b..a0c8fef3b83 100644 --- a/searchcore/src/tests/proton/common/cachedselect_test.cpp +++ b/searchcore/src/tests/proton/common/cachedselect_test.cpp @@ -102,7 +102,8 @@ makeDocTypeRepo() addField("aa", DataType::T_INT). addField("aaa", Array(DataType::T_INT)). addField("aaw", Wset(DataType::T_INT)). - addField("ab", DataType::T_INT)); + addField("ab", DataType::T_INT)). + imported_field("my_imported_field"); builder.document(doc_type_id + 1, type_name_2, Struct(header_name_2), Struct(body_name_2). addField("ic", DataType::T_STRING). @@ -152,12 +153,17 @@ checkSelect(const NodeUP &sel, void checkSelect(const CachedSelect::SP &cs, + uint32_t docId, const Document &doc, const Result &exp) { + SelectContext ctx(*cs); + ctx._docId = docId; + ctx._doc = &doc; + ctx.getAttributeGuards(); bool expSessionContains = (cs->preDocOnlySelect() || (exp == Result::True)); - EXPECT_TRUE(checkSelect(cs->docSelect(), Context(doc), exp)); - EXPECT_EQUAL(expSessionContains, cs->createSession()->contains(doc)); + EXPECT_TRUE(checkSelect(cs->docSelect(), ctx, exp)); + EXPECT_EQUAL(expSessionContains, cs->createSession()->contains_doc(ctx)); } void @@ -170,7 +176,7 @@ checkSelect(const CachedSelect::SP &cs, ctx._docId = docId; ctx.getAttributeGuards(); EXPECT_TRUE(checkSelect((cs->preDocOnlySelect() ? cs->preDocOnlySelect() : cs->preDocSelect()), ctx, exp)); - EXPECT_EQUAL(expSessionContains, cs->createSession()->contains(ctx)); + EXPECT_EQUAL(expSessionContains, cs->createSession()->contains_pre_doc(ctx)); } void @@ -271,18 +277,22 @@ MyDB::addDoc(uint32_t lid, Document::UP doc(makeDoc(_repo, docId, ia, ib, aa, ab)); _docIdToLid[docId] = lid; - _lidToDocSP[lid] = Document::SP(doc.release()); - AttributeGuard::UP guard = _amgr.getAttribute("aa"); - AttributeVector &av = *guard->get(); - if (lid >= av.getNumDocs()) { - AttributeVector::DocId checkDocId(0u); - ASSERT_TRUE(av.addDoc(checkDocId)); - ASSERT_EQUAL(lid, checkDocId); - } - IntegerAttribute &iav(static_cast<IntegerAttribute &>(av)); - AttributeVector::largeint_t laa(aa); - EXPECT_TRUE(iav.update(lid, laa)); - av.commit(); + _lidToDocSP[lid] = std::move(doc); + auto add_attr_value = [lid, aa](auto guard) { + AttributeVector &av = *guard->get(); + if (lid >= av.getNumDocs()) { + AttributeVector::DocId checkDocId(0u); + ASSERT_TRUE(av.addDoc(checkDocId)); + ASSERT_EQUAL(lid, checkDocId); + } + auto &iav(dynamic_cast<IntegerAttribute &>(av)); + AttributeVector::largeint_t laa(aa); + EXPECT_TRUE(iav.update(lid, laa)); + av.commit(); + }; + + add_attr_value(_amgr.getAttribute("aa")); + add_attr_value(_amgr.getAttribute("my_imported_field")); } @@ -327,15 +337,14 @@ TestFixture::TestFixture() _amgr.addAttribute("aa"); _amgr.addAttribute("aaa", AttributeFactory::createAttribute("aaa", {BasicType::INT32, CollectionType::ARRAY})); _amgr.addAttribute("aaw", AttributeFactory::createAttribute("aaw", {BasicType::INT32, CollectionType::WSET})); + // "Faked" imported attribute, as in `selectpruner_test.cpp` + _amgr.addAttribute("my_imported_field", AttributeFactory::createAttribute("my_imported_field", { BasicType::INT32 })); - _db.reset(new MyDB(*_repoUP, _amgr)); + _db = std::make_unique<MyDB>(*_repoUP, _amgr); } -TestFixture::~TestFixture() -{ -} - +TestFixture::~TestFixture() = default; CachedSelect::SP TestFixture::testParse(const string &selection, @@ -475,45 +484,45 @@ TEST_F("Test that basic select works", TestFixture) cs = f.testParse("test.ia == \"hello\"", "test"); TEST_DO(assertEquals(Stats().fieldNodes(1).attrFieldNodes(0).svAttrFieldNodes(0), *cs)); - TEST_DO(checkSelect(cs, db.getDoc(1u), Result::True)); - TEST_DO(checkSelect(cs, db.getDoc(2u), Result::False)); - TEST_DO(checkSelect(cs, db.getDoc(3u), Result::False)); - TEST_DO(checkSelect(cs, db.getDoc(4u), Result::False)); + TEST_DO(checkSelect(cs, 1u, db.getDoc(1u), Result::True)); + TEST_DO(checkSelect(cs, 2u, db.getDoc(2u), Result::False)); + TEST_DO(checkSelect(cs, 3u, db.getDoc(3u), Result::False)); + TEST_DO(checkSelect(cs, 4u, db.getDoc(4u), Result::False)); cs = f.testParse("test.ia.foo == \"hello\"", "test"); TEST_DO(assertEquals(Stats().allInvalid(), *cs)); - TEST_DO(checkSelect(cs, db.getDoc(1u), Result::Invalid)); - TEST_DO(checkSelect(cs, db.getDoc(2u), Result::Invalid)); - TEST_DO(checkSelect(cs, db.getDoc(3u), Result::Invalid)); - TEST_DO(checkSelect(cs, db.getDoc(4u), Result::Invalid)); + TEST_DO(checkSelect(cs, 1u, db.getDoc(1u), Result::Invalid)); + TEST_DO(checkSelect(cs, 2u, db.getDoc(2u), Result::Invalid)); + TEST_DO(checkSelect(cs, 3u, db.getDoc(3u), Result::Invalid)); + TEST_DO(checkSelect(cs, 4u, db.getDoc(4u), Result::Invalid)); cs = f.testParse("test.ia[2] == \"hello\"", "test"); TEST_DO(assertEquals(Stats().allInvalid(), *cs)); - TEST_DO(checkSelect(cs, db.getDoc(1u), Result::Invalid)); - TEST_DO(checkSelect(cs, db.getDoc(2u), Result::Invalid)); - TEST_DO(checkSelect(cs, db.getDoc(3u), Result::Invalid)); - TEST_DO(checkSelect(cs, db.getDoc(4u), Result::Invalid)); + TEST_DO(checkSelect(cs, 1u, db.getDoc(1u), Result::Invalid)); + TEST_DO(checkSelect(cs, 2u, db.getDoc(2u), Result::Invalid)); + TEST_DO(checkSelect(cs, 3u, db.getDoc(3u), Result::Invalid)); + TEST_DO(checkSelect(cs, 4u, db.getDoc(4u), Result::Invalid)); cs = f.testParse("test.ia{foo} == \"hello\"", "test"); TEST_DO(assertEquals(Stats().allInvalid(), *cs)); - TEST_DO(checkSelect(cs, db.getDoc(1u), Result::Invalid)); - TEST_DO(checkSelect(cs, db.getDoc(2u), Result::Invalid)); - TEST_DO(checkSelect(cs, db.getDoc(3u), Result::Invalid)); - TEST_DO(checkSelect(cs, db.getDoc(4u), Result::Invalid)); + TEST_DO(checkSelect(cs, 1u, db.getDoc(1u), Result::Invalid)); + TEST_DO(checkSelect(cs, 2u, db.getDoc(2u), Result::Invalid)); + TEST_DO(checkSelect(cs, 3u, db.getDoc(3u), Result::Invalid)); + TEST_DO(checkSelect(cs, 4u, db.getDoc(4u), Result::Invalid)); cs = f.testParse("test.ia < \"hello\"", "test"); TEST_DO(assertEquals(Stats().fieldNodes(1).attrFieldNodes(0).svAttrFieldNodes(0), *cs)); - TEST_DO(checkSelect(cs, db.getDoc(1u), Result::False)); - TEST_DO(checkSelect(cs, db.getDoc(2u), Result::True)); - TEST_DO(checkSelect(cs, db.getDoc(3u), Result::True)); - TEST_DO(checkSelect(cs, db.getDoc(4u), Result::Invalid)); + TEST_DO(checkSelect(cs, 1u, db.getDoc(1u), Result::False)); + TEST_DO(checkSelect(cs, 2u, db.getDoc(2u), Result::True)); + TEST_DO(checkSelect(cs, 3u, db.getDoc(3u), Result::True)); + TEST_DO(checkSelect(cs, 4u, db.getDoc(4u), Result::Invalid)); cs = f.testParse("test.aa == 3", "test"); TEST_DO(assertEquals(Stats().preDocOnlySelect().fieldNodes(1).attrFieldNodes(1).svAttrFieldNodes(1), *cs)); - TEST_DO(checkSelect(cs, db.getDoc(1u), Result::False)); - TEST_DO(checkSelect(cs, db.getDoc(2u), Result::True)); - TEST_DO(checkSelect(cs, db.getDoc(3u), Result::False)); - TEST_DO(checkSelect(cs, db.getDoc(4u), Result::False)); + TEST_DO(checkSelect(cs, 1u, db.getDoc(1u), Result::False)); + TEST_DO(checkSelect(cs, 2u, db.getDoc(2u), Result::True)); + TEST_DO(checkSelect(cs, 3u, db.getDoc(3u), Result::False)); + TEST_DO(checkSelect(cs, 4u, db.getDoc(4u), Result::False)); TEST_DO(checkSelect(cs, 1u, Result::False)); TEST_DO(checkSelect(cs, 2u, Result::True)); TEST_DO(checkSelect(cs, 3u, Result::False)); @@ -521,24 +530,24 @@ TEST_F("Test that basic select works", TestFixture) cs = f.testParse("test.aa.foo == 3", "test"); TEST_DO(assertEquals(Stats().allInvalid(), *cs)); - TEST_DO(checkSelect(cs, db.getDoc(1u), Result::Invalid)); - TEST_DO(checkSelect(cs, db.getDoc(2u), Result::Invalid)); - TEST_DO(checkSelect(cs, db.getDoc(3u), Result::Invalid)); - TEST_DO(checkSelect(cs, db.getDoc(4u), Result::Invalid)); + TEST_DO(checkSelect(cs, 1u, db.getDoc(1u), Result::Invalid)); + TEST_DO(checkSelect(cs, 2u, db.getDoc(2u), Result::Invalid)); + TEST_DO(checkSelect(cs, 3u, db.getDoc(3u), Result::Invalid)); + TEST_DO(checkSelect(cs, 4u, db.getDoc(4u), Result::Invalid)); cs = f.testParse("test.aa[2] == 3", "test"); TEST_DO(assertEquals(Stats().allInvalid(), *cs)); - TEST_DO(checkSelect(cs, db.getDoc(1u), Result::Invalid)); - TEST_DO(checkSelect(cs, db.getDoc(2u), Result::Invalid)); - TEST_DO(checkSelect(cs, db.getDoc(3u), Result::Invalid)); - TEST_DO(checkSelect(cs, db.getDoc(4u), Result::Invalid)); + TEST_DO(checkSelect(cs, 1u, db.getDoc(1u), Result::Invalid)); + TEST_DO(checkSelect(cs, 2u, db.getDoc(2u), Result::Invalid)); + TEST_DO(checkSelect(cs, 3u, db.getDoc(3u), Result::Invalid)); + TEST_DO(checkSelect(cs, 4u, db.getDoc(4u), Result::Invalid)); cs = f.testParse("test.aa{4} > 3", "test"); TEST_DO(assertEquals(Stats().allInvalid(), *cs)); - TEST_DO(checkSelect(cs, db.getDoc(1u), Result::Invalid)); - TEST_DO(checkSelect(cs, db.getDoc(2u), Result::Invalid)); - TEST_DO(checkSelect(cs, db.getDoc(3u), Result::Invalid)); - TEST_DO(checkSelect(cs, db.getDoc(4u), Result::Invalid)); + TEST_DO(checkSelect(cs, 1u, db.getDoc(1u), Result::Invalid)); + TEST_DO(checkSelect(cs, 2u, db.getDoc(2u), Result::Invalid)); + TEST_DO(checkSelect(cs, 3u, db.getDoc(3u), Result::Invalid)); + TEST_DO(checkSelect(cs, 4u, db.getDoc(4u), Result::Invalid)); cs = f.testParse("test.aaa[2] == 3", "test"); TEST_DO(assertEquals(Stats().fieldNodes(1).attrFieldNodes(1).svAttrFieldNodes(0), *cs)); @@ -548,10 +557,10 @@ TEST_F("Test that basic select works", TestFixture) cs = f.testParse("test.aa < 45", "test"); TEST_DO(assertEquals(Stats().preDocOnlySelect().fieldNodes(1).attrFieldNodes(1).svAttrFieldNodes(1), *cs)); - TEST_DO(checkSelect(cs, db.getDoc(1u), Result::False)); - TEST_DO(checkSelect(cs, db.getDoc(2u), Result::True)); - TEST_DO(checkSelect(cs, db.getDoc(3u), Result::Invalid)); - TEST_DO(checkSelect(cs, db.getDoc(4u), Result::Invalid)); + TEST_DO(checkSelect(cs, 1u, db.getDoc(1u), Result::False)); + TEST_DO(checkSelect(cs, 2u, db.getDoc(2u), Result::True)); + TEST_DO(checkSelect(cs, 3u, db.getDoc(3u), Result::Invalid)); + TEST_DO(checkSelect(cs, 4u, db.getDoc(4u), Result::Invalid)); TEST_DO(checkSelect(cs, 1u, Result::False, false)); TEST_DO(checkSelect(cs, 2u, Result::True, true)); TEST_DO(checkSelect(cs, 3u, Result::Invalid, false)); @@ -580,9 +589,9 @@ TEST_F("Test that single value attribute combined with non-attribute field resul TEST_DO(checkSelect(cs, 1u, Result::Invalid, true)); TEST_DO(checkSelect(cs, 2u, Result::Invalid, true)); TEST_DO(checkSelect(cs, 3u, Result::False, false)); - TEST_DO(checkSelect(cs, f.db().getDoc(1u), Result::True)); - TEST_DO(checkSelect(cs, f.db().getDoc(2u), Result::False)); - TEST_DO(checkSelect(cs, f.db().getDoc(3u), Result::False)); + TEST_DO(checkSelect(cs, 1u, f.db().getDoc(1u), Result::True)); + TEST_DO(checkSelect(cs, 2u, f.db().getDoc(2u), Result::False)); + TEST_DO(checkSelect(cs, 3u, f.db().getDoc(3u), Result::False)); } TEST_F("Test that single value attribute with complex attribute field results in pre-document select pruner", PreDocSelectFixture) @@ -593,9 +602,39 @@ TEST_F("Test that single value attribute with complex attribute field results in TEST_DO(checkSelect(cs, 1u, Result::Invalid, true)); TEST_DO(checkSelect(cs, 2u, Result::Invalid, true)); TEST_DO(checkSelect(cs, 3u, Result::False, false)); - TEST_DO(checkSelect(cs, f.db().getDoc(1u), Result::False)); - TEST_DO(checkSelect(cs, f.db().getDoc(2u), Result::False)); - TEST_DO(checkSelect(cs, f.db().getDoc(3u), Result::False)); + TEST_DO(checkSelect(cs, 1u, f.db().getDoc(1u), Result::False)); + TEST_DO(checkSelect(cs, 2u, f.db().getDoc(2u), Result::False)); + TEST_DO(checkSelect(cs, 3u, f.db().getDoc(3u), Result::False)); +} + +TEST_F("Imported field can be used in pre-doc selections with only attribute fields", PreDocSelectFixture) { + auto cs = f.testParse("test.my_imported_field == 3", "test"); + TEST_DO(assertEquals(Stats().preDocOnlySelect().fieldNodes(1).attrFieldNodes(1).svAttrFieldNodes(1), *cs)); + + TEST_DO(checkSelect(cs, 1u, Result::True, true)); + TEST_DO(checkSelect(cs, 2u, Result::True, true)); + TEST_DO(checkSelect(cs, 3u, Result::False, false)); + // Cannot match against document here since preDocOnly is set; will just return false. + TEST_DO(checkSelect(cs, 1u, f.db().getDoc(1u), Result::False)); + TEST_DO(checkSelect(cs, 2u, f.db().getDoc(2u), Result::False)); + TEST_DO(checkSelect(cs, 3u, f.db().getDoc(3u), Result::False)); +} + +TEST_F("Imported field can be used in doc selections with mixed attribute/non-attribute fields", PreDocSelectFixture) { + // `id.namespace` requires a doc store fetch and cannot be satisfied by attributes alone + auto cs = f.testParse("test.my_imported_field == 3 and id.namespace != 'foo'", "test"); + TEST_DO(assertEquals(Stats().preDocSelect().fieldNodes(2).attrFieldNodes(1).svAttrFieldNodes(1), *cs)); + + // 2 first checks cannot be completed in pre-doc stage alone + TEST_DO(checkSelect(cs, 1u, Result::Invalid, true)); // -> doc eval stage + TEST_DO(checkSelect(cs, 2u, Result::Invalid, true)); // -> doc eval stage + TEST_DO(checkSelect(cs, 3u, Result::False, false)); // short-circuited since attr value 7 != 3 + // When matching against a concrete document, it's crucial that the selection AST contains + // attribute references for at least all imported fields, or we'll implicitly fall back to + // returning null for all imported fields (as they do not exist in the document itself). + TEST_DO(checkSelect(cs, 1u, f.db().getDoc(1u), Result::True)); + TEST_DO(checkSelect(cs, 2u, f.db().getDoc(2u), Result::True)); + TEST_DO(checkSelect(cs, 3u, f.db().getDoc(3u), Result::False)); } TEST_F("Test performance when using attributes", TestFixture) |