#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace DB { namespace { enum Level { GROUP = -1, GLOBAL, DATABASE, TABLE, DICTIONARY, VIEW, COLUMN, }; DataTypeEnum8::Values getLevelEnumValues() { DataTypeEnum8::Values enum_values; enum_values.emplace_back("GLOBAL", static_cast(GLOBAL)); enum_values.emplace_back("DATABASE", static_cast(DATABASE)); enum_values.emplace_back("TABLE", static_cast(TABLE)); enum_values.emplace_back("DICTIONARY", static_cast(DICTIONARY)); enum_values.emplace_back("VIEW", static_cast(VIEW)); enum_values.emplace_back("COLUMN", static_cast(COLUMN)); return enum_values; } } const std::vector> & StorageSystemPrivileges::getAccessTypeEnumValues() { static const std::vector> values = [] { std::vector> res; #define ADD_ACCESS_TYPE_ENUM_VALUE(name, aliases, node_type, parent_group_name) \ res.emplace_back(toString(AccessType::name), static_cast(AccessType::name)); APPLY_FOR_ACCESS_TYPES(ADD_ACCESS_TYPE_ENUM_VALUE) #undef ADD_ACCESS_TYPE_ENUM_VALUE return res; }(); return values; } NamesAndTypesList StorageSystemPrivileges::getNamesAndTypes() { NamesAndTypesList names_and_types{ {"privilege", std::make_shared(getAccessTypeEnumValues())}, {"aliases", std::make_shared(std::make_shared())}, {"level", std::make_shared(std::make_shared(getLevelEnumValues()))}, {"parent_group", std::make_shared(std::make_shared(getAccessTypeEnumValues()))}, }; return names_and_types; } void StorageSystemPrivileges::fillData(MutableColumns & res_columns, ContextPtr, const SelectQueryInfo &) const { size_t column_index = 0; auto & column_access_type = assert_cast(*res_columns[column_index++]).getData(); auto & column_aliases = assert_cast(assert_cast(*res_columns[column_index]).getData()); auto & column_aliases_offsets = assert_cast(*res_columns[column_index++]).getOffsets(); auto & column_level = assert_cast(assert_cast(*res_columns[column_index]).getNestedColumn()).getData(); auto & column_level_null_map = assert_cast(*res_columns[column_index++]).getNullMapData(); auto & column_parent_group = assert_cast(assert_cast(*res_columns[column_index]).getNestedColumn()).getData(); auto & column_parent_group_null_map = assert_cast(*res_columns[column_index++]).getNullMapData(); auto add_row = [&](AccessType access_type, const std::string_view & aliases, Level max_level, AccessType parent_group) { column_access_type.push_back(static_cast(access_type)); for (size_t pos = 0; pos < aliases.length();) { size_t next_pos = aliases.find_first_of(',', pos); std::string_view alias = aliases.substr(pos, next_pos - pos); pos = ((next_pos == std::string_view::npos) ? next_pos : next_pos + 1); while (alias.starts_with(' ')) alias.remove_prefix(1); while (alias.ends_with(' ')) alias.remove_suffix(1); column_aliases.insertData(alias.data(), alias.length()); } column_aliases_offsets.push_back(column_aliases.size()); if (max_level == GROUP) { column_level.push_back(0); column_level_null_map.push_back(true); } else { column_level.push_back(static_cast(max_level)); column_level_null_map.push_back(false); } if (parent_group == AccessType::NONE) { column_parent_group.push_back(0); column_parent_group_null_map.push_back(true); } else { column_parent_group.push_back(static_cast(parent_group)); column_parent_group_null_map.push_back(false); } }; #define STORAGE_SYSTEM_PRIVILEGES_ADD_ROW(name, aliases, node_type, parent_group_name) \ add_row(AccessType::name, aliases, node_type, AccessType::parent_group_name); APPLY_FOR_ACCESS_TYPES(STORAGE_SYSTEM_PRIVILEGES_ADD_ROW) #undef STORAGE_SYSTEM_PRIVILEGES_ADD_ROW } }