Maybe better to show some code (simplified). Expecting the free and release to have separate responsibilities I wrote initially (the variables with underscore are class fields). The Execute is called at some point and Free is called either after the IExternalFunctionImpl finished executing or in IExternalResultSetImpl::dispose (because that's the only place I'm aware of I know no more fetching will occur and the fetching might end up in the middle not reading all the results (otherwise I would know it because fetchNext would return != IStatus::RESULT_OK).
void Execute(const char* stmt) { auto status = ThrowStatusWrapper(_context->getMaster()->getStatus()); _attachment = _context->getAttachment(&status); _transaction = _context->getTransaction(&status); _statement = _attachment->prepare(&status, _transaction, 0, stmt, SQL_DIALECT_CURRENT, 0); _cursor = _statement->openCursor(&status, _transaction, nullptr, nullptr, outMetadata, 0); _msg = new unsigned char[outMetadata->getMessageLength(&status)]; // other method does the fetchNext } void Free() { _cursor->close(&status); _statement->free(&status); delete _msg; _msg = nullptr; _cursor->release(); _cursor = nullptr; _statement->release(); _statement = nullptr; _transaction->release(); _transaction = nullptr; _attachment->release(); _attachment = nullptr; } -- Mgr. Jiří Činčura https://www.tabsoverspaces.com/ Firebird-Devel mailing list, web interface at https://lists.sourceforge.net/lists/listinfo/firebird-devel