StarRocks current_role 函数详解:查询当前会话已激活角色
【免费下载链接】starrocksThe world's fastest open query engine for sub-second analytics both on and off the data lakehouse. With the flexibility to support nearly any scenario, StarRocks provides best-in-class performance for multi-dimensional analytics, real-time analytics, and ad-hoc queries. A Linux Foundation project.项目地址: https://gitcode.com/GitHub_Trending/st/starrocks
本文围绕 StarRocks 的current_role()信息函数展开,介绍其语法、返回值与典型用法,并结合前端(FE)源码说明该函数背后的实现原理,以及它与SET ROLE、GRANT、is_role_in_session()等角色权限(RBAC)体系组件的联动方式。读完本文,你将掌握如何在当前会话中查询已激活的角色,并能通过该函数验证角色激活是否生效,为权限问题的排查提供依据。
功能概述
current_role()用于查询当前用户(当前会话)中已激活的角色。它是 StarRocks 内置的"信息函数"(Information Function)之一,在 FunctionSet.java 中与connection_id()、database()、user()、current_user()、current_group()等一同被收录进INFORMATION_FUNCTIONS集合,因此可以像普通表达式一样在SELECT语句中使用。
需要区分两个概念:
- 用户被授予的角色(Granted Roles):通过
GRANT语句授予给用户的全部角色; - 已激活的角色(Activated Roles):在当前会话中真正生效的角色,只有激活后,角色所附带的权限与嵌套角色才会参与授权检查。
current_role()返回的是后者——即当前会话中已激活的角色列表。
语法与参数
current_role(); current_role;该函数支持两种调用形式:带括号的current_role(),以及省略括号的current_role(与database、user等信息函数保持一致)。
参数:无。
返回值:VARCHAR类型。
返回值详解
current_role()的返回值由 ExpressionAnalyzer.java 中的visitInformationFunction逻辑决定,其行为可以归纳为以下三种情况:
- 有已激活角色:返回当前会话所有已激活角色的名称,多个角色之间以逗号加空格(
,)分隔; - 没有已激活角色:返回字符串
NONE; - 返回值的类型固定为
VARCHAR。
从源码实现看,该函数逐个读取会话上下文中记录的角色 ID(session.getCurrentRoleIds()),再通过AuthorizationMgr.getRolePrivilegeCollectionUnlocked(roleId, false)反查出对应的角色名称并拼接输出;若角色 ID 列表为空,则直接返回"NONE"。
已激活角色从何而来:源码级调用链
要理解current_role()的返回值,需要了解"已激活角色"在 StarRocks 中的产生路径。当前会话的角色 ID 集合存储于 FE 的ConnectContext中,主要通过以下两条路径被设置:
1. 登录时设置默认角色
用户建立连接(如通过 MySQL 协议登录)时,FE 会根据认证信息初始化当前会话的角色。见 UserIdentityUtils.java:当 Thrift 认证信息中携带了current_role_ids时,会将其与用户实际拥有的角色求交集后写入ConnectContext;否则以用户身份对应的默认角色作为当前角色。
2. 执行 SET ROLE 激活角色
用户在会话内通过SET ROLE语句动态切换/激活角色,见 SetRoleExecutor.java。SET ROLE支持四种形式:
-- 激活指定的一个或多个角色 SET ROLE <role_name>[,<role_name>,..]; -- 激活用户的所有角色,但排除指定的角色 SET ROLE ALL EXCEPT <role_name>[,<role_name>,..]; -- 激活用户的所有角色 SET ROLE ALL; -- 关闭当前会话的所有角色(不激活任何角色) SET ROLE NONE;SET ROLE执行时会校验角色确实已授予给当前用户(getValidRoleId会检查角色是否存在、是否被授予),随后调用context.setCurrentRoleIds(roleIds)更新会话的角色状态。之后调用current_role(),即可看到激活结果。
完整使用示例
原文档给出的基础示例如下:
mysql> select current_role(); +----------------+ | current_role() | +----------------+ | db_admin | +----------------+下面结合角色生命周期,给出一个完整的端到端示例:
-- 1. 查看当前用户被授予了哪些角色 SHOW GRANTS; +--------------+---------+----------------------------------------------+ | UserIdentity | Catalog | Grants | +--------------+---------+----------------------------------------------+ | 'test'@'%' | NULL | GRANT 'db_admin', 'user_admin' TO 'test'@'%' | +--------------+---------+----------------------------------------------+ -- 2. 尚未激活任何角色时,current_role() 返回 NONE SELECT CURRENT_ROLE(); +----------------+ | CURRENT_ROLE() | +----------------+ | NONE | +----------------+ -- 3. 激活 db_admin 角色 SET ROLE db_admin; -- 4. 再次查询,角色已激活 SELECT CURRENT_ROLE(); +--------------------+ | CURRENT_ROLE() | +--------------------+ | db_admin | +--------------------+ -- 5. 激活全部角色(ALL 形式) SET ROLE ALL; SELECT CURRENT_ROLE(); +----------------------------+ | CURRENT_ROLE() | +----------------------------+ | db_admin, user_admin | +----------------------------+ -- 6. 关闭所有角色 SET ROLE NONE; SELECT CURRENT_ROLE(); +----------------+ | CURRENT_ROLE() | +----------------+ | NONE | +----------------+注意:
SET ROLE命令自 v3.0 起支持。current_role()的返回值受会话中角色激活状态影响,不同会话之间互不影响。
与 is_role_in_session() 的配合使用
除current_role()外,StarRocks 还提供了is_role_in_session(VARCHAR role_name)用于精确验证某个角色(含嵌套角色)是否在会话中激活,详见 is_role_in_session(该函数自 v3.1.4 起支持)。两者定位不同:
current_role():返回激活角色的名称列表,适合快速查看整体状态;is_role_in_session():返回布尔值(1表示已激活、0表示未激活),适合在脚本中做条件判断,或校验嵌套角色是否随父角色一并生效。
示例:
-- 创建角色与用户,并将 r2、r3 嵌套进 r1,最后授予用户 u1 create role r1; create role r2; create role r3; create user u1; grant r3 to role r2; grant r2 to role r1; grant r1 to user u1; -- 以 u1 身份操作 execute as u1 with no revert; -- 未激活前:r1 未激活 select is_role_in_session("r1"); -- 返回 0 -- 激活 r1 后,嵌套角色 r2、r3 一并激活 set role "r1"; select is_role_in_session("r1"); -- 返回 1 select is_role_in_session("r2"); -- 返回 1 select is_role_in_session("r3"); -- 返回 1注意事项与最佳实践
激活角色影响全部授权检查:已激活的角色会影响所有权限校验,包括对
information_schema系统视图的查询。例如执行SET ROLE role1后,SELECT * FROM information_schema.tables只会返回role1权限范围内的表。因此在使用current_role()排查"为什么看不到某张表/某条元数据"时,请先确认当前会话激活的角色是否符合预期。只能激活已授予的角色:
SET ROLE无法激活用户未持有的角色,源码中getValidRoleId会显式校验并抛出 "Role xxx is not granted to ..." 异常。若激活失败,可通过 SHOW GRANTS 确认用户实际拥有的角色。无角色返回 NONE:当会话未激活任何角色时,
current_role()返回字符串NONE,而非空串或 NULL,判断"是否有激活角色"时可据此处理。角色生命周期管理:角色的创建、授权、修改、删除分别对应 CREATE ROLE、GRANT、ALTER USER、SHOW ROLES 等语句;被删除的角色会从会话激活列表中移除,此时
current_role()的输出也会相应变化。
总结
current_role()是 StarRocks 权限体系中一个轻量但实用的信息函数:它以VARCHAR形式返回当前会话已激活的角色名称列表,无激活角色时返回NONE。在源码层面,它由 FE 的ExpressionAnalyzer依据ConnectContext中的角色 ID 集合解析生成,与SET ROLE的角色激活机制、is_role_in_session()的角色校验机制共同构成了一套完整的角色状态查询与验证工具链,可用于日常的权限审计、问题排查与自动化脚本中的权限断言。
【免费下载链接】starrocksThe world's fastest open query engine for sub-second analytics both on and off the data lakehouse. With the flexibility to support nearly any scenario, StarRocks provides best-in-class performance for multi-dimensional analytics, real-time analytics, and ad-hoc queries. A Linux Foundation project.项目地址: https://gitcode.com/GitHub_Trending/st/starrocks
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考