1
0
Fork 0

Merge branch 'aql2' of ssh://github.com/triAGENS/ArangoDB into aql2

This commit is contained in:
Max Neunhoeffer 2014-07-28 15:52:45 +02:00
commit 43f96516a4
5 changed files with 267 additions and 15 deletions

View File

@ -33,9 +33,82 @@
#include "Aql/Types.h" #include "Aql/Types.h"
#include "Aql/ExecutionPlan.h" #include "Aql/ExecutionPlan.h"
struct TRI_json_s;
namespace triagens { namespace triagens {
namespace aql { namespace aql {
class ExecutionBlock {
public:
ExecutionBlock (ExecutionPlan const* ep)
: _exePlan(ep) { }
virtual ~ExecutionBlock () {
std::cout << "EXECUTIONBLOCK DTOR\n";
for (auto i = _dependencies.begin(); i != _dependencies.end(); ++i) {
delete *i;
}
}
// Methods for execution:
int initialise () {
return TRI_ERROR_NO_ERROR;
}
int bind (std::map<std::string, struct TRI_json_s*>* params);
std::map<std::string, struct TRI_json_s*>* getParameters ();
int execute () {
return TRI_ERROR_NO_ERROR;
}
int shutdown () {
return TRI_ERROR_NO_ERROR;
}
virtual AqlValue* getOne () = 0;
std::vector<AqlValue*> getSome (int atLeast, int atMost);
bool skip (int number);
int64_t count ();
int64_t remaining ();
protected:
ExecutionPlan const* _exePlan;
std::vector<ExecutionBlock*> _dependencies;
std::deque<AqlValue*> _buffer;
};
class EnumerateCollectionBlock : public ExecutionBlock {
public:
EnumerateCollectionBlock (EnumerateCollectionPlan const* ep)
: ExecutionBlock(ep) {
}
~EnumerateCollectionBlock () {
std::cout << "ENUMERATECOLLECTIONBLOCK DTOR\n";
}
AqlValue* getOne () {
if (_buffer.empty()) {
}
auto value = _buffer.front();
_buffer.pop_front();
return value;
}
};
} // namespace triagens::aql } // namespace triagens::aql
} // namespace triagens } // namespace triagens

View File

@ -40,6 +40,8 @@
namespace triagens { namespace triagens {
namespace aql { namespace aql {
class ExecutionBlock;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief class ExecutionPlan, abstract base class of all execution plans /// @brief class ExecutionPlan, abstract base class of all execution plans
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -202,6 +204,9 @@ namespace triagens {
virtual void appendAsString (std::string& st, int indent = 0); virtual void appendAsString (std::string& st, int indent = 0);
virtual ExecutionBlock* instanciate () = 0;
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// --SECTION-- private variables // --SECTION-- private variables
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -216,6 +221,84 @@ namespace triagens {
}; };
// -----------------------------------------------------------------------------
// --SECTION-- class RootPlan
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief class RootPlan, derived from ExecutionPlan
////////////////////////////////////////////////////////////////////////////////
class RootPlan : public ExecutionPlan {
friend class RootBlock;
////////////////////////////////////////////////////////////////////////////////
/// @brief constructor
////////////////////////////////////////////////////////////////////////////////
public:
RootPlan ()
: ExecutionPlan() {
}
////////////////////////////////////////////////////////////////////////////////
/// @brief return the type of the node
////////////////////////////////////////////////////////////////////////////////
virtual NodeType getType () {
return ROOT;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief return the type of the node as a string
////////////////////////////////////////////////////////////////////////////////
virtual std::string getTypeString () {
return std::string("RootPlan");
}
////////////////////////////////////////////////////////////////////////////////
/// @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 RootPlan();
cloneDependencies(c);
return static_cast<ExecutionPlan*>(c);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief turn the plan node into an execution block node
////////////////////////////////////////////////////////////////////////////////
ExecutionBlock* instanciate () {
return nullptr;
}
// -----------------------------------------------------------------------------
// --SECTION-- private variables
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief we need to know the database and the collection
////////////////////////////////////////////////////////////////////////////////
private:
TRI_vocbase_t* _vocbase;
std::string _collname;
};
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// --SECTION-- class EnumerateCollectionPlan // --SECTION-- class EnumerateCollectionPlan
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -226,6 +309,8 @@ namespace triagens {
class EnumerateCollectionPlan : public ExecutionPlan { class EnumerateCollectionPlan : public ExecutionPlan {
friend class EnumerateCollectionBlock;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief constructor with a vocbase and a collection name /// @brief constructor with a vocbase and a collection name
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -269,6 +354,18 @@ namespace triagens {
return static_cast<ExecutionPlan*>(c); return static_cast<ExecutionPlan*>(c);
} }
////////////////////////////////////////////////////////////////////////////////
/// @brief turn the plan node into an execution block node
////////////////////////////////////////////////////////////////////////////////
ExecutionBlock* instanciate () {
return nullptr;
}
// -----------------------------------------------------------------------------
// --SECTION-- private variables
// -----------------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief we need to know the database and the collection /// @brief we need to know the database and the collection
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -337,6 +434,14 @@ namespace triagens {
return static_cast<ExecutionPlan*>(c); return static_cast<ExecutionPlan*>(c);
} }
////////////////////////////////////////////////////////////////////////////////
/// @brief turn the plan node into an execution block node
////////////////////////////////////////////////////////////////////////////////
ExecutionBlock* instanciate () {
return nullptr;
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief we need to know the offset and limit /// @brief we need to know the offset and limit
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -401,6 +506,14 @@ namespace triagens {
return static_cast<ExecutionPlan*>(c); return static_cast<ExecutionPlan*>(c);
} }
////////////////////////////////////////////////////////////////////////////////
/// @brief turn the plan node into an execution block node
////////////////////////////////////////////////////////////////////////////////
ExecutionBlock* instanciate () {
return nullptr;
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief we need to know the offset and limit /// @brief we need to know the offset and limit
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -466,6 +579,14 @@ namespace triagens {
return static_cast<ExecutionPlan*>(c); return static_cast<ExecutionPlan*>(c);
} }
////////////////////////////////////////////////////////////////////////////////
/// @brief turn the plan node into an execution block node
////////////////////////////////////////////////////////////////////////////////
ExecutionBlock* instanciate () {
return nullptr;
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief we need to know the offset and limit /// @brief we need to know the offset and limit
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View File

@ -37,12 +37,12 @@ namespace triagens {
namespace aql { namespace aql {
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// --SECTION-- AqlDocuments // --SECTION-- AqlValues
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief struct AqlDocument, used to pipe documents through executions /// @brief struct AqlValue, used to pipe documents through executions
/// the execution engine keeps one AqlDocument struct for each document /// the execution engine keeps one AqlValue struct for each document
/// that is piped through the engine. Note that the document can exist /// that is piped through the engine. Note that the document can exist
/// in one of two formats throughout its lifetime in the engine. /// in one of two formats throughout its lifetime in the engine.
/// When it resides originally in the WAl or a datafile, it stays /// When it resides originally in the WAl or a datafile, it stays
@ -60,25 +60,24 @@ namespace triagens {
/// Note that both Json subobjects are constructed as AUTOFREE. /// Note that both Json subobjects are constructed as AUTOFREE.
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
struct AqlDocument { struct AqlValue {
triagens::basics::Json _json; triagens::basics::Json _json;
TRI_doc_mptr_copy_t* _mptr; TRI_doc_mptr_t* _mptr;
triagens::basics::Json _vars; triagens::basics::Json _vars;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief convenience constructors /// @brief convenience constructors
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
AqlDocument () AqlValue ()
: _json(), _mptr(nullptr), _vars() { : _json(), _mptr(nullptr), _vars() {
} }
AqlDocument (TRI_doc_mptr_t* mptr) AqlValue (TRI_doc_mptr_t* mptr)
: _json(), _vars() { : _json(), _mptr(mptr), _vars() {
_mptr = new TRI_doc_mptr_copy_t(*mptr);
} }
AqlDocument (triagens::basics::Json json) AqlValue (triagens::basics::Json json)
: _json(json), _mptr(nullptr), _vars() { : _json(json), _mptr(nullptr), _vars() {
} }
@ -86,12 +85,32 @@ namespace triagens {
/// @brief destructor /// @brief destructor
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
~AqlDocument () { ~AqlValue () {
if (_mptr != nullptr) { if (_mptr != nullptr) {
delete _mptr; delete _mptr;
} }
} }
////////////////////////////////////////////////////////////////////////////////
/// @brief return a string representation of the value
////////////////////////////////////////////////////////////////////////////////
std::string toString () const {
std::string out;
if (! _json.isEmpty()) {
out += _json.toString();
}
else if (_mptr != nullptr) {
out.append("got a master pointer");
}
if (! _vars.isEmpty()) {
out += _vars.toString();
}
return out;
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief getValue, get the current value of a variable or attribute /// @brief getValue, get the current value of a variable or attribute
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -157,7 +176,7 @@ namespace triagens {
/// @brief execute the expression /// @brief execute the expression
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
triagens::basics::Json execute (AqlDocument* aqldoc); triagens::basics::Json execute (AqlValue* aqldoc);
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief private members /// @brief private members

View File

@ -34,6 +34,8 @@
#include "Ahuacatl/ahuacatl-context.h" #include "Ahuacatl/ahuacatl-context.h"
#include "Ahuacatl/ahuacatl-explain.h" #include "Ahuacatl/ahuacatl-explain.h"
#include "Ahuacatl/ahuacatl-result.h" #include "Ahuacatl/ahuacatl-result.h"
#include "Aql/ExecutionPlan.h"
#include "Aql/ExecutionBlock.h"
#include "Aql/Query.h" #include "Aql/Query.h"
#include "Basics/StringUtils.h" #include "Basics/StringUtils.h"
#include "Basics/Utf8Helper.h" #include "Basics/Utf8Helper.h"
@ -5395,6 +5397,42 @@ static v8::Handle<v8::Value> JS_ParseAql (v8::Arguments const& argv) {
return scope.Close(result); return scope.Close(result);
} }
////////////////////////////////////////////////////////////////////////////////
/// @brief peng an AQL query
////////////////////////////////////////////////////////////////////////////////
static v8::Handle<v8::Value> JS_PengAql (v8::Arguments const& argv) {
v8::HandleScope scope;
TRI_vocbase_t* vocbase = GetContextVocBase();
if (vocbase == nullptr) {
TRI_V8_EXCEPTION(scope, TRI_ERROR_ARANGO_DATABASE_NOT_FOUND);
}
if (argv.Length() != 0) {
TRI_V8_EXCEPTION_USAGE(scope, "AQL_PENG()");
}
triagens::aql::ExecutionPlan* enumPlan = new triagens::aql::EnumerateCollectionPlan(vocbase, "fuxx");
triagens::aql::ExecutionPlan* rootPlan = new triagens::aql::RootPlan();
rootPlan->addDependency(enumPlan);
triagens::aql::ExecutionBlock* exec = rootPlan->instanciate();
exec->initialise();
exec->execute();
triagens::aql::AqlValue* value;
while (nullptr != (value = exec->getOne())) {
std::cout << value->toString();
delete value;
}
exec->shutdown();
return scope.Close(v8::Undefined());
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief executes an AQL query /// @brief executes an AQL query
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -10710,6 +10748,7 @@ void TRI_InitV8VocBridge (v8::Handle<v8::Context> context,
// new AQL functions. not intended to be used directly by end users // new AQL functions. not intended to be used directly by end users
TRI_AddGlobalFunctionVocbase(context, "AQL_EXECUTE", JS_ExecuteAql, true); TRI_AddGlobalFunctionVocbase(context, "AQL_EXECUTE", JS_ExecuteAql, true);
TRI_AddGlobalFunctionVocbase(context, "AQL_PARSE", JS_ParseAql, true); TRI_AddGlobalFunctionVocbase(context, "AQL_PARSE", JS_ParseAql, true);
TRI_AddGlobalFunctionVocbase(context, "AQL_PENG", JS_PengAql, true);
// cursor functions. not intended to be used by end users // cursor functions. not intended to be used by end users
TRI_AddGlobalFunctionVocbase(context, "CURSOR", JS_Cursor, true); TRI_AddGlobalFunctionVocbase(context, "CURSOR", JS_Cursor, true);

View File

@ -615,7 +615,7 @@ namespace triagens {
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief append an Json value to the end of a Json list, an exception /// @brief append a Json value to the end of a Json list, an exception
/// is thrown if *this is not a Json list. Note that you can call this with /// is thrown if *this is not a Json list. Note that you can call this with
/// a Json as argument because of the automatic type conversion /// a Json as argument because of the automatic type conversion
/// to TRI_json_t* with steal semantics. Therefore /// to TRI_json_t* with steal semantics. Therefore
@ -752,7 +752,7 @@ namespace triagens {
/// @brief checks whether *this is an empty Json (not even null). /// @brief checks whether *this is an empty Json (not even null).
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
bool isEmpty () throw() { bool isEmpty () const throw() {
return _json == nullptr; return _json == nullptr;
} }
@ -760,7 +760,7 @@ namespace triagens {
/// @brief converts the Json recursively into a string. /// @brief converts the Json recursively into a string.
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
std::string toString () { std::string toString () const {
if (_json != nullptr) { if (_json != nullptr) {
return JsonHelper::toString(_json); return JsonHelper::toString(_json);
} }