【Calcite 系列】深入理解 Calcite 的 AggregateValuesRule

AggregateValuesRule 处理的是 Aggregate 压在 Values 之上的极端小输入场景,尤其是空 Values 和"纯去重 aggregate"这两类情况。它不会试图通用执行所有聚合,而是专注做一些完全可以在优化阶段直接折叠的改写。本文结合源码实现,分析这条规则如何在空输入上直接构造聚合结果,以及它是怎样把 Aggregate(Values) 规约成去重后的 Values 的。

1. 规则要解决什么问题

有些查询在优化阶段就已经变成:

text 复制代码
Aggregate
  Values(...)

例如:

  • WHERE 1 = 0 之后的空输入;
  • IN (...) 常量列表展开后的 values;
  • 仅用 aggregate 去重的极小关系。

这时没必要等到执行期再跑真正的聚合算子。

2. 第一类场景:空 Values + 全局聚合

源码首先处理:

java 复制代码
aggregate.getGroupCount() == 0 && values.getTuples().isEmpty()

也就是 GROUP BY () 且输入为空。

这时它会直接按聚合函数种类构造结果字面量:

  • COUNT / SUM0 -> 0
  • MIN / MAX / SUM -> NULL

然后直接生成一个单行 Values 作为结果。

3. 为什么只支持这几类聚合

对于空输入,不同聚合函数的返回值语义并不统一。

源码只对以下几种做了明确支持:

  • COUNT
  • SUM0
  • MIN
  • MAX
  • SUM

其他未知聚合函数会直接退出,避免错误推断其空输入语义。

4. 第二类场景:Aggregate 只是做 DISTINCT

如果满足:

  1. Aggregate.isSimple(aggregate)
  2. aggCallList 为空;
  3. aggregate.getRowType().equals(values.getRowType())

说明这个 Aggregate 本质上只是对 Values 去重。

这时规则会直接:

java 复制代码
values.getTuples().stream().distinct()

把重复元组去掉,再生成一个新的 Values

5. 为什么要求 row type 相同

如果 aggregate 输出行类型和 values 输入行类型不一样,那么简单去重后直接返回 Values 可能会破坏 schema。

所以源码只在两者 row type 完全一致时,才把它规约成纯 Values

6. 这条规则为什么很有用

虽然它看起来只处理很小的 corner case,但这些场景在规则链里非常常见:

  • 常量折叠后产生空关系;
  • 子查询展开后变成 Values
  • IN 列表去重;
  • grand total on empty input。

如果不提前规约,后续规则和执行器都得带着这些"本可常量化"的节点继续走。

7. 代表性测试

RelOptRulesTest 中这条规则的直接测试非常集中:

  • testAggregateValuesRuleWithInRepeatingValues
  • testAggregateValuesRuleWithRepeatingValues
  • testAggregateValuesRuleWithAggregation
  • testAggregateValuesRuleWithSameRowType
  • testAggregateValuesRuleWithDifferentRowTypes
  • testEmptyAggregateEmptyKeyWithAggregateValuesRule

这些测试分别覆盖:

  • Values 去重;
  • 空输入上的聚合结果;
  • row type 相同/不同的区别;
  • grand total on empty input。

总结

AggregateValuesRule 是一条典型的"小输入折叠规则":

  1. Values + 全局聚合时,直接产出一行常量结果;
  2. 纯去重 Aggregate 时,直接把 Values 自身去重;
  3. 只在语义非常明确的场景下生效。

它的价值不在复杂度,而在于把一类完全可以在优化阶段完成的计算提前消掉。

相关推荐
玩美数据4 分钟前
2026全球出海市场研究TOP5:深度行业洞察与高效供应商网络塑造市场竞争力
大数据·人工智能
qq_543447826 分钟前
等保合规服务商哪家好?
大数据
2501_948106919 分钟前
计算机毕业设计之jsp物业管理系统
java·大数据·开发语言·汽车·课程设计
中科岩创11 分钟前
全栈本地化专属部署架构,服务智慧矿山信息化安全建设!
大数据·人工智能·物联网
TDengine (老段)18 分钟前
TDengine 索引使用指南 — 何时建、怎么建、怎么用
java·大数据·数据库·物联网·时序数据库·tdengine·涛思数据
ATA888827 分钟前
企业数据库账号安全的技术解决方案
数据库·安全
DB哥讲数据库28 分钟前
MySQL 8.4 安装教程:超详细图文讲解(附mysql安装包)
linux·数据库·mysql·centos
Databend31 分钟前
AST Visitor API 迁移,怎么证明 AI 没改坏 SQL 语义?
数据库·ai编程
TDengine (老段)34 分钟前
TDengine DDL 完整参考 — Database/STable/Table/Column/Tag
大数据·数据库·物联网·时序数据库·tdengine·涛思数据
xlxxy_35 分钟前
sap获取批次特性报表
java·linux·开发语言·前端·数据库·abap·mm