1use crate::ast::expr::{Expression, Identifier, TableName};
2use core::range::Range;
3use oak_core::source::{SourceBuffer, ToSource};
4
5#[derive(Debug, Clone)]
7#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
8pub struct SelectStatement {
9 pub items: Vec<SelectItem>,
11 pub from: Option<TableName>,
13 pub joins: Vec<JoinClause>,
15 pub expr: Option<Expression>, pub group_by: Option<GroupByClause>,
19 pub having: Option<HavingClause>,
21 pub order_by: Option<OrderByClause>,
23 pub limit: Option<LimitClause>,
25 #[serde(with = "oak_core::serde_range")]
27 pub span: Range<usize>,
28}
29
30impl ToSource for SelectStatement {
31 fn to_source(&self, buffer: &mut SourceBuffer) {
32 buffer.push("SELECT");
33 for (i, item) in self.items.iter().enumerate() {
34 if i > 0 {
35 buffer.push(",");
36 }
37 item.to_source(buffer);
38 }
39 if let Some(from) = &self.from {
40 buffer.push("FROM");
41 from.to_source(buffer);
42 }
43 for join in &self.joins {
44 join.to_source(buffer);
45 }
46 if let Some(expr) = &self.expr {
47 buffer.push("WHERE");
48 expr.to_source(buffer);
49 }
50 if let Some(group_by) = &self.group_by {
51 group_by.to_source(buffer);
52 }
53 if let Some(having) = &self.having {
54 having.to_source(buffer);
55 }
56 if let Some(order_by) = &self.order_by {
57 order_by.to_source(buffer);
58 }
59 if let Some(limit) = &self.limit {
60 limit.to_source(buffer);
61 }
62 }
63}
64
65#[derive(Debug, Clone)]
67#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
68pub enum SelectItem {
69 Star {
71 #[serde(with = "oak_core::serde_range")]
73 span: Range<usize>,
74 },
75 Expression {
77 expr: Expression,
79 alias: Option<Identifier>,
81 #[serde(with = "oak_core::serde_range")]
83 span: Range<usize>,
84 },
85}
86
87impl ToSource for SelectItem {
88 fn to_source(&self, buffer: &mut SourceBuffer) {
89 match self {
90 SelectItem::Star { .. } => buffer.push("*"),
91 SelectItem::Expression { expr, alias, .. } => {
92 expr.to_source(buffer);
93 if let Some(alias) = alias {
94 buffer.push("AS");
95 alias.to_source(buffer);
96 }
97 }
98 }
99 }
100}
101
102#[derive(Debug, Clone)]
104#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
105pub struct JoinClause {
106 pub join_type: JoinType,
108 pub table: TableName,
110 pub on: Option<Expression>,
112 #[serde(with = "oak_core::serde_range")]
114 pub span: Range<usize>,
115}
116
117impl ToSource for JoinClause {
118 fn to_source(&self, buffer: &mut SourceBuffer) {
119 self.join_type.to_source(buffer);
120 buffer.push("JOIN");
121 self.table.to_source(buffer);
122 if let Some(on) = &self.on {
123 buffer.push("ON");
124 on.to_source(buffer);
125 }
126 }
127}
128
129#[derive(Debug, Clone, Copy, PartialEq, Eq)]
131#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
132pub enum JoinType {
133 Inner,
135 Left,
137 Right,
139 Full,
141}
142
143impl ToSource for JoinType {
144 fn to_source(&self, buffer: &mut SourceBuffer) {
145 match self {
146 JoinType::Inner => buffer.push("INNER"),
147 JoinType::Left => buffer.push("LEFT"),
148 JoinType::Right => buffer.push("RIGHT"),
149 JoinType::Full => buffer.push("FULL"),
150 }
151 }
152}
153
154#[derive(Debug, Clone)]
156#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
157pub struct GroupByClause {
158 pub columns: Vec<Expression>,
160 #[serde(with = "oak_core::serde_range")]
162 pub span: Range<usize>,
163}
164
165impl ToSource for GroupByClause {
166 fn to_source(&self, buffer: &mut SourceBuffer) {
167 buffer.push("GROUP");
168 buffer.push("BY");
169 for (i, col) in self.columns.iter().enumerate() {
170 if i > 0 {
171 buffer.push(",");
172 }
173 col.to_source(buffer);
174 }
175 }
176}
177
178#[derive(Debug, Clone)]
180#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
181pub struct HavingClause {
182 pub condition: Expression,
184 #[serde(with = "oak_core::serde_range")]
186 pub span: Range<usize>,
187}
188
189impl ToSource for HavingClause {
190 fn to_source(&self, buffer: &mut SourceBuffer) {
191 buffer.push("HAVING");
192 self.condition.to_source(buffer);
193 }
194}
195
196#[derive(Debug, Clone)]
198#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
199pub struct OrderByClause {
200 pub items: Vec<OrderByItem>,
202 #[serde(with = "oak_core::serde_range")]
204 pub span: Range<usize>,
205}
206
207impl ToSource for OrderByClause {
208 fn to_source(&self, buffer: &mut SourceBuffer) {
209 buffer.push("ORDER");
210 buffer.push("BY");
211 for (i, item) in self.items.iter().enumerate() {
212 if i > 0 {
213 buffer.push(",");
214 }
215 item.to_source(buffer);
216 }
217 }
218}
219
220#[derive(Debug, Clone)]
222#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
223pub struct OrderByItem {
224 pub expr: Expression,
226 pub direction: OrderDirection,
228 #[serde(with = "oak_core::serde_range")]
230 pub span: Range<usize>,
231}
232
233impl ToSource for OrderByItem {
234 fn to_source(&self, buffer: &mut SourceBuffer) {
235 self.expr.to_source(buffer);
236 self.direction.to_source(buffer);
237 }
238}
239
240#[derive(Debug, Clone, Copy, PartialEq, Eq)]
242#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
243pub enum OrderDirection {
244 Asc,
246 Desc,
248}
249
250impl ToSource for OrderDirection {
251 fn to_source(&self, buffer: &mut SourceBuffer) {
252 match self {
253 OrderDirection::Asc => buffer.push("ASC"),
254 OrderDirection::Desc => buffer.push("DESC"),
255 }
256 }
257}
258
259#[derive(Debug, Clone)]
261#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
262pub struct LimitClause {
263 pub limit: Expression,
265 pub offset: Option<Expression>,
267 #[serde(with = "oak_core::serde_range")]
269 pub span: Range<usize>,
270}
271
272impl ToSource for LimitClause {
273 fn to_source(&self, buffer: &mut SourceBuffer) {
274 buffer.push("LIMIT");
275 self.limit.to_source(buffer);
276 if let Some(offset) = &self.offset {
277 buffer.push("OFFSET");
278 offset.to_source(buffer);
279 }
280 }
281}