1
0
Fork 0

pass function arguments by reference

This commit is contained in:
Jan Steemann 2015-06-16 18:01:45 +02:00
parent a2b9919a6f
commit dec79dd051
9 changed files with 200 additions and 176 deletions

View File

@ -597,7 +597,7 @@ Json AqlItemBlock::toJson (triagens::arango::AqlTransaction* trx) const {
else {
auto it = table.find(a);
if (it == table.end()) {
raw(a.toJson(trx, _docColls[column]));
raw(a.toJson(trx, _docColls[column], true));
data(Json(1.0));
table.emplace(std::make_pair(a, pos++));
}

View File

@ -361,7 +361,7 @@ triagens::basics::Json AqlValue::at (triagens::arango::AqlTransaction* trx,
size_t const n = current->size();
if (offset + i < n) {
auto vecCollection = current->getDocumentCollection(0);
return current->getValue(i - offset, 0).toJson(trx, vecCollection);
return current->getValue(i - offset, 0).toJson(trx, vecCollection, true);
}
offset += (*it)->size();
}
@ -587,7 +587,7 @@ v8::Handle<v8::Value> AqlValue::toV8 (v8::Isolate* isolate,
size_t const n = current->size();
auto vecCollection = current->getDocumentCollection(0);
for (size_t i = 0; i < n; ++i) {
result->Set(j++, current->getValue(i, 0).toV8(isolate, trx, vecCollection));
result->Set(j++, current->getValueReference(i, 0).toV8(isolate, trx, vecCollection));
}
}
return result;
@ -622,10 +622,14 @@ v8::Handle<v8::Value> AqlValue::toV8 (v8::Isolate* isolate,
////////////////////////////////////////////////////////////////////////////////
Json AqlValue::toJson (triagens::arango::AqlTransaction* trx,
TRI_document_collection_t const* document) const {
TRI_document_collection_t const* document,
bool copy) const {
switch (_type) {
case JSON: {
return _json->copy();
if (copy) {
return _json->copy();
}
return Json(_json->zone(), _json->json(), Json::NOFREE);
}
case SHAPED: {
@ -682,7 +686,7 @@ Json AqlValue::toJson (triagens::arango::AqlTransaction* trx,
size_t const n = current->size();
auto vecCollection = current->getDocumentCollection(0);
for (size_t i = 0; i < n; ++i) {
json.add(current->getValue(i, 0).toJson(trx, vecCollection));
json.add(current->getValueReference(i, 0).toJson(trx, vecCollection, true));
}
}
@ -777,7 +781,7 @@ uint64_t AqlValue::hash (triagens::arango::AqlTransaction* trx,
size_t const n = current->size();
auto vecCollection = current->getDocumentCollection(0);
for (size_t i = 0; i < n; ++i) {
json.add(current->getValue(i, 0).toJson(trx, vecCollection));
json.add(current->getValue(i, 0).toJson(trx, vecCollection, false));
}
}
@ -989,7 +993,7 @@ Json AqlValue::extractArrayMember (triagens::arango::AqlTransaction* trx,
if (p < totalSize + (*it)->size()) {
// found the correct vector
auto vecCollection = (*it)->getDocumentCollection(0);
return (*it)->getValue(p - totalSize, 0).toJson(trx, vecCollection);
return (*it)->getValue(p - totalSize, 0).toJson(trx, vecCollection, copy);
}
totalSize += (*it)->size();
}
@ -1037,7 +1041,7 @@ AqlValue AqlValue::CreateFromBlocks (triagens::arango::AqlTransaction* trx,
// only enumerate the registers that are left
for (auto const& reg : registers) {
values.set(variableNames[reg.first], current->getValueReference(i, reg.first).toJson(trx, reg.second));
values.set(variableNames[reg.first], current->getValueReference(i, reg.first).toJson(trx, reg.second, true));
}
json->add(values);
@ -1067,7 +1071,7 @@ AqlValue AqlValue::CreateFromBlocks (triagens::arango::AqlTransaction* trx,
auto document = current->getDocumentCollection(expressionRegister);
for (size_t i = 0; i < current->size(); ++i) {
json->add(current->getValueReference(i, expressionRegister).toJson(trx, document));
json->add(current->getValueReference(i, expressionRegister).toJson(trx, document, true));
}
}
@ -1098,48 +1102,48 @@ int AqlValue::Compare (triagens::arango::AqlTransaction* trx,
(right._type == AqlValue::SHAPED ||
right._type == AqlValue::RANGE ||
right._type == AqlValue::DOCVEC)) {
triagens::basics::Json rjson = right.toJson(trx, rightcoll);
triagens::basics::Json rjson = right.toJson(trx, rightcoll, false);
return TRI_CompareValuesJson(left._json->json(), rjson.json(), compareUtf8);
}
// SHAPED against x
if (left._type == AqlValue::SHAPED) {
triagens::basics::Json ljson = left.toJson(trx, leftcoll);
triagens::basics::Json ljson = left.toJson(trx, leftcoll, false);
if (right._type == AqlValue::JSON) {
return TRI_CompareValuesJson(ljson.json(), right._json->json(), compareUtf8);
}
else if (right._type == AqlValue::RANGE ||
right._type == AqlValue::DOCVEC) {
triagens::basics::Json rjson = right.toJson(trx, rightcoll);
triagens::basics::Json rjson = right.toJson(trx, rightcoll, false);
return TRI_CompareValuesJson(ljson.json(), rjson.json(), compareUtf8);
}
}
// RANGE against x
if (left._type == AqlValue::RANGE) {
triagens::basics::Json ljson = left.toJson(trx, leftcoll);
triagens::basics::Json ljson = left.toJson(trx, leftcoll, false);
if (right._type == AqlValue::JSON) {
return TRI_CompareValuesJson(ljson.json(), right._json->json(), compareUtf8);
}
else if (right._type == AqlValue::SHAPED ||
right._type == AqlValue::DOCVEC) {
triagens::basics::Json rjson = right.toJson(trx, rightcoll);
triagens::basics::Json rjson = right.toJson(trx, rightcoll, false);
return TRI_CompareValuesJson(ljson.json(), rjson.json(), compareUtf8);
}
}
// DOCVEC against x
if (left._type == AqlValue::DOCVEC) {
triagens::basics::Json ljson = left.toJson(trx, leftcoll);
triagens::basics::Json ljson = left.toJson(trx, leftcoll, false);
if (right._type == AqlValue::JSON) {
return TRI_CompareValuesJson(ljson.json(), right._json->json(), compareUtf8);
}
else if (right._type == AqlValue::SHAPED ||
right._type == AqlValue::RANGE) {
triagens::basics::Json rjson = right.toJson(trx, rightcoll);
triagens::basics::Json rjson = right.toJson(trx, rightcoll, false);
return TRI_CompareValuesJson(ljson.json(), rjson.json(), compareUtf8);
}
}

View File

@ -299,7 +299,8 @@ namespace triagens {
////////////////////////////////////////////////////////////////////////////////
triagens::basics::Json toJson (triagens::arango::AqlTransaction*,
TRI_document_collection_t const*) const;
TRI_document_collection_t const*,
bool) const;
////////////////////////////////////////////////////////////////////////////////
/// @brief creates a hash value for the AqlValue

View File

@ -1183,7 +1183,7 @@ void IndexRangeBlock::buildExpressions () {
a.destroy(); // the TRI_json_t* of a._json has been stolen
}
else if (a._type == AqlValue::SHAPED || a._type == AqlValue::DOCVEC) {
bound = a.toJson(_trx, myCollection);
bound = a.toJson(_trx, myCollection, true);
a.destroy(); // the TRI_json_t* of a._json has been stolen
}
else {
@ -1253,7 +1253,7 @@ void IndexRangeBlock::buildExpressions () {
a.destroy(); // the TRI_json_t* of a._json has been stolen
}
else if (a._type == AqlValue::SHAPED || a._type == AqlValue::DOCVEC) {
bound = a.toJson(_trx, myCollection);
bound = a.toJson(_trx, myCollection, true);
a.destroy(); // the TRI_json_t* of a._json has been stolen
}
else {
@ -3620,7 +3620,7 @@ void SortedAggregateBlock::emitGroup (AqlItemBlock const* cur,
// that a group might theoretically consist of multiple documents, from different collections. but there
// is only one collection pointer per output register
auto document = cur->getDocumentCollection((*it).second);
res->setValue(row, (*it).first, AqlValue(new Json(_currentGroup.groupValues[i].toJson(_trx, document))));
res->setValue(row, (*it).first, AqlValue(new Json(_currentGroup.groupValues[i].toJson(_trx, document, true))));
}
else {
res->setValue(row, (*it).first, _currentGroup.groupValues[i]);
@ -4806,7 +4806,7 @@ AqlItemBlock* InsertBlock::work (std::vector<AqlItemBlock*>& blocks) {
if (errorCode == TRI_ERROR_NO_ERROR) {
TRI_doc_mptr_copy_t mptr;
auto json = a.toJson(_trx, document);
auto json = a.toJson(_trx, document, false);
if (isEdgeCollection) {
// edge
@ -4937,7 +4937,7 @@ AqlItemBlock* UpdateBlock::work (std::vector<AqlItemBlock*>& blocks) {
if (errorCode == TRI_ERROR_NO_ERROR) {
TRI_doc_mptr_copy_t mptr;
auto json = a.toJson(_trx, document);
auto json = a.toJson(_trx, document, true);
// read old document
TRI_doc_mptr_copy_t oldDocument;
@ -5116,8 +5116,8 @@ AqlItemBlock* UpsertBlock::work (std::vector<AqlItemBlock*>& blocks) {
AqlValue updateDoc = res->getValue(i, updateRegisterId);
if (updateDoc.isObject()) {
auto updateJson = updateDoc.toJson(_trx, updateDocument);
auto searchJson = a.toJson(_trx, keyDocument);
auto const updateJson = updateDoc.toJson(_trx, updateDocument, false);
auto searchJson = a.toJson(_trx, keyDocument, true);
if (! searchJson.isObject()) {
errorCode = TRI_ERROR_ARANGO_DOCUMENT_TYPE_INVALID;
@ -5212,7 +5212,7 @@ AqlItemBlock* UpsertBlock::work (std::vector<AqlItemBlock*>& blocks) {
}
if (errorCode == TRI_ERROR_NO_ERROR) {
auto insertJson = insertDoc.toJson(_trx, insertDocument);
auto const insertJson = insertDoc.toJson(_trx, insertDocument, true);
// use default value
errorCode = TRI_ERROR_OUT_OF_MEMORY;
@ -5369,7 +5369,7 @@ AqlItemBlock* ReplaceBlock::work (std::vector<AqlItemBlock*>& blocks) {
if (errorCode == TRI_ERROR_NO_ERROR) {
TRI_doc_mptr_copy_t mptr;
auto json = a.toJson(_trx, document);
auto const json = a.toJson(_trx, document, true);
// all exceptions are caught in _trx->update()
errorCode = _trx->update(trxCollection, key, 0, &mptr, json.json(), TRI_DOC_UPDATE_LAST_WRITE, 0, nullptr, ep->_options.waitForSync);

View File

@ -568,7 +568,7 @@ AqlValue Expression::executeSimpleExpression (AstNode const* node,
TRI_document_collection_t const* myCollection = nullptr;
AqlValue result = executeSimpleExpression(member, &myCollection, trx, argv, startPos, vars, regs, false);
array->add(result.toJson(trx, myCollection));
array->add(result.toJson(trx, myCollection, true));
result.destroy();
}
@ -599,7 +599,7 @@ AqlValue Expression::executeSimpleExpression (AstNode const* node,
member = member->getMember(0);
AqlValue result = executeSimpleExpression(member, &myCollection, trx, argv, startPos, vars, regs, false);
object->set(key, result.toJson(trx, myCollection));
object->set(key, result.toJson(trx, myCollection, true));
result.destroy();
}
return AqlValue(object.release());
@ -644,20 +644,32 @@ AqlValue Expression::executeSimpleExpression (AstNode const* node,
auto func = static_cast<Function*>(node->getData());
TRI_ASSERT(func->implementation != nullptr);
TRI_document_collection_t const* myCollection = nullptr;
auto member = node->getMemberUnchecked(0);
TRI_ASSERT(member->type == NODE_TYPE_ARRAY);
AqlValue result = executeSimpleExpression(member, &myCollection, trx, argv, startPos, vars, regs, false);
size_t const n = member->numMembers();
FunctionParameters parameters;
parameters.reserve(n);
try {
auto res2 = func->implementation(_ast->query(), trx, myCollection, result);
result.destroy();
for (size_t i = 0; i < n; ++i) {
TRI_document_collection_t const* myCollection = nullptr;
auto value = executeSimpleExpression(member->getMemberUnchecked(i), &myCollection, trx, argv, startPos, vars, regs, false);
parameters.emplace_back(std::make_pair(value, myCollection));
}
auto res2 = func->implementation(_ast->query(), trx, parameters);
for (auto& it : parameters) {
it.first.destroy();
}
return res2;
}
catch (...) {
// prevent leak and rethrow error
result.destroy();
for (auto& it : parameters) {
it.first.destroy();
}
throw;
}
}

View File

@ -44,6 +44,23 @@ using Json = triagens::basics::Json;
// --SECTION-- private functions
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief extract a function parameter from the arguments list
////////////////////////////////////////////////////////////////////////////////
static Json ExtractFunctionParameter (triagens::arango::AqlTransaction* trx,
FunctionParameters const& parameters,
size_t position,
bool copy) {
if (position >= parameters.size()) {
// parameter out of range
return Json(Json::Null);
}
auto const& parameter = parameters[position];
return parameter.first.toJson(trx, parameter.second, copy);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief register warning
////////////////////////////////////////////////////////////////////////////////
@ -80,17 +97,16 @@ static void RegisterInvalidArgumentWarning (triagens::aql::Query* query,
////////////////////////////////////////////////////////////////////////////////
static bool GetBooleanParameter (triagens::arango::AqlTransaction* trx,
TRI_document_collection_t const* collection,
AqlValue const& parameters,
FunctionParameters const& parameters,
size_t startParameter,
bool defaultValue) {
size_t const n = parameters.arraySize();
size_t const n = parameters.size();
if (startParameter >= n) {
return defaultValue;
}
Json temp = parameters.extractArrayMember(trx, collection, startParameter, false);
auto temp = ExtractFunctionParameter(trx, parameters, startParameter, false);
auto const valueJson = temp.json();
if (TRI_IsBooleanJson(valueJson)) {
@ -116,14 +132,13 @@ static bool GetBooleanParameter (triagens::arango::AqlTransaction* trx,
static void ExtractKeys (std::unordered_set<std::string>& names,
triagens::aql::Query* query,
triagens::arango::AqlTransaction* trx,
TRI_document_collection_t const* collection,
AqlValue const& parameters,
FunctionParameters const& parameters,
size_t startParameter,
char const* functionName) {
size_t const n = parameters.arraySize();
size_t const n = parameters.size();
for (size_t i = startParameter; i < n; ++i) {
Json param(parameters.extractArrayMember(trx, collection, i, false));
auto param = ExtractFunctionParameter(trx, parameters, i, false);
if (param.isString()) {
TRI_json_t const* json = param.json();
@ -218,10 +233,9 @@ static void AppendAsString (triagens::basics::StringBuffer& buffer,
AqlValue Functions::IsNull (triagens::aql::Query*,
triagens::arango::AqlTransaction* trx,
TRI_document_collection_t const* collection,
FunctionParameters parameters) {
Json j(parameters.extractArrayMember(trx, collection, 0, false));
return AqlValue(new Json(j.isNull()));
FunctionParameters const& parameters) {
auto value = ExtractFunctionParameter(trx, parameters, 0, false);
return AqlValue(new Json(value.isNull()));
}
////////////////////////////////////////////////////////////////////////////////
@ -230,10 +244,9 @@ AqlValue Functions::IsNull (triagens::aql::Query*,
AqlValue Functions::IsBool (triagens::aql::Query*,
triagens::arango::AqlTransaction* trx,
TRI_document_collection_t const* collection,
FunctionParameters parameters) {
Json j(parameters.extractArrayMember(trx, collection, 0, false));
return AqlValue(new Json(j.isBoolean()));
FunctionParameters const& parameters) {
auto value = ExtractFunctionParameter(trx, parameters, 0, false);
return AqlValue(new Json(value.isBoolean()));
}
////////////////////////////////////////////////////////////////////////////////
@ -242,10 +255,9 @@ AqlValue Functions::IsBool (triagens::aql::Query*,
AqlValue Functions::IsNumber (triagens::aql::Query*,
triagens::arango::AqlTransaction* trx,
TRI_document_collection_t const* collection,
FunctionParameters parameters) {
Json j(parameters.extractArrayMember(trx, collection, 0, false));
return AqlValue(new Json(j.isNumber()));
FunctionParameters const& parameters) {
auto value = ExtractFunctionParameter(trx, parameters, 0, false);
return AqlValue(new Json(value.isNumber()));
}
////////////////////////////////////////////////////////////////////////////////
@ -254,10 +266,9 @@ AqlValue Functions::IsNumber (triagens::aql::Query*,
AqlValue Functions::IsString (triagens::aql::Query*,
triagens::arango::AqlTransaction* trx,
TRI_document_collection_t const* collection,
FunctionParameters parameters) {
Json j(parameters.extractArrayMember(trx, collection, 0, false));
return AqlValue(new Json(j.isString()));
FunctionParameters const& parameters) {
auto value = ExtractFunctionParameter(trx, parameters, 0, false);
return AqlValue(new Json(value.isString()));
}
////////////////////////////////////////////////////////////////////////////////
@ -266,10 +277,9 @@ AqlValue Functions::IsString (triagens::aql::Query*,
AqlValue Functions::IsArray (triagens::aql::Query*,
triagens::arango::AqlTransaction* trx,
TRI_document_collection_t const* collection,
FunctionParameters parameters) {
Json j(parameters.extractArrayMember(trx, collection, 0, false));
return AqlValue(new Json(j.isArray()));
FunctionParameters const& parameters) {
auto value = ExtractFunctionParameter(trx, parameters, 0, false);
return AqlValue(new Json(value.isArray()));
}
////////////////////////////////////////////////////////////////////////////////
@ -278,10 +288,9 @@ AqlValue Functions::IsArray (triagens::aql::Query*,
AqlValue Functions::IsObject (triagens::aql::Query*,
triagens::arango::AqlTransaction* trx,
TRI_document_collection_t const* collection,
FunctionParameters parameters) {
Json j(parameters.extractArrayMember(trx, collection, 0, false));
return AqlValue(new Json(j.isObject()));
FunctionParameters const& parameters) {
auto value = ExtractFunctionParameter(trx, parameters, 0, false);
return AqlValue(new Json(value.isObject()));
}
////////////////////////////////////////////////////////////////////////////////
@ -290,11 +299,16 @@ AqlValue Functions::IsObject (triagens::aql::Query*,
AqlValue Functions::Length (triagens::aql::Query*,
triagens::arango::AqlTransaction* trx,
TRI_document_collection_t const* collection,
FunctionParameters parameters) {
Json j(parameters.extractArrayMember(trx, collection, 0, false));
FunctionParameters const& parameters) {
if (! parameters.empty() &&
parameters[0].first.isArray()) {
// shortcut!
return AqlValue(new Json(static_cast<double>(parameters[0].first.arraySize())));
}
TRI_json_t const* json = j.json();
auto value = ExtractFunctionParameter(trx, parameters, 0, false);
TRI_json_t const* json = value.json();
size_t length = 0;
if (json != nullptr) {
@ -354,14 +368,13 @@ AqlValue Functions::Length (triagens::aql::Query*,
AqlValue Functions::Concat (triagens::aql::Query*,
triagens::arango::AqlTransaction* trx,
TRI_document_collection_t const* collection,
FunctionParameters parameters) {
FunctionParameters const& parameters) {
triagens::basics::StringBuffer buffer(TRI_UNKNOWN_MEM_ZONE, 24);
size_t const n = parameters.arraySize();
size_t const n = parameters.size();
for (size_t i = 0; i < n; ++i) {
Json member = parameters.at(trx, i);
auto member = ExtractFunctionParameter(trx, parameters, i, false);
if (member.isEmpty() || member.isNull()) {
continue;
@ -405,24 +418,25 @@ AqlValue Functions::Concat (triagens::aql::Query*,
AqlValue Functions::Passthru (triagens::aql::Query*,
triagens::arango::AqlTransaction* trx,
TRI_document_collection_t const* collection,
FunctionParameters parameters) {
FunctionParameters const& parameters) {
Json j(parameters.extractArrayMember(trx, collection, 0, true));
auto jr = new Json(TRI_UNKNOWN_MEM_ZONE, j.json());
j.steal();
return AqlValue(jr);
if (parameters.empty()) {
return AqlValue(new Json(Json::Null));
}
auto json = ExtractFunctionParameter(trx, parameters, 0, true);
return AqlValue(new Json(TRI_UNKNOWN_MEM_ZONE, json.steal()));
}
////////////////////////////////////////////////////////////////////////////////
/// @brief function UNSET
////////////////////////////////////////////////////////////////////////////////
AqlValue Functions::Unset (triagens::aql::Query* query,
triagens::arango::AqlTransaction* trx,
TRI_document_collection_t const* collection,
FunctionParameters parameters) {
Json value(parameters.extractArrayMember(trx, collection, 0, false));
FunctionParameters const& parameters) {
auto value = ExtractFunctionParameter(trx, parameters, 0, false);
if (! value.isObject()) {
RegisterInvalidArgumentWarning(query, "UNSET");
@ -430,7 +444,7 @@ AqlValue Functions::Unset (triagens::aql::Query* query,
}
std::unordered_set<std::string> names;
ExtractKeys(names, query, trx, collection, parameters, 1, "UNSET");
ExtractKeys(names, query, trx, parameters, 1, "UNSET");
// create result object
@ -478,9 +492,8 @@ AqlValue Functions::Unset (triagens::aql::Query* query,
AqlValue Functions::Keep (triagens::aql::Query* query,
triagens::arango::AqlTransaction* trx,
TRI_document_collection_t const* collection,
FunctionParameters parameters) {
Json value(parameters.extractArrayMember(trx, collection, 0, false));
FunctionParameters const& parameters) {
auto value = ExtractFunctionParameter(trx, parameters, 0, false);
if (! value.isObject()) {
RegisterInvalidArgumentWarning(query, "KEEP");
@ -488,7 +501,7 @@ AqlValue Functions::Keep (triagens::aql::Query* query,
}
std::unordered_set<std::string> names;
ExtractKeys(names, query, trx, collection, parameters, 1, "KEEP");
ExtractKeys(names, query, trx, parameters, 1, "KEEP");
// create result object
@ -528,9 +541,8 @@ AqlValue Functions::Keep (triagens::aql::Query* query,
AqlValue Functions::Merge (triagens::aql::Query* query,
triagens::arango::AqlTransaction* trx,
TRI_document_collection_t const* collection,
FunctionParameters parameters) {
size_t const n = parameters.arraySize();
FunctionParameters const& parameters) {
size_t const n = parameters.size();
if (n == 0) {
// no parameters
@ -538,7 +550,7 @@ AqlValue Functions::Merge (triagens::aql::Query* query,
}
// use the first argument as the preliminary result
Json initial(parameters.extractArrayMember(trx, collection, 0, true));
auto initial = ExtractFunctionParameter(trx, parameters, 0, true);
if (! initial.isObject()) {
RegisterInvalidArgumentWarning(query, "MERGE");
@ -549,7 +561,7 @@ AqlValue Functions::Merge (triagens::aql::Query* query,
// now merge in all other arguments
for (size_t i = 1; i < n; ++i) {
Json param(parameters.extractArrayMember(trx, collection, i, false));
auto param = ExtractFunctionParameter(trx, parameters, i, false);
if (! param.isObject()) {
RegisterInvalidArgumentWarning(query, "MERGE");
@ -576,16 +588,15 @@ AqlValue Functions::Merge (triagens::aql::Query* query,
AqlValue Functions::Has (triagens::aql::Query* query,
triagens::arango::AqlTransaction* trx,
TRI_document_collection_t const* collection,
FunctionParameters parameters) {
size_t const n = parameters.arraySize();
FunctionParameters const& parameters) {
size_t const n = parameters.size();
if (n < 2) {
// no parameters
return AqlValue(new Json(false));
}
Json value(parameters.extractArrayMember(trx, collection, 0, false));
auto value = ExtractFunctionParameter(trx, parameters, 0, false);
if (! value.isObject()) {
// not an object
@ -593,7 +604,7 @@ AqlValue Functions::Has (triagens::aql::Query* query,
}
// process name parameter
Json name(parameters.extractArrayMember(trx, collection, 1, false));
auto name = ExtractFunctionParameter(trx, parameters, 1, false);
char const* p;
@ -616,16 +627,15 @@ AqlValue Functions::Has (triagens::aql::Query* query,
AqlValue Functions::Attributes (triagens::aql::Query* query,
triagens::arango::AqlTransaction* trx,
TRI_document_collection_t const* collection,
FunctionParameters parameters) {
size_t const n = parameters.arraySize();
FunctionParameters const& parameters) {
size_t const n = parameters.size();
if (n < 1) {
// no parameters
return AqlValue(new Json(Json::Null));
}
Json value(parameters.extractArrayMember(trx, collection, 0, false));
auto value = ExtractFunctionParameter(trx, parameters, 0, false);
if (! value.isObject()) {
// not an object
@ -633,8 +643,8 @@ AqlValue Functions::Attributes (triagens::aql::Query* query,
return AqlValue(new Json(Json::Null));
}
bool const removeInternal = GetBooleanParameter(trx, collection, parameters, 1, false);
bool const doSort = GetBooleanParameter(trx, collection, parameters, 2, false);
bool const removeInternal = GetBooleanParameter(trx, parameters, 1, false);
bool const doSort = GetBooleanParameter(trx, parameters, 2, false);
auto const valueJson = value.json();
TRI_ASSERT(TRI_IsObjectJson(valueJson));
@ -693,16 +703,15 @@ AqlValue Functions::Attributes (triagens::aql::Query* query,
AqlValue Functions::Values (triagens::aql::Query* query,
triagens::arango::AqlTransaction* trx,
TRI_document_collection_t const* collection,
FunctionParameters parameters) {
size_t const n = parameters.arraySize();
FunctionParameters const& parameters) {
size_t const n = parameters.size();
if (n < 1) {
// no parameters
return AqlValue(new Json(Json::Null));
}
Json value(parameters.extractArrayMember(trx, collection, 0, false));
auto value = ExtractFunctionParameter(trx, parameters, 0, false);
if (! value.isObject()) {
// not an object
@ -710,7 +719,7 @@ AqlValue Functions::Values (triagens::aql::Query* query,
return AqlValue(new Json(Json::Null));
}
bool const removeInternal = GetBooleanParameter(trx, collection, parameters, 1, false);
bool const removeInternal = GetBooleanParameter(trx, parameters, 1, false);
auto const valueJson = value.json();
TRI_ASSERT(TRI_IsObjectJson(valueJson));
@ -752,9 +761,8 @@ AqlValue Functions::Values (triagens::aql::Query* query,
AqlValue Functions::Min (triagens::aql::Query* query,
triagens::arango::AqlTransaction* trx,
TRI_document_collection_t const* collection,
FunctionParameters parameters) {
Json value(parameters.extractArrayMember(trx, collection, 0, false));
FunctionParameters const& parameters) {
auto value = ExtractFunctionParameter(trx, parameters, 0, false);
if (! value.isArray()) {
// not an array
@ -798,9 +806,8 @@ AqlValue Functions::Min (triagens::aql::Query* query,
AqlValue Functions::Max (triagens::aql::Query* query,
triagens::arango::AqlTransaction* trx,
TRI_document_collection_t const* collection,
FunctionParameters parameters) {
Json value(parameters.extractArrayMember(trx, collection, 0, false));
FunctionParameters const& parameters) {
auto value = ExtractFunctionParameter(trx, parameters, 0, false);
if (! value.isArray()) {
// not an array
@ -844,9 +851,8 @@ AqlValue Functions::Max (triagens::aql::Query* query,
AqlValue Functions::Sum (triagens::aql::Query* query,
triagens::arango::AqlTransaction* trx,
TRI_document_collection_t const* collection,
FunctionParameters parameters) {
Json value(parameters.extractArrayMember(trx, collection, 0, false));
FunctionParameters const& parameters) {
auto value = ExtractFunctionParameter(trx, parameters, 0, false);
if (! value.isArray()) {
// not an array
@ -891,9 +897,8 @@ AqlValue Functions::Sum (triagens::aql::Query* query,
AqlValue Functions::Average (triagens::aql::Query* query,
triagens::arango::AqlTransaction* trx,
TRI_document_collection_t const* collection,
FunctionParameters parameters) {
Json value(parameters.extractArrayMember(trx, collection, 0, false));
FunctionParameters const& parameters) {
auto value = ExtractFunctionParameter(trx, parameters, 0, false);
if (! value.isArray()) {
// not an array
@ -941,9 +946,8 @@ AqlValue Functions::Average (triagens::aql::Query* query,
AqlValue Functions::Md5 (triagens::aql::Query* query,
triagens::arango::AqlTransaction* trx,
TRI_document_collection_t const* collection,
FunctionParameters parameters) {
Json value(parameters.extractArrayMember(trx, collection, 0, false));
FunctionParameters const& parameters) {
auto value = ExtractFunctionParameter(trx, parameters, 0, false);
triagens::basics::StringBuffer buffer(TRI_UNKNOWN_MEM_ZONE);
AppendAsString(buffer, value.json());
@ -970,9 +974,8 @@ AqlValue Functions::Md5 (triagens::aql::Query* query,
AqlValue Functions::Sha1 (triagens::aql::Query* query,
triagens::arango::AqlTransaction* trx,
TRI_document_collection_t const* collection,
FunctionParameters parameters) {
Json value(parameters.extractArrayMember(trx, collection, 0, false));
FunctionParameters const& parameters) {
auto value = ExtractFunctionParameter(trx, parameters, 0, false);
triagens::basics::StringBuffer buffer(TRI_UNKNOWN_MEM_ZONE);
AppendAsString(buffer, value.json());
@ -999,13 +1002,12 @@ AqlValue Functions::Sha1 (triagens::aql::Query* query,
AqlValue Functions::Unique (triagens::aql::Query* query,
triagens::arango::AqlTransaction* trx,
TRI_document_collection_t const* collection,
FunctionParameters parameters) {
if (parameters.arraySize() != 1) {
FunctionParameters const& parameters) {
if (parameters.size() != 1) {
THROW_ARANGO_EXCEPTION_PARAMS(TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "UNIQUE");
}
Json value(parameters.extractArrayMember(trx, collection, 0, false));
auto value = ExtractFunctionParameter(trx, parameters, 0, false);
if (! value.isArray()) {
// not an array
@ -1055,18 +1057,17 @@ AqlValue Functions::Unique (triagens::aql::Query* query,
AqlValue Functions::Union (triagens::aql::Query* query,
triagens::arango::AqlTransaction* trx,
TRI_document_collection_t const* collection,
FunctionParameters parameters) {
size_t const n = parameters.arraySize();
FunctionParameters const& parameters) {
size_t const n = parameters.size();
if (parameters.arraySize() < 2) {
if (n < 2) {
THROW_ARANGO_EXCEPTION_PARAMS(TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "UNION");
}
std::unique_ptr<TRI_json_t> result(TRI_CreateArrayJson(TRI_UNKNOWN_MEM_ZONE, 16));
for (size_t i = 0; i < n; ++i) {
Json value(parameters.extractArrayMember(trx, collection, i, false));
auto value = ExtractFunctionParameter(trx, parameters, i, false);
if (! value.isArray()) {
// not an array
@ -1116,9 +1117,10 @@ AqlValue Functions::Union (triagens::aql::Query* query,
AqlValue Functions::UnionDistinct (triagens::aql::Query* query,
triagens::arango::AqlTransaction* trx,
TRI_document_collection_t const* collection,
FunctionParameters parameters) {
if (parameters.arraySize() < 2) {
FunctionParameters const& parameters) {
size_t const n = parameters.size();
if (n < 2) {
THROW_ARANGO_EXCEPTION_PARAMS(TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "UNION_DISTINCT");
}
@ -1135,11 +1137,10 @@ AqlValue Functions::UnionDistinct (triagens::aql::Query* query,
};
std::unique_ptr<TRI_json_t> result;
size_t const n = parameters.arraySize();
try {
for (size_t i = 0; i < n; ++i) {
Json value(parameters.extractArrayMember(trx, collection, i, false));
auto value = ExtractFunctionParameter(trx, parameters, i, false);
if (! value.isArray()) {
// not an array
@ -1206,11 +1207,10 @@ AqlValue Functions::UnionDistinct (triagens::aql::Query* query,
AqlValue Functions::Intersection (triagens::aql::Query* query,
triagens::arango::AqlTransaction* trx,
TRI_document_collection_t const* collection,
FunctionParameters parameters) {
size_t const n = parameters.arraySize();
FunctionParameters const& parameters) {
size_t const n = parameters.size();
if (parameters.arraySize() < 2) {
if (n < 2) {
THROW_ARANGO_EXCEPTION_PARAMS(TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "INTERSECTION");
}
@ -1231,7 +1231,7 @@ AqlValue Functions::Intersection (triagens::aql::Query* query,
try {
for (size_t i = 0; i < n; ++i) {
Json value(parameters.extractArrayMember(trx, collection, i, false));
auto value = ExtractFunctionParameter(trx, parameters, i, false);
if (! value.isArray()) {
// not an array

View File

@ -46,12 +46,11 @@ namespace triagens {
// --SECTION-- public typedefs
// -----------------------------------------------------------------------------
typedef AqlValue const FunctionParameters;
typedef std::vector<std::pair<AqlValue, TRI_document_collection_t const*>> FunctionParameters;
typedef std::function<AqlValue(triagens::aql::Query*,
triagens::arango::AqlTransaction*,
TRI_document_collection_t const*,
FunctionParameters)> FunctionImplementation;
FunctionParameters const&)> FunctionImplementation;
// -----------------------------------------------------------------------------
// --SECTION-- AQL function bindings
@ -59,31 +58,31 @@ namespace triagens {
struct Functions {
static AqlValue IsNull (triagens::aql::Query*, triagens::arango::AqlTransaction*, TRI_document_collection_t const*, FunctionParameters);
static AqlValue IsBool (triagens::aql::Query*, triagens::arango::AqlTransaction*, TRI_document_collection_t const*, FunctionParameters);
static AqlValue IsNumber (triagens::aql::Query*, triagens::arango::AqlTransaction*, TRI_document_collection_t const*, FunctionParameters);
static AqlValue IsString (triagens::aql::Query*, triagens::arango::AqlTransaction*, TRI_document_collection_t const*, FunctionParameters);
static AqlValue IsArray (triagens::aql::Query*, triagens::arango::AqlTransaction*, TRI_document_collection_t const*, FunctionParameters);
static AqlValue IsObject (triagens::aql::Query*, triagens::arango::AqlTransaction*, TRI_document_collection_t const*, FunctionParameters);
static AqlValue Length (triagens::aql::Query*, triagens::arango::AqlTransaction*, TRI_document_collection_t const*, FunctionParameters);
static AqlValue Concat (triagens::aql::Query*, triagens::arango::AqlTransaction*, TRI_document_collection_t const*, FunctionParameters);
static AqlValue Passthru (triagens::aql::Query*, triagens::arango::AqlTransaction*, TRI_document_collection_t const*, FunctionParameters);
static AqlValue Unset (triagens::aql::Query*, triagens::arango::AqlTransaction*, TRI_document_collection_t const*, FunctionParameters);
static AqlValue Keep (triagens::aql::Query*, triagens::arango::AqlTransaction*, TRI_document_collection_t const*, FunctionParameters);
static AqlValue Merge (triagens::aql::Query*, triagens::arango::AqlTransaction*, TRI_document_collection_t const*, FunctionParameters);
static AqlValue Has (triagens::aql::Query*, triagens::arango::AqlTransaction*, TRI_document_collection_t const*, FunctionParameters);
static AqlValue Attributes (triagens::aql::Query*, triagens::arango::AqlTransaction*, TRI_document_collection_t const*, FunctionParameters);
static AqlValue Values (triagens::aql::Query*, triagens::arango::AqlTransaction*, TRI_document_collection_t const*, FunctionParameters);
static AqlValue Min (triagens::aql::Query*, triagens::arango::AqlTransaction*, TRI_document_collection_t const*, FunctionParameters);
static AqlValue Max (triagens::aql::Query*, triagens::arango::AqlTransaction*, TRI_document_collection_t const*, FunctionParameters);
static AqlValue Sum (triagens::aql::Query*, triagens::arango::AqlTransaction*, TRI_document_collection_t const*, FunctionParameters);
static AqlValue Average (triagens::aql::Query*, triagens::arango::AqlTransaction*, TRI_document_collection_t const*, FunctionParameters);
static AqlValue Md5 (triagens::aql::Query*, triagens::arango::AqlTransaction*, TRI_document_collection_t const*, FunctionParameters);
static AqlValue Sha1 (triagens::aql::Query*, triagens::arango::AqlTransaction*, TRI_document_collection_t const*, FunctionParameters);
static AqlValue Unique (triagens::aql::Query*, triagens::arango::AqlTransaction*, TRI_document_collection_t const*, FunctionParameters);
static AqlValue Union (triagens::aql::Query*, triagens::arango::AqlTransaction*, TRI_document_collection_t const*, FunctionParameters);
static AqlValue UnionDistinct (triagens::aql::Query*, triagens::arango::AqlTransaction*, TRI_document_collection_t const*, FunctionParameters);
static AqlValue Intersection (triagens::aql::Query*, triagens::arango::AqlTransaction*, TRI_document_collection_t const*, FunctionParameters);
static AqlValue IsNull (triagens::aql::Query*, triagens::arango::AqlTransaction*, FunctionParameters const&);
static AqlValue IsBool (triagens::aql::Query*, triagens::arango::AqlTransaction*, FunctionParameters const&);
static AqlValue IsNumber (triagens::aql::Query*, triagens::arango::AqlTransaction*, FunctionParameters const&);
static AqlValue IsString (triagens::aql::Query*, triagens::arango::AqlTransaction*, FunctionParameters const&);
static AqlValue IsArray (triagens::aql::Query*, triagens::arango::AqlTransaction*, FunctionParameters const&);
static AqlValue IsObject (triagens::aql::Query*, triagens::arango::AqlTransaction*, FunctionParameters const&);
static AqlValue Length (triagens::aql::Query*, triagens::arango::AqlTransaction*, FunctionParameters const&);
static AqlValue Concat (triagens::aql::Query*, triagens::arango::AqlTransaction*, FunctionParameters const&);
static AqlValue Passthru (triagens::aql::Query*, triagens::arango::AqlTransaction*, FunctionParameters const&);
static AqlValue Unset (triagens::aql::Query*, triagens::arango::AqlTransaction*, FunctionParameters const&);
static AqlValue Keep (triagens::aql::Query*, triagens::arango::AqlTransaction*, FunctionParameters const&);
static AqlValue Merge (triagens::aql::Query*, triagens::arango::AqlTransaction*, FunctionParameters const&);
static AqlValue Has (triagens::aql::Query*, triagens::arango::AqlTransaction*, FunctionParameters const&);
static AqlValue Attributes (triagens::aql::Query*, triagens::arango::AqlTransaction*, FunctionParameters const&);
static AqlValue Values (triagens::aql::Query*, triagens::arango::AqlTransaction*, FunctionParameters const&);
static AqlValue Min (triagens::aql::Query*, triagens::arango::AqlTransaction*, FunctionParameters const&);
static AqlValue Max (triagens::aql::Query*, triagens::arango::AqlTransaction*, FunctionParameters const&);
static AqlValue Sum (triagens::aql::Query*, triagens::arango::AqlTransaction*, FunctionParameters const&);
static AqlValue Average (triagens::aql::Query*, triagens::arango::AqlTransaction*, FunctionParameters const&);
static AqlValue Md5 (triagens::aql::Query*, triagens::arango::AqlTransaction*, FunctionParameters const&);
static AqlValue Sha1 (triagens::aql::Query*, triagens::arango::AqlTransaction*, FunctionParameters const&);
static AqlValue Unique (triagens::aql::Query*, triagens::arango::AqlTransaction*, FunctionParameters const&);
static AqlValue Union (triagens::aql::Query*, triagens::arango::AqlTransaction*, FunctionParameters const&);
static AqlValue UnionDistinct (triagens::aql::Query*, triagens::arango::AqlTransaction*, FunctionParameters const&);
static AqlValue Intersection (triagens::aql::Query*, triagens::arango::AqlTransaction*, FunctionParameters const&);
};
}

View File

@ -667,7 +667,7 @@ QueryResult Query::execute (QueryRegistry* registry) {
auto val = value->getValueReference(i, resultRegister);
if (! val.isEmpty()) {
jsonResult.add(val.toJson(_trx, doc));
jsonResult.add(val.toJson(_trx, doc, true));
}
}
delete value;

View File

@ -1024,6 +1024,14 @@ namespace triagens {
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief return the JSON's memory zone
////////////////////////////////////////////////////////////////////////////////
TRI_memory_zone_t* zone () const {
return TRI_MemoryZone(_zone);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief checks whether *this is a Json that is equal to null.
////////////////////////////////////////////////////////////////////////////////