mirror of https://gitee.com/bigwinds/arangodb
fixed value detection, added tests
This commit is contained in:
parent
475a1d61ee
commit
a72bbaea08
|
@ -26,6 +26,7 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "Ahuacatl/ahuacatl-ast-node.h"
|
||||
#include "Ahuacatl/ahuacatl-collections.h"
|
||||
#include "Ahuacatl/ahuacatl-functions.h"
|
||||
#include "Ahuacatl/ahuacatl-parser-functions.h"
|
||||
|
||||
|
@ -411,6 +412,11 @@ TRI_aql_node_t* TRI_CreateNodeCollectionAql (TRI_aql_context_t* const context,
|
|||
|
||||
// duplicates are not a problem here, we simply ignore them
|
||||
TRI_InsertKeyAssociativePointer(&context->_collectionNames, name, (void*) name, false);
|
||||
|
||||
if (context->_collectionNames._nrUsed > AQL_MAX_COLLECTIONS) {
|
||||
TRI_SetErrorContextAql(context, TRI_ERROR_QUERY_TOO_MANY_COLLECTIONS, NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
|
|
@ -973,6 +973,7 @@ TRI_aql_codegen_js_t* TRI_GenerateCodeAql (const void* const data) {
|
|||
TRI_AppendStringStringBuffer(&generator->_buffer, "({ });");
|
||||
|
||||
LOG_DEBUG("generated code: %s", generator->_buffer._buffer);
|
||||
//printf("generated code: %s", generator->_buffer._buffer);
|
||||
return generator;
|
||||
}
|
||||
|
||||
|
|
|
@ -42,6 +42,25 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- defines
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup Ahuacatl
|
||||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief max number of collections usable in a query
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define AQL_MAX_COLLECTIONS 32
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- public types
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
|
@ -54,7 +54,7 @@ static TRI_string_buffer_t* FcallCode(const char* const name,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (TRI_AppendStringStringBuffer(buffer, "(function(){return ") != TRI_ERROR_NO_ERROR) {
|
||||
if (TRI_AppendStringStringBuffer(buffer, "(function(){return AHUACATL_FCALL(") != TRI_ERROR_NO_ERROR) {
|
||||
TRI_FreeStringBuffer(TRI_UNKNOWN_MEM_ZONE, buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -64,7 +64,7 @@ static TRI_string_buffer_t* FcallCode(const char* const name,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (TRI_AppendCharStringBuffer(buffer, '(') != TRI_ERROR_NO_ERROR) {
|
||||
if (TRI_AppendStringStringBuffer(buffer, ",[") != TRI_ERROR_NO_ERROR) {
|
||||
TRI_FreeStringBuffer(TRI_UNKNOWN_MEM_ZONE, buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -85,7 +85,7 @@ static TRI_string_buffer_t* FcallCode(const char* const name,
|
|||
}
|
||||
}
|
||||
|
||||
if (TRI_AppendStringStringBuffer(buffer, ");})") != TRI_ERROR_NO_ERROR) {
|
||||
if (TRI_AppendStringStringBuffer(buffer, "]);})") != TRI_ERROR_NO_ERROR) {
|
||||
TRI_FreeStringBuffer(TRI_UNKNOWN_MEM_ZONE, buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -143,6 +143,7 @@ static TRI_aql_node_t* OptimiseFcall (TRI_aql_context_t* const context,
|
|||
json = TRI_ExecuteResultContext(execContext);
|
||||
if (!json) {
|
||||
TRI_FreeExecutionContext(execContext);
|
||||
TRI_SetErrorContextAql(context, TRI_ERROR_QUERY_SCRIPT, NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -166,8 +167,7 @@ static TRI_aql_node_t* OptimiseUnaryArithmeticOperation (TRI_aql_context_t* cons
|
|||
}
|
||||
|
||||
if (!TRI_IsNumericValueNodeAql(operand)) {
|
||||
// todo: fix error message
|
||||
TRI_SetErrorContextAql(context, TRI_ERROR_OUT_OF_MEMORY, NULL);
|
||||
TRI_SetErrorContextAql(context, TRI_ERROR_QUERY_INVALID_ARITHMETIC_VALUE, NULL);
|
||||
return node;
|
||||
}
|
||||
|
||||
|
@ -202,8 +202,7 @@ static TRI_aql_node_t* OptimiseUnaryLogicalOperation (TRI_aql_context_t* const c
|
|||
}
|
||||
|
||||
if (!TRI_IsBooleanValueNodeAql(operand)) {
|
||||
// todo: fix error message
|
||||
TRI_SetErrorContextAql(context, TRI_ERROR_OUT_OF_MEMORY, NULL);
|
||||
TRI_SetErrorContextAql(context, TRI_ERROR_QUERY_INVALID_LOGICAL_VALUE, NULL);
|
||||
return node;
|
||||
}
|
||||
|
||||
|
@ -240,14 +239,12 @@ static TRI_aql_node_t* OptimiseBinaryLogicalOperation (TRI_aql_context_t* const
|
|||
isEligibleRhs = TRI_IsConstantValueNodeAql(rhs);
|
||||
|
||||
if (isEligibleLhs && !TRI_IsBooleanValueNodeAql(lhs)) {
|
||||
// todo: fix error message
|
||||
TRI_SetErrorContextAql(context, TRI_ERROR_OUT_OF_MEMORY, NULL);
|
||||
TRI_SetErrorContextAql(context, TRI_ERROR_QUERY_INVALID_LOGICAL_VALUE, NULL);
|
||||
return node;
|
||||
}
|
||||
|
||||
if (isEligibleRhs && !TRI_IsBooleanValueNodeAql(rhs)) {
|
||||
// todo: fix error message
|
||||
TRI_SetErrorContextAql(context, TRI_ERROR_OUT_OF_MEMORY, NULL);
|
||||
TRI_SetErrorContextAql(context, TRI_ERROR_QUERY_INVALID_LOGICAL_VALUE, NULL);
|
||||
return node;
|
||||
}
|
||||
|
||||
|
@ -304,20 +301,13 @@ static TRI_aql_node_t* OptimiseBinaryArithmeticOperation (TRI_aql_context_t* con
|
|||
isEligibleRhs = TRI_IsConstantValueNodeAql(rhs);
|
||||
|
||||
if (isEligibleLhs && !TRI_IsNumericValueNodeAql(lhs)) {
|
||||
// todo: fix error message
|
||||
TRI_SetErrorContextAql(context, TRI_ERROR_OUT_OF_MEMORY, NULL);
|
||||
TRI_SetErrorContextAql(context, TRI_ERROR_QUERY_INVALID_ARITHMETIC_VALUE, NULL);
|
||||
return node;
|
||||
}
|
||||
|
||||
|
||||
if (isEligibleRhs && !TRI_IsNumericValueNodeAql(rhs)) {
|
||||
// todo: fix error message
|
||||
TRI_SetErrorContextAql(context, TRI_ERROR_OUT_OF_MEMORY, NULL);
|
||||
return node;
|
||||
}
|
||||
|
||||
if (TRI_IsConstantValueNodeAql(rhs) && !TRI_IsNumericValueNodeAql(rhs)) {
|
||||
// todo: fix error message
|
||||
TRI_SetErrorContextAql(context, TRI_ERROR_OUT_OF_MEMORY, NULL);
|
||||
TRI_SetErrorContextAql(context, TRI_ERROR_QUERY_INVALID_ARITHMETIC_VALUE, NULL);
|
||||
return node;
|
||||
}
|
||||
|
||||
|
@ -342,16 +332,14 @@ static TRI_aql_node_t* OptimiseBinaryArithmeticOperation (TRI_aql_context_t* con
|
|||
}
|
||||
else if (node->_type == AQL_NODE_OPERATOR_BINARY_DIV) {
|
||||
if (TRI_GetNumericNodeValueAql(rhs) == 0.0) {
|
||||
// todo: fix error message
|
||||
TRI_SetErrorContextAql(context, TRI_ERROR_OUT_OF_MEMORY, NULL);
|
||||
TRI_SetErrorContextAql(context, TRI_ERROR_QUERY_DIVISON_BY_ZERO, NULL);
|
||||
return node;
|
||||
}
|
||||
value = TRI_GetNumericNodeValueAql(lhs) / TRI_GetNumericNodeValueAql(rhs);
|
||||
}
|
||||
else if (node->_type == AQL_NODE_OPERATOR_BINARY_MOD) {
|
||||
if (TRI_GetNumericNodeValueAql(rhs) == 0.0) {
|
||||
// todo: fix error message
|
||||
TRI_SetErrorContextAql(context, TRI_ERROR_OUT_OF_MEMORY, NULL);
|
||||
TRI_SetErrorContextAql(context, TRI_ERROR_QUERY_DIVISON_BY_ZERO, NULL);
|
||||
return node;
|
||||
}
|
||||
value = fmod(TRI_GetNumericNodeValueAql(lhs), TRI_GetNumericNodeValueAql(rhs));
|
||||
|
|
|
@ -229,6 +229,10 @@ bool TRI_ValidateQueryContextAql (TRI_aql_context_t* const context) {
|
|||
return false;
|
||||
}
|
||||
|
||||
if (context->_error._code) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// TRI_DumpTreeAql(context->_first);
|
||||
return true;
|
||||
}
|
||||
|
@ -257,6 +261,10 @@ bool TRI_BindQueryContextAql (TRI_aql_context_t* const context,
|
|||
// bind parameter injection failed
|
||||
return false;
|
||||
}
|
||||
|
||||
if (context->_error._code) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -271,6 +279,10 @@ bool TRI_OptimiseQueryContextAql (TRI_aql_context_t* const context) {
|
|||
// constant folding failed
|
||||
return false;
|
||||
}
|
||||
|
||||
if (context->_error._code) {
|
||||
return false;
|
||||
}
|
||||
// TRI_DumpTreeAql((TRI_aql_node_t*) context->_first);
|
||||
|
||||
return true;
|
||||
|
@ -295,6 +307,10 @@ bool TRI_LockQueryContextAql (TRI_aql_context_t* const context) {
|
|||
if (!TRI_AddBarrierCollectionsAql(context)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (context->_error._code) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -40,8 +40,8 @@
|
|||
/// @brief shorthand to register a query function and process the result
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define REGISTER_FUNCTION(internalName, externalName, deterministic, minArgs, maxArgs) \
|
||||
result &= TRI_RegisterFunctionAql (functions, internalName, "AHUACATL_" externalName, deterministic, minArgs, maxArgs);
|
||||
#define REGISTER_FUNCTION(internalName, externalName, deterministic, group, minArgs, maxArgs) \
|
||||
result &= TRI_RegisterFunctionAql (functions, internalName, "AHUACATL_" externalName, deterministic, group, minArgs, maxArgs);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
|
@ -114,30 +114,37 @@ TRI_associative_pointer_t* TRI_InitialiseFunctionsAql (void) {
|
|||
NULL);
|
||||
|
||||
// cast functions
|
||||
REGISTER_FUNCTION("TONUMBER", "CAST_NUMBER", true, 1, 1);
|
||||
REGISTER_FUNCTION("TOSTRING", "CAST_STRING", true, 1, 1);
|
||||
REGISTER_FUNCTION("TOBOOL", "CAST_BOOL", true, 1, 1);
|
||||
REGISTER_FUNCTION("TONULL", "CAST_NULL", true, 1, 1);
|
||||
REGISTER_FUNCTION("TONUMBER", "CAST_NUMBER", true, false, 1, 1);
|
||||
REGISTER_FUNCTION("TOSTRING", "CAST_STRING", true, false, 1, 1);
|
||||
REGISTER_FUNCTION("TOBOOL", "CAST_BOOL", true, false, 1, 1);
|
||||
REGISTER_FUNCTION("TONULL", "CAST_NULL", true, false, 1, 1);
|
||||
|
||||
// string concat
|
||||
REGISTER_FUNCTION("CONCAT", "STRING_CONCAT", true, false, 2, 256);
|
||||
|
||||
// type check functions
|
||||
REGISTER_FUNCTION("ISNULL", "IS_NULL", true, 1, 1);
|
||||
REGISTER_FUNCTION("ISBOOL", "IS_BOOL", true, 1, 1);
|
||||
REGISTER_FUNCTION("ISNUMBER", "IS_NUMBER", true, 1, 1);
|
||||
REGISTER_FUNCTION("ISSTRING", "IS_STRING", true, 1, 1);
|
||||
REGISTER_FUNCTION("ISLIST", "IS_LIST", true, 1, 1);
|
||||
REGISTER_FUNCTION("ISDOCUMENT", "IS_DOCUMENT", true, 1, 1);
|
||||
|
||||
// string concat
|
||||
REGISTER_FUNCTION("CONCAT", "STRING_CONCAT", true, 2, 256);
|
||||
|
||||
// numeric functions
|
||||
REGISTER_FUNCTION("ISNULL", "IS_NULL", true, false, 1, 1);
|
||||
REGISTER_FUNCTION("ISBOOL", "IS_BOOL", true, false, 1, 1);
|
||||
REGISTER_FUNCTION("ISNUMBER", "IS_NUMBER", true, false, 1, 1);
|
||||
REGISTER_FUNCTION("ISSTRING", "IS_STRING", true, false, 1, 1);
|
||||
REGISTER_FUNCTION("ISLIST", "IS_LIST", true, false, 1, 1);
|
||||
REGISTER_FUNCTION("ISDOCUMENT", "IS_DOCUMENT", true, false, 1, 1);
|
||||
|
||||
// numeric functions
|
||||
REGISTER_FUNCTION("FLOOR", "NUMBER_FLOOR", true, false, 1, 1);
|
||||
REGISTER_FUNCTION("CEIL", "NUMBER_CEIL", true, false, 1, 1);
|
||||
REGISTER_FUNCTION("ROUND", "NUMBER_ROUND", true, false, 1, 1);
|
||||
REGISTER_FUNCTION("ABS", "NUMBER_ABS", true, false, 1, 1);
|
||||
REGISTER_FUNCTION("RAND", "NUMBER_RAND", false, false, 0, 0);
|
||||
|
||||
// string functions
|
||||
|
||||
// misc functions
|
||||
REGISTER_FUNCTION("MERGE", "MERGE", true, 2, 256);
|
||||
REGISTER_FUNCTION("UNION", "UNION", true, 2, 256);
|
||||
REGISTER_FUNCTION("LENGTH", "LENGTH", true, 1, 1);
|
||||
REGISTER_FUNCTION("MERGE", "MERGE", true, false, 2, 256);
|
||||
REGISTER_FUNCTION("UNION", "UNION", true, false, 2, 256);
|
||||
REGISTER_FUNCTION("LENGTH", "LENGTH", true, true, 1, 1);
|
||||
REGISTER_FUNCTION("MIN", "MIN", true, true, 1, 256);
|
||||
REGISTER_FUNCTION("MAX", "MAX", true, true, 1, 256);
|
||||
|
||||
if (!result) {
|
||||
TRI_FreeFunctionsAql(functions);
|
||||
|
@ -212,6 +219,7 @@ bool TRI_RegisterFunctionAql (TRI_associative_pointer_t* functions,
|
|||
const char* const externalName,
|
||||
const char* const internalName,
|
||||
const bool isDeterministic,
|
||||
const bool isGroup,
|
||||
const int minArgs,
|
||||
const int maxArgs) {
|
||||
TRI_aql_function_t* function;
|
||||
|
@ -236,9 +244,10 @@ bool TRI_RegisterFunctionAql (TRI_associative_pointer_t* functions,
|
|||
return false;
|
||||
}
|
||||
|
||||
function->_isDeterministic = isDeterministic;
|
||||
function->_isGroup = isGroup;
|
||||
function->_minArgs = minArgs;
|
||||
function->_maxArgs = maxArgs;
|
||||
function->_isDeterministic = isDeterministic;
|
||||
|
||||
if (TRI_InsertKeyAssociativePointer(functions, externalName, function, false)) {
|
||||
// function already registered
|
||||
|
|
|
@ -52,6 +52,7 @@ typedef struct TRI_aql_function_s {
|
|||
int _minArgs;
|
||||
int _maxArgs;
|
||||
bool _isDeterministic;
|
||||
bool _isGroup;
|
||||
}
|
||||
TRI_aql_function_t;
|
||||
|
||||
|
@ -94,6 +95,7 @@ bool TRI_RegisterFunctionAql (TRI_associative_pointer_t*,
|
|||
const char* const,
|
||||
const char* const,
|
||||
const bool,
|
||||
const bool,
|
||||
const int,
|
||||
const int);
|
||||
|
||||
|
|
|
@ -123,6 +123,11 @@ ERROR_QUERY_DOCUMENT_ATTRIBUTE_REDECLARED,1523,"document attribute '%s' is assig
|
|||
ERROR_QUERY_VARIABLE_NAME_INVALID,1524,"variable name '%s' has an invalid format","Will be raised when an invalid variable name is used."
|
||||
ERROR_QUERY_BIND_PARAMETERS_INVALID,1525,"invalid structure of bind parameters","Will be raised when the structure of bind parameters passed has an unexpected format."
|
||||
ERROR_QUERY_COLLECTION_LOCK_FAILED,1526,"unable to read-lock collection %s","Will be raised when a read lock on the collection cannot be acquired."
|
||||
ERROR_QUERY_TOO_MANY_COLLECTIONS,1527,"too many collections","Will be raised when the number of collections in a query is beyond the allowed value."
|
||||
ERROR_QUERY_INVALID_LOGICAL_VALUE,1528,"invalid logical value","Will be raised when a non-boolean value is used in a logical operation."
|
||||
ERROR_QUERY_INVALID_ARITHMETIC_VALUE,1529,"invalid arithmetic value","Will be raised when a non-numeric value is used in an arithmetic operation."
|
||||
ERROR_QUERY_DIVISON_BY_ZERO,1530,"division by zero","Will be raised when there is an attempt to divide by zero."
|
||||
ERROR_QUERY_SCRIPT,1531,"runtime error","Will be raised when a runtime error is caused by the query."
|
||||
|
||||
################################################################################
|
||||
## AvocadoDB cursor errors
|
||||
|
|
|
@ -89,6 +89,11 @@ void TRI_InitialiseErrorMessages (void) {
|
|||
REG_ERROR(ERROR_QUERY_VARIABLE_NAME_INVALID, "variable name '%s' has an invalid format");
|
||||
REG_ERROR(ERROR_QUERY_BIND_PARAMETERS_INVALID, "invalid structure of bind parameters");
|
||||
REG_ERROR(ERROR_QUERY_COLLECTION_LOCK_FAILED, "unable to read-lock collection %s");
|
||||
REG_ERROR(ERROR_QUERY_TOO_MANY_COLLECTIONS, "too many collections");
|
||||
REG_ERROR(ERROR_QUERY_INVALID_LOGICAL_VALUE, "invalid logical value");
|
||||
REG_ERROR(ERROR_QUERY_INVALID_ARITHMETIC_VALUE, "invalid arithmetic value");
|
||||
REG_ERROR(ERROR_QUERY_DIVISON_BY_ZERO, "division by zero");
|
||||
REG_ERROR(ERROR_QUERY_SCRIPT, "runtime error");
|
||||
REG_ERROR(ERROR_CURSOR_NOT_FOUND, "cursor not found");
|
||||
REG_ERROR(ERROR_SESSION_USERHANDLER_URL_INVALID, "expecting <prefix>/user/<username>");
|
||||
REG_ERROR(ERROR_SESSION_USERHANDLER_CANNOT_CREATE_USER, "cannot create user");
|
||||
|
|
|
@ -195,6 +195,18 @@ extern "C" {
|
|||
/// unexpected format.
|
||||
/// - 1526: @CODE{unable to read-lock collection \%s}
|
||||
/// Will be raised when a read lock on the collection cannot be acquired.
|
||||
/// - 1527: @CODE{too many collections}
|
||||
/// Will be raised when the number of collections in a query is beyond the
|
||||
/// allowed value.
|
||||
/// - 1528: @CODE{invalid logical value}
|
||||
/// Will be raised when a non-boolean value is used in a logical operation.
|
||||
/// - 1529: @CODE{invalid arithmetic value}
|
||||
/// Will be raised when a non-numeric value is used in an arithmetic
|
||||
/// operation.
|
||||
/// - 1530: @CODE{division by zero}
|
||||
/// Will be raised when there is an attempt to divide by zero.
|
||||
/// - 1531: @CODE{runtime error}
|
||||
/// Will be raised when a runtime error is caused by the query.
|
||||
/// - 1600: @CODE{cursor not found}
|
||||
/// Will be raised when a cursor is requested via its id but a cursor with
|
||||
/// that id cannot be found.
|
||||
|
@ -1099,6 +1111,57 @@ void TRI_InitialiseErrorMessages (void);
|
|||
|
||||
#define TRI_ERROR_QUERY_COLLECTION_LOCK_FAILED (1526)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief 1527: ERROR_QUERY_TOO_MANY_COLLECTIONS
|
||||
///
|
||||
/// too many collections
|
||||
///
|
||||
/// Will be raised when the number of collections in a query is beyond the
|
||||
/// allowed value.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define TRI_ERROR_QUERY_TOO_MANY_COLLECTIONS (1527)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief 1528: ERROR_QUERY_INVALID_LOGICAL_VALUE
|
||||
///
|
||||
/// invalid logical value
|
||||
///
|
||||
/// Will be raised when a non-boolean value is used in a logical operation.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define TRI_ERROR_QUERY_INVALID_LOGICAL_VALUE (1528)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief 1529: ERROR_QUERY_INVALID_ARITHMETIC_VALUE
|
||||
///
|
||||
/// invalid arithmetic value
|
||||
///
|
||||
/// Will be raised when a non-numeric value is used in an arithmetic operation.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define TRI_ERROR_QUERY_INVALID_ARITHMETIC_VALUE (1529)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief 1530: ERROR_QUERY_DIVISON_BY_ZERO
|
||||
///
|
||||
/// division by zero
|
||||
///
|
||||
/// Will be raised when there is an attempt to divide by zero.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define TRI_ERROR_QUERY_DIVISON_BY_ZERO (1530)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief 1531: ERROR_QUERY_SCRIPT
|
||||
///
|
||||
/// runtime error
|
||||
///
|
||||
/// Will be raised when a runtime error is caused by the query.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define TRI_ERROR_QUERY_SCRIPT (1531)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief 1600: ERROR_CURSOR_NOT_FOUND
|
||||
///
|
||||
|
|
|
@ -83,6 +83,11 @@ ModuleCache["/internal"].exports.errors = {
|
|||
"ERROR_QUERY_VARIABLE_NAME_INVALID" : { "code" : 1524, "message" : "variable name '%s' has an invalid format" },
|
||||
"ERROR_QUERY_BIND_PARAMETERS_INVALID" : { "code" : 1525, "message" : "invalid structure of bind parameters" },
|
||||
"ERROR_QUERY_COLLECTION_LOCK_FAILED" : { "code" : 1526, "message" : "unable to read-lock collection %s" },
|
||||
"ERROR_QUERY_TOO_MANY_COLLECTIONS" : { "code" : 1527, "message" : "too many collections" },
|
||||
"ERROR_QUERY_INVALID_LOGICAL_VALUE" : { "code" : 1528, "message" : "invalid logical value" },
|
||||
"ERROR_QUERY_INVALID_ARITHMETIC_VALUE" : { "code" : 1529, "message" : "invalid arithmetic value" },
|
||||
"ERROR_QUERY_DIVISON_BY_ZERO" : { "code" : 1530, "message" : "division by zero" },
|
||||
"ERROR_QUERY_SCRIPT" : { "code" : 1531, "message" : "runtime error" },
|
||||
"ERROR_CURSOR_NOT_FOUND" : { "code" : 1600, "message" : "cursor not found" },
|
||||
"ERROR_SESSION_USERHANDLER_URL_INVALID" : { "code" : 1700, "message" : "expecting <prefix>/user/<username>" },
|
||||
"ERROR_SESSION_USERHANDLER_CANNOT_CREATE_USER" : { "code" : 1701, "message" : "cannot create user" },
|
||||
|
|
|
@ -84,6 +84,11 @@ static string JS_common_bootstrap_errors =
|
|||
" \"ERROR_QUERY_VARIABLE_NAME_INVALID\" : { \"code\" : 1524, \"message\" : \"variable name '%s' has an invalid format\" }, \n"
|
||||
" \"ERROR_QUERY_BIND_PARAMETERS_INVALID\" : { \"code\" : 1525, \"message\" : \"invalid structure of bind parameters\" }, \n"
|
||||
" \"ERROR_QUERY_COLLECTION_LOCK_FAILED\" : { \"code\" : 1526, \"message\" : \"unable to read-lock collection %s\" }, \n"
|
||||
" \"ERROR_QUERY_TOO_MANY_COLLECTIONS\" : { \"code\" : 1527, \"message\" : \"too many collections\" }, \n"
|
||||
" \"ERROR_QUERY_INVALID_LOGICAL_VALUE\" : { \"code\" : 1528, \"message\" : \"invalid logical value\" }, \n"
|
||||
" \"ERROR_QUERY_INVALID_ARITHMETIC_VALUE\" : { \"code\" : 1529, \"message\" : \"invalid arithmetic value\" }, \n"
|
||||
" \"ERROR_QUERY_DIVISON_BY_ZERO\" : { \"code\" : 1530, \"message\" : \"division by zero\" }, \n"
|
||||
" \"ERROR_QUERY_SCRIPT\" : { \"code\" : 1531, \"message\" : \"runtime error\" }, \n"
|
||||
" \"ERROR_CURSOR_NOT_FOUND\" : { \"code\" : 1600, \"message\" : \"cursor not found\" }, \n"
|
||||
" \"ERROR_SESSION_USERHANDLER_URL_INVALID\" : { \"code\" : 1700, \"message\" : \"expecting <prefix>/user/<username>\" }, \n"
|
||||
" \"ERROR_SESSION_USERHANDLER_CANNOT_CREATE_USER\" : { \"code\" : 1701, \"message\" : \"cannot create user\" }, \n"
|
||||
|
|
|
@ -86,14 +86,6 @@ function AHUACATL_FCALL(name, parameters) {
|
|||
return name.apply(null, parameters);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief get the value of a bind parameter
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function AHUACATL_GET_PARAMETER (name) {
|
||||
throw "bind parameters not yet supported";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief return the numeric value or undefined if it is out of range
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -1131,6 +1123,75 @@ function AHUACATL_IS_DOCUMENT (value) {
|
|||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- numeric functions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup Ahuacatl
|
||||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief integer closest to value, not greater than value
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function AHUACATL_NUMBER_FLOOR (value) {
|
||||
if (!AHUACATL_IS_NUMBER(value)) {
|
||||
throw "expecting number for floor";
|
||||
}
|
||||
|
||||
return Math.floor(value);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief integer closest to value and not less than value
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function AHUACATL_NUMBER_CEIL (value) {
|
||||
if (!AHUACATL_IS_NUMBER(value)) {
|
||||
throw "expecting number for ceil";
|
||||
}
|
||||
|
||||
return Math.ceil(value);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief integer closest to value
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function AHUACATL_NUMBER_ROUND (value) {
|
||||
if (!AHUACATL_IS_NUMBER(value)) {
|
||||
throw "expecting number for round";
|
||||
}
|
||||
|
||||
return Math.round(value);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief absolute value
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function AHUACATL_NUMBER_ABS (value) {
|
||||
if (!AHUACATL_IS_NUMBER(value)) {
|
||||
throw "expecting number for abs";
|
||||
}
|
||||
|
||||
return Math.abs(value);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief a random value between 0 and 1
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function AHUACATL_NUMBER_RAND () {
|
||||
return Math.random();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- high level query functions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -1280,6 +1341,56 @@ function AHUACATL_UNION () {
|
|||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief maximum of all values
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function AHUACATL_MAX () {
|
||||
var result = null;
|
||||
var value = arguments[0];
|
||||
|
||||
AHUACATL_LIST(value);
|
||||
|
||||
for (var i in value) {
|
||||
var currentValue = value[i];
|
||||
|
||||
if (AHUACATL_TYPEWEIGHT(currentValue) === AHUACATL_TYPEWEIGHT_NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (result === null || AHUACATL_RELATIONAL_GREATER(currentValue, result)) {
|
||||
result = currentValue;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief minimum of all values
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function AHUACATL_MIN () {
|
||||
var result = null;
|
||||
var value = arguments[0];
|
||||
|
||||
AHUACATL_LIST(value);
|
||||
|
||||
for (var i in value) {
|
||||
var currentValue = value[i];
|
||||
|
||||
if (AHUACATL_TYPEWEIGHT(currentValue) === AHUACATL_TYPEWEIGHT_NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (result === null || AHUACATL_RELATIONAL_LESS(currentValue, result)) {
|
||||
result = currentValue;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -88,14 +88,6 @@ static string JS_server_ahuacatl =
|
|||
"}\n"
|
||||
"\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"/// @brief get the value of a bind parameter\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"\n"
|
||||
"function AHUACATL_GET_PARAMETER (name) {\n"
|
||||
" throw \"bind parameters not yet supported\";\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"/// @brief return the numeric value or undefined if it is out of range\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"\n"
|
||||
|
@ -1133,6 +1125,75 @@ static string JS_server_ahuacatl =
|
|||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"\n"
|
||||
"// -----------------------------------------------------------------------------\n"
|
||||
"// --SECTION-- numeric functions\n"
|
||||
"// -----------------------------------------------------------------------------\n"
|
||||
"\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"/// @addtogroup Ahuacatl\n"
|
||||
"/// @{\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"/// @brief integer closest to value, not greater than value\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"\n"
|
||||
"function AHUACATL_NUMBER_FLOOR (value) {\n"
|
||||
" if (!AHUACATL_IS_NUMBER(value)) {\n"
|
||||
" throw \"expecting number for floor\";\n"
|
||||
" }\n"
|
||||
" \n"
|
||||
" return Math.floor(value);\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"/// @brief integer closest to value and not less than value\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"\n"
|
||||
"function AHUACATL_NUMBER_CEIL (value) {\n"
|
||||
" if (!AHUACATL_IS_NUMBER(value)) {\n"
|
||||
" throw \"expecting number for ceil\";\n"
|
||||
" }\n"
|
||||
" \n"
|
||||
" return Math.ceil(value);\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"/// @brief integer closest to value \n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"\n"
|
||||
"function AHUACATL_NUMBER_ROUND (value) {\n"
|
||||
" if (!AHUACATL_IS_NUMBER(value)) {\n"
|
||||
" throw \"expecting number for round\";\n"
|
||||
" }\n"
|
||||
" \n"
|
||||
" return Math.round(value);\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"/// @brief absolute value\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"\n"
|
||||
"function AHUACATL_NUMBER_ABS (value) {\n"
|
||||
" if (!AHUACATL_IS_NUMBER(value)) {\n"
|
||||
" throw \"expecting number for abs\";\n"
|
||||
" }\n"
|
||||
" \n"
|
||||
" return Math.abs(value);\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"/// @brief a random value between 0 and 1\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"\n"
|
||||
"function AHUACATL_NUMBER_RAND () {\n"
|
||||
" return Math.random();\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"/// @}\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"\n"
|
||||
"// -----------------------------------------------------------------------------\n"
|
||||
"// --SECTION-- high level query functions\n"
|
||||
"// -----------------------------------------------------------------------------\n"
|
||||
"\n"
|
||||
|
@ -1282,6 +1343,56 @@ static string JS_server_ahuacatl =
|
|||
"}\n"
|
||||
"\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"/// @brief maximum of all values\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"\n"
|
||||
"function AHUACATL_MAX () {\n"
|
||||
" var result = null;\n"
|
||||
" var value = arguments[0];\n"
|
||||
"\n"
|
||||
" AHUACATL_LIST(value);\n"
|
||||
"\n"
|
||||
" for (var i in value) {\n"
|
||||
" var currentValue = value[i];\n"
|
||||
" \n"
|
||||
" if (AHUACATL_TYPEWEIGHT(currentValue) === AHUACATL_TYPEWEIGHT_NULL) {\n"
|
||||
" continue;\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" if (result === null || AHUACATL_RELATIONAL_GREATER(currentValue, result)) {\n"
|
||||
" result = currentValue;\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" return result;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"/// @brief minimum of all values\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"\n"
|
||||
"function AHUACATL_MIN () {\n"
|
||||
" var result = null;\n"
|
||||
" var value = arguments[0];\n"
|
||||
"\n"
|
||||
" AHUACATL_LIST(value);\n"
|
||||
"\n"
|
||||
" for (var i in value) {\n"
|
||||
" var currentValue = value[i];\n"
|
||||
" \n"
|
||||
" if (AHUACATL_TYPEWEIGHT(currentValue) === AHUACATL_TYPEWEIGHT_NULL) {\n"
|
||||
" continue;\n"
|
||||
" }\n"
|
||||
" \n"
|
||||
" if (result === null || AHUACATL_RELATIONAL_LESS(currentValue, result)) {\n"
|
||||
" result = currentValue;\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" return result;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"/// @}\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"\n"
|
||||
|
|
|
@ -106,7 +106,17 @@ function ahuacatlFunctionsTestSuite () {
|
|||
/// @brief test length function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testLength : function () {
|
||||
testLength1 : function () {
|
||||
var expected = [ 0, 0, 0 ];
|
||||
var actual = getQueryResults("FOR year IN [ 2010, 2011, 2012 ] LET quarters = ((FOR q IN [ ] return q)) return LENGTH(quarters)", true);
|
||||
assertEqual(expected, actual);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test length function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testLength2 : function () {
|
||||
var expected = [ 4, 4, 4 ];
|
||||
var actual = getQueryResults("FOR year IN [ 2010, 2011, 2012 ] LET quarters = ((FOR q IN [ 1, 2, 3, 4 ] return q)) return LENGTH(quarters)", true);
|
||||
assertEqual(expected, actual);
|
||||
|
@ -116,12 +126,77 @@ function ahuacatlFunctionsTestSuite () {
|
|||
/// @brief test concat function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testConcat : function () {
|
||||
testConcat1 : function () {
|
||||
var expected = [ "theQuickBrownFoxJumps" ];
|
||||
var actual = getQueryResults("FOR r IN [ 1 ] return CONCAT('the', 'Quick', null, 'Brown', null, 'Fox', 'Jumps')", true);
|
||||
assertEqual(expected, actual);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test concat function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testConcat2 : function () {
|
||||
var expected = [ "theQuickBrownアボカドJumps名称について" ];
|
||||
var actual = getQueryResults("FOR r IN [ 1 ] return CONCAT('the', 'Quick', null, 'Brown', null, 'アボカド', 'Jumps', '名称について')", true);
|
||||
assertEqual(expected, actual);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test floor function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testFloor : function () {
|
||||
var expected = [ -100, -3, -3, -3, -2, -2, -2, -2, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 3, 99 ];
|
||||
var actual = getQueryResults("FOR r IN [ -99.999, -3, -2.1, -2.01, -2, -1.99, -1.1, -1.01, -1, -0.9, -0.6, -0.5, -0.4, -0.1, -0.01, 0, 0.01, 0.1, 0.4, 0.5, 0.6, 0.9, 1, 1.01, 1.1, 1.99, 2, 2.01, 2.1, 3, 99.999 ] return FLOOR(r)", true);
|
||||
assertEqual(expected, actual);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test ceil function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testCeil : function () {
|
||||
var expected = [ -99, -3, -2, -2, -2, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 100 ];
|
||||
var actual = getQueryResults("FOR r IN [ -99.999, -3, -2.1, -2.01, -2, -1.99, -1.1, -1.01, -1, -0.9, -0.6, -0.5, -0.4, -0.1, -0.01, 0, 0.01, 0.1, 0.4, 0.5, 0.6, 0.9, 1, 1.01, 1.1, 1.99, 2, 2.01, 2.1, 3, 99.999 ] return CEIL(r)", true);
|
||||
assertEqual(expected, actual);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test abs function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testAbs : function () {
|
||||
var expected = [ 99.999, 3, 2.1, 2.01, 2, 1.99, 1.1, 1.01, 1, 0.9, 0.6, 0.5, 0.4, 0.1, 0.01, 0, 0.01, 0.1, 0.4, 0.5, 0.6, 0.9, 1, 1.01, 1.1, 1.99, 2, 2.01, 2.1, 3, 99.999 ];
|
||||
var actual = getQueryResults("FOR r IN [ -99.999, -3, -2.1, -2.01, -2, -1.99, -1.1, -1.01, -1, -0.9, -0.6, -0.5, -0.4, -0.1, -0.01, 0, 0.01, 0.1, 0.4, 0.5, 0.6, 0.9, 1, 1.01, 1.1, 1.99, 2, 2.01, 2.1, 3, 99.999 ] return ABS(r)", true);
|
||||
assertEqual(expected, actual);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test round function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testRound : function () {
|
||||
var expected = [ -100, -3, -2, -2, -2, -2, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 100 ];
|
||||
var actual = getQueryResults("FOR r IN [ -99.999, -3, -2.1, -2.01, -2, -1.99, -1.1, -1.01, -1, -0.9, -0.6, -0.5, -0.4, -0.1, -0.01, 0, 0.01, 0.1, 0.4, 0.5, 0.6, 0.9, 1, 1.01, 1.1, 1.99, 2, 2.01, 2.1, 3, 99.999 ] return ROUND(r)", true);
|
||||
assertEqual(expected, actual);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test rand function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testRand : function () {
|
||||
var actual = getQueryResults("FOR r IN [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 ] return RAND()", true);
|
||||
for (var i in actual) {
|
||||
if (!actual.hasOwnProperty(i)) {
|
||||
continue;
|
||||
}
|
||||
var value = actual[i];
|
||||
assertTrue(value >= 0.0 && value < 1.0);
|
||||
}
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test merge function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -192,6 +267,65 @@ function ahuacatlFunctionsTestSuite () {
|
|||
assertEqual(expected, actual);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test min function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testMin1 : function () {
|
||||
var expected = [ null, null ];
|
||||
var actual = getQueryResults("FOR u IN [ [ ], [ null, null ] ] return MIN(u)", true);
|
||||
assertEqual(expected, actual);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test min function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testMin2 : function () {
|
||||
var expected = [ 1, 1, 1, 1, 1, 1 ];
|
||||
var actual = getQueryResults("FOR u IN [ [ 1, 2, 3 ], [ 3, 2, 1 ], [ 1, 3, 2 ], [ 2, 3, 1 ], [ 2, 1, 3 ], [ 3, 1, 2 ] ] return MIN(u)", true);
|
||||
assertEqual(expected, actual);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test min function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testMin3 : function () {
|
||||
var expected = [ 2, false, false, false, false, true, -1, '', 1 ];
|
||||
var actual = getQueryResults("FOR u IN [ [ 3, 2, '1' ], [ [ ], null, true, false, 1, '0' ], [ '0', 1, false, true, null, [ ] ], [ false, true ], [ 0, false ], [ true, 0 ], [ '0', -1 ], [ '', '-1' ], [ [ ], 1 ] ] return MIN(u)", true);
|
||||
assertEqual(expected, actual);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test max function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testMax1 : function () {
|
||||
var expected = [ null, null ];
|
||||
var actual = getQueryResults("FOR u IN [ [ ], [ null, null ] ] return MAX(u)", true);
|
||||
assertEqual(expected, actual);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test max function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testMax2 : function () {
|
||||
var expected = [ 3, 3, 3, 3, 3, 3 ];
|
||||
var actual = getQueryResults("FOR u IN [ [ 1, 2, 3 ], [ 3, 2, 1 ], [ 1, 3, 2 ], [ 2, 3, 1 ], [ 2, 1, 3 ], [ 3, 1, 2 ] ] return MAX(u)", true);
|
||||
assertEqual(expected, actual);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test min function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testMax3 : function () {
|
||||
var expected = [ '1', [ ], [ ], true, 0, 0, '0', '-1', [ ] ];
|
||||
var actual = getQueryResults("FOR u IN [ [ 3, 2, '1' ], [ [ ], null, true, false, 1, '0' ], [ '0', 1, false, true, null, [ ] ], [ false, true ], [ 0, false ], [ true, 0 ], [ '0', -1 ], [ '', '-1' ], [ [ ], 1 ] ] return MAX(u)", true);
|
||||
assertEqual(expected, actual);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue