1
0
Fork 0

Merge branch 'spdvpk' of https://github.com/arangodb/arangodb into spdvpk

This commit is contained in:
Jan Steemann 2016-03-07 20:29:12 +01:00
commit 25c937b03e
15 changed files with 228 additions and 311 deletions

View File

@ -534,7 +534,9 @@ AstNode::AstNode(Ast* ast, arangodb::basics::Json const& json)
break; break;
} }
case NODE_TYPE_VARIABLE: { case NODE_TYPE_VARIABLE: {
auto variable = ast->variables()->createVariable(json); #warning Fix this
auto builder = JsonHelper::toVelocyPack(json.json());
auto variable = ast->variables()->createVariable(builder->slice());
TRI_ASSERT(variable != nullptr); TRI_ASSERT(variable != nullptr);
setData(variable); setData(variable);
break; break;

View File

@ -377,7 +377,9 @@ ExecutionNode::ExecutionNode(ExecutionPlan* plan,
len = jsonvarsUsedLater.size(); len = jsonvarsUsedLater.size();
_varsUsedLater.reserve(len); _varsUsedLater.reserve(len);
for (size_t i = 0; i < len; i++) { for (size_t i = 0; i < len; i++) {
auto oneVarUsedLater = std::make_unique<Variable>(jsonvarsUsedLater.at(i)); #warning Still Json Version. Ignore return val
auto builder = JsonHelper::toVelocyPack(jsonvarsUsedLater.at(i).json());
auto oneVarUsedLater = std::make_unique<Variable>(builder->slice());
Variable* oneVariable = allVars->getVariable(oneVarUsedLater->id); Variable* oneVariable = allVars->getVariable(oneVarUsedLater->id);
if (oneVariable == nullptr) { if (oneVariable == nullptr) {
@ -398,7 +400,9 @@ ExecutionNode::ExecutionNode(ExecutionPlan* plan,
len = jsonvarsValidList.size(); len = jsonvarsValidList.size();
_varsValid.reserve(len); _varsValid.reserve(len);
for (size_t i = 0; i < len; i++) { for (size_t i = 0; i < len; i++) {
auto oneVarValid = std::make_unique<Variable>(jsonvarsValidList.at(i)); #warning Deprecated
auto builder = JsonHelper::toVelocyPack(jsonvarsValidList.at(i).json());
auto oneVarValid = std::make_unique<Variable>(builder->slice());
Variable* oneVariable = allVars->getVariable(oneVarValid->id); Variable* oneVariable = allVars->getVariable(oneVarValid->id);
if (oneVariable == nullptr) { if (oneVariable == nullptr) {
@ -629,8 +633,9 @@ Variable* ExecutionNode::varFromJson(Ast* ast,
"Mandatory variable \"" + std::string(variableName) + "\" not found."; "Mandatory variable \"" + std::string(variableName) + "\" not found.";
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, msg.c_str()); THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, msg.c_str());
} }
#warning Deprecated
return ast->variables()->createVariable(variableJson); auto builder = JsonHelper::toVelocyPack(variableJson.json());
return ast->variables()->createVariable(builder->slice());
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View File

@ -42,6 +42,9 @@
#include "Basics/tri-strings.h" #include "Basics/tri-strings.h"
#include "Basics/VelocyPackHelper.h" #include "Basics/VelocyPackHelper.h"
#include <velocypack/Iterator.h>
#include <velocypack/velocypack-aliases.h>
using namespace arangodb::aql; using namespace arangodb::aql;
using namespace arangodb::basics; using namespace arangodb::basics;
@ -97,48 +100,47 @@ ExecutionPlan* ExecutionPlan::instantiateFromAst(Ast* ast) {
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief process the list of collections in a JSON /// @brief process the list of collections in a VelocyPack
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void ExecutionPlan::getCollectionsFromJson(Ast* ast, void ExecutionPlan::getCollectionsFromVelocyPack(Ast* ast,
arangodb::basics::Json const& json) { VPackSlice const slice) {
TRI_ASSERT(ast != nullptr); TRI_ASSERT(ast != nullptr);
arangodb::basics::Json jsonCollections = json.get("collections"); VPackSlice collectionsSlice = slice.get("collections");
if (!jsonCollections.isArray()) { if (!collectionsSlice.isArray()) {
THROW_ARANGO_EXCEPTION_MESSAGE( THROW_ARANGO_EXCEPTION_MESSAGE(
TRI_ERROR_INTERNAL, TRI_ERROR_INTERNAL,
"json node \"collections\" not found or not an array"); "json node \"collections\" not found or not an array");
} }
auto const size = jsonCollections.size(); for (auto const& collection : VPackArrayIterator(collectionsSlice)) {
auto typeStr = arangodb::basics::VelocyPackHelper::checkAndGetStringValue(
for (size_t i = 0; i < size; i++) { collection, "type");
arangodb::basics::Json oneJsonCollection =
jsonCollections.at(static_cast<int>(i));
auto typeStr = arangodb::basics::JsonHelper::checkAndGetStringValue(
oneJsonCollection.json(), "type");
ast->query()->collections()->add( ast->query()->collections()->add(
arangodb::basics::JsonHelper::checkAndGetStringValue( arangodb::basics::VelocyPackHelper::checkAndGetStringValue(collection,
oneJsonCollection.json(), "name"), "name"),
TRI_GetTransactionTypeFromStr( TRI_GetTransactionTypeFromStr(
arangodb::basics::JsonHelper::checkAndGetStringValue( arangodb::basics::VelocyPackHelper::checkAndGetStringValue(
oneJsonCollection.json(), "type").c_str())); collection, "type")
.c_str()));
} }
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief create an execution plan from JSON /// @brief create an execution plan from VelocyPack
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
ExecutionPlan* ExecutionPlan::instantiateFromJson( ExecutionPlan* ExecutionPlan::instantiateFromVelocyPack(
Ast* ast, arangodb::basics::Json const& json) { Ast* ast, VPackSlice const slice) {
TRI_ASSERT(ast != nullptr); TRI_ASSERT(ast != nullptr);
auto plan = std::make_unique<ExecutionPlan>(ast); auto plan = std::make_unique<ExecutionPlan>(ast);
#warning In place slice => Json
Json json(TRI_UNKNOWN_MEM_ZONE,
arangodb::basics::VelocyPackHelper::velocyPackToJson(slice));
plan->_root = plan->fromJson(json); plan->_root = plan->fromJson(json);
plan->_varUsageComputed = true; plan->_varUsageComputed = true;

View File

@ -63,18 +63,18 @@ class ExecutionPlan {
static ExecutionPlan* instantiateFromAst(Ast*); static ExecutionPlan* instantiateFromAst(Ast*);
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
/// @brief process the list of collections in a JSON /// @brief process the list of collections in a VelocyPack
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
static void getCollectionsFromJson(Ast* ast, static void getCollectionsFromVelocyPack(Ast* ast,
arangodb::basics::Json const& Json); arangodb::velocypack::Slice const);
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
/// @brief create an execution plan from JSON /// @brief create an execution plan from VelocyPack
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
static ExecutionPlan* instantiateFromJson(Ast* ast, static ExecutionPlan* instantiateFromVelocyPack(
arangodb::basics::Json const& Json); Ast* ast, arangodb::velocypack::Slice const);
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
/// @brief clone the plan by recursively cloning starting from the root /// @brief clone the plan by recursively cloning starting from the root

View File

@ -47,6 +47,7 @@
#include "VocBase/Graphs.h" #include "VocBase/Graphs.h"
#include <velocypack/Builder.h> #include <velocypack/Builder.h>
#include <velocypack/Iterator.h>
#include <velocypack/velocypack-aliases.h> #include <velocypack/velocypack-aliases.h>
using namespace arangodb; using namespace arangodb;
@ -146,19 +147,6 @@ std::shared_ptr<VPackBuilder> Profile::toVelocyPack() {
return result; return result;
} }
////////////////////////////////////////////////////////////////////////////////
/// @brief convert the profile to JSON
////////////////////////////////////////////////////////////////////////////////
TRI_json_t* Profile::toJson(TRI_memory_zone_t*) {
arangodb::basics::Json result(arangodb::basics::Json::Object);
for (auto const& it : results) {
result.set(StateNames[static_cast<int>(it.first)].c_str(),
arangodb::basics::Json(it.second));
}
return result.steal();
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief whether or not query tracking is disabled globally /// @brief whether or not query tracking is disabled globally
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -172,7 +160,7 @@ bool Query::DoDisableQueryTracking = false;
Query::Query(arangodb::ApplicationV8* applicationV8, Query::Query(arangodb::ApplicationV8* applicationV8,
bool contextOwnedByExterior, TRI_vocbase_t* vocbase, bool contextOwnedByExterior, TRI_vocbase_t* vocbase,
char const* queryString, size_t queryLength, char const* queryString, size_t queryLength,
std::shared_ptr<VPackBuilder> bindParameters, VPackSlice const options, QueryPart part) std::shared_ptr<VPackBuilder> const bindParameters, std::shared_ptr<VPackBuilder> const options, QueryPart part)
: _id(0), : _id(0),
_applicationV8(applicationV8), _applicationV8(applicationV8),
_vocbase(vocbase), _vocbase(vocbase),
@ -180,9 +168,9 @@ Query::Query(arangodb::ApplicationV8* applicationV8,
_context(nullptr), _context(nullptr),
_queryString(queryString), _queryString(queryString),
_queryLength(queryLength), _queryLength(queryLength),
_queryJson(), _queryBuilder(),
_bindParameters(bindParameters), _bindParameters(bindParameters),
_options(arangodb::basics::VelocyPackHelper::velocyPackToJson(options)), _options(options),
_collections(vocbase), _collections(vocbase),
_strings(), _strings(),
_shortStringStorage(1024), _shortStringStorage(1024),
@ -205,98 +193,14 @@ Query::Query(arangodb::ApplicationV8* applicationV8,
TRI_ASSERT(_vocbase != nullptr); TRI_ASSERT(_vocbase != nullptr);
} }
////////////////////////////////////////////////////////////////////////////////
/// @brief creates a query
////////////////////////////////////////////////////////////////////////////////
Query::Query(arangodb::ApplicationV8* applicationV8,
bool contextOwnedByExterior, TRI_vocbase_t* vocbase,
char const* queryString, size_t queryLength,
std::shared_ptr<VPackBuilder> bindParameters, TRI_json_t* options, QueryPart part)
: _id(0),
_applicationV8(applicationV8),
_vocbase(vocbase),
_executor(nullptr),
_context(nullptr),
_queryString(queryString),
_queryLength(queryLength),
_queryJson(),
_bindParameters(bindParameters),
_options(options),
_collections(vocbase),
_strings(),
_shortStringStorage(1024),
_ast(nullptr),
_profile(nullptr),
_state(INVALID_STATE),
_plan(nullptr),
_parser(nullptr),
_trx(nullptr),
_engine(nullptr),
_maxWarningCount(10),
_warnings(),
_startTime(TRI_microtime()),
_part(part),
_contextOwnedByExterior(contextOwnedByExterior),
_killed(false),
_isModificationQuery(false) {
// std::cout << TRI_CurrentThreadId() << ", QUERY " << this << " CTOR: " <<
// queryString << "\n";
TRI_ASSERT(_vocbase != nullptr);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief creates a query from Json
////////////////////////////////////////////////////////////////////////////////
Query::Query(arangodb::ApplicationV8* applicationV8,
bool contextOwnedByExterior, TRI_vocbase_t* vocbase,
arangodb::basics::Json queryStruct, TRI_json_t* options,
QueryPart part)
: _id(0),
_applicationV8(applicationV8),
_vocbase(vocbase),
_executor(nullptr),
_context(nullptr),
_queryString(nullptr),
_queryLength(0),
_queryJson(queryStruct),
_bindParameters(nullptr),
_options(options),
_collections(vocbase),
_strings(),
_shortStringStorage(1024),
_ast(nullptr),
_profile(nullptr),
_state(INVALID_STATE),
_plan(nullptr),
_parser(nullptr),
_trx(nullptr),
_engine(nullptr),
_maxWarningCount(10),
_warnings(),
_startTime(TRI_microtime()),
_part(part),
_contextOwnedByExterior(contextOwnedByExterior),
_killed(false),
_isModificationQuery(false) {
// std::cout << TRI_CurrentThreadId() << ", QUERY " << this << " CTOR (JSON):
// " << _queryJson.toString() << "\n";
TRI_ASSERT(_vocbase != nullptr);
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief creates a query from VelocyPack /// @brief creates a query from VelocyPack
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
Query::Query(arangodb::ApplicationV8* applicationV8, Query::Query(arangodb::ApplicationV8* applicationV8,
bool contextOwnedByExterior, TRI_vocbase_t* vocbase, bool contextOwnedByExterior, TRI_vocbase_t* vocbase,
std::shared_ptr<VPackBuilder> queryStruct, std::shared_ptr<VPackBuilder> const queryStruct,
VPackSlice const options, QueryPart part) std::shared_ptr<VPackBuilder> const options, QueryPart part)
: _id(0), : _id(0),
_applicationV8(applicationV8), _applicationV8(applicationV8),
_vocbase(vocbase), _vocbase(vocbase),
@ -304,10 +208,9 @@ Query::Query(arangodb::ApplicationV8* applicationV8,
_context(nullptr), _context(nullptr),
_queryString(nullptr), _queryString(nullptr),
_queryLength(0), _queryLength(0),
_queryJson(TRI_UNKNOWN_MEM_ZONE, arangodb::basics::VelocyPackHelper::velocyPackToJson( _queryBuilder(queryStruct),
queryStruct->slice())),
_bindParameters(nullptr), _bindParameters(nullptr),
_options(arangodb::basics::VelocyPackHelper::velocyPackToJson(options)), _options(options),
_collections(vocbase), _collections(vocbase),
_strings(), _strings(),
_shortStringStorage(1024), _shortStringStorage(1024),
@ -343,11 +246,6 @@ Query::~Query() {
delete _profile; delete _profile;
_profile = nullptr; _profile = nullptr;
if (_options != nullptr) {
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, _options);
_options = nullptr;
}
delete _executor; delete _executor;
_executor = nullptr; _executor = nullptr;
@ -390,21 +288,11 @@ Query::~Query() {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
Query* Query::clone(QueryPart part, bool withPlan) { Query* Query::clone(QueryPart part, bool withPlan) {
std::unique_ptr<TRI_json_t> options;
if (_options != nullptr) {
options.reset(TRI_CopyJson(TRI_UNKNOWN_MEM_ZONE, _options));
if (options == nullptr) {
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
}
}
std::unique_ptr<Query> clone; std::unique_ptr<Query> clone;
clone.reset(new Query(_applicationV8, false, _vocbase, _queryString, clone.reset(new Query(_applicationV8, false, _vocbase, _queryString,
_queryLength, std::shared_ptr<VPackBuilder>(), options.get(), part)); _queryLength, std::shared_ptr<VPackBuilder>(), _options, part));
options.release();
if (_plan != nullptr) { if (_plan != nullptr) {
if (withPlan) { if (withPlan) {
@ -618,11 +506,13 @@ QueryResult Query::prepare(QueryRegistry* registry) {
// Now plan and all derived plans belong to the optimizer // Now plan and all derived plans belong to the optimizer
plan.reset(opt.stealBest()); // Now we own the best one again plan.reset(opt.stealBest()); // Now we own the best one again
planRegisters = true; planRegisters = true;
} else { // no queryString, we are instantiating from _queryJson } else { // no queryString, we are instantiating from _queryBuilder
enterState(PLAN_INSTANTIATION); enterState(PLAN_INSTANTIATION);
ExecutionPlan::getCollectionsFromJson(parser->ast(), _queryJson);
parser->ast()->variables()->fromJson(_queryJson); VPackSlice const querySlice = _queryBuilder->slice();
ExecutionPlan::getCollectionsFromVelocyPack(parser->ast(), querySlice);
parser->ast()->variables()->fromVelocyPack(querySlice);
// creating the plan may have produced some collections // creating the plan may have produced some collections
// we need to add them to the transaction now (otherwise the query will // we need to add them to the transaction now (otherwise the query will
// fail) // fail)
@ -637,8 +527,8 @@ QueryResult Query::prepare(QueryRegistry* registry) {
return transactionError(res); return transactionError(res);
} }
// we have an execution plan in JSON format // we have an execution plan in VelocyPack format
plan.reset(ExecutionPlan::instantiateFromJson(parser->ast(), _queryJson)); plan.reset(ExecutionPlan::instantiateFromVelocyPack(parser->ast(), _queryBuilder->slice()));
if (plan.get() == nullptr) { if (plan.get() == nullptr) {
// oops // oops
return QueryResult(TRI_ERROR_INTERNAL); return QueryResult(TRI_ERROR_INTERNAL);
@ -721,7 +611,12 @@ QueryResult Query::execute(QueryRegistry* registry) {
if (cacheEntry != nullptr) { if (cacheEntry != nullptr) {
// got a result from the query cache // got a result from the query cache
QueryResult res(TRI_ERROR_NO_ERROR); QueryResult res(TRI_ERROR_NO_ERROR);
res.warnings = warningsToJson(TRI_UNKNOWN_MEM_ZONE); #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 = TRI_CopyJson(TRI_UNKNOWN_MEM_ZONE, cacheEntry->_queryResult); res.json = TRI_CopyJson(TRI_UNKNOWN_MEM_ZONE, cacheEntry->_queryResult);
res.cached = true; res.cached = true;
@ -838,12 +733,17 @@ QueryResult Query::execute(QueryRegistry* registry) {
enterState(FINALIZATION); enterState(FINALIZATION);
QueryResult result(TRI_ERROR_NO_ERROR); QueryResult result(TRI_ERROR_NO_ERROR);
result.warnings = warningsToJson(TRI_UNKNOWN_MEM_ZONE); #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.json = jsonResult.steal();
result.stats = stats; result.stats = stats;
if (_profile != nullptr && profiling()) { if (_profile != nullptr && profiling()) {
result.profile = _profile->toJson(TRI_UNKNOWN_MEM_ZONE); result.profile = _profile->toVelocyPack();
} }
return result; return result;
@ -992,11 +892,16 @@ QueryResultV8 Query::executeV8(v8::Isolate* isolate, QueryRegistry* registry) {
enterState(FINALIZATION); enterState(FINALIZATION);
result.warnings = warningsToJson(TRI_UNKNOWN_MEM_ZONE); #warning Replace QueryResult with VPack
VPackBuilder tmp;
tmp.openObject();
warningsToVelocyPack(tmp);
tmp.close();
result.warnings = arangodb::basics::VelocyPackHelper::velocyPackToJson(tmp.slice().get("warnings"));
result.stats = stats; result.stats = stats;
if (_profile != nullptr && profiling()) { if (_profile != nullptr && profiling()) {
result.profile = _profile->toJson(TRI_UNKNOWN_MEM_ZONE); result.profile = _profile->toVelocyPack();
} }
return result; return result;
@ -1130,7 +1035,13 @@ QueryResult Query::explain() {
_trx->commit(); _trx->commit();
result.warnings = warningsToJson(TRI_UNKNOWN_MEM_ZONE); #warning Replace QueryResult with VPack
VPackBuilder tmp;
tmp.openObject();
warningsToVelocyPack(tmp);
tmp.close();
result.warnings = arangodb::basics::VelocyPackHelper::velocyPackToJson(tmp.slice().get("warnings"));
result.stats = opt._stats.toVelocyPack(); result.stats = opt._stats.toVelocyPack();
return result; return result;
@ -1308,16 +1219,17 @@ void Query::getStats(VPackBuilder& builder) {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
bool Query::getBooleanOption(char const* option, bool defaultValue) const { bool Query::getBooleanOption(char const* option, bool defaultValue) const {
if (!TRI_IsObjectJson(_options)) { VPackSlice options = _options->slice();
if (!options.isObject()) {
return defaultValue; return defaultValue;
} }
TRI_json_t const* valueJson = TRI_LookupObjectJson(_options, option); VPackSlice value = options.get(option);
if (!TRI_IsBooleanJson(valueJson)) { if (!value.isBoolean()) {
return defaultValue; return defaultValue;
} }
return valueJson->_value._boolean; return value.getBool();
} }
@ -1327,43 +1239,21 @@ bool Query::getBooleanOption(char const* option, bool defaultValue) const {
/// warnings. If there are none it will not modify the builder /// warnings. If there are none it will not modify the builder
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
void Query::warningsToVelocyPack(arangodb::velocypack::Builder&) const { void Query::warningsToVelocyPack(arangodb::velocypack::Builder& builder) const {
#warning Needs to be implemented. TRI_ASSERT(builder.isOpenObject());
THROW_ARANGO_EXCEPTION(TRI_ERROR_NOT_IMPLEMENTED);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief convert the list of warnings to JSON
////////////////////////////////////////////////////////////////////////////////
TRI_json_t* Query::warningsToJson(TRI_memory_zone_t* zone) const {
if (_warnings.empty()) { if (_warnings.empty()) {
return nullptr; return;
} }
size_t const n = _warnings.size(); size_t const n = _warnings.size();
TRI_json_t* json = TRI_CreateArrayJson(zone, n); builder.add(VPackValue("warnings"));
{
if (json != nullptr) { VPackArrayBuilder guard(&builder);
for (size_t i = 0; i < n; ++i) { for (size_t i = 0; i < n; ++i) {
TRI_json_t* error = TRI_CreateObjectJson(zone, 2); VPackObjectBuilder objGuard(&builder);
builder.add("code", VPackValue(_warnings[i].first));
if (error != nullptr) { builder.add("message", VPackValue(_warnings[i].second));
TRI_Insert3ObjectJson(
zone, error, "code",
TRI_CreateNumberJson(zone,
static_cast<double>(_warnings[i].first)));
TRI_Insert3ObjectJson(
zone, error, "message",
TRI_CreateStringCopyJson(zone, _warnings[i].second.c_str(),
_warnings[i].second.size()));
TRI_PushBack3ArrayJson(zone, json, error);
}
} }
} }
return json;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -1470,16 +1360,17 @@ bool Query::canUseQueryCache() const {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
double Query::getNumericOption(char const* option, double defaultValue) const { double Query::getNumericOption(char const* option, double defaultValue) const {
if (!TRI_IsObjectJson(_options)) { VPackSlice options = _options->slice();
if (!options.isObject()) {
return defaultValue; return defaultValue;
} }
TRI_json_t const* valueJson = TRI_LookupObjectJson(_options, option); VPackSlice value = options.get(option);
if (!TRI_IsNumberJson(valueJson)) { if (!value.isNumber()) {
return defaultValue; return defaultValue;
} }
return valueJson->_value._number; return value.getNumericValue<double>();
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -1507,21 +1398,19 @@ QueryResult Query::transactionError(int errorCode) const {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
bool Query::inspectSimplePlans() const { bool Query::inspectSimplePlans() const {
if (!TRI_IsObjectJson(_options)) { VPackSlice options = _options->slice();
if (!options.isObject()) {
return true; // default return true; // default
} }
TRI_json_t const* optJson = TRI_LookupObjectJson(_options, "optimizer"); VPackSlice opt = options.get("optimizer");
if (!TRI_IsObjectJson(optJson)) { if (!opt.isObject()) {
return true; // default return true; // default
} }
TRI_json_t const* j = TRI_LookupObjectJson(optJson, "inspectSimplePlans"); return arangodb::basics::VelocyPackHelper::getBooleanValue(
if (TRI_IsBooleanJson(j)) { opt, "inspectSimplePlans", true);
return j->_value._boolean;
}
return true; // default;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -1531,31 +1420,27 @@ bool Query::inspectSimplePlans() const {
std::vector<std::string> Query::getRulesFromOptions() const { std::vector<std::string> Query::getRulesFromOptions() const {
std::vector<std::string> rules; std::vector<std::string> rules;
if (!TRI_IsObjectJson(_options)) { VPackSlice options = _options->slice();
if (!options.isObject()){
return rules; return rules;
} }
TRI_json_t const* optJson = TRI_LookupObjectJson(_options, "optimizer"); VPackSlice opt = options.get("optimizer");
if (!TRI_IsObjectJson(optJson)) { if (!opt.isObject()) {
return rules; return rules;
} }
TRI_json_t const* rulesJson = TRI_LookupObjectJson(optJson, "rules"); VPackSlice rulesList = opt.get("rules");
if (!TRI_IsArrayJson(rulesJson)) { if (!rulesList.isArray()) {
return rules; return rules;
} }
size_t const n = TRI_LengthArrayJson(rulesJson); for (auto const& rule : VPackArrayIterator(rulesList)) {
if (rule.isString()){
for (size_t i = 0; i < n; ++i) { rules.emplace_back(rule.copyString());
TRI_json_t const* rule = static_cast<TRI_json_t const*>(
TRI_AtVector(&rulesJson->_value._objects, i));
if (TRI_IsStringJson(rule)) {
rules.emplace_back(rule->_value._string.data,
rule->_value._string.length - 1);
} }
} }

View File

@ -38,7 +38,6 @@
#include <velocypack/Builder.h> #include <velocypack/Builder.h>
struct TRI_json_t;
struct TRI_vocbase_t; struct TRI_vocbase_t;
namespace arangodb { namespace arangodb {
@ -97,8 +96,6 @@ struct Profile {
std::shared_ptr<arangodb::velocypack::Builder> toVelocyPack(); std::shared_ptr<arangodb::velocypack::Builder> toVelocyPack();
TRI_json_t* toJson(TRI_memory_zone_t*);
Query* query; Query* query;
std::vector<std::pair<ExecutionState, double>> results; std::vector<std::pair<ExecutionState, double>> results;
double stamp; double stamp;
@ -116,19 +113,12 @@ class Query {
public: public:
Query(arangodb::ApplicationV8*, bool, TRI_vocbase_t*, char const*, size_t, Query(arangodb::ApplicationV8*, bool, TRI_vocbase_t*, char const*, size_t,
std::shared_ptr<arangodb::velocypack::Builder>, struct TRI_json_t*, std::shared_ptr<arangodb::velocypack::Builder> const,
QueryPart); std::shared_ptr<arangodb::velocypack::Builder> const, QueryPart);
Query(arangodb::ApplicationV8*, bool, TRI_vocbase_t*, char const*, size_t,
std::shared_ptr<arangodb::velocypack::Builder>,
arangodb::velocypack::Slice const, QueryPart);
Query(arangodb::ApplicationV8*, bool, TRI_vocbase_t*, Query(arangodb::ApplicationV8*, bool, TRI_vocbase_t*,
arangodb::basics::Json queryStruct, struct TRI_json_t*, QueryPart); std::shared_ptr<arangodb::velocypack::Builder> const,
std::shared_ptr<arangodb::velocypack::Builder> const, QueryPart);
Query(arangodb::ApplicationV8*, bool, TRI_vocbase_t*,
std::shared_ptr<arangodb::velocypack::Builder>,
arangodb::velocypack::Slice const, QueryPart);
~Query(); ~Query();
@ -407,12 +397,6 @@ class Query {
bool getBooleanOption(char const*, bool) const; bool getBooleanOption(char const*, bool) const;
//////////////////////////////////////////////////////////////////////////////
/// @brief convert the list of warnings to JSON
//////////////////////////////////////////////////////////////////////////////
TRI_json_t* warningsToJson(TRI_memory_zone_t*) const;
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
/// @brief convert the list of warnings to VelocyPack. /// @brief convert the list of warnings to VelocyPack.
/// Will add a new entry { ..., warnings: <warnings>, } if there are /// Will add a new entry { ..., warnings: <warnings>, } if there are
@ -582,10 +566,10 @@ class Query {
size_t const _queryLength; size_t const _queryLength;
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
/// @brief query in a JSON structure /// @brief query in a VelocyPack structure
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
arangodb::basics::Json const _queryJson; std::shared_ptr<arangodb::velocypack::Builder> const _queryBuilder;
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
/// @brief bind parameters for the query /// @brief bind parameters for the query
@ -597,7 +581,7 @@ class Query {
/// @brief query options /// @brief query options
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
TRI_json_t* _options; std::shared_ptr<arangodb::velocypack::Builder> _options;
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
/// @brief collections used in the query /// @brief collections used in the query

View File

@ -77,9 +77,6 @@ struct QueryResult {
if (json != nullptr) { if (json != nullptr) {
TRI_FreeJson(zone, json); TRI_FreeJson(zone, json);
} }
if (profile != nullptr) {
TRI_FreeJson(zone, profile);
}
} }
int code; int code;
@ -91,7 +88,7 @@ struct QueryResult {
TRI_json_t* warnings; TRI_json_t* warnings;
TRI_json_t* json; TRI_json_t* json;
std::shared_ptr<arangodb::velocypack::Builder> stats; std::shared_ptr<arangodb::velocypack::Builder> stats;
TRI_json_t* profile; std::shared_ptr<arangodb::velocypack::Builder> profile;
TRI_json_t* clusterplan; TRI_json_t* clusterplan;
}; };
} }

View File

@ -92,7 +92,8 @@ void RestAqlHandler::createQueryFromVelocyPack() {
return; return;
} }
VPackSlice options = querySlice.get("options"); auto options = std::make_shared<VPackBuilder>(
VPackBuilder::clone(querySlice.get("options")));
std::string const part = VelocyPackHelper::getStringValue(querySlice, "part", ""); std::string const part = VelocyPackHelper::getStringValue(querySlice, "part", "");
@ -240,10 +241,9 @@ void RestAqlHandler::explainQuery() {
return; return;
} }
#warning Can we use Builder::clone(Slice) here?
auto bindVars = std::make_shared<VPackBuilder>(VPackBuilder::clone(querySlice.get("parameters"))); auto bindVars = std::make_shared<VPackBuilder>(VPackBuilder::clone(querySlice.get("parameters")));
VPackSlice options = querySlice.get("options"); auto options = std::make_shared<VPackBuilder>(VPackBuilder::clone(querySlice.get("options")));
auto query = new Query(_applicationV8, false, _vocbase, queryString.c_str(), auto query = new Query(_applicationV8, false, _vocbase, queryString.c_str(),
queryString.size(), bindVars, options, PART_MAIN); queryString.size(), bindVars, options, PART_MAIN);
@ -314,9 +314,10 @@ void RestAqlHandler::createQueryFromString() {
return; return;
} }
auto bindVars = std::make_shared<VPackBuilder>(VPackBuilder::clone(querySlice.get("parameters"))); auto bindVars = std::make_shared<VPackBuilder>(
VPackBuilder::clone(querySlice.get("parameters")));
VPackSlice options = querySlice.get("options"); auto options = std::make_shared<VPackBuilder>(
VPackBuilder::clone(querySlice.get("options")));
auto query = auto query =
new Query(_applicationV8, false, _vocbase, queryString.c_str(), new Query(_applicationV8, false, _vocbase, queryString.c_str(),

View File

@ -22,12 +22,11 @@
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
#include "Variable.h" #include "Variable.h"
#include "Basics/JsonHelper.h" #include "Basics/VelocyPackHelper.h"
#include <velocypack/velocypack-aliases.h> #include <velocypack/velocypack-aliases.h>
using namespace arangodb::aql; using namespace arangodb::aql;
using JsonHelper = arangodb::basics::JsonHelper;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief name of $OLD variable /// @brief name of $OLD variable
@ -54,10 +53,11 @@ char const* const Variable::NAME_CURRENT = "$CURRENT";
Variable::Variable(std::string const& name, VariableId id) Variable::Variable(std::string const& name, VariableId id)
: name(name), value(nullptr), id(id) {} : name(name), value(nullptr), id(id) {}
Variable::Variable(arangodb::basics::Json const& json) Variable::Variable(arangodb::velocypack::Slice const slice)
: Variable( : Variable(arangodb::basics::VelocyPackHelper::checkAndGetStringValue(
JsonHelper::checkAndGetStringValue(json.json(), "name"), slice, "name"),
JsonHelper::checkAndGetNumericValue<VariableId>(json.json(), "id")) {} arangodb::basics::VelocyPackHelper::checkAndGetNumericValue<
VariableId>(slice, "id")) {}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief destroy the variable /// @brief destroy the variable

View File

@ -25,10 +25,19 @@
#define ARANGOD_AQL_VARIABLE_H 1 #define ARANGOD_AQL_VARIABLE_H 1
#include "Basics/Common.h" #include "Basics/Common.h"
#include "Basics/JsonHelper.h"
#include "Aql/types.h" #include "Aql/types.h"
namespace arangodb { namespace arangodb {
namespace velocypack {
class Builder;
class Slice;
}
namespace basics {
class Json;
}
namespace aql { namespace aql {
struct Variable { struct Variable {
@ -38,7 +47,7 @@ struct Variable {
Variable(std::string const&, VariableId); Variable(std::string const&, VariableId);
explicit Variable(basics::Json const& json); explicit Variable(arangodb::velocypack::Slice const);
Variable* clone() const { return new Variable(name, id); } Variable* clone() const { return new Variable(name, id); }

View File

@ -24,6 +24,11 @@
#include "Aql/VariableGenerator.h" #include "Aql/VariableGenerator.h"
#include "Basics/Exceptions.h" #include "Basics/Exceptions.h"
#include <velocypack/Iterator.h>
#include <velocypack/Slice.h>
#include <velocypack/velocypack-aliases.h>
using namespace arangodb::aql; using namespace arangodb::aql;
using Json = arangodb::basics::Json; using Json = arangodb::basics::Json;
@ -130,12 +135,12 @@ Variable* VariableGenerator::createVariable(Variable const* original) {
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief generate a variable from JSON /// @brief generate a variable from VelocyPack
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
Variable* VariableGenerator::createVariable( Variable* VariableGenerator::createVariable(
arangodb::basics::Json const& json) { VPackSlice const slice) {
auto variable = new Variable(json); auto variable = new Variable(slice);
auto existing = getVariable(variable->id); auto existing = getVariable(variable->id);
if (existing != nullptr) { if (existing != nullptr) {
@ -227,21 +232,22 @@ arangodb::basics::Json VariableGenerator::toJson(
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief import from JSON /// @brief import from VelocyPack
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void VariableGenerator::fromJson(Json const& query) { void VariableGenerator::fromVelocyPack(VPackSlice const& query) {
Json jsonAllVariablesList = query.get("variables"); VPackSlice allVariablesList = query.get("variables");
if (!jsonAllVariablesList.isArray()) { if (!allVariablesList.isArray()) {
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL,
"variables needs to be an array"); "variables needs to be an array");
} }
auto len = jsonAllVariablesList.size(); auto len = allVariablesList.length();
_variables.reserve(len); _variables.reserve(len);
for (size_t i = 0; i < len; i++) { for (auto const& var : VPackArrayIterator(allVariablesList)) {
createVariable(jsonAllVariablesList.at(i)); createVariable(var);
} }
} }

View File

@ -66,10 +66,10 @@ class VariableGenerator {
Variable* createVariable(std::string const&, bool); Variable* createVariable(std::string const&, bool);
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
/// @brief generate a variable from JSON /// @brief generate a variable from VelocyPack
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
Variable* createVariable(arangodb::basics::Json const&); Variable* createVariable(arangodb::velocypack::Slice const);
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
/// @brief clones a variable from an existing one /// @brief clones a variable from an existing one
@ -114,10 +114,10 @@ class VariableGenerator {
arangodb::basics::Json toJson(TRI_memory_zone_t*) const; arangodb::basics::Json toJson(TRI_memory_zone_t*) const;
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
/// @brief import from JSON /// @brief import from VelocyPack
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
void fromJson(arangodb::basics::Json const& jsonAllVariablesList); void fromVelocyPack(arangodb::velocypack::Slice const& allVariablesList);
private: private:
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////

View File

@ -108,15 +108,14 @@ void RestCursorHandler::processQuery(VPackSlice const& slice) {
bindVarsBuilder->add(bindVars); bindVarsBuilder->add(bindVars);
} }
VPackBuilder optionsBuilder = buildOptions(slice); auto options = std::make_shared<VPackBuilder>(buildOptions(slice));
VPackSlice options = optionsBuilder.slice();
VPackValueLength l; VPackValueLength l;
char const* queryString = querySlice.getString(l); char const* queryString = querySlice.getString(l);
arangodb::aql::Query query( arangodb::aql::Query query(
_applicationV8, false, _vocbase, queryString, static_cast<size_t>(l), _applicationV8, false, _vocbase, queryString, static_cast<size_t>(l),
bindVarsBuilder, bindVarsBuilder,
arangodb::basics::VelocyPackHelper::velocyPackToJson(options), options,
arangodb::aql::PART_MAIN); arangodb::aql::PART_MAIN);
registerQuery(&query); registerQuery(&query);
@ -139,10 +138,11 @@ void RestCursorHandler::processQuery(VPackSlice const& slice) {
_response->setContentType("application/json; charset=utf-8"); _response->setContentType("application/json; charset=utf-8");
std::shared_ptr<VPackBuilder> extra = buildExtra(queryResult); std::shared_ptr<VPackBuilder> extra = buildExtra(queryResult);
VPackSlice opts = options->slice();
size_t batchSize = size_t batchSize =
arangodb::basics::VelocyPackHelper::getNumericValue<size_t>( arangodb::basics::VelocyPackHelper::getNumericValue<size_t>(
options, "batchSize", 1000); opts, "batchSize", 1000);
size_t const n = TRI_LengthArrayJson(queryResult.json); size_t const n = TRI_LengthArrayJson(queryResult.json);
if (n <= batchSize) { if (n <= batchSize) {
@ -158,7 +158,7 @@ void RestCursorHandler::processQuery(VPackSlice const& slice) {
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
} }
result.add("hasMore", VPackValue(false)); result.add("hasMore", VPackValue(false));
if (arangodb::basics::VelocyPackHelper::getBooleanValue(options, "count", if (arangodb::basics::VelocyPackHelper::getBooleanValue(opts, "count",
false)) { false)) {
result.add("count", VPackValue(n)); result.add("count", VPackValue(n));
} }
@ -188,9 +188,9 @@ void RestCursorHandler::processQuery(VPackSlice const& slice) {
TRI_ASSERT(cursors != nullptr); TRI_ASSERT(cursors != nullptr);
double ttl = arangodb::basics::VelocyPackHelper::getNumericValue<double>( double ttl = arangodb::basics::VelocyPackHelper::getNumericValue<double>(
options, "ttl", 30); opts, "ttl", 30);
bool count = arangodb::basics::VelocyPackHelper::getBooleanValue( bool count = arangodb::basics::VelocyPackHelper::getBooleanValue(
options, "count", false); opts, "count", false);
// steal the query JSON, cursor will take over the ownership // steal the query JSON, cursor will take over the ownership
auto j = queryResult.json; auto j = queryResult.json;
@ -350,10 +350,7 @@ std::shared_ptr<VPackBuilder> RestCursorHandler::buildExtra(
} }
if (queryResult.profile != nullptr) { if (queryResult.profile != nullptr) {
extra->add(VPackValue("profile")); extra->add(VPackValue("profile"));
int res = arangodb::basics::JsonHelper::toVelocyPack(queryResult.profile, *extra); extra->add(queryResult.profile->slice());
if (res != TRI_ERROR_NO_ERROR) {
return nullptr;
}
queryResult.profile = nullptr; queryResult.profile = nullptr;
} }
if (queryResult.warnings == nullptr) { if (queryResult.warnings == nullptr) {

View File

@ -1120,22 +1120,24 @@ static void JS_ExplainAql(v8::FunctionCallbackInfo<v8::Value> const& args) {
} }
} }
std::unique_ptr<TRI_json_t> options; auto options = std::make_shared<VPackBuilder>();
if (args.Length() > 2) { if (args.Length() > 2) {
// handle options // handle options
if (!args[2]->IsObject()) { if (!args[2]->IsObject()) {
TRI_V8_THROW_TYPE_ERROR("expecting object for <options>"); TRI_V8_THROW_TYPE_ERROR("expecting object for <options>");
} }
int res = TRI_V8ToVPack(isolate, *options, args[2], false);
options.reset(TRI_ObjectToJson(isolate, args[2])); if (res != TRI_ERROR_NO_ERROR) {
TRI_V8_THROW_EXCEPTION(res);
}
} }
// bind parameters will be freed by the query later // bind parameters will be freed by the query later
TRI_GET_GLOBALS(); TRI_GET_GLOBALS();
arangodb::aql::Query query(v8g->_applicationV8, true, vocbase, arangodb::aql::Query query(v8g->_applicationV8, true, vocbase,
queryString.c_str(), queryString.size(), queryString.c_str(), queryString.size(),
bindVars, options.release(), bindVars, options,
arangodb::aql::PART_MAIN); arangodb::aql::PART_MAIN);
auto queryResult = query.explain(); auto queryResult = query.explain();
@ -1205,8 +1207,13 @@ static void JS_ExecuteAqlJson(v8::FunctionCallbackInfo<v8::Value> const& args) {
TRI_V8_THROW_TYPE_ERROR("expecting object for <queryjson>"); TRI_V8_THROW_TYPE_ERROR("expecting object for <queryjson>");
} }
std::unique_ptr<TRI_json_t> queryjson(TRI_ObjectToJson(isolate, args[0])); auto queryBuilder = std::make_shared<VPackBuilder>();
std::unique_ptr<TRI_json_t> options; int res = TRI_V8ToVPack(isolate, *queryBuilder, args[0], false);
if (res != TRI_ERROR_NO_ERROR) {
TRI_V8_THROW_EXCEPTION(res);
}
auto options = std::make_shared<VPackBuilder>();
if (args.Length() > 1) { if (args.Length() > 1) {
// we have options! yikes! // we have options! yikes!
@ -1214,15 +1221,15 @@ static void JS_ExecuteAqlJson(v8::FunctionCallbackInfo<v8::Value> const& args) {
TRI_V8_THROW_TYPE_ERROR("expecting object for <options>"); TRI_V8_THROW_TYPE_ERROR("expecting object for <options>");
} }
options.reset(TRI_ObjectToJson(isolate, args[1])); res = TRI_V8ToVPack(isolate, *options, args[1], false);
if (res != TRI_ERROR_NO_ERROR) {
TRI_V8_THROW_EXCEPTION(res);
}
} }
TRI_GET_GLOBALS(); TRI_GET_GLOBALS();
arangodb::aql::Query query(v8g->_applicationV8, true, vocbase, arangodb::aql::Query query(v8g->_applicationV8, true, vocbase, queryBuilder,
Json(TRI_UNKNOWN_MEM_ZONE, queryjson.release()), options, arangodb::aql::PART_MAIN);
options.get(), arangodb::aql::PART_MAIN);
options.release();
auto queryResult = query.execute( auto queryResult = query.execute(
static_cast<arangodb::aql::QueryRegistry*>(v8g->_queryRegistry)); static_cast<arangodb::aql::QueryRegistry*>(v8g->_queryRegistry));
@ -1246,7 +1253,7 @@ static void JS_ExecuteAqlJson(v8::FunctionCallbackInfo<v8::Value> const& args) {
} }
if (queryResult.profile != nullptr) { if (queryResult.profile != nullptr) {
result->ForceSet(TRI_V8_ASCII_STRING("profile"), result->ForceSet(TRI_V8_ASCII_STRING("profile"),
TRI_ObjectJson(isolate, queryResult.profile)); TRI_VPackToV8(isolate, queryResult.profile->slice()));
} }
if (queryResult.warnings == nullptr) { if (queryResult.warnings == nullptr) {
result->ForceSet(TRI_V8_ASCII_STRING("warnings"), v8::Array::New(isolate)); result->ForceSet(TRI_V8_ASCII_STRING("warnings"), v8::Array::New(isolate));
@ -1291,7 +1298,7 @@ static void JS_ExecuteAql(v8::FunctionCallbackInfo<v8::Value> const& args) {
std::shared_ptr<VPackBuilder> bindVars; std::shared_ptr<VPackBuilder> bindVars;
// options // options
std::unique_ptr<TRI_json_t> options; auto options = std::make_shared<VPackBuilder>();
if (args.Length() > 1) { if (args.Length() > 1) {
if (!args[1]->IsUndefined() && !args[1]->IsNull() && !args[1]->IsObject()) { if (!args[1]->IsUndefined() && !args[1]->IsNull() && !args[1]->IsObject()) {
@ -1313,17 +1320,17 @@ static void JS_ExecuteAql(v8::FunctionCallbackInfo<v8::Value> const& args) {
TRI_V8_THROW_TYPE_ERROR("expecting object for <options>"); TRI_V8_THROW_TYPE_ERROR("expecting object for <options>");
} }
options.reset(TRI_ObjectToJson(isolate, args[2])); int res = TRI_V8ToVPack(isolate, *options, args[2], false);
if (res != TRI_ERROR_NO_ERROR) {
TRI_V8_THROW_EXCEPTION(res);
}
} }
// bind parameters will be freed by the query later // bind parameters will be freed by the query later
TRI_GET_GLOBALS(); TRI_GET_GLOBALS();
arangodb::aql::Query query(v8g->_applicationV8, true, vocbase, arangodb::aql::Query query(v8g->_applicationV8, true, vocbase,
queryString.c_str(), queryString.size(), queryString.c_str(), queryString.size(), bindVars,
bindVars, options.get(), options, arangodb::aql::PART_MAIN);
arangodb::aql::PART_MAIN);
options.release();
auto queryResult = query.executeV8( auto queryResult = query.executeV8(
isolate, static_cast<arangodb::aql::QueryRegistry*>(v8g->_queryRegistry)); isolate, static_cast<arangodb::aql::QueryRegistry*>(v8g->_queryRegistry));
@ -1352,7 +1359,7 @@ static void JS_ExecuteAql(v8::FunctionCallbackInfo<v8::Value> const& args) {
} }
if (queryResult.profile != nullptr) { if (queryResult.profile != nullptr) {
result->ForceSet(TRI_V8_ASCII_STRING("profile"), result->ForceSet(TRI_V8_ASCII_STRING("profile"),
TRI_ObjectJson(isolate, queryResult.profile)); TRI_VPackToV8(isolate, queryResult.profile->slice()));
} }
if (queryResult.warnings == nullptr) { if (queryResult.warnings == nullptr) {
result->ForceSet(TRI_V8_ASCII_STRING("warnings"), v8::Array::New(isolate)); result->ForceSet(TRI_V8_ASCII_STRING("warnings"), v8::Array::New(isolate));

View File

@ -126,6 +126,28 @@ class VelocyPackHelper {
static std::string checkAndGetStringValue(VPackSlice const&, char const*); static std::string checkAndGetStringValue(VPackSlice const&, char const*);
//////////////////////////////////////////////////////////////////////////////
/// @brief returns a Numeric sub-element, or throws if <name> does not exist
/// or it is not a Number
//////////////////////////////////////////////////////////////////////////////
template <typename T>
static T checkAndGetNumericValue(VPackSlice const& slice, char const* name) {
TRI_ASSERT(slice.isObject());
if (!slice.hasKey(name)) {
std::string msg =
"The attribute '" + std::string(name) + "' was not found.";
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_BAD_PARAMETER, msg);
}
VPackSlice const sub = slice.get(name);
if (!sub.isNumber()) {
std::string msg =
"The attribute '" + std::string(name) + "' is not a number.";
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_BAD_PARAMETER, msg);
}
return sub.getNumericValue<T>();
}
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
/// @brief returns a string value, or the default value if it is not a string /// @brief returns a string value, or the default value if it is not a string
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////