mirror of https://gitee.com/bigwinds/arangodb
Merge branch 'aql2' of ssh://github.com/triAGENS/ArangoDB into aql2
This commit is contained in:
commit
43f96516a4
|
@ -33,9 +33,82 @@
|
|||
#include "Aql/Types.h"
|
||||
#include "Aql/ExecutionPlan.h"
|
||||
|
||||
struct TRI_json_s;
|
||||
|
||||
namespace triagens {
|
||||
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
|
||||
|
||||
|
|
|
@ -40,6 +40,8 @@
|
|||
namespace triagens {
|
||||
namespace aql {
|
||||
|
||||
class ExecutionBlock;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @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 ExecutionBlock* instanciate () = 0;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --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
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -226,6 +309,8 @@ namespace triagens {
|
|||
|
||||
class EnumerateCollectionPlan : public ExecutionPlan {
|
||||
|
||||
friend class EnumerateCollectionBlock;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief constructor with a vocbase and a collection name
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -269,6 +354,18 @@ namespace triagens {
|
|||
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
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -337,6 +434,14 @@ namespace triagens {
|
|||
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
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -401,6 +506,14 @@ namespace triagens {
|
|||
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
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -466,6 +579,14 @@ namespace triagens {
|
|||
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
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -37,12 +37,12 @@ namespace triagens {
|
|||
namespace aql {
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- AqlDocuments
|
||||
// --SECTION-- AqlValues
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief struct AqlDocument, used to pipe documents through executions
|
||||
/// the execution engine keeps one AqlDocument struct for each document
|
||||
/// @brief struct AqlValue, used to pipe documents through executions
|
||||
/// the execution engine keeps one AqlValue 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
|
||||
|
@ -60,25 +60,24 @@ namespace triagens {
|
|||
/// Note that both Json subobjects are constructed as AUTOFREE.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct AqlDocument {
|
||||
struct AqlValue {
|
||||
triagens::basics::Json _json;
|
||||
TRI_doc_mptr_copy_t* _mptr;
|
||||
TRI_doc_mptr_t* _mptr;
|
||||
triagens::basics::Json _vars;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief convenience constructors
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AqlDocument ()
|
||||
AqlValue ()
|
||||
: _json(), _mptr(nullptr), _vars() {
|
||||
}
|
||||
|
||||
AqlDocument (TRI_doc_mptr_t* mptr)
|
||||
: _json(), _vars() {
|
||||
_mptr = new TRI_doc_mptr_copy_t(*mptr);
|
||||
AqlValue (TRI_doc_mptr_t* mptr)
|
||||
: _json(), _mptr(mptr), _vars() {
|
||||
}
|
||||
|
||||
AqlDocument (triagens::basics::Json json)
|
||||
AqlValue (triagens::basics::Json json)
|
||||
: _json(json), _mptr(nullptr), _vars() {
|
||||
}
|
||||
|
||||
|
@ -86,12 +85,32 @@ namespace triagens {
|
|||
/// @brief destructor
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
~AqlDocument () {
|
||||
~AqlValue () {
|
||||
if (_mptr != nullptr) {
|
||||
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
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -157,7 +176,7 @@ namespace triagens {
|
|||
/// @brief execute the expression
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
triagens::basics::Json execute (AqlDocument* aqldoc);
|
||||
triagens::basics::Json execute (AqlValue* aqldoc);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief private members
|
||||
|
|
|
@ -34,6 +34,8 @@
|
|||
#include "Ahuacatl/ahuacatl-context.h"
|
||||
#include "Ahuacatl/ahuacatl-explain.h"
|
||||
#include "Ahuacatl/ahuacatl-result.h"
|
||||
#include "Aql/ExecutionPlan.h"
|
||||
#include "Aql/ExecutionBlock.h"
|
||||
#include "Aql/Query.h"
|
||||
#include "Basics/StringUtils.h"
|
||||
#include "Basics/Utf8Helper.h"
|
||||
|
@ -5395,6 +5397,42 @@ static v8::Handle<v8::Value> JS_ParseAql (v8::Arguments const& argv) {
|
|||
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
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -10710,6 +10748,7 @@ void TRI_InitV8VocBridge (v8::Handle<v8::Context> context,
|
|||
// new AQL functions. not intended to be used directly by end users
|
||||
TRI_AddGlobalFunctionVocbase(context, "AQL_EXECUTE", JS_ExecuteAql, 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
|
||||
TRI_AddGlobalFunctionVocbase(context, "CURSOR", JS_Cursor, true);
|
||||
|
|
|
@ -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
|
||||
/// a Json as argument because of the automatic type conversion
|
||||
/// 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).
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool isEmpty () throw() {
|
||||
bool isEmpty () const throw() {
|
||||
return _json == nullptr;
|
||||
}
|
||||
|
||||
|
@ -760,7 +760,7 @@ namespace triagens {
|
|||
/// @brief converts the Json recursively into a string.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::string toString () {
|
||||
std::string toString () const {
|
||||
if (_json != nullptr) {
|
||||
return JsonHelper::toString(_json);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue