diff --git a/arangod/Aql/Ast.cpp b/arangod/Aql/Ast.cpp index 93b23bdadd..def4f90686 100644 --- a/arangod/Aql/Ast.cpp +++ b/arangod/Aql/Ast.cpp @@ -29,8 +29,8 @@ #include "Aql/Ast.h" #include "Aql/Collection.h" +#include "Aql/Executor.h" #include "Aql/Parser.h" -#include "Aql/V8Executor.h" #include "BasicsC/tri-strings.h" #include "Utils/Exception.h" #include "VocBase/collection.h" diff --git a/arangod/Aql/AstNode.cpp b/arangod/Aql/AstNode.cpp index 404956ba4f..9fe1670dd0 100644 --- a/arangod/Aql/AstNode.cpp +++ b/arangod/Aql/AstNode.cpp @@ -29,9 +29,9 @@ #include "Aql/AstNode.h" #include "Aql/Ast.h" +#include "Aql/Executor.h" #include "Aql/Function.h" #include "Aql/Scopes.h" -#include "Aql/V8Executor.h" #include "Basics/StringBuffer.h" #include "Basics/JsonHelper.h" diff --git a/arangod/Aql/V8Executor.cpp b/arangod/Aql/Executor.cpp similarity index 95% rename from arangod/Aql/V8Executor.cpp rename to arangod/Aql/Executor.cpp index 81b5406da3..437babfc78 100644 --- a/arangod/Aql/V8Executor.cpp +++ b/arangod/Aql/Executor.cpp @@ -1,5 +1,5 @@ //////////////////////////////////////////////////////////////////////////////// -/// @brief Aql, v8 context executor +/// @brief Aql, expression executor /// /// @file /// @@ -27,7 +27,7 @@ /// @author Copyright 2012-2013, triAGENS GmbH, Cologne, Germany //////////////////////////////////////////////////////////////////////////////// -#include "Aql/V8Executor.h" +#include "Aql/Executor.h" #include "Aql/AstNode.h" #include "Aql/Functions.h" #include "Aql/V8Expression.h" @@ -47,7 +47,7 @@ using namespace triagens::aql; /// @brief internal functions used in execution //////////////////////////////////////////////////////////////////////////////// -std::unordered_map const V8Executor::InternalFunctionNames{ +std::unordered_map const Executor::InternalFunctionNames{ { static_cast(NODE_TYPE_OPERATOR_UNARY_PLUS), "UNARY_PLUS" }, { static_cast(NODE_TYPE_OPERATOR_UNARY_MINUS), "UNARY_MINUS" }, { static_cast(NODE_TYPE_OPERATOR_UNARY_NOT), "LOGICAL_NOT" }, @@ -72,7 +72,7 @@ std::unordered_map const V8Executor::InternalFunctionNam /// @brief user-accessible functions //////////////////////////////////////////////////////////////////////////////// -std::unordered_map const V8Executor::FunctionNames{ +std::unordered_map const Executor::FunctionNames{ // meanings of the symbols in the function arguments list // ------------------------------------------------------ // @@ -227,7 +227,7 @@ std::unordered_map const V8Executor::FunctionNames{ /// @brief creates an executor //////////////////////////////////////////////////////////////////////////////// -V8Executor::V8Executor () : +Executor::Executor () : _buffer(nullptr) { } @@ -235,7 +235,7 @@ V8Executor::V8Executor () : /// @brief destroys an executor //////////////////////////////////////////////////////////////////////////////// -V8Executor::~V8Executor () { +Executor::~Executor () { if (_buffer != nullptr) { delete _buffer; _buffer = nullptr; @@ -250,7 +250,7 @@ V8Executor::~V8Executor () { /// @brief generates an expression execution object //////////////////////////////////////////////////////////////////////////////// -V8Expression* V8Executor::generateExpression (AstNode const* node) { +V8Expression* Executor::generateExpression (AstNode const* node) { generateCodeExpression(node); // std::cout << "Executor::generateExpression: " << _buffer->c_str() << "\n"; @@ -270,7 +270,7 @@ V8Expression* V8Executor::generateExpression (AstNode const* node) { /// @brief executes an expression directly //////////////////////////////////////////////////////////////////////////////// -TRI_json_t* V8Executor::executeExpression (AstNode const* node) { +TRI_json_t* Executor::executeExpression (AstNode const* node) { generateCodeExpression(node); // std::cout << "Executor::ExecuteExpression: " << _buffer->c_str() << "\n"; @@ -299,7 +299,7 @@ TRI_json_t* V8Executor::executeExpression (AstNode const* node) { /// @brief returns a reference to a built-in function //////////////////////////////////////////////////////////////////////////////// -Function const* V8Executor::getFunctionByName (std::string const& name) { +Function const* Executor::getFunctionByName (std::string const& name) { auto it = FunctionNames.find(name); if (it == FunctionNames.end()) { @@ -319,8 +319,8 @@ Function const* V8Executor::getFunctionByName (std::string const& name) { /// exception from it if so //////////////////////////////////////////////////////////////////////////////// -void V8Executor::HandleV8Error (v8::TryCatch& tryCatch, - v8::Handle& result) { +void Executor::HandleV8Error (v8::TryCatch& tryCatch, + v8::Handle& result) { if (tryCatch.HasCaught()) { // caught a V8 exception if (! tryCatch.CanContinue()) { @@ -375,7 +375,7 @@ void V8Executor::HandleV8Error (v8::TryCatch& tryCatch, /// @brief compile a V8 function from the code contained in the buffer //////////////////////////////////////////////////////////////////////////////// -v8::Handle V8Executor::compileExpression () { +v8::Handle Executor::compileExpression () { TRI_ASSERT(_buffer != nullptr); v8::Handle compiled = v8::Script::Compile(v8::String::New(_buffer->c_str(), (int) _buffer->length()), @@ -392,7 +392,7 @@ v8::Handle V8Executor::compileExpression () { /// @brief generate JavaScript code for an arbitrary expression //////////////////////////////////////////////////////////////////////////////// -void V8Executor::generateCodeExpression (AstNode const* node) { +void Executor::generateCodeExpression (AstNode const* node) { // initialise and/or clear the buffer initBuffer(); TRI_ASSERT(_buffer != nullptr); @@ -410,7 +410,7 @@ void V8Executor::generateCodeExpression (AstNode const* node) { /// @brief generates code for a string value //////////////////////////////////////////////////////////////////////////////// -void V8Executor::generateCodeString (char const* value) { +void Executor::generateCodeString (char const* value) { TRI_ASSERT(value != nullptr); _buffer->appendChar('"'); @@ -422,7 +422,7 @@ void V8Executor::generateCodeString (char const* value) { /// @brief generate JavaScript code for a list //////////////////////////////////////////////////////////////////////////////// -void V8Executor::generateCodeList (AstNode const* node) { +void Executor::generateCodeList (AstNode const* node) { TRI_ASSERT(node != nullptr); size_t const n = node->numMembers(); @@ -442,7 +442,7 @@ void V8Executor::generateCodeList (AstNode const* node) { /// @brief generate JavaScript code for an array //////////////////////////////////////////////////////////////////////////////// -void V8Executor::generateCodeArray (AstNode const* node) { +void Executor::generateCodeArray (AstNode const* node) { TRI_ASSERT(node != nullptr); size_t const n = node->numMembers(); @@ -468,7 +468,7 @@ void V8Executor::generateCodeArray (AstNode const* node) { /// @brief generate JavaScript code for a unary operator //////////////////////////////////////////////////////////////////////////////// -void V8Executor::generateCodeUnaryOperator (AstNode const* node) { +void Executor::generateCodeUnaryOperator (AstNode const* node) { TRI_ASSERT(node != nullptr); TRI_ASSERT(node->numMembers() == 1); @@ -491,7 +491,7 @@ void V8Executor::generateCodeUnaryOperator (AstNode const* node) { /// @brief generate JavaScript code for a binary operator //////////////////////////////////////////////////////////////////////////////// -void V8Executor::generateCodeBinaryOperator (AstNode const* node) { +void Executor::generateCodeBinaryOperator (AstNode const* node) { TRI_ASSERT(node != nullptr); TRI_ASSERT(node->numMembers() == 2); @@ -529,7 +529,7 @@ void V8Executor::generateCodeBinaryOperator (AstNode const* node) { /// @brief generate JavaScript code for the ternary operator //////////////////////////////////////////////////////////////////////////////// -void V8Executor::generateCodeTernaryOperator (AstNode const* node) { +void Executor::generateCodeTernaryOperator (AstNode const* node) { TRI_ASSERT(node != nullptr); TRI_ASSERT(node->numMembers() == 3); @@ -556,7 +556,7 @@ void V8Executor::generateCodeTernaryOperator (AstNode const* node) { /// @brief generate JavaScript code for a variable (read) access //////////////////////////////////////////////////////////////////////////////// -void V8Executor::generateCodeReference (AstNode const* node) { +void Executor::generateCodeReference (AstNode const* node) { TRI_ASSERT(node != nullptr); TRI_ASSERT(node->numMembers() == 0); @@ -571,7 +571,7 @@ void V8Executor::generateCodeReference (AstNode const* node) { /// @brief generate JavaScript code for a variable //////////////////////////////////////////////////////////////////////////////// -void V8Executor::generateCodeVariable (AstNode const* node) { +void Executor::generateCodeVariable (AstNode const* node) { TRI_ASSERT(node != nullptr); TRI_ASSERT(node->numMembers() == 0); @@ -586,7 +586,7 @@ void V8Executor::generateCodeVariable (AstNode const* node) { /// @brief generate JavaScript code for a full collection access //////////////////////////////////////////////////////////////////////////////// -void V8Executor::generateCodeCollection (AstNode const* node) { +void Executor::generateCodeCollection (AstNode const* node) { TRI_ASSERT(node != nullptr); TRI_ASSERT(node->numMembers() == 0); @@ -601,7 +601,7 @@ void V8Executor::generateCodeCollection (AstNode const* node) { /// @brief generate JavaScript code for a call to a built-in function //////////////////////////////////////////////////////////////////////////////// -void V8Executor::generateCodeFunctionCall (AstNode const* node) { +void Executor::generateCodeFunctionCall (AstNode const* node) { TRI_ASSERT(node != nullptr); TRI_ASSERT(node->numMembers() == 1); @@ -652,7 +652,7 @@ void V8Executor::generateCodeFunctionCall (AstNode const* node) { /// @brief generate JavaScript code for a call to a user-defined function //////////////////////////////////////////////////////////////////////////////// -void V8Executor::generateCodeUserFunctionCall (AstNode const* node) { +void Executor::generateCodeUserFunctionCall (AstNode const* node) { TRI_ASSERT(node != nullptr); TRI_ASSERT(node->numMembers() == 1); @@ -682,7 +682,7 @@ void V8Executor::generateCodeUserFunctionCall (AstNode const* node) { /// @brief generate JavaScript code for an expansion (i.e. [*] operator) //////////////////////////////////////////////////////////////////////////////// -void V8Executor::generateCodeExpand (AstNode const* node) { +void Executor::generateCodeExpand (AstNode const* node) { TRI_ASSERT(node != nullptr); TRI_ASSERT(node->numMembers() == 2); @@ -704,7 +704,7 @@ void V8Executor::generateCodeExpand (AstNode const* node) { /// @brief generate JavaScript code for an expansion iterator //////////////////////////////////////////////////////////////////////////////// -void V8Executor::generateCodeExpandIterator (AstNode const* node) { +void Executor::generateCodeExpandIterator (AstNode const* node) { TRI_ASSERT(node != nullptr); TRI_ASSERT(node->numMembers() == 2); @@ -716,7 +716,7 @@ void V8Executor::generateCodeExpandIterator (AstNode const* node) { /// @brief generate JavaScript code for a range (i.e. 1..10) //////////////////////////////////////////////////////////////////////////////// -void V8Executor::generateCodeRange (AstNode const* node) { +void Executor::generateCodeRange (AstNode const* node) { TRI_ASSERT(node != nullptr); TRI_ASSERT(node->numMembers() == 2); @@ -731,7 +731,7 @@ void V8Executor::generateCodeRange (AstNode const* node) { /// @brief generate JavaScript code for a named attribute access //////////////////////////////////////////////////////////////////////////////// -void V8Executor::generateCodeNamedAccess (AstNode const* node) { +void Executor::generateCodeNamedAccess (AstNode const* node) { TRI_ASSERT(node != nullptr); TRI_ASSERT(node->numMembers() == 1); @@ -746,7 +746,7 @@ void V8Executor::generateCodeNamedAccess (AstNode const* node) { /// @brief generate JavaScript code for a bound attribute access //////////////////////////////////////////////////////////////////////////////// -void V8Executor::generateCodeBoundAccess (AstNode const* node) { +void Executor::generateCodeBoundAccess (AstNode const* node) { TRI_ASSERT(node != nullptr); TRI_ASSERT(node->numMembers() == 2); @@ -761,7 +761,7 @@ void V8Executor::generateCodeBoundAccess (AstNode const* node) { /// @brief generate JavaScript code for an indexed attribute access //////////////////////////////////////////////////////////////////////////////// -void V8Executor::generateCodeIndexedAccess (AstNode const* node) { +void Executor::generateCodeIndexedAccess (AstNode const* node) { TRI_ASSERT(node != nullptr); TRI_ASSERT(node->numMembers() == 2); @@ -776,7 +776,7 @@ void V8Executor::generateCodeIndexedAccess (AstNode const* node) { /// @brief generate JavaScript code for a node //////////////////////////////////////////////////////////////////////////////// -void V8Executor::generateCodeNode (AstNode const* node) { +void Executor::generateCodeNode (AstNode const* node) { TRI_ASSERT(node != nullptr); switch (node->type) { @@ -873,7 +873,7 @@ void V8Executor::generateCodeNode (AstNode const* node) { /// @brief create the string buffer //////////////////////////////////////////////////////////////////////////////// -triagens::basics::StringBuffer* V8Executor::initBuffer () { +triagens::basics::StringBuffer* Executor::initBuffer () { if (_buffer == nullptr) { _buffer = new triagens::basics::StringBuffer(TRI_UNKNOWN_MEM_ZONE); diff --git a/arangod/Aql/V8Executor.h b/arangod/Aql/Executor.h similarity index 98% rename from arangod/Aql/V8Executor.h rename to arangod/Aql/Executor.h index e02f591261..4f2af1f620 100644 --- a/arangod/Aql/V8Executor.h +++ b/arangod/Aql/Executor.h @@ -1,5 +1,5 @@ //////////////////////////////////////////////////////////////////////////////// -/// @brief Aql, v8 context executor +/// @brief Aql, expression executor /// /// @file /// @@ -47,10 +47,10 @@ namespace triagens { struct V8Expression; // ----------------------------------------------------------------------------- -// --SECTION-- class V8Executor +// --SECTION-- class Executor // ----------------------------------------------------------------------------- - class V8Executor { + class Executor { // ----------------------------------------------------------------------------- // --SECTION-- constructors / destructors @@ -62,13 +62,13 @@ namespace triagens { /// @brief create the executor //////////////////////////////////////////////////////////////////////////////// - V8Executor (); + Executor (); //////////////////////////////////////////////////////////////////////////////// /// @brief destroy the executor //////////////////////////////////////////////////////////////////////////////// - ~V8Executor (); + ~Executor (); // ----------------------------------------------------------------------------- // --SECTION-- public methods diff --git a/arangod/Aql/Expression.cpp b/arangod/Aql/Expression.cpp index 458ca87bcc..9fb0dbd1bc 100644 --- a/arangod/Aql/Expression.cpp +++ b/arangod/Aql/Expression.cpp @@ -30,8 +30,8 @@ #include "Aql/Expression.h" #include "Aql/AqlValue.h" #include "Aql/Ast.h" +#include "Aql/Executor.h" #include "Aql/Types.h" -#include "Aql/V8Executor.h" #include "Aql/V8Expression.h" #include "Aql/Variable.h" #include "Basics/JsonHelper.h" @@ -52,7 +52,7 @@ using JsonHelper = triagens::basics::JsonHelper; /// @brief create the expression //////////////////////////////////////////////////////////////////////////////// -Expression::Expression (V8Executor* executor, +Expression::Expression (Executor* executor, AstNode const* node) : _executor(executor), _node(node), diff --git a/arangod/Aql/Expression.h b/arangod/Aql/Expression.h index 5e095246ed..6982cd2584 100644 --- a/arangod/Aql/Expression.h +++ b/arangod/Aql/Expression.h @@ -48,7 +48,7 @@ namespace triagens { struct AqlValue; class Ast; struct Variable; - class V8Executor; + class Executor; struct V8Expression; //////////////////////////////////////////////////////////////////////////////// @@ -74,7 +74,7 @@ namespace triagens { /// @brief constructor, using an AST start node //////////////////////////////////////////////////////////////////////////////// - Expression (V8Executor*, + Expression (Executor*, AstNode const*); Expression (Ast*, @@ -219,7 +219,7 @@ namespace triagens { /// @brief the V8 executor //////////////////////////////////////////////////////////////////////////////// - V8Executor* _executor; + Executor* _executor; //////////////////////////////////////////////////////////////////////////////// /// @brief the AST node that contains the expression to execute diff --git a/arangod/Aql/Optimizer.cpp b/arangod/Aql/Optimizer.cpp index 9052a4499a..6b506938a9 100644 --- a/arangod/Aql/Optimizer.cpp +++ b/arangod/Aql/Optimizer.cpp @@ -101,12 +101,7 @@ int Optimizer::createPlans (ExecutionPlan* plan, _newPlans.clear(); - // int pass = 1; while (leastDoneLevel < maxRuleLevel) { - /* - std::cout << "Entering pass " << pass << " of query optimization..." - << std::endl; - */ // Find variable usage for all old plans now: for (auto p : _plans.list) { if (! p->varUsageComputed()) { diff --git a/arangod/Aql/OptimizerRules.cpp b/arangod/Aql/OptimizerRules.cpp index 2e6c73ef51..0e897e044a 100644 --- a/arangod/Aql/OptimizerRules.cpp +++ b/arangod/Aql/OptimizerRules.cpp @@ -377,7 +377,7 @@ class FilterToEnumCollFinder : public WalkerWorker { RangesInfo* _ranges; Optimizer* _opt; ExecutionPlan* _plan; - Variable const* _var; + std::unordered_set _varIds; bool _canThrow; int _level; @@ -386,9 +386,9 @@ class FilterToEnumCollFinder : public WalkerWorker { FilterToEnumCollFinder (Optimizer* opt, ExecutionPlan* plan, Variable const* var) : _opt(opt), _plan(plan), - _var(var), _canThrow(false) { _ranges = new RangesInfo(); + _varIds.insert(var->id); }; ~FilterToEnumCollFinder () { @@ -398,10 +398,15 @@ class FilterToEnumCollFinder : public WalkerWorker { bool before (ExecutionNode* en) { _canThrow = (_canThrow || en->canThrow()); // can any node walked over throw? - if (en->getType() == triagens::aql::ExecutionNode::CALCULATION) { + if (en->getType() == triagens::aql::ExecutionNode::FILTER) { + std::vector inVar = en->getVariablesUsedHere(); + TRI_ASSERT(inVar.size() == 1); + _varIds.insert(inVar[0]->id); + } + else if (en->getType() == triagens::aql::ExecutionNode::CALCULATION) { auto outvar = en->getVariablesSetHere(); TRI_ASSERT(outvar.size() == 1); - if (outvar[0]->id == _var->id) { + if (_varIds.find(outvar[0]->id) != _varIds.end()) { auto node = static_cast(en); std::string attr; std::string enumCollVar; diff --git a/arangod/Aql/Query.cpp b/arangod/Aql/Query.cpp index dbeb6fa464..b8277b7079 100644 --- a/arangod/Aql/Query.cpp +++ b/arangod/Aql/Query.cpp @@ -31,8 +31,8 @@ #include "Aql/ExecutionBlock.h" #include "Aql/ExecutionEngine.h" #include "Aql/ExecutionPlan.h" +#include "Aql/Executor.h" #include "Aql/Parser.h" -#include "Aql/V8Executor.h" #include "Aql/ExecutionEngine.h" #include "Aql/Optimizer.h" #include "Basics/JsonHelper.h" @@ -411,10 +411,10 @@ QueryResult Query::explain () { /// @brief get v8 executor //////////////////////////////////////////////////////////////////////////////// -V8Executor* Query::executor () { +Executor* Query::executor () { if (_executor == nullptr) { // the executor is a singleton per query - _executor = new V8Executor; + _executor = new Executor; } TRI_ASSERT(_executor != nullptr); diff --git a/arangod/Aql/Query.h b/arangod/Aql/Query.h index 366db3405e..c583b71fe7 100644 --- a/arangod/Aql/Query.h +++ b/arangod/Aql/Query.h @@ -42,7 +42,7 @@ struct TRI_vocbase_s; namespace triagens { namespace aql { - class V8Executor; + class Executor; class Expression; struct Variable; struct AstNode; @@ -189,7 +189,7 @@ namespace triagens { /// @brief get v8 executor //////////////////////////////////////////////////////////////////////////////// - V8Executor* executor (); + Executor* executor (); //////////////////////////////////////////////////////////////////////////////// /// @brief register a string @@ -234,7 +234,7 @@ namespace triagens { /// @brief V8 code executor //////////////////////////////////////////////////////////////////////////////// - V8Executor* _executor; + Executor* _executor; //////////////////////////////////////////////////////////////////////////////// /// @brief the actual query string diff --git a/arangod/Aql/V8Expression.cpp b/arangod/Aql/V8Expression.cpp index 909e08f5d7..0ccfde13f1 100644 --- a/arangod/Aql/V8Expression.cpp +++ b/arangod/Aql/V8Expression.cpp @@ -28,7 +28,7 @@ //////////////////////////////////////////////////////////////////////////////// #include "Aql/V8Expression.h" -#include "Aql/V8Executor.h" +#include "Aql/Executor.h" #include "Aql/Variable.h" #include "BasicsC/json.h" #include "V8/v8-conv.h" @@ -94,7 +94,7 @@ AqlValue V8Expression::execute (AQL_TRANSACTION_V8* trx, v8::TryCatch tryCatch; v8::Handle result = func->Call(func, 1, args); - V8Executor::HandleV8Error(tryCatch, result); + Executor::HandleV8Error(tryCatch, result); // no exception was thrown if we get here TRI_json_t* json = nullptr; diff --git a/arangod/CMakeLists.txt b/arangod/CMakeLists.txt index e96da6f9cd..5561cee0c9 100644 --- a/arangod/CMakeLists.txt +++ b/arangod/CMakeLists.txt @@ -67,6 +67,7 @@ add_executable( Aql/ExecutionNode.cpp Aql/ExecutionPlan.cpp Aql/ExecutionStats.cpp + Aql/Executor.cpp Aql/Expression.cpp Aql/Function.cpp Aql/Functions.cpp @@ -79,7 +80,6 @@ add_executable( Aql/Scopes.cpp Aql/Types.cpp Aql/tokens.cpp - Aql/V8Executor.cpp Aql/V8Expression.cpp Aql/Variable.cpp Aql/VariableGenerator.cpp diff --git a/arangod/Makefile.files b/arangod/Makefile.files index 5b4302810b..aa33ba8d9c 100644 --- a/arangod/Makefile.files +++ b/arangod/Makefile.files @@ -48,6 +48,7 @@ arangod_libarangod_a_SOURCES = \ arangod/Aql/ExecutionNode.cpp \ arangod/Aql/ExecutionPlan.cpp \ arangod/Aql/ExecutionStats.cpp \ + arangod/Aql/Executor.cpp \ arangod/Aql/Expression.cpp \ arangod/Aql/Function.cpp \ arangod/Aql/Functions.cpp \ @@ -60,7 +61,6 @@ arangod_libarangod_a_SOURCES = \ arangod/Aql/Scopes.cpp \ arangod/Aql/Types.cpp \ arangod/Aql/tokens.cpp \ - arangod/Aql/V8Executor.cpp \ arangod/Aql/V8Expression.cpp \ arangod/Aql/Variable.cpp \ arangod/Aql/VariableGenerator.cpp \