1
0
Fork 0

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

This commit is contained in:
Frank Celler 2014-10-23 11:30:45 +02:00
commit 25bb5dac94
21 changed files with 447 additions and 270 deletions

View File

@ -44,6 +44,14 @@ using Json = triagens::basics::Json;
using JsonHelper = triagens::basics::JsonHelper;
using StringBuffer = triagens::basics::StringBuffer;
#ifdef TRI_ENABLE_MAINTAINER_MODE
#define ENTER_BLOCK try { (void) 0;
#define LEAVE_BLOCK } catch (...) { std::cout << "caught an exception in " << __FUNCTION__ << ", " << __FILE__ << ":" << __LINE__ << "!\n"; throw; }
#else
#define ENTER_BLOCK
#define LEAVE_BLOCK
#endif
// -----------------------------------------------------------------------------
// --SECTION-- struct AggregatorGroup
// -----------------------------------------------------------------------------
@ -234,9 +242,8 @@ int ExecutionBlock::initialize () {
/// @brief shutdown, will be called exactly once for the whole query
////////////////////////////////////////////////////////////////////////////////
int ExecutionBlock::shutdown () {
int ExecutionBlock::shutdown (int errorCode) {
int ret = TRI_ERROR_NO_ERROR;
int res;
for (auto it = _buffer.begin(); it != _buffer.end(); ++it) {
delete *it;
@ -244,8 +251,9 @@ int ExecutionBlock::shutdown () {
_buffer.clear();
for (auto it = _dependencies.begin(); it != _dependencies.end(); ++it) {
int res;
try {
res = (*it)->shutdown();
res = (*it)->shutdown(errorCode);
}
catch (...) {
res = TRI_ERROR_INTERNAL;
@ -558,12 +566,18 @@ int SingletonBlock::initializeCursor (AqlItemBlock* items, size_t pos) {
return TRI_ERROR_NO_ERROR;
}
int SingletonBlock::shutdown () {
int res = ExecutionBlock::shutdown();
////////////////////////////////////////////////////////////////////////////////
/// @brief shutdown the singleton block
////////////////////////////////////////////////////////////////////////////////
int SingletonBlock::shutdown (int errorCode) {
int res = ExecutionBlock::shutdown(errorCode);
if (_inputRegisterValues != nullptr) {
delete _inputRegisterValues;
_inputRegisterValues = nullptr;
}
return res;
}
@ -2330,6 +2344,7 @@ int AggregateBlock::getOrSkipSome (size_t atLeast,
_pos = 0;
bool hasMore = ! _buffer.empty();
if (! hasMore) {
hasMore = ExecutionBlock::getBlock(atLeast, atMost);
}
@ -3308,6 +3323,7 @@ GatherBlock::GatherBlock (ExecutionEngine* engine,
////////////////////////////////////////////////////////////////////////////////
GatherBlock::~GatherBlock () {
ENTER_BLOCK
for (std::deque<AqlItemBlock*>& x : _gatherBlockBuffer) {
for (AqlItemBlock* y: x) {
delete y;
@ -3315,6 +3331,7 @@ GatherBlock::~GatherBlock () {
x.clear();
}
_gatherBlockBuffer.clear();
LEAVE_BLOCK
}
////////////////////////////////////////////////////////////////////////////////
@ -3322,6 +3339,7 @@ GatherBlock::~GatherBlock () {
////////////////////////////////////////////////////////////////////////////////
int GatherBlock::initialize () {
ENTER_BLOCK
auto res = ExecutionBlock::initialize();
if (res != TRI_ERROR_NO_ERROR) {
@ -3329,17 +3347,19 @@ int GatherBlock::initialize () {
}
return TRI_ERROR_NO_ERROR;
LEAVE_BLOCK
}
////////////////////////////////////////////////////////////////////////////////
/// @brief shutdown: need our own method since our _buffer is different
////////////////////////////////////////////////////////////////////////////////
int GatherBlock::shutdown () {
int GatherBlock::shutdown (int errorCode) {
ENTER_BLOCK
// don't call default shutdown method since it does the wrong thing to
// _gatherBlockBuffer
for (auto it = _dependencies.begin(); it != _dependencies.end(); ++it) {
int res = (*it)->shutdown();
int res = (*it)->shutdown(errorCode);
if (res != TRI_ERROR_NO_ERROR) {
return res;
@ -3355,6 +3375,7 @@ int GatherBlock::shutdown () {
_gatherBlockBuffer.clear();
return TRI_ERROR_NO_ERROR;
LEAVE_BLOCK
}
////////////////////////////////////////////////////////////////////////////////
@ -3362,6 +3383,7 @@ int GatherBlock::shutdown () {
////////////////////////////////////////////////////////////////////////////////
int GatherBlock::initializeCursor (AqlItemBlock* items, size_t pos) {
ENTER_BLOCK
int res = ExecutionBlock::initializeCursor(items, pos);
if (res != TRI_ERROR_NO_ERROR) {
@ -3388,6 +3410,7 @@ int GatherBlock::initializeCursor (AqlItemBlock* items, size_t pos) {
_done = false;
return TRI_ERROR_NO_ERROR;
LEAVE_BLOCK
}
////////////////////////////////////////////////////////////////////////////////
@ -3396,6 +3419,7 @@ int GatherBlock::initializeCursor (AqlItemBlock* items, size_t pos) {
////////////////////////////////////////////////////////////////////////////////
int64_t GatherBlock::count () const {
ENTER_BLOCK
int64_t sum = 0;
for (auto x: _dependencies) {
if (x->count() == -1) {
@ -3404,6 +3428,7 @@ int64_t GatherBlock::count () const {
sum += x->count();
}
return sum;
LEAVE_BLOCK
}
////////////////////////////////////////////////////////////////////////////////
@ -3412,6 +3437,7 @@ int64_t GatherBlock::count () const {
////////////////////////////////////////////////////////////////////////////////
int64_t GatherBlock::remaining () {
ENTER_BLOCK
int64_t sum = 0;
for (auto x : _dependencies) {
if (x->remaining() == -1) {
@ -3420,6 +3446,7 @@ int64_t GatherBlock::remaining () {
sum += x->remaining();
}
return sum;
LEAVE_BLOCK
}
////////////////////////////////////////////////////////////////////////////////
@ -3428,6 +3455,7 @@ int64_t GatherBlock::remaining () {
////////////////////////////////////////////////////////////////////////////////
bool GatherBlock::hasMore () {
ENTER_BLOCK
if (_done) {
return false;
}
@ -3452,6 +3480,7 @@ bool GatherBlock::hasMore () {
}
_done = true;
return false;
LEAVE_BLOCK
}
////////////////////////////////////////////////////////////////////////////////
@ -3459,6 +3488,7 @@ bool GatherBlock::hasMore () {
////////////////////////////////////////////////////////////////////////////////
AqlItemBlock* GatherBlock::getSome (size_t atLeast, size_t atMost) {
ENTER_BLOCK
if (_done) {
return nullptr;
}
@ -3572,6 +3602,7 @@ AqlItemBlock* GatherBlock::getSome (size_t atLeast, size_t atMost) {
}
return res.release();
LEAVE_BLOCK
}
////////////////////////////////////////////////////////////////////////////////
@ -3579,6 +3610,7 @@ AqlItemBlock* GatherBlock::getSome (size_t atLeast, size_t atMost) {
////////////////////////////////////////////////////////////////////////////////
size_t GatherBlock::skipSome (size_t atLeast, size_t atMost) {
ENTER_BLOCK
if (_done) {
return 0;
}
@ -3655,6 +3687,7 @@ size_t GatherBlock::skipSome (size_t atLeast, size_t atMost) {
}
return skipped;
LEAVE_BLOCK
}
////////////////////////////////////////////////////////////////////////////////
@ -3663,6 +3696,7 @@ size_t GatherBlock::skipSome (size_t atLeast, size_t atMost) {
////////////////////////////////////////////////////////////////////////////////
bool GatherBlock::getBlock (size_t i, size_t atLeast, size_t atMost) {
ENTER_BLOCK
TRI_ASSERT(0 <= i && i < _dependencies.size());
AqlItemBlock* docs = _dependencies.at(i)->getSome(atLeast, atMost);
if (docs != nullptr) {
@ -3677,6 +3711,7 @@ bool GatherBlock::getBlock (size_t i, size_t atLeast, size_t atMost) {
}
return false;
LEAVE_BLOCK
}
////////////////////////////////////////////////////////////////////////////////
@ -3725,10 +3760,11 @@ bool GatherBlock::OurLessThan::operator() (std::pair<size_t, size_t> const& a,
BlockWithClients::BlockWithClients (ExecutionEngine* engine,
ExecutionNode const* ep,
std::vector<std::string> const& shardIds) :
ExecutionBlock(engine, ep),
_nrClients(shardIds.size()),
_initOrShutdown(true) {
std::vector<std::string> const& shardIds)
: ExecutionBlock(engine, ep),
_nrClients(shardIds.size()),
_initOrShutdown(true) {
_shardIdMap.reserve(_nrClients);
for (size_t i = 0; i < _nrClients; i++) {
_shardIdMap.emplace(std::make_pair(shardIds[i], i));
@ -3739,12 +3775,15 @@ BlockWithClients::BlockWithClients (ExecutionEngine* engine,
/// @brief shutdown
////////////////////////////////////////////////////////////////////////////////
int BlockWithClients::shutdown () {
if (!_initOrShutdown) {
int BlockWithClients::shutdown (int errorCode) {
ENTER_BLOCK
if (! _initOrShutdown) {
return TRI_ERROR_NO_ERROR;
}
_initOrShutdown = false;
return ExecutionBlock::shutdown();
return ExecutionBlock::shutdown(errorCode);
LEAVE_BLOCK
}
////////////////////////////////////////////////////////////////////////////////
@ -3754,6 +3793,7 @@ int BlockWithClients::shutdown () {
AqlItemBlock* BlockWithClients::getSomeForShard (size_t atLeast,
size_t atMost,
std::string const& shardId) {
ENTER_BLOCK
size_t skipped = 0;
AqlItemBlock* result = nullptr;
int out = getOrSkipSomeForShard(atLeast, atMost, false, result, skipped, shardId);
@ -3761,6 +3801,7 @@ AqlItemBlock* BlockWithClients::getSomeForShard (size_t atLeast,
THROW_ARANGO_EXCEPTION(out);
}
return result;
LEAVE_BLOCK
}
////////////////////////////////////////////////////////////////////////////////
@ -3770,6 +3811,7 @@ AqlItemBlock* BlockWithClients::getSomeForShard (size_t atLeast,
size_t BlockWithClients::skipSomeForShard (size_t atLeast,
size_t atMost,
std::string const& shardId) {
ENTER_BLOCK
size_t skipped = 0;
AqlItemBlock* result = nullptr;
int out = getOrSkipSomeForShard(atLeast, atMost, true, result, skipped, shardId);
@ -3778,6 +3820,7 @@ size_t BlockWithClients::skipSomeForShard (size_t atLeast,
THROW_ARANGO_EXCEPTION(out);
}
return skipped;
LEAVE_BLOCK
}
////////////////////////////////////////////////////////////////////////////////
@ -3786,6 +3829,7 @@ size_t BlockWithClients::skipSomeForShard (size_t atLeast,
bool BlockWithClients::skipForShard (size_t number,
std::string const& shardId) {
ENTER_BLOCK
size_t skipped = skipSomeForShard(number, number, shardId);
size_t nr = skipped;
while (nr != 0 && skipped < number) {
@ -3796,6 +3840,7 @@ bool BlockWithClients::skipForShard (size_t number,
return true;
}
return ! hasMoreForShard(shardId);
LEAVE_BLOCK
}
////////////////////////////////////////////////////////////////////////////////
@ -3804,6 +3849,7 @@ bool BlockWithClients::skipForShard (size_t number,
////////////////////////////////////////////////////////////////////////////////
size_t BlockWithClients::getClientId (std::string const& shardId) {
ENTER_BLOCK
if (shardId.empty()) {
TRI_ASSERT(false);
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "got empty shard id");
@ -3816,6 +3862,7 @@ size_t BlockWithClients::getClientId (std::string const& shardId) {
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, message);
}
return ((*it).second);
LEAVE_BLOCK
}
////////////////////////////////////////////////////////////////////////////////
@ -3824,6 +3871,7 @@ size_t BlockWithClients::getClientId (std::string const& shardId) {
////////////////////////////////////////////////////////////////////////////////
bool BlockWithClients::preInitCursor () {
ENTER_BLOCK
if (! _initOrShutdown) {
return false;
}
@ -3837,6 +3885,7 @@ bool BlockWithClients::preInitCursor () {
_initOrShutdown = false;
return true;
LEAVE_BLOCK
}
// -----------------------------------------------------------------------------
@ -3848,6 +3897,7 @@ bool BlockWithClients::preInitCursor () {
////////////////////////////////////////////////////////////////////////////////
int ScatterBlock::initializeCursor (AqlItemBlock* items, size_t pos) {
ENTER_BLOCK
if (! preInitCursor()) {
return TRI_ERROR_NO_ERROR;
}
@ -3863,6 +3913,7 @@ int ScatterBlock::initializeCursor (AqlItemBlock* items, size_t pos) {
_posForClient.push_back(std::make_pair(0, 0));
}
return TRI_ERROR_NO_ERROR;
LEAVE_BLOCK
}
////////////////////////////////////////////////////////////////////////////////
@ -3870,6 +3921,7 @@ int ScatterBlock::initializeCursor (AqlItemBlock* items, size_t pos) {
////////////////////////////////////////////////////////////////////////////////
bool ScatterBlock::hasMoreForShard (std::string const& shardId) {
ENTER_BLOCK
size_t clientId = getClientId(shardId);
if (_doneForClient.at(clientId)) {
@ -3888,6 +3940,7 @@ bool ScatterBlock::hasMoreForShard (std::string const& shardId) {
}
}
return true;
LEAVE_BLOCK
}
////////////////////////////////////////////////////////////////////////////////
@ -3896,6 +3949,7 @@ bool ScatterBlock::hasMoreForShard (std::string const& shardId) {
////////////////////////////////////////////////////////////////////////////////
int64_t ScatterBlock::remainingForShard (std::string const& shardId) {
ENTER_BLOCK
size_t clientId = getClientId(shardId);
if (_doneForClient.at(clientId)) {
return 0;
@ -3916,6 +3970,7 @@ int64_t ScatterBlock::remainingForShard (std::string const& shardId) {
}
return sum;
LEAVE_BLOCK
}
////////////////////////////////////////////////////////////////////////////////
@ -3925,7 +3980,7 @@ int64_t ScatterBlock::remainingForShard (std::string const& shardId) {
int ScatterBlock::getOrSkipSomeForShard (size_t atLeast,
size_t atMost, bool skipping, AqlItemBlock*& result,
size_t& skipped, std::string const& shardId) {
ENTER_BLOCK
TRI_ASSERT(0 < atLeast && atLeast <= atMost);
TRI_ASSERT(result == nullptr && skipped == 0);
@ -3984,6 +4039,7 @@ int ScatterBlock::getOrSkipSomeForShard (size_t atLeast,
}
return TRI_ERROR_NO_ERROR;
LEAVE_BLOCK
}
// -----------------------------------------------------------------------------
@ -4011,6 +4067,7 @@ DistributeBlock::DistributeBlock (ExecutionEngine* engine,
////////////////////////////////////////////////////////////////////////////////
int DistributeBlock::initializeCursor (AqlItemBlock* items, size_t pos) {
ENTER_BLOCK
if (! preInitCursor()) {
return TRI_ERROR_NO_ERROR;
}
@ -4027,6 +4084,7 @@ int DistributeBlock::initializeCursor (AqlItemBlock* items, size_t pos) {
}
return TRI_ERROR_NO_ERROR;
LEAVE_BLOCK
}
////////////////////////////////////////////////////////////////////////////////
@ -4034,6 +4092,7 @@ int DistributeBlock::initializeCursor (AqlItemBlock* items, size_t pos) {
////////////////////////////////////////////////////////////////////////////////
bool DistributeBlock::hasMoreForShard (std::string const& shardId) {
ENTER_BLOCK
size_t clientId = getClientId(shardId);
if (_doneForClient.at(clientId)) {
@ -4049,6 +4108,7 @@ bool DistributeBlock::hasMoreForShard (std::string const& shardId) {
return false;
}
return true;
LEAVE_BLOCK
}
////////////////////////////////////////////////////////////////////////////////
@ -4061,6 +4121,7 @@ int DistributeBlock::getOrSkipSomeForShard (size_t atLeast,
AqlItemBlock*& result,
size_t& skipped,
std::string const& shardId) {
ENTER_BLOCK
TRI_ASSERT(0 < atLeast && atLeast <= atMost);
TRI_ASSERT(result == nullptr && skipped == 0);
@ -4166,6 +4227,7 @@ int DistributeBlock::getOrSkipSomeForShard (size_t atLeast,
}
return TRI_ERROR_NO_ERROR;
LEAVE_BLOCK
}
////////////////////////////////////////////////////////////////////////////////
@ -4179,6 +4241,7 @@ int DistributeBlock::getOrSkipSomeForShard (size_t atLeast,
bool DistributeBlock::getBlockForClient (size_t atLeast,
size_t atMost,
size_t clientId) {
ENTER_BLOCK
if (_buffer.empty()) {
_index = 0; // position in _buffer
_pos = 0; // position in _buffer.at(_index)
@ -4215,6 +4278,7 @@ bool DistributeBlock::getBlockForClient (size_t atLeast,
}
return true;
LEAVE_BLOCK
}
////////////////////////////////////////////////////////////////////////////////
@ -4224,6 +4288,7 @@ bool DistributeBlock::getBlockForClient (size_t atLeast,
////////////////////////////////////////////////////////////////////////////////
size_t DistributeBlock::sendToClient (AqlValue val) {
ENTER_BLOCK
TRI_json_t const* json;
if (val._type == AqlValue::JSON) {
json = val._json->json();
@ -4259,6 +4324,7 @@ size_t DistributeBlock::sendToClient (AqlValue val) {
TRI_ASSERT(!shardId.empty());
return getClientId(shardId);
LEAVE_BLOCK
}
// -----------------------------------------------------------------------------
@ -4271,6 +4337,7 @@ size_t DistributeBlock::sendToClient (AqlValue val) {
static bool throwExceptionAfterBadSyncRequest (ClusterCommResult* res,
bool isShutdown) {
ENTER_BLOCK
if (res->status == CL_COMM_TIMEOUT) {
std::string errorMessage;
errorMessage += std::string("Timeout in communication with shard '") +
@ -4358,6 +4425,7 @@ static bool throwExceptionAfterBadSyncRequest (ClusterCommResult* res,
}
return false;
LEAVE_BLOCK
}
////////////////////////////////////////////////////////////////////////////////
@ -4394,8 +4462,9 @@ RemoteBlock::~RemoteBlock () {
ClusterCommResult* RemoteBlock::sendRequest (
triagens::rest::HttpRequest::HttpRequestType type,
std::string urlPart,
std::string const& urlPart,
std::string const& body) const {
ENTER_BLOCK
ClusterComm* cc = ClusterComm::instance();
// Later, we probably want to set these sensibly:
@ -4418,6 +4487,7 @@ ClusterCommResult* RemoteBlock::sendRequest (
defaultTimeOut);
return result;
LEAVE_BLOCK
}
////////////////////////////////////////////////////////////////////////////////
@ -4425,6 +4495,7 @@ ClusterCommResult* RemoteBlock::sendRequest (
////////////////////////////////////////////////////////////////////////////////
int RemoteBlock::initialize () {
ENTER_BLOCK
int res = ExecutionBlock::initialize();
if (res != TRI_ERROR_NO_ERROR) {
@ -4432,6 +4503,7 @@ int RemoteBlock::initialize () {
}
return TRI_ERROR_NO_ERROR;
LEAVE_BLOCK
}
////////////////////////////////////////////////////////////////////////////////
@ -4439,6 +4511,7 @@ int RemoteBlock::initialize () {
////////////////////////////////////////////////////////////////////////////////
int RemoteBlock::initializeCursor (AqlItemBlock* items, size_t pos) {
ENTER_BLOCK
// For every call we simply forward via HTTP
Json body(Json::Array, 2);
@ -4468,19 +4541,21 @@ int RemoteBlock::initializeCursor (AqlItemBlock* items, size_t pos) {
responseBodyBuf.begin()));
return JsonHelper::getNumericValue<int>
(responseBodyJson.json(), "code", TRI_ERROR_INTERNAL);
LEAVE_BLOCK
}
////////////////////////////////////////////////////////////////////////////////
/// @brief shutdown, will be called exactly once for the whole query
////////////////////////////////////////////////////////////////////////////////
int RemoteBlock::shutdown () {
int RemoteBlock::shutdown (int errorCode) {
ENTER_BLOCK
// For every call we simply forward via HTTP
std::unique_ptr<ClusterCommResult> res;
res.reset(sendRequest(rest::HttpRequest::HTTP_REQUEST_PUT,
"/_api/aql/shutdown/",
string()));
string("{\"code\":" + std::to_string(errorCode) + "}")));
if (throwExceptionAfterBadSyncRequest(res.get(), true)) {
// artificially ignore error in case query was not found during shutdown
return TRI_ERROR_NO_ERROR;
@ -4495,6 +4570,7 @@ int RemoteBlock::shutdown () {
return JsonHelper::getNumericValue<int>
(responseBodyJson.json(), "code", TRI_ERROR_INTERNAL);
LEAVE_BLOCK
}
////////////////////////////////////////////////////////////////////////////////
@ -4503,6 +4579,7 @@ int RemoteBlock::shutdown () {
AqlItemBlock* RemoteBlock::getSome (size_t atLeast,
size_t atMost) {
ENTER_BLOCK
// For every call we simply forward via HTTP
Json body(Json::Array, 2);
@ -4527,7 +4604,14 @@ AqlItemBlock* RemoteBlock::getSome (size_t atLeast,
}
auto items = new triagens::aql::AqlItemBlock(responseBodyJson);
ExecutionStats newStats(responseBodyJson.get("stats"));
_engine->_stats.addDelta(_deltaStats, newStats);
_deltaStats = newStats;
return items;
LEAVE_BLOCK
}
////////////////////////////////////////////////////////////////////////////////
@ -4535,6 +4619,7 @@ AqlItemBlock* RemoteBlock::getSome (size_t atLeast,
////////////////////////////////////////////////////////////////////////////////
size_t RemoteBlock::skipSome (size_t atLeast, size_t atMost) {
ENTER_BLOCK
// For every call we simply forward via HTTP
Json body(Json::Array, 2);
@ -4560,6 +4645,7 @@ size_t RemoteBlock::skipSome (size_t atLeast, size_t atMost) {
size_t skipped = JsonHelper::getNumericValue<size_t>(responseBodyJson.json(),
"skipped", 0);
return skipped;
LEAVE_BLOCK
}
////////////////////////////////////////////////////////////////////////////////
@ -4567,6 +4653,7 @@ size_t RemoteBlock::skipSome (size_t atLeast, size_t atMost) {
////////////////////////////////////////////////////////////////////////////////
bool RemoteBlock::hasMore () {
ENTER_BLOCK
// For every call we simply forward via HTTP
std::unique_ptr<ClusterCommResult> res;
res.reset(sendRequest(rest::HttpRequest::HTTP_REQUEST_GET,
@ -4584,6 +4671,7 @@ bool RemoteBlock::hasMore () {
THROW_ARANGO_EXCEPTION(TRI_ERROR_CLUSTER_AQL_COMMUNICATION);
}
return JsonHelper::getBooleanValue(responseBodyJson.json(), "hasMore", true);
LEAVE_BLOCK
}
////////////////////////////////////////////////////////////////////////////////
@ -4591,6 +4679,7 @@ bool RemoteBlock::hasMore () {
////////////////////////////////////////////////////////////////////////////////
int64_t RemoteBlock::count () const {
ENTER_BLOCK
// For every call we simply forward via HTTP
std::unique_ptr<ClusterCommResult> res;
res.reset(sendRequest(rest::HttpRequest::HTTP_REQUEST_GET,
@ -4609,6 +4698,7 @@ int64_t RemoteBlock::count () const {
}
return JsonHelper::getNumericValue<int64_t>
(responseBodyJson.json(), "count", 0);
LEAVE_BLOCK
}
////////////////////////////////////////////////////////////////////////////////
@ -4616,6 +4706,7 @@ int64_t RemoteBlock::count () const {
////////////////////////////////////////////////////////////////////////////////
int64_t RemoteBlock::remaining () {
ENTER_BLOCK
// For every call we simply forward via HTTP
std::unique_ptr<ClusterCommResult> res;
res.reset(sendRequest(rest::HttpRequest::HTTP_REQUEST_GET,
@ -4634,6 +4725,7 @@ int64_t RemoteBlock::remaining () {
}
return JsonHelper::getNumericValue<int64_t>
(responseBodyJson.json(), "remaining", 0);
LEAVE_BLOCK
}
// Local Variables:

View File

@ -36,6 +36,7 @@
#include "Aql/ExecutionNode.h"
#include "Aql/Range.h"
#include "Aql/WalkerWorker.h"
#include "Aql/ExecutionStats.h"
#include "Utils/AqlTransaction.h"
#include "Utils/transactions.h"
#include "Utils/V8TransactionContext.h"
@ -185,7 +186,7 @@ namespace triagens {
/// @brief shutdown, will be called exactly once for the whole query
////////////////////////////////////////////////////////////////////////////////
virtual int shutdown ();
virtual int shutdown (int);
////////////////////////////////////////////////////////////////////////////////
/// @brief getOne, gets one more item
@ -278,7 +279,7 @@ namespace triagens {
virtual int64_t remaining ();
ExecutionNode const* getPlanNode () {
ExecutionNode const* getPlanNode () const {
return _exeNode;
}
@ -377,7 +378,7 @@ namespace triagens {
}
}
int initialize () {
int initialize () override {
_inputRegisterValues = nullptr; // just in case
return ExecutionBlock::initialize();
}
@ -386,19 +387,19 @@ namespace triagens {
/// @brief initializeCursor, store a copy of the register values coming from above
////////////////////////////////////////////////////////////////////////////////
int initializeCursor (AqlItemBlock* items, size_t pos);
int initializeCursor (AqlItemBlock* items, size_t pos) override;
int shutdown ();
int shutdown (int) override final;
bool hasMore () {
bool hasMore () override final {
return ! _done;
}
int64_t count () const {
int64_t count () const override final {
return 1;
}
int64_t remaining () {
int64_t remaining () override final {
return _done ? 0 : 1;
}
@ -456,15 +457,15 @@ namespace triagens {
/// @brief initialize, here we fetch all docs from the database
////////////////////////////////////////////////////////////////////////////////
int initialize ();
int initialize () override;
////////////////////////////////////////////////////////////////////////////////
/// @brief initCursor, here we release our docs from this collection
////////////////////////////////////////////////////////////////////////////////
int initializeCursor (AqlItemBlock* items, size_t pos);
int initializeCursor (AqlItemBlock* items, size_t pos) override;
AqlItemBlock* getSome (size_t atLeast, size_t atMost);
AqlItemBlock* getSome (size_t atLeast, size_t atMost) override;
////////////////////////////////////////////////////////////////////////////////
// skip between atLeast and atMost, returns the number actually skipped . . .
@ -472,7 +473,7 @@ namespace triagens {
// things to skip overall.
////////////////////////////////////////////////////////////////////////////////
size_t skipSome (size_t atLeast, size_t atMost);
size_t skipSome (size_t atLeast, size_t atMost) override final;
// -----------------------------------------------------------------------------
// --SECTION-- private variables
@ -529,15 +530,15 @@ namespace triagens {
/// @brief initialize, here we fetch all docs from the database
////////////////////////////////////////////////////////////////////////////////
int initialize ();
int initialize () override;
////////////////////////////////////////////////////////////////////////////////
/// @brief initializeCursor, here we release our docs from this collection
////////////////////////////////////////////////////////////////////////////////
int initializeCursor (AqlItemBlock* items, size_t pos);
int initializeCursor (AqlItemBlock* items, size_t pos) override;
AqlItemBlock* getSome (size_t atLeast, size_t atMost);
AqlItemBlock* getSome (size_t atLeast, size_t atMost) override;
////////////////////////////////////////////////////////////////////////////////
// skip between atLeast and atMost, returns the number actually skipped . . .
@ -545,7 +546,7 @@ namespace triagens {
// things to skip overall.
////////////////////////////////////////////////////////////////////////////////
virtual size_t skipSome (size_t atLeast, size_t atMost);
size_t skipSome (size_t atLeast, size_t atMost) override final;
// -----------------------------------------------------------------------------
// --SECTION-- private methods
@ -650,15 +651,15 @@ namespace triagens {
~EnumerateListBlock ();
int initialize ();
int initialize () override;
////////////////////////////////////////////////////////////////////////////////
/// @brief initializeCursor, here we release our docs from this collection
////////////////////////////////////////////////////////////////////////////////
int initializeCursor (AqlItemBlock* items, size_t pos);
int initializeCursor (AqlItemBlock* items, size_t pos) override;
AqlItemBlock* getSome (size_t atLeast, size_t atMost);
AqlItemBlock* getSome (size_t atLeast, size_t atMost) override;
////////////////////////////////////////////////////////////////////////////////
// skip between atLeast and atMost returns the number actually skipped . . .
@ -666,7 +667,7 @@ namespace triagens {
// things to skip overall.
////////////////////////////////////////////////////////////////////////////////
size_t skipSome (size_t atLeast, size_t atMost);
size_t skipSome (size_t atLeast, size_t atMost) override final;
////////////////////////////////////////////////////////////////////////////////
/// @brief create an AqlValue from the inVariable using the current _index
@ -727,7 +728,7 @@ namespace triagens {
~CalculationBlock ();
int initialize ();
int initialize () override;
////////////////////////////////////////////////////////////////////////////////
/// @brief doEvaluation, private helper to do the work
@ -743,8 +744,8 @@ namespace triagens {
/// @brief getSome
////////////////////////////////////////////////////////////////////////////////
virtual AqlItemBlock* getSome (size_t atLeast,
size_t atMost);
AqlItemBlock* getSome (size_t atLeast,
size_t atMost) override;
private:
@ -794,10 +795,10 @@ namespace triagens {
~SubqueryBlock ();
int initialize ();
int initialize () override;
virtual AqlItemBlock* getSome (size_t atLeast,
size_t atMost);
AqlItemBlock* getSome (size_t atLeast,
size_t atMost) override;
////////////////////////////////////////////////////////////////////////////////
/// @brief getter for the pointer to the subquery
@ -835,7 +836,7 @@ namespace triagens {
~FilterBlock ();
int initialize ();
int initialize () override;
////////////////////////////////////////////////////////////////////////////////
/// @brief internal function to actually decide
@ -860,13 +861,13 @@ namespace triagens {
AqlItemBlock*& result,
size_t& skipped);
bool hasMore ();
bool hasMore () override final;
int64_t count () const {
int64_t count () const override final {
return -1; // refuse to work
}
int64_t remaining () {
int64_t remaining () override final {
return -1; // refuse to work
}
@ -900,7 +901,7 @@ namespace triagens {
~AggregateBlock ();
int initialize ();
int initialize () override;
private:
@ -960,7 +961,7 @@ namespace triagens {
~SortBlock ();
int initialize ();
int initialize () override;
virtual int initializeCursor (AqlItemBlock* items, size_t pos);
@ -1032,7 +1033,7 @@ namespace triagens {
~LimitBlock () {
}
int initialize ();
int initialize () override;
int initializeCursor (AqlItemBlock* items, size_t pos);
@ -1096,8 +1097,8 @@ namespace triagens {
/// @brief getSome
////////////////////////////////////////////////////////////////////////////////
virtual AqlItemBlock* getSome (size_t atLeast,
size_t atMost);
AqlItemBlock* getSome (size_t atLeast,
size_t atMost) override;
};
@ -1126,8 +1127,8 @@ namespace triagens {
/// @brief getSome
////////////////////////////////////////////////////////////////////////////////
virtual AqlItemBlock* getSome (size_t atLeast,
size_t atMost);
AqlItemBlock* getSome (size_t atLeast,
size_t atMost) override final;
// -----------------------------------------------------------------------------
// --SECTION-- protected methods
@ -1327,7 +1328,7 @@ namespace triagens {
~NoResultsBlock () {
}
int initialize () {
int initialize () override {
return ExecutionBlock::initialize();
}
@ -1337,15 +1338,15 @@ namespace triagens {
int initializeCursor (AqlItemBlock* items, size_t pos);
bool hasMore () {
bool hasMore () override final {
return false;
}
int64_t count () const {
int64_t count () const override final {
return 0;
}
int64_t remaining () {
int64_t remaining () override final {
return 0;
}
@ -1384,13 +1385,13 @@ namespace triagens {
/// @brief initialize
////////////////////////////////////////////////////////////////////////////////
int initialize ();
int initialize () override;
////////////////////////////////////////////////////////////////////////////////
/// @brief shutdown: need our own method since our _buffer is different
////////////////////////////////////////////////////////////////////////////////
int shutdown ();
int shutdown (int) override final;
////////////////////////////////////////////////////////////////////////////////
/// @brief initializeCursor
@ -1403,33 +1404,33 @@ namespace triagens {
/// dependency has count -1
////////////////////////////////////////////////////////////////////////////////
int64_t count () const;
int64_t count () const override final;
////////////////////////////////////////////////////////////////////////////////
/// @brief remaining: the sum of the remaining() of the dependencies or -1 (if
/// any dependency has remaining -1
////////////////////////////////////////////////////////////////////////////////
int64_t remaining ();
int64_t remaining () override final;
////////////////////////////////////////////////////////////////////////////////
/// @brief hasMore: true if any position of _buffer hasMore and false
/// otherwise.
////////////////////////////////////////////////////////////////////////////////
bool hasMore ();
bool hasMore () override final;
////////////////////////////////////////////////////////////////////////////////
/// @brief getSome
////////////////////////////////////////////////////////////////////////////////
AqlItemBlock* getSome (size_t, size_t);
AqlItemBlock* getSome (size_t, size_t) override final;
////////////////////////////////////////////////////////////////////////////////
/// @brief skipSome
////////////////////////////////////////////////////////////////////////////////
size_t skipSome (size_t, size_t);
size_t skipSome (size_t, size_t) override final;
////////////////////////////////////////////////////////////////////////////////
/// @brief _gatherBlockPos: pairs (i, _pos in _buffer.at(i)), i.e. the same as
@ -1517,7 +1518,6 @@ namespace triagens {
std::vector<std::string> const& shardIds);
virtual ~BlockWithClients () {}
// -----------------------------------------------------------------------------
// --SECTION-- BlockWithClients public methods
@ -1529,13 +1529,13 @@ namespace triagens {
/// @brief shutdown
////////////////////////////////////////////////////////////////////////////////
int shutdown ();
int shutdown (int) override;
////////////////////////////////////////////////////////////////////////////////
/// @brief getSome: shouldn't be used, use skipSomeForShard
////////////////////////////////////////////////////////////////////////////////
AqlItemBlock* getSome (size_t atLeast, size_t atMost) {
AqlItemBlock* getSome (size_t atLeast, size_t atMost) override final {
TRI_ASSERT(false);
THROW_ARANGO_EXCEPTION(TRI_ERROR_NOT_IMPLEMENTED);
}
@ -1544,7 +1544,7 @@ namespace triagens {
/// @brief skipSome: shouldn't be used, use skipSomeForShard
////////////////////////////////////////////////////////////////////////////////
size_t skipSome (size_t atLeast, size_t atMost) {
size_t skipSome (size_t atLeast, size_t atMost) override final {
TRI_ASSERT(false);
THROW_ARANGO_EXCEPTION(TRI_ERROR_NOT_IMPLEMENTED);
}
@ -1553,7 +1553,7 @@ namespace triagens {
/// @brief remaining
////////////////////////////////////////////////////////////////////////////////
int64_t remaining () {
int64_t remaining () override final {
TRI_ASSERT(false);
THROW_ARANGO_EXCEPTION(TRI_ERROR_NOT_IMPLEMENTED);
}
@ -1562,16 +1562,7 @@ namespace triagens {
/// @brief hasMore
////////////////////////////////////////////////////////////////////////////////
bool hasMore () {
TRI_ASSERT(false);
THROW_ARANGO_EXCEPTION(TRI_ERROR_NOT_IMPLEMENTED);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief skip
////////////////////////////////////////////////////////////////////////////////
int64_t skip () {
bool hasMore () override final {
TRI_ASSERT(false);
THROW_ARANGO_EXCEPTION(TRI_ERROR_NOT_IMPLEMENTED);
}
@ -1865,7 +1856,7 @@ namespace triagens {
/// @brief initialize
////////////////////////////////////////////////////////////////////////////////
int initialize () final;
int initialize () override final;
////////////////////////////////////////////////////////////////////////////////
/// @brief initializeCursor, could be called multiple times
@ -1877,38 +1868,38 @@ namespace triagens {
/// @brief shutdown, will be called exactly once for the whole query
////////////////////////////////////////////////////////////////////////////////
int shutdown () final;
int shutdown (int) override final;
////////////////////////////////////////////////////////////////////////////////
/// @brief getSome
////////////////////////////////////////////////////////////////////////////////
AqlItemBlock* getSome (size_t atLeast,
size_t atMost) final;
size_t atMost) override final;
////////////////////////////////////////////////////////////////////////////////
/// @brief skipSome
////////////////////////////////////////////////////////////////////////////////
size_t skipSome (size_t atLeast, size_t atMost) final;
size_t skipSome (size_t atLeast, size_t atMost) override final;
////////////////////////////////////////////////////////////////////////////////
/// @brief hasMore
////////////////////////////////////////////////////////////////////////////////
bool hasMore () final;
bool hasMore () override final;
////////////////////////////////////////////////////////////////////////////////
/// @brief count
////////////////////////////////////////////////////////////////////////////////
int64_t count () const final;
int64_t count () const override final;
////////////////////////////////////////////////////////////////////////////////
/// @brief remaining
////////////////////////////////////////////////////////////////////////////////
int64_t remaining () final;
int64_t remaining () override final;
////////////////////////////////////////////////////////////////////////////////
/// @brief internal method to send a request
@ -1918,7 +1909,7 @@ namespace triagens {
triagens::arango::ClusterCommResult* sendRequest (
rest::HttpRequest::HttpRequestType type,
std::string urlPart,
std::string const& urlPart,
std::string const& body) const;
////////////////////////////////////////////////////////////////////////////////
@ -1940,6 +1931,13 @@ namespace triagens {
std::string _queryId;
////////////////////////////////////////////////////////////////////////////////
/// @brief the ID of the query on the server as a string
////////////////////////////////////////////////////////////////////////////////
ExecutionStats _deltaStats;
};
} // namespace triagens::aql

View File

@ -161,7 +161,8 @@ ExecutionEngine::ExecutionEngine (Query* query)
: _stats(),
_blocks(),
_root(nullptr),
_query(query) {
_query(query),
_wasShutdown(false) {
_blocks.reserve(8);
}
@ -171,8 +172,11 @@ ExecutionEngine::ExecutionEngine (Query* query)
////////////////////////////////////////////////////////////////////////////////
ExecutionEngine::~ExecutionEngine () {
if (_root != nullptr) {
_root->shutdown();
try {
shutdown(TRI_ERROR_INTERNAL);
}
catch (...) {
// shutdown can throw - ignore it in the destructor
}
for (auto it = _blocks.begin(); it != _blocks.end(); ++it) {
@ -333,39 +337,25 @@ struct CoordinatorInstanciator : public WalkerWorker<ExecutionNode> {
if ((*it).location == COORDINATOR) {
// create a coordinator-based engine
engine = buildEngineCoordinator((*it), queryIds);
TRI_ASSERT(engine != nullptr);
auto plan = engine->getQuery()->plan();
TRI_ASSERT(plan != nullptr);
TRI_ASSERT(plan->empty());
if ((*it).id > 0) {
Query* otherQuery = query->clone(PART_DEPENDENT);
otherQuery->engine(engine);
int res = otherQuery->trx()->begin();
if (res != TRI_ERROR_NO_ERROR) {
THROW_ARANGO_EXCEPTION_MESSAGE(res, "could not begin transaction");
}
auto* newPlan = new ExecutionPlan(otherQuery->ast());
otherQuery->setPlan(newPlan);
// clone all variables
for (auto it2 : query->ast()->variables()->variables(true)) {
auto var = query->ast()->variables()->getVariable(it2.first);
TRI_ASSERT(var != nullptr);
otherQuery->ast()->variables()->createVariable(var);
}
ExecutionNode const* current = (*it).nodes.front();
ExecutionNode* previous = nullptr;
// TODO: fix instanciation here as in DBserver case
while (current != nullptr) {
auto clone = current->clone(newPlan, false, true);
newPlan->registerNode(clone);
auto clone = current->clone(plan, false, true);
plan->registerNode(clone);
if (previous == nullptr) {
// set the root node
newPlan->root(clone);
plan->root(clone);
}
else {
previous->addDependency(clone);
@ -380,16 +370,13 @@ struct CoordinatorInstanciator : public WalkerWorker<ExecutionNode> {
current = deps[0];
}
// TODO: test if this is necessary or does harm
// newPlan->setVarUsageComputed();
// we need to instanciate this engine in the registry
// create a remote id for the engine that we can pass to
// the plans to be created for the DBServers
id = TRI_NewTickServer();
queryRegistry->insert(otherQuery->vocbase(), id, otherQuery, 3600.0);
queryRegistry->insert(id, engine->getQuery(), 3600.0);
}
}
else {
@ -576,7 +563,11 @@ struct CoordinatorInstanciator : public WalkerWorker<ExecutionNode> {
ExecutionEngine* buildEngineCoordinator (EngineInfo& info,
std::unordered_map<std::string, std::string> const& queryIds) {
std::unique_ptr<ExecutionEngine> engine(new ExecutionEngine(query));
// need a new query instance on the coordinator
auto clone = query->clone(PART_DEPENDENT, false);
std::unique_ptr<ExecutionEngine> engine(new ExecutionEngine(clone));
clone->engine(engine.get());
std::unordered_map<ExecutionNode*, ExecutionBlock*> cache;
RemoteNode* remoteNode = nullptr;
@ -615,19 +606,21 @@ struct CoordinatorInstanciator : public WalkerWorker<ExecutionNode> {
}
}
if (nodeType == ExecutionNode::GATHER ||
nodeType == ExecutionNode::DISTRIBUTE) {
// we found a gather or distribute node
if (nodeType == ExecutionNode::GATHER /* ||
nodeType == ExecutionNode::DISTRIBUTE */) {
// we found a gather node
TRI_ASSERT(remoteNode != nullptr);
// now we'll create a remote node for each shard and add it to the gather|distribute node
// now we'll create a remote node for each shard and add it to the gather node
Collection const* collection = nullptr;
if (nodeType == ExecutionNode::GATHER) {
collection = static_cast<GatherNode const*>((*en))->collection();
}
/* TODO: do we need to handle distribute nodes here, too??
else if (nodeType == ExecutionNode::DISTRIBUTE) {
collection = static_cast<DistributeNode const*>((*en))->collection();
}
*/
else {
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
}

View File

@ -131,10 +131,15 @@ namespace triagens {
/// @brief shutdown, will be called exactly once for the whole query
////////////////////////////////////////////////////////////////////////////////
int shutdown () {
if (_root != nullptr) {
return _root->shutdown();
int shutdown (int errorCode) {
if (_root != nullptr && ! _wasShutdown) {
// prevent a duplicate shutdown
int res = _root->shutdown(errorCode);
_wasShutdown = true;
return res;
}
return TRI_ERROR_NO_ERROR;
}
@ -236,6 +241,12 @@ namespace triagens {
////////////////////////////////////////////////////////////////////////////////
Query* _query;
////////////////////////////////////////////////////////////////////////////////
/// @brief whether or not shutdown() was executed
////////////////////////////////////////////////////////////////////////////////
bool _wasShutdown;
};
}

View File

@ -107,6 +107,14 @@ namespace triagens {
TRI_memory_zone_t* zone,
bool verbose) const;
////////////////////////////////////////////////////////////////////////////////
/// @brief check if the plan is empty
////////////////////////////////////////////////////////////////////////////////
inline bool empty () const {
return (_root == nullptr);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief note that an optimizer rule was applied
////////////////////////////////////////////////////////////////////////////////

View File

@ -28,9 +28,10 @@
////////////////////////////////////////////////////////////////////////////////
#include "Aql/ExecutionStats.h"
#include "Utils/Exception.h"
using namespace triagens::aql;
using Json = triagens::basics::Json;
using JsonHelper = triagens::basics::JsonHelper;
// -----------------------------------------------------------------------------
// --SECTION-- public methods
@ -50,6 +51,24 @@ Json ExecutionStats::toJson () const {
return json;
}
ExecutionStats::ExecutionStats()
:writesExecuted(0),
writesIgnored(0),
scannedFull(0),
scannedIndex(0) {
}
ExecutionStats::ExecutionStats (triagens::basics::Json const& jsonStats) {
if (!jsonStats.isArray()) {
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "stats is not an Array");
}
writesExecuted = JsonHelper::checkAndGetNumericValue<int>(jsonStats.json(), "writesExecuted");
writesIgnored = JsonHelper::checkAndGetNumericValue<int>(jsonStats.json(), "writesIgnored");
scannedFull = JsonHelper::checkAndGetNumericValue<int>(jsonStats.json(), "scannedFull");
scannedIndex = JsonHelper::checkAndGetNumericValue<int>(jsonStats.json(), "scannedIndex");
}
// -----------------------------------------------------------------------------
// --SECTION-- END-OF-FILE
// -----------------------------------------------------------------------------

View File

@ -38,35 +38,66 @@ namespace triagens {
struct ExecutionStats {
ExecutionStats ();
////////////////////////////////////////////////////////////////////////////////
/// @brief instanciate the statistics from JSON
////////////////////////////////////////////////////////////////////////////////
ExecutionStats (triagens::basics::Json const& jsonStats);
////////////////////////////////////////////////////////////////////////////////
/// @brief convert the statistics to JSON
////////////////////////////////////////////////////////////////////////////////
triagens::basics::Json toJson () const;
////////////////////////////////////////////////////////////////////////////////
/// @brief sumarize two sets of ExecutionStats
////////////////////////////////////////////////////////////////////////////////
void add (ExecutionStats const& summand) {
writesExecuted += summand.writesExecuted;
writesIgnored += summand.writesIgnored;
scannedFull += summand.scannedFull;
scannedIndex += summand.scannedIndex;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief sumarize the delta of two other sets of ExecutionStats to us
////////////////////////////////////////////////////////////////////////////////
void addDelta (ExecutionStats const& lastStats, ExecutionStats const& newStats) {
writesExecuted += newStats.writesExecuted - lastStats.writesExecuted;
writesIgnored += newStats.writesIgnored - lastStats.writesIgnored;
scannedFull += newStats.scannedFull - lastStats.scannedFull;
scannedIndex += newStats.scannedIndex - lastStats.scannedIndex;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief number of successfully executed write operations
////////////////////////////////////////////////////////////////////////////////
int64_t writesExecuted = 0;
int64_t writesExecuted;
////////////////////////////////////////////////////////////////////////////////
/// @brief number of ignored write operations (ignored due to errors)
////////////////////////////////////////////////////////////////////////////////
int64_t writesIgnored = 0;
int64_t writesIgnored;
////////////////////////////////////////////////////////////////////////////////
/// @brief number of documents scanned (full-collection scan)
////////////////////////////////////////////////////////////////////////////////
int64_t scannedFull = 0;
int64_t scannedFull;
////////////////////////////////////////////////////////////////////////////////
/// @brief number of documents scanned (using indexes scan)
////////////////////////////////////////////////////////////////////////////////
int64_t scannedIndex = 0;
int64_t scannedIndex;
};

View File

@ -146,7 +146,6 @@ Query::Query (triagens::arango::ApplicationV8* applicationV8,
_trx(nullptr),
_engine(nullptr),
_part(part),
_clusterStatus(-1),
_contextOwnedByExterior(contextOwnedByExterior) {
TRI_ASSERT(_vocbase != nullptr);
@ -191,7 +190,6 @@ Query::Query (triagens::arango::ApplicationV8* applicationV8,
_trx(nullptr),
_engine(nullptr),
_part(part),
_clusterStatus(-1),
_contextOwnedByExterior(contextOwnedByExterior) {
TRI_ASSERT(_vocbase != nullptr);
@ -212,7 +210,7 @@ Query::Query (triagens::arango::ApplicationV8* applicationV8,
////////////////////////////////////////////////////////////////////////////////
Query::~Query () {
cleanupPlanAndEngine();
cleanupPlanAndEngine(TRI_ERROR_INTERNAL); // abort the transaction
if (_profile != nullptr) {
delete _profile;
@ -260,9 +258,12 @@ Query::~Query () {
////////////////////////////////////////////////////////////////////////////////
/// @brief clone a query
/// note: as a side-effect, this will also create and start a transaction for
/// the query
////////////////////////////////////////////////////////////////////////////////
Query* Query::clone (QueryPart part) {
Query* Query::clone (QueryPart part,
bool withPlan) {
TRI_json_t* options = nullptr;
if (_options != nullptr) {
@ -289,7 +290,10 @@ Query* Query::clone (QueryPart part) {
}
if (_plan != nullptr) {
clone->_plan = _plan->clone(*clone);
if (withPlan) {
// clone the existing plan
clone->setPlan(_plan->clone(*clone));
}
// clone all variables
for (auto it : _ast->variables()->variables(true)) {
@ -298,11 +302,23 @@ Query* Query::clone (QueryPart part) {
clone->ast()->variables()->createVariable(var);
}
}
if (clone->_plan == nullptr) {
// initialize an empty plan
clone->setPlan(new ExecutionPlan(ast()));
}
TRI_ASSERT(clone->_trx == nullptr);
clone->_trx = _trx->clone(); // A daughter transaction which does not
// actually lock the collections
int res = clone->_trx->begin();
if (res != TRI_ERROR_NO_ERROR) {
THROW_ARANGO_EXCEPTION_MESSAGE(res, "could not begin transaction");
}
return clone.release();
}
@ -508,19 +524,19 @@ QueryResult Query::prepare (QueryRegistry* registry) {
return QueryResult();
}
catch (triagens::arango::Exception const& ex) {
cleanupPlanAndEngine();
cleanupPlanAndEngine(ex.code());
return QueryResult(ex.code(), getStateString() + ex.message());
}
catch (std::bad_alloc const&) {
cleanupPlanAndEngine();
cleanupPlanAndEngine(TRI_ERROR_OUT_OF_MEMORY);
return QueryResult(TRI_ERROR_OUT_OF_MEMORY, getStateString() + TRI_errno_string(TRI_ERROR_OUT_OF_MEMORY));
}
catch (std::exception const& ex) {
cleanupPlanAndEngine();
cleanupPlanAndEngine(TRI_ERROR_INTERNAL);
return QueryResult(TRI_ERROR_INTERNAL, getStateString() + ex.what());
}
catch (...) {
cleanupPlanAndEngine();
cleanupPlanAndEngine(TRI_ERROR_INTERNAL);
return QueryResult(TRI_ERROR_INTERNAL, getStateString() + TRI_errno_string(TRI_ERROR_INTERNAL));
}
}
@ -562,7 +578,7 @@ QueryResult Query::execute (QueryRegistry* registry) {
_trx->commit();
cleanupPlanAndEngine();
cleanupPlanAndEngine(TRI_ERROR_NO_ERROR);
enterState(FINALIZATION);
@ -577,19 +593,19 @@ QueryResult Query::execute (QueryRegistry* registry) {
return result;
}
catch (triagens::arango::Exception const& ex) {
cleanupPlanAndEngine();
cleanupPlanAndEngine(ex.code());
return QueryResult(ex.code(), getStateString() + ex.message());
}
catch (std::bad_alloc const&) {
cleanupPlanAndEngine();
cleanupPlanAndEngine(TRI_ERROR_OUT_OF_MEMORY);
return QueryResult(TRI_ERROR_OUT_OF_MEMORY, getStateString() + TRI_errno_string(TRI_ERROR_OUT_OF_MEMORY));
}
catch (std::exception const& ex) {
cleanupPlanAndEngine();
cleanupPlanAndEngine(TRI_ERROR_INTERNAL);
return QueryResult(TRI_ERROR_INTERNAL, getStateString() + ex.what());
}
catch (...) {
cleanupPlanAndEngine();
cleanupPlanAndEngine(TRI_ERROR_INTERNAL);
return QueryResult(TRI_ERROR_INTERNAL, getStateString() + TRI_errno_string(TRI_ERROR_INTERNAL));
}
}
@ -796,22 +812,6 @@ char* Query::registerString (std::string const& p,
// --SECTION-- private methods
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief whether or not we are running in a cluster
////////////////////////////////////////////////////////////////////////////////
bool Query::isRunningInCluster () {
if (_clusterStatus == -1) {
// not yet determined
_clusterStatus = 0;
if (triagens::arango::ServerState::instance()->isRunningInCluster()) {
_clusterStatus = 1;
}
}
TRI_ASSERT(_clusterStatus == 0 || _clusterStatus == 1);
return (_clusterStatus == 1);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief enter a V8 context
////////////////////////////////////////////////////////////////////////////////
@ -844,22 +844,28 @@ void Query::enterContext () {
void Query::exitContext () {
if (! _contextOwnedByExterior) {
if (_context != nullptr) {
if (isRunningInCluster()) {
// unregister transaction and resolver in context
TRI_v8_global_t* v8g = static_cast<TRI_v8_global_t*>(v8::Isolate::GetCurrent()->GetData());
auto ctx = static_cast<triagens::arango::V8TransactionContext*>(v8g->_transactionContext);
if (ctx != nullptr) {
ctx->unregisterTransaction();
}
_applicationV8->exitContext(_context);
_context = nullptr;
// unregister transaction and resolver in context
TRI_v8_global_t* v8g = static_cast<TRI_v8_global_t*>(v8::Isolate::GetCurrent()->GetData());
auto ctx = static_cast<triagens::arango::V8TransactionContext*>(v8g->_transactionContext);
if (ctx != nullptr) {
ctx->unregisterTransaction();
}
_applicationV8->exitContext(_context);
_context = nullptr;
}
TRI_ASSERT(_context == nullptr);
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief returns statistics for current query.
////////////////////////////////////////////////////////////////////////////////
triagens::basics::Json Query::getStats() {
return _engine->_stats.toJson();
}
////////////////////////////////////////////////////////////////////////////////
/// @brief fetch a boolean value from the options
////////////////////////////////////////////////////////////////////////////////
@ -974,9 +980,15 @@ std::string Query::getStateString () const {
/// @brief cleanup plan and engine for current query
////////////////////////////////////////////////////////////////////////////////
void Query::cleanupPlanAndEngine () {
void Query::cleanupPlanAndEngine (int errorCode) {
if (_engine != nullptr) {
_engine->shutdown();
try {
_engine->shutdown(errorCode);
}
catch (...) {
// shutdown may fail but we must not throw here
// (we're also called from the destructor)
}
delete _engine;
_engine = nullptr;
}

View File

@ -146,7 +146,13 @@ namespace triagens {
~Query ();
Query* clone (QueryPart);
////////////////////////////////////////////////////////////////////////////////
/// @brief clone a query
/// note: as a side-effect, this will also create and start a transaction for
/// the query
////////////////////////////////////////////////////////////////////////////////
Query* clone (QueryPart, bool);
// -----------------------------------------------------------------------------
// --SECTION-- public methods
@ -349,16 +355,11 @@ namespace triagens {
}
////////////////////////////////////////////////////////////////////////////////
/// @brief set the transaction for the query
/// @brief get the plan for the query
////////////////////////////////////////////////////////////////////////////////
void setTrx (triagens::arango::AqlTransaction* trx) {
TRI_ASSERT(_trx == nullptr);
_trx = trx;
}
triagens::arango::AqlTransaction* getTrx () {
return _trx;
ExecutionPlan* plan () const {
return _plan;
}
////////////////////////////////////////////////////////////////////////////////
@ -379,16 +380,16 @@ namespace triagens {
void exitContext ();
////////////////////////////////////////////////////////////////////////////////
/// @brief returns statistics for current query.
////////////////////////////////////////////////////////////////////////////////
triagens::basics::Json getStats();
// -----------------------------------------------------------------------------
// --SECTION-- private methods
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief whether or not we are running in a cluster
////////////////////////////////////////////////////////////////////////////////
bool isRunningInCluster ();
////////////////////////////////////////////////////////////////////////////////
/// @brief fetch a boolean value from the options
////////////////////////////////////////////////////////////////////////////////
@ -431,7 +432,7 @@ namespace triagens {
/// @brief cleanup plan and engine for current query
////////////////////////////////////////////////////////////////////////////////
void cleanupPlanAndEngine ();
void cleanupPlanAndEngine (int);
// -----------------------------------------------------------------------------
// --SECTION-- private variables
@ -562,12 +563,6 @@ namespace triagens {
QueryPart const _part;
////////////////////////////////////////////////////////////////////////////////
/// @brief internal variable we use to determine whether we are in a cluster
////////////////////////////////////////////////////////////////////////////////
short int _clusterStatus;
////////////////////////////////////////////////////////////////////////////////
/// @brief whether or not someone else has acquired a V8 context for us
////////////////////////////////////////////////////////////////////////////////

View File

@ -45,8 +45,10 @@ using namespace triagens::aql;
QueryRegistry::~QueryRegistry () {
std::vector<std::pair<std::string, QueryId>> toDelete;
{
WRITE_LOCKER(_lock);
WRITE_LOCKER(_lock);
try {
for (auto& x : _queries) {
// x.first is a TRI_vocbase_t* and
// x.second is a std::unordered_map<QueryId, QueryInfo*>
@ -57,9 +59,14 @@ QueryRegistry::~QueryRegistry () {
}
}
}
catch (...) {
// the emplace_back() above might fail
// prevent throwing exceptions in the destructor
}
for (auto& p : toDelete) {
try { // just in case
destroy(p.first, p.second);
destroy(p.first, p.second, TRI_ERROR_TRANSACTION_ABORTED);
}
catch (...) {
}
@ -70,12 +77,13 @@ QueryRegistry::~QueryRegistry () {
/// @brief insert
////////////////////////////////////////////////////////////////////////////////
void QueryRegistry::insert (TRI_vocbase_t* vocbase,
QueryId id,
void QueryRegistry::insert (QueryId id,
Query* query,
double ttl) {
TRI_ASSERT(query != nullptr);
TRI_ASSERT(query->trx() != nullptr);
auto vocbase = query->vocbase();
WRITE_LOCKER(_lock);
@ -171,7 +179,9 @@ void QueryRegistry::close (TRI_vocbase_t* vocbase, QueryId id, double ttl) {
/// @brief destroy
////////////////////////////////////////////////////////////////////////////////
void QueryRegistry::destroy (std::string const& vocbase, QueryId id) {
void QueryRegistry::destroy (std::string const& vocbase,
QueryId id,
int errorCode) {
WRITE_LOCKER(_lock);
auto m = _queries.find(vocbase);
@ -193,6 +203,11 @@ void QueryRegistry::destroy (std::string const& vocbase, QueryId id) {
triagens::arango::TransactionBase::increaseNumbers(1, 1);
}
if (errorCode == TRI_ERROR_NO_ERROR) {
// commit the operation
qi->_query->trx()->commit();
}
// Now we can delete it:
delete qi->_query;
delete qi;
@ -205,8 +220,10 @@ void QueryRegistry::destroy (std::string const& vocbase, QueryId id) {
/// @brief destroy
////////////////////////////////////////////////////////////////////////////////
void QueryRegistry::destroy (TRI_vocbase_t* vocbase, QueryId id) {
destroy(vocbase->_name, id);
void QueryRegistry::destroy (TRI_vocbase_t* vocbase,
QueryId id,
int errorCode) {
destroy(vocbase->_name, id, errorCode);
}
////////////////////////////////////////////////////////////////////////////////
@ -232,8 +249,8 @@ void QueryRegistry::expireQueries () {
}
}
for (auto& p : toDelete) {
try { // just in case
destroy(p.first, p.second);
try { // just in case
destroy(p.first, p.second, TRI_ERROR_TRANSACTION_ABORTED);
}
catch (...) {
}

View File

@ -65,8 +65,7 @@ namespace triagens {
/// query will be deleted if it is not opened for that amount of time.
////////////////////////////////////////////////////////////////////////////////
void insert (TRI_vocbase_t* vocbase,
QueryId id,
void insert (QueryId id,
Query* query,
double ttl = 3600.0);
@ -99,9 +98,9 @@ namespace triagens {
/// from the same thread that has opened it!
////////////////////////////////////////////////////////////////////////////////
void destroy (std::string const& vocbase, QueryId id);
void destroy (std::string const& vocbase, QueryId id, int errorCode);
void destroy (TRI_vocbase_t* vocbase, QueryId id);
void destroy (TRI_vocbase_t* vocbase, QueryId id, int errorCode);
////////////////////////////////////////////////////////////////////////////////
/// @brief expireQueries, this deletes all expired queries from the registry

View File

@ -151,7 +151,7 @@ void RestAqlHandler::createQueryFromJson () {
_qId = TRI_NewTickServer();
try {
_queryRegistry->insert(_vocbase, _qId, query, ttl);
_queryRegistry->insert(_qId, query, ttl);
}
catch (...) {
LOG_ERROR("could not keep query in registry");
@ -336,7 +336,7 @@ void RestAqlHandler::createQueryFromString () {
_qId = TRI_NewTickServer();
try {
_queryRegistry->insert(_vocbase, _qId, query, ttl);
_queryRegistry->insert(_qId, query, ttl);
}
catch (...) {
LOG_ERROR("could not keep query in registry");
@ -416,14 +416,10 @@ void RestAqlHandler::useQuery (std::string const& operation,
TRI_ASSERT(_qId > 0);
TRI_ASSERT(query->engine() != nullptr);
Json queryJson;
if (operation != "shutdown") {
// /shutdown does not require a body
queryJson = Json(TRI_UNKNOWN_MEM_ZONE, parseJsonBody());
if (queryJson.isEmpty()) {
_queryRegistry->close(_vocbase, _qId);
return;
}
Json queryJson = Json(TRI_UNKNOWN_MEM_ZONE, parseJsonBody());
if (queryJson.isEmpty()) {
_queryRegistry->close(_vocbase, _qId);
return;
}
try {
@ -747,6 +743,7 @@ void RestAqlHandler::handleUseQuery (std::string const& operation,
else {
try {
answerBody = items->toJson(query->trx());
answerBody.set("stats", query->getStats());
// std::cout << "ANSWERBODY: " << JsonHelper::toString(answerBody.json()) << "\n\n";
}
catch (...) {
@ -837,9 +834,11 @@ void RestAqlHandler::handleUseQuery (std::string const& operation,
}
else if (operation == "shutdown") {
int res = TRI_ERROR_INTERNAL;
int errorCode = JsonHelper::getNumericValue<int>(queryJson.json(), "code", TRI_ERROR_INTERNAL);
try {
res = query->engine()->shutdown();
_queryRegistry->destroy(_vocbase, _qId);
res = query->engine()->shutdown(errorCode); // pass errorCode to shutdown
_queryRegistry->destroy(_vocbase, _qId, errorCode);
}
catch (...) {
LOG_ERROR("shutdown lead to an exception");

View File

@ -1192,7 +1192,7 @@ void ArangoServer::closeDatabases () {
// stop the replication appliers so all replication transactions can end
TRI_StopReplicationAppliersServer(_server);
// enfore logfile manager shutdown so we are sure no one else will
// enforce logfile manager shutdown so we are sure no one else will
// write to the logs
wal::LogfileManager::instance()->stop();

View File

@ -47,7 +47,7 @@ using namespace triagens::arango;
/// @brief ArangoDB server
////////////////////////////////////////////////////////////////////////////////
static ArangoServer* ArangoInstance = 0;
static ArangoServer* ArangoInstance = nullptr;
////////////////////////////////////////////////////////////////////////////////
/// @brief running flag
@ -174,7 +174,7 @@ static void InstallServiceCommand (string command) {
SC_HANDLE schSCManager = OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_ALL_ACCESS);
if (schSCManager == 0) {
cout << "FATAL: OpenSCManager failed with " << GetLastError() << endl;
cerr << "FATAL: OpenSCManager failed with " << GetLastError() << endl;
exit(EXIT_FAILURE);
}
@ -196,7 +196,7 @@ static void InstallServiceCommand (string command) {
CloseServiceHandle(schSCManager);
if (schService == 0) {
cout << "FATAL: CreateServiceA failed with " << GetLastError() << endl;
cerr << "FATAL: CreateServiceA failed with " << GetLastError() << endl;
exit(EXIT_FAILURE);
}
@ -220,7 +220,7 @@ static void InstallService (int argc, char* argv[]) {
CHAR path[MAX_PATH];
if(! GetModuleFileNameA(NULL, path, MAX_PATH)) {
cout << "FATAL: GetModuleFileNameA failed" << endl;
cerr << "FATAL: GetModuleFileNameA failed" << endl;
exit(EXIT_FAILURE);
}
@ -251,7 +251,7 @@ static void DeleteService (int argc, char* argv[]) {
SC_HANDLE schSCManager = OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_ALL_ACCESS);
if (schSCManager == 0) {
cout << "FATAL: OpenSCManager failed with " << GetLastError() << endl;
cerr << "FATAL: OpenSCManager failed with " << GetLastError() << endl;
exit(EXIT_FAILURE);
}
@ -263,12 +263,12 @@ static void DeleteService (int argc, char* argv[]) {
CloseServiceHandle(schSCManager);
if (schService == 0) {
cout << "FATAL: OpenServiceA failed with " << GetLastError() << endl;
cerr << "FATAL: OpenServiceA failed with " << GetLastError() << endl;
exit(EXIT_FAILURE);
}
if (! DeleteService(schService)) {
cout << "FATAL: DeleteService failed with " << GetLastError() << endl;
cerr << "FATAL: DeleteService failed with " << GetLastError() << endl;
exit(EXIT_FAILURE);
}
@ -309,7 +309,7 @@ static void SetServiceStatus (DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD
ss.dwControlsAccepted = 0;
SetServiceStatus(ServiceStatus, &ss);
if (ArangoInstance != 0) {
if (ArangoInstance != nullptr) {
ArangoInstance->beginShutdown();
}
@ -346,7 +346,7 @@ static void WINAPI ServiceCtrl (DWORD dwCtrlCode) {
if (dwCtrlCode == SERVICE_CONTROL_STOP || dwCtrlCode == SERVICE_CONTROL_SHUTDOWN) {
SetServiceStatus(SERVICE_STOP_PENDING, NO_ERROR, 0, 0);
if (ArangoInstance != 0) {
if (ArangoInstance != nullptr) {
ArangoInstance->beginShutdown();
while (IsRunning) {
@ -402,9 +402,9 @@ static void WINAPI ServiceMain (DWORD dwArgc, LPSTR *lpszArgv) {
int main (int argc, char* argv[]) {
int res = 0;
bool startAsService = false;
#ifdef _WIN32
bool startAsService = false;
if (1 < argc) {
if (TRI_EqualString(argv[1], "--install-service")) {
@ -440,30 +440,36 @@ int main (int argc, char* argv[]) {
ARGV = argv;
if (! StartServiceCtrlDispatcher(ste)) {
cout << "FATAL: StartServiceCtrlDispatcher has failed with " << GetLastError() << endl;
exit(EXIT_SUCCESS);
cerr << "FATAL: StartServiceCtrlDispatcher has failed with " << GetLastError() << endl;
exit(EXIT_FAILURE);
}
}
else {
#endif
if (! startAsService) {
ArangoInstance = new ArangoServer(argc, argv);
res = ArangoInstance->start();
}
#else
if (ArangoInstance != nullptr) {
try {
delete ArangoInstance;
}
catch (...) {
// caught an error during shutdown
res = EXIT_FAILURE;
ArangoInstance = new ArangoServer(argc, argv);
res = ArangoInstance->start();
#endif
if (ArangoInstance != 0) {
delete ArangoInstance;
ArangoInstance = 0;
#ifdef TRI_ENABLE_MAINTAINER_MODE
cerr << "Caught an exception during shutdown";
#endif
}
ArangoInstance = nullptr;
}
// shutdown sub-systems
TRIAGENS_REST_SHUTDOWN;
TRI_GlobalExitFunction(res, NULL);
TRI_GlobalExitFunction(res, nullptr);
return res;
}

View File

@ -286,7 +286,7 @@ ApplicationV8::ApplicationV8 (TRI_server_t* server,
_gcFrequency(10.0),
_v8Options(""),
_startupLoader(),
_vocbase(0),
_vocbase(nullptr),
_nrInstances(),
_contexts(),
_contextCondition(),
@ -352,7 +352,7 @@ ApplicationV8::V8Context* ApplicationV8::enterContext (std::string const& name,
// in case we are in the shutdown phase, do not enter a context!
// the context might have been deleted by the shutdown
if (_stopping) {
return 0;
return nullptr;
}
LOG_TRACE("found unused V8 context");
@ -594,7 +594,7 @@ void ApplicationV8::collectGarbage () {
// there is no context to clean up, probably they all have been cleaned up
// already. increase the wait time so we don't cycle too much in the GC loop
// and waste CPU unnecessary
useReducedWait = (context != 0);
useReducedWait = (context != nullptr);
}
}

View File

@ -1988,15 +1988,13 @@ int TRI_InitDatabasesServer (TRI_server_t* server) {
////////////////////////////////////////////////////////////////////////////////
int TRI_StopServer (TRI_server_t* server) {
int res;
// set shutdown flag
TRI_LockMutex(&server->_createLock);
server->_shutdown = true;
TRI_UnlockMutex(&server->_createLock);
// stop dbm thread
res = TRI_JoinThread(&server->_databaseManager);
int res = TRI_JoinThread(&server->_databaseManager);
CloseDatabases(server);

View File

@ -531,8 +531,9 @@ function getQueryMultiplePlansAndExecutions (query, bindVars, testObject, debug)
}
results[i] = AQL_EXECUTEJSON(plans[i].plan, paramNone);
// ignore statistics for comparisons
delete results[i].stats;
// ignore these statistics for comparisons
delete results[i].stats.scannedFull;
delete results[i].stats.scannedIndex;
if (debug) {
require("internal").print("\n" + i + " DONE\n");

View File

@ -34,7 +34,6 @@ var helper = require("org/arangodb/aql-helper");
var cluster = require("org/arangodb/cluster");
var getQueryMultiplePlansAndExecutions = helper.getQueryMultiplePlansAndExecutions;
////////////////////////////////////////////////////////////////////////////////
/// @brief test suite
////////////////////////////////////////////////////////////////////////////////
@ -95,7 +94,7 @@ function ahuacatlRemoveSuite () {
var allresults = getQueryMultiplePlansAndExecutions(query, {}, this);
assertEqual(100, c1.count());
for (var i=0; i < allresults.results.length; i++) {
for (var i = 0; i < allresults.results.length; i++) {
assertEqual(expected, allresults.results[i].stats,
"comparing " + i + " : " + allresults.results[i].stats);
}
@ -113,7 +112,7 @@ function ahuacatlRemoveSuite () {
var allresults = getQueryMultiplePlansAndExecutions(query, { "@cn": cn1 }, this);
assertEqual(100, c1.count());
for (var i=0; i < allresults.results.length; i++) {
for (var i = 0; i < allresults.results.length; i++) {
assertEqual(expected, allresults.results[i].stats,
"comparing " + i + " : " + allresults.results[i].stats);
}
@ -399,7 +398,6 @@ function ahuacatlInsertSuite () {
}
db._drop("UnitTestsAhuacatlEdge");
edge = db._createEdgeCollection("UnitTestsAhuacatlEdge");
},
////////////////////////////////////////////////////////////////////////////////
@ -424,7 +422,7 @@ function ahuacatlInsertSuite () {
var allresults = getQueryMultiplePlansAndExecutions(query, {}, this);
assertEqual(100, c1.count());
for (var i=0; i < allresults.results.length; i++) {
for (var i = 0; i < allresults.results.length; i++) {
assertEqual(expected, allresults.results[i].stats,
"comparing " + i + " : " + allresults.results[i].stats);
}
@ -439,7 +437,7 @@ function ahuacatlInsertSuite () {
var allresults = getQueryMultiplePlansAndExecutions(query, { "@cn": cn1 }, this);
assertEqual(100, c1.count());
for (var i=0; i < allresults.results.length; i++) {
for (var i = 0; i < allresults.results.length; i++) {
assertEqual(expected, allresults.results[i].stats,
"comparing " + i + " : " + allresults.results[i].stats);
}
@ -455,7 +453,7 @@ function ahuacatlInsertSuite () {
var allresults = getQueryMultiplePlansAndExecutions(query, { "@cn": cn1 }, this);
assertEqual(100, c1.count());
for (var i=0; i < allresults.results.length; i++) {
for (var i = 0; i < allresults.results.length; i++) {
assertEqual(expected, allresults.results[i].stats,
"comparing " + i + " : " + allresults.results[i].stats);
}
@ -471,7 +469,7 @@ function ahuacatlInsertSuite () {
var allresults = getQueryMultiplePlansAndExecutions(query, { "@cn": cn1 }, this);
assertEqual(101, c1.count());
for (var i=0; i < allresults.results.length; i++) {
for (var i = 0; i < allresults.results.length; i++) {
assertEqual(expected, allresults.results[i].stats,
"comparing " + i + " : " + allresults.results[i].stats);
}

View File

@ -870,7 +870,7 @@ namespace triagens {
/// @brief checks whether *this is a Json that is equal to null.
////////////////////////////////////////////////////////////////////////////////
bool isNull () throw() {
bool isNull () const throw() {
return _json != nullptr && _json->_type == TRI_JSON_NULL;
}
@ -878,7 +878,7 @@ namespace triagens {
/// @brief checks whether *this is a boolean Json.
////////////////////////////////////////////////////////////////////////////////
bool isBoolean () throw() {
bool isBoolean () const throw() {
return TRI_IsBooleanJson(_json);
}
@ -886,7 +886,7 @@ namespace triagens {
/// @brief checks whether *this is a number Json.
////////////////////////////////////////////////////////////////////////////////
bool isNumber () throw() {
bool isNumber () const throw() {
return TRI_IsNumberJson(_json);
}
@ -894,7 +894,7 @@ namespace triagens {
/// @brief checks whether *this is a string Json.
////////////////////////////////////////////////////////////////////////////////
bool isString () throw() {
bool isString () const throw() {
return TRI_IsStringJson(_json);
}
@ -902,7 +902,7 @@ namespace triagens {
/// @brief checks whether *this is an array Json.
////////////////////////////////////////////////////////////////////////////////
bool isArray () throw() {
bool isArray () const throw() {
return TRI_IsArrayJson(_json);
}
@ -910,7 +910,7 @@ namespace triagens {
/// @brief checks whether *this is a list Json.
////////////////////////////////////////////////////////////////////////////////
bool isList () throw() {
bool isList () const throw() {
return TRI_IsListJson(_json);
}

View File

@ -241,7 +241,7 @@ AnyServer::AnyServer ()
_supervisorMode(false),
_pidFile(""),
_workingDirectory(""),
_applicationServer(0) {
_applicationServer(nullptr) {
}
////////////////////////////////////////////////////////////////////////////////
@ -249,7 +249,7 @@ AnyServer::AnyServer ()
////////////////////////////////////////////////////////////////////////////////
AnyServer::~AnyServer () {
if (_applicationServer != 0) {
if (_applicationServer != nullptr) {
delete _applicationServer;
}
}

View File

@ -2838,7 +2838,7 @@ static v8::Handle<v8::Value> JS_PBKDF2 (v8::Arguments const& argv) {
// extract arguments
if (argv.Length() < 4 || ! argv[0]->IsString() || ! argv[1]->IsString() || ! argv[2]->IsNumber() || ! argv[3]->IsNumber()) {
TRI_V8_EXCEPTION_USAGE(scope, "PBKDF2(<salt>, <password>, <iterations>, <keyLength>, <algorithm>)");
TRI_V8_EXCEPTION_USAGE(scope, "PBKDF2(<salt>, <password>, <iterations>, <keyLength>)");
}
string salt = TRI_ObjectToString(argv[0]);