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

假设投影是虚拟的、作用域限于会话的 PROJECTION，你可以将其附加到 `MergeTree` 家族表上，而无需实际构建或存储它们。它们仅存在于当前会话中，可通过 [`EXPLAIN WHATIF`](/docs/zh/reference/statements/explain#explain-whatif) 列出。

`EXPLAIN WHATIF` 目前还无法评估假设投影带来的收益——它会将每一个都报告为 `status: not_applicable`。目前定义它们的价值在于：无需物化即可针对表校验某个定义，以及供读取 [`system.hypothetical_projections`](/docs/zh/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 同样不可能被 materialized。此过程不会构建或写入任何内容——仅在当前会话中存储该描述。

* `name` — PROJECTION 名称；在本会话中必须在 `(database, table)` 范围内唯一，且不得与表上已有的真实 PROJECTION 重名。
* body 支持与真实 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 作为 entries 的键。真实 `ADD PROJECTION` 施加的各项限制在这里同样适用：带有 `UNIQUE KEY` 的表、在 `deduplicate_merge_projection_mode = throw` 下非 `Ordinary` 的 merging 模式、旧语法的 `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/zh/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/zh/reference/statements/hypothetical-index#required-privileges) 现已要求的那样。

`DROP HYPOTHETICAL PROJECTION` 需要相同的特权，从而确保在删除语句中指定某个表时，不会泄露该表是否存在或是否符合条件。`DROP ALL HYPOTHETICAL PROJECTIONS` 不指定任何表，因此无需任何特权。

## 另请参阅

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