mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-28 02:21:59 +00:00
Avoid superfluous dictionaries load (system.tables, SHOW CREATE TABLE)
This patch avoids loading dictionaries for: - SELECT * FROM system.tables (used by clickhouse-client for completion) - SHOW CREATE TABLE some_dict But the dictionary will still be loaded on: - SHOW CREATE TABLE some_dict (from the database with Dictionary engine)
This commit is contained in:
parent
e0c972448e
commit
55a143d1a5
@ -64,7 +64,7 @@ StoragePtr DatabaseDictionary::tryGetTable(
|
||||
const Context & context,
|
||||
const String & table_name) const
|
||||
{
|
||||
auto dict_ptr = context.getExternalDictionariesLoader().tryGetDictionary(table_name);
|
||||
auto dict_ptr = context.getExternalDictionariesLoader().tryGetDictionary(table_name, true /*load*/);
|
||||
if (dict_ptr)
|
||||
{
|
||||
const DictionaryStructure & dictionary_structure = dict_ptr->getStructure();
|
||||
@ -94,7 +94,7 @@ ASTPtr DatabaseDictionary::getCreateTableQueryImpl(const Context & context,
|
||||
|
||||
const auto & dictionaries = context.getExternalDictionariesLoader();
|
||||
auto dictionary = throw_on_error ? dictionaries.getDictionary(table_name)
|
||||
: dictionaries.tryGetDictionary(table_name);
|
||||
: dictionaries.tryGetDictionary(table_name, true /*load*/);
|
||||
if (!dictionary)
|
||||
return {};
|
||||
|
||||
|
@ -26,6 +26,8 @@ namespace ErrorCodes
|
||||
extern const int TABLE_ALREADY_EXISTS;
|
||||
extern const int UNKNOWN_TABLE;
|
||||
extern const int DICTIONARY_ALREADY_EXISTS;
|
||||
extern const int FILE_DOESNT_EXIST;
|
||||
extern const int CANNOT_GET_CREATE_TABLE_QUERY;
|
||||
}
|
||||
|
||||
|
||||
@ -165,7 +167,7 @@ void DatabaseWithDictionaries::removeDictionary(const Context & context, const S
|
||||
}
|
||||
}
|
||||
|
||||
StoragePtr DatabaseWithDictionaries::tryGetTable(const Context & context, const String & table_name) const
|
||||
StoragePtr DatabaseWithDictionaries::tryGetTableImpl(const Context & context, const String & table_name, bool load) const
|
||||
{
|
||||
if (auto table_ptr = DatabaseWithOwnTablesBase::tryGetTable(context, table_name))
|
||||
return table_ptr;
|
||||
@ -173,10 +175,34 @@ StoragePtr DatabaseWithDictionaries::tryGetTable(const Context & context, const
|
||||
if (isDictionaryExist(context, table_name))
|
||||
/// We don't need lock database here, because database doesn't store dictionary itself
|
||||
/// just metadata
|
||||
return getDictionaryStorage(context, table_name);
|
||||
return getDictionaryStorage(context, table_name, load);
|
||||
|
||||
return {};
|
||||
}
|
||||
StoragePtr DatabaseWithDictionaries::tryGetTable(const Context & context, const String & table_name) const
|
||||
{
|
||||
return tryGetTableImpl(context, table_name, true /*load*/);
|
||||
}
|
||||
|
||||
ASTPtr DatabaseWithDictionaries::getCreateTableQueryImpl(const Context & context, const String & table_name, bool throw_on_error) const
|
||||
{
|
||||
ASTPtr ast;
|
||||
bool has_table = tryGetTableImpl(context, table_name, false /*load*/) != nullptr;
|
||||
auto table_metadata_path = getObjectMetadataPath(table_name);
|
||||
try
|
||||
{
|
||||
ast = getCreateQueryFromMetadata(context, table_metadata_path, throw_on_error);
|
||||
}
|
||||
catch (const Exception & e)
|
||||
{
|
||||
if (!has_table && e.code() == ErrorCodes::FILE_DOESNT_EXIST && throw_on_error)
|
||||
throw Exception{"Table " + backQuote(table_name) + " doesn't exist",
|
||||
ErrorCodes::CANNOT_GET_CREATE_TABLE_QUERY};
|
||||
else if (throw_on_error)
|
||||
throw;
|
||||
}
|
||||
return ast;
|
||||
}
|
||||
|
||||
DatabaseTablesIteratorPtr DatabaseWithDictionaries::getTablesWithDictionaryTablesIterator(
|
||||
const Context & context, const FilterByNameFunction & filter_by_dictionary_name)
|
||||
@ -195,7 +221,7 @@ DatabaseTablesIteratorPtr DatabaseWithDictionaries::getTablesWithDictionaryTable
|
||||
while (dictionaries_it && dictionaries_it->isValid())
|
||||
{
|
||||
auto table_name = dictionaries_it->name();
|
||||
auto table_ptr = getDictionaryStorage(context, table_name);
|
||||
auto table_ptr = getDictionaryStorage(context, table_name, false /*load*/);
|
||||
if (table_ptr)
|
||||
result.emplace(table_name, table_ptr);
|
||||
dictionaries_it->next();
|
||||
@ -223,11 +249,11 @@ bool DatabaseWithDictionaries::isDictionaryExist(const Context & /*context*/, co
|
||||
return dictionaries.find(dictionary_name) != dictionaries.end();
|
||||
}
|
||||
|
||||
StoragePtr DatabaseWithDictionaries::getDictionaryStorage(const Context & context, const String & table_name) const
|
||||
StoragePtr DatabaseWithDictionaries::getDictionaryStorage(const Context & context, const String & table_name, bool load) const
|
||||
{
|
||||
auto dict_name = database_name + "." + table_name;
|
||||
const auto & external_loader = context.getExternalDictionariesLoader();
|
||||
auto dict_ptr = external_loader.tryGetDictionary(dict_name);
|
||||
auto dict_ptr = external_loader.tryGetDictionary(dict_name, load);
|
||||
if (dict_ptr)
|
||||
{
|
||||
const DictionaryStructure & dictionary_structure = dict_ptr->getStructure();
|
||||
|
@ -20,6 +20,8 @@ public:
|
||||
|
||||
StoragePtr tryGetTable(const Context & context, const String & table_name) const override;
|
||||
|
||||
ASTPtr getCreateTableQueryImpl(const Context & context, const String & table_name, bool throw_on_error) const override;
|
||||
|
||||
DatabaseTablesIteratorPtr getTablesWithDictionaryTablesIterator(const Context & context, const FilterByNameFunction & filter_by_dictionary_name) override;
|
||||
|
||||
DatabaseDictionariesIteratorPtr getDictionariesIterator(const Context & context, const FilterByNameFunction & filter_by_dictionary_name) override;
|
||||
@ -37,7 +39,7 @@ protected:
|
||||
void attachToExternalDictionariesLoader(Context & context);
|
||||
void detachFromExternalDictionariesLoader();
|
||||
|
||||
StoragePtr getDictionaryStorage(const Context & context, const String & table_name) const;
|
||||
StoragePtr getDictionaryStorage(const Context & context, const String & table_name, bool load) const;
|
||||
|
||||
ASTPtr getCreateDictionaryQueryImpl(const Context & context,
|
||||
const String & dictionary_name,
|
||||
@ -45,6 +47,8 @@ protected:
|
||||
|
||||
private:
|
||||
ext::scope_guard database_as_config_repo_for_external_loader;
|
||||
|
||||
StoragePtr tryGetTableImpl(const Context & context, const String & table_name, bool load) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -23,9 +23,12 @@ public:
|
||||
return std::static_pointer_cast<const IDictionaryBase>(load(name));
|
||||
}
|
||||
|
||||
DictPtr tryGetDictionary(const std::string & name) const
|
||||
DictPtr tryGetDictionary(const std::string & name, bool load) const
|
||||
{
|
||||
if (load)
|
||||
return std::static_pointer_cast<const IDictionaryBase>(tryLoad(name));
|
||||
else
|
||||
return std::static_pointer_cast<const IDictionaryBase>(getCurrentLoadResult(name).object);
|
||||
}
|
||||
|
||||
static void resetAll();
|
||||
|
@ -0,0 +1,19 @@
|
||||
NOT_LOADED
|
||||
NOT_LOADED
|
||||
CREATE DICTIONARY dict_db_01224.dict
|
||||
(
|
||||
`key` UInt64 DEFAULT 0,
|
||||
`val` UInt64 DEFAULT 10
|
||||
)
|
||||
PRIMARY KEY key
|
||||
SOURCE(CLICKHOUSE(HOST 'localhost' PORT 9000 USER 'default' TABLE 'dict_data' PASSWORD '' DB 'dict_db_01224'))
|
||||
LIFETIME(MIN 0 MAX 0)
|
||||
LAYOUT(FLAT())
|
||||
NOT_LOADED
|
||||
CREATE TABLE dict_db_01224_dictionary.`dict_db_01224.dict`
|
||||
(
|
||||
`key` UInt64,
|
||||
`val` UInt64
|
||||
)
|
||||
ENGINE = Dictionary(`dict_db_01224.dict`)
|
||||
LOADED
|
@ -0,0 +1,32 @@
|
||||
DROP DATABASE IF EXISTS dict_db_01224;
|
||||
DROP DATABASE IF EXISTS dict_db_01224_dictionary;
|
||||
CREATE DATABASE dict_db_01224;
|
||||
|
||||
CREATE TABLE dict_db_01224.dict_data (key UInt64, val UInt64) Engine=Memory();
|
||||
CREATE DICTIONARY dict_db_01224.dict
|
||||
(
|
||||
key UInt64 DEFAULT 0,
|
||||
val UInt64 DEFAULT 10
|
||||
)
|
||||
PRIMARY KEY key
|
||||
SOURCE(CLICKHOUSE(HOST 'localhost' PORT 9000 USER 'default' TABLE 'dict_data' PASSWORD '' DB 'dict_db_01224'))
|
||||
LIFETIME(MIN 0 MAX 0)
|
||||
LAYOUT(FLAT());
|
||||
|
||||
SELECT status FROM system.dictionaries WHERE database = 'dict_db_01224' AND name = 'dict';
|
||||
|
||||
SELECT * FROM system.tables FORMAT Null;
|
||||
SELECT status FROM system.dictionaries WHERE database = 'dict_db_01224' AND name = 'dict';
|
||||
|
||||
SHOW CREATE TABLE dict_db_01224.dict FORMAT TSVRaw;
|
||||
SELECT status FROM system.dictionaries WHERE database = 'dict_db_01224' AND name = 'dict';
|
||||
|
||||
CREATE DATABASE dict_db_01224_dictionary Engine=Dictionary;
|
||||
SHOW CREATE TABLE dict_db_01224_dictionary.`dict_db_01224.dict` FORMAT TSVRaw;
|
||||
SELECT status FROM system.dictionaries WHERE database = 'dict_db_01224' AND name = 'dict';
|
||||
|
||||
DROP DICTIONARY dict_db_01224.dict;
|
||||
SELECT status FROM system.dictionaries WHERE database = 'dict_db_01224' AND name = 'dict';
|
||||
|
||||
DROP DATABASE dict_db_01224;
|
||||
DROP DATABASE dict_db_01224_dictionary;
|
Loading…
Reference in New Issue
Block a user