From 2eba123ecf5c666c5dff213a9321972fbc7bff66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Cs=C3=A1rdi?= Date: Mon, 9 Oct 2023 14:16:22 +0200 Subject: [PATCH] More careful result destructor Only set the current result to null if we are cleaning up the current result. What happens is that when a result is not cleaned up and then you make another query, then the first result set is not freed, but it is left dangling, with a reference to the connection: https://github.com/r-dbi/odbc/blob/a0ba73c72ca8f4cf33181fead7644b9b90aa2d4c/src/odbc_connection.cpp#L19 We test that the first result is invalidated in DBItest, here: https://github.com/r-dbi/DBItest/blob/2c29217bdd0b3314e6ec65216d99a3bf83a63464/R/spec-result-send-query.R#L92 So after that test there is still a result object, until the garbage collector runs next. If the garbage collector happens to run when there is another active result for the same connection, we remove that result from the connection, even though it is not the result we are finalizing. The workaround in this PR check that we are finalizing the active result in the destructor. A better solution would be to finalize the old result when a new one is set, but that seemed more difficult with the current code base. --- src/odbc_result.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/odbc_result.cpp b/src/odbc_result.cpp index fde99d6e..d3a882b1 100644 --- a/src/odbc_result.cpp +++ b/src/odbc_result.cpp @@ -208,7 +208,7 @@ bool odbc_result::complete() { bool odbc_result::active() { return c_->is_current_result(this); } odbc_result::~odbc_result() { - if (c_ != nullptr) { + if (c_ != nullptr && active()) { try { c_->set_current_result(nullptr); } catch (...) {