1
0
Fork 0

pass ExecutionEngine to ExecutionBlock, added stats for ExecutionEngine

This commit is contained in:
Jan Steemann 2014-08-21 12:33:13 +02:00
parent 317c7870f0
commit 1442b9ebeb
11 changed files with 312 additions and 102 deletions

View File

@ -26,6 +26,7 @@
////////////////////////////////////////////////////////////////////////////////
#include "Aql/ExecutionBlock.h"
#include "Aql/ExecutionEngine.h"
#include "Basics/StringUtils.h"
#include "Basics/json-utilities.h"
#include "Utils/Exception.h"
@ -105,6 +106,20 @@ size_t const ExecutionBlock::DefaultBatchSize = 1000;
// --SECTION-- constructors / destructors
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief constructor
////////////////////////////////////////////////////////////////////////////////
ExecutionBlock::ExecutionBlock (ExecutionEngine* engine,
ExecutionNode const* ep)
: _engine(engine),
_trx(engine->getTransaction()),
_exeNode(ep),
_varOverview(nullptr),
_depth(0),
_done(false) {
}
////////////////////////////////////////////////////////////////////////////////
/// @brief destructor
////////////////////////////////////////////////////////////////////////////////
@ -513,9 +528,9 @@ int SingletonBlock::getOrSkipSome (size_t atLeast,
// --SECTION-- class EnumerateCollectionBlock
// -----------------------------------------------------------------------------
EnumerateCollectionBlock::EnumerateCollectionBlock (AQL_TRANSACTION_V8* trx,
EnumerateCollectionBlock::EnumerateCollectionBlock (ExecutionEngine* engine,
EnumerateCollectionNode const* ep)
: ExecutionBlock(trx, ep),
: ExecutionBlock(engine, ep),
_collection(ep->_collection),
_posInAllDocs(0) {
}
@ -1884,13 +1899,12 @@ AqlItemBlock* ReturnBlock::getSome (size_t atLeast,
// --SECTION-- class ModificationBlock
// -----------------------------------------------------------------------------
ModificationBlock::ModificationBlock (AQL_TRANSACTION_V8* trx,
ModificationBlock::ModificationBlock (ExecutionEngine* engine,
ModificationNode const* ep)
: ExecutionBlock(trx, ep),
: ExecutionBlock(engine, ep),
_collection(ep->_collection) {
}
ModificationBlock::~ModificationBlock () {
}
@ -1989,16 +2003,37 @@ int ModificationBlock::extractKey (AqlValue const& value,
return TRI_ERROR_ARANGO_DOCUMENT_KEY_MISSING;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief process the result of a data-modification operation
////////////////////////////////////////////////////////////////////////////////
void ModificationBlock::handleResult (int code,
bool ignoreErrors) {
if (code == TRI_ERROR_NO_ERROR) {
// update the success counter
++_engine->_stats.writesExecuted;
}
else {
if (ignoreErrors) {
// update the ignored counter
++_engine->_stats.writesIgnored;
}
else {
// bubble up the error
THROW_ARANGO_EXCEPTION(code);
}
}
}
// -----------------------------------------------------------------------------
// --SECTION-- class RemoveBlock
// -----------------------------------------------------------------------------
RemoveBlock::RemoveBlock (AQL_TRANSACTION_V8* trx,
RemoveBlock::RemoveBlock (ExecutionEngine* engine,
RemoveNode const* ep)
: ModificationBlock(trx, ep) {
: ModificationBlock(engine, ep) {
}
RemoveBlock::~RemoveBlock () {
}
@ -2055,12 +2090,8 @@ void RemoveBlock::work (std::vector<AqlItemBlock*>& blocks) {
nullptr,
ep->_options.waitForSync);
}
if (errorCode != TRI_ERROR_NO_ERROR &&
! ep->_options.ignoreErrors) {
// bubble up the error
THROW_ARANGO_EXCEPTION(errorCode);
}
handleResult(errorCode, ep->_options.ignoreErrors);
}
// done with a block
@ -2075,9 +2106,9 @@ void RemoveBlock::work (std::vector<AqlItemBlock*>& blocks) {
// --SECTION-- class InsertBlock
// -----------------------------------------------------------------------------
InsertBlock::InsertBlock (AQL_TRANSACTION_V8* trx,
InsertBlock::InsertBlock (ExecutionEngine* engine,
InsertNode const* ep)
: ModificationBlock(trx, ep) {
: ModificationBlock(engine, ep) {
}
InsertBlock::~InsertBlock () {
@ -2172,10 +2203,7 @@ void InsertBlock::work (std::vector<AqlItemBlock*>& blocks) {
}
}
if (errorCode != TRI_ERROR_NO_ERROR &&
! ep->_options.ignoreErrors) {
THROW_ARANGO_EXCEPTION(errorCode);
}
handleResult(errorCode, ep->_options.ignoreErrors);
}
// done with a block
@ -2190,9 +2218,9 @@ void InsertBlock::work (std::vector<AqlItemBlock*>& blocks) {
// --SECTION-- class UpdateBlock
// -----------------------------------------------------------------------------
UpdateBlock::UpdateBlock (AQL_TRANSACTION_V8* trx,
UpdateBlock::UpdateBlock (ExecutionEngine* engine,
UpdateNode const* ep)
: ModificationBlock(trx, ep) {
: ModificationBlock(engine, ep) {
}
UpdateBlock::~UpdateBlock () {
@ -2293,10 +2321,7 @@ void UpdateBlock::work (std::vector<AqlItemBlock*>& blocks) {
}
}
if (errorCode != TRI_ERROR_NO_ERROR &&
! ep->_options.ignoreErrors) {
THROW_ARANGO_EXCEPTION(errorCode);
}
handleResult(errorCode, ep->_options.ignoreErrors);
}
// done with a block
@ -2311,9 +2336,9 @@ void UpdateBlock::work (std::vector<AqlItemBlock*>& blocks) {
// --SECTION-- class ReplaceBlock
// -----------------------------------------------------------------------------
ReplaceBlock::ReplaceBlock (AQL_TRANSACTION_V8* trx,
ReplaceBlock::ReplaceBlock (ExecutionEngine* engine,
ReplaceNode const* ep)
: ModificationBlock(trx, ep) {
: ModificationBlock(engine, ep) {
}
ReplaceBlock::~ReplaceBlock () {
@ -2385,10 +2410,7 @@ void ReplaceBlock::work (std::vector<AqlItemBlock*>& blocks) {
errorCode = _trx->update(trxCollection, key, 0, &mptr, json.json(), TRI_DOC_UPDATE_LAST_WRITE, 0, nullptr, ep->_options.waitForSync);
}
if (errorCode != TRI_ERROR_NO_ERROR &&
! ep->_options.ignoreErrors) {
THROW_ARANGO_EXCEPTION(errorCode);
}
handleResult(errorCode, ep->_options.ignoreErrors);
}
// done with a block

View File

@ -43,6 +43,8 @@
namespace triagens {
namespace aql {
class ExecutionEngine;
// -----------------------------------------------------------------------------
// --SECTION-- AggregatorGroup
// -----------------------------------------------------------------------------
@ -99,11 +101,8 @@ namespace triagens {
/// @brief constructor
////////////////////////////////////////////////////////////////////////////////
ExecutionBlock (AQL_TRANSACTION_V8* trx,
ExecutionNode const* ep)
: _trx(trx), _exeNode(ep), _done(false), _depth(0),
_varOverview(nullptr) {
}
ExecutionBlock (ExecutionEngine*,
ExecutionNode const*);
////////////////////////////////////////////////////////////////////////////////
/// @brief destructor
@ -266,6 +265,7 @@ namespace triagens {
void inheritRegisters (AqlItemBlock const* src,
AqlItemBlock* dst,
size_t row);
////////////////////////////////////////////////////////////////////////////////
/// @brief the following is internal to pull one more block and append it to
/// our _buffer deque. Returns true if a new block was appended and false if
@ -332,6 +332,12 @@ namespace triagens {
AqlItemBlock*& result,
size_t& skipped);
////////////////////////////////////////////////////////////////////////////////
/// @brief the execution engine
////////////////////////////////////////////////////////////////////////////////
ExecutionEngine* _engine;
////////////////////////////////////////////////////////////////////////////////
/// @brief the transaction for this query
////////////////////////////////////////////////////////////////////////////////
@ -362,18 +368,18 @@ namespace triagens {
std::deque<AqlItemBlock*> _buffer;
////////////////////////////////////////////////////////////////////////////////
/// @brief info about variables, filled in by staticAnalysis
////////////////////////////////////////////////////////////////////////////////
std::shared_ptr<VarOverview> _varOverview;
////////////////////////////////////////////////////////////////////////////////
/// @brief current working position in the first entry of _buffer
////////////////////////////////////////////////////////////////////////////////
size_t _pos;
////////////////////////////////////////////////////////////////////////////////
/// @brief if this is set, we are done, this is reset to false by execute()
////////////////////////////////////////////////////////////////////////////////
bool _done;
////////////////////////////////////////////////////////////////////////////////
/// @brief depth of frames (number of FOR statements here or above)
////////////////////////////////////////////////////////////////////////////////
@ -381,10 +387,14 @@ namespace triagens {
int _depth; // will be filled in by staticAnalysis
////////////////////////////////////////////////////////////////////////////////
/// @brief info about variables, filled in by staticAnalysis
/// @brief if this is set, we are done, this is reset to false by execute()
////////////////////////////////////////////////////////////////////////////////
std::shared_ptr<VarOverview> _varOverview;
bool _done;
// -----------------------------------------------------------------------------
// --SECTION-- public variables
// -----------------------------------------------------------------------------
public:
@ -403,8 +413,10 @@ namespace triagens {
public:
SingletonBlock (AQL_TRANSACTION_V8* trx, SingletonNode const* ep)
: ExecutionBlock(trx, ep), _inputRegisterValues(nullptr) {
SingletonBlock (ExecutionEngine* engine,
SingletonNode const* ep)
: ExecutionBlock(engine, ep),
_inputRegisterValues(nullptr) {
}
~SingletonBlock () {
@ -467,7 +479,7 @@ namespace triagens {
public:
EnumerateCollectionBlock (AQL_TRANSACTION_V8* trx,
EnumerateCollectionBlock (ExecutionEngine* engine,
EnumerateCollectionNode const* ep);
~EnumerateCollectionBlock ();
@ -557,9 +569,9 @@ namespace triagens {
public:
EnumerateListBlock (AQL_TRANSACTION_V8* trx,
EnumerateListNode const* ep)
: ExecutionBlock(trx, ep) {
EnumerateListBlock (ExecutionEngine* engine,
EnumerateListNode const* ep)
: ExecutionBlock(engine, ep) {
}
@ -638,9 +650,9 @@ namespace triagens {
public:
CalculationBlock (AQL_TRANSACTION_V8* trx,
CalculationBlock (ExecutionEngine* engine,
CalculationNode const* en)
: ExecutionBlock(trx, en),
: ExecutionBlock(engine, en),
_expression(en->expression()),
_outReg(0) {
@ -668,11 +680,12 @@ namespace triagens {
virtual AqlItemBlock* getSome (size_t atLeast,
size_t atMost);
private:
////////////////////////////////////////////////////////////////////////////////
/// @brief we hold a pointer to the expression in the plan
////////////////////////////////////////////////////////////////////////////////
private:
Expression* _expression;
////////////////////////////////////////////////////////////////////////////////
@ -709,10 +722,11 @@ namespace triagens {
public:
SubqueryBlock (AQL_TRANSACTION_V8* trx,
SubqueryBlock (ExecutionEngine* engine,
SubqueryNode const* en,
ExecutionBlock* subquery)
: ExecutionBlock(trx, en), _outReg(0),
: ExecutionBlock(engine, en),
_outReg(0),
_subquery(subquery) {
}
@ -755,8 +769,9 @@ namespace triagens {
public:
FilterBlock (AQL_TRANSACTION_V8* trx, FilterNode const* ep)
: ExecutionBlock(trx, ep) {
FilterBlock (ExecutionEngine* engine,
FilterNode const* ep)
: ExecutionBlock(engine, ep) {
}
~FilterBlock () {
@ -822,9 +837,9 @@ namespace triagens {
public:
AggregateBlock (AQL_TRANSACTION_V8* trx,
AggregateBlock (ExecutionEngine* engine,
ExecutionNode const* ep)
: ExecutionBlock(trx, ep),
: ExecutionBlock(engine, ep),
_groupRegister(0),
_variableNames() {
}
@ -886,9 +901,9 @@ namespace triagens {
public:
SortBlock (AQL_TRANSACTION_V8* trx,
SortBlock (ExecutionEngine* engine,
ExecutionNode const* ep)
: ExecutionBlock(trx, ep),
: ExecutionBlock(engine, ep),
_stable(false) {
}
@ -955,8 +970,11 @@ namespace triagens {
public:
LimitBlock (AQL_TRANSACTION_V8* trx, LimitNode const* ep)
: ExecutionBlock(trx, ep), _offset(ep->_offset), _limit(ep->_limit),
LimitBlock (ExecutionEngine* engine,
LimitNode const* ep)
: ExecutionBlock(engine, ep),
_offset(ep->_offset),
_limit(ep->_limit),
_state(0) { // start in the beginning
}
@ -1010,8 +1028,9 @@ namespace triagens {
/// @brief constructor
////////////////////////////////////////////////////////////////////////////////
ReturnBlock (AQL_TRANSACTION_V8* trx, ReturnNode const* ep)
: ExecutionBlock(trx, ep) {
ReturnBlock (ExecutionEngine* engine,
ReturnNode const* ep)
: ExecutionBlock(engine, ep) {
}
@ -1043,7 +1062,8 @@ namespace triagens {
/// @brief constructor
////////////////////////////////////////////////////////////////////////////////
ModificationBlock (AQL_TRANSACTION_V8*, ModificationNode const*);
ModificationBlock (ExecutionEngine*,
ModificationNode const*);
////////////////////////////////////////////////////////////////////////////////
/// @brief destructor
@ -1086,6 +1106,13 @@ namespace triagens {
TRI_document_collection_t const*,
std::string&) const;
////////////////////////////////////////////////////////////////////////////////
/// @brief process the result of a data-modification operation
////////////////////////////////////////////////////////////////////////////////
void handleResult (int,
bool);
// -----------------------------------------------------------------------------
// --SECTION-- protected variables
// -----------------------------------------------------------------------------
@ -1100,7 +1127,6 @@ namespace triagens {
};
// -----------------------------------------------------------------------------
// --SECTION-- RemoveBlock
// -----------------------------------------------------------------------------
@ -1113,7 +1139,8 @@ namespace triagens {
/// @brief constructor
////////////////////////////////////////////////////////////////////////////////
RemoveBlock (AQL_TRANSACTION_V8* trx, RemoveNode const* ep);
RemoveBlock (ExecutionEngine*,
RemoveNode const*);
////////////////////////////////////////////////////////////////////////////////
/// @brief destructor
@ -1147,7 +1174,8 @@ namespace triagens {
/// @brief constructor
////////////////////////////////////////////////////////////////////////////////
InsertBlock (AQL_TRANSACTION_V8* trx, InsertNode const* ep);
InsertBlock (ExecutionEngine*,
InsertNode const*);
////////////////////////////////////////////////////////////////////////////////
/// @brief destructor
@ -1181,7 +1209,8 @@ namespace triagens {
/// @brief constructor
////////////////////////////////////////////////////////////////////////////////
UpdateBlock (AQL_TRANSACTION_V8* trx, UpdateNode const* ep);
UpdateBlock (ExecutionEngine*,
UpdateNode const*);
////////////////////////////////////////////////////////////////////////////////
/// @brief destructor
@ -1215,7 +1244,8 @@ namespace triagens {
/// @brief constructor
////////////////////////////////////////////////////////////////////////////////
ReplaceBlock (AQL_TRANSACTION_V8* trx, ReplaceNode const* ep);
ReplaceBlock (ExecutionEngine*,
ReplaceNode const*);
////////////////////////////////////////////////////////////////////////////////
/// @brief destructor
@ -1245,8 +1275,9 @@ namespace triagens {
public:
NoResultsBlock (AQL_TRANSACTION_V8* trx, SingletonNode const* ep)
: ExecutionBlock(trx, ep) {
NoResultsBlock (ExecutionEngine* engine,
SingletonNode const* ep)
: ExecutionBlock(engine, ep) {
}
~NoResultsBlock () {

View File

@ -45,7 +45,8 @@ using namespace triagens::aql;
////////////////////////////////////////////////////////////////////////////////
ExecutionEngine::ExecutionEngine (AQL_TRANSACTION_V8* trx)
: _blocks(),
: _stats(),
_blocks(),
_root(nullptr),
_trx(trx) {
@ -88,42 +89,42 @@ struct Instanciator : public WalkerWorker<ExecutionNode> {
switch (en->getType()) {
case ExecutionNode::SINGLETON: {
eb = new SingletonBlock(engine->getTransaction(),
eb = new SingletonBlock(engine,
static_cast<SingletonNode const*>(en));
break;
}
case ExecutionNode::ENUMERATE_COLLECTION: {
eb = new EnumerateCollectionBlock(engine->getTransaction(),
eb = new EnumerateCollectionBlock(engine,
static_cast<EnumerateCollectionNode const*>(en));
break;
}
case ExecutionNode::ENUMERATE_LIST: {
eb = new EnumerateListBlock(engine->getTransaction(),
eb = new EnumerateListBlock(engine,
static_cast<EnumerateListNode const*>(en));
break;
}
case ExecutionNode::CALCULATION: {
eb = new CalculationBlock(engine->getTransaction(),
eb = new CalculationBlock(engine,
static_cast<CalculationNode const*>(en));
break;
}
case ExecutionNode::FILTER: {
eb = new FilterBlock(engine->getTransaction(),
eb = new FilterBlock(engine,
static_cast<FilterNode const*>(en));
break;
}
case ExecutionNode::LIMIT: {
eb = new LimitBlock(engine->getTransaction(),
eb = new LimitBlock(engine,
static_cast<LimitNode const*>(en));
break;
}
case ExecutionNode::SORT: {
eb = new SortBlock(engine->getTransaction(),
eb = new SortBlock(engine,
static_cast<SortNode const*>(en));
break;
}
case ExecutionNode::AGGREGATE: {
eb = new AggregateBlock(engine->getTransaction(),
eb = new AggregateBlock(engine,
static_cast<AggregateNode const*>(en));
break;
}
@ -133,41 +134,41 @@ struct Instanciator : public WalkerWorker<ExecutionNode> {
TRI_ASSERT(it != cache.end());
eb = new SubqueryBlock(engine->getTransaction(),
eb = new SubqueryBlock(engine,
static_cast<SubqueryNode const*>(en),
it->second);
break;
}
case ExecutionNode::RETURN: {
eb = new ReturnBlock(engine->getTransaction(),
eb = new ReturnBlock(engine,
static_cast<ReturnNode const*>(en));
root = eb;
break;
}
case ExecutionNode::REMOVE: {
eb = new RemoveBlock(engine->getTransaction(),
eb = new RemoveBlock(engine,
static_cast<RemoveNode const*>(en));
root = eb;
break;
}
case ExecutionNode::INSERT: {
eb = new InsertBlock(engine->getTransaction(),
eb = new InsertBlock(engine,
static_cast<InsertNode const*>(en));
root = eb;
break;
}
case ExecutionNode::UPDATE: {
eb = new UpdateBlock(engine->getTransaction(),
eb = new UpdateBlock(engine,
static_cast<UpdateNode const*>(en));
root = eb;
break;
}
case ExecutionNode::REPLACE: {
eb = new ReplaceBlock(engine->getTransaction(),
eb = new ReplaceBlock(engine,
static_cast<ReplaceNode const*>(en));
root = eb;

View File

@ -35,6 +35,7 @@
#include "arangod/Aql/AqlItemBlock.h"
#include "arangod/Aql/ExecutionBlock.h"
#include "arangod/Aql/ExecutionPlan.h"
#include "arangod/Aql/ExecutionStats.h"
#include "Utils/AqlTransaction.h"
namespace triagens {
@ -124,7 +125,7 @@ namespace triagens {
/// @brief hasMore
////////////////////////////////////////////////////////////////////////////////
bool hasMore () {
inline bool hasMore () const {
return _root->hasMore();
}
@ -132,7 +133,7 @@ namespace triagens {
/// @brief count
////////////////////////////////////////////////////////////////////////////////
int64_t count () {
inline int64_t count () const {
return _root->count();
}
@ -140,7 +141,7 @@ namespace triagens {
/// @brief remaining
////////////////////////////////////////////////////////////////////////////////
int64_t remaining () {
inline int64_t remaining () const {
return _root->remaining();
}
@ -150,6 +151,19 @@ namespace triagens {
void addBlock (ExecutionBlock*);
// -----------------------------------------------------------------------------
// --SECTION-- public variables
// -----------------------------------------------------------------------------
public:
////////////////////////////////////////////////////////////////////////////////
/// @brief execution statistics for the query
/// note that the statistics are modification by execution blocks
////////////////////////////////////////////////////////////////////////////////
ExecutionStats _stats;
// -----------------------------------------------------------------------------
// --SECTION-- private variables
// -----------------------------------------------------------------------------

View File

@ -0,0 +1,58 @@
////////////////////////////////////////////////////////////////////////////////
/// @brief Aql, execution statistics
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2014 ArangoDB GmbH, Cologne, Germany
/// Copyright 2004-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 ArangoDB GmbH, Cologne, Germany
///
/// @author Jan Steemann
/// @author Copyright 2014, ArangoDB GmbH, Cologne, Germany
/// @author Copyright 2012-2013, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////
#include "Aql/ExecutionStats.h"
using namespace triagens::aql;
using Json = triagens::basics::Json;
// -----------------------------------------------------------------------------
// --SECTION-- public methods
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief convert the statistics to JSON
////////////////////////////////////////////////////////////////////////////////
Json ExecutionStats::toJson () const {
Json json(Json::Array);
json.set("writesExecuted", Json(static_cast<double>(writesExecuted)));
json.set("writesIgnored", Json(static_cast<double>(writesIgnored)));
return json;
}
// -----------------------------------------------------------------------------
// --SECTION-- END-OF-FILE
// -----------------------------------------------------------------------------
// Local Variables:
// mode: outline-minor
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}"
// End:

View File

@ -0,0 +1,73 @@
////////////////////////////////////////////////////////////////////////////////
/// @brief Aql, execution statistics
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2014 ArangoDB GmbH, Cologne, Germany
/// Copyright 2004-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 ArangoDB GmbH, Cologne, Germany
///
/// @author Jan Steemann
/// @author Copyright 2014, ArangoDB GmbH, Cologne, Germany
/// @author Copyright 2012-2013, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////
#ifndef ARANGODB_AQL_EXECUTION_STATS_H
#define ARANGODB_AQL_EXECUTION_STATS_H 1
#include "Basics/Common.h"
#include "Basics/JsonHelper.h"
namespace triagens {
namespace aql {
struct ExecutionStats {
////////////////////////////////////////////////////////////////////////////////
/// @brief convert the statistics to JSON
////////////////////////////////////////////////////////////////////////////////
triagens::basics::Json toJson () const;
////////////////////////////////////////////////////////////////////////////////
/// @brief counter for successfully executed write operations
////////////////////////////////////////////////////////////////////////////////
int64_t writesExecuted = 0;
////////////////////////////////////////////////////////////////////////////////
/// @brief counter for ignored write operations (ignore due to errors)
////////////////////////////////////////////////////////////////////////////////
int64_t writesIgnored = 0;
};
}
}
#endif
// -----------------------------------------------------------------------------
// --SECTION-- END-OF-FILE
// -----------------------------------------------------------------------------
// Local Variables:
// mode: outline-minor
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}"
// End:

View File

@ -248,6 +248,7 @@ QueryResult Query::execute () {
plan = opt.stealBest(); // Now we own the best one again
triagens::basics::Json json(triagens::basics::Json::List);
triagens::basics::Json stats;
try {
auto engine = ExecutionEngine::instanciateFromPlan(&trx, plan);
@ -268,6 +269,8 @@ QueryResult Query::execute () {
delete value;
}
stats = engine->_stats.toJson();
delete engine;
}
catch (...) {
@ -284,7 +287,8 @@ QueryResult Query::execute () {
trx.commit();
QueryResult result(TRI_ERROR_NO_ERROR);
result.json = json.steal();
result.json = json.steal();
result.stats = stats.steal();
return result;
}
catch (triagens::arango::Exception const& ex) {

View File

@ -47,8 +47,11 @@ namespace triagens {
code = other.code;
details = other.details;
json = other.json;
stats = other.stats;
zone = other.zone;
other.json = nullptr;
other.stats = nullptr;
}
QueryResult (int code,
@ -56,27 +59,25 @@ namespace triagens {
: code(code),
details(details),
zone(TRI_UNKNOWN_MEM_ZONE),
json(nullptr) {
json(nullptr),
stats(nullptr) {
}
explicit QueryResult (int code)
: code(code),
details(""),
zone(TRI_UNKNOWN_MEM_ZONE),
json(nullptr) {
: QueryResult(code, "") {
}
QueryResult ()
: code(TRI_ERROR_NO_ERROR),
details(),
zone(TRI_UNKNOWN_MEM_ZONE),
json(nullptr) {
: QueryResult(TRI_ERROR_NO_ERROR) {
}
~QueryResult () {
if (json != nullptr) {
TRI_FreeJson(zone, json);
}
if (stats != nullptr) {
TRI_FreeJson(zone, stats);
}
}
int code;
@ -85,6 +86,7 @@ namespace triagens {
std::vector<std::string> collectionNames;
TRI_memory_zone_t* zone;
TRI_json_t* json;
TRI_json_t* stats;
};
}

View File

@ -66,6 +66,7 @@ add_executable(
Aql/ExecutionEngine.cpp
Aql/ExecutionNode.cpp
Aql/ExecutionPlan.cpp
Aql/ExecutionStats.cpp
Aql/Expression.cpp
Aql/Function.cpp
Aql/grammar.cpp

View File

@ -47,6 +47,7 @@ arangod_libarangod_a_SOURCES = \
arangod/Aql/ExecutionEngine.cpp \
arangod/Aql/ExecutionNode.cpp \
arangod/Aql/ExecutionPlan.cpp \
arangod/Aql/ExecutionStats.cpp \
arangod/Aql/Expression.cpp \
arangod/Aql/Function.cpp \
arangod/Aql/grammar.cpp \

View File

@ -1063,6 +1063,9 @@ static v8::Handle<v8::Value> JS_ExecuteAql (v8::Arguments const& argv) {
if (queryResult.json != nullptr) {
result->Set(TRI_V8_STRING("json"), TRI_ObjectJson(queryResult.json));
}
if (queryResult.stats != nullptr) {
result->Set(TRI_V8_STRING("stats"), TRI_ObjectJson(queryResult.stats));
}
return scope.Close(result);
}