1#[derive(Debug, Clone, PartialEq, Eq, Hash)]
10pub enum QuoteStyle {
11 None,
13 DoubleQuotes,
15 Brackets,
17}
18
19#[derive(Debug, Clone, PartialEq, Eq, Hash)]
21pub struct ColumnRef {
22 pub name: String,
23 pub quote_style: QuoteStyle,
24 pub table_prefix: Option<String>,
26}
27
28impl ColumnRef {
29 pub fn unquoted(name: String) -> Self {
31 Self {
32 name,
33 quote_style: QuoteStyle::None,
34 table_prefix: None,
35 }
36 }
37
38 pub fn quoted(name: String) -> Self {
40 Self {
41 name,
42 quote_style: QuoteStyle::DoubleQuotes,
43 table_prefix: None,
44 }
45 }
46
47 pub fn qualified(table: String, name: String) -> Self {
49 Self {
50 name,
51 quote_style: QuoteStyle::None,
52 table_prefix: Some(table),
53 }
54 }
55
56 pub fn to_qualified_string(&self) -> String {
58 match &self.table_prefix {
59 Some(table) => format!("{}.{}", table, self.name),
60 None => self.name.clone(),
61 }
62 }
63
64 pub fn bracketed(name: String) -> Self {
66 Self {
67 name,
68 quote_style: QuoteStyle::Brackets,
69 table_prefix: None,
70 }
71 }
72
73 pub fn to_sql(&self) -> String {
75 let column_part = match self.quote_style {
76 QuoteStyle::None => self.name.clone(),
77 QuoteStyle::DoubleQuotes => format!("\"{}\"", self.name),
78 QuoteStyle::Brackets => format!("[{}]", self.name),
79 };
80
81 match &self.table_prefix {
82 Some(table) => format!("{}.{}", table, column_part),
83 None => column_part,
84 }
85 }
86}
87
88impl PartialEq<str> for ColumnRef {
89 fn eq(&self, other: &str) -> bool {
90 self.name == other
91 }
92}
93
94impl PartialEq<&str> for ColumnRef {
95 fn eq(&self, other: &&str) -> bool {
96 self.name == *other
97 }
98}
99
100impl std::fmt::Display for ColumnRef {
101 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
102 write!(f, "{}", self.to_sql())
103 }
104}
105
106#[derive(Debug, Clone)]
107pub enum SqlExpression {
108 Column(ColumnRef),
109 StringLiteral(String),
110 NumberLiteral(String),
111 BooleanLiteral(bool),
112 Null, DateTimeConstructor {
114 year: i32,
115 month: u32,
116 day: u32,
117 hour: Option<u32>,
118 minute: Option<u32>,
119 second: Option<u32>,
120 },
121 DateTimeToday {
122 hour: Option<u32>,
123 minute: Option<u32>,
124 second: Option<u32>,
125 },
126 MethodCall {
127 object: String,
128 method: String,
129 args: Vec<SqlExpression>,
130 },
131 ChainedMethodCall {
132 base: Box<SqlExpression>,
133 method: String,
134 args: Vec<SqlExpression>,
135 },
136 FunctionCall {
137 name: String,
138 args: Vec<SqlExpression>,
139 distinct: bool, },
141 WindowFunction {
142 name: String,
143 args: Vec<SqlExpression>,
144 window_spec: WindowSpec,
145 },
146 BinaryOp {
147 left: Box<SqlExpression>,
148 op: String,
149 right: Box<SqlExpression>,
150 },
151 InList {
152 expr: Box<SqlExpression>,
153 values: Vec<SqlExpression>,
154 },
155 NotInList {
156 expr: Box<SqlExpression>,
157 values: Vec<SqlExpression>,
158 },
159 Between {
160 expr: Box<SqlExpression>,
161 lower: Box<SqlExpression>,
162 upper: Box<SqlExpression>,
163 },
164 Not {
165 expr: Box<SqlExpression>,
166 },
167 CaseExpression {
168 when_branches: Vec<WhenBranch>,
169 else_branch: Option<Box<SqlExpression>>,
170 },
171 SimpleCaseExpression {
172 expr: Box<SqlExpression>,
173 when_branches: Vec<SimpleWhenBranch>,
174 else_branch: Option<Box<SqlExpression>>,
175 },
176 ScalarSubquery {
179 query: Box<SelectStatement>,
180 },
181 InSubquery {
184 expr: Box<SqlExpression>,
185 subquery: Box<SelectStatement>,
186 },
187 Unnest {
191 column: Box<SqlExpression>,
192 delimiter: String,
193 },
194 NotInSubquery {
197 expr: Box<SqlExpression>,
198 subquery: Box<SelectStatement>,
199 },
200}
201
202#[derive(Debug, Clone)]
203pub struct WhenBranch {
204 pub condition: Box<SqlExpression>,
205 pub result: Box<SqlExpression>,
206}
207
208#[derive(Debug, Clone)]
209pub struct SimpleWhenBranch {
210 pub value: Box<SqlExpression>,
211 pub result: Box<SqlExpression>,
212}
213
214#[derive(Debug, Clone)]
217pub struct WhereClause {
218 pub conditions: Vec<Condition>,
219}
220
221#[derive(Debug, Clone)]
222pub struct Condition {
223 pub expr: SqlExpression,
224 pub connector: Option<LogicalOp>, }
226
227#[derive(Debug, Clone)]
228pub enum LogicalOp {
229 And,
230 Or,
231}
232
233#[derive(Debug, Clone, PartialEq)]
236pub enum SortDirection {
237 Asc,
238 Desc,
239}
240
241#[derive(Debug, Clone)]
242pub struct OrderByColumn {
243 pub column: String,
244 pub direction: SortDirection,
245}
246
247#[derive(Debug, Clone, PartialEq)]
251pub enum FrameBound {
252 UnboundedPreceding,
253 CurrentRow,
254 Preceding(i64),
255 Following(i64),
256 UnboundedFollowing,
257}
258
259#[derive(Debug, Clone, PartialEq)]
261pub enum FrameUnit {
262 Rows,
263 Range,
264}
265
266#[derive(Debug, Clone)]
268pub struct WindowFrame {
269 pub unit: FrameUnit,
270 pub start: FrameBound,
271 pub end: Option<FrameBound>, }
273
274#[derive(Debug, Clone)]
275pub struct WindowSpec {
276 pub partition_by: Vec<String>,
277 pub order_by: Vec<OrderByColumn>,
278 pub frame: Option<WindowFrame>, }
280
281#[derive(Debug, Clone)]
285pub enum SelectItem {
286 Column(ColumnRef),
288 Expression { expr: SqlExpression, alias: String },
290 Star,
292}
293
294#[derive(Debug, Clone)]
295pub struct SelectStatement {
296 pub distinct: bool, pub columns: Vec<String>, pub select_items: Vec<SelectItem>, pub from_table: Option<String>,
300 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>,
305 pub order_by: Option<Vec<OrderByColumn>>,
306 pub group_by: Option<Vec<SqlExpression>>, pub having: Option<SqlExpression>, pub limit: Option<usize>,
309 pub offset: Option<usize>,
310 pub ctes: Vec<CTE>, pub into_table: Option<IntoTable>, }
313
314#[derive(Debug, Clone, PartialEq)]
316pub struct IntoTable {
317 pub name: String,
319}
320
321#[derive(Debug, Clone)]
325pub enum TableFunction {
326 Generator {
327 name: String,
328 args: Vec<SqlExpression>,
329 },
330}
331
332#[derive(Debug, Clone)]
334pub struct CTE {
335 pub name: String,
336 pub column_list: Option<Vec<String>>, pub cte_type: CTEType,
338}
339
340#[derive(Debug, Clone)]
342pub enum CTEType {
343 Standard(SelectStatement),
344 Web(WebCTESpec),
345}
346
347#[derive(Debug, Clone)]
349pub struct WebCTESpec {
350 pub url: String,
351 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>, }
361
362#[derive(Debug, Clone)]
364pub struct TemplateVar {
365 pub placeholder: String, pub table_name: String, pub column: Option<String>, pub index: Option<usize>, }
370
371#[derive(Debug, Clone)]
373pub enum HttpMethod {
374 GET,
375 POST,
376 PUT,
377 DELETE,
378 PATCH,
379}
380
381#[derive(Debug, Clone)]
383pub enum DataFormat {
384 CSV,
385 JSON,
386 Auto, }
388
389#[derive(Debug, Clone)]
391pub enum TableSource {
392 Table(String), DerivedTable {
394 query: Box<SelectStatement>,
396 alias: String, },
398}
399
400#[derive(Debug, Clone, PartialEq)]
402pub enum JoinType {
403 Inner,
404 Left,
405 Right,
406 Full,
407 Cross,
408}
409
410#[derive(Debug, Clone, PartialEq)]
412pub enum JoinOperator {
413 Equal,
414 NotEqual,
415 LessThan,
416 GreaterThan,
417 LessThanOrEqual,
418 GreaterThanOrEqual,
419}
420
421#[derive(Debug, Clone)]
423pub struct SingleJoinCondition {
424 pub left_column: String, pub operator: JoinOperator, pub right_column: String, }
428
429#[derive(Debug, Clone)]
431pub struct JoinCondition {
432 pub conditions: Vec<SingleJoinCondition>, }
434
435#[derive(Debug, Clone)]
437pub struct JoinClause {
438 pub join_type: JoinType,
439 pub table: TableSource, pub alias: Option<String>, pub condition: JoinCondition, }