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")]
145 span: Range<usize>,
146 },
147 NotNull {
149 #[serde(with = "oak_core::serde_range")]
150 span: Range<usize>,
151 },
152 Nullable {
154 #[serde(with = "oak_core::serde_range")]
155 span: Range<usize>,
156 },
157 Unique {
159 #[serde(with = "oak_core::serde_range")]
160 span: Range<usize>,
161 },
162 Default(Expression, #[serde(with = "oak_core::serde_range")] Range<usize>),
164 Check(Expression, #[serde(with = "oak_core::serde_range")] Range<usize>),
166 AutoIncrement {
168 #[serde(with = "oak_core::serde_range")]
169 span: Range<usize>,
170 },
171}
172
173impl ToSource for ColumnConstraint {
174 fn to_source(&self, buffer: &mut SourceBuffer) {
175 match self {
176 ColumnConstraint::PrimaryKey { .. } => {
177 buffer.push("PRIMARY");
178 buffer.push("KEY");
179 }
180 ColumnConstraint::NotNull { .. } => {
181 buffer.push("NOT");
182 buffer.push("NULL");
183 }
184 ColumnConstraint::Nullable { .. } => buffer.push("NULL"),
185 ColumnConstraint::Unique { .. } => buffer.push("UNIQUE"),
186 ColumnConstraint::Default(expr, _) => {
187 buffer.push("DEFAULT");
188 expr.to_source(buffer);
189 }
190 ColumnConstraint::Check(expr, _) => {
191 buffer.push("CHECK");
192 buffer.push("(");
193 expr.to_source(buffer);
194 buffer.push(")");
195 }
196 ColumnConstraint::AutoIncrement { .. } => buffer.push("AUTOINCREMENT"),
197 }
198 }
199}
200
201#[derive(Debug, Clone, Copy, PartialEq, Eq)]
203#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
204pub enum CreateObjectType {
205 Table,
207 View,
209 Index,
211 Database,
213}
214
215impl ToSource for CreateObjectType {
216 fn to_source(&self, buffer: &mut SourceBuffer) {
217 match self {
218 CreateObjectType::Table => buffer.push("TABLE"),
219 CreateObjectType::View => buffer.push("VIEW"),
220 CreateObjectType::Index => buffer.push("INDEX"),
221 CreateObjectType::Database => buffer.push("DATABASE"),
222 }
223 }
224}
225
226#[derive(Debug, Clone)]
228#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
229pub struct DropStatement {
230 pub object_type: DropObjectType,
232 pub name: Identifier,
234 pub if_exists: bool,
236 #[serde(with = "oak_core::serde_range")]
238 pub span: Range<usize>,
239}
240
241impl ToSource for DropStatement {
242 fn to_source(&self, buffer: &mut SourceBuffer) {
243 buffer.push("DROP");
244 self.object_type.to_source(buffer);
245 if self.if_exists {
246 buffer.push("IF");
247 buffer.push("EXISTS");
248 }
249 self.name.to_source(buffer);
250 }
251}
252
253#[derive(Debug, Clone, Copy, PartialEq, Eq)]
255#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
256pub enum DropObjectType {
257 Table,
259 View,
261 Index,
263 Database,
265}
266
267impl ToSource for DropObjectType {
268 fn to_source(&self, buffer: &mut SourceBuffer) {
269 match self {
270 DropObjectType::Table => buffer.push("TABLE"),
271 DropObjectType::View => buffer.push("VIEW"),
272 DropObjectType::Index => buffer.push("INDEX"),
273 DropObjectType::Database => buffer.push("DATABASE"),
274 }
275 }
276}
277
278#[derive(Debug, Clone)]
280#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
281pub struct AlterStatement {
282 pub table_name: TableName,
284 pub action: Option<AlterAction>,
286 #[serde(with = "oak_core::serde_range")]
288 pub span: Range<usize>,
289}
290
291#[derive(Debug, Clone)]
293#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
294pub enum AlterAction {
295 AddColumn {
297 name: Identifier,
299 data_type: Option<Arc<str>>,
301 #[serde(with = "oak_core::serde_range")]
303 span: Range<usize>,
304 },
305 DropColumn {
307 name: Identifier,
309 #[serde(with = "oak_core::serde_range")]
311 span: Range<usize>,
312 },
313 RenameTo {
315 new_name: Identifier,
317 #[serde(with = "oak_core::serde_range")]
319 span: Range<usize>,
320 },
321}
322
323impl ToSource for AlterStatement {
324 fn to_source(&self, buffer: &mut SourceBuffer) {
325 buffer.push("ALTER");
326 buffer.push("TABLE");
327 self.table_name.to_source(buffer);
328 if let Some(action) = &self.action {
329 match action {
330 AlterAction::AddColumn { name, data_type, .. } => {
331 buffer.push("ADD");
332 buffer.push("COLUMN");
333 name.to_source(buffer);
334 if let Some(dt) = data_type {
335 buffer.push(dt);
336 }
337 }
338 AlterAction::DropColumn { name, .. } => {
339 buffer.push("DROP");
340 buffer.push("COLUMN");
341 name.to_source(buffer);
342 }
343 AlterAction::RenameTo { new_name, .. } => {
344 buffer.push("RENAME");
345 buffer.push("TO");
346 new_name.to_source(buffer);
347 }
348 }
349 }
350 }
351}