1mod expr;
7mod stmt;
8mod types;
9
10pub use types::StructField as TypeStructField;
12pub use types::{DataTypeKind, DataTypeSpec};
13
14pub use expr::*;
16
17pub use stmt::*;
19
20use crate::error::Span;
21
22#[derive(Debug, Clone, PartialEq, Eq, Hash)]
24pub struct Ident {
25 pub value: String,
27 pub quoted: bool,
29 pub span: Span,
31}
32
33impl Ident {
34 pub fn new(value: impl Into<String>, span: Span) -> Self {
35 Self {
36 value: value.into(),
37 quoted: false,
38 span,
39 }
40 }
41
42 pub fn quoted(value: impl Into<String>, span: Span) -> Self {
43 Self {
44 value: value.into(),
45 quoted: true,
46 span,
47 }
48 }
49
50 pub fn matches(&self, other: &str) -> bool {
52 if self.quoted {
53 self.value == other
54 } else {
55 self.value.eq_ignore_ascii_case(other)
56 }
57 }
58}
59
60impl std::fmt::Display for Ident {
61 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
62 if self.quoted {
63 write!(f, "`{}`", self.value)
64 } else {
65 write!(f, "{}", self.value)
66 }
67 }
68}
69
70#[derive(Debug, Clone, PartialEq)]
72pub struct ObjectName {
73 pub parts: Vec<Ident>,
74 pub span: Span,
75}
76
77impl ObjectName {
78 pub fn new(parts: Vec<Ident>, span: Span) -> Self {
79 Self { parts, span }
80 }
81
82 pub fn simple(name: Ident) -> Self {
83 let span = name.span;
84 Self {
85 parts: vec![name],
86 span,
87 }
88 }
89
90 pub fn name(&self) -> Option<&Ident> {
92 self.parts.last()
93 }
94
95 pub fn schema(&self) -> Option<&Ident> {
97 if self.parts.len() >= 2 {
98 Some(&self.parts[self.parts.len() - 2])
99 } else {
100 None
101 }
102 }
103
104 pub fn catalog(&self) -> Option<&Ident> {
106 if self.parts.len() >= 3 {
107 Some(&self.parts[self.parts.len() - 3])
108 } else {
109 None
110 }
111 }
112}
113
114impl std::fmt::Display for ObjectName {
115 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
116 let parts: Vec<String> = self.parts.iter().map(|p| p.to_string()).collect();
117 write!(f, "{}", parts.join("."))
118 }
119}
120
121#[derive(Debug, Clone, PartialEq)]
123pub struct ColumnDef {
124 pub name: Ident,
125 pub data_type: Option<DataTypeSpec>,
126 pub constraints: Vec<ColumnConstraint>,
127 pub options: Vec<SqlOption>,
128 pub span: Span,
129}
130
131#[derive(Debug, Clone, PartialEq)]
133pub enum ColumnConstraint {
134 NotNull,
135 Null,
136 PrimaryKey,
137 Unique,
138 Default(Box<Expr>),
139 Check(Box<Expr>),
140 References {
141 table: ObjectName,
142 columns: Vec<Ident>,
143 on_delete: Option<ReferentialAction>,
144 on_update: Option<ReferentialAction>,
145 },
146 Generated {
147 expr: Box<Expr>,
148 always: bool,
149 },
150 Hidden,
151}
152
153#[derive(Debug, Clone, Copy, PartialEq, Eq)]
155pub enum ReferentialAction {
156 NoAction,
157 Restrict,
158 Cascade,
159 SetNull,
160 SetDefault,
161}
162
163#[derive(Debug, Clone, PartialEq)]
165pub enum TableConstraint {
166 PrimaryKey {
167 name: Option<Ident>,
168 columns: Vec<SortKey>,
169 options: Vec<SqlOption>,
170 },
171 Unique {
172 name: Option<Ident>,
173 columns: Vec<Ident>,
174 },
175 ForeignKey {
176 name: Option<Ident>,
177 columns: Vec<Ident>,
178 references_table: ObjectName,
179 references_columns: Vec<Ident>,
180 on_delete: Option<ReferentialAction>,
181 on_update: Option<ReferentialAction>,
182 },
183 Check {
184 name: Option<Ident>,
185 expr: Box<Expr>,
186 enforced: Option<bool>,
187 },
188}
189
190#[derive(Debug, Clone, PartialEq)]
192pub struct SortKey {
193 pub column: Ident,
194 pub order: Option<SortOrder>,
195 pub nulls: Option<NullsOrder>,
196}
197
198#[derive(Debug, Clone, Copy, PartialEq, Eq)]
200pub enum SortOrder {
201 Asc,
202 Desc,
203}
204
205#[derive(Debug, Clone, Copy, PartialEq, Eq)]
207pub enum NullsOrder {
208 First,
209 Last,
210}
211
212#[derive(Debug, Clone, PartialEq)]
214pub struct SqlOption {
215 pub name: Ident,
216 pub value: Box<Expr>,
217}
218
219#[derive(Debug, Clone, PartialEq)]
221pub struct Alias {
222 pub name: Ident,
223 pub columns: Vec<Ident>,
224}
225
226impl Alias {
227 pub fn new(name: Ident) -> Self {
228 Self {
229 name,
230 columns: Vec::new(),
231 }
232 }
233
234 pub fn with_columns(name: Ident, columns: Vec<Ident>) -> Self {
235 Self { name, columns }
236 }
237}
238
239#[derive(Debug, Clone, PartialEq)]
241pub struct WithClause {
242 pub recursive: bool,
243 pub ctes: Vec<Cte>,
244 pub span: Span,
245}
246
247#[derive(Debug, Clone, PartialEq)]
249pub struct Cte {
250 pub name: Ident,
251 pub columns: Vec<Ident>,
252 pub query: Box<Query>,
253 pub span: Span,
254}
255
256#[derive(Debug, Clone, PartialEq)]
258pub struct Query {
259 pub with: Option<WithClause>,
260 pub body: QueryBody,
261 pub order_by: Vec<OrderByExpr>,
262 pub limit: Option<LimitClause>,
263 pub span: Span,
264}
265
266#[derive(Debug, Clone, PartialEq)]
268pub enum QueryBody {
269 Select(Box<Select>),
270 SetOperation {
271 op: SetOperator,
272 all: bool,
273 left: Box<QueryBody>,
274 right: Box<QueryBody>,
275 },
276 Parenthesized(Box<Query>),
277}
278
279#[derive(Debug, Clone, Copy, PartialEq, Eq)]
281pub enum SetOperator {
282 Union,
283 Intersect,
284 Except,
285}
286
287#[derive(Debug, Clone, PartialEq)]
289pub struct LimitClause {
290 pub count: Option<Box<Expr>>,
291 pub offset: Option<Box<Expr>>,
292}
293
294#[derive(Debug, Clone, PartialEq)]
296pub struct OrderByExpr {
297 pub expr: Box<Expr>,
298 pub order: Option<SortOrder>,
299 pub nulls: Option<NullsOrder>,
300}
301
302#[derive(Debug, Clone, PartialEq)]
304pub struct Select {
305 pub distinct: Option<Distinct>,
306 pub select_as: Option<SelectAs>,
308 pub projection: Vec<SelectItem>,
309 pub from: Option<FromClause>,
310 pub where_clause: Option<Box<Expr>>,
311 pub group_by: Option<GroupByClause>,
312 pub having: Option<Box<Expr>>,
313 pub qualify: Option<Box<Expr>>,
314 pub window: Vec<WindowDef>,
315 pub span: Span,
316}
317
318#[derive(Debug, Clone, PartialEq)]
320pub enum SelectAs {
321 Struct,
323 Value,
325 TypeName(ObjectName),
327}
328
329#[derive(Debug, Clone, PartialEq)]
331pub enum Distinct {
332 All,
333 Distinct,
334}
335
336#[derive(Debug, Clone, PartialEq)]
338pub enum SelectItem {
339 Expr {
341 expr: Box<Expr>,
342 alias: Option<Ident>,
343 },
344 Wildcard,
346 QualifiedWildcard { qualifier: ObjectName },
348 WildcardExcept {
350 qualifier: Option<ObjectName>,
351 except: Vec<Ident>,
352 },
353 WildcardReplace {
355 qualifier: Option<ObjectName>,
356 replace: Vec<(Box<Expr>, Ident)>,
357 },
358}
359
360#[derive(Debug, Clone, PartialEq)]
362pub struct FromClause {
363 pub tables: Vec<TableRef>,
364}
365
366#[derive(Debug, Clone, PartialEq)]
368pub enum TableRef {
369 Table {
371 name: ObjectName,
372 alias: Option<Alias>,
373 hints: Vec<SqlOption>,
374 },
375 Subquery {
377 query: Box<Query>,
378 alias: Option<Alias>,
379 },
380 Unnest {
382 expr: Box<Expr>,
383 alias: Option<Alias>,
384 with_offset: bool,
385 offset_alias: Option<Ident>,
386 },
387 Join {
389 left: Box<TableRef>,
390 right: Box<TableRef>,
391 join_type: JoinType,
392 condition: Option<JoinCondition>,
393 },
394 Parenthesized(Box<TableRef>),
396 TableFunction {
398 name: ObjectName,
399 args: Vec<FunctionArg>,
400 alias: Option<Alias>,
401 },
402}
403
404#[derive(Debug, Clone, Copy, PartialEq, Eq)]
406pub enum JoinType {
407 Inner,
408 Left,
409 Right,
410 Full,
411 Cross,
412 Natural,
413 LeftSemi,
414 RightSemi,
415 LeftAnti,
416 RightAnti,
417}
418
419#[derive(Debug, Clone, PartialEq)]
421pub enum JoinCondition {
422 On(Box<Expr>),
423 Using(Vec<Ident>),
424}
425
426#[derive(Debug, Clone, PartialEq)]
428pub struct GroupByClause {
429 pub items: Vec<GroupByItem>,
430}
431
432#[derive(Debug, Clone, PartialEq)]
434pub enum GroupByItem {
435 Expr(Box<Expr>),
436 Rollup(Vec<Box<Expr>>),
437 Cube(Vec<Box<Expr>>),
438 GroupingSets(Vec<Vec<Box<Expr>>>),
439}
440
441#[derive(Debug, Clone, PartialEq)]
443pub struct WindowDef {
444 pub name: Ident,
445 pub spec: WindowSpec,
446}
447
448#[derive(Debug, Clone, PartialEq)]
450pub struct WindowSpec {
451 pub partition_by: Vec<Box<Expr>>,
452 pub order_by: Vec<OrderByExpr>,
453 pub frame: Option<WindowFrame>,
454}
455
456#[derive(Debug, Clone, PartialEq)]
458pub struct WindowFrame {
459 pub unit: WindowFrameUnit,
460 pub start: WindowFrameBound,
461 pub end: Option<WindowFrameBound>,
462}
463
464#[derive(Debug, Clone, Copy, PartialEq, Eq)]
466pub enum WindowFrameUnit {
467 Rows,
468 Range,
469 Groups,
470}
471
472#[derive(Debug, Clone, PartialEq)]
474pub enum WindowFrameBound {
475 CurrentRow,
476 Preceding(Option<Box<Expr>>), Following(Option<Box<Expr>>), }