8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-02-02 10:40:38 +01:00

Unlink JResultSet from DsqlCursor when cursor is closed due to end of transaction - this fixes AV in tcs/BLOB.0.DSQL

This commit is contained in:
alexpeshkoff 2015-02-17 11:42:50 +00:00
parent f1a5ed749b
commit f8a9d903e2
4 changed files with 24 additions and 2 deletions

View File

@ -34,7 +34,7 @@ static const char* const SCRATCH = "fb_cursor_";
static const ULONG PREFETCH_SIZE = 65536; // 64 KB
DsqlCursor::DsqlCursor(dsql_req* req, ULONG flags)
: m_request(req), m_flags(flags),
: m_request(req), m_resultSet(NULL), m_flags(flags),
m_space(req->getPool(), SCRATCH),
m_state(BOS), m_eof(false), m_position(0), m_cachedCount(0),
m_messageSize(req->getStatement()->getReceiveMsg()->msg_length)
@ -42,6 +42,12 @@ DsqlCursor::DsqlCursor(dsql_req* req, ULONG flags)
TRA_link_cursor(m_request->req_transaction, this);
}
DsqlCursor::~DsqlCursor()
{
if (m_resultSet)
m_resultSet->resetHandle();
}
jrd_tra* DsqlCursor::getTransaction() const
{
return m_request->req_transaction;
@ -52,6 +58,12 @@ Attachment* DsqlCursor::getAttachment() const
return m_request->req_dbb->dbb_attachment;
}
void DsqlCursor::setInterfacePtr(JResultSet* interfacePtr) throw()
{
fb_assert(!m_resultSet);
m_resultSet = interfacePtr;
}
void DsqlCursor::close(thread_db* tdbb, DsqlCursor* cursor)
{
if (!cursor)

View File

@ -28,16 +28,19 @@
namespace Jrd {
class dsql_req;
class JResultSet;
class DsqlCursor
{
enum State { BOS, POSITIONED, EOS };
public:
explicit DsqlCursor(dsql_req* req, ULONG flags);
DsqlCursor(dsql_req* req, ULONG flags);
~DsqlCursor();
jrd_tra* getTransaction() const;
Attachment* getAttachment() const;
void setInterfacePtr(JResultSet* interfacePtr) throw();
static void close(thread_db* tdbb, DsqlCursor* cursor);
@ -63,6 +66,7 @@ private:
bool cacheInput(thread_db* tdbb, FB_UINT64 position = MAX_UINT64);
dsql_req* const m_request;
JResultSet* m_resultSet;
const ULONG m_flags;
TempSpace m_space;
State m_state;

View File

@ -167,6 +167,11 @@ public:
return cursor;
}
void resetHandle()
{
cursor = NULL;
}
private:
DsqlCursor* cursor;
Firebird::RefPtr<JStatement> statement;

View File

@ -4500,6 +4500,7 @@ JResultSet* JStatement::openCursor(CheckStatusWrapper* user_status, ITransaction
rs = new JResultSet(cursor, this);
rs->addRef();
cursor->setInterfacePtr(rs);
}
catch (const Exception& ex)
{