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>, }
312
313#[derive(Debug, Clone)]
317pub enum TableFunction {
318 Generator {
319 name: String,
320 args: Vec<SqlExpression>,
321 },
322}
323
324#[derive(Debug, Clone)]
326pub struct CTE {
327 pub name: String,
328 pub column_list: Option<Vec<String>>, pub cte_type: CTEType,
330}
331
332#[derive(Debug, Clone)]
334pub enum CTEType {
335 Standard(SelectStatement),
336 Web(WebCTESpec),
337}
338
339#[derive(Debug, Clone)]
341pub struct WebCTESpec {
342 pub url: String,
343 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)>, }
352
353#[derive(Debug, Clone)]
355pub enum HttpMethod {
356 GET,
357 POST,
358 PUT,
359 DELETE,
360 PATCH,
361}
362
363#[derive(Debug, Clone)]
365pub enum DataFormat {
366 CSV,
367 JSON,
368 Auto, }
370
371#[derive(Debug, Clone)]
373pub enum TableSource {
374 Table(String), DerivedTable {
376 query: Box<SelectStatement>,
378 alias: String, },
380}
381
382#[derive(Debug, Clone, PartialEq)]
384pub enum JoinType {
385 Inner,
386 Left,
387 Right,
388 Full,
389 Cross,
390}
391
392#[derive(Debug, Clone, PartialEq)]
394pub enum JoinOperator {
395 Equal,
396 NotEqual,
397 LessThan,
398 GreaterThan,
399 LessThanOrEqual,
400 GreaterThanOrEqual,
401}
402
403#[derive(Debug, Clone)]
405pub struct SingleJoinCondition {
406 pub left_column: String, pub operator: JoinOperator, pub right_column: String, }
410
411#[derive(Debug, Clone)]
413pub struct JoinCondition {
414 pub conditions: Vec<SingleJoinCondition>, }
416
417#[derive(Debug, Clone)]
419pub struct JoinClause {
420 pub join_type: JoinType,
421 pub table: TableSource, pub alias: Option<String>, pub condition: JoinCondition, }