risingwave_sqlparser/ast/
ddl.rs

1// Licensed under the Apache License, Version 2.0 (the "License");
2// you may not use this file except in compliance with the License.
3// You may obtain a copy of the License at
4//
5//     http://www.apache.org/licenses/LICENSE-2.0
6//
7// Unless required by applicable law or agreed to in writing, software
8// distributed under the License is distributed on an "AS IS" BASIS,
9// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10// See the License for the specific language governing permissions and
11// limitations under the License.
12
13//! AST types specific to CREATE/ALTER variants of [`crate::ast::Statement`]
14//! (commonly referred to as Data Definition Language, or DDL)
15
16#[cfg(not(feature = "std"))]
17use alloc::{boxed::Box, string::ToString, vec::Vec};
18use core::fmt;
19
20#[cfg(feature = "serde")]
21use serde::{Deserialize, Serialize};
22
23use super::{FormatEncodeOptions, SqlOption};
24use crate::ast::{
25    DataType, Expr, Ident, ObjectName, SecretRefValue, SetVariableValue, Value,
26    display_comma_separated, display_separated,
27};
28use crate::tokenizer::Token;
29
30#[derive(Debug, Clone, PartialEq, Eq, Hash)]
31#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
32pub enum AlterDatabaseOperation {
33    ChangeOwner { new_owner_name: Ident },
34    RenameDatabase { database_name: ObjectName },
35}
36
37#[derive(Debug, Clone, PartialEq, Eq, Hash)]
38#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
39pub enum AlterSchemaOperation {
40    ChangeOwner { new_owner_name: Ident },
41    RenameSchema { schema_name: ObjectName },
42    SwapRenameSchema { target_schema: ObjectName },
43}
44
45/// An `ALTER TABLE` (`Statement::AlterTable`) operation
46#[derive(Debug, Clone, PartialEq, Eq, Hash)]
47#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
48pub enum AlterTableOperation {
49    /// `ADD <table_constraint>`
50    AddConstraint(TableConstraint),
51    /// `ADD [ COLUMN ] <column_def>`
52    AddColumn {
53        column_def: ColumnDef,
54    },
55    /// TODO: implement `DROP CONSTRAINT <name>`
56    DropConstraint {
57        name: Ident,
58    },
59    /// `DROP [ COLUMN ] [ IF EXISTS ] <column_name> [ CASCADE ]`
60    DropColumn {
61        column_name: Ident,
62        if_exists: bool,
63        cascade: bool,
64    },
65    /// `RENAME [ COLUMN ] <old_column_name> TO <new_column_name>`
66    RenameColumn {
67        old_column_name: Ident,
68        new_column_name: Ident,
69    },
70    /// `RENAME TO <table_name>`
71    RenameTable {
72        table_name: ObjectName,
73    },
74    // CHANGE [ COLUMN ] <old_name> <new_name> <data_type> [ <options> ]
75    ChangeColumn {
76        old_name: Ident,
77        new_name: Ident,
78        data_type: DataType,
79        options: Vec<ColumnOption>,
80    },
81    /// `RENAME CONSTRAINT <old_constraint_name> TO <new_constraint_name>`
82    ///
83    /// Note: this is a PostgreSQL-specific operation.
84    RenameConstraint {
85        old_name: Ident,
86        new_name: Ident,
87    },
88    /// `ALTER [ COLUMN ]`
89    AlterColumn {
90        column_name: Ident,
91        op: AlterColumnOperation,
92    },
93    /// `OWNER TO <owner_name>`
94    ChangeOwner {
95        new_owner_name: Ident,
96    },
97    /// `SET SCHEMA <schema_name>`
98    SetSchema {
99        new_schema_name: ObjectName,
100    },
101    /// `SET PARALLELISM TO <parallelism> [ DEFERRED ]`
102    SetParallelism {
103        parallelism: SetVariableValue,
104        deferred: bool,
105    },
106    RefreshSchema,
107    /// `SET SOURCE_RATE_LIMIT TO <rate_limit>`
108    SetSourceRateLimit {
109        rate_limit: i32,
110    },
111    /// SET BACKFILL_RATE_LIMIT TO <rate_limit>
112    SetBackfillRateLimit {
113        rate_limit: i32,
114    },
115    /// `SET DML_RATE_LIMIT TO <rate_limit>`
116    SetDmlRateLimit {
117        rate_limit: i32,
118    },
119    /// `SWAP WITH <table_name>`
120    SwapRenameTable {
121        target_table: ObjectName,
122    },
123    /// `DROP CONNECTOR`
124    DropConnector,
125}
126
127#[derive(Debug, Clone, PartialEq, Eq, Hash)]
128#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
129pub enum AlterIndexOperation {
130    RenameIndex {
131        index_name: ObjectName,
132    },
133    /// `SET PARALLELISM TO <parallelism> [ DEFERRED ]`
134    SetParallelism {
135        parallelism: SetVariableValue,
136        deferred: bool,
137    },
138}
139
140#[derive(Debug, Clone, PartialEq, Eq, Hash)]
141#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
142pub enum AlterViewOperation {
143    RenameView {
144        view_name: ObjectName,
145    },
146    ChangeOwner {
147        new_owner_name: Ident,
148    },
149    SetSchema {
150        new_schema_name: ObjectName,
151    },
152    /// `SET PARALLELISM TO <parallelism> [ DEFERRED ]`
153    SetParallelism {
154        parallelism: SetVariableValue,
155        deferred: bool,
156    },
157    /// `SET RESOURCE_GROUP TO 'RESOURCE GROUP' [ DEFERRED ]`
158    /// `RESET RESOURCE_GROUP [ DEFERRED ]`
159    SetResourceGroup {
160        resource_group: Option<SetVariableValue>,
161        deferred: bool,
162    },
163    /// `SET BACKFILL_RATE_LIMIT TO <rate_limit>`
164    SetBackfillRateLimit {
165        rate_limit: i32,
166    },
167    /// `SWAP WITH <view_name>`
168    SwapRenameView {
169        target_view: ObjectName,
170    },
171}
172
173#[derive(Debug, Clone, PartialEq, Eq, Hash)]
174#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
175pub enum AlterSinkOperation {
176    RenameSink {
177        sink_name: ObjectName,
178    },
179    ChangeOwner {
180        new_owner_name: Ident,
181    },
182    SetSchema {
183        new_schema_name: ObjectName,
184    },
185    /// `SET PARALLELISM TO <parallelism> [ DEFERRED ]`
186    SetParallelism {
187        parallelism: SetVariableValue,
188        deferred: bool,
189    },
190    /// `SWAP WITH <sink_name>`
191    SwapRenameSink {
192        target_sink: ObjectName,
193    },
194    SetSinkRateLimit {
195        rate_limit: i32,
196    },
197    SetSinkProps {
198        changed_props: Vec<SqlOption>,
199    },
200}
201
202#[derive(Debug, Clone, PartialEq, Eq, Hash)]
203#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
204pub enum AlterSubscriptionOperation {
205    RenameSubscription { subscription_name: ObjectName },
206    ChangeOwner { new_owner_name: Ident },
207    SetSchema { new_schema_name: ObjectName },
208    SwapRenameSubscription { target_subscription: ObjectName },
209}
210
211#[derive(Debug, Clone, PartialEq, Eq, Hash)]
212#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
213pub enum AlterSourceOperation {
214    RenameSource {
215        source_name: ObjectName,
216    },
217    AddColumn {
218        column_def: ColumnDef,
219    },
220    ChangeOwner {
221        new_owner_name: Ident,
222    },
223    SetSchema {
224        new_schema_name: ObjectName,
225    },
226    FormatEncode {
227        format_encode: FormatEncodeOptions,
228    },
229    RefreshSchema,
230    SetSourceRateLimit {
231        rate_limit: i32,
232    },
233    SwapRenameSource {
234        target_source: ObjectName,
235    },
236    /// `SET PARALLELISM TO <parallelism> [ DEFERRED ]`
237    SetParallelism {
238        parallelism: SetVariableValue,
239        deferred: bool,
240    },
241}
242
243#[derive(Debug, Clone, PartialEq, Eq, Hash)]
244#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
245pub enum AlterFunctionOperation {
246    SetSchema { new_schema_name: ObjectName },
247}
248
249#[derive(Debug, Clone, PartialEq, Eq, Hash)]
250#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
251pub enum AlterConnectionOperation {
252    SetSchema { new_schema_name: ObjectName },
253    ChangeOwner { new_owner_name: Ident },
254}
255
256#[derive(Debug, Clone, PartialEq, Eq, Hash)]
257#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
258pub enum AlterSecretOperation {
259    ChangeCredential { new_credential: Value },
260}
261
262#[derive(Debug, Clone, PartialEq, Eq, Hash)]
263#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
264pub enum AlterFragmentOperation {
265    AlterBackfillRateLimit { rate_limit: i32 },
266}
267
268impl fmt::Display for AlterDatabaseOperation {
269    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
270        match self {
271            AlterDatabaseOperation::ChangeOwner { new_owner_name } => {
272                write!(f, "OWNER TO {}", new_owner_name)
273            }
274            AlterDatabaseOperation::RenameDatabase { database_name } => {
275                write!(f, "RENAME TO {}", database_name)
276            }
277        }
278    }
279}
280
281impl fmt::Display for AlterSchemaOperation {
282    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
283        match self {
284            AlterSchemaOperation::ChangeOwner { new_owner_name } => {
285                write!(f, "OWNER TO {}", new_owner_name)
286            }
287            AlterSchemaOperation::RenameSchema { schema_name } => {
288                write!(f, "RENAME TO {}", schema_name)
289            }
290            AlterSchemaOperation::SwapRenameSchema { target_schema } => {
291                write!(f, "SWAP WITH {}", target_schema)
292            }
293        }
294    }
295}
296
297impl fmt::Display for AlterTableOperation {
298    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
299        match self {
300            AlterTableOperation::AddConstraint(c) => write!(f, "ADD {}", c),
301            AlterTableOperation::AddColumn { column_def } => {
302                write!(f, "ADD COLUMN {}", column_def)
303            }
304            AlterTableOperation::AlterColumn { column_name, op } => {
305                write!(f, "ALTER COLUMN {} {}", column_name, op)
306            }
307            AlterTableOperation::DropConstraint { name } => write!(f, "DROP CONSTRAINT {}", name),
308            AlterTableOperation::DropColumn {
309                column_name,
310                if_exists,
311                cascade,
312            } => write!(
313                f,
314                "DROP COLUMN {}{}{}",
315                if *if_exists { "IF EXISTS " } else { "" },
316                column_name,
317                if *cascade { " CASCADE" } else { "" }
318            ),
319            AlterTableOperation::RenameColumn {
320                old_column_name,
321                new_column_name,
322            } => write!(
323                f,
324                "RENAME COLUMN {} TO {}",
325                old_column_name, new_column_name
326            ),
327            AlterTableOperation::RenameTable { table_name } => {
328                write!(f, "RENAME TO {}", table_name)
329            }
330            AlterTableOperation::ChangeColumn {
331                old_name,
332                new_name,
333                data_type,
334                options,
335            } => {
336                write!(f, "CHANGE COLUMN {} {} {}", old_name, new_name, data_type)?;
337                if options.is_empty() {
338                    Ok(())
339                } else {
340                    write!(f, " {}", display_separated(options, " "))
341                }
342            }
343            AlterTableOperation::RenameConstraint { old_name, new_name } => {
344                write!(f, "RENAME CONSTRAINT {} TO {}", old_name, new_name)
345            }
346            AlterTableOperation::ChangeOwner { new_owner_name } => {
347                write!(f, "OWNER TO {}", new_owner_name)
348            }
349            AlterTableOperation::SetSchema { new_schema_name } => {
350                write!(f, "SET SCHEMA {}", new_schema_name)
351            }
352            AlterTableOperation::SetParallelism {
353                parallelism,
354                deferred,
355            } => {
356                write!(
357                    f,
358                    "SET PARALLELISM TO {}{}",
359                    parallelism,
360                    if *deferred { " DEFERRED" } else { "" }
361                )
362            }
363            AlterTableOperation::RefreshSchema => {
364                write!(f, "REFRESH SCHEMA")
365            }
366            AlterTableOperation::SetSourceRateLimit { rate_limit } => {
367                write!(f, "SET SOURCE_RATE_LIMIT TO {}", rate_limit)
368            }
369            AlterTableOperation::SetBackfillRateLimit { rate_limit } => {
370                write!(f, "SET BACKFILL_RATE_LIMIT TO {}", rate_limit)
371            }
372            AlterTableOperation::SetDmlRateLimit { rate_limit } => {
373                write!(f, "SET DML_RATE_LIMIT TO {}", rate_limit)
374            }
375            AlterTableOperation::SwapRenameTable { target_table } => {
376                write!(f, "SWAP WITH {}", target_table)
377            }
378            AlterTableOperation::DropConnector => {
379                write!(f, "DROP CONNECTOR")
380            }
381        }
382    }
383}
384
385impl fmt::Display for AlterIndexOperation {
386    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
387        match self {
388            AlterIndexOperation::RenameIndex { index_name } => {
389                write!(f, "RENAME TO {index_name}")
390            }
391            AlterIndexOperation::SetParallelism {
392                parallelism,
393                deferred,
394            } => {
395                write!(
396                    f,
397                    "SET PARALLELISM TO {}{}",
398                    parallelism,
399                    if *deferred { " DEFERRED" } else { "" }
400                )
401            }
402        }
403    }
404}
405
406impl fmt::Display for AlterViewOperation {
407    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
408        match self {
409            AlterViewOperation::RenameView { view_name } => {
410                write!(f, "RENAME TO {view_name}")
411            }
412            AlterViewOperation::ChangeOwner { new_owner_name } => {
413                write!(f, "OWNER TO {}", new_owner_name)
414            }
415            AlterViewOperation::SetSchema { new_schema_name } => {
416                write!(f, "SET SCHEMA {}", new_schema_name)
417            }
418            AlterViewOperation::SetParallelism {
419                parallelism,
420                deferred,
421            } => {
422                write!(
423                    f,
424                    "SET PARALLELISM TO {}{}",
425                    parallelism,
426                    if *deferred { " DEFERRED" } else { "" }
427                )
428            }
429            AlterViewOperation::SetBackfillRateLimit { rate_limit } => {
430                write!(f, "SET BACKFILL_RATE_LIMIT TO {}", rate_limit)
431            }
432            AlterViewOperation::SwapRenameView { target_view } => {
433                write!(f, "SWAP WITH {}", target_view)
434            }
435            AlterViewOperation::SetResourceGroup {
436                resource_group,
437                deferred,
438            } => {
439                let deferred = if *deferred { " DEFERRED" } else { "" };
440
441                if let Some(resource_group) = resource_group {
442                    write!(f, "SET RESOURCE_GROUP TO {} {}", resource_group, deferred)
443                } else {
444                    write!(f, "RESET RESOURCE_GROUP {}", deferred)
445                }
446            }
447        }
448    }
449}
450
451impl fmt::Display for AlterSinkOperation {
452    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
453        match self {
454            AlterSinkOperation::RenameSink { sink_name } => {
455                write!(f, "RENAME TO {sink_name}")
456            }
457            AlterSinkOperation::ChangeOwner { new_owner_name } => {
458                write!(f, "OWNER TO {}", new_owner_name)
459            }
460            AlterSinkOperation::SetSchema { new_schema_name } => {
461                write!(f, "SET SCHEMA {}", new_schema_name)
462            }
463            AlterSinkOperation::SetParallelism {
464                parallelism,
465                deferred,
466            } => {
467                write!(
468                    f,
469                    "SET PARALLELISM TO {}{}",
470                    parallelism,
471                    if *deferred { " DEFERRED" } else { "" }
472                )
473            }
474            AlterSinkOperation::SwapRenameSink { target_sink } => {
475                write!(f, "SWAP WITH {}", target_sink)
476            }
477            AlterSinkOperation::SetSinkRateLimit { rate_limit } => {
478                write!(f, "SET SINK_RATE_LIMIT TO {}", rate_limit)
479            }
480            AlterSinkOperation::SetSinkProps { changed_props } => {
481                write!(f, "CONNECTOR WITH {:?}", changed_props)
482            }
483        }
484    }
485}
486
487impl fmt::Display for AlterSubscriptionOperation {
488    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
489        match self {
490            AlterSubscriptionOperation::RenameSubscription { subscription_name } => {
491                write!(f, "RENAME TO {subscription_name}")
492            }
493            AlterSubscriptionOperation::ChangeOwner { new_owner_name } => {
494                write!(f, "OWNER TO {}", new_owner_name)
495            }
496            AlterSubscriptionOperation::SetSchema { new_schema_name } => {
497                write!(f, "SET SCHEMA {}", new_schema_name)
498            }
499            AlterSubscriptionOperation::SwapRenameSubscription {
500                target_subscription,
501            } => {
502                write!(f, "SWAP WITH {}", target_subscription)
503            }
504        }
505    }
506}
507
508impl fmt::Display for AlterSourceOperation {
509    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
510        match self {
511            AlterSourceOperation::RenameSource { source_name } => {
512                write!(f, "RENAME TO {source_name}")
513            }
514            AlterSourceOperation::AddColumn { column_def } => {
515                write!(f, "ADD COLUMN {column_def}")
516            }
517            AlterSourceOperation::ChangeOwner { new_owner_name } => {
518                write!(f, "OWNER TO {}", new_owner_name)
519            }
520            AlterSourceOperation::SetSchema { new_schema_name } => {
521                write!(f, "SET SCHEMA {}", new_schema_name)
522            }
523            AlterSourceOperation::FormatEncode { format_encode } => {
524                write!(f, "{format_encode}")
525            }
526            AlterSourceOperation::RefreshSchema => {
527                write!(f, "REFRESH SCHEMA")
528            }
529            AlterSourceOperation::SetSourceRateLimit { rate_limit } => {
530                write!(f, "SET SOURCE_RATE_LIMIT TO {}", rate_limit)
531            }
532            AlterSourceOperation::SwapRenameSource { target_source } => {
533                write!(f, "SWAP WITH {}", target_source)
534            }
535            AlterSourceOperation::SetParallelism {
536                parallelism,
537                deferred,
538            } => {
539                write!(
540                    f,
541                    "SET PARALLELISM TO {}{}",
542                    parallelism,
543                    if *deferred { " DEFERRED" } else { "" }
544                )
545            }
546        }
547    }
548}
549
550impl fmt::Display for AlterFunctionOperation {
551    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
552        match self {
553            AlterFunctionOperation::SetSchema { new_schema_name } => {
554                write!(f, "SET SCHEMA {new_schema_name}")
555            }
556        }
557    }
558}
559
560impl fmt::Display for AlterConnectionOperation {
561    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
562        match self {
563            AlterConnectionOperation::SetSchema { new_schema_name } => {
564                write!(f, "SET SCHEMA {new_schema_name}")
565            }
566            AlterConnectionOperation::ChangeOwner { new_owner_name } => {
567                write!(f, "OWNER TO {new_owner_name}")
568            }
569        }
570    }
571}
572
573impl fmt::Display for AlterSecretOperation {
574    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
575        match self {
576            AlterSecretOperation::ChangeCredential { new_credential } => {
577                write!(f, "AS {new_credential}")
578            }
579        }
580    }
581}
582
583/// An `ALTER COLUMN` (`Statement::AlterTable`) operation
584#[derive(Debug, Clone, PartialEq, Eq, Hash)]
585#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
586pub enum AlterColumnOperation {
587    /// `SET NOT NULL`
588    SetNotNull,
589    /// `DROP NOT NULL`
590    DropNotNull,
591    /// `SET DEFAULT <expr>`
592    SetDefault { value: Expr },
593    /// `DROP DEFAULT`
594    DropDefault,
595    /// `[SET DATA] TYPE <data_type> [USING <expr>]`
596    SetDataType {
597        data_type: DataType,
598        /// PostgreSQL specific
599        using: Option<Expr>,
600    },
601}
602
603impl fmt::Display for AlterColumnOperation {
604    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
605        match self {
606            AlterColumnOperation::SetNotNull => write!(f, "SET NOT NULL",),
607            AlterColumnOperation::DropNotNull => write!(f, "DROP NOT NULL",),
608            AlterColumnOperation::SetDefault { value } => {
609                write!(f, "SET DEFAULT {}", value)
610            }
611            AlterColumnOperation::DropDefault => {
612                write!(f, "DROP DEFAULT")
613            }
614            AlterColumnOperation::SetDataType { data_type, using } => {
615                if let Some(expr) = using {
616                    write!(f, "SET DATA TYPE {} USING {}", data_type, expr)
617                } else {
618                    write!(f, "SET DATA TYPE {}", data_type)
619                }
620            }
621        }
622    }
623}
624
625impl fmt::Display for AlterFragmentOperation {
626    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
627        match self {
628            AlterFragmentOperation::AlterBackfillRateLimit { rate_limit } => {
629                write!(f, "SET BACKFILL_RATE_LIMIT TO {}", rate_limit)
630            }
631        }
632    }
633}
634
635/// The watermark on source.
636/// `WATERMARK FOR <column> AS (<expr>)`
637#[derive(Debug, Clone, PartialEq, Eq, Hash)]
638#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
639pub struct SourceWatermark {
640    pub column: Ident,
641    pub expr: Expr,
642}
643
644impl fmt::Display for SourceWatermark {
645    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
646        write!(f, "WATERMARK FOR {} AS {}", self.column, self.expr,)
647    }
648}
649
650/// A table-level constraint, specified in a `CREATE TABLE` or an
651/// `ALTER TABLE ADD <constraint>` statement.
652#[derive(Debug, Clone, PartialEq, Eq, Hash)]
653#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
654pub enum TableConstraint {
655    /// `[ CONSTRAINT <name> ] { PRIMARY KEY | UNIQUE } (<columns>)`
656    Unique {
657        name: Option<Ident>,
658        columns: Vec<Ident>,
659        /// Whether this is a `PRIMARY KEY` or just a `UNIQUE` constraint
660        is_primary: bool,
661    },
662    /// A referential integrity constraint (`[ CONSTRAINT <name> ] FOREIGN KEY (<columns>)
663    /// REFERENCES <foreign_table> (<referred_columns>)
664    /// { [ON DELETE <referential_action>] [ON UPDATE <referential_action>] |
665    ///   [ON UPDATE <referential_action>] [ON DELETE <referential_action>]
666    /// }`).
667    ForeignKey {
668        name: Option<Ident>,
669        columns: Vec<Ident>,
670        foreign_table: ObjectName,
671        referred_columns: Vec<Ident>,
672        on_delete: Option<ReferentialAction>,
673        on_update: Option<ReferentialAction>,
674    },
675    /// `[ CONSTRAINT <name> ] CHECK (<expr>)`
676    Check {
677        name: Option<Ident>,
678        expr: Box<Expr>,
679    },
680}
681
682impl fmt::Display for TableConstraint {
683    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
684        match self {
685            TableConstraint::Unique {
686                name,
687                columns,
688                is_primary,
689            } => write!(
690                f,
691                "{}{} ({})",
692                display_constraint_name(name),
693                if *is_primary { "PRIMARY KEY" } else { "UNIQUE" },
694                display_comma_separated(columns)
695            ),
696            TableConstraint::ForeignKey {
697                name,
698                columns,
699                foreign_table,
700                referred_columns,
701                on_delete,
702                on_update,
703            } => {
704                write!(
705                    f,
706                    "{}FOREIGN KEY ({}) REFERENCES {}({})",
707                    display_constraint_name(name),
708                    display_comma_separated(columns),
709                    foreign_table,
710                    display_comma_separated(referred_columns),
711                )?;
712                if let Some(action) = on_delete {
713                    write!(f, " ON DELETE {}", action)?;
714                }
715                if let Some(action) = on_update {
716                    write!(f, " ON UPDATE {}", action)?;
717                }
718                Ok(())
719            }
720            TableConstraint::Check { name, expr } => {
721                write!(f, "{}CHECK ({})", display_constraint_name(name), expr)
722            }
723        }
724    }
725}
726
727/// SQL column definition
728#[derive(Debug, Clone, PartialEq, Eq, Hash)]
729#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
730pub struct ColumnDef {
731    pub name: Ident,
732    pub data_type: Option<DataType>,
733    pub collation: Option<ObjectName>,
734    pub options: Vec<ColumnOptionDef>,
735}
736
737impl ColumnDef {
738    pub fn new(
739        name: Ident,
740        data_type: DataType,
741        collation: Option<ObjectName>,
742        options: Vec<ColumnOptionDef>,
743    ) -> Self {
744        ColumnDef {
745            name,
746            data_type: Some(data_type),
747            collation,
748            options,
749        }
750    }
751
752    pub fn is_generated(&self) -> bool {
753        self.options
754            .iter()
755            .any(|option| matches!(option.option, ColumnOption::GeneratedColumns(_)))
756    }
757}
758
759impl fmt::Display for ColumnDef {
760    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
761        write!(
762            f,
763            "{} {}",
764            self.name,
765            if let Some(data_type) = &self.data_type {
766                data_type.to_string()
767            } else {
768                "None".to_owned()
769            }
770        )?;
771        for option in &self.options {
772            write!(f, " {}", option)?;
773        }
774        Ok(())
775    }
776}
777
778/// An optionally-named `ColumnOption`: `[ CONSTRAINT <name> ] <column-option>`.
779///
780/// Note that implementations are substantially more permissive than the ANSI
781/// specification on what order column options can be presented in, and whether
782/// they are allowed to be named. The specification distinguishes between
783/// constraints (NOT NULL, UNIQUE, PRIMARY KEY, and CHECK), which can be named
784/// and can appear in any order, and other options (DEFAULT, GENERATED), which
785/// cannot be named and must appear in a fixed order. PostgreSQL, however,
786/// allows preceding any option with `CONSTRAINT <name>`, even those that are
787/// not really constraints, like NULL and DEFAULT. MSSQL is less permissive,
788/// allowing DEFAULT, UNIQUE, PRIMARY KEY and CHECK to be named, but not NULL or
789/// NOT NULL constraints (the last of which is in violation of the spec).
790///
791/// For maximum flexibility, we don't distinguish between constraint and
792/// non-constraint options, lumping them all together under the umbrella of
793/// "column options," and we allow any column option to be named.
794#[derive(Debug, Clone, PartialEq, Eq, Hash)]
795#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
796pub struct ColumnOptionDef {
797    pub name: Option<Ident>,
798    pub option: ColumnOption,
799}
800
801impl fmt::Display for ColumnOptionDef {
802    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
803        write!(f, "{}{}", display_constraint_name(&self.name), self.option)
804    }
805}
806
807/// `ColumnOption`s are modifiers that follow a column definition in a `CREATE
808/// TABLE` statement.
809#[derive(Debug, Clone, PartialEq, Eq, Hash)]
810#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
811pub enum ColumnOption {
812    /// `NULL`
813    Null,
814    /// `NOT NULL`
815    NotNull,
816    /// `DEFAULT <restricted-expr>`
817    DefaultValue(Expr),
818    /// Default value from previous bound `DefaultColumnDesc`. Used internally
819    /// for schema change and should not be specified by users.
820    DefaultValueInternal {
821        /// Protobuf encoded `DefaultColumnDesc`.
822        persisted: Box<[u8]>,
823        /// Optional AST for unparsing. If `None`, the default value will be
824        /// shown as `DEFAULT INTERNAL` which is for demonstrating and should
825        /// not be specified by users.
826        expr: Option<Expr>,
827    },
828    /// `{ PRIMARY KEY | UNIQUE }`
829    Unique { is_primary: bool },
830    /// A referential integrity constraint (`[FOREIGN KEY REFERENCES
831    /// <foreign_table> (<referred_columns>)
832    /// { [ON DELETE <referential_action>] [ON UPDATE <referential_action>] |
833    ///   [ON UPDATE <referential_action>] [ON DELETE <referential_action>]
834    /// }`).
835    ForeignKey {
836        foreign_table: ObjectName,
837        referred_columns: Vec<Ident>,
838        on_delete: Option<ReferentialAction>,
839        on_update: Option<ReferentialAction>,
840    },
841    /// `CHECK (<expr>)`
842    Check(Expr),
843    /// Dialect-specific options, such as:
844    /// - MySQL's `AUTO_INCREMENT` or SQLite's `AUTOINCREMENT`
845    /// - ...
846    DialectSpecific(Vec<Token>),
847    /// AS ( <generation_expr> )`
848    GeneratedColumns(Expr),
849}
850
851impl fmt::Display for ColumnOption {
852    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
853        use ColumnOption::*;
854        match self {
855            Null => write!(f, "NULL"),
856            NotNull => write!(f, "NOT NULL"),
857            DefaultValue(expr) => write!(f, "DEFAULT {}", expr),
858            DefaultValueInternal { persisted: _, expr } => {
859                if let Some(expr) = expr {
860                    write!(f, "DEFAULT {}", expr)
861                } else {
862                    write!(f, "DEFAULT INTERNAL")
863                }
864            }
865            Unique { is_primary } => {
866                write!(f, "{}", if *is_primary { "PRIMARY KEY" } else { "UNIQUE" })
867            }
868            ForeignKey {
869                foreign_table,
870                referred_columns,
871                on_delete,
872                on_update,
873            } => {
874                write!(f, "REFERENCES {}", foreign_table)?;
875                if !referred_columns.is_empty() {
876                    write!(f, " ({})", display_comma_separated(referred_columns))?;
877                }
878                if let Some(action) = on_delete {
879                    write!(f, " ON DELETE {}", action)?;
880                }
881                if let Some(action) = on_update {
882                    write!(f, " ON UPDATE {}", action)?;
883                }
884                Ok(())
885            }
886            Check(expr) => write!(f, "CHECK ({})", expr),
887            DialectSpecific(val) => write!(f, "{}", display_separated(val, " ")),
888            GeneratedColumns(expr) => write!(f, "AS {}", expr),
889        }
890    }
891}
892
893fn display_constraint_name(name: &'_ Option<Ident>) -> impl fmt::Display + '_ {
894    struct ConstraintName<'a>(&'a Option<Ident>);
895    impl fmt::Display for ConstraintName<'_> {
896        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
897            if let Some(name) = self.0 {
898                write!(f, "CONSTRAINT {} ", name)?;
899            }
900            Ok(())
901        }
902    }
903    ConstraintName(name)
904}
905
906/// `<referential_action> =
907/// { RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT }`
908///
909/// Used in foreign key constraints in `ON UPDATE` and `ON DELETE` options.
910#[derive(Debug, Clone, PartialEq, Eq, Hash)]
911#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
912pub enum ReferentialAction {
913    Restrict,
914    Cascade,
915    SetNull,
916    NoAction,
917    SetDefault,
918}
919
920impl fmt::Display for ReferentialAction {
921    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
922        f.write_str(match self {
923            ReferentialAction::Restrict => "RESTRICT",
924            ReferentialAction::Cascade => "CASCADE",
925            ReferentialAction::SetNull => "SET NULL",
926            ReferentialAction::NoAction => "NO ACTION",
927            ReferentialAction::SetDefault => "SET DEFAULT",
928        })
929    }
930}
931
932/// secure secret definition for webhook source
933#[derive(Debug, Clone, PartialEq, Eq, Hash)]
934#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
935pub struct WebhookSourceInfo {
936    pub secret_ref: Option<SecretRefValue>,
937    pub signature_expr: Expr,
938    pub wait_for_persistence: bool,
939}