MergeTree 家族表上,而无需实际构建或存储它们。它们仅存在于当前会话中,可通过 EXPLAIN WHATIF 列出。
EXPLAIN WHATIF 目前还无法评估假设投影带来的收益——它会将每一个都报告为 status: not_applicable。目前定义它们的价值在于:无需物化即可针对表校验某个定义,以及供读取 system.hypothetical_projections 的工具使用。
CREATE HYPOTHETICAL PROJECTION
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 以及不可变磁盘均会被拒绝。
示例
DROP HYPOTHETICAL PROJECTION
DROP ALL HYPOTHETICAL PROJECTIONS
DROP ALL HYPOTHETICAL INDEXES 的作用则相反。
作用域与生命周期
- 假设投影仅存在于当前会话中——对其他会话不可见,并在会话结束时被丢弃。
- 定义或删除假设投影不会真正构建 PROJECTION,也绝不会影响针对该表的普通查询。
- 可通过
system.hypothetical_projections查看当前会话的假设投影。
所需特权
CREATE HYPOTHETICAL PROJECTION 需要该表上的 ALTER ADD PROJECTION 特权——与真实的 ALTER TABLE ... ADD PROJECTION 所需特权相同——因为它会根据表的列校验该定义。它不会读取任何表数据,因此暂时不需要 PROJECTION 所涉及列上的 SELECT 特权;当 EXPLAIN WHATIF 开始对 PROJECTION 进行估算时,就会读取这些列,届时便需要列级 SELECT 特权,正如 CREATE HYPOTHETICAL INDEX 现已要求的那样。
DROP HYPOTHETICAL PROJECTION 需要相同的特权,从而确保在删除语句中指定某个表时,不会泄露该表是否存在或是否符合条件。DROP ALL HYPOTHETICAL PROJECTIONS 不指定任何表,因此无需任何特权。