Skip to content

Commit

Permalink
Add max_databases setting
Browse files Browse the repository at this point in the history
`max_databases` allows to limit max number of databases a user
can create. In case the user tries to create a new database and
the current number of databases is equal or larger then `max_databases`
an Error is thrown.
  • Loading branch information
Khatskevich committed Jan 22, 2025
1 parent 0777d9c commit 166c6f6
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 1 deletion.
2 changes: 2 additions & 0 deletions src/Core/Settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,8 @@ class IColumn;
M(UInt64, max_concurrent_queries_for_all_users, 0, "The maximum number of concurrent requests for all users.", 0) \
M(UInt64, max_concurrent_queries_for_user, 0, "The maximum number of concurrent requests per user.", 0) \
\
M(UInt64, max_databases, 0, "The maximum number of created databases.", 0) \
\
M(Bool, insert_deduplicate, true, "For INSERT queries in the replicated table, specifies that deduplication of inserting blocks should be performed", 0) \
M(Bool, async_insert_deduplicate, false, "For async INSERT queries in the replicated table, specifies that deduplication of inserting blocks should be performed", 0) \
\
Expand Down
18 changes: 17 additions & 1 deletion src/Interpreters/InterpreterCreateQuery.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ namespace DB
namespace ErrorCodes
{
extern const int ACCESS_DENIED;
extern const int CANNOT_CREATE_DATABASE;
extern const int TABLE_ALREADY_EXISTS;
extern const int DICTIONARY_ALREADY_EXISTS;
extern const int EMPTY_LIST_OF_COLUMNS_PASSED;
Expand Down Expand Up @@ -1806,6 +1807,19 @@ BlockIO InterpreterCreateQuery::createReplicatedDatabaseByClient() {
return {};
}

void InterpreterCreateQuery::checkMaxDatabases() {
if (internal)
return;
auto max_databases = getContext()->getSettingsRef().max_databases;
if (!max_databases)
return;
auto databases = DatabaseCatalog::instance().getDatabases();
auto databases_cnt = databases.size();
if (databases_cnt >= max_databases) {
throw Exception(ErrorCodes::CANNOT_CREATE_DATABASE, "Cannot create database: the number of databases {} + 1 exceeds the limit of {}", databases_cnt, max_databases);
}
}

void InterpreterCreateQuery::checkDatabaseNameAllowed() {
auto & create = query_ptr->as<ASTCreateQuery &>();
if (internal)
Expand Down Expand Up @@ -1841,8 +1855,10 @@ BlockIO InterpreterCreateQuery::execute()
FunctionNameNormalizer().visit(query_ptr.get());
auto & create = query_ptr->as<ASTCreateQuery &>();
bool is_create_database = create.database && !create.table;
if (is_create_database)
if (is_create_database) {
checkDatabaseNameAllowed();
checkMaxDatabases();
}
auto context = getContext();
auto username = context->getUserName();
auto user_with_interect_db_creation = context->getServerSettings().getString("user_with_indirect_database_creation");
Expand Down
1 change: 1 addition & 0 deletions src/Interpreters/InterpreterCreateQuery.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ class InterpreterCreateQuery : public IInterpreter, WithMutableContext
};

BlockIO createReplicatedDatabaseByClient();
void checkMaxDatabases();
void checkDatabaseNameAllowed();
BlockIO createDatabase(ASTCreateQuery & create);
BlockIO createTable(ASTCreateQuery & create);
Expand Down

0 comments on commit 166c6f6

Please sign in to comment.