diff --git a/arangod/Aql/AqlValue.cpp b/arangod/Aql/AqlValue.cpp index 50023f21ab..7f773de6cb 100644 --- a/arangod/Aql/AqlValue.cpp +++ b/arangod/Aql/AqlValue.cpp @@ -165,7 +165,7 @@ AqlValue AqlValue::at(int64_t position, bool& mustDestroy, } if (position >= 0 && position < n) { if (doCopy) { - mustDestroy = true; + mustDestroy = (type() == VPACK_MANAGED); return AqlValue(s.at(position)); } // return a reference to an existing slice @@ -237,7 +237,7 @@ AqlValue AqlValue::getKeyAttribute(arangodb::AqlTransaction* trx, VPackSlice found = Transaction::extractKeyFromDocument(s); if (!found.isNone()) { if (doCopy) { - mustDestroy = true; + mustDestroy = (type() == VPACK_MANAGED); return AqlValue(found); } // return a reference to an existing slice @@ -278,7 +278,7 @@ AqlValue AqlValue::getIdAttribute(arangodb::AqlTransaction* trx, } if (!found.isNone()) { if (doCopy) { - mustDestroy = true; + mustDestroy = (type() == VPACK_MANAGED); return AqlValue(found); } // return a reference to an existing slice @@ -314,7 +314,7 @@ AqlValue AqlValue::getFromAttribute(arangodb::AqlTransaction* trx, VPackSlice found = Transaction::extractFromFromDocument(s); if (!found.isNone()) { if (doCopy) { - mustDestroy = true; + mustDestroy = (type() == VPACK_MANAGED); return AqlValue(found); } // return a reference to an existing slice @@ -350,7 +350,7 @@ AqlValue AqlValue::getToAttribute(arangodb::AqlTransaction* trx, VPackSlice found = Transaction::extractToFromDocument(s); if (!found.isNone()) { if (doCopy) { - mustDestroy = true; + mustDestroy = (type() == VPACK_MANAGED); return AqlValue(found); } // return a reference to an existing slice @@ -392,7 +392,7 @@ AqlValue AqlValue::get(arangodb::AqlTransaction* trx, } if (!found.isNone()) { if (doCopy) { - mustDestroy = true; + mustDestroy = (type() == VPACK_MANAGED); return AqlValue(found); } // return a reference to an existing slice @@ -434,7 +434,7 @@ AqlValue AqlValue::get(arangodb::AqlTransaction* trx, } if (!found.isNone()) { if (doCopy) { - mustDestroy = true; + mustDestroy = (type() == VPACK_MANAGED); return AqlValue(found); } // return a reference to an existing slice diff --git a/arangod/Aql/AttributeAccessor.cpp b/arangod/Aql/AttributeAccessor.cpp index 12085489e4..93832e2ef3 100644 --- a/arangod/Aql/AttributeAccessor.cpp +++ b/arangod/Aql/AttributeAccessor.cpp @@ -32,12 +32,13 @@ using namespace arangodb::aql; /// @brief create the accessor AttributeAccessor::AttributeAccessor( - std::vector const& attributeParts, Variable const* variable) + std::vector&& attributeParts, Variable const* variable) : _attributeParts(attributeParts), _variable(variable), _type(EXTRACT_MULTI) { TRI_ASSERT(_variable != nullptr); + TRI_ASSERT(!_attributeParts.empty()); // determine accessor type if (_attributeParts.size() == 1) { diff --git a/arangod/Aql/AttributeAccessor.h b/arangod/Aql/AttributeAccessor.h index ff9c10367d..42bbbc9c90 100644 --- a/arangod/Aql/AttributeAccessor.h +++ b/arangod/Aql/AttributeAccessor.h @@ -38,7 +38,7 @@ struct Variable; /// @brief AttributeAccessor class AttributeAccessor { public: - AttributeAccessor(std::vector const&, Variable const*); + AttributeAccessor(std::vector&&, Variable const*); ~AttributeAccessor() = default; /// @brief execute the accessor diff --git a/arangod/Aql/BasicBlocks.cpp b/arangod/Aql/BasicBlocks.cpp index 20af995808..017ec3c4b9 100644 --- a/arangod/Aql/BasicBlocks.cpp +++ b/arangod/Aql/BasicBlocks.cpp @@ -173,6 +173,8 @@ bool FilterBlock::getBlock(size_t atLeast, size_t atMost) { _buffer.pop_front(); // Block was useless, just try again delete cur; // free this block + + throwIfKilled(); // check if we were aborted } return true; diff --git a/arangod/Aql/ExecutionNode.cpp b/arangod/Aql/ExecutionNode.cpp index 23a36997b2..d1b962e7cd 100644 --- a/arangod/Aql/ExecutionNode.cpp +++ b/arangod/Aql/ExecutionNode.cpp @@ -34,7 +34,6 @@ #include "Aql/SortNode.h" #include "Aql/TraversalNode.h" #include "Aql/WalkerWorker.h" -#include "Basics/StringBuffer.h" using namespace arangodb::basics; using namespace arangodb::aql; diff --git a/arangod/Aql/Expression.cpp b/arangod/Aql/Expression.cpp index 640163d27a..912998a40d 100644 --- a/arangod/Aql/Expression.cpp +++ b/arangod/Aql/Expression.cpp @@ -346,7 +346,7 @@ void Expression::analyzeExpression() { auto v = static_cast(member->getData()); // specialize the simple expression into an attribute accessor - _accessor = new AttributeAccessor(parts, v); + _accessor = new AttributeAccessor(std::move(parts), v); _type = ATTRIBUTE; _built = true; } @@ -769,7 +769,6 @@ AqlValue Expression::executeSimpleExpressionFCall( auto member = node->getMemberUnchecked(0); TRI_ASSERT(member->type == NODE_TYPE_ARRAY); - VPackBuilder builder; size_t const n = member->numMembers(); VPackFunctionParameters parameters; @@ -782,9 +781,7 @@ AqlValue Expression::executeSimpleExpressionFCall( auto arg = member->getMemberUnchecked(i); if (arg->type == NODE_TYPE_COLLECTION) { - builder.clear(); - builder.add(VPackValue(arg->getString())); - parameters.emplace_back(AqlValue(builder)); + parameters.emplace_back(AqlValue(arg->getString())); destroyParameters.push_back(true); } else { bool localMustDestroy; @@ -1356,8 +1353,8 @@ AqlValue Expression::executeSimpleExpressionArithmetic( return AqlValue(VelocyPackHelper::ZeroValue()); } - VPackBuilder builder; + TransactionBuilderLeaser builder(trx); mustDestroy = true; // builder = dynamic data - builder.add(VPackValue(result)); - return AqlValue(builder); + builder->add(VPackValue(result)); + return AqlValue(*builder.get()); } diff --git a/arangod/Aql/IndexBlock.cpp b/arangod/Aql/IndexBlock.cpp index e4ff362716..93fbc541e7 100644 --- a/arangod/Aql/IndexBlock.cpp +++ b/arangod/Aql/IndexBlock.cpp @@ -533,8 +533,14 @@ AqlItemBlock* IndexBlock::getSome(size_t atLeast, size_t atMost) { // we do not need to do a lookup in // getPlanNode()->_registerPlan->varInfo, // but can just take cur->getNrRegs() as registerId: - res->setValue(j, static_cast(curRegs), - AqlValue(_documents[_posInDocs++])); + auto doc = _documents[_posInDocs++]; + if (doc.isExternal()) { + res->setValue(j, static_cast(curRegs), + AqlValue(doc.resolveExternal().begin())); + } else { + res->setValue(j, static_cast(curRegs), + AqlValue(doc)); + } // No harm done, if the setValue throws! } } diff --git a/arangod/Aql/OptimizerRules.cpp b/arangod/Aql/OptimizerRules.cpp index 097d3a7bc3..eb90033920 100644 --- a/arangod/Aql/OptimizerRules.cpp +++ b/arangod/Aql/OptimizerRules.cpp @@ -231,8 +231,7 @@ void arangodb::aql::removeRedundantSortsRule(Optimizer* opt, } std::unordered_set toUnlink; - - arangodb::basics::StringBuffer buffer(TRI_UNKNOWN_MEM_ZONE); + arangodb::basics::StringBuffer buffer(TRI_UNKNOWN_MEM_ZONE, false); for (auto const& n : nodes) { if (toUnlink.find(n) != toUnlink.end()) { @@ -1367,7 +1366,7 @@ void arangodb::aql::removeRedundantCalculationsRule( return; } - arangodb::basics::StringBuffer buffer(TRI_UNKNOWN_MEM_ZONE); + arangodb::basics::StringBuffer buffer(TRI_UNKNOWN_MEM_ZONE, false); std::unordered_map replacements; for (auto const& n : nodes) {