行ポリシーを作成します。これは、ユーザーがテーブルから読み取れる行を決定するためのフィルターです。
構文:
-- 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 は3つのパッキング形式を受け入れます (完全なデカルト積ではありません) 。
- 複数の名前、1つの対象 —
pol1, pol2 ON table1は、列挙した各名前をその1つのテーブル (またはdb.*) に作成します。 - 1つの名前、複数の対象 —
pol1 ON table1, table2は、同じ短縮名を列挙した各対象に作成します。 - 混在したペア —
p1 ON t1, p2 ON t2は、各名前を対応する対象にのみ作成します。
複数名のリストを、1つのグループ内で複数テーブルの ON リストと組み合わせることはできません。p1, p2 ON t1, t2 は拒否されます。複数名グループの後に、同じステートメント内で別のカンマ区切りの name ON target グループを追加することもできません。
省略可能な ON CLUSTER は、ステートメント全体に適用されます (指定できるクラスター名は1つです) 。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 table2USING 句
行を絞り込むための条件を指定できます。ある行に対する条件の評価結果が非ゼロの場合、その行はユーザーに表示されます。
TO 句
TO 句では、このポリシーの適用対象となるユーザーとロールの一覧を指定できます。たとえば、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=1 または c=2 のいずれかを満たす行を参照できるようにします。
AS 句は、ポリシーを他のポリシーとどのように組み合わせるかを指定します。ポリシーには permissive と restrictive の 2 種類があります。デフォルトではポリシーは permissive であり、これはブール演算子 OR を使用して組み合わせられることを意味します。
別の方法として、ポリシーを restrictive として定義することもできます。restrictive ポリシーは、ブール演算子 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ユーザー peter が行を参照できるのは、b=1 かつ c=2 の両方を満たす場合に限られます。
データベースポリシーは、テーブルポリシーと組み合わせて適用されます。
たとえば、次のポリシーです。
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 が table1 の行を参照できるのは、b=1 かつ c=2 の場合だけです。ただし、
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 句
クラスター全体に対して行ポリシーを作成できます。詳しくは分散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