mirror of https://gitee.com/bigwinds/arangodb
Merge branch 'spdvpk' of https://github.com/arangodb/arangodb into spdvpk
This commit is contained in:
commit
25c937b03e
|
@ -534,7 +534,9 @@ AstNode::AstNode(Ast* ast, arangodb::basics::Json const& json)
|
|||
break;
|
||||
}
|
||||
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);
|
||||
setData(variable);
|
||||
break;
|
||||
|
|
|
@ -377,7 +377,9 @@ ExecutionNode::ExecutionNode(ExecutionPlan* plan,
|
|||
len = jsonvarsUsedLater.size();
|
||||
_varsUsedLater.reserve(len);
|
||||
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);
|
||||
|
||||
if (oneVariable == nullptr) {
|
||||
|
@ -398,7 +400,9 @@ ExecutionNode::ExecutionNode(ExecutionPlan* plan,
|
|||
len = jsonvarsValidList.size();
|
||||
_varsValid.reserve(len);
|
||||
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);
|
||||
|
||||
if (oneVariable == nullptr) {
|
||||
|
@ -629,8 +633,9 @@ Variable* ExecutionNode::varFromJson(Ast* ast,
|
|||
"Mandatory variable \"" + std::string(variableName) + "\" not found.";
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, msg.c_str());
|
||||
}
|
||||
|
||||
return ast->variables()->createVariable(variableJson);
|
||||
#warning Deprecated
|
||||
auto builder = JsonHelper::toVelocyPack(variableJson.json());
|
||||
return ast->variables()->createVariable(builder->slice());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -42,6 +42,9 @@
|
|||
#include "Basics/tri-strings.h"
|
||||
#include "Basics/VelocyPackHelper.h"
|
||||
|
||||
#include <velocypack/Iterator.h>
|
||||
#include <velocypack/velocypack-aliases.h>
|
||||
|
||||
using namespace arangodb::aql;
|
||||
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,
|
||||
arangodb::basics::Json const& json) {
|
||||
void ExecutionPlan::getCollectionsFromVelocyPack(Ast* ast,
|
||||
VPackSlice const slice) {
|
||||
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(
|
||||
TRI_ERROR_INTERNAL,
|
||||
"json node \"collections\" not found or not an array");
|
||||
}
|
||||
|
||||
auto const size = jsonCollections.size();
|
||||
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
arangodb::basics::Json oneJsonCollection =
|
||||
jsonCollections.at(static_cast<int>(i));
|
||||
auto typeStr = arangodb::basics::JsonHelper::checkAndGetStringValue(
|
||||
oneJsonCollection.json(), "type");
|
||||
|
||||
for (auto const& collection : VPackArrayIterator(collectionsSlice)) {
|
||||
auto typeStr = arangodb::basics::VelocyPackHelper::checkAndGetStringValue(
|
||||
collection, "type");
|
||||
ast->query()->collections()->add(
|
||||
arangodb::basics::JsonHelper::checkAndGetStringValue(
|
||||
oneJsonCollection.json(), "name"),
|
||||
arangodb::basics::VelocyPackHelper::checkAndGetStringValue(collection,
|
||||
"name"),
|
||||
TRI_GetTransactionTypeFromStr(
|
||||
arangodb::basics::JsonHelper::checkAndGetStringValue(
|
||||
oneJsonCollection.json(), "type").c_str()));
|
||||
arangodb::basics::VelocyPackHelper::checkAndGetStringValue(
|
||||
collection, "type")
|
||||
.c_str()));
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an execution plan from JSON
|
||||
/// @brief create an execution plan from VelocyPack
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ExecutionPlan* ExecutionPlan::instantiateFromJson(
|
||||
Ast* ast, arangodb::basics::Json const& json) {
|
||||
ExecutionPlan* ExecutionPlan::instantiateFromVelocyPack(
|
||||
Ast* ast, VPackSlice const slice) {
|
||||
TRI_ASSERT(ast != nullptr);
|
||||
|
||||
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->_varUsageComputed = true;
|
||||
|
||||
|
|
|
@ -63,18 +63,18 @@ class ExecutionPlan {
|
|||
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,
|
||||
arangodb::basics::Json const& Json);
|
||||
static void getCollectionsFromVelocyPack(Ast* ast,
|
||||
arangodb::velocypack::Slice const);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an execution plan from JSON
|
||||
/// @brief create an execution plan from VelocyPack
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static ExecutionPlan* instantiateFromJson(Ast* ast,
|
||||
arangodb::basics::Json const& Json);
|
||||
static ExecutionPlan* instantiateFromVelocyPack(
|
||||
Ast* ast, arangodb::velocypack::Slice const);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief clone the plan by recursively cloning starting from the root
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
#include "VocBase/Graphs.h"
|
||||
|
||||
#include <velocypack/Builder.h>
|
||||
#include <velocypack/Iterator.h>
|
||||
#include <velocypack/velocypack-aliases.h>
|
||||
|
||||
using namespace arangodb;
|
||||
|
@ -146,19 +147,6 @@ std::shared_ptr<VPackBuilder> Profile::toVelocyPack() {
|
|||
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
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -172,7 +160,7 @@ bool Query::DoDisableQueryTracking = false;
|
|||
Query::Query(arangodb::ApplicationV8* applicationV8,
|
||||
bool contextOwnedByExterior, TRI_vocbase_t* vocbase,
|
||||
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),
|
||||
_applicationV8(applicationV8),
|
||||
_vocbase(vocbase),
|
||||
|
@ -180,9 +168,9 @@ Query::Query(arangodb::ApplicationV8* applicationV8,
|
|||
_context(nullptr),
|
||||
_queryString(queryString),
|
||||
_queryLength(queryLength),
|
||||
_queryJson(),
|
||||
_queryBuilder(),
|
||||
_bindParameters(bindParameters),
|
||||
_options(arangodb::basics::VelocyPackHelper::velocyPackToJson(options)),
|
||||
_options(options),
|
||||
_collections(vocbase),
|
||||
_strings(),
|
||||
_shortStringStorage(1024),
|
||||
|
@ -205,98 +193,14 @@ Query::Query(arangodb::ApplicationV8* applicationV8,
|
|||
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
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Query::Query(arangodb::ApplicationV8* applicationV8,
|
||||
bool contextOwnedByExterior, TRI_vocbase_t* vocbase,
|
||||
std::shared_ptr<VPackBuilder> queryStruct,
|
||||
VPackSlice const options, QueryPart part)
|
||||
std::shared_ptr<VPackBuilder> const queryStruct,
|
||||
std::shared_ptr<VPackBuilder> const options, QueryPart part)
|
||||
: _id(0),
|
||||
_applicationV8(applicationV8),
|
||||
_vocbase(vocbase),
|
||||
|
@ -304,10 +208,9 @@ Query::Query(arangodb::ApplicationV8* applicationV8,
|
|||
_context(nullptr),
|
||||
_queryString(nullptr),
|
||||
_queryLength(0),
|
||||
_queryJson(TRI_UNKNOWN_MEM_ZONE, arangodb::basics::VelocyPackHelper::velocyPackToJson(
|
||||
queryStruct->slice())),
|
||||
_queryBuilder(queryStruct),
|
||||
_bindParameters(nullptr),
|
||||
_options(arangodb::basics::VelocyPackHelper::velocyPackToJson(options)),
|
||||
_options(options),
|
||||
_collections(vocbase),
|
||||
_strings(),
|
||||
_shortStringStorage(1024),
|
||||
|
@ -343,11 +246,6 @@ Query::~Query() {
|
|||
delete _profile;
|
||||
_profile = nullptr;
|
||||
|
||||
if (_options != nullptr) {
|
||||
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, _options);
|
||||
_options = nullptr;
|
||||
}
|
||||
|
||||
delete _executor;
|
||||
_executor = nullptr;
|
||||
|
||||
|
@ -390,21 +288,11 @@ Query::~Query() {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
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;
|
||||
|
||||
clone.reset(new Query(_applicationV8, false, _vocbase, _queryString,
|
||||
_queryLength, std::shared_ptr<VPackBuilder>(), options.get(), part));
|
||||
options.release();
|
||||
_queryLength, std::shared_ptr<VPackBuilder>(), _options, part));
|
||||
|
||||
if (_plan != nullptr) {
|
||||
if (withPlan) {
|
||||
|
@ -618,11 +506,13 @@ QueryResult Query::prepare(QueryRegistry* registry) {
|
|||
// Now plan and all derived plans belong to the optimizer
|
||||
plan.reset(opt.stealBest()); // Now we own the best one again
|
||||
planRegisters = true;
|
||||
} else { // no queryString, we are instantiating from _queryJson
|
||||
} else { // no queryString, we are instantiating from _queryBuilder
|
||||
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
|
||||
// we need to add them to the transaction now (otherwise the query will
|
||||
// fail)
|
||||
|
@ -637,8 +527,8 @@ QueryResult Query::prepare(QueryRegistry* registry) {
|
|||
return transactionError(res);
|
||||
}
|
||||
|
||||
// we have an execution plan in JSON format
|
||||
plan.reset(ExecutionPlan::instantiateFromJson(parser->ast(), _queryJson));
|
||||
// we have an execution plan in VelocyPack format
|
||||
plan.reset(ExecutionPlan::instantiateFromVelocyPack(parser->ast(), _queryBuilder->slice()));
|
||||
if (plan.get() == nullptr) {
|
||||
// oops
|
||||
return QueryResult(TRI_ERROR_INTERNAL);
|
||||
|
@ -721,7 +611,12 @@ QueryResult Query::execute(QueryRegistry* registry) {
|
|||
if (cacheEntry != nullptr) {
|
||||
// got a result from the query cache
|
||||
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.cached = true;
|
||||
|
||||
|
@ -838,12 +733,17 @@ QueryResult Query::execute(QueryRegistry* registry) {
|
|||
enterState(FINALIZATION);
|
||||
|
||||
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.stats = stats;
|
||||
|
||||
if (_profile != nullptr && profiling()) {
|
||||
result.profile = _profile->toJson(TRI_UNKNOWN_MEM_ZONE);
|
||||
result.profile = _profile->toVelocyPack();
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -992,11 +892,16 @@ QueryResultV8 Query::executeV8(v8::Isolate* isolate, QueryRegistry* registry) {
|
|||
|
||||
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;
|
||||
|
||||
if (_profile != nullptr && profiling()) {
|
||||
result.profile = _profile->toJson(TRI_UNKNOWN_MEM_ZONE);
|
||||
result.profile = _profile->toVelocyPack();
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -1130,7 +1035,13 @@ QueryResult Query::explain() {
|
|||
|
||||
_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();
|
||||
|
||||
return result;
|
||||
|
@ -1308,16 +1219,17 @@ void Query::getStats(VPackBuilder& builder) {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool Query::getBooleanOption(char const* option, bool defaultValue) const {
|
||||
if (!TRI_IsObjectJson(_options)) {
|
||||
VPackSlice options = _options->slice();
|
||||
if (!options.isObject()) {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
TRI_json_t const* valueJson = TRI_LookupObjectJson(_options, option);
|
||||
if (!TRI_IsBooleanJson(valueJson)) {
|
||||
VPackSlice value = options.get(option);
|
||||
if (!value.isBoolean()) {
|
||||
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
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Query::warningsToVelocyPack(arangodb::velocypack::Builder&) const {
|
||||
#warning Needs to be implemented.
|
||||
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 {
|
||||
void Query::warningsToVelocyPack(arangodb::velocypack::Builder& builder) const {
|
||||
TRI_ASSERT(builder.isOpenObject());
|
||||
if (_warnings.empty()) {
|
||||
return nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
size_t const n = _warnings.size();
|
||||
TRI_json_t* json = TRI_CreateArrayJson(zone, n);
|
||||
|
||||
if (json != nullptr) {
|
||||
builder.add(VPackValue("warnings"));
|
||||
{
|
||||
VPackArrayBuilder guard(&builder);
|
||||
for (size_t i = 0; i < n; ++i) {
|
||||
TRI_json_t* error = TRI_CreateObjectJson(zone, 2);
|
||||
|
||||
if (error != nullptr) {
|
||||
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);
|
||||
}
|
||||
VPackObjectBuilder objGuard(&builder);
|
||||
builder.add("code", VPackValue(_warnings[i].first));
|
||||
builder.add("message", VPackValue(_warnings[i].second));
|
||||
}
|
||||
}
|
||||
|
||||
return json;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -1470,16 +1360,17 @@ bool Query::canUseQueryCache() const {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
double Query::getNumericOption(char const* option, double defaultValue) const {
|
||||
if (!TRI_IsObjectJson(_options)) {
|
||||
VPackSlice options = _options->slice();
|
||||
if (!options.isObject()) {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
TRI_json_t const* valueJson = TRI_LookupObjectJson(_options, option);
|
||||
if (!TRI_IsNumberJson(valueJson)) {
|
||||
VPackSlice value = options.get(option);
|
||||
if (!value.isNumber()) {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
return valueJson->_value._number;
|
||||
return value.getNumericValue<double>();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -1507,21 +1398,19 @@ QueryResult Query::transactionError(int errorCode) const {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool Query::inspectSimplePlans() const {
|
||||
if (!TRI_IsObjectJson(_options)) {
|
||||
VPackSlice options = _options->slice();
|
||||
if (!options.isObject()) {
|
||||
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
|
||||
}
|
||||
|
||||
TRI_json_t const* j = TRI_LookupObjectJson(optJson, "inspectSimplePlans");
|
||||
if (TRI_IsBooleanJson(j)) {
|
||||
return j->_value._boolean;
|
||||
}
|
||||
return true; // default;
|
||||
return arangodb::basics::VelocyPackHelper::getBooleanValue(
|
||||
opt, "inspectSimplePlans", true);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -1531,31 +1420,27 @@ bool Query::inspectSimplePlans() const {
|
|||
std::vector<std::string> Query::getRulesFromOptions() const {
|
||||
std::vector<std::string> rules;
|
||||
|
||||
if (!TRI_IsObjectJson(_options)) {
|
||||
VPackSlice options = _options->slice();
|
||||
|
||||
if (!options.isObject()){
|
||||
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;
|
||||
}
|
||||
|
||||
TRI_json_t const* rulesJson = TRI_LookupObjectJson(optJson, "rules");
|
||||
VPackSlice rulesList = opt.get("rules");
|
||||
|
||||
if (!TRI_IsArrayJson(rulesJson)) {
|
||||
if (!rulesList.isArray()) {
|
||||
return rules;
|
||||
}
|
||||
|
||||
size_t const n = TRI_LengthArrayJson(rulesJson);
|
||||
|
||||
for (size_t i = 0; i < n; ++i) {
|
||||
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);
|
||||
for (auto const& rule : VPackArrayIterator(rulesList)) {
|
||||
if (rule.isString()){
|
||||
rules.emplace_back(rule.copyString());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -38,7 +38,6 @@
|
|||
|
||||
#include <velocypack/Builder.h>
|
||||
|
||||
struct TRI_json_t;
|
||||
struct TRI_vocbase_t;
|
||||
|
||||
namespace arangodb {
|
||||
|
@ -97,8 +96,6 @@ struct Profile {
|
|||
|
||||
std::shared_ptr<arangodb::velocypack::Builder> toVelocyPack();
|
||||
|
||||
TRI_json_t* toJson(TRI_memory_zone_t*);
|
||||
|
||||
Query* query;
|
||||
std::vector<std::pair<ExecutionState, double>> results;
|
||||
double stamp;
|
||||
|
@ -116,19 +113,12 @@ class Query {
|
|||
|
||||
public:
|
||||
Query(arangodb::ApplicationV8*, bool, TRI_vocbase_t*, char const*, size_t,
|
||||
std::shared_ptr<arangodb::velocypack::Builder>, struct TRI_json_t*,
|
||||
QueryPart);
|
||||
|
||||
Query(arangodb::ApplicationV8*, bool, TRI_vocbase_t*, char const*, size_t,
|
||||
std::shared_ptr<arangodb::velocypack::Builder>,
|
||||
arangodb::velocypack::Slice const, QueryPart);
|
||||
std::shared_ptr<arangodb::velocypack::Builder> const,
|
||||
std::shared_ptr<arangodb::velocypack::Builder> const, QueryPart);
|
||||
|
||||
Query(arangodb::ApplicationV8*, bool, TRI_vocbase_t*,
|
||||
arangodb::basics::Json queryStruct, struct TRI_json_t*, QueryPart);
|
||||
|
||||
Query(arangodb::ApplicationV8*, bool, TRI_vocbase_t*,
|
||||
std::shared_ptr<arangodb::velocypack::Builder>,
|
||||
arangodb::velocypack::Slice const, QueryPart);
|
||||
std::shared_ptr<arangodb::velocypack::Builder> const,
|
||||
std::shared_ptr<arangodb::velocypack::Builder> const, QueryPart);
|
||||
|
||||
~Query();
|
||||
|
||||
|
@ -407,12 +397,6 @@ class Query {
|
|||
|
||||
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.
|
||||
/// Will add a new entry { ..., warnings: <warnings>, } if there are
|
||||
|
@ -582,10 +566,10 @@ class Query {
|
|||
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
|
||||
|
@ -597,7 +581,7 @@ class Query {
|
|||
/// @brief query options
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TRI_json_t* _options;
|
||||
std::shared_ptr<arangodb::velocypack::Builder> _options;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief collections used in the query
|
||||
|
|
|
@ -77,9 +77,6 @@ struct QueryResult {
|
|||
if (json != nullptr) {
|
||||
TRI_FreeJson(zone, json);
|
||||
}
|
||||
if (profile != nullptr) {
|
||||
TRI_FreeJson(zone, profile);
|
||||
}
|
||||
}
|
||||
|
||||
int code;
|
||||
|
@ -91,7 +88,7 @@ struct QueryResult {
|
|||
TRI_json_t* warnings;
|
||||
TRI_json_t* json;
|
||||
std::shared_ptr<arangodb::velocypack::Builder> stats;
|
||||
TRI_json_t* profile;
|
||||
std::shared_ptr<arangodb::velocypack::Builder> profile;
|
||||
TRI_json_t* clusterplan;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -92,7 +92,8 @@ void RestAqlHandler::createQueryFromVelocyPack() {
|
|||
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", "");
|
||||
|
||||
|
@ -240,10 +241,9 @@ void RestAqlHandler::explainQuery() {
|
|||
return;
|
||||
}
|
||||
|
||||
#warning Can we use Builder::clone(Slice) here?
|
||||
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(),
|
||||
queryString.size(), bindVars, options, PART_MAIN);
|
||||
|
@ -314,9 +314,10 @@ void RestAqlHandler::createQueryFromString() {
|
|||
return;
|
||||
}
|
||||
|
||||
auto bindVars = std::make_shared<VPackBuilder>(VPackBuilder::clone(querySlice.get("parameters")));
|
||||
|
||||
VPackSlice options = querySlice.get("options");
|
||||
auto bindVars = std::make_shared<VPackBuilder>(
|
||||
VPackBuilder::clone(querySlice.get("parameters")));
|
||||
auto options = std::make_shared<VPackBuilder>(
|
||||
VPackBuilder::clone(querySlice.get("options")));
|
||||
|
||||
auto query =
|
||||
new Query(_applicationV8, false, _vocbase, queryString.c_str(),
|
||||
|
|
|
@ -22,12 +22,11 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "Variable.h"
|
||||
#include "Basics/JsonHelper.h"
|
||||
#include "Basics/VelocyPackHelper.h"
|
||||
|
||||
#include <velocypack/velocypack-aliases.h>
|
||||
|
||||
using namespace arangodb::aql;
|
||||
using JsonHelper = arangodb::basics::JsonHelper;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief name of $OLD variable
|
||||
|
@ -54,10 +53,11 @@ char const* const Variable::NAME_CURRENT = "$CURRENT";
|
|||
Variable::Variable(std::string const& name, VariableId id)
|
||||
: name(name), value(nullptr), id(id) {}
|
||||
|
||||
Variable::Variable(arangodb::basics::Json const& json)
|
||||
: Variable(
|
||||
JsonHelper::checkAndGetStringValue(json.json(), "name"),
|
||||
JsonHelper::checkAndGetNumericValue<VariableId>(json.json(), "id")) {}
|
||||
Variable::Variable(arangodb::velocypack::Slice const slice)
|
||||
: Variable(arangodb::basics::VelocyPackHelper::checkAndGetStringValue(
|
||||
slice, "name"),
|
||||
arangodb::basics::VelocyPackHelper::checkAndGetNumericValue<
|
||||
VariableId>(slice, "id")) {}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief destroy the variable
|
||||
|
|
|
@ -25,10 +25,19 @@
|
|||
#define ARANGOD_AQL_VARIABLE_H 1
|
||||
|
||||
#include "Basics/Common.h"
|
||||
#include "Basics/JsonHelper.h"
|
||||
#include "Aql/types.h"
|
||||
|
||||
|
||||
namespace arangodb {
|
||||
namespace velocypack {
|
||||
class Builder;
|
||||
class Slice;
|
||||
}
|
||||
|
||||
namespace basics {
|
||||
class Json;
|
||||
}
|
||||
|
||||
namespace aql {
|
||||
|
||||
struct Variable {
|
||||
|
@ -38,7 +47,7 @@ struct Variable {
|
|||
|
||||
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); }
|
||||
|
||||
|
|
|
@ -24,6 +24,11 @@
|
|||
#include "Aql/VariableGenerator.h"
|
||||
#include "Basics/Exceptions.h"
|
||||
|
||||
#include <velocypack/Iterator.h>
|
||||
#include <velocypack/Slice.h>
|
||||
#include <velocypack/velocypack-aliases.h>
|
||||
|
||||
|
||||
using namespace arangodb::aql;
|
||||
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(
|
||||
arangodb::basics::Json const& json) {
|
||||
auto variable = new Variable(json);
|
||||
VPackSlice const slice) {
|
||||
auto variable = new Variable(slice);
|
||||
|
||||
auto existing = getVariable(variable->id);
|
||||
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) {
|
||||
Json jsonAllVariablesList = query.get("variables");
|
||||
void VariableGenerator::fromVelocyPack(VPackSlice const& query) {
|
||||
VPackSlice allVariablesList = query.get("variables");
|
||||
|
||||
if (!jsonAllVariablesList.isArray()) {
|
||||
if (!allVariablesList.isArray()) {
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL,
|
||||
"variables needs to be an array");
|
||||
}
|
||||
|
||||
auto len = jsonAllVariablesList.size();
|
||||
auto len = allVariablesList.length();
|
||||
_variables.reserve(len);
|
||||
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
createVariable(jsonAllVariablesList.at(i));
|
||||
for (auto const& var : VPackArrayIterator(allVariablesList)) {
|
||||
createVariable(var);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -66,10 +66,10 @@ class VariableGenerator {
|
|||
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
|
||||
|
@ -114,10 +114,10 @@ class VariableGenerator {
|
|||
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:
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -108,15 +108,14 @@ void RestCursorHandler::processQuery(VPackSlice const& slice) {
|
|||
bindVarsBuilder->add(bindVars);
|
||||
}
|
||||
|
||||
VPackBuilder optionsBuilder = buildOptions(slice);
|
||||
VPackSlice options = optionsBuilder.slice();
|
||||
auto options = std::make_shared<VPackBuilder>(buildOptions(slice));
|
||||
VPackValueLength l;
|
||||
char const* queryString = querySlice.getString(l);
|
||||
|
||||
arangodb::aql::Query query(
|
||||
_applicationV8, false, _vocbase, queryString, static_cast<size_t>(l),
|
||||
bindVarsBuilder,
|
||||
arangodb::basics::VelocyPackHelper::velocyPackToJson(options),
|
||||
options,
|
||||
arangodb::aql::PART_MAIN);
|
||||
|
||||
registerQuery(&query);
|
||||
|
@ -139,10 +138,11 @@ void RestCursorHandler::processQuery(VPackSlice const& slice) {
|
|||
_response->setContentType("application/json; charset=utf-8");
|
||||
|
||||
std::shared_ptr<VPackBuilder> extra = buildExtra(queryResult);
|
||||
VPackSlice opts = options->slice();
|
||||
|
||||
size_t batchSize =
|
||||
arangodb::basics::VelocyPackHelper::getNumericValue<size_t>(
|
||||
options, "batchSize", 1000);
|
||||
opts, "batchSize", 1000);
|
||||
size_t const n = TRI_LengthArrayJson(queryResult.json);
|
||||
|
||||
if (n <= batchSize) {
|
||||
|
@ -158,7 +158,7 @@ void RestCursorHandler::processQuery(VPackSlice const& slice) {
|
|||
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
result.add("hasMore", VPackValue(false));
|
||||
if (arangodb::basics::VelocyPackHelper::getBooleanValue(options, "count",
|
||||
if (arangodb::basics::VelocyPackHelper::getBooleanValue(opts, "count",
|
||||
false)) {
|
||||
result.add("count", VPackValue(n));
|
||||
}
|
||||
|
@ -188,9 +188,9 @@ void RestCursorHandler::processQuery(VPackSlice const& slice) {
|
|||
TRI_ASSERT(cursors != nullptr);
|
||||
|
||||
double ttl = arangodb::basics::VelocyPackHelper::getNumericValue<double>(
|
||||
options, "ttl", 30);
|
||||
opts, "ttl", 30);
|
||||
bool count = arangodb::basics::VelocyPackHelper::getBooleanValue(
|
||||
options, "count", false);
|
||||
opts, "count", false);
|
||||
|
||||
// steal the query JSON, cursor will take over the ownership
|
||||
auto j = queryResult.json;
|
||||
|
@ -350,10 +350,7 @@ std::shared_ptr<VPackBuilder> RestCursorHandler::buildExtra(
|
|||
}
|
||||
if (queryResult.profile != nullptr) {
|
||||
extra->add(VPackValue("profile"));
|
||||
int res = arangodb::basics::JsonHelper::toVelocyPack(queryResult.profile, *extra);
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
return nullptr;
|
||||
}
|
||||
extra->add(queryResult.profile->slice());
|
||||
queryResult.profile = nullptr;
|
||||
}
|
||||
if (queryResult.warnings == nullptr) {
|
||||
|
|
|
@ -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) {
|
||||
// handle options
|
||||
if (!args[2]->IsObject()) {
|
||||
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
|
||||
TRI_GET_GLOBALS();
|
||||
arangodb::aql::Query query(v8g->_applicationV8, true, vocbase,
|
||||
queryString.c_str(), queryString.size(),
|
||||
bindVars, options.release(),
|
||||
bindVars, options,
|
||||
arangodb::aql::PART_MAIN);
|
||||
|
||||
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>");
|
||||
}
|
||||
|
||||
std::unique_ptr<TRI_json_t> queryjson(TRI_ObjectToJson(isolate, args[0]));
|
||||
std::unique_ptr<TRI_json_t> options;
|
||||
auto queryBuilder = std::make_shared<VPackBuilder>();
|
||||
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) {
|
||||
// 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>");
|
||||
}
|
||||
|
||||
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();
|
||||
arangodb::aql::Query query(v8g->_applicationV8, true, vocbase,
|
||||
Json(TRI_UNKNOWN_MEM_ZONE, queryjson.release()),
|
||||
options.get(), arangodb::aql::PART_MAIN);
|
||||
|
||||
options.release();
|
||||
arangodb::aql::Query query(v8g->_applicationV8, true, vocbase, queryBuilder,
|
||||
options, arangodb::aql::PART_MAIN);
|
||||
|
||||
auto queryResult = query.execute(
|
||||
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) {
|
||||
result->ForceSet(TRI_V8_ASCII_STRING("profile"),
|
||||
TRI_ObjectJson(isolate, queryResult.profile));
|
||||
TRI_VPackToV8(isolate, queryResult.profile->slice()));
|
||||
}
|
||||
if (queryResult.warnings == nullptr) {
|
||||
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;
|
||||
|
||||
// options
|
||||
std::unique_ptr<TRI_json_t> options;
|
||||
auto options = std::make_shared<VPackBuilder>();
|
||||
|
||||
if (args.Length() > 1) {
|
||||
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>");
|
||||
}
|
||||
|
||||
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
|
||||
TRI_GET_GLOBALS();
|
||||
arangodb::aql::Query query(v8g->_applicationV8, true, vocbase,
|
||||
queryString.c_str(), queryString.size(),
|
||||
bindVars, options.get(),
|
||||
arangodb::aql::PART_MAIN);
|
||||
|
||||
options.release();
|
||||
queryString.c_str(), queryString.size(), bindVars,
|
||||
options, arangodb::aql::PART_MAIN);
|
||||
|
||||
auto queryResult = query.executeV8(
|
||||
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) {
|
||||
result->ForceSet(TRI_V8_ASCII_STRING("profile"),
|
||||
TRI_ObjectJson(isolate, queryResult.profile));
|
||||
TRI_VPackToV8(isolate, queryResult.profile->slice()));
|
||||
}
|
||||
if (queryResult.warnings == nullptr) {
|
||||
result->ForceSet(TRI_V8_ASCII_STRING("warnings"), v8::Array::New(isolate));
|
||||
|
|
|
@ -126,6 +126,28 @@ class VelocyPackHelper {
|
|||
|
||||
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
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
|
Loading…
Reference in New Issue