mirror of https://gitee.com/bigwinds/arangodb
add exceptions for tokens function. (#8984)
* Provide users of the TOKENS function with errors. * remove newlines * fix compare * fix as asked for * improve fix
This commit is contained in:
parent
145cf3d294
commit
970f732dec
|
@ -199,8 +199,8 @@ class basic_string_ref {
|
||||||
size_t rhs_size
|
size_t rhs_size
|
||||||
) {
|
) {
|
||||||
const size_t lhs_size = lhs.size();
|
const size_t lhs_size = lhs.size();
|
||||||
int r = traits_type::compare(
|
int r = traits_type::compare(
|
||||||
lhs.c_str(), rhs,
|
lhs.c_str(), rhs,
|
||||||
(std::min)(lhs_size, rhs_size)
|
(std::min)(lhs_size, rhs_size)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -235,7 +235,7 @@ class basic_string_ref {
|
||||||
) {
|
) {
|
||||||
return lhs.compare(0, std::basic_string<char_type>::npos, rhs.c_str(), rhs.size()) < 0;
|
return lhs.compare(0, std::basic_string<char_type>::npos, rhs.c_str(), rhs.size()) < 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
friend bool operator>=(const basic_string_ref& lhs, const basic_string_ref& rhs) {
|
friend bool operator>=(const basic_string_ref& lhs, const basic_string_ref& rhs) {
|
||||||
return !(lhs < rhs);
|
return !(lhs < rhs);
|
||||||
}
|
}
|
||||||
|
@ -295,7 +295,7 @@ inline bool starts_with(
|
||||||
|
|
||||||
template< typename _Elem, typename _Traits >
|
template< typename _Elem, typename _Traits >
|
||||||
inline bool starts_with(
|
inline bool starts_with(
|
||||||
const std::basic_string<_Elem>& first,
|
const std::basic_string<_Elem>& first,
|
||||||
const basic_string_ref<_Elem, _Traits>& second) {
|
const basic_string_ref<_Elem, _Traits>& second) {
|
||||||
return 0 == first.compare(0, second.size(), second.c_str(), second.size());
|
return 0 == first.compare(0, second.size(), second.c_str(), second.size());
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,6 +66,8 @@
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
using namespace std::literals::string_literals;
|
||||||
|
|
||||||
static std::string const ANALYZER_COLLECTION_NAME("_analyzers");
|
static std::string const ANALYZER_COLLECTION_NAME("_analyzers");
|
||||||
static char const ANALYZER_PREFIX_DELIM = ':'; // name prefix delimiter (2 chars)
|
static char const ANALYZER_PREFIX_DELIM = ':'; // name prefix delimiter (2 chars)
|
||||||
static size_t const ANALYZER_PROPERTIES_SIZE_MAX = 1024 * 1024; // arbitrary value
|
static size_t const ANALYZER_PROPERTIES_SIZE_MAX = 1024 * 1024; // arbitrary value
|
||||||
|
@ -132,16 +134,26 @@ bool IdentityAnalyzer::reset(irs::string_ref const& data) {
|
||||||
return !_empty;
|
return !_empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::string const while_tokens =
|
||||||
|
" while computing result for function 'TOKENS'";
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
std::string operator+(std::string const& s, irs::string_ref const& r){
|
||||||
|
return s + std::string(r.c_str(), r.size());
|
||||||
|
}
|
||||||
|
std::string operator+(irs::string_ref const& r, std::string const& s){
|
||||||
|
return std::string(r.c_str(), r.size()) + s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
arangodb::aql::AqlValue aqlFnTokens(arangodb::aql::ExpressionContext* expressionContext,
|
arangodb::aql::AqlValue aqlFnTokens(arangodb::aql::ExpressionContext* expressionContext,
|
||||||
arangodb::transaction::Methods* trx,
|
arangodb::transaction::Methods* trx,
|
||||||
arangodb::aql::VPackFunctionParameters const& args) {
|
arangodb::aql::VPackFunctionParameters const& args) {
|
||||||
if (2 != args.size() || !args[0].isString() || !args[1].isString()) {
|
|
||||||
LOG_TOPIC("740fd", WARN, arangodb::iresearch::TOPIC)
|
|
||||||
<< "invalid arguments passed while computing result for function "
|
|
||||||
"'TOKENS'";
|
|
||||||
TRI_set_errno(TRI_ERROR_BAD_PARAMETER);
|
|
||||||
|
|
||||||
return arangodb::aql::AqlValue();
|
if (2 != args.size() || !args[0].isString() || !args[1].isString()) {
|
||||||
|
auto message = "invalid arguments" + while_tokens;
|
||||||
|
LOG_TOPIC("740fd", WARN, arangodb::iresearch::TOPIC) << message;
|
||||||
|
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_BAD_PARAMETER, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto data = arangodb::iresearch::getStringRef(args[0].slice());
|
auto data = arangodb::iresearch::getStringRef(args[0].slice());
|
||||||
|
@ -150,12 +162,9 @@ arangodb::aql::AqlValue aqlFnTokens(arangodb::aql::ExpressionContext* expression
|
||||||
arangodb::application_features::ApplicationServer::lookupFeature<arangodb::iresearch::IResearchAnalyzerFeature>();
|
arangodb::application_features::ApplicationServer::lookupFeature<arangodb::iresearch::IResearchAnalyzerFeature>();
|
||||||
|
|
||||||
if (!analyzers) {
|
if (!analyzers) {
|
||||||
LOG_TOPIC("fbd91", WARN, arangodb::iresearch::TOPIC)
|
auto const message = "failure to find feature 'arangosearch'"s + while_tokens;
|
||||||
<< "failure to find feature 'arangosearch' while computing result for "
|
LOG_TOPIC("fbd91", WARN, arangodb::iresearch::TOPIC) << message;
|
||||||
"function 'TOKENS'";
|
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, message);
|
||||||
TRI_set_errno(TRI_ERROR_INTERNAL);
|
|
||||||
|
|
||||||
return arangodb::aql::AqlValue();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
arangodb::iresearch::IResearchAnalyzerFeature::AnalyzerPool::ptr pool;
|
arangodb::iresearch::IResearchAnalyzerFeature::AnalyzerPool::ptr pool;
|
||||||
|
@ -178,43 +187,40 @@ arangodb::aql::AqlValue aqlFnTokens(arangodb::aql::ExpressionContext* expression
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pool) {
|
if (!pool) {
|
||||||
LOG_TOPIC("0d256", WARN, arangodb::iresearch::TOPIC)
|
using detail::operator+;
|
||||||
<< "failure to find arangosearch analyzer pool name '" << name
|
auto const message = "failure to find arangosearch analyzer with name '"s +
|
||||||
<< "' while computing result for function 'TOKENS'";
|
name + "'" + while_tokens;
|
||||||
TRI_set_errno(TRI_ERROR_BAD_PARAMETER);
|
LOG_TOPIC("0d256", WARN, arangodb::iresearch::TOPIC) << message;
|
||||||
|
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_BAD_PARAMETER, message);
|
||||||
return arangodb::aql::AqlValue();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto analyzer = pool->get();
|
auto analyzer = pool->get();
|
||||||
|
|
||||||
if (!analyzer) {
|
if (!analyzer) {
|
||||||
LOG_TOPIC("d7477", WARN, arangodb::iresearch::TOPIC)
|
using detail::operator+;
|
||||||
<< "failure to find arangosearch analyzer name '" << name
|
auto const message = "failure to find arangosearch analyzer with name '"s +
|
||||||
<< "' while computing result for function 'TOKENS'";
|
name + "'" + while_tokens;
|
||||||
TRI_set_errno(TRI_ERROR_BAD_PARAMETER);
|
LOG_TOPIC("d7477", WARN, arangodb::iresearch::TOPIC) << message;
|
||||||
|
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_BAD_PARAMETER, message);
|
||||||
return arangodb::aql::AqlValue();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!analyzer->reset(data)) {
|
if (!analyzer->reset(data)) {
|
||||||
LOG_TOPIC("45a2d", WARN, arangodb::iresearch::TOPIC)
|
using detail::operator+;
|
||||||
<< "failure to reset arangosearch analyzer name '" << name
|
auto const message = "failure to reset arangosearch analyzer: ' "s +
|
||||||
<< "' while computing result for function 'TOKENS'";
|
name + "'" + while_tokens;
|
||||||
TRI_set_errno(TRI_ERROR_INTERNAL);
|
LOG_TOPIC("45a2d", WARN, arangodb::iresearch::TOPIC) << message;
|
||||||
|
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, message);
|
||||||
return arangodb::aql::AqlValue();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& values = analyzer->attributes().get<irs::term_attribute>();
|
auto& values = analyzer->attributes().get<irs::term_attribute>();
|
||||||
|
|
||||||
if (!values) {
|
if (!values) {
|
||||||
LOG_TOPIC("f46f2", WARN, arangodb::iresearch::TOPIC)
|
using detail::operator+;
|
||||||
<< "failure to retrieve values from arangosearch analyzer name '"
|
auto const message =
|
||||||
<< name << "' while computing result for function 'TOKENS'";
|
"failure to retrieve values from arangosearch analyzer name '"s +
|
||||||
TRI_set_errno(TRI_ERROR_INTERNAL);
|
name + "'" + while_tokens;
|
||||||
|
LOG_TOPIC("f46f2", WARN, arangodb::iresearch::TOPIC) << message;
|
||||||
return arangodb::aql::AqlValue();
|
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
// to avoid copying Builder's default buffer when initializing AqlValue
|
// to avoid copying Builder's default buffer when initializing AqlValue
|
||||||
|
@ -222,11 +228,9 @@ arangodb::aql::AqlValue aqlFnTokens(arangodb::aql::ExpressionContext* expression
|
||||||
auto buffer = irs::memory::make_unique<arangodb::velocypack::Buffer<uint8_t>>();
|
auto buffer = irs::memory::make_unique<arangodb::velocypack::Buffer<uint8_t>>();
|
||||||
|
|
||||||
if (!buffer) {
|
if (!buffer) {
|
||||||
LOG_TOPIC("97cd0", WARN, arangodb::iresearch::TOPIC)
|
auto const message = "failure to allocate result buffer"s + while_tokens;
|
||||||
<< "failure to allocate result buffer while computing result for "
|
LOG_TOPIC("97cd0", WARN, arangodb::iresearch::TOPIC) << message;
|
||||||
"function 'TOKENS'";
|
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_OUT_OF_MEMORY, message);
|
||||||
|
|
||||||
return arangodb::aql::AqlValue();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
arangodb::velocypack::Builder builder(*buffer);
|
arangodb::velocypack::Builder builder(*buffer);
|
||||||
|
|
|
@ -2182,7 +2182,7 @@ SECTION("test_tokens") {
|
||||||
arangodb::iresearch::IResearchAnalyzerFeature feature(s.server);
|
arangodb::iresearch::IResearchAnalyzerFeature feature(s.server);
|
||||||
|
|
||||||
// AqlFunctionFeature::byName(..) throws exception instead of returning a nullptr
|
// AqlFunctionFeature::byName(..) throws exception instead of returning a nullptr
|
||||||
CHECK_THROWS((functions->byName("TOKENS")));
|
CHECK_THROWS(functions->byName("TOKENS"));
|
||||||
|
|
||||||
feature.start(); // load AQL functions
|
feature.start(); // load AQL functions
|
||||||
CHECK((nullptr != functions->byName("TOKENS")));
|
CHECK((nullptr != functions->byName("TOKENS")));
|
||||||
|
@ -2228,8 +2228,9 @@ SECTION("test_tokens") {
|
||||||
|
|
||||||
arangodb::SmallVector<arangodb::aql::AqlValue>::allocator_type::arena_type arena;
|
arangodb::SmallVector<arangodb::aql::AqlValue>::allocator_type::arena_type arena;
|
||||||
arangodb::aql::VPackFunctionParameters args{arena};
|
arangodb::aql::VPackFunctionParameters args{arena};
|
||||||
AqlValueWrapper result(impl(nullptr, nullptr, args));
|
CHECK_THROWS_WITH(
|
||||||
CHECK((result->isNone()));
|
AqlValueWrapper(impl(nullptr, nullptr, args)),
|
||||||
|
"invalid arguments while computing result for function 'TOKENS'");
|
||||||
}
|
}
|
||||||
|
|
||||||
// test invalid data type
|
// test invalid data type
|
||||||
|
@ -2243,8 +2244,9 @@ SECTION("test_tokens") {
|
||||||
VPackFunctionParametersWrapper args;
|
VPackFunctionParametersWrapper args;
|
||||||
args->emplace_back(data.c_str(), data.size());
|
args->emplace_back(data.c_str(), data.size());
|
||||||
args->emplace_back(arangodb::aql::AqlValueHintDouble(123.4));
|
args->emplace_back(arangodb::aql::AqlValueHintDouble(123.4));
|
||||||
AqlValueWrapper result(impl(nullptr, nullptr, *args));
|
CHECK_THROWS_WITH(
|
||||||
CHECK((result->isNone()));
|
AqlValueWrapper(impl(nullptr, nullptr, *args)),
|
||||||
|
"invalid arguments while computing result for function 'TOKENS'");
|
||||||
}
|
}
|
||||||
|
|
||||||
// test invalid analyzer type
|
// test invalid analyzer type
|
||||||
|
@ -2258,8 +2260,9 @@ SECTION("test_tokens") {
|
||||||
VPackFunctionParametersWrapper args;
|
VPackFunctionParametersWrapper args;
|
||||||
args->emplace_back(arangodb::aql::AqlValueHintDouble(123.4));
|
args->emplace_back(arangodb::aql::AqlValueHintDouble(123.4));
|
||||||
args->emplace_back(analyzer.c_str(), analyzer.size());
|
args->emplace_back(analyzer.c_str(), analyzer.size());
|
||||||
AqlValueWrapper result(impl(nullptr, nullptr, *args));
|
CHECK_THROWS_WITH(
|
||||||
CHECK((result->isNone()));
|
AqlValueWrapper(impl(nullptr, nullptr, *args)),
|
||||||
|
"invalid arguments while computing result for function 'TOKENS'");
|
||||||
}
|
}
|
||||||
|
|
||||||
// test invalid analyzer
|
// test invalid analyzer
|
||||||
|
@ -2274,8 +2277,10 @@ SECTION("test_tokens") {
|
||||||
VPackFunctionParametersWrapper args;
|
VPackFunctionParametersWrapper args;
|
||||||
args->emplace_back(data.c_str(), data.size());
|
args->emplace_back(data.c_str(), data.size());
|
||||||
args->emplace_back(analyzer.c_str(), analyzer.size());
|
args->emplace_back(analyzer.c_str(), analyzer.size());
|
||||||
AqlValueWrapper result(impl(nullptr, nullptr, *args));
|
CHECK_THROWS_WITH(
|
||||||
CHECK((result->isNone()));
|
AqlValueWrapper(impl(nullptr, nullptr, *args)),
|
||||||
|
"failure to find arangosearch analyzer with name 'invalid' while "
|
||||||
|
"computing result for function 'TOKENS'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -207,13 +207,12 @@ function iResearchFeatureAqlTestSuite () {
|
||||||
testDefaultAnalyzers : function() {
|
testDefaultAnalyzers : function() {
|
||||||
// invalid
|
// invalid
|
||||||
{
|
{
|
||||||
let result = db._query(
|
try {
|
||||||
"RETURN TOKENS('a quick brown fox jumps', 'invalid')",
|
db._query("RETURN TOKENS('a quick brown fox jumps', 'invalid')").toArray();
|
||||||
null,
|
fail();
|
||||||
{ }
|
} catch (err) {
|
||||||
).toArray();
|
assertEqual(err.errorNum, require("internal").errors.ERROR_BAD_PARAMETER.code);
|
||||||
assertEqual(1, result.length);
|
}
|
||||||
assertEqual(null, result[0]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// text_de
|
// text_de
|
||||||
|
|
Loading…
Reference in New Issue