Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
odbc_result/connection: better reference accounting #731
odbc_result/connection: better reference accounting #731
Changes from 2 commits
653219f
127dbf8
a6f3936
da25d60
File filter
Filter by extension
Conversations
Jump to
There are no files selected for viewing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you sure this code shouldn't belong in
odbc_connection::cancel_current_result()
?Re-looking at this code also made me realise that the
warning()
is potentially dangerous because ifoptions(warn = 2)
is set, then we'll never get to thecancel()
. We should probably add a test for that case too, using something likewithr::local_options(warn = 2)
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey Hadley - thanks for taking a look.
I think this is a good spot for it. We could try/catch closer to the place that throws currently. But I think we still need to update the exception handling here in case another piece of code throws ( now, or in the future, if we were to expand set_current_result / etc ).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It feels weird to me because the job of
c_->set_current_result(nullptr)
is to reset the current result, and now its purpose is leaking out side of its scope. i.e. I think it's a code smell that you have to use friend here in order to reach inside the implementation detail of another function.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi Hadley - thank you for continuing to think about this.
I think using
friend
here is OK: theodbc_connection/odbc_result
relationship is more than a bit incestuous to begin with, with both holding a (private) reference to each other. Looks like we needed to forward declare the objects just to get the code to compile.In terms of leaking purpose:
set_current_result
has two jobs - cancel the current statement with some caseology sprinkled in (throw
s ) and second, reset the pointer. As we can'tthrow
in the destructor, we could try and separate the calls - for example, wrap that second role in a onelinerpublic void reset_result_ptr( odbc_result* r ) noexcept
method. This would make it also so that we do not need to make the classesfriend
s. But I think I would probably still call that method in the destructor over adding exception handling inset_current_result
. The destructor might look something like this:Anyway - not really tied to anything here. Happy to go in a different direction.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was thinking about this being a destructor last night — I think that means we can't call
Rcpp::warning()
safely at all here, because it might long jump, and while I can't remember exactly what happens when you long jump out of C++ destructor I know it's not good.How about we merge this PR to fix the pressing problem and then file another issue to rethink the design of this system to be safer?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good - thanks!