Catalyst 全阶段代码生成的入口是 CollapseCodegenStages 规则,当设置了支持全阶段代码生成的功能时(默认将 spark.sql.codegen.wholeStage 设置为 true,CollapseCodegenStages 规则会将生成的物理计划中支持代码生成的节点生成的代码整合成一段,因此称为全阶段代码生成 WholeStageCodegen。

本例中查询生成的物理计划包括 FileSourceScanExec、FilterExec 和 ProjectExec 3 个节点。这 3 个节点都支持代码生成,因此 CollapseCodegenStages 规则会在 3 个物理算子节点上添加 WholeStageCodegenExec 节点,将这 3 个节点生成的代码整合在一起。此外,加入 WholeStageCodegenExec 物理节点后,物理计划打印输出时不会打印该节点本身,其所囊括的所有子节点在打印输出字符串时,都会统一加入特定的 * 字符作为前缀,用来区别不支持代码生成的物理计划节点。

对于物理算子树,CollapseCodegenStages 规则会根据节点是否支持代码生成采用不同的处理方式。如图所示,在遍历物理算子树时,当碰到不支持代码生成的节点时,
会在其上插入一个名为 InputAdapter 的物理节点对其进行封装。

在某种程度上,不支持代码生成的节点可以看作是分隔点,将整个物理计划拆分成多个代码段。InputAdapter 节点可以看作是对应 WholeStageCodegenExec 所包含子树的叶子节点,起到 InternalRow 的数据输入作用。每个 WholeStageCodegenExec 节点负责整合一个代码段。

如图所示插入了 3 个 WholeStageCodegenExec 节点。