diff --git a/arangod/Aql/Functions.cpp b/arangod/Aql/Functions.cpp index 503a0b9268..0a1c84df91 100644 --- a/arangod/Aql/Functions.cpp +++ b/arangod/Aql/Functions.cpp @@ -548,7 +548,7 @@ static void RequestEdges(VPackSlice const& vertexSlice, THROW_ARANGO_EXCEPTION(vertexResult.code); } } else { - result.add("vertex", vertexResult.slice()); + result.add("vertex", vertexResult.slice().resolveExternal()); } } } @@ -596,51 +596,28 @@ static void RegisterCollectionInTransaction( /// @brief Helper function to get a document by it's identifier /// Lazy Locks the collection if necessary. static void GetDocumentByIdentifier(arangodb::AqlTransaction* trx, - std::string const& collectionName, + std::string& collectionName, std::string const& identifier, bool ignoreError, VPackBuilder& result) { OperationOptions options; OperationResult opRes; - VPackBuilder searchBuilder; - searchBuilder.openObject(); - searchBuilder.add(VPackValue(TRI_VOC_ATTRIBUTE_KEY)); + TransactionBuilderLeaser searchBuilder(trx); + + searchBuilder->openObject(); + searchBuilder->add(VPackValue(TRI_VOC_ATTRIBUTE_KEY)); std::vector parts = arangodb::basics::StringUtils::split(identifier, "/"); - if (parts.size() == 1) { - searchBuilder.add(VPackValue(identifier)); - searchBuilder.close(); - - try { - TRI_voc_cid_t cid; - RegisterCollectionInTransaction(trx, collectionName, cid); - } catch (arangodb::basics::Exception const&) { - if (ignoreError) { - return; - } - throw; - } - - opRes = trx->document(collectionName, searchBuilder.slice(), options); + searchBuilder->add(VPackValue(identifier)); + searchBuilder->close(); } else if (parts.size() == 2) { if (collectionName.empty()) { - searchBuilder.add(VPackValue(parts[1])); - searchBuilder.close(); - - try { - TRI_voc_cid_t cid; - RegisterCollectionInTransaction(trx, parts[0], cid); - } catch (arangodb::basics::Exception const&) { - if (ignoreError) { - return; - } - throw; - } - - opRes = trx->document(parts[0], searchBuilder.slice(), options); + searchBuilder->add(VPackValue(parts[1])); + searchBuilder->close(); + collectionName = parts[0]; } else if (parts[0] != collectionName) { // Reqesting an _id that cannot be stored in this collection if (ignoreError) { @@ -648,20 +625,8 @@ static void GetDocumentByIdentifier(arangodb::AqlTransaction* trx, } THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_CROSS_COLLECTION_REQUEST); } else { - searchBuilder.add(VPackValue(parts[1])); - searchBuilder.close(); - - try { - TRI_voc_cid_t cid; - RegisterCollectionInTransaction(trx, collectionName, cid); - } catch (arangodb::basics::Exception const&) { - if (ignoreError) { - return; - } - throw; - } - - opRes = trx->document(collectionName, searchBuilder.slice(), options); + searchBuilder->add(VPackValue(parts[1])); + searchBuilder->close(); } } else { if (ignoreError) { @@ -669,6 +634,16 @@ static void GetDocumentByIdentifier(arangodb::AqlTransaction* trx, } THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_DOCUMENT_HANDLE_BAD); } + + try { + opRes = trx->document(collectionName, searchBuilder->slice(), options); + } catch (arangodb::basics::Exception const&) { + if (ignoreError) { + return; + } + throw; + } + if (opRes.failed()) { if (ignoreError) { return; @@ -766,7 +741,8 @@ static AqlValue VertexIdsToAqlValueVPack(arangodb::aql::Query* query, if (includeData) { for (auto& it : ids) { // THROWS ERRORS if the Document was not found - GetDocumentByIdentifier(trx, "", it, false, *builder.get()); + std::string colName; + GetDocumentByIdentifier(trx, colName, it, false, *builder.get()); } } else { for (auto& it : ids) { @@ -2436,7 +2412,8 @@ AqlValue Functions::Document(arangodb::aql::Query* query, TransactionBuilderLeaser builder(trx); if (id.isString()) { std::string identifier(id.slice().copyString()); - GetDocumentByIdentifier(trx, "", identifier, true, *builder.get()); + std::string colName; + GetDocumentByIdentifier(trx, colName, identifier, true, *builder.get()); if (builder->isEmpty()) { // not found return AqlValue(arangodb::basics::VelocyPackHelper::NullValue()); @@ -2450,7 +2427,8 @@ AqlValue Functions::Document(arangodb::aql::Query* query, for (auto const& next : VPackArrayIterator(idSlice)) { if (next.isString()) { std::string identifier = next.copyString(); - GetDocumentByIdentifier(trx, "", identifier, true, *builder.get()); + std::string colName; + GetDocumentByIdentifier(trx, colName, identifier, true, *builder.get()); } } builder->close(); @@ -2463,7 +2441,7 @@ AqlValue Functions::Document(arangodb::aql::Query* query, if (!collectionValue.isString()) { THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL); } - std::string const collectionName(collectionValue.slice().copyString()); + std::string collectionName(collectionValue.slice().copyString()); bool notFound = false; // TODO: what does this do? diff --git a/arangod/Aql/Graphs.cpp b/arangod/Aql/Graphs.cpp index 7702f38784..6881d353f5 100644 --- a/arangod/Aql/Graphs.cpp +++ b/arangod/Aql/Graphs.cpp @@ -101,7 +101,8 @@ void Graph::toVelocyPack(VPackBuilder& builder, bool verbose) const { } } -Graph::Graph(VPackSlice const& slice) : _vertexColls(), _edgeColls() { +Graph::Graph(VPackSlice const& info) : _vertexColls(), _edgeColls() { + VPackSlice const slice = info.resolveExternal(); if (slice.hasKey(_attrEdgeDefs)) { auto edgeDefs = slice.get(_attrEdgeDefs); diff --git a/arangod/RestHandler/RestVocbaseBaseHandler.cpp b/arangod/RestHandler/RestVocbaseBaseHandler.cpp index 05ab3769c0..73a90d8643 100644 --- a/arangod/RestHandler/RestVocbaseBaseHandler.cpp +++ b/arangod/RestHandler/RestVocbaseBaseHandler.cpp @@ -344,9 +344,10 @@ void RestVocbaseBaseHandler::generateNotModified(TRI_voc_rid_t rid) { /// @brief generates next entry from a result set //////////////////////////////////////////////////////////////////////////////// -void RestVocbaseBaseHandler::generateDocument(VPackSlice const& document, +void RestVocbaseBaseHandler::generateDocument(VPackSlice const& input, bool generateBody, VPackOptions const* options) { + VPackSlice document = input.resolveExternal(); std::string rev; if (document.isObject()) { rev = VelocyPackHelper::getStringValue(document, Transaction::RevString, ""); diff --git a/arangod/Utils/Transaction.cpp b/arangod/Utils/Transaction.cpp index 1b9bff60c0..19ea18892c 100644 --- a/arangod/Utils/Transaction.cpp +++ b/arangod/Utils/Transaction.cpp @@ -708,14 +708,14 @@ void Transaction::buildDocumentIdentity(TRI_document_collection_t* document, builder.add("_oldRev", oldRid); } if (oldMptr != nullptr) { - builder.add("old", VPackSlice(oldMptr->vpack())); + // builder.add("old", VPackSlice(oldMptr->vpack())); // TODO: add externals later. - //builder.add("old", VPackValue(VPackValueType::External, oldMptr->vpack())); + builder.add("old", VPackValue(oldMptr->vpack(), VPackValueType::External)); } if (newMptr != nullptr) { - builder.add("new", VPackSlice(newMptr->vpack())); + // builder.add("new", VPackSlice(newMptr->vpack())); // TODO: add externals later. - //builder.add("new", VPackValue(VPackValueType::External, newMptr->vpack())); + builder.add("new", VPackValue(newMptr->vpack(), VPackValueType::External)); } builder.close(); } @@ -1110,9 +1110,7 @@ OperationResult Transaction::documentLocal(std::string const& collectionName, } if (!options.silent) { - //resultBuilder.add(VPackValue(static_cast(mptr.vpack()), VPackValueType::External)); - // This is the future, for now, we have to do this: - resultBuilder.add(VPackSlice(mptr.vpack())); + resultBuilder.add(VPackValue(static_cast(mptr.vpack()), VPackValueType::External)); } else if (isMultiple) { resultBuilder.add(VPackSlice::nullSlice()); } diff --git a/arangod/VocBase/ExampleMatcher.cpp b/arangod/VocBase/ExampleMatcher.cpp index f6572fc91a..b39836b7ae 100644 --- a/arangod/VocBase/ExampleMatcher.cpp +++ b/arangod/VocBase/ExampleMatcher.cpp @@ -1,4 +1,4 @@ -//////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// /// DISCLAIMER /// /// Copyright 2014-2016 ArangoDB GmbH, Cologne, Germany @@ -183,7 +183,8 @@ ExampleMatcher::ExampleMatcher(VPackSlice const& example, /// @brief Checks if the given velocyPack matches the examples in this class //////////////////////////////////////////////////////////////////////////////// -bool ExampleMatcher::matches(VPackSlice const toMatch) const { +bool ExampleMatcher::matches(VPackSlice const test) const { + VPackSlice toMatch = test.resolveExternal(); for (auto const& def : definitions) { VPackSlice const compareValue = def.slice(); size_t i = 0; diff --git a/arangod/VocBase/Traverser.cpp b/arangod/VocBase/Traverser.cpp index 5c965f79ef..ecae00231d 100644 --- a/arangod/VocBase/Traverser.cpp +++ b/arangod/VocBase/Traverser.cpp @@ -238,7 +238,7 @@ bool TraverserExpression::matchesCheck(arangodb::Transaction* trx, VPackSlice const& element) const { TRI_ASSERT(trx != nullptr); - VPackSlice value = element; + VPackSlice value = element.resolveExternal(); // initialize compare value to Null VPackSlice result = arangodb::basics::VelocyPackHelper::NullValue(); diff --git a/arangod/VocBase/vocbase.cpp b/arangod/VocBase/vocbase.cpp index b6f963449a..739722f862 100644 --- a/arangod/VocBase/vocbase.cpp +++ b/arangod/VocBase/vocbase.cpp @@ -2319,7 +2319,8 @@ void TRI_FillVPackSub(TRI_vpack_sub_t* sub, /// @brief extract the _rev attribute from a slice //////////////////////////////////////////////////////////////////////////////// -TRI_voc_rid_t TRI_ExtractRevisionId(VPackSlice const slice) { +TRI_voc_rid_t TRI_ExtractRevisionId(VPackSlice slice) { + slice = slice.resolveExternal(); TRI_ASSERT(slice.isObject()); VPackSlice r(slice.get(TRI_VOC_ATTRIBUTE_REV));