1
0
Fork 0

Merge remote branch 'origin/master' into devel

This commit is contained in:
Frank Celler 2012-04-23 16:45:56 +02:00
commit 458de2acb6
7 changed files with 237 additions and 15 deletions

View File

@ -39,7 +39,7 @@
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @brief register a function name for later disposal
/// @brief register a function name for easier later disposal
////////////////////////////////////////////////////////////////////////////////
static bool RegisterString (TRI_aql_codegen_t* const generator,
@ -51,6 +51,10 @@ static bool RegisterString (TRI_aql_codegen_t* const generator,
return true;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief get a function name using the rule "f" + number
////////////////////////////////////////////////////////////////////////////////
static char* GetIndexedFunctionName (TRI_aql_codegen_t* const generator,
const size_t funcIndex) {
char* numberString;
@ -71,6 +75,11 @@ static char* GetIndexedFunctionName (TRI_aql_codegen_t* const generator,
return functionName;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief get the next function name (using the rule "f" + number, number will
/// be increased on each call)
////////////////////////////////////////////////////////////////////////////////
static char* GetNextFunctionName (TRI_aql_codegen_t* const generator) {
char* functionName;
@ -81,6 +90,10 @@ static char* GetNextFunctionName (TRI_aql_codegen_t* const generator) {
return functionName;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief free a code scope
////////////////////////////////////////////////////////////////////////////////
static void FreeScope (TRI_aql_codegen_scope_t* const scope) {
assert(scope);
@ -93,10 +106,16 @@ static void FreeScope (TRI_aql_codegen_scope_t* const scope) {
TRI_Free(scope);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief create a code scope
////////////////////////////////////////////////////////////////////////////////
static TRI_aql_codegen_scope_t* CreateScope (TRI_aql_codegen_t* const generator,
const char* const funcName,
const TRI_aql_scope_type_e type) {
TRI_aql_codegen_scope_t* scope = (TRI_aql_codegen_scope_t*) TRI_Allocate(sizeof(TRI_aql_codegen_scope_t));
TRI_aql_codegen_scope_t* scope;
scope = (TRI_aql_codegen_scope_t*) TRI_Allocate(sizeof(TRI_aql_codegen_scope_t));
if (!scope) {
return NULL;
@ -123,7 +142,13 @@ static TRI_aql_codegen_scope_t* CreateScope (TRI_aql_codegen_t* const generator,
return scope;
}
static bool StartScope (TRI_aql_codegen_t* const generator, const TRI_aql_scope_type_e type, const char* const funcName) {
////////////////////////////////////////////////////////////////////////////////
/// @brief start a new code scope
////////////////////////////////////////////////////////////////////////////////
static bool StartScope (TRI_aql_codegen_t* const generator,
const TRI_aql_scope_type_e type,
const char* const funcName) {
TRI_aql_codegen_scope_t* scope;
assert(generator);
@ -140,6 +165,10 @@ static bool StartScope (TRI_aql_codegen_t* const generator, const TRI_aql_scope_
return true;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief return the scope currently used
////////////////////////////////////////////////////////////////////////////////
static TRI_aql_codegen_scope_t* GetCurrentScope (TRI_aql_codegen_t* const generator) {
TRI_aql_codegen_scope_t* scope;
size_t length;
@ -155,6 +184,10 @@ static TRI_aql_codegen_scope_t* GetCurrentScope (TRI_aql_codegen_t* const genera
return scope;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief increase the indent level in the current scope
////////////////////////////////////////////////////////////////////////////////
static void Indent (TRI_aql_codegen_t* const generator) {
TRI_aql_codegen_scope_t* scope;
assert(generator);
@ -165,6 +198,10 @@ static void Indent (TRI_aql_codegen_t* const generator) {
scope->_indent++;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief decrease the indent level in the current scope
////////////////////////////////////////////////////////////////////////////////
static void Outdent (TRI_aql_codegen_t* const generator) {
TRI_aql_codegen_scope_t* scope;
assert(generator);
@ -176,6 +213,10 @@ static void Outdent (TRI_aql_codegen_t* const generator) {
--scope->_indent;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief add the current indentation to the output buffer in the current scope
////////////////////////////////////////////////////////////////////////////////
static void AppendIndent (TRI_aql_codegen_t* const generator) {
TRI_aql_codegen_scope_t* scope;
size_t i;
@ -189,6 +230,10 @@ static void AppendIndent (TRI_aql_codegen_t* const generator) {
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief remove the current scope from the stack
////////////////////////////////////////////////////////////////////////////////
static void RemoveCurrentScope (TRI_aql_codegen_t* const generator) {
TRI_aql_codegen_scope_t* scope;
size_t length;
@ -203,6 +248,10 @@ static void RemoveCurrentScope (TRI_aql_codegen_t* const generator) {
FreeScope(scope);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief close all for loops in current scope
////////////////////////////////////////////////////////////////////////////////
static void CloseForLoops (TRI_aql_codegen_t* const generator) {
TRI_aql_codegen_scope_t* scope;
size_t i;
@ -223,7 +272,14 @@ static void CloseForLoops (TRI_aql_codegen_t* const generator) {
}
}
static bool AppendFunction (TRI_aql_codegen_t* const generator, const TRI_aql_scope_type_e type, const char* const name, const char* const body) {
////////////////////////////////////////////////////////////////////////////////
/// @brief write a function definition to the output buffer
////////////////////////////////////////////////////////////////////////////////
static bool AppendFunction (TRI_aql_codegen_t* const generator,
const TRI_aql_scope_type_e type,
const char* const name,
const char* const body) {
assert(generator);
assert(name);
assert(body);
@ -249,6 +305,10 @@ static bool AppendFunction (TRI_aql_codegen_t* const generator, const TRI_aql_sc
return true;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief end a scope. this will also write the scope's function to the
/// output buffer
////////////////////////////////////////////////////////////////////////////////
static char* EndScope (TRI_aql_codegen_t* const generator) {
TRI_aql_codegen_scope_t* scope;
@ -288,6 +348,10 @@ static char* EndScope (TRI_aql_codegen_t* const generator) {
return funcName;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief increase the number of for loops in the current scope by one
////////////////////////////////////////////////////////////////////////////////
static void IncreaseForCount (TRI_aql_codegen_t* const generator) {
TRI_aql_codegen_scope_t* scope;
@ -305,6 +369,10 @@ static void IncreaseForCount (TRI_aql_codegen_t* const generator) {
scope->_forLoops++;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief append code the current scope's output buffer
////////////////////////////////////////////////////////////////////////////////
static void AppendCode (TRI_aql_codegen_t* const generator, const char* const code) {
TRI_aql_codegen_scope_t* scope;
@ -317,7 +385,12 @@ static void AppendCode (TRI_aql_codegen_t* const generator, const char* const co
TRI_AppendStringStringBuffer(scope->_buffer, code);
}
static bool AppendValue (TRI_aql_codegen_t* const generator, const TRI_aql_node_value_t* const node) {
////////////////////////////////////////////////////////////////////////////////
/// @brief append the value of a value node to the current scope's output buffer
////////////////////////////////////////////////////////////////////////////////
static bool AppendValue (TRI_aql_codegen_t* const generator,
const TRI_aql_node_value_t* const node) {
TRI_aql_codegen_scope_t* scope;
assert(generator);
@ -364,7 +437,12 @@ static bool AppendValue (TRI_aql_codegen_t* const generator, const TRI_aql_node_
return true;
}
static void SetVariablePrefix (TRI_aql_codegen_t* const generator, const char* const prefix) {
////////////////////////////////////////////////////////////////////////////////
/// @brief set a variable prefix for all variables to be printed
////////////////////////////////////////////////////////////////////////////////
static void SetVariablePrefix (TRI_aql_codegen_t* const generator,
const char* const prefix) {
TRI_aql_codegen_scope_t* scope;
assert(generator);
@ -376,7 +454,12 @@ static void SetVariablePrefix (TRI_aql_codegen_t* const generator, const char* c
scope->_variablePrefix = (char*) prefix;
}
static bool AppendVarname (TRI_aql_codegen_t* const generator, const TRI_aql_node_t* const data) {
////////////////////////////////////////////////////////////////////////////////
/// @brief print a variable name in the current scope, enclosed in $['...']
////////////////////////////////////////////////////////////////////////////////
static bool AppendVarname (TRI_aql_codegen_t* const generator,
const TRI_aql_node_t* const data) {
TRI_aql_node_variable_t* node = (TRI_aql_node_variable_t*) data;
AppendCode(generator, "$['");
@ -386,7 +469,12 @@ static bool AppendVarname (TRI_aql_codegen_t* const generator, const TRI_aql_nod
return true;
}
static bool AppendVarname0 (TRI_aql_codegen_t* const generator, const TRI_aql_node_t* const data) {
////////////////////////////////////////////////////////////////////////////////
/// @brief print a variable name in the current scope, without modifications
////////////////////////////////////////////////////////////////////////////////
static bool AppendVarname0 (TRI_aql_codegen_t* const generator,
const TRI_aql_node_t* const data) {
TRI_aql_node_variable_t* node = (TRI_aql_node_variable_t*) data;
AppendCode(generator, node->_name);
@ -394,7 +482,12 @@ static bool AppendVarname0 (TRI_aql_codegen_t* const generator, const TRI_aql_no
return true;
}
static bool AppendVarname1 (TRI_aql_codegen_t* const generator, const TRI_aql_node_t* const data) {
////////////////////////////////////////////////////////////////////////////////
/// @brief print a variable name in the current scope, prepended by "_"
////////////////////////////////////////////////////////////////////////////////
static bool AppendVarname1 (TRI_aql_codegen_t* const generator,
const TRI_aql_node_t* const data) {
TRI_aql_node_variable_t* node = (TRI_aql_node_variable_t*) data;
AppendCode(generator, "_");
@ -403,7 +496,12 @@ static bool AppendVarname1 (TRI_aql_codegen_t* const generator, const TRI_aql_no
return true;
}
static bool AppendVarname2 (TRI_aql_codegen_t* const generator, const TRI_aql_node_t* const data) {
////////////////////////////////////////////////////////////////////////////////
/// @brief print a variable name in the current scope, prepended by "__"
////////////////////////////////////////////////////////////////////////////////
static bool AppendVarname2 (TRI_aql_codegen_t* const generator,
const TRI_aql_node_t* const data) {
TRI_aql_node_variable_t* node = (TRI_aql_node_variable_t*) data;
AppendCode(generator, "__");
@ -412,7 +510,12 @@ static bool AppendVarname2 (TRI_aql_codegen_t* const generator, const TRI_aql_no
return true;
}
static bool AppendOwnPropertyName (TRI_aql_codegen_t* const generator, const char* const name) {
////////////////////////////////////////////////////////////////////////////////
/// @brief print hasOwnProperty(...) if construct in current scope
////////////////////////////////////////////////////////////////////////////////
static bool AppendOwnPropertyName (TRI_aql_codegen_t* const generator,
const char* const name) {
AppendIndent(generator);
AppendCode(generator, "if (!__");
AppendCode(generator, name);
@ -429,7 +532,12 @@ static bool AppendOwnPropertyName (TRI_aql_codegen_t* const generator, const cha
return true;
}
static bool AppendOwnPropertyVar (TRI_aql_codegen_t* const generator, const TRI_aql_node_t* const data) {
////////////////////////////////////////////////////////////////////////////////
/// @brief print hasOwnProperty(...) if construct in current scope
////////////////////////////////////////////////////////////////////////////////
static bool AppendOwnPropertyVar (TRI_aql_codegen_t* const generator,
const TRI_aql_node_t* const data) {
AppendIndent(generator);
AppendCode(generator, "if (!");
AppendVarname2(generator, data);
@ -446,6 +554,10 @@ static bool AppendOwnPropertyVar (TRI_aql_codegen_t* const generator, const TRI_
return true;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief generate the code for an individual node and all subnodes
////////////////////////////////////////////////////////////////////////////////
static void GenerateCode (TRI_aql_codegen_t* const generator,
const TRI_aql_node_t* const data) {
TRI_aql_node_t* node;
@ -1030,7 +1142,9 @@ static void GenerateCode (TRI_aql_codegen_t* const generator,
////////////////////////////////////////////////////////////////////////////////
TRI_aql_codegen_t* TRI_CreateCodegenAql (void) {
TRI_aql_codegen_t* generator = (TRI_aql_codegen_t*) TRI_Allocate(sizeof(TRI_aql_codegen_t));
TRI_aql_codegen_t* generator;
generator = (TRI_aql_codegen_t*) TRI_Allocate(sizeof(TRI_aql_codegen_t));
if (!generator) {
return NULL;

View File

@ -50,6 +50,10 @@ extern "C" {
/// @{
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @brief enumeration of scope types
////////////////////////////////////////////////////////////////////////////////
typedef enum {
AQL_SCOPE_STANDALONE = 0,
AQL_SCOPE_RESULT = 1,
@ -57,6 +61,10 @@ typedef enum {
}
TRI_aql_scope_type_e;
////////////////////////////////////////////////////////////////////////////////
/// @brief a function scope created by the code generator
////////////////////////////////////////////////////////////////////////////////
typedef struct TRI_aql_codegen_scope_s {
TRI_aql_scope_type_e _type;
TRI_string_buffer_t* _buffer;
@ -67,6 +75,10 @@ typedef struct TRI_aql_codegen_scope_s {
}
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;

View File

@ -36,6 +36,10 @@
/// @addtogroup Ahuacatl
/// @{
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @brief get the "nice" name of an AST node
////////////////////////////////////////////////////////////////////////////////
static char* GetTypeName (const TRI_aql_node_type_e type) {
switch (type) {
@ -128,6 +132,10 @@ static char* GetTypeName (const TRI_aql_node_type_e type) {
assert(false);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief print some indentation
////////////////////////////////////////////////////////////////////////////////
static void Indent (TRI_aql_dump_t* const state) {
size_t i;
@ -136,20 +144,36 @@ static void Indent (TRI_aql_dump_t* const state) {
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief print the type name of an AST node
////////////////////////////////////////////////////////////////////////////////
static void PrintType (TRI_aql_dump_t* const state, const TRI_aql_node_type_e type) {
Indent(state);
printf("%s\n", GetTypeName(type));
}
////////////////////////////////////////////////////////////////////////////////
/// @brief increase the indent level by one
////////////////////////////////////////////////////////////////////////////////
static inline void IndentState (TRI_aql_dump_t* const state) {
++state->_indent;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief decrease the indent level by one
////////////////////////////////////////////////////////////////////////////////
static inline void OutdentState (TRI_aql_dump_t* const state) {
assert(state->_indent > 0);
--state->_indent;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief dump an AST value node's value
////////////////////////////////////////////////////////////////////////////////
static void DumpValue (TRI_aql_dump_t* const state, TRI_aql_node_value_t* node) {
switch (node->_value._type) {
case AQL_TYPE_FAIL:
@ -173,6 +197,10 @@ static void DumpValue (TRI_aql_dump_t* const state, TRI_aql_node_value_t* node)
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief dump an AST node with all subnodes
////////////////////////////////////////////////////////////////////////////////
static void DumpNode (TRI_aql_dump_t* const state, TRI_aql_node_t* const data) {
TRI_aql_node_t* node;

View File

@ -38,11 +38,28 @@
extern "C" {
#endif
// -----------------------------------------------------------------------------
// --SECTION-- public types
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup Ahuacatl
/// @{
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @brief internal state of dump
////////////////////////////////////////////////////////////////////////////////
typedef struct TRI_aql_dump_s {
int64_t _indent;
}
TRI_aql_dump_t;
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- public functions
// -----------------------------------------------------------------------------

View File

@ -1005,6 +1005,11 @@ SHELL_SERVER = @srcdir@/js/common/tests/shell-document.js \
UNITTESTS_SERVER = $(addprefix --unit-tests ,$(SHELL_SERVER))
################################################################################
################################################################################
SHELL_SERVER_AHUACATL = @srcdir@/js/server/tests/ahuacatl-queries.js
UNITTESTS_SERVER_AHUACATL = $(addprefix --unit-tests ,$(SHELL_SERVER_AHUACATL))
################################################################################
################################################################################
SHELL_SERVER_INDEX = @srcdir@/js/server/tests/aql-index-primary.js \
@ -2886,6 +2891,7 @@ unittests: unittests-verbose unittests-brief
unittests-brief: \
unittests-boost \
unittests-shell-server \
unittests-shell-server-ahuacatl \
unittests-http-server \
unittests-shell-client \
unittests-http-server \
@ -2976,6 +2982,24 @@ unittests-shell-server:
@echo
.PHONY: unittests-shell-server-ahuacatl
unittests-shell-server-ahuacatl:
@echo
@echo "================================================================================"
@echo "|| SHELL SERVER TESTS (AHUACATL) ||"
@echo "================================================================================"
@echo
@rm -rf "$(VOCDIR)"
@mkdir "$(VOCDIR)"
$(VALGRIND) @builddir@/avocado "$(VOCDIR)" $(SERVER_OPT) $(UNITTESTS_SERVER_AHUACATL) || test "$(FORCE)" == "1"
@rm -rf "$(VOCDIR)"
@echo
.PHONY: unittests-shell-server-index
unittests-shell-server-index:

View File

@ -14,6 +14,7 @@ unittests: unittests-verbose unittests-brief
unittests-brief: \
unittests-boost \
unittests-shell-server \
unittests-shell-server-ahuacatl \
unittests-http-server \
unittests-shell-client \
unittests-http-server \
@ -148,6 +149,32 @@ unittests-shell-server:
@echo
################################################################################
## SHELL SERVER TESTS (AHUACATL)
################################################################################
SHELL_SERVER_AHUACATL = @srcdir@/js/server/tests/ahuacatl-queries.js
.PHONY: unittests-shell-server-ahuacatl
UNITTESTS_SERVER_AHUACATL = $(addprefix --unit-tests ,$(SHELL_SERVER_AHUACATL))
unittests-shell-server-ahuacatl:
@echo
@echo "================================================================================"
@echo "|| SHELL SERVER TESTS (AHUACATL) ||"
@echo "================================================================================"
@echo
@rm -rf "$(VOCDIR)"
@mkdir "$(VOCDIR)"
$(VALGRIND) @builddir@/avocado "$(VOCDIR)" $(SERVER_OPT) $(UNITTESTS_SERVER_AHUACATL) || test "$(FORCE)" == "1"
@rm -rf "$(VOCDIR)"
@echo
################################################################################
## SHELL SERVER TESTS (INDEX)
################################################################################

View File

@ -551,9 +551,9 @@ function ahuacatlQueryTestSuite () {
////////////////////////////////////////////////////////////////////////////////
testRelations1 : function () {
var expected = [ { "name" : "Abigail", "numFriends" : 3 }, { "name" : "Michael", "numFriends" : 2 }, { "name" : "Sophia", "numFriends" : 2 }, { "name" : "Mariah", "numFriends" : 2 } ];
var expected = [ { "name" : "Abigail", "numFriends" : 3 }, { "name" : "Alexander", "numFriends" : 2 }, { "name" : "Isabella", "numFriends" : 2 }, { "name" : "John", "numFriends" : 2 } ];
actual = getQueryResults("FOR u in " + users.name() + " FILTER u.active == true LET f = ((FOR r IN " + relations.name() + " FILTER r.from == u.id && r.type == \"friend\" RETURN r)) SORT AHUACATL_LENGTH(f) DESC LIMIT 0,4 FILTER AHUACATL_LENGTH(f) > 0 RETURN { \"name\" : u.name, \"numFriends\" : AHUACATL_LENGTH(f) }", false);
actual = getQueryResults("FOR u in " + users.name() + " FILTER u.active == true LET f = ((FOR r IN " + relations.name() + " FILTER r.from == u.id && r.type == \"friend\" RETURN r)) SORT AHUACATL_LENGTH(f) DESC, u.name LIMIT 0,4 FILTER AHUACATL_LENGTH(f) > 0 RETURN { \"name\" : u.name, \"numFriends\" : AHUACATL_LENGTH(f) }", false);
assertEqual(expected, actual);
},