1use super::{display_comma_separated, DataType, Expr, Ident, ObjectName};
16use std::fmt;
17
18#[derive(Debug, Clone, PartialEq, Eq, Hash)]
20pub enum AlterTableOperation {
21 AddColumn(ColumnDef),
22 AddConstraint(TableConstraint),
24 DropColumn {
25 column: Ident,
26 if_exists: bool,
27 cascade: bool,
28 },
29 DropConstraint {
31 name: Ident,
32 },
33}
34
35impl fmt::Display for AlterTableOperation {
36 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
37 match self {
38 AlterTableOperation::AddColumn(column_def) => write!(f, "ADD COLUMN {}", column_def),
39 AlterTableOperation::AddConstraint(c) => write!(f, "ADD {}", c),
40 AlterTableOperation::DropColumn {
41 column,
42 if_exists,
43 cascade,
44 } => write!(
45 f,
46 "DROP COLUMN {}{} {}",
47 if *if_exists { "IF EXISTS " } else { " " },
48 column,
49 if *cascade { "CASCADE" } else { "" }
50 ),
51 AlterTableOperation::DropConstraint { name } => write!(f, "DROP CONSTRAINT {}", name),
52 }
53 }
54}
55
56#[derive(Debug, Clone, PartialEq, Eq, Hash)]
59pub enum TableConstraint {
60 Unique {
62 name: Option<Ident>,
63 columns: Vec<Ident>,
64 is_primary: bool,
66 },
67 ForeignKey {
70 name: Option<Ident>,
71 columns: Vec<Ident>,
72 foreign_table: ObjectName,
73 referred_columns: Vec<Ident>,
74 },
75 Check {
77 name: Option<Ident>,
78 expr: Box<Expr>,
79 },
80}
81
82impl fmt::Display for TableConstraint {
83 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
84 match self {
85 TableConstraint::Unique {
86 name,
87 columns,
88 is_primary,
89 } => write!(
90 f,
91 "{}{} ({})",
92 display_constraint_name(name),
93 if *is_primary { "PRIMARY KEY" } else { "UNIQUE" },
94 display_comma_separated(columns)
95 ),
96 TableConstraint::ForeignKey {
97 name,
98 columns,
99 foreign_table,
100 referred_columns,
101 } => write!(
102 f,
103 "{}FOREIGN KEY ({}) REFERENCES {}({})",
104 display_constraint_name(name),
105 display_comma_separated(columns),
106 foreign_table,
107 display_comma_separated(referred_columns)
108 ),
109 TableConstraint::Check { name, expr } => {
110 write!(f, "{}CHECK ({})", display_constraint_name(name), expr)
111 }
112 }
113 }
114}
115
116#[derive(Debug, Clone, PartialEq, Eq, Hash)]
118pub struct ColumnDef {
119 pub name: Ident,
120 pub data_type: DataType,
121 pub collation: Option<ObjectName>,
122 pub options: Vec<ColumnOptionDef>,
123}
124
125impl fmt::Display for ColumnDef {
126 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
127 write!(f, "{} {}", self.name, self.data_type)?;
130 for option in &self.options {
131 write!(f, " {}", option)?;
132 }
133 Ok(())
134 }
135}
136
137#[derive(Debug, Clone, PartialEq, Eq, Hash)]
154pub struct ColumnOptionDef {
155 pub name: Option<Ident>,
156 pub option: ColumnOption,
157}
158
159impl fmt::Display for ColumnOptionDef {
160 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
161 write!(f, "{}{}", display_constraint_name(&self.name), self.option)
162 }
163}
164
165#[derive(Debug, Clone, PartialEq, Eq, Hash)]
168pub enum ColumnOption {
169 Null,
171 NotNull,
173 Default(Expr),
175 Unique {
177 is_primary: bool,
178 },
179 ForeignKey {
182 foreign_table: ObjectName,
183 referred_columns: Vec<Ident>,
184 },
185 Check(Expr),
187}
188
189impl fmt::Display for ColumnOption {
190 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
191 use ColumnOption::*;
192 match self {
193 Null => write!(f, "NULL"),
194 NotNull => write!(f, "NOT NULL"),
195 Default(expr) => write!(f, "DEFAULT {}", expr),
196 Unique { is_primary } => {
197 write!(f, "{}", if *is_primary { "PRIMARY KEY" } else { "UNIQUE" })
198 }
199 ForeignKey {
200 foreign_table,
201 referred_columns,
202 } => write!(
203 f,
204 "REFERENCES {} ({})",
205 foreign_table,
206 display_comma_separated(referred_columns)
207 ),
208 Check(expr) => write!(f, "CHECK ({})", expr),
209 }
210 }
211}
212
213fn display_constraint_name(name: &Option<Ident>) -> impl fmt::Display + '_ {
214 struct ConstraintName<'a>(&'a Option<Ident>);
215 impl<'a> fmt::Display for ConstraintName<'a> {
216 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
217 if let Some(name) = self.0 {
218 write!(f, "CONSTRAINT {} ", name)?;
219 }
220 Ok(())
221 }
222 }
223 ConstraintName(name)
224}