From cdb181d9ca25951a5d3601a284515bb002a74f7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gwendal=20Rou=C3=A9?= Date: Wed, 4 Sep 2024 09:19:24 +0200 Subject: [PATCH] Don't invoke sqlite3_db_release_memory on closed database connections --- GRDB/Core/Database.swift | 4 +++- Tests/GRDBTests/DatabasePoolTests.swift | 8 ++++++++ Tests/GRDBTests/DatabaseQueueTests.swift | 7 +++++++ 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/GRDB/Core/Database.swift b/GRDB/Core/Database.swift index 474373db5f..9d5a13b7bd 100644 --- a/GRDB/Core/Database.swift +++ b/GRDB/Core/Database.swift @@ -1575,7 +1575,9 @@ public final class Database: CustomStringConvertible, CustomDebugStringConvertib /// Frees as much memory as possible. public func releaseMemory() { SchedulingWatchdog.preconditionValidQueue(self) - sqlite3_db_release_memory(sqliteConnection) + if let sqliteConnection { + sqlite3_db_release_memory(sqliteConnection) + } schemaCache.clear() internalStatementCache.clear() publicStatementCache.clear() diff --git a/Tests/GRDBTests/DatabasePoolTests.swift b/Tests/GRDBTests/DatabasePoolTests.swift index 7580b1a347..8b45af6ab7 100644 --- a/Tests/GRDBTests/DatabasePoolTests.swift +++ b/Tests/GRDBTests/DatabasePoolTests.swift @@ -439,4 +439,12 @@ class DatabasePoolTests: GRDBTestCase { // In the zombie state, closing is a noop try dbPool.close() } + + // Regression test for + func test_releaseMemory_after_close() throws { + let dbPool = try makeDatabasePool() + try dbPool.read { _ in } // Create a reader + try dbPool.close() + dbPool.releaseMemory() + } } diff --git a/Tests/GRDBTests/DatabaseQueueTests.swift b/Tests/GRDBTests/DatabaseQueueTests.swift index 7bd5adf2b5..43c415a4fa 100644 --- a/Tests/GRDBTests/DatabaseQueueTests.swift +++ b/Tests/GRDBTests/DatabaseQueueTests.swift @@ -467,4 +467,11 @@ class DatabaseQueueTests: GRDBTestCase { try db.execute(sql: "SELECT * FROM sqlite_master") } } + + // Regression test for + func test_releaseMemory_after_close() throws { + let dbQueue = try makeDatabaseQueue() + try dbQueue.close() + dbQueue.releaseMemory() + } }