Skip to content

Commit

Permalink
Add fakequery string to creation of queries on DBServers
Browse files Browse the repository at this point in the history
  • Loading branch information
ObiWahn committed Aug 25, 2017
1 parent fa5564e commit b3d2316
Show file tree
Hide file tree
Showing 6 changed files with 39 additions and 28 deletions.
2 changes: 1 addition & 1 deletion arangod/Aql/ExecutionEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -601,7 +601,7 @@ struct CoordinatorInstanciator : public WalkerWorker<ExecutionNode> {
query->queryOptions().toVelocyPack(result, true);

if(!fakeQueryString.empty()){
result.add("fakeQueryString", VPackValue(fakeQueryString));
result.add("fakeQueryString", VPackValuePair(fakeQueryString.data(), fakeQueryString.size(), VPackValueType::String));
}

result.close();
Expand Down
25 changes: 13 additions & 12 deletions arangod/Aql/Query.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@

#include "Aql/AqlItemBlock.h"
#include "Aql/AqlTransaction.h"
#include "Aql/AqlQueryResultCache.h"
#include "Aql/ExecutionBlock.h"
#include "Aql/ExecutionEngine.h"
#include "Aql/ExecutionPlan.h"
Expand Down Expand Up @@ -83,6 +82,7 @@ Query::Query(bool contextOwnedByExterior, TRI_vocbase_t* vocbase,
_vocbase(vocbase),
_context(nullptr),
_queryString(queryString),
_fakeQueryString(),
_queryBuilder(),
_bindParameters(bindParameters),
_options(options),
Expand Down Expand Up @@ -157,13 +157,14 @@ Query::Query(bool contextOwnedByExterior, TRI_vocbase_t* vocbase,
Query::Query(bool contextOwnedByExterior, TRI_vocbase_t* vocbase,
std::shared_ptr<VPackBuilder> const& queryStruct,
std::shared_ptr<VPackBuilder> const& options, QueryPart part,
std::string queryString)
std::string const& queryString)
: _id(0),
_resourceMonitor(),
_resources(&_resourceMonitor),
_vocbase(vocbase),
_context(nullptr),
_queryString(std::move(queryString)),
_queryString(),
_fakeQueryString(QueryString(queryString)),
_queryBuilder(queryStruct),
_options(options),
_collections(vocbase),
Expand Down Expand Up @@ -338,12 +339,12 @@ void Query::prepare(QueryRegistry* registry, uint64_t queryHash) {
if (!_queryString.empty() &&
queryHash != DontCache &&
_part == PART_MAIN) {
// LOG_TOPIC(INFO, Logger::FIXME) << "trying to find query in execution plan cache: '" << _queryString << "', hash: " << queryHash;
//LOG_TOPIC(INFO, Logger::FIXME) << "trying to find query in execution plan cache: '" << _queryString << "', hash: " << queryHash;

// store & lookup velocypack plans!!
std::shared_ptr<PlanCacheEntry> planCacheEntry = PlanCache::instance()->lookup(_vocbase, queryHash, queryString);
if (planCacheEntry != nullptr) {
// LOG_TOPIC(INFO, Logger::FIXME) << "query found in execution plan cache: '" << _queryString << "'";
//LOG_TOPIC(INFO, Logger::FIXME) << "query found in execution plan cache: '" << _queryString << "'";

TRI_ASSERT(_trx == nullptr);
TRI_ASSERT(_collections.empty());
Expand Down Expand Up @@ -392,7 +393,7 @@ void Query::prepare(QueryRegistry* registry, uint64_t queryHash) {
_part == PART_MAIN &&
_warnings.empty() &&
_ast->root()->isCacheable()) {
// LOG_TOPIC(INFO, Logger::FIXME) << "storing query in execution plan cache '" << _queryString << "', hash: " << queryHash;
//LOG_TOPIC(INFO, Logger::FIXME) << "storing query in execution plan cache '" << _queryString << "', hash: " << queryHash;
PlanCache::instance()->store(_vocbase, queryHash, _queryString, plan.get());
}
#endif
Expand All @@ -414,7 +415,6 @@ void Query::prepare(QueryRegistry* registry, uint64_t queryHash) {
}

_plan = std::move(plan);
arangodb::aql::cache::fakeQueryString(_plan.get());
}

/// @brief prepare an AQL query, this is a preparation for execute, but
Expand Down Expand Up @@ -1181,12 +1181,13 @@ void Query::log() {

/// @brief calculate a hash value for the query and bind parameters
uint64_t Query::hash() {
if (_queryString.empty()) {
QueryString& string = hashString();
if (string.empty()) {
return DontCache;
}

// hash the query string first
uint64_t hash = _queryString.hash();
uint64_t hash = string.hash();

// handle "fullCount" option. if this option is set, the query result will
// be different to when it is not set!
Expand Down Expand Up @@ -1216,8 +1217,8 @@ uint64_t Query::hash() {
}

/// @brief whether or not the query cache can be used for the query
bool Query::canUseQueryCache() const {
if (_queryString.size() < 8) {
bool Query::canUseQueryCache() {
if (hashString().size() < 8) {
return false;
}

Expand All @@ -1230,7 +1231,7 @@ bool Query::canUseQueryCache() const {
// query will only be cached if `cache` attribute is not set to false

// cannot use query cache on a coordinator at the moment
return !arangodb::ServerState::instance()->isRunningInCluster();
return !arangodb::ServerState::instance()->isCoordinator();
}

return false;
Expand Down
12 changes: 10 additions & 2 deletions arangod/Aql/Query.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ class Query {
Query(bool contextOwnedByExterior, TRI_vocbase_t*,
std::shared_ptr<arangodb::velocypack::Builder> const& queryStruct,
std::shared_ptr<arangodb::velocypack::Builder> const& options, QueryPart,
std::string queryString = std::string(""));
std::string const& queryString = std::string(""));

~Query();

Expand All @@ -95,6 +95,13 @@ class Query {
public:

QueryString const& queryString() const { return _queryString; }
QueryString& hashString() {
if (_fakeQueryString.empty()) {
return _queryString;
} else {
return _fakeQueryString;
}
}

/// @brief Inject a transaction from outside. Use with care!
void injectTransaction (transaction::Methods* trx) {
Expand Down Expand Up @@ -258,7 +265,7 @@ class Query {
uint64_t hash();

/// @brief whether or not the query cache can be used for the query
bool canUseQueryCache() const;
bool canUseQueryCache();

private:
/// @brief neatly format exception messages for the users
Expand Down Expand Up @@ -300,6 +307,7 @@ class Query {

/// @brief the actual query string
QueryString _queryString;
QueryString _fakeQueryString;

/// @brief query in a VelocyPack structure
std::shared_ptr<arangodb::velocypack::Builder> const _queryBuilder;
Expand Down
8 changes: 4 additions & 4 deletions arangod/Aql/QueryString.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
#include "Basics/fasthash.h"

using namespace arangodb::aql;

void QueryString::append(std::string& out) const {
if (empty()) {
return;
Expand All @@ -45,7 +45,7 @@ uint64_t QueryString::hash() {

return _hash;
}

std::string QueryString::extract(size_t maxLength) const {
if (_length <= maxLength) {
// no truncation
Expand All @@ -54,7 +54,7 @@ std::string QueryString::extract(size_t maxLength) const {

// query string needs truncation
size_t length = maxLength;

// do not create invalid UTF-8 sequences
while (length > 0) {
uint8_t c = _data[length - 1];
Expand Down Expand Up @@ -145,7 +145,7 @@ std::ostream& operator<<(std::ostream& stream, QueryString const& queryString) {
} else {
stream.write(queryString.data(), queryString.length());
}

return stream;
}

Expand Down
8 changes: 4 additions & 4 deletions arangod/Aql/QueryString.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,15 @@ class QueryString {
QueryString(QueryString const& other) = default;
QueryString& operator=(QueryString const& other) = default;

QueryString(char const* data, size_t length)
QueryString(char const* data, size_t length)
: _data(data), _length(length), _hash(0), _hashed(false) {}

explicit QueryString(arangodb::StringRef const& ref)
explicit QueryString(arangodb::StringRef const& ref)
: QueryString(ref.data(), ref.size()) {}

explicit QueryString(std::string const& val)
explicit QueryString(std::string const& val)
: QueryString(val.data(), val.size()) {}

QueryString() : QueryString(nullptr, 0) {}

~QueryString() = default;
Expand Down
12 changes: 7 additions & 5 deletions arangod/Aql/RestAqlHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,10 @@ void RestAqlHandler::createQueryFromVelocyPack() {
VPackSlice fakeQuerySlice = querySlice.get("fakeQueryString");
if (!fakeQuerySlice.isNone() && fakeQuerySlice.isString()) {
fakeQueryString = fakeQuerySlice.copyString();
LOG_TOPIC(ERR,Logger::FIXME) << "###########createQueryFromVelocyPack: '" << fakeQueryString << "'";
}


auto options = std::make_shared<VPackBuilder>(
VPackBuilder::clone(querySlice.get("options")));

Expand All @@ -105,16 +107,16 @@ void RestAqlHandler::createQueryFromVelocyPack() {
auto planBuilder = std::make_shared<VPackBuilder>(VPackBuilder::clone(plan));
auto query = std::make_unique<Query>(false, _vocbase, planBuilder, options,
(part == "main" ? PART_MAIN : PART_DEPENDENT),
std::move(fakeQueryString));
fakeQueryString);

try {
query->prepare(_queryRegistry, 0);
} catch (std::exception const& ex) {
LOG_TOPIC(ERR, arangodb::Logger::FIXME) << "failed to instantiate the query: " << ex.what();
LOG_TOPIC(ERR, arangodb::Logger::FIXME) << "failed to instantiate the query (prepare): " << ex.what();
generateError(rest::ResponseCode::BAD, TRI_ERROR_QUERY_BAD_JSON_PLAN, ex.what());
return;
} catch (...) {
LOG_TOPIC(ERR, arangodb::Logger::FIXME) << "failed to instantiate the query";
LOG_TOPIC(ERR, arangodb::Logger::FIXME) << "failed to instantiate the query (prepare)";
generateError(rest::ResponseCode::BAD, TRI_ERROR_QUERY_BAD_JSON_PLAN);
return;
}
Expand Down Expand Up @@ -182,7 +184,7 @@ void RestAqlHandler::parseQuery() {
std::shared_ptr<VPackBuilder>(), nullptr, PART_MAIN);
QueryResult res = query->parse();
if (res.code != TRI_ERROR_NO_ERROR) {
LOG_TOPIC(ERR, arangodb::Logger::FIXME) << "failed to instantiate the Query: " << res.details;
LOG_TOPIC(ERR, arangodb::Logger::FIXME) << "failed to instantiate the Query (parse): " << res.details;
generateError(rest::ResponseCode::BAD, res.code, res.details);
return;
}
Expand Down Expand Up @@ -253,7 +255,7 @@ void RestAqlHandler::explainQuery() {
bindVars, options, PART_MAIN);
QueryResult res = query->explain();
if (res.code != TRI_ERROR_NO_ERROR) {
LOG_TOPIC(ERR, arangodb::Logger::FIXME) << "failed to instantiate the Query: " << res.details;
LOG_TOPIC(ERR, arangodb::Logger::FIXME) << "failed to instantiate the Query (explain): " << res.details;
generateError(rest::ResponseCode::BAD, res.code, res.details);
return;
}
Expand Down

0 comments on commit b3d2316

Please sign in to comment.