1#[derive(Debug, Clone, PartialEq)]
10pub struct Comment {
11 pub text: String,
13 pub is_line_comment: bool,
15}
16
17impl Comment {
18 pub fn line(text: String) -> Self {
20 Self {
21 text,
22 is_line_comment: true,
23 }
24 }
25
26 pub fn block(text: String) -> Self {
28 Self {
29 text,
30 is_line_comment: false,
31 }
32 }
33}
34
35#[derive(Debug, Clone, PartialEq, Eq, Hash)]
39pub enum QuoteStyle {
40 None,
42 DoubleQuotes,
44 Brackets,
46}
47
48#[derive(Debug, Clone, PartialEq, Eq, Hash)]
50pub struct ColumnRef {
51 pub name: String,
52 pub quote_style: QuoteStyle,
53 pub table_prefix: Option<String>,
55}
56
57impl ColumnRef {
58 pub fn unquoted(name: String) -> Self {
60 Self {
61 name,
62 quote_style: QuoteStyle::None,
63 table_prefix: None,
64 }
65 }
66
67 pub fn quoted(name: String) -> Self {
69 Self {
70 name,
71 quote_style: QuoteStyle::DoubleQuotes,
72 table_prefix: None,
73 }
74 }
75
76 pub fn qualified(table: String, name: String) -> Self {
78 Self {
79 name,
80 quote_style: QuoteStyle::None,
81 table_prefix: Some(table),
82 }
83 }
84
85 pub fn to_qualified_string(&self) -> String {
87 match &self.table_prefix {
88 Some(table) => format!("{}.{}", table, self.name),
89 None => self.name.clone(),
90 }
91 }
92
93 pub fn bracketed(name: String) -> Self {
95 Self {
96 name,
97 quote_style: QuoteStyle::Brackets,
98 table_prefix: None,
99 }
100 }
101
102 pub fn to_sql(&self) -> String {
104 let column_part = match self.quote_style {
105 QuoteStyle::None => self.name.clone(),
106 QuoteStyle::DoubleQuotes => format!("\"{}\"", self.name),
107 QuoteStyle::Brackets => format!("[{}]", self.name),
108 };
109
110 match &self.table_prefix {
111 Some(table) => format!("{}.{}", table, column_part),
112 None => column_part,
113 }
114 }
115}
116
117impl PartialEq<str> for ColumnRef {
118 fn eq(&self, other: &str) -> bool {
119 self.name == other
120 }
121}
122
123impl PartialEq<&str> for ColumnRef {
124 fn eq(&self, other: &&str) -> bool {
125 self.name == *other
126 }
127}
128
129impl std::fmt::Display for ColumnRef {
130 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
131 write!(f, "{}", self.to_sql())
132 }
133}
134
135#[derive(Debug, Clone)]
136pub enum SqlExpression {
137 Column(ColumnRef),
138 StringLiteral(String),
139 NumberLiteral(String),
140 BooleanLiteral(bool),
141 Null, DateTimeConstructor {
143 year: i32,
144 month: u32,
145 day: u32,
146 hour: Option<u32>,
147 minute: Option<u32>,
148 second: Option<u32>,
149 },
150 DateTimeToday {
151 hour: Option<u32>,
152 minute: Option<u32>,
153 second: Option<u32>,
154 },
155 MethodCall {
156 object: String,
157 method: String,
158 args: Vec<SqlExpression>,
159 },
160 ChainedMethodCall {
161 base: Box<SqlExpression>,
162 method: String,
163 args: Vec<SqlExpression>,
164 },
165 FunctionCall {
166 name: String,
167 args: Vec<SqlExpression>,
168 distinct: bool, },
170 WindowFunction {
171 name: String,
172 args: Vec<SqlExpression>,
173 window_spec: WindowSpec,
174 },
175 BinaryOp {
176 left: Box<SqlExpression>,
177 op: String,
178 right: Box<SqlExpression>,
179 },
180 InList {
181 expr: Box<SqlExpression>,
182 values: Vec<SqlExpression>,
183 },
184 NotInList {
185 expr: Box<SqlExpression>,
186 values: Vec<SqlExpression>,
187 },
188 Between {
189 expr: Box<SqlExpression>,
190 lower: Box<SqlExpression>,
191 upper: Box<SqlExpression>,
192 },
193 Not {
194 expr: Box<SqlExpression>,
195 },
196 CaseExpression {
197 when_branches: Vec<WhenBranch>,
198 else_branch: Option<Box<SqlExpression>>,
199 },
200 SimpleCaseExpression {
201 expr: Box<SqlExpression>,
202 when_branches: Vec<SimpleWhenBranch>,
203 else_branch: Option<Box<SqlExpression>>,
204 },
205 ScalarSubquery {
208 query: Box<SelectStatement>,
209 },
210 InSubquery {
213 expr: Box<SqlExpression>,
214 subquery: Box<SelectStatement>,
215 },
216 Unnest {
220 column: Box<SqlExpression>,
221 delimiter: String,
222 },
223 NotInSubquery {
226 expr: Box<SqlExpression>,
227 subquery: Box<SelectStatement>,
228 },
229}
230
231#[derive(Debug, Clone)]
232pub struct WhenBranch {
233 pub condition: Box<SqlExpression>,
234 pub result: Box<SqlExpression>,
235}
236
237#[derive(Debug, Clone)]
238pub struct SimpleWhenBranch {
239 pub value: Box<SqlExpression>,
240 pub result: Box<SqlExpression>,
241}
242
243#[derive(Debug, Clone)]
246pub struct WhereClause {
247 pub conditions: Vec<Condition>,
248}
249
250#[derive(Debug, Clone)]
251pub struct Condition {
252 pub expr: SqlExpression,
253 pub connector: Option<LogicalOp>, }
255
256#[derive(Debug, Clone)]
257pub enum LogicalOp {
258 And,
259 Or,
260}
261
262#[derive(Debug, Clone, PartialEq)]
265pub enum SortDirection {
266 Asc,
267 Desc,
268}
269
270#[derive(Debug, Clone)]
271pub struct OrderByColumn {
272 pub column: String,
273 pub direction: SortDirection,
274}
275
276#[derive(Debug, Clone, PartialEq)]
280pub enum FrameBound {
281 UnboundedPreceding,
282 CurrentRow,
283 Preceding(i64),
284 Following(i64),
285 UnboundedFollowing,
286}
287
288#[derive(Debug, Clone, PartialEq)]
290pub enum FrameUnit {
291 Rows,
292 Range,
293}
294
295#[derive(Debug, Clone)]
297pub struct WindowFrame {
298 pub unit: FrameUnit,
299 pub start: FrameBound,
300 pub end: Option<FrameBound>, }
302
303#[derive(Debug, Clone)]
304pub struct WindowSpec {
305 pub partition_by: Vec<String>,
306 pub order_by: Vec<OrderByColumn>,
307 pub frame: Option<WindowFrame>, }
309
310#[derive(Debug, Clone, PartialEq)]
314pub enum SetOperation {
315 UnionAll,
317 Union,
319 Intersect,
321 Except,
323}
324
325#[derive(Debug, Clone)]
327pub enum SelectItem {
328 Column {
330 column: ColumnRef,
331 leading_comments: Vec<Comment>,
332 trailing_comment: Option<Comment>,
333 },
334 Expression {
336 expr: SqlExpression,
337 alias: String,
338 leading_comments: Vec<Comment>,
339 trailing_comment: Option<Comment>,
340 },
341 Star {
343 leading_comments: Vec<Comment>,
344 trailing_comment: Option<Comment>,
345 },
346}
347
348#[derive(Debug, Clone)]
349pub struct SelectStatement {
350 pub distinct: bool, pub columns: Vec<String>, pub select_items: Vec<SelectItem>, pub from_table: Option<String>,
354 pub from_subquery: Option<Box<SelectStatement>>, pub from_function: Option<TableFunction>, pub from_alias: Option<String>, pub joins: Vec<JoinClause>, pub where_clause: Option<WhereClause>,
359 pub order_by: Option<Vec<OrderByColumn>>,
360 pub group_by: Option<Vec<SqlExpression>>, pub having: Option<SqlExpression>, pub limit: Option<usize>,
363 pub offset: Option<usize>,
364 pub ctes: Vec<CTE>, pub into_table: Option<IntoTable>, pub set_operations: Vec<(SetOperation, Box<SelectStatement>)>, pub leading_comments: Vec<Comment>, pub trailing_comment: Option<Comment>, }
372
373#[derive(Debug, Clone, PartialEq)]
375pub struct IntoTable {
376 pub name: String,
378}
379
380#[derive(Debug, Clone)]
384pub enum TableFunction {
385 Generator {
386 name: String,
387 args: Vec<SqlExpression>,
388 },
389}
390
391#[derive(Debug, Clone)]
393pub struct CTE {
394 pub name: String,
395 pub column_list: Option<Vec<String>>, pub cte_type: CTEType,
397}
398
399#[derive(Debug, Clone)]
401pub enum CTEType {
402 Standard(SelectStatement),
403 Web(WebCTESpec),
404}
405
406#[derive(Debug, Clone)]
408pub struct WebCTESpec {
409 pub url: String,
410 pub format: Option<DataFormat>, pub headers: Vec<(String, String)>, pub cache_seconds: Option<u64>, pub method: Option<HttpMethod>, pub body: Option<String>, pub json_path: Option<String>, pub form_files: Vec<(String, String)>, pub form_fields: Vec<(String, String)>, pub template_vars: Vec<TemplateVar>, }
420
421#[derive(Debug, Clone)]
423pub struct TemplateVar {
424 pub placeholder: String, pub table_name: String, pub column: Option<String>, pub index: Option<usize>, }
429
430#[derive(Debug, Clone)]
432pub enum HttpMethod {
433 GET,
434 POST,
435 PUT,
436 DELETE,
437 PATCH,
438}
439
440#[derive(Debug, Clone)]
442pub enum DataFormat {
443 CSV,
444 JSON,
445 Auto, }
447
448#[derive(Debug, Clone)]
450pub enum TableSource {
451 Table(String), DerivedTable {
453 query: Box<SelectStatement>,
455 alias: String, },
457}
458
459#[derive(Debug, Clone, PartialEq)]
461pub enum JoinType {
462 Inner,
463 Left,
464 Right,
465 Full,
466 Cross,
467}
468
469#[derive(Debug, Clone, PartialEq)]
471pub enum JoinOperator {
472 Equal,
473 NotEqual,
474 LessThan,
475 GreaterThan,
476 LessThanOrEqual,
477 GreaterThanOrEqual,
478}
479
480#[derive(Debug, Clone)]
482pub struct SingleJoinCondition {
483 pub left_column: String, pub operator: JoinOperator, pub right_column: String, }
487
488#[derive(Debug, Clone)]
490pub struct JoinCondition {
491 pub conditions: Vec<SingleJoinCondition>, }
493
494#[derive(Debug, Clone)]
496pub struct JoinClause {
497 pub join_type: JoinType,
498 pub table: TableSource, pub alias: Option<String>, pub condition: JoinCondition, }