Skip to main content

hematite/query/
plan.rs

1//! Query plan structures and access-path descriptions.
2
3use crate::parser::ast::AggregateFunction;
4use crate::parser::ast::{
5    AlterStatement, CreateIndexStatement, CreateStatement, DeleteStatement, DropIndexStatement,
6    DropStatement, InsertStatement, SelectStatement, UpdateStatement,
7};
8
9use super::optimizer::SelectOptimizations;
10
11pub struct QueryPlan {
12    pub node: PlanNode,
13    pub program: ExecutionProgram,
14    pub estimated_cost: f64,
15    pub select_analysis: Option<SelectAnalysis>,
16    pub optimizations: Option<SelectOptimizations>,
17}
18
19impl std::fmt::Debug for QueryPlan {
20    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
21        f.debug_struct("QueryPlan")
22            .field("node", &self.node)
23            .field("estimated_cost", &self.estimated_cost)
24            .field("select_analysis", &self.select_analysis)
25            .field("optimizations", &self.optimizations)
26            .field("program", &self.program)
27            .finish()
28    }
29}
30
31#[derive(Debug, Clone)]
32pub enum ExecutionProgram {
33    Select {
34        statement: SelectStatement,
35        access_path: SelectAccessPath,
36    },
37    Insert {
38        statement: InsertStatement,
39    },
40    Update {
41        statement: UpdateStatement,
42        access_path: SelectAccessPath,
43    },
44    Delete {
45        statement: DeleteStatement,
46        access_path: SelectAccessPath,
47    },
48    Create {
49        statement: CreateStatement,
50    },
51    CreateIndex {
52        statement: CreateIndexStatement,
53    },
54    Alter {
55        statement: AlterStatement,
56    },
57    Drop {
58        statement: DropStatement,
59    },
60    DropIndex {
61        statement: DropIndexStatement,
62    },
63}
64
65#[derive(Debug, Clone)]
66pub enum PlanNode {
67    Select(SelectPlanNode),
68    Insert(InsertPlanNode),
69    Update(UpdatePlanNode),
70    Delete(DeletePlanNode),
71    Create(CreatePlanNode),
72    CreateIndex(CreateIndexPlanNode),
73    Alter(AlterPlanNode),
74    Drop(DropPlanNode),
75    DropIndex(DropIndexPlanNode),
76}
77
78#[derive(Debug, Clone)]
79pub struct SelectPlanNode {
80    pub table_name: String,
81    pub source_count: usize,
82    pub access_path: SelectAccessPath,
83    pub projection: SelectProjection,
84    pub distinct: bool,
85    pub has_filter: bool,
86    pub order_by_columns: Vec<String>,
87    pub limit: Option<usize>,
88    pub offset: Option<usize>,
89}
90
91#[derive(Debug, Clone, PartialEq, Eq)]
92pub enum SelectAccessPath {
93    FullTableScan,
94    JoinScan,
95    RowIdLookup,
96    PrimaryKeyLookup,
97    SecondaryIndexLookup(String),
98}
99
100#[derive(Debug, Clone, PartialEq, Eq)]
101pub enum SelectProjection {
102    Wildcard,
103    Columns(Vec<String>),
104    Expressions(usize),
105    CountAll,
106    Aggregate {
107        function: AggregateFunction,
108        column: String,
109    },
110}
111
112#[derive(Debug, Clone, PartialEq, Eq)]
113pub struct InsertPlanNode {
114    pub table_name: String,
115    pub row_count: usize,
116}
117
118#[derive(Debug, Clone, PartialEq, Eq)]
119pub struct UpdatePlanNode {
120    pub table_name: String,
121    pub assignment_count: usize,
122    pub has_filter: bool,
123    pub access_path: SelectAccessPath,
124}
125
126#[derive(Debug, Clone, PartialEq, Eq)]
127pub struct DeletePlanNode {
128    pub table_name: String,
129    pub has_filter: bool,
130    pub access_path: SelectAccessPath,
131}
132
133#[derive(Debug, Clone, PartialEq, Eq)]
134pub struct CreatePlanNode {
135    pub table_name: String,
136    pub column_count: usize,
137}
138
139#[derive(Debug, Clone, PartialEq, Eq)]
140pub struct DropPlanNode {
141    pub table_name: String,
142}
143
144#[derive(Debug, Clone, PartialEq, Eq)]
145pub struct AlterPlanNode {
146    pub table_name: String,
147}
148
149#[derive(Debug, Clone, PartialEq, Eq)]
150pub struct CreateIndexPlanNode {
151    pub table_name: String,
152    pub index_name: String,
153    pub column_count: usize,
154}
155
156#[derive(Debug, Clone, PartialEq, Eq)]
157pub struct DropIndexPlanNode {
158    pub table_name: String,
159    pub index_name: String,
160}
161
162#[derive(Debug, Clone)]
163pub struct SelectAnalysis {
164    pub table_name: String,
165    pub source_count: usize,
166    pub has_complex_source: bool,
167    pub table_id: crate::catalog::TableId,
168    pub rowid_lookup: Option<u64>,
169    pub estimated_rows: usize,
170    pub usable_indexes: Vec<IndexUsage>,
171    pub accessed_columns: Vec<ColumnAccess>,
172}
173
174#[derive(Debug, Clone)]
175pub struct IndexUsage {
176    pub column_id: crate::catalog::ColumnId,
177    pub index_type: IndexType,
178    pub index_name: Option<String>,
179    pub selectivity: f64,
180}
181
182#[derive(Debug, Clone)]
183pub enum IndexType {
184    PrimaryKey,
185    Secondary,
186}
187
188#[derive(Debug, Clone)]
189pub struct ColumnAccess {
190    pub column_id: crate::catalog::ColumnId,
191    pub access_type: ColumnAccessType,
192}
193
194#[derive(Debug, Clone)]
195pub enum ColumnAccessType {
196    Read,
197    Write,
198}