mirror of https://gitee.com/bigwinds/arangodb
Merge branch 'devel' of github.com:triAGENS/ArangoDB into devel
This commit is contained in:
commit
ed46b28f7c
|
@ -1,6 +1,8 @@
|
|||
v1.5.x (XXXX-XX-XX)
|
||||
-------------------
|
||||
|
||||
* added AQL functions `NTH` and `POSITION`
|
||||
|
||||
* added signal handler for arangosh to save last command in more cases
|
||||
|
||||
* added extra prompt placeholders for arangosh:
|
||||
|
|
|
@ -1103,6 +1103,16 @@ AQL supports the following functions to operate on list values:
|
|||
- @FN{LAST(@FA{list})}: returns the last element in @FA{list} or `null` if the
|
||||
list is empty.
|
||||
|
||||
- @FN{NTH(@FA{list}, @FA{position})}: returns the list element at position @FA{position}.
|
||||
Positions start at 0. If @FA{position} is negative or beyond the upper bound of the list
|
||||
specified by @FA{list}, then `null` will be returned.
|
||||
|
||||
- @FN{POSITION(@FA{list}, @FA{search}, @FA{return-index})}: returns the position of the
|
||||
element @FA{search} in list @FA{list}. Positions start at 0. If the element is not
|
||||
found, then `-1` is returned. If @FA{return-index} is `false`, then instead of the
|
||||
position only `true` or `false` are returned, depending on whether the sought element
|
||||
is contained in the list.
|
||||
|
||||
- @FN{UNIQUE(@FA{list})}: returns all unique elements in @FA{list}. To determine
|
||||
uniqueness, the function will use the comparison order defined in @ref AqlTypeOrder.
|
||||
Calling this function might return the unique elements in any order.
|
||||
|
|
|
@ -673,6 +673,8 @@ TRI_associative_pointer_t* TRI_CreateFunctionsAql (void) {
|
|||
REGISTER_FUNCTION("REVERSE", "REVERSE", true, false, "ls", NULL);
|
||||
REGISTER_FUNCTION("FIRST", "FIRST", true, false, "l", NULL);
|
||||
REGISTER_FUNCTION("LAST", "LAST", true, false, "l", NULL);
|
||||
REGISTER_FUNCTION("NTH", "NTH", true, false, "l,n", NULL);
|
||||
REGISTER_FUNCTION("POSITION", "POSITION", true, false, "l,.|b", NULL);
|
||||
|
||||
// document functions
|
||||
REGISTER_FUNCTION("HAS", "HAS", true, false, "az,s", NULL);
|
||||
|
|
|
@ -2482,6 +2482,44 @@ function LAST (value) {
|
|||
return value[value.length - 1];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief get the position of an element in a list
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function POSITION (value, search, returnIndex) {
|
||||
"use strict";
|
||||
|
||||
LIST(value);
|
||||
returnIndex = returnIndex || false;
|
||||
|
||||
var i, n = value.length;
|
||||
|
||||
if (n > 0) {
|
||||
for (i = 0; i < n; ++i) {
|
||||
if (RELATIONAL_EQUAL(value[i], search)) {
|
||||
return returnIndex ? i : true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return returnIndex ? -1 : false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief get the nth element in a list, or null if the item does not exist
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function NTH (value, position) {
|
||||
"use strict";
|
||||
|
||||
LIST(value);
|
||||
if (position < 0 || position >= value.length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return value[position];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief reverse the elements in a list or in a string
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -4035,6 +4073,8 @@ exports.LIMIT = LIMIT;
|
|||
exports.LENGTH = LENGTH;
|
||||
exports.FIRST = FIRST;
|
||||
exports.LAST = LAST;
|
||||
exports.POSITION = POSITION;
|
||||
exports.NTH = NTH;
|
||||
exports.REVERSE = REVERSE;
|
||||
exports.RANGE = RANGE;
|
||||
exports.UNIQUE = UNIQUE;
|
||||
|
|
|
@ -306,6 +306,149 @@ function ahuacatlFunctionsTestSuite () {
|
|||
assertQueryError(errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH.code, "RETURN LAST({ })");
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test position function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testPosition : function () {
|
||||
var list = [ "foo", "bar", null, "baz", true, 42, [ "BORK" ], { code: "foo", name: "test" }, false, 0, "" ];
|
||||
|
||||
var data = [
|
||||
[ "foo", 0 ],
|
||||
[ "bar", 1 ],
|
||||
[ null, 2 ],
|
||||
[ "baz", 3 ],
|
||||
[ true, 4 ],
|
||||
[ 42, 5 ],
|
||||
[ [ "BORK" ], 6 ],
|
||||
[ { code: "foo", name: "test" }, 7 ],
|
||||
[ false, 8 ],
|
||||
[ 0, 9 ],
|
||||
[ "", 10 ]
|
||||
];
|
||||
|
||||
data.forEach(function (d) {
|
||||
var search = d[0];
|
||||
var expected = d[1];
|
||||
|
||||
// find if element is contained in list (should be true)
|
||||
var actual = getQueryResults("RETURN POSITION(@list, @search, false)", { list: list, search: search });
|
||||
assertTrue(actual[0]);
|
||||
|
||||
// find position of element in list
|
||||
actual = getQueryResults("RETURN POSITION(@list, @search, true)", { list: list, search: search });
|
||||
assertEqual(expected, actual[0]);
|
||||
|
||||
// look up the element using the position
|
||||
actual = getQueryResults("RETURN NTH(@list, @position)", { list: list, position: actual[0] });
|
||||
assertEqual(search, actual[0]);
|
||||
});
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test position function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testPositionNotThere : function () {
|
||||
var list = [ "foo", "bar", null, "baz", true, 42, [ "BORK" ], { code: "foo", name: "test" }, false, 0, "" ];
|
||||
|
||||
var data = [ "foot", "barz", 43, 1, -42, { code: "foo", name: "test", bar: "baz" }, " ", " foo", "FOO", "bazt", 0.1, [ ], [ "bork" ] ];
|
||||
|
||||
data.forEach(function (d) {
|
||||
var actual = getQueryResults("RETURN POSITION(@list, @search, false)", { list: list, search: d });
|
||||
assertFalse(actual[0]);
|
||||
|
||||
actual = getQueryResults("RETURN POSITION(@list, @search, true)", { list: list, search: d });
|
||||
assertEqual(-1, actual[0]);
|
||||
});
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test position function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testPositionInvalid : function () {
|
||||
assertQueryError(errors.ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH.code, "RETURN POSITION()");
|
||||
assertQueryError(errors.ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH.code, "RETURN POSITION([ ])");
|
||||
assertQueryError(errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH.code, "RETURN POSITION(null, 'foo')");
|
||||
assertQueryError(errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH.code, "RETURN POSITION(true, 'foo')");
|
||||
assertQueryError(errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH.code, "RETURN POSITION(4, 'foo')");
|
||||
assertQueryError(errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH.code, "RETURN POSITION(\"yes\", 'foo')");
|
||||
assertQueryError(errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH.code, "RETURN POSITION({ }, 'foo')");
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test nth function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testNthEmpty : function () {
|
||||
var i;
|
||||
|
||||
for (i = -3; i <= 3; ++i) {
|
||||
var actual = getQueryResults("RETURN NTH([ ], @pos)", { pos: i });
|
||||
assertNull(actual[0]);
|
||||
}
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test nth function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testNthNegative : function () {
|
||||
var i;
|
||||
|
||||
for (i = -3; i <= 3; ++i) {
|
||||
var actual = getQueryResults("RETURN NTH([ 1, 2, 3, 4 ], @pos)", { pos: i });
|
||||
if (i < 0) {
|
||||
assertNull(actual[0]);
|
||||
}
|
||||
else {
|
||||
assertEqual(i + 1, actual[0]);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test nth function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testNthBounds : function () {
|
||||
var i;
|
||||
|
||||
for (i = 0; i <= 10; ++i) {
|
||||
var actual = getQueryResults("RETURN NTH([ 'a1', 'a2', 'a3', 'a4', 'a5' ], @pos)", { pos: i });
|
||||
if (i < 5) {
|
||||
assertEqual('a' + (i + 1), actual[0]);
|
||||
}
|
||||
else {
|
||||
assertNull(actual[0]);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test nth function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testNthInvalid : function () {
|
||||
assertQueryError(errors.ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH.code, "RETURN NTH()");
|
||||
assertQueryError(errors.ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH.code, "RETURN NTH([ ])");
|
||||
assertQueryError(errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH.code, "RETURN NTH(null, 1)");
|
||||
assertQueryError(errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH.code, "RETURN NTH(true, 1)");
|
||||
assertQueryError(errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH.code, "RETURN NTH(4, 1)");
|
||||
assertQueryError(errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH.code, "RETURN NTH(\"yes\", 1)");
|
||||
assertQueryError(errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH.code, "RETURN NTH({ }, 1)");
|
||||
|
||||
assertQueryError(errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH.code, "RETURN NTH([ ], null)");
|
||||
assertQueryError(errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH.code, "RETURN NTH([ ], false)");
|
||||
assertQueryError(errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH.code, "RETURN NTH([ ], true)");
|
||||
assertQueryError(errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH.code, "RETURN NTH([ ], '')");
|
||||
assertQueryError(errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH.code, "RETURN NTH([ ], '1234')");
|
||||
assertQueryError(errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH.code, "RETURN NTH([ ], [ ])");
|
||||
assertQueryError(errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH.code, "RETURN NTH([ ], { \"foo\": true})");
|
||||
assertQueryError(errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH.code, "RETURN NTH([ ], { })");
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test reverse function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
Loading…
Reference in New Issue