Compare commits

...

2 Commits

Author SHA1 Message Date
gvolfing
54f4c02948 Remove unused function 2023-09-13 14:29:25 +02:00
gvolfing
c091bae418 Add POC of memory compaction attempts
Add new query "COMPACT MEMORY" and implement the underlying
functionality for it. This proof of concept is bulding on the snapshot
creation/reloading features we already have.
2023-09-13 13:51:24 +02:00
21 changed files with 143 additions and 6 deletions

View File

@@ -61,7 +61,8 @@ const std::vector<Permission> kPermissionsAll = {Permission::MATCH,
Permission::TRANSACTION_MANAGEMENT, Permission::TRANSACTION_MANAGEMENT,
Permission::STORAGE_MODE, Permission::STORAGE_MODE,
Permission::MULTI_DATABASE_EDIT, Permission::MULTI_DATABASE_EDIT,
Permission::MULTI_DATABASE_USE}; Permission::MULTI_DATABASE_USE,
Permission::COMPACT_MEMORY};
} // namespace } // namespace
@@ -117,6 +118,8 @@ std::string PermissionToString(Permission permission) {
return "MULTI_DATABASE_EDIT"; return "MULTI_DATABASE_EDIT";
case Permission::MULTI_DATABASE_USE: case Permission::MULTI_DATABASE_USE:
return "MULTI_DATABASE_USE"; return "MULTI_DATABASE_USE";
case Permission::COMPACT_MEMORY:
return "COMPACT_MEMORY";
} }
} }

View File

@@ -47,6 +47,7 @@ enum class Permission : uint64_t {
STORAGE_MODE = 1U << 22U, STORAGE_MODE = 1U << 22U,
MULTI_DATABASE_EDIT = 1U << 23U, MULTI_DATABASE_EDIT = 1U << 23U,
MULTI_DATABASE_USE = 1U << 24U, MULTI_DATABASE_USE = 1U << 24U,
COMPACT_MEMORY = 1U << 25U,
}; };
// clang-format on // clang-format on

View File

@@ -66,6 +66,8 @@ auth::Permission PrivilegeToPermission(query::AuthQuery::Privilege privilege) {
return auth::Permission::MULTI_DATABASE_EDIT; return auth::Permission::MULTI_DATABASE_EDIT;
case query::AuthQuery::Privilege::MULTI_DATABASE_USE: case query::AuthQuery::Privilege::MULTI_DATABASE_USE:
return auth::Permission::MULTI_DATABASE_USE; return auth::Permission::MULTI_DATABASE_USE;
case query::AuthQuery::Privilege::COMPACT_MEMORY:
return auth::Permission::COMPACT_MEMORY;
} }
} }

View File

@@ -230,6 +230,12 @@ class FreeMemoryModificationInMulticommandTxException : public QueryException {
: QueryException("Free memory query not allowed in multicommand transactions.") {} : QueryException("Free memory query not allowed in multicommand transactions.") {}
}; };
class CompactMemoryModificationInMulticommandTxException : public QueryException {
public:
CompactMemoryModificationInMulticommandTxException()
: QueryException("COMPACT MEMORY is query not allowed in multicommand transactions.") {}
};
class FreeMemoryDisabledOnDiskStorage : public QueryException { class FreeMemoryDisabledOnDiskStorage : public QueryException {
public: public:
FreeMemoryDisabledOnDiskStorage() : QueryException("Free memory does nothing when using disk storage. ") {} FreeMemoryDisabledOnDiskStorage() : QueryException("Free memory does nothing when using disk storage. ") {}

View File

@@ -243,6 +243,9 @@ constexpr utils::TypeInfo query::LoadCsv::kType{utils::TypeId::AST_LOAD_CSV, "Lo
constexpr utils::TypeInfo query::FreeMemoryQuery::kType{utils::TypeId::AST_FREE_MEMORY_QUERY, "FreeMemoryQuery", constexpr utils::TypeInfo query::FreeMemoryQuery::kType{utils::TypeId::AST_FREE_MEMORY_QUERY, "FreeMemoryQuery",
&query::Query::kType}; &query::Query::kType};
constexpr utils::TypeInfo query::CompactMemoryQuery::kType{utils::TypeId::AST_COMPACT_MEMORY_QUERY,
"CompactMemoryQuery", &query::Query::kType};
constexpr utils::TypeInfo query::TriggerQuery::kType{utils::TypeId::AST_TRIGGER_QUERY, "TriggerQuery", constexpr utils::TypeInfo query::TriggerQuery::kType{utils::TypeId::AST_TRIGGER_QUERY, "TriggerQuery",
&query::Query::kType}; &query::Query::kType};

View File

@@ -2813,6 +2813,7 @@ class AuthQuery : public memgraph::query::Query {
TRANSACTION_MANAGEMENT, TRANSACTION_MANAGEMENT,
MULTI_DATABASE_EDIT, MULTI_DATABASE_EDIT,
MULTI_DATABASE_USE, MULTI_DATABASE_USE,
COMPACT_MEMORY,
}; };
enum class FineGrainedPrivilege { NOTHING, READ, UPDATE, CREATE_DELETE }; enum class FineGrainedPrivilege { NOTHING, READ, UPDATE, CREATE_DELETE };
@@ -2891,7 +2892,8 @@ const std::vector<AuthQuery::Privilege> kPrivilegesAll = {AuthQuery::Privilege::
AuthQuery::Privilege::TRANSACTION_MANAGEMENT, AuthQuery::Privilege::TRANSACTION_MANAGEMENT,
AuthQuery::Privilege::STORAGE_MODE, AuthQuery::Privilege::STORAGE_MODE,
AuthQuery::Privilege::MULTI_DATABASE_EDIT, AuthQuery::Privilege::MULTI_DATABASE_EDIT,
AuthQuery::Privilege::MULTI_DATABASE_USE}; AuthQuery::Privilege::MULTI_DATABASE_USE,
AuthQuery::Privilege::COMPACT_MEMORY};
class InfoQuery : public memgraph::query::Query { class InfoQuery : public memgraph::query::Query {
public: public:
@@ -3115,6 +3117,19 @@ class FreeMemoryQuery : public memgraph::query::Query {
} }
}; };
class CompactMemoryQuery : public memgraph::query::Query {
public:
static const utils::TypeInfo kType;
const utils::TypeInfo &GetTypeInfo() const override { return kType; }
DEFVISITABLE(QueryVisitor<void>);
CompactMemoryQuery *Clone(AstStorage *storage) const override {
CompactMemoryQuery *object = storage->Create<CompactMemoryQuery>();
return object;
}
};
class TriggerQuery : public memgraph::query::Query { class TriggerQuery : public memgraph::query::Query {
public: public:
static const utils::TypeInfo kType; static const utils::TypeInfo kType;

View File

@@ -106,6 +106,7 @@ class Exists;
class MultiDatabaseQuery; class MultiDatabaseQuery;
class ShowDatabasesQuery; class ShowDatabasesQuery;
class EdgeImportModeQuery; class EdgeImportModeQuery;
class CompactMemoryQuery;
using TreeCompositeVisitor = utils::CompositeVisitor< using TreeCompositeVisitor = utils::CompositeVisitor<
SingleQuery, CypherUnion, NamedExpression, OrOperator, XorOperator, AndOperator, NotOperator, AdditionOperator, SingleQuery, CypherUnion, NamedExpression, OrOperator, XorOperator, AndOperator, NotOperator, AdditionOperator,
@@ -144,6 +145,6 @@ class QueryVisitor
ConstraintQuery, DumpQuery, ReplicationQuery, LockPathQuery, FreeMemoryQuery, TriggerQuery, ConstraintQuery, DumpQuery, ReplicationQuery, LockPathQuery, FreeMemoryQuery, TriggerQuery,
IsolationLevelQuery, CreateSnapshotQuery, StreamQuery, SettingQuery, VersionQuery, IsolationLevelQuery, CreateSnapshotQuery, StreamQuery, SettingQuery, VersionQuery,
ShowConfigQuery, TransactionQueueQuery, StorageModeQuery, AnalyzeGraphQuery, ShowConfigQuery, TransactionQueueQuery, StorageModeQuery, AnalyzeGraphQuery,
MultiDatabaseQuery, ShowDatabasesQuery, EdgeImportModeQuery> {}; MultiDatabaseQuery, ShowDatabasesQuery, EdgeImportModeQuery, CompactMemoryQuery> {};
} // namespace memgraph::query } // namespace memgraph::query

View File

@@ -410,6 +410,12 @@ antlrcpp::Any CypherMainVisitor::visitFreeMemoryQuery(MemgraphCypher::FreeMemory
return free_memory_query; return free_memory_query;
} }
antlrcpp::Any CypherMainVisitor::visitCompactMemoryQuery(MemgraphCypher::CompactMemoryQueryContext *ctx) {
auto *compact_memory_query = storage_->Create<CompactMemoryQuery>();
query_ = compact_memory_query;
return compact_memory_query;
}
antlrcpp::Any CypherMainVisitor::visitTriggerQuery(MemgraphCypher::TriggerQueryContext *ctx) { antlrcpp::Any CypherMainVisitor::visitTriggerQuery(MemgraphCypher::TriggerQueryContext *ctx) {
MG_ASSERT(ctx->children.size() == 1, "TriggerQuery should have exactly one child!"); MG_ASSERT(ctx->children.size() == 1, "TriggerQuery should have exactly one child!");
auto *trigger_query = std::any_cast<TriggerQuery *>(ctx->children[0]->accept(this)); auto *trigger_query = std::any_cast<TriggerQuery *>(ctx->children[0]->accept(this));
@@ -1576,6 +1582,7 @@ antlrcpp::Any CypherMainVisitor::visitPrivilege(MemgraphCypher::PrivilegeContext
if (ctx->STORAGE_MODE()) return AuthQuery::Privilege::STORAGE_MODE; if (ctx->STORAGE_MODE()) return AuthQuery::Privilege::STORAGE_MODE;
if (ctx->MULTI_DATABASE_EDIT()) return AuthQuery::Privilege::MULTI_DATABASE_EDIT; if (ctx->MULTI_DATABASE_EDIT()) return AuthQuery::Privilege::MULTI_DATABASE_EDIT;
if (ctx->MULTI_DATABASE_USE()) return AuthQuery::Privilege::MULTI_DATABASE_USE; if (ctx->MULTI_DATABASE_USE()) return AuthQuery::Privilege::MULTI_DATABASE_USE;
if (ctx->COMPACT_MEMORY()) return AuthQuery::Privilege::COMPACT_MEMORY;
LOG_FATAL("Should not get here - unknown privilege!"); LOG_FATAL("Should not get here - unknown privilege!");
} }

View File

@@ -241,6 +241,11 @@ class CypherMainVisitor : public antlropencypher::MemgraphCypherBaseVisitor {
*/ */
antlrcpp::Any visitFreeMemoryQuery(MemgraphCypher::FreeMemoryQueryContext *ctx) override; antlrcpp::Any visitFreeMemoryQuery(MemgraphCypher::FreeMemoryQueryContext *ctx) override;
/**
* @return CompactMemoryQuery*
*/
antlrcpp::Any visitCompactMemoryQuery(MemgraphCypher::CompactMemoryQueryContext *ctx) override;
/** /**
* @return TriggerQuery* * @return TriggerQuery*
*/ */

View File

@@ -37,6 +37,7 @@ memgraphCypherKeyword : cypherKeyword
| CLEAR | CLEAR
| COMMIT | COMMIT
| COMMITTED | COMMITTED
| COMPACT
| CONFIG | CONFIG
| CONFIGS | CONFIGS
| CONSUMER_GROUP | CONSUMER_GROUP
@@ -148,6 +149,7 @@ query : cypherQuery
| multiDatabaseQuery | multiDatabaseQuery
| showDatabases | showDatabases
| edgeImportModeQuery | edgeImportModeQuery
| compactMemoryQuery
; ;
authQuery : createRole authQuery : createRole
@@ -314,6 +316,7 @@ privilege : CREATE
| STORAGE_MODE | STORAGE_MODE
| MULTI_DATABASE_EDIT | MULTI_DATABASE_EDIT
| MULTI_DATABASE_USE | MULTI_DATABASE_USE
| COMPACT_MEMORY
; ;
granularPrivilege : NOTHING | READ | UPDATE | CREATE_DELETE ; granularPrivilege : NOTHING | READ | UPDATE | CREATE_DELETE ;
@@ -482,3 +485,5 @@ dropDatabase : DROP DATABASE databaseName ;
showDatabases: SHOW DATABASES ; showDatabases: SHOW DATABASES ;
edgeImportModeQuery : EDGE IMPORT MODE ( ACTIVE | INACTIVE ) ; edgeImportModeQuery : EDGE IMPORT MODE ( ACTIVE | INACTIVE ) ;
compactMemoryQuery : COMPACT MEMORY ;

View File

@@ -41,6 +41,7 @@ CHECK : C H E C K ;
CLEAR : C L E A R ; CLEAR : C L E A R ;
COMMIT : C O M M I T ; COMMIT : C O M M I T ;
COMMITTED : C O M M I T T E D ; COMMITTED : C O M M I T T E D ;
COMPACT : C O M P A C T ;
CONFIG : C O N F I G ; CONFIG : C O N F I G ;
CONFIGS : C O N F I G S; CONFIGS : C O N F I G S;
CONSUMER_GROUP : C O N S U M E R UNDERSCORE G R O U P ; CONSUMER_GROUP : C O N S U M E R UNDERSCORE G R O U P ;

View File

@@ -69,6 +69,10 @@ class PrivilegeExtractor : public QueryVisitor<void>, public HierarchicalTreeVis
void Visit(FreeMemoryQuery &free_memory_query) override { AddPrivilege(AuthQuery::Privilege::FREE_MEMORY); } void Visit(FreeMemoryQuery &free_memory_query) override { AddPrivilege(AuthQuery::Privilege::FREE_MEMORY); }
void Visit(CompactMemoryQuery & /*compact_memory_query*/) override {
AddPrivilege(AuthQuery::Privilege::COMPACT_MEMORY);
}
void Visit(ShowConfigQuery & /*show_config_query*/) override { AddPrivilege(AuthQuery::Privilege::CONFIG); } void Visit(ShowConfigQuery & /*show_config_query*/) override { AddPrivilege(AuthQuery::Privilege::CONFIG); }
void Visit(TriggerQuery &trigger_query) override { AddPrivilege(AuthQuery::Privilege::TRIGGER); } void Visit(TriggerQuery &trigger_query) override { AddPrivilege(AuthQuery::Privilege::TRIGGER); }

View File

@@ -219,7 +219,8 @@ const trie::Trie kKeywords = {"union",
"directory", "directory",
"lock", "lock",
"unlock", "unlock",
"build"}; "build",
"compact"};
// Unicode codepoints that are allowed at the start of the unescaped name. // Unicode codepoints that are allowed at the start of the unescaped name.
const std::bitset<kBitsetSize> kUnescapedNameAllowedStarts( const std::bitset<kBitsetSize> kUnescapedNameAllowedStarts(

View File

@@ -2255,6 +2255,23 @@ PreparedQuery PrepareFreeMemoryQuery(ParsedQuery parsed_query, bool in_explicit_
RWType::NONE}; RWType::NONE};
} }
PreparedQuery PrepareCompactMemoryQuery(ParsedQuery parsed_query, const bool in_explicit_transaction,
InterpreterContext *interpreter_context) {
if (in_explicit_transaction) {
throw CompactMemoryModificationInMulticommandTxException();
}
return PreparedQuery{
{},
std::move(parsed_query.required_privileges),
[interpreter_context](AnyStream *stream, std::optional<int> n) -> std::optional<QueryHandlerResult> {
interpreter_context->db->CompactMemory();
// memory::PurgeUnusedMemory();
return QueryHandlerResult::COMMIT;
},
RWType::NONE};
}
PreparedQuery PrepareShowConfigQuery(ParsedQuery parsed_query, bool in_explicit_transaction) { PreparedQuery PrepareShowConfigQuery(ParsedQuery parsed_query, bool in_explicit_transaction) {
if (in_explicit_transaction) { if (in_explicit_transaction) {
throw ShowConfigModificationInMulticommandTxException(); throw ShowConfigModificationInMulticommandTxException();
@@ -3654,6 +3671,9 @@ Interpreter::PrepareResult Interpreter::Prepare(const std::string &query_string,
prepared_query = PrepareLockPathQuery(std::move(parsed_query), in_explicit_transaction_, interpreter_context_); prepared_query = PrepareLockPathQuery(std::move(parsed_query), in_explicit_transaction_, interpreter_context_);
} else if (utils::Downcast<FreeMemoryQuery>(parsed_query.query)) { } else if (utils::Downcast<FreeMemoryQuery>(parsed_query.query)) {
prepared_query = PrepareFreeMemoryQuery(std::move(parsed_query), in_explicit_transaction_, interpreter_context_); prepared_query = PrepareFreeMemoryQuery(std::move(parsed_query), in_explicit_transaction_, interpreter_context_);
} else if (utils::Downcast<CompactMemoryQuery>(parsed_query.query)) {
prepared_query =
PrepareCompactMemoryQuery(std::move(parsed_query), in_explicit_transaction_, interpreter_context_);
} else if (utils::Downcast<ShowConfigQuery>(parsed_query.query)) { } else if (utils::Downcast<ShowConfigQuery>(parsed_query.query)) {
prepared_query = PrepareShowConfigQuery(std::move(parsed_query), in_explicit_transaction_); prepared_query = PrepareShowConfigQuery(std::move(parsed_query), in_explicit_transaction_);
} else if (utils::Downcast<TriggerQuery>(parsed_query.query)) { } else if (utils::Downcast<TriggerQuery>(parsed_query.query)) {

View File

@@ -849,7 +849,7 @@ bool SharedLibraryModule::Load(const std::filesystem::path &file_path) {
handle_ = dlopen(file_path.c_str(), RTLD_NOW | RTLD_LOCAL | RTLD_DEEPBIND); handle_ = dlopen(file_path.c_str(), RTLD_NOW | RTLD_LOCAL | RTLD_DEEPBIND);
if (!handle_) { if (!handle_) {
spdlog::error( spdlog::error(
utils::MessageWithLink("Unable to load module {}; {}.", file_path, dlerror(), "https://memgr.ph/modules")); utils::MessageWithLink("1 Unable to load module {}; {}.", file_path, dlerror(), "https://memgr.ph/modules"));
return false; return false;
} }
// Get required mgp_init_module // Get required mgp_init_module
@@ -857,7 +857,7 @@ bool SharedLibraryModule::Load(const std::filesystem::path &file_path) {
char *dl_errored = dlerror(); char *dl_errored = dlerror();
if (!init_fn_ || dl_errored) { if (!init_fn_ || dl_errored) {
spdlog::error( spdlog::error(
utils::MessageWithLink("Unable to load module {}; {}.", file_path, dl_errored, "https://memgr.ph/modules")); utils::MessageWithLink("2 Unable to load module {}; {}.", file_path, dl_errored, "https://memgr.ph/modules"));
dlclose(handle_); dlclose(handle_);
handle_ = nullptr; handle_ = nullptr;
return false; return false;

View File

@@ -367,6 +367,7 @@ class DiskStorage final : public Storage {
StorageInfo GetInfo() const override; StorageInfo GetInfo() const override;
void FreeMemory(std::unique_lock<utils::RWLock> /*lock*/) override {} void FreeMemory(std::unique_lock<utils::RWLock> /*lock*/) override {}
void CompactMemory(std::unique_lock<utils::RWLock> /*lock*/) override {}
void EstablishNewEpoch() override { throw utils::BasicException("Disk storage mode does not support replication."); } void EstablishNewEpoch() override { throw utils::BasicException("Disk storage mode does not support replication."); }

View File

@@ -10,6 +10,7 @@
// licenses/APL.txt. // licenses/APL.txt.
#include "storage/v2/inmemory/storage.hpp" #include "storage/v2/inmemory/storage.hpp"
#include <memory>
#include "storage/v2/durability/durability.hpp" #include "storage/v2/durability/durability.hpp"
#include "storage/v2/durability/snapshot.hpp" #include "storage/v2/durability/snapshot.hpp"
@@ -17,6 +18,7 @@
#include "storage/v2/inmemory/replication/replication_client.hpp" #include "storage/v2/inmemory/replication/replication_client.hpp"
#include "storage/v2/inmemory/replication/replication_server.hpp" #include "storage/v2/inmemory/replication/replication_server.hpp"
#include "storage/v2/inmemory/unique_constraints.hpp" #include "storage/v2/inmemory/unique_constraints.hpp"
#include "utils/exceptions.hpp"
namespace memgraph::storage { namespace memgraph::storage {
@@ -1785,6 +1787,55 @@ void InMemoryStorage::FreeMemory(std::unique_lock<utils::RWLock> main_guard) {
static_cast<InMemoryLabelPropertyIndex *>(indices_.label_property_index_.get())->RunGC(); static_cast<InMemoryLabelPropertyIndex *>(indices_.label_property_index_.get())->RunGC();
} }
void InMemoryStorage::CompactMemory(std::unique_lock<utils::RWLock> main_guard) {
// Version 1
// 1. Create snapshot.
auto snap_err = CreateSnapshot(false);
if (snap_err.HasError()) {
throw utils::BasicException("Failed to create snapshot.");
}
// 2. Clear Storage.
edges_.clear();
vertices_.clear();
indices_.label_index_ = std::make_unique<InMemoryLabelIndex>(&indices_, config_);
indices_.label_property_index_ = std::make_unique<InMemoryLabelPropertyIndex>(&indices_, config_);
constraints_.existence_constraints_ = std::make_unique<ExistenceConstraints>();
constraints_.unique_constraints_ = std::make_unique<InMemoryUniqueConstraints>();
edge_count_.store(0);
// 3. Recover
auto &epoch = replication_state_.GetEpoch();
auto info = durability::RecoverData(snapshot_directory_, wal_directory_, &uuid_, &epoch.id,
&replication_state_.history, &vertices_, &edges_, &edge_count_,
name_id_mapper_.get(), &indices_, &constraints_, config_, &wal_seq_num_);
if (info) {
vertex_id_ = info->next_vertex_id;
edge_id_ = info->next_edge_id;
timestamp_ = std::max(timestamp_, info->next_timestamp);
if (info->last_commit_timestamp) {
replication_state_.last_commit_timestamp_ = *info->last_commit_timestamp;
}
}
// Version 2
// 1. Take complete control, block everything else.
// 2. Force-call garbage collection in both storage modes.
// 3. Recreate the skip lists and indices. Order may matter.
// 4. Delete old skiplists.
// 5. Force-call garbage collection again.
// 6. Profit.
// Version 3
// Same as version 1 but intsead revoery ops use rocksdb
// to temporarly store the data.
// MISC
// - How does this play together with replication?
// - How does this play together with the MemoryChecker?
// - How does this play together with multi-tenancy?
}
uint64_t InMemoryStorage::CommitTimestamp(const std::optional<uint64_t> desired_commit_timestamp) { uint64_t InMemoryStorage::CommitTimestamp(const std::optional<uint64_t> desired_commit_timestamp) {
if (!desired_commit_timestamp) { if (!desired_commit_timestamp) {
return timestamp_++; return timestamp_++;

View File

@@ -361,6 +361,7 @@ class InMemoryStorage final : public Storage {
LabelId label, const std::set<PropertyId> &properties, std::optional<uint64_t> desired_commit_timestamp) override; LabelId label, const std::set<PropertyId> &properties, std::optional<uint64_t> desired_commit_timestamp) override;
void FreeMemory(std::unique_lock<utils::RWLock> main_guard) override; void FreeMemory(std::unique_lock<utils::RWLock> main_guard) override;
void CompactMemory(std::unique_lock<utils::RWLock> main_guard) override;
utils::FileRetainer::FileLockerAccessor::ret_type IsPathLocked(); utils::FileRetainer::FileLockerAccessor::ret_type IsPathLocked();
utils::FileRetainer::FileLockerAccessor::ret_type LockPath(); utils::FileRetainer::FileLockerAccessor::ret_type LockPath();

View File

@@ -254,6 +254,10 @@ class Storage {
void FreeMemory() { FreeMemory({}); } void FreeMemory() { FreeMemory({}); }
virtual void CompactMemory(std::unique_lock<utils::RWLock> main_guard) = 0;
void CompactMemory() { CompactMemory({}); }
virtual std::unique_ptr<Accessor> Access(std::optional<IsolationLevel> override_isolation_level) = 0; virtual std::unique_ptr<Accessor> Access(std::optional<IsolationLevel> override_isolation_level) = 0;
std::unique_ptr<Accessor> Access() { return Access(std::optional<IsolationLevel>{}); } std::unique_ptr<Accessor> Access() { return Access(std::optional<IsolationLevel>{}); }

View File

@@ -171,6 +171,7 @@ enum class TypeId : uint64_t {
AST_LOCK_PATH_QUERY, AST_LOCK_PATH_QUERY,
AST_LOAD_CSV, AST_LOAD_CSV,
AST_FREE_MEMORY_QUERY, AST_FREE_MEMORY_QUERY,
AST_COMPACT_MEMORY_QUERY,
AST_TRIGGER_QUERY, AST_TRIGGER_QUERY,
AST_ISOLATION_LEVEL_QUERY, AST_ISOLATION_LEVEL_QUERY,
AST_STORAGE_MODE_QUERY, AST_STORAGE_MODE_QUERY,

View File

@@ -169,6 +169,11 @@ TEST_F(TestPrivilegeExtractor, FreeMemoryQuery) {
EXPECT_THAT(GetRequiredPrivileges(query), UnorderedElementsAre(AuthQuery::Privilege::FREE_MEMORY)); EXPECT_THAT(GetRequiredPrivileges(query), UnorderedElementsAre(AuthQuery::Privilege::FREE_MEMORY));
} }
TEST_F(TestPrivilegeExtractor, CompactMemoryQuery) {
auto *query = storage.Create<CompactMemoryQuery>();
EXPECT_THAT(GetRequiredPrivileges(query), UnorderedElementsAre(AuthQuery::Privilege::COMPACT_MEMORY));
}
TEST_F(TestPrivilegeExtractor, TriggerQuery) { TEST_F(TestPrivilegeExtractor, TriggerQuery) {
auto *query = storage.Create<TriggerQuery>(); auto *query = storage.Create<TriggerQuery>();
EXPECT_THAT(GetRequiredPrivileges(query), UnorderedElementsAre(AuthQuery::Privilege::TRIGGER)); EXPECT_THAT(GetRequiredPrivileges(query), UnorderedElementsAre(AuthQuery::Privilege::TRIGGER));