mirror of https://gitee.com/bigwinds/arangodb
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:
commit
f9291ee25b
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
|
@ -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);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
@ -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 \
|
||||
|
|
|
@ -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@
|
||||
|
|
|
@ -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
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -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
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -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);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
},
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue