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 | |
19 | namespace DB |
20 | { |
21 | |
22 | NamesAndTypesList 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 | |
48 | void 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 | |