mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-10 01:25:21 +00:00
Removed SET GLOBAL query. [#MTRSADMIN-3068]
It even was not supported properly in console client.
This commit is contained in:
parent
353dba545d
commit
2167e4efdd
@ -128,6 +128,7 @@ struct ContextShared
|
||||
std::unique_ptr<MergeTreeSettings> merge_tree_settings; /// Settings of MergeTree* engines.
|
||||
size_t max_table_size_to_drop = 50000000000lu; /// Protects MergeTree tables from accidental DROP (50GB by default)
|
||||
|
||||
|
||||
/// Named sessions. The user could specify session identifier to reuse settings and temporary tables in subsequent requests.
|
||||
|
||||
class SessionKeyHash
|
||||
@ -498,30 +499,42 @@ ConfigurationPtr Context::getUsersConfig()
|
||||
}
|
||||
|
||||
|
||||
void Context::calculateUserSettings()
|
||||
{
|
||||
auto lock = getLock();
|
||||
|
||||
String profile = shared->users.get(client_info.current_user).profile;
|
||||
|
||||
/// 1) Set default settings (hardcoded values)
|
||||
/// NOTE: we ignore global_context settings (from which it is usually copied)
|
||||
/// NOTE: global_context settings are immutable and not auto updated
|
||||
settings = Settings();
|
||||
|
||||
/// 2) Apply settings from default profile
|
||||
auto default_profile_name = getDefaultProfileName();
|
||||
if (profile != default_profile_name)
|
||||
settings.setProfile(default_profile_name, *shared->users_config);
|
||||
|
||||
/// 3) Apply settings from current user
|
||||
settings.setProfile(profile, *shared->users_config);
|
||||
}
|
||||
|
||||
|
||||
void Context::setUser(const String & name, const String & password, const Poco::Net::SocketAddress & address, const String & quota_key)
|
||||
{
|
||||
auto lock = getLock();
|
||||
|
||||
const User & user_props = shared->users.get(name, password, address.host());
|
||||
|
||||
/// 1) Set default (hardcoded) settings values, ignoring global_context settings from which it was copied
|
||||
settings = Settings();
|
||||
|
||||
/// 2) Apply settings from default profile
|
||||
auto default_profile_name = getDefaultProfileName();
|
||||
if (user_props.profile != default_profile_name)
|
||||
settings.setProfile(default_profile_name, *shared->users_config);
|
||||
|
||||
/// 3) Apply settings from current user
|
||||
settings.setProfile(user_props.profile, *shared->users_config);
|
||||
|
||||
setQuota(user_props.quota, quota_key, name, address.host());
|
||||
|
||||
client_info.current_user = name;
|
||||
client_info.current_address = address;
|
||||
|
||||
if (!quota_key.empty())
|
||||
client_info.quota_key = quota_key;
|
||||
|
||||
calculateUserSettings();
|
||||
|
||||
setQuota(user_props.quota, quota_key, name, address.host());
|
||||
}
|
||||
|
||||
|
||||
|
@ -138,6 +138,8 @@ public:
|
||||
|
||||
/// Must be called before getClientInfo.
|
||||
void setUser(const String & name, const String & password, const Poco::Net::SocketAddress & address, const String & quota_key);
|
||||
/// Compute and set actual user settings, client_info.current_user should be set
|
||||
void calculateUserSettings();
|
||||
|
||||
ClientInfo & getClientInfo() { return client_info; };
|
||||
const ClientInfo & getClientInfo() const { return client_info; };
|
||||
|
@ -15,20 +15,21 @@ namespace ErrorCodes
|
||||
BlockIO InterpreterSetQuery::execute()
|
||||
{
|
||||
const ASTSetQuery & ast = typeid_cast<const ASTSetQuery &>(*query_ptr);
|
||||
Context & target = ast.global ? context.getGlobalContext() : context.getSessionContext();
|
||||
executeImpl(ast, target);
|
||||
|
||||
checkAccess(ast);
|
||||
|
||||
if (ast.global)
|
||||
throw Exception("SET GLOBAL command is depricated", ErrorCodes::NOT_IMPLEMENTED);
|
||||
|
||||
Context & target = context.getSessionContext();
|
||||
for (const auto & change : ast.changes)
|
||||
target.setSetting(change.name, change.value);
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
void InterpreterSetQuery::executeForCurrentContext()
|
||||
{
|
||||
const ASTSetQuery & ast = typeid_cast<const ASTSetQuery &>(*query_ptr);
|
||||
executeImpl(ast, context);
|
||||
}
|
||||
|
||||
|
||||
void InterpreterSetQuery::executeImpl(const ASTSetQuery & ast, Context & target)
|
||||
void InterpreterSetQuery::checkAccess(const ASTSetQuery & ast)
|
||||
{
|
||||
/** The `readonly` value is understood as follows:
|
||||
* 0 - everything allowed.
|
||||
@ -40,12 +41,24 @@ void InterpreterSetQuery::executeImpl(const ASTSetQuery & ast, Context & target)
|
||||
throw Exception("Cannot execute SET query in readonly mode", ErrorCodes::READONLY);
|
||||
|
||||
if (context.getSettingsRef().limits.readonly > 1)
|
||||
for (ASTSetQuery::Changes::const_iterator it = ast.changes.begin(); it != ast.changes.end(); ++it)
|
||||
if (it->name == "readonly")
|
||||
{
|
||||
for (const auto & change : ast.changes)
|
||||
{
|
||||
if (change.name == "readonly")
|
||||
throw Exception("Cannot modify 'readonly' setting in readonly mode", ErrorCodes::READONLY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (ASTSetQuery::Changes::const_iterator it = ast.changes.begin(); it != ast.changes.end(); ++it)
|
||||
target.setSetting(it->name, it->value);
|
||||
|
||||
void InterpreterSetQuery::executeForCurrentContext()
|
||||
{
|
||||
const ASTSetQuery & ast = typeid_cast<const ASTSetQuery &>(*query_ptr);
|
||||
|
||||
checkAccess(ast);
|
||||
|
||||
for (const auto & change : ast.changes)
|
||||
context.setSetting(change.name, change.value);
|
||||
}
|
||||
|
||||
|
||||
|
@ -24,6 +24,8 @@ public:
|
||||
*/
|
||||
BlockIO execute() override;
|
||||
|
||||
void checkAccess(const ASTSetQuery & ast);
|
||||
|
||||
/** Set setting for current context (query context).
|
||||
* It is used for interpretation of SETTINGS clause in SELECT query.
|
||||
*/
|
||||
|
@ -317,22 +317,22 @@ void Users::loadFromConfig(Poco::Util::AbstractConfiguration & config)
|
||||
cont[key] = User(key, "users." + key, config);
|
||||
}
|
||||
|
||||
const User & Users::get(const String & name, const String & password, const Poco::Net::IPAddress & address) const
|
||||
const User & Users::get(const String & user_name, const String & password, const Poco::Net::IPAddress & address) const
|
||||
{
|
||||
Container::const_iterator it = cont.find(name);
|
||||
auto it = cont.find(user_name);
|
||||
|
||||
if (cont.end() == it)
|
||||
throw Exception("Unknown user " + name, ErrorCodes::UNKNOWN_USER);
|
||||
throw Exception("Unknown user " + user_name, ErrorCodes::UNKNOWN_USER);
|
||||
|
||||
if (!it->second.addresses.contains(address))
|
||||
throw Exception("User " + name + " is not allowed to connect from address " + address.toString(), ErrorCodes::IP_ADDRESS_NOT_ALLOWED);
|
||||
throw Exception("User " + user_name + " is not allowed to connect from address " + address.toString(), ErrorCodes::IP_ADDRESS_NOT_ALLOWED);
|
||||
|
||||
auto on_wrong_password = [&]()
|
||||
{
|
||||
if (password.empty())
|
||||
throw Exception("Password required for user " + name, ErrorCodes::REQUIRED_PASSWORD);
|
||||
throw Exception("Password required for user " + user_name, ErrorCodes::REQUIRED_PASSWORD);
|
||||
else
|
||||
throw Exception("Wrong password for user " + name, ErrorCodes::WRONG_PASSWORD);
|
||||
throw Exception("Wrong password for user " + user_name, ErrorCodes::WRONG_PASSWORD);
|
||||
};
|
||||
|
||||
if (!it->second.password_sha256_hex.empty())
|
||||
@ -364,6 +364,18 @@ const User & Users::get(const String & name, const String & password, const Poco
|
||||
return it->second;
|
||||
}
|
||||
|
||||
|
||||
const User & Users::get(const String & user_name)
|
||||
{
|
||||
auto it = cont.find(user_name);
|
||||
|
||||
if (cont.end() == it)
|
||||
throw Exception("Unknown user " + user_name, ErrorCodes::UNKNOWN_USER);
|
||||
|
||||
return it->second;
|
||||
}
|
||||
|
||||
|
||||
bool Users::isAllowedDatabase(const std::string & user_name, const std::string & database_name) const
|
||||
{
|
||||
auto it = cont.find(user_name);
|
||||
|
@ -83,10 +83,14 @@ private:
|
||||
public:
|
||||
void loadFromConfig(Poco::Util::AbstractConfiguration & config);
|
||||
|
||||
const User & get(const String & name, const String & password, const Poco::Net::IPAddress & address) const;
|
||||
/// Find user and make authorize checks
|
||||
const User & get(const String & user_name, const String & password, const Poco::Net::IPAddress & address) const;
|
||||
|
||||
/// Just find user
|
||||
const User & get(const String & user_name);
|
||||
|
||||
/// Check if the user has access to the database.
|
||||
bool isAllowedDatabase(const std::string & user_name, const std::string & database_name) const;
|
||||
bool isAllowedDatabase(const String & user_name, const String & database_name) const;
|
||||
};
|
||||
|
||||
|
||||
|
@ -642,12 +642,12 @@ private:
|
||||
if (set_query)
|
||||
{
|
||||
/// Save all changes in settings to avoid losing them if the connection is lost.
|
||||
for (ASTSetQuery::Changes::const_iterator it = set_query->changes.begin(); it != set_query->changes.end(); ++it)
|
||||
for (const auto & change : set_query->changes)
|
||||
{
|
||||
if (it->name == "profile")
|
||||
current_profile = it->value.safeGet<String>();
|
||||
if (change.name == "profile")
|
||||
current_profile = change.value.safeGet<String>();
|
||||
else
|
||||
context.setSetting(it->name, it->value);
|
||||
context.setSetting(change.name, change.value);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,27 @@
|
||||
Settings
|
||||
========
|
||||
|
||||
In this section, we review settings that you can make using a SET query or in a config file. Remember that these settings can be set for a session or globally. Settings that can only be made in the server config file are not covered here.
|
||||
In this section, we review settings that you can make using a SET query or in a config file.
|
||||
Remember that these settings can be set for a session or globally.
|
||||
Settings that can only be made in the server config file are not covered here.
|
||||
|
||||
|
||||
There are three ways to setup settings (sorted by priority):
|
||||
|
||||
* Settings in server configuration files.
|
||||
|
||||
They are set in user profiles.
|
||||
|
||||
* Session-level settings.
|
||||
|
||||
Use ``SET setting=value`` command in ClickHouse console client running in interactive mode.
|
||||
Also sessions are supported in HTTP interface (you need to pass ``session_id`` HTTP parameter)
|
||||
|
||||
* Query-level settings.
|
||||
|
||||
Use ``--setting=value`` command line parameters in non-iteractive mode of ClickHouse console client.
|
||||
Use HTTP parameters (``URL?setting_1=value&setting_2=value...``) with HTTP ClickHouse interface.
|
||||
|
||||
|
||||
.. toctree::
|
||||
:glob:
|
||||
|
@ -518,10 +518,8 @@ SET
|
||||
Lets you set the 'param' setting to 'value'. You can also make all the settings from the specified settings profile in a single query. To do this, specify 'profile' as the setting name. For more information, see the section "Settings". The setting is made for the session, or for the server (globally) if GLOBAL is specified.
|
||||
When making a global setting, the setting is not applied to sessions already running, including the current session. It will only be used for new sessions.
|
||||
|
||||
Settings made using SET GLOBAL have a lower priority compared with settings made in the config file in the user profile. In other words, user settings can't be overridden by SET GLOBAL.
|
||||
|
||||
When the server is restarted, global settings made using SET GLOBAL are lost.
|
||||
To make settings that persist after a server restart, you can only use the server's config file. (This can't be done using a SET query.)
|
||||
When the server is restarted, settings made using SET are lost.
|
||||
To make settings that persist after a server restart, you can only use the server's config file.
|
||||
|
||||
OPTIMIZE
|
||||
~~~~~~~~
|
||||
|
@ -1,22 +1,25 @@
|
||||
Настройки
|
||||
=========
|
||||
|
||||
Описанные в разделе настройки могут быть заданы следующими способами:
|
||||
Все настройки, описанные ниже, могут быть заданы несколькими способами.
|
||||
Настройки задаются послойно, т.е. каждый следующий слой перезаписывает предыдущие настройки.
|
||||
|
||||
* Глобально.
|
||||
|
||||
В конфигурационных файлах сервера.
|
||||
Способы задания настроек, упорядоченные по их приоритету:
|
||||
|
||||
* Настройки в конфигурационных файлах сервера.
|
||||
|
||||
Задаются через профили пользователей.
|
||||
|
||||
* Для сессии.
|
||||
|
||||
При запуске консольного клиента ClickHouse в интерактивном режиме отправьте запрос ``SET setting=value``.
|
||||
|
||||
Из консольного клиента ClickHouse в интерактивном режиме отправьте запрос ``SET setting=value``.
|
||||
Аналогично можно использовать ClickHouse-сессии в HTTP-протоколе, для этого необходимо указывать HTTP-праметр ``session_id``.
|
||||
|
||||
* Для запроса.
|
||||
|
||||
|
||||
* При запуске консольного клиента ClickHouse в неинтерактивном режиме установите параметр запуска ``--setting=value``.
|
||||
* При использовании HTTP API передавайте cgi-параметры (``URL?setting_1=value&setting_2=value...``).
|
||||
|
||||
|
||||
Настройки, которые можно задать только в конфигурационном файле сервера, в разделе не рассматриваются.
|
||||
|
||||
.. toctree::
|
||||
|
@ -524,16 +524,15 @@ SET
|
||||
|
||||
.. code-block:: sql
|
||||
|
||||
SET [GLOBAL] param = value
|
||||
SET param = value
|
||||
|
||||
Позволяет установить настройку ``param`` в значение ``value``. Также можно одним запросом установить все настройки из заданного профиля настроек - для этого, укажите в качестве имени настройки profile. Подробнее смотри раздел "Настройки".
|
||||
Настройка устанавливается на сессию, или на сервер (глобально), если указано ``GLOBAL``.
|
||||
При установке глобальной настройки, настройка на все уже запущенные сессии, включая текущую сессию, не устанавливается, а будет использована только для новых сессий.
|
||||
|
||||
Настройки, заданные с помощью ``SET GLOBAL`` имеют меньший приоритет по сравнению с настройками, указанными в профиле пользователя, в конфигурационном файле. То есть, переопределить такие настройки с помощью ``SET GLOBAL`` невозможно.
|
||||
|
||||
При перезапуске сервера, теряются глобальные настройки, установленные с помощью ``SET GLOBAL``.
|
||||
Установить настройки, которые переживут перезапуск сервера, можно только с помощью конфигурационного файла сервера. (Это не может быть сделано с помощью запроса ``SET``.)
|
||||
При перезапуске сервера, теряются настройки, установленные с помощью ``SET``.
|
||||
Установить настройки, которые переживут перезапуск сервера, можно только с помощью конфигурационного файла сервера.
|
||||
|
||||
OPTIMIZE
|
||||
~~~~~~~~
|
||||
|
Loading…
Reference in New Issue
Block a user