> ## Documentation Index
> Fetch the complete documentation index at: https://clickhouse.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

> 가상(what-if) 프로젝션에 대한 문서

# HYPOTHETICAL PROJECTION

가상 프로젝션(hypothetical projections)은 세션 범위의 가상 프로젝션으로, 실제로 빌드하거나 저장하지 않고도 `MergeTree` 엔진 계열 테이블에 ATTACH할 수 있습니다. 이러한 프로젝션은 현재 세션 안에서만 존재하며 [`EXPLAIN WHATIF`](/docs/ko/reference/statements/explain#explain-whatif)로 조회할 수 있습니다.

`EXPLAIN WHATIF`는 아직 가상 프로젝션의 이점을 추정하지 못하며, 각 프로젝션을 `status: not_applicable`로 보고합니다. 현재로서는 프로젝션을 머티리얼라이즈하지 않고 해당 테이블을 기준으로 정의를 검증하거나, [`system.hypothetical_projections`](/docs/ko/reference/system-tables/hypothetical_projections)를 읽는 도구를 사용할 때 유용합니다.

## CREATE HYPOTHETICAL PROJECTION

```sql theme={null}
CREATE HYPOTHETICAL PROJECTION [IF NOT EXISTS] name
    ON [db.]table_name (SELECT <columns> [WHERE ...] [GROUP BY ...] [ORDER BY ...]) [WITH SETTINGS (...)]

CREATE HYPOTHETICAL PROJECTION [IF NOT EXISTS] name
    ON [db.]table_name INDEX <expression> TYPE <projection_index_type> [WITH SETTINGS (...)]
```

구문은 `ALTER TABLE ... ADD PROJECTION`과 동일하며, 정의 역시 완전히 같은 방식으로 검사됩니다. 따라서 여기서 거부된 프로젝션은 실제로도 구체화될 수 없습니다. 아무것도 생성되거나 기록되지 않고, 설명만 현재 세션에 저장됩니다.

* `name` — 프로젝션 이름입니다. 해당 세션 내에서 `(database, table)` 단위로 고유해야 하며, 테이블에 존재하는 실제 프로젝션과 이름이 겹쳐서는 안 됩니다.
* 본문은 실제 프로젝션과 동일한 형태를 허용합니다. 즉, `ORDER BY`를 사용하는 재정렬 프로젝션, `GROUP BY`를 사용하는 집계 프로젝션, `WHERE`를 사용하는 필터링 프로젝션, 또는 프로젝션 인덱스 형태인 `INDEX <expression> TYPE <projection_index_type>`을 사용할 수 있습니다.
* `WITH SETTINGS (...)`도 허용되며 그대로 보존됩니다. 해당 설정은 `system.hypothetical_projections`에서 확인할 수 있습니다.

대상 테이블은 `Atomic` 데이터베이스에 있는 `MergeTree` 엔진 계열 테이블이어야 합니다(즉, UUID가 있어야 합니다). 세션 저장소가 테이블 UUID를 키로 항목을 저장하기 때문입니다. 실제 `ADD PROJECTION`에 적용되는 제약도 여기에 그대로 적용됩니다. 즉, `UNIQUE KEY`가 있는 테이블, `deduplicate_merge_projection_mode = throw` 상태에서 `Ordinary`가 아닌 머지 모드, 구 문법 `MergeTree`, 변경 불가능한 디스크는 거부됩니다.

**예시**

```sql theme={null}
CREATE HYPOTHETICAL PROJECTION p_by_b ON t (SELECT a, b ORDER BY b);
CREATE HYPOTHETICAL PROJECTION p_idx ON t INDEX b TYPE basic;
```

## DROP HYPOTHETICAL PROJECTION

```sql theme={null}
DROP HYPOTHETICAL PROJECTION [IF EXISTS] name ON [db.]table_name
```

현재 세션에서 가상 프로젝션을 제거합니다.

## DROP ALL HYPOTHETICAL PROJECTIONS

```sql theme={null}
DROP ALL HYPOTHETICAL PROJECTIONS
```

현재 세션에 정의된 모든 가상 프로젝션을 테이블에 관계없이 삭제합니다. 가상 인덱스는 그대로 유지되며, `DROP ALL HYPOTHETICAL INDEXES`는 이와 반대로 동작합니다.

## 범위와 수명

* 가상 프로젝션은 **현재 세션**에만 존재합니다. 다른 세션에서는 보이지 않으며, 세션이 종료되면 사라집니다.
* 가상 프로젝션을 정의하거나 삭제해도 실제 프로젝션이 생성되지 않으며, 해당 테이블에 대한 일반 쿼리에도 전혀 영향을 주지 않습니다.
* 현재 세션의 가상 프로젝션은 [`system.hypothetical_projections`](/docs/ko/reference/system-tables/hypothetical_projections)에서 확인할 수 있습니다.

## 필요한 privilege

`CREATE HYPOTHETICAL PROJECTION`은 정의가 테이블의 컬럼과 맞는지 검사하기 때문에, 테이블에 대한 `ALTER ADD PROJECTION` privilege가 필요합니다. 이는 실제 `ALTER TABLE ... ADD PROJECTION`에 필요한 privilege와 동일합니다. 테이블 데이터를 읽지는 않으므로 아직 프로젝션 컬럼에 대한 `SELECT`는 필요하지 않습니다. 다만 `EXPLAIN WHATIF`가 프로젝션 추정을 수행하게 되면 해당 컬럼을 읽으므로, [`CREATE HYPOTHETICAL INDEX`](/docs/ko/reference/statements/hypothetical-index#required-privileges)에서 이미 그러한 것처럼 그때는 컬럼 수준의 `SELECT`가 필요합니다.

`DROP HYPOTHETICAL PROJECTION`에도 동일한 privilege가 필요합니다. 삭제 구문에 테이블 이름을 지정하는 것만으로 해당 테이블의 존재 여부나 적용 가능 여부가 드러나지 않도록 하기 위함입니다. `DROP ALL HYPOTHETICAL PROJECTIONS`는 테이블 이름을 지정하지 않으므로 privilege가 필요하지 않습니다.

## 관련 항목

* [`CREATE HYPOTHETICAL INDEX`](/docs/ko/reference/statements/hypothetical-index)
* [`EXPLAIN WHATIF`](/docs/ko/reference/statements/explain#explain-whatif)
* [`system.hypothetical_projections`](/docs/ko/reference/system-tables/hypothetical_projections)
* [프로젝션](/docs/ko/reference/engines/table-engines/mergetree-family/mergetree#projections)
