1
0
Fork 0

simplify query list a great deal and use less dynamic memory for its entries

This commit is contained in:
jsteemann 2017-03-02 13:20:37 +01:00
parent 83a8c7281d
commit 1b7b668066
9 changed files with 131 additions and 139 deletions

View File

@ -732,7 +732,7 @@ QueryResult Query::execute(QueryRegistry* registry) {
// patch stats in place // patch stats in place
// we do this because "executionTime" should include the whole span of the execution and we have to set it at the very end // we do this because "executionTime" should include the whole span of the execution and we have to set it at the very end
basics::VelocyPackHelper::patchDouble(result.stats->slice().get("executionTime"), TRI_microtime() - _startTime); basics::VelocyPackHelper::patchDouble(result.stats->slice().get("executionTime"), runTime());
LOG_TOPIC(DEBUG, Logger::QUERIES) << TRI_microtime() - _startTime << " " LOG_TOPIC(DEBUG, Logger::QUERIES) << TRI_microtime() - _startTime << " "
<< "Query::execute:returning" << "Query::execute:returning"
@ -742,22 +742,22 @@ QueryResult Query::execute(QueryRegistry* registry) {
} catch (arangodb::basics::Exception const& ex) { } catch (arangodb::basics::Exception const& ex) {
setExecutionTime(); setExecutionTime();
cleanupPlanAndEngine(ex.code()); cleanupPlanAndEngine(ex.code());
return QueryResult(ex.code(), ex.message() + QueryExecutionState::toString(_state)); return QueryResult(ex.code(), ex.message() + QueryExecutionState::toStringWithPrefix(_state));
} catch (std::bad_alloc const&) { } catch (std::bad_alloc const&) {
setExecutionTime(); setExecutionTime();
cleanupPlanAndEngine(TRI_ERROR_OUT_OF_MEMORY); cleanupPlanAndEngine(TRI_ERROR_OUT_OF_MEMORY);
return QueryResult( return QueryResult(
TRI_ERROR_OUT_OF_MEMORY, TRI_ERROR_OUT_OF_MEMORY,
TRI_errno_string(TRI_ERROR_OUT_OF_MEMORY) + QueryExecutionState::toString(_state)); TRI_errno_string(TRI_ERROR_OUT_OF_MEMORY) + QueryExecutionState::toStringWithPrefix(_state));
} catch (std::exception const& ex) { } catch (std::exception const& ex) {
setExecutionTime(); setExecutionTime();
cleanupPlanAndEngine(TRI_ERROR_INTERNAL); cleanupPlanAndEngine(TRI_ERROR_INTERNAL);
return QueryResult(TRI_ERROR_INTERNAL, ex.what() + QueryExecutionState::toString(_state)); return QueryResult(TRI_ERROR_INTERNAL, ex.what() + QueryExecutionState::toStringWithPrefix(_state));
} catch (...) { } catch (...) {
setExecutionTime(); setExecutionTime();
cleanupPlanAndEngine(TRI_ERROR_INTERNAL); cleanupPlanAndEngine(TRI_ERROR_INTERNAL);
return QueryResult(TRI_ERROR_INTERNAL, return QueryResult(TRI_ERROR_INTERNAL,
TRI_errno_string(TRI_ERROR_INTERNAL) + QueryExecutionState::toString(_state)); TRI_errno_string(TRI_ERROR_INTERNAL) + QueryExecutionState::toStringWithPrefix(_state));
} }
} }
@ -918,7 +918,7 @@ QueryResultV8 Query::executeV8(v8::Isolate* isolate, QueryRegistry* registry) {
// patch executionTime stats value in place // patch executionTime stats value in place
// we do this because "executionTime" should include the whole span of the execution and we have to set it at the very end // we do this because "executionTime" should include the whole span of the execution and we have to set it at the very end
basics::VelocyPackHelper::patchDouble(result.stats->slice().get("executionTime"), TRI_microtime() - _startTime); basics::VelocyPackHelper::patchDouble(result.stats->slice().get("executionTime"), runTime());
LOG_TOPIC(DEBUG, Logger::QUERIES) << TRI_microtime() - _startTime << " " LOG_TOPIC(DEBUG, Logger::QUERIES) << TRI_microtime() - _startTime << " "
<< "Query::executeV8:returning" << "Query::executeV8:returning"
@ -928,22 +928,22 @@ QueryResultV8 Query::executeV8(v8::Isolate* isolate, QueryRegistry* registry) {
} catch (arangodb::basics::Exception const& ex) { } catch (arangodb::basics::Exception const& ex) {
setExecutionTime(); setExecutionTime();
cleanupPlanAndEngine(ex.code()); cleanupPlanAndEngine(ex.code());
return QueryResultV8(ex.code(), ex.message() + QueryExecutionState::toString(_state)); return QueryResultV8(ex.code(), ex.message() + QueryExecutionState::toStringWithPrefix(_state));
} catch (std::bad_alloc const&) { } catch (std::bad_alloc const&) {
setExecutionTime(); setExecutionTime();
cleanupPlanAndEngine(TRI_ERROR_OUT_OF_MEMORY); cleanupPlanAndEngine(TRI_ERROR_OUT_OF_MEMORY);
return QueryResultV8( return QueryResultV8(
TRI_ERROR_OUT_OF_MEMORY, TRI_ERROR_OUT_OF_MEMORY,
TRI_errno_string(TRI_ERROR_OUT_OF_MEMORY) + QueryExecutionState::toString(_state)); TRI_errno_string(TRI_ERROR_OUT_OF_MEMORY) + QueryExecutionState::toStringWithPrefix(_state));
} catch (std::exception const& ex) { } catch (std::exception const& ex) {
setExecutionTime(); setExecutionTime();
cleanupPlanAndEngine(TRI_ERROR_INTERNAL); cleanupPlanAndEngine(TRI_ERROR_INTERNAL);
return QueryResultV8(TRI_ERROR_INTERNAL, ex.what() + QueryExecutionState::toString(_state)); return QueryResultV8(TRI_ERROR_INTERNAL, ex.what() + QueryExecutionState::toStringWithPrefix(_state));
} catch (...) { } catch (...) {
setExecutionTime(); setExecutionTime();
cleanupPlanAndEngine(TRI_ERROR_INTERNAL); cleanupPlanAndEngine(TRI_ERROR_INTERNAL);
return QueryResult(TRI_ERROR_INTERNAL, return QueryResult(TRI_ERROR_INTERNAL,
TRI_errno_string(TRI_ERROR_INTERNAL) + QueryExecutionState::toString(_state)); TRI_errno_string(TRI_ERROR_INTERNAL) + QueryExecutionState::toStringWithPrefix(_state));
} }
} }
@ -1056,16 +1056,16 @@ QueryResult Query::explain() {
return result; return result;
} catch (arangodb::basics::Exception const& ex) { } catch (arangodb::basics::Exception const& ex) {
return QueryResult(ex.code(), ex.message() + QueryExecutionState::toString(_state)); return QueryResult(ex.code(), ex.message() + QueryExecutionState::toStringWithPrefix(_state));
} catch (std::bad_alloc const&) { } catch (std::bad_alloc const&) {
return QueryResult( return QueryResult(
TRI_ERROR_OUT_OF_MEMORY, TRI_ERROR_OUT_OF_MEMORY,
TRI_errno_string(TRI_ERROR_OUT_OF_MEMORY) + QueryExecutionState::toString(_state)); TRI_errno_string(TRI_ERROR_OUT_OF_MEMORY) + QueryExecutionState::toStringWithPrefix(_state));
} catch (std::exception const& ex) { } catch (std::exception const& ex) {
return QueryResult(TRI_ERROR_INTERNAL, ex.what() + QueryExecutionState::toString(_state)); return QueryResult(TRI_ERROR_INTERNAL, ex.what() + QueryExecutionState::toStringWithPrefix(_state));
} catch (...) { } catch (...) {
return QueryResult(TRI_ERROR_INTERNAL, return QueryResult(TRI_ERROR_INTERNAL,
TRI_errno_string(TRI_ERROR_INTERNAL) + QueryExecutionState::toString(_state)); TRI_errno_string(TRI_ERROR_INTERNAL) + QueryExecutionState::toStringWithPrefix(_state));
} }
} }

View File

@ -104,6 +104,9 @@ class Query {
/// @brief return the start timestamp of the query /// @brief return the start timestamp of the query
double startTime () const { return _startTime; } double startTime () const { return _startTime; }
/// @brief return the current runtime of the query
double runTime () const { return TRI_microtime() - _startTime; }
/// @brief whether or not the query is killed /// @brief whether or not the query is killed
inline bool killed() const { return _killed; } inline bool killed() const { return _killed; }

View File

@ -26,7 +26,7 @@
using namespace arangodb::aql; using namespace arangodb::aql;
/// @brief names of query phases / states /// @brief names of query phases / states
static std::string StateNames[] = { static std::string const StateNames[] = {
"initializing", // INITIALIZATION "initializing", // INITIALIZATION
"parsing", // PARSING "parsing", // PARSING
"optimizing ast", // AST_OPTIMIZATION "optimizing ast", // AST_OPTIMIZATION
@ -35,6 +35,7 @@ static std::string StateNames[] = {
"optimizing plan", // PLAN_OPTIMIZATION "optimizing plan", // PLAN_OPTIMIZATION
"executing", // EXECUTION "executing", // EXECUTION
"finalizing", // FINALIZATION "finalizing", // FINALIZATION
"finished", // FINISHED
"invalid" // INVALID "invalid" // INVALID
}; };
@ -46,6 +47,11 @@ static_assert(sizeof(StateNames) / sizeof(std::string) ==
/// @brief get a description of the query's current state /// @brief get a description of the query's current state
std::string QueryExecutionState::toString(QueryExecutionState::ValueType state) { std::string QueryExecutionState::toString(QueryExecutionState::ValueType state) {
return StateNames[static_cast<int>(state)];
}
/// @brief get a description of the query's current state, prefixed with " (while "
std::string QueryExecutionState::toStringWithPrefix(QueryExecutionState::ValueType state) {
return std::string(" (while " + StateNames[static_cast<int>(state)] + ")"); return std::string(" (while " + StateNames[static_cast<int>(state)] + ")");
} }

View File

@ -42,11 +42,13 @@ enum class ValueType {
PLAN_OPTIMIZATION, PLAN_OPTIMIZATION,
EXECUTION, EXECUTION,
FINALIZATION, FINALIZATION,
FINISHED,
INVALID_STATE INVALID_STATE
}; };
std::string toString(QueryExecutionState::ValueType state); std::string toString(QueryExecutionState::ValueType state);
std::string toStringWithPrefix(QueryExecutionState::ValueType state);
} }
} }

View File

@ -31,14 +31,11 @@
using namespace arangodb::aql; using namespace arangodb::aql;
QueryEntry::QueryEntry(arangodb::aql::Query const* query, double started)
: query(query), started(started) {}
QueryEntryCopy::QueryEntryCopy(TRI_voc_tick_t id, QueryEntryCopy::QueryEntryCopy(TRI_voc_tick_t id,
std::string const& queryString, double started, std::string const& queryString, double started,
double runTime, std::string const& queryState) double runTime, QueryExecutionState::ValueType state)
: id(id), queryString(queryString), started(started), runTime(runTime), : id(id), queryString(queryString), started(started), runTime(runTime),
queryState(queryState) {} state(state) {}
double const QueryList::DefaultSlowQueryThreshold = 10.0; double const QueryList::DefaultSlowQueryThreshold = 10.0;
size_t const QueryList::DefaultMaxSlowQueries = 64; size_t const QueryList::DefaultMaxSlowQueries = 64;
@ -62,32 +59,26 @@ QueryList::QueryList(TRI_vocbase_t*)
QueryList::~QueryList() { QueryList::~QueryList() {
WRITE_LOCKER(writeLocker, _lock); WRITE_LOCKER(writeLocker, _lock);
for (auto& it : _current) {
delete it.second;
}
_current.clear(); _current.clear();
_slow.clear(); _slow.clear();
} }
/// @brief insert a query /// @brief insert a query
bool QueryList::insert(Query const* query, double stamp) { bool QueryList::insert(Query const* query) {
// not enable or no query string // not enable or no query string
if (!_enabled || query == nullptr || query->queryString() == nullptr) { if (!_enabled || query == nullptr || query->queryString() == nullptr) {
return false; return false;
} }
try { try {
auto entry = std::make_unique<QueryEntry>(query, stamp);
WRITE_LOCKER(writeLocker, _lock); WRITE_LOCKER(writeLocker, _lock);
TRI_IF_FAILURE("QueryList::insert") { TRI_IF_FAILURE("QueryList::insert") {
THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG); THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG);
} }
auto it = _current.emplace(query->id(), entry.get()); auto it = _current.emplace(query->id(), query);
if (it.second) { if (it.second) {
entry.release();
return true; return true;
} }
} catch (...) { } catch (...) {
@ -97,7 +88,7 @@ bool QueryList::insert(Query const* query, double stamp) {
} }
/// @brief remove a query /// @brief remove a query
void QueryList::remove(Query const* query, double now) { void QueryList::remove(Query const* query) {
// we're intentionally not checking _enabled here... // we're intentionally not checking _enabled here...
// note: there is the possibility that a query got inserted when the // note: there is the possibility that a query got inserted when the
@ -111,78 +102,77 @@ void QueryList::remove(Query const* query, double now) {
} }
size_t const maxLength = _maxQueryStringLength; size_t const maxLength = _maxQueryStringLength;
QueryEntry* entry = nullptr;
{ WRITE_LOCKER(writeLocker, _lock);
WRITE_LOCKER(writeLocker, _lock); auto it = _current.find(query->id());
auto it = _current.find(query->id());
if (it != _current.end()) { if (it != _current.end()) {
entry = (*it).second; Query const* query = (*it).second;
_current.erase(it); _current.erase(it);
TRI_ASSERT(entry != nullptr); TRI_ASSERT(query != nullptr);
double const started = query->startTime();
double const now = TRI_microtime();
try { try {
// check if we need to push the query into the list of slow queries // check if we need to push the query into the list of slow queries
if (_trackSlowQueries && _slowQueryThreshold >= 0.0 && if (_trackSlowQueries && _slowQueryThreshold >= 0.0 &&
now - entry->started >= _slowQueryThreshold) { now - started >= _slowQueryThreshold) {
// yes. // yes.
char const* queryString = entry->query->queryString(); std::string q;
size_t const originalLength = entry->query->queryLength(); char const* queryString = query->queryString();
size_t length = originalLength; size_t length = query->queryLength();
if (length > maxLength) { if (length > maxLength) {
length = maxLength; // query string needs truncation
TRI_ASSERT(length <= originalLength); length = maxLength;
// do not create invalid UTF-8 sequences // do not create invalid UTF-8 sequences
while (length > 0) { while (length > 0) {
uint8_t c = queryString[length - 1]; uint8_t c = queryString[length - 1];
if ((c & 128) == 0) { if ((c & 128) == 0) {
// single-byte character // single-byte character
break; break;
} }
--length; --length;
// start of a multi-byte sequence // start of a multi-byte sequence
if ((c & 192) == 192) { if ((c & 192) == 192) {
// decrease length by one more, so we the string contains the // decrease length by one more, so we the string contains the
// last part of the previous (multi-byte?) sequence // last part of the previous (multi-byte?) sequence
break; break;
}
} }
} }
TRI_IF_FAILURE("QueryList::remove") { q.reserve(length + 3);
THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG); q.append(queryString, length);
} q.append("...", 3);
} else {
std::string q(queryString, length); // no truncation
q.append(originalLength > maxLength ? "..." : ""); q.append(queryString, length);
LOG_TOPIC(WARN, Logger::QUERIES) << "slow query: '" << q << "', took: " << Logger::FIXED(now - entry->started);
_slow.emplace_back(QueryEntryCopy(
entry->query->id(),
std::move(q),
entry->started, now - entry->started,
std::string(" (while finished)")));
if (++_slowCount > _maxSlowQueries) {
// free first element
_slow.pop_front();
--_slowCount;
}
} }
} catch (...) {
}
}
}
if (entry != nullptr) { TRI_IF_FAILURE("QueryList::remove") {
delete entry; THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG);
}
LOG_TOPIC(WARN, Logger::QUERIES) << "slow query: '" << q << "', took: " << Logger::FIXED(now - started);
_slow.emplace_back(QueryEntryCopy(
query->id(),
std::move(q),
started, now - started,
QueryExecutionState::ValueType::FINISHED));
if (++_slowCount > _maxSlowQueries) {
// free first element
_slow.pop_front();
--_slowCount;
}
}
} catch (...) {
}
} }
} }
@ -199,10 +189,10 @@ int QueryList::kill(TRI_voc_tick_t id) {
return TRI_ERROR_QUERY_NOT_FOUND; return TRI_ERROR_QUERY_NOT_FOUND;
} }
auto entry = (*it).second; Query const* query = (*it).second;
queryString.assign(entry->query->queryString(), queryString.assign(query->queryString(),
entry->query->queryLength()); query->queryLength());
const_cast<arangodb::aql::Query*>(entry->query)->killed(true); const_cast<arangodb::aql::Query*>(query)->killed(true);
} }
// log outside the lock // log outside the lock
@ -218,20 +208,19 @@ uint64_t QueryList::killAll(bool silent) {
WRITE_LOCKER(writeLocker, _lock); WRITE_LOCKER(writeLocker, _lock);
for (auto& it : _current) { for (auto& it : _current) {
auto entry = it.second; Query const* query = it.second;
const_cast<arangodb::aql::Query*>(entry->query)->killed(true);
++killed; std::string queryString(query->queryString(),
query->queryLength());
std::string queryString(entry->query->queryString(),
entry->query->queryLength());
if (silent) { if (silent) {
LOG_TOPIC(TRACE, arangodb::Logger::FIXME) << "killing AQL query " << entry->query->id() << " '" << queryString << "'"; LOG_TOPIC(TRACE, arangodb::Logger::FIXME) << "killing AQL query " << query->id() << " '" << queryString << "'";
} else { } else {
LOG_TOPIC(WARN, arangodb::Logger::FIXME) << "killing AQL query " << entry->query->id() << " '" << queryString << "'"; LOG_TOPIC(WARN, arangodb::Logger::FIXME) << "killing AQL query " << query->id() << " '" << queryString << "'";
} }
const_cast<arangodb::aql::Query*>(query)->killed(true);
++killed;
} }
return killed; return killed;
@ -249,14 +238,14 @@ std::vector<QueryEntryCopy> QueryList::listCurrent() {
result.reserve(_current.size()); result.reserve(_current.size());
for (auto const& it : _current) { for (auto const& it : _current) {
auto entry = it.second; Query const* query = it.second;
if (entry == nullptr || entry->query->queryString() == nullptr) { if (query == nullptr || query->queryString() == nullptr) {
continue; continue;
} }
char const* queryString = entry->query->queryString(); char const* queryString = query->queryString();
size_t const originalLength = entry->query->queryLength(); size_t const originalLength = query->queryLength();
size_t length = originalLength; size_t length = originalLength;
if (length > maxLength) { if (length > maxLength) {
@ -280,13 +269,15 @@ std::vector<QueryEntryCopy> QueryList::listCurrent() {
} }
} }
} }
double const started = query->startTime();
result.emplace_back( result.emplace_back(
QueryEntryCopy(entry->query->id(), QueryEntryCopy(query->id(),
std::string(queryString, length) std::string(queryString, length)
.append(originalLength > maxLength ? "..." : ""), .append(originalLength > maxLength ? "..." : ""),
entry->started, now - entry->started, started, now - started,
QueryExecutionState::toString(entry->query->state()))); query->state()));
} }
} }

View File

@ -25,6 +25,7 @@
#define ARANGOD_AQL_QUERY_LIST_H 1 #define ARANGOD_AQL_QUERY_LIST_H 1
#include "Basics/Common.h" #include "Basics/Common.h"
#include "Aql/QueryExecutionState.h"
#include "Basics/ReadWriteLock.h" #include "Basics/ReadWriteLock.h"
#include "VocBase/voc-types.h" #include "VocBase/voc-types.h"
@ -41,25 +42,18 @@ class Query;
// --SECTION-- struct QueryEntry // --SECTION-- struct QueryEntry
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
struct QueryEntry {
QueryEntry(arangodb::aql::Query const*, double);
arangodb::aql::Query const* query;
double const started;
};
struct QueryEntryCopy { struct QueryEntryCopy {
QueryEntryCopy (TRI_voc_tick_t, QueryEntryCopy (TRI_voc_tick_t id,
std::string const&, std::string const& queryString,
double, double started,
double, double runTime,
std::string const&); QueryExecutionState::ValueType state);
TRI_voc_tick_t id; TRI_voc_tick_t id;
std::string queryString; std::string queryString;
double started; double started;
double runTime; double runTime;
std::string queryState; QueryExecutionState::ValueType state;
}; };
class QueryList { class QueryList {
@ -143,10 +137,10 @@ class QueryList {
} }
/// @brief enter a query /// @brief enter a query
bool insert(Query const*, double); bool insert(Query const*);
/// @brief remove a query /// @brief remove a query
void remove(Query const*, double); void remove(Query const*);
/// @brief kills a query /// @brief kills a query
int kill(TRI_voc_tick_t); int kill(TRI_voc_tick_t);
@ -168,7 +162,7 @@ class QueryList {
arangodb::basics::ReadWriteLock _lock; arangodb::basics::ReadWriteLock _lock;
/// @brief list of current queries /// @brief list of current queries
std::unordered_map<TRI_voc_tick_t, QueryEntry*> _current; std::unordered_map<TRI_voc_tick_t, Query const*> _current;
/// @brief list of slow queries /// @brief list of slow queries
std::list<QueryEntryCopy> _slow; std::list<QueryEntryCopy> _slow;

View File

@ -39,7 +39,7 @@ QueryProfile::QueryProfile(Query* query)
auto queryList = query->vocbase()->queryList(); auto queryList = query->vocbase()->queryList();
try { try {
tracked = queryList->insert(query, stamp); tracked = queryList->insert(query);
} catch (...) { } catch (...) {
} }
} }
@ -51,7 +51,7 @@ QueryProfile::~QueryProfile() {
auto queryList = query->vocbase()->queryList(); auto queryList = query->vocbase()->queryList();
try { try {
queryList->remove(query, stamp); queryList->remove(query);
} catch (...) { } catch (...) {
} }
} }

View File

@ -106,17 +106,14 @@ bool RestQueryHandler::readQuery(bool slow) {
result.add(VPackValue(VPackValueType::Array)); result.add(VPackValue(VPackValueType::Array));
for (auto const& q : queries) { for (auto const& q : queries) {
auto const& timeString = TRI_StringTimeStamp(q.started, Logger::getUseLocalTime()); auto timeString = TRI_StringTimeStamp(q.started, Logger::getUseLocalTime());
auto const& queryString = q.queryString;
auto const& queryState = q.queryState.substr(8, q.queryState.size() - 9);
result.add(VPackValue(VPackValueType::Object)); result.add(VPackValue(VPackValueType::Object));
result.add("id", VPackValue(StringUtils::itoa(q.id))); result.add("id", VPackValue(StringUtils::itoa(q.id)));
result.add("query", VPackValue(queryString)); result.add("query", VPackValue(q.queryString));
result.add("started", VPackValue(timeString)); result.add("started", VPackValue(timeString));
result.add("runTime", VPackValue(q.runTime)); result.add("runTime", VPackValue(q.runTime));
result.add("state", VPackValue(queryState)); result.add("state", VPackValue(QueryExecutionState::toString(q.state)));
result.close(); result.close();
} }
result.close(); result.close();

View File

@ -39,6 +39,7 @@
#include "ApplicationFeatures/HttpEndpointProvider.h" #include "ApplicationFeatures/HttpEndpointProvider.h"
#include "Aql/Query.h" #include "Aql/Query.h"
#include "Aql/QueryCache.h" #include "Aql/QueryCache.h"
#include "Aql/QueryExecutionState.h"
#include "Aql/QueryList.h" #include "Aql/QueryList.h"
#include "Aql/QueryRegistry.h" #include "Aql/QueryRegistry.h"
#include "Basics/HybridLogicalClock.h" #include "Basics/HybridLogicalClock.h"
@ -1475,8 +1476,7 @@ static void JS_QueriesCurrentAql(
auto result = v8::Array::New(isolate, static_cast<int>(queries.size())); auto result = v8::Array::New(isolate, static_cast<int>(queries.size()));
for (auto q : queries) { for (auto q : queries) {
auto const&& timeString = TRI_StringTimeStamp(q.started, false); auto timeString = TRI_StringTimeStamp(q.started, false);
auto const& queryState = q.queryState.substr(8, q.queryState.size() - 9);
v8::Handle<v8::Object> obj = v8::Object::New(isolate); v8::Handle<v8::Object> obj = v8::Object::New(isolate);
obj->Set(TRI_V8_ASCII_STRING("id"), V8TickId(isolate, q.id)); obj->Set(TRI_V8_ASCII_STRING("id"), V8TickId(isolate, q.id));
@ -1484,7 +1484,7 @@ static void JS_QueriesCurrentAql(
obj->Set(TRI_V8_ASCII_STRING("started"), TRI_V8_STD_STRING(timeString)); obj->Set(TRI_V8_ASCII_STRING("started"), TRI_V8_STD_STRING(timeString));
obj->Set(TRI_V8_ASCII_STRING("runTime"), obj->Set(TRI_V8_ASCII_STRING("runTime"),
v8::Number::New(isolate, q.runTime)); v8::Number::New(isolate, q.runTime));
obj->Set(TRI_V8_ASCII_STRING("state"), TRI_V8_STD_STRING(queryState)); obj->Set(TRI_V8_ASCII_STRING("state"), TRI_V8_STD_STRING(aql::QueryExecutionState::toString(q.state)));
result->Set(i++, obj); result->Set(i++, obj);
} }
@ -1528,8 +1528,7 @@ static void JS_QueriesSlowAql(v8::FunctionCallbackInfo<v8::Value> const& args) {
auto result = v8::Array::New(isolate, static_cast<int>(queries.size())); auto result = v8::Array::New(isolate, static_cast<int>(queries.size()));
for (auto q : queries) { for (auto q : queries) {
auto const&& timeString = TRI_StringTimeStamp(q.started, false); auto timeString = TRI_StringTimeStamp(q.started, false);
auto const& queryState = q.queryState.substr(8, q.queryState.size() - 9);
v8::Handle<v8::Object> obj = v8::Object::New(isolate); v8::Handle<v8::Object> obj = v8::Object::New(isolate);
obj->Set(TRI_V8_ASCII_STRING("id"), V8TickId(isolate, q.id)); obj->Set(TRI_V8_ASCII_STRING("id"), V8TickId(isolate, q.id));
@ -1537,7 +1536,7 @@ static void JS_QueriesSlowAql(v8::FunctionCallbackInfo<v8::Value> const& args) {
obj->Set(TRI_V8_ASCII_STRING("started"), TRI_V8_STD_STRING(timeString)); obj->Set(TRI_V8_ASCII_STRING("started"), TRI_V8_STD_STRING(timeString));
obj->Set(TRI_V8_ASCII_STRING("runTime"), obj->Set(TRI_V8_ASCII_STRING("runTime"),
v8::Number::New(isolate, q.runTime)); v8::Number::New(isolate, q.runTime));
obj->Set(TRI_V8_ASCII_STRING("state"), TRI_V8_STD_STRING(queryState)); obj->Set(TRI_V8_ASCII_STRING("state"), TRI_V8_STD_STRING(aql::QueryExecutionState::toString(q.state)));
result->Set(i++, obj); result->Set(i++, obj);
} }