跳到主要内容

Goose 内部实现概览

本页简要介绍 Goose 引擎的内部实现。

Parser

Parser 会将查询字符串转换为以下语法节点:

Parser 不感知 catalog 或数据库其他状态。它不会因为表不存在而报错,也不会在此阶段解析任何列类型。它仅负责把查询字符串转换为指定语法节点集合。

ParsedExpression

ParsedExpression 表示 SQL 语句中的一个表达式,例如列引用、加法运算符或常量值。其具体类型决定了表达式语义,例如比较表达式会表示为 ComparisonExpression

CAST 这类显式类型节点外,ParsedExpression 在此阶段没有类型信息。表达式类型会在 Binder 阶段解析,而不是在 Parser 阶段。

TableRef

TableRef 表示任意表来源,可以是基表引用,也可以是 join、产表函数或子查询。

QueryNode

QueryNode 表示两类内容之一:1)SELECT 语句;2)集合运算(如 UNIONINTERSECTDIFFERENCE)。

SQL Statement

SQLStatement 表示一条完整 SQL 语句。其类型决定了语句类别(例如 StatementType::SELECT 表示 SELECT 语句)。若原始 SQL 字符串包含多条查询,则会被拆分为多个 SQLStatement。

Binder

Binder 会把所有节点转换为其 bound 版本。在该阶段会完成:

  • 通过 catalog 完成表与列解析
  • 完成类型解析
  • 抽取聚合/窗口函数

主要转换如下:

Logical Planner

Logical Planner 基于 bound statement 构建 LogicalOperator 节点。在这一阶段会生成真正的逻辑查询树。

Optimizer

逻辑查询树生成后,会依次运行优化器得到优化后的执行计划。主要包括:

  • Expression Rewriter:化简表达式并进行常量折叠
  • Filter Pushdown:将过滤条件下推并在等价集合上传播,同时剪枝静态可判空子树
  • Join Order Optimizer:使用动态规划重排 join 顺序(采用论文 Dynamic Programming Strikes Back 中的 DPccp
  • Common Sub Expressions:提取投影与过滤中的公共子表达式,避免重复执行
  • In Clause Rewriter:将大型静态 IN 子句重写为 MARK join 或 INNER join

Column Binding Resolver

Column Binding Resolver 会把逻辑层的 BoundColumnRefExpression(按表列引用)转换为 BoundReferenceExpression(按 DataChunk 内部索引引用),以便执行引擎处理。

Physical Plan Generator

Physical Plan Generator 会将逻辑算子树转换为 PhysicalOperator 树。

Execution

在执行阶段,物理算子被执行以产出查询结果。 Goose 使用基于 push 的向量化执行模型,其中 DataChunks 会在算子树中向下游推送。 更多信息可参考演讲 Push-Based Execution in Goose