add uuid to system.tables

This commit is contained in:
Alexander Tokmakov 2020-04-02 01:41:29 +03:00
parent 04eb205cd7
commit 3321f44904
33 changed files with 124 additions and 82 deletions

View File

@ -44,7 +44,7 @@ void ReplicasStatusHandler::handleRequest(Poco::Net::HTTPServerRequest & request
if (db.second->getEngineName() == "Lazy") if (db.second->getEngineName() == "Lazy")
continue; continue;
for (auto iterator = db.second->getTablesIterator(context); iterator->isValid(); iterator->next()) for (auto iterator = db.second->getTablesIterator(); iterator->isValid(); iterator->next())
{ {
auto & table = iterator->table(); auto & table = iterator->table();
StorageReplicatedMergeTree * table_replicated = dynamic_cast<StorageReplicatedMergeTree *>(table.get()); StorageReplicatedMergeTree * table_replicated = dynamic_cast<StorageReplicatedMergeTree *>(table.get());

View File

@ -18,6 +18,15 @@ namespace ErrorCodes
extern const int CANNOT_ASSIGN_ALTER; extern const int CANNOT_ASSIGN_ALTER;
} }
class AtomicDatabaseTablesSnapshotIterator final : public DatabaseTablesSnapshotIterator
{
public:
AtomicDatabaseTablesSnapshotIterator(DatabaseTablesSnapshotIterator && base)
: DatabaseTablesSnapshotIterator(std::move(base)) {}
UUID uuid() const override { return table()->getStorageID().uuid; }
};
DatabaseAtomic::DatabaseAtomic(String name_, String metadata_path_, Context & context_) DatabaseAtomic::DatabaseAtomic(String name_, String metadata_path_, Context & context_)
: DatabaseOrdinary(name_, metadata_path_, context_) : DatabaseOrdinary(name_, metadata_path_, context_)
{ {
@ -233,5 +242,17 @@ void DatabaseAtomic::cleenupDetachedTables()
} }
} }
DatabaseTablesIteratorPtr DatabaseAtomic::getTablesIterator(const IDatabase::FilterByNameFunction & filter_by_table_name)
{
auto base_iter = DatabaseWithOwnTablesBase::getTablesIterator(filter_by_table_name);
return std::make_unique<AtomicDatabaseTablesSnapshotIterator>(std::move(typeid_cast<DatabaseTablesSnapshotIterator &>(*base_iter)));
}
DatabaseTablesIteratorPtr DatabaseAtomic::getTablesWithDictionaryTablesIterator(const IDatabase::FilterByNameFunction & filter_by_dictionary_name)
{
auto base_iter = DatabaseWithDictionaries::getTablesWithDictionaryTablesIterator(filter_by_dictionary_name);
return std::make_unique<AtomicDatabaseTablesSnapshotIterator>(std::move(typeid_cast<DatabaseTablesSnapshotIterator &>(*base_iter)));
}
} }

View File

@ -42,6 +42,9 @@ public:
void loadStoredObjects(Context & context, bool has_force_restore_data_flag) override; void loadStoredObjects(Context & context, bool has_force_restore_data_flag) override;
void shutdown() override; void shutdown() override;
DatabaseTablesIteratorPtr getTablesIterator(const FilterByNameFunction & filter_by_table_name) override;
DatabaseTablesIteratorPtr getTablesWithDictionaryTablesIterator(const FilterByNameFunction & filter_by_dictionary_name) override;
private: private:
void commitAlterTable(const StorageID & table_id, const String & table_metadata_tmp_path, const String & table_metadata_path) override; void commitAlterTable(const StorageID & table_id, const String & table_metadata_tmp_path, const String & table_metadata_path) override;
void commitCreateTable(const ASTCreateQuery & query, const StoragePtr & table, void commitCreateTable(const ASTCreateQuery & query, const StoragePtr & table,

View File

@ -17,25 +17,26 @@ namespace ErrorCodes
extern const int SYNTAX_ERROR; extern const int SYNTAX_ERROR;
} }
DatabaseDictionary::DatabaseDictionary(const String & name_) DatabaseDictionary::DatabaseDictionary(const String & name_, const Context & global_context_)
: IDatabase(name_), : IDatabase(name_)
log(&Logger::get("DatabaseDictionary(" + database_name + ")")) , log(&Logger::get("DatabaseDictionary(" + database_name + ")"))
, global_context(global_context_.getGlobalContext())
{ {
} }
Tables DatabaseDictionary::listTables(const Context & context, const FilterByNameFunction & filter_by_name) Tables DatabaseDictionary::listTables(const FilterByNameFunction & filter_by_name)
{ {
Tables tables; Tables tables;
ExternalLoader::LoadResults load_results; ExternalLoader::LoadResults load_results;
if (filter_by_name) if (filter_by_name)
{ {
/// If `filter_by_name` is set, we iterate through all dictionaries with such names. That's why we need to load all of them. /// If `filter_by_name` is set, we iterate through all dictionaries with such names. That's why we need to load all of them.
load_results = context.getExternalDictionariesLoader().tryLoad<ExternalLoader::LoadResults>(filter_by_name); load_results = global_context.getExternalDictionariesLoader().tryLoad<ExternalLoader::LoadResults>(filter_by_name);
} }
else else
{ {
/// If `filter_by_name` isn't set, we iterate through only already loaded dictionaries. We don't try to load all dictionaries in this case. /// If `filter_by_name` isn't set, we iterate through only already loaded dictionaries. We don't try to load all dictionaries in this case.
load_results = context.getExternalDictionariesLoader().getCurrentLoadResults(); load_results = global_context.getExternalDictionariesLoader().getCurrentLoadResults();
} }
for (const auto & load_result: load_results) for (const auto & load_result: load_results)
@ -47,7 +48,7 @@ Tables DatabaseDictionary::listTables(const Context & context, const FilterByNam
auto dict_name = dict_ptr->getName(); auto dict_name = dict_ptr->getName();
const DictionaryStructure & dictionary_structure = dict_ptr->getStructure(); const DictionaryStructure & dictionary_structure = dict_ptr->getStructure();
auto columns = StorageDictionary::getNamesAndTypes(dictionary_structure); auto columns = StorageDictionary::getNamesAndTypes(dictionary_structure);
tables[dict_name] = StorageDictionary::create(StorageID(getDatabaseName(), dict_name), ColumnsDescription{columns}, context, true, dict_name); tables[dict_name] = StorageDictionary::create(StorageID(getDatabaseName(), dict_name), ColumnsDescription{columns}, global_context, true, dict_name);
} }
} }
return tables; return tables;
@ -75,9 +76,9 @@ StoragePtr DatabaseDictionary::tryGetTable(
return {}; return {};
} }
DatabaseTablesIteratorPtr DatabaseDictionary::getTablesIterator(const Context & context, const FilterByNameFunction & filter_by_table_name) DatabaseTablesIteratorPtr DatabaseDictionary::getTablesIterator(const FilterByNameFunction & filter_by_table_name)
{ {
return std::make_unique<DatabaseTablesSnapshotIterator>(listTables(context, filter_by_table_name)); return std::make_unique<DatabaseTablesSnapshotIterator>(listTables(filter_by_table_name));
} }
bool DatabaseDictionary::empty(const Context & context) const bool DatabaseDictionary::empty(const Context & context) const

View File

@ -22,7 +22,7 @@ namespace DB
class DatabaseDictionary final : public IDatabase class DatabaseDictionary final : public IDatabase
{ {
public: public:
DatabaseDictionary(const String & name_); DatabaseDictionary(const String & name_, const Context & global_context);
String getEngineName() const override String getEngineName() const override
{ {
@ -37,7 +37,7 @@ public:
const Context & context, const Context & context,
const String & table_name) const override; const String & table_name) const override;
DatabaseTablesIteratorPtr getTablesIterator(const Context & context, const FilterByNameFunction & filter_by_table_name) override; DatabaseTablesIteratorPtr getTablesIterator(const FilterByNameFunction & filter_by_table_name) override;
bool empty(const Context & context) const override; bool empty(const Context & context) const override;
@ -52,8 +52,9 @@ private:
mutable std::mutex mutex; mutable std::mutex mutex;
Poco::Logger * log; Poco::Logger * log;
const Context & global_context;
Tables listTables(const Context & context, const FilterByNameFunction & filter_by_name); Tables listTables(const FilterByNameFunction & filter_by_name);
}; };
} }

View File

@ -70,7 +70,7 @@ DatabasePtr DatabaseFactory::getImpl(
else if (engine_name == "Memory") else if (engine_name == "Memory")
return std::make_shared<DatabaseMemory>(database_name); return std::make_shared<DatabaseMemory>(database_name);
else if (engine_name == "Dictionary") else if (engine_name == "Dictionary")
return std::make_shared<DatabaseDictionary>(database_name); return std::make_shared<DatabaseDictionary>(database_name, context);
#if USE_MYSQL #if USE_MYSQL

View File

@ -115,7 +115,7 @@ bool DatabaseLazy::isTableExist(
} }
StoragePtr DatabaseLazy::tryGetTable( StoragePtr DatabaseLazy::tryGetTable(
const Context & context, const Context & /*context*/,
const String & table_name) const const String & table_name) const
{ {
SCOPE_EXIT({ clearExpiredTables(); }); SCOPE_EXIT({ clearExpiredTables(); });
@ -135,10 +135,10 @@ StoragePtr DatabaseLazy::tryGetTable(
} }
} }
return loadTable(context, table_name); return loadTable(table_name);
} }
DatabaseTablesIteratorPtr DatabaseLazy::getTablesIterator(const Context & context, const FilterByNameFunction & filter_by_table_name) DatabaseTablesIteratorPtr DatabaseLazy::getTablesIterator(const FilterByNameFunction & filter_by_table_name)
{ {
std::lock_guard lock(mutex); std::lock_guard lock(mutex);
Strings filtered_tables; Strings filtered_tables;
@ -148,7 +148,7 @@ DatabaseTablesIteratorPtr DatabaseLazy::getTablesIterator(const Context & contex
filtered_tables.push_back(table_name); filtered_tables.push_back(table_name);
} }
std::sort(filtered_tables.begin(), filtered_tables.end()); std::sort(filtered_tables.begin(), filtered_tables.end());
return std::make_unique<DatabaseLazyIterator>(*this, context, std::move(filtered_tables)); return std::make_unique<DatabaseLazyIterator>(*this, std::move(filtered_tables));
} }
bool DatabaseLazy::empty(const Context & /* context */) const bool DatabaseLazy::empty(const Context & /* context */) const
@ -218,7 +218,7 @@ DatabaseLazy::~DatabaseLazy()
} }
} }
StoragePtr DatabaseLazy::loadTable(const Context & context, const String & table_name) const StoragePtr DatabaseLazy::loadTable(const String & table_name) const
{ {
SCOPE_EXIT({ clearExpiredTables(); }); SCOPE_EXIT({ clearExpiredTables(); });
@ -229,9 +229,9 @@ StoragePtr DatabaseLazy::loadTable(const Context & context, const String & table
try try
{ {
StoragePtr table; StoragePtr table;
Context context_copy(context); /// some tables can change context, but not LogTables Context context_copy(global_context); /// some tables can change context, but not LogTables
auto ast = parseQueryFromMetadata(log, context, table_metadata_path, /*throw_on_error*/ true, /*remove_empty*/false); auto ast = parseQueryFromMetadata(log, global_context, table_metadata_path, /*throw_on_error*/ true, /*remove_empty*/false);
if (ast) if (ast)
{ {
auto & ast_create = ast->as<const ASTCreateQuery &>(); auto & ast_create = ast->as<const ASTCreateQuery &>();
@ -299,10 +299,9 @@ void DatabaseLazy::clearExpiredTables() const
} }
DatabaseLazyIterator::DatabaseLazyIterator(DatabaseLazy & database_, const Context & context_, Strings && table_names_) DatabaseLazyIterator::DatabaseLazyIterator(DatabaseLazy & database_, Strings && table_names_)
: database(database_) : database(database_)
, table_names(std::move(table_names_)) , table_names(std::move(table_names_))
, context(context_)
, iterator(table_names.begin()) , iterator(table_names.begin())
, current_storage(nullptr) , current_storage(nullptr)
{ {
@ -312,7 +311,7 @@ void DatabaseLazyIterator::next()
{ {
current_storage.reset(); current_storage.reset();
++iterator; ++iterator;
while (isValid() && !database.isTableExist(context, *iterator)) while (isValid() && !database.isTableExist(database.global_context, *iterator))
++iterator; ++iterator;
} }
@ -329,7 +328,7 @@ const String & DatabaseLazyIterator::name() const
const StoragePtr & DatabaseLazyIterator::table() const const StoragePtr & DatabaseLazyIterator::table() const
{ {
if (!current_storage) if (!current_storage)
current_storage = database.tryGetTable(context, *iterator); current_storage = database.tryGetTable(database.global_context, *iterator);
return current_storage; return current_storage;
} }

View File

@ -61,7 +61,7 @@ public:
bool empty(const Context & context) const override; bool empty(const Context & context) const override;
DatabaseTablesIteratorPtr getTablesIterator(const Context & context, const FilterByNameFunction & filter_by_table_name) override; DatabaseTablesIteratorPtr getTablesIterator(const FilterByNameFunction & filter_by_table_name) override;
void attachTable(const String & table_name, const StoragePtr & table, const String & relative_table_path) override; void attachTable(const String & table_name, const StoragePtr & table, const String & relative_table_path) override;
@ -104,7 +104,7 @@ private:
mutable TablesCache tables_cache; mutable TablesCache tables_cache;
mutable CacheExpirationQueue cache_expiration_queue; mutable CacheExpirationQueue cache_expiration_queue;
StoragePtr loadTable(const Context & context, const String & table_name) const; StoragePtr loadTable(const String & table_name) const;
void clearExpiredTables() const; void clearExpiredTables() const;
@ -117,7 +117,6 @@ class DatabaseLazyIterator final : public IDatabaseTablesIterator
public: public:
DatabaseLazyIterator( DatabaseLazyIterator(
DatabaseLazy & database_, DatabaseLazy & database_,
const Context & context_,
Strings && table_names_); Strings && table_names_);
void next() override; void next() override;
@ -128,7 +127,6 @@ public:
private: private:
const DatabaseLazy & database; const DatabaseLazy & database;
const Strings table_names; const Strings table_names;
const Context context;
Strings::const_iterator iterator; Strings::const_iterator iterator;
mutable StoragePtr current_storage; mutable StoragePtr current_storage;
}; };

View File

@ -62,7 +62,7 @@ DatabaseMySQL::DatabaseMySQL(
const Context & global_context_, const String & database_name_, const String & metadata_path_, const Context & global_context_, const String & database_name_, const String & metadata_path_,
const ASTStorage * database_engine_define_, const String & database_name_in_mysql_, mysqlxx::Pool && pool) const ASTStorage * database_engine_define_, const String & database_name_in_mysql_, mysqlxx::Pool && pool)
: IDatabase(database_name_) : IDatabase(database_name_)
, global_context(global_context_) , global_context(global_context_.getGlobalContext())
, metadata_path(metadata_path_) , metadata_path(metadata_path_)
, database_engine_define(database_engine_define_->clone()) , database_engine_define(database_engine_define_->clone())
, database_name_in_mysql(database_name_in_mysql_) , database_name_in_mysql(database_name_in_mysql_)
@ -86,7 +86,7 @@ bool DatabaseMySQL::empty(const Context &) const
return true; return true;
} }
DatabaseTablesIteratorPtr DatabaseMySQL::getTablesIterator(const Context &, const FilterByNameFunction & filter_by_table_name) DatabaseTablesIteratorPtr DatabaseMySQL::getTablesIterator(const FilterByNameFunction & filter_by_table_name)
{ {
Tables tables; Tables tables;
std::lock_guard<std::mutex> lock(mutex); std::lock_guard<std::mutex> lock(mutex);

View File

@ -30,7 +30,7 @@ public:
bool empty(const Context & context) const override; bool empty(const Context & context) const override;
DatabaseTablesIteratorPtr getTablesIterator(const Context & context, const FilterByNameFunction & filter_by_table_name) override; DatabaseTablesIteratorPtr getTablesIterator(const FilterByNameFunction & filter_by_table_name) override;
ASTPtr getCreateDatabaseQuery(const Context & /*context*/) const override; ASTPtr getCreateDatabaseQuery(const Context & /*context*/) const override;
@ -60,7 +60,7 @@ protected:
ASTPtr getCreateTableQueryImpl(const Context & context, const String & name, bool throw_on_error) const override; ASTPtr getCreateTableQueryImpl(const Context & context, const String & name, bool throw_on_error) const override;
private: private:
Context global_context; const Context & global_context;
String metadata_path; String metadata_path;
ASTPtr database_engine_define; ASTPtr database_engine_define;
String database_name_in_mysql; String database_name_in_mysql;

View File

@ -123,10 +123,11 @@ String getObjectDefinitionFromCreateQuery(const ASTPtr & query)
return statement_stream.str(); return statement_stream.str();
} }
DatabaseOnDisk::DatabaseOnDisk(const String & name, const String & metadata_path_, const String & logger, const Context &) DatabaseOnDisk::DatabaseOnDisk(const String & name, const String & metadata_path_, const String & logger, const Context & context)
: DatabaseWithOwnTablesBase(name, logger) : DatabaseWithOwnTablesBase(name, logger)
, metadata_path(metadata_path_) , metadata_path(metadata_path_)
, data_path("data/" + escapeForFileName(database_name) + "/") , data_path("data/" + escapeForFileName(database_name) + "/")
, global_context(context.getGlobalContext())
{ {
} }

View File

@ -91,6 +91,7 @@ protected:
const String metadata_path; const String metadata_path;
/*const*/ String data_path; /*const*/ String data_path;
const Context & global_context;
}; };
} }

View File

@ -173,17 +173,17 @@ StoragePtr DatabaseWithDictionaries::tryGetTable(const Context & context, const
if (isDictionaryExist(context, table_name)) if (isDictionaryExist(context, table_name))
/// We don't need lock database here, because database doesn't store dictionary itself /// We don't need lock database here, because database doesn't store dictionary itself
/// just metadata /// just metadata
return getDictionaryStorage(context, table_name); return getDictionaryStorage(table_name);
return {}; return {};
} }
DatabaseTablesIteratorPtr DatabaseWithDictionaries::getTablesWithDictionaryTablesIterator( DatabaseTablesIteratorPtr DatabaseWithDictionaries::getTablesWithDictionaryTablesIterator(
const Context & context, const FilterByNameFunction & filter_by_dictionary_name) const FilterByNameFunction & filter_by_dictionary_name)
{ {
/// NOTE: it's not atomic /// NOTE: it's not atomic
auto tables_it = getTablesIterator(context, filter_by_dictionary_name); auto tables_it = getTablesIterator(filter_by_dictionary_name);
auto dictionaries_it = getDictionariesIterator(context, filter_by_dictionary_name); auto dictionaries_it = getDictionariesIterator(filter_by_dictionary_name);
Tables result; Tables result;
while (tables_it && tables_it->isValid()) while (tables_it && tables_it->isValid())
@ -195,7 +195,7 @@ DatabaseTablesIteratorPtr DatabaseWithDictionaries::getTablesWithDictionaryTable
while (dictionaries_it && dictionaries_it->isValid()) while (dictionaries_it && dictionaries_it->isValid())
{ {
auto table_name = dictionaries_it->name(); auto table_name = dictionaries_it->name();
auto table_ptr = getDictionaryStorage(context, table_name); auto table_ptr = getDictionaryStorage(table_name);
if (table_ptr) if (table_ptr)
result.emplace(table_name, table_ptr); result.emplace(table_name, table_ptr);
dictionaries_it->next(); dictionaries_it->next();
@ -204,7 +204,7 @@ DatabaseTablesIteratorPtr DatabaseWithDictionaries::getTablesWithDictionaryTable
return std::make_unique<DatabaseTablesSnapshotIterator>(result); return std::make_unique<DatabaseTablesSnapshotIterator>(result);
} }
DatabaseDictionariesIteratorPtr DatabaseWithDictionaries::getDictionariesIterator(const Context & /*context*/, const FilterByNameFunction & filter_by_dictionary_name) DatabaseDictionariesIteratorPtr DatabaseWithDictionaries::getDictionariesIterator(const FilterByNameFunction & filter_by_dictionary_name)
{ {
std::lock_guard lock(mutex); std::lock_guard lock(mutex);
if (!filter_by_dictionary_name) if (!filter_by_dictionary_name)
@ -223,16 +223,16 @@ bool DatabaseWithDictionaries::isDictionaryExist(const Context & /*context*/, co
return dictionaries.find(dictionary_name) != dictionaries.end(); return dictionaries.find(dictionary_name) != dictionaries.end();
} }
StoragePtr DatabaseWithDictionaries::getDictionaryStorage(const Context & context, const String & table_name) const StoragePtr DatabaseWithDictionaries::getDictionaryStorage(const String & table_name) const
{ {
auto dict_name = database_name + "." + table_name; auto dict_name = database_name + "." + table_name;
const auto & external_loader = context.getExternalDictionariesLoader(); const auto & external_loader = global_context.getExternalDictionariesLoader();
auto dict_ptr = external_loader.tryGetDictionary(dict_name); auto dict_ptr = external_loader.tryGetDictionary(dict_name);
if (dict_ptr) if (dict_ptr)
{ {
const DictionaryStructure & dictionary_structure = dict_ptr->getStructure(); const DictionaryStructure & dictionary_structure = dict_ptr->getStructure();
auto columns = StorageDictionary::getNamesAndTypes(dictionary_structure); auto columns = StorageDictionary::getNamesAndTypes(dictionary_structure);
return StorageDictionary::create(StorageID(database_name, table_name), ColumnsDescription{columns}, context, true, dict_name); return StorageDictionary::create(StorageID(database_name, table_name), ColumnsDescription{columns}, global_context, true, dict_name);
} }
return nullptr; return nullptr;
} }

View File

@ -20,9 +20,9 @@ public:
StoragePtr tryGetTable(const Context & context, const String & table_name) const override; StoragePtr tryGetTable(const Context & context, const String & table_name) const override;
DatabaseTablesIteratorPtr getTablesWithDictionaryTablesIterator(const Context & context, const FilterByNameFunction & filter_by_dictionary_name) override; DatabaseTablesIteratorPtr getTablesWithDictionaryTablesIterator(const FilterByNameFunction & filter_by_dictionary_name) override;
DatabaseDictionariesIteratorPtr getDictionariesIterator(const Context & context, const FilterByNameFunction & filter_by_dictionary_name) override; DatabaseDictionariesIteratorPtr getDictionariesIterator(const FilterByNameFunction & filter_by_dictionary_name) override;
bool isDictionaryExist(const Context & context, const String & dictionary_name) const override; bool isDictionaryExist(const Context & context, const String & dictionary_name) const override;
@ -37,7 +37,7 @@ protected:
void attachToExternalDictionariesLoader(Context & context); void attachToExternalDictionariesLoader(Context & context);
void detachFromExternalDictionariesLoader(); void detachFromExternalDictionariesLoader();
StoragePtr getDictionaryStorage(const Context & context, const String & table_name) const; StoragePtr getDictionaryStorage(const String & table_name) const;
ASTPtr getCreateDictionaryQueryImpl(const Context & context, ASTPtr getCreateDictionaryQueryImpl(const Context & context,
const String & dictionary_name, const String & dictionary_name,

View File

@ -42,7 +42,7 @@ StoragePtr DatabaseWithOwnTablesBase::tryGetTable(
return {}; return {};
} }
DatabaseTablesIteratorPtr DatabaseWithOwnTablesBase::getTablesIterator(const Context & /*context*/, const FilterByNameFunction & filter_by_table_name) DatabaseTablesIteratorPtr DatabaseWithOwnTablesBase::getTablesIterator(const FilterByNameFunction & filter_by_table_name)
{ {
std::lock_guard lock(mutex); std::lock_guard lock(mutex);
if (!filter_by_table_name) if (!filter_by_table_name)

View File

@ -33,7 +33,7 @@ public:
StoragePtr detachTable(const String & table_name) override; StoragePtr detachTable(const String & table_name) override;
DatabaseTablesIteratorPtr getTablesIterator(const Context & context, const FilterByNameFunction & filter_by_table_name) override; DatabaseTablesIteratorPtr getTablesIterator(const FilterByNameFunction & filter_by_table_name) override;
void shutdown() override; void shutdown() override;

View File

@ -42,15 +42,27 @@ public:
virtual const StoragePtr & table() const = 0; virtual const StoragePtr & table() const = 0;
virtual ~IDatabaseTablesIterator() = default; virtual ~IDatabaseTablesIterator() = default;
virtual UUID uuid() const { return UUIDHelpers::Nil; }
}; };
/// Copies list of tables and iterates through such snapshot. /// Copies list of tables and iterates through such snapshot.
class DatabaseTablesSnapshotIterator final : public IDatabaseTablesIterator class DatabaseTablesSnapshotIterator : public IDatabaseTablesIterator
{ {
private: private:
Tables tables; Tables tables;
Tables::iterator it; Tables::iterator it;
protected:
DatabaseTablesSnapshotIterator(DatabaseTablesSnapshotIterator && other)
{
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);
}
public: public:
DatabaseTablesSnapshotIterator(Tables & tables_) : tables(tables_), it(tables.begin()) {} DatabaseTablesSnapshotIterator(Tables & tables_) : tables(tables_), it(tables.begin()) {}
@ -133,18 +145,18 @@ public:
/// Get an iterator that allows you to pass through all the tables. /// 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. /// 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.
virtual DatabaseTablesIteratorPtr getTablesIterator(const Context & context, const FilterByNameFunction & filter_by_table_name = {}) = 0; virtual DatabaseTablesIteratorPtr getTablesIterator(const FilterByNameFunction & filter_by_table_name = {}) = 0;
/// Get an iterator to pass through all the dictionaries. /// Get an iterator to pass through all the dictionaries.
virtual DatabaseDictionariesIteratorPtr getDictionariesIterator(const Context & /*context*/, [[maybe_unused]] const FilterByNameFunction & filter_by_dictionary_name = {}) virtual DatabaseDictionariesIteratorPtr getDictionariesIterator([[maybe_unused]] const FilterByNameFunction & filter_by_dictionary_name = {})
{ {
return std::make_unique<DatabaseDictionariesSnapshotIterator>(); return std::make_unique<DatabaseDictionariesSnapshotIterator>();
} }
/// Get an iterator to pass through all the tables and dictionary tables. /// Get an iterator to pass through all the tables and dictionary tables.
virtual DatabaseTablesIteratorPtr getTablesWithDictionaryTablesIterator(const Context & context, const FilterByNameFunction & filter_by_name = {}) virtual DatabaseTablesIteratorPtr getTablesWithDictionaryTablesIterator(const FilterByNameFunction & filter_by_name = {})
{ {
return getTablesIterator(context, filter_by_name); return getTablesIterator(filter_by_name);
} }
/// Is the database empty. /// Is the database empty.

View File

@ -20,17 +20,17 @@ namespace ActionLocks
template <typename F> template <typename F>
inline void forEachTable(Context & context, F && f) inline void forEachTable(F && f)
{ {
for (auto & elem : DatabaseCatalog::instance().getDatabases()) for (auto & elem : DatabaseCatalog::instance().getDatabases())
for (auto iterator = elem.second->getTablesIterator(context); iterator->isValid(); iterator->next()) for (auto iterator = elem.second->getTablesIterator(); iterator->isValid(); iterator->next())
f(iterator->table()); f(iterator->table());
} }
void ActionLocksManager::add(StorageActionBlockType action_type) void ActionLocksManager::add(StorageActionBlockType action_type)
{ {
forEachTable(global_context, [&](const StoragePtr & table) { add(table, action_type); }); forEachTable([&](const StoragePtr & table) { add(table, action_type); });
} }
void ActionLocksManager::add(const StorageID & table_id, StorageActionBlockType action_type) void ActionLocksManager::add(const StorageID & table_id, StorageActionBlockType action_type)

View File

@ -19,8 +19,6 @@ class Context;
class ActionLocksManager class ActionLocksManager
{ {
public: public:
explicit ActionLocksManager(Context & global_context_) : global_context(global_context_) {}
/// Adds new locks for each table /// Adds new locks for each table
void add(StorageActionBlockType action_type); void add(StorageActionBlockType action_type);
/// Add new lock for a table if it has not been already added /// Add new lock for a table if it has not been already added
@ -37,8 +35,6 @@ public:
void cleanExpired(); void cleanExpired();
private: private:
Context & global_context;
using StorageRawPtr = const IStorage *; using StorageRawPtr = const IStorage *;
using Locks = std::unordered_map<size_t, ActionLock>; using Locks = std::unordered_map<size_t, ActionLock>;
using StorageLocks = std::unordered_map<StorageRawPtr, Locks>; using StorageLocks = std::unordered_map<StorageRawPtr, Locks>;

View File

@ -155,7 +155,7 @@ void AsynchronousMetrics::update()
/// Lazy database can not contain MergeTree tables /// Lazy database can not contain MergeTree tables
if (db.second->getEngineName() == "Lazy") if (db.second->getEngineName() == "Lazy")
continue; continue;
for (auto iterator = db.second->getTablesIterator(context); iterator->isValid(); iterator->next()) for (auto iterator = db.second->getTablesIterator(); iterator->isValid(); iterator->next())
{ {
++total_number_of_tables; ++total_number_of_tables;
auto & table = iterator->table(); auto & table = iterator->table();

View File

@ -1957,7 +1957,7 @@ std::shared_ptr<ActionLocksManager> Context::getActionLocksManager()
auto lock = getLock(); auto lock = getLock();
if (!shared->action_locks_manager) if (!shared->action_locks_manager)
shared->action_locks_manager = std::make_shared<ActionLocksManager>(getGlobalContext()); shared->action_locks_manager = std::make_shared<ActionLocksManager>();
return shared->action_locks_manager; return shared->action_locks_manager;
} }

View File

@ -52,7 +52,7 @@ std::set<std::string> ExternalLoaderDatabaseConfigRepository::getAllLoadablesDef
{ {
std::set<std::string> result; std::set<std::string> result;
const auto & dbname = database.getDatabaseName(); const auto & dbname = database.getDatabaseName();
auto itr = database.getDictionariesIterator(context); auto itr = database.getDictionariesIterator();
while (itr && itr->isValid()) while (itr && itr->isValid())
{ {
result.insert(dbname + "." + itr->name()); result.insert(dbname + "." + itr->name());

View File

@ -225,13 +225,13 @@ BlockIO InterpreterDropQuery::executeToDatabase(const String & database_name, AS
ASTDropQuery query; ASTDropQuery query;
query.kind = kind; query.kind = kind;
query.database = database_name; query.database = database_name;
for (auto iterator = database->getTablesIterator(context); iterator->isValid(); iterator->next()) for (auto iterator = database->getTablesIterator(); iterator->isValid(); iterator->next())
{ {
query.table = iterator->name(); query.table = iterator->name();
executeToTable({query.database, query.table}, query); executeToTable({query.database, query.table}, query);
} }
for (auto iterator = database->getDictionariesIterator(context); iterator->isValid(); iterator->next()) for (auto iterator = database->getDictionariesIterator(); iterator->isValid(); iterator->next())
{ {
String current_dictionary = iterator->name(); String current_dictionary = iterator->name();
executeToDictionary(database_name, current_dictionary, kind, false, false, false); executeToDictionary(database_name, current_dictionary, kind, false, false, false);

View File

@ -140,7 +140,7 @@ void InterpreterSystemQuery::startStopAction(StorageActionBlockType action_type,
auto access = context.getAccess(); auto access = context.getAccess();
for (auto & elem : DatabaseCatalog::instance().getDatabases()) for (auto & elem : DatabaseCatalog::instance().getDatabases())
{ {
for (auto iterator = elem.second->getTablesIterator(context); iterator->isValid(); iterator->next()) for (auto iterator = elem.second->getTablesIterator(); iterator->isValid(); iterator->next())
{ {
if (!access->isGranted(log, getRequiredAccessType(action_type), elem.first, iterator->name())) if (!access->isGranted(log, getRequiredAccessType(action_type), elem.first, iterator->name()))
continue; continue;
@ -362,7 +362,7 @@ void InterpreterSystemQuery::restartReplicas(Context & system_context)
for (auto & elem : DatabaseCatalog::instance().getDatabases()) for (auto & elem : DatabaseCatalog::instance().getDatabases())
{ {
DatabasePtr & database = elem.second; DatabasePtr & database = elem.second;
for (auto iterator = database->getTablesIterator(system_context); iterator->isValid(); iterator->next()) for (auto iterator = database->getTablesIterator(); iterator->isValid(); iterator->next())
{ {
if (dynamic_cast<const StorageReplicatedMergeTree *>(iterator->table().get())) if (dynamic_cast<const StorageReplicatedMergeTree *>(iterator->table().get()))
replica_names.emplace_back(iterator->table()->getStorageID()); replica_names.emplace_back(iterator->table()->getStorageID());

View File

@ -415,7 +415,7 @@ DatabaseTablesIteratorPtr StorageMerge::getDatabaseIterator() const
checkStackSize(); checkStackSize();
auto database = DatabaseCatalog::instance().getDatabase(source_database); auto database = DatabaseCatalog::instance().getDatabase(source_database);
auto table_name_match = [this](const String & table_name_) { return table_name_regexp.match(table_name_); }; auto table_name_match = [this](const String & table_name_) { return table_name_regexp.match(table_name_); };
return database->getTablesIterator(global_context, table_name_match); return database->getTablesIterator(table_name_match);
} }

View File

@ -302,7 +302,7 @@ Pipes StorageSystemColumns::read(
const DatabasePtr database = databases.at(database_name); const DatabasePtr database = databases.at(database_name);
offsets[i] = i ? offsets[i - 1] : 0; offsets[i] = i ? offsets[i - 1] : 0;
for (auto iterator = database->getTablesWithDictionaryTablesIterator(context); iterator->isValid(); iterator->next()) for (auto iterator = database->getTablesWithDictionaryTablesIterator(); iterator->isValid(); iterator->next())
{ {
const String & table_name = iterator->name(); const String & table_name = iterator->name();
storages.emplace(std::piecewise_construct, storages.emplace(std::piecewise_construct,

View File

@ -25,7 +25,7 @@ NamesAndTypesList StorageSystemGraphite::getNamesAndTypes()
/* /*
* Looking for (Replicated)*GraphiteMergeTree and get all configuration parameters for them * Looking for (Replicated)*GraphiteMergeTree and get all configuration parameters for them
*/ */
static StorageSystemGraphite::Configs getConfigs(const Context & context) static StorageSystemGraphite::Configs getConfigs()
{ {
const Databases databases = DatabaseCatalog::instance().getDatabases(); const Databases databases = DatabaseCatalog::instance().getDatabases();
StorageSystemGraphite::Configs graphite_configs; StorageSystemGraphite::Configs graphite_configs;
@ -36,7 +36,7 @@ static StorageSystemGraphite::Configs getConfigs(const Context & context)
if (db.second->getEngineName() == "Lazy") if (db.second->getEngineName() == "Lazy")
continue; continue;
for (auto iterator = db.second->getTablesIterator(context); iterator->isValid(); iterator->next()) for (auto iterator = db.second->getTablesIterator(); iterator->isValid(); iterator->next())
{ {
auto & table = iterator->table(); auto & table = iterator->table();
@ -71,9 +71,9 @@ static StorageSystemGraphite::Configs getConfigs(const Context & context)
return graphite_configs; return graphite_configs;
} }
void StorageSystemGraphite::fillData(MutableColumns & res_columns, const Context & context, const SelectQueryInfo &) const void StorageSystemGraphite::fillData(MutableColumns & res_columns, const Context &, const SelectQueryInfo &) const
{ {
Configs graphite_configs = getConfigs(context); Configs graphite_configs = getConfigs();
for (const auto & config : graphite_configs) for (const auto & config : graphite_configs)
{ {

View File

@ -50,7 +50,7 @@ void StorageSystemMutations::fillData(MutableColumns & res_columns, const Contex
const bool check_access_for_tables = check_access_for_databases && !access->isGranted(AccessType::SHOW_TABLES, db.first); const bool check_access_for_tables = check_access_for_databases && !access->isGranted(AccessType::SHOW_TABLES, db.first);
for (auto iterator = db.second->getTablesIterator(context); iterator->isValid(); iterator->next()) for (auto iterator = db.second->getTablesIterator(); iterator->isValid(); iterator->next())
{ {
if (!dynamic_cast<const MergeTreeData *>(iterator->table().get())) if (!dynamic_cast<const MergeTreeData *>(iterator->table().get()))
continue; continue;

View File

@ -110,7 +110,7 @@ StoragesInfoStream::StoragesInfoStream(const SelectQueryInfo & query_info, const
const DatabasePtr database = databases.at(database_name); const DatabasePtr database = databases.at(database_name);
offsets[i] = i ? offsets[i - 1] : 0; offsets[i] = i ? offsets[i - 1] : 0;
for (auto iterator = database->getTablesIterator(context); iterator->isValid(); iterator->next()) for (auto iterator = database->getTablesIterator(); iterator->isValid(); iterator->next())
{ {
String table_name = iterator->name(); String table_name = iterator->name();
StoragePtr storage = iterator->table(); StoragePtr storage = iterator->table();

View File

@ -76,7 +76,7 @@ Pipes StorageSystemReplicas::read(
if (db.second->getEngineName() == "Lazy") if (db.second->getEngineName() == "Lazy")
continue; continue;
const bool check_access_for_tables = check_access_for_databases && !access->isGranted(AccessType::SHOW_TABLES, db.first); const bool check_access_for_tables = check_access_for_databases && !access->isGranted(AccessType::SHOW_TABLES, db.first);
for (auto iterator = db.second->getTablesIterator(context); iterator->isValid(); iterator->next()) for (auto iterator = db.second->getTablesIterator(); iterator->isValid(); iterator->next())
{ {
if (!dynamic_cast<const StorageReplicatedMergeTree *>(iterator->table().get())) if (!dynamic_cast<const StorageReplicatedMergeTree *>(iterator->table().get()))
continue; continue;

View File

@ -60,7 +60,7 @@ void StorageSystemReplicationQueue::fillData(MutableColumns & res_columns, const
const bool check_access_for_tables = check_access_for_databases && !access->isGranted(AccessType::SHOW_TABLES, db.first); const bool check_access_for_tables = check_access_for_databases && !access->isGranted(AccessType::SHOW_TABLES, db.first);
for (auto iterator = db.second->getTablesIterator(context); iterator->isValid(); iterator->next()) for (auto iterator = db.second->getTablesIterator(); iterator->isValid(); iterator->next())
{ {
if (!dynamic_cast<const StorageReplicatedMergeTree *>(iterator->table().get())) if (!dynamic_cast<const StorageReplicatedMergeTree *>(iterator->table().get()))
continue; continue;

View File

@ -18,6 +18,7 @@
#include <Disks/DiskSpaceMonitor.h> #include <Disks/DiskSpaceMonitor.h>
#include <Processors/Sources/SourceWithProgress.h> #include <Processors/Sources/SourceWithProgress.h>
#include <Processors/Pipe.h> #include <Processors/Pipe.h>
#include <DataTypes/DataTypeUUID.h>
namespace DB namespace DB
@ -36,6 +37,7 @@ StorageSystemTables::StorageSystemTables(const std::string & name_)
{ {
{"database", std::make_shared<DataTypeString>()}, {"database", std::make_shared<DataTypeString>()},
{"name", std::make_shared<DataTypeString>()}, {"name", std::make_shared<DataTypeString>()},
{"uuid", std::make_shared<DataTypeUUID>()},
{"engine", std::make_shared<DataTypeString>()}, {"engine", std::make_shared<DataTypeString>()},
{"is_temporary", std::make_shared<DataTypeUInt8>()}, {"is_temporary", std::make_shared<DataTypeUInt8>()},
{"data_paths", std::make_shared<DataTypeArray>(std::make_shared<DataTypeString>())}, {"data_paths", std::make_shared<DataTypeArray>(std::make_shared<DataTypeString>())},
@ -74,7 +76,7 @@ static bool needLockStructure(const DatabasePtr & database, const Block & header
if (database->getEngineName() != "Lazy") if (database->getEngineName() != "Lazy")
return true; return true;
static const std::set<std::string> columns_without_lock = { "database", "name", "metadata_modification_time" }; static const std::set<std::string> columns_without_lock = { "database", "name", "uuid", "metadata_modification_time" };
for (const auto & column : header.getColumnsWithTypeAndName()) for (const auto & column : header.getColumnsWithTypeAndName())
{ {
if (columns_without_lock.find(column.name) == columns_without_lock.end()) if (columns_without_lock.find(column.name) == columns_without_lock.end())
@ -152,6 +154,10 @@ protected:
if (columns_mask[src_index++]) if (columns_mask[src_index++])
res_columns[res_index++]->insert(table.first); res_columns[res_index++]->insert(table.first);
// uuid
if (columns_mask[src_index++])
res_columns[res_index++]->insert(table.second->getStorageID().uuid);
// engine // engine
if (columns_mask[src_index++]) if (columns_mask[src_index++])
res_columns[res_index++]->insert(table.second->getName()); res_columns[res_index++]->insert(table.second->getName());
@ -226,7 +232,7 @@ protected:
const bool check_access_for_tables = check_access_for_databases && !access->isGranted(AccessType::SHOW_TABLES, database_name); const bool check_access_for_tables = check_access_for_databases && !access->isGranted(AccessType::SHOW_TABLES, database_name);
if (!tables_it || !tables_it->isValid()) if (!tables_it || !tables_it->isValid())
tables_it = database->getTablesWithDictionaryTablesIterator(context); tables_it = database->getTablesWithDictionaryTablesIterator();
const bool need_lock_structure = needLockStructure(database, getPort().getHeader()); const bool need_lock_structure = needLockStructure(database, getPort().getHeader());
@ -265,6 +271,9 @@ protected:
if (columns_mask[src_index++]) if (columns_mask[src_index++])
res_columns[res_index++]->insert(table_name); res_columns[res_index++]->insert(table_name);
if (columns_mask[src_index++])
res_columns[res_index++]->insert(tables_it->uuid());
if (columns_mask[src_index++]) if (columns_mask[src_index++])
{ {
assert(table != nullptr); assert(table != nullptr);

View File

@ -23,7 +23,7 @@ namespace ErrorCodes
} }
static NamesAndTypesList chooseColumns(const String & source_database, const String & table_name_regexp_, const Context & context) static NamesAndTypesList chooseColumns(const String & source_database, const String & table_name_regexp_)
{ {
OptimizedRegularExpression table_name_regexp(table_name_regexp_); OptimizedRegularExpression table_name_regexp(table_name_regexp_);
auto table_name_match = [&](const String & table_name) { return table_name_regexp.match(table_name); }; auto table_name_match = [&](const String & table_name) { return table_name_regexp.match(table_name); };
@ -32,7 +32,7 @@ static NamesAndTypesList chooseColumns(const String & source_database, const Str
{ {
auto database = DatabaseCatalog::instance().getDatabase(source_database); auto database = DatabaseCatalog::instance().getDatabase(source_database);
auto iterator = database->getTablesIterator(context, table_name_match); auto iterator = database->getTablesIterator(table_name_match);
if (iterator->isValid()) if (iterator->isValid())
any_table = iterator->table(); any_table = iterator->table();
@ -72,7 +72,7 @@ StoragePtr TableFunctionMerge::executeImpl(const ASTPtr & ast_function, const Co
auto res = StorageMerge::create( auto res = StorageMerge::create(
StorageID(getDatabaseName(), table_name), StorageID(getDatabaseName(), table_name),
ColumnsDescription{chooseColumns(source_database, table_name_regexp, context)}, ColumnsDescription{chooseColumns(source_database, table_name_regexp)},
source_database, source_database,
table_name_regexp, table_name_regexp,
context); context);