1
0
Fork 0

Merge branch 'devel' of github.com:triAGENS/AvocadoDB

Conflicts:
	V8/v8-c-utils.h
	V8/v8-utils.cpp
	V8/v8-vocbase.cpp
This commit is contained in:
Frank Celler 2012-05-02 13:59:14 +02:00
commit f9291ee25b
26 changed files with 754 additions and 1497 deletions

View File

@ -946,7 +946,7 @@ TRI_aql_node_t* TRI_CreateNodeFcallAql (TRI_aql_context_t* const context,
}
ADD_MEMBER(parameters)
TRI_AQL_NODE_STRING(node) = function->_internalName;
TRI_AQL_NODE_DATA(node) = function;
}
return node;

View File

@ -36,109 +36,6 @@
/// @{
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @brief create a value node from a bind parameter
////////////////////////////////////////////////////////////////////////////////
static TRI_aql_node_t* CreateNodeFromJson (TRI_aql_context_t* const context,
TRI_json_t* json) {
TRI_aql_node_t* node = NULL;
switch (json->_type) {
case TRI_JSON_UNUSED:
break;
case TRI_JSON_NULL:
node = TRI_CreateNodeValueNullAql(context);
break;
case TRI_JSON_BOOLEAN:
node = TRI_CreateNodeValueBoolAql(context, json->_value._boolean);
break;
case TRI_JSON_NUMBER:
node = TRI_CreateNodeValueDoubleAql(context, json->_value._number);
break;
case TRI_JSON_STRING:
node = TRI_CreateNodeValueStringAql(context, json->_value._string.data);
break;
case TRI_JSON_LIST: {
size_t i;
size_t n;
node = TRI_CreateNodeListAql(context);
n = json->_value._objects._length;
for (i = 0; i < n; ++i) {
TRI_json_t* subJson;
TRI_aql_node_t* member;
subJson = (TRI_json_t*) TRI_AtVector(&json->_value._objects, i);
assert(subJson);
member = CreateNodeFromJson(context, subJson);
if (member) {
TRI_PushBackVectorPointer(&node->_members, (void*) member);
}
else {
TRI_SetErrorContextAql(context, TRI_ERROR_OUT_OF_MEMORY, NULL);
return NULL;
}
}
break;
}
case TRI_JSON_ARRAY: {
size_t i;
size_t n;
node = TRI_CreateNodeArrayAql(context);
n = json->_value._objects._length;
for (i = 0; i < n; i += 2) {
TRI_json_t* nameJson;
TRI_json_t* valueJson;
TRI_aql_node_t* member;
TRI_aql_node_t* valueNode;
char* name;
// json_t containing the array element name
nameJson = (TRI_json_t*) TRI_AtVector(&json->_value._objects, i);
assert(nameJson);
name = nameJson->_value._string.data;
assert(name);
// json_t containing the array element value
valueJson = (TRI_json_t*) TRI_AtVector(&json->_value._objects, i + 1);
assert(valueJson);
valueNode = CreateNodeFromJson(context, valueJson);
if (!valueNode) {
TRI_SetErrorContextAql(context, TRI_ERROR_OUT_OF_MEMORY, NULL);
return NULL;
}
member = TRI_CreateNodeArrayElementAql(context, name, valueNode);
if (member) {
TRI_PushBackVectorPointer(&node->_members, (void*) member);
}
else {
TRI_SetErrorContextAql(context, TRI_ERROR_OUT_OF_MEMORY, NULL);
return NULL;
}
}
break;
}
}
if (!node) {
TRI_SetErrorContextAql(context, TRI_ERROR_OUT_OF_MEMORY, NULL);
}
return node;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief check if a node is a bind parameter and convert it into a value node
@ -167,7 +64,7 @@ static TRI_aql_node_t* ModifyNode (void* data,
bind = (TRI_aql_bind_parameter_t*) TRI_LookupByKeyAssociativePointer(bindValues, name);
if (bind) {
node = CreateNodeFromJson(context, bind->_value);
node = TRI_JsonNodeAql(context, bind->_value);
}
return node;

View File

@ -37,6 +37,7 @@
#include "Ahuacatl/ahuacatl-ast-node.h"
#include "Ahuacatl/ahuacatl-context.h"
#include "Ahuacatl/ahuacatl-conversions.h"
#include "Ahuacatl/ahuacatl-tree-walker.h"
#ifdef __cplusplus

View File

@ -28,6 +28,7 @@
#include <BasicsC/logging.h>
#include "Ahuacatl/ahuacatl-codegen-js.h"
#include "Ahuacatl/ahuacatl-functions.h"
// -----------------------------------------------------------------------------
// --SECTION-- private functions
@ -108,11 +109,6 @@ static void AppendInt (TRI_aql_codegen_js_t* const generator,
TRI_AppendInt64StringBuffer(GetBuffer(generator), value);
}
static void AppendDouble (TRI_aql_codegen_js_t* const generator,
const double value) {
TRI_AppendDoubleStringBuffer(GetBuffer(generator), value);
}
static void AppendQuoted (TRI_aql_codegen_js_t* const generator,
const char* name) {
if (!name) {
@ -298,38 +294,8 @@ static size_t HandleSortNode (TRI_aql_codegen_js_t* const generator,
static void HandleValue (TRI_aql_codegen_js_t* const generator,
const TRI_aql_node_t* const node) {
switch (node->_value._type) {
case AQL_TYPE_FAIL:
AppendString(generator, "fail");
break;
case AQL_TYPE_NULL:
AppendString(generator, "null");
break;
case AQL_TYPE_BOOL:
AppendString(generator, node->_value._value._bool ? "true" : "false");
break;
case AQL_TYPE_INT:
AppendInt(generator, node->_value._value._int);
break;
case AQL_TYPE_DOUBLE:
AppendDouble(generator, node->_value._value._double);
break;
case AQL_TYPE_STRING: {
char* escapedString;
size_t outLength;
AppendString(generator, "'");
escapedString = TRI_EscapeUtf8String(node->_value._value._string, strlen(node->_value._value._string), false, &outLength);
if (escapedString) {
AppendString(generator, escapedString);
TRI_Free(TRI_UNKNOWN_MEM_ZONE, escapedString);
}
else {
generator->_error = true;
}
AppendString(generator, "'");
break;
}
if (!TRI_ValueJavascriptAql(GetBuffer(generator), &node->_value, node->_value._type)) {
generator->_error = true;
}
}
@ -360,12 +326,12 @@ static void HandleArray (TRI_aql_codegen_js_t* const generator,
}
DumpNode(generator, TRI_AQL_NODE_MEMBER(node, i));
}
AppendString(generator, " }");
AppendString(generator, " }");
}
static void HandleArrayElement (TRI_aql_codegen_js_t* const generator,
const TRI_aql_node_t* const node) {
AppendQuoted(generator, TRI_AQL_NODE_STRING(node));
TRI_ValueJavascriptAql(GetBuffer(generator), &node->_value, AQL_TYPE_STRING);
AppendString(generator, " : ");
DumpNode(generator, TRI_AQL_NODE_MEMBER(node, 0));
}
@ -601,7 +567,7 @@ static void HandleBinaryIn (TRI_aql_codegen_js_t* const generator,
static void HandleFcall (TRI_aql_codegen_js_t* const generator,
const TRI_aql_node_t* const node) {
AppendString(generator, "AHUACATL_FCALL(");
AppendString(generator, TRI_AQL_NODE_STRING(node));
AppendString(generator, TRI_GetInternalNameFunctionAql((TRI_aql_function_t*) TRI_AQL_NODE_DATA(node)));
AppendString(generator, ", ");
DumpNode(generator, TRI_AQL_NODE_MEMBER(node, 0));
AppendString(generator, ")");
@ -683,7 +649,7 @@ static void HandleLimit (TRI_aql_codegen_js_t* const generator,
size_t r2 = NextRegister(generator);
size_t funcIndex;
AppendString(generator, "result.push($);\n");
AppendString(generator, "result.push(AHUACATL_CLONE($));\n");
CloseForLoops(generator);
AppendString(generator, "result = AHUACATL_LIMIT(result, ");
DumpNode(generator, TRI_AQL_NODE_MEMBER(node, 0));
@ -931,7 +897,7 @@ static void DumpNode (TRI_aql_codegen_js_t* generator, const TRI_aql_node_t* con
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- public functions
// --SECTION-- constructors / destructors
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
@ -939,12 +905,20 @@ static void DumpNode (TRI_aql_codegen_js_t* generator, const TRI_aql_node_t* con
/// @{
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @brief free memory associated with a code generator
////////////////////////////////////////////////////////////////////////////////
void TRI_FreeGeneratorAql (TRI_aql_codegen_js_t* const generator) {
TRI_DestroyVectorPointer(&generator->_functions);
TRI_DestroyStringBuffer(&generator->_buffer);
TRI_Free(TRI_UNKNOWN_MEM_ZONE, generator);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief create a code generator
////////////////////////////////////////////////////////////////////////////////
TRI_aql_codegen_js_t* TRI_CreateGeneratorAql (void) {
TRI_aql_codegen_js_t* generator;
@ -962,6 +936,18 @@ TRI_aql_codegen_js_t* TRI_CreateGeneratorAql (void) {
return generator;
}
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- public functions
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup Ahuacatl
/// @{
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @brief generate Javascript code for the AST nodes recursively
@ -986,7 +972,7 @@ TRI_aql_codegen_js_t* TRI_GenerateCodeAql (const void* const data) {
TRI_AppendInt64StringBuffer(&generator->_buffer, (int64_t) funcIndex);
TRI_AppendStringStringBuffer(&generator->_buffer, "({ });");
//printf("GENERATED CODE:\n%s\n\n", generator->_buffer._buffer);
LOG_DEBUG("generated code: %s", generator->_buffer._buffer);
return generator;
}

View File

@ -33,9 +33,9 @@
#include <BasicsC/string-buffer.h>
#include <BasicsC/vector.h>
#include <BasicsC/conversions.h>
#include <BasicsC/associative.h>
#include "Ahuacatl/ahuacatl-ast-node.h"
#include "Ahuacatl/ahuacatl-conversions.h"
#ifdef __cplusplus
extern "C" {
@ -50,12 +50,20 @@ extern "C" {
/// @{
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @brief internal function types
////////////////////////////////////////////////////////////////////////////////
typedef enum {
AQL_FUNCTION_STANDALONE,
AQL_FUNCTION_COMPARE
}
TRI_aql_codegen_function_type_e;
////////////////////////////////////////////////////////////////////////////////
/// @brief code generator internal function struct
////////////////////////////////////////////////////////////////////////////////
typedef struct TRI_aql_codegen_function_s {
TRI_string_buffer_t _buffer;
size_t _index;
@ -65,6 +73,10 @@ typedef struct TRI_aql_codegen_function_s {
TRI_aql_codegen_function_t;
////////////////////////////////////////////////////////////////////////////////
/// @brief code generator struct
////////////////////////////////////////////////////////////////////////////////
typedef struct TRI_aql_codegen_js_s {
TRI_string_buffer_t _buffer;
TRI_vector_pointer_t _functions;
@ -79,7 +91,7 @@ TRI_aql_codegen_js_t;
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- public functions
// --SECTION-- constructors / destructors
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
@ -87,10 +99,31 @@ TRI_aql_codegen_js_t;
/// @{
////////////////////////////////////////////////////////////////////////////////
TRI_aql_codegen_js_t* TRI_CreateGeneratorAql (void);
////////////////////////////////////////////////////////////////////////////////
/// @brief free memory associated with a code generator
////////////////////////////////////////////////////////////////////////////////
void TRI_FreeGeneratorAql (TRI_aql_codegen_js_t* const);
////////////////////////////////////////////////////////////////////////////////
/// @brief create a code generator
////////////////////////////////////////////////////////////////////////////////
TRI_aql_codegen_js_t* TRI_CreateGeneratorAql (void);
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- public functions
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup Ahuacatl
/// @{
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @brief generate Javascript code for the AST nodes recursively
////////////////////////////////////////////////////////////////////////////////

View File

@ -26,6 +26,10 @@
////////////////////////////////////////////////////////////////////////////////
#include "Ahuacatl/ahuacatl-constant-folder.h"
#include "Ahuacatl/ahuacatl-conversions.h"
#include "Ahuacatl/ahuacatl-functions.h"
#include "V8/v8-execution.h"
// -----------------------------------------------------------------------------
// --SECTION-- private functions
@ -36,6 +40,119 @@
/// @{
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @brief create code for a function call
////////////////////////////////////////////////////////////////////////////////
static TRI_string_buffer_t* FcallCode(const char* const name,
const TRI_aql_node_t* const args) {
TRI_string_buffer_t* buffer = TRI_CreateStringBuffer(TRI_UNKNOWN_MEM_ZONE);
size_t i;
size_t n;
if (!buffer) {
return NULL;
}
if (TRI_AppendStringStringBuffer(buffer, "(function(){return ") != 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_AppendCharStringBuffer(buffer, '(') != TRI_ERROR_NO_ERROR) {
TRI_FreeStringBuffer(TRI_UNKNOWN_MEM_ZONE, buffer);
return NULL;
}
n = args->_members._length;
for (i = 0; i < n; ++i) {
TRI_aql_node_t* arg = (TRI_aql_node_t*) args->_members._buffer[i];
if (i > 0) {
if (TRI_AppendCharStringBuffer(buffer, ',') != TRI_ERROR_NO_ERROR) {
TRI_FreeStringBuffer(TRI_UNKNOWN_MEM_ZONE, buffer);
return NULL;
}
}
if (!TRI_NodeJavascriptAql(buffer, arg)) {
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 optimise a function call
////////////////////////////////////////////////////////////////////////////////
static TRI_aql_node_t* OptimiseFcall (TRI_aql_context_t* const context,
TRI_aql_node_t* node) {
TRI_aql_node_t* args = (TRI_aql_node_t*) node->_members._buffer[0];
TRI_aql_function_t* function;
TRI_js_exec_context_t* execContext;
TRI_string_buffer_t* code;
TRI_json_t* json;
size_t i;
size_t n;
function = (TRI_aql_function_t*) TRI_AQL_NODE_DATA(node);
assert(function);
// check if function is deterministic
if (!function->_isDeterministic) {
return node;
}
// check if function call arguments are deterministic
n = args->_members._length;
for (i = 0; i < n; ++i) {
TRI_aql_node_t* arg = (TRI_aql_node_t*) args->_members._buffer[i];
if (!arg || !TRI_IsConstantValueNodeAql(arg)) {
return node;
}
}
// all arguments are constants
code = FcallCode(function->_internalName, args);
if (!code) {
TRI_SetErrorContextAql(context, TRI_ERROR_OUT_OF_MEMORY, NULL);
return node;
}
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);
if (!json) {
TRI_FreeExecutionContext(execContext);
return NULL;
}
node = TRI_JsonNodeAql(context, json);
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, json);
return node;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief optimise an arithmetic operation with one operand
////////////////////////////////////////////////////////////////////////////////
@ -54,7 +171,6 @@ static TRI_aql_node_t* OptimiseUnaryArithmeticOperation (TRI_aql_context_t* cons
return node;
}
assert(node->_type == AQL_NODE_OPERATOR_UNARY_PLUS ||
node->_type == AQL_NODE_OPERATOR_UNARY_MINUS);
@ -276,6 +392,8 @@ static TRI_aql_node_t* ModifyNode (void* data, TRI_aql_node_t* node) {
case AQL_NODE_OPERATOR_BINARY_DIV:
case AQL_NODE_OPERATOR_BINARY_MOD:
return OptimiseBinaryArithmeticOperation(context, node);
case AQL_NODE_FCALL:
return OptimiseFcall(context, node);
default:
break;
}

View File

@ -271,6 +271,7 @@ bool TRI_OptimiseQueryContextAql (TRI_aql_context_t* const context) {
// constant folding failed
return false;
}
// TRI_DumpTreeAql((TRI_aql_node_t*) context->_first);
return true;
}
@ -295,8 +296,6 @@ bool TRI_LockQueryContextAql (TRI_aql_context_t* const context) {
return false;
}
// TRI_DumpTreeAql((TRI_aql_node_t*) context->_first);
return true;
}
@ -514,15 +513,22 @@ bool TRI_AddVariableContextAql (TRI_aql_context_t* const context, const char* na
char* TRI_RegisterStringAql (TRI_aql_context_t* const context,
const char* const value,
const size_t length) {
const size_t length,
const bool deescape) {
char* copy;
size_t outLength;
if (!value) {
ABORT_OOM
}
copy = TRI_UnescapeUtf8String(value, length, &outLength);
if (deescape) {
size_t outLength;
copy = TRI_UnescapeUtf8String(value, length, &outLength);
}
else {
copy = TRI_DuplicateString(value);
}
if (!copy) {
ABORT_OOM
}

View File

@ -62,7 +62,6 @@ extern "C" {
typedef struct TRI_aql_scope_s {
struct TRI_aql_scope_s* _parent; // parent scope
TRI_associative_pointer_t _variables; // symbol table
// void* _node; // the start node of the scope
void* _first;
void* _last;
}
@ -202,7 +201,8 @@ bool TRI_AddVariableContextAql (TRI_aql_context_t* const, const char*);
char* TRI_RegisterStringAql (TRI_aql_context_t* const,
const char* const,
const size_t);
const size_t,
const bool);
////////////////////////////////////////////////////////////////////////////////
/// @brief checks if a variable is defined in the current scope or above

View File

@ -0,0 +1,273 @@
////////////////////////////////////////////////////////////////////////////////
/// @brief Ahuacatl, conversions
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2010-2012 triagens GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is triAGENS GmbH, Cologne, Germany
///
/// @author Jan Steemann
/// @author Copyright 2012, triagens GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////
#include "Ahuacatl/ahuacatl-conversions.h"
////////////////////////////////////////////////////////////////////////////////
/// @brief append list values to a string buffer
////////////////////////////////////////////////////////////////////////////////
static bool AppendListValues (TRI_string_buffer_t* const buffer,
const TRI_aql_node_t* const node) {
size_t i, n;
n = node->_members._length;
for (i = 0; i < n; ++i) {
if (i > 0) {
if (TRI_AppendCharStringBuffer(buffer, ',') != TRI_ERROR_NO_ERROR) {
return false;
}
}
if (!TRI_NodeJavascriptAql(buffer, TRI_AQL_NODE_MEMBER(node, i))) {
return false;
}
}
return true;
}
// -----------------------------------------------------------------------------
// --SECTION-- public functions
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup Ahuacatl
/// @{
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @brief create a value node from a json struct
////////////////////////////////////////////////////////////////////////////////
TRI_aql_node_t* TRI_JsonNodeAql (TRI_aql_context_t* const context,
const TRI_json_t* const json) {
TRI_aql_node_t* node = NULL;
char* value;
switch (json->_type) {
case TRI_JSON_UNUSED:
break;
case TRI_JSON_NULL:
node = TRI_CreateNodeValueNullAql(context);
break;
case TRI_JSON_BOOLEAN:
node = TRI_CreateNodeValueBoolAql(context, json->_value._boolean);
break;
case TRI_JSON_NUMBER:
node = TRI_CreateNodeValueDoubleAql(context, json->_value._number);
break;
case TRI_JSON_STRING:
value = TRI_RegisterStringAql(context, json->_value._string.data, strlen(json->_value._string.data), false);
node = TRI_CreateNodeValueStringAql(context, value);
break;
case TRI_JSON_LIST: {
size_t i;
size_t n;
node = TRI_CreateNodeListAql(context);
n = json->_value._objects._length;
for (i = 0; i < n; ++i) {
TRI_json_t* subJson;
TRI_aql_node_t* member;
subJson = (TRI_json_t*) TRI_AtVector(&json->_value._objects, i);
assert(subJson);
member = TRI_JsonNodeAql(context, subJson);
if (member) {
TRI_PushBackVectorPointer(&node->_members, (void*) member);
}
else {
TRI_SetErrorContextAql(context, TRI_ERROR_OUT_OF_MEMORY, NULL);
return NULL;
}
}
break;
}
case TRI_JSON_ARRAY: {
size_t i;
size_t n;
node = TRI_CreateNodeArrayAql(context);
n = json->_value._objects._length;
for (i = 0; i < n; i += 2) {
TRI_json_t* nameJson;
TRI_json_t* valueJson;
TRI_aql_node_t* member;
TRI_aql_node_t* valueNode;
char* name;
// json_t containing the array element name
nameJson = (TRI_json_t*) TRI_AtVector(&json->_value._objects, i);
assert(nameJson);
assert(nameJson->_value._string.data);
name = TRI_RegisterStringAql(context, nameJson->_value._string.data, strlen(nameJson->_value._string.data), false);
if (!name) {
TRI_SetErrorContextAql(context, TRI_ERROR_OUT_OF_MEMORY, NULL);
return NULL;
}
// json_t containing the array element value
valueJson = (TRI_json_t*) TRI_AtVector(&json->_value._objects, i + 1);
assert(valueJson);
valueNode = TRI_JsonNodeAql(context, valueJson);
if (!valueNode) {
TRI_SetErrorContextAql(context, TRI_ERROR_OUT_OF_MEMORY, NULL);
return NULL;
}
member = TRI_CreateNodeArrayElementAql(context, name, valueNode);
if (member) {
TRI_PushBackVectorPointer(&node->_members, (void*) member);
}
else {
TRI_SetErrorContextAql(context, TRI_ERROR_OUT_OF_MEMORY, NULL);
return NULL;
}
}
break;
}
}
if (!node) {
TRI_SetErrorContextAql(context, TRI_ERROR_OUT_OF_MEMORY, NULL);
}
return node;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief convert a value node to its Javascript representation
////////////////////////////////////////////////////////////////////////////////
bool TRI_ValueJavascriptAql (TRI_string_buffer_t* const buffer,
const TRI_aql_value_t* const value,
const TRI_aql_value_type_e type) {
switch (type) {
case AQL_TYPE_FAIL:
return (TRI_AppendStringStringBuffer(buffer, "fail") == TRI_ERROR_NO_ERROR);
case AQL_TYPE_NULL:
return (TRI_AppendStringStringBuffer(buffer, "null") == TRI_ERROR_NO_ERROR);
case AQL_TYPE_BOOL:
return (TRI_AppendStringStringBuffer(buffer, value->_value._bool ? "true" : "false") == TRI_ERROR_NO_ERROR);
case AQL_TYPE_INT:
return (TRI_AppendInt64StringBuffer(buffer, value->_value._int) == TRI_ERROR_NO_ERROR);
case AQL_TYPE_DOUBLE:
return (TRI_AppendDoubleStringBuffer(buffer, value->_value._double) == TRI_ERROR_NO_ERROR);
case AQL_TYPE_STRING: {
char* escapedString;
size_t outLength;
if (TRI_AppendCharStringBuffer(buffer, '"') != TRI_ERROR_NO_ERROR) {
return false;
}
escapedString = TRI_EscapeUtf8String(value->_value._string, strlen(value->_value._string), false, &outLength);
if (!escapedString) {
return false;
}
if (TRI_AppendStringStringBuffer(buffer, escapedString) != TRI_ERROR_NO_ERROR) {
TRI_Free(TRI_UNKNOWN_MEM_ZONE, escapedString);
return false;
}
TRI_Free(TRI_UNKNOWN_MEM_ZONE, escapedString);
return (TRI_AppendCharStringBuffer(buffer, '"') == TRI_ERROR_NO_ERROR);
}
}
return false;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief convert a node to its Javascript representation
////////////////////////////////////////////////////////////////////////////////
bool TRI_NodeJavascriptAql (TRI_string_buffer_t* const buffer,
const TRI_aql_node_t* const node) {
switch (node->_type) {
case AQL_NODE_VALUE:
return TRI_ValueJavascriptAql(buffer, &node->_value, node->_value._type);
case AQL_NODE_ARRAY_ELEMENT:
if (!TRI_ValueJavascriptAql(buffer, &node->_value, AQL_TYPE_STRING)) {
return false;
}
if (TRI_AppendCharStringBuffer(buffer, ':') != TRI_ERROR_NO_ERROR) {
return false;
}
return TRI_NodeJavascriptAql(buffer, TRI_AQL_NODE_MEMBER(node, 0));
case AQL_NODE_LIST:
if (TRI_AppendCharStringBuffer(buffer, '[') != TRI_ERROR_NO_ERROR) {
return false;
}
if (!AppendListValues(buffer, node)) {
return false;
}
return (TRI_AppendCharStringBuffer(buffer, ']') == TRI_ERROR_NO_ERROR);
case AQL_NODE_ARRAY:
if (TRI_AppendCharStringBuffer(buffer, '{') != TRI_ERROR_NO_ERROR) {
return false;
}
if (!AppendListValues(buffer, node)) {
return false;
}
return (TRI_AppendCharStringBuffer(buffer, '}') == TRI_ERROR_NO_ERROR);
default:
return false;
}
}
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// Local Variables:
// mode: outline-minor
// outline-regexp: "^\\(/// @brief\\|/// {@inheritDoc}\\|/// @addtogroup\\|// --SECTION--\\|/// @\\}\\)"
// End:

View File

@ -1,5 +1,5 @@
////////////////////////////////////////////////////////////////////////////////
/// @brief Ahuacatl, AST to JS code generator
/// @brief Ahuacatl, conversions
///
/// @file
///
@ -25,15 +25,13 @@
/// @author Copyright 2012, triagens GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////
#ifndef TRIAGENS_DURHAM_AHUACATL_AST_CODEGEN_JS_H
#define TRIAGENS_DURHAM_AHUACATL_AST_CODEGEN_JS_H 1
#ifndef TRIAGENS_DURHAM_AHUACATL_CONVERSIONS_H
#define TRIAGENS_DURHAM_AHUACATL_CONVERSIONS_H 1
#include <BasicsC/common.h>
#include <BasicsC/strings.h>
#include <BasicsC/string-buffer.h>
#include <BasicsC/vector.h>
#include <BasicsC/conversions.h>
#include <BasicsC/associative.h>
#include <BasicsC/json.h>
#include <BasicsC/string-buffer.h>
#include "Ahuacatl/ahuacatl-ast-node.h"
@ -41,58 +39,6 @@
extern "C" {
#endif
// -----------------------------------------------------------------------------
// --SECTION-- public types
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup Ahuacatl
/// @{
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @brief enumeration of scope types
////////////////////////////////////////////////////////////////////////////////
typedef enum {
AQL_CODE_SCOPE_STANDALONE = 0,
AQL_CODE_SCOPE_RESULT = 1,
AQL_CODE_SCOPE_COMPARE = 2
}
TRI_aql_code_scope_type_e;
////////////////////////////////////////////////////////////////////////////////
/// @brief a function scope created by the code generator
////////////////////////////////////////////////////////////////////////////////
typedef struct TRI_aql_codegen_scope_s {
TRI_aql_code_scope_type_e _type;
TRI_string_buffer_t* _buffer;
char* _funcName;
char* _variablePrefix;
size_t _forLoops;
size_t _indent;
}
TRI_aql_codegen_scope_t;
////////////////////////////////////////////////////////////////////////////////
/// @brief the code generator
////////////////////////////////////////////////////////////////////////////////
typedef struct TRI_aql_codegen_s {
TRI_string_buffer_t _buffer;
TRI_vector_pointer_t _scopes;
size_t _funcIndex;
bool _error;
char* _funcName;
TRI_vector_pointer_t _strings;
}
TRI_aql_codegen_t;
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- public functions
// -----------------------------------------------------------------------------
@ -103,22 +49,26 @@ TRI_aql_codegen_t;
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @brief create a code generator
/// @brief create a value node from a json struct
////////////////////////////////////////////////////////////////////////////////
TRI_aql_codegen_t* TRI_CreateCodegenAql (void);
TRI_aql_node_t* TRI_JsonNodeAql (TRI_aql_context_t* const,
const TRI_json_t* const);
////////////////////////////////////////////////////////////////////////////////
/// @brief free the code generator
/// @brief convert a value node to its Javascript representation
////////////////////////////////////////////////////////////////////////////////
void TRI_FreeCodegenAql (TRI_aql_codegen_t* const);
bool TRI_ValueJavascriptAql (TRI_string_buffer_t* const,
const TRI_aql_value_t* const,
const TRI_aql_value_type_e);
////////////////////////////////////////////////////////////////////////////////
/// @brief generate Javascript code for the AST nodes recursively
/// @brief convert a node to its Javascript representation
////////////////////////////////////////////////////////////////////////////////
char* TRI_GenerateCodeAql (const void* const);
bool TRI_NodeJavascriptAql (TRI_string_buffer_t* const,
const TRI_aql_node_t* const);
////////////////////////////////////////////////////////////////////////////////
/// @}

View File

@ -169,6 +169,20 @@ void TRI_FreeFunctionsAql (TRI_associative_pointer_t* functions) {
TRI_Free(TRI_UNKNOWN_MEM_ZONE, functions);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief return a pointer to a function by name
////////////////////////////////////////////////////////////////////////////////
TRI_aql_function_t* TRI_GetFunctionAql (TRI_associative_pointer_t* functions,
const char* const internalName) {
TRI_aql_function_t* function;
function = (TRI_aql_function_t*) TRI_LookupByKeyAssociativePointer(functions, (void*) internalName);
assert(function);
return function;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief check if a function name is valid
////////////////////////////////////////////////////////////////////////////////
@ -186,16 +200,7 @@ bool TRI_IsValidFunctionAql (TRI_associative_pointer_t* functions,
/// @brief get internal function name for an external one
////////////////////////////////////////////////////////////////////////////////
char* TRI_GetInternalNameFunctionAql (TRI_associative_pointer_t* functions,
const char* const externalName) {
TRI_aql_function_t* function;
function = (TRI_aql_function_t*) TRI_LookupByKeyAssociativePointer(functions, externalName);
if (!function) {
return NULL;
}
const char* TRI_GetInternalNameFunctionAql (const TRI_aql_function_t* const function) {
return function->_internalName;
}
@ -233,6 +238,7 @@ bool TRI_RegisterFunctionAql (TRI_associative_pointer_t* functions,
function->_minArgs = minArgs;
function->_maxArgs = maxArgs;
function->_isDeterministic = isDeterministic;
if (TRI_InsertKeyAssociativePointer(functions, externalName, function, false)) {
// function already registered

View File

@ -67,6 +67,13 @@ TRI_associative_pointer_t* TRI_InitialiseFunctionsAql (void);
void TRI_FreeFunctionsAql (TRI_associative_pointer_t*);
////////////////////////////////////////////////////////////////////////////////
/// @brief return a pointer to a function by name
////////////////////////////////////////////////////////////////////////////////
TRI_aql_function_t* TRI_GetFunctionAql (TRI_associative_pointer_t*,
const char*);
////////////////////////////////////////////////////////////////////////////////
/// @brief check if a function name is valid
////////////////////////////////////////////////////////////////////////////////
@ -77,7 +84,7 @@ bool TRI_IsValidFunctionAql (TRI_associative_pointer_t*, const char* const);
/// @brief get internal function name for an external one
////////////////////////////////////////////////////////////////////////////////
char* TRI_GetInternalNameFunctionAql (TRI_associative_pointer_t*, const char* const);
const char* TRI_GetInternalNameFunctionAql (const TRI_aql_function_t* const);
////////////////////////////////////////////////////////////////////////////////
/// @brief register a function name

View File

@ -1353,7 +1353,7 @@ YY_RULE_SETUP
case 39:
YY_RULE_SETUP
{
yylval->strval = TRI_RegisterStringAql(yyextra, yytext, strlen(yytext));
yylval->strval = TRI_RegisterStringAql(yyextra, yytext, strlen(yytext), false);
return T_STRING;
}
YY_BREAK
@ -1361,7 +1361,7 @@ case 40:
/* rule 40 can match eol */
YY_RULE_SETUP
{
yylval->strval = TRI_RegisterStringAql(yyextra, yytext + 1, strlen(yytext) - 2);
yylval->strval = TRI_RegisterStringAql(yyextra, yytext + 1, strlen(yytext) - 2, true);
return T_STRING;
}
YY_BREAK
@ -1369,7 +1369,7 @@ case 41:
/* rule 41 can match eol */
YY_RULE_SETUP
{
yylval->strval = TRI_RegisterStringAql(yyextra, yytext + 1, strlen(yytext) - 2);
yylval->strval = TRI_RegisterStringAql(yyextra, yytext + 1, strlen(yytext) - 2, true);
return T_QUOTED_STRING;
}
YY_BREAK
@ -1377,14 +1377,14 @@ case 42:
/* rule 42 can match eol */
YY_RULE_SETUP
{
yylval->strval = TRI_RegisterStringAql(yyextra, yytext + 1, strlen(yytext) - 2);
yylval->strval = TRI_RegisterStringAql(yyextra, yytext + 1, strlen(yytext) - 2, true);
return T_QUOTED_STRING;
}
YY_BREAK
case 43:
YY_RULE_SETUP
{
yylval->strval = TRI_RegisterStringAql(yyextra, yytext, strlen(yytext));
yylval->strval = TRI_RegisterStringAql(yyextra, yytext, strlen(yytext), false);
return T_NUMBER;
}
YY_BREAK
@ -1394,7 +1394,7 @@ YY_RULE_SETUP
case 44:
YY_RULE_SETUP
{
yylval->strval = TRI_RegisterStringAql(yyextra, yytext + 1, strlen(yytext) - 1);
yylval->strval = TRI_RegisterStringAql(yyextra, yytext + 1, strlen(yytext) - 1, false);
return T_PARAMETER;
}
YY_BREAK

View File

@ -215,27 +215,27 @@
* --------------------------------------------------------------------------- */
([a-zA-Z][_a-zA-Z0-9]*|_+[a-zA-Z]+[_a-zA-Z0-9]*) {
yylval->strval = TRI_RegisterStringAql(yyextra, yytext, strlen(yytext));
yylval->strval = TRI_RegisterStringAql(yyextra, yytext, strlen(yytext), false);
return T_STRING;
}
`(\\.|[^\\`])*` {
yylval->strval = TRI_RegisterStringAql(yyextra, yytext + 1, strlen(yytext) - 2);
yylval->strval = TRI_RegisterStringAql(yyextra, yytext + 1, strlen(yytext) - 2, true);
return T_STRING;
}
\"(\\.|[^\\\"])*\" {
yylval->strval = TRI_RegisterStringAql(yyextra, yytext + 1, strlen(yytext) - 2);
yylval->strval = TRI_RegisterStringAql(yyextra, yytext + 1, strlen(yytext) - 2, true);
return T_QUOTED_STRING;
}
'(\\.|[^\\'])*' {
yylval->strval = TRI_RegisterStringAql(yyextra, yytext + 1, strlen(yytext) - 2);
yylval->strval = TRI_RegisterStringAql(yyextra, yytext + 1, strlen(yytext) - 2, true);
return T_QUOTED_STRING;
}
(0|[1-9][0-9]*)(\.[0-9]+([eE]([\-\+])?[0-9]+)?)? {
yylval->strval = TRI_RegisterStringAql(yyextra, yytext, strlen(yytext));
yylval->strval = TRI_RegisterStringAql(yyextra, yytext, strlen(yytext), false);
return T_NUMBER;
}
@ -244,7 +244,7 @@
* --------------------------------------------------------------------------- */
@[a-zA-Z][a-zA-Z0-9_]* {
yylval->strval = TRI_RegisterStringAql(yyextra, yytext + 1, strlen(yytext) - 1);
yylval->strval = TRI_RegisterStringAql(yyextra, yytext + 1, strlen(yytext) - 1, false);
return T_PARAMETER;
}

View File

@ -143,9 +143,11 @@ static void DumpNode (void* data, const TRI_aql_node_t* const node) {
case AQL_NODE_PARAMETER:
case AQL_NODE_ARRAY_ELEMENT:
case AQL_NODE_ATTRIBUTE_ACCESS:
case AQL_NODE_FCALL:
DumpString(state, node);
break;
case AQL_NODE_FCALL:
printf("name: %s\n", TRI_GetInternalNameFunctionAql((TRI_aql_function_t*) TRI_AQL_NODE_DATA(node)));
break;
case AQL_NODE_SORT_ELEMENT:
PrintIndent(state);

View File

@ -35,6 +35,7 @@
#include <BasicsC/associative.h>
#include "Ahuacatl/ahuacatl-ast-node.h"
#include "Ahuacatl/ahuacatl-functions.h"
#include "Ahuacatl/ahuacatl-tree-walker.h"
#ifdef __cplusplus

File diff suppressed because it is too large Load Diff

View File

@ -158,6 +158,7 @@ avocado_SOURCES = \
Ahuacatl/ahuacatl-collections.c \
Ahuacatl/ahuacatl-constant-folder.c \
Ahuacatl/ahuacatl-context.c \
Ahuacatl/ahuacatl-conversions.c \
Ahuacatl/ahuacatl-error.c \
Ahuacatl/ahuacatl-functions.c \
Ahuacatl/ahuacatl-grammar.c \

View File

@ -339,6 +339,7 @@ am_avocado_OBJECTS = Admin/ApplicationAdminServer.$(OBJEXT) \
Ahuacatl/ahuacatl-collections.$(OBJEXT) \
Ahuacatl/ahuacatl-constant-folder.$(OBJEXT) \
Ahuacatl/ahuacatl-context.$(OBJEXT) \
Ahuacatl/ahuacatl-conversions.$(OBJEXT) \
Ahuacatl/ahuacatl-error.$(OBJEXT) \
Ahuacatl/ahuacatl-functions.$(OBJEXT) \
Ahuacatl/ahuacatl-grammar.$(OBJEXT) \
@ -773,6 +774,7 @@ avocado_SOURCES = \
Ahuacatl/ahuacatl-collections.c \
Ahuacatl/ahuacatl-constant-folder.c \
Ahuacatl/ahuacatl-context.c \
Ahuacatl/ahuacatl-conversions.c \
Ahuacatl/ahuacatl-error.c \
Ahuacatl/ahuacatl-functions.c \
Ahuacatl/ahuacatl-grammar.c \
@ -1687,6 +1689,8 @@ Ahuacatl/ahuacatl-constant-folder.$(OBJEXT): Ahuacatl/$(am__dirstamp) \
Ahuacatl/$(DEPDIR)/$(am__dirstamp)
Ahuacatl/ahuacatl-context.$(OBJEXT): Ahuacatl/$(am__dirstamp) \
Ahuacatl/$(DEPDIR)/$(am__dirstamp)
Ahuacatl/ahuacatl-conversions.$(OBJEXT): Ahuacatl/$(am__dirstamp) \
Ahuacatl/$(DEPDIR)/$(am__dirstamp)
Ahuacatl/ahuacatl-error.$(OBJEXT): Ahuacatl/$(am__dirstamp) \
Ahuacatl/$(DEPDIR)/$(am__dirstamp)
Ahuacatl/ahuacatl-functions.$(OBJEXT): Ahuacatl/$(am__dirstamp) \
@ -1953,6 +1957,7 @@ mostlyclean-compile:
-rm -f Ahuacatl/ahuacatl-collections.$(OBJEXT)
-rm -f Ahuacatl/ahuacatl-constant-folder.$(OBJEXT)
-rm -f Ahuacatl/ahuacatl-context.$(OBJEXT)
-rm -f Ahuacatl/ahuacatl-conversions.$(OBJEXT)
-rm -f Ahuacatl/ahuacatl-error.$(OBJEXT)
-rm -f Ahuacatl/ahuacatl-functions.$(OBJEXT)
-rm -f Ahuacatl/ahuacatl-grammar.$(OBJEXT)
@ -2193,6 +2198,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@Ahuacatl/$(DEPDIR)/ahuacatl-collections.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@Ahuacatl/$(DEPDIR)/ahuacatl-constant-folder.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@Ahuacatl/$(DEPDIR)/ahuacatl-context.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@Ahuacatl/$(DEPDIR)/ahuacatl-conversions.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@Ahuacatl/$(DEPDIR)/ahuacatl-error.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@Ahuacatl/$(DEPDIR)/ahuacatl-functions.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@Ahuacatl/$(DEPDIR)/ahuacatl-grammar.Po@am__quote@

View File

@ -1553,6 +1553,68 @@ TRI_shaped_json_t* TRI_ShapedJsonV8Object (v8::Handle<v8::Value> object, TRI_sha
return shaped;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief convert a V8 value to a json_t value
////////////////////////////////////////////////////////////////////////////////
TRI_json_t* TRI_ObjectToJson (v8::Handle<v8::Value> parameter) {
if (parameter->IsBoolean()) {
v8::Handle<v8::Boolean> booleanParameter = parameter->ToBoolean();
return TRI_CreateBooleanJson(TRI_UNKNOWN_MEM_ZONE, booleanParameter->Value());
}
if (parameter->IsNull()) {
return TRI_CreateNullJson(TRI_UNKNOWN_MEM_ZONE);
}
if (parameter->IsNumber()) {
v8::Handle<v8::Number> numberParameter = parameter->ToNumber();
return TRI_CreateNumberJson(TRI_UNKNOWN_MEM_ZONE, numberParameter->Value());
}
if (parameter->IsString()) {
v8::Handle<v8::String> stringParameter= parameter->ToString();
v8::String::Utf8Value str(stringParameter);
return TRI_CreateStringCopyJson(TRI_UNKNOWN_MEM_ZONE, *str);
}
if (parameter->IsArray()) {
v8::Handle<v8::Array> arrayParameter = v8::Handle<v8::Array>::Cast(parameter);
TRI_json_t* listJson = TRI_CreateListJson(TRI_UNKNOWN_MEM_ZONE);
if (listJson) {
for (uint32_t j = 0; j < arrayParameter->Length(); ++j) {
v8::Handle<v8::Value> item = arrayParameter->Get(j);
TRI_json_t* result = TRI_ObjectToJson(item);
if (result) {
TRI_PushBack2ListJson(listJson, result);
TRI_Free(TRI_UNKNOWN_MEM_ZONE, result);
}
}
}
return listJson;
}
if (parameter->IsObject()) {
v8::Handle<v8::Array> arrayParameter = v8::Handle<v8::Array>::Cast(parameter);
TRI_json_t* arrayJson = TRI_CreateArrayJson(TRI_UNKNOWN_MEM_ZONE);
if (arrayJson) {
v8::Handle<v8::Array> names = arrayParameter->GetOwnPropertyNames();
for (uint32_t j = 0; j < names->Length(); ++j) {
v8::Handle<v8::Value> key = names->Get(j);
v8::Handle<v8::Value> item = arrayParameter->Get(key);
TRI_json_t* result = TRI_ObjectToJson(item);
if (result) {
TRI_Insert2ArrayJson(TRI_UNKNOWN_MEM_ZONE, arrayJson, TRI_ObjectToString(key).c_str(), result);
TRI_Free(TRI_UNKNOWN_MEM_ZONE, result);
}
}
}
return arrayJson;
}
return NULL;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief converts an V8 object to a string
////////////////////////////////////////////////////////////////////////////////

View File

@ -92,6 +92,12 @@ v8::Handle<v8::Value> TRI_JsonShapeData (TRI_shaper_t*,
TRI_shaped_json_t* TRI_ShapedJsonV8Object (v8::Handle<v8::Value>, TRI_shaper_t*);
////////////////////////////////////////////////////////////////////////////////
/// @brief convert a V8 value to a json_t value
////////////////////////////////////////////////////////////////////////////////
TRI_json_t* TRI_ObjectToJson (v8::Handle<v8::Value>);
////////////////////////////////////////////////////////////////////////////////
/// @brief converts an V8 object to a string
////////////////////////////////////////////////////////////////////////////////

View File

@ -677,6 +677,28 @@ bool TRI_ExecuteOrderExecutionContext (TRI_js_exec_context_t context, int* r) {
return true;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief executes a result context
////////////////////////////////////////////////////////////////////////////////
TRI_json_t* TRI_ExecuteResultContext (TRI_js_exec_context_t context) {
js_exec_context_t* ctx;
ctx = (js_exec_context_t*) context;
// convert back into a handle
v8::Persistent<v8::Function> func = ctx->_func;
// and execute the function
v8::Handle<v8::Value> args[] = { ctx->_arguments };
v8::Handle<v8::Value> result = func->Call(func, 1, args);
if (result.IsEmpty()) {
return NULL;
}
return TRI_ObjectToJson(result);
}
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////

View File

@ -142,6 +142,12 @@ bool TRI_ExecuteRefExecutionContext (TRI_memory_zone_t*,
bool TRI_ExecuteOrderExecutionContext (TRI_js_exec_context_t, int* result);
////////////////////////////////////////////////////////////////////////////////
/// @brief executes a result context
////////////////////////////////////////////////////////////////////////////////
TRI_json_t* TRI_ExecuteResultContext (TRI_js_exec_context_t context);
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////

View File

@ -2831,6 +2831,7 @@ static v8::Handle<v8::Value> JS_RunAhuacatl (v8::Arguments const& argv) {
// bind parameters
TRI_json_t* parameters = 0;
if (argv.Length() > 1) {
parameters = TRI_JsonObject(argv[1]);
}
@ -2874,10 +2875,13 @@ static v8::Handle<v8::Value> JS_RunAhuacatl (v8::Arguments const& argv) {
TRI_FreeGeneratorAql(generator);
TRI_json_t* json = TRI_JsonObject(result);
if (json) {
TRI_general_cursor_result_t* cursorResult = TRI_CreateResultAql(json);
if (cursorResult) {
cursor = TRI_CreateGeneralCursor(cursorResult, doCount, batchSize);
if (!cursor) {
TRI_Free(TRI_UNKNOWN_MEM_ZONE, cursorResult);
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, json);
@ -3079,6 +3083,7 @@ static v8::Handle<v8::Value> JS_WhereHashConstAql (const v8::Arguments& argv) {
for (int j = 1; j < argv.Length(); ++j) {
v8::Handle<v8::Value> parameter = argv[j];
TRI_json_t* jsonParameter = TRI_JsonObject(parameter);
if (jsonParameter == 0) { // NOT the null json value!
return scope.Close(v8::ThrowException(v8::String::New("type value not currently supported for hash index")));
}
@ -3165,6 +3170,7 @@ static v8::Handle<v8::Value> JS_WherePQConstAql (const v8::Arguments& argv) {
for (int j = 1; j < argv.Length(); ++j) {
v8::Handle<v8::Value> parameter = argv[j];
TRI_json_t* jsonParameter = TRI_JsonObject(parameter);
if (jsonParameter == 0) { // NOT the null json value!
return scope.Close(v8::ThrowException(v8::String::New("type value not currently supported for priority queue index")));
}
@ -3279,6 +3285,7 @@ static v8::Handle<v8::Value> JS_WhereSkiplistConstAql (const v8::Arguments& argv
for (int j = 1; j < argv.Length(); ++j) {
v8::Handle<v8::Value> parameter = argv[j];
TRI_json_t* jsonParameter = TRI_JsonObject(parameter);
if (jsonParameter == 0) { // NOT the null json value!
return scope.Close(v8::ThrowException(v8::String::New("type value not currently supported for skiplist index")));
}
@ -3650,6 +3657,7 @@ static TRI_json_t* parametersToJson(v8::Arguments const& argv, int startPos, int
for (int j = startPos; j < endPos; ++j) {
v8::Handle<v8::Value> parameter = argv[j];
TRI_json_t* jsonParameter = TRI_JsonObject(parameter);
if (jsonParameter == 0) { // NOT the null json value!
v8::ThrowException(v8::String::New("type value not currently supported for skiplist index"));
return 0;

View File

@ -144,7 +144,7 @@ function ahuacatlEscapingTestSuite () {
/// @brief test punctuation names escaping
////////////////////////////////////////////////////////////////////////////////
testPunctuationName1 : function () {
testPunctuationBackticks1 : function () {
var expected = [ 1, 2, 3 ];
var actual = getQueryResults("FOR `brown_fox` IN [ 1, 2, 3 ] RETURN `brown_fox`", true);
assertEqual(expected, actual);
@ -154,12 +154,122 @@ function ahuacatlEscapingTestSuite () {
/// @brief test punctuation names escaping
////////////////////////////////////////////////////////////////////////////////
testPunctuationName2 : function () {
testPunctuationBackticks2 : function () {
var expected = [ 1, 2, 3 ];
var actual = getQueryResults("FOR `brown_fox__1234_` IN [ 1, 2, 3 ] RETURN `brown_fox__1234_`", true);
assertEqual(expected, actual);
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test punctuation names escaping
////////////////////////////////////////////////////////////////////////////////
testPunctuationBackticks3 : function () {
var expected = [ 1, 2, 3 ];
var actual = getQueryResults("FOR `brown fox 1234_` IN [ 1, 2, 3 ] RETURN `brown fox 1234_`", true);
assertEqual(expected, actual);
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test punctuation names escaping
////////////////////////////////////////////////////////////////////////////////
testPunctuationBackticks4 : function () {
var expected = [ 1, 3 ];
var actual = getQueryResults("FOR r IN [ { \"a\" : 1, \"b\" : 1 }, { \"a\" : 2, \"b\" : 2 }, { \"a\" : 1, \"b\" : 3 } ] FILTER r.`a` == 1 RETURN r.`b`", true);
assertEqual(expected, actual);
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test punctuation names escaping
////////////////////////////////////////////////////////////////////////////////
testPunctuationBackticks5 : function () {
var expected = [ 1, 3 ];
var actual = getQueryResults("FOR r IN [ { \"a fox\" : 1, \"b fox\" : 1 }, { \"a fox\" : 2, \"b fox\" : 2 }, { \"a fox\" : 1, \"b fox\" : 3 } ] FILTER r.`a fox` == 1 RETURN r.`b fox`", true);
assertEqual(expected, actual);
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test punctuation names escaping
////////////////////////////////////////////////////////////////////////////////
testPunctuationDoubleQuotes1 : function () {
var expected = [ { '"a"' : 1 }, { '"a"' : '"b"' } ];
var actual = getQueryResults("FOR r IN [ { '\"a\"' : 1 }, { '\"a\"' : '\"b\"' } ] RETURN r", true);
assertEqual(expected, actual);
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test punctuation names escaping
////////////////////////////////////////////////////////////////////////////////
testPunctuationDoubleQuotes2 : function () {
var expected = [ { '"a fox"' : 1 }, { '"a fox "' : '"b fox"' } ];
var actual = getQueryResults("FOR r IN [ { '\"a fox\"' : 1 }, { '\"a fox \"' : '\"b fox\"' } ] RETURN r", true);
assertEqual(expected, actual);
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test punctuation names escaping
////////////////////////////////////////////////////////////////////////////////
testPunctuationDoubleQuotes3 : function () {
var expected = [ { '"a" \\ " fox"' : 1 }, { '"a" \\ " fox "' : '"b fox"' } ];
var actual = getQueryResults("FOR r IN [ { '\"a\" \\\\ \\\" fox\"' : 1 }, { '\"a\" \\\\ \\\" fox \"' : '\"b fox\"' } ] RETURN r", true);
assertEqual(expected, actual);
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test punctuation names escaping
////////////////////////////////////////////////////////////////////////////////
testPunctuationSingleQuotes1 : function () {
var expected = [ { "'a'" : 1 }, { "'a'" : "'b'" } ];
var actual = getQueryResults("FOR r IN [ { \"'a'\" : 1 }, { \"'a'\" : \"'b'\" } ] RETURN r", true);
assertEqual(expected, actual);
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test punctuation names escaping
////////////////////////////////////////////////////////////////////////////////
testPunctuationSingleQuotes2 : function () {
var expected = [ { "'a fox'" : 1 }, { "'a fox'" : "'b fox'" } ];
var actual = getQueryResults("FOR r IN [ { \"'a fox'\" : 1 }, { \"'a fox'\" : \"'b fox'\" } ] RETURN r", true);
assertEqual(expected, actual);
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test punctuation names escaping
////////////////////////////////////////////////////////////////////////////////
testPunctuationSingleQuotes3 : function () {
var expected = [ { "'a \\ ' fox'" : 1 }, { "'a \\ ' fox'" : "'b fox'" } ];
var actual = getQueryResults("FOR r IN [ { \"'a \\\\ \\' fox'\" : 1 }, { \"'a \\\\ \\' fox'\" : \"'b fox'\" } ] RETURN r", true);
assertEqual(expected, actual);
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test UTF8 names escaping
////////////////////////////////////////////////////////////////////////////////
testUtf8Names1 : function () {
var expected = [ "wälder", "hänsel", "grätel", "fraß", "kloß" ];
var actual = getQueryResults("FOR r IN [ { \"äöüÄÖÜß\" : \"wälder\" }, { \"äöüÄÖÜß\" : \"hänsel\" }, { \"äöüÄÖÜß\" : \"grätel\" }, { \"äöüÄÖÜß\" : \"fraß\" }, { \"äöüÄÖÜß\" : \"kloß\" } ] RETURN r.`äöüÄÖÜß`", true);
assertEqual(expected, actual);
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test UTF8 names escaping
////////////////////////////////////////////////////////////////////////////////
testUtf8Names2 : function () {
var expected = [ "中央アメリカ", "熱帯", "亜熱帯" ];
var actual = getQueryResults("FOR r IN [ { \"アボカド\" : \"中央アメリカ\" }, { \"アボカド\" : \"熱帯\" }, { \"アボカド\" : \"亜熱帯\" } ] RETURN r.`アボカド`", true);
assertEqual(expected, actual);
},
};
}