| 1 | #include <Databases/DatabasesCommon.h> |
| 2 | #include <Interpreters/InterpreterCreateQuery.h> |
| 3 | #include <Parsers/ParserCreateQuery.h> |
| 4 | #include <Parsers/formatAST.h> |
| 5 | #include <Storages/StorageDictionary.h> |
| 6 | #include <Storages/StorageFactory.h> |
| 7 | #include <Common/typeid_cast.h> |
| 8 | #include <TableFunctions/TableFunctionFactory.h> |
| 9 | |
| 10 | |
| 11 | namespace DB |
| 12 | { |
| 13 | |
| 14 | namespace ErrorCodes |
| 15 | { |
| 16 | extern const int EMPTY_LIST_OF_COLUMNS_PASSED; |
| 17 | extern const int TABLE_ALREADY_EXISTS; |
| 18 | extern const int UNKNOWN_TABLE; |
| 19 | extern const int LOGICAL_ERROR; |
| 20 | extern const int DICTIONARY_ALREADY_EXISTS; |
| 21 | } |
| 22 | |
| 23 | DatabaseWithOwnTablesBase::DatabaseWithOwnTablesBase(const String & name_, const String & logger) |
| 24 | : IDatabase(name_), log(&Logger::get(logger)) |
| 25 | { |
| 26 | } |
| 27 | |
| 28 | bool DatabaseWithOwnTablesBase::isTableExist( |
| 29 | const Context & /*context*/, |
| 30 | const String & table_name) const |
| 31 | { |
| 32 | std::lock_guard lock(mutex); |
| 33 | return tables.find(table_name) != tables.end() || dictionaries.find(table_name) != dictionaries.end(); |
| 34 | } |
| 35 | |
| 36 | StoragePtr DatabaseWithOwnTablesBase::tryGetTable( |
| 37 | const Context & /*context*/, |
| 38 | const String & table_name) const |
| 39 | { |
| 40 | std::lock_guard lock(mutex); |
| 41 | auto it = tables.find(table_name); |
| 42 | if (it != tables.end()) |
| 43 | return it->second; |
| 44 | return {}; |
| 45 | } |
| 46 | |
| 47 | DatabaseTablesIteratorPtr DatabaseWithOwnTablesBase::getTablesIterator(const Context & /*context*/, const FilterByNameFunction & filter_by_table_name) |
| 48 | { |
| 49 | std::lock_guard lock(mutex); |
| 50 | if (!filter_by_table_name) |
| 51 | return std::make_unique<DatabaseTablesSnapshotIterator>(tables); |
| 52 | |
| 53 | Tables filtered_tables; |
| 54 | for (const auto & [table_name, storage] : tables) |
| 55 | if (filter_by_table_name(table_name)) |
| 56 | filtered_tables.emplace(table_name, storage); |
| 57 | |
| 58 | return std::make_unique<DatabaseTablesSnapshotIterator>(std::move(filtered_tables)); |
| 59 | } |
| 60 | |
| 61 | bool DatabaseWithOwnTablesBase::empty(const Context & /*context*/) const |
| 62 | { |
| 63 | std::lock_guard lock(mutex); |
| 64 | return tables.empty() && dictionaries.empty(); |
| 65 | } |
| 66 | |
| 67 | StoragePtr DatabaseWithOwnTablesBase::detachTable(const String & table_name) |
| 68 | { |
| 69 | StoragePtr res; |
| 70 | { |
| 71 | std::lock_guard lock(mutex); |
| 72 | if (dictionaries.count(table_name)) |
| 73 | throw Exception("Cannot detach dictionary " + database_name + "." + table_name + " as table, use DETACH DICTIONARY query." , ErrorCodes::UNKNOWN_TABLE); |
| 74 | |
| 75 | auto it = tables.find(table_name); |
| 76 | if (it == tables.end()) |
| 77 | throw Exception("Table " + backQuote(database_name) + "." + backQuote(table_name) + " doesn't exist." , ErrorCodes::UNKNOWN_TABLE); |
| 78 | res = it->second; |
| 79 | tables.erase(it); |
| 80 | } |
| 81 | |
| 82 | return res; |
| 83 | } |
| 84 | |
| 85 | void DatabaseWithOwnTablesBase::attachTable(const String & table_name, const StoragePtr & table) |
| 86 | { |
| 87 | std::lock_guard lock(mutex); |
| 88 | if (!tables.emplace(table_name, table).second) |
| 89 | throw Exception("Table " + database_name + "." + table_name + " already exists." , ErrorCodes::TABLE_ALREADY_EXISTS); |
| 90 | } |
| 91 | |
| 92 | void DatabaseWithOwnTablesBase::shutdown() |
| 93 | { |
| 94 | /// You can not hold a lock during shutdown. |
| 95 | /// Because inside `shutdown` function tables can work with database, and mutex is not recursive. |
| 96 | |
| 97 | Tables tables_snapshot; |
| 98 | { |
| 99 | std::lock_guard lock(mutex); |
| 100 | tables_snapshot = tables; |
| 101 | } |
| 102 | |
| 103 | for (const auto & kv : tables_snapshot) |
| 104 | { |
| 105 | kv.second->shutdown(); |
| 106 | } |
| 107 | |
| 108 | std::lock_guard lock(mutex); |
| 109 | tables.clear(); |
| 110 | dictionaries.clear(); |
| 111 | } |
| 112 | |
| 113 | DatabaseWithOwnTablesBase::~DatabaseWithOwnTablesBase() |
| 114 | { |
| 115 | try |
| 116 | { |
| 117 | DatabaseWithOwnTablesBase::shutdown(); |
| 118 | } |
| 119 | catch (...) |
| 120 | { |
| 121 | tryLogCurrentException(__PRETTY_FUNCTION__); |
| 122 | } |
| 123 | } |
| 124 | |
| 125 | } |
| 126 | |