mirror of https://gitee.com/bigwinds/arangodb
Merge branch 'devel' of github.com:triAGENS/AvocadoDB into devel
This commit is contained in:
commit
22f4bc3651
|
@ -1667,6 +1667,7 @@ char* TRI_GenerateCodeAql (const void* const data) {
|
||||||
OutputString(&generator->_buffer, REGISTER_PREFIX);
|
OutputString(&generator->_buffer, REGISTER_PREFIX);
|
||||||
OutputInt(&generator->_buffer, (int64_t) resultRegister);
|
OutputInt(&generator->_buffer, (int64_t) resultRegister);
|
||||||
OutputString(&generator->_buffer, ";\n");
|
OutputString(&generator->_buffer, ";\n");
|
||||||
|
|
||||||
OutputString(&generator->_buffer, "})()");
|
OutputString(&generator->_buffer, "})()");
|
||||||
|
|
||||||
if (generator->_error) {
|
if (generator->_error) {
|
||||||
|
|
|
@ -41,7 +41,58 @@
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief create code for a function call
|
/// @brief create javascript function code for a relational operation
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
static TRI_string_buffer_t* RelationCode (const char* const name,
|
||||||
|
const TRI_aql_node_t* const lhs,
|
||||||
|
const TRI_aql_node_t* const rhs) {
|
||||||
|
TRI_string_buffer_t* buffer = TRI_CreateStringBuffer(TRI_UNKNOWN_MEM_ZONE);
|
||||||
|
|
||||||
|
if (!lhs || !rhs) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TRI_AppendStringStringBuffer(buffer, "(function(){return AHUACATL_RELATIONAL_") != TRI_ERROR_NO_ERROR) {
|
||||||
|
TRI_FreeStringBuffer(TRI_UNKNOWN_MEM_ZONE, buffer);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TRI_AppendStringStringBuffer(buffer, name) != TRI_ERROR_NO_ERROR) {
|
||||||
|
TRI_FreeStringBuffer(TRI_UNKNOWN_MEM_ZONE, buffer);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TRI_AppendStringStringBuffer(buffer, "(") != TRI_ERROR_NO_ERROR) {
|
||||||
|
TRI_FreeStringBuffer(TRI_UNKNOWN_MEM_ZONE, buffer);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!TRI_NodeJavascriptAql(buffer, lhs)) {
|
||||||
|
TRI_FreeStringBuffer(TRI_UNKNOWN_MEM_ZONE, buffer);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TRI_AppendCharStringBuffer(buffer, ',') != TRI_ERROR_NO_ERROR) {
|
||||||
|
TRI_FreeStringBuffer(TRI_UNKNOWN_MEM_ZONE, buffer);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!TRI_NodeJavascriptAql(buffer, rhs)) {
|
||||||
|
TRI_FreeStringBuffer(TRI_UNKNOWN_MEM_ZONE, buffer);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TRI_AppendStringStringBuffer(buffer, ");})") != TRI_ERROR_NO_ERROR) {
|
||||||
|
TRI_FreeStringBuffer(TRI_UNKNOWN_MEM_ZONE, buffer);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief create javascript function code for a function call
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
static TRI_string_buffer_t* FcallCode (const char* const name,
|
static TRI_string_buffer_t* FcallCode (const char* const name,
|
||||||
|
@ -99,7 +150,7 @@ static TRI_string_buffer_t* FcallCode(const char* const name,
|
||||||
|
|
||||||
static TRI_aql_node_t* OptimiseFcall (TRI_aql_context_t* const context,
|
static TRI_aql_node_t* OptimiseFcall (TRI_aql_context_t* const context,
|
||||||
TRI_aql_node_t* node) {
|
TRI_aql_node_t* node) {
|
||||||
TRI_aql_node_t* args = (TRI_aql_node_t*) node->_members._buffer[0];
|
TRI_aql_node_t* args = TRI_AQL_NODE_MEMBER(node, 0);
|
||||||
TRI_aql_function_t* function;
|
TRI_aql_function_t* function;
|
||||||
TRI_js_exec_context_t* execContext;
|
TRI_js_exec_context_t* execContext;
|
||||||
TRI_string_buffer_t* code;
|
TRI_string_buffer_t* code;
|
||||||
|
@ -126,12 +177,14 @@ static TRI_aql_node_t* OptimiseFcall (TRI_aql_context_t* const context,
|
||||||
}
|
}
|
||||||
|
|
||||||
// all arguments are constants
|
// all arguments are constants
|
||||||
|
// create the function code
|
||||||
code = FcallCode(function->_internalName, args);
|
code = FcallCode(function->_internalName, args);
|
||||||
if (!code) {
|
if (!code) {
|
||||||
TRI_SetErrorContextAql(context, TRI_ERROR_OUT_OF_MEMORY, NULL);
|
TRI_SetErrorContextAql(context, TRI_ERROR_OUT_OF_MEMORY, NULL);
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// execute the function code
|
||||||
execContext = TRI_CreateExecutionContext(code->_buffer);
|
execContext = TRI_CreateExecutionContext(code->_buffer);
|
||||||
TRI_FreeStringBuffer(TRI_UNKNOWN_MEM_ZONE, code);
|
TRI_FreeStringBuffer(TRI_UNKNOWN_MEM_ZONE, code);
|
||||||
|
|
||||||
|
@ -147,10 +200,83 @@ static TRI_aql_node_t* OptimiseFcall (TRI_aql_context_t* const context,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// use the constant values instead of the function call node
|
||||||
node = TRI_JsonNodeAql(context, json);
|
node = TRI_JsonNodeAql(context, json);
|
||||||
|
if (!node) {
|
||||||
|
TRI_SetErrorContextAql(context, TRI_ERROR_OUT_OF_MEMORY, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, json);
|
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, json);
|
||||||
|
|
||||||
|
LOG_TRACE("optimised function call");
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief optimise a sort expression
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
static TRI_aql_node_t* OptimiseSort (TRI_aql_context_t* const context,
|
||||||
|
TRI_aql_node_t* node) {
|
||||||
|
TRI_aql_node_t* list = TRI_AQL_NODE_MEMBER(node, 0);
|
||||||
|
size_t i, n;
|
||||||
|
|
||||||
|
if (!list) {
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
n = list->_members._length;
|
||||||
|
while (i < n) {
|
||||||
|
// sort element
|
||||||
|
TRI_aql_node_t* element = TRI_AQL_NODE_MEMBER(list, i);
|
||||||
|
TRI_aql_node_t* expression = TRI_AQL_NODE_MEMBER(element, 0);
|
||||||
|
|
||||||
|
// check if the sort element is constant
|
||||||
|
if (!expression || !TRI_IsConstantValueNodeAql(expression)) {
|
||||||
|
++i;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// sort element is constant so it can be removed
|
||||||
|
TRI_RemoveVectorPointer(&list->_members, i);
|
||||||
|
--n;
|
||||||
|
|
||||||
|
LOG_TRACE("optimised away sort element");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (n == 0) {
|
||||||
|
// no members left => sort removed
|
||||||
|
LOG_TRACE("optimised away sort");
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief optimise a filter expression
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
static TRI_aql_node_t* OptimiseFilter (TRI_aql_context_t* const context,
|
||||||
|
TRI_aql_node_t* node) {
|
||||||
|
TRI_aql_node_t* expression = TRI_AQL_NODE_MEMBER(node, 0);
|
||||||
|
bool result;
|
||||||
|
|
||||||
|
if (!expression || !TRI_IsConstantValueNodeAql(expression)) {
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = TRI_GetBooleanNodeValueAql(expression);
|
||||||
|
if (result) {
|
||||||
|
// filter expression is always true => remove it
|
||||||
|
LOG_TRACE("optimised away constant filter");
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,7 +286,7 @@ static TRI_aql_node_t* OptimiseFcall (TRI_aql_context_t* const context,
|
||||||
|
|
||||||
static TRI_aql_node_t* OptimiseUnaryArithmeticOperation (TRI_aql_context_t* const context,
|
static TRI_aql_node_t* OptimiseUnaryArithmeticOperation (TRI_aql_context_t* const context,
|
||||||
TRI_aql_node_t* node) {
|
TRI_aql_node_t* node) {
|
||||||
TRI_aql_node_t* operand = (TRI_aql_node_t*) node->_members._buffer[0];
|
TRI_aql_node_t* operand = TRI_AQL_NODE_MEMBER(node, 0);
|
||||||
|
|
||||||
if (!operand || !TRI_IsConstantValueNodeAql(operand)) {
|
if (!operand || !TRI_IsConstantValueNodeAql(operand)) {
|
||||||
return node;
|
return node;
|
||||||
|
@ -195,7 +321,7 @@ static TRI_aql_node_t* OptimiseUnaryArithmeticOperation (TRI_aql_context_t* cons
|
||||||
|
|
||||||
static TRI_aql_node_t* OptimiseUnaryLogicalOperation (TRI_aql_context_t* const context,
|
static TRI_aql_node_t* OptimiseUnaryLogicalOperation (TRI_aql_context_t* const context,
|
||||||
TRI_aql_node_t* node) {
|
TRI_aql_node_t* node) {
|
||||||
TRI_aql_node_t* operand = (TRI_aql_node_t*) node->_members._buffer[0];
|
TRI_aql_node_t* operand = TRI_AQL_NODE_MEMBER(node, 0);
|
||||||
|
|
||||||
if (!operand || !TRI_IsConstantValueNodeAql(operand)) {
|
if (!operand || !TRI_IsConstantValueNodeAql(operand)) {
|
||||||
return node;
|
return node;
|
||||||
|
@ -214,6 +340,8 @@ static TRI_aql_node_t* OptimiseUnaryLogicalOperation (TRI_aql_context_t* const c
|
||||||
if (!node) {
|
if (!node) {
|
||||||
TRI_SetErrorContextAql(context, TRI_ERROR_OUT_OF_MEMORY, NULL);
|
TRI_SetErrorContextAql(context, TRI_ERROR_OUT_OF_MEMORY, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LOG_TRACE("optimised away unary logical operation");
|
||||||
}
|
}
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
|
@ -225,8 +353,8 @@ static TRI_aql_node_t* OptimiseUnaryLogicalOperation (TRI_aql_context_t* const c
|
||||||
|
|
||||||
static TRI_aql_node_t* OptimiseBinaryLogicalOperation (TRI_aql_context_t* const context,
|
static TRI_aql_node_t* OptimiseBinaryLogicalOperation (TRI_aql_context_t* const context,
|
||||||
TRI_aql_node_t* node) {
|
TRI_aql_node_t* node) {
|
||||||
TRI_aql_node_t* lhs = (TRI_aql_node_t*) node->_members._buffer[0];
|
TRI_aql_node_t* lhs = TRI_AQL_NODE_MEMBER(node, 0);
|
||||||
TRI_aql_node_t* rhs = (TRI_aql_node_t*) node->_members._buffer[1];
|
TRI_aql_node_t* rhs = TRI_AQL_NODE_MEMBER(node, 1);
|
||||||
bool isEligibleLhs;
|
bool isEligibleLhs;
|
||||||
bool isEligibleRhs;
|
bool isEligibleRhs;
|
||||||
bool lhsValue;
|
bool lhsValue;
|
||||||
|
@ -257,6 +385,8 @@ static TRI_aql_node_t* OptimiseBinaryLogicalOperation (TRI_aql_context_t* const
|
||||||
assert(node->_type == AQL_NODE_OPERATOR_BINARY_AND ||
|
assert(node->_type == AQL_NODE_OPERATOR_BINARY_AND ||
|
||||||
node->_type == AQL_NODE_OPERATOR_BINARY_OR);
|
node->_type == AQL_NODE_OPERATOR_BINARY_OR);
|
||||||
|
|
||||||
|
LOG_TRACE("optimised away binary logical operation");
|
||||||
|
|
||||||
if (node->_type == AQL_NODE_OPERATOR_BINARY_AND) {
|
if (node->_type == AQL_NODE_OPERATOR_BINARY_AND) {
|
||||||
if (lhsValue) {
|
if (lhsValue) {
|
||||||
// if (true && rhs) => rhs
|
// if (true && rhs) => rhs
|
||||||
|
@ -281,14 +411,86 @@ static TRI_aql_node_t* OptimiseBinaryLogicalOperation (TRI_aql_context_t* const
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief optimise a relational operation with two operands
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
static TRI_aql_node_t* OptimiseBinaryRelationalOperation (TRI_aql_context_t* const context,
|
||||||
|
TRI_aql_node_t* node) {
|
||||||
|
TRI_aql_node_t* lhs = TRI_AQL_NODE_MEMBER(node, 0);
|
||||||
|
TRI_aql_node_t* rhs = TRI_AQL_NODE_MEMBER(node, 1);
|
||||||
|
TRI_js_exec_context_t* execContext;
|
||||||
|
TRI_string_buffer_t* code;
|
||||||
|
TRI_json_t* json;
|
||||||
|
char* func;
|
||||||
|
|
||||||
|
if (!lhs || !TRI_IsConstantValueNodeAql(lhs) || !rhs || !TRI_IsConstantValueNodeAql(rhs)) {
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node->_type == AQL_NODE_OPERATOR_BINARY_EQ) {
|
||||||
|
func = "EQUAL";
|
||||||
|
}
|
||||||
|
else if (node->_type == AQL_NODE_OPERATOR_BINARY_NE) {
|
||||||
|
func = "UNEQUAL";
|
||||||
|
}
|
||||||
|
else if (node->_type == AQL_NODE_OPERATOR_BINARY_GT) {
|
||||||
|
func = "GREATER";
|
||||||
|
}
|
||||||
|
else if (node->_type == AQL_NODE_OPERATOR_BINARY_GE) {
|
||||||
|
func = "GREATER_EQUAL";
|
||||||
|
}
|
||||||
|
else if (node->_type == AQL_NODE_OPERATOR_BINARY_LT) {
|
||||||
|
func = "LESS";
|
||||||
|
}
|
||||||
|
else if (node->_type == AQL_NODE_OPERATOR_BINARY_LE) {
|
||||||
|
func = "LESS_EQUAL";
|
||||||
|
}
|
||||||
|
else if (node->_type == AQL_NODE_OPERATOR_BINARY_IN) {
|
||||||
|
func = "IN";
|
||||||
|
}
|
||||||
|
|
||||||
|
code = RelationCode(func, lhs, rhs);
|
||||||
|
if (!code) {
|
||||||
|
TRI_SetErrorContextAql(context, TRI_ERROR_OUT_OF_MEMORY, NULL);
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
// execute the function code
|
||||||
|
execContext = TRI_CreateExecutionContext(code->_buffer);
|
||||||
|
TRI_FreeStringBuffer(TRI_UNKNOWN_MEM_ZONE, code);
|
||||||
|
|
||||||
|
if (!execContext) {
|
||||||
|
TRI_SetErrorContextAql(context, TRI_ERROR_OUT_OF_MEMORY, NULL);
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
json = TRI_ExecuteResultContext(execContext);
|
||||||
|
TRI_FreeExecutionContext(execContext);
|
||||||
|
if (!json) {
|
||||||
|
TRI_SetErrorContextAql(context, TRI_ERROR_QUERY_SCRIPT, NULL);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// use the constant values instead of the function call node
|
||||||
|
node = TRI_JsonNodeAql(context, json);
|
||||||
|
if (!node) {
|
||||||
|
TRI_SetErrorContextAql(context, TRI_ERROR_OUT_OF_MEMORY, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_TRACE("optimised away binary relational operation");
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief optimise an arithmetic operation with two operands
|
/// @brief optimise an arithmetic operation with two operands
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
static TRI_aql_node_t* OptimiseBinaryArithmeticOperation (TRI_aql_context_t* const context,
|
static TRI_aql_node_t* OptimiseBinaryArithmeticOperation (TRI_aql_context_t* const context,
|
||||||
TRI_aql_node_t* node) {
|
TRI_aql_node_t* node) {
|
||||||
TRI_aql_node_t* lhs = (TRI_aql_node_t*) node->_members._buffer[0];
|
TRI_aql_node_t* lhs = TRI_AQL_NODE_MEMBER(node, 0);
|
||||||
TRI_aql_node_t* rhs = (TRI_aql_node_t*) node->_members._buffer[1];
|
TRI_aql_node_t* rhs = TRI_AQL_NODE_MEMBER(node, 1);
|
||||||
bool isEligibleLhs;
|
bool isEligibleLhs;
|
||||||
bool isEligibleRhs;
|
bool isEligibleRhs;
|
||||||
double value;
|
double value;
|
||||||
|
@ -351,6 +553,8 @@ static TRI_aql_node_t* OptimiseBinaryArithmeticOperation (TRI_aql_context_t* con
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LOG_TRACE("optimised away binary arithmetic operation");
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -374,12 +578,24 @@ static TRI_aql_node_t* ModifyNode (void* data, TRI_aql_node_t* node) {
|
||||||
case AQL_NODE_OPERATOR_BINARY_AND:
|
case AQL_NODE_OPERATOR_BINARY_AND:
|
||||||
case AQL_NODE_OPERATOR_BINARY_OR:
|
case AQL_NODE_OPERATOR_BINARY_OR:
|
||||||
return OptimiseBinaryLogicalOperation(context, node);
|
return OptimiseBinaryLogicalOperation(context, node);
|
||||||
|
case AQL_NODE_OPERATOR_BINARY_EQ:
|
||||||
|
case AQL_NODE_OPERATOR_BINARY_NE:
|
||||||
|
case AQL_NODE_OPERATOR_BINARY_LT:
|
||||||
|
case AQL_NODE_OPERATOR_BINARY_LE:
|
||||||
|
case AQL_NODE_OPERATOR_BINARY_GT:
|
||||||
|
case AQL_NODE_OPERATOR_BINARY_GE:
|
||||||
|
case AQL_NODE_OPERATOR_BINARY_IN:
|
||||||
|
return OptimiseBinaryRelationalOperation(context, node);
|
||||||
case AQL_NODE_OPERATOR_BINARY_PLUS:
|
case AQL_NODE_OPERATOR_BINARY_PLUS:
|
||||||
case AQL_NODE_OPERATOR_BINARY_MINUS:
|
case AQL_NODE_OPERATOR_BINARY_MINUS:
|
||||||
case AQL_NODE_OPERATOR_BINARY_TIMES:
|
case AQL_NODE_OPERATOR_BINARY_TIMES:
|
||||||
case AQL_NODE_OPERATOR_BINARY_DIV:
|
case AQL_NODE_OPERATOR_BINARY_DIV:
|
||||||
case AQL_NODE_OPERATOR_BINARY_MOD:
|
case AQL_NODE_OPERATOR_BINARY_MOD:
|
||||||
return OptimiseBinaryArithmeticOperation(context, node);
|
return OptimiseBinaryArithmeticOperation(context, node);
|
||||||
|
case AQL_NODE_SORT:
|
||||||
|
return OptimiseSort(context, node);
|
||||||
|
case AQL_NODE_FILTER:
|
||||||
|
return OptimiseFilter(context, node);
|
||||||
case AQL_NODE_FCALL:
|
case AQL_NODE_FCALL:
|
||||||
return OptimiseFcall(context, node);
|
return OptimiseFcall(context, node);
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include <BasicsC/common.h>
|
#include <BasicsC/common.h>
|
||||||
#include <BasicsC/strings.h>
|
#include <BasicsC/strings.h>
|
||||||
#include <BasicsC/hashes.h>
|
#include <BasicsC/hashes.h>
|
||||||
|
#include <BasicsC/logging.h>
|
||||||
#include <BasicsC/vector.h>
|
#include <BasicsC/vector.h>
|
||||||
#include <BasicsC/associative.h>
|
#include <BasicsC/associative.h>
|
||||||
|
|
||||||
|
|
|
@ -42,11 +42,13 @@
|
||||||
|
|
||||||
static TRI_aql_node_t* ModifyNode (TRI_aql_modify_tree_walker_t* const walker,
|
static TRI_aql_node_t* ModifyNode (TRI_aql_modify_tree_walker_t* const walker,
|
||||||
TRI_aql_node_t* node) {
|
TRI_aql_node_t* node) {
|
||||||
TRI_aql_node_t* result = NULL;
|
TRI_aql_node_t* first = NULL;
|
||||||
|
TRI_aql_node_t* last = NULL;
|
||||||
|
|
||||||
assert(walker);
|
assert(walker);
|
||||||
|
|
||||||
while (node) {
|
while (node) {
|
||||||
|
TRI_aql_node_t* old;
|
||||||
size_t i;
|
size_t i;
|
||||||
size_t n = node->_members._length;
|
size_t n = node->_members._length;
|
||||||
|
|
||||||
|
@ -61,18 +63,37 @@ static TRI_aql_node_t* ModifyNode (TRI_aql_modify_tree_walker_t* const walker,
|
||||||
node->_members._buffer[i] = ModifyNode(walker, member);
|
node->_members._buffer[i] = ModifyNode(walker, member);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// keep old node pointer
|
||||||
|
old = node;
|
||||||
|
|
||||||
// the visit function might set it to NULL
|
// the visit function might set it to NULL
|
||||||
node = walker->visitFunc(walker->_data, node);
|
node = walker->visitFunc(walker->_data, node);
|
||||||
if (!result) {
|
if (!first) {
|
||||||
result = node;
|
// first remaining node in chain
|
||||||
|
first = node;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (last) {
|
||||||
|
// keep node chaining intact
|
||||||
|
last->_next = node;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node) {
|
if (node) {
|
||||||
|
last = node;
|
||||||
|
}
|
||||||
|
|
||||||
|
// determine next next in chain
|
||||||
|
if (node == old) {
|
||||||
|
// node did not change
|
||||||
node = node->_next;
|
node = node->_next;
|
||||||
}
|
}
|
||||||
|
else if (node != old && old != NULL) {
|
||||||
|
// node changed
|
||||||
|
node = old->_next;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return first;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -99,7 +99,7 @@ ERROR_AVOCADO_DATAFILE_FULL,1300,"datafile full","Will be raised when the datafi
|
||||||
################################################################################
|
################################################################################
|
||||||
|
|
||||||
ERROR_QUERY_KILLED,1500,"query killed","Will be raised when a running query is killed by an explicit admin command."
|
ERROR_QUERY_KILLED,1500,"query killed","Will be raised when a running query is killed by an explicit admin command."
|
||||||
ERROR_QUERY_PARSE,1501,"parse error: %s","Will be raised when query is parsed and is found to be syntactially invalid."
|
ERROR_QUERY_PARSE,1501,"%s","Will be raised when query is parsed and is found to be syntactially invalid."
|
||||||
ERROR_QUERY_EMPTY,1502,"query is empty","Will be raised when an empty query is specified."
|
ERROR_QUERY_EMPTY,1502,"query is empty","Will be raised when an empty query is specified."
|
||||||
ERROR_QUERY_SPECIFICATION_INVALID,1503,"query specification invalid","Will be raised when a query is sent to the server with an incomplete or invalid query specification structure."
|
ERROR_QUERY_SPECIFICATION_INVALID,1503,"query specification invalid","Will be raised when a query is sent to the server with an incomplete or invalid query specification structure."
|
||||||
ERROR_QUERY_NUMBER_OUT_OF_RANGE,1504,"number '%s' is out of range","Will be raised when a numeric value inside a query is out of the allowed value range."
|
ERROR_QUERY_NUMBER_OUT_OF_RANGE,1504,"number '%s' is out of range","Will be raised when a numeric value inside a query is out of the allowed value range."
|
||||||
|
@ -117,7 +117,7 @@ ERROR_QUERY_BIND_PARAMETER_UNDECLARED,1515,"bind parameter '%s' was not declared
|
||||||
ERROR_QUERY_BIND_PARAMETER_VALUE_INVALID,1516,"invalid value for bind parameter '%s'","Will be raised when an invalid value is specified for one of the bind parameters."
|
ERROR_QUERY_BIND_PARAMETER_VALUE_INVALID,1516,"invalid value for bind parameter '%s'","Will be raised when an invalid value is specified for one of the bind parameters."
|
||||||
ERROR_QUERY_BIND_PARAMETER_NUMBER_OUT_OF_RANGE,1517,"bind parameter number '%s' out of range","Will be specified when the numeric index for a bind parameter of type @n is out of the allowed range."
|
ERROR_QUERY_BIND_PARAMETER_NUMBER_OUT_OF_RANGE,1517,"bind parameter number '%s' out of range","Will be specified when the numeric index for a bind parameter of type @n is out of the allowed range."
|
||||||
ERROR_QUERY_FUNCTION_NAME_UNKNOWN,1518,"usage of unknown function '%s'","Will be raised when an undefined function is called."
|
ERROR_QUERY_FUNCTION_NAME_UNKNOWN,1518,"usage of unknown function '%s'","Will be raised when an undefined function is called."
|
||||||
ERROR_QUERY_RUNTIME_ERROR,1520,"runtime error in query","Will be raised when a Javascript runtime error occurs while executing a query."
|
ERROR_QUERY_RUNTIME_ERROR,1520,"runtime error '%s'","Will be raised when a Javascript runtime error occurs while executing a query."
|
||||||
ERROR_QUERY_LIMIT_VALUE_OUT_OF_RANGE,1521,"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)."
|
ERROR_QUERY_LIMIT_VALUE_OUT_OF_RANGE,1521,"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)."
|
||||||
ERROR_QUERY_VARIABLE_REDECLARED,1522,"variable '%s' is assigned multiple times","Will be raised when a variable gets re-assigned in a query."
|
ERROR_QUERY_VARIABLE_REDECLARED,1522,"variable '%s' is assigned multiple times","Will be raised when a variable gets re-assigned in a query."
|
||||||
ERROR_QUERY_DOCUMENT_ATTRIBUTE_REDECLARED,1523,"document attribute '%s' is assigned multiple times","Will be raised when a document attribute is re-assigned."
|
ERROR_QUERY_DOCUMENT_ATTRIBUTE_REDECLARED,1523,"document attribute '%s' is assigned multiple times","Will be raised when a document attribute is re-assigned."
|
||||||
|
|
|
@ -65,7 +65,7 @@ void TRI_InitialiseErrorMessages (void) {
|
||||||
REG_ERROR(ERROR_AVOCADO_CAP_CONSTRAINT_ALREADY_DEFINED, "cap constraint already defined");
|
REG_ERROR(ERROR_AVOCADO_CAP_CONSTRAINT_ALREADY_DEFINED, "cap constraint already defined");
|
||||||
REG_ERROR(ERROR_AVOCADO_DATAFILE_FULL, "datafile full");
|
REG_ERROR(ERROR_AVOCADO_DATAFILE_FULL, "datafile full");
|
||||||
REG_ERROR(ERROR_QUERY_KILLED, "query killed");
|
REG_ERROR(ERROR_QUERY_KILLED, "query killed");
|
||||||
REG_ERROR(ERROR_QUERY_PARSE, "parse error: %s");
|
REG_ERROR(ERROR_QUERY_PARSE, "%s");
|
||||||
REG_ERROR(ERROR_QUERY_EMPTY, "query is empty");
|
REG_ERROR(ERROR_QUERY_EMPTY, "query is empty");
|
||||||
REG_ERROR(ERROR_QUERY_SPECIFICATION_INVALID, "query specification invalid");
|
REG_ERROR(ERROR_QUERY_SPECIFICATION_INVALID, "query specification invalid");
|
||||||
REG_ERROR(ERROR_QUERY_NUMBER_OUT_OF_RANGE, "number '%s' is out of range");
|
REG_ERROR(ERROR_QUERY_NUMBER_OUT_OF_RANGE, "number '%s' is out of range");
|
||||||
|
@ -83,7 +83,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_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_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_FUNCTION_NAME_UNKNOWN, "usage of unknown function '%s'");
|
||||||
REG_ERROR(ERROR_QUERY_RUNTIME_ERROR, "runtime error in query");
|
REG_ERROR(ERROR_QUERY_RUNTIME_ERROR, "runtime error '%s'");
|
||||||
REG_ERROR(ERROR_QUERY_LIMIT_VALUE_OUT_OF_RANGE, "limit value '%s' is out of range");
|
REG_ERROR(ERROR_QUERY_LIMIT_VALUE_OUT_OF_RANGE, "limit value '%s' is out of range");
|
||||||
REG_ERROR(ERROR_QUERY_VARIABLE_REDECLARED, "variable '%s' is assigned multiple times");
|
REG_ERROR(ERROR_QUERY_VARIABLE_REDECLARED, "variable '%s' is assigned multiple times");
|
||||||
REG_ERROR(ERROR_QUERY_DOCUMENT_ATTRIBUTE_REDECLARED, "document attribute '%s' is assigned multiple times");
|
REG_ERROR(ERROR_QUERY_DOCUMENT_ATTRIBUTE_REDECLARED, "document attribute '%s' is assigned multiple times");
|
||||||
|
|
|
@ -130,7 +130,7 @@ extern "C" {
|
||||||
/// - 1500: @CODE{query killed}
|
/// - 1500: @CODE{query killed}
|
||||||
/// Will be raised when a running query is killed by an explicit admin
|
/// Will be raised when a running query is killed by an explicit admin
|
||||||
/// command.
|
/// command.
|
||||||
/// - 1501: @CODE{parse error: \%s}
|
/// - 1501: @CODE{\%s}
|
||||||
/// Will be raised when query is parsed and is found to be syntactially
|
/// Will be raised when query is parsed and is found to be syntactially
|
||||||
/// invalid.
|
/// invalid.
|
||||||
/// - 1502: @CODE{query is empty}
|
/// - 1502: @CODE{query is empty}
|
||||||
|
@ -180,7 +180,7 @@ extern "C" {
|
||||||
/// is out of the allowed range.
|
/// is out of the allowed range.
|
||||||
/// - 1518: @CODE{usage of unknown function '\%s'}
|
/// - 1518: @CODE{usage of unknown function '\%s'}
|
||||||
/// Will be raised when an undefined function is called.
|
/// Will be raised when an undefined function is called.
|
||||||
/// - 1520: @CODE{runtime error in query}
|
/// - 1520: @CODE{runtime error '\%s'}
|
||||||
/// Will be raised when a Javascript runtime error occurs while executing a
|
/// Will be raised when a Javascript runtime error occurs while executing a
|
||||||
/// query.
|
/// query.
|
||||||
/// - 1521: @CODE{limit value '\%s' is out of range}
|
/// - 1521: @CODE{limit value '\%s' is out of range}
|
||||||
|
@ -891,7 +891,7 @@ void TRI_InitialiseErrorMessages (void);
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief 1501: ERROR_QUERY_PARSE
|
/// @brief 1501: ERROR_QUERY_PARSE
|
||||||
///
|
///
|
||||||
/// parse error: %s
|
/// %s
|
||||||
///
|
///
|
||||||
/// Will be raised when query is parsed and is found to be syntactially invalid.
|
/// Will be raised when query is parsed and is found to be syntactially invalid.
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -1083,7 +1083,7 @@ void TRI_InitialiseErrorMessages (void);
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief 1520: ERROR_QUERY_RUNTIME_ERROR
|
/// @brief 1520: ERROR_QUERY_RUNTIME_ERROR
|
||||||
///
|
///
|
||||||
/// runtime error in query
|
/// runtime error '%s'
|
||||||
///
|
///
|
||||||
/// Will be raised when a Javascript runtime error occurs while executing a
|
/// Will be raised when a Javascript runtime error occurs while executing a
|
||||||
/// query.
|
/// query.
|
||||||
|
|
|
@ -362,20 +362,31 @@ GeoIndex * GeoIndex_new(void)
|
||||||
int i,j;
|
int i,j;
|
||||||
double lat, lon, x, y, z;
|
double lat, lon, x, y, z;
|
||||||
|
|
||||||
gix = malloc(sizeof(GeoIx));
|
gix = TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, sizeof(GeoIx), false);
|
||||||
if(gix==NULL) return (GeoIndex *) gix;
|
|
||||||
|
if(gix == NULL) {
|
||||||
|
return (GeoIndex *) gix;
|
||||||
|
}
|
||||||
|
|
||||||
/* try to allocate all the things we need */
|
/* try to allocate all the things we need */
|
||||||
gix->pots = malloc(GEOPOTSTART*sizeof(GeoPot));
|
gix->pots = TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, GEOPOTSTART*sizeof(GeoPot), false);
|
||||||
gix->gc = malloc(GEOSLOTSTART*sizeof(GeoCoordinate));
|
gix->gc = TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, GEOSLOTSTART*sizeof(GeoCoordinate), false);
|
||||||
|
|
||||||
/* if any of them fail, free the ones that succeeded */
|
/* if any of them fail, free the ones that succeeded */
|
||||||
/* and then return the NULL pointer for our user */
|
/* and then return the NULL pointer for our user */
|
||||||
if ( ( gix->pots == NULL) ||
|
if ( ( gix->pots == NULL) ||
|
||||||
( gix->gc == NULL) )
|
( gix->gc == NULL) )
|
||||||
{
|
{
|
||||||
if ( gix->pots != NULL) free(gix->pots);
|
if ( gix->pots != NULL) {
|
||||||
if ( gix->gc != NULL) free(gix->gc);
|
TRI_Free(TRI_UNKNOWN_MEM_ZONE, gix->pots);
|
||||||
free(gix);
|
}
|
||||||
|
|
||||||
|
if ( gix->gc != NULL) {
|
||||||
|
TRI_Free(TRI_UNKNOWN_MEM_ZONE, gix->gc);
|
||||||
|
}
|
||||||
|
|
||||||
|
TRI_Free(TRI_UNKNOWN_MEM_ZONE, gix);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -555,10 +566,15 @@ GeoIndex * GeoIndex_new(void)
|
||||||
void GeoIndex_free(GeoIndex * gi)
|
void GeoIndex_free(GeoIndex * gi)
|
||||||
{
|
{
|
||||||
GeoIx * gix;
|
GeoIx * gix;
|
||||||
|
|
||||||
|
if (gi == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
gix = (GeoIx *) gi;
|
gix = (GeoIx *) gi;
|
||||||
free(gix->gc);
|
TRI_Free(TRI_UNKNOWN_MEM_ZONE, gix->gc);
|
||||||
free(gix->pots);
|
TRI_Free(TRI_UNKNOWN_MEM_ZONE, gix->pots);
|
||||||
free(gix);
|
TRI_Free(TRI_UNKNOWN_MEM_ZONE, gix);
|
||||||
}
|
}
|
||||||
/* =================================================== */
|
/* =================================================== */
|
||||||
/* GeoMkHilbert routine */
|
/* GeoMkHilbert routine */
|
||||||
|
@ -785,16 +801,30 @@ GeoResults * GeoResultsCons(int alloc)
|
||||||
GeoResults * gres;
|
GeoResults * gres;
|
||||||
int * sa;
|
int * sa;
|
||||||
double * dd;
|
double * dd;
|
||||||
gres=malloc(sizeof(GeoResults));
|
|
||||||
sa=malloc(alloc*sizeof(int));
|
if (alloc <= 0) {
|
||||||
dd=malloc(alloc*sizeof(double));
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
gres = TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, sizeof(GeoResults), false);
|
||||||
|
sa = TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, alloc*sizeof(int), false);
|
||||||
|
dd = TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, alloc*sizeof(double), false);
|
||||||
if( (gres==NULL) ||
|
if( (gres==NULL) ||
|
||||||
(sa==NULL) ||
|
(sa==NULL) ||
|
||||||
(dd==NULL) )
|
(dd==NULL) )
|
||||||
{
|
{
|
||||||
if(gres!=NULL) free(gres);
|
if(gres!=NULL) {
|
||||||
if(sa!=NULL) free(sa);
|
TRI_Free(TRI_UNKNOWN_MEM_ZONE, gres);
|
||||||
if(dd!=NULL) free(dd);
|
}
|
||||||
|
|
||||||
|
if(sa!=NULL) {
|
||||||
|
TRI_Free(TRI_UNKNOWN_MEM_ZONE, sa);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(dd!=NULL) {
|
||||||
|
TRI_Free(TRI_UNKNOWN_MEM_ZONE, dd);
|
||||||
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
gres->pointsct = 0;
|
gres->pointsct = 0;
|
||||||
|
@ -939,15 +969,28 @@ GeoCoordinates * GeoAnswers (GeoIx * gix, GeoResults * gr)
|
||||||
GeoCoordinate * gc;
|
GeoCoordinate * gc;
|
||||||
int i,j,slot;
|
int i,j,slot;
|
||||||
double mole;
|
double mole;
|
||||||
ans = malloc(sizeof(GeoCoordinates));
|
|
||||||
gc = malloc(gr->pointsct * sizeof(GeoCoordinate));
|
if (gr->pointsct == 0) {
|
||||||
|
TRI_Free(TRI_UNKNOWN_MEM_ZONE, gr->slot);
|
||||||
|
TRI_Free(TRI_UNKNOWN_MEM_ZONE, gr->snmd);
|
||||||
|
TRI_Free(TRI_UNKNOWN_MEM_ZONE, gr);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ans = TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, sizeof(GeoCoordinates), false);
|
||||||
|
gc = TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, gr->pointsct * sizeof(GeoCoordinate), false);
|
||||||
|
|
||||||
if( (ans==NULL) || (gc==NULL) )
|
if( (ans==NULL) || (gc==NULL) )
|
||||||
{
|
{
|
||||||
if(ans!=NULL) free(ans);
|
if(ans!=NULL) {
|
||||||
if(gc!=NULL) free(gc);
|
TRI_Free(TRI_UNKNOWN_MEM_ZONE, ans);
|
||||||
free(gr->slot);
|
}
|
||||||
free(gr->snmd);
|
if(gc!=NULL) {
|
||||||
free(gr);
|
TRI_Free(TRI_UNKNOWN_MEM_ZONE, gc);
|
||||||
|
}
|
||||||
|
TRI_Free(TRI_UNKNOWN_MEM_ZONE, gr->slot);
|
||||||
|
TRI_Free(TRI_UNKNOWN_MEM_ZONE, gr->snmd);
|
||||||
|
TRI_Free(TRI_UNKNOWN_MEM_ZONE, gr);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
ans->length = gr->pointsct;
|
ans->length = gr->pointsct;
|
||||||
|
@ -970,8 +1013,10 @@ GeoCoordinates * GeoAnswers (GeoIx * gix, GeoResults * gr)
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
ans->distances = gr->snmd;
|
ans->distances = gr->snmd;
|
||||||
free(gr->slot);
|
|
||||||
free(gr);
|
TRI_Free(TRI_UNKNOWN_MEM_ZONE, gr->slot);
|
||||||
|
TRI_Free(TRI_UNKNOWN_MEM_ZONE, gr);
|
||||||
|
|
||||||
return ans;
|
return ans;
|
||||||
}
|
}
|
||||||
/* =================================================== */
|
/* =================================================== */
|
||||||
|
@ -1076,9 +1121,9 @@ GeoCoordinates * GeoIndex_PointsWithinRadius(GeoIndex * gi,
|
||||||
r = GeoResultsGrow(gres);
|
r = GeoResultsGrow(gres);
|
||||||
if(r==-1)
|
if(r==-1)
|
||||||
{
|
{
|
||||||
free(gres->snmd);
|
TRI_Free(TRI_UNKNOWN_MEM_ZONE, gres->snmd);
|
||||||
free(gres->slot);
|
TRI_Free(TRI_UNKNOWN_MEM_ZONE, gres->slot);
|
||||||
free(gres);
|
TRI_Free(TRI_UNKNOWN_MEM_ZONE, gres);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
gres->slot[gres->pointsct]=slot;
|
gres->slot[gres->pointsct]=slot;
|
||||||
|
@ -2041,9 +2086,9 @@ int GeoIndex_remove(GeoIndex * gi, GeoCoordinate * c)
|
||||||
/* =================================================== */
|
/* =================================================== */
|
||||||
void GeoIndex_CoordinatesFree(GeoCoordinates * clist)
|
void GeoIndex_CoordinatesFree(GeoCoordinates * clist)
|
||||||
{
|
{
|
||||||
free(clist->coordinates);
|
TRI_Free(TRI_UNKNOWN_MEM_ZONE, clist->coordinates);
|
||||||
free(clist->distances);
|
TRI_Free(TRI_UNKNOWN_MEM_ZONE, clist->distances);
|
||||||
free(clist);
|
TRI_Free(TRI_UNKNOWN_MEM_ZONE, clist);
|
||||||
}
|
}
|
||||||
/* =================================================== */
|
/* =================================================== */
|
||||||
/* GeoIndex_hint does nothing! */
|
/* GeoIndex_hint does nothing! */
|
||||||
|
|
|
@ -28,14 +28,7 @@
|
||||||
/* GeoIndex.h - header file for GeoIndex algorithms */
|
/* GeoIndex.h - header file for GeoIndex algorithms */
|
||||||
/* Version 2.1 8.1.2012 R. A. Parker */
|
/* Version 2.1 8.1.2012 R. A. Parker */
|
||||||
|
|
||||||
#ifdef GEO_STANDALONE
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <math.h>
|
|
||||||
#else
|
|
||||||
#include "BasicsC/common.h"
|
#include "BasicsC/common.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
|
@ -264,6 +264,7 @@ void runTest (int mode)
|
||||||
double la,lo;
|
double la,lo;
|
||||||
double d1;
|
double d1;
|
||||||
int i,j,r;
|
int i,j,r;
|
||||||
|
void* nullp = 0;
|
||||||
|
|
||||||
errors=0;
|
errors=0;
|
||||||
|
|
||||||
|
@ -332,9 +333,11 @@ void runTest (int mode)
|
||||||
/* do both searches with an empty index */
|
/* do both searches with an empty index */
|
||||||
|
|
||||||
list1 = GeoIndex_NearestCountPoints(gi,&gcp1,3);
|
list1 = GeoIndex_NearestCountPoints(gi,&gcp1,3);
|
||||||
gccheck(20,list1, 0,"AAAAAAAAAAAAAAAAAAAAAAAAA");
|
// gccheck(20,list1,0,"AAAAAAAAAAAAAAAAAAAAAAAAA");
|
||||||
|
BOOST_CHECK_EQUAL(nullp, list1); // no results, check against null pointer
|
||||||
list1 = GeoIndex_PointsWithinRadius(gi,&gcp1,100000.0);
|
list1 = GeoIndex_PointsWithinRadius(gi,&gcp1,100000.0);
|
||||||
gccheck(21,list1,0,"AAAAAAAAAAAAAAAAAAAAAAAAA");
|
// gccheck(21,list1,0,"AAAAAAAAAAAAAAAAAAAAAAAAA");
|
||||||
|
BOOST_CHECK_EQUAL(nullp, list1); // no results, check against null pointer
|
||||||
|
|
||||||
/* stick in Jo'burg */
|
/* stick in Jo'burg */
|
||||||
gcp4.data=ix + 4;
|
gcp4.data=ix + 4;
|
||||||
|
@ -349,9 +352,11 @@ void runTest (int mode)
|
||||||
r = GeoIndex_remove(gi,&gcp4);
|
r = GeoIndex_remove(gi,&gcp4);
|
||||||
icheck(25,0,r);
|
icheck(25,0,r);
|
||||||
list1 = GeoIndex_NearestCountPoints(gi,&gcp1,3);
|
list1 = GeoIndex_NearestCountPoints(gi,&gcp1,3);
|
||||||
gccheck(26,list1, 0,"AAAAAAAAAAAAAAAAAAAAAAAAA");
|
// gccheck(26,list1, 0,"AAAAAAAAAAAAAAAAAAAAAAAAA");
|
||||||
|
BOOST_CHECK_EQUAL(nullp, list1); // no results, check against null pointer
|
||||||
list1 = GeoIndex_PointsWithinRadius(gi,&gcp1,100000.0);
|
list1 = GeoIndex_PointsWithinRadius(gi,&gcp1,100000.0);
|
||||||
gccheck(27,list1,0,"AAAAAAAAAAAAAAAAAAAAAAAAA");
|
// gccheck(27,list1,0,"AAAAAAAAAAAAAAAAAAAAAAAAA");
|
||||||
|
BOOST_CHECK_EQUAL(nullp, list1); // no results, check against null pointer
|
||||||
|
|
||||||
/* try to delete from an empty index */
|
/* try to delete from an empty index */
|
||||||
|
|
||||||
|
@ -1037,9 +1042,12 @@ void runTest (int mode)
|
||||||
{
|
{
|
||||||
coonum(&gcp1,j);
|
coonum(&gcp1,j);
|
||||||
list1 = GeoIndex_PointsWithinRadius(gi,&gcp1,127000.0);
|
list1 = GeoIndex_PointsWithinRadius(gi,&gcp1,127000.0);
|
||||||
|
if (list1) {
|
||||||
|
// only free if pointer is valid
|
||||||
GeoIndex_CoordinatesFree(list1);
|
GeoIndex_CoordinatesFree(list1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
BOOST_TEST_MESSAGE("End of timing test");
|
BOOST_TEST_MESSAGE("End of timing test");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1052,9 +1060,12 @@ void runTest (int mode)
|
||||||
{
|
{
|
||||||
coonum(&gcp1,j);
|
coonum(&gcp1,j);
|
||||||
list1 = GeoIndex_NearestCountPoints(gi,&gcp1,2);
|
list1 = GeoIndex_NearestCountPoints(gi,&gcp1,2);
|
||||||
|
if (list1) {
|
||||||
|
// only free if pointer is valid
|
||||||
GeoIndex_CoordinatesFree(list1);
|
GeoIndex_CoordinatesFree(list1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
BOOST_TEST_MESSAGE("End of timing test");
|
BOOST_TEST_MESSAGE("End of timing test");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -279,7 +279,13 @@ static v8::Handle<v8::Object> CreateErrorObject (int errorNumber, string const&
|
||||||
|
|
||||||
v8g = (TRI_v8_global_t*) v8::Isolate::GetCurrent()->GetData();
|
v8g = (TRI_v8_global_t*) v8::Isolate::GetCurrent()->GetData();
|
||||||
|
|
||||||
string msg = TRI_errno_string(errorNumber) + string(": ") + message;
|
string msg;
|
||||||
|
if (message.size()) {
|
||||||
|
msg = message;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
msg = TRI_errno_string(errorNumber) + string(": ") + message;
|
||||||
|
}
|
||||||
v8::Handle<v8::String> errorMessage = v8::String::New(msg.c_str());
|
v8::Handle<v8::String> errorMessage = v8::String::New(msg.c_str());
|
||||||
|
|
||||||
v8::Handle<v8::Object> errorObject = v8::Exception::Error(errorMessage)->ToObject();
|
v8::Handle<v8::Object> errorObject = v8::Exception::Error(errorMessage)->ToObject();
|
||||||
|
@ -287,6 +293,7 @@ static v8::Handle<v8::Object> CreateErrorObject (int errorNumber, string const&
|
||||||
|
|
||||||
errorObject->Set(v8::String::New("errorNum"), v8::Number::New(errorNumber));
|
errorObject->Set(v8::String::New("errorNum"), v8::Number::New(errorNumber));
|
||||||
errorObject->Set(v8::String::New("errorMessage"), errorMessage);
|
errorObject->Set(v8::String::New("errorMessage"), errorMessage);
|
||||||
|
|
||||||
errorObject->SetPrototype(proto);
|
errorObject->SetPrototype(proto);
|
||||||
|
|
||||||
return errorObject;
|
return errorObject;
|
||||||
|
@ -2930,6 +2937,13 @@ static v8::Handle<v8::Value> JS_RunAhuacatl (v8::Arguments const& argv) {
|
||||||
return scope.Close(WrapGeneralCursor(cursor));
|
return scope.Close(WrapGeneralCursor(cursor));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tryCatch.HasCaught()) {
|
||||||
|
TRI_SetErrorContextAql(context, TRI_ERROR_QUERY_RUNTIME_ERROR, TRI_ObjectToString(tryCatch.Exception()).c_str());
|
||||||
|
v8::Handle<v8::Object> errorObject = CreateErrorObjectAhuacatl(&context->_error);
|
||||||
|
|
||||||
|
return scope.Close(errorObject);
|
||||||
|
}
|
||||||
|
|
||||||
return scope.Close(v8::ThrowException(v8::String::New("cannot create cursor")));
|
return scope.Close(v8::ThrowException(v8::String::New("cannot create cursor")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6384,21 +6398,6 @@ void TRI_InitV8VocBridge (v8::Handle<v8::Context> context, TRI_vocbase_t* vocbas
|
||||||
v8g->ToKey = v8::Persistent<v8::String>::New(v8::String::New("_to"));
|
v8g->ToKey = v8::Persistent<v8::String>::New(v8::String::New("_to"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// .............................................................................
|
|
||||||
// generate the query error template
|
|
||||||
// .............................................................................
|
|
||||||
|
|
||||||
ft = v8::FunctionTemplate::New();
|
|
||||||
ft->SetClassName(v8::String::New("AvocadoError"));
|
|
||||||
|
|
||||||
rt = ft->InstanceTemplate();
|
|
||||||
|
|
||||||
v8g->ErrorTempl = v8::Persistent<v8::ObjectTemplate>::New(rt);
|
|
||||||
|
|
||||||
// must come after SetInternalFieldCount
|
|
||||||
context->Global()->Set(v8::String::New("AvocadoError"),
|
|
||||||
ft->GetFunction());
|
|
||||||
|
|
||||||
// .............................................................................
|
// .............................................................................
|
||||||
// generate the TRI_vocbase_t template
|
// generate the TRI_vocbase_t template
|
||||||
// .............................................................................
|
// .............................................................................
|
||||||
|
|
|
@ -59,7 +59,7 @@ ModuleCache["/internal"].exports.errors = {
|
||||||
"ERROR_AVOCADO_CAP_CONSTRAINT_ALREADY_DEFINED" : { "code" : 1215, "message" : "cap constraint already defined" },
|
"ERROR_AVOCADO_CAP_CONSTRAINT_ALREADY_DEFINED" : { "code" : 1215, "message" : "cap constraint already defined" },
|
||||||
"ERROR_AVOCADO_DATAFILE_FULL" : { "code" : 1300, "message" : "datafile full" },
|
"ERROR_AVOCADO_DATAFILE_FULL" : { "code" : 1300, "message" : "datafile full" },
|
||||||
"ERROR_QUERY_KILLED" : { "code" : 1500, "message" : "query killed" },
|
"ERROR_QUERY_KILLED" : { "code" : 1500, "message" : "query killed" },
|
||||||
"ERROR_QUERY_PARSE" : { "code" : 1501, "message" : "parse error: %s" },
|
"ERROR_QUERY_PARSE" : { "code" : 1501, "message" : "%s" },
|
||||||
"ERROR_QUERY_EMPTY" : { "code" : 1502, "message" : "query is empty" },
|
"ERROR_QUERY_EMPTY" : { "code" : 1502, "message" : "query is empty" },
|
||||||
"ERROR_QUERY_SPECIFICATION_INVALID" : { "code" : 1503, "message" : "query specification invalid" },
|
"ERROR_QUERY_SPECIFICATION_INVALID" : { "code" : 1503, "message" : "query specification invalid" },
|
||||||
"ERROR_QUERY_NUMBER_OUT_OF_RANGE" : { "code" : 1504, "message" : "number '%s' is out of range" },
|
"ERROR_QUERY_NUMBER_OUT_OF_RANGE" : { "code" : 1504, "message" : "number '%s' is out of range" },
|
||||||
|
@ -77,7 +77,7 @@ ModuleCache["/internal"].exports.errors = {
|
||||||
"ERROR_QUERY_BIND_PARAMETER_VALUE_INVALID" : { "code" : 1516, "message" : "invalid value for bind parameter '%s'" },
|
"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_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_FUNCTION_NAME_UNKNOWN" : { "code" : 1518, "message" : "usage of unknown function '%s'" },
|
||||||
"ERROR_QUERY_RUNTIME_ERROR" : { "code" : 1520, "message" : "runtime error in query" },
|
"ERROR_QUERY_RUNTIME_ERROR" : { "code" : 1520, "message" : "runtime error '%s'" },
|
||||||
"ERROR_QUERY_LIMIT_VALUE_OUT_OF_RANGE" : { "code" : 1521, "message" : "limit value '%s' is out of range" },
|
"ERROR_QUERY_LIMIT_VALUE_OUT_OF_RANGE" : { "code" : 1521, "message" : "limit value '%s' is out of range" },
|
||||||
"ERROR_QUERY_VARIABLE_REDECLARED" : { "code" : 1522, "message" : "variable '%s' is assigned multiple times" },
|
"ERROR_QUERY_VARIABLE_REDECLARED" : { "code" : 1522, "message" : "variable '%s' is assigned multiple times" },
|
||||||
"ERROR_QUERY_DOCUMENT_ATTRIBUTE_REDECLARED" : { "code" : 1523, "message" : "document attribute '%s' is assigned multiple times" },
|
"ERROR_QUERY_DOCUMENT_ATTRIBUTE_REDECLARED" : { "code" : 1523, "message" : "document attribute '%s' is assigned multiple times" },
|
||||||
|
|
|
@ -60,7 +60,7 @@ static string JS_common_bootstrap_errors =
|
||||||
" \"ERROR_AVOCADO_CAP_CONSTRAINT_ALREADY_DEFINED\" : { \"code\" : 1215, \"message\" : \"cap constraint already defined\" }, \n"
|
" \"ERROR_AVOCADO_CAP_CONSTRAINT_ALREADY_DEFINED\" : { \"code\" : 1215, \"message\" : \"cap constraint already defined\" }, \n"
|
||||||
" \"ERROR_AVOCADO_DATAFILE_FULL\" : { \"code\" : 1300, \"message\" : \"datafile full\" }, \n"
|
" \"ERROR_AVOCADO_DATAFILE_FULL\" : { \"code\" : 1300, \"message\" : \"datafile full\" }, \n"
|
||||||
" \"ERROR_QUERY_KILLED\" : { \"code\" : 1500, \"message\" : \"query killed\" }, \n"
|
" \"ERROR_QUERY_KILLED\" : { \"code\" : 1500, \"message\" : \"query killed\" }, \n"
|
||||||
" \"ERROR_QUERY_PARSE\" : { \"code\" : 1501, \"message\" : \"parse error: %s\" }, \n"
|
" \"ERROR_QUERY_PARSE\" : { \"code\" : 1501, \"message\" : \"%s\" }, \n"
|
||||||
" \"ERROR_QUERY_EMPTY\" : { \"code\" : 1502, \"message\" : \"query is empty\" }, \n"
|
" \"ERROR_QUERY_EMPTY\" : { \"code\" : 1502, \"message\" : \"query is empty\" }, \n"
|
||||||
" \"ERROR_QUERY_SPECIFICATION_INVALID\" : { \"code\" : 1503, \"message\" : \"query specification invalid\" }, \n"
|
" \"ERROR_QUERY_SPECIFICATION_INVALID\" : { \"code\" : 1503, \"message\" : \"query specification invalid\" }, \n"
|
||||||
" \"ERROR_QUERY_NUMBER_OUT_OF_RANGE\" : { \"code\" : 1504, \"message\" : \"number '%s' is out of range\" }, \n"
|
" \"ERROR_QUERY_NUMBER_OUT_OF_RANGE\" : { \"code\" : 1504, \"message\" : \"number '%s' is out of range\" }, \n"
|
||||||
|
@ -78,7 +78,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_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_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_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_RUNTIME_ERROR\" : { \"code\" : 1520, \"message\" : \"runtime error '%s'\" }, \n"
|
||||||
" \"ERROR_QUERY_LIMIT_VALUE_OUT_OF_RANGE\" : { \"code\" : 1521, \"message\" : \"limit value '%s' is out of range\" }, \n"
|
" \"ERROR_QUERY_LIMIT_VALUE_OUT_OF_RANGE\" : { \"code\" : 1521, \"message\" : \"limit value '%s' is out of range\" }, \n"
|
||||||
" \"ERROR_QUERY_VARIABLE_REDECLARED\" : { \"code\" : 1522, \"message\" : \"variable '%s' is assigned multiple times\" }, \n"
|
" \"ERROR_QUERY_VARIABLE_REDECLARED\" : { \"code\" : 1522, \"message\" : \"variable '%s' is assigned multiple times\" }, \n"
|
||||||
" \"ERROR_QUERY_DOCUMENT_ATTRIBUTE_REDECLARED\" : { \"code\" : 1523, \"message\" : \"document attribute '%s' is assigned multiple times\" }, \n"
|
" \"ERROR_QUERY_DOCUMENT_ATTRIBUTE_REDECLARED\" : { \"code\" : 1523, \"message\" : \"document attribute '%s' is assigned multiple times\" }, \n"
|
||||||
|
|
Loading…
Reference in New Issue