행 정책, 즉 사용자가 테이블에서 읽을 수 있는 행을 결정하는 데 사용되는 필터를 생성합니다.
구문:
-- 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가지 패킹 형식을 허용합니다(완전한 카테시안 곱은 아님).
- 여러 호스트 이름, 하나의 대상 —
pol1, pol2 ON table1은 나열된 각 호스트 이름을 해당 단일 테이블(또는db.*)에 생성합니다. - 하나의 호스트 이름, 여러 대상 —
pol1 ON table1, table2는 나열된 각 대상에 동일한 짧은 호스트 이름을 생성합니다. - 혼합 쌍 —
p1 ON t1, p2 ON t2는 각 호스트 이름을 짝이 되는 대상에만 생성합니다.
여러 호스트 이름 목록은 한 그룹 내에서 여러 테이블의 ON 목록과 결합할 수 없습니다. p1, p2 ON t1, t2는 거부됩니다. 여러 호스트 이름 그룹 뒤에는 같은 SQL 문에서 쉼표로 구분된 다른 name ON target 그룹을 추가할 수도 없습니다.
선택적 ON CLUSTER는 전체 SQL 문에 적용됩니다(클러스터 이름 1개). ClickHouse는 하나의 생성 문에 패킹된 정책 호스트 이름별로 서로 다른 ON CLUSTER를 허용하지 않습니다. 정책을 서로 다른 클러스터에 생성해야 하는 경우 별도의 CREATE ROW POLICY SQL 문을 실행하십시오.
여러 호스트 이름 및 테이블
유효한 예:
-- 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 절
행을 필터링할 조건을 지정할 수 있습니다. 특정 행에 대해 이 조건의 계산 결과가 0이 아니면 사용자는 해당 행을 볼 수 있습니다.
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 절은 정책을 다른 정책과 어떤 방식으로 결합할지 지정합니다. 정책은 허용형일 수도 있고 제한형일 수도 있습니다. 기본적으로 정책은 허용형이며, 이 경우 불리언 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사용자 peter가 b=1 AND 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는 b=1 AND c=2를 모두 만족할 때만 table1의 행을 볼 수 있으며,
mydb의 다른 모든 테이블에는 해당 사용자에게 b=1 정책만 적용됩니다.
분산 및 원격 기반 테이블
행 정책은 테이블 데이터가 실제로 읽히는 위치에서 행을 필터링합니다. 분산 테이블이나 이를 감싼 래퍼(예: 대상이 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