diff --git a/src/dsql/dsql.cpp b/src/dsql/dsql.cpp index 1bfda5440f..805fb6ab20 100644 --- a/src/dsql/dsql.cpp +++ b/src/dsql/dsql.cpp @@ -586,7 +586,7 @@ void DSQL_execute_immediate(thread_db* tdbb, Jrd::Attachment* attachment, jrd_tr } -void DsqlDmlRequest::dsqlPass(thread_db* tdbb, DsqlCompilerScratch* scratch, +void DsqlDmlRequest::dsqlPass(thread_db* tdbb, DsqlCompilerScratch* scratch, bool* destroyScratchPool, ntrace_result_t* traceResult) { { // scope @@ -671,9 +671,9 @@ void DsqlDmlRequest::dsqlPass(thread_db* tdbb, DsqlCompilerScratch* scratch, if (status) status_exception::raise(tdbb->tdbb_status_vector); - // Delete the scratch pool to reclaim memory. + // We don't need the scratch pool anymore. Tell our caller to delete it. node = NULL; - req_dbb->deletePool(&scratch->getPool()); + *destroyScratchPool = true; } // Execute a dynamic SQL statement. @@ -829,7 +829,7 @@ void DsqlDmlRequest::execute(thread_db* tdbb, jrd_tra** traHandle, trace.finish(have_cursor, ITracePlugin::RESULT_SUCCESS); } -void DsqlDdlRequest::dsqlPass(thread_db* tdbb, DsqlCompilerScratch* scratch, +void DsqlDdlRequest::dsqlPass(thread_db* tdbb, DsqlCompilerScratch* scratch, bool* destroyScratchPool, ntrace_result_t* traceResult) { internalScratch = scratch; @@ -914,7 +914,7 @@ void DsqlDdlRequest::rethrowDdlException(status_exception& ex, bool metadataUpda } -void DsqlTransactionRequest::dsqlPass(thread_db* tdbb, DsqlCompilerScratch* scratch, +void DsqlTransactionRequest::dsqlPass(thread_db* tdbb, DsqlCompilerScratch* scratch, bool* destroyScratchPool, ntrace_result_t* /*traceResult*/) { node = Node::doDsqlPass(scratch, node); @@ -933,7 +933,7 @@ void DsqlTransactionRequest::execute(thread_db* tdbb, jrd_tra** traHandle, } -void DsqlSessionManagementRequest::dsqlPass(thread_db* tdbb, DsqlCompilerScratch* scratch, +void DsqlSessionManagementRequest::dsqlPass(thread_db* tdbb, DsqlCompilerScratch* scratch, bool* destroyScratchPool, ntrace_result_t* /*traceResult*/) { node = Node::doDsqlPass(scratch, node); @@ -1400,24 +1400,24 @@ static dsql_req* prepareStatement(thread_db* tdbb, dsql_dbb* database, jrd_tra* // allocate the statement block, then prepare the statement - Jrd::ContextPoolHolder statementContext(tdbb, database->createPool()); - MemoryPool& statementPool = *tdbb->getDefaultPool(); - - DsqlCompiledStatement* statement = FB_NEW_POOL(statementPool) DsqlCompiledStatement(statementPool); - - MemoryPool* scratchPool = database->createPool(&statementPool); - - DsqlCompilerScratch* scratch = FB_NEW_POOL(*scratchPool) DsqlCompilerScratch(*scratchPool, database, - transaction, statement); - scratch->clientDialect = clientDialect; - - if (isInternalRequest) - scratch->flags |= DsqlCompilerScratch::FLAG_INTERNAL_REQUEST; - + MemoryPool* statementPool = database->createPool(); + MemoryPool* scratchPool = NULL; dsql_req* request = NULL; + Jrd::ContextPoolHolder statementContext(tdbb, statementPool); try { + DsqlCompiledStatement* statement = FB_NEW_POOL(*statementPool) DsqlCompiledStatement(*statementPool); + + scratchPool = database->createPool(); + + DsqlCompilerScratch* scratch = FB_NEW_POOL(*scratchPool) DsqlCompilerScratch(*scratchPool, database, + transaction, statement); + scratch->clientDialect = clientDialect; + + if (isInternalRequest) + scratch->flags |= DsqlCompilerScratch::FLAG_INTERNAL_REQUEST; + string transformedText; { // scope to delete parser before the scratch pool is gone @@ -1429,6 +1429,7 @@ static dsql_req* prepareStatement(thread_db* tdbb, dsql_dbb* database, jrd_tra* // Parse the SQL statement. If it croaks, return request = parser.parse(); + request->liveScratchPool = scratchPool; if (parser.isStmtAmbiguous()) scratch->flags |= DsqlCompilerScratch::FLAG_AMBIGUOUS_STMT; @@ -1473,12 +1474,12 @@ static dsql_req* prepareStatement(thread_db* tdbb, dsql_dbb* database, jrd_tra* transformedText.assign(temp.begin(), temp.getCount()); } - statement->setSqlText(FB_NEW_POOL(statementPool) RefString(statementPool, transformedText)); + statement->setSqlText(FB_NEW_POOL(*statementPool) RefString(*statementPool, transformedText)); // allocate the send and receive messages - statement->setSendMsg(FB_NEW_POOL(statementPool) dsql_msg(statementPool)); - dsql_msg* message = FB_NEW_POOL(statementPool) dsql_msg(statementPool); + statement->setSendMsg(FB_NEW_POOL(*statementPool) dsql_msg(*statementPool)); + dsql_msg* message = FB_NEW_POOL(*statementPool) dsql_msg(*statementPool); statement->setReceiveMsg(message); message->msg_number = 1; @@ -1490,7 +1491,14 @@ static dsql_req* prepareStatement(thread_db* tdbb, dsql_dbb* database, jrd_tra* ntrace_result_t traceResult = ITracePlugin::RESULT_SUCCESS; try { - request->dsqlPass(tdbb, scratch, &traceResult); + bool destroyScratchPool = false; + request->dsqlPass(tdbb, scratch, &destroyScratchPool, &traceResult); + + if (destroyScratchPool) + { + database->deletePool(scratchPool); + request->liveScratchPool = scratchPool = NULL; + } } catch (const Exception&) { @@ -1510,6 +1518,14 @@ static dsql_req* prepareStatement(thread_db* tdbb, dsql_dbb* database, jrd_tra* request->req_traced = false; dsql_req::destroy(tdbb, request, true); } + else + { + if (scratchPool) + database->deletePool(scratchPool); + + if (statementPool) + database->deletePool(statementPool); + } throw; } @@ -1577,6 +1593,7 @@ static void release_statement(DsqlCompiledStatement* statement) dsql_req::dsql_req(MemoryPool& pool) : req_pool(pool), statement(NULL), + liveScratchPool(NULL), cursors(req_pool), req_dbb(NULL), req_transaction(NULL), @@ -1772,7 +1789,12 @@ void dsql_req::destroy(thread_db* tdbb, dsql_req* request, bool drop) // Release the entire request if explicitly asked for if (drop) + { request->req_dbb->deletePool(&request->getPool()); + + if (request->liveScratchPool) + request->req_dbb->deletePool(request->liveScratchPool); + } } diff --git a/src/dsql/dsql.h b/src/dsql/dsql.h index d100cce692..b5ca3823d1 100644 --- a/src/dsql/dsql.h +++ b/src/dsql/dsql.h @@ -163,9 +163,9 @@ public: ~dsql_dbb(); - MemoryPool* createPool(MemoryPool* parent = NULL) + MemoryPool* createPool() { - return dbb_attachment->createPool(parent); + return dbb_attachment->createPool(); } void deletePool(MemoryPool* pool) @@ -490,8 +490,6 @@ public: } public: - MemoryPool& getPool() { return PermanentStorage::getPool(); } - Type getType() const { return type; } void setType(Type value) { type = value; } @@ -573,7 +571,7 @@ public: return statement; } - virtual void dsqlPass(thread_db* tdbb, DsqlCompilerScratch* scratch, + virtual void dsqlPass(thread_db* tdbb, DsqlCompilerScratch* scratch, bool* destroyScratchPool, ntrace_result_t* traceResult) = 0; virtual void execute(thread_db* tdbb, jrd_tra** traHandle, @@ -611,6 +609,7 @@ private: public: const DsqlCompiledStatement* statement; + MemoryPool* liveScratchPool; Firebird::Array cursors; // Cursor update statements dsql_dbb* req_dbb; // DSQL attachment @@ -651,7 +650,7 @@ public: { } - virtual void dsqlPass(thread_db* tdbb, DsqlCompilerScratch* scratch, + virtual void dsqlPass(thread_db* tdbb, DsqlCompilerScratch* scratch, bool* destroyScratchPool, ntrace_result_t* traceResult); virtual void execute(thread_db* tdbb, jrd_tra** traHandle, @@ -681,7 +680,7 @@ public: { } - virtual void dsqlPass(thread_db* tdbb, DsqlCompilerScratch* scratch, + virtual void dsqlPass(thread_db* tdbb, DsqlCompilerScratch* scratch, bool* destroyScratchPool, ntrace_result_t* traceResult); virtual void execute(thread_db* tdbb, jrd_tra** traHandle, @@ -708,7 +707,7 @@ public: req_traced = false; } - virtual void dsqlPass(thread_db* tdbb, DsqlCompilerScratch* scratch, + virtual void dsqlPass(thread_db* tdbb, DsqlCompilerScratch* scratch, bool* destroyScratchPool, ntrace_result_t* traceResult); virtual void execute(thread_db* tdbb, jrd_tra** traHandle, @@ -730,7 +729,7 @@ public: req_traced = false; } - virtual void dsqlPass(thread_db* tdbb, DsqlCompilerScratch* scratch, + virtual void dsqlPass(thread_db* tdbb, DsqlCompilerScratch* scratch, bool* destroyScratchPool, ntrace_result_t* traceResult); virtual void execute(thread_db* tdbb, jrd_tra** traHandle, diff --git a/src/jrd/Attachment.cpp b/src/jrd/Attachment.cpp index 860a4d184f..f4a6301d31 100644 --- a/src/jrd/Attachment.cpp +++ b/src/jrd/Attachment.cpp @@ -111,11 +111,10 @@ void Jrd::Attachment::destroy(Attachment* const attachment) } -MemoryPool* Jrd::Attachment::createPool(MemoryPool* parent) +MemoryPool* Jrd::Attachment::createPool() { - MemoryPool* const pool = MemoryPool::createPool(parent ? parent : att_pool, att_memory_stats); - if (!parent) - att_pools.add(pool); + MemoryPool* const pool = MemoryPool::createPool(NULL, att_memory_stats); + att_pools.add(pool); return pool; } diff --git a/src/jrd/Attachment.h b/src/jrd/Attachment.h index 13e42089c3..95d04ac64e 100644 --- a/src/jrd/Attachment.h +++ b/src/jrd/Attachment.h @@ -374,7 +374,7 @@ public: Firebird::Array att_pools; // pools - MemoryPool* createPool(MemoryPool* parent = NULL); + MemoryPool* createPool(); void deletePool(MemoryPool* pool); /// former Database members - end