#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace DB { NamesAndTypesList StorageSystemDictionaries::getNamesAndTypes() { return { {"database", std::make_shared()}, {"name", std::make_shared()}, {"uuid", std::make_shared()}, {"status", std::make_shared(getStatusEnumAllPossibleValues())}, {"origin", std::make_shared()}, {"type", std::make_shared()}, {"key", std::make_shared()}, {"attribute.names", std::make_shared(std::make_shared())}, {"attribute.types", std::make_shared(std::make_shared())}, {"bytes_allocated", std::make_shared()}, {"query_count", std::make_shared()}, {"hit_rate", std::make_shared()}, {"element_count", std::make_shared()}, {"load_factor", std::make_shared()}, {"source", std::make_shared()}, {"lifetime_min", std::make_shared()}, {"lifetime_max", std::make_shared()}, {"loading_start_time", std::make_shared()}, {"last_successful_update_time", std::make_shared()}, {"loading_duration", std::make_shared()}, //{ "creation_time", std::make_shared() }, {"last_exception", std::make_shared()} }; } void StorageSystemDictionaries::fillData(MutableColumns & res_columns, const Context & context, const SelectQueryInfo & /*query_info*/) const { const auto access = context.getAccess(); const bool check_access_for_dictionaries = !access->isGranted(AccessType::SHOW_DICTIONARIES); const auto & external_dictionaries = context.getExternalDictionariesLoader(); for (const auto & load_result : external_dictionaries.getLoadResults()) { const auto dict_ptr = std::dynamic_pointer_cast(load_result.object); 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; String db_or_tag = dict_id.database_name.empty() ? IDictionary::NO_DATABASE_TAG : dict_id.database_name; if (check_access_for_dictionaries && !access->isGranted(AccessType::SHOW_DICTIONARIES, db_or_tag, dict_id.table_name)) continue; 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(load_result.status)); res_columns[i++]->insert(load_result.config ? load_result.config->path : ""); std::exception_ptr last_exception = load_result.exception; if (dict_ptr) { res_columns[i++]->insert(dict_ptr->getTypeName()); const auto & dict_struct = dict_ptr->getStructure(); res_columns[i++]->insert(dict_struct.getKeyDescription()); res_columns[i++]->insert(ext::map(dict_struct.attributes, [] (auto & attr) { return attr.name; })); res_columns[i++]->insert(ext::map(dict_struct.attributes, [] (auto & attr) { return attr.type->getName(); })); res_columns[i++]->insert(dict_ptr->getBytesAllocated()); res_columns[i++]->insert(dict_ptr->getQueryCount()); res_columns[i++]->insert(dict_ptr->getHitRate()); 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 != 12; ++j) // Number of empty fields if dict_ptr is null res_columns[i++]->insertDefault(); } res_columns[i++]->insert(static_cast(std::chrono::system_clock::to_time_t(load_result.loading_start_time))); res_columns[i++]->insert(static_cast(std::chrono::system_clock::to_time_t(load_result.last_successful_update_time))); res_columns[i++]->insert(std::chrono::duration_cast>(load_result.loading_duration).count()); if (last_exception) res_columns[i++]->insert(getExceptionMessage(last_exception, false)); else res_columns[i++]->insertDefault(); } } }