//////////////////////////////////////////////////////////////////////////////// /// @brief Infrastructure for ExecutionPlans /// /// @file arangod/Aql/ExecutionPlan.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_EXECUTION_PLAN_H #define ARANGODB_AQL_EXECUTION_PLAN_H 1 #include #include #include #include #include #include "Aql/Types.h" namespace triagens { namespace aql { class ExecutionBlock; //////////////////////////////////////////////////////////////////////////////// /// @brief class ExecutionPlan, abstract base class of all execution plans //////////////////////////////////////////////////////////////////////////////// class ExecutionPlan { //////////////////////////////////////////////////////////////////////////////// /// @brief node type //////////////////////////////////////////////////////////////////////////////// public: enum NodeType { ILLEGAL, SINGLETON, ENUMERATE_COLLECTION, INDEX_RANGE, STATIC_LIST, FILTER, LIMIT, INTERSECTION, PROJECTION, CALCULATION, SORT, AGGREGATE_ON_SORTED, AGGREGATE_ON_UNSORTED, LOOKUP_JOIN, MERGE_JOIN, LOOKUP_INDEX_UNIQUE, LOOKUP_INDEX_RANGE, LOOKUP_FULL_COLLECTION, CONCATENATION, MERGE, REMOTE, INSERT, REMOVE, REPLACE, UPDATE, ROOT }; // ----------------------------------------------------------------------------- // --SECTION-- public methods // ----------------------------------------------------------------------------- //////////////////////////////////////////////////////////////////////////////// /// @brief default constructor //////////////////////////////////////////////////////////////////////////////// ExecutionPlan () { } //////////////////////////////////////////////////////////////////////////////// /// @brief constructor with one dependency //////////////////////////////////////////////////////////////////////////////// ExecutionPlan (ExecutionPlan* ep) { _dependencies.push_back(ep); } //////////////////////////////////////////////////////////////////////////////// /// @brief destructor, free dependencies //////////////////////////////////////////////////////////////////////////////// virtual ~ExecutionPlan () { for (auto i = _dependencies.begin(); i != _dependencies.end(); ++i) { delete *i; } } //////////////////////////////////////////////////////////////////////////////// /// @brief return the type of the node //////////////////////////////////////////////////////////////////////////////// virtual NodeType getType () const { return ILLEGAL; } //////////////////////////////////////////////////////////////////////////////// /// @brief return the type of the node as a string //////////////////////////////////////////////////////////////////////////////// virtual std::string getTypeString () const { return std::string("ExecutionPlan (abstract)"); } //////////////////////////////////////////////////////////////////////////////// /// @brief add a dependency //////////////////////////////////////////////////////////////////////////////// void addDependency (ExecutionPlan* ep) { _dependencies.push_back(ep); } //////////////////////////////////////////////////////////////////////////////// /// @brief get all dependencies //////////////////////////////////////////////////////////////////////////////// vector getDependencies () const { return _dependencies; } //////////////////////////////////////////////////////////////////////////////// /// @brief remove a dependency, returns true if the pointer was found and /// removed, please note that this does not delete ep! //////////////////////////////////////////////////////////////////////////////// bool removeDependency (ExecutionPlan* ep) { auto it = _dependencies.begin(); while (it != _dependencies.end()) { if (*it == ep) { _dependencies.erase(it); return true; } ++it; } return false; } //////////////////////////////////////////////////////////////////////////////// /// @brief access the pos-th dependency //////////////////////////////////////////////////////////////////////////////// ExecutionPlan* operator[] (size_t pos) const { if (pos > _dependencies.size()) { return nullptr; } else { return _dependencies.at(pos); } } //////////////////////////////////////////////////////////////////////////////// /// @brief clone execution plan recursively, this makes the class abstract //////////////////////////////////////////////////////////////////////////////// virtual ExecutionPlan* clone () const = 0; // make class abstract //////////////////////////////////////////////////////////////////////////////// /// @brief helper for cloning, use virtual clone methods for dependencies //////////////////////////////////////////////////////////////////////////////// void cloneDependencies (ExecutionPlan* theClone) const { auto it = _dependencies.begin(); while (it != _dependencies.end()) { theClone->_dependencies.push_back((*it)->clone()); ++it; } } //////////////////////////////////////////////////////////////////////////////// /// @brief export to JSON, returns an AUTOFREE Json object //////////////////////////////////////////////////////////////////////////////// virtual triagens::basics::Json toJson ( TRI_memory_zone_t* zone = TRI_UNKNOWN_MEM_ZONE) const; //////////////////////////////////////////////////////////////////////////////// /// @brief convert to a string, basically for debugging purposes //////////////////////////////////////////////////////////////////////////////// virtual void appendAsString (std::string& st, int indent = 0); // ----------------------------------------------------------------------------- // --SECTION-- private variables // ----------------------------------------------------------------------------- //////////////////////////////////////////////////////////////////////////////// /// @brief our dependent nodes //////////////////////////////////////////////////////////////////////////////// protected: std::vector _dependencies; }; // ----------------------------------------------------------------------------- // --SECTION-- class SingletonPlan // ----------------------------------------------------------------------------- //////////////////////////////////////////////////////////////////////////////// /// @brief class SingletonPlan, derived from ExecutionPlan //////////////////////////////////////////////////////////////////////////////// class SingletonPlan : public ExecutionPlan { friend class SingletonBlock; //////////////////////////////////////////////////////////////////////////////// /// @brief constructor with a vocbase and a collection name //////////////////////////////////////////////////////////////////////////////// public: SingletonPlan (int32_t nrvars) : ExecutionPlan(), _nrVars(nrvars) { } //////////////////////////////////////////////////////////////////////////////// /// @brief return the type of the node //////////////////////////////////////////////////////////////////////////////// virtual NodeType getType () const { return SINGLETON; } //////////////////////////////////////////////////////////////////////////////// /// @brief return the type of the node as a string //////////////////////////////////////////////////////////////////////////////// virtual std::string getTypeString () const { return std::string("SingletonPlan"); } //////////////////////////////////////////////////////////////////////////////// /// @brief export to JSON //////////////////////////////////////////////////////////////////////////////// virtual triagens::basics::Json toJson ( TRI_memory_zone_t* zone = TRI_UNKNOWN_MEM_ZONE) const; //////////////////////////////////////////////////////////////////////////////// /// @brief clone execution plan recursively //////////////////////////////////////////////////////////////////////////////// virtual ExecutionPlan* clone () const { auto c = new SingletonPlan(_nrVars); cloneDependencies(c); return static_cast(c); } //////////////////////////////////////////////////////////////////////////////// /// @brief we need to know how many variables we have in this scope //////////////////////////////////////////////////////////////////////////////// private: int32_t _nrVars; }; // ----------------------------------------------------------------------------- // --SECTION-- class EnumerateCollectionPlan // ----------------------------------------------------------------------------- //////////////////////////////////////////////////////////////////////////////// /// @brief class EnumerateCollectionPlan, derived from ExecutionPlan //////////////////////////////////////////////////////////////////////////////// class EnumerateCollectionPlan : public ExecutionPlan { friend class EnumerateCollectionBlock; //////////////////////////////////////////////////////////////////////////////// /// @brief constructor with a vocbase and a collection name //////////////////////////////////////////////////////////////////////////////// public: EnumerateCollectionPlan (TRI_vocbase_t* vocbase, std::string collname, int32_t nrVars) : ExecutionPlan(), _vocbase(vocbase), _collname(collname), _nrVars(nrVars) { } //////////////////////////////////////////////////////////////////////////////// /// @brief return the type of the node //////////////////////////////////////////////////////////////////////////////// virtual NodeType getType () const { return ENUMERATE_COLLECTION; } //////////////////////////////////////////////////////////////////////////////// /// @brief return the type of the node as a string //////////////////////////////////////////////////////////////////////////////// virtual std::string getTypeString () const { return std::string("EnumerateCollectionPlan"); } //////////////////////////////////////////////////////////////////////////////// /// @brief export to JSON //////////////////////////////////////////////////////////////////////////////// virtual triagens::basics::Json toJson ( TRI_memory_zone_t* zone = TRI_UNKNOWN_MEM_ZONE) const; //////////////////////////////////////////////////////////////////////////////// /// @brief clone execution plan recursively //////////////////////////////////////////////////////////////////////////////// virtual ExecutionPlan* clone () const { auto c = new EnumerateCollectionPlan(_vocbase, _collname, _nrVars); cloneDependencies(c); return static_cast(c); } //////////////////////////////////////////////////////////////////////////////// /// @brief we need to know the database and the collection //////////////////////////////////////////////////////////////////////////////// private: TRI_vocbase_t* _vocbase; std::string _collname; int32_t _nrVars; }; // ----------------------------------------------------------------------------- // --SECTION-- class LimitPlan // ----------------------------------------------------------------------------- //////////////////////////////////////////////////////////////////////////////// /// @brief class LimitPlan, derived from ExecutionPlan //////////////////////////////////////////////////////////////////////////////// class LimitPlan : public ExecutionPlan { //////////////////////////////////////////////////////////////////////////////// /// @brief constructors for various arguments, always with offset and limit //////////////////////////////////////////////////////////////////////////////// public: LimitPlan (size_t o, size_t l) : ExecutionPlan(), _offset(o), _limit(l) { } LimitPlan (size_t l) : ExecutionPlan(), _offset(0), _limit(l) { } //////////////////////////////////////////////////////////////////////////////// /// @brief return the type of the node //////////////////////////////////////////////////////////////////////////////// virtual NodeType getType () const { return LIMIT; } //////////////////////////////////////////////////////////////////////////////// /// @brief return the type of the node as a string //////////////////////////////////////////////////////////////////////////////// virtual std::string getTypeString () const { return std::string("LimitPlan"); } //////////////////////////////////////////////////////////////////////////////// /// @brief export to JSON //////////////////////////////////////////////////////////////////////////////// virtual triagens::basics::Json toJson ( TRI_memory_zone_t* zone = TRI_UNKNOWN_MEM_ZONE) const; //////////////////////////////////////////////////////////////////////////////// /// @brief clone execution plan recursively //////////////////////////////////////////////////////////////////////////////// virtual ExecutionPlan* clone () const { auto c = new LimitPlan(_offset, _limit); cloneDependencies(c); return static_cast(c); } //////////////////////////////////////////////////////////////////////////////// /// @brief we need to know the offset and limit //////////////////////////////////////////////////////////////////////////////// private: size_t _offset; size_t _limit; }; // ----------------------------------------------------------------------------- // --SECTION-- class FilterPlan // ----------------------------------------------------------------------------- //////////////////////////////////////////////////////////////////////////////// /// @brief class FilterPlan, derived from ExecutionPlan //////////////////////////////////////////////////////////////////////////////// class FilterPlan : public ExecutionPlan { //////////////////////////////////////////////////////////////////////////////// /// @brief constructors for various arguments, always with offset and limit //////////////////////////////////////////////////////////////////////////////// public: FilterPlan (std::string attribute, triagens::basics::Json value) : ExecutionPlan(), _attribute(attribute), _value(value) { } //////////////////////////////////////////////////////////////////////////////// /// @brief return the type of the node //////////////////////////////////////////////////////////////////////////////// virtual NodeType getType () const { return FILTER; } //////////////////////////////////////////////////////////////////////////////// /// @brief return the type of the node as a string //////////////////////////////////////////////////////////////////////////////// virtual std::string getTypeString () const { return std::string("FilterPlan"); } //////////////////////////////////////////////////////////////////////////////// /// @brief export to JSON //////////////////////////////////////////////////////////////////////////////// virtual triagens::basics::Json toJson ( TRI_memory_zone_t* zone = TRI_UNKNOWN_MEM_ZONE) const; //////////////////////////////////////////////////////////////////////////////// /// @brief clone execution plan recursively //////////////////////////////////////////////////////////////////////////////// virtual ExecutionPlan* clone () const { auto c = new FilterPlan(_attribute, _value.copy()); cloneDependencies(c); return static_cast(c); } //////////////////////////////////////////////////////////////////////////////// /// @brief we need to know the offset and limit //////////////////////////////////////////////////////////////////////////////// private: std::string _attribute; 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 () const { return CALCULATION; } //////////////////////////////////////////////////////////////////////////////// /// @brief return the type of the node as a string //////////////////////////////////////////////////////////////////////////////// virtual std::string getTypeString () const { return std::string("CalculationPlan"); } //////////////////////////////////////////////////////////////////////////////// /// @brief export to JSON //////////////////////////////////////////////////////////////////////////////// virtual triagens::basics::Json toJson ( TRI_memory_zone_t* zone = TRI_UNKNOWN_MEM_ZONE) const; //////////////////////////////////////////////////////////////////////////////// /// @brief clone execution plan recursively //////////////////////////////////////////////////////////////////////////////// virtual ExecutionPlan* clone () const { auto c = new CalculationPlan(//_aqlExpression->clone()); _aqlExpression); cloneDependencies(c); return static_cast(c); } //////////////////////////////////////////////////////////////////////////////// /// @brief we need to know the offset and limit //////////////////////////////////////////////////////////////////////////////// private: AqlExpression* _aqlExpression; }; // ----------------------------------------------------------------------------- // --SECTION-- class RootPlan // ----------------------------------------------------------------------------- //////////////////////////////////////////////////////////////////////////////// /// @brief class RootPlan, derived from ExecutionPlan //////////////////////////////////////////////////////////////////////////////// class RootPlan : public ExecutionPlan { friend class RootBlock; //////////////////////////////////////////////////////////////////////////////// /// @brief constructors for various arguments, always with offset and limit //////////////////////////////////////////////////////////////////////////////// public: RootPlan () : ExecutionPlan(), dummy(0) { } //////////////////////////////////////////////////////////////////////////////// /// @brief return the type of the node //////////////////////////////////////////////////////////////////////////////// virtual NodeType getType () const { return ROOT; } //////////////////////////////////////////////////////////////////////////////// /// @brief return the type of the node as a string //////////////////////////////////////////////////////////////////////////////// virtual std::string getTypeString () const { return std::string("RootPlan"); } //////////////////////////////////////////////////////////////////////////////// /// @brief export to JSON //////////////////////////////////////////////////////////////////////////////// virtual triagens::basics::Json toJson ( TRI_memory_zone_t* zone = TRI_UNKNOWN_MEM_ZONE) const; //////////////////////////////////////////////////////////////////////////////// /// @brief clone execution plan recursively //////////////////////////////////////////////////////////////////////////////// virtual ExecutionPlan* clone () const { auto c = new RootPlan(); cloneDependencies(c); return static_cast(c); } //////////////////////////////////////////////////////////////////////////////// /// @brief we need to know the offset and limit //////////////////////////////////////////////////////////////////////////////// private: int dummy; }; } // namespace triagens::aql } // namespace triagens #endif // Local Variables: // mode: outline-minor // outline-regexp: "^\\(/// @brief\\|/// {@inheritDoc}\\|/// @addtogroup\\|// --SECTION--\\|/// @\\}\\)" // End: