1#include <DataTypes/DataTypeArray.h>
2#include <DataTypes/DataTypeDateTime.h>
3#include <DataTypes/DataTypesNumber.h>
4#include <DataTypes/DataTypeString.h>
5#include <DataTypes/DataTypeEnum.h>
6#include <Dictionaries/IDictionary.h>
7#include <Dictionaries/IDictionarySource.h>
8#include <Dictionaries/DictionaryStructure.h>
9#include <Interpreters/Context.h>
10#include <Interpreters/ExternalDictionariesLoader.h>
11#include <Storages/System/StorageSystemDictionaries.h>
12#include <Storages/VirtualColumnUtils.h>
13#include <Columns/ColumnString.h>
14#include <Core/Names.h>
15
16#include <ext/map.h>
17#include <mutex>
18
19namespace DB
20{
21
22NamesAndTypesList StorageSystemDictionaries::getNamesAndTypes()
23{
24 return {
25 {"database", std::make_shared<DataTypeString>()},
26 {"name", std::make_shared<DataTypeString>()},
27 {"status", std::make_shared<DataTypeEnum8>(ExternalLoader::getStatusEnumAllPossibleValues())},
28 {"origin", std::make_shared<DataTypeString>()},
29 {"type", std::make_shared<DataTypeString>()},
30 {"key", std::make_shared<DataTypeString>()},
31 {"attribute.names", std::make_shared<DataTypeArray>(std::make_shared<DataTypeString>())},
32 {"attribute.types", std::make_shared<DataTypeArray>(std::make_shared<DataTypeString>())},
33 {"bytes_allocated", std::make_shared<DataTypeUInt64>()},
34 {"query_count", std::make_shared<DataTypeUInt64>()},
35 {"hit_rate", std::make_shared<DataTypeFloat64>()},
36 {"element_count", std::make_shared<DataTypeUInt64>()},
37 {"load_factor", std::make_shared<DataTypeFloat64>()},
38 {"source", std::make_shared<DataTypeString>()},
39 {"lifetime_min", std::make_shared<DataTypeUInt64>()},
40 {"lifetime_max", std::make_shared<DataTypeUInt64>()},
41 {"loading_start_time", std::make_shared<DataTypeDateTime>()},
42 {"loading_duration", std::make_shared<DataTypeFloat32>()},
43 //{ "creation_time", std::make_shared<DataTypeDateTime>() },
44 {"last_exception", std::make_shared<DataTypeString>()}
45 };
46}
47
48void StorageSystemDictionaries::fillData(MutableColumns & res_columns, const Context & context, const SelectQueryInfo & /*query_info*/) const
49{
50 const auto & external_dictionaries = context.getExternalDictionariesLoader();
51 for (const auto & load_result : external_dictionaries.getCurrentLoadResults())
52 {
53 const auto dict_ptr = std::dynamic_pointer_cast<const IDictionaryBase>(load_result.object);
54
55 String database, short_name;
56 if (dict_ptr)
57 {
58 database = dict_ptr->getDatabase();
59 short_name = dict_ptr->getName();
60 }
61 else
62 {
63 short_name = load_result.name;
64 if (!load_result.repository_name.empty() && startsWith(short_name, load_result.repository_name + "."))
65 {
66 database = load_result.repository_name;
67 short_name = short_name.substr(database.length() + 1);
68 }
69 }
70
71 size_t i = 0;
72 res_columns[i++]->insert(database);
73 res_columns[i++]->insert(short_name);
74 res_columns[i++]->insert(static_cast<Int8>(load_result.status));
75 res_columns[i++]->insert(load_result.origin);
76
77 std::exception_ptr last_exception = load_result.exception;
78
79 if (dict_ptr)
80 {
81 res_columns[i++]->insert(dict_ptr->getTypeName());
82
83 const auto & dict_struct = dict_ptr->getStructure();
84 res_columns[i++]->insert(dict_struct.getKeyDescription());
85 res_columns[i++]->insert(ext::map<Array>(dict_struct.attributes, [] (auto & attr) { return attr.name; }));
86 res_columns[i++]->insert(ext::map<Array>(dict_struct.attributes, [] (auto & attr) { return attr.type->getName(); }));
87 res_columns[i++]->insert(dict_ptr->getBytesAllocated());
88 res_columns[i++]->insert(dict_ptr->getQueryCount());
89 res_columns[i++]->insert(dict_ptr->getHitRate());
90 res_columns[i++]->insert(dict_ptr->getElementCount());
91 res_columns[i++]->insert(dict_ptr->getLoadFactor());
92 res_columns[i++]->insert(dict_ptr->getSource()->toString());
93
94 const auto & lifetime = dict_ptr->getLifetime();
95 res_columns[i++]->insert(lifetime.min_sec);
96 res_columns[i++]->insert(lifetime.max_sec);
97 if (!last_exception)
98 last_exception = dict_ptr->getLastException();
99 }
100 else
101 {
102 for (size_t j = 0; j != 12; ++j) // Number of empty fields if dict_ptr is null
103 res_columns[i++]->insertDefault();
104 }
105
106 res_columns[i++]->insert(static_cast<UInt64>(std::chrono::system_clock::to_time_t(load_result.loading_start_time)));
107 res_columns[i++]->insert(std::chrono::duration_cast<std::chrono::duration<float>>(load_result.loading_duration).count());
108
109 if (last_exception)
110 res_columns[i++]->insert(getExceptionMessage(last_exception, false));
111 else
112 res_columns[i++]->insertDefault();
113
114 }
115}
116
117}
118
119