DataFusion BinaryExpr:从 Logical Expr 到 Physical Expr 的“落地点” Deep Dive
这篇文档精准回答了 DataFusion 中 BinaryExpr 的关键问题:logical 形态到底在何时何地转换为 physical 形态。问题聚焦文章不泛谈优化理论,而是聚焦单点追踪:Expr::BinaryExpr 的转换落点。目标是建立“计划输出可见现象”与“源码调用链”之间的一一映射。给出固定版本与可复现…
DataFusion BinaryExpr:从 Logical Expr 到 Physical Expr 的“落地点” Deep Dive 这篇文档回答一个非常具体的问题:BinaryExpr 这个 physical 表示,是在什么时候、在哪里(具体代码位置)从 logical 转过来的? 并用一个可运行的 SQL 示例,把“看到的计划(plan)”和“源码里发生的转换”一一对应起来。 Code Version: DataFusion 002136e4bac97ba143c2500273a87f92389bd970(本地 datafusion-cli 输出为 v50.1.0)1. Introduction(问题与范围) 在 DataFusion 中:Logical 表达式(datafusion_expr::Expr)描述“要算什么”(语义 / 逻辑层)。Physical 表达式(datafusion_physical_expr::PhysicalExpr trait object)描述“怎么在 Arrow RecordBatch 上算”(执行 / 物理层)。 BinaryExpr 同名但分属两个层次:logical 有一个 BinaryExpr,physical 也有一个 BinaryExpr。要定位它们“何时发生转换”,关键是找到物理计划(ExecutionPlan)构建时对表达式做的那一步 “logical → physical”。 ⏭️ 如果你只想要结论:看 §4(转换点与调用链)和 §8(Code Index)。2. Background / Prerequisites(概念前置)2.1 两个 BinaryExpr 的“长相” Logical:datafusion_expr::BinaryExpr(字段是 Box<Expr>)定义位置:datafusion/expr/src/expr.rs:815结构大意:{ left: Box<Expr>, op: Operator, right: Box<Expr> } Physical:datafusion_physical_expr::expressions::BinaryExpr(字段是 Arc<dyn PhysicalExpr>)定义位置:datafusion/physical-expr/src/expressions/binary.rs:57结构大意:{ left: Arc<dyn PhysicalExpr>, op: Operator, right: Arc<dyn PhysicalExpr>, fail_on_overflow: bool } 两者最大的差别是:logical 递归地持有 Expr,physical 递归地持有 PhysicalExpr trait object,并绑定了执行期所需的行为(例如 evaluation / Arrow kernels / 溢出策略等)。2.2 “logical → physical” 发生在什么阶段? DataFusion 的典型流水线可以粗略理解为:flowchart LR A[SQL] -->|parse+plan| B[LogicalPlan + Expr] B -->|optimizer| C[Optimized LogicalPlan] C -->|physical planner| D[ExecutionPlan + PhysicalExpr] style A fill:#e1f5fe,stroke:#01579b style B fill:#fff3e0,stroke:#e65100 style C fill:#fff3e0,stroke:#e65100 style D fill:#e8f5e9,stroke:#2e7d32 本文的核心关注点在 C → D:physical planner 在构建 ExecutionPlan 的同时,会把各节点(例如 Filter / Projection)里面的 logical Expr 转成可执行的 physical PhysicalExpr。3. 用一个 SQL 例子把“计划”跑出来 这个 SQL 同时包含三种典型的二元表达式:投影里的算术:a + b过滤条件里的比较:a > 1、b < 4过滤条件里的逻辑 AND:(a > 1) AND (b < 4)SELECT a + b AS s FROM (VALUES (1,2),(3,4)) AS t(a,b) WHERE a > 1 AND b < 4; 3.1 用 datafusion-cli 观察 logical / physical plan 在仓库根目录运行(为了方便脚本化,这里用 --format nd-jso…
正在初始化 WebAssembly 引擎…
首次编译原生模块可能需要数秒
就绪后,页面交互将以接近原生的速度运行