diff --git a/arangod/Aql/AqlItemBlock.cpp b/arangod/Aql/AqlItemBlock.cpp index 8eabed896b..91fc1a7474 100644 --- a/arangod/Aql/AqlItemBlock.cpp +++ b/arangod/Aql/AqlItemBlock.cpp @@ -110,7 +110,21 @@ void AqlItemBlock::shrink (size_t nrItems) { // erase all stored values in the region that we freed for (size_t i = nrItems; i < _nrItems; ++i) { for (RegisterId j = 0; j < _nrRegs; ++j) { - eraseValue(i, j); + AqlValue& a(_data[_nrRegs * i + j]); + if (! a.isEmpty()) { + auto it = _valueCount.find(a); + if (it != _valueCount.end()) { + if (--it->second == 0) { + a.destroy(); + try { + _valueCount.erase(it); + } + catch (...) { + } + } + } + a.erase(); + } } } @@ -131,13 +145,11 @@ void AqlItemBlock::clearRegisters (std::unordered_set& toClear) { auto it = _valueCount.find(a); if (it != _valueCount.end()) { if (--it->second == 0) { + a.destroy(); try { _valueCount.erase(it); - a.destroy(); } catch (...) { - it->second++; - throw; } } } diff --git a/arangod/Aql/AqlItemBlock.h b/arangod/Aql/AqlItemBlock.h index 62b0071795..136e531c6a 100644 --- a/arangod/Aql/AqlItemBlock.h +++ b/arangod/Aql/AqlItemBlock.h @@ -130,8 +130,6 @@ namespace triagens { _valueCount.erase(it); } catch (...) { - it->second++; - throw; } } } diff --git a/arangod/Aql/Expression.cpp b/arangod/Aql/Expression.cpp index 9fb0dbd1bc..e38992d774 100644 --- a/arangod/Aql/Expression.cpp +++ b/arangod/Aql/Expression.cpp @@ -184,7 +184,8 @@ void Expression::analyzeExpression () { } //////////////////////////////////////////////////////////////////////////////// -/// @brief execute an expression of type SIMPLE +/// @brief execute an expression of type SIMPLE, the convention is that +/// the resulting AqlValue will be destroyed outside eventually //////////////////////////////////////////////////////////////////////////////// AqlValue Expression::executeSimpleExpression (AstNode const* node, @@ -207,6 +208,7 @@ AqlValue Expression::executeSimpleExpression (AstNode const* node, AqlValue result = executeSimpleExpression(member, &myCollection, trx, docColls, argv, startPos, vars, regs); auto j = result.extractArrayMember(trx, myCollection, name); + result.destroy(); return AqlValue(new Json(TRI_UNKNOWN_MEM_ZONE, j.steal())); } @@ -228,6 +230,7 @@ AqlValue Expression::executeSimpleExpression (AstNode const* node, if (result.isList()) { if (index->isNumericValue()) { auto j = result.extractListMember(trx, myCollection, index->getIntValue()); + result.destroy(); return AqlValue(new Json(TRI_UNKNOWN_MEM_ZONE, j.steal())); } else if (index->isStringValue()) { @@ -238,6 +241,7 @@ AqlValue Expression::executeSimpleExpression (AstNode const* node, // stoll() might throw an exception if the string is not a number int64_t position = static_cast(std::stoll(p)); auto j = result.extractListMember(trx, myCollection, position); + result.destroy(); return AqlValue(new Json(TRI_UNKNOWN_MEM_ZONE, j.steal())); } catch (...) { @@ -250,6 +254,7 @@ AqlValue Expression::executeSimpleExpression (AstNode const* node, if (index->isNumericValue()) { std::string const indexString = std::to_string(index->getIntValue()); auto j = result.extractArrayMember(trx, myCollection, indexString.c_str()); + result.destroy(); return AqlValue(new Json(TRI_UNKNOWN_MEM_ZONE, j.steal())); } else if (index->isStringValue()) { @@ -257,10 +262,12 @@ AqlValue Expression::executeSimpleExpression (AstNode const* node, TRI_ASSERT(p != nullptr); auto j = result.extractArrayMember(trx, myCollection, p); + result.destroy(); return AqlValue(new Json(TRI_UNKNOWN_MEM_ZONE, j.steal())); } // fall-through to returning null } + result.destroy(); return AqlValue(new Json(Json::Null)); } @@ -276,6 +283,7 @@ AqlValue Expression::executeSimpleExpression (AstNode const* node, AqlValue result = executeSimpleExpression(member, &myCollection, trx, docColls, argv, startPos, vars, regs); list->add(result.toJson(trx, myCollection)); + result.destroy(); } return AqlValue(list); } @@ -300,6 +308,7 @@ AqlValue Expression::executeSimpleExpression (AstNode const* node, AqlValue result = executeSimpleExpression(member, &myCollection, trx, docColls, argv, startPos, vars, regs); resultArray->set(key, result.toJson(trx, myCollection)); + result.destroy(); } return AqlValue(resultArray); } @@ -344,7 +353,9 @@ AqlValue Expression::executeSimpleExpression (AstNode const* node, auto member = node->getMember(0); AqlValue result = executeSimpleExpression(member, &myCollection, trx, docColls, argv, startPos, vars, regs); - return func->implementation(trx, myCollection, result); + auto res2 = func->implementation(trx, myCollection, result); + result.destroy(); + return res2; } THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "unhandled type in simple expression");