Skip to content
ClickHouse Docs
ClickHouse DocsClickHouse Docs

CREATE ROW POLICY

创建行策略,即一种用于确定用户可从表中读取哪些行的过滤器。

语法:

-- Multiple names on one table target
CREATE [ROW] POLICY [IF NOT EXISTS | OR REPLACE] policy_name [, ...]
    [ON CLUSTER cluster_name]
    ON { [db.]table | db.* }
    [IN access_storage_type]
    [FOR SELECT] USING condition
    [AS {PERMISSIVE | RESTRICTIVE}]
    [TO {role1 [, role2 ...] | ALL | ALL EXCEPT role1 [, role2 ...]}]

-- One name on multiple table targets
CREATE [ROW] POLICY [IF NOT EXISTS | OR REPLACE] policy_name
    [ON CLUSTER cluster_name]
    ON { [db.]table | db.* } [, ...]
    [IN access_storage_type]
    [FOR SELECT] USING condition
    [AS {PERMISSIVE | RESTRICTIVE}]
    [TO {role1 [, role2 ...] | ALL | ALL EXCEPT role1 [, role2 ...]}]

-- Mixed packing: each name paired with its own table target
CREATE [ROW] POLICY [IF NOT EXISTS | OR REPLACE]
    policy_name ON { [db.]table | db.* } [, policy_name ON { [db.]table | db.* } ...]
    [ON CLUSTER cluster_name]
    [IN access_storage_type]
    [FOR SELECT] USING condition
    [AS {PERMISSIVE | RESTRICTIVE}]
    [TO {role1 [, role2 ...] | ALL | ALL EXCEPT role1 [, role2 ...]}]

ParserRowPolicyNames 支持三种打包形式 (并非完整的笛卡尔积) :

  1. 多个名称,一个目标pol1, pol2 ON table1 会在该表 (或 db.*) 上创建列出的每个名称。
  2. 一个名称,多个目标pol1 ON table1, table2 会在每个列出的目标上创建相同的短名称。
  3. 混合配对p1 ON t1, p2 ON t2 仅在各自配对的目标上创建对应的名称。

多名称列表不能与多表 ON 列表组合在同一组中:p1, p2 ON t1, t2 会被拒绝。多名称组之后,也不能在同一语句中追加另一个以逗号分隔的 name ON target 组。

可选的 ON CLUSTER 适用于整个语句 (仅指定一个集群名称) 。ClickHouse 接受在单个创建语句中为每个策略名称指定不同的 ON CLUSTER — 若必须在不同集群上创建策略,请分别执行 CREATE ROW POLICY 语句。

多个名称和表

有效:

-- Several policy names, one table
CREATE ROW POLICY pol1, pol2, pol3 ON table1
    FOR SELECT USING id = 1
    TO accountant;

-- One policy name, several tables
CREATE ROW POLICY IF NOT EXISTS pol1 ON table1, table2, table3
    FOR SELECT USING id = 1
    TO accountant;

-- Mixed packing: different name per table
CREATE ROW POLICY p4 ON db.table, p5 ON db2.table2
    USING a = b;

-- Same policy on several tables, on a cluster
CREATE ROW POLICY IF NOT EXISTS pol1 ON CLUSTER replicated_cluster ON table1, table2
    FOR SELECT USING id = 1
    TO accountant;

无效:

-- Multi-name × multi-table in one ON-group (not a Cartesian product)
CREATE ROW POLICY p1, p2 ON t1, t2
    FOR SELECT USING id = 1
    TO accountant;

-- Different clusters per name in one statement
CREATE ROW POLICY pol1 ON CLUSTER cluster1 ON table1, pol2 ON CLUSTER cluster2 ON table2

USING 子句

允许指定用于过滤行的条件。若某一行上的该条件计算结果非零,用户就能看到该行。

TO 子句

TO 部分中,您可以指定此策略适用的用户和 roles 列表。例如,CREATE ROW POLICY ... TO accountant, john@localhost

关键字 ALL 表示所有 ClickHouse 用户,包括当前用户。关键字 ALL EXCEPT 允许从所有用户列表中排除某些用户,例如 CREATE ROW POLICY ... TO ALL EXCEPT accountant, john@localhost

AS 子句

允许同一用户在同一张表上同时启用多个策略。因此,我们需要一种方式来组合多个策略中的条件。

默认情况下,策略通过布尔 OR 运算符进行组合。例如,以下策略:

CREATE ROW POLICY pol1 ON mydb.table1 USING b=1 TO mira, peter
CREATE ROW POLICY pol2 ON mydb.table1 USING c=2 TO peter, antonio

允许用户 peter 查看满足 b=1c=2 的行。

AS 子句指定策略应如何与其他策略组合。策略可以是宽松型或限制型。默认情况下,策略为宽松型,这意味着它们会通过布尔 OR 运算符组合。

或者,也可以将策略定义为限制型。限制型策略会通过布尔 AND 运算符组合。

以下是通用公式:

row_is_visible = (one or more of the permissive policies' conditions are non-zero) AND
                 (all of the restrictive policies's conditions are non-zero)

例如,以下策略:

CREATE ROW POLICY pol1 ON mydb.table1 USING b=1 TO mira, peter
CREATE ROW POLICY pol2 ON mydb.table1 USING c=2 AS RESTRICTIVE TO peter, antonio

仅当 b=1c=2 两个条件同时满足时,才允许用户 peter 查看这些行。

数据库策略会与表策略组合生效。

例如,以下策略:

CREATE ROW POLICY pol1 ON mydb.* USING b=1 TO mira, peter
CREATE ROW POLICY pol2 ON mydb.table1 USING c=2 AS RESTRICTIVE TO peter, antonio

使用户 peter 只有在同时满足 b=1c=2 时才能看到 table1 的行,尽管 mydb 中的任何其他表对该用户都只会应用 b=1 策略。

Distributed 和由远程服务器支持的表

行策略会在实际读取表数据的位置过滤行。将读取操作委托给远程服务器的表,例如 Distributed 表或其封装 (例如,目标为 Distributed 的 materialized view) ,只会将查询文本发送到远程服务器,无法对远程读取应用策略过滤器。为避免过滤器被悄然忽略,策略适用用户对这类表发起的查询会因 ILLEGAL_PREWHERE 错误而被拒绝。

请改为在每台远程服务器的底层本地表上定义策略;当发送的查询读取这些表时,策略会在该处生效:

-- Filters reads of local_table on this server, including reads shipped by a Distributed table over it.
CREATE ROW POLICY filter ON mydb.local_table USING a < 1000 TO john;

ON CLUSTER 子句

允许在集群中创建行策略,参见 Distributed DDL。这也是在集群中每台服务器的本地表上创建策略的便捷方式。

示例

CREATE ROW POLICY filter1 ON mydb.mytable USING a<1000 TO accountant, john@localhost

CREATE ROW POLICY filter2 ON mydb.mytable USING a<1000 AND b=5 TO ALL EXCEPT mira

CREATE ROW POLICY filter3 ON mydb.mytable USING 1 TO admin

CREATE ROW POLICY filter4 ON mydb.* USING 1 TO admin

Navigation