> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-trino-dialect.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> ROW POLICY 문서

# CREATE ROW POLICY

[행 정책](/ko/concepts/features/security/access-rights#row-policy-management), 즉 사용자가 테이블에서 읽을 수 있는 행을 결정하는 데 사용되는 필터를 생성합니다.

<Tip>
  행 정책은 읽기 전용 권한이 있는 사용자에게만 유효합니다. 사용자가 테이블을 수정하거나 테이블 간에 파티션을 복사할 수 있으면 행 정책의 제한이 무력화됩니다.
</Tip>

구문:

```sql theme={null}
-- 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`은 나열된 각 호스트 이름을 해당 단일 테이블(또는 `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 문을 실행하십시오.

<div id="multiple-names-and-tables">
  ## 여러 호스트 이름 및 테이블
</div>

유효한 예:

```sql theme={null}
-- 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;
```

유효하지 않음:

```sql theme={null}
-- 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
```

<div id="using-clause">
  ## USING 절
</div>

행을 필터링할 조건을 지정할 수 있습니다. 특정 행에 대해 이 조건의 계산 결과가 0이 아니면 사용자는 해당 행을 볼 수 있습니다.

<div id="to-clause">
  ## TO 절
</div>

`TO` 섹션에서는 이 정책을 적용할 사용자 및 역할 목록을 지정할 수 있습니다. 예를 들어 `CREATE ROW POLICY ... TO accountant, john@localhost`와 같습니다.

키워드 `ALL`은 현재 사용자를 포함한 모든 ClickHouse 사용자를 의미합니다. 키워드 `ALL EXCEPT`는 전체 사용자 목록에서 일부 사용자를 제외할 수 있도록 하며, 예를 들어 `CREATE ROW POLICY ... TO ALL EXCEPT accountant, john@localhost`와 같습니다.

<div id="as-clause">
  ## AS 절
</div>

동일한 사용자에게 동일한 테이블에 대해 한 번에 둘 이상의 정책을 활성화할 수 있습니다. 따라서 여러 정책의 조건을 결합할 방법이 필요합니다.

기본적으로 정책은 불리언 `OR` 연산자를 사용해 결합됩니다. 예를 들어, 다음과 같은 정책이 있습니다.

```sql theme={null}
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` 연산자를 사용해 결합됩니다.

다음은 일반식입니다:

```text theme={null}
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)
```

예를 들어, 다음과 같은 정책이 있습니다:

```sql theme={null}
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`를 모두 만족하는 행만 볼 수 있도록 설정합니다.

데이터베이스 정책은 테이블 정책과 결합됩니다.

예를 들어, 다음과 같은 정책이 있습니다:

```sql theme={null}
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` 정책만 적용됩니다.

<div id="distributed-and-remote-backed-tables">
  ## 분산 및 원격 기반 테이블
</div>

행 정책은 테이블 데이터가 실제로 읽히는 위치에서 행을 필터링합니다. [분산](/ko/reference/engines/table-engines/special/distributed) 테이블이나 이를 감싼 래퍼(예: 대상이 `Distributed`인 materialized view)처럼 읽기 작업을 원격 서버에 위임하는 테이블은 쿼리 텍스트만 원격 서버로 전송하므로, 원격 읽기에는 정책 필터를 적용할 수 없습니다. 필터가 적용되지 않은 채 누락되는 것을 방지하기 위해, 정책이 적용되는 사용자가 이러한 테이블에 실행하는 쿼리는 `ILLEGAL_PREWHERE` 오류와 함께 거부됩니다.

대신 각 원격 서버의 기반이 되는 로컬 테이블에 정책을 정의하십시오. 전송된 쿼리가 해당 테이블을 읽을 때 այնտեղ 정책이 적용됩니다:

```sql theme={null}
-- 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;
```

<Warning>
  이 기능은 기본값인 텍스트 형식으로 쿼리를 전송할 때 작동합니다. [`serialize_query_plan = 1`](/ko/reference/settings/session-settings/serialize#serialize_query_plan)을 사용하면 initiator가 이미 생성된 읽기 계획을 전송합니다. 이 계획을 실행하는 remote server는 자체 행 정책을 적용하지 않으므로, `local_table`을 사용하는 `Distributed` 테이블을 읽으면 필터링되지 않은 행이 반환됩니다. 행 정책을 반드시 적용해야 하는 사용자는 `serialize_query_plan = 0`을 유지하십시오. 자세한 내용은 [issue #112891](https://github.com/ClickHouse/ClickHouse/issues/112891)을 참조하십시오.
</Warning>

<div id="on-cluster-clause">
  ## ON CLUSTER 절
</div>

클러스터 전체에서 행 정책을 생성할 수 있습니다. [분산 DDL](/ko/reference/statements/distributed-ddl)을 참조하십시오. 또한 클러스터의 모든 서버에 있는 로컬 테이블에 정책을 생성하는 편리한 방법이기도 합니다.

<div id="examples">
  ## 예시
</div>

`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`
