#include #include #include #include #include #include #include #include #include #include namespace DB { namespace { void updateRowPolicyFromQueryImpl( RowPolicy & policy, const ASTCreateRowPolicyQuery & query, const RowPolicyName & override_name, const std::optional & override_to_roles) { if (!override_name.empty()) policy.setFullName(override_name); else if (!query.new_short_name.empty()) policy.setShortName(query.new_short_name); else if (query.names->full_names.size() == 1) policy.setFullName(query.names->full_names.front()); if (query.is_restrictive) policy.setRestrictive(*query.is_restrictive); for (const auto & [condition_type, condition] : query.conditions) policy.conditions[condition_type] = condition ? serializeAST(*condition) : String{}; if (override_to_roles) policy.to_roles = *override_to_roles; else if (query.roles) policy.to_roles = *query.roles; } } BlockIO InterpreterCreateRowPolicyQuery::execute() { auto & query = query_ptr->as(); auto & access_control = getContext()->getAccessControl(); getContext()->checkAccess(query.alter ? AccessType::ALTER_ROW_POLICY : AccessType::CREATE_ROW_POLICY); if (!query.cluster.empty()) { query.replaceCurrentUserTag(getContext()->getUserName()); return executeDDLQueryOnCluster(query_ptr, getContext()); } assert(query.names->cluster.empty()); std::optional roles_from_query; if (query.roles) roles_from_query = RolesOrUsersSet{*query.roles, access_control, getContext()->getUserID()}; query.replaceEmptyDatabase(getContext()->getCurrentDatabase()); if (query.alter) { auto update_func = [&](const AccessEntityPtr & entity) -> AccessEntityPtr { auto updated_policy = typeid_cast>(entity->clone()); updateRowPolicyFromQueryImpl(*updated_policy, query, {}, roles_from_query); return updated_policy; }; Strings names = query.names->toStrings(); if (query.if_exists) { auto ids = access_control.find(names); access_control.tryUpdate(ids, update_func); } else access_control.update(access_control.getIDs(names), update_func); } else { std::vector new_policies; for (const auto & full_name : query.names->full_names) { auto new_policy = std::make_shared(); updateRowPolicyFromQueryImpl(*new_policy, query, full_name, roles_from_query); new_policies.emplace_back(std::move(new_policy)); } if (query.if_not_exists) access_control.tryInsert(new_policies); else if (query.or_replace) access_control.insertOrReplace(new_policies); else access_control.insert(new_policies); } return {}; } void InterpreterCreateRowPolicyQuery::updateRowPolicyFromQuery(RowPolicy & policy, const ASTCreateRowPolicyQuery & query) { updateRowPolicyFromQueryImpl(policy, query, {}, {}); } }