mirror of https://gitee.com/bigwinds/arangodb
Aql/QueryResult now only uses VelocyPack instead of TRI_json_t. Also adapted all calling places
This commit is contained in:
parent
0552cd54c3
commit
e60e7a3652
|
@ -141,9 +141,11 @@ Ast::~Ast() {}
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief convert the AST into JSON
|
||||
/// the caller is responsible for freeing the JSON later
|
||||
/// @DEPRECATED
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TRI_json_t* Ast::toJson(TRI_memory_zone_t* zone, bool verbose) const {
|
||||
#warning Deprecated
|
||||
TRI_json_t* json = TRI_CreateArrayJson(zone);
|
||||
|
||||
if (json == nullptr) {
|
||||
|
@ -160,6 +162,19 @@ TRI_json_t* Ast::toJson(TRI_memory_zone_t* zone, bool verbose) const {
|
|||
return json;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief convert the AST into VelocyPack
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::shared_ptr<VPackBuilder> Ast::toVelocyPack(bool verbose) const {
|
||||
auto builder = std::make_shared<VPackBuilder>();
|
||||
{
|
||||
VPackArrayBuilder guard(builder.get());
|
||||
_root->toVelocyPack(*builder, verbose);
|
||||
}
|
||||
return builder;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief destroy the AST
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -184,10 +184,17 @@ class Ast {
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief convert the AST into JSON
|
||||
/// the caller is responsible for freeing the JSON later
|
||||
/// @DEPRECATED
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TRI_json_t* toJson(TRI_memory_zone_t*, bool) const;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief convert the AST into JSON
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::shared_ptr<arangodb::velocypack::Builder> toVelocyPack(bool) const;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief add an operation to the root node
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -472,6 +472,7 @@ struct CoordinatorInstanciator : public WalkerWorker<ExecutionNode> {
|
|||
EngineInfo const& info, Collection* collection,
|
||||
QueryId& connectedId, std::string const& shardId,
|
||||
TRI_json_t* jsonPlan) {
|
||||
#warning still Json inplace. Needs to be fixed
|
||||
// create a JSON representation of the plan
|
||||
Json result(Json::Object);
|
||||
|
||||
|
@ -487,8 +488,10 @@ struct CoordinatorInstanciator : public WalkerWorker<ExecutionNode> {
|
|||
"type", Json(TRI_TransactionTypeGetStr(collection->accessType))));
|
||||
|
||||
jsonNodesList.set("collections", jsonCollectionsList);
|
||||
jsonNodesList.set("variables",
|
||||
query->ast()->variables()->toJson(TRI_UNKNOWN_MEM_ZONE));
|
||||
|
||||
VPackBuilder tmp;
|
||||
query->ast()->variables()->toVelocyPack(tmp);
|
||||
jsonNodesList.set("variables", arangodb::basics::VelocyPackHelper::velocyPackToJson(tmp.slice()));
|
||||
|
||||
result.set("plan", jsonNodesList);
|
||||
if (info.part == arangodb::aql::PART_MAIN) {
|
||||
|
|
|
@ -214,10 +214,12 @@ ExecutionPlan* ExecutionPlan::clone(Query const& query) {
|
|||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief export to JSON, returns an AUTOFREE Json object
|
||||
/// DEPRECATED
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
arangodb::basics::Json ExecutionPlan::toJson(Ast* ast, TRI_memory_zone_t* zone,
|
||||
bool verbose) const {
|
||||
#warning Remove this
|
||||
// TODO
|
||||
VPackBuilder b;
|
||||
_root->toVelocyPack(b, verbose);
|
||||
|
@ -247,7 +249,10 @@ arangodb::basics::Json ExecutionPlan::toJson(Ast* ast, TRI_memory_zone_t* zone,
|
|||
}
|
||||
|
||||
result.set("collections", jsonCollectionList);
|
||||
result.set("variables", ast->variables()->toJson(TRI_UNKNOWN_MEM_ZONE));
|
||||
|
||||
VPackBuilder tmpTwo;
|
||||
ast->variables()->toVelocyPack(tmpTwo);
|
||||
result.set("variables", arangodb::basics::VelocyPackHelper::velocyPackToJson(tmpTwo.slice()));
|
||||
size_t nrItems = 0;
|
||||
result.set("estimatedCost", arangodb::basics::Json(_root->getCost(nrItems)));
|
||||
result.set("estimatedNrItems",
|
||||
|
@ -256,6 +261,41 @@ arangodb::basics::Json ExecutionPlan::toJson(Ast* ast, TRI_memory_zone_t* zone,
|
|||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief export to VelocyPack
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void ExecutionPlan::toVelocyPack(Ast* ast, bool verbose,
|
||||
VPackBuilder& builder) const {
|
||||
_root->toVelocyPack(builder, verbose);
|
||||
// set up rules
|
||||
auto appliedRules(Optimizer::translateRules(_appliedRules));
|
||||
|
||||
builder.add(VPackValue("rules"));
|
||||
{
|
||||
VPackArrayBuilder guard(&builder);
|
||||
for (auto const& r : appliedRules) {
|
||||
builder.add(VPackValue(r));
|
||||
}
|
||||
}
|
||||
builder.add(VPackValue("collections"));
|
||||
auto usedCollections = *ast->query()->collections()->collections();
|
||||
{
|
||||
VPackArrayBuilder guard(&builder);
|
||||
for (auto const& c : usedCollections) {
|
||||
VPackObjectBuilder objGuard(&builder);
|
||||
builder.add("name", VPackValue(c.first));
|
||||
builder.add("type",
|
||||
VPackValue(TRI_TransactionTypeGetStr(c.second->accessType)));
|
||||
}
|
||||
}
|
||||
builder.add(VPackValue("variables"));
|
||||
ast->variables()->toVelocyPack(builder);
|
||||
size_t nrItems = 0;
|
||||
builder.add("estimatedCost", VPackValue(_root->getCost(nrItems)));
|
||||
builder.add("estimatedNrItems", VPackValue(nrItems));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief get a list of all applied rules
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -96,6 +96,12 @@ class ExecutionPlan {
|
|||
arangodb::basics::Json toJson(Ast* ast, TRI_memory_zone_t* zone,
|
||||
bool verbose) const;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief export to VelocyPack
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void toVelocyPack(Ast*, bool, arangodb::velocypack::Builder&) const;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief check if the plan is empty
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -117,7 +117,7 @@ QueryResult Parser::parse(bool withDetails) {
|
|||
if (withDetails) {
|
||||
result.collectionNames = _query->collectionNames();
|
||||
result.bindParameters = _ast->bindParameters();
|
||||
result.json = _ast->toJson(TRI_UNKNOWN_MEM_ZONE, false);
|
||||
result.result = _ast->toVelocyPack(false);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
|
|
@ -612,19 +612,10 @@ QueryResult Query::execute(QueryRegistry* registry) {
|
|||
if (cacheEntry != nullptr) {
|
||||
// got a result from the query cache
|
||||
QueryResult res(TRI_ERROR_NO_ERROR);
|
||||
#warning Replace QueryResult with VPack
|
||||
VPackBuilder tmp;
|
||||
tmp.openObject();
|
||||
warningsToVelocyPack(tmp);
|
||||
tmp.close();
|
||||
res.warnings = arangodb::basics::VelocyPackHelper::velocyPackToJson(tmp.slice().get("warnings"));
|
||||
res.json = arangodb::basics::VelocyPackHelper::velocyPackToJson(cacheEntry->_queryResult->slice());
|
||||
res.warnings = warningsToVelocyPack();
|
||||
TRI_ASSERT(cacheEntry->_queryResult != nullptr);
|
||||
res.result = cacheEntry->_queryResult;
|
||||
res.cached = true;
|
||||
|
||||
if (res.json == nullptr) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
@ -650,14 +641,13 @@ QueryResult Query::execute(QueryRegistry* registry) {
|
|||
useQueryCache = false;
|
||||
}
|
||||
|
||||
arangodb::basics::Json jsonResult(arangodb::basics::Json::Array, 16);
|
||||
|
||||
AqlItemBlock* value = nullptr;
|
||||
auto resultBuilder = std::make_shared<VPackBuilder>();
|
||||
try {
|
||||
VPackArrayBuilder guard(resultBuilder.get());
|
||||
// this is the RegisterId our results can be found in
|
||||
auto const resultRegister = _engine->resultRegister();
|
||||
|
||||
AqlItemBlock* value = nullptr;
|
||||
|
||||
try {
|
||||
if (useQueryCache) {
|
||||
// iterate over result, return it and store it in query cache
|
||||
while (nullptr != (value = _engine->getSome(
|
||||
|
@ -665,14 +655,12 @@ QueryResult Query::execute(QueryRegistry* registry) {
|
|||
auto doc = value->getDocumentCollection(resultRegister);
|
||||
|
||||
size_t const n = value->size();
|
||||
// reserve space for n additional results at once
|
||||
jsonResult.reserve(n);
|
||||
|
||||
for (size_t i = 0; i < n; ++i) {
|
||||
auto val = value->getValueReference(i, resultRegister);
|
||||
|
||||
if (!val.isEmpty()) {
|
||||
jsonResult.add(val.toJson(_trx, doc, true));
|
||||
val.toVelocyPack(_trx, doc, *resultBuilder);
|
||||
}
|
||||
}
|
||||
delete value;
|
||||
|
@ -681,14 +669,8 @@ QueryResult Query::execute(QueryRegistry* registry) {
|
|||
|
||||
if (_warnings.empty()) {
|
||||
// finally store the generated result in the query cache
|
||||
std::shared_ptr<VPackBuilder> copy(arangodb::basics::JsonHelper::toVelocyPack(jsonResult.json()));
|
||||
|
||||
if (copy == nullptr) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
auto result = QueryCache::instance()->store(
|
||||
_vocbase, queryStringHash, _queryString, _queryLength, copy,
|
||||
_vocbase, queryStringHash, _queryString, _queryLength, resultBuilder,
|
||||
_trx->collectionNames());
|
||||
|
||||
if (result == nullptr) {
|
||||
|
@ -702,14 +684,11 @@ QueryResult Query::execute(QueryRegistry* registry) {
|
|||
auto doc = value->getDocumentCollection(resultRegister);
|
||||
|
||||
size_t const n = value->size();
|
||||
// reserve space for n additional results at once
|
||||
jsonResult.reserve(n);
|
||||
|
||||
for (size_t i = 0; i < n; ++i) {
|
||||
auto val = value->getValueReference(i, resultRegister);
|
||||
|
||||
if (!val.isEmpty()) {
|
||||
jsonResult.add(val.toJson(_trx, doc, true));
|
||||
val.toVelocyPack(_trx, doc, *resultBuilder);
|
||||
}
|
||||
}
|
||||
delete value;
|
||||
|
@ -732,13 +711,8 @@ QueryResult Query::execute(QueryRegistry* registry) {
|
|||
enterState(FINALIZATION);
|
||||
|
||||
QueryResult result(TRI_ERROR_NO_ERROR);
|
||||
#warning Replace QueryResult with VPack
|
||||
VPackBuilder tmp;
|
||||
tmp.openObject();
|
||||
warningsToVelocyPack(tmp);
|
||||
tmp.close();
|
||||
result.warnings = arangodb::basics::VelocyPackHelper::velocyPackToJson(tmp.slice().get("warnings"));
|
||||
result.json = jsonResult.steal();
|
||||
result.warnings = warningsToVelocyPack();
|
||||
result.result = resultBuilder;
|
||||
result.stats = stats;
|
||||
|
||||
if (_profile != nullptr && profiling()) {
|
||||
|
@ -890,12 +864,7 @@ QueryResultV8 Query::executeV8(v8::Isolate* isolate, QueryRegistry* registry) {
|
|||
|
||||
enterState(FINALIZATION);
|
||||
|
||||
#warning Replace QueryResult with VPack
|
||||
VPackBuilder tmp;
|
||||
tmp.openObject();
|
||||
warningsToVelocyPack(tmp);
|
||||
tmp.close();
|
||||
result.warnings = arangodb::basics::VelocyPackHelper::velocyPackToJson(tmp.slice().get("warnings"));
|
||||
result.warnings = warningsToVelocyPack();
|
||||
result.stats = stats;
|
||||
|
||||
if (_profile != nullptr && profiling()) {
|
||||
|
@ -996,9 +965,11 @@ QueryResult Query::explain() {
|
|||
|
||||
QueryResult result(TRI_ERROR_NO_ERROR);
|
||||
QueryRegistry localRegistry;
|
||||
result.result = std::make_shared<VPackBuilder>();
|
||||
|
||||
if (allPlans()) {
|
||||
arangodb::basics::Json out(Json::Array);
|
||||
{
|
||||
VPackArrayBuilder guard(result.result.get());
|
||||
|
||||
auto plans = opt.getPlans();
|
||||
for (auto& it : plans) {
|
||||
|
@ -1006,11 +977,9 @@ QueryResult Query::explain() {
|
|||
|
||||
it->findVarUsage();
|
||||
it->planRegisters();
|
||||
out.add(it->toJson(parser.ast(), TRI_UNKNOWN_MEM_ZONE, verbosePlans()));
|
||||
it->toVelocyPack(parser.ast(), verbosePlans(), *result.result);
|
||||
}
|
||||
}
|
||||
|
||||
result.json = out.steal();
|
||||
|
||||
// cacheability not available here
|
||||
result.cached = false;
|
||||
} else {
|
||||
|
@ -1021,9 +990,7 @@ QueryResult Query::explain() {
|
|||
|
||||
bestPlan->findVarUsage();
|
||||
bestPlan->planRegisters();
|
||||
result.json =
|
||||
bestPlan->toJson(parser.ast(), TRI_UNKNOWN_MEM_ZONE, verbosePlans())
|
||||
.steal();
|
||||
bestPlan->toVelocyPack(parser.ast(), verbosePlans(), *result.result);
|
||||
|
||||
// cacheability
|
||||
result.cached = (_queryString != nullptr && _queryLength > 0 &&
|
||||
|
@ -1033,12 +1000,7 @@ QueryResult Query::explain() {
|
|||
|
||||
_trx->commit();
|
||||
|
||||
#warning Replace QueryResult with VPack
|
||||
VPackBuilder tmp;
|
||||
tmp.openObject();
|
||||
warningsToVelocyPack(tmp);
|
||||
tmp.close();
|
||||
result.warnings = arangodb::basics::VelocyPackHelper::velocyPackToJson(tmp.slice().get("warnings"));
|
||||
result.warnings = warningsToVelocyPack();
|
||||
|
||||
result.stats = opt._stats.toVelocyPack();
|
||||
|
||||
|
@ -1237,7 +1199,8 @@ bool Query::getBooleanOption(char const* option, bool defaultValue) const {
|
|||
/// warnings. If there are none it will not modify the builder
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Query::warningsToVelocyPack(arangodb::velocypack::Builder& builder) const {
|
||||
void Query::addWarningsToVelocyPackObject(
|
||||
arangodb::velocypack::Builder& builder) const {
|
||||
TRI_ASSERT(builder.isOpenObject());
|
||||
if (_warnings.empty()) {
|
||||
return;
|
||||
|
@ -1254,6 +1217,28 @@ void Query::warningsToVelocyPack(arangodb::velocypack::Builder& builder) const {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief transform the list of warnings to VelocyPack.
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::shared_ptr<VPackBuilder> Query::warningsToVelocyPack() const {
|
||||
if (_warnings.empty()) {
|
||||
return nullptr;
|
||||
}
|
||||
auto result = std::make_shared<VPackBuilder>();
|
||||
{
|
||||
VPackArrayBuilder guard(result.get());
|
||||
size_t const n = _warnings.size();
|
||||
for (size_t i = 0; i < n; ++i) {
|
||||
VPackObjectBuilder objGuard(result.get());
|
||||
result->add("code", VPackValue(_warnings[i].first));
|
||||
result->add("message", VPackValue(_warnings[i].second));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief initializes the query
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -398,12 +398,19 @@ class Query {
|
|||
bool getBooleanOption(char const*, bool) const;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief convert the list of warnings to VelocyPack.
|
||||
/// @brief add the list of warnings to VelocyPack.
|
||||
/// Will add a new entry { ..., warnings: <warnings>, } if there are
|
||||
/// warnings. If there are none it will not modify the builder
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void warningsToVelocyPack(arangodb::velocypack::Builder&) const;
|
||||
void addWarningsToVelocyPackObject(arangodb::velocypack::Builder&) const;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief transform the list of warnings to VelocyPack.
|
||||
/// NOTE: returns nullptr if there are no warnings.
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::shared_ptr<arangodb::velocypack::Builder> warningsToVelocyPack() const;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief fetch the global query tracking value
|
||||
|
|
|
@ -40,19 +40,15 @@ struct QueryResult {
|
|||
code = other.code;
|
||||
cached = other.cached;
|
||||
details = other.details;
|
||||
warnings = other.warnings;
|
||||
json = other.json;
|
||||
stats = other.stats;
|
||||
profile = other.profile;
|
||||
zone = other.zone;
|
||||
warnings.swap(other.warnings);
|
||||
result.swap(other.result);
|
||||
stats.swap(other.stats);
|
||||
profile.swap(other.profile);
|
||||
|
||||
clusterplan = other.clusterplan;
|
||||
bindParameters = other.bindParameters;
|
||||
collectionNames = other.collectionNames;
|
||||
|
||||
other.warnings = nullptr;
|
||||
other.json = nullptr;
|
||||
other.stats = nullptr;
|
||||
other.profile = nullptr;
|
||||
other.clusterplan = nullptr;
|
||||
}
|
||||
|
||||
|
@ -60,9 +56,8 @@ struct QueryResult {
|
|||
: code(code),
|
||||
cached(false),
|
||||
details(details),
|
||||
zone(TRI_UNKNOWN_MEM_ZONE),
|
||||
warnings(nullptr),
|
||||
json(nullptr),
|
||||
result(nullptr),
|
||||
profile(nullptr),
|
||||
clusterplan(nullptr) {}
|
||||
|
||||
|
@ -71,12 +66,6 @@ struct QueryResult {
|
|||
QueryResult() : QueryResult(TRI_ERROR_NO_ERROR) {}
|
||||
|
||||
virtual ~QueryResult() {
|
||||
if (warnings != nullptr) {
|
||||
TRI_FreeJson(zone, warnings);
|
||||
}
|
||||
if (json != nullptr) {
|
||||
TRI_FreeJson(zone, json);
|
||||
}
|
||||
}
|
||||
|
||||
int code;
|
||||
|
@ -84,9 +73,8 @@ struct QueryResult {
|
|||
std::string details;
|
||||
std::unordered_set<std::string> bindParameters;
|
||||
std::vector<std::string> collectionNames;
|
||||
TRI_memory_zone_t* zone;
|
||||
TRI_json_t* warnings;
|
||||
TRI_json_t* json;
|
||||
std::shared_ptr<arangodb::velocypack::Builder> warnings;
|
||||
std::shared_ptr<arangodb::velocypack::Builder> result;
|
||||
std::shared_ptr<arangodb::velocypack::Builder> stats;
|
||||
std::shared_ptr<arangodb::velocypack::Builder> profile;
|
||||
TRI_json_t* clusterplan;
|
||||
|
|
|
@ -202,14 +202,9 @@ void RestAqlHandler::parseQuery() {
|
|||
answerBuilder.add(VPackValue(p));
|
||||
}
|
||||
}
|
||||
#warning res.json has to be replaced by VPack in first-place
|
||||
answerBuilder.add(VPackValue("ast"));
|
||||
int errCode = JsonHelper::toVelocyPack(res.json, answerBuilder);
|
||||
if (errCode != TRI_ERROR_NO_ERROR) {
|
||||
#warning only temporary, wrong error does not matter at all.
|
||||
generateError(HttpResponse::BAD, errCode);
|
||||
}
|
||||
res.json = nullptr;
|
||||
answerBuilder.add(res.result->slice());
|
||||
res.result = nullptr;
|
||||
} catch (...) {
|
||||
generateError(HttpResponse::BAD, TRI_ERROR_OUT_OF_MEMORY,
|
||||
"out of memory");
|
||||
|
@ -259,19 +254,14 @@ void RestAqlHandler::explainQuery() {
|
|||
VPackBuilder answerBuilder;
|
||||
try {
|
||||
VPackObjectBuilder guard(&answerBuilder);
|
||||
if (res.json != nullptr) {
|
||||
#warning QueryResult needs to be replaced by VPack
|
||||
if (res.result != nullptr) {
|
||||
if (query->allPlans()) {
|
||||
answerBuilder.add(VPackValue("plans"));
|
||||
} else {
|
||||
answerBuilder.add(VPackValue("plan"));
|
||||
}
|
||||
int errCode = JsonHelper::toVelocyPack(res.json, answerBuilder);
|
||||
if (errCode != TRI_ERROR_NO_ERROR) {
|
||||
#warning only temporary, wrong error does not matter at all.
|
||||
generateError(HttpResponse::BAD, errCode);
|
||||
}
|
||||
res.json = nullptr;
|
||||
answerBuilder.add(res.result->slice());
|
||||
res.result = nullptr;
|
||||
}
|
||||
} catch (...) {
|
||||
generateError(HttpResponse::BAD, TRI_ERROR_OUT_OF_MEMORY,
|
||||
|
@ -842,7 +832,7 @@ void RestAqlHandler::handleUseQuery(std::string const& operation, Query* query,
|
|||
query->getStats(answerBuilder);
|
||||
|
||||
// return warnings if present
|
||||
query->warningsToVelocyPack(answerBuilder);
|
||||
query->addWarningsToVelocyPackObject(answerBuilder);
|
||||
|
||||
// delete the query from the registry
|
||||
_queryRegistry->destroy(_vocbase, _qId, errorCode);
|
||||
|
|
|
@ -217,18 +217,14 @@ std::string VariableGenerator::nextName() {
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief export to JSON, returns an AUTOFREE Json object
|
||||
/// @brief export to VelocyPack
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
arangodb::basics::Json VariableGenerator::toJson(
|
||||
TRI_memory_zone_t* zone) const {
|
||||
Json jsonAllVariablesList(Json::Array, _variables.size());
|
||||
|
||||
void VariableGenerator::toVelocyPack(VPackBuilder& builder) const {
|
||||
VPackArrayBuilder guard(&builder);
|
||||
for (auto const& oneVariable : _variables) {
|
||||
jsonAllVariablesList(oneVariable.second->toJson());
|
||||
oneVariable.second->toVelocyPack(builder);
|
||||
}
|
||||
|
||||
return jsonAllVariablesList;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -107,11 +107,11 @@ class VariableGenerator {
|
|||
|
||||
std::string nextName();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief export to JSON, returns an AUTOFREE Json object
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief export to VelocyPack
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
arangodb::basics::Json toJson(TRI_memory_zone_t*) const;
|
||||
void toVelocyPack(arangodb::velocypack::Builder& builder) const;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief import from VelocyPack
|
||||
|
|
|
@ -131,7 +131,13 @@ void RestCursorHandler::processQuery(VPackSlice const& slice) {
|
|||
THROW_ARANGO_EXCEPTION_MESSAGE(queryResult.code, queryResult.details);
|
||||
}
|
||||
|
||||
TRI_ASSERT(TRI_IsArrayJson(queryResult.json));
|
||||
VPackSlice qResult = queryResult.result->slice();
|
||||
|
||||
if (qResult.isNone()) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
TRI_ASSERT(qResult.isArray());
|
||||
|
||||
{
|
||||
createResponse(HttpResponse::CREATED);
|
||||
|
@ -143,7 +149,7 @@ void RestCursorHandler::processQuery(VPackSlice const& slice) {
|
|||
size_t batchSize =
|
||||
arangodb::basics::VelocyPackHelper::getNumericValue<size_t>(
|
||||
opts, "batchSize", 1000);
|
||||
size_t const n = TRI_LengthArrayJson(queryResult.json);
|
||||
size_t const n = static_cast<size_t>(qResult.length());
|
||||
|
||||
if (n <= batchSize) {
|
||||
// result is smaller than batchSize and will be returned directly. no need
|
||||
|
@ -153,10 +159,7 @@ void RestCursorHandler::processQuery(VPackSlice const& slice) {
|
|||
try {
|
||||
VPackObjectBuilder b(&result);
|
||||
result.add(VPackValue("result"));
|
||||
int res = arangodb::basics::JsonHelper::toVelocyPack(queryResult.json, result);
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
result.add(qResult);
|
||||
result.add("hasMore", VPackValue(false));
|
||||
if (arangodb::basics::VelocyPackHelper::getBooleanValue(opts, "count",
|
||||
false)) {
|
||||
|
@ -192,19 +195,9 @@ void RestCursorHandler::processQuery(VPackSlice const& slice) {
|
|||
bool count = arangodb::basics::VelocyPackHelper::getBooleanValue(
|
||||
opts, "count", false);
|
||||
|
||||
// steal the query JSON, cursor will take over the ownership
|
||||
auto j = queryResult.json;
|
||||
std::shared_ptr<VPackBuilder> builder = arangodb::basics::JsonHelper::toVelocyPack(j);
|
||||
{
|
||||
// Temporarily validate that transformation actually worked.
|
||||
// Can be removed again as soon as queryResult returns VPack
|
||||
VPackSlice validate = builder->slice();
|
||||
if (validate.isNone() && j != nullptr) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
}
|
||||
// steal the query result, cursor will take over the ownership
|
||||
arangodb::JsonCursor* cursor = cursors->createFromVelocyPack(
|
||||
builder, batchSize, extra, ttl, count, queryResult.cached);
|
||||
queryResult.result, batchSize, extra, ttl, count, queryResult.cached);
|
||||
|
||||
try {
|
||||
_response->body().appendChar('{');
|
||||
|
@ -358,10 +351,7 @@ std::shared_ptr<VPackBuilder> RestCursorHandler::buildExtra(
|
|||
extra->close();
|
||||
} else {
|
||||
extra->add(VPackValue("warnings"));
|
||||
int res = arangodb::basics::JsonHelper::toVelocyPack(queryResult.warnings, *extra);
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
return nullptr;
|
||||
}
|
||||
extra->add(queryResult.warnings->slice());
|
||||
}
|
||||
} catch (...) {
|
||||
return nullptr;
|
||||
|
|
|
@ -390,14 +390,10 @@ bool RestQueryHandler::parseQuery() {
|
|||
}
|
||||
result.close(); // bindVars
|
||||
|
||||
auto tmp = VPackParser::fromJson(
|
||||
arangodb::basics::JsonHelper::toString(parseResult.json));
|
||||
result.add("ast", tmp->slice());
|
||||
result.add("ast", parseResult.result->slice());
|
||||
|
||||
if (parseResult.warnings != nullptr) {
|
||||
auto tmp = VPackParser::fromJson(
|
||||
arangodb::basics::JsonHelper::toString(parseResult.warnings));
|
||||
result.add("warnings", tmp->slice());
|
||||
result.add("warnings", parseResult.warnings->slice());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -333,18 +333,19 @@ void RestSimpleHandler::lookupByKeys(VPackSlice const& slice) {
|
|||
}
|
||||
|
||||
size_t resultSize = 10;
|
||||
if (TRI_IsArrayJson(queryResult.json)) {
|
||||
resultSize = TRI_LengthArrayJson(queryResult.json);
|
||||
VPackSlice qResult = queryResult.result->slice();
|
||||
if (qResult.isArray()) {
|
||||
resultSize = static_cast<size_t>(qResult.length());
|
||||
}
|
||||
|
||||
VPackBuilder result;
|
||||
{
|
||||
VPackObjectBuilder guard(&result);
|
||||
createResponse(HttpResponse::OK);
|
||||
_response->setContentType("application/json; charset=utf-8");
|
||||
|
||||
arangodb::basics::Json result(arangodb::basics::Json::Object, 3);
|
||||
|
||||
if (TRI_IsArrayJson(queryResult.json)) {
|
||||
size_t const n = TRI_LengthArrayJson(queryResult.json);
|
||||
if (qResult.isArray()) {
|
||||
|
||||
// This is for internal use of AQL Traverser only.
|
||||
// Should not be documented
|
||||
|
@ -371,53 +372,48 @@ void RestSimpleHandler::lookupByKeys(VPackSlice const& slice) {
|
|||
}
|
||||
}
|
||||
|
||||
arangodb::basics::Json filteredDocuments(
|
||||
arangodb::basics::Json::Array, n);
|
||||
arangodb::basics::Json filteredIds(arangodb::basics::Json::Array);
|
||||
result.add(VPackValue("documents"));
|
||||
std::vector<std::string> filteredIds;
|
||||
|
||||
for (size_t i = 0; i < n; ++i) {
|
||||
TRI_json_t const* tmp = TRI_LookupArrayJson(queryResult.json, i);
|
||||
if (tmp != nullptr) {
|
||||
result.openArray();
|
||||
for (auto const& tmp : VPackArrayIterator(qResult)) {
|
||||
if (!tmp.isNone()) {
|
||||
bool add = true;
|
||||
for (auto& e : expressions) {
|
||||
if (!e->isEdgeAccess && !e->matchesCheck(tmp)) {
|
||||
add = false;
|
||||
try {
|
||||
std::string _id =
|
||||
arangodb::basics::JsonHelper::checkAndGetStringValue(
|
||||
arangodb::basics::VelocyPackHelper::checkAndGetStringValue(
|
||||
tmp, "_id");
|
||||
arangodb::basics::Json tmp(_id);
|
||||
filteredIds.add(tmp.steal());
|
||||
} catch (...) {
|
||||
// This should never occur.
|
||||
}
|
||||
filteredIds.emplace_back(_id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (add) {
|
||||
filteredDocuments.add(TRI_CopyJson(TRI_UNKNOWN_MEM_ZONE, tmp));
|
||||
result.add(tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
result.close();
|
||||
|
||||
result.set("documents", filteredDocuments);
|
||||
result.set("filtered", filteredIds);
|
||||
result.add(VPackValue("filtered"));
|
||||
result.openArray();
|
||||
for (auto const& it : filteredIds) {
|
||||
result.add(VPackValue(it));
|
||||
}
|
||||
result.close();
|
||||
} else {
|
||||
result.set("documents", arangodb::basics::Json(
|
||||
TRI_UNKNOWN_MEM_ZONE, queryResult.json,
|
||||
arangodb::basics::Json::AUTOFREE));
|
||||
queryResult.json = nullptr;
|
||||
result.add(VPackValue("documents"));
|
||||
result.add(qResult);
|
||||
queryResult.result = nullptr;
|
||||
}
|
||||
} else {
|
||||
result.set("documents", arangodb::basics::Json(
|
||||
TRI_UNKNOWN_MEM_ZONE, queryResult.json,
|
||||
arangodb::basics::Json::AUTOFREE));
|
||||
queryResult.json = nullptr;
|
||||
result.add(VPackValue("documents"));
|
||||
result.add(qResult);
|
||||
queryResult.result = nullptr;
|
||||
}
|
||||
|
||||
result.set("error", arangodb::basics::Json(false));
|
||||
result.set("code", arangodb::basics::Json(
|
||||
static_cast<double>(_response->responseCode())));
|
||||
result.add("error", VPackValue(false));
|
||||
result.add("code", VPackValue(_response->responseCode()));
|
||||
|
||||
// reserve 48 bytes per result document by default
|
||||
int res = _response->body().reserve(48 * resultSize);
|
||||
|
@ -426,7 +422,10 @@ void RestSimpleHandler::lookupByKeys(VPackSlice const& slice) {
|
|||
THROW_ARANGO_EXCEPTION(res);
|
||||
}
|
||||
|
||||
result.dump(_response->body());
|
||||
arangodb::basics::VPackStringBufferAdapter buffer(
|
||||
_response->body().stringBuffer());
|
||||
VPackDumper dumper(&buffer);
|
||||
dumper.dump(result.slice());
|
||||
}
|
||||
} catch (arangodb::basics::Exception const& ex) {
|
||||
unregisterQuery();
|
||||
|
|
|
@ -1028,13 +1028,13 @@ static void JS_ParseAql(v8::FunctionCallbackInfo<v8::Value> const& args) {
|
|||
}
|
||||
|
||||
result->Set(TRI_V8_ASCII_STRING("ast"),
|
||||
TRI_ObjectJson(isolate, parseResult.json));
|
||||
TRI_VPackToV8(isolate, parseResult.result->slice()));
|
||||
|
||||
if (parseResult.warnings == nullptr) {
|
||||
result->Set(TRI_V8_ASCII_STRING("warnings"), v8::Array::New(isolate));
|
||||
} else {
|
||||
result->Set(TRI_V8_ASCII_STRING("warnings"),
|
||||
TRI_ObjectJson(isolate, parseResult.warnings));
|
||||
TRI_VPackToV8(isolate, parseResult.warnings->slice()));
|
||||
}
|
||||
|
||||
TRI_V8_RETURN(result);
|
||||
|
@ -1147,13 +1147,13 @@ static void JS_ExplainAql(v8::FunctionCallbackInfo<v8::Value> const& args) {
|
|||
}
|
||||
|
||||
v8::Handle<v8::Object> result = v8::Object::New(isolate);
|
||||
if (queryResult.json != nullptr) {
|
||||
if (queryResult.result != nullptr) {
|
||||
if (query.allPlans()) {
|
||||
result->Set(TRI_V8_ASCII_STRING("plans"),
|
||||
TRI_ObjectJson(isolate, queryResult.json));
|
||||
TRI_VPackToV8(isolate, queryResult.result->slice()));
|
||||
} else {
|
||||
result->Set(TRI_V8_ASCII_STRING("plan"),
|
||||
TRI_ObjectJson(isolate, queryResult.json));
|
||||
TRI_VPackToV8(isolate, queryResult.result->slice()));
|
||||
result->Set(TRI_V8_ASCII_STRING("cacheable"),
|
||||
v8::Boolean::New(isolate, queryResult.cached));
|
||||
}
|
||||
|
@ -1167,7 +1167,7 @@ static void JS_ExplainAql(v8::FunctionCallbackInfo<v8::Value> const& args) {
|
|||
result->Set(TRI_V8_ASCII_STRING("warnings"), v8::Array::New(isolate));
|
||||
} else {
|
||||
result->Set(TRI_V8_ASCII_STRING("warnings"),
|
||||
TRI_ObjectJson(isolate, queryResult.warnings));
|
||||
TRI_VPackToV8(isolate, queryResult.warnings->slice()));
|
||||
}
|
||||
if (queryResult.stats != nullptr) {
|
||||
VPackSlice stats = queryResult.stats->slice();
|
||||
|
@ -1240,9 +1240,9 @@ static void JS_ExecuteAqlJson(v8::FunctionCallbackInfo<v8::Value> const& args) {
|
|||
|
||||
// return the array value as it is. this is a performance optimisation
|
||||
v8::Handle<v8::Object> result = v8::Object::New(isolate);
|
||||
if (queryResult.json != nullptr) {
|
||||
if (queryResult.result != nullptr) {
|
||||
result->ForceSet(TRI_V8_ASCII_STRING("json"),
|
||||
TRI_ObjectJson(isolate, queryResult.json));
|
||||
TRI_VPackToV8(isolate, queryResult.result->slice()));
|
||||
}
|
||||
if (queryResult.stats != nullptr) {
|
||||
VPackSlice stats = queryResult.stats->slice();
|
||||
|
@ -1259,7 +1259,7 @@ static void JS_ExecuteAqlJson(v8::FunctionCallbackInfo<v8::Value> const& args) {
|
|||
result->ForceSet(TRI_V8_ASCII_STRING("warnings"), v8::Array::New(isolate));
|
||||
} else {
|
||||
result->ForceSet(TRI_V8_ASCII_STRING("warnings"),
|
||||
TRI_ObjectJson(isolate, queryResult.warnings));
|
||||
TRI_VPackToV8(isolate, queryResult.warnings->slice()));
|
||||
}
|
||||
result->ForceSet(TRI_V8_ASCII_STRING("cached"),
|
||||
v8::Boolean::New(isolate, queryResult.cached));
|
||||
|
@ -1365,7 +1365,7 @@ static void JS_ExecuteAql(v8::FunctionCallbackInfo<v8::Value> const& args) {
|
|||
result->ForceSet(TRI_V8_ASCII_STRING("warnings"), v8::Array::New(isolate));
|
||||
} else {
|
||||
result->ForceSet(TRI_V8_ASCII_STRING("warnings"),
|
||||
TRI_ObjectJson(isolate, queryResult.warnings));
|
||||
TRI_VPackToV8(isolate, queryResult.warnings->slice()));
|
||||
}
|
||||
result->ForceSet(TRI_V8_ASCII_STRING("cached"),
|
||||
v8::Boolean::New(isolate, queryResult.cached));
|
||||
|
|
Loading…
Reference in New Issue