mirror of https://gitee.com/bigwinds/arangodb
issue 526.4.1: add analyzer removal and feature validation functionality (#8575)
This commit is contained in:
parent
14843a4275
commit
778417cdf0
|
@ -60,7 +60,7 @@
|
|||
|
||||
namespace {
|
||||
|
||||
static std::string const ANALYZER_COLLECTION_NAME("_iresearch_analyzers");
|
||||
static std::string const ANALYZER_COLLECTION_NAME("_analyzers");
|
||||
static char const ANALYZER_PREFIX_DELIM = ':'; // name prefix delimiter (2 chars)
|
||||
static size_t const DEFAULT_POOL_SIZE = 8; // arbitrary value
|
||||
static std::string const FEATURE_NAME("IResearchAnalyzer");
|
||||
|
@ -467,6 +467,34 @@ std::pair<irs::string_ref, irs::string_ref> splitAnalyzerName( // split name
|
|||
return std::make_pair(irs::string_ref::NIL, analyzer); // unprefixed analyzer name
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief validate that features are supported by arangod an ensure that their
|
||||
/// dependencies are met
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
arangodb::Result validateFeatures(irs::flags const& features) {
|
||||
for(auto& feature: features) {
|
||||
if (&irs::frequency::type() == feature) {
|
||||
// no extra validation required
|
||||
} else if (&irs::norm::type() == feature) {
|
||||
// no extra validation required
|
||||
} else if (&irs::position::type() == feature) {
|
||||
if (!features.check(irs::frequency::type())) {
|
||||
return arangodb::Result( // result
|
||||
TRI_ERROR_BAD_PARAMETER, // code
|
||||
std::string("missing feature '") + std::string(irs::frequency::type().name()) +"' required when '" + std::string(feature->name()) + "' feature is specified"
|
||||
);
|
||||
}
|
||||
} else if (feature) {
|
||||
return arangodb::Result( // result
|
||||
TRI_ERROR_BAD_PARAMETER, // code
|
||||
std::string("unsupported analyzer feature '") + std::string(feature->name()) + "'" // value
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return arangodb::Result();
|
||||
}
|
||||
|
||||
typedef irs::async_utils::read_write_mutex::read_mutex ReadMutex;
|
||||
typedef irs::async_utils::read_write_mutex::write_mutex WriteMutex;
|
||||
|
||||
|
@ -660,11 +688,6 @@ IResearchAnalyzerFeature::IResearchAnalyzerFeature(arangodb::application_feature
|
|||
split = splitAnalyzerName(analyzer);
|
||||
}
|
||||
|
||||
// FIXME TODO remove temporary workaround once emplace(...) and all tests are updated
|
||||
if (split.first.null()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return !split.first.null() // have a vocbase
|
||||
&& ctx->canUseDatabase(split.first, level) // can use vocbase
|
||||
&& ctx->canUseCollection(split.first, ANALYZER_COLLECTION_NAME, level); // can use analyzers
|
||||
|
@ -715,11 +738,6 @@ std::pair<IResearchAnalyzerFeature::AnalyzerPool::ptr, bool> IResearchAnalyzerFe
|
|||
|
||||
// skip initialization and persistance
|
||||
if (!initAndPersist) {
|
||||
if (itr.second) {
|
||||
_customAnalyzers[itr.first->first] =
|
||||
itr.first->second; // mark as custom if insertion took place
|
||||
}
|
||||
|
||||
erase = false;
|
||||
|
||||
return std::make_pair(pool, itr.second);
|
||||
|
@ -845,6 +863,12 @@ arangodb::Result IResearchAnalyzerFeature::ensure( // ensure analyzer existence
|
|||
const_cast<AnalyzerPool::ptr&>(value) = pool; // lazy-instantiate pool to avoid allocation if pool is already present
|
||||
return pool ? irs::hashed_string_ref(key.hash(), pool->name()) : key; // reuse hash but point ref at value in pool
|
||||
};
|
||||
auto res = validateFeatures(features);
|
||||
|
||||
if (!res.ok()) {
|
||||
return res;
|
||||
}
|
||||
|
||||
WriteMutex mutex(_mutex);
|
||||
SCOPED_LOCK(mutex);
|
||||
|
||||
|
@ -885,7 +909,7 @@ arangodb::Result IResearchAnalyzerFeature::ensure( // ensure analyzer existence
|
|||
}
|
||||
|
||||
// persist only on coordinator and single-server
|
||||
auto res = arangodb::ServerState::instance()->isCoordinator() // coordinator
|
||||
res = arangodb::ServerState::instance()->isCoordinator() // coordinator
|
||||
|| arangodb::ServerState::instance()->isSingleServer() // single-server
|
||||
? storeAnalyzer(*pool) : arangodb::Result();
|
||||
|
||||
|
@ -929,114 +953,6 @@ arangodb::Result IResearchAnalyzerFeature::ensure( // ensure analyzer existence
|
|||
return arangodb::Result();
|
||||
}
|
||||
|
||||
size_t IResearchAnalyzerFeature::erase(irs::string_ref const& name) noexcept {
|
||||
try {
|
||||
WriteMutex mutex(_mutex);
|
||||
SCOPED_LOCK(mutex);
|
||||
|
||||
auto itr =
|
||||
_customAnalyzers.find(irs::make_hashed_ref(name, std::hash<irs::string_ref>()));
|
||||
|
||||
if (itr == _customAnalyzers.end()) {
|
||||
return 0; // nothing to erase
|
||||
}
|
||||
|
||||
auto pool = itr->second;
|
||||
|
||||
if (!pool) {
|
||||
LOG_TOPIC("ea7df", WARN, arangodb::iresearch::TOPIC)
|
||||
<< "removal of an unset arangosearch analizer name '" << name << "'";
|
||||
_analyzers.erase(itr->first); // ok to erase since found in '_customAnalyzers'
|
||||
_customAnalyzers.erase(itr);
|
||||
|
||||
return 0; // no actual valid analyzer was removed (this is definitly a
|
||||
// bug somewhere)
|
||||
}
|
||||
|
||||
if (_started) {
|
||||
auto vocbase = getSystemDatabase();
|
||||
|
||||
if (!vocbase) {
|
||||
LOG_TOPIC("68dc6", WARN, arangodb::iresearch::TOPIC)
|
||||
<< "failure to get system database while removing arangosearch "
|
||||
"analyzer name '"
|
||||
<< pool->name() << "'";
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
arangodb::SingleCollectionTransaction trx(
|
||||
arangodb::transaction::StandaloneContext::Create(*vocbase),
|
||||
ANALYZER_COLLECTION_NAME, arangodb::AccessMode::Type::WRITE);
|
||||
auto res = trx.begin();
|
||||
|
||||
if (!res.ok()) {
|
||||
LOG_TOPIC("13ff5", WARN, arangodb::iresearch::TOPIC)
|
||||
<< "failure to start transaction while removing configuration for "
|
||||
"arangosearch analyzer name '"
|
||||
<< pool->name() << "'";
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
arangodb::velocypack::Builder builder;
|
||||
arangodb::OperationOptions options;
|
||||
|
||||
builder.openObject();
|
||||
builder.add(arangodb::StaticStrings::KeyString, toValuePair(pool->_key));
|
||||
builder.close();
|
||||
options.waitForSync = true;
|
||||
|
||||
auto result = trx.remove(ANALYZER_COLLECTION_NAME, builder.slice(), options);
|
||||
|
||||
// stataic analyzers are not persisted
|
||||
if (!result.ok() && result.isNot(TRI_ERROR_ARANGO_DOCUMENT_NOT_FOUND)) {
|
||||
LOG_TOPIC("4e7f4", WARN, arangodb::iresearch::TOPIC)
|
||||
<< "failure to persist AnalyzerPool configuration while removing "
|
||||
"arangosearch analyzer name '"
|
||||
<< pool->name() << "'";
|
||||
trx.abort();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!trx.commit().ok()) {
|
||||
LOG_TOPIC("68afe", WARN, arangodb::iresearch::TOPIC)
|
||||
<< "failure to commit AnalyzerPool configuration while removing "
|
||||
"arangosearch analyzer name '"
|
||||
<< pool->name() << "'";
|
||||
trx.abort();
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// OK to erase if !_started because on start() the persisted configuration
|
||||
// will be loaded
|
||||
_analyzers.erase(itr->first); // ok to erase since found in '_customAnalyzers'
|
||||
_customAnalyzers.erase(itr);
|
||||
|
||||
return 1;
|
||||
} catch (arangodb::basics::Exception& e) {
|
||||
LOG_TOPIC("3cbe0", WARN, arangodb::iresearch::TOPIC)
|
||||
<< "caught exception while removing an arangosearch analizer name '"
|
||||
<< name << "': " << e.code() << " " << e.what();
|
||||
IR_LOG_EXCEPTION();
|
||||
} catch (std::exception& e) {
|
||||
LOG_TOPIC("e4cd7", WARN, arangodb::iresearch::TOPIC)
|
||||
<< "caught exception while removing an arangosearch analizer name '"
|
||||
<< name << "': " << e.what();
|
||||
IR_LOG_EXCEPTION();
|
||||
} catch (...) {
|
||||
LOG_TOPIC("1afcb", WARN, arangodb::iresearch::TOPIC)
|
||||
<< "caught exception while removing an arangosearch analizer name '"
|
||||
<< name << "'";
|
||||
IR_LOG_EXCEPTION();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
IResearchAnalyzerFeature::AnalyzerPool::ptr IResearchAnalyzerFeature::get( // find analyzer
|
||||
irs::string_ref const& name // analyzer name
|
||||
) const noexcept {
|
||||
|
@ -1119,8 +1035,6 @@ IResearchAnalyzerFeature::AnalyzerPool::ptr IResearchAnalyzerFeature::get( // fi
|
|||
// register the indentity analyzer
|
||||
{
|
||||
static const irs::flags extraFeatures = {irs::frequency::type(), irs::norm::type()};
|
||||
// static const irs::flags extraFeatures = { }; // FIXME TODO use above
|
||||
// once tfidf/bm25 sort is fixed
|
||||
static const irs::string_ref name("identity");
|
||||
PTR_NAMED(AnalyzerPool, pool, name);
|
||||
|
||||
|
@ -1315,6 +1229,14 @@ bool IResearchAnalyzerFeature::loadConfiguration() {
|
|||
properties = getStringRef(propertiesSlice);
|
||||
}
|
||||
|
||||
auto normalizedName = // normalized name
|
||||
collection->vocbase().name() + "::" + std::string(name);
|
||||
auto& staticAnalyzersMap = getStaticAnalyzers();
|
||||
|
||||
if (staticAnalyzersMap.find(irs::make_hashed_ref(name, std::hash<irs::string_ref>())) == staticAnalyzersMap.end()) {
|
||||
name = normalizedName; // use normalized name if it's not a static analyzer
|
||||
}
|
||||
|
||||
auto entry = emplace(name, type, properties,
|
||||
false); // do not persist since this config is already
|
||||
// coming from the persisted store
|
||||
|
@ -1489,11 +1411,6 @@ bool IResearchAnalyzerFeature::loadConfiguration() {
|
|||
auto split = splitAnalyzerName(name);
|
||||
|
||||
if (expandVocbasePrefix) {
|
||||
// FIXME TODO remove temporary workaround once emplace(...) and all tests are updated
|
||||
if (split.first.null()) {
|
||||
return split.second;
|
||||
}
|
||||
|
||||
if (split.first.null()) {
|
||||
return std::string(activeVocbase.name()).append(2, ANALYZER_PREFIX_DELIM).append(split.second);
|
||||
}
|
||||
|
@ -1525,6 +1442,170 @@ void IResearchAnalyzerFeature::prepare() {
|
|||
::iresearch::analysis::analyzers::init();
|
||||
}
|
||||
|
||||
arangodb::Result IResearchAnalyzerFeature::remove( // remove analyzer
|
||||
irs::string_ref const& name, // analyzer name
|
||||
bool force /*= false*/ // force removal
|
||||
) {
|
||||
try {
|
||||
auto split = splitAnalyzerName(name);
|
||||
|
||||
if (split.first.null()) {
|
||||
return arangodb::Result( // result
|
||||
TRI_ERROR_FORBIDDEN, // code
|
||||
"static analyzers cannot be removed" // message
|
||||
);
|
||||
}
|
||||
|
||||
WriteMutex mutex(_mutex);
|
||||
SCOPED_LOCK(mutex);
|
||||
|
||||
auto itr = // find analyzer
|
||||
_analyzers.find(irs::make_hashed_ref(name, std::hash<irs::string_ref>()));
|
||||
|
||||
if (itr == _analyzers.end()) {
|
||||
return arangodb::Result( // result
|
||||
TRI_ERROR_ARANGO_DOCUMENT_NOT_FOUND, // code
|
||||
std::string("failure to find analyzer while removing arangosearch analyzer '") + std::string(name)+ "'"
|
||||
);
|
||||
}
|
||||
|
||||
auto& pool = itr->second;
|
||||
|
||||
// this should never happen since analyzers should always be valid, but this
|
||||
// will make the state consistent again
|
||||
if (!pool) {
|
||||
_analyzers.erase(itr);
|
||||
|
||||
return arangodb::Result( // result
|
||||
TRI_ERROR_ARANGO_DOCUMENT_NOT_FOUND, // code
|
||||
std::string("failure to find a valid analyzer while removing arangosearch analyzer '") + std::string(name)+ "'"
|
||||
);
|
||||
}
|
||||
|
||||
if (!force && pool.use_count() > 1) { // +1 for ref in '_analyzers'
|
||||
return arangodb::Result( // result
|
||||
TRI_ERROR_FORBIDDEN, // code
|
||||
std::string("analyzer in-use while removing arangosearch analyzer '") + std::string(name)+ "'"
|
||||
);
|
||||
}
|
||||
|
||||
// on db-server analyzers are not persisted
|
||||
// allow removal even inRecovery()
|
||||
if (arangodb::ServerState::instance()->isDBServer()) {
|
||||
_analyzers.erase(itr);
|
||||
|
||||
return arangodb::Result();
|
||||
}
|
||||
|
||||
// .........................................................................
|
||||
// after here the analyzer must be removed from the persisted store first
|
||||
// .........................................................................
|
||||
|
||||
// this should never happen since non-static analyzers should always have a
|
||||
// valid '_key' after
|
||||
if (pool->_key.null()) {
|
||||
return arangodb::Result( // result
|
||||
TRI_ERROR_INTERNAL, // code
|
||||
std::string("failure to find '") + arangodb::StaticStrings::KeyString + "' while removing arangosearch analyzer '" + std::string(name)+ "'"
|
||||
);
|
||||
}
|
||||
|
||||
auto* engine = arangodb::EngineSelectorFeature::ENGINE;
|
||||
|
||||
// do not allow persistence while in recovery
|
||||
if (engine && engine->inRecovery()) {
|
||||
return arangodb::Result( // result
|
||||
TRI_ERROR_INTERNAL, // code
|
||||
std::string("failure to remove arangosearch analyzer '") + std::string(name)+ "' configuration while storage engine in recovery"
|
||||
);
|
||||
}
|
||||
|
||||
auto* dbFeature = arangodb::application_features::ApplicationServer::lookupFeature< // find feature
|
||||
arangodb::DatabaseFeature // feature type
|
||||
>("Database");
|
||||
|
||||
if (!dbFeature) {
|
||||
return arangodb::Result( // result
|
||||
TRI_ERROR_INTERNAL, // code
|
||||
std::string("failure to find feature 'Database' while removing arangosearch analyzer '") + std::string(name)+ "'"
|
||||
);
|
||||
}
|
||||
|
||||
auto* vocbase = dbFeature->useDatabase(split.first);
|
||||
|
||||
if (!vocbase) {
|
||||
return arangodb::Result( // result
|
||||
TRI_ERROR_ARANGO_DOCUMENT_NOT_FOUND, // code
|
||||
std::string("failure to find vocbase while removing arangosearch analyzer '") + std::string(name)+ "'"
|
||||
);
|
||||
}
|
||||
|
||||
std::shared_ptr<arangodb::LogicalCollection> collection;
|
||||
auto collectionCallback = [&collection]( // store collection
|
||||
std::shared_ptr<arangodb::LogicalCollection> const& col // args
|
||||
)->void {
|
||||
collection = col;
|
||||
};
|
||||
|
||||
arangodb::methods::Collections::lookup( // find collection
|
||||
*vocbase, ANALYZER_COLLECTION_NAME, collectionCallback // args
|
||||
);
|
||||
|
||||
if (!collection) {
|
||||
return arangodb::Result( // result
|
||||
TRI_ERROR_ARANGO_DATA_SOURCE_NOT_FOUND, // code
|
||||
std::string("failure to find collection while removing arangosearch analyzer '") + std::string(name)+ "'"
|
||||
);
|
||||
}
|
||||
|
||||
arangodb::SingleCollectionTransaction trx( // transaction
|
||||
arangodb::transaction::StandaloneContext::Create(*vocbase), // transaction context
|
||||
ANALYZER_COLLECTION_NAME, // collection name
|
||||
arangodb::AccessMode::Type::WRITE // collection access type
|
||||
);
|
||||
auto res = trx.begin();
|
||||
|
||||
if (!res.ok()) {
|
||||
return res;
|
||||
}
|
||||
|
||||
arangodb::velocypack::Builder builder;
|
||||
arangodb::OperationOptions options;
|
||||
|
||||
builder.openObject();
|
||||
builder.add(arangodb::StaticStrings::KeyString, toValuePair(pool->_key));
|
||||
builder.close();
|
||||
|
||||
auto result = // remove
|
||||
trx.remove(ANALYZER_COLLECTION_NAME, builder.slice(), options);
|
||||
|
||||
if (!result.ok()) {
|
||||
trx.abort();
|
||||
|
||||
return result.result;
|
||||
}
|
||||
|
||||
_analyzers.erase(itr);
|
||||
} catch (arangodb::basics::Exception const& e) {
|
||||
return arangodb::Result( // result
|
||||
e.code(), // code
|
||||
std::string("caught exception while removing configuration for arangosearch analyzer name '") + std::string(name) + "': " + std::to_string(e.code()) + " "+ e.what()
|
||||
);
|
||||
} catch (std::exception const& e) {
|
||||
return arangodb::Result( // result
|
||||
TRI_ERROR_INTERNAL, // code
|
||||
std::string("caught exception while removing configuration for arangosearch analyzer name '") + std::string(name) + "': " + e.what()
|
||||
);
|
||||
} catch (...) {
|
||||
return arangodb::Result( // result
|
||||
TRI_ERROR_INTERNAL, // code
|
||||
std::string("caught exception while removing configuration for arangosearch analyzer name '") + std::string(name) + "'"
|
||||
);
|
||||
}
|
||||
|
||||
return arangodb::Result();
|
||||
}
|
||||
|
||||
void IResearchAnalyzerFeature::start() {
|
||||
ApplicationFeature::start();
|
||||
|
||||
|
@ -1542,9 +1623,9 @@ void IResearchAnalyzerFeature::start() {
|
|||
"IResearch functions";
|
||||
}
|
||||
}
|
||||
|
||||
/*FIXME TODO disable until V8 handler is implemented for JavaScript tests
|
||||
registerUpgradeTasks(); // register tasks after UpgradeFeature::prepare() has finished
|
||||
|
||||
*/
|
||||
// ensure that the configuration collection is present before loading
|
||||
// configuration for the case of inRecovery() if there is no collection then
|
||||
// obviously no custom analyzer configurations were persisted (so missing
|
||||
|
@ -1752,8 +1833,6 @@ arangodb::Result IResearchAnalyzerFeature::storeAnalyzer(AnalyzerPool& pool) {
|
|||
builder.add("name", toValuePair(split.second));
|
||||
builder.add("type", toValuePair(pool.type()));
|
||||
|
||||
// do not allow to pass null properties since it causes undefined behavior
|
||||
// in `arangodb::velocypack::Builder`
|
||||
if (pool.properties().null()) {
|
||||
builder.add( // add value
|
||||
"properties", // name
|
||||
|
@ -1763,6 +1842,35 @@ arangodb::Result IResearchAnalyzerFeature::storeAnalyzer(AnalyzerPool& pool) {
|
|||
builder.add("properties", toValuePair(pool.properties()));
|
||||
}
|
||||
|
||||
// only add features if there are present
|
||||
if (!pool.features().empty()) {
|
||||
builder.add( // add array
|
||||
"features", // name
|
||||
arangodb::velocypack::Value(arangodb::velocypack::ValueType::Array) // value
|
||||
);
|
||||
|
||||
for (auto& feature: pool.features()) {
|
||||
// this should never happen since irs::flags currently provides no way
|
||||
// to set nullptr
|
||||
if (!feature) {
|
||||
return arangodb::Result( // result
|
||||
TRI_ERROR_INTERNAL, // code
|
||||
std::string("failure to to add null feature persising arangosearch analyzer '") + pool.name()+ "'"
|
||||
);
|
||||
}
|
||||
|
||||
if (feature->name().null()) {
|
||||
builder.add( // add value
|
||||
arangodb::velocypack::Value(arangodb::velocypack::ValueType::Null) // value
|
||||
);
|
||||
} else {
|
||||
builder.add(toValuePair(feature->name()));
|
||||
}
|
||||
}
|
||||
|
||||
builder.close();
|
||||
}
|
||||
|
||||
builder.close();
|
||||
options.waitForSync = true;
|
||||
|
||||
|
|
|
@ -150,14 +150,9 @@ class IResearchAnalyzerFeature final : public arangodb::application_features::Ap
|
|||
// FIXME TODO remove
|
||||
AnalyzerPool::ptr ensure(irs::string_ref const& name);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @return number of analyzers removed
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
size_t erase(irs::string_ref const& name) noexcept;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief find analyzer
|
||||
/// @param name analyzer name (used verbatim)
|
||||
/// @param name analyzer name (already normalized)
|
||||
/// @return analyzer with the specified name or nullptr
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
AnalyzerPool::ptr get(irs::string_ref const& name) const noexcept;
|
||||
|
@ -193,6 +188,14 @@ class IResearchAnalyzerFeature final : public arangodb::application_features::Ap
|
|||
);
|
||||
|
||||
void prepare() override;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief remove the specified analyzer
|
||||
/// @param name analyzer name (already normalized)
|
||||
/// @param force remove even if the analyzer is actively referenced
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
arangodb::Result remove(irs::string_ref const& name, bool force = false);
|
||||
|
||||
void start() override;
|
||||
void stop() override;
|
||||
|
||||
|
|
|
@ -1149,7 +1149,22 @@ bool fromFuncAnalyzer(irs::boolean_filter* filter, QueryContext const& ctx,
|
|||
return false;
|
||||
}
|
||||
|
||||
analyzer = analyzerFeature->get(analyzerIdValue);
|
||||
if (ctx.trx) {
|
||||
auto* sysDatabase = arangodb::application_features::ApplicationServer::lookupFeature< // find feature
|
||||
arangodb::SystemDatabaseFeature // featue type
|
||||
>();
|
||||
auto sysVocbase = sysDatabase ? sysDatabase->use() : nullptr;
|
||||
|
||||
if (sysVocbase) {
|
||||
analyzer = analyzerFeature->get( // get analyzer
|
||||
arangodb::iresearch::IResearchAnalyzerFeature::normalize( // normalize
|
||||
analyzerIdValue, ctx.trx->vocbase(), *sysVocbase // args
|
||||
)
|
||||
);
|
||||
}
|
||||
} else {
|
||||
analyzer = analyzerFeature->get(analyzerIdValue); // verbatim
|
||||
}
|
||||
|
||||
if (!analyzer) {
|
||||
LOG_TOPIC("404c9", WARN, arangodb::iresearch::TOPIC)
|
||||
|
|
|
@ -653,55 +653,56 @@ namespace iresearch {
|
|||
return LINK_TYPE;
|
||||
}
|
||||
|
||||
/*static*/ arangodb::Result IResearchLinkHelper::validateLinks(
|
||||
TRI_vocbase_t& vocbase, arangodb::velocypack::Slice const& links) {
|
||||
/*static*/ arangodb::Result IResearchLinkHelper::validateLinks( // validate
|
||||
TRI_vocbase_t& vocbase, // vocbase
|
||||
arangodb::velocypack::Slice const& links // link definitions
|
||||
) {
|
||||
if (!links.isObject()) {
|
||||
return arangodb::Result(
|
||||
TRI_ERROR_BAD_PARAMETER,
|
||||
std::string("while validating arangosearch link definition, error: "
|
||||
"definition is not an object"));
|
||||
return arangodb::Result( // result
|
||||
TRI_ERROR_BAD_PARAMETER, // code
|
||||
std::string("while validating arangosearch link definition, error: definition is not an object")
|
||||
);
|
||||
}
|
||||
|
||||
size_t offset = 0;
|
||||
arangodb::CollectionNameResolver resolver(vocbase);
|
||||
|
||||
for (arangodb::velocypack::ObjectIterator itr(links); itr.valid(); ++itr, ++offset) {
|
||||
for (arangodb::velocypack::ObjectIterator itr(links); // setup
|
||||
itr.valid(); // condition
|
||||
++itr, ++offset // step
|
||||
) {
|
||||
auto collectionName = itr.key();
|
||||
auto linkDefinition = itr.value();
|
||||
|
||||
if (!collectionName.isString()) {
|
||||
return arangodb::Result(
|
||||
TRI_ERROR_BAD_PARAMETER,
|
||||
std::string("while validating arangosearch link definition, error: "
|
||||
"collection at offset ") +
|
||||
std::to_string(offset) + " is not a string");
|
||||
return arangodb::Result( // result
|
||||
TRI_ERROR_BAD_PARAMETER, // code
|
||||
std::string("while validating arangosearch link definition, error: collection at offset ") + std::to_string(offset) + " is not a string"
|
||||
);
|
||||
}
|
||||
|
||||
auto collection = resolver.getCollection(collectionName.copyString());
|
||||
|
||||
if (!collection) {
|
||||
return arangodb::Result(TRI_ERROR_ARANGO_DATA_SOURCE_NOT_FOUND,
|
||||
std::string("while validating arangosearch link "
|
||||
"definition, error: collection '") +
|
||||
collectionName.copyString() + "' not found");
|
||||
return arangodb::Result( // result
|
||||
TRI_ERROR_ARANGO_DATA_SOURCE_NOT_FOUND, // code
|
||||
std::string("while validating arangosearch link definition, error: collection '") + collectionName.copyString() + "' not found"
|
||||
);
|
||||
}
|
||||
|
||||
// check link auth as per https://github.com/arangodb/backlog/issues/459
|
||||
if (arangodb::ExecContext::CURRENT &&
|
||||
!arangodb::ExecContext::CURRENT->canUseCollection(vocbase.name(),
|
||||
collection->name(),
|
||||
arangodb::auth::Level::RO)) {
|
||||
return arangodb::Result(TRI_ERROR_FORBIDDEN,
|
||||
std::string("while validating arangosearch link "
|
||||
"definition, error: collection '") +
|
||||
collectionName.copyString() +
|
||||
"' not authorized for read access");
|
||||
if (arangodb::ExecContext::CURRENT // have context
|
||||
&& !arangodb::ExecContext::CURRENT->canUseCollection(vocbase.name(), collection->name(), arangodb::auth::Level::RO)) {
|
||||
return arangodb::Result( // result
|
||||
TRI_ERROR_FORBIDDEN, // code
|
||||
std::string("while validating arangosearch link definition, error: collection '") + collectionName.copyString() + "' not authorized for read access"
|
||||
);
|
||||
}
|
||||
|
||||
IResearchLinkMeta meta;
|
||||
std::string errorField;
|
||||
|
||||
if (!linkDefinition.isNull() && !meta.init(linkDefinition, errorField)) { // for db-server analyzer validation should have already apssed on coordinator
|
||||
if (!linkDefinition.isNull() && !meta.init(linkDefinition, errorField, &vocbase)) { // for db-server analyzer validation should have already apssed on coordinator
|
||||
return arangodb::Result( // result
|
||||
TRI_ERROR_BAD_PARAMETER, // code
|
||||
errorField.empty()
|
||||
|
|
|
@ -53,7 +53,7 @@ std::string ensureGuid(std::string&& guid, TRI_voc_cid_t id, TRI_voc_cid_t planI
|
|||
// id numbers can also not conflict, first character is always 'h'
|
||||
if (arangodb::ServerState::instance()->isCoordinator() ||
|
||||
arangodb::ServerState::instance()->isDBServer()) {
|
||||
TRI_ASSERT(planId);
|
||||
TRI_ASSERT(planId); // ensured by LogicalDataSource constructor + '_id' != 0
|
||||
guid.append("c");
|
||||
guid.append(std::to_string(planId));
|
||||
guid.push_back('/');
|
||||
|
@ -65,9 +65,9 @@ std::string ensureGuid(std::string&& guid, TRI_voc_cid_t id, TRI_voc_cid_t planI
|
|||
} else if (isSystem) {
|
||||
guid.append(name);
|
||||
} else {
|
||||
TRI_ASSERT(id); // ensured by ensureId(...)
|
||||
char buf[sizeof(TRI_server_id_t) * 2 + 1];
|
||||
auto len = TRI_StringUInt64HexInPlace(arangodb::ServerIdFeature::getId(), buf);
|
||||
TRI_ASSERT(id);
|
||||
guid.append("h");
|
||||
guid.append(buf, len);
|
||||
TRI_ASSERT(guid.size() > 3);
|
||||
|
@ -83,14 +83,31 @@ TRI_voc_cid_t ensureId(TRI_voc_cid_t id) {
|
|||
return id;
|
||||
}
|
||||
|
||||
if (arangodb::ServerState::instance()->isCoordinator() ||
|
||||
arangodb::ServerState::instance()->isDBServer()) {
|
||||
auto* ci = arangodb::ClusterInfo::instance();
|
||||
|
||||
return ci ? ci->uniqid(1) : 0;
|
||||
if (!arangodb::ServerState::instance()->isCoordinator() // not coordinator
|
||||
&& !arangodb::ServerState::instance()->isDBServer() // not db-server
|
||||
) {
|
||||
return TRI_NewTickServer();
|
||||
}
|
||||
|
||||
return TRI_NewTickServer();
|
||||
auto* ci = arangodb::ClusterInfo::instance();
|
||||
|
||||
if (!ci) {
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE( // exception
|
||||
TRI_ERROR_INTERNAL, // code
|
||||
"failure to find 'ClusterInfo' instance while generating LogicalDataSource ID" // message
|
||||
);
|
||||
}
|
||||
|
||||
id = ci->uniqid(1);
|
||||
|
||||
if (!id) {
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE( // exception
|
||||
TRI_ERROR_INTERNAL, // code
|
||||
"invalid zero value returned for uniqueid by 'ClusterInfo' while generating LogicalDataSource ID" // message
|
||||
);
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
bool readIsSystem(arangodb::velocypack::Slice definition) {
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -84,7 +84,7 @@ class EmptyAnalyzer: public irs::analysis::analyzer {
|
|||
|
||||
private:
|
||||
irs::attribute_view _attrs;
|
||||
TestAttribute _attr;
|
||||
irs::frequency _attr;
|
||||
};
|
||||
|
||||
DEFINE_ANALYZER_TYPE_NAMED(EmptyAnalyzer, "iresearch-document-empty");
|
||||
|
@ -177,8 +177,8 @@ struct IResearchDocumentSetup {
|
|||
// ensure that there will be no exception on 'emplace'
|
||||
InvalidAnalyzer::returnNullFromMake = false;
|
||||
|
||||
analyzers->emplace(result, "iresearch-document-empty", "iresearch-document-empty", "en", irs::flags{ TestAttribute::type() }); // cache analyzer
|
||||
analyzers->emplace(result, "iresearch-document-invalid", "iresearch-document-invalid", "en", irs::flags{ TestAttribute::type() }); // cache analyzer
|
||||
analyzers->emplace(result, "iresearch-document-empty", "iresearch-document-empty", "en", irs::flags{ irs::frequency::type() }); // cache analyzer
|
||||
analyzers->emplace(result, "iresearch-document-invalid", "iresearch-document-invalid", "en", irs::flags{ irs::frequency::type() }); // cache analyzer
|
||||
|
||||
// suppress log messages since tests check error conditions
|
||||
arangodb::LogTopic::setLogLevel(arangodb::iresearch::TOPIC.name(), arangodb::LogLevel::FATAL);
|
||||
|
@ -710,7 +710,7 @@ SECTION("FieldIterator_traverse_complex_object_ordered_check_value_types") {
|
|||
auto const expected_analyzer = irs::analysis::analyzers::get("iresearch-document-empty", irs::text_format::json, "en");
|
||||
auto& analyzer = dynamic_cast<EmptyAnalyzer&>(field.get_tokens());
|
||||
CHECK(&expected_analyzer->type() == &analyzer.type());
|
||||
CHECK(irs::flags({TestAttribute::type()}) == field.features());
|
||||
CHECK(irs::flags({irs::frequency::type()}) == field.features());
|
||||
}
|
||||
|
||||
++it;
|
||||
|
@ -1385,15 +1385,15 @@ SECTION("FieldIterator_nullptr_analyzer") {
|
|||
InvalidAnalyzer::returnNullFromMake = false;
|
||||
|
||||
analyzers.start();
|
||||
analyzers.erase("empty");
|
||||
analyzers.erase("invalid");
|
||||
analyzers.remove("empty");
|
||||
analyzers.remove("invalid");
|
||||
|
||||
// ensure that there will be no exception on 'emplace'
|
||||
InvalidAnalyzer::returnNullFromMake = false;
|
||||
|
||||
arangodb::iresearch::IResearchAnalyzerFeature::EmplaceResult result;
|
||||
analyzers.emplace(result, "empty", "iresearch-document-empty", "en", irs::flags{TestAttribute::type()});
|
||||
analyzers.emplace(result, "invalid", "iresearch-document-invalid", "en", irs::flags{TestAttribute::type()});
|
||||
analyzers.emplace(result, "empty", "iresearch-document-empty", "en", irs::flags{irs::frequency::type()});
|
||||
analyzers.emplace(result, "invalid", "iresearch-document-invalid", "en", irs::flags{irs::frequency::type()});
|
||||
}
|
||||
|
||||
// last analyzer invalid
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include "Aql/ExecutionPlan.h"
|
||||
#include "Aql/ExpressionContext.h"
|
||||
#include "Aql/Query.h"
|
||||
#include "Cluster/ClusterFeature.h"
|
||||
#include "GeneralServer/AuthenticationFeature.h"
|
||||
#include "IResearch/IResearchCommon.h"
|
||||
#include "IResearch/IResearchFeature.h"
|
||||
|
@ -54,6 +55,7 @@
|
|||
#include "RestServer/ViewTypesFeature.h"
|
||||
#include "StorageEngine/EngineSelectorFeature.h"
|
||||
#include "Transaction/StandaloneContext.h"
|
||||
#include "V8Server/V8DealerFeature.h"
|
||||
|
||||
#include "analysis/analyzers.hpp"
|
||||
#include "analysis/token_streams.hpp"
|
||||
|
@ -71,13 +73,12 @@
|
|||
// --SECTION-- setup / tear-down
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
struct IResearchFilterSetup {
|
||||
struct IResearchFilterBooleanSetup {
|
||||
StorageEngineMock engine;
|
||||
arangodb::application_features::ApplicationServer server;
|
||||
std::unique_ptr<TRI_vocbase_t> system;
|
||||
std::vector<std::pair<arangodb::application_features::ApplicationFeature*, bool>> features;
|
||||
|
||||
IResearchFilterSetup(): engine(server), server(nullptr, nullptr) {
|
||||
IResearchFilterBooleanSetup(): engine(server), server(nullptr, nullptr) {
|
||||
arangodb::EngineSelectorFeature::ENGINE = &engine;
|
||||
arangodb::aql::AqlFunctionFeature* functions = nullptr;
|
||||
|
||||
|
@ -86,14 +87,18 @@ struct IResearchFilterSetup {
|
|||
// suppress INFO {authentication} Authentication is turned on (system only), authentication for unix sockets is turned on
|
||||
arangodb::LogTopic::setLogLevel(arangodb::Logger::AUTHENTICATION.name(), arangodb::LogLevel::WARN);
|
||||
|
||||
// suppress log messages since tests check error conditions
|
||||
arangodb::LogTopic::setLogLevel(arangodb::iresearch::TOPIC.name(), arangodb::LogLevel::FATAL);
|
||||
irs::logger::output_le(iresearch::logger::IRL_FATAL, stderr);
|
||||
|
||||
// setup required application features
|
||||
features.emplace_back(new arangodb::AuthenticationFeature(server), true);
|
||||
features.emplace_back(new arangodb::DatabaseFeature(server), false);
|
||||
features.emplace_back(new arangodb::QueryRegistryFeature(server), false); // must be first
|
||||
arangodb::application_features::ApplicationServer::server->addFeature(features.back().first); // need QueryRegistryFeature feature to be added now in order to create the system database
|
||||
system = irs::memory::make_unique<TRI_vocbase_t>(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 0, TRI_VOC_SYSTEM_DATABASE);
|
||||
features.emplace_back(new arangodb::SystemDatabaseFeature(server, system.get()), false); // required for IResearchAnalyzerFeature
|
||||
features.emplace_back(new arangodb::SystemDatabaseFeature(server), true); // required for IResearchAnalyzerFeature
|
||||
features.emplace_back(new arangodb::TraverserEngineRegistryFeature(server), false); // must be before AqlFeature
|
||||
features.emplace_back(new arangodb::V8DealerFeature(server), false); // required for DatabaseFeature::createDatabase(...)
|
||||
features.emplace_back(new arangodb::ViewTypesFeature(server), false); // required for IResearchFeature
|
||||
features.emplace_back(new arangodb::AqlFeature(server), true);
|
||||
features.emplace_back(functions = new arangodb::aql::AqlFunctionFeature(server), true); // required for IResearchAnalyzerFeature
|
||||
|
@ -104,6 +109,11 @@ struct IResearchFilterSetup {
|
|||
features.emplace_back(new arangodb::LdapFeature(server), false); // required for AuthenticationFeature with USE_ENTERPRISE
|
||||
#endif
|
||||
|
||||
// required for V8DealerFeature::prepare(), ClusterFeature::prepare() not required
|
||||
arangodb::application_features::ApplicationServer::server->addFeature(
|
||||
new arangodb::ClusterFeature(server)
|
||||
);
|
||||
|
||||
for (auto& f : features) {
|
||||
arangodb::application_features::ApplicationServer::server->addFeature(f.first);
|
||||
}
|
||||
|
@ -112,6 +122,12 @@ struct IResearchFilterSetup {
|
|||
f.first->prepare();
|
||||
}
|
||||
|
||||
auto const databases = arangodb::velocypack::Parser::fromJson(std::string("[ { \"name\": \"") + arangodb::StaticStrings::SystemDatabase + "\" } ]");
|
||||
auto* dbFeature = arangodb::application_features::ApplicationServer::lookupFeature<
|
||||
arangodb::DatabaseFeature
|
||||
>("Database");
|
||||
dbFeature->loadDatabases(databases->slice());
|
||||
|
||||
for (auto& f : features) {
|
||||
if (f.second) {
|
||||
f.first->start();
|
||||
|
@ -146,17 +162,20 @@ struct IResearchFilterSetup {
|
|||
return params[0];
|
||||
}});
|
||||
|
||||
// suppress log messages since tests check error conditions
|
||||
arangodb::LogTopic::setLogLevel(arangodb::iresearch::TOPIC.name(), arangodb::LogLevel::FATAL);
|
||||
irs::logger::output_le(iresearch::logger::IRL_FATAL, stderr);
|
||||
auto* analyzers = arangodb::application_features::ApplicationServer::lookupFeature<
|
||||
arangodb::iresearch::IResearchAnalyzerFeature
|
||||
>();
|
||||
arangodb::iresearch::IResearchAnalyzerFeature::EmplaceResult result;
|
||||
TRI_vocbase_t* vocbase;
|
||||
|
||||
dbFeature->createDatabase(1, "testVocbase", vocbase); // required for IResearchAnalyzerFeature::emplace(...)
|
||||
analyzers->emplace(result, "testVocbase::test_analyzer", "TestAnalyzer", "abc"); // cache analyzer
|
||||
}
|
||||
|
||||
~IResearchFilterSetup() {
|
||||
system.reset(); // destroy before reseting the 'ENGINE'
|
||||
~IResearchFilterBooleanSetup() {
|
||||
arangodb::AqlFeature(server).stop(); // unset singleton instance
|
||||
arangodb::LogTopic::setLogLevel(arangodb::iresearch::TOPIC.name(), arangodb::LogLevel::DEFAULT);
|
||||
arangodb::application_features::ApplicationServer::server = nullptr;
|
||||
arangodb::EngineSelectorFeature::ENGINE = nullptr;
|
||||
|
||||
// destroy application features
|
||||
for (auto& f : features) {
|
||||
|
@ -170,6 +189,7 @@ struct IResearchFilterSetup {
|
|||
}
|
||||
|
||||
arangodb::LogTopic::setLogLevel(arangodb::Logger::AUTHENTICATION.name(), arangodb::LogLevel::DEFAULT);
|
||||
arangodb::EngineSelectorFeature::ENGINE = nullptr;
|
||||
}
|
||||
}; // IResearchFilterSetup
|
||||
|
||||
|
@ -182,7 +202,7 @@ struct IResearchFilterSetup {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TEST_CASE("IResearchFilterBooleanTest", "[iresearch][iresearch-filter]") {
|
||||
IResearchFilterSetup s;
|
||||
IResearchFilterBooleanSetup s;
|
||||
UNUSED(s);
|
||||
|
||||
SECTION("Ternary") {
|
||||
|
@ -307,7 +327,7 @@ SECTION("UnaryNot") {
|
|||
auto& root = expected.add<irs::Not>();
|
||||
root.boost(2.5);
|
||||
root.filter<irs::And>()
|
||||
.add<irs::by_term>().field(mangleString("a.b[42].c", "test_analyzer")).term("1");
|
||||
.add<irs::by_term>().field(mangleString("a.b[42].c", "testVocbase::test_analyzer")).term("1");
|
||||
|
||||
assertFilterSuccess("FOR d IN collection FILTER analyzer(BOOST(not (d.a.b[42].c == '1'), 2.5), 'test_analyzer') RETURN d", expected);
|
||||
assertFilterSuccess("FOR d IN collection FILTER analyzer(boost(not (d['a']['b'][42]['c'] == '1'), 2.5), 'test_analyzer') RETURN d", expected);
|
||||
|
@ -349,7 +369,7 @@ SECTION("UnaryNot") {
|
|||
irs::Or expected;
|
||||
expected.add<irs::Not>()
|
||||
.filter<irs::And>()
|
||||
.add<irs::by_term>().field(mangleString("a.b[23].c", "test_analyzer")).term("42");
|
||||
.add<irs::by_term>().field(mangleString("a.b[23].c", "testVocbase::test_analyzer")).term("42");
|
||||
|
||||
assertFilterSuccess("LET c=41 FOR d IN collection FILTER ANALYZER(not (d.a.b[23].c == TO_STRING(c+1)), 'test_analyzer') RETURN d", expected, &ctx);
|
||||
assertFilterSuccess("LET c=41 FOR d IN collection FILTER ANALYZER(not (d.a['b'][23].c == TO_STRING(c+1)), 'test_analyzer') RETURN d", expected, &ctx);
|
||||
|
@ -1388,9 +1408,9 @@ SECTION("BinaryOr") {
|
|||
irs::Or expected;
|
||||
auto& root = expected.add<irs::Or>();
|
||||
root.add<irs::by_range>()
|
||||
.field(mangleString("a.b.c", "test_analyzer"))
|
||||
.field(mangleString("a.b.c", "testVocbase::test_analyzer"))
|
||||
.include<irs::Bound::MAX>(false).term<irs::Bound::MAX>("1");
|
||||
root.add<irs::by_term>().field(mangleString("c.b.a", "test_analyzer")).term("2");
|
||||
root.add<irs::by_term>().field(mangleString("c.b.a", "testVocbase::test_analyzer")).term("2");
|
||||
|
||||
assertFilterSuccess("FOR d IN collection FILTER analyzer(d.a.b.c < '1' or d.c.b.a == '2', 'test_analyzer') RETURN d", expected);
|
||||
assertFilterSuccess("FOR d IN collection FILTER analyzer(d['a']['b']['c'] < '1', 'test_analyzer') or analyzER(d.c.b.a == '2', 'test_analyzer') RETURN d", expected);
|
||||
|
@ -1405,9 +1425,9 @@ SECTION("BinaryOr") {
|
|||
auto& root = expected.add<irs::Or>();
|
||||
root.boost(0.5);
|
||||
root.add<irs::by_range>()
|
||||
.field(mangleString("a.b.c", "test_analyzer"))
|
||||
.field(mangleString("a.b.c", "testVocbase::test_analyzer"))
|
||||
.include<irs::Bound::MAX>(false).term<irs::Bound::MAX>("1");
|
||||
root.add<irs::by_term>().field(mangleString("c.b.a", "test_analyzer")).term("2");
|
||||
root.add<irs::by_term>().field(mangleString("c.b.a", "testVocbase::test_analyzer")).term("2");
|
||||
|
||||
assertFilterSuccess("FOR d IN collection FILTER boost(analyzer(d.a.b.c < '1' or d.c.b.a == '2', 'test_analyzer'), 0.5) RETURN d", expected);
|
||||
assertFilterSuccess("FOR d IN collection FILTER analyzer(boost(d.a.b.c < '1' or d.c.b.a == '2', 0.5), 'test_analyzer') RETURN d", expected);
|
||||
|
@ -1419,7 +1439,7 @@ SECTION("BinaryOr") {
|
|||
auto& root = expected.add<irs::Or>();
|
||||
root.boost(0.5);
|
||||
root.add<irs::by_range>()
|
||||
.field(mangleString("a.b.c", "test_analyzer"))
|
||||
.field(mangleString("a.b.c", "testVocbase::test_analyzer"))
|
||||
.include<irs::Bound::MAX>(false).term<irs::Bound::MAX>("1").boost(2.5);
|
||||
root.add<irs::by_term>().field(mangleStringIdentity("c.b.a")).term("2");
|
||||
|
||||
|
@ -1447,9 +1467,9 @@ SECTION("BinaryOr") {
|
|||
auto& root = expected.add<irs::Or>();
|
||||
root.boost(2.5);
|
||||
auto& subRoot = root.add<irs::Or>();
|
||||
subRoot.add<irs::by_term>().field(mangleString("a", "test_analyzer")).term("1").boost(0.5);
|
||||
subRoot.add<irs::by_term>().field(mangleString("a", "testVocbase::test_analyzer")).term("1").boost(0.5);
|
||||
subRoot.add<irs::by_term>().field(mangleStringIdentity("a")).term("2");
|
||||
root.add<irs::Not>().filter<irs::by_term>().field(mangleString("b", "test_analyzer")).term("3").boost(1.5);
|
||||
root.add<irs::Not>().filter<irs::by_term>().field(mangleString("b", "testVocbase::test_analyzer")).term("3").boost(1.5);
|
||||
|
||||
assertFilterSuccess("FOR d IN collection FILTER boost(analyzer(analyzer(boost(d.a == '1', 0.5), 'test_analyzer') or analyzer('2' == d.a, 'identity') or boost(d.b != '3', 1.5), 'test_analyzer'), 2.5) RETURN d", expected);
|
||||
assertFilterSuccess("FOR d IN collection FILTER boost(analyzer(boost(d['a'] == '1', 0.5), 'test_analyzer') or '2' == d['a'] or boost(analyzer(d.b != '3', 'test_analyzer'), 1.5), 2.5) RETURN d", expected);
|
||||
|
@ -1935,7 +1955,7 @@ SECTION("BinaryAnd") {
|
|||
auto& root = expected.add<irs::And>();
|
||||
root.boost(0.5);
|
||||
root.add<irs::by_range>()
|
||||
.field(mangleString("a.b.c", "test_analyzer"))
|
||||
.field(mangleString("a.b.c", "testVocbase::test_analyzer"))
|
||||
.include<irs::Bound::MAX>(false).term<irs::Bound::MAX>("1");
|
||||
root.add<irs::by_term>().field(mangleStringIdentity("c.b.a")).term("2");
|
||||
|
||||
|
@ -1947,7 +1967,7 @@ SECTION("BinaryAnd") {
|
|||
irs::Or expected;
|
||||
auto& root = expected.add<irs::And>();
|
||||
root.add<irs::by_range>()
|
||||
.field(mangleString("a.b.c", "test_analyzer"))
|
||||
.field(mangleString("a.b.c", "testVocbase::test_analyzer"))
|
||||
.include<irs::Bound::MAX>(false).term<irs::Bound::MAX>("1").boost(0.5);
|
||||
root.add<irs::by_term>().field(mangleStringIdentity("c.b.a")).term("2").boost(0.5);
|
||||
|
||||
|
@ -1985,7 +2005,7 @@ SECTION("BinaryAnd") {
|
|||
.include<irs::Bound::MAX>(false).term<irs::Bound::MAX>("1");
|
||||
root.add<irs::Not>()
|
||||
.filter<irs::And>()
|
||||
.add<irs::by_term>().field(mangleString("c.b.a", "test_analyzer")).term("2");
|
||||
.add<irs::by_term>().field(mangleString("c.b.a", "testVocbase::test_analyzer")).term("2");
|
||||
|
||||
assertFilterSuccess("FOR d IN collection FILTER boost(d.a.b.c < '1' and not analyzer(d.c.b.a == '2', 'test_analyzer'), 0.5) RETURN d", expected);
|
||||
}
|
||||
|
@ -1999,7 +2019,7 @@ SECTION("BinaryAnd") {
|
|||
.include<irs::Bound::MAX>(false).term<irs::Bound::MAX>("1");
|
||||
root.add<irs::Not>()
|
||||
.filter<irs::And>()
|
||||
.add<irs::by_term>().field(mangleString("c.b.a", "test_analyzer")).term("2").boost(0.5);
|
||||
.add<irs::by_term>().field(mangleString("c.b.a", "testVocbase::test_analyzer")).term("2").boost(0.5);
|
||||
|
||||
assertFilterSuccess("FOR d IN collection FILTER d.a.b.c < '1' and not boost(analyzer(d.c.b.a == '2', 'test_analyzer'), 0.5) RETURN d", expected);
|
||||
}
|
||||
|
@ -2795,7 +2815,7 @@ SECTION("BinaryAnd") {
|
|||
irs::Or expected;
|
||||
auto& range = expected.add<irs::by_range>();
|
||||
range.boost(0.5);
|
||||
range.field(mangleString("a.b.c", "test_analyzer"))
|
||||
range.field(mangleString("a.b.c", "testVocbase::test_analyzer"))
|
||||
.include<irs::Bound::MIN>(true).term<irs::Bound::MIN>("15")
|
||||
.include<irs::Bound::MAX>(false).term<irs::Bound::MAX>("40");
|
||||
|
||||
|
@ -2843,12 +2863,12 @@ SECTION("BinaryAnd") {
|
|||
irs::Or expected;
|
||||
auto& root = expected.add<irs::And>();
|
||||
root.add<irs::by_range>()
|
||||
.field(mangleString("a.b.c", "test_analyzer"))
|
||||
.field(mangleString("a.b.c", "testVocbase::test_analyzer"))
|
||||
.include<irs::Bound::MIN>(true)
|
||||
.term<irs::Bound::MIN>("15")
|
||||
.boost(0.5);
|
||||
root.add<irs::by_range>()
|
||||
.field(mangleString("a.b.c", "test_analyzer"))
|
||||
.field(mangleString("a.b.c", "testVocbase::test_analyzer"))
|
||||
.include<irs::Bound::MAX>(true)
|
||||
.term<irs::Bound::MAX>("40")
|
||||
.boost(0.5);
|
||||
|
@ -2862,11 +2882,11 @@ SECTION("BinaryAnd") {
|
|||
auto& root = expected.add<irs::And>();
|
||||
root.boost(0.5);
|
||||
root.add<irs::by_range>()
|
||||
.field(mangleString("a.b.c", "test_analyzer"))
|
||||
.field(mangleString("a.b.c", "testVocbase::test_analyzer"))
|
||||
.include<irs::Bound::MIN>(true)
|
||||
.term<irs::Bound::MIN>("15");
|
||||
root.add<irs::by_range>()
|
||||
.field(mangleString("a.b.c", "test_analyzer"))
|
||||
.field(mangleString("a.b.c", "testVocbase::test_analyzer"))
|
||||
.include<irs::Bound::MAX>(true)
|
||||
.term<irs::Bound::MAX>("40");
|
||||
|
||||
|
@ -2923,7 +2943,7 @@ SECTION("BinaryAnd") {
|
|||
irs::Or expected;
|
||||
auto& range = expected.add<irs::by_range>();
|
||||
range.boost(2.f);
|
||||
range.field(mangleString("a.b.c.e.f", "test_analyzer"))
|
||||
range.field(mangleString("a.b.c.e.f", "testVocbase::test_analyzer"))
|
||||
.include<irs::Bound::MIN>(false).term<irs::Bound::MIN>("15")
|
||||
.include<irs::Bound::MAX>(true).term<irs::Bound::MAX>("40");
|
||||
|
||||
|
@ -3048,7 +3068,7 @@ SECTION("BinaryAnd") {
|
|||
auto& root = expected.add<irs::And>();
|
||||
root.boost(1.5);
|
||||
root.add<irs::by_range>()
|
||||
.field(mangleString("a.b.c", "test_analyzer"))
|
||||
.field(mangleString("a.b.c", "testVocbase::test_analyzer"))
|
||||
.include<irs::Bound::MIN>(true).term<irs::Bound::MIN>("15");
|
||||
root.add<irs::by_granular_range>()
|
||||
.field(mangleNumeric("a.b.c"))
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include "Aql/ExecutionPlan.h"
|
||||
#include "Aql/ExpressionContext.h"
|
||||
#include "Aql/Query.h"
|
||||
#include "Cluster/ClusterFeature.h"
|
||||
#include "GeneralServer/AuthenticationFeature.h"
|
||||
#include "IResearch/IResearchCommon.h"
|
||||
#include "IResearch/IResearchFeature.h"
|
||||
|
@ -55,6 +56,7 @@
|
|||
#include "StorageEngine/EngineSelectorFeature.h"
|
||||
#include "Transaction/Methods.h"
|
||||
#include "Transaction/StandaloneContext.h"
|
||||
#include "V8Server/V8DealerFeature.h"
|
||||
|
||||
#include "analysis/analyzers.hpp"
|
||||
#include "analysis/token_streams.hpp"
|
||||
|
@ -72,13 +74,12 @@
|
|||
// --SECTION-- setup / tear-down
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
struct IResearchFilterSetup {
|
||||
struct IResearchFilterCompareSetup {
|
||||
StorageEngineMock engine;
|
||||
arangodb::application_features::ApplicationServer server;
|
||||
std::unique_ptr<TRI_vocbase_t> system;
|
||||
std::vector<std::pair<arangodb::application_features::ApplicationFeature*, bool>> features;
|
||||
|
||||
IResearchFilterSetup(): engine(server), server(nullptr, nullptr) {
|
||||
IResearchFilterCompareSetup(): engine(server), server(nullptr, nullptr) {
|
||||
arangodb::EngineSelectorFeature::ENGINE = &engine;
|
||||
arangodb::aql::AqlFunctionFeature* functions = nullptr;
|
||||
|
||||
|
@ -87,14 +88,18 @@ struct IResearchFilterSetup {
|
|||
// suppress INFO {authentication} Authentication is turned on (system only), authentication for unix sockets is turned on
|
||||
arangodb::LogTopic::setLogLevel(arangodb::Logger::AUTHENTICATION.name(), arangodb::LogLevel::WARN);
|
||||
|
||||
// suppress log messages since tests check error conditions
|
||||
arangodb::LogTopic::setLogLevel(arangodb::iresearch::TOPIC.name(), arangodb::LogLevel::FATAL);
|
||||
irs::logger::output_le(iresearch::logger::IRL_FATAL, stderr);
|
||||
|
||||
// setup required application features
|
||||
features.emplace_back(new arangodb::AuthenticationFeature(server), true);
|
||||
features.emplace_back(new arangodb::DatabaseFeature(server), false);
|
||||
features.emplace_back(new arangodb::QueryRegistryFeature(server), false); // must be first
|
||||
arangodb::application_features::ApplicationServer::server->addFeature(features.back().first); // need QueryRegistryFeature feature to be added now in order to create the system database
|
||||
system = irs::memory::make_unique<TRI_vocbase_t>(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 0, TRI_VOC_SYSTEM_DATABASE);
|
||||
features.emplace_back(new arangodb::SystemDatabaseFeature(server, system.get()), false); // required for IResearchAnalyzerFeature
|
||||
features.emplace_back(new arangodb::SystemDatabaseFeature(server), true); // required for IResearchAnalyzerFeature
|
||||
features.emplace_back(new arangodb::TraverserEngineRegistryFeature(server), false); // must be before AqlFeature
|
||||
features.emplace_back(new arangodb::V8DealerFeature(server), false); // required for DatabaseFeature::createDatabase(...)
|
||||
features.emplace_back(new arangodb::ViewTypesFeature(server), false); // required for IResearchFeature
|
||||
features.emplace_back(new arangodb::AqlFeature(server), true);
|
||||
features.emplace_back(functions = new arangodb::aql::AqlFunctionFeature(server), true); // required for IResearchAnalyzerFeature
|
||||
|
@ -105,6 +110,11 @@ struct IResearchFilterSetup {
|
|||
features.emplace_back(new arangodb::LdapFeature(server), false); // required for AuthenticationFeature with USE_ENTERPRISE
|
||||
#endif
|
||||
|
||||
// required for V8DealerFeature::prepare(), ClusterFeature::prepare() not required
|
||||
arangodb::application_features::ApplicationServer::server->addFeature(
|
||||
new arangodb::ClusterFeature(server)
|
||||
);
|
||||
|
||||
for (auto& f : features) {
|
||||
arangodb::application_features::ApplicationServer::server->addFeature(f.first);
|
||||
}
|
||||
|
@ -113,6 +123,12 @@ struct IResearchFilterSetup {
|
|||
f.first->prepare();
|
||||
}
|
||||
|
||||
auto const databases = arangodb::velocypack::Parser::fromJson(std::string("[ { \"name\": \"") + arangodb::StaticStrings::SystemDatabase + "\" } ]");
|
||||
auto* dbFeature = arangodb::application_features::ApplicationServer::lookupFeature<
|
||||
arangodb::DatabaseFeature
|
||||
>("Database");
|
||||
dbFeature->loadDatabases(databases->slice());
|
||||
|
||||
for (auto& f : features) {
|
||||
if (f.second) {
|
||||
f.first->start();
|
||||
|
@ -147,17 +163,20 @@ struct IResearchFilterSetup {
|
|||
return params[0];
|
||||
}});
|
||||
|
||||
// suppress log messages since tests check error conditions
|
||||
arangodb::LogTopic::setLogLevel(arangodb::iresearch::TOPIC.name(), arangodb::LogLevel::FATAL);
|
||||
irs::logger::output_le(iresearch::logger::IRL_FATAL, stderr);
|
||||
auto* analyzers = arangodb::application_features::ApplicationServer::lookupFeature<
|
||||
arangodb::iresearch::IResearchAnalyzerFeature
|
||||
>();
|
||||
arangodb::iresearch::IResearchAnalyzerFeature::EmplaceResult result;
|
||||
TRI_vocbase_t* vocbase;
|
||||
|
||||
dbFeature->createDatabase(1, "testVocbase", vocbase); // required for IResearchAnalyzerFeature::emplace(...)
|
||||
analyzers->emplace(result, "testVocbase::test_analyzer", "TestAnalyzer", "abc"); // cache analyzer
|
||||
}
|
||||
|
||||
~IResearchFilterSetup() {
|
||||
system.reset(); // destroy before reseting the 'ENGINE'
|
||||
~IResearchFilterCompareSetup() {
|
||||
arangodb::AqlFeature(server).stop(); // unset singleton instance
|
||||
arangodb::LogTopic::setLogLevel(arangodb::iresearch::TOPIC.name(), arangodb::LogLevel::DEFAULT);
|
||||
arangodb::application_features::ApplicationServer::server = nullptr;
|
||||
arangodb::EngineSelectorFeature::ENGINE = nullptr;
|
||||
|
||||
// destroy application features
|
||||
for (auto& f : features) {
|
||||
|
@ -171,6 +190,7 @@ struct IResearchFilterSetup {
|
|||
}
|
||||
|
||||
arangodb::LogTopic::setLogLevel(arangodb::Logger::AUTHENTICATION.name(), arangodb::LogLevel::DEFAULT);
|
||||
arangodb::EngineSelectorFeature::ENGINE = nullptr;
|
||||
}
|
||||
}; // IResearchFilterSetup
|
||||
|
||||
|
@ -183,7 +203,7 @@ struct IResearchFilterSetup {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TEST_CASE("IResearchFilterCompareTest", "[iresearch][iresearch-filter]") {
|
||||
IResearchFilterSetup s;
|
||||
IResearchFilterCompareSetup s;
|
||||
UNUSED(s);
|
||||
|
||||
SECTION("BinaryEq") {
|
||||
|
@ -249,7 +269,7 @@ SECTION("BinaryEq") {
|
|||
// complex attribute with offset, string, analyzer
|
||||
{
|
||||
irs::Or expected;
|
||||
expected.add<irs::by_term>().field(mangleString("a.b[23].c", "test_analyzer")).term("1");
|
||||
expected.add<irs::by_term>().field(mangleString("a.b[23].c", "testVocbase::test_analyzer")).term("1");
|
||||
|
||||
assertFilterSuccess("FOR d IN collection FILTER analyzer(d.a.b[23].c == '1', 'test_analyzer') RETURN d", expected);
|
||||
assertFilterSuccess("FOR d IN collection FILTER analyzer(d.a['b'][23].c == '1', 'test_analyzer') RETURN d", expected);
|
||||
|
@ -262,7 +282,7 @@ SECTION("BinaryEq") {
|
|||
// complex attribute with offset, string, analyzer, boost
|
||||
{
|
||||
irs::Or expected;
|
||||
expected.add<irs::by_term>().field(mangleString("a.b[23].c", "test_analyzer")).term("1").boost(0.5);
|
||||
expected.add<irs::by_term>().field(mangleString("a.b[23].c", "testVocbase::test_analyzer")).term("1").boost(0.5);
|
||||
|
||||
assertFilterSuccess("FOR d IN collection FILTER analyzer(boost(d.a.b[23].c == '1', 0.5), 'test_analyzer') RETURN d", expected);
|
||||
assertFilterSuccess("FOR d IN collection FILTER boost(analyzer(d.a['b'][23].c == '1', 'test_analyzer'), 0.5) RETURN d", expected);
|
||||
|
@ -863,7 +883,7 @@ SECTION("BinaryNotEq") {
|
|||
ctx.vars.emplace(var.name, value);
|
||||
|
||||
irs::Or expected;
|
||||
expected.add<irs::Not>().filter<irs::by_term>().field(mangleString("a.b[23].c", "test_analyzer")).term("42").boost(42);
|
||||
expected.add<irs::Not>().filter<irs::by_term>().field(mangleString("a.b[23].c", "testVocbase::test_analyzer")).term("42").boost(42);
|
||||
|
||||
assertFilterSuccess("LET c=41 FOR d IN collection FILTER analyzer(boost(d.a.b[23].c != TO_STRING(c+1), c+1), 'test_analyzer') RETURN d", expected, &ctx);
|
||||
}
|
||||
|
@ -1427,7 +1447,7 @@ SECTION("BinaryGE") {
|
|||
|
||||
irs::Or expected;
|
||||
expected.add<irs::by_range>()
|
||||
.field(mangleString("a.b[23].c", "test_analyzer"))
|
||||
.field(mangleString("a.b[23].c", "testVocbase::test_analyzer"))
|
||||
.include<irs::Bound::MIN>(true).term<irs::Bound::MIN>("42")
|
||||
.boost(42);
|
||||
|
||||
|
@ -2000,7 +2020,7 @@ SECTION("BinaryGT") {
|
|||
|
||||
irs::Or expected;
|
||||
expected.add<irs::by_range>()
|
||||
.field(mangleString("a.b[23].c", "test_analyzer"))
|
||||
.field(mangleString("a.b[23].c", "testVocbase::test_analyzer"))
|
||||
.include<irs::Bound::MIN>(false).term<irs::Bound::MIN>("42")
|
||||
.boost(42);
|
||||
|
||||
|
@ -2591,7 +2611,7 @@ SECTION("BinaryLE") {
|
|||
|
||||
irs::Or expected;
|
||||
expected.add<irs::by_range>()
|
||||
.field(mangleString("a.b[23].c", "test_analyzer"))
|
||||
.field(mangleString("a.b[23].c", "testVocbase::test_analyzer"))
|
||||
.include<irs::Bound::MAX>(true).term<irs::Bound::MAX>("42")
|
||||
.boost(42);
|
||||
|
||||
|
@ -3166,7 +3186,7 @@ SECTION("BinaryLT") {
|
|||
|
||||
irs::Or expected;
|
||||
expected.add<irs::by_range>()
|
||||
.field(mangleString("a.b[23].c", "test_analyzer"))
|
||||
.field(mangleString("a.b[23].c", "testVocbase::test_analyzer"))
|
||||
.include<irs::Bound::MAX>(false).term<irs::Bound::MAX>("42")
|
||||
.boost(42);
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include "Aql/ExecutionPlan.h"
|
||||
#include "Aql/ExpressionContext.h"
|
||||
#include "Aql/Query.h"
|
||||
#include "Cluster/ClusterFeature.h"
|
||||
#include "GeneralServer/AuthenticationFeature.h"
|
||||
#include "IResearch/IResearchCommon.h"
|
||||
#include "IResearch/IResearchFeature.h"
|
||||
|
@ -56,6 +57,7 @@
|
|||
#include "RestServer/TraverserEngineRegistryFeature.h"
|
||||
#include "RestServer/ViewTypesFeature.h"
|
||||
#include "Sharding/ShardingFeature.h"
|
||||
#include "V8Server/V8DealerFeature.h"
|
||||
|
||||
#include "analysis/analyzers.hpp"
|
||||
#include "analysis/token_streams.hpp"
|
||||
|
@ -73,13 +75,12 @@
|
|||
// --SECTION-- setup / tear-down
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
struct IResearchFilterSetup {
|
||||
struct IResearchFilterFunctionSetup {
|
||||
StorageEngineMock engine;
|
||||
arangodb::application_features::ApplicationServer server;
|
||||
std::unique_ptr<TRI_vocbase_t> system;
|
||||
std::vector<std::pair<arangodb::application_features::ApplicationFeature*, bool>> features;
|
||||
|
||||
IResearchFilterSetup(): engine(server), server(nullptr, nullptr) {
|
||||
IResearchFilterFunctionSetup(): engine(server), server(nullptr, nullptr) {
|
||||
arangodb::EngineSelectorFeature::ENGINE = &engine;
|
||||
arangodb::aql::AqlFunctionFeature* functions = nullptr;
|
||||
|
||||
|
@ -88,15 +89,19 @@ struct IResearchFilterSetup {
|
|||
// suppress INFO {authentication} Authentication is turned on (system only), authentication for unix sockets is turned on
|
||||
arangodb::LogTopic::setLogLevel(arangodb::Logger::AUTHENTICATION.name(), arangodb::LogLevel::WARN);
|
||||
|
||||
// suppress log messages since tests check error conditions
|
||||
arangodb::LogTopic::setLogLevel(arangodb::iresearch::TOPIC.name(), arangodb::LogLevel::FATAL);
|
||||
irs::logger::output_le(iresearch::logger::IRL_FATAL, stderr);
|
||||
|
||||
// setup required application features
|
||||
features.emplace_back(new arangodb::AuthenticationFeature(server), true);
|
||||
features.emplace_back(new arangodb::DatabaseFeature(server), false);
|
||||
features.emplace_back(new arangodb::QueryRegistryFeature(server), false); // must be first
|
||||
features.emplace_back(new arangodb::ShardingFeature(server), false);
|
||||
arangodb::application_features::ApplicationServer::server->addFeature(features.back().first); // need QueryRegistryFeature feature to be added now in order to create the system database
|
||||
system = irs::memory::make_unique<TRI_vocbase_t>(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 0, TRI_VOC_SYSTEM_DATABASE);
|
||||
features.emplace_back(new arangodb::SystemDatabaseFeature(server, system.get()), false); // required for IResearchAnalyzerFeature
|
||||
features.emplace_back(new arangodb::SystemDatabaseFeature(server), true); // required for IResearchAnalyzerFeature
|
||||
features.emplace_back(new arangodb::TraverserEngineRegistryFeature(server), false); // must be before AqlFeature
|
||||
features.emplace_back(new arangodb::V8DealerFeature(server), false); // required for DatabaseFeature::createDatabase(...)
|
||||
features.emplace_back(new arangodb::ViewTypesFeature(server), false); // required for IResearchFeature
|
||||
features.emplace_back(new arangodb::AqlFeature(server), true);
|
||||
features.emplace_back(functions = new arangodb::aql::AqlFunctionFeature(server), true); // required for IResearchAnalyzerFeature
|
||||
|
@ -107,6 +112,11 @@ struct IResearchFilterSetup {
|
|||
features.emplace_back(new arangodb::LdapFeature(server), false); // required for AuthenticationFeature with USE_ENTERPRISE
|
||||
#endif
|
||||
|
||||
// required for V8DealerFeature::prepare(), ClusterFeature::prepare() not required
|
||||
arangodb::application_features::ApplicationServer::server->addFeature(
|
||||
new arangodb::ClusterFeature(server)
|
||||
);
|
||||
|
||||
for (auto& f : features) {
|
||||
arangodb::application_features::ApplicationServer::server->addFeature(f.first);
|
||||
}
|
||||
|
@ -115,6 +125,12 @@ struct IResearchFilterSetup {
|
|||
f.first->prepare();
|
||||
}
|
||||
|
||||
auto const databases = arangodb::velocypack::Parser::fromJson(std::string("[ { \"name\": \"") + arangodb::StaticStrings::SystemDatabase + "\" } ]");
|
||||
auto* dbFeature = arangodb::application_features::ApplicationServer::lookupFeature<
|
||||
arangodb::DatabaseFeature
|
||||
>("Database");
|
||||
dbFeature->loadDatabases(databases->slice());
|
||||
|
||||
for (auto& f : features) {
|
||||
if (f.second) {
|
||||
f.first->start();
|
||||
|
@ -149,17 +165,20 @@ struct IResearchFilterSetup {
|
|||
return params[0];
|
||||
}});
|
||||
|
||||
// suppress log messages since tests check error conditions
|
||||
arangodb::LogTopic::setLogLevel(arangodb::iresearch::TOPIC.name(), arangodb::LogLevel::FATAL);
|
||||
irs::logger::output_le(iresearch::logger::IRL_FATAL, stderr);
|
||||
auto* analyzers = arangodb::application_features::ApplicationServer::lookupFeature<
|
||||
arangodb::iresearch::IResearchAnalyzerFeature
|
||||
>();
|
||||
arangodb::iresearch::IResearchAnalyzerFeature::EmplaceResult result;
|
||||
TRI_vocbase_t* vocbase;
|
||||
|
||||
dbFeature->createDatabase(1, "testVocbase", vocbase); // required for IResearchAnalyzerFeature::emplace(...)
|
||||
analyzers->emplace(result, "testVocbase::test_analyzer", "TestAnalyzer", "abc"); // cache analyzer
|
||||
}
|
||||
|
||||
~IResearchFilterSetup() {
|
||||
system.reset(); // destroy before reseting the 'ENGINE'
|
||||
~IResearchFilterFunctionSetup() {
|
||||
arangodb::AqlFeature(server).stop(); // unset singleton instance
|
||||
arangodb::LogTopic::setLogLevel(arangodb::iresearch::TOPIC.name(), arangodb::LogLevel::DEFAULT);
|
||||
arangodb::application_features::ApplicationServer::server = nullptr;
|
||||
arangodb::EngineSelectorFeature::ENGINE = nullptr;
|
||||
|
||||
// destroy application features
|
||||
for (auto& f : features) {
|
||||
|
@ -173,6 +192,7 @@ struct IResearchFilterSetup {
|
|||
}
|
||||
|
||||
arangodb::LogTopic::setLogLevel(arangodb::Logger::AUTHENTICATION.name(), arangodb::LogLevel::DEFAULT);
|
||||
arangodb::EngineSelectorFeature::ENGINE = nullptr;
|
||||
}
|
||||
}; // IResearchFilterSetup
|
||||
|
||||
|
@ -185,7 +205,7 @@ struct IResearchFilterSetup {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TEST_CASE("IResearchFilterFunctionTest", "[iresearch][iresearch-filter]") {
|
||||
IResearchFilterSetup s;
|
||||
IResearchFilterFunctionSetup s;
|
||||
UNUSED(s);
|
||||
|
||||
SECTION("AttributeAccess") {
|
||||
|
@ -660,7 +680,7 @@ SECTION("Analyzer") {
|
|||
// simple analyzer
|
||||
{
|
||||
irs::Or expected;
|
||||
expected.add<irs::by_term>().field(mangleString("foo", "test_analyzer")).term("bar");
|
||||
expected.add<irs::by_term>().field(mangleString("foo", "testVocbase::test_analyzer")).term("bar");
|
||||
|
||||
assertFilterSuccess(
|
||||
"FOR d IN collection FILTER ANALYZER(d.foo == 'bar', 'test_analyzer') RETURN d",
|
||||
|
@ -685,7 +705,7 @@ SECTION("Analyzer") {
|
|||
ctx.vars.emplace("x", arangodb::aql::AqlValue(arangodb::aql::AqlValue("test_")));
|
||||
|
||||
irs::Or expected;
|
||||
expected.add<irs::by_term>().field(mangleString("foo", "test_analyzer")).term("bar");
|
||||
expected.add<irs::by_term>().field(mangleString("foo", "testVocbase::test_analyzer")).term("bar");
|
||||
|
||||
assertFilterSuccess(
|
||||
"LET x='test_' FOR d IN collection FILTER ANALYZER(d.foo == 'bar', CONCAT(x, 'analyzer')) RETURN d",
|
||||
|
@ -1253,7 +1273,7 @@ SECTION("Exists") {
|
|||
{
|
||||
irs::Or expected;
|
||||
auto& exists = expected.add<irs::by_column_existence>();
|
||||
exists.field(mangleString("name", "test_analyzer")).prefix_match(false);
|
||||
exists.field(mangleString("name", "testVocbase::test_analyzer")).prefix_match(false);
|
||||
|
||||
assertFilterSuccess("FOR d IN myView FILTER analyzer(exists(d.name, 'analyzer'), 'test_analyzer') RETURN d", expected);
|
||||
assertFilterSuccess("FOR d IN myView FILTER exists(d.name, 'analyzer', 'test_analyzer') RETURN d", expected);
|
||||
|
@ -1289,7 +1309,7 @@ SECTION("Exists") {
|
|||
|
||||
irs::Or expected;
|
||||
auto& exists = expected.add<irs::by_column_existence>();
|
||||
exists.field(mangleString("name", "test_analyzer")).prefix_match(false);
|
||||
exists.field(mangleString("name", "testVocbase::test_analyzer")).prefix_match(false);
|
||||
|
||||
assertFilterSuccess("LET type='analyz' LET anl='test_' FOR d IN myView FILTER analyzer(exists(d.name, CONCAT(type,'er')), CONCAT(anl,'analyzer')) RETURN d", expected, &ctx);
|
||||
assertFilterSuccess("LET type='analyz' LET anl='test_' FOR d IN myView FILTER analyzer(eXists(d.name, CONCAT(type,'er')), CONCAT(anl,'analyzer')) RETURN d", expected, &ctx);
|
||||
|
@ -1301,7 +1321,7 @@ SECTION("Exists") {
|
|||
{
|
||||
irs::Or expected;
|
||||
auto& exists = expected.add<irs::by_column_existence>();
|
||||
exists.field(mangleString("name", "test_analyzer")).prefix_match(false);
|
||||
exists.field(mangleString("name", "testVocbase::test_analyzer")).prefix_match(false);
|
||||
|
||||
assertFilterSuccess("FOR d IN myView FILTER analyzer(exists(d['name'], 'analyzer'), 'test_analyzer') RETURN d", expected);
|
||||
assertFilterSuccess("FOR d IN myView FILTER analyzer(eXists(d['name'], 'analyzer'), 'test_analyzer') RETURN d", expected);
|
||||
|
@ -1392,7 +1412,7 @@ SECTION("Phrase") {
|
|||
{
|
||||
irs::Or expected;
|
||||
auto& phrase = expected.add<irs::by_phrase>();
|
||||
phrase.field(mangleString("name", "test_analyzer"));
|
||||
phrase.field(mangleString("name", "testVocbase::test_analyzer"));
|
||||
phrase.push_back("q").push_back("u").push_back("i").push_back("c").push_back("k");
|
||||
|
||||
assertFilterSuccess("FOR d IN myView FILTER Analyzer(phrase(d.name, 'quick'), 'test_analyzer') RETURN d", expected);
|
||||
|
@ -1442,7 +1462,7 @@ SECTION("Phrase") {
|
|||
|
||||
irs::Or expected;
|
||||
auto& phrase = expected.add<irs::by_phrase>();
|
||||
phrase.field(mangleString("a.b.c.e[4].f[5].g[3].g.a", "test_analyzer"));
|
||||
phrase.field(mangleString("a.b.c.e[4].f[5].g[3].g.a", "testVocbase::test_analyzer"));
|
||||
phrase.push_back("q").push_back("u").push_back("i").push_back("c").push_back("k");
|
||||
|
||||
assertFilterSuccess("LET a='a' LET c='c' LET offsetInt=4 LET offsetDbl=5.6 FOR d IN collection FILTER analyzer(phrase(d[a].b[c].e[offsetInt].f[offsetDbl].g[_FORWARD_(3)].g[_FORWARD_('a')], 'quick'), 'test_analyzer') RETURN d", expected, &ctx);
|
||||
|
@ -1490,7 +1510,7 @@ SECTION("Phrase") {
|
|||
{
|
||||
irs::Or expected;
|
||||
auto& phrase = expected.add<irs::by_phrase>();
|
||||
phrase.field(mangleString("[42]", "test_analyzer"));
|
||||
phrase.field(mangleString("[42]", "testVocbase::test_analyzer"));
|
||||
phrase.push_back("q").push_back("u").push_back("i").push_back("c").push_back("k");
|
||||
|
||||
assertFilterSuccess("FOR d IN myView FILTER AnalYZER(phrase(d[42], 'quick'), 'test_analyzer') RETURN d", expected);
|
||||
|
@ -1508,7 +1528,7 @@ SECTION("Phrase") {
|
|||
|
||||
irs::Or expected;
|
||||
auto& phrase = expected.add<irs::by_phrase>();
|
||||
phrase.field(mangleString("name", "test_analyzer"));
|
||||
phrase.field(mangleString("name", "testVocbase::test_analyzer"));
|
||||
phrase.push_back("q").push_back("u").push_back("i").push_back("c").push_back("k");
|
||||
|
||||
assertFilterSuccess("LET value='qui' LET analyzer='test_' FOR d IN myView FILTER AnAlYzEr(phrase(d.name, CONCAT(value,'ck')), CONCAT(analyzer, 'analyzer')) RETURN d", expected, &ctx);
|
||||
|
@ -1560,7 +1580,7 @@ SECTION("Phrase") {
|
|||
{
|
||||
irs::Or expected;
|
||||
auto& phrase = expected.add<irs::by_phrase>();
|
||||
phrase.field(mangleString("name", "test_analyzer"));
|
||||
phrase.field(mangleString("name", "testVocbase::test_analyzer"));
|
||||
phrase.push_back("q").push_back("u").push_back("i").push_back("c").push_back("k");
|
||||
phrase.push_back("b").push_back("r").push_back("o").push_back("w").push_back("n");
|
||||
|
||||
|
@ -1595,7 +1615,7 @@ SECTION("Phrase") {
|
|||
{
|
||||
irs::Or expected;
|
||||
auto& phrase = expected.add<irs::by_phrase>();
|
||||
phrase.field(mangleString("obj.name", "test_analyzer"));
|
||||
phrase.field(mangleString("obj.name", "testVocbase::test_analyzer"));
|
||||
phrase.push_back("q").push_back("u").push_back("i").push_back("c").push_back("k");
|
||||
phrase.push_back("b", 5).push_back("r").push_back("o").push_back("w").push_back("n");
|
||||
|
||||
|
@ -1630,7 +1650,7 @@ SECTION("Phrase") {
|
|||
{
|
||||
irs::Or expected;
|
||||
auto& phrase = expected.add<irs::by_phrase>();
|
||||
phrase.field(mangleString("obj.name", "test_analyzer")).boost(3.0f);
|
||||
phrase.field(mangleString("obj.name", "testVocbase::test_analyzer")).boost(3.0f);
|
||||
phrase.push_back("q").push_back("u").push_back("i").push_back("c").push_back("k");
|
||||
phrase.push_back("b", 5).push_back("r").push_back("o").push_back("w").push_back("n");
|
||||
|
||||
|
@ -1647,7 +1667,7 @@ SECTION("Phrase") {
|
|||
{
|
||||
irs::Or expected;
|
||||
auto& phrase = expected.add<irs::by_phrase>();
|
||||
phrase.field(mangleString("obj[3].name[1]", "test_analyzer"));
|
||||
phrase.field(mangleString("obj[3].name[1]", "testVocbase::test_analyzer"));
|
||||
phrase.push_back("q").push_back("u").push_back("i").push_back("c").push_back("k");
|
||||
phrase.push_back("b", 5).push_back("r").push_back("o").push_back("w").push_back("n");
|
||||
|
||||
|
@ -1682,7 +1702,7 @@ SECTION("Phrase") {
|
|||
{
|
||||
irs::Or expected;
|
||||
auto& phrase = expected.add<irs::by_phrase>();
|
||||
phrase.field(mangleString("[5].obj.name[100]", "test_analyzer"));
|
||||
phrase.field(mangleString("[5].obj.name[100]", "testVocbase::test_analyzer"));
|
||||
phrase.push_back("q").push_back("u").push_back("i").push_back("c").push_back("k");
|
||||
phrase.push_back("b", 5).push_back("r").push_back("o").push_back("w").push_back("n");
|
||||
|
||||
|
@ -1717,7 +1737,7 @@ SECTION("Phrase") {
|
|||
{
|
||||
irs::Or expected;
|
||||
auto& phrase = expected.add<irs::by_phrase>();
|
||||
phrase.field(mangleString("obj.properties.id.name", "test_analyzer"));
|
||||
phrase.field(mangleString("obj.properties.id.name", "testVocbase::test_analyzer"));
|
||||
phrase.push_back("q").push_back("u").push_back("i").push_back("c").push_back("k");
|
||||
phrase.push_back("b", 3).push_back("r").push_back("o").push_back("w").push_back("n");
|
||||
phrase.push_back("f", 2).push_back("o").push_back("x");
|
||||
|
@ -1792,7 +1812,7 @@ SECTION("Phrase") {
|
|||
{
|
||||
irs::Or expected;
|
||||
auto& phrase = expected.add<irs::by_phrase>();
|
||||
phrase.field(mangleString("obj.properties.id.name", "test_analyzer"));
|
||||
phrase.field(mangleString("obj.properties.id.name", "testVocbase::test_analyzer"));
|
||||
phrase.push_back("q").push_back("u").push_back("i").push_back("c").push_back("k");
|
||||
phrase.push_back("b", 3).push_back("r").push_back("o").push_back("w").push_back("n");
|
||||
phrase.push_back("f", 2).push_back("o").push_back("x");
|
||||
|
@ -2091,7 +2111,7 @@ SECTION("StartsWith") {
|
|||
{
|
||||
irs::Or expected;
|
||||
auto& prefix = expected.add<irs::by_prefix>();
|
||||
prefix.field(mangleString("obj[400].properties[3].name", "test_analyzer")).term("abc");
|
||||
prefix.field(mangleString("obj[400].properties[3].name", "testVocbase::test_analyzer")).term("abc");
|
||||
prefix.scored_terms_limit(128);
|
||||
|
||||
assertFilterSuccess("FOR d IN myView FILTER Analyzer(starts_with(d['obj'][400]['properties'][3]['name'], 'abc'), 'test_analyzer') RETURN d", expected);
|
||||
|
@ -2204,7 +2224,7 @@ SECTION("StartsWith") {
|
|||
|
||||
irs::Or expected;
|
||||
auto& prefix = expected.add<irs::by_prefix>();
|
||||
prefix.field(mangleString("obj[400].properties[3].name", "test_analyzer")).term("abc");
|
||||
prefix.field(mangleString("obj[400].properties[3].name", "testVocbase::test_analyzer")).term("abc");
|
||||
prefix.scored_terms_limit(6);
|
||||
|
||||
assertFilterSuccess("LET scoringLimit=5 LET prefix='ab' LET analyzer='analyzer' FOR d IN myView FILTER analyzer(starts_with(d['obj'][400]['properties'][3]['name'], CONCAT(prefix, 'c'), (scoringLimit + 1.5)), CONCAT('test_',analyzer)) RETURN d", expected, &ctx);
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include "Aql/ExecutionPlan.h"
|
||||
#include "Aql/ExpressionContext.h"
|
||||
#include "Aql/Query.h"
|
||||
#include "Cluster/ClusterFeature.h"
|
||||
#include "GeneralServer/AuthenticationFeature.h"
|
||||
#include "IResearch/IResearchCommon.h"
|
||||
#include "IResearch/IResearchFeature.h"
|
||||
|
@ -54,6 +55,7 @@
|
|||
#include "RestServer/ViewTypesFeature.h"
|
||||
#include "StorageEngine/EngineSelectorFeature.h"
|
||||
#include "Transaction/StandaloneContext.h"
|
||||
#include "V8Server/V8DealerFeature.h"
|
||||
|
||||
#include "analysis/analyzers.hpp"
|
||||
#include "analysis/token_streams.hpp"
|
||||
|
@ -71,13 +73,12 @@
|
|||
// --SECTION-- setup / tear-down
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
struct IResearchFilterSetup {
|
||||
struct IResearchFilterInSetup {
|
||||
StorageEngineMock engine;
|
||||
arangodb::application_features::ApplicationServer server;
|
||||
std::unique_ptr<TRI_vocbase_t> system;
|
||||
std::vector<std::pair<arangodb::application_features::ApplicationFeature*, bool>> features;
|
||||
|
||||
IResearchFilterSetup(): engine(server), server(nullptr, nullptr) {
|
||||
IResearchFilterInSetup(): engine(server), server(nullptr, nullptr) {
|
||||
arangodb::EngineSelectorFeature::ENGINE = &engine;
|
||||
arangodb::aql::AqlFunctionFeature* functions = nullptr;
|
||||
|
||||
|
@ -86,14 +87,18 @@ struct IResearchFilterSetup {
|
|||
// suppress INFO {authentication} Authentication is turned on (system only), authentication for unix sockets is turned on
|
||||
arangodb::LogTopic::setLogLevel(arangodb::Logger::AUTHENTICATION.name(), arangodb::LogLevel::WARN);
|
||||
|
||||
// suppress log messages since tests check error conditions
|
||||
arangodb::LogTopic::setLogLevel(arangodb::iresearch::TOPIC.name(), arangodb::LogLevel::FATAL);
|
||||
irs::logger::output_le(iresearch::logger::IRL_FATAL, stderr);
|
||||
|
||||
// setup required application features
|
||||
features.emplace_back(new arangodb::AuthenticationFeature(server), true);
|
||||
features.emplace_back(new arangodb::DatabaseFeature(server), false);
|
||||
features.emplace_back(new arangodb::QueryRegistryFeature(server), false); // must be first
|
||||
arangodb::application_features::ApplicationServer::server->addFeature(features.back().first); // need QueryRegistryFeature feature to be added now in order to create the system database
|
||||
system = irs::memory::make_unique<TRI_vocbase_t>(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 0, TRI_VOC_SYSTEM_DATABASE);
|
||||
features.emplace_back(new arangodb::SystemDatabaseFeature(server, system.get()), false); // required for IResearchAnalyzerFeature
|
||||
features.emplace_back(new arangodb::SystemDatabaseFeature(server), true); // required for IResearchAnalyzerFeature
|
||||
features.emplace_back(new arangodb::TraverserEngineRegistryFeature(server), false); // must be before AqlFeature
|
||||
features.emplace_back(new arangodb::V8DealerFeature(server), false); // required for DatabaseFeature::createDatabase(...)
|
||||
features.emplace_back(new arangodb::ViewTypesFeature(server), false); // required for IResearchFeature
|
||||
features.emplace_back(new arangodb::AqlFeature(server), true);
|
||||
features.emplace_back(functions = new arangodb::aql::AqlFunctionFeature(server), true); // required for IResearchAnalyzerFeature
|
||||
|
@ -104,6 +109,11 @@ struct IResearchFilterSetup {
|
|||
features.emplace_back(new arangodb::LdapFeature(server), false); // required for AuthenticationFeature with USE_ENTERPRISE
|
||||
#endif
|
||||
|
||||
// required for V8DealerFeature::prepare(), ClusterFeature::prepare() not required
|
||||
arangodb::application_features::ApplicationServer::server->addFeature(
|
||||
new arangodb::ClusterFeature(server)
|
||||
);
|
||||
|
||||
for (auto& f : features) {
|
||||
arangodb::application_features::ApplicationServer::server->addFeature(f.first);
|
||||
}
|
||||
|
@ -112,6 +122,12 @@ struct IResearchFilterSetup {
|
|||
f.first->prepare();
|
||||
}
|
||||
|
||||
auto const databases = arangodb::velocypack::Parser::fromJson(std::string("[ { \"name\": \"") + arangodb::StaticStrings::SystemDatabase + "\" } ]");
|
||||
auto* dbFeature = arangodb::application_features::ApplicationServer::lookupFeature<
|
||||
arangodb::DatabaseFeature
|
||||
>("Database");
|
||||
dbFeature->loadDatabases(databases->slice());
|
||||
|
||||
for (auto& f : features) {
|
||||
if (f.second) {
|
||||
f.first->start();
|
||||
|
@ -146,17 +162,20 @@ struct IResearchFilterSetup {
|
|||
return params[0];
|
||||
}});
|
||||
|
||||
// suppress log messages since tests check error conditions
|
||||
arangodb::LogTopic::setLogLevel(arangodb::iresearch::TOPIC.name(), arangodb::LogLevel::FATAL);
|
||||
irs::logger::output_le(iresearch::logger::IRL_FATAL, stderr);
|
||||
auto* analyzers = arangodb::application_features::ApplicationServer::lookupFeature<
|
||||
arangodb::iresearch::IResearchAnalyzerFeature
|
||||
>();
|
||||
arangodb::iresearch::IResearchAnalyzerFeature::EmplaceResult result;
|
||||
TRI_vocbase_t* vocbase;
|
||||
|
||||
dbFeature->createDatabase(1, "testVocbase", vocbase); // required for IResearchAnalyzerFeature::emplace(...)
|
||||
analyzers->emplace(result, "testVocbase::test_analyzer", "TestAnalyzer", "abc"); // cache analyzer
|
||||
}
|
||||
|
||||
~IResearchFilterSetup() {
|
||||
system.reset(); // destroy before reseting the 'ENGINE'
|
||||
~IResearchFilterInSetup() {
|
||||
arangodb::AqlFeature(server).stop(); // unset singleton instance
|
||||
arangodb::LogTopic::setLogLevel(arangodb::iresearch::TOPIC.name(), arangodb::LogLevel::DEFAULT);
|
||||
arangodb::application_features::ApplicationServer::server = nullptr;
|
||||
arangodb::EngineSelectorFeature::ENGINE = nullptr;
|
||||
|
||||
// destroy application features
|
||||
for (auto& f : features) {
|
||||
|
@ -170,6 +189,7 @@ struct IResearchFilterSetup {
|
|||
}
|
||||
|
||||
arangodb::LogTopic::setLogLevel(arangodb::Logger::AUTHENTICATION.name(), arangodb::LogLevel::DEFAULT);
|
||||
arangodb::EngineSelectorFeature::ENGINE = nullptr;
|
||||
}
|
||||
}; // IResearchFilterSetup
|
||||
|
||||
|
@ -182,7 +202,7 @@ struct IResearchFilterSetup {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TEST_CASE("IResearchFilterTestIn", "[iresearch][iresearch-filter]") {
|
||||
IResearchFilterSetup s;
|
||||
IResearchFilterInSetup s;
|
||||
UNUSED(s);
|
||||
|
||||
SECTION("BinaryIn") {
|
||||
|
@ -250,9 +270,9 @@ SECTION("BinaryIn") {
|
|||
{
|
||||
irs::Or expected;
|
||||
auto& root = expected.add<irs::Or>();
|
||||
root.add<irs::by_term>().field(mangleString("a.b.c[412].e.f", "test_analyzer")).term("1");
|
||||
root.add<irs::by_term>().field(mangleString("a.b.c[412].e.f", "test_analyzer")).term("2");
|
||||
root.add<irs::by_term>().field(mangleString("a.b.c[412].e.f", "test_analyzer")).term("3");
|
||||
root.add<irs::by_term>().field(mangleString("a.b.c[412].e.f", "testVocbase::test_analyzer")).term("1");
|
||||
root.add<irs::by_term>().field(mangleString("a.b.c[412].e.f", "testVocbase::test_analyzer")).term("2");
|
||||
root.add<irs::by_term>().field(mangleString("a.b.c[412].e.f", "testVocbase::test_analyzer")).term("3");
|
||||
|
||||
assertFilterSuccess("FOR d IN collection FILTER ANALYZER(d.a['b']['c'][412].e.f in ['1','2','3'], 'test_analyzer') RETURN d", expected);
|
||||
assertFilterSuccess("FOR d IN collection FILTER ANALYZER(d.a.b.c[412].e.f in ['1','2','3'], 'test_analyzer') RETURN d", expected);
|
||||
|
@ -276,9 +296,9 @@ SECTION("BinaryIn") {
|
|||
irs::Or expected;
|
||||
auto& root = expected.add<irs::Or>();
|
||||
root.boost(2.5);
|
||||
root.add<irs::by_term>().field(mangleString("a.b.c[412].e.f", "test_analyzer")).term("1");
|
||||
root.add<irs::by_term>().field(mangleString("a.b.c[412].e.f", "test_analyzer")).term("2");
|
||||
root.add<irs::by_term>().field(mangleString("a.b.c[412].e.f", "test_analyzer")).term("3");
|
||||
root.add<irs::by_term>().field(mangleString("a.b.c[412].e.f", "testVocbase::test_analyzer")).term("1");
|
||||
root.add<irs::by_term>().field(mangleString("a.b.c[412].e.f", "testVocbase::test_analyzer")).term("2");
|
||||
root.add<irs::by_term>().field(mangleString("a.b.c[412].e.f", "testVocbase::test_analyzer")).term("3");
|
||||
|
||||
assertFilterSuccess("FOR d IN collection FILTER ANALYZER(BOOST(d.a['b']['c'][412].e.f in ['1','2','3'], 2.5), 'test_analyzer') RETURN d", expected);
|
||||
assertFilterSuccess("FOR d IN collection FILTER BOOST(ANALYZER(d.a.b.c[412].e.f in ['1','2','3'], 'test_analyzer'), 2.5) RETURN d", expected);
|
||||
|
@ -308,7 +328,7 @@ SECTION("BinaryIn") {
|
|||
{
|
||||
irs::Or expected;
|
||||
auto& root = expected.add<irs::Or>();
|
||||
root.add<irs::by_term>().field(mangleString("quick.brown.fox", "test_analyzer")).term("1");
|
||||
root.add<irs::by_term>().field(mangleString("quick.brown.fox", "testVocbase::test_analyzer")).term("1");
|
||||
root.add<irs::by_term>().field(mangleNull("quick.brown.fox")).term(irs::null_token_stream::value_null());
|
||||
root.add<irs::by_term>().field(mangleBool("quick.brown.fox")).term(irs::boolean_token_stream::value_true());
|
||||
root.add<irs::by_term>().field(mangleBool("quick.brown.fox")).term(irs::boolean_token_stream::value_false());
|
||||
|
@ -350,7 +370,7 @@ SECTION("BinaryIn") {
|
|||
irs::Or expected;
|
||||
auto& root = expected.add<irs::Or>();
|
||||
root.boost(1.5);
|
||||
root.add<irs::by_term>().field(mangleString("quick.brown.fox", "test_analyzer")).term("1");
|
||||
root.add<irs::by_term>().field(mangleString("quick.brown.fox", "testVocbase::test_analyzer")).term("1");
|
||||
root.add<irs::by_term>().field(mangleNull("quick.brown.fox")).term(irs::null_token_stream::value_null());
|
||||
root.add<irs::by_term>().field(mangleBool("quick.brown.fox")).term(irs::boolean_token_stream::value_true());
|
||||
root.add<irs::by_term>().field(mangleBool("quick.brown.fox")).term(irs::boolean_token_stream::value_false());
|
||||
|
@ -491,9 +511,9 @@ SECTION("BinaryIn") {
|
|||
|
||||
irs::Or expected;
|
||||
auto& root = expected.add<irs::Or>();
|
||||
root.add<irs::by_term>().field(mangleString("a.b.c.e.f", "test_analyzer")).term("1");
|
||||
root.add<irs::by_term>().field(mangleString("a.b.c.e.f", "testVocbase::test_analyzer")).term("1");
|
||||
root.add<irs::by_term>().field(mangleNumeric("a.b.c.e.f")).term(term->value());
|
||||
root.add<irs::by_term>().field(mangleString("a.b.c.e.f", "test_analyzer")).term("3");
|
||||
root.add<irs::by_term>().field(mangleString("a.b.c.e.f", "testVocbase::test_analyzer")).term("3");
|
||||
|
||||
assertFilterSuccess("LET x=['1', 2, '3'] FOR d IN collection FILTER ANALYZER(d.a.b.c.e.f in x, 'test_analyzer') RETURN d", expected, &ctx);
|
||||
}
|
||||
|
@ -539,9 +559,9 @@ SECTION("BinaryIn") {
|
|||
irs::Or expected;
|
||||
auto& root = expected.add<irs::Or>();
|
||||
root.boost(1.5);
|
||||
root.add<irs::by_term>().field(mangleString("a.b.c.e.f", "test_analyzer")).term("1");
|
||||
root.add<irs::by_term>().field(mangleString("a.b.c.e.f", "testVocbase::test_analyzer")).term("1");
|
||||
root.add<irs::by_term>().field(mangleNumeric("a.b.c.e.f")).term(term->value());
|
||||
root.add<irs::by_term>().field(mangleString("a.b.c.e.f", "test_analyzer")).term("3");
|
||||
root.add<irs::by_term>().field(mangleString("a.b.c.e.f", "testVocbase::test_analyzer")).term("3");
|
||||
|
||||
assertFilterSuccess("LET x=['1', 2, '3'] FOR d IN collection FILTER ANALYZER(BOOST(d.a.b.c.e.f in x, 1.5), 'test_analyzer') RETURN d", expected, &ctx);
|
||||
assertFilterSuccess("LET x=['1', 2, '3'] FOR d IN collection FILTER BOOST(ANALYZER(d.a.b.c.e.f in x, 'test_analyzer'), 1.5) RETURN d", expected, &ctx);
|
||||
|
@ -1265,8 +1285,8 @@ SECTION("BinaryIn") {
|
|||
|
||||
irs::Or expected;
|
||||
auto& root = expected.add<irs::Or>();
|
||||
root.add<irs::by_term>().field(mangleString("a.b.c.e.f", "test_analyzer")).term("1");
|
||||
root.add<irs::by_term>().field(mangleString("a.b.c.e.f", "test_analyzer")).term("str");
|
||||
root.add<irs::by_term>().field(mangleString("a.b.c.e.f", "testVocbase::test_analyzer")).term("1");
|
||||
root.add<irs::by_term>().field(mangleString("a.b.c.e.f", "testVocbase::test_analyzer")).term("str");
|
||||
root.add<irs::by_term>().field(mangleBool("a.b.c.e.f")).term(irs::boolean_token_stream::value_false());
|
||||
root.add<irs::by_term>().field(mangleNumeric("a.b.c.e.f")).term(term->value());
|
||||
root.add<irs::by_term>().field(mangleNull("a.b.c.e.f")).term(irs::null_token_stream::value_null());
|
||||
|
@ -1295,8 +1315,8 @@ SECTION("BinaryIn") {
|
|||
irs::Or expected;
|
||||
auto& root = expected.add<irs::Or>();
|
||||
root.boost(2.5);
|
||||
root.add<irs::by_term>().field(mangleString("a.b.c.e.f", "test_analyzer")).term("1");
|
||||
root.add<irs::by_term>().field(mangleString("a.b.c.e.f", "test_analyzer")).term("str");
|
||||
root.add<irs::by_term>().field(mangleString("a.b.c.e.f", "testVocbase::test_analyzer")).term("1");
|
||||
root.add<irs::by_term>().field(mangleString("a.b.c.e.f", "testVocbase::test_analyzer")).term("str");
|
||||
root.add<irs::by_term>().field(mangleBool("a.b.c.e.f")).term(irs::boolean_token_stream::value_false());
|
||||
root.add<irs::by_term>().field(mangleNumeric("a.b.c.e.f")).term(term->value());
|
||||
root.add<irs::by_term>().field(mangleNull("a.b.c.e.f")).term(irs::null_token_stream::value_null());
|
||||
|
@ -2115,9 +2135,9 @@ SECTION("BinaryNotIn") {
|
|||
{
|
||||
irs::Or expected;
|
||||
auto& root = expected.add<irs::Not>().filter<irs::And>();
|
||||
root.add<irs::by_term>().field(mangleString("a.b.c[323].e.f", "test_analyzer")).term("1");
|
||||
root.add<irs::by_term>().field(mangleString("a.b.c[323].e.f", "test_analyzer")).term("2");
|
||||
root.add<irs::by_term>().field(mangleString("a.b.c[323].e.f", "test_analyzer")).term("3");
|
||||
root.add<irs::by_term>().field(mangleString("a.b.c[323].e.f", "testVocbase::test_analyzer")).term("1");
|
||||
root.add<irs::by_term>().field(mangleString("a.b.c[323].e.f", "testVocbase::test_analyzer")).term("2");
|
||||
root.add<irs::by_term>().field(mangleString("a.b.c[323].e.f", "testVocbase::test_analyzer")).term("3");
|
||||
|
||||
assertFilterSuccess("FOR d IN collection FILTER analyzer(d.a.b.c[323].e.f not in ['1','2','3'], 'test_analyzer') RETURN d", expected);
|
||||
assertFilterSuccess("FOR d IN collection FILTER analyzer(d.a['b'].c[323].e.f not in ['1','2','3'], 'test_analyzer') RETURN d", expected);
|
||||
|
@ -2129,9 +2149,9 @@ SECTION("BinaryNotIn") {
|
|||
irs::Or expected;
|
||||
auto& root = expected.add<irs::Not>().filter<irs::And>();
|
||||
root.boost(2.5);
|
||||
root.add<irs::by_term>().field(mangleString("a.b.c[323].e.f", "test_analyzer")).term("1");
|
||||
root.add<irs::by_term>().field(mangleString("a.b.c[323].e.f", "test_analyzer")).term("2");
|
||||
root.add<irs::by_term>().field(mangleString("a.b.c[323].e.f", "test_analyzer")).term("3");
|
||||
root.add<irs::by_term>().field(mangleString("a.b.c[323].e.f", "testVocbase::test_analyzer")).term("1");
|
||||
root.add<irs::by_term>().field(mangleString("a.b.c[323].e.f", "testVocbase::test_analyzer")).term("2");
|
||||
root.add<irs::by_term>().field(mangleString("a.b.c[323].e.f", "testVocbase::test_analyzer")).term("3");
|
||||
|
||||
assertFilterSuccess("FOR d IN collection FILTER boost(analyzer(d.a.b.c[323].e.f not in ['1','2','3'], 'test_analyzer'), 2.5) RETURN d", expected);
|
||||
assertFilterSuccess("FOR d IN collection FILTER analyzer(boost(d.a['b'].c[323].e.f not in ['1','2','3'], 2.5), 'test_analyzer') RETURN d", expected);
|
||||
|
@ -2163,7 +2183,7 @@ SECTION("BinaryNotIn") {
|
|||
{
|
||||
irs::Or expected;
|
||||
auto& root = expected.add<irs::Not>().filter<irs::And>();
|
||||
root.add<irs::by_term>().field(mangleString("quick.brown.fox", "test_analyzer")).term("1");
|
||||
root.add<irs::by_term>().field(mangleString("quick.brown.fox", "testVocbase::test_analyzer")).term("1");
|
||||
root.add<irs::by_term>().field(mangleNull("quick.brown.fox")).term(irs::null_token_stream::value_null());
|
||||
root.add<irs::by_term>().field(mangleBool("quick.brown.fox")).term(irs::boolean_token_stream::value_true());
|
||||
root.add<irs::by_term>().field(mangleBool("quick.brown.fox")).term(irs::boolean_token_stream::value_false());
|
||||
|
@ -2184,7 +2204,7 @@ SECTION("BinaryNotIn") {
|
|||
irs::Or expected;
|
||||
auto& root = expected.add<irs::Not>().filter<irs::And>();
|
||||
root.boost(1.5);
|
||||
root.add<irs::by_term>().field(mangleString("quick.brown.fox", "test_analyzer")).term("1");
|
||||
root.add<irs::by_term>().field(mangleString("quick.brown.fox", "testVocbase::test_analyzer")).term("1");
|
||||
root.add<irs::by_term>().field(mangleNull("quick.brown.fox")).term(irs::null_token_stream::value_null());
|
||||
root.add<irs::by_term>().field(mangleBool("quick.brown.fox")).term(irs::boolean_token_stream::value_true());
|
||||
root.add<irs::by_term>().field(mangleBool("quick.brown.fox")).term(irs::boolean_token_stream::value_false());
|
||||
|
@ -2297,9 +2317,9 @@ SECTION("BinaryNotIn") {
|
|||
|
||||
irs::Or expected;
|
||||
auto& root = expected.add<irs::Not>().filter<irs::And>();
|
||||
root.add<irs::by_term>().field(mangleString("a.b.c.e.f", "test_analyzer")).term("1");
|
||||
root.add<irs::by_term>().field(mangleString("a.b.c.e.f", "testVocbase::test_analyzer")).term("1");
|
||||
root.add<irs::by_term>().field(mangleNumeric("a.b.c.e.f")).term(term->value());
|
||||
root.add<irs::by_term>().field(mangleString("a.b.c.e.f", "test_analyzer")).term("3");
|
||||
root.add<irs::by_term>().field(mangleString("a.b.c.e.f", "testVocbase::test_analyzer")).term("3");
|
||||
|
||||
assertFilterSuccess("LET x=['1', 2, '3'] FOR d IN collection FILTER analyzer(d.a.b.c.e.f not in x, 'test_analyzer') RETURN d", expected, &ctx);
|
||||
}
|
||||
|
@ -2321,9 +2341,9 @@ SECTION("BinaryNotIn") {
|
|||
irs::Or expected;
|
||||
auto& root = expected.add<irs::Not>().filter<irs::And>();
|
||||
root.boost(3.5);
|
||||
root.add<irs::by_term>().field(mangleString("a.b.c.e.f", "test_analyzer")).term("1");
|
||||
root.add<irs::by_term>().field(mangleString("a.b.c.e.f", "testVocbase::test_analyzer")).term("1");
|
||||
root.add<irs::by_term>().field(mangleNumeric("a.b.c.e.f")).term(term->value());
|
||||
root.add<irs::by_term>().field(mangleString("a.b.c.e.f", "test_analyzer")).term("3");
|
||||
root.add<irs::by_term>().field(mangleString("a.b.c.e.f", "testVocbase::test_analyzer")).term("3");
|
||||
|
||||
assertFilterSuccess("LET x=['1', 2, '3'] FOR d IN collection FILTER boost(analyzer(d.a.b.c.e.f not in x, 'test_analyzer'), 3.5) RETURN d", expected, &ctx);
|
||||
assertFilterSuccess("LET x=['1', 2, '3'] FOR d IN collection FILTER analyzer(boost(d.a.b.c.e.f not in x, 3.5), 'test_analyzer') RETURN d", expected, &ctx);
|
||||
|
@ -2373,9 +2393,9 @@ SECTION("BinaryNotIn") {
|
|||
|
||||
irs::Or expected;
|
||||
auto& root = expected.add<irs::Not>().filter<irs::And>();
|
||||
root.add<irs::by_term>().field(mangleString("a.b.c.e.f", "test_analyzer")).term("1");
|
||||
root.add<irs::by_term>().field(mangleString("a.b.c.e.f", "testVocbase::test_analyzer")).term("1");
|
||||
root.add<irs::by_term>().field(mangleNumeric("a.b.c.e.f")).term(term->value());
|
||||
root.add<irs::by_term>().field(mangleString("a.b.c.e.f", "test_analyzer")).term("3");
|
||||
root.add<irs::by_term>().field(mangleString("a.b.c.e.f", "testVocbase::test_analyzer")).term("3");
|
||||
|
||||
// not a constant in array
|
||||
assertFilterSuccess(
|
||||
|
@ -2402,9 +2422,9 @@ SECTION("BinaryNotIn") {
|
|||
irs::Or expected;
|
||||
auto& root = expected.add<irs::Not>().filter<irs::And>();
|
||||
root.boost(1.5);
|
||||
root.add<irs::by_term>().field(mangleString("a.b.c.e.f", "test_analyzer")).term("1");
|
||||
root.add<irs::by_term>().field(mangleString("a.b.c.e.f", "testVocbase::test_analyzer")).term("1");
|
||||
root.add<irs::by_term>().field(mangleNumeric("a.b.c.e.f")).term(term->value());
|
||||
root.add<irs::by_term>().field(mangleString("a.b.c.e.f", "test_analyzer")).term("3");
|
||||
root.add<irs::by_term>().field(mangleString("a.b.c.e.f", "testVocbase::test_analyzer")).term("3");
|
||||
|
||||
// not a constant in array
|
||||
assertFilterSuccess(
|
||||
|
|
|
@ -33,6 +33,13 @@
|
|||
#include "Aql/OptimizerRulesFeature.h"
|
||||
#include "Basics/VelocyPackHelper.h"
|
||||
#include "Basics/files.h"
|
||||
#include "Cluster/ClusterFeature.h"
|
||||
|
||||
#if USE_ENTERPRISE
|
||||
#include "Enterprise/Ldap/LdapFeature.h"
|
||||
#endif
|
||||
|
||||
#include "GeneralServer/AuthenticationFeature.h"
|
||||
#include "Sharding/ShardingFeature.h"
|
||||
#include "IResearch/IResearchAnalyzerFeature.h"
|
||||
#include "IResearch/IResearchCommon.h"
|
||||
|
@ -52,6 +59,7 @@
|
|||
#include "utils/utf8_path.hpp"
|
||||
#include "velocypack/Iterator.h"
|
||||
#include "velocypack/Parser.h"
|
||||
#include "V8Server/V8DealerFeature.h"
|
||||
#include "VocBase/LogicalCollection.h"
|
||||
#include "VocBase/LogicalView.h"
|
||||
|
||||
|
@ -133,7 +141,6 @@ REGISTER_ANALYZER_JSON(TestAnalyzer, TestAnalyzer::make);
|
|||
struct IResearchIndexSetup {
|
||||
StorageEngineMock engine;
|
||||
arangodb::application_features::ApplicationServer server;
|
||||
std::unique_ptr<TRI_vocbase_t> system;
|
||||
std::vector<std::pair<arangodb::application_features::ApplicationFeature*, bool>> features;
|
||||
|
||||
IResearchIndexSetup(): engine(server), server(nullptr, nullptr) {
|
||||
|
@ -151,20 +158,30 @@ struct IResearchIndexSetup {
|
|||
|
||||
// setup required application features
|
||||
features.emplace_back(new arangodb::AqlFeature(server), true); // required for arangodb::aql::Query(...)
|
||||
features.emplace_back(new arangodb::AuthenticationFeature(server), false); // required for ExecContext in Collections::create(...)
|
||||
features.emplace_back(new arangodb::DatabaseFeature(server), false); // required for LogicalViewStorageEngine::modify(...)
|
||||
features.emplace_back(new arangodb::DatabasePathFeature(server), false); // requires for IResearchView::open()
|
||||
features.emplace_back(new arangodb::ShardingFeature(server), false);
|
||||
features.emplace_back(new arangodb::V8DealerFeature(server), false); // required for DatabaseFeature::createDatabase(...)
|
||||
features.emplace_back(new arangodb::ViewTypesFeature(server), true); // required by TRI_vocbase_t::createView(...)
|
||||
features.emplace_back(new arangodb::QueryRegistryFeature(server), false); // required by TRI_vocbase_t(...)
|
||||
arangodb::application_features::ApplicationServer::server->addFeature(features.back().first); // need QueryRegistryFeature feature to be added now in order to create the system database
|
||||
system = irs::memory::make_unique<TRI_vocbase_t>(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 0, TRI_VOC_SYSTEM_DATABASE);
|
||||
features.emplace_back(new arangodb::SystemDatabaseFeature(server, system.get()), false); // required for IResearchAnalyzerFeature
|
||||
features.emplace_back(new arangodb::SystemDatabaseFeature(server), true); // required for IResearchAnalyzerFeature
|
||||
features.emplace_back(new arangodb::TraverserEngineRegistryFeature(server), false); // required for AQLFeature
|
||||
features.emplace_back(new arangodb::aql::AqlFunctionFeature(server), true); // required for IResearchAnalyzerFeature
|
||||
features.emplace_back(new arangodb::aql::OptimizerRulesFeature(server), true); // required for arangodb::aql::Query::execute(...)
|
||||
features.emplace_back(new arangodb::iresearch::IResearchAnalyzerFeature(server), true); // required for use of iresearch analyzers
|
||||
features.emplace_back(new arangodb::iresearch::IResearchFeature(server), true); // required for creating views of type 'iresearch'
|
||||
|
||||
#if USE_ENTERPRISE
|
||||
features.emplace_back(new arangodb::LdapFeature(server), false); // required for AuthenticationFeature with USE_ENTERPRISE
|
||||
#endif
|
||||
|
||||
// required for V8DealerFeature::prepare(), ClusterFeature::prepare() not required
|
||||
arangodb::application_features::ApplicationServer::server->addFeature(
|
||||
new arangodb::ClusterFeature(server)
|
||||
);
|
||||
|
||||
for (auto& f: features) {
|
||||
arangodb::application_features::ApplicationServer::server->addFeature(f.first);
|
||||
}
|
||||
|
@ -173,6 +190,12 @@ struct IResearchIndexSetup {
|
|||
f.first->prepare();
|
||||
}
|
||||
|
||||
auto const databases = arangodb::velocypack::Parser::fromJson(std::string("[ { \"name\": \"") + arangodb::StaticStrings::SystemDatabase + "\" } ]");
|
||||
auto* dbFeature = arangodb::application_features::ApplicationServer::lookupFeature<
|
||||
arangodb::DatabaseFeature
|
||||
>("Database");
|
||||
dbFeature->loadDatabases(databases->slice());
|
||||
|
||||
for (auto& f: features) {
|
||||
if (f.second) {
|
||||
f.first->start();
|
||||
|
@ -183,20 +206,20 @@ struct IResearchIndexSetup {
|
|||
arangodb::iresearch::IResearchAnalyzerFeature
|
||||
>();
|
||||
arangodb::iresearch::IResearchAnalyzerFeature::EmplaceResult result;
|
||||
TRI_vocbase_t* vocbase;
|
||||
|
||||
analyzers->emplace(result, "test_A", "TestInsertAnalyzer", "X"); // cache analyzer
|
||||
analyzers->emplace(result, "test_B", "TestInsertAnalyzer", "Y"); // cache analyzer
|
||||
dbFeature->createDatabase(1, "testVocbase", vocbase); // required for IResearchAnalyzerFeature::emplace(...)
|
||||
analyzers->emplace(result, "testVocbase::test_A", "TestInsertAnalyzer", "X"); // cache analyzer
|
||||
analyzers->emplace(result, "testVocbase::test_B", "TestInsertAnalyzer", "Y"); // cache analyzer
|
||||
|
||||
auto* dbPathFeature = arangodb::application_features::ApplicationServer::getFeature<arangodb::DatabasePathFeature>("DatabasePath");
|
||||
arangodb::tests::setDatabasePath(*dbPathFeature); // ensure test data is stored in a unique directory
|
||||
}
|
||||
|
||||
~IResearchIndexSetup() {
|
||||
system.reset(); // destroy before reseting the 'ENGINE'
|
||||
arangodb::LogTopic::setLogLevel(arangodb::iresearch::TOPIC.name(), arangodb::LogLevel::DEFAULT);
|
||||
arangodb::LogTopic::setLogLevel(arangodb::Logger::AQL.name(), arangodb::LogLevel::DEFAULT);
|
||||
arangodb::application_features::ApplicationServer::server = nullptr;
|
||||
arangodb::EngineSelectorFeature::ENGINE = nullptr;
|
||||
|
||||
// destroy application features
|
||||
for (auto& f: features) {
|
||||
|
@ -210,6 +233,7 @@ struct IResearchIndexSetup {
|
|||
}
|
||||
|
||||
arangodb::LogTopic::setLogLevel(arangodb::Logger::AUTHENTICATION.name(), arangodb::LogLevel::DEFAULT);
|
||||
arangodb::EngineSelectorFeature::ENGINE = nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -76,7 +76,6 @@
|
|||
struct IResearchLinkSetup {
|
||||
StorageEngineMock engine;
|
||||
arangodb::application_features::ApplicationServer server;
|
||||
std::unique_ptr<TRI_vocbase_t> system;
|
||||
std::vector<std::pair<arangodb::application_features::ApplicationFeature*, bool>> features;
|
||||
std::string testFilesystemPath;
|
||||
|
||||
|
@ -102,8 +101,7 @@ struct IResearchLinkSetup {
|
|||
features.emplace_back(new arangodb::ViewTypesFeature(server), true);
|
||||
features.emplace_back(new arangodb::QueryRegistryFeature(server), false);
|
||||
arangodb::application_features::ApplicationServer::server->addFeature(features.back().first); // need QueryRegistryFeature feature to be added now in order to create the system database
|
||||
system = irs::memory::make_unique<TRI_vocbase_t>(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 0, TRI_VOC_SYSTEM_DATABASE);
|
||||
features.emplace_back(new arangodb::SystemDatabaseFeature(server, system.get()), false); // required for IResearchAnalyzerFeature
|
||||
features.emplace_back(new arangodb::SystemDatabaseFeature(server), true); // required for IResearchAnalyzerFeature
|
||||
features.emplace_back(new arangodb::TraverserEngineRegistryFeature(server), false); // required for AqlFeature::stop()
|
||||
features.emplace_back(new arangodb::DatabasePathFeature(server), false);
|
||||
features.emplace_back(new arangodb::aql::AqlFunctionFeature(server), true); // required for IResearchAnalyzerFeature
|
||||
|
@ -129,6 +127,12 @@ struct IResearchLinkSetup {
|
|||
f.first->prepare();
|
||||
}
|
||||
|
||||
auto const databases = arangodb::velocypack::Parser::fromJson(std::string("[ { \"name\": \"") + arangodb::StaticStrings::SystemDatabase + "\" } ]");
|
||||
auto* dbFeature = arangodb::application_features::ApplicationServer::lookupFeature<
|
||||
arangodb::DatabaseFeature
|
||||
>("Database");
|
||||
dbFeature->loadDatabases(databases->slice());
|
||||
|
||||
for (auto& f : features) {
|
||||
if (f.second) {
|
||||
f.first->start();
|
||||
|
@ -139,12 +143,6 @@ struct IResearchLinkSetup {
|
|||
TransactionStateMock::beginTransactionCount = 0;
|
||||
TransactionStateMock::commitTransactionCount = 0;
|
||||
|
||||
auto const databases = arangodb::velocypack::Parser::fromJson(std::string("[ { \"name\": \"") + arangodb::StaticStrings::SystemDatabase + "\" } ]");
|
||||
auto* dbFeature = arangodb::application_features::ApplicationServer::lookupFeature<
|
||||
arangodb::DatabaseFeature
|
||||
>("Database");
|
||||
dbFeature->loadDatabases(databases->slice());
|
||||
|
||||
auto* dbPathFeature = arangodb::application_features::ApplicationServer::getFeature<arangodb::DatabasePathFeature>("DatabasePath");
|
||||
arangodb::tests::setDatabasePath(*dbPathFeature); // ensure test data is stored in a unique directory
|
||||
testFilesystemPath = dbPathFeature->directory();
|
||||
|
@ -155,7 +153,6 @@ struct IResearchLinkSetup {
|
|||
}
|
||||
|
||||
~IResearchLinkSetup() {
|
||||
system.reset(); // destroy before reseting the 'ENGINE'
|
||||
arangodb::application_features::ApplicationServer::lookupFeature<arangodb::SystemDatabaseFeature>()->unprepare(); // release system database before reseting the 'ENGINE'
|
||||
TRI_RemoveDirectory(testFilesystemPath.c_str());
|
||||
arangodb::LogTopic::setLogLevel(arangodb::iresearch::TOPIC.name(), arangodb::LogLevel::DEFAULT);
|
||||
|
|
|
@ -76,7 +76,7 @@ struct IResearchLinkHelperSetup {
|
|||
features.emplace_back(new arangodb::DatabaseFeature(server), false);
|
||||
features.emplace_back(new arangodb::DatabasePathFeature(server), false); // required for IResearchLink::init(...)
|
||||
features.emplace_back(new arangodb::QueryRegistryFeature(server), false); // required for constructing TRI_vocbase_t
|
||||
features.emplace_back(new arangodb::SystemDatabaseFeature(server), false); // required by IResearchAnalyzerFeature::storeAnalyzer(...)
|
||||
features.emplace_back(new arangodb::SystemDatabaseFeature(server), true); // required by IResearchAnalyzerFeature::storeAnalyzer(...)
|
||||
features.emplace_back(new arangodb::TraverserEngineRegistryFeature(server), false); // required for AqlFeature::stop()
|
||||
features.emplace_back(new arangodb::V8DealerFeature(server), false); // required for DatabaseFeature::createDatabase(...)
|
||||
features.emplace_back(new arangodb::ViewTypesFeature(server), false); // required for LogicalView::instantiate(...)
|
||||
|
@ -100,22 +100,17 @@ struct IResearchLinkHelperSetup {
|
|||
f.first->prepare();
|
||||
}
|
||||
|
||||
for (auto& f: features) {
|
||||
if (f.second) {
|
||||
f.first->start();
|
||||
}
|
||||
}
|
||||
|
||||
auto const databases = arangodb::velocypack::Parser::fromJson(std::string("[ { \"name\": \"") + arangodb::StaticStrings::SystemDatabase + "\" } ]");
|
||||
auto* dbFeature = arangodb::application_features::ApplicationServer::lookupFeature<
|
||||
arangodb::DatabaseFeature
|
||||
>("Database");
|
||||
dbFeature->loadDatabases(databases->slice());
|
||||
|
||||
auto* sysDatabase = arangodb::application_features::ApplicationServer::lookupFeature<
|
||||
arangodb::SystemDatabaseFeature
|
||||
>();
|
||||
sysDatabase->start(); // load system database after loadDatabases()
|
||||
for (auto& f: features) {
|
||||
if (f.second) {
|
||||
f.first->start();
|
||||
}
|
||||
}
|
||||
|
||||
auto* dbPathFeature = arangodb::application_features::ApplicationServer::getFeature<arangodb::DatabasePathFeature>("DatabasePath");
|
||||
arangodb::tests::setDatabasePath(*dbPathFeature); // ensure test data is stored in a unique directory
|
||||
|
@ -266,7 +261,7 @@ SECTION("test_normalize") {
|
|||
arangodb::velocypack::Builder builder;
|
||||
builder.openObject();
|
||||
CHECK((false == arangodb::iresearch::IResearchLinkHelper::normalize(builder, json->slice(), false, *sysVocbase).ok()));
|
||||
CHECK((true == !analyzers->get("testAnalyzer1")));
|
||||
CHECK((true == !analyzers->get(arangodb::StaticStrings::SystemDatabase + "::testAnalyzer1")));
|
||||
}
|
||||
|
||||
// analyzer single-server (inRecovery) fail persist in recovery
|
||||
|
@ -278,7 +273,7 @@ SECTION("test_normalize") {
|
|||
arangodb::velocypack::Builder builder;
|
||||
builder.openObject();
|
||||
CHECK((false == arangodb::iresearch::IResearchLinkHelper::normalize(builder, json->slice(), false, *sysVocbase).ok()));
|
||||
CHECK((true == !analyzers->get("testAnalyzer2")));
|
||||
CHECK((true == !analyzers->get(arangodb::StaticStrings::SystemDatabase + "::testAnalyzer2")));
|
||||
}
|
||||
|
||||
// analyzer single-server (no engine) fail persist if not storage engine, else SEGFAULT in Methods(...)
|
||||
|
@ -290,7 +285,7 @@ SECTION("test_normalize") {
|
|||
arangodb::velocypack::Builder builder;
|
||||
builder.openObject();
|
||||
CHECK((false == arangodb::iresearch::IResearchLinkHelper::normalize(builder, json->slice(), false, *sysVocbase).ok()));
|
||||
CHECK((true == !analyzers->get("testAnalyzer3")));
|
||||
CHECK((true == !analyzers->get(arangodb::StaticStrings::SystemDatabase + "::testAnalyzer3")));
|
||||
}
|
||||
|
||||
// analyzer coordinator
|
||||
|
@ -302,7 +297,7 @@ SECTION("test_normalize") {
|
|||
arangodb::velocypack::Builder builder;
|
||||
builder.openObject();
|
||||
CHECK((false == arangodb::iresearch::IResearchLinkHelper::normalize(builder, json->slice(), false, *sysVocbase).ok()));
|
||||
CHECK((true == !analyzers->get("testAnalyzer4")));
|
||||
CHECK((true == !analyzers->get(arangodb::StaticStrings::SystemDatabase + "::testAnalyzer4")));
|
||||
}
|
||||
|
||||
// analyzer coordinator (inRecovery) fail persist in recovery
|
||||
|
@ -317,7 +312,7 @@ SECTION("test_normalize") {
|
|||
arangodb::velocypack::Builder builder;
|
||||
builder.openObject();
|
||||
CHECK((false == arangodb::iresearch::IResearchLinkHelper::normalize(builder, json->slice(), false, *sysVocbase).ok()));
|
||||
CHECK((true == !analyzers->get("testAnalyzer5")));
|
||||
CHECK((true == !analyzers->get(arangodb::StaticStrings::SystemDatabase + "::testAnalyzer5")));
|
||||
}
|
||||
|
||||
// analyzer coordinator (no engine)
|
||||
|
@ -332,7 +327,7 @@ SECTION("test_normalize") {
|
|||
arangodb::velocypack::Builder builder;
|
||||
builder.openObject();
|
||||
CHECK((false == arangodb::iresearch::IResearchLinkHelper::normalize(builder, json->slice(), false, *sysVocbase).ok()));
|
||||
CHECK((true == !analyzers->get("testAnalyzer6")));
|
||||
CHECK((true == !analyzers->get(arangodb::StaticStrings::SystemDatabase + "::testAnalyzer6")));
|
||||
}
|
||||
|
||||
// analyzer db-server
|
||||
|
@ -343,9 +338,9 @@ SECTION("test_normalize") {
|
|||
auto serverRoleRestore = irs::make_finally([&before]()->void { arangodb::ServerState::instance()->setRole(before); });
|
||||
arangodb::velocypack::Builder builder;
|
||||
builder.openObject();
|
||||
CHECK((true == !analyzers->get("testAnalyzer7")));
|
||||
CHECK((true == !analyzers->get(arangodb::StaticStrings::SystemDatabase + "::testAnalyzer7")));
|
||||
CHECK((true == arangodb::iresearch::IResearchLinkHelper::normalize(builder, json->slice(), false, *sysVocbase).ok()));
|
||||
CHECK((false == !analyzers->get("testAnalyzer7")));
|
||||
CHECK((false == !analyzers->get(arangodb::StaticStrings::SystemDatabase + "::testAnalyzer7")));
|
||||
}
|
||||
|
||||
// meta has analyzer which is not authorised
|
||||
|
|
|
@ -156,8 +156,8 @@ struct IResearchLinkMetaSetup {
|
|||
>();
|
||||
arangodb::iresearch::IResearchAnalyzerFeature::EmplaceResult result;
|
||||
|
||||
analyzers->emplace(result, "empty", "empty", "en", irs::flags{ TestAttributeZ::type() }); // cache the 'empty' analyzer
|
||||
analyzers->emplace(result, "testVocbase::empty", "empty", "de", irs::flags{ TestAttributeZ::type() }); // cache the 'empty' analyzer for 'testVocbase'
|
||||
analyzers->emplace(result, "empty", "empty", "en", irs::flags{ irs::frequency::type() }); // cache the 'empty' analyzer
|
||||
analyzers->emplace(result, "testVocbase::empty", "empty", "de", irs::flags{ irs::frequency::type() }); // cache the 'empty' analyzer for 'testVocbase'
|
||||
|
||||
// suppress log messages since tests check error conditions
|
||||
arangodb::LogTopic::setLogLevel(arangodb::iresearch::TOPIC.name(), arangodb::LogLevel::FATAL);
|
||||
|
@ -226,7 +226,7 @@ SECTION("test_inheritDefaults") {
|
|||
defaults._trackListPositions = true;
|
||||
defaults._storeValues = arangodb::iresearch::ValueStorage::FULL;
|
||||
defaults._analyzers.clear();
|
||||
defaults._analyzers.emplace_back(analyzers.ensure("empty"));
|
||||
defaults._analyzers.emplace_back(analyzers.get(arangodb::StaticStrings::SystemDatabase + "::empty"));
|
||||
defaults._fields["abc"]->_fields["xyz"] = arangodb::iresearch::IResearchLinkMeta();
|
||||
|
||||
auto json = arangodb::velocypack::Parser::fromJson("{}");
|
||||
|
@ -263,7 +263,7 @@ SECTION("test_inheritDefaults") {
|
|||
|
||||
CHECK(1U == meta._analyzers.size());
|
||||
CHECK((*(meta._analyzers.begin())));
|
||||
CHECK(("empty" == (*(meta._analyzers.begin()))->name()));
|
||||
CHECK((arangodb::StaticStrings::SystemDatabase + "::empty" == (*(meta._analyzers.begin()))->name()));
|
||||
CHECK((irs::flags() == (*(meta._analyzers.begin()))->features()));
|
||||
CHECK(false == !meta._analyzers.begin()->get());
|
||||
}
|
||||
|
@ -363,7 +363,7 @@ SECTION("test_readCustomizedValues") {
|
|||
CHECK(1U == actual._analyzers.size());
|
||||
CHECK((*(actual._analyzers.begin())));
|
||||
CHECK(("empty" == (*(actual._analyzers.begin()))->name()));
|
||||
CHECK((irs::flags({TestAttributeZ::type()}) == (*(actual._analyzers.begin()))->features()));
|
||||
CHECK((irs::flags({irs::frequency::type()}) == (*(actual._analyzers.begin()))->features()));
|
||||
CHECK(false == !actual._analyzers.begin()->get());
|
||||
} else if ("some" == fieldOverride.key()) {
|
||||
CHECK(true == actual._fields.empty()); // not inherited
|
||||
|
@ -374,7 +374,7 @@ SECTION("test_readCustomizedValues") {
|
|||
auto itr = actual._analyzers.begin();
|
||||
CHECK((*itr));
|
||||
CHECK(("empty" == (*itr)->name()));
|
||||
CHECK((irs::flags({TestAttributeZ::type()}) == (*itr)->features()));
|
||||
CHECK((irs::flags({irs::frequency::type()}) == (*itr)->features()));
|
||||
CHECK(false == !itr->get());
|
||||
++itr;
|
||||
CHECK((*itr));
|
||||
|
@ -389,7 +389,7 @@ SECTION("test_readCustomizedValues") {
|
|||
auto itr = actual._analyzers.begin();
|
||||
CHECK((*itr));
|
||||
CHECK(("empty" == (*itr)->name()));
|
||||
CHECK((irs::flags({TestAttributeZ::type()}) == (*itr)->features()));
|
||||
CHECK((irs::flags({irs::frequency::type()}) == (*itr)->features()));
|
||||
CHECK(false == !itr->get());
|
||||
++itr;
|
||||
CHECK((*itr));
|
||||
|
@ -408,7 +408,7 @@ SECTION("test_readCustomizedValues") {
|
|||
auto itr = meta._analyzers.begin();
|
||||
CHECK((*itr));
|
||||
CHECK(("empty" == (*itr)->name()));
|
||||
CHECK((irs::flags({TestAttributeZ::type()}) == (*itr)->features()));
|
||||
CHECK((irs::flags({irs::frequency::type()}) == (*itr)->features()));
|
||||
CHECK(false == !itr->get());
|
||||
++itr;
|
||||
CHECK((*itr));
|
||||
|
@ -455,10 +455,8 @@ SECTION("test_readCustomizedValues") {
|
|||
CHECK((arangodb::iresearch::ValueStorage::FULL == actual._storeValues));
|
||||
CHECK((1U == actual._analyzers.size()));
|
||||
CHECK((*(actual._analyzers.begin())));
|
||||
/* FIXME TODO uncomment once emplace(...) and all tests are updated
|
||||
CHECK(("testVocbase::empty" == (*(actual._analyzers.begin()))->name()));
|
||||
*/
|
||||
CHECK((irs::flags({TestAttributeZ::type()}) == (*(actual._analyzers.begin()))->features()));
|
||||
CHECK((irs::flags({irs::frequency::type()}) == (*(actual._analyzers.begin()))->features()));
|
||||
CHECK((false == !actual._analyzers.begin()->get()));
|
||||
} else if ("some" == fieldOverride.key()) {
|
||||
CHECK((true == actual._fields.empty())); // not inherited
|
||||
|
@ -468,10 +466,8 @@ SECTION("test_readCustomizedValues") {
|
|||
CHECK((2U == actual._analyzers.size()));
|
||||
auto itr = actual._analyzers.begin();
|
||||
CHECK((*itr));
|
||||
/* FIXME TODO uncomment once emplace(...) and all tests are updated
|
||||
CHECK(("testVocbase::empty" == (*itr)->name()));
|
||||
*/
|
||||
CHECK((irs::flags({TestAttributeZ::type()}) == (*itr)->features()));
|
||||
CHECK((irs::flags({irs::frequency::type()}) == (*itr)->features()));
|
||||
CHECK((false == !itr->get()));
|
||||
++itr;
|
||||
CHECK((*itr));
|
||||
|
@ -485,10 +481,8 @@ SECTION("test_readCustomizedValues") {
|
|||
CHECK((arangodb::iresearch::ValueStorage::FULL == actual._storeValues));
|
||||
auto itr = actual._analyzers.begin();
|
||||
CHECK((*itr));
|
||||
/* FIXME TODO uncomment once emplace(...) and all tests are updated
|
||||
CHECK(("testVocbase::empty" == (*itr)->name()));
|
||||
*/
|
||||
CHECK((irs::flags({TestAttributeZ::type()}) == (*itr)->features()));
|
||||
CHECK((irs::flags({irs::frequency::type()}) == (*itr)->features()));
|
||||
CHECK((false == !itr->get()));
|
||||
++itr;
|
||||
CHECK((*itr));
|
||||
|
@ -506,10 +500,8 @@ SECTION("test_readCustomizedValues") {
|
|||
CHECK((arangodb::iresearch::ValueStorage::FULL == meta._storeValues));
|
||||
auto itr = meta._analyzers.begin();
|
||||
CHECK((*itr));
|
||||
/* FIXME TODO uncomment once emplace(...) and all tests are updated
|
||||
CHECK(("testVocbase::empty" == (*itr)->name()));
|
||||
*/
|
||||
CHECK((irs::flags({TestAttributeZ::type()}) == (*itr)->features()));
|
||||
CHECK((irs::flags({irs::frequency::type()}) == (*itr)->features()));
|
||||
CHECK((false == !itr->get()));
|
||||
++itr;
|
||||
CHECK((*itr));
|
||||
|
@ -656,7 +648,7 @@ SECTION("test_writeCustomizedValues") {
|
|||
arangodb::iresearch::IResearchAnalyzerFeature::EmplaceResult emplaceResult;
|
||||
arangodb::iresearch::IResearchLinkMeta meta;
|
||||
|
||||
analyzers.emplace(emplaceResult, "empty", "empty", "en", { irs::attribute::type_id::get("position") });
|
||||
analyzers.emplace(emplaceResult, "empty", "empty", "en", { irs::frequency::type() });
|
||||
|
||||
meta._includeAllFields = true;
|
||||
meta._trackListPositions = true;
|
||||
|
@ -879,7 +871,7 @@ SECTION("test_writeCustomizedValues") {
|
|||
&& tmpSlice.at(0).get("type").isString() && std::string("empty") == tmpSlice.at(0).get("type").copyString()
|
||||
&& tmpSlice.at(0).get("properties").isString() && std::string("en") == tmpSlice.at(0).get("properties").copyString()
|
||||
&& tmpSlice.at(0).get("features").isArray() && 1 == tmpSlice.at(0).get("features").length()
|
||||
&& tmpSlice.at(0).get("features").at(0).isString() && std::string("position") == tmpSlice.at(0).get("features").at(0).copyString()
|
||||
&& tmpSlice.at(0).get("features").at(0).isString() && std::string("frequency") == tmpSlice.at(0).get("features").at(0).copyString()
|
||||
));
|
||||
} else if ("some" == fieldOverride.copyString()) {
|
||||
CHECK((2U == sliceOverride.length()));
|
||||
|
@ -1108,7 +1100,7 @@ SECTION("test_writeCustomizedValues") {
|
|||
&& tmpSlice.at(0).get("type").isString() && std::string("empty") == tmpSlice.at(0).get("type").copyString()
|
||||
&& tmpSlice.at(0).get("properties").isString() && std::string("en") == tmpSlice.at(0).get("properties").copyString()
|
||||
&& tmpSlice.at(0).get("features").isArray() && 1 == tmpSlice.at(0).get("features").length()
|
||||
&& tmpSlice.at(0).get("features").at(0).isString() && std::string("position") == tmpSlice.at(0).get("features").at(0).copyString()
|
||||
&& tmpSlice.at(0).get("features").at(0).isString() && std::string("frequency") == tmpSlice.at(0).get("features").at(0).copyString()
|
||||
));
|
||||
} else if ("some" == fieldOverride.copyString()) {
|
||||
CHECK((2U == sliceOverride.length()));
|
||||
|
@ -1389,7 +1381,7 @@ SECTION("test_readAnalyzerDefinitions") {
|
|||
CHECK((std::string("empty") == meta._analyzers[0]->type()));
|
||||
CHECK((std::string("en") == meta._analyzers[0]->properties()));
|
||||
CHECK((1 == meta._analyzers[0]->features().size()));
|
||||
CHECK((true == meta._analyzers[0]->features().check(TestAttributeZ::type())));
|
||||
CHECK((true == meta._analyzers[0]->features().check(irs::frequency::type())));
|
||||
}
|
||||
|
||||
// existing analyzer (name only) inRecovery
|
||||
|
@ -1408,13 +1400,13 @@ SECTION("test_readAnalyzerDefinitions") {
|
|||
CHECK((std::string("empty") == meta._analyzers[0]->type()));
|
||||
CHECK((std::string("en") == meta._analyzers[0]->properties()));
|
||||
CHECK((1 == meta._analyzers[0]->features().size()));
|
||||
CHECK((true == meta._analyzers[0]->features().check(TestAttributeZ::type())));
|
||||
CHECK((true == meta._analyzers[0]->features().check(irs::frequency::type())));
|
||||
}
|
||||
|
||||
// existing analyzer (full) analyzer creation not allowed (passs)
|
||||
{
|
||||
auto json = arangodb::velocypack::Parser::fromJson("{ \
|
||||
\"analyzers\": [ { \"name\": \"empty\", \"type\": \"empty\", \"properties\": \"en\", \"features\": [ \"TestAttributeZ\" ] } ] \
|
||||
\"analyzers\": [ { \"name\": \"empty\", \"type\": \"empty\", \"properties\": \"en\", \"features\": [ \"frequency\" ] } ] \
|
||||
}");
|
||||
arangodb::iresearch::IResearchLinkMeta meta;
|
||||
std::string errorField;
|
||||
|
@ -1424,13 +1416,13 @@ SECTION("test_readAnalyzerDefinitions") {
|
|||
CHECK((std::string("empty") == meta._analyzers[0]->type()));
|
||||
CHECK((std::string("en") == meta._analyzers[0]->properties()));
|
||||
CHECK((1 == meta._analyzers[0]->features().size()));
|
||||
CHECK((true == meta._analyzers[0]->features().check(TestAttributeZ::type())));
|
||||
CHECK((true == meta._analyzers[0]->features().check(irs::frequency::type())));
|
||||
}
|
||||
|
||||
// existing analyzer (full)
|
||||
{
|
||||
auto json = arangodb::velocypack::Parser::fromJson("{ \
|
||||
\"analyzers\": [ { \"name\": \"empty\", \"type\": \"empty\", \"properties\": \"en\", \"features\": [ \"TestAttributeZ\" ] } ] \
|
||||
\"analyzers\": [ { \"name\": \"empty\", \"type\": \"empty\", \"properties\": \"en\", \"features\": [ \"frequency\" ] } ] \
|
||||
}");
|
||||
arangodb::iresearch::IResearchLinkMeta meta;
|
||||
std::string errorField;
|
||||
|
@ -1440,13 +1432,13 @@ SECTION("test_readAnalyzerDefinitions") {
|
|||
CHECK((std::string("empty") == meta._analyzers[0]->type()));
|
||||
CHECK((std::string("en") == meta._analyzers[0]->properties()));
|
||||
CHECK((1 == meta._analyzers[0]->features().size()));
|
||||
CHECK((true == meta._analyzers[0]->features().check(TestAttributeZ::type())));
|
||||
CHECK((true == meta._analyzers[0]->features().check(irs::frequency::type())));
|
||||
}
|
||||
|
||||
// existing analyzer (full) inRecovery
|
||||
{
|
||||
auto json = arangodb::velocypack::Parser::fromJson("{ \
|
||||
\"analyzers\": [ { \"name\": \"empty\", \"type\": \"empty\", \"properties\": \"en\", \"features\": [ \"TestAttributeZ\" ] } ] \
|
||||
\"analyzers\": [ { \"name\": \"empty\", \"type\": \"empty\", \"properties\": \"en\", \"features\": [ \"frequency\" ] } ] \
|
||||
}");
|
||||
auto before = StorageEngineMock::inRecoveryResult;
|
||||
StorageEngineMock::inRecoveryResult = true;
|
||||
|
@ -1459,13 +1451,13 @@ SECTION("test_readAnalyzerDefinitions") {
|
|||
CHECK((std::string("empty") == meta._analyzers[0]->type()));
|
||||
CHECK((std::string("en") == meta._analyzers[0]->properties()));
|
||||
CHECK((1 == meta._analyzers[0]->features().size()));
|
||||
CHECK((true == meta._analyzers[0]->features().check(TestAttributeZ::type())));
|
||||
CHECK((true == meta._analyzers[0]->features().check(irs::frequency::type())));
|
||||
}
|
||||
|
||||
// existing analyzer (definition mismatch)
|
||||
{
|
||||
auto json = arangodb::velocypack::Parser::fromJson("{ \
|
||||
\"analyzers\": [ { \"name\": \"empty\", \"type\": \"empty\", \"properties\": \"ru\", \"features\": [ \"TestAttributeZ\" ] } ] \
|
||||
\"analyzers\": [ { \"name\": \"empty\", \"type\": \"empty\", \"properties\": \"ru\", \"features\": [ \"frequency\" ] } ] \
|
||||
}");
|
||||
arangodb::iresearch::IResearchLinkMeta meta;
|
||||
std::string errorField;
|
||||
|
@ -1476,7 +1468,7 @@ SECTION("test_readAnalyzerDefinitions") {
|
|||
// existing analyzer (definition mismatch) inRecovery
|
||||
{
|
||||
auto json = arangodb::velocypack::Parser::fromJson("{ \
|
||||
\"analyzers\": [ { \"name\": \"empty\", \"type\": \"empty\", \"properties\": \"ru\", \"features\": [ \"TestAttributeZ\" ] } ] \
|
||||
\"analyzers\": [ { \"name\": \"empty\", \"type\": \"empty\", \"properties\": \"ru\", \"features\": [ \"frequency\" ] } ] \
|
||||
}");
|
||||
auto before = StorageEngineMock::inRecoveryResult;
|
||||
StorageEngineMock::inRecoveryResult = true;
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include "Aql/OptimizerRulesFeature.h"
|
||||
#include "Aql/Query.h"
|
||||
#include "Basics/VelocyPackHelper.h"
|
||||
#include "Cluster/ClusterFeature.h"
|
||||
#include "GeneralServer/AuthenticationFeature.h"
|
||||
#include "IResearch/IResearchCommon.h"
|
||||
#include "IResearch/IResearchFeature.h"
|
||||
|
@ -53,6 +54,7 @@
|
|||
#include "RestServer/TraverserEngineRegistryFeature.h"
|
||||
#include "Sharding/ShardingFeature.h"
|
||||
#include "V8/v8-globals.h"
|
||||
#include "V8Server/V8DealerFeature.h"
|
||||
#include "VocBase/LogicalCollection.h"
|
||||
#include "VocBase/LogicalView.h"
|
||||
|
||||
|
@ -78,7 +80,6 @@ namespace {
|
|||
struct IResearchQueryAndSetup {
|
||||
StorageEngineMock engine;
|
||||
arangodb::application_features::ApplicationServer server;
|
||||
std::unique_ptr<TRI_vocbase_t> system;
|
||||
std::vector<std::pair<arangodb::application_features::ApplicationFeature*, bool>> features;
|
||||
|
||||
IResearchQueryAndSetup(): engine(server), server(nullptr, nullptr) {
|
||||
|
@ -96,6 +97,7 @@ struct IResearchQueryAndSetup {
|
|||
irs::logger::output_le(iresearch::logger::IRL_FATAL, stderr);
|
||||
|
||||
// setup required application features
|
||||
features.emplace_back(new arangodb::V8DealerFeature(server), false); // required for DatabaseFeature::createDatabase(...)
|
||||
features.emplace_back(new arangodb::ViewTypesFeature(server), true);
|
||||
features.emplace_back(new arangodb::AuthenticationFeature(server), true);
|
||||
features.emplace_back(new arangodb::DatabasePathFeature(server), false);
|
||||
|
@ -103,8 +105,7 @@ struct IResearchQueryAndSetup {
|
|||
features.emplace_back(new arangodb::ShardingFeature(server), false); //
|
||||
features.emplace_back(new arangodb::QueryRegistryFeature(server), false); // must be first
|
||||
arangodb::application_features::ApplicationServer::server->addFeature(features.back().first); // need QueryRegistryFeature feature to be added now in order to create the system database
|
||||
system = irs::memory::make_unique<TRI_vocbase_t>(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 0, TRI_VOC_SYSTEM_DATABASE);
|
||||
features.emplace_back(new arangodb::SystemDatabaseFeature(server, system.get()), false); // required for IResearchAnalyzerFeature
|
||||
features.emplace_back(new arangodb::SystemDatabaseFeature(server), true); // required for IResearchAnalyzerFeature
|
||||
features.emplace_back(new arangodb::TraverserEngineRegistryFeature(server), false); // must be before AqlFeature
|
||||
features.emplace_back(new arangodb::AqlFeature(server), true);
|
||||
features.emplace_back(new arangodb::aql::OptimizerRulesFeature(server), true);
|
||||
|
@ -116,6 +117,11 @@ struct IResearchQueryAndSetup {
|
|||
features.emplace_back(new arangodb::LdapFeature(server), false); // required for AuthenticationFeature with USE_ENTERPRISE
|
||||
#endif
|
||||
|
||||
// required for V8DealerFeature::prepare(), ClusterFeature::prepare() not required
|
||||
arangodb::application_features::ApplicationServer::server->addFeature(
|
||||
new arangodb::ClusterFeature(server)
|
||||
);
|
||||
|
||||
for (auto& f : features) {
|
||||
arangodb::application_features::ApplicationServer::server->addFeature(f.first);
|
||||
}
|
||||
|
@ -124,6 +130,12 @@ struct IResearchQueryAndSetup {
|
|||
f.first->prepare();
|
||||
}
|
||||
|
||||
auto const databases = arangodb::velocypack::Parser::fromJson(std::string("[ { \"name\": \"") + arangodb::StaticStrings::SystemDatabase + "\" } ]");
|
||||
auto* dbFeature = arangodb::application_features::ApplicationServer::lookupFeature<
|
||||
arangodb::DatabaseFeature
|
||||
>("Database");
|
||||
dbFeature->loadDatabases(databases->slice());
|
||||
|
||||
for (auto& f : features) {
|
||||
if (f.second) {
|
||||
f.first->start();
|
||||
|
@ -134,22 +146,22 @@ struct IResearchQueryAndSetup {
|
|||
arangodb::iresearch::IResearchAnalyzerFeature
|
||||
>();
|
||||
arangodb::iresearch::IResearchAnalyzerFeature::EmplaceResult result;
|
||||
TRI_vocbase_t* vocbase;
|
||||
|
||||
analyzers->emplace(result, "test_analyzer", "TestAnalyzer", "abc"); // cache analyzer
|
||||
analyzers->emplace(result, "test_csv_analyzer", "TestDelimAnalyzer", ","); // cache analyzer
|
||||
dbFeature->createDatabase(1, "testVocbase", vocbase); // required for IResearchAnalyzerFeature::emplace(...)
|
||||
analyzers->emplace(result, "testVocbase::test_analyzer", "TestAnalyzer", "abc"); // cache analyzer
|
||||
analyzers->emplace(result, "testVocbase::test_csv_analyzer", "TestDelimAnalyzer", ","); // cache analyzer
|
||||
|
||||
auto* dbPathFeature = arangodb::application_features::ApplicationServer::getFeature<arangodb::DatabasePathFeature>("DatabasePath");
|
||||
arangodb::tests::setDatabasePath(*dbPathFeature); // ensure test data is stored in a unique directory
|
||||
}
|
||||
|
||||
~IResearchQueryAndSetup() {
|
||||
system.reset(); // destroy before reseting the 'ENGINE'
|
||||
arangodb::AqlFeature(server).stop(); // unset singleton instance
|
||||
arangodb::LogTopic::setLogLevel(arangodb::iresearch::TOPIC.name(), arangodb::LogLevel::DEFAULT);
|
||||
arangodb::LogTopic::setLogLevel(arangodb::Logger::FIXME.name(), arangodb::LogLevel::DEFAULT);
|
||||
arangodb::LogTopic::setLogLevel(arangodb::Logger::AQL.name(), arangodb::LogLevel::DEFAULT);
|
||||
arangodb::application_features::ApplicationServer::server = nullptr;
|
||||
arangodb::EngineSelectorFeature::ENGINE = nullptr;
|
||||
|
||||
// destroy application features
|
||||
for (auto& f : features) {
|
||||
|
@ -163,6 +175,7 @@ struct IResearchQueryAndSetup {
|
|||
}
|
||||
|
||||
arangodb::LogTopic::setLogLevel(arangodb::Logger::AUTHENTICATION.name(), arangodb::LogLevel::DEFAULT);
|
||||
arangodb::EngineSelectorFeature::ENGINE = nullptr;
|
||||
}
|
||||
}; // IResearchQuerySetup
|
||||
|
||||
|
|
|
@ -30,7 +30,9 @@
|
|||
#include "Enterprise/Ldap/LdapFeature.h"
|
||||
#endif
|
||||
|
||||
#include "Cluster/ClusterFeature.h"
|
||||
#include "V8/v8-globals.h"
|
||||
#include "V8Server/V8DealerFeature.h"
|
||||
#include "VocBase/LogicalCollection.h"
|
||||
#include "VocBase/LogicalView.h"
|
||||
#include "Transaction/StandaloneContext.h"
|
||||
|
@ -78,7 +80,6 @@ namespace {
|
|||
struct IResearchQueryComplexBooleanSetup {
|
||||
StorageEngineMock engine;
|
||||
arangodb::application_features::ApplicationServer server;
|
||||
std::unique_ptr<TRI_vocbase_t> system;
|
||||
std::vector<std::pair<arangodb::application_features::ApplicationFeature*, bool>> features;
|
||||
|
||||
IResearchQueryComplexBooleanSetup(): engine(server), server(nullptr, nullptr) {
|
||||
|
@ -96,6 +97,7 @@ struct IResearchQueryComplexBooleanSetup {
|
|||
irs::logger::output_le(iresearch::logger::IRL_FATAL, stderr);
|
||||
|
||||
// setup required application features
|
||||
features.emplace_back(new arangodb::V8DealerFeature(server), false); // required for DatabaseFeature::createDatabase(...)
|
||||
features.emplace_back(new arangodb::ViewTypesFeature(server), true);
|
||||
features.emplace_back(new arangodb::AuthenticationFeature(server), true);
|
||||
features.emplace_back(new arangodb::DatabasePathFeature(server), false);
|
||||
|
@ -103,8 +105,7 @@ struct IResearchQueryComplexBooleanSetup {
|
|||
features.emplace_back(new arangodb::ShardingFeature(server), false); //
|
||||
features.emplace_back(new arangodb::QueryRegistryFeature(server), false); // must be first
|
||||
arangodb::application_features::ApplicationServer::server->addFeature(features.back().first); // need QueryRegistryFeature feature to be added now in order to create the system database
|
||||
system = irs::memory::make_unique<TRI_vocbase_t>(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 0, TRI_VOC_SYSTEM_DATABASE);
|
||||
features.emplace_back(new arangodb::SystemDatabaseFeature(server, system.get()), false); // required for IResearchAnalyzerFeature
|
||||
features.emplace_back(new arangodb::SystemDatabaseFeature(server), true); // required for IResearchAnalyzerFeature
|
||||
features.emplace_back(new arangodb::TraverserEngineRegistryFeature(server), false); // must be before AqlFeature
|
||||
features.emplace_back(new arangodb::AqlFeature(server), true);
|
||||
features.emplace_back(new arangodb::aql::OptimizerRulesFeature(server), true);
|
||||
|
@ -116,6 +117,11 @@ struct IResearchQueryComplexBooleanSetup {
|
|||
features.emplace_back(new arangodb::LdapFeature(server), false); // required for AuthenticationFeature with USE_ENTERPRISE
|
||||
#endif
|
||||
|
||||
// required for V8DealerFeature::prepare(), ClusterFeature::prepare() not required
|
||||
arangodb::application_features::ApplicationServer::server->addFeature(
|
||||
new arangodb::ClusterFeature(server)
|
||||
);
|
||||
|
||||
for (auto& f : features) {
|
||||
arangodb::application_features::ApplicationServer::server->addFeature(f.first);
|
||||
}
|
||||
|
@ -124,6 +130,12 @@ struct IResearchQueryComplexBooleanSetup {
|
|||
f.first->prepare();
|
||||
}
|
||||
|
||||
auto const databases = arangodb::velocypack::Parser::fromJson(std::string("[ { \"name\": \"") + arangodb::StaticStrings::SystemDatabase + "\" } ]");
|
||||
auto* dbFeature = arangodb::application_features::ApplicationServer::lookupFeature<
|
||||
arangodb::DatabaseFeature
|
||||
>("Database");
|
||||
dbFeature->loadDatabases(databases->slice());
|
||||
|
||||
for (auto& f : features) {
|
||||
if (f.second) {
|
||||
f.first->start();
|
||||
|
@ -134,10 +146,12 @@ struct IResearchQueryComplexBooleanSetup {
|
|||
arangodb::iresearch::IResearchAnalyzerFeature
|
||||
>();
|
||||
arangodb::iresearch::IResearchAnalyzerFeature::EmplaceResult result;
|
||||
TRI_vocbase_t* vocbase;
|
||||
|
||||
dbFeature->createDatabase(1, "testVocbase", vocbase); // required for IResearchAnalyzerFeature::emplace(...)
|
||||
analyzers->emplace(
|
||||
result,
|
||||
"test_analyzer",
|
||||
"testVocbase::test_analyzer",
|
||||
"TestAnalyzer",
|
||||
"abc",
|
||||
irs::flags{ irs::frequency::type(), irs::position::type() } // required for PHRASE
|
||||
|
@ -145,7 +159,7 @@ struct IResearchQueryComplexBooleanSetup {
|
|||
|
||||
analyzers->emplace(
|
||||
result,
|
||||
"test_csv_analyzer",
|
||||
"testVocbase::test_csv_analyzer",
|
||||
"TestDelimAnalyzer",
|
||||
","
|
||||
); // cache analyzer
|
||||
|
@ -155,13 +169,11 @@ struct IResearchQueryComplexBooleanSetup {
|
|||
}
|
||||
|
||||
~IResearchQueryComplexBooleanSetup() {
|
||||
system.reset(); // destroy before reseting the 'ENGINE'
|
||||
arangodb::AqlFeature(server).stop(); // unset singleton instance
|
||||
arangodb::LogTopic::setLogLevel(arangodb::iresearch::TOPIC.name(), arangodb::LogLevel::DEFAULT);
|
||||
arangodb::LogTopic::setLogLevel(arangodb::Logger::FIXME.name(), arangodb::LogLevel::DEFAULT);
|
||||
arangodb::LogTopic::setLogLevel(arangodb::Logger::AQL.name(), arangodb::LogLevel::DEFAULT);
|
||||
arangodb::application_features::ApplicationServer::server = nullptr;
|
||||
arangodb::EngineSelectorFeature::ENGINE = nullptr;
|
||||
|
||||
// destroy application features
|
||||
for (auto& f : features) {
|
||||
|
@ -175,6 +187,7 @@ struct IResearchQueryComplexBooleanSetup {
|
|||
}
|
||||
|
||||
arangodb::LogTopic::setLogLevel(arangodb::Logger::AUTHENTICATION.name(), arangodb::LogLevel::DEFAULT);
|
||||
arangodb::EngineSelectorFeature::ENGINE = nullptr;
|
||||
}
|
||||
}; // IResearchQuerySetup
|
||||
|
||||
|
|
|
@ -82,7 +82,6 @@ namespace {
|
|||
struct IResearchQueryExistsSetup {
|
||||
StorageEngineMock engine;
|
||||
arangodb::application_features::ApplicationServer server;
|
||||
std::unique_ptr<TRI_vocbase_t> system;
|
||||
std::vector<std::pair<arangodb::application_features::ApplicationFeature*, bool>> features;
|
||||
|
||||
IResearchQueryExistsSetup(): engine(server), server(nullptr, nullptr) {
|
||||
|
@ -109,8 +108,7 @@ struct IResearchQueryExistsSetup {
|
|||
features.emplace_back(new arangodb::ShardingFeature(server), false);
|
||||
features.emplace_back(new arangodb::QueryRegistryFeature(server), false); // must be first
|
||||
arangodb::application_features::ApplicationServer::server->addFeature(features.back().first); // need QueryRegistryFeature feature to be added now in order to create the system database
|
||||
system = irs::memory::make_unique<TRI_vocbase_t>(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 0, TRI_VOC_SYSTEM_DATABASE);
|
||||
features.emplace_back(new arangodb::SystemDatabaseFeature(server, system.get()), false); // required for IResearchAnalyzerFeature
|
||||
features.emplace_back(new arangodb::SystemDatabaseFeature(server), true); // required for IResearchAnalyzerFeature
|
||||
features.emplace_back(new arangodb::TraverserEngineRegistryFeature(server), false); // must be before AqlFeature
|
||||
features.emplace_back(new arangodb::AqlFeature(server), true);
|
||||
features.emplace_back(new arangodb::aql::OptimizerRulesFeature(server), true);
|
||||
|
@ -147,12 +145,20 @@ struct IResearchQueryExistsSetup {
|
|||
}
|
||||
}
|
||||
|
||||
auto* analyzers = arangodb::application_features::ApplicationServer::lookupFeature<
|
||||
arangodb::iresearch::IResearchAnalyzerFeature
|
||||
>();
|
||||
arangodb::iresearch::IResearchAnalyzerFeature::EmplaceResult result;
|
||||
TRI_vocbase_t* vocbase;
|
||||
|
||||
dbFeature->createDatabase(1, "testVocbase", vocbase); // required for IResearchAnalyzerFeature::emplace(...)
|
||||
analyzers->emplace(result, "testVocbase::text_en", "text", "{ \"locale\": \"en.UTF-8\", \"ignored_words\": [ ] }", { irs::frequency::type(), irs::norm::type(), irs::position::type() }); // cache analyzer
|
||||
|
||||
auto* dbPathFeature = arangodb::application_features::ApplicationServer::getFeature<arangodb::DatabasePathFeature>("DatabasePath");
|
||||
arangodb::tests::setDatabasePath(*dbPathFeature); // ensure test data is stored in a unique directory
|
||||
}
|
||||
|
||||
~IResearchQueryExistsSetup() {
|
||||
system.reset(); // destroy before reseting the 'ENGINE'
|
||||
arangodb::AqlFeature(server).stop(); // unset singleton instance
|
||||
arangodb::LogTopic::setLogLevel(arangodb::iresearch::TOPIC.name(), arangodb::LogLevel::DEFAULT);
|
||||
arangodb::LogTopic::setLogLevel(arangodb::Logger::FIXME.name(), arangodb::LogLevel::DEFAULT);
|
||||
|
@ -189,21 +195,7 @@ TEST_CASE("IResearchQueryTestExists", "[iresearch][iresearch-query]") {
|
|||
IResearchQueryExistsSetup s;
|
||||
UNUSED(s);
|
||||
|
||||
auto* analyzers = arangodb::application_features::ApplicationServer::lookupFeature<
|
||||
arangodb::iresearch::IResearchAnalyzerFeature
|
||||
>();
|
||||
REQUIRE((nullptr != analyzers));
|
||||
auto* dbFeature = arangodb::application_features::ApplicationServer::lookupFeature<
|
||||
arangodb::DatabaseFeature
|
||||
>("Database");
|
||||
TRI_vocbase_t* vocbasePtr;
|
||||
REQUIRE((TRI_ERROR_NO_ERROR == dbFeature->createDatabase(1, "testVocbase", vocbasePtr))); // required for IResearchAnalyzerFeature::emplace(...)
|
||||
REQUIRE((nullptr != vocbasePtr));
|
||||
auto& vocbase = *vocbasePtr;
|
||||
//TRI_vocbase_t vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase");
|
||||
arangodb::iresearch::IResearchAnalyzerFeature::EmplaceResult result;
|
||||
REQUIRE((analyzers->emplace(result, "testVocbase::text_en", "text", "{ \"locale\": \"en.UTF-8\", \"ignored_words\": [ ] }", { irs::frequency::type(), irs::norm::type(), irs::position::type() }).ok()));
|
||||
REQUIRE((false == !result.first));
|
||||
TRI_vocbase_t vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase");
|
||||
std::vector<arangodb::velocypack::Builder> insertedDocs;
|
||||
arangodb::LogicalView* view;
|
||||
|
||||
|
|
|
@ -34,7 +34,9 @@
|
|||
#include "Aql/ExpressionContext.h"
|
||||
#include "Aql/OptimizerRulesFeature.h"
|
||||
#include "Aql/Query.h"
|
||||
#include "Cluster/ClusterFeature.h"
|
||||
#include "V8/v8-globals.h"
|
||||
#include "V8Server/V8DealerFeature.h"
|
||||
#include "VocBase/LogicalCollection.h"
|
||||
#include "VocBase/LogicalView.h"
|
||||
#include "Transaction/Methods.h"
|
||||
|
@ -85,7 +87,6 @@ namespace {
|
|||
struct IResearchQueryJoinSetup {
|
||||
StorageEngineMock engine;
|
||||
arangodb::application_features::ApplicationServer server;
|
||||
std::unique_ptr<TRI_vocbase_t> system;
|
||||
std::vector<std::pair<arangodb::application_features::ApplicationFeature*, bool>> features;
|
||||
|
||||
IResearchQueryJoinSetup(): engine(server), server(nullptr, nullptr) {
|
||||
|
@ -104,6 +105,7 @@ struct IResearchQueryJoinSetup {
|
|||
irs::logger::output_le(iresearch::logger::IRL_FATAL, stderr);
|
||||
|
||||
// setup required application features
|
||||
features.emplace_back(new arangodb::V8DealerFeature(server), false); // required for DatabaseFeature::createDatabase(...)
|
||||
features.emplace_back(new arangodb::ViewTypesFeature(server), true);
|
||||
features.emplace_back(new arangodb::AuthenticationFeature(server), true);
|
||||
features.emplace_back(new arangodb::DatabasePathFeature(server), false);
|
||||
|
@ -111,8 +113,7 @@ struct IResearchQueryJoinSetup {
|
|||
features.emplace_back(new arangodb::ShardingFeature(server), false);
|
||||
features.emplace_back(new arangodb::QueryRegistryFeature(server), false); // must be first
|
||||
arangodb::application_features::ApplicationServer::server->addFeature(features.back().first); // need QueryRegistryFeature feature to be added now in order to create the system database
|
||||
system = irs::memory::make_unique<TRI_vocbase_t>(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 0, TRI_VOC_SYSTEM_DATABASE);
|
||||
features.emplace_back(new arangodb::SystemDatabaseFeature(server, system.get()), false); // required for IResearchAnalyzerFeature
|
||||
features.emplace_back(new arangodb::SystemDatabaseFeature(server), true); // required for IResearchAnalyzerFeature
|
||||
features.emplace_back(new arangodb::TraverserEngineRegistryFeature(server), false); // must be before AqlFeature
|
||||
features.emplace_back(new arangodb::AqlFeature(server), true);
|
||||
features.emplace_back(new arangodb::aql::OptimizerRulesFeature(server), true);
|
||||
|
@ -124,6 +125,11 @@ struct IResearchQueryJoinSetup {
|
|||
features.emplace_back(new arangodb::LdapFeature(server), false); // required for AuthenticationFeature with USE_ENTERPRISE
|
||||
#endif
|
||||
|
||||
// required for V8DealerFeature::prepare(), ClusterFeature::prepare() not required
|
||||
arangodb::application_features::ApplicationServer::server->addFeature(
|
||||
new arangodb::ClusterFeature(server)
|
||||
);
|
||||
|
||||
for (auto& f : features) {
|
||||
arangodb::application_features::ApplicationServer::server->addFeature(f.first);
|
||||
}
|
||||
|
@ -132,6 +138,12 @@ struct IResearchQueryJoinSetup {
|
|||
f.first->prepare();
|
||||
}
|
||||
|
||||
auto const databases = arangodb::velocypack::Parser::fromJson(std::string("[ { \"name\": \"") + arangodb::StaticStrings::SystemDatabase + "\" } ]");
|
||||
auto* dbFeature = arangodb::application_features::ApplicationServer::lookupFeature<
|
||||
arangodb::DatabaseFeature
|
||||
>("Database");
|
||||
dbFeature->loadDatabases(databases->slice());
|
||||
|
||||
for (auto& f : features) {
|
||||
if (f.second) {
|
||||
f.first->start();
|
||||
|
@ -181,22 +193,22 @@ struct IResearchQueryJoinSetup {
|
|||
arangodb::iresearch::IResearchAnalyzerFeature
|
||||
>();
|
||||
arangodb::iresearch::IResearchAnalyzerFeature::EmplaceResult result;
|
||||
TRI_vocbase_t* vocbase;
|
||||
|
||||
analyzers->emplace(result, "test_analyzer", "TestAnalyzer", "abc"); // cache analyzer
|
||||
analyzers->emplace(result, "test_csv_analyzer", "TestDelimAnalyzer", ","); // cache analyzer
|
||||
dbFeature->createDatabase(1, "testVocbase", vocbase); // required for IResearchAnalyzerFeature::emplace(...)
|
||||
analyzers->emplace(result, "testVocbase::test_analyzer", "TestAnalyzer", "abc"); // cache analyzer
|
||||
analyzers->emplace(result, "testVocbase::test_csv_analyzer", "TestDelimAnalyzer", ","); // cache analyzer
|
||||
|
||||
auto* dbPathFeature = arangodb::application_features::ApplicationServer::getFeature<arangodb::DatabasePathFeature>("DatabasePath");
|
||||
arangodb::tests::setDatabasePath(*dbPathFeature); // ensure test data is stored in a unique directory
|
||||
}
|
||||
|
||||
~IResearchQueryJoinSetup() {
|
||||
system.reset(); // destroy before reseting the 'ENGINE'
|
||||
arangodb::AqlFeature(server).stop(); // unset singleton instance
|
||||
arangodb::LogTopic::setLogLevel(arangodb::iresearch::TOPIC.name(), arangodb::LogLevel::DEFAULT);
|
||||
arangodb::LogTopic::setLogLevel(arangodb::Logger::FIXME.name(), arangodb::LogLevel::DEFAULT);
|
||||
arangodb::LogTopic::setLogLevel(arangodb::Logger::AQL.name(), arangodb::LogLevel::DEFAULT);
|
||||
arangodb::application_features::ApplicationServer::server = nullptr;
|
||||
arangodb::EngineSelectorFeature::ENGINE = nullptr;
|
||||
|
||||
// destroy application features
|
||||
for (auto& f : features) {
|
||||
|
@ -210,6 +222,7 @@ struct IResearchQueryJoinSetup {
|
|||
}
|
||||
|
||||
arangodb::LogTopic::setLogLevel(arangodb::Logger::AUTHENTICATION.name(), arangodb::LogLevel::DEFAULT);
|
||||
arangodb::EngineSelectorFeature::ENGINE = nullptr;
|
||||
}
|
||||
}; // IResearchQuerySetup
|
||||
|
||||
|
|
|
@ -30,7 +30,9 @@
|
|||
#include "Enterprise/Ldap/LdapFeature.h"
|
||||
#endif
|
||||
|
||||
#include "Cluster/ClusterFeature.h"
|
||||
#include "V8/v8-globals.h"
|
||||
#include "V8Server/V8DealerFeature.h"
|
||||
#include "VocBase/LogicalCollection.h"
|
||||
#include "VocBase/LogicalView.h"
|
||||
#include "VocBase/ManagedDocumentResult.h"
|
||||
|
@ -79,7 +81,6 @@ namespace {
|
|||
struct IResearchQueryOrSetup {
|
||||
StorageEngineMock engine;
|
||||
arangodb::application_features::ApplicationServer server;
|
||||
std::unique_ptr<TRI_vocbase_t> system;
|
||||
std::vector<std::pair<arangodb::application_features::ApplicationFeature*, bool>> features;
|
||||
|
||||
IResearchQueryOrSetup(): engine(server), server(nullptr, nullptr) {
|
||||
|
@ -97,6 +98,7 @@ struct IResearchQueryOrSetup {
|
|||
irs::logger::output_le(iresearch::logger::IRL_FATAL, stderr);
|
||||
|
||||
// setup required application features
|
||||
features.emplace_back(new arangodb::V8DealerFeature(server), false); // required for DatabaseFeature::createDatabase(...)
|
||||
features.emplace_back(new arangodb::ViewTypesFeature(server), true);
|
||||
features.emplace_back(new arangodb::AuthenticationFeature(server), true);
|
||||
features.emplace_back(new arangodb::DatabasePathFeature(server), false);
|
||||
|
@ -104,8 +106,7 @@ struct IResearchQueryOrSetup {
|
|||
features.emplace_back(new arangodb::ShardingFeature(server), false);
|
||||
features.emplace_back(new arangodb::QueryRegistryFeature(server), false); // must be first
|
||||
arangodb::application_features::ApplicationServer::server->addFeature(features.back().first); // need QueryRegistryFeature feature to be added now in order to create the system database
|
||||
system = irs::memory::make_unique<TRI_vocbase_t>(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 0, TRI_VOC_SYSTEM_DATABASE);
|
||||
features.emplace_back(new arangodb::SystemDatabaseFeature(server, system.get()), false); // required for IResearchAnalyzerFeature
|
||||
features.emplace_back(new arangodb::SystemDatabaseFeature(server), true); // required for IResearchAnalyzerFeature
|
||||
features.emplace_back(new arangodb::TraverserEngineRegistryFeature(server), false); // must be before AqlFeature
|
||||
features.emplace_back(new arangodb::AqlFeature(server), true);
|
||||
features.emplace_back(new arangodb::aql::OptimizerRulesFeature(server), true);
|
||||
|
@ -117,6 +118,11 @@ struct IResearchQueryOrSetup {
|
|||
features.emplace_back(new arangodb::LdapFeature(server), false); // required for AuthenticationFeature with USE_ENTERPRISE
|
||||
#endif
|
||||
|
||||
// required for V8DealerFeature::prepare(), ClusterFeature::prepare() not required
|
||||
arangodb::application_features::ApplicationServer::server->addFeature(
|
||||
new arangodb::ClusterFeature(server)
|
||||
);
|
||||
|
||||
for (auto& f : features) {
|
||||
arangodb::application_features::ApplicationServer::server->addFeature(f.first);
|
||||
}
|
||||
|
@ -125,6 +131,12 @@ struct IResearchQueryOrSetup {
|
|||
f.first->prepare();
|
||||
}
|
||||
|
||||
auto const databases = arangodb::velocypack::Parser::fromJson(std::string("[ { \"name\": \"") + arangodb::StaticStrings::SystemDatabase + "\" } ]");
|
||||
auto* dbFeature = arangodb::application_features::ApplicationServer::lookupFeature<
|
||||
arangodb::DatabaseFeature
|
||||
>("Database");
|
||||
dbFeature->loadDatabases(databases->slice());
|
||||
|
||||
for (auto& f : features) {
|
||||
if (f.second) {
|
||||
f.first->start();
|
||||
|
@ -135,10 +147,12 @@ struct IResearchQueryOrSetup {
|
|||
arangodb::iresearch::IResearchAnalyzerFeature
|
||||
>();
|
||||
arangodb::iresearch::IResearchAnalyzerFeature::EmplaceResult result;
|
||||
TRI_vocbase_t* vocbase;
|
||||
|
||||
dbFeature->createDatabase(1, "testVocbase", vocbase); // required for IResearchAnalyzerFeature::emplace(...)
|
||||
analyzers->emplace(
|
||||
result,
|
||||
"test_analyzer",
|
||||
"testVocbase::test_analyzer",
|
||||
"TestAnalyzer",
|
||||
"abc",
|
||||
irs::flags{ irs::frequency::type(), irs::position::type() } // required for PHRASE
|
||||
|
@ -146,7 +160,7 @@ struct IResearchQueryOrSetup {
|
|||
|
||||
analyzers->emplace(
|
||||
result,
|
||||
"test_csv_analyzer",
|
||||
"testVocbase::test_csv_analyzer",
|
||||
"TestDelimAnalyzer",
|
||||
","
|
||||
); // cache analyzer
|
||||
|
@ -156,13 +170,11 @@ struct IResearchQueryOrSetup {
|
|||
}
|
||||
|
||||
~IResearchQueryOrSetup() {
|
||||
system.reset(); // destroy before reseting the 'ENGINE'
|
||||
arangodb::AqlFeature(server).stop(); // unset singleton instance
|
||||
arangodb::LogTopic::setLogLevel(arangodb::iresearch::TOPIC.name(), arangodb::LogLevel::DEFAULT);
|
||||
arangodb::LogTopic::setLogLevel(arangodb::Logger::FIXME.name(), arangodb::LogLevel::DEFAULT);
|
||||
arangodb::LogTopic::setLogLevel(arangodb::Logger::AQL.name(), arangodb::LogLevel::DEFAULT);
|
||||
arangodb::application_features::ApplicationServer::server = nullptr;
|
||||
arangodb::EngineSelectorFeature::ENGINE = nullptr;
|
||||
|
||||
// destroy application features
|
||||
for (auto& f : features) {
|
||||
|
@ -176,6 +188,7 @@ struct IResearchQueryOrSetup {
|
|||
}
|
||||
|
||||
arangodb::LogTopic::setLogLevel(arangodb::Logger::AUTHENTICATION.name(), arangodb::LogLevel::DEFAULT);
|
||||
arangodb::EngineSelectorFeature::ENGINE = nullptr;
|
||||
}
|
||||
}; // IResearchQuerySetup
|
||||
|
||||
|
|
|
@ -30,7 +30,9 @@
|
|||
#include "Enterprise/Ldap/LdapFeature.h"
|
||||
#endif
|
||||
|
||||
#include "Cluster/ClusterFeature.h"
|
||||
#include "V8/v8-globals.h"
|
||||
#include "V8Server/V8DealerFeature.h"
|
||||
#include "VocBase/LogicalCollection.h"
|
||||
#include "VocBase/LogicalView.h"
|
||||
#include "Transaction/StandaloneContext.h"
|
||||
|
@ -78,7 +80,6 @@ namespace {
|
|||
struct IResearchQueryPhraseSetup {
|
||||
StorageEngineMock engine;
|
||||
arangodb::application_features::ApplicationServer server;
|
||||
std::unique_ptr<TRI_vocbase_t> system;
|
||||
std::vector<std::pair<arangodb::application_features::ApplicationFeature*, bool>> features;
|
||||
|
||||
IResearchQueryPhraseSetup(): engine(server), server(nullptr, nullptr) {
|
||||
|
@ -96,6 +97,7 @@ struct IResearchQueryPhraseSetup {
|
|||
irs::logger::output_le(iresearch::logger::IRL_FATAL, stderr);
|
||||
|
||||
// setup required application features
|
||||
features.emplace_back(new arangodb::V8DealerFeature(server), false); // required for DatabaseFeature::createDatabase(...)
|
||||
features.emplace_back(new arangodb::ViewTypesFeature(server), true);
|
||||
features.emplace_back(new arangodb::AuthenticationFeature(server), true);
|
||||
features.emplace_back(new arangodb::DatabasePathFeature(server), false);
|
||||
|
@ -103,8 +105,7 @@ struct IResearchQueryPhraseSetup {
|
|||
features.emplace_back(new arangodb::ShardingFeature(server), false);
|
||||
features.emplace_back(new arangodb::QueryRegistryFeature(server), false); // must be first
|
||||
arangodb::application_features::ApplicationServer::server->addFeature(features.back().first); // need QueryRegistryFeature feature to be added now in order to create the system database
|
||||
system = irs::memory::make_unique<TRI_vocbase_t>(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 0, TRI_VOC_SYSTEM_DATABASE);
|
||||
features.emplace_back(new arangodb::SystemDatabaseFeature(server, system.get()), false); // required for IResearchAnalyzerFeature
|
||||
features.emplace_back(new arangodb::SystemDatabaseFeature(server), true); // required for IResearchAnalyzerFeature
|
||||
features.emplace_back(new arangodb::TraverserEngineRegistryFeature(server), false); // must be before AqlFeature
|
||||
features.emplace_back(new arangodb::AqlFeature(server), true);
|
||||
features.emplace_back(new arangodb::aql::OptimizerRulesFeature(server), true);
|
||||
|
@ -116,6 +117,11 @@ struct IResearchQueryPhraseSetup {
|
|||
features.emplace_back(new arangodb::LdapFeature(server), false); // required for AuthenticationFeature with USE_ENTERPRISE
|
||||
#endif
|
||||
|
||||
// required for V8DealerFeature::prepare(), ClusterFeature::prepare() not required
|
||||
arangodb::application_features::ApplicationServer::server->addFeature(
|
||||
new arangodb::ClusterFeature(server)
|
||||
);
|
||||
|
||||
for (auto& f : features) {
|
||||
arangodb::application_features::ApplicationServer::server->addFeature(f.first);
|
||||
}
|
||||
|
@ -124,6 +130,12 @@ struct IResearchQueryPhraseSetup {
|
|||
f.first->prepare();
|
||||
}
|
||||
|
||||
auto const databases = arangodb::velocypack::Parser::fromJson(std::string("[ { \"name\": \"") + arangodb::StaticStrings::SystemDatabase + "\" } ]");
|
||||
auto* dbFeature = arangodb::application_features::ApplicationServer::lookupFeature<
|
||||
arangodb::DatabaseFeature
|
||||
>("Database");
|
||||
dbFeature->loadDatabases(databases->slice());
|
||||
|
||||
for (auto& f : features) {
|
||||
if (f.second) {
|
||||
f.first->start();
|
||||
|
@ -134,10 +146,12 @@ struct IResearchQueryPhraseSetup {
|
|||
arangodb::iresearch::IResearchAnalyzerFeature
|
||||
>();
|
||||
arangodb::iresearch::IResearchAnalyzerFeature::EmplaceResult result;
|
||||
TRI_vocbase_t* vocbase;
|
||||
|
||||
dbFeature->createDatabase(1, "testVocbase", vocbase); // required for IResearchAnalyzerFeature::emplace(...)
|
||||
analyzers->emplace(
|
||||
result,
|
||||
"test_analyzer",
|
||||
"testVocbase::test_analyzer",
|
||||
"TestAnalyzer",
|
||||
"abc",
|
||||
irs::flags{ irs::frequency::type(), irs::position::type() } // required for PHRASE
|
||||
|
@ -145,7 +159,7 @@ struct IResearchQueryPhraseSetup {
|
|||
|
||||
analyzers->emplace(
|
||||
result,
|
||||
"test_csv_analyzer",
|
||||
"testVocbase::test_csv_analyzer",
|
||||
"TestDelimAnalyzer",
|
||||
","
|
||||
); // cache analyzer
|
||||
|
@ -155,13 +169,11 @@ struct IResearchQueryPhraseSetup {
|
|||
}
|
||||
|
||||
~IResearchQueryPhraseSetup() {
|
||||
system.reset(); // destroy before reseting the 'ENGINE'
|
||||
arangodb::AqlFeature(server).stop(); // unset singleton instance
|
||||
arangodb::LogTopic::setLogLevel(arangodb::iresearch::TOPIC.name(), arangodb::LogLevel::DEFAULT);
|
||||
arangodb::LogTopic::setLogLevel(arangodb::Logger::FIXME.name(), arangodb::LogLevel::DEFAULT);
|
||||
arangodb::LogTopic::setLogLevel(arangodb::Logger::AQL.name(), arangodb::LogLevel::DEFAULT);
|
||||
arangodb::application_features::ApplicationServer::server = nullptr;
|
||||
arangodb::EngineSelectorFeature::ENGINE = nullptr;
|
||||
|
||||
// destroy application features
|
||||
for (auto& f : features) {
|
||||
|
@ -175,6 +187,7 @@ struct IResearchQueryPhraseSetup {
|
|||
}
|
||||
|
||||
arangodb::LogTopic::setLogLevel(arangodb::Logger::AUTHENTICATION.name(), arangodb::LogLevel::DEFAULT);
|
||||
arangodb::EngineSelectorFeature::ENGINE = nullptr;
|
||||
}
|
||||
}; // IResearchQuerySetup
|
||||
|
||||
|
|
|
@ -34,7 +34,9 @@
|
|||
#include "Aql/ExpressionContext.h"
|
||||
#include "Aql/OptimizerRulesFeature.h"
|
||||
#include "Aql/Query.h"
|
||||
#include "Cluster/ClusterFeature.h"
|
||||
#include "V8/v8-globals.h"
|
||||
#include "V8Server/V8DealerFeature.h"
|
||||
#include "VocBase/LogicalCollection.h"
|
||||
#include "VocBase/LogicalView.h"
|
||||
#include "Transaction/Methods.h"
|
||||
|
@ -85,7 +87,6 @@ namespace {
|
|||
struct IResearchQueryScorerSetup {
|
||||
StorageEngineMock engine;
|
||||
arangodb::application_features::ApplicationServer server;
|
||||
std::unique_ptr<TRI_vocbase_t> system;
|
||||
std::vector<std::pair<arangodb::application_features::ApplicationFeature*, bool>> features;
|
||||
|
||||
IResearchQueryScorerSetup(): engine(server), server(nullptr, nullptr) {
|
||||
|
@ -103,6 +104,7 @@ struct IResearchQueryScorerSetup {
|
|||
irs::logger::output_le(iresearch::logger::IRL_FATAL, stderr);
|
||||
|
||||
// setup required application features
|
||||
features.emplace_back(new arangodb::V8DealerFeature(server), false); // required for DatabaseFeature::createDatabase(...)
|
||||
features.emplace_back(new arangodb::ViewTypesFeature(server), true);
|
||||
features.emplace_back(new arangodb::AuthenticationFeature(server), true);
|
||||
features.emplace_back(new arangodb::DatabasePathFeature(server), false);
|
||||
|
@ -110,8 +112,7 @@ struct IResearchQueryScorerSetup {
|
|||
features.emplace_back(new arangodb::ShardingFeature(server), false);
|
||||
features.emplace_back(new arangodb::QueryRegistryFeature(server), false); // must be first
|
||||
arangodb::application_features::ApplicationServer::server->addFeature(features.back().first); // need QueryRegistryFeature feature to be added now in order to create the system database
|
||||
system = irs::memory::make_unique<TRI_vocbase_t>(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 0, TRI_VOC_SYSTEM_DATABASE);
|
||||
features.emplace_back(new arangodb::SystemDatabaseFeature(server, system.get()), false); // required for IResearchAnalyzerFeature
|
||||
features.emplace_back(new arangodb::SystemDatabaseFeature(server), true); // required for IResearchAnalyzerFeature
|
||||
features.emplace_back(new arangodb::TraverserEngineRegistryFeature(server), false); // must be before AqlFeature
|
||||
features.emplace_back(new arangodb::AqlFeature(server), true);
|
||||
features.emplace_back(new arangodb::aql::OptimizerRulesFeature(server), true);
|
||||
|
@ -123,6 +124,11 @@ struct IResearchQueryScorerSetup {
|
|||
features.emplace_back(new arangodb::LdapFeature(server), false); // required for AuthenticationFeature with USE_ENTERPRISE
|
||||
#endif
|
||||
|
||||
// required for V8DealerFeature::prepare(), ClusterFeature::prepare() not required
|
||||
arangodb::application_features::ApplicationServer::server->addFeature(
|
||||
new arangodb::ClusterFeature(server)
|
||||
);
|
||||
|
||||
for (auto& f : features) {
|
||||
arangodb::application_features::ApplicationServer::server->addFeature(f.first);
|
||||
}
|
||||
|
@ -131,6 +137,12 @@ struct IResearchQueryScorerSetup {
|
|||
f.first->prepare();
|
||||
}
|
||||
|
||||
auto const databases = arangodb::velocypack::Parser::fromJson(std::string("[ { \"name\": \"") + arangodb::StaticStrings::SystemDatabase + "\" } ]");
|
||||
auto* dbFeature = arangodb::application_features::ApplicationServer::lookupFeature<
|
||||
arangodb::DatabaseFeature
|
||||
>("Database");
|
||||
dbFeature->loadDatabases(databases->slice());
|
||||
|
||||
for (auto& f : features) {
|
||||
if (f.second) {
|
||||
f.first->start();
|
||||
|
@ -180,21 +192,21 @@ struct IResearchQueryScorerSetup {
|
|||
arangodb::iresearch::IResearchAnalyzerFeature
|
||||
>();
|
||||
arangodb::iresearch::IResearchAnalyzerFeature::EmplaceResult result;
|
||||
TRI_vocbase_t* vocbase;
|
||||
|
||||
analyzers->emplace(result, "test_analyzer", "TestAnalyzer", "abc"); // cache analyzer
|
||||
analyzers->emplace(result, "test_csv_analyzer", "TestDelimAnalyzer", ","); // cache analyzer
|
||||
dbFeature->createDatabase(1, "testVocbase", vocbase); // required for IResearchAnalyzerFeature::emplace(...)
|
||||
analyzers->emplace(result, "testVocbase::test_analyzer", "TestAnalyzer", "abc"); // cache analyzer
|
||||
analyzers->emplace(result, "testVocbase::test_csv_analyzer", "TestDelimAnalyzer", ","); // cache analyzer
|
||||
|
||||
auto* dbPathFeature = arangodb::application_features::ApplicationServer::getFeature<arangodb::DatabasePathFeature>("DatabasePath");
|
||||
arangodb::tests::setDatabasePath(*dbPathFeature); // ensure test data is stored in a unique directory
|
||||
}
|
||||
|
||||
~IResearchQueryScorerSetup() {
|
||||
system.reset(); // destroy before reseting the 'ENGINE'
|
||||
arangodb::AqlFeature(server).stop(); // unset singleton instance
|
||||
arangodb::LogTopic::setLogLevel(arangodb::iresearch::TOPIC.name(), arangodb::LogLevel::DEFAULT);
|
||||
arangodb::LogTopic::setLogLevel(arangodb::Logger::FIXME.name(), arangodb::LogLevel::DEFAULT);
|
||||
arangodb::application_features::ApplicationServer::server = nullptr;
|
||||
arangodb::EngineSelectorFeature::ENGINE = nullptr;
|
||||
|
||||
// destroy application features
|
||||
for (auto& f : features) {
|
||||
|
@ -208,6 +220,7 @@ struct IResearchQueryScorerSetup {
|
|||
}
|
||||
|
||||
arangodb::LogTopic::setLogLevel(arangodb::Logger::AUTHENTICATION.name(), arangodb::LogLevel::DEFAULT);
|
||||
arangodb::EngineSelectorFeature::ENGINE = nullptr;
|
||||
}
|
||||
}; // IResearchQueryScorerSetup
|
||||
|
||||
|
|
|
@ -88,7 +88,6 @@ extern const char* ARGV0; // defined in main.cpp
|
|||
struct IResearchQueryTokensSetup {
|
||||
StorageEngineMock engine;
|
||||
arangodb::application_features::ApplicationServer server;
|
||||
std::unique_ptr<TRI_vocbase_t> system;
|
||||
std::vector<std::pair<arangodb::application_features::ApplicationFeature*, bool>> features;
|
||||
|
||||
IResearchQueryTokensSetup(): engine(server), server(nullptr, nullptr) {
|
||||
|
@ -112,8 +111,7 @@ struct IResearchQueryTokensSetup {
|
|||
features.emplace_back(new arangodb::ShardingFeature(server), false);
|
||||
features.emplace_back(new arangodb::QueryRegistryFeature(server), false); // must be first
|
||||
arangodb::application_features::ApplicationServer::server->addFeature(features.back().first); // need QueryRegistryFeature feature to be added now in order to create the system database
|
||||
system = irs::memory::make_unique<TRI_vocbase_t>(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 0, TRI_VOC_SYSTEM_DATABASE);
|
||||
features.emplace_back(new arangodb::SystemDatabaseFeature(server, system.get()), false); // required for IResearchAnalyzerFeature
|
||||
features.emplace_back(new arangodb::SystemDatabaseFeature(server), true); // required for IResearchAnalyzerFeature
|
||||
features.emplace_back(new arangodb::TraverserEngineRegistryFeature(server), false); // must be before AqlFeature
|
||||
features.emplace_back(new arangodb::V8DealerFeature(server), false); // required for DatabaseFeature::createDatabase(...)
|
||||
features.emplace_back(new arangodb::AqlFeature(server), true);
|
||||
|
@ -139,32 +137,33 @@ struct IResearchQueryTokensSetup {
|
|||
f.first->prepare();
|
||||
}
|
||||
|
||||
auto const databases = arangodb::velocypack::Parser::fromJson(std::string("[ { \"name\": \"") + arangodb::StaticStrings::SystemDatabase + "\" } ]");
|
||||
auto* dbFeature = arangodb::application_features::ApplicationServer::lookupFeature<
|
||||
arangodb::DatabaseFeature
|
||||
>("Database");
|
||||
dbFeature->loadDatabases(databases->slice());
|
||||
|
||||
for (auto& f : features) {
|
||||
if (f.second) {
|
||||
f.first->start();
|
||||
}
|
||||
}
|
||||
|
||||
auto* dbFeature = arangodb::application_features::ApplicationServer::lookupFeature<
|
||||
arangodb::DatabaseFeature
|
||||
>("Database");
|
||||
TRI_vocbase_t* vocbase;
|
||||
dbFeature->createDatabase(1, "testVocbase", vocbase); // required for IResearchAnalyzerFeature::emplace(...)
|
||||
|
||||
auto* analyzers = arangodb::application_features::ApplicationServer::lookupFeature<
|
||||
arangodb::iresearch::IResearchAnalyzerFeature
|
||||
>();
|
||||
arangodb::iresearch::IResearchAnalyzerFeature::EmplaceResult result;
|
||||
TRI_vocbase_t* vocbase;
|
||||
|
||||
analyzers->emplace(result, "test_analyzer", "TestAnalyzer", "abc"); // cache analyzer
|
||||
analyzers->emplace(result, "test_csv_analyzer", "TestDelimAnalyzer", ","); // cache analyzer
|
||||
dbFeature->createDatabase(1, "testVocbase", vocbase); // required for IResearchAnalyzerFeature::emplace(...)
|
||||
analyzers->emplace(result, "testVocbase::test_analyzer", "TestAnalyzer", "abc"); // cache analyzer
|
||||
analyzers->emplace(result, "testVocbase::test_csv_analyzer", "TestDelimAnalyzer", ","); // cache analyzer
|
||||
|
||||
auto* dbPathFeature = arangodb::application_features::ApplicationServer::getFeature<arangodb::DatabasePathFeature>("DatabasePath");
|
||||
arangodb::tests::setDatabasePath(*dbPathFeature); // ensure test data is stored in a unique directory
|
||||
}
|
||||
|
||||
~IResearchQueryTokensSetup() {
|
||||
system.reset(); // destroy before reseting the 'ENGINE'
|
||||
arangodb::AqlFeature(server).stop(); // unset singleton instance
|
||||
arangodb::LogTopic::setLogLevel(arangodb::iresearch::TOPIC.name(), arangodb::LogLevel::DEFAULT);
|
||||
arangodb::LogTopic::setLogLevel(arangodb::Logger::FIXME.name(), arangodb::LogLevel::DEFAULT);
|
||||
|
|
|
@ -493,7 +493,14 @@ void assertExpressionFilter(
|
|||
|
||||
// supportsFilterCondition
|
||||
{
|
||||
arangodb::iresearch::QueryContext const ctx{ nullptr, nullptr, nullptr, nullptr, ref };
|
||||
arangodb::transaction::Methods trx(
|
||||
arangodb::transaction::StandaloneContext::Create(vocbase),
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
arangodb::transaction::Options()
|
||||
);
|
||||
arangodb::iresearch::QueryContext const ctx{ &trx, nullptr, nullptr, nullptr, ref };
|
||||
CHECK((arangodb::iresearch::FilterFactory::filter(nullptr, ctx, *filterNode)));
|
||||
}
|
||||
|
||||
|
@ -619,7 +626,15 @@ void assertFilter(
|
|||
|
||||
// optimization time
|
||||
{
|
||||
arangodb::iresearch::QueryContext const ctx{ nullptr, nullptr, nullptr, nullptr, ref };
|
||||
arangodb::transaction ::Methods trx(
|
||||
arangodb::transaction::StandaloneContext::Create(vocbase),
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
arangodb::transaction::Options()
|
||||
);
|
||||
|
||||
arangodb::iresearch::QueryContext const ctx{ &trx, nullptr, nullptr, nullptr, ref };
|
||||
CHECK((parseOk == arangodb::iresearch::FilterFactory::filter(nullptr, ctx, *filterNode)));
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue