mirror of https://gitee.com/bigwinds/arangodb
issue #80: support LENGTH(collection)
This commit is contained in:
parent
fbc1d65135
commit
7c0e146246
|
@ -1138,8 +1138,8 @@ static void ProcessArgList (TRI_aql_codegen_js_t* const generator,
|
|||
ScopeOutput(generator, ", ");
|
||||
}
|
||||
|
||||
if (parameter->_type == AQL_NODE_COLLECTION) {
|
||||
// collection arguments will be created as string arguments => e.g. "users"
|
||||
if (parameter->_type == AQL_NODE_COLLECTION && TRI_ConvertParameterFunctionAql(function, i)) {
|
||||
// collection arguments will be created as string argument => e.g. "users"
|
||||
ScopeOutputQuoted(generator, TRI_AQL_NODE_STRING(parameter));
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -128,6 +128,7 @@ static bool CheckArgumentType (TRI_aql_node_t* parameter,
|
|||
if (*name == '@') {
|
||||
// collection bind parameter. this is an error
|
||||
found._collection = true;
|
||||
found._list = true; // a collection is a list of documents
|
||||
}
|
||||
else {
|
||||
// regular bind parameter
|
||||
|
@ -168,13 +169,14 @@ static bool CheckArgumentType (TRI_aql_node_t* parameter,
|
|||
else if (parameter->_type == AQL_NODE_COLLECTION) {
|
||||
// actual parameter is a collection
|
||||
found._collection = true;
|
||||
found._list = true; // a collection is a list of documents
|
||||
}
|
||||
else {
|
||||
// we cannot yet determine the type of the parameter
|
||||
// this is the case if the argument is an expression, a function call etc.
|
||||
|
||||
if (!allowed->_collection) {
|
||||
// if we do require anything else but collection, we don't know the
|
||||
// if we do require anything else but a collection, we don't know the
|
||||
// type and must exit here
|
||||
return true;
|
||||
}
|
||||
|
@ -341,7 +343,8 @@ TRI_associative_pointer_t* TRI_InitialiseFunctionsAql (void) {
|
|||
NULL);
|
||||
|
||||
// . = argument of any type (except collection)
|
||||
// c = collection
|
||||
// c = collection name, will be converted into list with documents
|
||||
// h = collection name, will be converted into string
|
||||
// z = null
|
||||
// b = bool
|
||||
// n = number
|
||||
|
@ -380,11 +383,11 @@ TRI_associative_pointer_t* TRI_InitialiseFunctionsAql (void) {
|
|||
REGISTER_FUNCTION("RAND", "NUMBER_RAND", false, false, "");
|
||||
|
||||
// geo functions
|
||||
REGISTER_FUNCTION("NEAR", "GEO_NEAR", false, false, "c,n,n,n|s");
|
||||
REGISTER_FUNCTION("WITHIN", "GEO_WITHIN", false, false, "c,n,n,n|s");
|
||||
REGISTER_FUNCTION("NEAR", "GEO_NEAR", false, false, "h,n,n,n|s");
|
||||
REGISTER_FUNCTION("WITHIN", "GEO_WITHIN", false, false, "h,n,n,n|s");
|
||||
|
||||
// graph functions
|
||||
REGISTER_FUNCTION("PATHS", "GRAPH_PATHS", false, false, "c,c|s,b");
|
||||
REGISTER_FUNCTION("PATHS", "GRAPH_PATHS", false, false, "c,h|s,b");
|
||||
|
||||
// misc functions
|
||||
REGISTER_FUNCTION("FAIL", "FAIL", false, false, "|s"); // FAIL is non-deterministic, otherwise query optimisation will fail!
|
||||
|
@ -531,6 +534,45 @@ bool TRI_RegisterFunctionAql (TRI_associative_pointer_t* functions,
|
|||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief check whether a function argument must be converted to another type
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool TRI_ConvertParameterFunctionAql (const TRI_aql_function_t* const function,
|
||||
const size_t checkArg) {
|
||||
const char* pattern;
|
||||
char c;
|
||||
size_t i = 0;
|
||||
bool foundArg = false;
|
||||
|
||||
assert(function);
|
||||
|
||||
i = 0;
|
||||
pattern = function->_argPattern;
|
||||
while ((c = *pattern++)) {
|
||||
switch (c) {
|
||||
case '|':
|
||||
case ',':
|
||||
if (foundArg) {
|
||||
if (++i > checkArg) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
foundArg = false;
|
||||
break;
|
||||
case 'h':
|
||||
if (i == checkArg) {
|
||||
return true;
|
||||
}
|
||||
// break intentionally missing
|
||||
default:
|
||||
foundArg = true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief validate the arguments passed to a function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -642,7 +684,11 @@ bool TRI_ValidateArgsFunctionAql (TRI_aql_context_t* const context,
|
|||
allowed._array = true;
|
||||
foundArg = true;
|
||||
break;
|
||||
case 'c': // collection
|
||||
case 'c': // collection name => list
|
||||
allowed._collection = true;
|
||||
foundArg = true;
|
||||
break;
|
||||
case 'h': // collection name => string
|
||||
allowed._collection = true;
|
||||
foundArg = true;
|
||||
break;
|
||||
|
|
|
@ -103,6 +103,13 @@ bool TRI_RegisterFunctionAql (TRI_associative_pointer_t*,
|
|||
const bool,
|
||||
const char* const);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief check whether a function argument must be converted to another type
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool TRI_ConvertParameterFunctionAql (const TRI_aql_function_t* const,
|
||||
const size_t);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief validate the arguments passed to a function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -1912,8 +1912,8 @@ function AHUACATL_GEO_WITHIN () {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function AHUACATL_GRAPH_PATHS () {
|
||||
var collection1 = arguments[0];
|
||||
var collection2 = arguments[1];
|
||||
var vertices = arguments[0];
|
||||
var edgeCollection = arguments[1];
|
||||
var direction = arguments[2] != undefined ? arguments[2] : "outbound";
|
||||
var followCycles = arguments[3] ? arguments[3] : false;
|
||||
|
||||
|
@ -1921,6 +1921,8 @@ function AHUACATL_GRAPH_PATHS () {
|
|||
var maxLength = 10;
|
||||
var searchDirection;
|
||||
|
||||
AHUACATL_LIST(vertices);
|
||||
|
||||
// validate arguments
|
||||
if (direction == "outbound") {
|
||||
searchDirection = 1;
|
||||
|
@ -1940,18 +1942,14 @@ function AHUACATL_GRAPH_PATHS () {
|
|||
AHUACATL_THROW(internal.errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, "PATHS");
|
||||
}
|
||||
|
||||
var vertexCollection = internal.db[collection1];
|
||||
var edgeCollection = internal.edges[collection2];
|
||||
var searchAttributes = {
|
||||
"vertexCollection" : vertexCollection,
|
||||
"edgeCollection" : edgeCollection,
|
||||
"edgeCollection" : internal.edges[edgeCollection],
|
||||
"minLength" : minLength,
|
||||
"maxLength" : maxLength,
|
||||
"direction" : searchDirection,
|
||||
"followCycles" : followCycles,
|
||||
};
|
||||
|
||||
var vertices = vertexCollection.all().toArray();
|
||||
// TODO: restrict allEdges to edges with certain _from values etc.
|
||||
|
||||
var result = [ ];
|
||||
|
|
|
@ -1913,8 +1913,8 @@ static string JS_server_ahuacatl =
|
|||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"\n"
|
||||
"function AHUACATL_GRAPH_PATHS () {\n"
|
||||
" var collection1 = arguments[0];\n"
|
||||
" var collection2 = arguments[1];\n"
|
||||
" var vertices = arguments[0];\n"
|
||||
" var edgeCollection = arguments[1];\n"
|
||||
" var direction = arguments[2] != undefined ? arguments[2] : \"outbound\";\n"
|
||||
" var followCycles = arguments[3] ? arguments[3] : false;\n"
|
||||
"\n"
|
||||
|
@ -1922,6 +1922,8 @@ static string JS_server_ahuacatl =
|
|||
" var maxLength = 10;\n"
|
||||
" var searchDirection;\n"
|
||||
"\n"
|
||||
" AHUACATL_LIST(vertices);\n"
|
||||
"\n"
|
||||
" // validate arguments\n"
|
||||
" if (direction == \"outbound\") {\n"
|
||||
" searchDirection = 1;\n"
|
||||
|
@ -1941,18 +1943,14 @@ static string JS_server_ahuacatl =
|
|||
" AHUACATL_THROW(internal.errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, \"PATHS\");\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" var vertexCollection = internal.db[collection1];\n"
|
||||
" var edgeCollection = internal.edges[collection2];\n"
|
||||
" var searchAttributes = { \n"
|
||||
" \"vertexCollection\" : vertexCollection, \n"
|
||||
" \"edgeCollection\" : edgeCollection, \n"
|
||||
" \"edgeCollection\" : internal.edges[edgeCollection],\n"
|
||||
" \"minLength\" : minLength, \n"
|
||||
" \"maxLength\" : maxLength, \n"
|
||||
" \"direction\" : searchDirection,\n"
|
||||
" \"followCycles\" : followCycles,\n"
|
||||
" };\n"
|
||||
"\n"
|
||||
" var vertices = vertexCollection.all().toArray();\n"
|
||||
" // TODO: restrict allEdges to edges with certain _from values etc.\n"
|
||||
"\n"
|
||||
" var result = [ ];\n"
|
||||
|
|
Loading…
Reference in New Issue