mirror of https://gitee.com/bigwinds/arangodb
Merge branch 'aql2' of ssh://github.com/triAGENS/ArangoDB into aql2
This commit is contained in:
commit
aefea865f5
|
@ -51,8 +51,8 @@ Function::Function (std::string const& externalName,
|
||||||
arguments(arguments),
|
arguments(arguments),
|
||||||
isDeterministic(isDeterministic),
|
isDeterministic(isDeterministic),
|
||||||
canThrow(canThrow),
|
canThrow(canThrow),
|
||||||
containsCollectionParameter(false),
|
implementation(implementation),
|
||||||
implementation(implementation) {
|
conversions() {
|
||||||
|
|
||||||
initArguments();
|
initArguments();
|
||||||
}
|
}
|
||||||
|
@ -68,56 +68,16 @@ Function::~Function () {
|
||||||
// --SECTION-- public methods
|
// --SECTION-- public methods
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief whether or not a positional argument needs to be converted from a
|
|
||||||
/// collection parameter to a collection name parameter
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
bool Function::mustConvertArgument (size_t position) const {
|
|
||||||
bool foundArg = false;
|
|
||||||
size_t i = 0;
|
|
||||||
char const* p = arguments.c_str();
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
char const c = *p++;
|
|
||||||
|
|
||||||
switch (c) {
|
|
||||||
case '\0':
|
|
||||||
return false;
|
|
||||||
|
|
||||||
case '|':
|
|
||||||
case ',':
|
|
||||||
if (foundArg) {
|
|
||||||
if (++i > position) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
foundArg = false;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'h':
|
|
||||||
if (i == position) {
|
|
||||||
// found an argument to convert
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
foundArg = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
foundArg = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief parse the argument list and set the minimum and maximum number of
|
/// @brief parse the argument list and set the minimum and maximum number of
|
||||||
/// arguments
|
/// arguments
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void Function::initArguments () {
|
void Function::initArguments () {
|
||||||
minRequiredArguments = maxRequiredArguments = 0;
|
minRequiredArguments = 0;
|
||||||
|
maxRequiredArguments = 0;
|
||||||
|
|
||||||
|
size_t position = 0;
|
||||||
|
|
||||||
// setup some parsing state
|
// setup some parsing state
|
||||||
bool inOptional = false;
|
bool inOptional = false;
|
||||||
|
@ -140,6 +100,7 @@ void Function::initArguments () {
|
||||||
|
|
||||||
case '|':
|
case '|':
|
||||||
// beginning of optional arguments
|
// beginning of optional arguments
|
||||||
|
++position;
|
||||||
TRI_ASSERT(! inOptional);
|
TRI_ASSERT(! inOptional);
|
||||||
if (foundArg) {
|
if (foundArg) {
|
||||||
++minRequiredArguments;
|
++minRequiredArguments;
|
||||||
|
@ -151,6 +112,7 @@ void Function::initArguments () {
|
||||||
|
|
||||||
case ',':
|
case ',':
|
||||||
// next argument
|
// next argument
|
||||||
|
++position;
|
||||||
TRI_ASSERT(foundArg);
|
TRI_ASSERT(foundArg);
|
||||||
|
|
||||||
if (! inOptional) {
|
if (! inOptional) {
|
||||||
|
@ -166,12 +128,35 @@ void Function::initArguments () {
|
||||||
maxRequiredArguments = MaxArguments;
|
maxRequiredArguments = MaxArguments;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
default:
|
case 'h':
|
||||||
if (c == 'h') {
|
// we found a collection parameter
|
||||||
// note that we found a collection parameter
|
|
||||||
containsCollectionParameter = true;
|
// set the conversion info for the position
|
||||||
|
if (conversions.size() <= position) {
|
||||||
|
// we don't yet have another parameter at this position
|
||||||
|
conversions.push_back(CONVERSION_REQUIRED);
|
||||||
|
}
|
||||||
|
else if (conversions[position] == CONVERSION_NONE) {
|
||||||
|
// we already had a parameter at this position
|
||||||
|
conversions[position] = CONVERSION_OPTIONAL;
|
||||||
}
|
}
|
||||||
foundArg = true;
|
foundArg = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
// we found any other parameter
|
||||||
|
|
||||||
|
// set the conversion info for the position
|
||||||
|
if (conversions.size() <= position) {
|
||||||
|
// we don't yet have another parameter at this position
|
||||||
|
conversions.push_back(CONVERSION_NONE);
|
||||||
|
}
|
||||||
|
else if (conversions[position] == CONVERSION_REQUIRED) {
|
||||||
|
// we already had a parameter at this position
|
||||||
|
conversions[position] = CONVERSION_OPTIONAL;
|
||||||
|
}
|
||||||
|
foundArg = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,12 @@ namespace triagens {
|
||||||
|
|
||||||
struct Function {
|
struct Function {
|
||||||
|
|
||||||
|
enum Conversion {
|
||||||
|
CONVERSION_NONE,
|
||||||
|
CONVERSION_OPTIONAL,
|
||||||
|
CONVERSION_REQUIRED
|
||||||
|
};
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// --SECTION-- constructors / destructors
|
// --SECTION-- constructors / destructors
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
@ -87,7 +93,12 @@ namespace triagens {
|
||||||
/// collection parameter to a collection name parameter
|
/// collection parameter to a collection name parameter
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
bool mustConvertArgument (size_t) const;
|
inline Conversion getArgumentConversion (size_t position) const {
|
||||||
|
if (position >= conversions.size()) {
|
||||||
|
return CONVERSION_NONE;
|
||||||
|
}
|
||||||
|
return conversions[position];
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief parse the argument list and set the minimum and maximum number of
|
/// @brief parse the argument list and set the minimum and maximum number of
|
||||||
|
@ -104,63 +115,62 @@ namespace triagens {
|
||||||
/// @brief function name (name used in JavaScript implementation)
|
/// @brief function name (name used in JavaScript implementation)
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
std::string const internalName;
|
std::string const internalName;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief function name (name visible to the end user)
|
/// @brief function name (name visible to the end user)
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
std::string const externalName;
|
std::string const externalName;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief function arguments
|
/// @brief function arguments
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
std::string const arguments;
|
std::string const arguments;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief whether or not the function is deterministic (i.e. its results are
|
/// @brief whether or not the function is deterministic (i.e. its results are
|
||||||
/// identical when called repeatedly with the same input values)
|
/// identical when called repeatedly with the same input values)
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
bool const isDeterministic;
|
bool const isDeterministic;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief whether or not the function may throw a runtime exception
|
/// @brief whether or not the function may throw a runtime exception
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
bool const canThrow;
|
bool const canThrow;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief whether or not the function contains a collection parameter that
|
|
||||||
/// will cause some special conversion during function calls
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
bool containsCollectionParameter;
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief minimum number of required arguments
|
/// @brief minimum number of required arguments
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
size_t minRequiredArguments;
|
size_t minRequiredArguments;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief maximum number of required arguments
|
/// @brief maximum number of required arguments
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
size_t maxRequiredArguments;
|
size_t maxRequiredArguments;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief C++ implementation of the function (maybe nullptr)
|
/// @brief C++ implementation of the function (maybe nullptr)
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
FunctionImplementation implementation;
|
FunctionImplementation implementation;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief function argument conversion information
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
std::vector<Conversion> conversions;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief maximum number of function arguments that can be used
|
/// @brief maximum number of function arguments that can be used
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
static size_t const MaxArguments = 1024;
|
static size_t const MaxArguments = 1024;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -623,28 +623,28 @@ void V8Executor::generateCodeFunctionCall (AstNode const* node) {
|
||||||
|
|
||||||
auto member = args->getMember(i);
|
auto member = args->getMember(i);
|
||||||
|
|
||||||
if (member != nullptr) {
|
if (member == nullptr) {
|
||||||
if (func->containsCollectionParameter &&
|
continue;
|
||||||
member->type == NODE_TYPE_COLLECTION &&
|
}
|
||||||
func->mustConvertArgument(i)) {
|
|
||||||
// the parameter at this position is a collection name that is converted to a string
|
auto conversion = func->getArgumentConversion(i);
|
||||||
// do a parameter conversion from a collection parameter to a collection name parameter
|
|
||||||
char const* name = member->getStringValue();
|
if (member->type == NODE_TYPE_COLLECTION &&
|
||||||
generateCodeString(name);
|
(conversion == Function::CONVERSION_REQUIRED || conversion == Function::CONVERSION_OPTIONAL)) {
|
||||||
}
|
// the parameter at this position is a collection name that is converted to a string
|
||||||
/*
|
// do a parameter conversion from a collection parameter to a collection name parameter
|
||||||
else {
|
char const* name = member->getStringValue();
|
||||||
// the parameter at the position is not a collection name... fail
|
generateCodeString(name);
|
||||||
THROW_ARANGO_EXCEPTION_PARAMS(TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, func->internalName.c_str());
|
}
|
||||||
}
|
else if (conversion == Function::CONVERSION_REQUIRED) {
|
||||||
}
|
// the parameter at the position is not a collection name... fail
|
||||||
*/
|
THROW_ARANGO_EXCEPTION_PARAMS(TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, func->internalName.c_str());
|
||||||
else {
|
}
|
||||||
// generate regular code for the node
|
else {
|
||||||
generateCodeNode(args->getMember(i));
|
generateCodeNode(args->getMember(i));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_buffer->appendText(")");
|
_buffer->appendText(")");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3420,6 +3420,14 @@ function GEO_NEAR (collection, latitude, longitude, limit, distanceAttribute) {
|
||||||
// use default value
|
// use default value
|
||||||
limit = 100;
|
limit = 100;
|
||||||
}
|
}
|
||||||
|
else if (TYPEWEIGHT(limit) !== TYPEWEIGHT_NUMBER) {
|
||||||
|
THROW(INTERNAL.errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, "NEAR");
|
||||||
|
}
|
||||||
|
|
||||||
|
var weight = TYPEWEIGHT(distanceAttribute);
|
||||||
|
if (weight !== TYPEWEIGHT_NULL && weight !== TYPEWEIGHT_STRING) {
|
||||||
|
THROW(INTERNAL.errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, "NEAR");
|
||||||
|
}
|
||||||
|
|
||||||
if (isCoordinator) {
|
if (isCoordinator) {
|
||||||
var query = COLLECTION(collection).near(latitude, longitude);
|
var query = COLLECTION(collection).near(latitude, longitude);
|
||||||
|
@ -3462,6 +3470,11 @@ function GEO_WITHIN (collection, latitude, longitude, radius, distanceAttribute)
|
||||||
query._distance = distanceAttribute;
|
query._distance = distanceAttribute;
|
||||||
return query.toArray();
|
return query.toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var weight = TYPEWEIGHT(distanceAttribute);
|
||||||
|
if (weight !== TYPEWEIGHT_NULL && weight !== TYPEWEIGHT_STRING) {
|
||||||
|
THROW(INTERNAL.errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, "NEAR");
|
||||||
|
}
|
||||||
|
|
||||||
var idx = INDEX(COLLECTION(collection), [ "geo1", "geo2" ]);
|
var idx = INDEX(COLLECTION(collection), [ "geo1", "geo2" ]);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue