1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)]
12pub enum QuoteStyle {
13 #[default]
15 None,
16 DoubleQuote,
18 Backtick,
20 Bracket,
22}
23
24impl QuoteStyle {
25 #[must_use]
27 pub fn for_dialect(dialect: crate::dialects::Dialect) -> Self {
28 use crate::dialects::Dialect;
29 match dialect {
30 Dialect::Tsql | Dialect::Fabric => QuoteStyle::Bracket,
31 Dialect::Mysql | Dialect::BigQuery | Dialect::Hive | Dialect::Spark
32 | Dialect::Databricks | Dialect::Doris | Dialect::SingleStore
33 | Dialect::StarRocks => QuoteStyle::Backtick,
34 _ => QuoteStyle::DoubleQuote,
36 }
37 }
38
39 #[must_use]
41 pub fn is_quoted(self) -> bool {
42 !matches!(self, QuoteStyle::None)
43 }
44}
45
46#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
54pub enum Statement {
55 Select(SelectStatement),
56 Insert(InsertStatement),
57 Update(UpdateStatement),
58 Delete(DeleteStatement),
59 CreateTable(CreateTableStatement),
60 DropTable(DropTableStatement),
61 SetOperation(SetOperationStatement),
63 AlterTable(AlterTableStatement),
65 CreateView(CreateViewStatement),
67 DropView(DropViewStatement),
69 Truncate(TruncateStatement),
71 Transaction(TransactionStatement),
73 Explain(ExplainStatement),
75 Use(UseStatement),
77 Expression(Expr),
79}
80
81#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
90pub struct SelectStatement {
91 pub ctes: Vec<Cte>,
93 pub distinct: bool,
94 pub top: Option<Box<Expr>>,
96 pub columns: Vec<SelectItem>,
97 pub from: Option<FromClause>,
98 pub joins: Vec<JoinClause>,
99 pub where_clause: Option<Expr>,
100 pub group_by: Vec<Expr>,
101 pub having: Option<Expr>,
102 pub order_by: Vec<OrderByItem>,
103 pub limit: Option<Expr>,
104 pub offset: Option<Expr>,
105 pub fetch_first: Option<Expr>,
107 pub qualify: Option<Expr>,
109 pub window_definitions: Vec<WindowDefinition>,
111}
112
113#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
115pub struct Cte {
116 pub name: String,
117 pub columns: Vec<String>,
118 pub query: Box<Statement>,
119 pub materialized: Option<bool>,
120 pub recursive: bool,
121}
122
123#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
125pub struct WindowDefinition {
126 pub name: String,
127 pub spec: WindowSpec,
128}
129
130#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
136pub struct SetOperationStatement {
137 pub op: SetOperationType,
138 pub all: bool,
139 pub left: Box<Statement>,
140 pub right: Box<Statement>,
141 pub order_by: Vec<OrderByItem>,
142 pub limit: Option<Expr>,
143 pub offset: Option<Expr>,
144}
145
146#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
147pub enum SetOperationType {
148 Union,
149 Intersect,
150 Except,
151}
152
153#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
159pub enum SelectItem {
160 Wildcard,
162 QualifiedWildcard { table: String },
164 Expr { expr: Expr, alias: Option<String> },
166}
167
168#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
170pub struct FromClause {
171 pub source: TableSource,
172}
173
174#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
176pub enum TableSource {
177 Table(TableRef),
178 Subquery {
179 query: Box<Statement>,
180 alias: Option<String>,
181 },
182 TableFunction {
183 name: String,
184 args: Vec<Expr>,
185 alias: Option<String>,
186 },
187 Lateral {
189 source: Box<TableSource>,
190 },
191 Unnest {
193 expr: Box<Expr>,
194 alias: Option<String>,
195 with_offset: bool,
196 },
197}
198
199#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
201pub struct TableRef {
202 pub catalog: Option<String>,
203 pub schema: Option<String>,
204 pub name: String,
205 pub alias: Option<String>,
206 #[serde(default)]
208 pub name_quote_style: QuoteStyle,
209}
210
211#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
213pub struct JoinClause {
214 pub join_type: JoinType,
215 pub table: TableSource,
216 pub on: Option<Expr>,
217 pub using: Vec<String>,
218}
219
220#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
222pub enum JoinType {
223 Inner,
224 Left,
225 Right,
226 Full,
227 Cross,
228 Natural,
230 Lateral,
232}
233
234#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
236pub struct OrderByItem {
237 pub expr: Expr,
238 pub ascending: bool,
239 pub nulls_first: Option<bool>,
241}
242
243#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
255pub enum Expr {
256 Column {
258 table: Option<String>,
259 name: String,
260 #[serde(default)]
262 quote_style: QuoteStyle,
263 #[serde(default)]
265 table_quote_style: QuoteStyle,
266 },
267 Number(String),
269 StringLiteral(String),
271 Boolean(bool),
273 Null,
275 BinaryOp {
277 left: Box<Expr>,
278 op: BinaryOperator,
279 right: Box<Expr>,
280 },
281 UnaryOp {
283 op: UnaryOperator,
284 expr: Box<Expr>,
285 },
286 Function {
288 name: String,
289 args: Vec<Expr>,
290 distinct: bool,
291 filter: Option<Box<Expr>>,
293 over: Option<WindowSpec>,
295 },
296 Between {
298 expr: Box<Expr>,
299 low: Box<Expr>,
300 high: Box<Expr>,
301 negated: bool,
302 },
303 InList {
305 expr: Box<Expr>,
306 list: Vec<Expr>,
307 negated: bool,
308 },
309 InSubquery {
311 expr: Box<Expr>,
312 subquery: Box<Statement>,
313 negated: bool,
314 },
315 AnyOp {
317 expr: Box<Expr>,
318 op: BinaryOperator,
319 right: Box<Expr>,
320 },
321 AllOp {
323 expr: Box<Expr>,
324 op: BinaryOperator,
325 right: Box<Expr>,
326 },
327 IsNull {
329 expr: Box<Expr>,
330 negated: bool,
331 },
332 IsBool {
334 expr: Box<Expr>,
335 value: bool,
336 negated: bool,
337 },
338 Like {
340 expr: Box<Expr>,
341 pattern: Box<Expr>,
342 negated: bool,
343 escape: Option<Box<Expr>>,
344 },
345 ILike {
347 expr: Box<Expr>,
348 pattern: Box<Expr>,
349 negated: bool,
350 escape: Option<Box<Expr>>,
351 },
352 Case {
354 operand: Option<Box<Expr>>,
355 when_clauses: Vec<(Expr, Expr)>,
356 else_clause: Option<Box<Expr>>,
357 },
358 Nested(Box<Expr>),
360 Wildcard,
362 Subquery(Box<Statement>),
364 Exists {
366 subquery: Box<Statement>,
367 negated: bool,
368 },
369 Cast {
371 expr: Box<Expr>,
372 data_type: DataType,
373 },
374 TryCast {
376 expr: Box<Expr>,
377 data_type: DataType,
378 },
379 Extract {
381 field: DateTimeField,
382 expr: Box<Expr>,
383 },
384 Interval {
386 value: Box<Expr>,
387 unit: Option<DateTimeField>,
388 },
389 ArrayLiteral(Vec<Expr>),
391 Tuple(Vec<Expr>),
393 Coalesce(Vec<Expr>),
395 If {
397 condition: Box<Expr>,
398 true_val: Box<Expr>,
399 false_val: Option<Box<Expr>>,
400 },
401 NullIf {
403 expr: Box<Expr>,
404 r#else: Box<Expr>,
405 },
406 Collate {
408 expr: Box<Expr>,
409 collation: String,
410 },
411 Parameter(String),
413 TypeExpr(DataType),
415 QualifiedWildcard { table: String },
417 Star,
419 Alias {
421 expr: Box<Expr>,
422 name: String,
423 },
424 ArrayIndex {
426 expr: Box<Expr>,
427 index: Box<Expr>,
428 },
429 JsonAccess {
431 expr: Box<Expr>,
432 path: Box<Expr>,
433 as_text: bool,
435 },
436 Lambda {
438 params: Vec<String>,
439 body: Box<Expr>,
440 },
441 Default,
443}
444
445#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
451pub struct WindowSpec {
452 pub window_ref: Option<String>,
454 pub partition_by: Vec<Expr>,
455 pub order_by: Vec<OrderByItem>,
456 pub frame: Option<WindowFrame>,
457}
458
459#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
460pub struct WindowFrame {
461 pub kind: WindowFrameKind,
462 pub start: WindowFrameBound,
463 pub end: Option<WindowFrameBound>,
464}
465
466#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
467pub enum WindowFrameKind {
468 Rows,
469 Range,
470 Groups,
471}
472
473#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
474pub enum WindowFrameBound {
475 CurrentRow,
476 Preceding(Option<Box<Expr>>), Following(Option<Box<Expr>>), }
479
480#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
485pub enum DateTimeField {
486 Year,
487 Quarter,
488 Month,
489 Week,
490 Day,
491 DayOfWeek,
492 DayOfYear,
493 Hour,
494 Minute,
495 Second,
496 Millisecond,
497 Microsecond,
498 Nanosecond,
499 Epoch,
500 Timezone,
501 TimezoneHour,
502 TimezoneMinute,
503}
504
505#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
511pub enum BinaryOperator {
512 Plus,
513 Minus,
514 Multiply,
515 Divide,
516 Modulo,
517 Eq,
518 Neq,
519 Lt,
520 Gt,
521 LtEq,
522 GtEq,
523 And,
524 Or,
525 Xor,
526 Concat,
527 BitwiseAnd,
528 BitwiseOr,
529 BitwiseXor,
530 ShiftLeft,
531 ShiftRight,
532 Arrow,
534 DoubleArrow,
536}
537
538#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
540pub enum UnaryOperator {
541 Not,
542 Minus,
543 Plus,
544 BitwiseNot,
545}
546
547#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
553pub struct InsertStatement {
554 pub table: TableRef,
555 pub columns: Vec<String>,
556 pub source: InsertSource,
557 pub on_conflict: Option<OnConflict>,
559 pub returning: Vec<SelectItem>,
561}
562
563#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
564pub enum InsertSource {
565 Values(Vec<Vec<Expr>>),
566 Query(Box<Statement>),
567 Default,
568}
569
570#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
571pub struct OnConflict {
572 pub columns: Vec<String>,
573 pub action: ConflictAction,
574}
575
576#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
577pub enum ConflictAction {
578 DoNothing,
579 DoUpdate(Vec<(String, Expr)>),
580}
581
582#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
584pub struct UpdateStatement {
585 pub table: TableRef,
586 pub assignments: Vec<(String, Expr)>,
587 pub from: Option<FromClause>,
588 pub where_clause: Option<Expr>,
589 pub returning: Vec<SelectItem>,
590}
591
592#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
594pub struct DeleteStatement {
595 pub table: TableRef,
596 pub using: Option<FromClause>,
597 pub where_clause: Option<Expr>,
598 pub returning: Vec<SelectItem>,
599}
600
601#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
607pub struct CreateTableStatement {
608 pub if_not_exists: bool,
609 pub temporary: bool,
610 pub table: TableRef,
611 pub columns: Vec<ColumnDef>,
612 pub constraints: Vec<TableConstraint>,
613 pub as_select: Option<Box<Statement>>,
615}
616
617#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
619pub enum TableConstraint {
620 PrimaryKey {
621 name: Option<String>,
622 columns: Vec<String>,
623 },
624 Unique {
625 name: Option<String>,
626 columns: Vec<String>,
627 },
628 ForeignKey {
629 name: Option<String>,
630 columns: Vec<String>,
631 ref_table: TableRef,
632 ref_columns: Vec<String>,
633 on_delete: Option<ReferentialAction>,
634 on_update: Option<ReferentialAction>,
635 },
636 Check {
637 name: Option<String>,
638 expr: Expr,
639 },
640}
641
642#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
643pub enum ReferentialAction {
644 Cascade,
645 Restrict,
646 NoAction,
647 SetNull,
648 SetDefault,
649}
650
651#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
653pub struct ColumnDef {
654 pub name: String,
655 pub data_type: DataType,
656 pub nullable: Option<bool>,
657 pub default: Option<Expr>,
658 pub primary_key: bool,
659 pub unique: bool,
660 pub auto_increment: bool,
661 pub collation: Option<String>,
662 pub comment: Option<String>,
663}
664
665#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
667pub struct AlterTableStatement {
668 pub table: TableRef,
669 pub actions: Vec<AlterTableAction>,
670}
671
672#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
673pub enum AlterTableAction {
674 AddColumn(ColumnDef),
675 DropColumn { name: String, if_exists: bool },
676 RenameColumn { old_name: String, new_name: String },
677 AlterColumnType { name: String, data_type: DataType },
678 AddConstraint(TableConstraint),
679 DropConstraint { name: String },
680 RenameTable { new_name: String },
681}
682
683#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
685pub struct CreateViewStatement {
686 pub name: TableRef,
687 pub columns: Vec<String>,
688 pub query: Box<Statement>,
689 pub or_replace: bool,
690 pub materialized: bool,
691 pub if_not_exists: bool,
692}
693
694#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
696pub struct DropViewStatement {
697 pub name: TableRef,
698 pub if_exists: bool,
699 pub materialized: bool,
700}
701
702#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
704pub struct TruncateStatement {
705 pub table: TableRef,
706}
707
708#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
710pub enum TransactionStatement {
711 Begin,
712 Commit,
713 Rollback,
714 Savepoint(String),
715 ReleaseSavepoint(String),
716 RollbackTo(String),
717}
718
719#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
721pub struct ExplainStatement {
722 pub analyze: bool,
723 pub statement: Box<Statement>,
724}
725
726#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
728pub struct UseStatement {
729 pub name: String,
730}
731
732#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
734pub struct DropTableStatement {
735 pub if_exists: bool,
736 pub table: TableRef,
737 pub cascade: bool,
738}
739
740#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
746pub enum DataType {
747 TinyInt,
749 SmallInt,
750 Int,
751 BigInt,
752 Float,
753 Double,
754 Decimal { precision: Option<u32>, scale: Option<u32> },
755 Numeric { precision: Option<u32>, scale: Option<u32> },
756 Real,
757
758 Varchar(Option<u32>),
760 Char(Option<u32>),
761 Text,
762 String,
763 Binary(Option<u32>),
764 Varbinary(Option<u32>),
765
766 Boolean,
768
769 Date,
771 Time { precision: Option<u32> },
772 Timestamp { precision: Option<u32>, with_tz: bool },
773 Interval,
774 DateTime,
775
776 Blob,
778 Bytea,
779 Bytes,
780
781 Json,
783 Jsonb,
784
785 Uuid,
787
788 Array(Option<Box<DataType>>),
790 Map { key: Box<DataType>, value: Box<DataType> },
791 Struct(Vec<(String, DataType)>),
792 Tuple(Vec<DataType>),
793
794 Null,
796 Unknown(String),
797 Variant,
798 Object,
799 Xml,
800 Inet,
801 Cidr,
802 Macaddr,
803 Bit(Option<u32>),
804 Money,
805 Serial,
806 BigSerial,
807 SmallSerial,
808 Regclass,
809 Regtype,
810 Hstore,
811 Geography,
812 Geometry,
813 Super,
814}
815
816impl Expr {
821 pub fn walk<F>(&self, visitor: &mut F)
824 where
825 F: FnMut(&Expr) -> bool,
826 {
827 if !visitor(self) {
828 return;
829 }
830 match self {
831 Expr::BinaryOp { left, right, .. } => {
832 left.walk(visitor);
833 right.walk(visitor);
834 }
835 Expr::UnaryOp { expr, .. } => expr.walk(visitor),
836 Expr::Function { args, filter, .. } => {
837 for arg in args {
838 arg.walk(visitor);
839 }
840 if let Some(f) = filter {
841 f.walk(visitor);
842 }
843 }
844 Expr::Between { expr, low, high, .. } => {
845 expr.walk(visitor);
846 low.walk(visitor);
847 high.walk(visitor);
848 }
849 Expr::InList { expr, list, .. } => {
850 expr.walk(visitor);
851 for item in list {
852 item.walk(visitor);
853 }
854 }
855 Expr::InSubquery { expr, .. } => {
856 expr.walk(visitor);
857 }
858 Expr::IsNull { expr, .. } => expr.walk(visitor),
859 Expr::IsBool { expr, .. } => expr.walk(visitor),
860 Expr::AnyOp { expr, right, .. } | Expr::AllOp { expr, right, .. } => {
861 expr.walk(visitor);
862 right.walk(visitor);
863 }
864 Expr::Like { expr, pattern, .. } | Expr::ILike { expr, pattern, .. } => {
865 expr.walk(visitor);
866 pattern.walk(visitor);
867 }
868 Expr::Case {
869 operand,
870 when_clauses,
871 else_clause,
872 } => {
873 if let Some(op) = operand {
874 op.walk(visitor);
875 }
876 for (cond, result) in when_clauses {
877 cond.walk(visitor);
878 result.walk(visitor);
879 }
880 if let Some(el) = else_clause {
881 el.walk(visitor);
882 }
883 }
884 Expr::Nested(inner) => inner.walk(visitor),
885 Expr::Cast { expr, .. } | Expr::TryCast { expr, .. } => expr.walk(visitor),
886 Expr::Extract { expr, .. } => expr.walk(visitor),
887 Expr::Interval { value, .. } => value.walk(visitor),
888 Expr::ArrayLiteral(items) | Expr::Tuple(items) | Expr::Coalesce(items) => {
889 for item in items {
890 item.walk(visitor);
891 }
892 }
893 Expr::If { condition, true_val, false_val } => {
894 condition.walk(visitor);
895 true_val.walk(visitor);
896 if let Some(fv) = false_val {
897 fv.walk(visitor);
898 }
899 }
900 Expr::NullIf { expr, r#else } => {
901 expr.walk(visitor);
902 r#else.walk(visitor);
903 }
904 Expr::Collate { expr, .. } => expr.walk(visitor),
905 Expr::Alias { expr, .. } => expr.walk(visitor),
906 Expr::ArrayIndex { expr, index } => {
907 expr.walk(visitor);
908 index.walk(visitor);
909 }
910 Expr::JsonAccess { expr, path, .. } => {
911 expr.walk(visitor);
912 path.walk(visitor);
913 }
914 Expr::Lambda { body, .. } => body.walk(visitor),
915 Expr::Column { .. }
917 | Expr::Number(_)
918 | Expr::StringLiteral(_)
919 | Expr::Boolean(_)
920 | Expr::Null
921 | Expr::Wildcard
922 | Expr::Star
923 | Expr::Parameter(_)
924 | Expr::TypeExpr(_)
925 | Expr::QualifiedWildcard { .. }
926 | Expr::Default
927 | Expr::Subquery(_)
928 | Expr::Exists { .. } => {}
929 }
930 }
931
932 #[must_use]
934 pub fn find<F>(&self, predicate: &F) -> Option<&Expr>
935 where
936 F: Fn(&Expr) -> bool,
937 {
938 let mut result = None;
939 self.walk(&mut |expr| {
940 if result.is_some() {
941 return false;
942 }
943 if predicate(expr) {
944 result = Some(expr as *const Expr);
945 false
946 } else {
947 true
948 }
949 });
950 result.map(|p| unsafe { &*p })
952 }
953
954 #[must_use]
956 pub fn find_all<F>(&self, predicate: &F) -> Vec<&Expr>
957 where
958 F: Fn(&Expr) -> bool,
959 {
960 let mut results: Vec<*const Expr> = Vec::new();
961 self.walk(&mut |expr| {
962 if predicate(expr) {
963 results.push(expr as *const Expr);
964 }
965 true
966 });
967 results.into_iter().map(|p| unsafe { &*p }).collect()
968 }
969
970 #[must_use]
973 pub fn transform<F>(self, func: &F) -> Expr
974 where
975 F: Fn(Expr) -> Expr,
976 {
977 let transformed = match self {
978 Expr::BinaryOp { left, op, right } => Expr::BinaryOp {
979 left: Box::new(left.transform(func)),
980 op,
981 right: Box::new(right.transform(func)),
982 },
983 Expr::UnaryOp { op, expr } => Expr::UnaryOp {
984 op,
985 expr: Box::new(expr.transform(func)),
986 },
987 Expr::Function { name, args, distinct, filter, over } => Expr::Function {
988 name,
989 args: args.into_iter().map(|a| a.transform(func)).collect(),
990 distinct,
991 filter: filter.map(|f| Box::new(f.transform(func))),
992 over,
993 },
994 Expr::Nested(inner) => Expr::Nested(Box::new(inner.transform(func))),
995 Expr::Cast { expr, data_type } => Expr::Cast {
996 expr: Box::new(expr.transform(func)),
997 data_type,
998 },
999 Expr::Between { expr, low, high, negated } => Expr::Between {
1000 expr: Box::new(expr.transform(func)),
1001 low: Box::new(low.transform(func)),
1002 high: Box::new(high.transform(func)),
1003 negated,
1004 },
1005 Expr::Case { operand, when_clauses, else_clause } => Expr::Case {
1006 operand: operand.map(|o| Box::new(o.transform(func))),
1007 when_clauses: when_clauses
1008 .into_iter()
1009 .map(|(c, r)| (c.transform(func), r.transform(func)))
1010 .collect(),
1011 else_clause: else_clause.map(|e| Box::new(e.transform(func))),
1012 },
1013 Expr::IsBool { expr, value, negated } => Expr::IsBool {
1014 expr: Box::new(expr.transform(func)),
1015 value,
1016 negated,
1017 },
1018 Expr::AnyOp { expr, op, right } => Expr::AnyOp {
1019 expr: Box::new(expr.transform(func)),
1020 op,
1021 right: Box::new(right.transform(func)),
1022 },
1023 Expr::AllOp { expr, op, right } => Expr::AllOp {
1024 expr: Box::new(expr.transform(func)),
1025 op,
1026 right: Box::new(right.transform(func)),
1027 },
1028 other => other,
1029 };
1030 func(transformed)
1031 }
1032
1033 #[must_use]
1035 pub fn is_column(&self) -> bool {
1036 matches!(self, Expr::Column { .. })
1037 }
1038
1039 #[must_use]
1041 pub fn is_literal(&self) -> bool {
1042 matches!(
1043 self,
1044 Expr::Number(_) | Expr::StringLiteral(_) | Expr::Boolean(_) | Expr::Null
1045 )
1046 }
1047
1048 #[must_use]
1051 pub fn sql(&self) -> String {
1052 use crate::generator::Generator;
1053 Generator::expr_to_sql(self)
1054 }
1055}
1056
1057#[must_use]
1059pub fn find_columns(expr: &Expr) -> Vec<&Expr> {
1060 expr.find_all(&|e| matches!(e, Expr::Column { .. }))
1061}
1062
1063#[must_use]
1065pub fn find_tables(statement: &Statement) -> Vec<&TableRef> {
1066 match statement {
1067 Statement::Select(sel) => {
1068 let mut tables = Vec::new();
1069 if let Some(from) = &sel.from {
1070 collect_table_refs_from_source(&from.source, &mut tables);
1071 }
1072 for join in &sel.joins {
1073 collect_table_refs_from_source(&join.table, &mut tables);
1074 }
1075 tables
1076 }
1077 Statement::Insert(ins) => vec![&ins.table],
1078 Statement::Update(upd) => vec![&upd.table],
1079 Statement::Delete(del) => vec![&del.table],
1080 Statement::CreateTable(ct) => vec![&ct.table],
1081 Statement::DropTable(dt) => vec![&dt.table],
1082 _ => vec![],
1083 }
1084}
1085
1086fn collect_table_refs_from_source<'a>(source: &'a TableSource, tables: &mut Vec<&'a TableRef>) {
1087 match source {
1088 TableSource::Table(table_ref) => tables.push(table_ref),
1089 TableSource::Subquery { .. } => {}
1090 TableSource::TableFunction { .. } => {}
1091 TableSource::Lateral { source } => collect_table_refs_from_source(source, tables),
1092 TableSource::Unnest { .. } => {}
1093 }
1094}