Forbid changing isolation level for disk and analytical (#1367)

Co-authored-by: Marko Budiselić <marko.budiselic@memgraph.com>
This commit is contained in:
Andi 2023-10-23 06:02:56 +02:00 committed by GitHub
parent 945388fba6
commit af56ab6ea8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 19 additions and 15 deletions

View File

@ -307,6 +307,12 @@ class IsolationLevelModificationInAnalyticsException : public QueryException {
SPECIALIZE_GET_EXCEPTION_NAME(IsolationLevelModificationInAnalyticsException)
};
class IsolationLevelModificationInDiskTransactionalException : public QueryException {
public:
IsolationLevelModificationInDiskTransactionalException()
: QueryException("Snapshot isolation level is the only supported isolation level for disk storage.") {}
};
class StorageModeModificationInMulticommandTxException : public QueryException {
public:
StorageModeModificationInMulticommandTxException()

View File

@ -2613,25 +2613,26 @@ PreparedQuery PrepareIsolationLevelQuery(ParsedQuery parsed_query, const bool in
MG_ASSERT(isolation_level_query);
const auto isolation_level = ToStorageIsolationLevel(isolation_level_query->isolation_level_);
MG_ASSERT(current_db.db_acc_, "Storage Isolation Level query expects a current DB");
storage::Storage *storage = current_db.db_acc_->get()->storage();
if (storage->GetStorageMode() == storage::StorageMode::IN_MEMORY_ANALYTICAL) {
throw IsolationLevelModificationInAnalyticsException();
}
if (storage->GetStorageMode() == storage::StorageMode::ON_DISK_TRANSACTIONAL &&
isolation_level != storage::IsolationLevel::SNAPSHOT_ISOLATION) {
throw IsolationLevelModificationInDiskTransactionalException();
}
std::function<void()> callback;
switch (isolation_level_query->isolation_level_scope_) {
case IsolationLevelQuery::IsolationLevelScope::GLOBAL: // TODO:.....not GLOBAL is it?!
{
MG_ASSERT(current_db.db_acc_, "Storage Isolation Level query expects a current DB");
storage::Storage *storage = current_db.db_acc_->get()->storage();
case IsolationLevelQuery::IsolationLevelScope::GLOBAL: {
callback = [storage, isolation_level] {
if (auto maybe_error = storage->SetIsolationLevel(isolation_level); maybe_error.HasError()) {
switch (maybe_error.GetError()) {
case storage::Storage::SetIsolationLevelError::DisabledForAnalyticalMode:
throw IsolationLevelModificationInAnalyticsException();
break;
}
if (auto res = storage->SetIsolationLevel(isolation_level); res.HasError()) {
throw utils::BasicException("Failed setting global isolation level");
}
};
break;
}
case IsolationLevelQuery::IsolationLevelScope::SESSION: {
callback = [interpreter, isolation_level] { interpreter->SetSessionIsolationLevel(isolation_level); };
break;

View File

@ -111,10 +111,6 @@ IsolationLevel Storage::GetIsolationLevel() const noexcept { return isolation_le
utils::BasicResult<Storage::SetIsolationLevelError> Storage::SetIsolationLevel(IsolationLevel isolation_level) {
std::unique_lock main_guard{main_lock_};
if (storage_mode_ == storage::StorageMode::IN_MEMORY_ANALYTICAL) {
return Storage::SetIsolationLevelError::DisabledForAnalyticalMode;
}
isolation_level_ = isolation_level;
return {};
}

View File

@ -21,6 +21,7 @@ class GraphQLServer:
self.__wait_process_to_init(7687)
self.__wait_process_to_init(4000)
atexit.register(self.__shut_down)
print(f"GraphQLServer started")
def send_query(self, query: str, timeout=5.0) -> requests.Response:
try: