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
arangodb::aql::AqlValue filter(
struct Filter {
explicit Filter(
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_MESSAGE(
THROW_ARANGO_EXCEPTION_FORMAT(
TRI_ERROR_NOT_IMPLEMENTED,
"Filter 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()
);
}
arangodb::aql::AqlValue scorer(
irs::string_ref name;
irs::string_ref args;
}; // Filter
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_MESSAGE(
THROW_ARANGO_EXCEPTION_FORMAT(
TRI_ERROR_NOT_IMPLEMENTED,
"Scorer function is designed to be used with ArangoSearch view only"
"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()
);
}
typedef arangodb::aql::AqlValue (*IResearchFunctionPtr)(
arangodb::aql::Query*,
arangodb::transaction::Methods* ,
arangodb::SmallVector<arangodb::aql::AqlValue> const&
);
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) {
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) {
arangodb::iresearch::addFunction(functions, {
"EXISTS", // name
".|.,.", // positional arguments (attribute, [ "analyzer"|"type"|"string"|"numeric"|"bool"|"null" ])
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, {
"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)
});
registerFilter(functions, "EXISTS", ".|.,."); // (attribute, [ "analyzer"|"type"|"string"|"numeric"|"bool"|"null" ])
registerFilter(functions, "STARTS_WITH", ".,.|."); // (attribute, prefix, scoring-limit)
registerFilter(functions, "PHRASE", ".,.|.+"); // (attribute, input [, offset, input... ] [, analyzer])
registerFilter(functions, "MIN_MATCH", ".,.|.+"); // (filter expression [, filter expression, ... ], min match count)
registerFilter(functions, "BOOST", ".,."); // (filter expression, boost)
registerFilter(functions, "ANALYZER", ".,."); // (filter expression, analyzer)
}
void registerIndexFactory() {
@ -292,7 +274,9 @@ void registerIndexFactory() {
}
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
)->bool {
// ArangoDB, for API consistency, only supports scorers configurable via jSON
@ -307,13 +291,13 @@ void registerScorers(arangodb::aql::AqlFunctionFeature& functions) {
arangodb::iresearch::addFunction(functions, {
std::move(upperName),
".|+", // positional arguments (attribute [, <scorer-specific properties>...])
args.c_str(),
arangodb::aql::Function::makeFlags(
arangodb::aql::Function::Flags::Deterministic,
arangodb::aql::Function::Flags::Cacheable,
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;
@ -412,13 +396,11 @@ NS_BEGIN(arangodb)
NS_BEGIN(iresearch)
bool isFilter(arangodb::aql::Function const& func) noexcept {
auto* pimpl = func.implementation.target<IResearchFunctionPtr>();
return pimpl && *pimpl == &filter;
return nullptr != func.implementation.target<Filter>();
}
bool isScorer(arangodb::aql::Function const& func) noexcept {
auto* pimpl = func.implementation.target<IResearchFunctionPtr>();
return pimpl && *pimpl == &scorer;
return nullptr != func.implementation.target<Scorer>();
}
class IResearchFeature::Async {