2015-04-16 06:12:35 +00:00
# include <map>
# include <set>
2019-02-04 23:18:04 +00:00
# include <optional>
# include <memory>
2015-04-16 06:12:35 +00:00
# include <Poco/Mutex.h>
2017-05-24 19:31:50 +00:00
# include <Poco/UUID.h>
2017-01-21 04:24:28 +00:00
# include <Poco/Net/IPAddress.h>
2017-04-01 09:19:00 +00:00
# include <Common/Macros.h>
# include <Common/escapeForFileName.h>
2017-06-02 18:48:33 +00:00
# include <Common/setThreadName.h>
2017-04-01 09:19:00 +00:00
# include <Common/Stopwatch.h>
# include <Common/formatReadable.h>
2019-07-28 15:30:38 +00:00
# include <Common/thread_local_rng.h>
2018-12-21 12:17:30 +00:00
# include <Compression/ICompressionCodec.h>
2018-08-20 15:34:37 +00:00
# include <Core/BackgroundSchedulePool.h>
2018-06-10 19:22:49 +00:00
# include <Formats/FormatFactory.h>
2017-10-13 01:02:16 +00:00
# include <Databases/IDatabase.h>
2017-04-01 09:19:00 +00:00
# include <Storages/IStorage.h>
# include <Storages/MarkCache.h>
# include <Storages/MergeTree/BackgroundProcessingPool.h>
# include <Storages/MergeTree/MergeList.h>
# include <Storages/MergeTree/MergeTreeSettings.h>
2018-12-21 12:17:30 +00:00
# include <Storages/CompressionCodecSelector.h>
2018-03-01 01:49:36 +00:00
# include <TableFunctions/TableFunctionFactory.h>
2018-05-21 13:49:54 +00:00
# include <Interpreters/ActionLocksManager.h>
2019-03-22 12:08:30 +00:00
# include <Core/Settings.h>
2018-08-30 16:31:20 +00:00
# include <Interpreters/ExpressionJIT.h>
2019-09-26 16:12:15 +00:00
# include <Interpreters/UsersManager.h>
2017-04-01 09:19:00 +00:00
# include <Interpreters/Quota.h>
2019-09-26 16:12:15 +00:00
# include <Dictionaries/Embedded/GeoDictionariesLoader.h>
2017-04-01 09:19:00 +00:00
# include <Interpreters/EmbeddedDictionaries.h>
2019-09-30 16:12:08 +00:00
# include <Interpreters/ExternalLoaderXMLConfigRepository.h>
2019-10-15 14:09:57 +00:00
# include <Interpreters/ExternalLoaderDatabaseConfigRepository.h>
2019-09-26 10:41:33 +00:00
# include <Interpreters/ExternalDictionariesLoader.h>
2019-09-26 10:23:14 +00:00
# include <Interpreters/ExternalModelsLoader.h>
2018-08-30 16:31:20 +00:00
# include <Interpreters/ExpressionActions.h>
2017-04-01 09:19:00 +00:00
# include <Interpreters/ProcessList.h>
# include <Interpreters/Cluster.h>
# include <Interpreters/InterserverIOHandler.h>
2019-10-30 21:37:28 +00:00
# include <Access/SettingsConstraints.h>
2017-06-05 13:59:38 +00:00
# include <Interpreters/SystemLog.h>
2017-04-01 09:19:00 +00:00
# include <Interpreters/Context.h>
2019-02-21 16:41:27 +00:00
# include <Interpreters/DDLWorker.h>
2018-04-19 13:56:14 +00:00
# include <Common/DNSResolver.h>
2017-04-01 09:19:00 +00:00
# include <IO/ReadBufferFromFile.h>
# include <IO/UncompressedCache.h>
# include <Parsers/ASTCreateQuery.h>
# include <Parsers/ParserCreateQuery.h>
# include <Parsers/parseQuery.h>
2019-07-29 22:26:44 +00:00
# include <Common/StackTrace.h>
2018-02-28 20:34:25 +00:00
# include <Common/Config/ConfigProcessor.h>
2017-06-19 20:06:35 +00:00
# include <Common/ZooKeeper/ZooKeeper.h>
2018-11-22 15:59:00 +00:00
# include <Common/ShellCommand.h>
2019-07-10 20:47:39 +00:00
# include <Common/TraceCollector.h>
2017-06-05 13:59:38 +00:00
# include <common/logger_useful.h>
2015-04-16 06:12:35 +00:00
2014-08-22 01:01:28 +00:00
2016-12-07 22:49:42 +00:00
namespace ProfileEvents
{
2017-04-01 07:20:54 +00:00
extern const Event ContextLock ;
2018-08-31 12:39:27 +00:00
extern const Event CompiledCacheSizeBytes ;
2016-12-07 22:49:42 +00:00
}
namespace CurrentMetrics
{
2017-04-01 07:20:54 +00:00
extern const Metric ContextLockWait ;
extern const Metric MemoryTrackingForMerges ;
2016-12-07 22:49:42 +00:00
}
2012-08-02 17:33:31 +00:00
namespace DB
{
2016-01-11 21:46:36 +00:00
namespace ErrorCodes
{
2017-04-01 07:20:54 +00:00
extern const int DATABASE_ACCESS_DENIED ;
extern const int UNKNOWN_DATABASE ;
extern const int UNKNOWN_TABLE ;
extern const int TABLE_ALREADY_EXISTS ;
extern const int TABLE_WAS_NOT_DROPPED ;
extern const int DATABASE_ALREADY_EXISTS ;
extern const int THERE_IS_NO_SESSION ;
2018-03-02 05:44:17 +00:00
extern const int THERE_IS_NO_QUERY ;
2017-04-01 07:20:54 +00:00
extern const int NO_ELEMENTS_IN_CONFIG ;
extern const int DDL_GUARD_IS_ACTIVE ;
extern const int TABLE_SIZE_EXCEEDS_MAX_DROP_SIZE_LIMIT ;
2018-08-01 17:41:18 +00:00
extern const int PARTITION_SIZE_EXCEEDS_MAX_DROP_SIZE_LIMIT ;
2017-06-02 18:48:33 +00:00
extern const int SESSION_NOT_FOUND ;
extern const int SESSION_IS_LOCKED ;
2018-03-23 19:56:24 +00:00
extern const int CANNOT_GET_CREATE_TABLE_QUERY ;
2019-09-03 19:53:59 +00:00
extern const int LOGICAL_ERROR ;
2019-10-19 20:36:35 +00:00
extern const int SCALAR_ALREADY_EXISTS ;
extern const int UNKNOWN_SCALAR ;
2016-01-11 21:46:36 +00:00
}
2015-04-16 06:12:35 +00:00
2016-11-23 20:41:39 +00:00
/** Set of known objects (environment), that could be used in query.
* Shared ( global ) part . Order of members ( especially , order of destruction ) is very important .
2015-04-16 06:12:35 +00:00
*/
struct ContextShared
{
2017-04-01 07:20:54 +00:00
Logger * log = & Logger : : get ( " Context " ) ;
/// For access of most of shared objects. Recursive mutex.
2018-03-01 01:49:36 +00:00
mutable std : : recursive_mutex mutex ;
2017-04-01 07:20:54 +00:00
/// Separate mutex for access of dictionaries. Separate mutex to avoid locks when server doing request to itself.
mutable std : : mutex embedded_dictionaries_mutex ;
2019-06-02 12:11:01 +00:00
mutable std : : mutex external_dictionaries_mutex ;
2017-10-17 10:44:46 +00:00
mutable std : : mutex external_models_mutex ;
2017-04-01 07:20:54 +00:00
/// Separate mutex for re-initialization of zookeer session. This operation could take a long time and must not interfere with another operations.
mutable std : : mutex zookeeper_mutex ;
2017-04-02 17:37:49 +00:00
mutable zkutil : : ZooKeeperPtr zookeeper ; /// Client for ZooKeeper.
2017-04-01 07:20:54 +00:00
2017-04-02 17:37:49 +00:00
String interserver_io_host ; /// The host name by which this server is available for other servers.
2017-09-07 21:04:48 +00:00
UInt16 interserver_io_port = 0 ; /// and port.
2018-07-26 15:10:57 +00:00
String interserver_io_user ;
String interserver_io_password ;
2018-07-30 18:32:21 +00:00
String interserver_scheme ; /// http or https
2017-04-01 07:20:54 +00:00
2017-04-02 17:37:49 +00:00
String path ; /// Path to the data directory, with a slash at the end.
String tmp_path ; /// The path to the temporary files that occur when processing the request.
2017-06-02 21:01:17 +00:00
String flags_path ; /// Path to the directory with some control flags for server maintenance.
2018-04-19 05:32:09 +00:00
String user_files_path ; /// Path to the directory with user provided files, usable by 'file' table function.
2017-08-24 14:51:13 +00:00
ConfigurationPtr config ; /// Global configuration settings.
2017-04-02 17:37:49 +00:00
Databases databases ; /// List of databases and tables in them.
2019-02-04 23:18:04 +00:00
mutable std : : optional < EmbeddedDictionaries > embedded_dictionaries ; /// Metrica's dictionaries. Have lazy initialization.
2019-09-26 10:41:33 +00:00
mutable std : : optional < ExternalDictionariesLoader > external_dictionaries_loader ;
2019-09-26 10:23:14 +00:00
mutable std : : optional < ExternalModelsLoader > external_models_loader ;
2017-04-01 07:20:54 +00:00
String default_profile_name ; /// Default profile name used for default values.
2018-02-01 13:52:29 +00:00
String system_profile_name ; /// Profile used by system processes
2019-09-26 16:12:15 +00:00
std : : unique_ptr < UsersManager > users_manager ; /// Known users.
2017-04-02 17:37:49 +00:00
Quotas quotas ; /// Known quotas for resource use.
mutable UncompressedCachePtr uncompressed_cache ; /// The cache of decompressed blocks.
mutable MarkCachePtr mark_cache ; /// Cache of marks in compressed files.
ProcessList process_list ; /// Executing queries at the moment.
MergeList merge_list ; /// The list of executable merge (for (Replicated)?MergeTree)
ViewDependencies view_dependencies ; /// Current dependencies
ConfigurationPtr users_config ; /// Config with the users, profiles and quotas sections.
InterserverIOHandler interserver_io_handler ; /// Handler for interserver communication.
2019-02-04 23:18:04 +00:00
std : : optional < BackgroundProcessingPool > background_pool ; /// The thread pool for the background work performed by the tables.
2019-11-14 11:10:17 +00:00
std : : optional < BackgroundProcessingPool > background_move_pool ; /// The thread pool for the background moves performed by the tables.
2019-02-04 23:18:04 +00:00
std : : optional < BackgroundSchedulePool > schedule_pool ; /// A thread pool that can run different jobs in background (used in replicated tables)
2018-03-13 23:44:23 +00:00
MultiVersion < Macros > macros ; /// Substitutions extracted from config.
2019-02-21 16:41:27 +00:00
std : : unique_ptr < DDLWorker > ddl_worker ; /// Process ddl commands from zk.
2017-10-13 01:02:16 +00:00
/// Rules for selecting the compression settings, depending on the size of the part.
2018-12-21 12:17:30 +00:00
mutable std : : unique_ptr < CompressionCodecSelector > compression_codec_selector ;
2019-05-24 19:03:07 +00:00
/// Storage disk chooser
2019-07-23 13:34:17 +00:00
mutable std : : unique_ptr < DiskSpace : : DiskSelector > merge_tree_disk_selector ;
2019-05-24 19:03:07 +00:00
/// Storage policy chooser
2019-07-23 13:34:17 +00:00
mutable std : : unique_ptr < DiskSpace : : StoragePolicySelector > merge_tree_storage_policy_selector ;
2019-09-04 12:44:12 +00:00
2019-11-20 16:40:27 +00:00
std : : optional < MergeTreeSettings > merge_tree_settings ; /// Settings of MergeTree* engines.
std : : atomic_size_t max_table_size_to_drop = 50000000000lu ; /// Protects MergeTree tables from accidental DROP (50GB by default)
std : : atomic_size_t max_partition_size_to_drop = 50000000000lu ; /// Protects MergeTree partitions from accidental DROP (50GB by default)
2017-11-10 06:48:28 +00:00
String format_schema_path ; /// Path to a directory that contains schema files used by input formats.
2018-05-21 13:49:54 +00:00
ActionLocksManagerPtr action_locks_manager ; /// Set of storages' action lockers
2019-11-20 16:40:27 +00:00
std : : optional < SystemLogs > system_logs ; /// Used to log queries and operations on parts
2017-06-07 12:54:35 +00:00
2019-07-10 20:47:39 +00:00
std : : unique_ptr < TraceCollector > trace_collector ; /// Thread collecting traces from threads executing queries
2019-02-03 09:57:12 +00:00
2017-06-02 21:01:17 +00:00
/// Named sessions. The user could specify session identifier to reuse settings and temporary tables in subsequent requests.
class SessionKeyHash
{
2017-06-02 18:48:33 +00:00
public :
size_t operator ( ) ( const Context : : SessionKey & key ) const
{
2018-07-08 04:54:37 +00:00
SipHash hash ;
hash . update ( key . first ) ;
hash . update ( key . second ) ;
return hash . get64 ( ) ;
2017-06-02 18:48:33 +00:00
}
} ;
using Sessions = std : : unordered_map < Context : : SessionKey , std : : shared_ptr < Context > , SessionKeyHash > ;
using CloseTimes = std : : deque < std : : vector < Context : : SessionKey > > ;
mutable Sessions sessions ;
mutable CloseTimes close_times ;
std : : chrono : : steady_clock : : duration close_interval = std : : chrono : : seconds ( 1 ) ;
std : : chrono : : steady_clock : : time_point close_cycle_time = std : : chrono : : steady_clock : : now ( ) ;
UInt64 close_cycle = 0 ;
2017-04-01 07:20:54 +00:00
/// Clusters for distributed tables
/// Initialized on demand (on distributed storages initialization) since Settings should be initialized
std : : unique_ptr < Clusters > clusters ;
ConfigurationPtr clusters_config ; /// Soteres updated configs
mutable std : : mutex clusters_mutex ; /// Guards clusters and clusters_config
2018-08-30 16:31:20 +00:00
# if USE_EMBEDDED_COMPILER
std : : shared_ptr < CompiledExpressionCache > compiled_expression_cache ;
# endif
2017-04-01 07:20:54 +00:00
bool shutdown_called = false ;
2017-04-02 17:37:49 +00:00
/// Do not allow simultaneous execution of DDL requests on the same table.
2019-10-22 10:47:43 +00:00
/// database -> object -> (mutex, counter), counter: how many threads are running a query on the table at the same time
2018-09-24 18:02:25 +00:00
/// For the duration of the operation, an element is placed here, and an object is returned,
2018-09-19 09:34:07 +00:00
/// which deletes the element in the destructor when counter becomes zero.
/// In case the element already exists, waits, when query will be executed in other thread. See class DDLGuard below.
2017-04-01 07:20:54 +00:00
using DDLGuards = std : : unordered_map < String , DDLGuard : : Map > ;
DDLGuards ddl_guards ;
2017-04-02 17:37:49 +00:00
/// If you capture mutex and ddl_guards_mutex, then you need to grab them strictly in this order.
2017-04-01 07:20:54 +00:00
mutable std : : mutex ddl_guards_mutex ;
Stopwatch uptime_watch ;
Context : : ApplicationType application_type = Context : : ApplicationType : : SERVER ;
2018-11-22 15:59:00 +00:00
/// vector of xdbc-bridge commands, they will be killed when Context will be destroyed
std : : vector < std : : unique_ptr < ShellCommand > > bridge_commands ;
2018-03-13 10:41:47 +00:00
Context : : ConfigReloadCallback config_reload_callback ;
2019-09-26 16:12:15 +00:00
ContextShared ( )
: macros ( std : : make_unique < Macros > ( ) )
2017-06-19 20:35:53 +00:00
{
2017-07-10 04:34:14 +00:00
/// TODO: make it singleton (?)
2017-06-19 20:35:53 +00:00
static std : : atomic < size_t > num_calls { 0 } ;
if ( + + num_calls > 1 )
{
std : : cerr < < " Attempting to create multiple ContextShared instances. Stack trace: \n " < < StackTrace ( ) . toString ( ) ;
std : : cerr . flush ( ) ;
std : : terminate ( ) ;
}
2017-11-27 21:31:13 +00:00
initialize ( ) ;
2017-06-19 20:35:53 +00:00
}
2017-04-01 07:20:54 +00:00
~ ContextShared ( )
{
try
{
shutdown ( ) ;
}
catch ( . . . )
{
tryLogCurrentException ( __PRETTY_FUNCTION__ ) ;
}
}
2017-04-02 17:37:49 +00:00
/** Perform a complex job of destroying objects in advance.
2017-04-01 07:20:54 +00:00
*/
void shutdown ( )
{
if ( shutdown_called )
return ;
shutdown_called = true ;
2019-06-21 17:25:47 +00:00
/** After system_logs have been shut down it is guaranteed that no system table gets created or written to.
* Note that part changes at shutdown won ' t be logged to part log .
*/
2019-03-21 19:22:38 +00:00
2019-06-21 19:24:30 +00:00
if ( system_logs )
system_logs - > shutdown ( ) ;
2019-02-04 14:08:39 +00:00
2017-04-02 17:37:49 +00:00
/** At this point, some tables may have threads that block our mutex.
2019-03-21 19:22:38 +00:00
* To shutdown them correctly , we will copy the current list of tables ,
2017-04-02 17:37:49 +00:00
* and ask them all to finish their work .
* Then delete all objects with tables .
2017-04-01 07:20:54 +00:00
*/
Databases current_databases ;
{
2018-02-25 02:23:04 +00:00
std : : lock_guard lock ( mutex ) ;
2017-04-01 07:20:54 +00:00
current_databases = databases ;
}
2019-03-21 19:22:38 +00:00
/// We still hold "databases" in Context (instead of std::move) for Buffer tables to flush data correctly.
2017-04-01 07:20:54 +00:00
for ( auto & database : current_databases )
database . second - > shutdown ( ) ;
{
2018-02-25 02:23:04 +00:00
std : : lock_guard lock ( mutex ) ;
2017-04-01 07:20:54 +00:00
databases . clear ( ) ;
}
2019-02-04 23:18:04 +00:00
/// Preemptive destruction is important, because these objects may have a refcount to ContextShared (cyclic reference).
/// TODO: Get rid of this.
2019-06-30 01:56:16 +00:00
system_logs . reset ( ) ;
2019-02-04 23:18:04 +00:00
embedded_dictionaries . reset ( ) ;
2019-09-26 10:41:33 +00:00
external_dictionaries_loader . reset ( ) ;
2019-09-26 10:23:14 +00:00
external_models_loader . reset ( ) ;
2019-02-04 23:18:04 +00:00
background_pool . reset ( ) ;
2019-11-14 11:10:17 +00:00
background_move_pool . reset ( ) ;
2019-02-04 23:18:04 +00:00
schedule_pool . reset ( ) ;
2019-02-21 16:41:27 +00:00
ddl_worker . reset ( ) ;
2019-02-09 22:26:51 +00:00
2019-07-10 20:47:39 +00:00
/// Stop trace collector if any
trace_collector . reset ( ) ;
2017-04-01 07:20:54 +00:00
}
2017-11-27 21:31:13 +00:00
2019-07-06 20:42:03 +00:00
bool hasTraceCollector ( )
{
2019-07-06 20:29:00 +00:00
return trace_collector ! = nullptr ;
}
2019-05-19 20:22:44 +00:00
void initializeTraceCollector ( std : : shared_ptr < TraceLog > trace_log )
2019-02-09 22:40:47 +00:00
{
2019-07-06 20:29:00 +00:00
if ( trace_log = = nullptr )
return ;
2019-07-10 20:47:39 +00:00
trace_collector = std : : make_unique < TraceCollector > ( trace_log ) ;
2017-04-01 07:20:54 +00:00
}
2017-11-27 21:31:13 +00:00
private :
void initialize ( )
{
2019-09-26 16:12:15 +00:00
users_manager = std : : make_unique < UsersManager > ( ) ;
2017-11-27 21:31:13 +00:00
}
2015-04-16 06:12:35 +00:00
} ;
2017-06-19 20:31:23 +00:00
Context : : Context ( ) = default ;
2019-04-24 22:52:08 +00:00
Context : : Context ( const Context & ) = default ;
Context & Context : : operator = ( const Context & ) = default ;
2017-06-19 20:31:23 +00:00
2019-09-26 16:12:15 +00:00
Context Context : : createGlobal ( )
2015-04-16 06:12:35 +00:00
{
2017-06-19 20:31:23 +00:00
Context res ;
res . quota = std : : make_shared < QuotaForIntervals > ( ) ;
2019-09-27 09:02:06 +00:00
res . shared = std : : make_shared < ContextShared > ( ) ;
2017-06-19 20:31:23 +00:00
return res ;
2015-04-16 06:12:35 +00:00
}
2019-02-04 14:08:39 +00:00
Context : : ~ Context ( ) = default ;
2015-04-16 06:12:35 +00:00
2018-03-01 01:49:36 +00:00
InterserverIOHandler & Context : : getInterserverIOHandler ( ) { return shared - > interserver_io_handler ; }
2016-12-07 22:49:42 +00:00
2018-03-01 01:49:36 +00:00
std : : unique_lock < std : : recursive_mutex > Context : : getLock ( ) const
2016-12-07 22:49:42 +00:00
{
2017-04-01 07:20:54 +00:00
ProfileEvents : : increment ( ProfileEvents : : ContextLock ) ;
CurrentMetrics : : Increment increment { CurrentMetrics : : ContextLockWait } ;
2018-03-01 01:49:36 +00:00
return std : : unique_lock ( shared - > mutex ) ;
2016-12-07 22:49:42 +00:00
}
2018-03-01 01:49:36 +00:00
ProcessList & Context : : getProcessList ( ) { return shared - > process_list ; }
const ProcessList & Context : : getProcessList ( ) const { return shared - > process_list ; }
MergeList & Context : : getMergeList ( ) { return shared - > merge_list ; }
const MergeList & Context : : getMergeList ( ) const { return shared - > merge_list ; }
2015-04-16 06:12:35 +00:00
2016-03-19 01:18:49 +00:00
const Databases Context : : getDatabases ( ) const
{
2017-04-01 07:20:54 +00:00
auto lock = getLock ( ) ;
return shared - > databases ;
2016-03-19 01:18:49 +00:00
}
Databases Context : : getDatabases ( )
{
2017-04-01 07:20:54 +00:00
auto lock = getLock ( ) ;
return shared - > databases ;
2016-03-19 01:18:49 +00:00
}
2017-01-05 16:34:05 +00:00
2017-06-02 18:48:33 +00:00
Context : : SessionKey Context : : getSessionKey ( const String & session_id ) const
{
auto & user_name = client_info . current_user ;
if ( user_name . empty ( ) )
throw Exception ( " Empty user name. " , ErrorCodes : : LOGICAL_ERROR ) ;
return SessionKey ( user_name , session_id ) ;
}
2017-06-02 21:01:17 +00:00
void Context : : scheduleCloseSession ( const Context : : SessionKey & key , std : : chrono : : steady_clock : : duration timeout )
2017-06-02 18:48:33 +00:00
{
const UInt64 close_index = timeout / shared - > close_interval + 1 ;
const auto new_close_cycle = shared - > close_cycle + close_index ;
2017-06-02 21:01:17 +00:00
if ( session_close_cycle ! = new_close_cycle )
2017-06-02 18:48:33 +00:00
{
2017-06-02 21:01:17 +00:00
session_close_cycle = new_close_cycle ;
2017-06-02 18:48:33 +00:00
if ( shared - > close_times . size ( ) < close_index + 1 )
shared - > close_times . resize ( close_index + 1 ) ;
shared - > close_times [ close_index ] . emplace_back ( key ) ;
}
}
std : : shared_ptr < Context > Context : : acquireSession ( const String & session_id , std : : chrono : : steady_clock : : duration timeout , bool session_check ) const
{
auto lock = getLock ( ) ;
const auto & key = getSessionKey ( session_id ) ;
auto it = shared - > sessions . find ( key ) ;
if ( it = = shared - > sessions . end ( ) )
{
if ( session_check )
throw Exception ( " Session not found. " , ErrorCodes : : SESSION_NOT_FOUND ) ;
2018-06-06 17:35:35 +00:00
auto new_session = std : : make_shared < Context > ( * this ) ;
2017-06-02 18:48:33 +00:00
2017-06-02 21:01:17 +00:00
new_session - > scheduleCloseSession ( key , timeout ) ;
2017-06-02 18:48:33 +00:00
it = shared - > sessions . insert ( std : : make_pair ( key , std : : move ( new_session ) ) ) . first ;
}
else if ( it - > second - > client_info . current_user ! = client_info . current_user )
{
throw Exception ( " Session belongs to a different user " , ErrorCodes : : LOGICAL_ERROR ) ;
}
const auto & session = it - > second ;
2017-06-02 21:01:17 +00:00
if ( session - > session_is_used )
2017-06-02 18:48:33 +00:00
throw Exception ( " Session is locked by a concurrent client. " , ErrorCodes : : SESSION_IS_LOCKED ) ;
2017-06-02 21:01:17 +00:00
session - > session_is_used = true ;
2017-06-02 18:48:33 +00:00
session - > client_info = client_info ;
return session ;
}
void Context : : releaseSession ( const String & session_id , std : : chrono : : steady_clock : : duration timeout )
{
auto lock = getLock ( ) ;
2017-06-02 21:01:17 +00:00
session_is_used = false ;
scheduleCloseSession ( getSessionKey ( session_id ) , timeout ) ;
2017-06-02 18:48:33 +00:00
}
std : : chrono : : steady_clock : : duration Context : : closeSessions ( ) const
{
auto lock = getLock ( ) ;
const auto now = std : : chrono : : steady_clock : : now ( ) ;
if ( now < shared - > close_cycle_time )
return shared - > close_cycle_time - now ;
const auto current_cycle = shared - > close_cycle ;
2017-06-02 21:01:17 +00:00
+ + shared - > close_cycle ;
2017-06-02 18:48:33 +00:00
shared - > close_cycle_time = now + shared - > close_interval ;
if ( shared - > close_times . empty ( ) )
return shared - > close_interval ;
auto & sessions_to_close = shared - > close_times . front ( ) ;
for ( const auto & key : sessions_to_close )
{
const auto session = shared - > sessions . find ( key ) ;
2017-06-02 21:01:17 +00:00
if ( session ! = shared - > sessions . end ( ) & & session - > second - > session_close_cycle < = current_cycle )
2017-06-02 18:48:33 +00:00
{
2017-06-02 21:01:17 +00:00
if ( session - > second - > session_is_used )
session - > second - > scheduleCloseSession ( key , std : : chrono : : seconds ( 0 ) ) ;
2017-06-02 18:48:33 +00:00
else
shared - > sessions . erase ( session ) ;
}
}
shared - > close_times . pop_front ( ) ;
return shared - > close_interval ;
}
2017-01-05 16:34:05 +00:00
static String resolveDatabase ( const String & database_name , const String & current_database )
{
2017-04-01 07:20:54 +00:00
String res = database_name . empty ( ) ? current_database : database_name ;
if ( res . empty ( ) )
throw Exception ( " Default database is not selected " , ErrorCodes : : UNKNOWN_DATABASE ) ;
return res ;
2017-01-05 16:34:05 +00:00
}
2016-03-19 01:18:49 +00:00
const DatabasePtr Context : : getDatabase ( const String & database_name ) const
{
2017-04-01 07:20:54 +00:00
auto lock = getLock ( ) ;
String db = resolveDatabase ( database_name , current_database ) ;
assertDatabaseExists ( db ) ;
return shared - > databases [ db ] ;
2016-03-19 01:18:49 +00:00
}
DatabasePtr Context : : getDatabase ( const String & database_name )
{
2017-04-01 07:20:54 +00:00
auto lock = getLock ( ) ;
String db = resolveDatabase ( database_name , current_database ) ;
assertDatabaseExists ( db ) ;
return shared - > databases [ db ] ;
2016-03-19 01:18:49 +00:00
}
const DatabasePtr Context : : tryGetDatabase ( const String & database_name ) const
{
2017-04-01 07:20:54 +00:00
auto lock = getLock ( ) ;
String db = resolveDatabase ( database_name , current_database ) ;
auto it = shared - > databases . find ( db ) ;
if ( it = = shared - > databases . end ( ) )
return { } ;
return it - > second ;
2016-03-19 01:18:49 +00:00
}
DatabasePtr Context : : tryGetDatabase ( const String & database_name )
{
2017-04-01 07:20:54 +00:00
auto lock = getLock ( ) ;
String db = resolveDatabase ( database_name , current_database ) ;
auto it = shared - > databases . find ( db ) ;
if ( it = = shared - > databases . end ( ) )
return { } ;
return it - > second ;
2016-03-19 01:18:49 +00:00
}
2012-08-02 17:33:31 +00:00
String Context : : getPath ( ) const
{
2019-11-11 11:34:03 +00:00
//FIXME there is no <path> in clickhouse-local, so context->getPath() + relative_data_path may not work correctly (it may create StorageFile for example)
2017-04-01 07:20:54 +00:00
auto lock = getLock ( ) ;
return shared - > path ;
2012-08-02 17:33:31 +00:00
}
2015-01-07 17:19:23 +00:00
String Context : : getTemporaryPath ( ) const
{
2017-04-01 07:20:54 +00:00
auto lock = getLock ( ) ;
return shared - > tmp_path ;
2015-01-07 17:19:23 +00:00
}
2016-10-24 14:01:24 +00:00
String Context : : getFlagsPath ( ) const
{
2017-04-01 07:20:54 +00:00
auto lock = getLock ( ) ;
return shared - > flags_path ;
2016-10-24 14:01:24 +00:00
}
2018-04-19 05:32:09 +00:00
String Context : : getUserFilesPath ( ) const
{
auto lock = getLock ( ) ;
return shared - > user_files_path ;
}
2012-08-02 17:33:31 +00:00
void Context : : setPath ( const String & path )
{
2017-04-01 07:20:54 +00:00
auto lock = getLock ( ) ;
2018-04-19 05:32:09 +00:00
2017-04-01 07:20:54 +00:00
shared - > path = path ;
2018-04-19 05:32:09 +00:00
if ( shared - > tmp_path . empty ( ) )
shared - > tmp_path = shared - > path + " tmp/ " ;
if ( shared - > flags_path . empty ( ) )
shared - > flags_path = shared - > path + " flags/ " ;
if ( shared - > user_files_path . empty ( ) )
shared - > user_files_path = shared - > path + " user_files/ " ;
2012-08-02 17:33:31 +00:00
}
2015-01-07 17:19:23 +00:00
void Context : : setTemporaryPath ( const String & path )
{
2017-04-01 07:20:54 +00:00
auto lock = getLock ( ) ;
shared - > tmp_path = path ;
2015-01-07 17:19:23 +00:00
}
2016-10-24 14:01:24 +00:00
void Context : : setFlagsPath ( const String & path )
{
2017-04-01 07:20:54 +00:00
auto lock = getLock ( ) ;
shared - > flags_path = path ;
2016-10-24 14:01:24 +00:00
}
2018-04-19 05:32:09 +00:00
void Context : : setUserFilesPath ( const String & path )
{
auto lock = getLock ( ) ;
shared - > user_files_path = path ;
}
2017-08-24 14:51:13 +00:00
void Context : : setConfig ( const ConfigurationPtr & config )
{
auto lock = getLock ( ) ;
shared - > config = config ;
}
2018-07-08 04:54:37 +00:00
const Poco : : Util : : AbstractConfiguration & Context : : getConfigRef ( ) const
2017-08-24 14:51:13 +00:00
{
auto lock = getLock ( ) ;
return shared - > config ? * shared - > config : Poco : : Util : : Application : : instance ( ) . config ( ) ;
}
2012-08-02 17:33:31 +00:00
2016-10-14 15:06:46 +00:00
void Context : : setUsersConfig ( const ConfigurationPtr & config )
2013-08-10 07:46:45 +00:00
{
2017-04-01 07:20:54 +00:00
auto lock = getLock ( ) ;
shared - > users_config = config ;
2019-03-29 20:31:06 +00:00
shared - > users_manager - > loadFromConfig ( * shared - > users_config ) ;
2017-04-01 07:20:54 +00:00
shared - > quotas . loadFromConfig ( * shared - > users_config ) ;
2014-02-13 07:17:22 +00:00
}
ConfigurationPtr Context : : getUsersConfig ( )
{
2017-04-01 07:20:54 +00:00
auto lock = getLock ( ) ;
return shared - > users_config ;
2013-08-10 07:46:45 +00:00
}
2019-12-05 11:42:13 +00:00
bool Context : : hasUserProperty ( const StorageID & table_id , const String & name ) const
2019-03-29 20:31:06 +00:00
{
auto lock = getLock ( ) ;
// No user - no properties.
if ( client_info . current_user . empty ( ) )
return false ;
const auto & props = shared - > users_manager - > getUser ( client_info . current_user ) - > table_props ;
2019-12-05 11:42:13 +00:00
auto db = props . find ( table_id . database_name ) ;
2019-03-29 20:31:06 +00:00
if ( db = = props . end ( ) )
return false ;
2019-12-05 11:42:13 +00:00
auto table_props = db - > second . find ( table_id . table_name ) ;
2019-03-29 20:31:06 +00:00
if ( table_props = = db - > second . end ( ) )
return false ;
return ! ! table_props - > second . count ( name ) ;
}
2019-12-05 11:42:13 +00:00
const String & Context : : getUserProperty ( const StorageID & table_id , const String & name ) const
2019-03-29 20:31:06 +00:00
{
auto lock = getLock ( ) ;
const auto & props = shared - > users_manager - > getUser ( client_info . current_user ) - > table_props ;
2019-12-05 11:42:13 +00:00
return props . at ( table_id . database_name ) . at ( table_id . table_name ) . at ( name ) ;
2019-03-29 20:31:06 +00:00
}
2017-06-07 12:54:35 +00:00
void Context : : calculateUserSettings ( )
2013-08-10 07:46:45 +00:00
{
2017-04-01 07:20:54 +00:00
auto lock = getLock ( ) ;
2013-08-10 07:46:45 +00:00
2019-03-29 20:31:06 +00:00
String profile = shared - > users_manager - > getUser ( client_info . current_user ) - > profile ;
2017-03-23 14:14:56 +00:00
2017-06-07 12:54:35 +00:00
/// 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
2017-06-05 17:54:40 +00:00
settings = Settings ( ) ;
2019-04-24 22:52:08 +00:00
settings_constraints = nullptr ;
2017-06-05 17:54:40 +00:00
/// 2) Apply settings from default profile
2017-04-01 07:20:54 +00:00
auto default_profile_name = getDefaultProfileName ( ) ;
2017-06-07 12:54:35 +00:00
if ( profile ! = default_profile_name )
2019-04-19 00:45:15 +00:00
setProfile ( default_profile_name ) ;
2017-06-05 17:54:40 +00:00
/// 3) Apply settings from current user
2019-04-19 00:45:15 +00:00
setProfile ( profile ) ;
}
void Context : : setProfile ( const String & profile )
{
2017-06-07 12:54:35 +00:00
settings . setProfile ( profile , * shared - > users_config ) ;
2019-04-24 22:52:08 +00:00
auto new_constraints
= settings_constraints ? std : : make_shared < SettingsConstraints > ( * settings_constraints ) : std : : make_shared < SettingsConstraints > ( ) ;
new_constraints - > setProfile ( profile , * shared - > users_config ) ;
settings_constraints = std : : move ( new_constraints ) ;
2017-06-07 12:54:35 +00:00
}
2017-06-05 17:54:40 +00:00
2019-07-28 13:12:26 +00:00
std : : shared_ptr < const User > Context : : getUser ( const String & user_name )
{
return shared - > users_manager - > getUser ( user_name ) ;
}
2017-06-07 12:54:35 +00:00
void Context : : setUser ( const String & name , const String & password , const Poco : : Net : : SocketAddress & address , const String & quota_key )
{
auto lock = getLock ( ) ;
2019-03-29 20:31:06 +00:00
auto user_props = shared - > users_manager - > authorizeAndGetUser ( name , password , address . host ( ) ) ;
2013-08-10 07:46:45 +00:00
2017-04-01 07:20:54 +00:00
client_info . current_user = name ;
client_info . current_address = address ;
2018-04-10 14:49:52 +00:00
client_info . current_password = password ;
2016-11-16 05:09:41 +00:00
2017-04-01 07:20:54 +00:00
if ( ! quota_key . empty ( ) )
client_info . quota_key = quota_key ;
2017-06-07 12:54:35 +00:00
calculateUserSettings ( ) ;
2017-11-30 14:53:12 +00:00
setQuota ( user_props - > quota , quota_key , name , address . host ( ) ) ;
2013-08-10 07:46:45 +00:00
}
2013-11-03 00:24:46 +00:00
void Context : : setQuota ( const String & name , const String & quota_key , const String & user_name , const Poco : : Net : : IPAddress & address )
2013-08-12 00:36:18 +00:00
{
2017-04-01 07:20:54 +00:00
auto lock = getLock ( ) ;
quota = shared - > quotas . get ( name , quota_key , user_name , address ) ;
2013-08-12 00:36:18 +00:00
}
QuotaForIntervals & Context : : getQuota ( )
{
2017-04-01 07:20:54 +00:00
auto lock = getLock ( ) ;
return * quota ;
2013-08-12 00:36:18 +00:00
}
2015-10-01 15:10:41 +00:00
void Context : : checkDatabaseAccessRights ( const std : : string & database_name ) const
2018-04-17 19:33:58 +00:00
{
auto lock = getLock ( ) ;
checkDatabaseAccessRightsImpl ( database_name ) ;
}
2018-08-14 02:18:57 +00:00
bool Context : : hasDatabaseAccessRights ( const String & database_name ) const
2018-08-13 09:11:58 +00:00
{
auto lock = getLock ( ) ;
return client_info . current_user . empty ( ) | | ( database_name = = " system " ) | |
2019-03-29 20:31:06 +00:00
shared - > users_manager - > hasAccessToDatabase ( client_info . current_user , database_name ) ;
2018-08-13 09:11:58 +00:00
}
2019-09-13 08:22:34 +00:00
bool Context : : hasDictionaryAccessRights ( const String & dictionary_name ) const
{
auto lock = getLock ( ) ;
return client_info . current_user . empty ( ) | |
shared - > users_manager - > hasAccessToDictionary ( client_info . current_user , dictionary_name ) ;
}
2018-04-17 19:33:58 +00:00
void Context : : checkDatabaseAccessRightsImpl ( const std : : string & database_name ) const
2015-10-01 15:10:41 +00:00
{
2017-04-01 07:20:54 +00:00
if ( client_info . current_user . empty ( ) | | ( database_name = = " system " ) )
{
2017-04-02 17:37:49 +00:00
/// An unnamed user, i.e. server, has access to all databases.
/// All users have access to the database system.
2017-04-01 07:20:54 +00:00
return ;
}
2019-03-29 20:31:06 +00:00
if ( ! shared - > users_manager - > hasAccessToDatabase ( client_info . current_user , database_name ) )
2018-08-23 18:44:13 +00:00
throw Exception ( " Access denied to database " + database_name + " for user " + client_info . current_user , ErrorCodes : : DATABASE_ACCESS_DENIED ) ;
2015-10-01 15:10:41 +00:00
}
2019-12-05 11:42:13 +00:00
//FIXME use uuids if not empty
void Context : : addDependencyUnsafe ( const StorageID & from , const StorageID & where )
2013-11-08 17:43:03 +00:00
{
2019-12-05 11:42:13 +00:00
checkDatabaseAccessRightsImpl ( from . database_name ) ;
checkDatabaseAccessRightsImpl ( where . database_name ) ;
2017-04-01 07:20:54 +00:00
shared - > view_dependencies [ from ] . insert ( where ) ;
2017-10-03 23:43:55 +00:00
// Notify table of dependencies change
2019-12-05 11:42:13 +00:00
auto table = tryGetTable ( from . database_name , from . table_name ) ;
2017-10-03 23:43:55 +00:00
if ( table ! = nullptr )
table - > updateDependencies ( ) ;
2013-11-08 17:43:03 +00:00
}
2019-12-05 11:42:13 +00:00
void Context : : addDependency ( const StorageID & from , const StorageID & where )
2013-11-08 17:43:03 +00:00
{
2017-04-01 07:20:54 +00:00
auto lock = getLock ( ) ;
2019-05-09 06:12:02 +00:00
addDependencyUnsafe ( from , where ) ;
}
2019-12-05 11:42:13 +00:00
void Context : : removeDependencyUnsafe ( const StorageID & from , const StorageID & where )
2019-05-09 06:12:02 +00:00
{
2019-12-05 11:42:13 +00:00
checkDatabaseAccessRightsImpl ( from . database_name ) ;
checkDatabaseAccessRightsImpl ( where . database_name ) ;
2017-04-01 07:20:54 +00:00
shared - > view_dependencies [ from ] . erase ( where ) ;
2017-10-03 23:43:55 +00:00
// Notify table of dependencies change
2019-12-05 11:42:13 +00:00
auto table = tryGetTable ( from . database_name , from . table_name ) ;
2017-10-03 23:43:55 +00:00
if ( table ! = nullptr )
table - > updateDependencies ( ) ;
2013-11-08 17:43:03 +00:00
}
2019-12-05 11:42:13 +00:00
void Context : : removeDependency ( const StorageID & from , const StorageID & where )
2019-05-09 06:12:02 +00:00
{
auto lock = getLock ( ) ;
removeDependencyUnsafe ( from , where ) ;
}
2019-12-05 11:42:13 +00:00
Dependencies Context : : getDependencies ( const StorageID & from ) const
2013-11-08 17:43:03 +00:00
{
2017-04-01 07:20:54 +00:00
auto lock = getLock ( ) ;
2014-12-23 20:32:00 +00:00
2019-12-05 11:42:13 +00:00
String db = resolveDatabase ( from . database_name , current_database ) ;
2017-10-13 17:19:48 +00:00
2019-12-05 11:42:13 +00:00
if ( from . database_name . empty ( ) & & tryGetExternalTable ( from . table_name ) )
2017-10-13 17:19:48 +00:00
{
/// Table is temporary. Access granted.
}
else
{
2018-04-17 19:33:58 +00:00
checkDatabaseAccessRightsImpl ( db ) ;
2017-10-13 17:19:48 +00:00
}
2014-12-23 20:32:00 +00:00
2019-12-05 11:42:13 +00:00
ViewDependencies : : const_iterator iter = shared - > view_dependencies . find ( StorageID ( db , from . table_name ) ) ;
2017-04-01 07:20:54 +00:00
if ( iter = = shared - > view_dependencies . end ( ) )
return { } ;
2014-12-23 20:32:00 +00:00
2017-04-01 07:20:54 +00:00
return Dependencies ( iter - > second . begin ( ) , iter - > second . end ( ) ) ;
2013-11-08 17:43:03 +00:00
}
2013-08-12 00:36:18 +00:00
2012-08-02 17:33:31 +00:00
bool Context : : isTableExist ( const String & database_name , const String & table_name ) const
{
2017-04-01 07:20:54 +00:00
auto lock = getLock ( ) ;
2012-08-02 17:33:31 +00:00
2017-04-01 07:20:54 +00:00
String db = resolveDatabase ( database_name , current_database ) ;
2018-04-17 19:33:58 +00:00
checkDatabaseAccessRightsImpl ( db ) ;
2012-08-02 17:33:31 +00:00
2017-04-01 07:20:54 +00:00
Databases : : const_iterator it = shared - > databases . find ( db ) ;
return shared - > databases . end ( ) ! = it
2017-09-11 12:39:01 +00:00
& & it - > second - > isTableExist ( * this , table_name ) ;
2012-08-02 17:33:31 +00:00
}
2019-10-11 13:21:52 +00:00
bool Context : : isDictionaryExists ( const String & database_name , const String & dictionary_name ) const
2012-08-02 17:33:31 +00:00
{
2017-04-01 07:20:54 +00:00
auto lock = getLock ( ) ;
2019-10-11 13:21:52 +00:00
2017-04-01 07:20:54 +00:00
String db = resolveDatabase ( database_name , current_database ) ;
2018-04-17 19:33:58 +00:00
checkDatabaseAccessRightsImpl ( db ) ;
2012-08-02 17:33:31 +00:00
2019-10-11 13:21:52 +00:00
Databases : : const_iterator it = shared - > databases . find ( db ) ;
return shared - > databases . end ( ) ! = it & & it - > second - > isDictionaryExist ( * this , dictionary_name ) ;
2018-02-14 04:00:37 +00:00
}
2019-10-11 13:21:52 +00:00
bool Context : : isDatabaseExist ( const String & database_name ) const
2012-08-02 17:33:31 +00:00
{
2017-04-01 07:20:54 +00:00
auto lock = getLock ( ) ;
String db = resolveDatabase ( database_name , current_database ) ;
2018-04-17 19:33:58 +00:00
checkDatabaseAccessRightsImpl ( db ) ;
2019-10-11 13:21:52 +00:00
return shared - > databases . end ( ) ! = shared - > databases . find ( db ) ;
}
2014-06-26 00:58:14 +00:00
2019-10-11 13:21:52 +00:00
bool Context : : isExternalTableExist ( const String & table_name ) const
{
return external_tables . end ( ) ! = external_tables . find ( table_name ) ;
2012-08-02 17:33:31 +00:00
}
2015-10-01 15:10:41 +00:00
void Context : : assertTableDoesntExist ( const String & database_name , const String & table_name , bool check_database_access_rights ) const
2012-08-02 17:33:31 +00:00
{
2017-04-01 07:20:54 +00:00
auto lock = getLock ( ) ;
2012-08-02 17:33:31 +00:00
2017-04-01 07:20:54 +00:00
String db = resolveDatabase ( database_name , current_database ) ;
if ( check_database_access_rights )
2018-04-17 19:33:58 +00:00
checkDatabaseAccessRightsImpl ( db ) ;
2012-08-02 17:33:31 +00:00
2017-04-01 07:20:54 +00:00
Databases : : const_iterator it = shared - > databases . find ( db ) ;
2017-09-11 12:39:01 +00:00
if ( shared - > databases . end ( ) ! = it & & it - > second - > isTableExist ( * this , table_name ) )
2018-04-03 21:29:11 +00:00
throw Exception ( " Table " + backQuoteIfNeed ( db ) + " . " + backQuoteIfNeed ( table_name ) + " already exists. " , ErrorCodes : : TABLE_ALREADY_EXISTS ) ;
2012-08-02 17:33:31 +00:00
}
2015-10-01 15:10:41 +00:00
void Context : : assertDatabaseExists ( const String & database_name , bool check_database_access_rights ) const
2012-08-02 17:33:31 +00:00
{
2017-04-01 07:20:54 +00:00
auto lock = getLock ( ) ;
2012-08-02 17:33:31 +00:00
2017-04-01 07:20:54 +00:00
String db = resolveDatabase ( database_name , current_database ) ;
if ( check_database_access_rights )
2018-04-17 19:33:58 +00:00
checkDatabaseAccessRightsImpl ( db ) ;
2012-08-02 17:33:31 +00:00
2017-04-01 07:20:54 +00:00
if ( shared - > databases . end ( ) = = shared - > databases . find ( db ) )
2018-04-03 21:29:11 +00:00
throw Exception ( " Database " + backQuoteIfNeed ( db ) + " doesn't exist " , ErrorCodes : : UNKNOWN_DATABASE ) ;
2012-08-02 17:33:31 +00:00
}
void Context : : assertDatabaseDoesntExist ( const String & database_name ) const
{
2017-04-01 07:20:54 +00:00
auto lock = getLock ( ) ;
2012-08-02 17:33:31 +00:00
2017-04-01 07:20:54 +00:00
String db = resolveDatabase ( database_name , current_database ) ;
2018-04-17 19:33:58 +00:00
checkDatabaseAccessRightsImpl ( db ) ;
2012-08-02 17:33:31 +00:00
2017-04-01 07:20:54 +00:00
if ( shared - > databases . end ( ) ! = shared - > databases . find ( db ) )
2018-04-03 21:29:11 +00:00
throw Exception ( " Database " + backQuoteIfNeed ( db ) + " already exists. " , ErrorCodes : : DATABASE_ALREADY_EXISTS ) ;
2012-08-02 17:33:31 +00:00
}
2019-10-19 20:36:35 +00:00
const Scalars & Context : : getScalars ( ) const
{
return scalars ;
}
const Block & Context : : getScalar ( const String & name ) const
{
auto it = scalars . find ( name ) ;
if ( scalars . end ( ) = = it )
throw Exception ( " Scalar " + backQuoteIfNeed ( name ) + " doesn't exist (internal bug) " , ErrorCodes : : UNKNOWN_SCALAR ) ;
return it - > second ;
}
2014-03-13 15:00:06 +00:00
Tables Context : : getExternalTables ( ) const
{
2017-04-01 07:20:54 +00:00
auto lock = getLock ( ) ;
2014-03-14 15:42:30 +00:00
2018-02-14 04:00:37 +00:00
Tables res ;
2018-02-23 01:23:57 +00:00
for ( auto & table : external_tables )
2018-02-14 04:00:37 +00:00
res [ table . first ] = table . second . first ;
2017-04-01 07:20:54 +00:00
if ( session_context & & session_context ! = this )
{
Tables buf = session_context - > getExternalTables ( ) ;
res . insert ( buf . begin ( ) , buf . end ( ) ) ;
}
else if ( global_context & & global_context ! = this )
{
Tables buf = global_context - > getExternalTables ( ) ;
res . insert ( buf . begin ( ) , buf . end ( ) ) ;
}
return res ;
2014-03-13 15:00:06 +00:00
}
StoragePtr Context : : tryGetExternalTable ( const String & table_name ) const
2014-03-04 15:31:56 +00:00
{
2018-02-14 04:00:37 +00:00
TableAndCreateASTs : : const_iterator jt = external_tables . find ( table_name ) ;
2017-04-01 07:20:54 +00:00
if ( external_tables . end ( ) = = jt )
return StoragePtr ( ) ;
2014-03-04 15:31:56 +00:00
2018-02-14 04:00:37 +00:00
return jt - > second . first ;
2014-03-04 15:31:56 +00:00
}
2012-08-02 17:33:31 +00:00
StoragePtr Context : : getTable ( const String & database_name , const String & table_name ) const
2015-08-19 21:15:27 +00:00
{
2017-04-01 07:20:54 +00:00
Exception exc ;
auto res = getTableImpl ( database_name , table_name , & exc ) ;
if ( ! res )
throw exc ;
return res ;
2015-08-19 21:15:27 +00:00
}
StoragePtr Context : : tryGetTable ( const String & database_name , const String & table_name ) const
{
2017-04-01 07:20:54 +00:00
return getTableImpl ( database_name , table_name , nullptr ) ;
2015-08-19 21:15:27 +00:00
}
StoragePtr Context : : getTableImpl ( const String & database_name , const String & table_name , Exception * exception ) const
2012-08-02 17:33:31 +00:00
{
2019-06-02 12:11:01 +00:00
String db ;
DatabasePtr database ;
2012-08-02 17:33:31 +00:00
2017-04-01 07:20:54 +00:00
{
2019-06-02 12:11:01 +00:00
auto lock = getLock ( ) ;
2015-08-19 21:15:27 +00:00
2019-06-02 12:11:01 +00:00
if ( database_name . empty ( ) )
{
StoragePtr res = tryGetExternalTable ( table_name ) ;
if ( res )
return res ;
}
2014-06-26 00:58:14 +00:00
2019-06-02 12:11:01 +00:00
db = resolveDatabase ( database_name , current_database ) ;
checkDatabaseAccessRightsImpl ( db ) ;
Databases : : const_iterator it = shared - > databases . find ( db ) ;
if ( shared - > databases . end ( ) = = it )
{
if ( exception )
* exception = Exception ( " Database " + backQuoteIfNeed ( db ) + " doesn't exist " , ErrorCodes : : UNKNOWN_DATABASE ) ;
return { } ;
}
database = it - > second ;
2017-04-01 07:20:54 +00:00
}
2014-06-26 00:58:14 +00:00
2019-06-02 12:11:01 +00:00
auto table = database - > tryGetTable ( * this , table_name ) ;
2017-04-01 07:20:54 +00:00
if ( ! table )
{
if ( exception )
2018-04-03 21:29:11 +00:00
* exception = Exception ( " Table " + backQuoteIfNeed ( db ) + " . " + backQuoteIfNeed ( table_name ) + " doesn't exist. " , ErrorCodes : : UNKNOWN_TABLE ) ;
2017-04-01 07:20:54 +00:00
return { } ;
}
2015-08-19 21:15:27 +00:00
2017-04-01 07:20:54 +00:00
return table ;
2013-05-06 10:31:35 +00:00
}
2012-08-02 17:33:31 +00:00
2018-02-23 01:23:57 +00:00
void Context : : addExternalTable ( const String & table_name , const StoragePtr & storage , const ASTPtr & ast )
2014-03-04 15:31:56 +00:00
{
2017-04-01 07:20:54 +00:00
if ( external_tables . end ( ) ! = external_tables . find ( table_name ) )
2018-04-03 21:29:11 +00:00
throw Exception ( " Temporary table " + backQuoteIfNeed ( table_name ) + " already exists. " , ErrorCodes : : TABLE_ALREADY_EXISTS ) ;
2015-08-19 21:15:27 +00:00
2018-02-14 04:00:37 +00:00
external_tables [ table_name ] = std : : pair ( storage , ast ) ;
2014-03-04 15:31:56 +00:00
}
2019-10-19 20:36:35 +00:00
void Context : : addScalar ( const String & name , const Block & block )
{
scalars [ name ] = block ;
}
bool Context : : hasScalar ( const String & name ) const
{
return scalars . count ( name ) ;
}
2017-08-15 17:00:18 +00:00
StoragePtr Context : : tryRemoveExternalTable ( const String & table_name )
2017-08-15 12:34:28 +00:00
{
2018-02-14 04:00:37 +00:00
TableAndCreateASTs : : const_iterator it = external_tables . find ( table_name ) ;
2018-03-01 11:40:55 +00:00
2017-08-15 17:00:18 +00:00
if ( external_tables . end ( ) = = it )
return StoragePtr ( ) ;
2017-08-15 12:34:28 +00:00
2018-02-14 04:00:37 +00:00
auto storage = it - > second . first ;
2017-08-15 17:00:18 +00:00
external_tables . erase ( it ) ;
return storage ;
2018-03-01 01:49:36 +00:00
}
2017-08-15 12:34:28 +00:00
2018-03-01 01:49:36 +00:00
StoragePtr Context : : executeTableFunction ( const ASTPtr & table_expression )
{
/// Slightly suboptimal.
auto hash = table_expression - > getTreeHash ( ) ;
String key = toString ( hash . first ) + ' _ ' + toString ( hash . second ) ;
StoragePtr & res = table_function_results [ key ] ;
if ( ! res )
{
2019-03-11 13:22:51 +00:00
TableFunctionPtr table_function_ptr = TableFunctionFactory : : instance ( ) . get ( table_expression - > as < ASTFunction > ( ) - > name , * this ) ;
2018-03-01 01:49:36 +00:00
/// Run it and remember the result
2019-07-18 18:29:49 +00:00
res = table_function_ptr - > execute ( table_expression , * this , table_function_ptr - > getName ( ) ) ;
2018-03-01 01:49:36 +00:00
}
return res ;
2017-08-15 12:34:28 +00:00
}
2014-03-04 15:31:56 +00:00
2018-03-01 01:49:36 +00:00
2018-12-09 17:50:35 +00:00
void Context : : addViewSource ( const StoragePtr & storage )
{
if ( view_source )
throw Exception (
" Temporary view source storage " + backQuoteIfNeed ( view_source - > getName ( ) ) + " already exists. " , ErrorCodes : : TABLE_ALREADY_EXISTS ) ;
view_source = storage ;
}
StoragePtr Context : : getViewSource ( )
{
return view_source ;
}
2018-09-24 19:08:11 +00:00
DDLGuard : : DDLGuard ( Map & map_ , std : : unique_lock < std : : mutex > guards_lock_ , const String & elem )
: map ( map_ ) , guards_lock ( std : : move ( guards_lock_ ) )
2016-03-21 12:57:12 +00:00
{
2018-09-18 18:33:15 +00:00
it = map . emplace ( elem , Entry { std : : make_unique < std : : mutex > ( ) , 0 } ) . first ;
+ + it - > second . counter ;
2018-09-24 19:08:11 +00:00
guards_lock . unlock ( ) ;
2019-01-02 06:44:36 +00:00
table_lock = std : : unique_lock ( * it - > second . mutex ) ;
2016-03-21 12:57:12 +00:00
}
DDLGuard : : ~ DDLGuard ( )
{
2018-09-24 19:08:11 +00:00
guards_lock . lock ( ) ;
2018-09-18 18:33:15 +00:00
- - it - > second . counter ;
if ( ! it - > second . counter )
{
table_lock . unlock ( ) ;
map . erase ( it ) ;
}
2016-03-21 12:57:12 +00:00
}
2018-09-18 18:33:15 +00:00
std : : unique_ptr < DDLGuard > Context : : getDDLGuard ( const String & database , const String & table ) const
2016-03-21 12:57:12 +00:00
{
2019-01-02 06:44:36 +00:00
std : : unique_lock lock ( shared - > ddl_guards_mutex ) ;
2018-09-24 19:08:11 +00:00
return std : : make_unique < DDLGuard > ( shared - > ddl_guards [ database ] , std : : move ( lock ) , table ) ;
2016-04-01 17:41:13 +00:00
}
2016-03-19 01:18:49 +00:00
void Context : : addDatabase ( const String & database_name , const DatabasePtr & database )
2012-08-02 17:33:31 +00:00
{
2017-04-01 07:20:54 +00:00
auto lock = getLock ( ) ;
2012-08-02 17:33:31 +00:00
2017-04-01 07:20:54 +00:00
assertDatabaseDoesntExist ( database_name ) ;
shared - > databases [ database_name ] = database ;
2012-08-02 17:33:31 +00:00
}
2016-03-21 12:57:12 +00:00
DatabasePtr Context : : detachDatabase ( const String & database_name )
2012-08-02 17:33:31 +00:00
{
2017-04-01 07:20:54 +00:00
auto lock = getLock ( ) ;
auto res = getDatabase ( database_name ) ;
2019-10-15 18:04:17 +00:00
getExternalDictionariesLoader ( ) . removeConfigRepository ( database_name ) ;
2017-04-01 07:20:54 +00:00
shared - > databases . erase ( database_name ) ;
2019-10-17 17:18:54 +00:00
2017-04-01 07:20:54 +00:00
return res ;
2012-08-02 17:33:31 +00:00
}
2018-03-13 13:28:32 +00:00
ASTPtr Context : : getCreateExternalTableQuery ( const String & table_name ) const
2018-02-14 04:00:37 +00:00
{
TableAndCreateASTs : : const_iterator jt = external_tables . find ( table_name ) ;
if ( external_tables . end ( ) = = jt )
2018-04-03 21:29:11 +00:00
throw Exception ( " Temporary table " + backQuoteIfNeed ( table_name ) + " doesn't exist " , ErrorCodes : : UNKNOWN_TABLE ) ;
2018-02-14 04:00:37 +00:00
return jt - > second . second ;
}
2012-08-02 17:33:31 +00:00
Settings Context : : getSettings ( ) const
{
2017-04-01 07:20:54 +00:00
return settings ;
2012-08-02 17:33:31 +00:00
}
void Context : : setSettings ( const Settings & settings_ )
{
2017-04-01 07:20:54 +00:00
settings = settings_ ;
2012-08-02 17:33:31 +00:00
}
2019-04-18 23:29:32 +00:00
void Context : : setSetting ( const String & name , const String & value )
2012-08-02 19:03:32 +00:00
{
2019-04-18 23:29:32 +00:00
auto lock = getLock ( ) ;
2017-04-01 07:20:54 +00:00
if ( name = = " profile " )
2018-03-02 05:44:17 +00:00
{
2019-04-19 00:45:15 +00:00
setProfile ( value ) ;
2019-04-18 23:29:32 +00:00
return ;
2018-03-02 05:44:17 +00:00
}
2019-04-18 23:29:32 +00:00
settings . set ( name , value ) ;
2014-02-13 07:17:22 +00:00
}
2019-04-18 23:29:32 +00:00
void Context : : setSetting ( const String & name , const Field & value )
2014-02-13 07:17:22 +00:00
{
2019-04-18 23:29:32 +00:00
auto lock = getLock ( ) ;
2017-04-01 07:20:54 +00:00
if ( name = = " profile " )
2018-03-02 05:44:17 +00:00
{
2019-04-19 00:45:15 +00:00
setProfile ( value . safeGet < String > ( ) ) ;
2019-04-18 23:29:32 +00:00
return ;
2018-03-02 05:44:17 +00:00
}
2019-04-18 23:29:32 +00:00
settings . set ( name , value ) ;
}
void Context : : applySettingChange ( const SettingChange & change )
{
setSetting ( change . name , change . value ) ;
}
void Context : : applySettingsChanges ( const SettingsChanges & changes )
{
auto lock = getLock ( ) ;
for ( const SettingChange & change : changes )
applySettingChange ( change ) ;
}
void Context : : checkSettingsConstraints ( const SettingChange & change )
{
2019-04-24 22:52:08 +00:00
if ( settings_constraints )
settings_constraints - > check ( settings , change ) ;
2019-04-18 23:29:32 +00:00
}
void Context : : checkSettingsConstraints ( const SettingsChanges & changes )
{
2019-04-24 22:52:08 +00:00
if ( settings_constraints )
settings_constraints - > check ( settings , changes ) ;
2012-08-02 19:03:32 +00:00
}
2012-08-02 17:33:31 +00:00
String Context : : getCurrentDatabase ( ) const
{
2017-04-01 07:20:54 +00:00
return current_database ;
2012-08-02 17:33:31 +00:00
}
2014-02-12 17:31:02 +00:00
String Context : : getCurrentQueryId ( ) const
{
2017-04-01 07:20:54 +00:00
return client_info . current_query_id ;
2014-02-12 17:31:02 +00:00
}
2019-08-31 12:18:14 +00:00
String Context : : getInitialQueryId ( ) const
{
return client_info . initial_query_id ;
}
2012-08-02 17:33:31 +00:00
void Context : : setCurrentDatabase ( const String & name )
{
2017-04-01 07:20:54 +00:00
auto lock = getLock ( ) ;
assertDatabaseExists ( name ) ;
current_database = name ;
2012-08-02 17:33:31 +00:00
}
2014-02-12 17:31:02 +00:00
void Context : : setCurrentQueryId ( const String & query_id )
{
2017-04-01 07:20:54 +00:00
if ( ! client_info . current_query_id . empty ( ) )
throw Exception ( " Logical error: attempt to set query_id twice " , ErrorCodes : : LOGICAL_ERROR ) ;
2015-08-19 21:15:27 +00:00
2017-04-01 07:20:54 +00:00
String query_id_to_set = query_id ;
2017-05-24 19:31:50 +00:00
2017-04-02 17:37:49 +00:00
if ( query_id_to_set . empty ( ) ) /// If the user did not submit his query_id, then we generate it ourselves.
2017-05-24 19:31:50 +00:00
{
/// Generate random UUID, but using lower quality RNG,
/// because Poco::UUIDGenerator::generateRandom method is using /dev/random, that is very expensive.
/// NOTE: Actually we don't need to use UUIDs for query identifiers.
/// We could use any suitable string instead.
union
{
char bytes [ 16 ] ;
struct
{
UInt64 a ;
UInt64 b ;
2019-01-04 12:10:00 +00:00
} words ;
2017-05-24 19:31:50 +00:00
} random ;
2019-09-06 12:46:42 +00:00
random . words . a = thread_local_rng ( ) ; //-V656
random . words . b = thread_local_rng ( ) ; //-V656
2017-05-24 19:31:50 +00:00
/// Use protected constructor.
2019-08-03 11:02:40 +00:00
struct qUUID : Poco : : UUID
2017-05-24 19:31:50 +00:00
{
2019-08-03 11:02:40 +00:00
qUUID ( const char * bytes , Poco : : UUID : : Version version )
2017-05-24 19:31:50 +00:00
: Poco : : UUID ( bytes , version ) { }
} ;
2019-08-03 11:02:40 +00:00
query_id_to_set = qUUID ( random . bytes , Poco : : UUID : : UUID_RANDOM ) . toString ( ) ;
2017-05-24 19:31:50 +00:00
}
2015-07-25 09:49:09 +00:00
2017-04-01 07:20:54 +00:00
client_info . current_query_id = query_id_to_set ;
2014-02-12 17:31:02 +00:00
}
2019-02-01 01:48:25 +00:00
void Context : : killCurrentQuery ( )
{
if ( process_list_elem )
{
process_list_elem - > cancelQuery ( true ) ;
}
} ;
2014-02-12 17:31:02 +00:00
2013-06-29 18:03:57 +00:00
String Context : : getDefaultFormat ( ) const
{
2017-04-01 07:20:54 +00:00
return default_format . empty ( ) ? " TabSeparated " : default_format ;
2013-06-29 18:03:57 +00:00
}
void Context : : setDefaultFormat ( const String & name )
{
2017-04-01 07:20:54 +00:00
default_format = name ;
2013-06-29 18:03:57 +00:00
}
2018-03-13 23:44:23 +00:00
MultiVersion < Macros > : : Version Context : : getMacros ( ) const
2014-08-11 15:59:01 +00:00
{
2018-03-13 23:44:23 +00:00
return shared - > macros . get ( ) ;
2014-08-11 15:59:01 +00:00
}
2018-03-13 23:44:23 +00:00
void Context : : setMacros ( std : : unique_ptr < Macros > & & macros )
2014-08-11 15:59:01 +00:00
{
2018-03-13 23:44:23 +00:00
shared - > macros . set ( std : : move ( macros ) ) ;
2014-08-11 15:59:01 +00:00
}
2018-03-02 05:44:17 +00:00
const Context & Context : : getQueryContext ( ) const
{
if ( ! query_context )
throw Exception ( " There is no query " , ErrorCodes : : THERE_IS_NO_QUERY ) ;
return * query_context ;
}
Context & Context : : getQueryContext ( )
{
if ( ! query_context )
throw Exception ( " There is no query " , ErrorCodes : : THERE_IS_NO_QUERY ) ;
return * query_context ;
}
2016-11-16 11:29:51 +00:00
const Context & Context : : getSessionContext ( ) const
{
2017-04-01 07:20:54 +00:00
if ( ! session_context )
throw Exception ( " There is no session " , ErrorCodes : : THERE_IS_NO_SESSION ) ;
return * session_context ;
2016-11-16 11:29:51 +00:00
}
2013-06-29 18:03:57 +00:00
2012-08-02 17:33:31 +00:00
Context & Context : : getSessionContext ( )
{
2017-04-01 07:20:54 +00:00
if ( ! session_context )
throw Exception ( " There is no session " , ErrorCodes : : THERE_IS_NO_SESSION ) ;
return * session_context ;
2012-08-02 17:33:31 +00:00
}
2016-11-15 10:57:11 +00:00
const Context & Context : : getGlobalContext ( ) const
{
2017-04-01 07:20:54 +00:00
if ( ! global_context )
throw Exception ( " Logical error: there is no global context " , ErrorCodes : : LOGICAL_ERROR ) ;
return * global_context ;
2016-11-15 10:57:11 +00:00
}
2012-08-02 17:33:31 +00:00
Context & Context : : getGlobalContext ( )
{
2017-04-01 07:20:54 +00:00
if ( ! global_context )
throw Exception ( " Logical error: there is no global context " , ErrorCodes : : LOGICAL_ERROR ) ;
return * global_context ;
2012-08-02 17:33:31 +00:00
}
2012-12-19 20:15:15 +00:00
2017-01-21 04:24:28 +00:00
const EmbeddedDictionaries & Context : : getEmbeddedDictionaries ( ) const
2012-12-19 20:15:15 +00:00
{
2017-04-01 07:20:54 +00:00
return getEmbeddedDictionariesImpl ( false ) ;
2015-02-10 17:40:40 +00:00
}
2017-08-24 18:19:06 +00:00
EmbeddedDictionaries & Context : : getEmbeddedDictionaries ( )
{
return getEmbeddedDictionariesImpl ( false ) ;
}
2015-02-10 17:40:40 +00:00
2019-09-26 10:41:33 +00:00
const ExternalDictionariesLoader & Context : : getExternalDictionariesLoader ( ) const
2015-03-27 13:11:22 +00:00
{
2019-01-02 06:44:36 +00:00
std : : lock_guard lock ( shared - > external_dictionaries_mutex ) ;
2019-09-26 10:41:33 +00:00
if ( ! shared - > external_dictionaries_loader )
2017-04-01 07:20:54 +00:00
{
if ( ! this - > global_context )
throw Exception ( " Logical error: there is no global context " , ErrorCodes : : LOGICAL_ERROR ) ;
2017-11-28 11:00:07 +00:00
2019-10-18 15:44:32 +00:00
shared - > external_dictionaries_loader . emplace ( * this - > global_context ) ;
2017-04-01 07:20:54 +00:00
}
2019-09-26 10:41:33 +00:00
return * shared - > external_dictionaries_loader ;
2015-04-02 16:30:18 +00:00
}
2019-09-26 10:41:33 +00:00
ExternalDictionariesLoader & Context : : getExternalDictionariesLoader ( )
2019-06-02 12:11:01 +00:00
{
2019-09-26 10:41:33 +00:00
return const_cast < ExternalDictionariesLoader & > ( const_cast < const Context * > ( this ) - > getExternalDictionariesLoader ( ) ) ;
2019-06-02 12:11:01 +00:00
}
2019-09-26 10:23:14 +00:00
const ExternalModelsLoader & Context : : getExternalModelsLoader ( ) const
2017-10-17 10:44:46 +00:00
{
2019-01-02 06:44:36 +00:00
std : : lock_guard lock ( shared - > external_models_mutex ) ;
2019-09-26 10:23:14 +00:00
if ( ! shared - > external_models_loader )
2017-10-17 10:44:46 +00:00
{
if ( ! this - > global_context )
throw Exception ( " Logical error: there is no global context " , ErrorCodes : : LOGICAL_ERROR ) ;
2017-11-28 11:00:07 +00:00
2019-10-21 14:59:35 +00:00
shared - > external_models_loader . emplace ( * this - > global_context ) ;
2017-10-17 10:44:46 +00:00
}
2019-09-26 10:23:14 +00:00
return * shared - > external_models_loader ;
2017-10-17 10:44:46 +00:00
}
2015-04-02 16:30:18 +00:00
2019-09-26 10:23:14 +00:00
ExternalModelsLoader & Context : : getExternalModelsLoader ( )
2015-04-02 16:30:18 +00:00
{
2019-09-26 10:23:14 +00:00
return const_cast < ExternalModelsLoader & > ( const_cast < const Context * > ( this ) - > getExternalModelsLoader ( ) ) ;
2015-04-02 16:30:18 +00:00
}
2019-06-02 12:11:01 +00:00
EmbeddedDictionaries & Context : : getEmbeddedDictionariesImpl ( const bool throw_on_error ) const
2015-04-02 16:30:18 +00:00
{
2019-06-02 12:11:01 +00:00
std : : lock_guard lock ( shared - > embedded_dictionaries_mutex ) ;
if ( ! shared - > embedded_dictionaries )
{
2019-09-26 16:12:15 +00:00
auto geo_dictionaries_loader = std : : make_unique < GeoDictionariesLoader > ( ) ;
2019-06-02 12:11:01 +00:00
shared - > embedded_dictionaries . emplace (
std : : move ( geo_dictionaries_loader ) ,
* this - > global_context ,
throw_on_error ) ;
}
return * shared - > embedded_dictionaries ;
2012-12-19 20:15:15 +00:00
}
2013-02-16 14:55:14 +00:00
2019-06-02 12:11:01 +00:00
void Context : : tryCreateEmbeddedDictionaries ( ) const
2017-10-17 10:44:46 +00:00
{
2019-06-02 12:11:01 +00:00
static_cast < void > ( getEmbeddedDictionariesImpl ( true ) ) ;
2017-10-17 10:44:46 +00:00
}
2013-02-16 14:55:14 +00:00
void Context : : setProgressCallback ( ProgressCallback callback )
{
2017-04-02 17:37:49 +00:00
/// Callback is set to a session or to a query. In the session, only one query is processed at a time. Therefore, the lock is not needed.
2017-04-01 07:20:54 +00:00
progress_callback = callback ;
2013-02-16 14:55:14 +00:00
}
ProgressCallback Context : : getProgressCallback ( ) const
{
2017-04-01 07:20:54 +00:00
return progress_callback ;
2013-02-16 14:55:14 +00:00
}
2013-09-03 20:21:28 +00:00
2013-11-03 05:32:42 +00:00
void Context : : setProcessListElement ( ProcessList : : Element * elem )
{
2017-04-02 17:37:49 +00:00
/// Set to a session or query. In the session, only one query is processed at a time. Therefore, the lock is not needed.
2017-04-01 07:20:54 +00:00
process_list_elem = elem ;
2013-11-03 05:32:42 +00:00
}
2017-09-04 17:49:39 +00:00
ProcessList : : Element * Context : : getProcessListElement ( ) const
2017-08-29 13:23:04 +00:00
{
return process_list_elem ;
}
2013-11-03 05:32:42 +00:00
2014-03-28 14:36:24 +00:00
void Context : : setUncompressedCache ( size_t max_size_in_bytes )
2013-09-08 05:53:10 +00:00
{
2017-04-01 07:20:54 +00:00
auto lock = getLock ( ) ;
2013-09-08 05:53:10 +00:00
2017-04-01 07:20:54 +00:00
if ( shared - > uncompressed_cache )
throw Exception ( " Uncompressed cache has been already created. " , ErrorCodes : : LOGICAL_ERROR ) ;
2013-09-08 05:53:10 +00:00
2017-04-01 07:20:54 +00:00
shared - > uncompressed_cache = std : : make_shared < UncompressedCache > ( max_size_in_bytes ) ;
2013-09-08 05:53:10 +00:00
}
UncompressedCachePtr Context : : getUncompressedCache ( ) const
{
2017-04-01 07:20:54 +00:00
auto lock = getLock ( ) ;
return shared - > uncompressed_cache ;
2013-09-08 05:53:10 +00:00
}
2017-08-07 17:01:04 +00:00
void Context : : dropUncompressedCache ( ) const
{
auto lock = getLock ( ) ;
if ( shared - > uncompressed_cache )
shared - > uncompressed_cache - > reset ( ) ;
}
2014-02-11 13:30:42 +00:00
void Context : : setMarkCache ( size_t cache_size_in_bytes )
{
2017-04-01 07:20:54 +00:00
auto lock = getLock ( ) ;
2014-02-11 13:30:42 +00:00
2017-04-01 07:20:54 +00:00
if ( shared - > mark_cache )
2017-08-30 21:25:44 +00:00
throw Exception ( " Mark cache has been already created. " , ErrorCodes : : LOGICAL_ERROR ) ;
2014-02-11 13:30:42 +00:00
2017-04-01 07:20:54 +00:00
shared - > mark_cache = std : : make_shared < MarkCache > ( cache_size_in_bytes , std : : chrono : : seconds ( settings . mark_cache_min_lifetime ) ) ;
2014-02-11 13:30:42 +00:00
}
2017-08-07 17:01:04 +00:00
2014-02-11 13:30:42 +00:00
MarkCachePtr Context : : getMarkCache ( ) const
{
2017-04-01 07:20:54 +00:00
auto lock = getLock ( ) ;
return shared - > mark_cache ;
2014-02-11 13:30:42 +00:00
}
2017-08-07 17:01:04 +00:00
void Context : : dropMarkCache ( ) const
{
auto lock = getLock ( ) ;
if ( shared - > mark_cache )
shared - > mark_cache - > reset ( ) ;
}
void Context : : dropCaches ( ) const
{
auto lock = getLock ( ) ;
if ( shared - > uncompressed_cache )
shared - > uncompressed_cache - > reset ( ) ;
if ( shared - > mark_cache )
shared - > mark_cache - > reset ( ) ;
}
2014-07-02 12:30:38 +00:00
BackgroundProcessingPool & Context : : getBackgroundPool ( )
{
2017-04-01 07:20:54 +00:00
auto lock = getLock ( ) ;
if ( ! shared - > background_pool )
2019-02-04 23:18:04 +00:00
shared - > background_pool . emplace ( settings . background_pool_size ) ;
2017-04-01 07:20:54 +00:00
return * shared - > background_pool ;
2014-07-02 12:30:38 +00:00
}
2019-11-14 11:10:17 +00:00
BackgroundProcessingPool & Context : : getBackgroundMovePool ( )
2019-11-07 08:54:28 +00:00
{
auto lock = getLock ( ) ;
2019-11-14 11:10:17 +00:00
if ( ! shared - > background_move_pool )
2019-11-17 21:00:10 +00:00
shared - > background_move_pool . emplace ( settings . background_move_pool_size , " BackgroundMovePool " , " BgMoveProcPool " ) ;
2019-11-14 11:10:17 +00:00
return * shared - > background_move_pool ;
2019-11-07 08:54:28 +00:00
}
2017-12-29 22:32:04 +00:00
BackgroundSchedulePool & Context : : getSchedulePool ( )
{
auto lock = getLock ( ) ;
if ( ! shared - > schedule_pool )
2019-02-04 23:18:04 +00:00
shared - > schedule_pool . emplace ( settings . background_schedule_pool_size ) ;
2017-12-29 22:32:04 +00:00
return * shared - > schedule_pool ;
}
2019-02-21 16:41:27 +00:00
void Context : : setDDLWorker ( std : : unique_ptr < DDLWorker > ddl_worker )
2017-04-13 13:42:29 +00:00
{
auto lock = getLock ( ) ;
if ( shared - > ddl_worker )
throw Exception ( " DDL background thread has already been initialized. " , ErrorCodes : : LOGICAL_ERROR ) ;
2019-02-21 16:41:27 +00:00
shared - > ddl_worker = std : : move ( ddl_worker ) ;
2017-04-13 13:42:29 +00:00
}
2017-09-04 17:49:39 +00:00
DDLWorker & Context : : getDDLWorker ( ) const
2017-04-13 13:42:29 +00:00
{
auto lock = getLock ( ) ;
if ( ! shared - > ddl_worker )
2017-09-04 17:49:39 +00:00
throw Exception ( " DDL background thread is not initialized. " , ErrorCodes : : LOGICAL_ERROR ) ;
2017-04-13 13:42:29 +00:00
return * shared - > ddl_worker ;
}
2014-05-13 10:10:26 +00:00
zkutil : : ZooKeeperPtr Context : : getZooKeeper ( ) const
2014-03-21 19:17:59 +00:00
{
2019-01-02 06:44:36 +00:00
std : : lock_guard lock ( shared - > zookeeper_mutex ) ;
2014-04-25 13:55:15 +00:00
2018-04-03 19:43:33 +00:00
if ( ! shared - > zookeeper )
shared - > zookeeper = std : : make_shared < zkutil : : ZooKeeper > ( getConfigRef ( ) , " zookeeper " ) ;
else if ( shared - > zookeeper - > expired ( ) )
2017-04-01 07:20:54 +00:00
shared - > zookeeper = shared - > zookeeper - > startNewSession ( ) ;
2014-04-25 13:55:15 +00:00
2017-04-01 07:20:54 +00:00
return shared - > zookeeper ;
2014-03-21 19:17:59 +00:00
}
2019-07-04 14:48:40 +00:00
void Context : : resetZooKeeper ( ) const
{
std : : lock_guard lock ( shared - > zookeeper_mutex ) ;
shared - > zookeeper . reset ( ) ;
}
2017-06-15 20:08:26 +00:00
bool Context : : hasZooKeeper ( ) const
{
2018-04-21 18:41:06 +00:00
return getConfigRef ( ) . has ( " zookeeper " ) ;
2017-06-15 20:08:26 +00:00
}
2014-03-21 19:17:59 +00:00
2014-11-19 20:40:51 +00:00
void Context : : setInterserverIOAddress ( const String & host , UInt16 port )
2014-03-21 19:49:27 +00:00
{
2017-04-01 07:20:54 +00:00
shared - > interserver_io_host = host ;
shared - > interserver_io_port = port ;
2014-03-21 19:49:27 +00:00
}
2014-11-19 20:40:51 +00:00
std : : pair < String , UInt16 > Context : : getInterserverIOAddress ( ) const
2014-03-21 19:49:27 +00:00
{
2017-04-01 07:20:54 +00:00
if ( shared - > interserver_io_host . empty ( ) | | shared - > interserver_io_port = = 0 )
2018-07-30 18:32:21 +00:00
throw Exception ( " Parameter 'interserver_http(s)_port' required for replication is not specified in configuration file. " ,
ErrorCodes : : NO_ELEMENTS_IN_CONFIG ) ;
2014-11-19 20:40:51 +00:00
2017-04-01 07:20:54 +00:00
return { shared - > interserver_io_host , shared - > interserver_io_port } ;
2014-03-21 19:49:27 +00:00
}
2018-07-30 18:32:21 +00:00
void Context : : setInterserverCredentials ( const String & user , const String & password )
2018-07-26 15:10:57 +00:00
{
shared - > interserver_io_user = user ;
shared - > interserver_io_password = password ;
}
std : : pair < String , String > Context : : getInterserverCredentials ( ) const
{
return { shared - > interserver_io_user , shared - > interserver_io_password } ;
}
2018-07-30 18:32:21 +00:00
void Context : : setInterserverScheme ( const String & scheme )
2014-03-21 19:49:27 +00:00
{
2018-07-30 18:32:21 +00:00
shared - > interserver_scheme = scheme ;
}
2014-11-19 20:40:51 +00:00
2018-07-30 18:32:21 +00:00
String Context : : getInterserverScheme ( ) const
{
return shared - > interserver_scheme ;
2014-03-21 19:49:27 +00:00
}
2015-09-24 04:50:53 +00:00
UInt16 Context : : getTCPPort ( ) const
{
2017-08-24 14:51:13 +00:00
auto lock = getLock ( ) ;
auto & config = getConfigRef ( ) ;
2019-06-14 15:35:45 +00:00
return config . getInt ( " tcp_port " , DBMS_DEFAULT_PORT ) ;
2015-09-24 04:50:53 +00:00
}
2018-11-06 14:42:30 +00:00
std : : optional < UInt16 > Context : : getTCPPortSecure ( ) const
{
auto lock = getLock ( ) ;
auto & config = getConfigRef ( ) ;
if ( config . has ( " tcp_port_secure " ) )
return config . getInt ( " tcp_port_secure " ) ;
return { } ;
}
2014-03-21 19:49:27 +00:00
2016-10-14 15:06:46 +00:00
std : : shared_ptr < Cluster > Context : : getCluster ( const std : : string & cluster_name ) const
2013-12-07 16:51:29 +00:00
{
2017-04-01 07:20:54 +00:00
auto res = getClusters ( ) . getCluster ( cluster_name ) ;
2013-12-10 17:06:57 +00:00
2017-04-01 07:20:54 +00:00
if ( ! res )
throw Exception ( " Requested cluster ' " + cluster_name + " ' not found " , ErrorCodes : : BAD_GET ) ;
2016-10-10 08:44:52 +00:00
2017-04-01 07:20:54 +00:00
return res ;
2013-12-07 16:51:29 +00:00
}
2015-01-10 02:30:03 +00:00
2016-10-10 08:44:52 +00:00
2016-10-14 15:06:46 +00:00
std : : shared_ptr < Cluster > Context : : tryGetCluster ( const std : : string & cluster_name ) const
{
2017-04-01 07:20:54 +00:00
return getClusters ( ) . getCluster ( cluster_name ) ;
2013-12-07 16:51:29 +00:00
}
2015-01-10 02:30:03 +00:00
2016-10-14 15:06:46 +00:00
2018-01-15 14:13:19 +00:00
void Context : : reloadClusterConfig ( )
{
2018-03-26 14:12:07 +00:00
while ( true )
{
ConfigurationPtr cluster_config ;
{
2019-01-02 06:44:36 +00:00
std : : lock_guard lock ( shared - > clusters_mutex ) ;
2018-03-26 14:12:07 +00:00
cluster_config = shared - > clusters_config ;
}
auto & config = cluster_config ? * cluster_config : getConfigRef ( ) ;
auto new_clusters = std : : make_unique < Clusters > ( config , settings ) ;
{
2019-01-02 06:44:36 +00:00
std : : lock_guard lock ( shared - > clusters_mutex ) ;
2018-03-26 14:12:07 +00:00
if ( shared - > clusters_config . get ( ) = = cluster_config . get ( ) )
{
shared - > clusters = std : : move ( new_clusters ) ;
return ;
}
/// Clusters config has been suddenly changed, recompute clusters
}
}
2018-01-15 14:13:19 +00:00
}
2016-10-10 08:44:52 +00:00
Clusters & Context : : getClusters ( ) const
2015-04-30 12:43:16 +00:00
{
2019-01-02 06:44:36 +00:00
std : : lock_guard lock ( shared - > clusters_mutex ) ;
2018-01-15 14:13:19 +00:00
if ( ! shared - > clusters )
2017-04-01 07:20:54 +00:00
{
2018-01-15 14:13:19 +00:00
auto & config = shared - > clusters_config ? * shared - > clusters_config : getConfigRef ( ) ;
shared - > clusters = std : : make_unique < Clusters > ( config , settings ) ;
2017-04-01 07:20:54 +00:00
}
2016-03-10 03:08:09 +00:00
2017-04-01 07:20:54 +00:00
return * shared - > clusters ;
2015-04-30 12:43:16 +00:00
}
2015-01-10 02:30:03 +00:00
2016-10-10 08:44:52 +00:00
2016-10-14 15:06:46 +00:00
/// On repeating calls updates existing clusters and adds new clusters, doesn't delete old clusters
2017-10-13 19:13:41 +00:00
void Context : : setClustersConfig ( const ConfigurationPtr & config , const String & config_name )
2016-10-10 08:44:52 +00:00
{
2019-01-02 06:44:36 +00:00
std : : lock_guard lock ( shared - > clusters_mutex ) ;
2016-10-10 08:44:52 +00:00
2017-04-01 07:20:54 +00:00
shared - > clusters_config = config ;
2017-10-13 19:13:41 +00:00
if ( ! shared - > clusters )
shared - > clusters = std : : make_unique < Clusters > ( * shared - > clusters_config , settings , config_name ) ;
else
shared - > clusters - > updateClusters ( * shared - > clusters_config , settings , config_name ) ;
2015-04-30 12:43:16 +00:00
}
2015-01-10 02:30:03 +00:00
2016-10-10 08:44:52 +00:00
2017-11-03 19:53:10 +00:00
void Context : : setCluster ( const String & cluster_name , const std : : shared_ptr < Cluster > & cluster )
{
2019-01-02 06:44:36 +00:00
std : : lock_guard lock ( shared - > clusters_mutex ) ;
2017-11-03 19:53:10 +00:00
if ( ! shared - > clusters )
throw Exception ( " Clusters are not set " , ErrorCodes : : LOGICAL_ERROR ) ;
shared - > clusters - > setCluster ( cluster_name , cluster ) ;
2015-04-30 12:43:16 +00:00
}
2015-01-10 02:30:03 +00:00
2016-10-10 08:44:52 +00:00
2019-08-04 15:51:04 +00:00
void Context : : initializeSystemLogs ( )
2015-01-10 02:30:03 +00:00
{
2017-04-01 07:20:54 +00:00
auto lock = getLock ( ) ;
2019-02-06 18:33:29 +00:00
shared - > system_logs . emplace ( * global_context , getConfigRef ( ) ) ;
2015-01-10 02:30:03 +00:00
}
2019-07-06 20:29:00 +00:00
bool Context : : hasTraceCollector ( )
{
return shared - > hasTraceCollector ( ) ;
}
2015-01-10 02:30:03 +00:00
2019-02-03 21:30:45 +00:00
void Context : : initializeTraceCollector ( )
2018-03-10 19:57:13 +00:00
{
2019-02-03 21:30:45 +00:00
shared - > initializeTraceCollector ( getTraceLog ( ) ) ;
2018-03-10 19:57:13 +00:00
}
2019-03-21 19:22:38 +00:00
std : : shared_ptr < QueryLog > Context : : getQueryLog ( )
2015-06-26 20:48:10 +00:00
{
2017-04-01 07:20:54 +00:00
auto lock = getLock ( ) ;
2015-06-26 20:48:10 +00:00
2019-02-04 14:08:39 +00:00
if ( ! shared - > system_logs | | ! shared - > system_logs - > query_log )
2019-03-21 19:22:38 +00:00
return { } ;
2017-06-05 13:59:38 +00:00
2019-03-21 19:22:38 +00:00
return shared - > system_logs - > query_log ;
2015-06-26 20:48:10 +00:00
}
2019-03-21 19:22:38 +00:00
std : : shared_ptr < QueryThreadLog > Context : : getQueryThreadLog ( )
2018-05-31 15:54:08 +00:00
{
auto lock = getLock ( ) ;
2019-02-04 14:08:39 +00:00
if ( ! shared - > system_logs | | ! shared - > system_logs - > query_thread_log )
2019-03-21 19:22:38 +00:00
return { } ;
2015-06-26 20:48:10 +00:00
2019-03-21 19:22:38 +00:00
return shared - > system_logs - > query_thread_log ;
2015-06-26 20:48:10 +00:00
}
2019-03-21 19:22:38 +00:00
std : : shared_ptr < PartLog > Context : : getPartLog ( const String & part_database )
2017-03-07 17:13:54 +00:00
{
2017-04-01 07:20:54 +00:00
auto lock = getLock ( ) ;
2017-03-07 17:13:54 +00:00
2019-02-22 16:10:14 +00:00
/// No part log or system logs are shutting down.
2019-02-04 14:08:39 +00:00
if ( ! shared - > system_logs | | ! shared - > system_logs - > part_log )
2019-03-21 19:22:38 +00:00
return { } ;
2017-06-05 13:59:38 +00:00
2018-03-10 19:57:13 +00:00
/// Will not log operations on system tables (including part_log itself).
/// It doesn't make sense and not allow to destruct PartLog correctly due to infinite logging and flushing,
/// and also make troubles on startup.
2019-02-04 14:08:39 +00:00
if ( part_database = = shared - > system_logs - > part_log_database )
2019-03-21 19:22:38 +00:00
return { } ;
2017-06-05 13:59:38 +00:00
2019-03-21 19:22:38 +00:00
return shared - > system_logs - > part_log ;
2017-03-07 17:13:54 +00:00
}
2019-05-19 20:22:44 +00:00
std : : shared_ptr < TraceLog > Context : : getTraceLog ( )
2019-02-03 21:30:45 +00:00
{
auto lock = getLock ( ) ;
2019-02-09 22:26:51 +00:00
if ( ! shared - > system_logs | | ! shared - > system_logs - > trace_log )
2019-07-23 14:50:38 +00:00
return { } ;
2019-02-03 21:30:45 +00:00
2019-05-19 20:22:44 +00:00
return shared - > system_logs - > trace_log ;
2019-02-03 21:30:45 +00:00
}
2019-08-13 14:31:46 +00:00
2019-07-31 14:03:23 +00:00
std : : shared_ptr < TextLog > Context : : getTextLog ( )
{
auto lock = getLock ( ) ;
2019-08-04 15:51:04 +00:00
if ( ! shared - > system_logs | | ! shared - > system_logs - > text_log )
return { } ;
2019-07-31 14:18:59 +00:00
2019-08-04 15:51:04 +00:00
return shared - > system_logs - > text_log ;
2019-07-31 14:03:23 +00:00
}
2017-03-07 17:13:54 +00:00
2019-08-13 14:31:46 +00:00
std : : shared_ptr < MetricLog > Context : : getMetricLog ( )
{
auto lock = getLock ( ) ;
if ( ! shared - > system_logs | | ! shared - > system_logs - > metric_log )
return { } ;
return shared - > system_logs - > metric_log ;
}
2018-12-21 12:17:30 +00:00
CompressionCodecPtr Context : : chooseCompressionCodec ( size_t part_size , double part_size_ratio ) const
2015-04-17 05:35:53 +00:00
{
2017-04-01 07:20:54 +00:00
auto lock = getLock ( ) ;
2015-04-17 05:35:53 +00:00
2018-12-21 12:17:30 +00:00
if ( ! shared - > compression_codec_selector )
2017-04-01 07:20:54 +00:00
{
constexpr auto config_name = " compression " ;
2017-08-24 14:51:13 +00:00
auto & config = getConfigRef ( ) ;
2015-04-17 05:35:53 +00:00
2017-04-01 07:20:54 +00:00
if ( config . has ( config_name ) )
2018-12-21 12:17:30 +00:00
shared - > compression_codec_selector = std : : make_unique < CompressionCodecSelector > ( config , " compression " ) ;
2017-04-01 07:20:54 +00:00
else
2018-12-21 12:17:30 +00:00
shared - > compression_codec_selector = std : : make_unique < CompressionCodecSelector > ( ) ;
2017-04-01 07:20:54 +00:00
}
2015-04-17 05:35:53 +00:00
2018-12-21 12:17:30 +00:00
return shared - > compression_codec_selector - > choose ( part_size , part_size_ratio ) ;
2015-04-17 05:35:53 +00:00
}
2019-07-23 13:34:17 +00:00
const DiskSpace : : DiskPtr & Context : : getDisk ( const String & name ) const
2019-04-04 17:19:11 +00:00
{
auto lock = getLock ( ) ;
2019-04-21 18:38:44 +00:00
const auto & disk_selector = getDiskSelector ( ) ;
return disk_selector [ name ] ;
}
2019-07-30 16:15:57 +00:00
DiskSpace : : DiskSelector & Context : : getDiskSelector ( ) const
2019-04-21 18:38:44 +00:00
{
auto lock = getLock ( ) ;
if ( ! shared - > merge_tree_disk_selector )
2019-04-04 17:19:11 +00:00
{
2019-04-21 18:38:44 +00:00
constexpr auto config_name = " storage_configuration.disks " ;
2019-04-04 17:19:11 +00:00
auto & config = getConfigRef ( ) ;
2019-09-11 17:17:10 +00:00
shared - > merge_tree_disk_selector = std : : make_unique < DiskSpace : : DiskSelector > ( config , config_name , getPath ( ) ) ;
2019-04-04 17:19:11 +00:00
}
2019-04-21 18:38:44 +00:00
return * shared - > merge_tree_disk_selector ;
}
2019-04-04 17:19:11 +00:00
2019-04-21 18:38:44 +00:00
2019-08-15 17:02:04 +00:00
const DiskSpace : : StoragePolicyPtr & Context : : getStoragePolicy ( const String & name ) const
2019-04-21 18:38:44 +00:00
{
auto lock = getLock ( ) ;
2019-08-01 10:29:14 +00:00
auto & policy_selector = getStoragePolicySelector ( ) ;
2019-04-21 18:38:44 +00:00
2019-08-01 10:29:14 +00:00
return policy_selector [ name ] ;
2019-05-24 19:03:07 +00:00
}
2019-08-01 10:29:14 +00:00
DiskSpace : : StoragePolicySelector & Context : : getStoragePolicySelector ( ) const
2019-05-24 19:03:07 +00:00
{
auto lock = getLock ( ) ;
if ( ! shared - > merge_tree_storage_policy_selector )
{
constexpr auto config_name = " storage_configuration.policies " ;
auto & config = getConfigRef ( ) ;
2019-07-23 13:34:17 +00:00
shared - > merge_tree_storage_policy_selector = std : : make_unique < DiskSpace : : StoragePolicySelector > ( config , config_name , getDiskSelector ( ) ) ;
2019-05-24 19:03:07 +00:00
}
return * shared - > merge_tree_storage_policy_selector ;
2019-04-04 17:19:11 +00:00
}
2018-08-10 17:42:12 +00:00
const MergeTreeSettings & Context : : getMergeTreeSettings ( ) const
2015-07-16 21:32:51 +00:00
{
2017-04-01 07:20:54 +00:00
auto lock = getLock ( ) ;
2015-07-16 21:32:51 +00:00
2017-04-01 07:20:54 +00:00
if ( ! shared - > merge_tree_settings )
{
2017-08-24 14:51:13 +00:00
auto & config = getConfigRef ( ) ;
2019-08-26 14:24:29 +00:00
MergeTreeSettings mt_settings ;
mt_settings . loadFromConfig ( " merge_tree " , config ) ;
shared - > merge_tree_settings . emplace ( mt_settings ) ;
2017-04-01 07:20:54 +00:00
}
2015-07-16 21:32:51 +00:00
2017-04-01 07:20:54 +00:00
return * shared - > merge_tree_settings ;
2015-07-16 21:32:51 +00:00
}
2019-01-04 12:10:00 +00:00
void Context : : checkCanBeDropped ( const String & database , const String & table , const size_t & size , const size_t & max_size_to_drop ) const
2017-01-19 19:11:12 +00:00
{
2018-08-06 08:25:29 +00:00
if ( ! max_size_to_drop | | size < = max_size_to_drop )
2017-04-01 07:20:54 +00:00
return ;
2017-01-19 19:11:12 +00:00
2017-04-01 07:20:54 +00:00
Poco : : File force_file ( getFlagsPath ( ) + " force_drop_table " ) ;
bool force_file_exists = force_file . exists ( ) ;
2017-01-19 19:11:12 +00:00
2017-04-01 07:20:54 +00:00
if ( force_file_exists )
{
try
{
force_file . remove ( ) ;
return ;
}
catch ( . . . )
{
/// User should recreate force file on each drop, it shouldn't be protected
2018-08-06 08:25:29 +00:00
tryLogCurrentException ( " Drop table check " , " Can't remove force file to enable table or partition drop " ) ;
2017-04-01 07:20:54 +00:00
}
}
2017-01-19 19:11:12 +00:00
2018-08-06 08:25:29 +00:00
String size_str = formatReadableSizeWithDecimalSuffix ( size ) ;
String max_size_to_drop_str = formatReadableSizeWithDecimalSuffix ( max_size_to_drop ) ;
2017-04-01 07:20:54 +00:00
std : : stringstream ostr ;
2017-01-19 19:11:12 +00:00
2018-08-06 08:25:29 +00:00
ostr < < " Table or Partition in " < < backQuoteIfNeed ( database ) < < " . " < < backQuoteIfNeed ( table ) < < " was not dropped. \n "
2017-04-01 07:20:54 +00:00
< < " Reason: \n "
2018-08-30 09:33:31 +00:00
< < " 1. Size ( " < < size_str < < " ) is greater than max_[table/partition]_size_to_drop ( " < < max_size_to_drop_str < < " ) \n "
2017-08-16 10:24:06 +00:00
< < " 2. File ' " < < force_file . path ( ) < < " ' intended to force DROP "
2018-08-06 08:25:29 +00:00
< < ( force_file_exists ? " exists but not writeable (could not be removed) " : " doesn't exist " ) < < " \n " ;
2017-01-23 19:18:25 +00:00
2017-04-01 07:20:54 +00:00
ostr < < " How to fix this: \n "
2018-08-30 09:33:31 +00:00
< < " 1. Either increase (or set to zero) max_[table/partition]_size_to_drop in server config and restart ClickHouse \n "
2017-04-01 07:20:54 +00:00
< < " 2. Either create forcing file " < < force_file . path ( ) < < " and make sure that ClickHouse has write permission for it. \n "
< < " Example: \n sudo touch ' " < < force_file . path ( ) < < " ' && sudo chmod 666 ' " < < force_file . path ( ) < < " ' " ;
2017-01-23 19:18:25 +00:00
2017-04-01 07:20:54 +00:00
throw Exception ( ostr . str ( ) , ErrorCodes : : TABLE_SIZE_EXCEEDS_MAX_DROP_SIZE_LIMIT ) ;
2017-01-19 19:11:12 +00:00
}
2018-08-06 08:25:29 +00:00
void Context : : setMaxTableSizeToDrop ( size_t max_size )
{
2019-11-22 13:56:16 +00:00
// Is initialized at server startup and updated at config reload
2019-11-20 16:40:27 +00:00
shared - > max_table_size_to_drop . store ( max_size , std : : memory_order_relaxed ) ;
2018-08-06 08:25:29 +00:00
}
2019-01-04 12:10:00 +00:00
void Context : : checkTableCanBeDropped ( const String & database , const String & table , const size_t & table_size ) const
2018-08-06 08:25:29 +00:00
{
2019-11-20 16:40:27 +00:00
size_t max_table_size_to_drop = shared - > max_table_size_to_drop . load ( std : : memory_order_relaxed ) ;
2018-08-06 08:25:29 +00:00
2018-08-06 08:43:34 +00:00
checkCanBeDropped ( database , table , table_size , max_table_size_to_drop ) ;
2018-08-06 08:25:29 +00:00
}
2018-08-03 08:33:57 +00:00
void Context : : setMaxPartitionSizeToDrop ( size_t max_size )
2018-08-01 17:41:18 +00:00
{
2019-11-22 13:56:16 +00:00
// Is initialized at server startup and updated at config reload
2019-11-20 16:40:27 +00:00
shared - > max_partition_size_to_drop . store ( max_size , std : : memory_order_relaxed ) ;
2018-08-01 17:41:18 +00:00
}
2019-01-04 12:10:00 +00:00
void Context : : checkPartitionCanBeDropped ( const String & database , const String & table , const size_t & partition_size ) const
2018-08-01 17:41:18 +00:00
{
2019-11-20 16:40:27 +00:00
size_t max_partition_size_to_drop = shared - > max_partition_size_to_drop . load ( std : : memory_order_relaxed ) ;
2018-08-01 17:41:18 +00:00
2018-08-06 08:43:34 +00:00
checkCanBeDropped ( database , table , partition_size , max_partition_size_to_drop ) ;
2018-08-01 17:41:18 +00:00
}
2019-02-10 16:55:12 +00:00
BlockInputStreamPtr Context : : getInputFormat ( const String & name , ReadBuffer & buf , const Block & sample , UInt64 max_block_size ) const
2016-02-13 06:37:19 +00:00
{
2018-06-10 19:22:49 +00:00
return FormatFactory : : instance ( ) . getInput ( name , buf , sample , * this , max_block_size ) ;
2016-02-13 06:37:19 +00:00
}
BlockOutputStreamPtr Context : : getOutputFormat ( const String & name , WriteBuffer & buf , const Block & sample ) const
{
2018-06-10 19:22:49 +00:00
return FormatFactory : : instance ( ) . getOutput ( name , buf , sample , * this ) ;
2016-02-13 06:37:19 +00:00
}
2019-03-26 18:28:37 +00:00
OutputFormatPtr Context : : getOutputFormatProcessor ( const String & name , WriteBuffer & buf , const Block & sample ) const
{
return FormatFactory : : instance ( ) . getOutputFormat ( name , buf , sample , * this ) ;
}
2016-02-13 06:37:19 +00:00
2016-04-09 07:47:08 +00:00
time_t Context : : getUptimeSeconds ( ) const
{
2017-04-01 07:20:54 +00:00
auto lock = getLock ( ) ;
return shared - > uptime_watch . elapsedSeconds ( ) ;
2016-04-09 07:47:08 +00:00
}
2018-03-13 10:41:47 +00:00
void Context : : setConfigReloadCallback ( ConfigReloadCallback & & callback )
{
/// Is initialized at server startup, so lock isn't required. Otherwise use mutex.
shared - > config_reload_callback = std : : move ( callback ) ;
}
void Context : : reloadConfig ( ) const
{
/// Use mutex if callback may be changed after startup.
if ( ! shared - > config_reload_callback )
throw Exception ( " Can't reload config beacuse config_reload_callback is not set. " , ErrorCodes : : LOGICAL_ERROR ) ;
shared - > config_reload_callback ( ) ;
}
2015-04-16 06:12:35 +00:00
void Context : : shutdown ( )
{
2017-04-01 07:20:54 +00:00
shared - > shutdown ( ) ;
2015-04-16 06:12:35 +00:00
}
2016-11-11 17:01:02 +00:00
Context : : ApplicationType Context : : getApplicationType ( ) const
{
2017-04-01 07:20:54 +00:00
return shared - > application_type ;
2016-11-11 17:01:02 +00:00
}
void Context : : setApplicationType ( ApplicationType type )
{
2017-04-01 07:20:54 +00:00
/// Lock isn't required, you should set it at start
shared - > application_type = type ;
2016-11-11 17:01:02 +00:00
}
2018-02-01 13:52:29 +00:00
void Context : : setDefaultProfiles ( const Poco : : Util : : AbstractConfiguration & config )
{
shared - > default_profile_name = config . getString ( " default_profile " , " default " ) ;
shared - > system_profile_name = config . getString ( " system_profile " , shared - > default_profile_name ) ;
setSetting ( " profile " , shared - > system_profile_name ) ;
}
2016-11-11 17:01:02 +00:00
2017-03-23 14:14:56 +00:00
String Context : : getDefaultProfileName ( ) const
{
2017-04-01 07:20:54 +00:00
return shared - > default_profile_name ;
2017-03-23 14:14:56 +00:00
}
2018-02-01 13:52:29 +00:00
String Context : : getSystemProfileName ( ) const
2017-03-23 14:14:56 +00:00
{
2018-02-01 13:52:29 +00:00
return shared - > system_profile_name ;
2017-03-23 14:14:56 +00:00
}
2017-11-10 06:48:28 +00:00
String Context : : getFormatSchemaPath ( ) const
{
return shared - > format_schema_path ;
}
void Context : : setFormatSchemaPath ( const String & path )
{
shared - > format_schema_path = path ;
}
2018-07-05 23:36:09 +00:00
Context : : SampleBlockCache & Context : : getSampleBlockCache ( ) const
2018-05-30 19:23:15 +00:00
{
2018-07-05 23:36:09 +00:00
return getQueryContext ( ) . sample_block_cache ;
2018-05-30 19:23:15 +00:00
}
2018-08-30 16:31:20 +00:00
2019-05-25 13:43:52 +00:00
bool Context : : hasQueryParameters ( ) const
2019-05-18 21:07:23 +00:00
{
2019-06-15 17:52:53 +00:00
return ! query_parameters . empty ( ) ;
2019-05-18 21:07:23 +00:00
}
2019-06-15 17:52:53 +00:00
const NameToNameMap & Context : : getQueryParameters ( ) const
2019-05-18 21:07:23 +00:00
{
2019-06-15 17:52:53 +00:00
return query_parameters ;
2019-05-18 21:07:23 +00:00
}
2019-06-15 17:52:53 +00:00
void Context : : setQueryParameter ( const String & name , const String & value )
2019-05-18 21:07:23 +00:00
{
2019-06-15 17:52:53 +00:00
if ( ! query_parameters . emplace ( name , value ) . second )
throw Exception ( " Duplicate name " + backQuote ( name ) + " of query parameter " , ErrorCodes : : BAD_ARGUMENTS ) ;
2019-05-18 21:07:23 +00:00
}
2018-08-30 16:31:20 +00:00
# if USE_EMBEDDED_COMPILER
2018-09-05 11:37:41 +00:00
std : : shared_ptr < CompiledExpressionCache > Context : : getCompiledExpressionCache ( ) const
2018-08-30 16:31:20 +00:00
{
auto lock = getLock ( ) ;
2018-09-05 11:37:41 +00:00
return shared - > compiled_expression_cache ;
}
2018-08-30 16:31:20 +00:00
2018-09-05 12:42:37 +00:00
void Context : : setCompiledExpressionCache ( size_t cache_size )
2018-09-05 11:37:41 +00:00
{
2018-08-30 16:31:20 +00:00
2018-09-05 11:37:41 +00:00
auto lock = getLock ( ) ;
if ( shared - > compiled_expression_cache )
throw Exception ( " Compiled expressions cache has been already created. " , ErrorCodes : : LOGICAL_ERROR ) ;
shared - > compiled_expression_cache = std : : make_shared < CompiledExpressionCache > ( cache_size ) ;
2018-08-30 16:31:20 +00:00
}
2018-09-05 11:37:41 +00:00
void Context : : dropCompiledExpressionCache ( ) const
2018-08-30 16:31:20 +00:00
{
auto lock = getLock ( ) ;
if ( shared - > compiled_expression_cache )
shared - > compiled_expression_cache - > reset ( ) ;
}
# endif
2018-11-22 15:59:00 +00:00
2019-10-10 20:47:47 +00:00
void Context : : addXDBCBridgeCommand ( std : : unique_ptr < ShellCommand > cmd ) const
2018-11-22 15:59:00 +00:00
{
auto lock = getLock ( ) ;
shared - > bridge_commands . emplace_back ( std : : move ( cmd ) ) ;
}
2019-03-06 16:41:35 +00:00
IHostContextPtr & Context : : getHostContext ( )
{
return host_context ;
}
const IHostContextPtr & Context : : getHostContext ( ) const
{
return host_context ;
}
2018-05-21 13:49:54 +00:00
std : : shared_ptr < ActionLocksManager > Context : : getActionLocksManager ( )
{
auto lock = getLock ( ) ;
if ( ! shared - > action_locks_manager )
shared - > action_locks_manager = std : : make_shared < ActionLocksManager > ( getGlobalContext ( ) ) ;
return shared - > action_locks_manager ;
}
2018-08-13 09:11:58 +00:00
2018-06-01 15:32:27 +00:00
void Context : : setExternalTablesInitializer ( ExternalTablesInitializer & & initializer )
{
if ( external_tables_initializer_callback )
throw Exception ( " External tables initializer is already set " , ErrorCodes : : LOGICAL_ERROR ) ;
external_tables_initializer_callback = std : : move ( initializer ) ;
}
void Context : : initializeExternalTablesIfSet ( )
{
if ( external_tables_initializer_callback )
{
external_tables_initializer_callback ( * this ) ;
/// Reset callback
external_tables_initializer_callback = { } ;
}
}
2018-08-14 20:29:42 +00:00
2019-05-28 18:30:10 +00:00
void Context : : setInputInitializer ( InputInitializer & & initializer )
{
if ( input_initializer_callback )
throw Exception ( " Input initializer is already set " , ErrorCodes : : LOGICAL_ERROR ) ;
input_initializer_callback = std : : move ( initializer ) ;
}
void Context : : initializeInput ( const StoragePtr & input_storage )
{
if ( ! input_initializer_callback )
throw Exception ( " Input initializer is not set " , ErrorCodes : : LOGICAL_ERROR ) ;
input_initializer_callback ( * this , input_storage ) ;
/// Reset callback
input_initializer_callback = { } ;
}
void Context : : setInputBlocksReaderCallback ( InputBlocksReader & & reader )
{
if ( input_blocks_reader )
throw Exception ( " Input blocks reader is already set " , ErrorCodes : : LOGICAL_ERROR ) ;
input_blocks_reader = std : : move ( reader ) ;
}
InputBlocksReader Context : : getInputBlocksReaderCallback ( ) const
{
return input_blocks_reader ;
}
void Context : : resetInputCallbacks ( )
{
if ( input_initializer_callback )
input_initializer_callback = { } ;
if ( input_blocks_reader )
input_blocks_reader = { } ;
}
2017-06-02 18:48:33 +00:00
SessionCleaner : : ~ SessionCleaner ( )
{
try
{
{
2019-01-02 06:44:36 +00:00
std : : lock_guard lock { mutex } ;
2017-06-02 18:48:33 +00:00
quit = true ;
}
cond . notify_one ( ) ;
thread . join ( ) ;
}
catch ( . . . )
{
DB : : tryLogCurrentException ( __PRETTY_FUNCTION__ ) ;
}
}
void SessionCleaner : : run ( )
{
2019-02-10 21:15:14 +00:00
setThreadName ( " SessionCleaner " ) ;
2017-06-02 18:48:33 +00:00
2019-01-02 06:44:36 +00:00
std : : unique_lock lock { mutex } ;
2017-06-02 18:48:33 +00:00
while ( true )
{
auto interval = context . closeSessions ( ) ;
if ( cond . wait_for ( lock , interval , [ this ] ( ) - > bool { return quit ; } ) )
break ;
}
}
2012-08-02 17:33:31 +00:00
}