diff --git a/arangod/Aql/ExecutionBlock.cpp b/arangod/Aql/ExecutionBlock.cpp index 6b738264bb..14bd9139fc 100644 --- a/arangod/Aql/ExecutionBlock.cpp +++ b/arangod/Aql/ExecutionBlock.cpp @@ -118,7 +118,7 @@ size_t const ExecutionBlock::DefaultBatchSize = 1000; ExecutionBlock::ExecutionBlock (ExecutionEngine* engine, ExecutionNode const* ep) : _engine(engine), - _trx(engine->getTransaction()), + _trx(engine->getQuery()->trx()), _exeNode(ep), _done(false) { } @@ -3829,7 +3829,7 @@ std::cout << "SENDING REQUEST TO " << _server << ", URLPART: " << urlPart << ", _server, type, std::string("/_db/") - + triagens::basics::StringUtils::urlEncode(_engine->getTransaction()->vocbase()->_name) + + triagens::basics::StringUtils::urlEncode(_engine->getQuery()->trx()->vocbase()->_name) + urlPart + _queryId, body, headers, @@ -3865,7 +3865,7 @@ int RemoteBlock::initializeCursor (AqlItemBlock* items, size_t pos) { } else { body("pos", Json(static_cast(pos))) - ("items", items->toJson(_engine->getTransaction())); + ("items", items->toJson(_engine->getQuery()->trx())); } std::string bodyString(body.toString()); diff --git a/arangod/Aql/ExecutionEngine.cpp b/arangod/Aql/ExecutionEngine.cpp index 6133479037..a8d669e868 100644 --- a/arangod/Aql/ExecutionEngine.cpp +++ b/arangod/Aql/ExecutionEngine.cpp @@ -148,12 +148,10 @@ static ExecutionBlock* createBlock (ExecutionEngine* engine, /// @brief create the engine //////////////////////////////////////////////////////////////////////////////// -ExecutionEngine::ExecutionEngine (AQL_TRANSACTION_V8* trx, - Query* query) +ExecutionEngine::ExecutionEngine (Query* query) : _stats(), _blocks(), _root(nullptr), - _trx(trx), _query(query) { _blocks.reserve(8); @@ -270,7 +268,7 @@ struct CoordinatorInstanciator : public WalkerWorker { std::vector nodes; }; - AQL_TRANSACTION_V8* trx; + std::shared_ptr trx; Query* query; QueryRegistry* queryRegistry; ExecutionBlock* root; @@ -280,10 +278,9 @@ struct CoordinatorInstanciator : public WalkerWorker { std::vector engineIds; // stack of engine ids, used for subqueries - CoordinatorInstanciator (AQL_TRANSACTION_V8* trx, - Query* query, + CoordinatorInstanciator (Query* query, QueryRegistry* queryRegistry) - : trx(trx), + : trx(query->getTrxPtr()), query(query), queryRegistry(queryRegistry), root(nullptr), @@ -316,7 +313,6 @@ struct CoordinatorInstanciator : public WalkerWorker { if ((*it).id > 0) { Query *otherQuery = query->clone(PART_DEPENDENT); - otherQuery->trx(trx); otherQuery->engine(engine); auto *newPlan = new ExecutionPlan(otherQuery->ast()); @@ -550,7 +546,7 @@ std::cout << "REGISTERING QUERY ON COORDINATOR WITH ID: " << id << "\n"; ExecutionEngine* buildEngineCoordinator (EngineInfo& info, std::unordered_map const& queryIds) { - std::unique_ptr engine(new ExecutionEngine(trx, query)); + std::unique_ptr engine(new ExecutionEngine(query)); std::unordered_map cache; RemoteNode* remoteNode = nullptr; @@ -689,7 +685,6 @@ void ExecutionEngine::addBlock (ExecutionBlock* block) { //////////////////////////////////////////////////////////////////////////////// ExecutionEngine* ExecutionEngine::instanciateFromPlan (QueryRegistry* queryRegistry, - AQL_TRANSACTION_V8* trx, Query* query, ExecutionPlan* plan) { ExecutionEngine* engine = nullptr; @@ -704,8 +699,7 @@ ExecutionEngine* ExecutionEngine::instanciateFromPlan (QueryRegistry* queryRegis if (isCoordinator()) { // instanciate the engine on the coordinator - query->trx(trx); - std::unique_ptr inst(new CoordinatorInstanciator(trx, query, queryRegistry)); + std::unique_ptr inst(new CoordinatorInstanciator(query, queryRegistry)); plan->root()->walk(inst.get()); engine = inst.get()->buildEngines(); @@ -713,7 +707,7 @@ ExecutionEngine* ExecutionEngine::instanciateFromPlan (QueryRegistry* queryRegis } else { // instanciate the engine on a local server - engine = new ExecutionEngine(trx, query); + engine = new ExecutionEngine(query); std::unique_ptr inst(new Instanciator(engine)); plan->root()->walk(inst.get()); root = inst.get()->root; diff --git a/arangod/Aql/ExecutionEngine.h b/arangod/Aql/ExecutionEngine.h index 0082844207..ca726ac576 100644 --- a/arangod/Aql/ExecutionEngine.h +++ b/arangod/Aql/ExecutionEngine.h @@ -58,8 +58,7 @@ namespace triagens { /// @brief create the engine //////////////////////////////////////////////////////////////////////////////// - ExecutionEngine (AQL_TRANSACTION_V8* trx, - Query* query); + ExecutionEngine (Query* query); //////////////////////////////////////////////////////////////////////////////// /// @brief destroy the engine, frees all assigned blocks @@ -84,7 +83,6 @@ namespace triagens { //////////////////////////////////////////////////////////////////////////////// static ExecutionEngine* instanciateFromPlan (QueryRegistry*, - AQL_TRANSACTION_V8*, Query*, ExecutionPlan*); @@ -106,14 +104,6 @@ namespace triagens { _root = root; } -//////////////////////////////////////////////////////////////////////////////// -/// @brief get the transaction -//////////////////////////////////////////////////////////////////////////////// - - AQL_TRANSACTION_V8* getTransaction () const { - return _trx; - } - //////////////////////////////////////////////////////////////////////////////// /// @brief get the query //////////////////////////////////////////////////////////////////////////////// @@ -231,12 +221,6 @@ namespace triagens { ExecutionBlock* _root; -//////////////////////////////////////////////////////////////////////////////// -/// @brief a pointer to the transaction for this query -//////////////////////////////////////////////////////////////////////////////// - - AQL_TRANSACTION_V8* _trx; - //////////////////////////////////////////////////////////////////////////////// /// @brief a pointer to the query //////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Aql/ExecutionNode.cpp b/arangod/Aql/ExecutionNode.cpp index 752821e788..387f6d86d4 100644 --- a/arangod/Aql/ExecutionNode.cpp +++ b/arangod/Aql/ExecutionNode.cpp @@ -517,12 +517,14 @@ triagens::basics::Json ExecutionNode::toJsonHelperGeneric (triagens::basics::Jso json("regsToClear", jsonRegsToClearList); } else { - Json emptyList(Json::List); - json("varInfoList", emptyList); + Json emptyList1(Json::List); + json("varInfoList", emptyList1); - json("nrRegs", emptyList); + Json emptyList2(Json::List); + json("nrRegs", emptyList2); - json("regsToClear", emptyList); + Json emptyList3(Json::List); + json("regsToClear", emptyList3); } return json; } diff --git a/arangod/Aql/Query.cpp b/arangod/Aql/Query.cpp index 542ec1d9c7..70e81ad76e 100644 --- a/arangod/Aql/Query.cpp +++ b/arangod/Aql/Query.cpp @@ -244,6 +244,7 @@ Query* Query::clone (QueryPart part) { theClone->_plan = _plan->clone(*theClone); } + theClone->_trx = _trx; return theClone; } @@ -361,15 +362,18 @@ QueryResult Query::prepare (QueryRegistry* registry) { // std::cout << "AST: " << triagens::basics::JsonHelper::toString(parser->ast()->toJson(TRI_UNKNOWN_MEM_ZONE, false)) << "\n"; } + std::shared_ptr trx(new AQL_TRANSACTION_V8(_vocbase, _collections.collections())); + _trx = trx; + // create the transaction object, but do not start it yet - std::unique_ptr trx(new AQL_TRANSACTION_V8(_vocbase, _collections.collections())); + // _trx = new std::shared_ptr(_vocbase, _collections.collections()); if (_queryString != nullptr) { // we have an AST - int res = trx->begin(); + int res = _trx->begin(); if (res != TRI_ERROR_NO_ERROR) { - return transactionError(res, *trx); + return transactionError(res); } enterState(PLAN_INSTANCIATION); @@ -385,14 +389,14 @@ QueryResult Query::prepare (QueryRegistry* registry) { // creating the plan may have produced some collections // we need to add them to the transaction now (otherwise the query will fail) - int res = trx->addCollectionList(_collections.collections()); + int res = _trx->addCollectionList(_collections.collections()); if (res == TRI_ERROR_NO_ERROR) { - res = trx->begin(); + res = _trx->begin(); } if (res != TRI_ERROR_NO_ERROR) { - return transactionError(res, *trx); + return transactionError(res); } // we have an execution plan in JSON format @@ -426,13 +430,12 @@ QueryResult Query::prepare (QueryRegistry* registry) { TRI_ASSERT(otherJsonString == JsonString); */ enterState(EXECUTION); - ExecutionEngine* engine(ExecutionEngine::instanciateFromPlan(registry, trx.get(), this, plan.get())); + ExecutionEngine* engine(ExecutionEngine::instanciateFromPlan(registry, this, plan.get())); // If all went well so far, then we keep _plan, _parser and _trx and // return: _plan = plan.release(); _parser = parser.release(); - _trx = trx.release(); _engine = engine; return QueryResult(); } @@ -481,7 +484,7 @@ QueryResult Query::execute (QueryRegistry* registry) { AqlValue val = value->getValue(i, 0); if (! val.isEmpty()) { - json.add(val.toJson(_trx, doc)); + json.add(val.toJson(trx(), doc)); } } delete value; @@ -590,13 +593,14 @@ QueryResult Query::explain () { // std::cout << "AST: " << triagens::basics::JsonHelper::toString(parser.ast()->toJson(TRI_UNKNOWN_MEM_ZONE)) << "\n"; // create the transaction object, but do not start it yet - AQL_TRANSACTION_V8 trx(_vocbase, _collections.collections()); + std::shared_ptr trx(new AQL_TRANSACTION_V8(_vocbase, _collections.collections())); + _trx = trx; // we have an AST - int res = trx.begin(); + int res = _trx->begin(); if (res != TRI_ERROR_NO_ERROR) { - return transactionError(res, trx); + return transactionError(res); } enterState(PLAN_INSTANCIATION); @@ -612,7 +616,7 @@ QueryResult Query::explain () { // get enabled/disabled rules opt.createPlans(plan, getRulesFromOptions()); - trx.commit(); + _trx->commit(); enterState(FINALIZATION); @@ -765,11 +769,10 @@ double Query::getNumericOption (char const* option, double defaultValue) const { /// @brief neatly format transaction error to the user. //////////////////////////////////////////////////////////////////////////////// -QueryResult Query::transactionError (int errorCode, - AQL_TRANSACTION_V8 const& trx) const { +QueryResult Query::transactionError (int errorCode) const { std::string err(TRI_errno_string(errorCode)); - auto detail = trx.getErrorData(); + auto detail = _trx->getErrorData(); if (detail.size() > 0) { err += std::string(" (") + detail + std::string(")"); } @@ -848,12 +851,7 @@ void Query::cleanupPlanAndEngine () { _engine = nullptr; } - if (_trx != nullptr) { - if (_part == PART_MAIN) { - delete _trx; - _trx = nullptr; - } - } + _trx.reset(); if (_parser != nullptr) { delete _parser; diff --git a/arangod/Aql/Query.h b/arangod/Aql/Query.h index 0680f5d3fc..099367f9be 100644 --- a/arangod/Aql/Query.h +++ b/arangod/Aql/Query.h @@ -59,7 +59,7 @@ namespace triagens { // ----------------------------------------------------------------------------- //////////////////////////////////////////////////////////////////////////////// -/// @brief query part +/// @brief equery part //////////////////////////////////////////////////////////////////////////////// enum QueryPart { @@ -337,18 +337,21 @@ namespace triagens { //////////////////////////////////////////////////////////////////////////////// AQL_TRANSACTION_V8* trx () { - return _trx; + return &*_trx; } //////////////////////////////////////////////////////////////////////////////// /// @brief set the transaction for the query //////////////////////////////////////////////////////////////////////////////// - void trx (AQL_TRANSACTION_V8* trx) { + void setTrxPtr (std::shared_ptr& trx) { TRI_ASSERT(_trx == nullptr); _trx = trx; } + std::shared_ptr& getTrxPtr () { + return _trx; + } //////////////////////////////////////////////////////////////////////////////// /// @brief set the plan for the query //////////////////////////////////////////////////////////////////////////////// @@ -383,7 +386,7 @@ namespace triagens { /// @brief neatly format transaction errors to the user. //////////////////////////////////////////////////////////////////////////////// - QueryResult transactionError (int errorCode, AQL_TRANSACTION_V8 const& trx) const; + QueryResult transactionError (int errorCode) const; //////////////////////////////////////////////////////////////////////////////// /// @brief enter a new state @@ -518,7 +521,7 @@ namespace triagens { /// to the HTTP API for queries. //////////////////////////////////////////////////////////////////////////////// - AQL_TRANSACTION_V8* _trx; + std::shared_ptr _trx; //////////////////////////////////////////////////////////////////////////////// /// @brief the ExecutionEngine object, if the query is prepared