-- 每个用户只能看到 owner 列等于自己登录名的行
CREATE FUNCTION my_schema.owner_only(owner STRING)
RETURNS BOOLEAN
AS owner = current_user();
也可以结合
current_roles()
current_roles()
(返回当前用户的角色数组)做基于角色的过滤:
-- admin 角色可见全部行,其他用户只能看到 region = 'east' 的行
CREATE FUNCTION my_schema.role_based(region STRING)
RETURNS BOOLEAN
AS array_contains(current_roles(), 'admin') OR region = 'east';
过滤条件也可以是与身份无关的固定逻辑:
-- 只允许 region = 'east' 的行可见
CREATE FUNCTION my_schema.only_east(region STRING)
RETURNS BOOLEAN
AS region = 'east';
函数还可以接收多个参数,实现多列组合判断:
-- 只允许 east 区且金额 >= 200 的行可见
CREATE FUNCTION my_schema.east_big(region STRING, amt INT)
RETURNS BOOLEAN
AS region = 'east' AND amt >= 200;
安全上下文函数
current_user()
current_user()
返回当前登录用户名,
current_roles()
current_roles()
返回当前用户的角色数组(注意大小写)。
第二步:绑定到表
建表时绑定
CREATE TABLE my_schema.docs (
id INT,
owner STRING,
content STRING
) ROW FILTER my_schema.owner_only ON (owner);
已有表绑定
ALTER TABLE my_schema.docs SET ROW FILTER my_schema.owner_only ON (owner);
ON (...)
ON (...)
中列出的列会按顺序作为参数传给过滤函数,列的类型和数量必须与函数定义匹配。
⚠️ 引用过滤函数时建议使用 schema 限定名(如
my_schema.owner_only
my_schema.owner_only
)。不带 schema 限定时,系统按当前 schema 解析,可能因找不到函数而报
function not found
function not found
。
第三步:验证绑定
DESC EXTENDED my_schema.docs;
输出末尾会出现
# Row Filter
# Row Filter
段:
# Row Filter
Function quick_start.my_schema.owner_only
Bound Parameters owner
行为示例
以
owner_only
owner_only
(基于
current_user()
current_user()
)为例,假设当前登录用户是
alice
alice
:
INSERT INTO my_schema.docs VALUES
(1, 'alice', 'alice doc'), (2, 'bob', 'bob doc'), (3, 'alice', 'another alice doc');
-- alice 查询:只返回 owner = 'alice' 的行
SELECT * FROM my_schema.docs ORDER BY id;
-- 1 | alice | alice doc
-- 3 | alice | another alice doc
同一条 SQL,不同用户登录时看到的数据不同——
bob
bob
登录时只会看到 id=2 的行。这就是行级安全按身份动态过滤的效果。
行过滤对各类操作的影响:
操作
行为
SELECT
SELECT
只返回可见行(过滤函数返回 true 的行)
聚合(
COUNT
COUNT
/
SUM
SUM
等)
只统计可见行
UPDATE
UPDATE
只更新可见行,不可见行不受影响
DELETE
DELETE
只删除可见行,不可见行保留
例如
alice
alice
执行
UPDATE my_schema.docs SET content = 'updated' WHERE id IN (1,2,3)
UPDATE my_schema.docs SET content = 'updated' WHERE id IN (1,2,3)
,实际只有可见的 id=1、id=3 被更新,属于
bob
bob
的 id=2 不受影响。
多列过滤函数示例
CREATE FUNCTION my_schema.east_big(region STRING, amt INT)
RETURNS BOOLEAN
AS region = 'east' AND amt >= 200;
CREATE TABLE my_schema.o2 (id INT, region STRING, amt INT)
ROW FILTER my_schema.east_big ON (region, amt);
INSERT INTO my_schema.o2 VALUES (1,'east',100), (2,'east',300), (3,'west',300);
SELECT * FROM my_schema.o2 ORDER BY id;
-- 2 | east | 300 (仅 region='east' 且 amt>=200 的行可见)
移除行过滤
ALTER TABLE my_schema.o2 DROP ROW FILTER;
移除后表中所有数据恢复可见,底层数据不受任何影响。
SELECT * FROM my_schema.o2 ORDER BY id;
-- 1 | east | 100
-- 2 | east | 300
-- 3 | west | 300