Destruct interpreter results before the db accessor

Reviewers: teon.banek

Reviewed By: teon.banek

Subscribers: pullbot

Differential Revision: https://phabricator.memgraph.io/D1500
This commit is contained in:
Matej Ferencevic 2018-07-19 10:06:08 +02:00
parent 3ac749caea
commit 10b4e45166

View File

@ -4,8 +4,8 @@
#include "database/graph_db_accessor.hpp"
#include "query/exceptions.hpp"
#include "query/interpreter.hpp"
#include "utils/string.hpp"
#include "utils/likely.hpp"
#include "utils/string.hpp"
namespace query {
@ -81,8 +81,11 @@ class TransactionEngine final {
// Stream all results and return the summary.
try {
results_->PullAll(*result_stream);
// Make a copy of the summary because the `Commit` call will destroy the
// `results_` object.
auto summary = results_->summary();
if (!in_explicit_transaction_) Commit();
return results_->summary();
return summary;
} catch (const utils::BasicException &) {
AbortCommand();
throw;
@ -90,6 +93,7 @@ class TransactionEngine final {
}
void Abort() {
results_ = std::experimental::nullopt;
if (!db_accessor_) return;
db_accessor_->Abort();
db_accessor_ = nullptr;
@ -99,17 +103,23 @@ class TransactionEngine final {
database::MasterBase &db_;
Interpreter &interpreter_;
std::unique_ptr<database::GraphDbAccessor> db_accessor_;
// The `query::Interpreter::Results` object MUST be destroyed before the
// `database::GraphDbAccessor` is destroyed because the `Results` object holds
// references to the `GraphDb` object and will crash the database when
// destructed if you are not careful.
std::experimental::optional<query::Interpreter::Results> results_;
bool in_explicit_transaction_{false};
bool expect_rollback_{false};
void Commit() {
results_ = std::experimental::nullopt;
if (!db_accessor_) return;
db_accessor_->Commit();
db_accessor_ = nullptr;
}
void AdvanceCommand() {
results_ = std::experimental::nullopt;
if (!db_accessor_) return;
db_accessor_->AdvanceCommand();
// TODO: this logic shouldn't be here!
@ -122,6 +132,7 @@ class TransactionEngine final {
}
void AbortCommand() {
results_ = std::experimental::nullopt;
if (in_explicit_transaction_) {
expect_rollback_ = true;
} else {