2016-03-19 01:18:49 +00:00
# pragma once
2022-07-20 20:54:43 +00:00
# include <Core/UUID.h>
# include <Databases/LoadingStrictnessLevel.h>
# include <Interpreters/Context_fwd.h>
2019-03-11 14:01:45 +00:00
# include <Parsers/IAST_fwd.h>
2019-05-17 14:34:25 +00:00
# include <Storages/IStorage_fwd.h>
2022-07-20 20:54:43 +00:00
# include <base/types.h>
2019-08-27 20:43:08 +00:00
# include <Common/Exception.h>
2021-08-31 08:53:48 +00:00
# include <Common/ThreadPool.h>
2022-09-16 14:25:32 +00:00
# include <QueryPipeline/BlockIO.h>
2021-04-10 23:33:54 +00:00
2019-03-11 14:01:45 +00:00
# include <ctime>
# include <functional>
# include <memory>
2021-05-06 06:07:59 +00:00
# include <mutex>
# include <vector>
# include <map>
2016-12-12 07:24:56 +00:00
2016-03-19 01:18:49 +00:00
namespace DB
{
2017-01-23 18:05:07 +00:00
struct Settings ;
2019-08-27 20:43:08 +00:00
struct ConstraintsDescription ;
struct IndicesDescription ;
2021-05-06 06:07:59 +00:00
struct StorageInMemoryMetadata ;
struct StorageID ;
2019-12-25 16:13:48 +00:00
class ASTCreateQuery ;
2021-08-27 06:30:21 +00:00
class AlterCommands ;
class SettingsChanges ;
2020-07-15 19:25:31 +00:00
using DictionariesWithID = std : : vector < std : : pair < String , UUID > > ;
2021-08-26 13:19:52 +00:00
struct ParsedTablesMetadata ;
2021-09-02 13:34:46 +00:00
struct QualifiedTableName ;
2022-06-22 22:56:41 +00:00
class IRestoreCoordination ;
2019-08-27 20:43:08 +00:00
namespace ErrorCodes
{
extern const int NOT_IMPLEMENTED ;
2019-11-01 12:47:55 +00:00
extern const int CANNOT_GET_CREATE_TABLE_QUERY ;
2021-08-31 08:53:48 +00:00
extern const int LOGICAL_ERROR ;
2019-08-27 20:43:08 +00:00
}
2016-12-12 07:24:56 +00:00
2019-10-10 17:33:01 +00:00
class IDatabaseTablesIterator
2016-03-19 01:18:49 +00:00
{
public :
virtual void next ( ) = 0 ;
virtual bool isValid ( ) const = 0 ;
virtual const String & name ( ) const = 0 ;
2020-06-02 02:06:16 +00:00
/// This method can return nullptr if it's Lazy database
/// (a database with support for lazy tables loading
/// - it maintains a list of tables but tables are loaded lazily).
2019-09-26 07:16:31 +00:00
virtual const StoragePtr & table ( ) const = 0 ;
2016-03-19 01:18:49 +00:00
2022-03-12 17:46:38 +00:00
explicit IDatabaseTablesIterator ( const String & database_name_ ) : database_name ( database_name_ ) { }
explicit IDatabaseTablesIterator ( String & & database_name_ ) : database_name ( std : : move ( database_name_ ) ) { }
2021-07-05 19:07:56 +00:00
2019-10-10 17:33:01 +00:00
virtual ~ IDatabaseTablesIterator ( ) = default ;
2020-04-01 22:41:29 +00:00
virtual UUID uuid ( ) const { return UUIDHelpers : : Nil ; }
2020-07-07 12:11:58 +00:00
const String & databaseName ( ) const { assert ( ! database_name . empty ( ) ) ; return database_name ; }
protected :
2022-03-12 17:46:38 +00:00
String database_name ;
2019-10-10 17:33:01 +00:00
} ;
/// Copies list of tables and iterates through such snapshot.
2020-04-01 22:41:29 +00:00
class DatabaseTablesSnapshotIterator : public IDatabaseTablesIterator
2019-10-10 17:33:01 +00:00
{
private :
Tables tables ;
Tables : : iterator it ;
2020-04-01 22:41:29 +00:00
protected :
2022-03-12 17:46:38 +00:00
DatabaseTablesSnapshotIterator ( DatabaseTablesSnapshotIterator & & other ) noexcept
2021-07-05 19:07:56 +00:00
: IDatabaseTablesIterator ( std : : move ( other . database_name ) )
2020-04-01 22:41:29 +00:00
{
size_t idx = std : : distance ( other . tables . begin ( ) , other . it ) ;
std : : swap ( tables , other . tables ) ;
other . it = other . tables . end ( ) ;
it = tables . begin ( ) ;
std : : advance ( it , idx ) ;
}
2019-10-10 17:33:01 +00:00
public :
2020-07-07 12:11:58 +00:00
DatabaseTablesSnapshotIterator ( const Tables & tables_ , const String & database_name_ )
2021-07-05 19:07:56 +00:00
: IDatabaseTablesIterator ( database_name_ ) , tables ( tables_ ) , it ( tables . begin ( ) )
2020-07-07 12:11:58 +00:00
{
}
2019-10-10 17:33:01 +00:00
2020-07-07 12:11:58 +00:00
DatabaseTablesSnapshotIterator ( Tables & & tables_ , String & & database_name_ )
2021-07-05 19:07:56 +00:00
: IDatabaseTablesIterator ( std : : move ( database_name_ ) ) , tables ( std : : move ( tables_ ) ) , it ( tables . begin ( ) )
2020-07-07 12:11:58 +00:00
{
}
2019-10-10 17:33:01 +00:00
2020-01-21 08:54:26 +00:00
void next ( ) override { + + it ; }
2019-10-10 17:33:01 +00:00
2020-01-21 08:54:26 +00:00
bool isValid ( ) const override { return it ! = tables . end ( ) ; }
2019-10-10 17:33:01 +00:00
2020-01-21 08:54:26 +00:00
const String & name ( ) const override { return it - > first ; }
2019-10-10 17:33:01 +00:00
2020-01-21 08:54:26 +00:00
const StoragePtr & table ( ) const override { return it - > second ; }
2016-03-19 01:18:49 +00:00
} ;
2019-10-10 17:33:01 +00:00
using DatabaseTablesIteratorPtr = std : : unique_ptr < IDatabaseTablesIterator > ;
2016-03-19 01:18:49 +00:00
2017-01-23 18:05:07 +00:00
/** Database engine.
* It is responsible for :
2019-10-10 17:33:01 +00:00
* - initialization of set of known tables and dictionaries ;
2017-01-23 18:05:07 +00:00
* - checking existence of a table and getting a table object ;
* - retrieving a list of all tables ;
* - creating and dropping tables ;
* - renaming tables and moving between databases with same engine .
2016-03-19 01:18:49 +00:00
*/
class IDatabase : public std : : enable_shared_from_this < IDatabase >
{
public :
2019-11-01 12:47:55 +00:00
IDatabase ( ) = delete ;
2022-03-12 17:46:38 +00:00
explicit IDatabase ( String database_name_ ) : database_name ( std : : move ( database_name_ ) ) { }
2019-11-01 12:47:55 +00:00
2017-01-23 18:05:07 +00:00
/// Get name of database engine.
2016-03-19 01:18:49 +00:00
virtual String getEngineName ( ) const = 0 ;
2020-10-15 15:57:17 +00:00
virtual bool canContainMergeTreeTables ( ) const { return true ; }
virtual bool canContainDistributedTables ( ) const { return true ; }
2019-07-19 14:22:57 +00:00
/// Load a set of existing tables.
2017-04-17 11:56:55 +00:00
/// You can call only once, right after the object is created.
2022-03-12 17:46:38 +00:00
virtual void loadStoredObjects ( /// NOLINT
2021-08-29 18:03:33 +00:00
ContextMutablePtr /*context*/ ,
2022-07-20 20:54:43 +00:00
LoadingStrictnessLevel /*mode*/ ,
bool /* skip_startup_tables */ )
2021-08-29 18:03:33 +00:00
{
}
2021-08-26 13:19:52 +00:00
virtual bool supportsLoadingInTopologicalOrder ( ) const { return false ; }
2021-08-31 08:53:48 +00:00
virtual void beforeLoadingMetadata (
2022-07-20 20:54:43 +00:00
ContextMutablePtr /*context*/ , LoadingStrictnessLevel /*mode*/ )
2021-08-31 08:53:48 +00:00
{
}
2022-06-21 22:50:16 +00:00
virtual void loadTablesMetadata ( ContextPtr /*local_context*/ , ParsedTablesMetadata & /*metadata*/ , bool /*is_startup*/ )
2021-08-26 13:19:52 +00:00
{
throw Exception ( ErrorCodes : : LOGICAL_ERROR , " Not implemented " ) ;
}
2022-07-20 20:54:43 +00:00
virtual void loadTableFromMetadata ( ContextMutablePtr /*local_context*/ , const String & /*file_path*/ , const QualifiedTableName & /*name*/ , const ASTPtr & /*ast*/ ,
LoadingStrictnessLevel /*mode*/ )
2021-08-26 13:19:52 +00:00
{
throw Exception ( ErrorCodes : : LOGICAL_ERROR , " Not implemented " ) ;
}
2022-07-20 20:54:43 +00:00
virtual void startupTables ( ThreadPool & /*thread_pool*/ , LoadingStrictnessLevel /*mode*/ ) { }
2016-06-10 20:46:58 +00:00
2022-02-03 12:17:55 +00:00
/// Check the existence of the table in memory (attached).
2021-04-10 23:33:54 +00:00
virtual bool isTableExist ( const String & name , ContextPtr context ) const = 0 ;
2016-03-19 01:18:49 +00:00
2022-02-03 12:17:55 +00:00
/// Check the existence of the table in any state (in active / detached / detached permanently state).
/// Throws exception when table exists.
virtual void checkMetadataFilenameAvailability ( const String & /*table_name*/ ) const { }
2017-04-17 11:56:55 +00:00
/// Get the table for work. Return nullptr if there is no table.
2021-04-10 23:33:54 +00:00
virtual StoragePtr tryGetTable ( const String & name , ContextPtr context ) const = 0 ;
2016-03-19 01:18:49 +00:00
2022-04-30 09:46:42 +00:00
StoragePtr getTable ( const String & name , ContextPtr context ) const ;
2020-04-13 14:09:56 +00:00
virtual UUID tryGetTableUUID ( const String & /*table_name*/ ) const { return UUIDHelpers : : Nil ; }
2019-06-02 12:11:01 +00:00
using FilterByNameFunction = std : : function < bool ( const String & ) > ;
2017-04-17 11:56:55 +00:00
/// Get an iterator that allows you to pass through all the tables.
/// It is possible to have "hidden" tables that are not visible when passing through, but are visible if you get them by name using the functions above.
2022-03-12 17:46:38 +00:00
virtual DatabaseTablesIteratorPtr getTablesIterator ( ContextPtr context , const FilterByNameFunction & filter_by_table_name = { } ) const = 0 ; /// NOLINT
2019-10-10 17:33:01 +00:00
2017-04-17 11:56:55 +00:00
/// Is the database empty.
2020-04-23 16:51:48 +00:00
virtual bool empty ( ) const = 0 ;
2016-03-19 01:18:49 +00:00
2017-04-17 11:56:55 +00:00
/// Add the table to the database. Record its presence in the metadata.
2017-01-23 18:05:07 +00:00
virtual void createTable (
2021-04-10 23:33:54 +00:00
ContextPtr /*context*/ ,
2019-11-01 12:47:55 +00:00
const String & /*name*/ ,
const StoragePtr & /*table*/ ,
const ASTPtr & /*query*/ )
{
2023-01-23 21:13:58 +00:00
throw Exception ( ErrorCodes : : NOT_IMPLEMENTED , " There is no CREATE TABLE query for Database{} " , getEngineName ( ) ) ;
2019-11-01 12:47:55 +00:00
}
2016-03-19 01:18:49 +00:00
2020-01-22 11:30:11 +00:00
/// Delete the table from the database, drop table and delete the metadata.
2022-03-12 17:46:38 +00:00
virtual void dropTable ( /// NOLINT
2021-04-10 23:33:54 +00:00
ContextPtr /*context*/ ,
2020-03-20 00:07:52 +00:00
const String & /*name*/ ,
2022-06-23 07:59:13 +00:00
[[maybe_unused]] bool sync = false )
2019-11-01 12:47:55 +00:00
{
2023-01-23 21:13:58 +00:00
throw Exception ( ErrorCodes : : NOT_IMPLEMENTED , " There is no DROP TABLE query for Database{} " , getEngineName ( ) ) ;
2019-11-01 12:47:55 +00:00
}
2016-03-19 01:18:49 +00:00
2017-04-17 11:56:55 +00:00
/// Add a table to the database, but do not add it to the metadata. The database may not support this method.
2020-11-30 17:52:32 +00:00
///
/// Note: ATTACH TABLE statement actually uses createTable method.
2022-03-12 17:46:38 +00:00
virtual void attachTable ( ContextPtr /* context */ , const String & /*name*/ , const StoragePtr & /*table*/ , [[maybe_unused]] const String & relative_table_path = { } ) /// NOLINT
2019-11-01 12:47:55 +00:00
{
2023-01-23 21:13:58 +00:00
throw Exception ( ErrorCodes : : NOT_IMPLEMENTED , " There is no ATTACH TABLE query for Database{} " , getEngineName ( ) ) ;
2019-11-01 12:47:55 +00:00
}
2016-03-19 01:18:49 +00:00
2017-04-17 11:56:55 +00:00
/// Forget about the table without deleting it, and return it. The database may not support this method.
2021-11-10 13:13:27 +00:00
virtual StoragePtr detachTable ( ContextPtr /* context */ , const String & /*name*/ )
2019-11-01 12:47:55 +00:00
{
2023-01-23 21:13:58 +00:00
throw Exception ( ErrorCodes : : NOT_IMPLEMENTED , " There is no DETACH TABLE query for Database{} " , getEngineName ( ) ) ;
2019-11-01 12:47:55 +00:00
}
2016-03-19 01:18:49 +00:00
2020-11-30 17:52:32 +00:00
/// Forget about the table without deleting it's data, but rename metadata file to prevent reloading it
/// with next restart. The database may not support this method.
2021-04-10 23:33:54 +00:00
virtual void detachTablePermanently ( ContextPtr /*context*/ , const String & /*name*/ )
2020-11-30 17:52:32 +00:00
{
2023-01-23 21:13:58 +00:00
throw Exception ( ErrorCodes : : NOT_IMPLEMENTED , " There is no DETACH TABLE PERMANENTLY query for Database{} " , getEngineName ( ) ) ;
2020-11-30 17:52:32 +00:00
}
2022-08-08 14:06:08 +00:00
/// Returns list of table names that were permanently detached.
/// This list may not be updated in runtime and may be filled only on server startup
virtual Strings getNamesOfPermanentlyDetachedTables ( ) const
{
2023-01-23 21:13:58 +00:00
throw Exception ( ErrorCodes : : NOT_IMPLEMENTED , " Cannot get names of permanently detached tables for Database{} " , getEngineName ( ) ) ;
2022-08-08 14:06:08 +00:00
}
2017-04-17 11:56:55 +00:00
/// Rename the table and possibly move the table to another database.
2017-01-23 18:05:07 +00:00
virtual void renameTable (
2021-04-10 23:33:54 +00:00
ContextPtr /*context*/ ,
2019-08-27 20:43:08 +00:00
const String & /*name*/ ,
IDatabase & /*to_database*/ ,
2020-03-31 20:38:05 +00:00
const String & /*to_name*/ ,
2020-07-16 21:41:26 +00:00
bool /*exchange*/ ,
bool /*dictionary*/ )
2019-08-27 20:43:08 +00:00
{
2023-01-23 21:13:58 +00:00
throw Exception ( ErrorCodes : : NOT_IMPLEMENTED , " {}: renameTable() is not supported " , getEngineName()) ;
2019-08-27 20:43:08 +00:00
}
2016-09-02 13:04:11 +00:00
2017-09-17 18:49:43 +00:00
using ASTModifier = std : : function < void ( IAST & ) > ;
2016-05-13 21:08:19 +00:00
2017-04-17 11:56:55 +00:00
/// Change the table structure in metadata.
2020-06-22 09:49:21 +00:00
/// You must call under the alter_lock of the corresponding table . If engine_modifier is empty, then engine does not change.
2016-05-13 21:08:19 +00:00
virtual void alterTable (
2021-04-10 23:33:54 +00:00
ContextPtr /*context*/ ,
2020-03-20 12:45:06 +00:00
const StorageID & /*table_id*/ ,
2019-12-26 18:17:05 +00:00
const StorageInMemoryMetadata & /*metadata*/ )
2019-08-27 20:43:08 +00:00
{
2023-01-23 21:13:58 +00:00
throw Exception ( ErrorCodes : : NOT_IMPLEMENTED , " {}: alterTable() is not supported " , getEngineName()) ;
2019-08-27 20:43:08 +00:00
}
2016-05-13 21:08:19 +00:00
2017-09-11 12:39:01 +00:00
/// Returns time of table's metadata change, 0 if there is no corresponding metadata file.
2019-11-06 16:05:04 +00:00
virtual time_t getObjectMetadataModificationTime ( const String & /*name*/ ) const
2019-11-01 12:47:55 +00:00
{
return static_cast < time_t > ( 0 ) ;
}
2017-09-11 12:39:01 +00:00
2017-04-17 11:56:55 +00:00
/// Get the CREATE TABLE query for the table. It can also provide information for detached tables for which there is metadata.
2021-04-10 23:33:54 +00:00
ASTPtr tryGetCreateTableQuery ( const String & name , ContextPtr context ) const noexcept
2019-11-01 12:47:55 +00:00
{
2020-05-28 20:10:45 +00:00
return getCreateTableQueryImpl ( name , context , false ) ;
2019-11-01 12:47:55 +00:00
}
2016-03-19 01:18:49 +00:00
2021-04-10 23:33:54 +00:00
ASTPtr getCreateTableQuery ( const String & name , ContextPtr context ) const
2018-03-23 19:56:24 +00:00
{
2020-05-28 20:10:45 +00:00
return getCreateTableQueryImpl ( name , context , true ) ;
2018-03-23 19:56:24 +00:00
}
2018-03-14 19:56:44 +00:00
2018-03-13 13:28:32 +00:00
/// Get the CREATE DATABASE query for current database.
2020-04-23 16:51:48 +00:00
virtual ASTPtr getCreateDatabaseQuery ( ) const = 0 ;
2016-03-19 01:18:49 +00:00
2021-09-27 11:23:18 +00:00
String getDatabaseComment ( ) const
{
std : : lock_guard lock { mutex } ;
return comment ;
}
void setDatabaseComment ( String new_comment )
{
std : : lock_guard lock { mutex } ;
comment = std : : move ( new_comment ) ;
}
2018-05-21 03:01:38 +00:00
/// Get name of database.
2020-07-07 12:11:58 +00:00
String getDatabaseName ( ) const
{
std : : lock_guard lock { mutex } ;
return database_name ;
}
2020-07-02 20:39:31 +00:00
/// Get UUID of database.
virtual UUID getUUID ( ) const { return UUIDHelpers : : Nil ; }
2021-11-02 12:58:45 +00:00
virtual void renameDatabase ( ContextPtr , const String & /*new_name*/ )
2020-07-07 12:11:58 +00:00
{
2023-01-23 21:13:58 +00:00
throw Exception ( ErrorCodes : : NOT_IMPLEMENTED , " {}: RENAME DATABASE is not supported " , getEngineName ( ) ) ;
2020-07-07 12:11:58 +00:00
}
2017-11-03 19:53:10 +00:00
/// Returns path for persistent data storage if the database supports it, empty string otherwise
2018-02-21 19:26:59 +00:00
virtual String getDataPath ( ) const { return { } ; }
2019-12-25 21:17:49 +00:00
2019-12-25 16:13:48 +00:00
/// Returns path for persistent data storage for table if the database supports it, empty string otherwise. Table must exist
virtual String getTableDataPath ( const String & /*table_name*/ ) const { return { } ; }
2019-11-11 11:34:03 +00:00
/// Returns path for persistent data storage for CREATE/ATTACH query if the database supports it, empty string otherwise
2019-12-25 16:13:48 +00:00
virtual String getTableDataPath ( const ASTCreateQuery & /*query*/ ) const { return { } ; }
2018-02-21 19:26:59 +00:00
/// Returns metadata path if the database supports it, empty string otherwise
virtual String getMetadataPath ( ) const { return { } ; }
/// Returns metadata path of a concrete table if the database supports it, empty string otherwise
2019-10-10 17:33:01 +00:00
virtual String getObjectMetadataPath ( const String & /*table_name*/ ) const { return { } ; }
2017-11-03 19:53:10 +00:00
2020-04-12 20:50:32 +00:00
/// All tables and dictionaries should be detached before detaching the database.
virtual bool shouldBeEmptyOnDetach ( ) const { return true ; }
2020-09-14 19:25:02 +00:00
virtual void assertCanBeDetached ( bool /*cleanup*/ ) { }
2021-04-20 11:22:02 +00:00
virtual void waitDetachedTableNotInUse ( const UUID & /*uuid*/ ) { }
virtual void checkDetachedTableNotInUse ( const UUID & /*uuid*/ ) { }
2020-11-24 12:28:54 +00:00
2017-04-17 11:56:55 +00:00
/// Ask all tables to complete the background threads they are using and delete all table objects.
2016-03-19 01:18:49 +00:00
virtual void shutdown ( ) = 0 ;
2018-06-09 15:48:22 +00:00
/// Delete data and metadata stored inside the database, if exists.
2021-04-10 23:33:54 +00:00
virtual void drop ( ContextPtr /*context*/ ) { }
2016-03-28 11:19:14 +00:00
2021-09-15 15:22:33 +00:00
virtual void applySettingsChanges ( const SettingsChanges & , ContextPtr )
2021-08-27 06:30:21 +00:00
{
2021-09-08 22:25:08 +00:00
throw Exception ( ErrorCodes : : NOT_IMPLEMENTED ,
" Database engine {} either does not support settings, or does not support altering settings " ,
getEngineName ( ) ) ;
2021-08-27 06:30:21 +00:00
}
2021-11-11 20:35:26 +00:00
virtual bool hasReplicationThread ( ) const { return false ; }
virtual void stopReplication ( )
{
throw Exception ( ErrorCodes : : LOGICAL_ERROR , " Database engine {} does not run a replication thread! " , getEngineName ( ) ) ;
}
2022-09-16 14:25:32 +00:00
virtual bool shouldReplicateQuery ( const ContextPtr & /*query_context*/ , const ASTPtr & /*query_ptr*/ ) const { return false ; }
virtual BlockIO tryEnqueueReplicatedDDL ( const ASTPtr & /*query*/ , ContextPtr /*query_context*/ , [[maybe_unused]] bool internal = false ) /// NOLINT
{
throw Exception ( ErrorCodes : : LOGICAL_ERROR , " Database engine {} does not have replicated DDL queue " , getEngineName ( ) ) ;
}
2022-06-22 22:56:41 +00:00
/// Returns CREATE TABLE queries and corresponding tables prepared for writing to a backup.
2022-06-23 10:17:54 +00:00
virtual std : : vector < std : : pair < ASTPtr , StoragePtr > > getTablesForBackup ( const FilterByNameFunction & filter , const ContextPtr & context ) const ;
2022-05-31 09:33:23 +00:00
/// Creates a table restored from backup.
2022-06-22 22:56:41 +00:00
virtual void createTableRestoredFromBackup ( const ASTPtr & create_table_query , ContextMutablePtr context , std : : shared_ptr < IRestoreCoordination > restore_coordination , UInt64 timeout_ms ) ;
2022-01-18 10:28:27 +00:00
2021-04-10 23:33:54 +00:00
virtual ~ IDatabase ( ) = default ;
2019-11-01 12:47:55 +00:00
protected :
2021-04-10 23:33:54 +00:00
virtual ASTPtr getCreateTableQueryImpl ( const String & /*name*/ , ContextPtr /*context*/ , bool throw_on_error ) const
2019-11-01 12:47:55 +00:00
{
if ( throw_on_error )
2023-01-23 21:13:58 +00:00
throw Exception ( ErrorCodes : : CANNOT_GET_CREATE_TABLE_QUERY , " There is no SHOW CREATE TABLE query for Database{} " , getEngineName ( ) ) ;
2019-11-01 12:47:55 +00:00
return nullptr ;
}
2020-07-07 12:11:58 +00:00
mutable std : : mutex mutex ;
2022-06-27 20:48:27 +00:00
String database_name TSA_GUARDED_BY ( mutex ) ;
String comment TSA_GUARDED_BY ( mutex ) ;
2016-03-19 01:18:49 +00:00
} ;
using DatabasePtr = std : : shared_ptr < IDatabase > ;
using Databases = std : : map < String , DatabasePtr > ;
}