> ## 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）projection に関するドキュメント

# HYPOTHETICAL PROJECTION

仮説的なプロジェクション (hypothetical projections) は、実際にビルドや保存を行うことなく `MergeTree` ファミリーのテーブルにアタッチできる、仮想的でセッションスコープのプロジェクションです。現在のセッション内にのみ存在し、[`EXPLAIN WHATIF`](/docs/ja/reference/statements/explain#explain-whatif) で一覧表示されます。

`EXPLAIN WHATIF` は、仮説的なプロジェクションの効果をまだ見積もりません。いずれも `status: not_applicable` として報告されます。現時点で仮説的なプロジェクションを定義する利点は、マテリアライズせずに定義内容をテーブルに対して検証できること、および [`system.hypothetical_projections`](/docs/ja/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` と同じで、定義の検証もまったく同じように行われます。そのため、ここで拒否された projection は実際にマテリアライズすることもできません。何も構築されず、書き込まれもしません。保存されるのは定義内容のみで、しかも現在のセッション内に限られます。

* `name` — projection 名。このセッションの `(database, table)` 内で一意である必要があり、テーブル上の実在の projection と衝突してはなりません。
* ボディは実在の projection と同じ形式を受け付けます。すなわち、`ORDER BY` による並べ替え projection、`GROUP BY` による集約 projection、`WHERE` によるフィルタ付き projection、または projection インデックス形式の `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` はその逆の動作となります。

## スコープとライフタイム

* 仮説的なプロジェクションは**現在のセッション**内にのみ存在し、他のセッションからは参照できず、セッション終了時に破棄されます。
* 定義や削除を行っても projection は構築されず、そのテーブルに対する通常のクエリに影響することもありません。
* 現在のセッションの仮説的なプロジェクションは [`system.hypothetical_projections`](/docs/ja/reference/system-tables/hypothetical_projections) で確認できます。

## 必要な権限

`CREATE HYPOTHETICAL PROJECTION` には、テーブルに対する `ALTER ADD PROJECTION` 権限が必要です。定義をテーブルのカラムと照合して検証するため、実際の `ALTER TABLE ... ADD PROJECTION` と同じ権限が求められます。テーブルのデータは読み取らないため、PROJECTION のカラムに対する `SELECT` 権限は現時点では不要です。ただし、`EXPLAIN WHATIF` が PROJECTION の見積もりを行うようになると、それらのカラムを読み取るため、その時点でカラムレベルの `SELECT` が必要になります。[`CREATE HYPOTHETICAL INDEX`](/docs/ja/reference/statements/hypothetical-index#required-privileges) では、すでにこの権限が必要です。

`DROP HYPOTHETICAL PROJECTION` にも同じ権限が必要です。これは、削除時にテーブル名を指定することで、そのテーブルが存在するか、対象となり得るかが判明してしまうことを防ぐためです。`DROP ALL HYPOTHETICAL PROJECTIONS` はテーブル名を指定しないため、権限は不要です。

## 関連項目

* [`CREATE HYPOTHETICAL INDEX`](/docs/ja/reference/statements/hypothetical-index)
* [`EXPLAIN WHATIF`](/docs/ja/reference/statements/explain#explain-whatif)
* [`system.hypothetical_projections`](/docs/ja/reference/system-tables/hypothetical_projections)
* [プロジェクション](/docs/ja/reference/engines/table-engines/mergetree-family/mergetree#projections)
