1use crate::ast::{
2 expr::{Expression, Identifier, TableName},
3 statements::query::SelectStatement,
4};
5use core::range::Range;
6use oak_core::source::{SourceBuffer, ToSource};
7use std::sync::Arc;
8
9#[derive(Debug, Clone)]
11#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
12pub struct CreateStatement {
13 pub object_type: CreateObjectType,
15 pub name: Identifier,
17 pub if_not_exists: bool,
19 pub body: CreateBody,
21 #[serde(with = "oak_core::serde_range")]
23 pub span: Range<usize>,
24}
25
26#[derive(Debug, Clone)]
28#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
29pub enum CreateBody {
30 Table {
32 columns: Vec<ColumnDefinition>,
34 #[serde(with = "oak_core::serde_range")]
36 span: Range<usize>,
37 },
38 View {
40 query: Box<SelectStatement>,
42 #[serde(with = "oak_core::serde_range")]
44 span: Range<usize>,
45 },
46 Index {
48 table_name: TableName,
50 columns: Vec<Identifier>,
52 unique: bool,
54 #[serde(with = "oak_core::serde_range")]
56 span: Range<usize>,
57 },
58 Database {
60 #[serde(with = "oak_core::serde_range")]
62 span: Range<usize>,
63 },
64}
65
66impl ToSource for CreateStatement {
67 fn to_source(&self, buffer: &mut SourceBuffer) {
68 buffer.push("CREATE");
69 if let CreateBody::Index { unique: true, .. } = &self.body {
70 buffer.push("UNIQUE");
71 }
72 self.object_type.to_source(buffer);
73 if self.if_not_exists {
74 buffer.push("IF");
75 buffer.push("NOT");
76 buffer.push("EXISTS");
77 }
78 self.name.to_source(buffer);
79 match &self.body {
80 CreateBody::Table { columns, .. } => {
81 if !columns.is_empty() {
82 buffer.push("(");
83 for (i, col) in columns.iter().enumerate() {
84 if i > 0 {
85 buffer.push(",");
86 }
87 col.to_source(buffer);
88 }
89 buffer.push(")");
90 }
91 }
92 CreateBody::View { query, .. } => {
93 buffer.push("AS");
94 query.to_source(buffer);
95 }
96 CreateBody::Index { table_name, columns, .. } => {
97 buffer.push("ON");
98 table_name.to_source(buffer);
99 buffer.push("(");
100 for (i, col) in columns.iter().enumerate() {
101 if i > 0 {
102 buffer.push(",");
103 }
104 col.to_source(buffer);
105 }
106 buffer.push(")");
107 }
108 CreateBody::Database { .. } => {}
109 }
110 }
111}
112
113#[derive(Debug, Clone)]
115#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
116pub struct ColumnDefinition {
117 pub name: Identifier,
119 pub data_type: Arc<str>,
121 pub constraints: Vec<ColumnConstraint>,
123 #[serde(with = "oak_core::serde_range")]
125 pub span: Range<usize>,
126}
127
128impl ToSource for ColumnDefinition {
129 fn to_source(&self, buffer: &mut SourceBuffer) {
130 self.name.to_source(buffer);
131 buffer.push(&self.data_type);
132 for constraint in &self.constraints {
133 constraint.to_source(buffer);
134 }
135 }
136}
137
138#[derive(Debug, Clone)]
140#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
141pub enum ColumnConstraint {
142 PrimaryKey {
144 #[serde(with = "oak_core::serde_range")]
146 span: Range<usize>,
147 },
148 NotNull {
150 #[serde(with = "oak_core::serde_range")]
152 span: Range<usize>,
153 },
154 Nullable {
156 #[serde(with = "oak_core::serde_range")]
158 span: Range<usize>,
159 },
160 Unique {
162 #[serde(with = "oak_core::serde_range")]
164 span: Range<usize>,
165 },
166 Default(Expression, #[serde(with = "oak_core::serde_range")] Range<usize>),
168 Check(Expression, #[serde(with = "oak_core::serde_range")] Range<usize>),
170 AutoIncrement {
172 #[serde(with = "oak_core::serde_range")]
174 span: Range<usize>,
175 },
176}
177
178impl ToSource for ColumnConstraint {
179 fn to_source(&self, buffer: &mut SourceBuffer) {
180 match self {
181 ColumnConstraint::PrimaryKey { .. } => {
182 buffer.push("PRIMARY");
183 buffer.push("KEY");
184 }
185 ColumnConstraint::NotNull { .. } => {
186 buffer.push("NOT");
187 buffer.push("NULL");
188 }
189 ColumnConstraint::Nullable { .. } => buffer.push("NULL"),
190 ColumnConstraint::Unique { .. } => buffer.push("UNIQUE"),
191 ColumnConstraint::Default(expr, _) => {
192 buffer.push("DEFAULT");
193 expr.to_source(buffer);
194 }
195 ColumnConstraint::Check(expr, _) => {
196 buffer.push("CHECK");
197 buffer.push("(");
198 expr.to_source(buffer);
199 buffer.push(")");
200 }
201 ColumnConstraint::AutoIncrement { .. } => buffer.push("AUTOINCREMENT"),
202 }
203 }
204}
205
206#[derive(Debug, Clone, Copy, PartialEq, Eq)]
208#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
209pub enum CreateObjectType {
210 Table,
212 View,
214 Index,
216 Database,
218}
219
220impl ToSource for CreateObjectType {
221 fn to_source(&self, buffer: &mut SourceBuffer) {
222 match self {
223 CreateObjectType::Table => buffer.push("TABLE"),
224 CreateObjectType::View => buffer.push("VIEW"),
225 CreateObjectType::Index => buffer.push("INDEX"),
226 CreateObjectType::Database => buffer.push("DATABASE"),
227 }
228 }
229}
230
231#[derive(Debug, Clone)]
233#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
234pub struct DropStatement {
235 pub object_type: DropObjectType,
237 pub name: Identifier,
239 pub if_exists: bool,
241 #[serde(with = "oak_core::serde_range")]
243 pub span: Range<usize>,
244}
245
246impl ToSource for DropStatement {
247 fn to_source(&self, buffer: &mut SourceBuffer) {
248 buffer.push("DROP");
249 self.object_type.to_source(buffer);
250 if self.if_exists {
251 buffer.push("IF");
252 buffer.push("EXISTS");
253 }
254 self.name.to_source(buffer);
255 }
256}
257
258#[derive(Debug, Clone, Copy, PartialEq, Eq)]
260#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
261pub enum DropObjectType {
262 Table,
264 View,
266 Index,
268 Database,
270}
271
272impl ToSource for DropObjectType {
273 fn to_source(&self, buffer: &mut SourceBuffer) {
274 match self {
275 DropObjectType::Table => buffer.push("TABLE"),
276 DropObjectType::View => buffer.push("VIEW"),
277 DropObjectType::Index => buffer.push("INDEX"),
278 DropObjectType::Database => buffer.push("DATABASE"),
279 }
280 }
281}
282
283#[derive(Debug, Clone)]
285#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
286pub struct AlterStatement {
287 pub table_name: TableName,
289 pub action: Option<AlterAction>,
291 #[serde(with = "oak_core::serde_range")]
293 pub span: Range<usize>,
294}
295
296#[derive(Debug, Clone)]
298#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
299pub enum AlterAction {
300 AddColumn {
302 name: Identifier,
304 data_type: Option<Arc<str>>,
306 #[serde(with = "oak_core::serde_range")]
308 span: Range<usize>,
309 },
310 DropColumn {
312 name: Identifier,
314 #[serde(with = "oak_core::serde_range")]
316 span: Range<usize>,
317 },
318 RenameTo {
320 new_name: Identifier,
322 #[serde(with = "oak_core::serde_range")]
324 span: Range<usize>,
325 },
326}
327
328impl ToSource for AlterStatement {
329 fn to_source(&self, buffer: &mut SourceBuffer) {
330 buffer.push("ALTER");
331 buffer.push("TABLE");
332 self.table_name.to_source(buffer);
333 if let Some(action) = &self.action {
334 match action {
335 AlterAction::AddColumn { name, data_type, .. } => {
336 buffer.push("ADD");
337 buffer.push("COLUMN");
338 name.to_source(buffer);
339 if let Some(dt) = data_type {
340 buffer.push(dt);
341 }
342 }
343 AlterAction::DropColumn { name, .. } => {
344 buffer.push("DROP");
345 buffer.push("COLUMN");
346 name.to_source(buffer);
347 }
348 AlterAction::RenameTo { new_name, .. } => {
349 buffer.push("RENAME");
350 buffer.push("TO");
351 new_name.to_source(buffer);
352 }
353 }
354 }
355 }
356}