1use 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}