Repository: ClickHouse/ClickHouse
File: src/Interpreters/Access/InterpreterGrantQuery.cpp (C++)

Code before:
        T & grantee,
        const AccessRightsElements & elements_to_grant,
        const AccessRightsElements & elements_to_revoke,
        const std::vector<UUID> & roles_to_grant,
        const RolesOrUsersSet & roles_to_revoke,
        bool admin_option)
    {
        if (!elements_to_revoke.empty())
            grantee.access.revoke(elements_to_revoke);

        if (!elements_to_grant.empty())
            grantee.access.grant(elements_to_grant);

        if (!roles_to_revoke.empty())
        {
            if (admin_option)
                grantee.granted_roles.revokeAdminOption(grantee.granted_roles.findGrantedWithAdminOption(roles_to_revoke));
            else
                grantee.granted_roles.revoke(grantee.granted_roles.findGranted(roles_to_revoke));
        }

        if (!roles_to_grant.empty())
        {
            if (admin_option)
                grantee.granted_roles.grantWithAdminOption(roles_to_grant);
            else
                grantee.granted_roles.grant(roles_to_grant);
        }
    }

    /// Updates grants of a specified user or role.
    void updateGrantedAccessRightsAndRoles(
        IAccessEntity & grantee,
        const AccessRightsElements & elements_to_grant,
        const AccessRightsElements & elements_to_revoke,
        const std::vector<UUID> & roles_to_grant,
        const RolesOrUsersSet & roles_to_revoke,
        bool admin_option)
    {
        if (auto * user = typeid_cast<User *>(&grantee))
            updateGrantedAccessRightsAndRolesTemplate(*user, elements_to_grant, elements_to_revoke, roles_to_grant, roles_to_revoke, admin_option);
        else if (auto * role = typeid_cast<Role *>(&grantee))
            updateGrantedAccessRightsAndRolesTemplate(*role, elements_to_grant, elements_to_revoke, roles_to_grant, roles_to_revoke, admin_option);
    }

    template <typename T>
    void grantCurrentGrantsTemplate(
        T & grantee,
        const AccessRights & rights_to_grant,
        const AccessRightsElements & elements_to_revoke)
    {

Review comment (suggestion):
The logic for removing default roles should include a comment explaining why this cleanup is necessary only for Users and not other grantee types. This would help maintainers understand the RBAC-specific invariant being enforced.
```suggestion
                {
                    /// Only User entities have default roles, and there is an invariant that
                    /// user's default_roles must always be a subset of the roles actually
                    /// granted to that user. When a role is revoked from a user, we must also
                    /// remove it from default_roles to keep this RBAC-specific invariant.
```

Code after:
        T & grantee,
        const AccessRightsElements & elements_to_grant,
        const AccessRightsElements & elements_to_revoke,
        const std::vector<UUID> & roles_to_grant,
        const RolesOrUsersSet & roles_to_revoke,
        bool admin_option)
    {
        if (!elements_to_revoke.empty())
            grantee.access.revoke(elements_to_revoke);

        if (!elements_to_grant.empty())
            grantee.access.grant(elements_to_grant);

        if (!roles_to_revoke.empty())
        {
            if (admin_option)
            {
                grantee.granted_roles.revokeAdminOption(grantee.granted_roles.findGrantedWithAdminOption(roles_to_revoke));
            }
            else
            {
                auto found_roles_to_revoke = grantee.granted_roles.findGranted(roles_to_revoke);
                grantee.granted_roles.revoke(found_roles_to_revoke);

                if constexpr (std::is_same_v<T, User>)
                {
                    for (const auto & id : found_roles_to_revoke)
                        grantee.default_roles.ids.erase(id);
                }
            }
        }

        if (!roles_to_grant.empty())
        {
            if (admin_option)
                grantee.granted_roles.grantWithAdminOption(roles_to_grant);
            else
                grantee.granted_roles.grant(roles_to_grant);
        }
    }

    /// Updates grants of a specified user or role.
    void updateGrantedAccessRightsAndRoles(
        IAccessEntity & grantee,
        const AccessRightsElements & elements_to_grant,
        const AccessRightsElements & elements_to_revoke,
        const std::vector<UUID> & roles_to_grant,
        const RolesOrUsersSet & roles_to_revoke,
        bool admin_option)
    {
        if (auto * user = typeid_cast<User *>(&grantee))