sea_query/backend/postgres/
table.rs1use super::*;
2use crate::write_int;
3
4impl TableBuilder for PostgresQueryBuilder {
5 fn prepare_column_def(&self, column_def: &ColumnDef, sql: &mut impl SqlWriter) {
6 fn f(this: &PostgresQueryBuilder, column_def: &ColumnDef, sql: &mut impl SqlWriter) {
7 this.prepare_column_type_check_auto_increment(column_def, sql);
8 }
9
10 self.prepare_column_def_common(column_def, sql, |column_def, sql| f(self, column_def, sql));
11 }
12
13 fn prepare_column_type(&self, column_type: &ColumnType, sql: &mut impl SqlWriter) {
14 match column_type {
15 ColumnType::Char(length) => match length {
16 Some(length) => {
17 sql.write_str("char(").unwrap();
18 write_int(sql, *length);
19 sql.write_char(')')
20 }
21 None => sql.write_str("char"),
22 },
23 ColumnType::String(length) => match length {
24 StringLen::N(length) => {
25 sql.write_str("varchar(").unwrap();
26 write_int(sql, *length);
27 sql.write_char(')')
28 }
29 _ => sql.write_str("varchar"),
30 },
31 ColumnType::Text => sql.write_str("text"),
32 ColumnType::TinyInteger | ColumnType::TinyUnsigned => sql.write_str("smallint"),
33 ColumnType::SmallInteger | ColumnType::SmallUnsigned => sql.write_str("smallint"),
34 ColumnType::Integer | ColumnType::Unsigned => sql.write_str("integer"),
35 ColumnType::BigInteger | ColumnType::BigUnsigned => sql.write_str("bigint"),
36 ColumnType::Float => sql.write_str("real"),
37 ColumnType::Double => sql.write_str("double precision"),
38 ColumnType::Decimal(precision) => match precision {
39 Some((precision, scale)) => {
40 sql.write_str("decimal(").unwrap();
41 write_int(sql, *precision);
42 sql.write_str(", ").unwrap();
43 write_int(sql, *scale);
44 sql.write_char(')')
45 }
46 None => sql.write_str("decimal"),
47 },
48 ColumnType::DateTime => sql.write_str("timestamp without time zone"),
49 ColumnType::Timestamp => sql.write_str("timestamp"),
50 ColumnType::TimestampWithTimeZone => sql.write_str("timestamp with time zone"),
51 ColumnType::Time => sql.write_str("time"),
52 ColumnType::Date => sql.write_str("date"),
53 ColumnType::Interval(fields, precision) => {
54 sql.write_str("interval").unwrap();
55
56 if let Some(fields) = fields {
57 write!(sql, " {fields}").unwrap();
58 }
59
60 if let Some(precision) = precision {
61 sql.write_char('(').unwrap();
62 write_int(sql, *precision);
63 sql.write_char(')').unwrap();
64 }
65 Ok(())
66 }
67 ColumnType::Binary(_) | ColumnType::VarBinary(_) | ColumnType::Blob => {
68 sql.write_str("bytea")
69 }
70 ColumnType::Bit(length) => match length {
71 Some(length) => {
72 sql.write_str("bit(").unwrap();
73 write_int(sql, *length);
74 sql.write_char(')')
75 }
76 None => sql.write_str("bit"),
77 },
78 ColumnType::VarBit(length) => {
79 sql.write_str("varbit(").unwrap();
80 write_int(sql, *length);
81 sql.write_char(')')
82 }
83 ColumnType::Boolean => sql.write_str("bool"),
84 ColumnType::Money(precision) => match precision {
85 Some((precision, scale)) => {
86 sql.write_str("money(").unwrap();
87 write_int(sql, *precision);
88 sql.write_str(", ").unwrap();
89 write_int(sql, *scale);
90 sql.write_char(')')
91 }
92 None => sql.write_str("money"),
93 },
94 ColumnType::Json => sql.write_str("json"),
95 ColumnType::JsonBinary => sql.write_str("jsonb"),
96 ColumnType::Uuid => sql.write_str("uuid"),
97 ColumnType::Array(elem_type) => {
98 self.prepare_column_type(elem_type, sql);
99 sql.write_str("[]")
100 }
101 ColumnType::Vector(size) => match size {
102 Some(size) => {
103 sql.write_str("vector(").unwrap();
104 write_int(sql, *size);
105 sql.write_str(")")
106 }
107 None => sql.write_str("vector"),
108 },
109 ColumnType::Custom(iden) => sql.write_str(&iden.0),
110 ColumnType::Enum { name, .. } => sql.write_str(&name.0),
111 ColumnType::Cidr => sql.write_str("cidr"),
112 ColumnType::Inet => sql.write_str("inet"),
113 ColumnType::MacAddr => sql.write_str("macaddr"),
114 ColumnType::Year => unimplemented!("Year is not available in Postgres."),
115 ColumnType::LTree => sql.write_str("ltree"),
116 }
117 .unwrap()
118 }
119
120 fn column_spec_auto_increment_keyword(&self) -> &str {
121 ""
122 }
123
124 fn prepare_table_alter_statement(&self, alter: &TableAlterStatement, sql: &mut impl SqlWriter) {
125 if alter.options.is_empty() {
126 panic!("No alter option found")
127 };
128 sql.write_str("ALTER TABLE ").unwrap();
129 if let Some(table) = &alter.table {
130 self.prepare_table_ref_table_stmt(table, sql);
131 sql.write_str(" ").unwrap();
132 }
133
134 let mut opts = alter.options.iter();
135
136 join_io!(
137 opts,
138 opt,
139 join {
140 sql.write_str(", ").unwrap();
141 },
142 do {
143 match opt {
144 TableAlterOption::AddColumn(AddColumnOption {
145 column,
146 if_not_exists,
147 }) => {
148 sql.write_str("ADD COLUMN ").unwrap();
149 if *if_not_exists {
150 sql.write_str("IF NOT EXISTS ").unwrap();
151 }
152
153 self.prepare_column_def_common(column, sql, |column_def, sql| {
154 if let Some(column_type) = &column_def.types {
155 write!(sql, " ").unwrap();
156 if column_def.spec.auto_increment {
157 self.prepare_column_auto_increment(column_type, sql);
158 } else {
159 self.prepare_column_type(column_type, sql);
160 }
161 }
162 });
163 }
164 TableAlterOption::ModifyColumn(column_def) => {
165 self.prepare_modify_column(sql, column_def);
166 }
167 TableAlterOption::RenameColumn(from_name, to_name) => {
168 sql.write_str("RENAME COLUMN ").unwrap();
169 self.prepare_iden(from_name, sql);
170 sql.write_str(" TO ").unwrap();
171 self.prepare_iden(to_name, sql);
172 }
173 TableAlterOption::DropColumn(column_name) => {
174 sql.write_str("DROP COLUMN ").unwrap();
175 self.prepare_iden(column_name, sql);
176 }
177 TableAlterOption::DropForeignKey(name) => {
178 let mut foreign_key = TableForeignKey::new();
179 foreign_key.name(name.to_string());
180 let drop = ForeignKeyDropStatement {
181 foreign_key,
182 table: None,
183 };
184 self.prepare_foreign_key_drop_statement_internal(
185 &drop,
186 sql,
187 Mode::TableAlter,
188 );
189 }
190 TableAlterOption::AddForeignKey(foreign_key) => {
191 let create = ForeignKeyCreateStatement {
192 foreign_key: foreign_key.to_owned(),
193 };
194 self.prepare_foreign_key_create_statement_internal(
195 &create,
196 sql,
197 Mode::TableAlter,
198 );
199 }
200 }
201 }
202 );
203 }
204
205 fn prepare_table_rename_statement(
206 &self,
207 rename: &TableRenameStatement,
208 sql: &mut impl SqlWriter,
209 ) {
210 sql.write_str("ALTER TABLE ").unwrap();
211 if let Some(from_name) = &rename.from_name {
212 self.prepare_table_ref_table_stmt(from_name, sql);
213 }
214 sql.write_str(" RENAME TO ").unwrap();
215 if let Some(to_name) = &rename.to_name {
216 self.prepare_table_ref_table_stmt(to_name, sql);
217 }
218 }
219}
220
221impl PostgresQueryBuilder {
222 fn prepare_column_auto_increment(&self, column_type: &ColumnType, sql: &mut impl SqlWriter) {
223 let num_ty = match column_type {
224 ColumnType::SmallInteger => "smallint GENERATED BY DEFAULT AS IDENTITY",
225 ColumnType::Integer => "integer GENERATED BY DEFAULT AS IDENTITY",
226 ColumnType::BigInteger => "bigint GENERATED BY DEFAULT AS IDENTITY",
227 _ => unimplemented!("{:?} doesn't support auto increment", column_type),
228 };
229
230 sql.write_str(num_ty).unwrap();
231 }
232
233 fn prepare_column_type_check_auto_increment(
234 &self,
235 column_def: &ColumnDef,
236 sql: &mut impl SqlWriter,
237 ) {
238 if let Some(column_type) = &column_def.types {
239 let is_auto_increment = column_def.spec.auto_increment;
240
241 sql.write_str(" ").unwrap();
242
243 if is_auto_increment {
244 self.prepare_column_auto_increment(column_type, sql);
245 } else {
246 self.prepare_column_type(column_type, sql);
247 }
248 }
249 }
250
251 fn prepare_column_def_common<F, W>(&self, column_def: &ColumnDef, sql: &mut W, f: F)
252 where
253 F: Fn(&ColumnDef, &mut W),
254 W: SqlWriter,
255 {
256 self.prepare_iden(&column_def.name, sql);
257
258 f(column_def, sql);
259
260 self.prepare_column_spec(&column_def.spec, sql);
261 }
262
263 fn prepare_modify_column(&self, sql: &mut impl SqlWriter, column_def: &ColumnDef) {
264 let mut is_first = true;
265
266 macro_rules! write_comma_if_not_first {
267 () => {
268 if !is_first {
269 write!(sql, ", ").unwrap();
270 } else {
271 is_first = false
272 }
273 };
274 }
275
276 if let Some(column_type) = &column_def.types {
277 write!(sql, "ALTER COLUMN ").unwrap();
278 self.prepare_iden(&column_def.name, sql);
279 write!(sql, " TYPE ").unwrap();
280 self.prepare_column_type(column_type, sql);
281 is_first = false;
282 }
283
284 if column_def.spec.auto_increment {
285 }
287
288 if let Some(nullable) = column_def.spec.nullable {
289 write_comma_if_not_first!();
290 write!(sql, "ALTER COLUMN ").unwrap();
291 self.prepare_iden(&column_def.name, sql);
292 if nullable {
293 write!(sql, " DROP NOT NULL").unwrap();
294 } else {
295 write!(sql, " SET NOT NULL").unwrap();
296 }
297 }
298
299 if let Some(default) = &column_def.spec.default {
300 write_comma_if_not_first!();
301 write!(sql, "ALTER COLUMN ").unwrap();
302 self.prepare_iden(&column_def.name, sql);
303 write!(sql, " SET DEFAULT ").unwrap();
304 QueryBuilder::prepare_expr(self, default, sql);
305 }
306 if column_def.spec.unique {
307 write_comma_if_not_first!();
308 write!(sql, "ADD UNIQUE (").unwrap();
309 self.prepare_iden(&column_def.name, sql);
310 write!(sql, ")").unwrap();
311 }
312 if column_def.spec.primary_key {
313 write_comma_if_not_first!();
314 write!(sql, "ADD PRIMARY KEY (").unwrap();
315 self.prepare_iden(&column_def.name, sql);
316 write!(sql, ")").unwrap();
317 }
318 if let Some(check) = &column_def.spec.check {
319 write_comma_if_not_first!();
320 self.prepare_check_constraint(check, sql);
321 }
322
323 if let Some(x) = &column_def.spec.generated {
324 let _ = x;
325 }
326
327 if let Some(x) = &column_def.spec.comment {
328 let _ = x;
329 }
330
331 if let Some(expr) = &column_def.spec.using {
332 write!(sql, " USING ").unwrap();
333 QueryBuilder::prepare_expr(self, expr, sql);
334 }
335
336 if let Some(extra) = &column_def.spec.extra {
337 write!(sql, "{extra}").unwrap()
338 }
339
340 let _ = is_first;
341 }
342}