mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-09-20 00:30:49 +00:00
Fix review notes
This commit is contained in:
parent
5e9340f682
commit
afada0ecb3
@ -22,69 +22,34 @@ namespace DB
|
||||
{
|
||||
namespace
|
||||
{
|
||||
/// Used for column indexes! Don't change the numbers!
|
||||
enum SystemDictionariesColumn
|
||||
{
|
||||
Database = 0,
|
||||
Name,
|
||||
Uuid,
|
||||
Status,
|
||||
Origin,
|
||||
Type,
|
||||
KeyNames,
|
||||
KeyTypes,
|
||||
AttributeNames,
|
||||
AttributeTypes,
|
||||
BytesAllocated,
|
||||
HierarchicalIndexBytesAllocated,
|
||||
QueryCount,
|
||||
HitRate,
|
||||
FoundRate,
|
||||
ElementCount,
|
||||
LoadFactor,
|
||||
Source,
|
||||
LifetimeMin,
|
||||
LifetimeMax,
|
||||
LoadingStartTime,
|
||||
LastSuccessfulUpdateTime,
|
||||
LoadingDuration,
|
||||
LastException,
|
||||
Comment,
|
||||
/// Virtual columns
|
||||
Key
|
||||
};
|
||||
|
||||
std::shared_ptr<const IDictionary> getDictionaryPtr(const ExternalLoader::LoadResult & load_result)
|
||||
{
|
||||
return std::dynamic_pointer_cast<const IDictionary>(load_result.object);
|
||||
}
|
||||
StorageID getDictionaryID(const ExternalLoader::LoadResult & load_result, const std::shared_ptr<const IDictionary> & dict_ptr)
|
||||
{
|
||||
StorageID dict_id = StorageID::createEmpty();
|
||||
|
||||
StorageID getDictionaryID(const ExternalLoader::LoadResult & load_result, const std::shared_ptr<const IDictionary> & dict_ptr)
|
||||
{
|
||||
StorageID dict_id = StorageID::createEmpty();
|
||||
if (dict_ptr)
|
||||
dict_id = dict_ptr->getDictionaryID();
|
||||
else if (load_result.config)
|
||||
dict_id = StorageID::fromDictionaryConfig(*load_result.config->config, load_result.config->key_in_config);
|
||||
else
|
||||
dict_id.table_name = load_result.name;
|
||||
|
||||
if (dict_ptr)
|
||||
dict_id = dict_ptr->getDictionaryID();
|
||||
else if (load_result.config)
|
||||
dict_id = StorageID::fromDictionaryConfig(*load_result.config->config, load_result.config->key_in_config);
|
||||
else
|
||||
dict_id.table_name = load_result.name;
|
||||
return dict_id;
|
||||
}
|
||||
|
||||
return dict_id;
|
||||
}
|
||||
std::optional<DictionaryStructure>
|
||||
getDictionaryStructure(const ExternalLoader::LoadResult & load_result, std::exception_ptr & last_exception)
|
||||
try
|
||||
{
|
||||
return ExternalDictionariesLoader::getDictionaryStructure(*load_result.config);
|
||||
}
|
||||
catch (const DB::Exception &)
|
||||
{
|
||||
if (!last_exception)
|
||||
last_exception = std::current_exception();
|
||||
return {};
|
||||
}
|
||||
|
||||
std::optional<DictionaryStructure>
|
||||
getDictionaryStructure(const ExternalLoader::LoadResult & load_result, std::exception_ptr & last_exception)
|
||||
try
|
||||
{
|
||||
return ExternalDictionariesLoader::getDictionaryStructure(*load_result.config);
|
||||
}
|
||||
catch (const DB::Exception &)
|
||||
{
|
||||
if (!last_exception)
|
||||
last_exception = std::current_exception();
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
NamesAndTypesList StorageSystemDictionaries::getNamesAndTypes()
|
||||
@ -135,83 +100,99 @@ void StorageSystemDictionaries::fillData(MutableColumns & res_columns, ContextPt
|
||||
if (!check_access_for_dictionaries)
|
||||
return;
|
||||
|
||||
for (size_t index = 0; const auto & load_result : external_dictionaries.getLoadResults())
|
||||
for (const auto & load_result : external_dictionaries.getLoadResults())
|
||||
{
|
||||
const auto dict_ptr = getDictionaryPtr(load_result);
|
||||
StorageID dict_id = getDictionaryID(load_result, dict_ptr);
|
||||
const auto dict_ptr = std::dynamic_pointer_cast<const IDictionary>(load_result.object);
|
||||
|
||||
auto last_exception = load_result.exception;
|
||||
std::exception_ptr last_exception = load_result.exception;
|
||||
auto dict_structure = getDictionaryStructure(load_result, last_exception);
|
||||
|
||||
StorageID dict_id = getDictionaryID(load_result, dict_ptr);
|
||||
|
||||
String db_or_tag = dict_id.database_name.empty() ? IDictionary::NO_DATABASE_TAG : dict_id.database_name;
|
||||
if (!access->isGranted(AccessType::SHOW_DICTIONARIES, db_or_tag, dict_id.table_name))
|
||||
continue;
|
||||
|
||||
res_columns[SystemDictionariesColumn::Database]->insert(dict_id.database_name);
|
||||
res_columns[SystemDictionariesColumn::Name]->insert(dict_id.table_name);
|
||||
res_columns[SystemDictionariesColumn::Uuid]->insert(dict_id.uuid);
|
||||
res_columns[SystemDictionariesColumn::Status]->insert(static_cast<Int8>(load_result.status));
|
||||
res_columns[SystemDictionariesColumn::Origin]->insert(load_result.config ? load_result.config->path : "");
|
||||
size_t i = 0;
|
||||
res_columns[i++]->insert(dict_id.database_name);
|
||||
res_columns[i++]->insert(dict_id.table_name);
|
||||
res_columns[i++]->insert(dict_id.uuid);
|
||||
res_columns[i++]->insert(static_cast<Int8>(load_result.status));
|
||||
res_columns[i++]->insert(load_result.config ? load_result.config->path : "");
|
||||
|
||||
if (dict_ptr)
|
||||
{
|
||||
res_columns[SystemDictionariesColumn::Type]->insert(dict_ptr->getTypeName());
|
||||
res_columns[SystemDictionariesColumn::BytesAllocated]->insert(dict_ptr->getBytesAllocated());
|
||||
res_columns[SystemDictionariesColumn::HierarchicalIndexBytesAllocated]->insert(dict_ptr->getHierarchicalIndexBytesAllocated());
|
||||
res_columns[SystemDictionariesColumn::QueryCount]->insert(dict_ptr->getQueryCount());
|
||||
res_columns[SystemDictionariesColumn::HitRate]->insert(dict_ptr->getHitRate());
|
||||
res_columns[SystemDictionariesColumn::FoundRate]->insert(dict_ptr->getFoundRate());
|
||||
res_columns[SystemDictionariesColumn::ElementCount]->insert(dict_ptr->getElementCount());
|
||||
res_columns[SystemDictionariesColumn::LoadFactor]->insert(dict_ptr->getLoadFactor());
|
||||
res_columns[SystemDictionariesColumn::Source]->insert(dict_ptr->getSource()->toString());
|
||||
|
||||
const auto & lifetime = dict_ptr->getLifetime();
|
||||
res_columns[SystemDictionariesColumn::LifetimeMin]->insert(lifetime.min_sec);
|
||||
res_columns[SystemDictionariesColumn::LifetimeMax]->insert(lifetime.max_sec);
|
||||
|
||||
res_columns[SystemDictionariesColumn::Comment]->insert(dict_ptr->getDictionaryComment());
|
||||
|
||||
if (!last_exception)
|
||||
last_exception = dict_ptr->getLastException();
|
||||
}
|
||||
else if (load_result.config && load_result.config->config->has("dictionary.comment"))
|
||||
{
|
||||
res_columns[SystemDictionariesColumn::Comment]->insert(load_result.config->config->getString("dictionary.comment"));
|
||||
}
|
||||
res_columns[i++]->insert(dict_ptr->getTypeName());
|
||||
else
|
||||
res_columns[i++]->insertDefault();
|
||||
|
||||
if (dict_structure)
|
||||
{
|
||||
res_columns[SystemDictionariesColumn::KeyNames]->insert(
|
||||
collections::map<Array>(dict_structure->getKeysNames(), [](auto & name) { return name; }));
|
||||
res_columns[i++]->insert(collections::map<Array>(dict_structure->getKeysNames(), [](auto & name) { return name; }));
|
||||
|
||||
if (dict_structure->id)
|
||||
res_columns[SystemDictionariesColumn::KeyTypes]->insert(Array({"UInt64"}));
|
||||
res_columns[i++]->insert(Array({"UInt64"}));
|
||||
else
|
||||
res_columns[SystemDictionariesColumn::KeyTypes]->insert(
|
||||
collections::map<Array>(*dict_structure->key, [](auto & attr) { return attr.type->getName(); }));
|
||||
res_columns[i++]->insert(collections::map<Array>(*dict_structure->key, [](auto & attr) { return attr.type->getName(); }));
|
||||
|
||||
res_columns[SystemDictionariesColumn::AttributeNames]->insert(
|
||||
collections::map<Array>(dict_structure->attributes, [](auto & attr) { return attr.name; }));
|
||||
res_columns[SystemDictionariesColumn::AttributeTypes]->insert(
|
||||
collections::map<Array>(dict_structure->attributes, [](auto & attr) { return attr.type->getName(); }));
|
||||
res_columns[SystemDictionariesColumn::Key]->insert(dict_structure->getKeyDescription());
|
||||
res_columns[i++]->insert(collections::map<Array>(dict_structure->attributes, [](auto & attr) { return attr.name; }));
|
||||
res_columns[i++]->insert(collections::map<Array>(dict_structure->attributes, [](auto & attr) { return attr.type->getName(); }));
|
||||
}
|
||||
else
|
||||
{
|
||||
for (size_t j = 0; j != 4; ++j) // Number of empty fields if dict_structure is null
|
||||
res_columns[i++]->insertDefault();
|
||||
}
|
||||
|
||||
res_columns[SystemDictionariesColumn::LoadingStartTime]->insert(
|
||||
static_cast<UInt64>(std::chrono::system_clock::to_time_t(load_result.loading_start_time)));
|
||||
res_columns[SystemDictionariesColumn::LastSuccessfulUpdateTime]->insert(
|
||||
static_cast<UInt64>(std::chrono::system_clock::to_time_t(load_result.last_successful_update_time)));
|
||||
res_columns[SystemDictionariesColumn::LoadingDuration]->insert(
|
||||
std::chrono::duration_cast<std::chrono::duration<float>>(load_result.loading_duration).count());
|
||||
if (dict_ptr)
|
||||
{
|
||||
res_columns[i++]->insert(dict_ptr->getBytesAllocated());
|
||||
res_columns[i++]->insert(dict_ptr->getHierarchicalIndexBytesAllocated());
|
||||
res_columns[i++]->insert(dict_ptr->getQueryCount());
|
||||
res_columns[i++]->insert(dict_ptr->getHitRate());
|
||||
res_columns[i++]->insert(dict_ptr->getFoundRate());
|
||||
res_columns[i++]->insert(dict_ptr->getElementCount());
|
||||
res_columns[i++]->insert(dict_ptr->getLoadFactor());
|
||||
res_columns[i++]->insert(dict_ptr->getSource()->toString());
|
||||
|
||||
const auto & lifetime = dict_ptr->getLifetime();
|
||||
res_columns[i++]->insert(lifetime.min_sec);
|
||||
res_columns[i++]->insert(lifetime.max_sec);
|
||||
if (!last_exception)
|
||||
last_exception = dict_ptr->getLastException();
|
||||
}
|
||||
else
|
||||
{
|
||||
for (size_t j = 0; j != 10; ++j) // Number of empty fields if dict_ptr is null
|
||||
res_columns[i++]->insertDefault();
|
||||
}
|
||||
|
||||
res_columns[i++]->insert(static_cast<UInt64>(std::chrono::system_clock::to_time_t(load_result.loading_start_time)));
|
||||
res_columns[i++]->insert(static_cast<UInt64>(std::chrono::system_clock::to_time_t(load_result.last_successful_update_time)));
|
||||
res_columns[i++]->insert(std::chrono::duration_cast<std::chrono::duration<float>>(load_result.loading_duration).count());
|
||||
|
||||
if (last_exception)
|
||||
res_columns[SystemDictionariesColumn::LastException]->insert(getExceptionMessage(last_exception, false));
|
||||
res_columns[i++]->insert(getExceptionMessage(last_exception, false));
|
||||
else
|
||||
res_columns[i++]->insertDefault();
|
||||
|
||||
index++;
|
||||
/// Set to default unfilled columns
|
||||
for (auto & column : res_columns)
|
||||
if (column->size() < index)
|
||||
column->insertDefault();
|
||||
if (dict_ptr)
|
||||
{
|
||||
res_columns[i++]->insert(dict_ptr->getDictionaryComment());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (load_result.config && load_result.config->config->has("dictionary.comment"))
|
||||
res_columns[i++]->insert(load_result.config->config->getString("dictionary.comment"));
|
||||
else
|
||||
res_columns[i++]->insertDefault();
|
||||
}
|
||||
|
||||
/// Start fill virtual columns
|
||||
|
||||
if (dict_structure)
|
||||
res_columns[i++]->insert(dict_structure->getKeyDescription());
|
||||
else
|
||||
res_columns[i++]->insertDefault();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,37 +0,0 @@
|
||||
<clickhouse>
|
||||
<dictionary>
|
||||
<name>bad_dict</name>
|
||||
|
||||
<source>
|
||||
<clickhouse>
|
||||
<host>localhost</host>
|
||||
<port>9000</port>
|
||||
<user>default</user>
|
||||
<password></password>
|
||||
<db>test</db>
|
||||
<table>source</table>
|
||||
</clickhouse>
|
||||
</source>
|
||||
|
||||
<lifetime>0</lifetime>
|
||||
|
||||
<layout>
|
||||
<cache><size_in_cells>128</size_in_cells></cache>
|
||||
</layout>
|
||||
|
||||
<structure>
|
||||
<id>
|
||||
<name>id</name>
|
||||
</id>
|
||||
|
||||
<attribute>
|
||||
<name>bad_attr</name>
|
||||
<type>bad_type</type>
|
||||
<null_value></null_value>
|
||||
<hierarchical>false</hierarchical>
|
||||
<injective>false</injective>
|
||||
</attribute>
|
||||
|
||||
</structure>
|
||||
</dictionary>
|
||||
</clickhouse>
|
@ -0,0 +1,37 @@
|
||||
<clickhouse>
|
||||
<dictionary>
|
||||
<name>invalid_dict</name>
|
||||
|
||||
<source>
|
||||
<clickhouse>
|
||||
<host>localhost</host>
|
||||
<port>9000</port>
|
||||
<user>default</user>
|
||||
<password></password>
|
||||
<db>test</db>
|
||||
<table>source</table>
|
||||
</clickhouse>
|
||||
</source>
|
||||
|
||||
<lifetime>0</lifetime>
|
||||
|
||||
<layout>
|
||||
<cache><size_in_cells>128</size_in_cells></cache>
|
||||
</layout>
|
||||
|
||||
<structure>
|
||||
<id>
|
||||
<name>id</name>
|
||||
</id>
|
||||
|
||||
<attribute>
|
||||
<name>bad_attr</name>
|
||||
<type>bad_type</type>
|
||||
<null_value></null_value>
|
||||
<hierarchical>false</hierarchical>
|
||||
<injective>false</injective>
|
||||
</attribute>
|
||||
|
||||
</structure>
|
||||
</dictionary>
|
||||
</clickhouse>
|
@ -4,7 +4,7 @@ from helpers.client import QueryRuntimeException
|
||||
from helpers.cluster import ClickHouseCluster
|
||||
|
||||
DICTIONARY_FILES = [
|
||||
"configs/dictionaries/bad_dict.xml",
|
||||
"configs/dictionaries/invalid_dict.xml",
|
||||
"configs/dictionaries/valid_dict.xml",
|
||||
]
|
||||
|
||||
@ -12,7 +12,7 @@ cluster = ClickHouseCluster(__file__)
|
||||
instance = cluster.add_instance("instance", dictionaries=DICTIONARY_FILES)
|
||||
|
||||
VALID_DICT_NAME = "valid_dict"
|
||||
BAD_DICT_NAME = "bad_dict"
|
||||
BAD_DICT_NAME = "invalid_dict"
|
||||
UNKNOWN_DATA_TYPE_EXCEPTION_STR = "DB::Exception: Unknown data type"
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user