Query Planner Module
src/plan/ bridges parsed SQL and executable operators. It converts the AST into a
logical plan, applies rewrites (via the optimizer), and finally emits a physical plan
(PhysicalPlan) that the Volcano engine can run.
Responsibilities
- LogicalPlanner – walks the AST, binds table/column names using
PlannerContext, performs type checking, and builds aLogicalPlantree. - PlannerContext – exposes catalog lookups plus scope information for CTEs, subqueries, and aliases.
- PhysicalPlanner – lowers an optimized
LogicalPlaninto a tree of Volcano operators.
Directory Layout
| Path | Description | Key Types |
|---|---|---|
logical_plan.rs | Logical algebra nodes. | LogicalPlan, LogicalExpr, JoinType |
logical_planner.rs | AST → logical transformation. | LogicalPlanner |
physical_plan.rs | PhysicalPlan enum definition. | PhysicalPlan, Physical* structs |
physical_planner.rs | Logical → physical lowering. | PhysicalPlanner |
planner_context.rs | Catalog/scope abstraction. | PlannerContext |
Workflow
- Name binding –
LogicalPlannerresolves table + column references, createsTableReferences, and validates schemas via the catalog. - Logical tree – each SQL clause becomes a logical node (FROM →
SeqScan, WHERE →Filter, GROUP BY →Aggregate, etc.). - Physical selection –
PhysicalPlannerpicks concrete algorithms (sequential scan, index scan, nested-loop join, sort, limit …). Because every physical node implementsVolcanoExecutor, the execution engine can pull tuples immediately.
Interactions
- SQL front-end – provides the AST; helper traits (
NormalizedIdent, etc.) keep name resolution consistent. - Catalog –
PlannerContextrelies on it to confirm table/index existence and fetch schemas. - Optimizer – operates purely on
LogicalPlan; the planner must emit clean, traversable trees so rules can fire. - Execution – physical nodes carry
TableReference,SchemaRef, and hints that the execution engine passes to the storage layer.
Teaching Ideas
- Implement a new logical operator (e.g.,
LogicalDistinct) and add the corresponding physical operator to trace the full lifecycle. - Experiment with early projection inside the logical plan and observe its impact on downstream operators.
- Use
pretty_format_logical_plan/physical_plandumps to visualise rewrites before and after optimizer passes.
Further reading: The Lifecycle of a Query