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 NotInSubquery {
190 expr: Box<SqlExpression>,
191 subquery: Box<SelectStatement>,
192 },
193}
194
195#[derive(Debug, Clone)]
196pub struct WhenBranch {
197 pub condition: Box<SqlExpression>,
198 pub result: Box<SqlExpression>,
199}
200
201#[derive(Debug, Clone)]
202pub struct SimpleWhenBranch {
203 pub value: Box<SqlExpression>,
204 pub result: Box<SqlExpression>,
205}
206
207#[derive(Debug, Clone)]
210pub struct WhereClause {
211 pub conditions: Vec<Condition>,
212}
213
214#[derive(Debug, Clone)]
215pub struct Condition {
216 pub expr: SqlExpression,
217 pub connector: Option<LogicalOp>, }
219
220#[derive(Debug, Clone)]
221pub enum LogicalOp {
222 And,
223 Or,
224}
225
226#[derive(Debug, Clone, PartialEq)]
229pub enum SortDirection {
230 Asc,
231 Desc,
232}
233
234#[derive(Debug, Clone)]
235pub struct OrderByColumn {
236 pub column: String,
237 pub direction: SortDirection,
238}
239
240#[derive(Debug, Clone, PartialEq)]
244pub enum FrameBound {
245 UnboundedPreceding,
246 CurrentRow,
247 Preceding(i64),
248 Following(i64),
249 UnboundedFollowing,
250}
251
252#[derive(Debug, Clone, PartialEq)]
254pub enum FrameUnit {
255 Rows,
256 Range,
257}
258
259#[derive(Debug, Clone)]
261pub struct WindowFrame {
262 pub unit: FrameUnit,
263 pub start: FrameBound,
264 pub end: Option<FrameBound>, }
266
267#[derive(Debug, Clone)]
268pub struct WindowSpec {
269 pub partition_by: Vec<String>,
270 pub order_by: Vec<OrderByColumn>,
271 pub frame: Option<WindowFrame>, }
273
274#[derive(Debug, Clone)]
278pub enum SelectItem {
279 Column(ColumnRef),
281 Expression { expr: SqlExpression, alias: String },
283 Star,
285}
286
287#[derive(Debug, Clone)]
288pub struct SelectStatement {
289 pub distinct: bool, pub columns: Vec<String>, pub select_items: Vec<SelectItem>, pub from_table: Option<String>,
293 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>,
298 pub order_by: Option<Vec<OrderByColumn>>,
299 pub group_by: Option<Vec<SqlExpression>>, pub having: Option<SqlExpression>, pub limit: Option<usize>,
302 pub offset: Option<usize>,
303 pub ctes: Vec<CTE>, }
305
306#[derive(Debug, Clone)]
310pub enum TableFunction {
311 Generator {
312 name: String,
313 args: Vec<SqlExpression>,
314 },
315}
316
317#[derive(Debug, Clone)]
319pub struct CTE {
320 pub name: String,
321 pub column_list: Option<Vec<String>>, pub cte_type: CTEType,
323}
324
325#[derive(Debug, Clone)]
327pub enum CTEType {
328 Standard(SelectStatement),
329 Web(WebCTESpec),
330}
331
332#[derive(Debug, Clone)]
334pub struct WebCTESpec {
335 pub url: String,
336 pub format: Option<DataFormat>, pub headers: Vec<(String, String)>, pub cache_seconds: Option<u64>, }
340
341#[derive(Debug, Clone)]
343pub enum DataFormat {
344 CSV,
345 JSON,
346 Auto, }
348
349#[derive(Debug, Clone)]
351pub enum TableSource {
352 Table(String), DerivedTable {
354 query: Box<SelectStatement>,
356 alias: String, },
358}
359
360#[derive(Debug, Clone, PartialEq)]
362pub enum JoinType {
363 Inner,
364 Left,
365 Right,
366 Full,
367 Cross,
368}
369
370#[derive(Debug, Clone, PartialEq)]
372pub enum JoinOperator {
373 Equal,
374 NotEqual,
375 LessThan,
376 GreaterThan,
377 LessThanOrEqual,
378 GreaterThanOrEqual,
379}
380
381#[derive(Debug, Clone)]
383pub struct JoinCondition {
384 pub left_column: String, pub operator: JoinOperator, pub right_column: String, }
388
389#[derive(Debug, Clone)]
391pub struct JoinClause {
392 pub join_type: JoinType,
393 pub table: TableSource, pub alias: Option<String>, pub condition: JoinCondition, }