1
0
Fork 0

make ArangoSearch error messages more descriptive (#7257)

This commit is contained in:
Andrey Abramov 2018-11-07 21:03:04 +03:00 committed by GitHub
parent 8278a91a59
commit dd31bb1186
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 77 additions and 95 deletions

View File

@ -118,31 +118,72 @@ class IResearchLogTopic final : public arangodb::LogTopic {
} }
}; // IResearchLogTopic }; // IResearchLogTopic
arangodb::aql::AqlValue filter( struct Filter {
arangodb::aql::Query*, explicit Filter(
arangodb::transaction::Methods* , irs::string_ref const& name,
arangodb::SmallVector<arangodb::aql::AqlValue> const&) { irs::string_ref const& args
THROW_ARANGO_EXCEPTION_MESSAGE( ) noexcept
TRI_ERROR_NOT_IMPLEMENTED, : name(name), args(args) {
"Filter function is designed to be used with ArangoSearch view only" }
);
}
arangodb::aql::AqlValue scorer( arangodb::aql::AqlValue operator()(
arangodb::aql::Query*, arangodb::aql::Query*,
arangodb::transaction::Methods* , arangodb::transaction::Methods* ,
arangodb::SmallVector<arangodb::aql::AqlValue> const&) { arangodb::SmallVector<arangodb::aql::AqlValue> const&) {
THROW_ARANGO_EXCEPTION_MESSAGE( THROW_ARANGO_EXCEPTION_FORMAT(
TRI_ERROR_NOT_IMPLEMENTED, TRI_ERROR_NOT_IMPLEMENTED,
"Scorer function is designed to be used with ArangoSearch view only" "ArangoSearch filter function '%s(%s)' is designed to be used only within a corresponding SEARCH statement of ArangoSearch view."
); " Please ensure function signature is correct.",
} name.c_str(),
args.c_str()
);
}
typedef arangodb::aql::AqlValue (*IResearchFunctionPtr)( irs::string_ref name;
arangodb::aql::Query*, irs::string_ref args;
arangodb::transaction::Methods* , }; // Filter
arangodb::SmallVector<arangodb::aql::AqlValue> const&
); struct Scorer {
explicit Scorer(
irs::string_ref const& name,
irs::string_ref const& args
) noexcept
: name(name), args(args) {
}
arangodb::aql::AqlValue operator()(
arangodb::aql::Query*,
arangodb::transaction::Methods* ,
arangodb::SmallVector<arangodb::aql::AqlValue> const&) {
THROW_ARANGO_EXCEPTION_FORMAT(
TRI_ERROR_NOT_IMPLEMENTED,
"ArangoSearch scorer function '%s(%s)' is designed to be used only outside SEARCH statement within a context of ArangoSearch view."
" Please ensure function signature is correct.",
name.c_str(),
args.c_str()
);
}
irs::string_ref name;
irs::string_ref args;
}; // Scorer
inline void registerFilter(
arangodb::aql::AqlFunctionFeature& functions,
irs::string_ref const& name,
irs::string_ref const& args
) {
arangodb::iresearch::addFunction(functions, {
name,
args.c_str(),
arangodb::aql::Function::makeFlags(
arangodb::aql::Function::Flags::Deterministic,
arangodb::aql::Function::Flags::Cacheable,
arangodb::aql::Function::Flags::CanRunOnDBServer
),
Filter(name, args) // function implementation (use function name as placeholder)
});
}
size_t computeThreadPoolSize(size_t threads, size_t threadsLimit) { size_t computeThreadPoolSize(size_t threads, size_t threadsLimit) {
static const size_t MAX_THREADS = 8; // arbitrary limit on the upper bound of threads in pool static const size_t MAX_THREADS = 8; // arbitrary limit on the upper bound of threads in pool
@ -178,71 +219,12 @@ void registerFunctions(arangodb::aql::AqlFunctionFeature& functions) {
} }
void registerFilters(arangodb::aql::AqlFunctionFeature& functions) { void registerFilters(arangodb::aql::AqlFunctionFeature& functions) {
arangodb::iresearch::addFunction(functions, { registerFilter(functions, "EXISTS", ".|.,."); // (attribute, [ "analyzer"|"type"|"string"|"numeric"|"bool"|"null" ])
"EXISTS", // name registerFilter(functions, "STARTS_WITH", ".,.|."); // (attribute, prefix, scoring-limit)
".|.,.", // positional arguments (attribute, [ "analyzer"|"type"|"string"|"numeric"|"bool"|"null" ]) registerFilter(functions, "PHRASE", ".,.|.+"); // (attribute, input [, offset, input... ] [, analyzer])
arangodb::aql::Function::makeFlags( registerFilter(functions, "MIN_MATCH", ".,.|.+"); // (filter expression [, filter expression, ... ], min match count)
arangodb::aql::Function::Flags::Deterministic, registerFilter(functions, "BOOST", ".,."); // (filter expression, boost)
arangodb::aql::Function::Flags::Cacheable, registerFilter(functions, "ANALYZER", ".,."); // (filter expression, analyzer)
arangodb::aql::Function::Flags::CanRunOnDBServer
),
&filter // function implementation (use function name as placeholder)
});
arangodb::iresearch::addFunction(functions, {
"STARTS_WITH", // name
".,.|.", // positional arguments (attribute, prefix, scoring-limit)
arangodb::aql::Function::makeFlags(
arangodb::aql::Function::Flags::Deterministic,
arangodb::aql::Function::Flags::Cacheable,
arangodb::aql::Function::Flags::CanRunOnDBServer
),
&filter // function implementation (use function name as placeholder)
});
arangodb::iresearch::addFunction(functions, {
"PHRASE", // name
".,.|.+", // positional arguments (attribute, input [, offset, input... ] [, analyzer])
arangodb::aql::Function::makeFlags(
arangodb::aql::Function::Flags::Deterministic,
arangodb::aql::Function::Flags::Cacheable,
arangodb::aql::Function::Flags::CanRunOnDBServer
),
&filter // function implementation (use function name as placeholder)
});
arangodb::iresearch::addFunction(functions, {
"MIN_MATCH", // name
".,.|.+", // positional arguments (filter expression [, filter expression, ... ], min match count)
arangodb::aql::Function::makeFlags(
arangodb::aql::Function::Flags::Deterministic,
arangodb::aql::Function::Flags::Cacheable,
arangodb::aql::Function::Flags::CanRunOnDBServer
),
&filter // function implementation (use function name as placeholder)
});
arangodb::iresearch::addFunction(functions, {
"BOOST", // name
".,.", // positional arguments (filter expression, boost)
arangodb::aql::Function::makeFlags(
arangodb::aql::Function::Flags::Deterministic,
arangodb::aql::Function::Flags::Cacheable,
arangodb::aql::Function::Flags::CanRunOnDBServer
),
&filter // function implementation (use function name as placeholder)
});
arangodb::iresearch::addFunction(functions, {
"ANALYZER", // name
".,.", // positional arguments (filter expression, analyzer)
arangodb::aql::Function::makeFlags(
arangodb::aql::Function::Flags::Deterministic,
arangodb::aql::Function::Flags::Cacheable,
arangodb::aql::Function::Flags::CanRunOnDBServer
),
&filter // function implementation (use function name as placeholder)
});
} }
void registerIndexFactory() { void registerIndexFactory() {
@ -292,7 +274,9 @@ void registerIndexFactory() {
} }
void registerScorers(arangodb::aql::AqlFunctionFeature& functions) { void registerScorers(arangodb::aql::AqlFunctionFeature& functions) {
irs::scorers::visit([&functions]( irs::string_ref const args(".|+"); // positional arguments (attribute [, <scorer-specific properties>...]);
irs::scorers::visit([&functions, &args](
irs::string_ref const& name, irs::text_format::type_id const& args_format irs::string_ref const& name, irs::text_format::type_id const& args_format
)->bool { )->bool {
// ArangoDB, for API consistency, only supports scorers configurable via jSON // ArangoDB, for API consistency, only supports scorers configurable via jSON
@ -307,13 +291,13 @@ void registerScorers(arangodb::aql::AqlFunctionFeature& functions) {
arangodb::iresearch::addFunction(functions, { arangodb::iresearch::addFunction(functions, {
std::move(upperName), std::move(upperName),
".|+", // positional arguments (attribute [, <scorer-specific properties>...]) args.c_str(),
arangodb::aql::Function::makeFlags( arangodb::aql::Function::makeFlags(
arangodb::aql::Function::Flags::Deterministic, arangodb::aql::Function::Flags::Deterministic,
arangodb::aql::Function::Flags::Cacheable, arangodb::aql::Function::Flags::Cacheable,
arangodb::aql::Function::Flags::CanRunOnDBServer arangodb::aql::Function::Flags::CanRunOnDBServer
), ),
&scorer // function implementation (use function name as placeholder) Scorer(name, args) // function implementation (use function name as placeholder)
}); });
return true; return true;
@ -412,13 +396,11 @@ NS_BEGIN(arangodb)
NS_BEGIN(iresearch) NS_BEGIN(iresearch)
bool isFilter(arangodb::aql::Function const& func) noexcept { bool isFilter(arangodb::aql::Function const& func) noexcept {
auto* pimpl = func.implementation.target<IResearchFunctionPtr>(); return nullptr != func.implementation.target<Filter>();
return pimpl && *pimpl == &filter;
} }
bool isScorer(arangodb::aql::Function const& func) noexcept { bool isScorer(arangodb::aql::Function const& func) noexcept {
auto* pimpl = func.implementation.target<IResearchFunctionPtr>(); return nullptr != func.implementation.target<Scorer>();
return pimpl && *pimpl == &scorer;
} }
class IResearchFeature::Async { class IResearchFeature::Async {