ClickHouse/dbms/src/Databases/DatabaseOnDisk.h

184 lines
5.6 KiB
C++
Raw Normal View History

2019-10-02 10:10:45 +00:00
#pragma once
2019-10-03 09:31:59 +00:00
#include <Common/escapeForFileName.h>
#include <Common/quoteString.h>
2019-10-02 10:10:45 +00:00
#include <Databases/DatabasesCommon.h>
2019-10-03 09:31:59 +00:00
#include <Interpreters/Context.h>
2019-10-03 07:59:48 +00:00
#include <Parsers/ASTCreateQuery.h>
#include <Storages/IStorage.h>
2019-10-02 10:10:45 +00:00
namespace DB
{
namespace detail
{
2019-10-10 20:47:47 +00:00
String getObjectMetadataPath(const String & base_path, const String & dictionary_name);
2019-10-02 10:10:45 +00:00
String getDatabaseMetadataPath(const String & base_path);
2019-10-03 07:59:48 +00:00
ASTPtr getQueryFromMetadata(const String & metadata_path, bool throw_on_error = true);
ASTPtr getCreateQueryFromMetadata(const String & metadata_path, const String & database, bool throw_on_error);
2019-10-02 10:10:45 +00:00
}
2019-10-10 17:33:01 +00:00
ASTPtr parseCreateQueryFromMetadataFile(const String & filepath, Poco::Logger * log);
std::pair<String, StoragePtr> createTableFromAST(
ASTCreateQuery ast_create_query,
const String & database_name,
const String & database_data_path,
Context & context,
bool has_force_restore_data_flag);
/** Get the row with the table definition based on the CREATE query.
* It is an ATTACH query that you can execute to create a table from the correspondent database.
* See the implementation.
*/
String getObjectDefinitionFromCreateQuery(const ASTPtr & query);
2019-10-08 00:24:26 +00:00
/* Class to provide basic operations with tables when metadata is stored on disk in .sql files.
2019-10-03 07:59:48 +00:00
*/
class DatabaseOnDisk
2019-10-02 10:10:45 +00:00
{
public:
2019-10-02 12:58:13 +00:00
static void createTable(
2019-10-03 07:59:48 +00:00
IDatabase & database,
2019-10-02 10:10:45 +00:00
const Context & context,
const String & table_name,
const StoragePtr & table,
2019-10-02 12:58:13 +00:00
const ASTPtr & query);
2019-10-02 10:10:45 +00:00
2019-10-10 17:33:01 +00:00
static void createDictionary(
IDatabase & database,
const Context & context,
const String & dictionary_name,
const ASTPtr & query);
2019-10-02 12:58:13 +00:00
static void removeTable(
2019-10-03 07:59:48 +00:00
IDatabase & database,
2019-10-02 10:10:45 +00:00
const Context & context,
2019-10-03 07:59:48 +00:00
const String & table_name,
Poco::Logger * log);
2019-10-02 10:10:45 +00:00
2019-10-10 17:33:01 +00:00
static void removeDictionary(
IDatabase & database,
const Context & context,
const String & dictionary_name,
Poco::Logger * log);
2019-10-03 07:59:48 +00:00
template <typename Database>
2019-10-02 12:58:13 +00:00
static void renameTable(
2019-10-03 07:59:48 +00:00
IDatabase & database,
2019-10-02 10:10:45 +00:00
const Context & context,
const String & table_name,
IDatabase & to_database,
const String & to_table_name,
2019-10-03 07:59:48 +00:00
TableStructureWriteLockHolder & lock);
2019-10-02 10:10:45 +00:00
2019-10-02 12:58:13 +00:00
static ASTPtr getCreateTableQuery(
2019-10-03 07:59:48 +00:00
const IDatabase & database,
2019-10-02 10:10:45 +00:00
const Context & context,
2019-10-03 07:59:48 +00:00
const String & table_name);
2019-10-02 10:10:45 +00:00
2019-10-02 12:58:13 +00:00
static ASTPtr tryGetCreateTableQuery(
2019-10-03 07:59:48 +00:00
const IDatabase & database,
2019-10-02 10:10:45 +00:00
const Context & context,
2019-10-03 07:59:48 +00:00
const String & table_name);
2019-10-02 10:10:45 +00:00
2019-10-10 17:33:01 +00:00
static ASTPtr getCreateDictionaryQuery(
const IDatabase & database,
const Context & context,
const String & dictionary_name);
static ASTPtr tryGetCreateDictionaryQuery(
const IDatabase & database,
const Context & context,
const String & dictionary_name);
2019-10-03 07:59:48 +00:00
static ASTPtr getCreateDatabaseQuery(
const IDatabase & database,
const Context & context);
2019-10-02 10:10:45 +00:00
2019-10-03 07:59:48 +00:00
static void drop(const IDatabase & database);
2019-10-02 10:10:45 +00:00
2019-10-10 17:33:01 +00:00
static String getObjectMetadataPath(
2019-10-03 07:59:48 +00:00
const IDatabase & database,
2019-10-10 17:33:01 +00:00
const String & object_name);
2019-10-02 10:10:45 +00:00
2019-10-10 17:33:01 +00:00
static time_t getObjectMetadataModificationTime(
2019-10-03 08:35:58 +00:00
const IDatabase & database,
2019-10-10 17:33:01 +00:00
const String & object_name);
2019-10-03 08:35:58 +00:00
2019-10-03 08:27:43 +00:00
using IteratingFunction = std::function<void(const String &)>;
2019-10-10 17:33:01 +00:00
static void iterateMetadataFiles(const IDatabase & database, Poco::Logger * log, const IteratingFunction & iterating_function);
2019-10-03 08:27:43 +00:00
2019-10-02 10:10:45 +00:00
private:
2019-10-03 07:59:48 +00:00
static ASTPtr getCreateTableQueryImpl(
const IDatabase & database,
const Context & context,
const String & table_name,
bool throw_on_error);
2019-10-10 17:33:01 +00:00
static ASTPtr getCreateDictionaryQueryImpl(
const IDatabase & database,
const Context & context,
const String & dictionary_name,
bool throw_on_error);
2019-10-03 07:59:48 +00:00
};
namespace ErrorCodes
{
extern const int NOT_IMPLEMENTED;
extern const int UNKNOWN_TABLE;
extern const int FILE_DOESNT_EXIST;
}
template <typename Database>
void DatabaseOnDisk::renameTable(
IDatabase & database,
const Context & context,
const String & table_name,
IDatabase & to_database,
const String & to_table_name,
TableStructureWriteLockHolder & lock)
{
Database * to_database_concrete = typeid_cast<Database *>(&to_database);
if (!to_database_concrete)
throw Exception("Moving tables between databases of different engines is not supported", ErrorCodes::NOT_IMPLEMENTED);
StoragePtr table = database.tryGetTable(context, table_name);
if (!table)
2019-10-08 08:10:55 +00:00
throw Exception("Table " + backQuote(database.getDatabaseName()) + "." + backQuote(table_name) + " doesn't exist.", ErrorCodes::UNKNOWN_TABLE);
2019-10-03 07:59:48 +00:00
/// Notify the table that it is renamed. If the table does not support renaming, exception is thrown.
try
{
table->rename(context.getPath() + "/data/" + escapeForFileName(to_database_concrete->getDatabaseName()) + "/",
to_database_concrete->getDatabaseName(),
to_table_name, lock);
}
catch (const Exception &)
{
throw;
}
catch (const Poco::Exception & e)
{
/// Better diagnostics.
throw Exception{Exception::CreateFromPoco, e};
}
2019-10-10 20:47:47 +00:00
ASTPtr ast = detail::getQueryFromMetadata(detail::getObjectMetadataPath(database.getMetadataPath(), table_name));
2019-10-03 07:59:48 +00:00
if (!ast)
2019-10-08 08:10:55 +00:00
throw Exception("There is no metadata file for table " + backQuote(table_name) + ".", ErrorCodes::FILE_DOESNT_EXIST);
2019-10-03 07:59:48 +00:00
ast->as<ASTCreateQuery &>().table = to_table_name;
/// NOTE Non-atomic.
to_database_concrete->createTable(context, to_table_name, table, ast);
database.removeTable(context, table_name);
}
2019-10-02 10:10:45 +00:00
}