Skip to content

Commit

Permalink
Fix #8185 - SIGSEGV with WHERE CURRENT OF statement with statement ca…
Browse files Browse the repository at this point in the history
…che turned on.
  • Loading branch information
asfernandes authored and dyemanov committed Nov 16, 2024
1 parent fe6f1ac commit 5ab64aa
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 8 deletions.
5 changes: 4 additions & 1 deletion src/dsql/DsqlRequests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
#include "../dsql/DsqlRequests.h"
#include "../dsql/dsql.h"
#include "../dsql/DsqlBatch.h"
///#include "../dsql/DsqlStatementCache.h"
#include "../dsql/DsqlStatementCache.h"
#include "../dsql/Nodes.h"
#include "../jrd/Statement.h"
#include "../jrd/req.h"
Expand Down Expand Up @@ -177,6 +177,9 @@ void DsqlRequest::destroy(thread_db* tdbb, DsqlRequest* dsqlRequest)
{
childStatement->addFlags(DsqlStatement::FLAG_ORPHAN);
childStatement->setParentRequest(nullptr);
childStatement->setParentDbKey(nullptr);
childStatement->setParentRecVersion(nullptr);
dsqlRequest->req_dbb->dbb_statement_cache->removeStatement(tdbb, childStatement);

// hvlad: lines below is commented out as
// - child is already unlinked from its parent request
Expand Down
34 changes: 31 additions & 3 deletions src/dsql/DsqlStatementCache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,20 +156,44 @@ void DsqlStatementCache::putStatement(thread_db* tdbb, const string& text, USHOR
#endif
}

void DsqlStatementCache::removeStatement(thread_db* tdbb, DsqlStatement* statement)
{
if (const auto cacheKey = statement->getCacheKey())
{
if (const auto entryPtr = map.get(cacheKey))
{
const auto entry = *entryPtr;

entry->dsqlStatement->resetCacheKey();

if (entry->active)
{
entry->dsqlStatement->addRef();
activeStatementList.erase(entry);
}
else
{
inactiveStatementList.erase(entry);
cacheSize -= entry->size;
}

map.remove(entry->key);
}
}
}

void DsqlStatementCache::statementGoingInactive(Firebird::RefStrPtr& key)
{
const auto entryPtr = map.get(key);

if (!entryPtr)
{
fb_assert(false);
return;
}

const auto entry = *entryPtr;

fb_assert(entry->active);
entry->active = false;
entry->dsqlStatement->addRef();
entry->size = entry->dsqlStatement->getSize(); // update size

inactiveStatementList.splice(inactiveStatementList.end(), activeStatementList, entry);
Expand All @@ -192,6 +216,9 @@ void DsqlStatementCache::purge(thread_db* tdbb, bool releaseLock)
entry.dsqlStatement->resetCacheKey();
}

for (auto& entry : inactiveStatementList)
entry.dsqlStatement->resetCacheKey();

map.clear();
activeStatementList.clear();
inactiveStatementList.clear();
Expand Down Expand Up @@ -273,6 +300,7 @@ void DsqlStatementCache::shrink()
while (cacheSize > maxCacheSize && !inactiveStatementList.isEmpty())
{
const auto& front = inactiveStatementList.front();
front.dsqlStatement->resetCacheKey();
map.remove(front.key);
cacheSize -= front.size;
inactiveStatementList.erase(inactiveStatementList.begin());
Expand Down
1 change: 1 addition & 0 deletions src/dsql/DsqlStatementCache.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ class DsqlStatementCache final : public Firebird::PermanentStorage
void putStatement(thread_db* tdbb, const Firebird::string& text, USHORT clientDialect, bool isInternalRequest,
Firebird::RefPtr<DsqlStatement> dsqlStatement);

void removeStatement(thread_db* tdbb, DsqlStatement* statement);
void statementGoingInactive(Firebird::RefStrPtr& key);

void purge(thread_db* tdbb, bool releaseLock);
Expand Down
6 changes: 2 additions & 4 deletions src/dsql/DsqlStatements.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,8 @@ int DsqlStatement::release()
{
if (cacheKey)
{
refCnt = ++refCounter;
auto key = cacheKey;
cacheKey = nullptr;
dsqlAttachment->dbb_statement_cache->statementGoingInactive(key);
dsqlAttachment->dbb_statement_cache->statementGoingInactive(cacheKey);
refCnt = refCounter;
}
else
{
Expand Down
1 change: 1 addition & 0 deletions src/dsql/DsqlStatements.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ class DsqlStatement : public Firebird::PermanentStorage
const dsql_par* getEof() const { return eof; }
void setEof(dsql_par* value) { eof = value; }

Firebird::RefStrPtr getCacheKey() { return cacheKey; }
void setCacheKey(Firebird::RefStrPtr& value) { cacheKey = value; }
void resetCacheKey() { cacheKey = nullptr; }

Expand Down

0 comments on commit 5ab64aa

Please sign in to comment.