mirror of https://gitee.com/bigwinds/arangodb
Merge branch 'devel' of https://github.com/arangodb/arangodb into devel
This commit is contained in:
commit
8e32a7789d
|
@ -39,7 +39,7 @@ For more information see the [Debugging](Debugging.md) section.
|
||||||
|
|
||||||
|
|
||||||
!SECTION Considerations for production environments
|
!SECTION Considerations for production environments
|
||||||
So you have created your server side application utilizing foxx services as their backend.
|
So you have created your server side application utilizing Foxx services as their backend.
|
||||||
To get optimal performance you may want to implement [an HTTP connection pool using keepalive](../../GeneralHttp/README.md#keep-alive).
|
To get optimal performance you may want to implement [an HTTP connection pool using keepalive](../../GeneralHttp/README.md#keep-alive).
|
||||||
|
|
||||||
You may even consider to implement [non blocking HTTP requests](../../GeneralHttp/README.md#blocking-vs.-non-blocking-http-requests) to save resources on your connection pool.
|
You may even consider to implement [non blocking HTTP requests](../../GeneralHttp/README.md#blocking-vs.-non-blocking-http-requests) to save resources on your connection pool.
|
|
@ -174,7 +174,7 @@ std::unordered_map<std::string, Function const> const Executor::FunctionNames{
|
||||||
{ "FIRST", Function("FIRST", "AQL_FIRST", "l", true, true, false, true, true, &Functions::First) },
|
{ "FIRST", Function("FIRST", "AQL_FIRST", "l", true, true, false, true, true, &Functions::First) },
|
||||||
{ "LAST", Function("LAST", "AQL_LAST", "l", true, true, false, true, true, &Functions::Last) },
|
{ "LAST", Function("LAST", "AQL_LAST", "l", true, true, false, true, true, &Functions::Last) },
|
||||||
{ "NTH", Function("NTH", "AQL_NTH", "l,n", true, true, false, true, true, &Functions::Nth) },
|
{ "NTH", Function("NTH", "AQL_NTH", "l,n", true, true, false, true, true, &Functions::Nth) },
|
||||||
{ "POSITION", Function("POSITION", "AQL_POSITION", "l,.|b", true, true, false, true, true) },
|
{ "POSITION", Function("POSITION", "AQL_POSITION", "l,.|b", true, true, false, true, true, &Functions::Position) },
|
||||||
{ "CALL", Function("CALL", "AQL_CALL", "s|.+", false, false, true, false, true) },
|
{ "CALL", Function("CALL", "AQL_CALL", "s|.+", false, false, true, false, true) },
|
||||||
{ "APPLY", Function("APPLY", "AQL_APPLY", "s|l", false, false, true, false, false) },
|
{ "APPLY", Function("APPLY", "AQL_APPLY", "s|l", false, false, true, false, false) },
|
||||||
{ "PUSH", Function("PUSH", "AQL_PUSH", "l,.|b", true, true, false, true, false, &Functions::Push) },
|
{ "PUSH", Function("PUSH", "AQL_PUSH", "l,.|b", true, true, false, true, false, &Functions::Push) },
|
||||||
|
|
|
@ -406,16 +406,22 @@ static void AppendAsString (triagens::basics::StringBuffer& buffer,
|
||||||
/// @brief Checks if the given list contains the element
|
/// @brief Checks if the given list contains the element
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
static bool ListContainsElement (Json const& list, Json const& testee) {
|
static bool ListContainsElement (Json const& list, Json const& testee, size_t& index) {
|
||||||
for (size_t i = 0; i < list.size(); ++i) {
|
for (size_t i = 0; i < list.size(); ++i) {
|
||||||
if (TRI_CheckSameValueJson(testee.json(), list.at(i).json())) {
|
if (TRI_CheckSameValueJson(testee.json(), list.at(i).json())) {
|
||||||
// We found the element in the list.
|
// We found the element in the list.
|
||||||
|
index = i;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool ListContainsElement (Json const& list, Json const& testee) {
|
||||||
|
size_t unused;
|
||||||
|
return ListContainsElement(list, testee, unused);
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief Computes the Variance of the given list.
|
/// @brief Computes the Variance of the given list.
|
||||||
/// If successful value will contain the variance and count
|
/// If successful value will contain the variance and count
|
||||||
|
@ -4087,6 +4093,50 @@ AqlValue Functions::Range (triagens::aql::Query* query,
|
||||||
return AqlValue(new Json(TRI_UNKNOWN_MEM_ZONE, result.steal()));
|
return AqlValue(new Json(TRI_UNKNOWN_MEM_ZONE, result.steal()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief function POSITION
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
AqlValue Functions::Position (triagens::aql::Query* query,
|
||||||
|
triagens::arango::AqlTransaction* trx,
|
||||||
|
FunctionParameters const& parameters) {
|
||||||
|
size_t const n = parameters.size();
|
||||||
|
if (n != 2 && n != 3) {
|
||||||
|
THROW_ARANGO_EXCEPTION_PARAMS(TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "POSITION", (int) 2, (int) 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
Json list = ExtractFunctionParameter(trx, parameters, 0, false);
|
||||||
|
|
||||||
|
if (! list.isArray()) {
|
||||||
|
RegisterWarning(query, "POSITION", TRI_ERROR_QUERY_ARRAY_EXPECTED);
|
||||||
|
return AqlValue(new Json(Json::Null));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool returnIndex = false;
|
||||||
|
if (n == 3) {
|
||||||
|
Json returnIndexJson = ExtractFunctionParameter(trx, parameters, 2, false);
|
||||||
|
returnIndex = ValueToBoolean(returnIndexJson.json());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (list.size() > 0) {
|
||||||
|
Json searchValue = ExtractFunctionParameter(trx, parameters, 1, false);
|
||||||
|
|
||||||
|
size_t index;
|
||||||
|
if (ListContainsElement(list, searchValue, index)) {
|
||||||
|
if (returnIndex) {
|
||||||
|
return AqlValue(new Json(static_cast<double>(index)));
|
||||||
|
}
|
||||||
|
return AqlValue(new Json(true));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (returnIndex) {
|
||||||
|
return AqlValue(new Json(-1));
|
||||||
|
}
|
||||||
|
return AqlValue(new Json(false));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// --SECTION-- END-OF-FILE
|
// --SECTION-- END-OF-FILE
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
|
@ -148,6 +148,7 @@ namespace triagens {
|
||||||
static AqlValue Median (triagens::aql::Query*, triagens::arango::AqlTransaction*, FunctionParameters const&);
|
static AqlValue Median (triagens::aql::Query*, triagens::arango::AqlTransaction*, FunctionParameters const&);
|
||||||
static AqlValue Percentile (triagens::aql::Query*, triagens::arango::AqlTransaction*, FunctionParameters const&);
|
static AqlValue Percentile (triagens::aql::Query*, triagens::arango::AqlTransaction*, FunctionParameters const&);
|
||||||
static AqlValue Range (triagens::aql::Query*, triagens::arango::AqlTransaction*, FunctionParameters const&);
|
static AqlValue Range (triagens::aql::Query*, triagens::arango::AqlTransaction*, FunctionParameters const&);
|
||||||
|
static AqlValue Position (triagens::aql::Query*, triagens::arango::AqlTransaction*, FunctionParameters const&);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -321,6 +321,30 @@ function ahuacatlFunctionsTestSuite () {
|
||||||
// look up the element using the position
|
// look up the element using the position
|
||||||
actual = getQueryResults("RETURN NTH(@list, @position)", { list: list, position: actual[0] });
|
actual = getQueryResults("RETURN NTH(@list, @position)", { list: list, position: actual[0] });
|
||||||
assertEqual(search, actual[0]);
|
assertEqual(search, actual[0]);
|
||||||
|
|
||||||
|
// find if element is contained in list (should be true)
|
||||||
|
actual = getQueryResults("RETURN NOOPT(POSITION(@list, @search, false))", { list: list, search: search });
|
||||||
|
assertTrue(actual[0]);
|
||||||
|
|
||||||
|
// find position of element in list
|
||||||
|
actual = getQueryResults("RETURN NOOPT(POSITION(@list, @search, true))", { list: list, search: search });
|
||||||
|
assertEqual(expected, actual[0]);
|
||||||
|
|
||||||
|
// look up the element using the position
|
||||||
|
actual = getQueryResults("RETURN NOOPT(NTH(@list, @position))", { list: list, position: actual[0] });
|
||||||
|
assertEqual(search, actual[0]);
|
||||||
|
|
||||||
|
// find if element is contained in list (should be true)
|
||||||
|
actual = getQueryResults("RETURN NOOPT(V8(POSITION(@list, @search, false)))", { list: list, search: search });
|
||||||
|
assertTrue(actual[0]);
|
||||||
|
|
||||||
|
// find position of element in list
|
||||||
|
actual = getQueryResults("RETURN NOOPT(V8(POSITION(@list, @search, true)))", { list: list, search: search });
|
||||||
|
assertEqual(expected, actual[0]);
|
||||||
|
|
||||||
|
// look up the element using the position
|
||||||
|
actual = getQueryResults("RETURN NOOPT(V8(NTH(@list, @position)))", { list: list, position: actual[0] });
|
||||||
|
assertEqual(search, actual[0]);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -339,6 +363,18 @@ function ahuacatlFunctionsTestSuite () {
|
||||||
|
|
||||||
actual = getQueryResults("RETURN POSITION(@list, @search, true)", { list: list, search: d });
|
actual = getQueryResults("RETURN POSITION(@list, @search, true)", { list: list, search: d });
|
||||||
assertEqual(-1, actual[0]);
|
assertEqual(-1, actual[0]);
|
||||||
|
|
||||||
|
actual = getQueryResults("RETURN NOOPT(POSITION(@list, @search, false))", { list: list, search: d });
|
||||||
|
assertFalse(actual[0]);
|
||||||
|
|
||||||
|
actual = getQueryResults("RETURN NOOPT(POSITION(@list, @search, true))", { list: list, search: d });
|
||||||
|
assertEqual(-1, actual[0]);
|
||||||
|
|
||||||
|
actual = getQueryResults("RETURN NOOPT(V8(POSITION(@list, @search, false)))", { list: list, search: d });
|
||||||
|
assertFalse(actual[0]);
|
||||||
|
|
||||||
|
actual = getQueryResults("RETURN NOOPT(V8(POSITION(@list, @search, true)))", { list: list, search: d });
|
||||||
|
assertEqual(-1, actual[0]);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -354,6 +390,22 @@ function ahuacatlFunctionsTestSuite () {
|
||||||
assertQueryWarningAndNull(errors.ERROR_QUERY_ARRAY_EXPECTED.code, "RETURN POSITION(4, 'foo')");
|
assertQueryWarningAndNull(errors.ERROR_QUERY_ARRAY_EXPECTED.code, "RETURN POSITION(4, 'foo')");
|
||||||
assertQueryWarningAndNull(errors.ERROR_QUERY_ARRAY_EXPECTED.code, "RETURN POSITION(\"yes\", 'foo')");
|
assertQueryWarningAndNull(errors.ERROR_QUERY_ARRAY_EXPECTED.code, "RETURN POSITION(\"yes\", 'foo')");
|
||||||
assertQueryWarningAndNull(errors.ERROR_QUERY_ARRAY_EXPECTED.code, "RETURN POSITION({ }, 'foo')");
|
assertQueryWarningAndNull(errors.ERROR_QUERY_ARRAY_EXPECTED.code, "RETURN POSITION({ }, 'foo')");
|
||||||
|
|
||||||
|
assertQueryError(errors.ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH.code, "RETURN NOOPT(POSITION())");
|
||||||
|
assertQueryError(errors.ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH.code, "RETURN NOOPT(POSITION([ ]))");
|
||||||
|
assertQueryWarningAndNull(errors.ERROR_QUERY_ARRAY_EXPECTED.code, "RETURN NOOPT(POSITION(null, 'foo'))");
|
||||||
|
assertQueryWarningAndNull(errors.ERROR_QUERY_ARRAY_EXPECTED.code, "RETURN NOOPT(POSITION(true, 'foo'))");
|
||||||
|
assertQueryWarningAndNull(errors.ERROR_QUERY_ARRAY_EXPECTED.code, "RETURN NOOPT(POSITION(4, 'foo'))");
|
||||||
|
assertQueryWarningAndNull(errors.ERROR_QUERY_ARRAY_EXPECTED.code, "RETURN NOOPT(POSITION(\"yes\", 'foo'))");
|
||||||
|
assertQueryWarningAndNull(errors.ERROR_QUERY_ARRAY_EXPECTED.code, "RETURN NOOPT(POSITION({ }, 'foo'))");
|
||||||
|
|
||||||
|
assertQueryError(errors.ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH.code, "RETURN NOOPT(V8(POSITION()))");
|
||||||
|
assertQueryError(errors.ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH.code, "RETURN NOOPT(V8(POSITION([ ])))");
|
||||||
|
assertQueryWarningAndNull(errors.ERROR_QUERY_ARRAY_EXPECTED.code, "RETURN NOOPT(V8(POSITION(null, 'foo')))");
|
||||||
|
assertQueryWarningAndNull(errors.ERROR_QUERY_ARRAY_EXPECTED.code, "RETURN NOOPT(V8(POSITION(true, 'foo')))");
|
||||||
|
assertQueryWarningAndNull(errors.ERROR_QUERY_ARRAY_EXPECTED.code, "RETURN NOOPT(V8(POSITION(4, 'foo')))");
|
||||||
|
assertQueryWarningAndNull(errors.ERROR_QUERY_ARRAY_EXPECTED.code, "RETURN NOOPT(V8(POSITION(\"yes\", 'foo')))");
|
||||||
|
assertQueryWarningAndNull(errors.ERROR_QUERY_ARRAY_EXPECTED.code, "RETURN NOOPT(V8(POSITION({ }, 'foo')))");
|
||||||
},
|
},
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
Loading…
Reference in New Issue