diff --git a/arangod/Aql/ExecutionBlock.h b/arangod/Aql/ExecutionBlock.h index dd01cbc40d..01ee1c79f2 100644 --- a/arangod/Aql/ExecutionBlock.h +++ b/arangod/Aql/ExecutionBlock.h @@ -30,70 +30,12 @@ #include -#include "VocBase/document-collection.h" - +#include "Aql/Types.h" #include "Aql/ExecutionPlan.h" namespace triagens { namespace aql { -// ----------------------------------------------------------------------------- -// --SECTION-- AqlDocuments -// ----------------------------------------------------------------------------- - -//////////////////////////////////////////////////////////////////////////////// -/// @brief struct AqlDocument, used to pipe documents through executions -/// the execution engine keeps one AqlDocument struct for each document -/// that is piped through the engine. Note that the document can exist in -/// one of two formats throughout its lifetime in the engine. When it resides -/// originally in a datafile, it stays there unchanged and we only store -/// a (pointer to) a copy of the TRI_doc_mptr_t struct. As soon as it is -/// modified (or created on the fly anyway), or if it originally resides -/// in the WAL, we keep the document as a TRI_json_t, wrapped by a Json -/// struct. That is, the following struct has the following invariant: -/// Either the whole struct is empty and thus _json is empty and _mptr is -/// a nullptr. Otherwise, either _json is empty and _mptr is not a nullptr, -/// or _json is non-empty and _mptr is anullptr. -/// Additionally, the struct contains another TRI_json_t holding the -/// current state of the LET variables (and possibly some other -/// computations). This is the _vars attribute. -/// Note that both Json subobjects are constructed as AUTOFREE. -//////////////////////////////////////////////////////////////////////////////// - - struct AqlDocument { - triagens::basics::Json _json; - TRI_doc_mptr_copy_t* _mptr; - triagens::basics::Json _vars; - -//////////////////////////////////////////////////////////////////////////////// -/// @brief convenience constructors -//////////////////////////////////////////////////////////////////////////////// - - AqlDocument () - : _json(), _mptr(nullptr), _vars() { - } - - AqlDocument (TRI_doc_mptr_t* mptr) - : _json(), _vars() { - _mptr = new TRI_doc_mptr_copy_t(*mptr); - } - - AqlDocument (triagens::basics::Json json) - : _json(json), _mptr(nullptr), _vars() { - } - -//////////////////////////////////////////////////////////////////////////////// -/// @brief destructor -//////////////////////////////////////////////////////////////////////////////// - - ~AqlDocument () { - if (_mptr != nullptr) { - delete _mptr; - } - } - - }; - } // namespace triagens::aql } // namespace triagens diff --git a/arangod/Aql/ExecutionPlan.cpp b/arangod/Aql/ExecutionPlan.cpp index 7db7d410b7..333a4e4d26 100644 --- a/arangod/Aql/ExecutionPlan.cpp +++ b/arangod/Aql/ExecutionPlan.cpp @@ -193,7 +193,8 @@ void testExecutionPlans () { auto ec = new EnumerateCollectionPlan(nullptr, "guck"); Json jjj(ec->toJson()); cout << jjj.toString() << endl; - auto li = new LimitPlan(ec, 12, 17); + auto li = new LimitPlan(12, 17); + li->addDependency(ec); jjj = li->toJson(); cout << jjj.toString() << endl; diff --git a/arangod/Aql/ExecutionPlan.h b/arangod/Aql/ExecutionPlan.h index 368271c361..d994f5cf61 100644 --- a/arangod/Aql/ExecutionPlan.h +++ b/arangod/Aql/ExecutionPlan.h @@ -35,58 +35,11 @@ #include #include -#include "Aql/AstNode.h" +#include "Aql/Types.h" namespace triagens { namespace aql { -//////////////////////////////////////////////////////////////////////////////// -/// @brief class AqlExpression, used in execution plans and execution blocks -//////////////////////////////////////////////////////////////////////////////// - - class AqlExpression { - - public: - -//////////////////////////////////////////////////////////////////////////////// -/// @brief default constructor, creating an empty expression -//////////////////////////////////////////////////////////////////////////////// - - AqlExpression () : _ast(nullptr) { - } - -//////////////////////////////////////////////////////////////////////////////// -/// @brief constructor, using an abstract syntax tree -//////////////////////////////////////////////////////////////////////////////// - - AqlExpression (AstNode* ast) : _ast(ast) { - } - -//////////////////////////////////////////////////////////////////////////////// -/// @brief destructor -//////////////////////////////////////////////////////////////////////////////// - - ~AqlExpression () { - } - -//////////////////////////////////////////////////////////////////////////////// -/// @brief getAst, get the underlying abstract syntax tree -//////////////////////////////////////////////////////////////////////////////// - - AstNode* getAst () { - return _ast; - } - -//////////////////////////////////////////////////////////////////////////////// -/// @brief private members -//////////////////////////////////////////////////////////////////////////////// - - private: - - AstNode* _ast; - - }; - //////////////////////////////////////////////////////////////////////////////// /// @brief class ExecutionPlan, abstract base class of all execution plans //////////////////////////////////////////////////////////////////////////////// @@ -351,18 +304,10 @@ namespace triagens { : ExecutionPlan(), _offset(o), _limit(l) { } - LimitPlan (ExecutionPlan* ep, size_t o, size_t l) - : ExecutionPlan(ep), _offset(o), _limit(l) { - } - LimitPlan (size_t l) : ExecutionPlan(), _offset(0), _limit(l) { } - LimitPlan (ExecutionPlan* ep, size_t l) - : ExecutionPlan(ep), _offset(0), _limit(l) { - } - //////////////////////////////////////////////////////////////////////////////// /// @brief return the type of the node //////////////////////////////////////////////////////////////////////////////// @@ -408,7 +353,7 @@ namespace triagens { }; // ----------------------------------------------------------------------------- -// --SECTION-- class LimitPlan +// --SECTION-- class FilterPlan // ----------------------------------------------------------------------------- //////////////////////////////////////////////////////////////////////////////// @@ -427,11 +372,6 @@ namespace triagens { : ExecutionPlan(), _attribute(attribute), _value(value) { } - FilterPlan (ExecutionPlan* ep, std::string attribute, - triagens::basics::Json value) - : ExecutionPlan(ep), _attribute(attribute), _value(value) { - } - //////////////////////////////////////////////////////////////////////////////// /// @brief return the type of the node //////////////////////////////////////////////////////////////////////////////// @@ -475,6 +415,69 @@ namespace triagens { triagens::basics::Json _value; }; + +// ----------------------------------------------------------------------------- +// --SECTION-- class CalculationPlan +// ----------------------------------------------------------------------------- + +//////////////////////////////////////////////////////////////////////////////// +/// @brief class CalculationPlan, derived from ExecutionPlan +//////////////////////////////////////////////////////////////////////////////// + + class CalculationPlan : public ExecutionPlan { + +//////////////////////////////////////////////////////////////////////////////// +/// @brief constructors for various arguments, always with offset and limit +//////////////////////////////////////////////////////////////////////////////// + + public: + + CalculationPlan (AqlExpression* aqlExpression) + : ExecutionPlan(), _aqlExpression(aqlExpression) { + } + +//////////////////////////////////////////////////////////////////////////////// +/// @brief return the type of the node +//////////////////////////////////////////////////////////////////////////////// + + virtual NodeType getType () { + return CALCULATION; + } + +//////////////////////////////////////////////////////////////////////////////// +/// @brief return the type of the node as a string +//////////////////////////////////////////////////////////////////////////////// + + virtual std::string getTypeString () { + return std::string("CalculationPlan"); + } + +//////////////////////////////////////////////////////////////////////////////// +/// @brief export to JSON +//////////////////////////////////////////////////////////////////////////////// + + virtual triagens::basics::Json toJson ( + TRI_memory_zone_t* zone = TRI_UNKNOWN_MEM_ZONE); + +//////////////////////////////////////////////////////////////////////////////// +/// @brief clone execution plan recursively +//////////////////////////////////////////////////////////////////////////////// + + virtual ExecutionPlan* clone () { + auto c = new CalculationPlan(_aqlExpression->clone()); + cloneDependencies(c); + return static_cast(c); + } + +//////////////////////////////////////////////////////////////////////////////// +/// @brief we need to know the offset and limit +//////////////////////////////////////////////////////////////////////////////// + + private: + + AqlExpression* _aqlExpression; + + }; } // namespace triagens::aql } // namespace triagens diff --git a/arangod/Aql/Types.h b/arangod/Aql/Types.h new file mode 100644 index 0000000000..e9a3a246db --- /dev/null +++ b/arangod/Aql/Types.h @@ -0,0 +1,185 @@ +//////////////////////////////////////////////////////////////////////////////// +/// @brief fundamental types for the optimisation and execution of AQL +/// +/// @file arangod/Aql/Types.h +/// +/// DISCLAIMER +/// +/// Copyright 2010-2014 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 Max Neunhoeffer +/// @author Copyright 2014, triagens GmbH, Cologne, Germany +//////////////////////////////////////////////////////////////////////////////// + +#ifndef ARANGODB_AQL_TYPES_H +#define ARANGODB_AQL_TYPES_H 1 + +#include + +#include "VocBase/document-collection.h" +#include "Aql/AstNode.h" + +namespace triagens { + namespace aql { + +// ----------------------------------------------------------------------------- +// --SECTION-- AqlDocuments +// ----------------------------------------------------------------------------- + +//////////////////////////////////////////////////////////////////////////////// +/// @brief struct AqlDocument, used to pipe documents through executions +/// the execution engine keeps one AqlDocument struct for each document +/// that is piped through the engine. Note that the document can exist +/// in one of two formats throughout its lifetime in the engine. +/// When it resides originally in the WAl or a datafile, it stays +/// there unchanged and we only store a (pointer to) a copy of the +/// TRI_doc_mptr_t struct. Sometimes, when it is modified (or created +/// on the fly anyway), we keep the document as a TRI_json_t, wrapped +/// by a Json struct. That is, the following struct has the following +/// invariant: +/// Either the whole struct is empty and thus _json is empty and _mptr +/// is a nullptr. Otherwise, either _json is empty and _mptr is not a +/// nullptr, or _json is non-empty and _mptr is anullptr. +/// Additionally, the struct contains another TRI_json_t holding +/// the current state of the LET variables (and possibly some other +/// computations). This is the _vars attribute. +/// Note that both Json subobjects are constructed as AUTOFREE. +//////////////////////////////////////////////////////////////////////////////// + + struct AqlDocument { + triagens::basics::Json _json; + TRI_doc_mptr_copy_t* _mptr; + triagens::basics::Json _vars; + +//////////////////////////////////////////////////////////////////////////////// +/// @brief convenience constructors +//////////////////////////////////////////////////////////////////////////////// + + AqlDocument () + : _json(), _mptr(nullptr), _vars() { + } + + AqlDocument (TRI_doc_mptr_t* mptr) + : _json(), _vars() { + _mptr = new TRI_doc_mptr_copy_t(*mptr); + } + + AqlDocument (triagens::basics::Json json) + : _json(json), _mptr(nullptr), _vars() { + } + +//////////////////////////////////////////////////////////////////////////////// +/// @brief destructor +//////////////////////////////////////////////////////////////////////////////// + + ~AqlDocument () { + if (_mptr != nullptr) { + delete _mptr; + } + } + +//////////////////////////////////////////////////////////////////////////////// +/// @brief getValue, get the current value of a variable or attribute +//////////////////////////////////////////////////////////////////////////////// + + triagens::basics::Json getValue (std::string name); + +//////////////////////////////////////////////////////////////////////////////// +/// @brief setValue, set the current value of a variable or attribute +//////////////////////////////////////////////////////////////////////////////// + + void setValue (std::string name, triagens::basics::Json json); + + }; + +// ----------------------------------------------------------------------------- +// --SECTION-- AqlExpressions +// ----------------------------------------------------------------------------- + +//////////////////////////////////////////////////////////////////////////////// +/// @brief class AqlExpression, used in execution plans and execution blocks +//////////////////////////////////////////////////////////////////////////////// + + class AqlExpression { + + public: + +//////////////////////////////////////////////////////////////////////////////// +/// @brief default constructor, creating an empty expression +//////////////////////////////////////////////////////////////////////////////// + + AqlExpression () : _ast(nullptr) { + } + +//////////////////////////////////////////////////////////////////////////////// +/// @brief constructor, using an abstract syntax tree +//////////////////////////////////////////////////////////////////////////////// + + AqlExpression (AstNode* ast) : _ast(ast) { + } + +//////////////////////////////////////////////////////////////////////////////// +/// @brief destructor +//////////////////////////////////////////////////////////////////////////////// + + ~AqlExpression () { + } + +//////////////////////////////////////////////////////////////////////////////// +/// @brief getAst, get the underlying abstract syntax tree +//////////////////////////////////////////////////////////////////////////////// + + AstNode* getAst () { + return _ast; + } + +//////////////////////////////////////////////////////////////////////////////// +/// @brief clone the expression, needed to clone execution plans +//////////////////////////////////////////////////////////////////////////////// + + AqlExpression* clone (); + +//////////////////////////////////////////////////////////////////////////////// +/// @brief execute the expression +//////////////////////////////////////////////////////////////////////////////// + + triagens::basics::Json execute (AqlDocument* aqldoc); + +//////////////////////////////////////////////////////////////////////////////// +/// @brief private members +//////////////////////////////////////////////////////////////////////////////// + + private: + + // do we need a (possibly empty) subquery entry here? + AstNode* _ast; + + }; + + } // namespace triagens::aql +} // namespace triagens + + + +#endif + +// Local Variables: +// mode: outline-minor +// outline-regexp: "^\\(/// @brief\\|/// {@inheritDoc}\\|/// @addtogroup\\|// --SECTION--\\|/// @\\}\\)" +// End: + +