Skip to main content
행 정책, 즉 사용자가 테이블에서 읽을 수 있는 행을 결정하는 데 사용되는 필터를 생성합니다.
행 정책은 읽기 전용 권한이 있는 사용자에게만 유효합니다. 사용자가 테이블을 수정하거나 테이블 간에 파티션을 복사할 수 있으면 행 정책의 제한이 무력화됩니다.
구문:
ParserRowPolicyNames는 3가지 패킹 형식을 허용합니다(완전한 카테시안 곱은 아님).
  1. 여러 이름, 하나의 대상 — pol1, pol2 ON table1은 나열된 각 이름을 해당 단일 테이블(또는 db.*)에 생성합니다.
  2. 하나의 이름, 여러 대상 — pol1 ON table1, table2는 나열된 각 대상에 동일한 짧은 이름을 생성합니다.
  3. 혼합 쌍 — 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 문을 실행하십시오. CREATE ROW POLICY에는 정책이 생성되는 테이블에 대한 CREATE ROW POLICY 권한이 필요합니다. OR REPLACE는 동일한 이름의 기존 정책을 적용 대상 역할까지 포함하여 폐기하므로, 해당 테이블에 대한 DROP ROW POLICY 권한도 추가로 필요합니다. DROP ROW POLICY 권한은 정책의 존재 여부와 관계없이 필요하므로, 이 SQL 문을 사용하여 어떤 정책이 존재하는지 알아낼 수는 없습니다.

여러 호스트 이름 및 테이블

유효한 예:
유효하지 않음:

USING 절

테이블에 적용할 필터 조건을 정의합니다. 사용자는 조건이 참인(0이 아닌 값으로 평가되는) 행만 볼 수 있습니다. 이는 사용자가 해당 테이블에 실행하는 모든 쿼리에 WHERE 조건을 추가하는 것과 비슷합니다. 예를 들어, 다음 정책은 analyst_role이 EU 지역의 행만 조회할 수 있도록 제한합니다.
이 정책을 적용하면 SELECT * FROM db.orders는 SELECT * FROM db.orders WHERE region = 'EU'를 실행했을 때와 동일한 행을 반환합니다.

TO 절

TO 섹션에서는 이 정책을 적용할 사용자 및 역할 목록을 지정할 수 있습니다. 예를 들어 CREATE ROW POLICY ... TO accountant, john@localhost와 같습니다. 키워드 ALL은 현재 사용자를 포함한 모든 ClickHouse 사용자를 의미합니다. 키워드 ALL EXCEPT는 전체 사용자 목록에서 일부 사용자를 제외할 수 있도록 하며, 예를 들어 CREATE ROW POLICY ... TO ALL EXCEPT accountant, john@localhost와 같습니다. ALL EXCEPT 뒤에 지정된 역할을 포함하여 TO 섹션에 명시된 역할은 사용자에게 부여된 모든 역할이 아니라 현재 사용자의 활성화된 역할(system.enabled_roles)과 비교되므로, SET ROLE로 적용되는 정책을 바꿀 수 있습니다.

AS 절

동일한 사용자에게 동일한 테이블에 대해 한 번에 둘 이상의 정책을 활성화할 수 있습니다. 따라서 여러 정책의 조건을 결합할 방법이 필요합니다. 기본적으로 정책은 불리언 OR 연산자를 사용해 결합됩니다. 예를 들어, 다음과 같은 정책이 있습니다.
사용자 peter가 b=1 또는 c=2인 행을 볼 수 있게 합니다. AS 절은 정책을 다른 정책과 어떤 방식으로 결합할지 지정합니다. 정책은 허용형일 수도 있고 제한형일 수도 있습니다. 기본적으로 정책은 허용형이며, 이 경우 불리언 OR 연산자를 사용해 결합됩니다. 대안으로 정책을 제한형으로 정의할 수도 있습니다. 제한형 정책은 불리언 AND 연산자를 사용해 결합됩니다. 다음은 일반식입니다:
허용형 조건이 하나도 적용되지 않으면 첫 번째 조건은 아무런 영향을 주지 않고 제한형 정책만으로 결정되는데, 이는 access_control_improvements.users_without_row_policies_can_read_rows가 기본적으로 활성화되어 있기 때문입니다. 따라서 어떤 조건도 적용되지 않는 사용자는 모든 행을 볼 수 있으며, 기본적으로 비활성화되어 있는 access_control_improvements.throw_on_unmatched_row_policies를 활성화하면 테이블에 조건이 존재하지만 그중 어느 것도 적용되지 않는 경우 대신 예외가 발생합니다. 예를 들어, 다음과 같은 정책이 있습니다:
사용자 peter가 b=1 AND c=2를 모두 만족하는 행만 볼 수 있도록 설정합니다. 데이터베이스 정책은 테이블 정책과 결합됩니다. 예를 들어, 다음과 같은 정책이 있습니다:
사용자 peter는 b=1 AND c=2를 모두 만족할 때만 table1의 행을 볼 수 있으며, mydb의 다른 모든 테이블에는 해당 사용자에게 b=1 정책만 적용됩니다.

다른 테이블에서 데이터를 읽는 테이블

row policy는 데이터를 실제로 읽는 지점에서 행을 필터링합니다. Alias 테이블은 대상 테이블의 행을 자신의 행처럼 반환하므로, 별칭을 통해 읽을 때도 대상 테이블의 row policy가 적용됩니다. 이 정책은 별칭 자체의 정책과 논리적 AND로 결합됩니다. Merge 테이블에는 데이터를 읽어 오는 각 테이블의 정책이 적용됩니다. 다만 일치하는 테이블이 Distributed 테이블처럼 원격에서 데이터를 읽는 경우는 예외입니다. 이때는 정책이 해당 테이블의 읽기 지점이 아니라 그 상위에서 실행되므로 원격 서버가 정책 적용 전에 쿼리를 처리합니다. 따라서 정책에 사용된 컬럼을 선택하지 않고 집계하면 쿼리가 실패할 수 있습니다. 또한 원격 서버가 정책에 의해 숨겨질 행까지 포함해 ORDER BY ... LIMIT을 적용하면 정책에서 허용하는 것보다 적은 행이 반환될 수 있습니다. 이런 경우 각 원격 서버의 기반 로컬 테이블에 정책을 정의하세요. 이 동작이 다른 테이블에서 데이터를 읽는 모든 테이블에 적용되는 것은 아닙니다. Buffer 테이블과 materialized view는 각각 대상 테이블을 통해 읽더라도 해당 테이블의 row policy를 상속하지 않습니다. 정책은 대상 테이블의 스키마를 기준으로 작성되며, SQL SECURITY DEFINER가 지정된 뷰에서는 읽기를 실행하는 사용자와 다른 사용자를 기준으로 평가되기 때문입니다. 이 경우 사용자가 실제로 쿼리하는 테이블에 정책을 정의하세요.

분산 및 원격 기반 테이블

행 정책은 테이블 데이터가 실제로 읽히는 위치에서 행을 필터링합니다. 분산 테이블이나 이를 감싼 래퍼(예: 대상이 Distributed인 materialized view)처럼 읽기 작업을 원격 서버에 위임하는 테이블은 쿼리 텍스트만 원격 서버로 전송하므로, 원격 읽기에는 정책 필터를 적용할 수 없습니다. 필터가 적용되지 않은 채 누락되는 것을 방지하기 위해, 정책이 적용되는 사용자가 이러한 테이블에 실행하는 쿼리는 ILLEGAL_PREWHERE 오류와 함께 거부됩니다. 대신 각 원격 서버의 기반이 되는 로컬 테이블에 정책을 정의하십시오. 전송된 쿼리가 해당 테이블을 읽을 때 այնտեղ 정책이 적용됩니다:
이 기능은 기본값인 텍스트 형식으로 쿼리를 전송할 때 작동합니다. serialize_query_plan = 1을 사용하면 initiator가 이미 생성된 읽기 계획을 전송합니다. 이 계획을 실행하는 remote server는 자체 행 정책을 적용하지 않으므로, local_table을 사용하는 Distributed 테이블을 읽으면 필터링되지 않은 행이 반환됩니다. 행 정책을 반드시 적용해야 하는 사용자는 serialize_query_plan = 0을 유지하십시오. 자세한 내용은 issue #112891을 참조하십시오.

Join 테이블

Join 테이블은 JOIN 또는 joinGet이 있는 그대로 읽어 들이는, 미리 준비된 해시 테이블이므로 이 과정에서는 행을 필터링할 수 없습니다. 이러한 테이블에 정책(policy)이 설정되어 있으면(데이터베이스 전체에 적용되는 ON db.* 정책 포함) 테이블에 대한 일반 SELECT는 필터링됩니다. 그러나 정책이 적용되어 있는 동안에는 해당 테이블에 대한 JOIN 및 joinGet 쿼리가 ACCESS_DENIED 오류와 함께 실패합니다.

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