sea_query/table/
column.rs

1use std::fmt;
2
3use crate::{expr::*, types::*};
4
5/// Specification of a table column
6#[derive(Debug, Clone)]
7pub struct ColumnDef {
8    pub(crate) table: Option<TableRef>,
9    pub(crate) name: DynIden,
10    pub(crate) types: Option<ColumnType>,
11    pub(crate) spec: Vec<ColumnSpec>,
12}
13
14pub trait IntoColumnDef {
15    fn into_column_def(self) -> ColumnDef;
16}
17
18/// All column types
19///
20/// | ColumnType            | MySQL data type   | PostgreSQL data type        | SQLite data type             |
21/// |-----------------------|-------------------|-----------------------------|------------------------------|
22/// | Char                  | char              | char                        | char                         |
23/// | String                | varchar           | varchar                     | varchar                      |
24/// | Text                  | text              | text                        | text                         |
25/// | TinyInteger           | tinyint           | smallint                    | tinyint                      |
26/// | SmallInteger          | smallint          | smallint                    | smallint                     |
27/// | Integer               | int               | integer                     | integer                      |
28/// | BigInteger            | bigint            | bigint                      | integer                      |
29/// | TinyUnsigned          | tinyint unsigned  | smallint                    | tinyint                      |
30/// | SmallUnsigned         | smallint unsigned | smallint                    | smallint                     |
31/// | Unsigned              | int unsigned      | integer                     | integer                      |
32/// | BigUnsigned           | bigint unsigned   | bigint                      | integer                      |
33/// | Float                 | float             | real                        | float                        |
34/// | Double                | double            | double precision            | double                       |
35/// | Decimal               | decimal           | decimal                     | real                         |
36/// | DateTime              | datetime          | timestamp without time zone | datetime_text                |
37/// | Timestamp             | timestamp         | timestamp                   | timestamp_text               |
38/// | TimestampWithTimeZone | timestamp         | timestamp with time zone    | timestamp_with_timezone_text |
39/// | Time                  | time              | time                        | time_text                    |
40/// | Date                  | date              | date                        | date_text                    |
41/// | Year                  | year              | N/A                         | N/A                          |
42/// | Interval              | N/A               | interval                    | N/A                          |
43/// | Blob                  | blob              | bytea                       | blob                         |
44/// | Binary                | binary            | bytea                       | blob                         |
45/// | VarBinary             | varbinary         | bytea                       | varbinary_blob               |
46/// | Bit                   | bit               | bit                         | N/A                          |
47/// | VarBit                | bit               | varbit                      | N/A                          |
48/// | Boolean               | bool              | bool                        | boolean                      |
49/// | Money                 | decimal           | money                       | real_money                   |
50/// | Json                  | json              | json                        | json_text                    |
51/// | JsonBinary            | json              | jsonb                       | jsonb_text                   |
52/// | Uuid                  | binary(16)        | uuid                        | uuid_text                    |
53/// | Enum                  | ENUM(...)         | ENUM_NAME                   | enum_text                    |
54/// | Array                 | N/A               | DATA_TYPE[]                 | N/A                          |
55/// | Vector                | N/A               | vector                      | N/A                          |
56/// | Cidr                  | N/A               | cidr                        | N/A                          |
57/// | Inet                  | N/A               | inet                        | N/A                          |
58/// | MacAddr               | N/A               | macaddr                     | N/A                          |
59/// | LTree                 | N/A               | ltree                       | N/A                          |
60#[non_exhaustive]
61#[derive(Debug, Clone)]
62pub enum ColumnType {
63    Char(Option<u32>),
64    String(StringLen),
65    Text,
66    Blob,
67    TinyInteger,
68    SmallInteger,
69    Integer,
70    BigInteger,
71    TinyUnsigned,
72    SmallUnsigned,
73    Unsigned,
74    BigUnsigned,
75    Float,
76    Double,
77    Decimal(Option<(u32, u32)>),
78    DateTime,
79    Timestamp,
80    TimestampWithTimeZone,
81    Time,
82    Date,
83    Year,
84    Interval(Option<PgInterval>, Option<u32>),
85    Binary(u32),
86    VarBinary(StringLen),
87    Bit(Option<u32>),
88    VarBit(u32),
89    Boolean,
90    Money(Option<(u32, u32)>),
91    Json,
92    JsonBinary,
93    Uuid,
94    Custom(DynIden),
95    Enum {
96        name: DynIden,
97        variants: Vec<DynIden>,
98    },
99    Array(RcOrArc<ColumnType>),
100    Vector(Option<u32>),
101    Cidr,
102    Inet,
103    MacAddr,
104    LTree,
105}
106
107/// Length for var-char/binary; default to 255
108#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
109pub enum StringLen {
110    /// String size
111    N(u32),
112    Max,
113    #[default]
114    None,
115}
116
117impl PartialEq for ColumnType {
118    fn eq(&self, other: &Self) -> bool {
119        match (self, other) {
120            (Self::Char(l0), Self::Char(r0)) => l0 == r0,
121            (Self::String(l0), Self::String(r0)) => l0 == r0,
122            (Self::Decimal(l0), Self::Decimal(r0)) => l0 == r0,
123            (Self::Interval(l0, l1), Self::Interval(r0, r1)) => l0 == r0 && l1 == r1,
124            (Self::Binary(l0), Self::Binary(r0)) => l0 == r0,
125            (Self::VarBinary(l0), Self::VarBinary(r0)) => l0 == r0,
126            (Self::Bit(l0), Self::Bit(r0)) => l0 == r0,
127            (Self::VarBit(l0), Self::VarBit(r0)) => l0 == r0,
128            (Self::Money(l0), Self::Money(r0)) => l0 == r0,
129            (Self::Custom(l0), Self::Custom(r0)) => l0.to_string() == r0.to_string(),
130            (
131                Self::Enum {
132                    name: l_name,
133                    variants: l_variants,
134                },
135                Self::Enum {
136                    name: r_name,
137                    variants: r_variants,
138                },
139            ) => {
140                l_name.to_string() == r_name.to_string()
141                    && l_variants
142                        .iter()
143                        .map(|v| v.to_string())
144                        .eq(r_variants.iter().map(|v| v.to_string()))
145            }
146            (Self::Array(l0), Self::Array(r0)) => l0 == r0,
147            _ => core::mem::discriminant(self) == core::mem::discriminant(other),
148        }
149    }
150}
151
152impl ColumnType {
153    pub fn custom<T>(ty: T) -> ColumnType
154    where
155        T: Into<String>,
156    {
157        ColumnType::Custom(Alias::new(ty).into_iden())
158    }
159
160    pub fn string(length: Option<u32>) -> ColumnType {
161        match length {
162            Some(s) => ColumnType::String(StringLen::N(s)),
163            None => ColumnType::String(StringLen::None),
164        }
165    }
166
167    pub fn var_binary(length: u32) -> ColumnType {
168        ColumnType::VarBinary(StringLen::N(length))
169    }
170}
171
172/// All column specification keywords
173#[derive(Debug, Clone)]
174pub enum ColumnSpec {
175    Null,
176    NotNull,
177    Default(SimpleExpr),
178    AutoIncrement,
179    UniqueKey,
180    PrimaryKey,
181    Check(SimpleExpr),
182    Generated { expr: SimpleExpr, stored: bool },
183    Extra(String),
184    Comment(String),
185    Using(SimpleExpr),
186}
187
188// All interval fields
189#[derive(Debug, Clone, Eq, PartialEq)]
190pub enum PgInterval {
191    Year,
192    Month,
193    Day,
194    Hour,
195    Minute,
196    Second,
197    YearToMonth,
198    DayToHour,
199    DayToMinute,
200    DayToSecond,
201    HourToMinute,
202    HourToSecond,
203    MinuteToSecond,
204}
205
206// All possible inputs to DATE_TRUNC (https://www.postgresql.org/docs/current/functions-datetime.html#FUNCTIONS-DATETIME-TRUNC)
207#[derive(Debug, Clone, Eq, PartialEq)]
208pub enum PgDateTruncUnit {
209    Microseconds,
210    Milliseconds,
211    Second,
212    Minute,
213    Hour,
214    Day,
215    Week,
216    Month,
217    Quarter,
218    Year,
219    Decade,
220    Century,
221    Millennium,
222}
223
224impl fmt::Display for PgDateTruncUnit {
225    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
226        let text = match self {
227            PgDateTruncUnit::Microseconds => "microseconds",
228            PgDateTruncUnit::Milliseconds => "milliseconds",
229            PgDateTruncUnit::Second => "second",
230            PgDateTruncUnit::Minute => "minute",
231            PgDateTruncUnit::Hour => "hour",
232            PgDateTruncUnit::Day => "day",
233            PgDateTruncUnit::Week => "week",
234            PgDateTruncUnit::Month => "month",
235            PgDateTruncUnit::Quarter => "quarter",
236            PgDateTruncUnit::Year => "year",
237            PgDateTruncUnit::Decade => "decade",
238            PgDateTruncUnit::Century => "century",
239            PgDateTruncUnit::Millennium => "millennium",
240        };
241        write!(f, "{}", text)
242    }
243}
244
245impl ColumnDef {
246    /// Construct a table column
247    pub fn new<T>(name: T) -> Self
248    where
249        T: IntoIden,
250    {
251        Self {
252            table: None,
253            name: name.into_iden(),
254            types: None,
255            spec: Vec::new(),
256        }
257    }
258
259    /// Construct a table column with column type
260    pub fn new_with_type<T>(name: T, types: ColumnType) -> Self
261    where
262        T: IntoIden,
263    {
264        Self {
265            table: None,
266            name: name.into_iden(),
267            types: Some(types),
268            spec: Vec::new(),
269        }
270    }
271
272    /// Set column not null
273    pub fn not_null(&mut self) -> &mut Self {
274        self.spec.push(ColumnSpec::NotNull);
275        self
276    }
277
278    /// Set column null
279    pub fn null(&mut self) -> &mut Self {
280        self.spec.push(ColumnSpec::Null);
281        self
282    }
283
284    /// Set default expression of a column
285    ///
286    /// ```
287    /// use sea_query::{tests_cfg::*, *};
288    ///
289    /// let table = Table::create()
290    ///     .table(Char::Table)
291    ///     .col(ColumnDef::new(Char::FontId).integer().default(12i32))
292    ///     .col(
293    ///         ColumnDef::new(Char::CreatedAt)
294    ///             .timestamp()
295    ///             .default(Expr::current_timestamp())
296    ///             .not_null(),
297    ///     )
298    ///     .to_owned();
299    ///
300    /// assert_eq!(
301    ///     table.to_string(MysqlQueryBuilder),
302    ///     [
303    ///         "CREATE TABLE `character` (",
304    ///         "`font_id` int DEFAULT 12,",
305    ///         "`created_at` timestamp DEFAULT CURRENT_TIMESTAMP NOT NULL",
306    ///         ")",
307    ///     ]
308    ///     .join(" ")
309    /// );
310    ///
311    /// assert_eq!(
312    ///     table.to_string(PostgresQueryBuilder),
313    ///     [
314    ///         r#"CREATE TABLE "character" ("#,
315    ///         r#""font_id" integer DEFAULT 12,"#,
316    ///         r#""created_at" timestamp DEFAULT CURRENT_TIMESTAMP NOT NULL"#,
317    ///         r#")"#,
318    ///     ]
319    ///     .join(" ")
320    /// );
321    /// ```
322    pub fn default<T>(&mut self, value: T) -> &mut Self
323    where
324        T: Into<SimpleExpr>,
325    {
326        self.spec.push(ColumnSpec::Default(value.into()));
327        self
328    }
329
330    /// Set column auto increment
331    pub fn auto_increment(&mut self) -> &mut Self {
332        self.spec.push(ColumnSpec::AutoIncrement);
333        self
334    }
335
336    /// Set column unique constraint
337    pub fn unique_key(&mut self) -> &mut Self {
338        self.spec.push(ColumnSpec::UniqueKey);
339        self
340    }
341
342    /// Set column as primary key
343    pub fn primary_key(&mut self) -> &mut Self {
344        self.spec.push(ColumnSpec::PrimaryKey);
345        self
346    }
347
348    /// Set column type as char with custom length
349    pub fn char_len(&mut self, length: u32) -> &mut Self {
350        self.types = Some(ColumnType::Char(Some(length)));
351        self
352    }
353
354    /// Set column type as char
355    pub fn char(&mut self) -> &mut Self {
356        self.types = Some(ColumnType::Char(None));
357        self
358    }
359
360    /// Set column type as string with custom length
361    pub fn string_len(&mut self, length: u32) -> &mut Self {
362        self.types = Some(ColumnType::String(StringLen::N(length)));
363        self
364    }
365
366    /// Set column type as string
367    pub fn string(&mut self) -> &mut Self {
368        self.types = Some(ColumnType::String(Default::default()));
369        self
370    }
371
372    /// Set column type as text
373    pub fn text(&mut self) -> &mut Self {
374        self.types = Some(ColumnType::Text);
375        self
376    }
377
378    /// Set column type as tiny_integer
379    pub fn tiny_integer(&mut self) -> &mut Self {
380        self.types = Some(ColumnType::TinyInteger);
381        self
382    }
383
384    /// Set column type as small_integer
385    pub fn small_integer(&mut self) -> &mut Self {
386        self.types = Some(ColumnType::SmallInteger);
387        self
388    }
389
390    /// Set column type as integer
391    pub fn integer(&mut self) -> &mut Self {
392        self.types = Some(ColumnType::Integer);
393        self
394    }
395
396    /// Set column type as big_integer
397    pub fn big_integer(&mut self) -> &mut Self {
398        self.types = Some(ColumnType::BigInteger);
399        self
400    }
401
402    /// Set column type as tiny_unsigned
403    pub fn tiny_unsigned(&mut self) -> &mut Self {
404        self.types = Some(ColumnType::TinyUnsigned);
405        self
406    }
407
408    /// Set column type as small_unsigned
409    pub fn small_unsigned(&mut self) -> &mut Self {
410        self.types = Some(ColumnType::SmallUnsigned);
411        self
412    }
413
414    /// Set column type as unsigned
415    pub fn unsigned(&mut self) -> &mut Self {
416        self.types = Some(ColumnType::Unsigned);
417        self
418    }
419
420    /// Set column type as big_unsigned
421    pub fn big_unsigned(&mut self) -> &mut Self {
422        self.types = Some(ColumnType::BigUnsigned);
423        self
424    }
425
426    /// Set column type as float
427    pub fn float(&mut self) -> &mut Self {
428        self.types = Some(ColumnType::Float);
429        self
430    }
431
432    /// Set column type as double
433    pub fn double(&mut self) -> &mut Self {
434        self.types = Some(ColumnType::Double);
435        self
436    }
437
438    /// Set column type as decimal with custom precision and scale
439    pub fn decimal_len(&mut self, precision: u32, scale: u32) -> &mut Self {
440        self.types = Some(ColumnType::Decimal(Some((precision, scale))));
441        self
442    }
443
444    /// Set column type as decimal
445    pub fn decimal(&mut self) -> &mut Self {
446        self.types = Some(ColumnType::Decimal(None));
447        self
448    }
449
450    /// Set column type as date_time
451    pub fn date_time(&mut self) -> &mut Self {
452        self.types = Some(ColumnType::DateTime);
453        self
454    }
455
456    /// Set column type as interval type with optional fields and precision. Postgres only
457    ///
458    /// ```
459    /// use sea_query::{tests_cfg::*, *};
460    /// assert_eq!(
461    ///     Table::create()
462    ///         .table(Glyph::Table)
463    ///         .col(
464    ///             ColumnDef::new(Alias::new("I1"))
465    ///                 .interval(None, None)
466    ///                 .not_null()
467    ///         )
468    ///         .col(
469    ///             ColumnDef::new(Alias::new("I2"))
470    ///                 .interval(Some(PgInterval::YearToMonth), None)
471    ///                 .not_null()
472    ///         )
473    ///         .col(
474    ///             ColumnDef::new(Alias::new("I3"))
475    ///                 .interval(None, Some(42))
476    ///                 .not_null()
477    ///         )
478    ///         .col(
479    ///             ColumnDef::new(Alias::new("I4"))
480    ///                 .interval(Some(PgInterval::Hour), Some(43))
481    ///                 .not_null()
482    ///         )
483    ///         .to_string(PostgresQueryBuilder),
484    ///     [
485    ///         r#"CREATE TABLE "glyph" ("#,
486    ///         r#""I1" interval NOT NULL,"#,
487    ///         r#""I2" interval YEAR TO MONTH NOT NULL,"#,
488    ///         r#""I3" interval(42) NOT NULL,"#,
489    ///         r#""I4" interval HOUR(43) NOT NULL"#,
490    ///         r#")"#,
491    ///     ]
492    ///     .join(" ")
493    /// );
494    /// ```
495    #[cfg(feature = "backend-postgres")]
496    pub fn interval(&mut self, fields: Option<PgInterval>, precision: Option<u32>) -> &mut Self {
497        self.types = Some(ColumnType::Interval(fields, precision));
498        self
499    }
500
501    #[cfg(feature = "postgres-vector")]
502    pub fn vector(&mut self, size: Option<u32>) -> &mut Self {
503        self.types = Some(ColumnType::Vector(size));
504        self
505    }
506
507    /// Set column type as timestamp
508    pub fn timestamp(&mut self) -> &mut Self {
509        self.types = Some(ColumnType::Timestamp);
510        self
511    }
512
513    /// Set column type as timestamp with time zone. Postgres only
514    pub fn timestamp_with_time_zone(&mut self) -> &mut Self {
515        self.types = Some(ColumnType::TimestampWithTimeZone);
516        self
517    }
518
519    /// Set column type as time
520    pub fn time(&mut self) -> &mut Self {
521        self.types = Some(ColumnType::Time);
522        self
523    }
524
525    /// Set column type as date
526    pub fn date(&mut self) -> &mut Self {
527        self.types = Some(ColumnType::Date);
528        self
529    }
530
531    /// Set column type as year
532    /// Only MySQL supports year
533    pub fn year(&mut self) -> &mut Self {
534        self.types = Some(ColumnType::Year);
535        self
536    }
537
538    /// Set column type as binary with custom length
539    pub fn binary_len(&mut self, length: u32) -> &mut Self {
540        self.types = Some(ColumnType::Binary(length));
541        self
542    }
543
544    /// Set column type as binary with default length of 1
545    pub fn binary(&mut self) -> &mut Self {
546        self.binary_len(1)
547    }
548
549    /// Set column type as binary with variable length
550    pub fn var_binary(&mut self, length: u32) -> &mut Self {
551        self.types = Some(ColumnType::VarBinary(StringLen::N(length)));
552        self
553    }
554
555    /// Set column type as bit with variable length
556    pub fn bit(&mut self, length: Option<u32>) -> &mut Self {
557        self.types = Some(ColumnType::Bit(length));
558        self
559    }
560
561    /// Set column type as varbit with variable length
562    pub fn varbit(&mut self, length: u32) -> &mut Self {
563        self.types = Some(ColumnType::VarBit(length));
564        self
565    }
566
567    /// Set column type as blob
568    pub fn blob(&mut self) -> &mut Self {
569        self.types = Some(ColumnType::Blob);
570        self
571    }
572
573    /// Set column type as boolean
574    pub fn boolean(&mut self) -> &mut Self {
575        self.types = Some(ColumnType::Boolean);
576        self
577    }
578
579    /// Set column type as money with custom precision and scale
580    pub fn money_len(&mut self, precision: u32, scale: u32) -> &mut Self {
581        self.types = Some(ColumnType::Money(Some((precision, scale))));
582        self
583    }
584
585    /// Set column type as money
586    pub fn money(&mut self) -> &mut Self {
587        self.types = Some(ColumnType::Money(None));
588        self
589    }
590
591    /// Set column type as json.
592    pub fn json(&mut self) -> &mut Self {
593        self.types = Some(ColumnType::Json);
594        self
595    }
596
597    /// Set column type as json binary.
598    pub fn json_binary(&mut self) -> &mut Self {
599        self.types = Some(ColumnType::JsonBinary);
600        self
601    }
602
603    /// Set column type as uuid
604    pub fn uuid(&mut self) -> &mut Self {
605        self.types = Some(ColumnType::Uuid);
606        self
607    }
608
609    /// Use a custom type on this column.
610    pub fn custom<T>(&mut self, name: T) -> &mut Self
611    where
612        T: IntoIden,
613    {
614        self.types = Some(ColumnType::Custom(name.into_iden()));
615        self
616    }
617
618    /// Set column type as enum.
619    pub fn enumeration<N, S, V>(&mut self, name: N, variants: V) -> &mut Self
620    where
621        N: IntoIden,
622        S: IntoIden,
623        V: IntoIterator<Item = S>,
624    {
625        self.types = Some(ColumnType::Enum {
626            name: name.into_iden(),
627            variants: variants.into_iter().map(IntoIden::into_iden).collect(),
628        });
629        self
630    }
631
632    /// Set column type as an array with a specified element type.
633    /// This is only supported on Postgres.
634    pub fn array(&mut self, elem_type: ColumnType) -> &mut Self {
635        self.types = Some(ColumnType::Array(RcOrArc::new(elem_type)));
636        self
637    }
638
639    /// Set columnt type as cidr.
640    /// This is only supported on Postgres.
641    pub fn cidr(&mut self) -> &mut Self {
642        self.types = Some(ColumnType::Cidr);
643        self
644    }
645
646    /// Set columnt type as inet.
647    /// This is only supported on Postgres.
648    pub fn inet(&mut self) -> &mut Self {
649        self.types = Some(ColumnType::Inet);
650        self
651    }
652
653    /// Set columnt type as macaddr.
654    /// This is only supported on Postgres.
655    pub fn mac_address(&mut self) -> &mut Self {
656        self.types = Some(ColumnType::MacAddr);
657        self
658    }
659
660    /// Set column type as `ltree`
661    /// This is only supported on Postgres.
662    ///
663    /// ```
664    /// use sea_query::{tests_cfg::*, *};
665    /// assert_eq!(
666    ///     Table::create()
667    ///         .table(Glyph::Table)
668    ///         .col(
669    ///             ColumnDef::new(Glyph::Id)
670    ///                 .integer()
671    ///                 .not_null()
672    ///                 .auto_increment()
673    ///                 .primary_key()
674    ///         )
675    ///         .col(ColumnDef::new(Glyph::Tokens).ltree())
676    ///         .to_string(PostgresQueryBuilder),
677    ///     [
678    ///         r#"CREATE TABLE "glyph" ("#,
679    ///         r#""id" serial NOT NULL PRIMARY KEY,"#,
680    ///         r#""tokens" ltree"#,
681    ///         r#")"#,
682    ///     ]
683    ///     .join(" ")
684    /// );
685    /// ```
686    pub fn ltree(&mut self) -> &mut Self {
687        self.types = Some(ColumnType::LTree);
688        self
689    }
690
691    /// Set constraints as SimpleExpr
692    ///
693    /// ```
694    /// use sea_query::{tests_cfg::*, *};
695    /// assert_eq!(
696    ///     Table::create()
697    ///         .table(Glyph::Table)
698    ///         .col(
699    ///             ColumnDef::new(Glyph::Id)
700    ///                 .integer()
701    ///                 .not_null()
702    ///                 .check(Expr::col(Glyph::Id).gt(10))
703    ///         )
704    ///         .to_string(MysqlQueryBuilder),
705    ///     r#"CREATE TABLE `glyph` ( `id` int NOT NULL CHECK (`id` > 10) )"#,
706    /// );
707    /// ```
708    pub fn check<T>(&mut self, value: T) -> &mut Self
709    where
710        T: Into<SimpleExpr>,
711    {
712        self.spec.push(ColumnSpec::Check(value.into()));
713        self
714    }
715
716    /// Sets the column as generated with SimpleExpr
717    pub fn generated<T>(&mut self, expr: T, stored: bool) -> &mut Self
718    where
719        T: Into<SimpleExpr>,
720    {
721        self.spec.push(ColumnSpec::Generated {
722            expr: expr.into(),
723            stored,
724        });
725        self
726    }
727
728    /// Some extra options in custom string
729    /// ```
730    /// use sea_query::{tests_cfg::*, *};
731    /// let table = Table::create()
732    ///     .table(Char::Table)
733    ///     .col(
734    ///         ColumnDef::new(Char::Id)
735    ///             .uuid()
736    ///             .extra("DEFAULT gen_random_uuid()")
737    ///             .primary_key()
738    ///             .not_null(),
739    ///     )
740    ///     .col(
741    ///         ColumnDef::new(Char::CreatedAt)
742    ///             .timestamp_with_time_zone()
743    ///             .extra("DEFAULT NOW()")
744    ///             .not_null(),
745    ///     )
746    ///     .to_owned();
747    /// assert_eq!(
748    ///     table.to_string(PostgresQueryBuilder),
749    ///     [
750    ///         r#"CREATE TABLE "character" ("#,
751    ///         r#""id" uuid DEFAULT gen_random_uuid() PRIMARY KEY NOT NULL,"#,
752    ///         r#""created_at" timestamp with time zone DEFAULT NOW() NOT NULL"#,
753    ///         r#")"#,
754    ///     ]
755    ///     .join(" ")
756    /// );
757    /// ```
758    pub fn extra<T>(&mut self, string: T) -> &mut Self
759    where
760        T: Into<String>,
761    {
762        self.spec.push(ColumnSpec::Extra(string.into()));
763        self
764    }
765
766    /// Some extra options in custom string
767    /// ```
768    /// use sea_query::{tests_cfg::*, *};
769    /// let table = Table::alter()
770    ///     .table(Char::Table)
771    ///     .modify_column(
772    ///         ColumnDef::new(Char::Id)
773    ///             .integer()
774    ///             .using(Expr::col(Char::Id).cast_as(Alias::new("integer"))),
775    ///     )
776    ///     .to_owned();
777    /// assert_eq!(
778    ///     table.to_string(PostgresQueryBuilder),
779    ///     [
780    ///         r#"ALTER TABLE "character""#,
781    ///         r#"ALTER COLUMN "id" TYPE integer USING CAST("id" AS integer)"#,
782    ///     ]
783    ///     .join(" ")
784    /// );
785    /// ```
786    pub fn using<T>(&mut self, value: T) -> &mut Self
787    where
788        T: Into<SimpleExpr>,
789    {
790        self.spec.push(ColumnSpec::Using(value.into()));
791        self
792    }
793
794    /// MySQL only.
795    pub fn comment<T>(&mut self, string: T) -> &mut Self
796    where
797        T: Into<String>,
798    {
799        self.spec.push(ColumnSpec::Comment(string.into()));
800        self
801    }
802
803    pub fn get_column_name(&self) -> String {
804        self.name.to_string()
805    }
806
807    pub fn get_column_type(&self) -> Option<&ColumnType> {
808        self.types.as_ref()
809    }
810
811    pub fn get_column_spec(&self) -> &Vec<ColumnSpec> {
812        self.spec.as_ref()
813    }
814
815    pub fn take(&mut self) -> Self {
816        Self {
817            table: self.table.take(),
818            name: std::mem::replace(&mut self.name, SeaRc::new(NullAlias::new())),
819            types: self.types.take(),
820            spec: std::mem::take(&mut self.spec),
821        }
822    }
823}
824
825impl IntoColumnDef for &mut ColumnDef {
826    fn into_column_def(self) -> ColumnDef {
827        self.take()
828    }
829}
830
831impl IntoColumnDef for ColumnDef {
832    fn into_column_def(self) -> ColumnDef {
833        self
834    }
835}