Fix reusing connection after changing user's default settings via ALTER USER or ALTER SETTINGS PROFILE.

This fixes integration test "test_settings_constraints_distributed".
This commit is contained in:
Vitaly Baranov 2020-03-31 17:45:46 +03:00
parent 23c34f8b5e
commit 5cd7b58499
4 changed files with 27 additions and 2 deletions

View File

@ -147,6 +147,10 @@ void TCPHandler::runImpl()
if (server.isCancelled() || in->eof())
break;
/// receiveHello() has set the default settings for the current user,
/// but this default itself could change while we were waiting for a packet from the client.
connection_context.resetSettingsToDefault();
/// Set context of request.
query_context = connection_context;

View File

@ -540,14 +540,14 @@ std::shared_ptr<const ContextAccess> ContextAccess::getFullAccess()
std::shared_ptr<const Settings> ContextAccess::getDefaultSettings() const
{
std::lock_guard lock{mutex};
return enabled_settings->getSettings();
return enabled_settings ? enabled_settings->getSettings() : nullptr;
}
std::shared_ptr<const SettingsConstraints> ContextAccess::getSettingsConstraints() const
{
std::lock_guard lock{mutex};
return enabled_settings->getConstraints();
return enabled_settings ? enabled_settings->getConstraints() : nullptr;
}
}

View File

@ -909,6 +909,7 @@ void Context::setSettings(const Settings & settings_)
auto old_allow_introspection_functions = settings.allow_introspection_functions;
settings = settings_;
active_default_settings = nullptr;
if ((settings.readonly != old_readonly) || (settings.allow_ddl != old_allow_ddl) || (settings.allow_introspection_functions != old_allow_introspection_functions))
calculateAccessRights();
@ -918,6 +919,7 @@ void Context::setSettings(const Settings & settings_)
void Context::setSetting(const StringRef & name, const String & value)
{
auto lock = getLock();
active_default_settings = nullptr;
if (name == "profile")
{
setProfile(value);
@ -933,6 +935,7 @@ void Context::setSetting(const StringRef & name, const String & value)
void Context::setSetting(const StringRef & name, const Field & value)
{
auto lock = getLock();
active_default_settings = nullptr;
if (name == "profile")
{
setProfile(value.safeGet<String>());
@ -959,6 +962,20 @@ void Context::applySettingsChanges(const SettingsChanges & changes)
}
void Context::resetSettingsToDefault()
{
auto lock = getLock();
auto default_settings = getAccess()->getDefaultSettings();
if (default_settings && (default_settings == active_default_settings))
return;
if (default_settings)
setSettings(*default_settings);
else
setSettings(Settings{});
active_default_settings = default_settings;
}
void Context::checkSettingsConstraints(const SettingChange & change) const
{
if (auto settings_constraints = getSettingsConstraints())

View File

@ -151,6 +151,7 @@ private:
bool use_default_roles = false;
std::shared_ptr<const ContextAccess> access;
std::shared_ptr<const EnabledRowPolicies> initial_row_policy;
std::shared_ptr<const Settings> active_default_settings;
String current_database;
Settings settings; /// Setting for query execution.
using ProgressCallback = std::function<void(const Progress & progress)>;
@ -345,6 +346,9 @@ public:
void applySettingChange(const SettingChange & change);
void applySettingsChanges(const SettingsChanges & changes);
/// Reset settings to the default values for the current user.
void resetSettingsToDefault();
/// Checks the constraints.
void checkSettingsConstraints(const SettingChange & change) const;
void checkSettingsConstraints(const SettingsChanges & changes) const;