Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

GitHub

This documentation is part of the "Projects with Books" initiative at zenOSmosis.

The source code for this project is available on GitHub.

Plan Structures

Relevant source files

Purpose and Scope

Plan structures are strongly-typed representations of SQL statements that bridge the SQL parsing layer and the execution layer. Defined in the llkv-plan crate, these structures capture the logical intent of SQL operations without retaining parser-specific AST details. The planner translates sqlparser ASTs into plan instances, which the runtime then dispatches to execution engines.

This page documents the structure and organization of plan types. For information about how correlated subqueries and scalar subqueries are represented and tracked, see Subquery and Correlation Handling.

Sources: llkv-plan/src/plans.rs:1-10 llkv-plan/README.md:10-16

Plan Type Hierarchy

LLKV organizes plan structures into three primary categories based on their SQL statement class:

Diagram: Plan Type Organization

graph TB
    Plans["Plan Structures\n(llkv-plan)"]
DDL["DDL Plans\nSchema Operations"]
DML["DML Plans\nData Modifications"]
Query["Query Plans\nData Retrieval"]
Plans --> DDL
 
   Plans --> DML
 
   Plans --> Query
    
 
   DDL --> CreateTablePlan
 
   DDL --> DropTablePlan
 
   DDL --> CreateViewPlan
 
   DDL --> DropViewPlan
 
   DDL --> CreateIndexPlan
 
   DDL --> DropIndexPlan
 
   DDL --> ReindexPlan
 
   DDL --> AlterTablePlan
 
   DDL --> RenameTablePlan
    
 
   DML --> InsertPlan
 
   DML --> UpdatePlan
 
   DML --> DeletePlan
 
   DML --> TruncatePlan
    
 
   Query --> SelectPlan
 
   Query --> CompoundSelectPlan
    
 
   SelectPlan --> TableRef
 
   SelectPlan --> JoinMetadata
 
   SelectPlan --> SelectProjection
 
   SelectPlan --> SelectFilter
 
   SelectPlan --> AggregateExpr
 
   SelectPlan --> OrderByPlan

Plans are consumed by llkv-runtime for execution orchestration and by llkv-executor for query evaluation. Each plan type encodes the necessary metadata for its corresponding operation without requiring re-parsing or runtime AST traversal.

Sources: llkv-plan/src/plans.rs:163-358 llkv-plan/src/plans.rs:620-703 llkv-plan/src/plans.rs:794-1023

SelectPlan Structure

SelectPlan represents SELECT queries and is the most complex plan type. It aggregates multiple sub-components to describe table references, join relationships, projections, filters, aggregates, and ordering.

Diagram: SelectPlan Component Structure

graph TB
    SelectPlan["SelectPlan\nllkv-plan/src/plans.rs:801"]
subgraph "Table Sources"
        Tables["tables: Vec<TableRef>"]
TableRef["TableRef\nschema, table, alias"]
end
    
    subgraph "Join Specification"
        Joins["joins: Vec<JoinMetadata>"]
JoinMetadata["JoinMetadata\nleft_table_index\njoin_type\non_condition"]
JoinPlan["JoinPlan\nInner/Left/Right/Full"]
end
    
    subgraph "Projections"
        Projections["projections:\nVec<SelectProjection>"]
AllColumns["AllColumns"]
AllColumnsExcept["AllColumnsExcept"]
Column["Column\nname, alias"]
Computed["Computed\nexpr, alias"]
end
    
    subgraph "Filtering"
        Filter["filter: Option<SelectFilter>"]
SelectFilter["SelectFilter\npredicate\nsubqueries"]
FilterSubquery["FilterSubquery\nid, plan,\ncorrelated_columns"]
end
    
    subgraph "Aggregation"
        Aggregates["aggregates:\nVec<AggregateExpr>"]
GroupBy["group_by: Vec<String>"]
Having["having:\nOption<Expr>"]
end
    
    subgraph "Ordering & Modifiers"
        OrderBy["order_by:\nVec<OrderByPlan>"]
Distinct["distinct: bool"]
end
    
    subgraph "Compound Operations"
        Compound["compound:\nOption<CompoundSelectPlan>"]
CompoundOps["Union/Intersect/Except\nDistinct/All"]
end
    
 
   SelectPlan --> Tables
 
   SelectPlan --> Joins
 
   SelectPlan --> Projections
 
   SelectPlan --> Filter
 
   SelectPlan --> Aggregates
 
   SelectPlan --> OrderBy
 
   SelectPlan --> Compound
    
 
   Tables --> TableRef
 
   Joins --> JoinMetadata
 
   JoinMetadata --> JoinPlan
 
   Projections --> AllColumns
 
   Projections --> AllColumnsExcept
 
   Projections --> Column
 
   Projections --> Computed
 
   Filter --> SelectFilter
 
   SelectFilter --> FilterSubquery
 
   Aggregates --> GroupBy
 
   Aggregates --> Having
 
   Compound --> CompoundOps

Sources: llkv-plan/src/plans.rs:794-944

TableRef - Table References

TableRef represents a table source in the FROM clause, with optional aliasing:

FieldTypeDescription
schemaStringSchema/namespace identifier (empty for default)
tableStringTable name
aliasOption<String>Optional alias for qualified name resolution

The display_name() method returns the alias if present, otherwise the qualified name. This enables consistent column name resolution during expression translation.

Sources: llkv-plan/src/plans.rs:708-752

JoinMetadata - Join Specification

JoinMetadata describes how adjacent tables in the tables vector are connected. Each entry links tables[left_table_index] with tables[left_table_index + 1]:

FieldTypeDescription
left_table_indexusizeIndex into SelectPlan.tables
join_typeJoinPlanInner, Left, Right, or Full
on_conditionOption<Expr<String>>Optional ON clause predicate

The JoinPlan enum mirrors llkv_join::JoinType but exists in the plan layer to avoid circular dependencies.

Sources: llkv-plan/src/plans.rs:758-792

SelectProjection - Projection Variants

SelectProjection specifies which columns appear in the result set:

VariantFieldsDescription
AllColumns-SELECT * (all columns from all tables)
AllColumnsExceptexclude: Vec<String>SELECT * EXCEPT (col1, col2, ...)
Columnname: String
alias: Option<String>Named column with optional alias
Computedexpr: ScalarExpr<String>
alias: StringComputed expression (e.g., col1 + col2 AS sum)

The executor translates these into ScanProjection instances that specify which columns to fetch from storage.

Sources: llkv-plan/src/plans.rs:998-1013

AggregateExpr - Aggregate Functions

AggregateExpr describes aggregate function calls in SELECT or HAVING clauses:

Diagram: AggregateExpr Variants

graph LR
    AggregateExpr["AggregateExpr"]
CountStar["CountStar\nalias, distinct"]
Column["Column\ncolumn, alias,\nfunction, distinct"]
Functions["AggregateFunction"]
Count["Count"]
SumInt64["SumInt64"]
TotalInt64["TotalInt64"]
MinInt64["MinInt64"]
MaxInt64["MaxInt64"]
CountNulls["CountNulls"]
GroupConcat["GroupConcat"]
AggregateExpr --> CountStar
 
   AggregateExpr --> Column
 
   Column --> Functions
 
   Functions --> Count
 
   Functions --> SumInt64
 
   Functions --> TotalInt64
 
   Functions --> MinInt64
 
   Functions --> MaxInt64
 
   Functions --> CountNulls
 
   Functions --> GroupConcat

The executor delegates to llkv-aggregate for accumulator-based evaluation.

Sources: llkv-plan/src/plans.rs:1028-1120

OrderByPlan - Sort Specification

OrderByPlan defines ORDER BY clause semantics:

FieldTypeDescription
targetOrderTargetColumn name, projection index, or All
sort_typeOrderSortTypeNative or CastTextToInteger
ascendingboolSort direction (ASC/DESC)
nulls_firstboolNULL placement (NULLS FIRST/LAST)

OrderTarget variants:

  • Column(String) - Sort by named column
  • Index(usize) - Sort by projection position (1-based in SQL)
  • All - Specialized SQLite behavior for sorting all columns

Sources: llkv-plan/src/plans.rs:1195-1217

CompoundSelectPlan - Set Operations

CompoundSelectPlan represents UNION, INTERSECT, and EXCEPT operations:

FieldTypeDescription
initialBox<SelectPlan>First SELECT in the compound
operationsVec<CompoundSelectComponent>Subsequent set operations

Each CompoundSelectComponent contains:

  • operator: CompoundOperator (Union, Intersect, Except)
  • quantifier: CompoundQuantifier (Distinct, All)
  • plan: SelectPlan for the right-hand side

The executor processes these sequentially, maintaining distinct caches for DISTINCT quantifiers.

Sources: llkv-plan/src/plans.rs:946-996

InsertPlan Structure

InsertPlan encapsulates data insertion operations with conflict resolution strategies:

FieldTypeDescription
tableStringTarget table name
columnsVec<String>Column names (empty means all columns)
sourceInsertSourceData source (rows, batches, or SELECT)
on_conflictInsertConflictActionConflict resolution strategy

InsertSource Variants

VariantDescription
Rows(Vec<Vec<PlanValue>>)Explicit value rows from INSERT VALUES
Batches(Vec<RecordBatch>)Pre-materialized Arrow batches
Select { plan: Box<SelectPlan> }INSERT INTO ... SELECT ...

InsertConflictAction Variants

SQLite-compatible conflict resolution actions:

VariantBehavior
NoneStandard behavior - fail on constraint violation
ReplaceUPDATE existing row on conflict (INSERT OR REPLACE)
IgnoreSkip conflicting rows (INSERT OR IGNORE)
AbortAbort transaction on conflict
FailFail statement without rollback
RollbackRollback entire transaction

Sources: llkv-plan/src/plans.rs:620-655

UpdatePlan and DeletePlan

UpdatePlan

UpdatePlan specifies row updates with optional filtering:

FieldTypeDescription
tableStringTarget table name
assignmentsVec<ColumnAssignment>Column updates
filterOption<Expr<String>>WHERE clause predicate

Each ColumnAssignment contains:

  • column: Target column name
  • value: AssignmentValue (literal or expression)

AssignmentValue variants:

  • Literal(PlanValue) - Static value (e.g., SET col = 42)
  • Expression(ScalarExpr<String>) - Computed value (e.g., SET col = col + 1)

Sources: llkv-plan/src/plans.rs:661-682

DeletePlan

DeletePlan specifies row deletions:

FieldTypeDescription
tableStringTarget table name
filterOption<Expr<String>>WHERE clause predicate

A missing filter indicates DELETE FROM table (deletes all rows).

Sources: llkv-plan/src/plans.rs:687-692

TruncatePlan

TruncatePlan represents TRUNCATE TABLE (removes all rows, resets sequences):

FieldTypeDescription
tableStringTarget table name

Sources: llkv-plan/src/plans.rs:698-702

DDL Plan Structures

CreateTablePlan

CreateTablePlan defines table creation with schema, constraints, and data sources:

FieldTypeDescription
nameStringTable name
if_not_existsboolSkip if table exists
or_replaceboolReplace existing table
columnsVec<PlanColumnSpec>Column definitions
sourceOption<CreateTableSource>Optional CREATE TABLE AS data
namespaceOption<String>Storage namespace (e.g., "temp")
foreign_keysVec<ForeignKeySpec>Foreign key constraints
multi_column_uniquesVec<MultiColumnUniqueSpec>Multi-column UNIQUE constraints

Sources: llkv-plan/src/plans.rs:176-203

PlanColumnSpec

PlanColumnSpec describes individual column metadata:

FieldTypeDescription
nameStringColumn name
data_typeDataTypeArrow data type
nullableboolNULL allowed
primary_keyboolPRIMARY KEY constraint
uniqueboolUNIQUE constraint
check_exprOption<String>CHECK constraint SQL expression

The IntoPlanColumnSpec trait enables ergonomic column specification using tuples like ("col_name", DataType::Int64, NotNull).

Sources: llkv-plan/src/plans.rs:499-605

CreateIndexPlan

CreateIndexPlan specifies index creation:

FieldTypeDescription
nameOption<String>Index name (auto-generated if None)
tableStringTarget table
uniqueboolUNIQUE index constraint
if_not_existsboolSkip if index exists
columnsVec<IndexColumnPlan>Indexed columns with sort order

Each IndexColumnPlan specifies:

  • name: Column name
  • ascending: Sort direction (ASC/DESC)
  • nulls_first: NULL placement

Sources: llkv-plan/src/plans.rs:433-497

AlterTablePlan

AlterTablePlan represents ALTER TABLE operations:

FieldTypeDescription
table_nameStringTarget table
if_existsboolSkip if table missing
operationAlterTableOperationSpecific operation

AlterTableOperation variants:

VariantFieldsDescription
RenameColumnold_column_name: String
new_column_name: StringRENAME COLUMN
SetColumnDataTypecolumn_name: String
new_data_type: StringALTER COLUMN SET DATA TYPE
DropColumncolumn_name: String
if_exists: bool
cascade: boolDROP COLUMN

Sources: llkv-plan/src/plans.rs:364-406

Additional DDL Plans

Plan TypePurposeKey Fields
DropTablePlanDROP TABLEname, if_exists
CreateViewPlanCREATE VIEWname, view_definition, select_plan
DropViewPlanDROP VIEWname, if_exists
RenameTablePlanRENAME TABLEcurrent_name, new_name, if_exists
DropIndexPlanDROP INDEXname, canonical_name, if_exists
ReindexPlanREINDEXname, canonical_name

Sources: llkv-plan/src/plans.rs:209-358

PlanValue - Value Representation

PlanValue provides a type-safe representation of literal values in plans, bridging SQL literals and Arrow arrays:

VariantDescription
NullSQL NULL
Integer(i64)Integer value (booleans stored as 0/1)
Float(f64)Floating-point value
Decimal(DecimalValue)Fixed-precision decimal
String(String)Text value
Date32(i32)Date (days since epoch)
Struct(FxHashMap<String, PlanValue>)Nested struct value
Interval(IntervalValue)Interval (months, days, nanos)

PlanValue implements From<T> for common types (i64, f64, String, bool) for ergonomic plan construction. The plan_value_from_literal() function converts llkv_expr::Literal to PlanValue, and plan_value_from_array() extracts values from Arrow arrays during INSERT SELECT operations.

Sources: llkv-plan/src/plans.rs:73-161 llkv-plan/src/plans.rs:1122-1189

Plan Translation Flow

Diagram: Plan Translation and Execution Flow

Plans serve as the interface contract between the SQL layer (llkv-sql) and the execution layer (llkv-runtime, llkv-executor). The translation layer in llkv-sql converts sqlparser AST nodes into strongly-typed plan structures, which the runtime validates and dispatches to appropriate executors.

Sources: llkv-plan/README.md:13-33 llkv-executor/README.md:12-31

Plan Construction Patterns

Builder Pattern for SelectPlan

SelectPlan uses fluent builder methods for incremental construction:

Sources: llkv-plan/src/plans.rs:827-943

Tuple-Based Column Specs

PlanColumnSpec implements IntoPlanColumnSpec for tuples, enabling concise table definitions:

Sources: llkv-plan/src/plans.rs:548-605

Integration with Expression System

Plans reference expressions from llkv-expr using parameterized types:

  • Expr<String>: Boolean predicates with column names (WHERE, HAVING, ON clauses)
  • ScalarExpr<String>: Scalar expressions with column names (projections, assignments)

The executor translates these to Expr<FieldId> and ScalarExpr<FieldId> after resolving column names against table schemas. For details on expression evaluation, see Expression AST and Expression Translation.

Sources: llkv-plan/src/plans.rs:28-34 llkv-plan/src/plans.rs:666-674