mirror of https://gitee.com/bigwinds/arangodb
merged
This commit is contained in:
parent
f295e32b8c
commit
be33a5c44f
|
@ -72,6 +72,7 @@ void TRI_InitialiseErrorMessages (void) {
|
|||
REG_ERROR(ERROR_QUERY_BIND_PARAMETER_VALUE_INVALID, "invalid value for bind parameter '%s'");
|
||||
REG_ERROR(ERROR_QUERY_BIND_PARAMETER_NUMBER_OUT_OF_RANGE, "bind parameter number '%s' out of range");
|
||||
REG_ERROR(ERROR_QUERY_FUNCTION_NAME_UNKNOWN, "usage of unknown function '%s'");
|
||||
REG_ERROR(ERROR_QUERY_RUNTIME_ERROR, "runtime error in query");
|
||||
REG_ERROR(ERROR_QUERY_LIMIT_VALUE_OUT_OF_RANGE, "limit value '%s' is out of range");
|
||||
REG_ERROR(ERROR_CURSOR_NOT_FOUND, "cursor not found");
|
||||
REG_ERROR(ERROR_SESSION_USERHANDLER_URL_INVALID, "expecting <prefix>/user/<username>");
|
||||
|
|
|
@ -158,6 +158,9 @@ extern "C" {
|
|||
/// is out of the allowed range.
|
||||
/// - 1518: @CODE{usage of unknown function '\%s'}
|
||||
/// Will be raised when an undefined function is called.
|
||||
/// - 1520: @CODE{runtime error in query}
|
||||
/// Will be raised when a Javascript runtime error occurs while executing a
|
||||
/// query.
|
||||
/// - 1521: @CODE{limit value '\%s' is out of range}
|
||||
/// Will be raised when a limit value in the query is outside the allowed
|
||||
/// range (e. g. when passing a negative skip value).
|
||||
|
@ -952,6 +955,17 @@ void TRI_InitialiseErrorMessages (void);
|
|||
|
||||
#define TRI_ERROR_QUERY_FUNCTION_NAME_UNKNOWN (1518)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief 1520: ERROR_QUERY_RUNTIME_ERROR
|
||||
///
|
||||
/// runtime error in query
|
||||
///
|
||||
/// Will be raised when a Javascript runtime error occurs while executing a
|
||||
/// query.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define TRI_ERROR_QUERY_RUNTIME_ERROR (1520)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief 1521: ERROR_QUERY_LIMIT_VALUE_OUT_OF_RANGE
|
||||
///
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
name
|
||||
username
|
||||
firstname
|
|
@ -0,0 +1,41 @@
|
|||
null < false
|
||||
null < true
|
||||
null < 0
|
||||
null < ''
|
||||
null < ' '
|
||||
null < '0'
|
||||
null < 'abc'
|
||||
null < [ ]
|
||||
null < { }
|
||||
|
||||
false < true
|
||||
false < 0
|
||||
false < ''
|
||||
false < ' '
|
||||
false < '0'
|
||||
false < 'abc'
|
||||
false < [ ]
|
||||
false < { }
|
||||
|
||||
true < 0
|
||||
true < ''
|
||||
true < ' '
|
||||
true < '0'
|
||||
true < 'abc'
|
||||
true < [ ]
|
||||
true < { }
|
||||
|
||||
0 < ''
|
||||
0 < ' '
|
||||
0 < '0'
|
||||
0 < 'abc'
|
||||
0 < [ ]
|
||||
0 < { }
|
||||
|
||||
'' < ' '
|
||||
'' < '0'
|
||||
'' < 'abc'
|
||||
'' < [ ]
|
||||
'' < { }
|
||||
|
||||
[ ] < { }
|
|
@ -0,0 +1,6 @@
|
|||
[ ] < [ 0 ]
|
||||
[ 1 ] < [ 2 ]
|
||||
[ 1, 2 ] < [ 2 ]
|
||||
[ 99, 99 ] < [ 100 ]
|
||||
[ false ] < [ true ]
|
||||
[ false, 1 ] < [ false, '' ]
|
|
@ -0,0 +1,8 @@
|
|||
{ } < { 'a' : 1 }
|
||||
{ } < { 'a' : null }
|
||||
{ 'a' : 1 } < { 'a' : 2 }
|
||||
{ 'b' : 1 } < { 'a' : 0 }
|
||||
{ 'a' : { 'c' : true } } < { 'a' : { 'c' : 0 } }
|
||||
{ 'a' : { 'c' : true, 'a' : 0 } } < { 'a' : { 'c' : false, 'a' : 1 } }
|
||||
|
||||
{ 'a' : 1, 'b' : 2 } == { 'b' : 2, 'a' : 1 }
|
|
@ -0,0 +1,2 @@
|
|||
concat('a', 'b')
|
||||
concat('Mr ', concat('Foxx', concat(' goes', ' fishing')))
|
|
@ -646,6 +646,7 @@ bool TRI_ExecuteRefExecutionContext (TRI_js_exec_context_t context, TRI_json_t*
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool TRI_ExecuteOrderExecutionContext (TRI_js_exec_context_t context, int* r) {
|
||||
v8::TryCatch tryCatch;
|
||||
js_exec_context_t* ctx;
|
||||
|
||||
ctx = (js_exec_context_t*) context;
|
||||
|
|
|
@ -695,10 +695,11 @@ static void WeakQueryCursorCallback (v8::Persistent<v8::Value> object, void* par
|
|||
/// @brief stores a cursor in a javascript object
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static v8::Handle<v8::Object> WrapQueryCursor (TRI_query_cursor_t* cursor) {
|
||||
TRI_v8_global_t* v8g;
|
||||
static v8::Handle<v8::Value> WrapQueryCursor (TRI_query_cursor_t* cursor) {
|
||||
v8::HandleScope scope;
|
||||
v8::TryCatch tryCatch;
|
||||
|
||||
TRI_v8_global_t* v8g;
|
||||
v8g = (TRI_v8_global_t*) v8::Isolate::GetCurrent()->GetData();
|
||||
|
||||
v8::Handle<v8::Object> cursorObject = v8g->QueryCursorTempl->NewInstance();
|
||||
|
@ -707,9 +708,12 @@ static v8::Handle<v8::Object> WrapQueryCursor (TRI_query_cursor_t* cursor) {
|
|||
if (i == v8g->JSQueryCursors.end()) {
|
||||
v8::Persistent<v8::Value> persistent = v8::Persistent<v8::Value>::New(v8::External::New(cursor));
|
||||
|
||||
if (tryCatch.HasCaught()) {
|
||||
return scope.Close(v8::Undefined());
|
||||
}
|
||||
|
||||
cursorObject->SetInternalField(SLOT_CLASS_TYPE, v8::Integer::New(WRP_QUERY_CURSOR_TYPE));
|
||||
cursorObject->SetInternalField(SLOT_CLASS, persistent);
|
||||
|
||||
v8g->JSQueryCursors[cursor] = persistent;
|
||||
|
||||
persistent.MakeWeak(cursor, WeakQueryCursorCallback);
|
||||
|
@ -1423,6 +1427,7 @@ static TRI_json_t* ConvertHelper(v8::Handle<v8::Value> parameter) {
|
|||
|
||||
static v8::Handle<v8::Value> JS_ParseAql (v8::Arguments const& argv) {
|
||||
v8::HandleScope scope;
|
||||
v8::TryCatch tryCatch;
|
||||
|
||||
if (argv.Length() != 1) {
|
||||
return scope.Close(v8::ThrowException(v8::String::New("usage: AQL_PARSE(<querystring>)")));
|
||||
|
@ -1467,12 +1472,16 @@ static v8::Handle<v8::Value> JS_ParseAql (v8::Arguments const& argv) {
|
|||
TRI_DestroyVectorString(¶meters);
|
||||
TRI_FreeQueryTemplate(template_);
|
||||
|
||||
if (tryCatch.HasCaught()) {
|
||||
return scope.Close(v8::ThrowException(v8::String::New("out of memory")));
|
||||
}
|
||||
return scope.Close(result);
|
||||
}
|
||||
catch (...) {
|
||||
}
|
||||
|
||||
TRI_FreeQueryTemplate(template_);
|
||||
|
||||
return scope.Close(v8::ThrowException(v8::String::New("out of memory")));
|
||||
}
|
||||
|
||||
|
@ -1483,6 +1492,7 @@ static v8::Handle<v8::Value> JS_ParseAql (v8::Arguments const& argv) {
|
|||
|
||||
static v8::Handle<v8::Value> JS_StatementAql (v8::Arguments const& argv) {
|
||||
v8::HandleScope scope;
|
||||
v8::TryCatch tryCatch;
|
||||
|
||||
if (argv.Length() < 1 || argv.Length() > 4) {
|
||||
return scope.Close(v8::ThrowException(v8::String::New("usage: AQL_STATEMENT(<querystring>, <bindvalues>, <doCount>, <max>)")));
|
||||
|
@ -1560,12 +1570,12 @@ static v8::Handle<v8::Value> JS_StatementAql (v8::Arguments const& argv) {
|
|||
TRI_FreeQueryTemplate(template_);
|
||||
return scope.Close(errorObject);
|
||||
}
|
||||
|
||||
|
||||
TRI_FreeQueryInstance(instance);
|
||||
TRI_FreeQueryTemplate(template_);
|
||||
|
||||
TRI_StoreShadowData(vocbase->_cursors, (const void* const) cursor);
|
||||
|
||||
|
||||
return scope.Close(WrapQueryCursor(cursor));
|
||||
}
|
||||
|
||||
|
@ -2534,6 +2544,7 @@ static v8::Handle<v8::Value> JS_ExecuteAql (v8::Arguments const& argv) {
|
|||
|
||||
static v8::Handle<v8::Value> JS_DisposeQueryCursor (v8::Arguments const& argv) {
|
||||
v8::HandleScope scope;
|
||||
v8::TryCatch tryCatch;
|
||||
|
||||
if (argv.Length() != 0) {
|
||||
return scope.Close(v8::ThrowException(v8::String::New("usage: dispose()")));
|
||||
|
@ -2545,7 +2556,9 @@ static v8::Handle<v8::Value> JS_DisposeQueryCursor (v8::Arguments const& argv) {
|
|||
}
|
||||
|
||||
if (TRI_DeleteDataShadowData(vocbase->_cursors, UnwrapQueryCursor(argv.Holder()))) {
|
||||
return scope.Close(v8::True());
|
||||
if (!tryCatch.HasCaught()) {
|
||||
return scope.Close(v8::True());
|
||||
}
|
||||
}
|
||||
|
||||
return scope.Close(v8::ThrowException(v8::String::New("corrupted or already disposed cursor")));
|
||||
|
@ -2557,6 +2570,7 @@ static v8::Handle<v8::Value> JS_DisposeQueryCursor (v8::Arguments const& argv) {
|
|||
|
||||
static v8::Handle<v8::Value> JS_IdQueryCursor (v8::Arguments const& argv) {
|
||||
v8::HandleScope scope;
|
||||
v8::TryCatch tryCatch;
|
||||
|
||||
if (argv.Length() != 0) {
|
||||
return scope.Close(v8::ThrowException(v8::String::New("usage: id()")));
|
||||
|
@ -2568,7 +2582,7 @@ static v8::Handle<v8::Value> JS_IdQueryCursor (v8::Arguments const& argv) {
|
|||
}
|
||||
|
||||
TRI_shadow_id id = TRI_GetIdDataShadowData(vocbase->_cursors, UnwrapQueryCursor(argv.Holder()));
|
||||
if (id) {
|
||||
if (id && !tryCatch.HasCaught()) {
|
||||
return scope.Close(v8::Number::New(id));
|
||||
}
|
||||
|
||||
|
@ -2581,6 +2595,7 @@ static v8::Handle<v8::Value> JS_IdQueryCursor (v8::Arguments const& argv) {
|
|||
|
||||
static v8::Handle<v8::Value> JS_CountQueryCursor (v8::Arguments const& argv) {
|
||||
v8::HandleScope scope;
|
||||
v8::TryCatch tryCatch;
|
||||
|
||||
if (argv.Length() != 0) {
|
||||
return scope.Close(v8::ThrowException(v8::String::New("usage: count()")));
|
||||
|
@ -2610,6 +2625,7 @@ static v8::Handle<v8::Value> JS_CountQueryCursor (v8::Arguments const& argv) {
|
|||
|
||||
static v8::Handle<v8::Value> JS_NextQueryCursor (v8::Arguments const& argv) {
|
||||
v8::HandleScope scope;
|
||||
v8::TryCatch tryCatch;
|
||||
|
||||
if (argv.Length() != 0) {
|
||||
return scope.Close(v8::ThrowException(v8::String::New("usage: next()")));
|
||||
|
@ -2655,8 +2671,8 @@ static v8::Handle<v8::Value> JS_NextQueryCursor (v8::Arguments const& argv) {
|
|||
if (context) {
|
||||
TRI_FreeExecutionContext(context);
|
||||
}
|
||||
|
||||
if (result) {
|
||||
|
||||
if (result && !tryCatch.HasCaught()) {
|
||||
return scope.Close(value);
|
||||
}
|
||||
}
|
||||
|
@ -2670,6 +2686,7 @@ static v8::Handle<v8::Value> JS_NextQueryCursor (v8::Arguments const& argv) {
|
|||
|
||||
static v8::Handle<v8::Value> JS_PersistQueryCursor (v8::Arguments const& argv) {
|
||||
v8::HandleScope scope;
|
||||
v8::TryCatch tryCatch;
|
||||
|
||||
if (argv.Length() != 0) {
|
||||
return scope.Close(v8::ThrowException(v8::String::New("usage: persist()")));
|
||||
|
@ -2681,7 +2698,7 @@ static v8::Handle<v8::Value> JS_PersistQueryCursor (v8::Arguments const& argv) {
|
|||
}
|
||||
|
||||
bool result = TRI_PersistDataShadowData(vocbase->_cursors, UnwrapQueryCursor(argv.Holder()));
|
||||
if (result) {
|
||||
if (result && !tryCatch.HasCaught()) {
|
||||
return scope.Close(v8::True());
|
||||
}
|
||||
|
||||
|
@ -2697,6 +2714,7 @@ static v8::Handle<v8::Value> JS_PersistQueryCursor (v8::Arguments const& argv) {
|
|||
|
||||
static v8::Handle<v8::Value> JS_GetRowsQueryCursor (v8::Arguments const& argv) {
|
||||
v8::HandleScope scope;
|
||||
v8::TryCatch tryCatch;
|
||||
|
||||
if (argv.Length() != 0) {
|
||||
return scope.Close(v8::ThrowException(v8::String::New("usage: getRows()")));
|
||||
|
@ -2765,7 +2783,7 @@ static v8::Handle<v8::Value> JS_GetRowsQueryCursor (v8::Arguments const& argv) {
|
|||
TRI_FreeExecutionContext(context);
|
||||
}
|
||||
|
||||
if (result) {
|
||||
if (result && !tryCatch.HasCaught()) {
|
||||
return scope.Close(rows);
|
||||
}
|
||||
}
|
||||
|
@ -2779,6 +2797,7 @@ static v8::Handle<v8::Value> JS_GetRowsQueryCursor (v8::Arguments const& argv) {
|
|||
|
||||
static v8::Handle<v8::Value> JS_GetBatchSizeQueryCursor (v8::Arguments const& argv) {
|
||||
v8::HandleScope scope;
|
||||
v8::TryCatch tryCatch;
|
||||
|
||||
if (argv.Length() != 0) {
|
||||
return scope.Close(v8::ThrowException(v8::String::New("usage: getBatchSize()")));
|
||||
|
@ -2808,6 +2827,7 @@ static v8::Handle<v8::Value> JS_GetBatchSizeQueryCursor (v8::Arguments const& ar
|
|||
|
||||
static v8::Handle<v8::Value> JS_HasCountQueryCursor (v8::Arguments const& argv) {
|
||||
v8::HandleScope scope;
|
||||
v8::TryCatch tryCatch;
|
||||
|
||||
if (argv.Length() != 0) {
|
||||
return scope.Close(v8::ThrowException(v8::String::New("usage: hasCount()")));
|
||||
|
@ -2837,6 +2857,7 @@ static v8::Handle<v8::Value> JS_HasCountQueryCursor (v8::Arguments const& argv)
|
|||
|
||||
static v8::Handle<v8::Value> JS_HasNextQueryCursor (v8::Arguments const& argv) {
|
||||
v8::HandleScope scope;
|
||||
v8::TryCatch tryCatch;
|
||||
|
||||
if (argv.Length() != 0) {
|
||||
return scope.Close(v8::ThrowException(v8::String::New("usage: hasNext()")));
|
||||
|
@ -4295,7 +4316,7 @@ static v8::Handle<v8::Value> JS_ReplaceVocbaseCol (v8::Arguments const& argv) {
|
|||
// inside a write transaction
|
||||
// .............................................................................
|
||||
|
||||
bool ok = doc->updateLock(doc, shaped, did, 0, 0, TRI_DOC_UPDATE_LAST_WRITE);
|
||||
int res = doc->updateLock(doc, shaped, did, 0, 0, TRI_DOC_UPDATE_LAST_WRITE);
|
||||
|
||||
// .............................................................................
|
||||
// outside a write transaction
|
||||
|
@ -4303,7 +4324,7 @@ static v8::Handle<v8::Value> JS_ReplaceVocbaseCol (v8::Arguments const& argv) {
|
|||
|
||||
TRI_FreeShapedJson(shaped);
|
||||
|
||||
if (! ok) {
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
string err = "cannot replace document: ";
|
||||
err += TRI_last_error();
|
||||
|
||||
|
@ -4505,7 +4526,7 @@ static v8::Handle<v8::Value> JS_ReplaceEdgesCol (v8::Arguments const& argv) {
|
|||
// inside a write transaction
|
||||
// .............................................................................
|
||||
|
||||
bool ok = doc->updateLock(doc, shaped, did, 0, 0, TRI_DOC_UPDATE_LAST_WRITE);
|
||||
int res = doc->updateLock(doc, shaped, did, 0, 0, TRI_DOC_UPDATE_LAST_WRITE);
|
||||
|
||||
// .............................................................................
|
||||
// outside a write transaction
|
||||
|
@ -4513,7 +4534,7 @@ static v8::Handle<v8::Value> JS_ReplaceEdgesCol (v8::Arguments const& argv) {
|
|||
|
||||
TRI_FreeShapedJson(shaped);
|
||||
|
||||
if (! ok) {
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
string err = "cannot replace document: ";
|
||||
err += TRI_last_error();
|
||||
|
||||
|
|
|
@ -223,6 +223,13 @@ TRI_query_cursor_t* TRI_ExecuteQueryInstance (TRI_query_instance_t* const instan
|
|||
instance->_query._limit._count);
|
||||
}
|
||||
}
|
||||
|
||||
if (instance->_doAbort) {
|
||||
selectResult->free(selectResult);
|
||||
cursor->_result._selectResult = NULL;
|
||||
cursor->free(cursor);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// adjust cursor length
|
||||
cursor->_length = selectResult->_numRows;
|
||||
|
|
|
@ -324,6 +324,15 @@ extern "C" {
|
|||
///
|
||||
/// @verbinclude compare3
|
||||
///
|
||||
/// The @LIT{in} operator checks whether the left-hand operand is contained in the
|
||||
/// right-hand operand. Therefore, the right-hand operand is supposed to be a
|
||||
/// list. If the right-hand operand is not of type list, the result will be @LIT{undefined}.
|
||||
/// The result will also be @LIT{undefined} if the left-hand operand is of type
|
||||
/// @LIT{undefined}. If the right-hand operand is a list, the list values will be
|
||||
/// checked one by one and be compared to the left-hand operand. If the left-hand
|
||||
/// operand is equal to one of the list elements, the result will be @LIT{true}.
|
||||
/// Otherwise, the result will be @LIT{false}.
|
||||
///
|
||||
/// @subsubsection AqlOperatorsLog Logical operators
|
||||
///
|
||||
/// The following logical operators are supported:
|
||||
|
@ -334,15 +343,17 @@ extern "C" {
|
|||
///
|
||||
/// @verbinclude logical
|
||||
///
|
||||
/// The @LIT{&&} and @LIT{||} operators return a boolean value if the result of the
|
||||
/// operation is known, and @LIT{undefined} otherwise.
|
||||
/// The @LIT{&&} and @LIT{||} operators expect their input operands to be boolean
|
||||
/// values. They will return @LIT{undefined} if any of the input operands is not a
|
||||
/// boolean value. If both input operands are booleans, the result of the operation
|
||||
/// will also be a boolean.
|
||||
///
|
||||
/// Both @LIT{&&} and @LIT{||} use short-circuit evaluation and only
|
||||
/// evaluate the second operand if the result of the operation cannot be
|
||||
/// determined by the first operand alone.
|
||||
///
|
||||
/// The @LIT{!} operator returns boolean value if the operation can be processed, or
|
||||
/// @LIT{undefined} if the operand is @LIT{undefined}.
|
||||
/// The @LIT{!} operator returns boolean value if the operation input operand is a
|
||||
/// boolean value, and @LIT{undefined} if the input operand is not of type boolean.
|
||||
///
|
||||
/// @subsubsection AqlOperatorsArit Arithmetic operators
|
||||
///
|
||||
|
@ -379,6 +390,8 @@ extern "C" {
|
|||
/// @subsubsection AQLOperatorsOther String concatenation
|
||||
///
|
||||
/// String concatenation can be achieved by using the @LIT{concat} function.
|
||||
///
|
||||
/// @verbinclude concat
|
||||
///
|
||||
/// @subsubsection AQLOperatorsPrec Operator precedence
|
||||
///
|
||||
|
|
|
@ -160,15 +160,59 @@ static void AppendBinaryFunc (TRI_query_javascript_converter_t* converter,
|
|||
TRI_AppendCharStringBuffer(converter->_buffer, ')');
|
||||
}
|
||||
|
||||
|
||||
static size_t WalkMembers (TRI_string_buffer_t* const buffer,
|
||||
const TRI_query_node_t* const node) {
|
||||
TRI_query_node_t* next = node->_next;
|
||||
size_t num = 0;
|
||||
|
||||
while (next) {
|
||||
TRI_AppendStringStringBuffer(buffer, ",'");
|
||||
TRI_AppendStringStringBuffer(buffer, next->_value._stringValue);
|
||||
TRI_AppendStringStringBuffer(buffer, "')");
|
||||
next = next->_next;
|
||||
++num;
|
||||
}
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Walk a horizontal list of elements and print them
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void TRI_WalkListQueryJavascript (TRI_query_javascript_converter_t* converter,
|
||||
const TRI_query_node_t* const node,
|
||||
TRI_associative_pointer_t* bindParameters,
|
||||
const char separator,
|
||||
size_t counter) {
|
||||
static void MemberAccess (TRI_query_javascript_converter_t* converter,
|
||||
const TRI_query_node_t* const node,
|
||||
TRI_associative_pointer_t* bindParameters) {
|
||||
TRI_string_buffer_t* buffer;
|
||||
size_t length;
|
||||
size_t i;
|
||||
|
||||
buffer = TRI_CreateStringBuffer();
|
||||
if (!buffer) {
|
||||
return;
|
||||
}
|
||||
|
||||
length = WalkMembers(buffer, node->_rhs);
|
||||
|
||||
for (i = 0; i < length; ++i) {
|
||||
TRI_AppendStringStringBuffer(converter->_buffer, "AQL_ACCESS_MEMBER(");
|
||||
}
|
||||
TRI_ConvertQueryJavascript(converter, node->_lhs, bindParameters);
|
||||
TRI_AppendStringStringBuffer(converter->_buffer, buffer->_buffer);
|
||||
|
||||
TRI_FreeStringBuffer(buffer);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Walk a horizontal list of elements and print them
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void WalkList (TRI_query_javascript_converter_t* converter,
|
||||
const TRI_query_node_t* const node,
|
||||
TRI_associative_pointer_t* bindParameters,
|
||||
const char separator,
|
||||
size_t counter) {
|
||||
TRI_query_node_t* next;
|
||||
|
||||
if (!node) {
|
||||
|
@ -291,12 +335,12 @@ void TRI_ConvertQueryJavascript (TRI_query_javascript_converter_t* converter,
|
|||
return;
|
||||
case TRI_QueryNodeValueArray:
|
||||
TRI_AppendCharStringBuffer(converter->_buffer, '[');
|
||||
TRI_WalkListQueryJavascript(converter, rhs, bindParameters, ',', 0);
|
||||
WalkList(converter, rhs, bindParameters, ',', 0);
|
||||
TRI_AppendCharStringBuffer(converter->_buffer, ']');
|
||||
return;
|
||||
case TRI_QueryNodeValueDocument:
|
||||
TRI_AppendCharStringBuffer(converter->_buffer, '{');
|
||||
TRI_WalkListQueryJavascript(converter, rhs, bindParameters, ',', 0);
|
||||
WalkList(converter, rhs, bindParameters, ',', 0);
|
||||
TRI_AppendCharStringBuffer(converter->_buffer, '}');
|
||||
return;
|
||||
case TRI_QueryNodeValueParameterNamed:
|
||||
|
@ -356,24 +400,26 @@ void TRI_ConvertQueryJavascript (TRI_query_javascript_converter_t* converter,
|
|||
AppendBinaryFunc(converter, node, lhs, rhs, bindParameters);
|
||||
return;
|
||||
case TRI_QueryNodeContainerMemberAccess:
|
||||
TRI_ConvertQueryJavascript(converter, lhs, bindParameters);
|
||||
TRI_WalkListQueryJavascript(converter, rhs, bindParameters, '.', 1);
|
||||
return;
|
||||
case TRI_QueryNodeContainerTernarySwitch:
|
||||
TRI_ConvertQueryJavascript(converter, lhs, bindParameters);
|
||||
TRI_AppendCharStringBuffer(converter->_buffer, ':');
|
||||
TRI_ConvertQueryJavascript(converter, rhs, bindParameters);
|
||||
MemberAccess(converter, node, bindParameters);
|
||||
return;
|
||||
case TRI_QueryNodeControlFunctionCall:
|
||||
TRI_ConvertQueryJavascript(converter, lhs, bindParameters);
|
||||
TRI_AppendCharStringBuffer(converter->_buffer, '(');
|
||||
TRI_WalkListQueryJavascript(converter, rhs, bindParameters, ',', 0);
|
||||
WalkList(converter, rhs, bindParameters, ',', 0);
|
||||
TRI_AppendCharStringBuffer(converter->_buffer, ')');
|
||||
return;
|
||||
case TRI_QueryNodeContainerTernarySwitch:
|
||||
TRI_AppendStringStringBuffer(converter->_buffer, "(r?");
|
||||
TRI_ConvertQueryJavascript(converter, lhs, bindParameters);
|
||||
TRI_AppendCharStringBuffer(converter->_buffer, ':');
|
||||
TRI_ConvertQueryJavascript(converter, rhs, bindParameters);
|
||||
TRI_AppendCharStringBuffer(converter->_buffer, ')');
|
||||
return;
|
||||
case TRI_QueryNodeControlTernary:
|
||||
TRI_AppendCharStringBuffer(converter->_buffer, '(');
|
||||
TRI_AppendStringStringBuffer(converter->_buffer, "AQL_TYPEWEIGHT(r=(");
|
||||
TRI_ConvertQueryJavascript(converter, lhs, bindParameters);
|
||||
TRI_AppendCharStringBuffer(converter->_buffer, '?');
|
||||
TRI_AppendStringStringBuffer(converter->_buffer, "))===AQL_TYPEWEIGHT_UNDEFINED?undefined:");
|
||||
TRI_ConvertQueryJavascript(converter, rhs, bindParameters);
|
||||
TRI_AppendCharStringBuffer(converter->_buffer, ')');
|
||||
return;
|
||||
|
|
|
@ -917,7 +917,10 @@ static inline bool CheckJoinClause (TRI_query_instance_t* const instance,
|
|||
|
||||
part = (TRI_join_part_t*) instance->_join._buffer[level];
|
||||
TRI_DefineWhereExecutionContext(instance, part->_context, level, true);
|
||||
TRI_ExecuteConditionExecutionContext(instance, part->_context, &whereResult);
|
||||
if (!TRI_ExecuteConditionExecutionContext(instance, part->_context, &whereResult)) {
|
||||
TRI_RegisterErrorQueryInstance(instance, TRI_ERROR_QUERY_RUNTIME_ERROR, "");
|
||||
return false;
|
||||
}
|
||||
|
||||
return whereResult;
|
||||
}
|
||||
|
@ -931,7 +934,10 @@ static inline bool CheckWhereClause (TRI_query_instance_t* const instance,
|
|||
bool whereResult;
|
||||
|
||||
TRI_DefineWhereExecutionContext(instance, instance->_query._where._context, level, false);
|
||||
TRI_ExecuteConditionExecutionContext(instance, instance->_query._where._context, &whereResult);
|
||||
if (!TRI_ExecuteConditionExecutionContext(instance, instance->_query._where._context, &whereResult)) {
|
||||
TRI_RegisterErrorQueryInstance(instance, TRI_ERROR_QUERY_RUNTIME_ERROR, "");
|
||||
return false;
|
||||
}
|
||||
|
||||
return whereResult;
|
||||
}
|
||||
|
|
|
@ -66,6 +66,7 @@ ModuleCache["/internal"].exports.errors = {
|
|||
"ERROR_QUERY_BIND_PARAMETER_VALUE_INVALID" : { "code" : 1516, "message" : "invalid value for bind parameter '%s'" },
|
||||
"ERROR_QUERY_BIND_PARAMETER_NUMBER_OUT_OF_RANGE" : { "code" : 1517, "message" : "bind parameter number '%s' out of range" },
|
||||
"ERROR_QUERY_FUNCTION_NAME_UNKNOWN" : { "code" : 1518, "message" : "usage of unknown function '%s'" },
|
||||
"ERROR_QUERY_RUNTIME_ERROR" : { "code" : 1520, "message" : "runtime error in query" },
|
||||
"ERROR_QUERY_LIMIT_VALUE_OUT_OF_RANGE" : { "code" : 1521, "message" : "limit value '%s' is out of range" },
|
||||
"ERROR_CURSOR_NOT_FOUND" : { "code" : 1600, "message" : "cursor not found" },
|
||||
"ERROR_SESSION_USERHANDLER_URL_INVALID" : { "code" : 1700, "message" : "expecting <prefix>/user/<username>" },
|
||||
|
|
|
@ -67,6 +67,7 @@ static string JS_common_bootstrap_errors =
|
|||
" \"ERROR_QUERY_BIND_PARAMETER_VALUE_INVALID\" : { \"code\" : 1516, \"message\" : \"invalid value for bind parameter '%s'\" }, \n"
|
||||
" \"ERROR_QUERY_BIND_PARAMETER_NUMBER_OUT_OF_RANGE\" : { \"code\" : 1517, \"message\" : \"bind parameter number '%s' out of range\" }, \n"
|
||||
" \"ERROR_QUERY_FUNCTION_NAME_UNKNOWN\" : { \"code\" : 1518, \"message\" : \"usage of unknown function '%s'\" }, \n"
|
||||
" \"ERROR_QUERY_RUNTIME_ERROR\" : { \"code\" : 1520, \"message\" : \"runtime error in query\" }, \n"
|
||||
" \"ERROR_QUERY_LIMIT_VALUE_OUT_OF_RANGE\" : { \"code\" : 1521, \"message\" : \"limit value '%s' is out of range\" }, \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"
|
||||
|
|
|
@ -109,6 +109,18 @@ function AQL_KEYS (lhs) {
|
|||
return keys;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief access a member of an object
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function AQL_ACCESS_MEMBER (lhs, rhs) {
|
||||
if (AQL_TYPEWEIGHT(lhs) !== AQL_TYPEWEIGHT_OBJECT) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return lhs[rhs];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief perform logical and
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -120,7 +132,11 @@ function AQL_LOGICAL_AND (lhs, rhs) {
|
|||
return undefined;
|
||||
}
|
||||
|
||||
return (lhs && rhs);
|
||||
if (!lhs) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return rhs;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -133,8 +149,12 @@ function AQL_LOGICAL_OR (lhs, rhs) {
|
|||
AQL_TYPEWEIGHT(rhs) !== AQL_TYPEWEIGHT_BOOL) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (lhs) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return (lhs || rhs);
|
||||
return rhs;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -111,6 +111,18 @@ static string JS_server_aql_operators =
|
|||
"}\n"
|
||||
"\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"/// @brief access a member of an object\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"\n"
|
||||
"function AQL_ACCESS_MEMBER (lhs, rhs) {\n"
|
||||
" if (AQL_TYPEWEIGHT(lhs) !== AQL_TYPEWEIGHT_OBJECT) {\n"
|
||||
" return undefined;\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" return lhs[rhs];\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"/// @brief perform logical and\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"\n"
|
||||
|
@ -121,7 +133,11 @@ static string JS_server_aql_operators =
|
|||
" return undefined; \n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" return (lhs && rhs);\n"
|
||||
" if (!lhs) {\n"
|
||||
" return false;\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" return rhs;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
|
@ -134,8 +150,12 @@ static string JS_server_aql_operators =
|
|||
" AQL_TYPEWEIGHT(rhs) !== AQL_TYPEWEIGHT_BOOL) {\n"
|
||||
" return undefined; \n"
|
||||
" }\n"
|
||||
" \n"
|
||||
" if (lhs) {\n"
|
||||
" return true;\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" return (lhs || rhs);\n"
|
||||
" return rhs;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
|
|
|
@ -260,7 +260,6 @@ function aqlSimpleTestSuite () {
|
|||
this.checkLength(0, 'c.value2 <= -100');
|
||||
|
||||
this.checkLength(0, 'c.value2 == 21');
|
||||
this.checkLength(0, 'c.value2 === 21');
|
||||
this.checkLength(0, 'c.value2 == 110');
|
||||
this.checkLength(0, 'c.value2 == 20.001');
|
||||
this.checkLength(0, 'c.value2 > 20');
|
||||
|
@ -295,16 +294,12 @@ function aqlSimpleTestSuite () {
|
|||
this.checkLength(0, 'c.value1 > 0', 'c.value1 > 20');
|
||||
this.checkLength(0, 'c.value1 >= 0', 'c.value1 > 20');
|
||||
this.checkLength(0, 'c.value1 == 0', 'c.value1 > 20');
|
||||
this.checkLength(0, 'c.value1 === 0', 'c.value1 > 20');
|
||||
this.checkLength(0, 'c.value1 !== 0', 'c.value1 > 20');
|
||||
this.checkLength(0, 'c.value1 != 0', 'c.value1 > 20');
|
||||
this.checkLength(0, 'c.value1 > 20', 'c.value1 > 0');
|
||||
this.checkLength(0, 'c.value1 > 20', 'c.value1 >= 0');
|
||||
this.checkLength(0, 'c.value1 >= 21', 'c.value1 > 0');
|
||||
this.checkLength(0, 'c.value1 >= 21', 'c.value1 >= 0');
|
||||
this.checkLength(0, 'c.value1 >= 21', 'c.value1 == 0');
|
||||
this.checkLength(0, 'c.value1 >= 21', 'c.value1 === 0');
|
||||
this.checkLength(0, 'c.value1 >= 21', 'c.value1 !== 0');
|
||||
this.checkLength(0, 'c.value1 >= 21', 'c.value1 != 0');
|
||||
}
|
||||
|
||||
|
@ -430,24 +425,17 @@ function aqlSimpleTestSuite () {
|
|||
function testMixedQueries () {
|
||||
this.checkLength(175,'c.value1 != 0', 'c.value2 < 11');
|
||||
this.checkLength(0,'c.value1 < 0', 'c.value2 > 14');
|
||||
this.checkLength(0,'c.value1 === 0', 'c.value2 === 18');
|
||||
this.checkLength(0,'c.value1 < 0', 'c.value2 >= 19');
|
||||
this.checkLength(1,'c.value1 == 0', 'c.value2 != 2');
|
||||
this.checkLength(0,'c.value1 < 0', 'c.value2 == 3');
|
||||
this.checkLength(0,'c.value1 <= 0', 'c.value2 > 4');
|
||||
this.checkLength(111,'c.value1 >= 0', 'c.value2 < 6');
|
||||
this.checkLength(7,'c.value1 > 10', 'c.value2 == 14');
|
||||
this.checkLength(7,'c.value1 != 10', 'c.value2 === 14');
|
||||
this.checkLength(11,'c.value1 == 10', 'c.value2 != 19');
|
||||
this.checkLength(3,'c.value1 == 10', 'c.value2 <= 2');
|
||||
this.checkLength(3,'c.value1 < 10', 'c.value2 === 7');
|
||||
this.checkLength(12,'c.value1 != 10', 'c.value2 == 8');
|
||||
this.checkLength(50,'c.value1 >= 11', 'c.value2 < 5');
|
||||
this.checkLength(6,'c.value1 === 11', 'c.value2 < 6');
|
||||
this.checkLength(10,'c.value1 != 12', 'c.value2 === 10');
|
||||
this.checkLength(132,'c.value1 > 12', 'c.value2 != 12');
|
||||
this.checkLength(13,'c.value1 === 12', 'c.value2 != 14');
|
||||
this.checkLength(0,'c.value1 === 12', 'c.value2 == 15');
|
||||
this.checkLength(0,'c.value1 <= 12', 'c.value2 > 18');
|
||||
this.checkLength(204,'c.value1 != 12', 'c.value2 != 6');
|
||||
this.checkLength(91,'c.value1 > 13', 'c.value2 <= 12');
|
||||
|
@ -463,28 +451,19 @@ function aqlSimpleTestSuite () {
|
|||
this.checkLength(7,'c.value1 == 15', 'c.value2 < 7');
|
||||
this.checkLength(99,'c.value1 < 15', 'c.value2 <= 8');
|
||||
this.checkLength(54,'c.value1 >= 15', 'c.value2 <= 8');
|
||||
this.checkLength(1,'c.value1 === 16', 'c.value2 == 3');
|
||||
this.checkLength(16,'c.value1 === 16', 'c.value2 != 6');
|
||||
this.checkLength(152,'c.value1 < 17', 'c.value2 != 16');
|
||||
this.checkLength(6,'c.value1 >= 17', 'c.value2 > 17');
|
||||
this.checkLength(16,'c.value1 <= 17', 'c.value2 === 2');
|
||||
this.checkLength(33,'c.value1 < 17', 'c.value2 < 2');
|
||||
this.checkLength(9,'c.value1 <= 18', 'c.value2 === 10');
|
||||
this.checkLength(205,'c.value1 != 18', 'c.value2 != 13');
|
||||
this.checkLength(171,'c.value1 < 18', 'c.value2 != 20');
|
||||
this.checkLength(0,'c.value1 === 18', 'c.value2 > 20');
|
||||
this.checkLength(161,'c.value1 < 18', 'c.value2 != 8');
|
||||
this.checkLength(2,'c.value1 > 18', 'c.value2 === 8');
|
||||
this.checkLength(1,'c.value1 == 19', 'c.value2 === 15');
|
||||
this.checkLength(2,'c.value1 >= 19', 'c.value2 == 18');
|
||||
this.checkLength(178,'c.value1 < 19', 'c.value2 != 7');
|
||||
this.checkLength(7,'c.value1 > 1', 'c.value2 == 14');
|
||||
this.checkLength(213,'c.value1 > 1', 'c.value2 <= 15');
|
||||
this.checkLength(1,'c.value1 > 1', 'c.value2 == 20');
|
||||
this.checkLength(0,'c.value1 == 1', 'c.value2 === 5');
|
||||
this.checkLength(55,'c.value1 <= 20', 'c.value2 > 10');
|
||||
this.checkLength(5,'c.value1 >= 20', 'c.value2 >= 16');
|
||||
this.checkLength(0,'c.value1 != 20', 'c.value2 === 20');
|
||||
this.checkLength(9,'c.value1 == 20', 'c.value2 <= 8');
|
||||
this.checkLength(10,'c.value1 >= 20', 'c.value2 <= 9');
|
||||
this.checkLength(3,'c.value1 > 2', 'c.value2 == 18');
|
||||
|
@ -493,16 +472,11 @@ function aqlSimpleTestSuite () {
|
|||
this.checkLength(17,'c.value1 != 3', 'c.value2 == 4');
|
||||
this.checkLength(208,'c.value1 > 3', 'c.value2 != 8');
|
||||
this.checkLength(188,'c.value1 > 4', 'c.value2 <= 13');
|
||||
this.checkLength(0,'c.value1 < 4', 'c.value2 === 4');
|
||||
this.checkLength(101,'c.value1 >= 4', 'c.value2 <= 5');
|
||||
this.checkLength(0,'c.value1 == 4', 'c.value2 > 7');
|
||||
this.checkLength(205,'c.value1 != 5', 'c.value2 >= 1');
|
||||
this.checkLength(150,'c.value1 >= 5', 'c.value2 < 10');
|
||||
this.checkLength(6,'c.value1 === 5', 'c.value2 < 14');
|
||||
this.checkLength(4,'c.value1 >= 5', 'c.value2 === 17');
|
||||
this.checkLength(4,'c.value1 > 5', 'c.value2 === 17');
|
||||
this.checkLength(0,'c.value1 <= 5', 'c.value2 == 18');
|
||||
this.checkLength(1,'c.value1 === 5', 'c.value2 == 2');
|
||||
this.checkLength(215,'c.value1 >= 5', 'c.value2 != 20');
|
||||
this.checkLength(15,'c.value1 > 5', 'c.value2 == 3');
|
||||
this.checkLength(202,'c.value1 >= 6', 'c.value2 != 13');
|
||||
|
@ -514,16 +488,11 @@ function aqlSimpleTestSuite () {
|
|||
this.checkLength(0,'c.value1 <= 7', 'c.value2 == 16');
|
||||
this.checkLength(0,'c.value1 == 7', 'c.value2 == 20');
|
||||
this.checkLength(203,'c.value1 >= 7', 'c.value2 <= 20');
|
||||
this.checkLength(5,'c.value1 <= 7', 'c.value2 === 3');
|
||||
this.checkLength(14,'c.value1 >= 7', 'c.value2 === 5');
|
||||
this.checkLength(36,'c.value1 <= 7', 'c.value2 <= 7');
|
||||
this.checkLength(174,'c.value1 > 8', 'c.value2 != 1');
|
||||
this.checkLength(9,'c.value1 === 8', 'c.value2 != 10');
|
||||
this.checkLength(167,'c.value1 != 8', 'c.value2 < 11');
|
||||
this.checkLength(9,'c.value1 === 8', 'c.value2 < 14');
|
||||
this.checkLength(0,'c.value1 <= 8', 'c.value2 == 20');
|
||||
this.checkLength(0,'c.value1 == 8', 'c.value2 >= 9');
|
||||
this.checkLength(4,'c.value1 >= 9', 'c.value2 === 17');
|
||||
this.checkLength(55,'c.value1 <= 9', 'c.value2 <= 18');
|
||||
this.checkLength(48,'c.value1 >= 9', 'c.value2 <= 3');
|
||||
this.checkLength(12,'c.value1 >= 9', 'c.value2 == 5');
|
||||
|
@ -590,7 +559,7 @@ function aqlSimpleTestSuite () {
|
|||
|
||||
function testValueTypes1 () {
|
||||
for (var i = 0; i <= 20; i++) {
|
||||
var results = this.runQuery("{ value1: c.value1, value2: c.value1 - 1, value3: c.value1 + 1, value4: null, value5: 'der fux' + 'xx' }", new Array("c.value1 == " + i));
|
||||
var results = this.runQuery("{ value1: c.value1, value2: c.value1 - 1, value3: c.value1 + 1, value4: null, value5: concat('der fux' , 'xx') }", new Array("c.value1 == " + i));
|
||||
for (var j = 0; j < results.length; j++) {
|
||||
assertEqual(i, results[j]["value1"]);
|
||||
assertEqual(i - 1, results[j]["value2"]);
|
||||
|
@ -610,7 +579,7 @@ function aqlSimpleTestSuite () {
|
|||
var results = this.runQuery("{ value1: null, value2: null + null, value3: undefined, value4: [], value5: { }, value6: 0, value7: 0.0 }", new Array("c.value1 == " + i));
|
||||
for (var j = 0; j < results.length; j++) {
|
||||
assertEqual(null, results[j]["value1"]);
|
||||
assertEqual(0, results[j]["value2"]);
|
||||
assertEqual(undefined, results[j]["value2"]);
|
||||
assertEqual(undefined, results[j]["value3"]);
|
||||
assertEqual([], results[j]["value4"]);
|
||||
assertEqual({}, results[j]["value5"]);
|
||||
|
|
Loading…
Reference in New Issue