1#[cfg(not(feature = "std"))]
22use alloc::{boxed::Box, string::String, vec::Vec};
23use core::fmt::{self, Display, Write};
24
25#[cfg(feature = "serde")]
26use serde::{Deserialize, Serialize};
27
28#[cfg(feature = "visitor")]
29use yachtsql_sqlparser_derive::{Visit, VisitMut};
30
31use crate::ast::value::escape_single_quote_string;
32use crate::ast::{
33 display_comma_separated, display_separated, ArgMode, CommentDef, ConditionalStatements,
34 CreateFunctionBody, CreateFunctionUsing, CreateTableLikeKind, CreateTableOptions, DataType,
35 Expr, FileFormat, FunctionBehavior, FunctionCalledOnNull, FunctionDeterminismSpecifier,
36 FunctionParallel, HiveDistributionStyle, HiveFormat, HiveIOFormat, HiveRowFormat, Ident,
37 InitializeKind, MySQLColumnPosition, ObjectName, OnCommit, OneOrManyWithParens,
38 OperateFunctionArg, OrderByExpr, ProjectionSelect, Query, RefreshModeKind, RowAccessPolicy,
39 SequenceOptions, Spanned, SqlOption, StorageSerializationPolicy, TableVersion, Tag,
40 TriggerEvent, TriggerExecBody, TriggerObject, TriggerPeriod, TriggerReferencing, Value,
41 ValueWithSpan, WrappedCollection,
42};
43use crate::display_utils::{DisplayCommaSeparated, Indent, NewLine, SpaceOrNewline};
44use crate::keywords::Keyword;
45use crate::tokenizer::{Span, Token};
46
47#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
49#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
50#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
51pub struct IndexColumn {
52 pub column: OrderByExpr,
53 pub operator_class: Option<Ident>,
54}
55
56impl fmt::Display for IndexColumn {
57 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
58 write!(f, "{}", self.column)?;
59 if let Some(operator_class) = &self.operator_class {
60 write!(f, " {operator_class}")?;
61 }
62 Ok(())
63 }
64}
65
66#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
69#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
70#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
71pub enum ReplicaIdentity {
72 None,
73 Full,
74 Default,
75 Index(Ident),
76}
77
78impl fmt::Display for ReplicaIdentity {
79 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
80 match self {
81 ReplicaIdentity::None => f.write_str("NONE"),
82 ReplicaIdentity::Full => f.write_str("FULL"),
83 ReplicaIdentity::Default => f.write_str("DEFAULT"),
84 ReplicaIdentity::Index(idx) => write!(f, "USING INDEX {idx}"),
85 }
86 }
87}
88
89#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
91#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
92#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
93pub enum AlterTableOperation {
94 AddConstraint {
96 constraint: TableConstraint,
97 not_valid: bool,
98 },
99 AddColumn {
101 column_keyword: bool,
103 if_not_exists: bool,
105 column_def: ColumnDef,
107 column_position: Option<MySQLColumnPosition>,
109 },
110 AddProjection {
115 if_not_exists: bool,
116 name: Ident,
117 select: ProjectionSelect,
118 },
119 DropProjection {
124 if_exists: bool,
125 name: Ident,
126 },
127 MaterializeProjection {
132 if_exists: bool,
133 name: Ident,
134 partition: Option<Ident>,
135 },
136 ClearProjection {
141 if_exists: bool,
142 name: Ident,
143 partition: Option<Ident>,
144 },
145 DisableRowLevelSecurity,
149 DisableRule {
153 name: Ident,
154 },
155 DisableTrigger {
159 name: Ident,
160 },
161 DropConstraint {
163 if_exists: bool,
164 name: Ident,
165 drop_behavior: Option<DropBehavior>,
166 },
167 DropColumn {
169 has_column_keyword: bool,
170 column_names: Vec<Ident>,
171 if_exists: bool,
172 drop_behavior: Option<DropBehavior>,
173 },
174 AttachPartition {
178 partition: Partition,
181 },
182 DetachPartition {
186 partition: Partition,
188 },
189 FreezePartition {
193 partition: Partition,
194 with_name: Option<Ident>,
195 },
196 UnfreezePartition {
200 partition: Partition,
201 with_name: Option<Ident>,
202 },
203 DropPrimaryKey {
208 drop_behavior: Option<DropBehavior>,
209 },
210 DropForeignKey {
215 name: Ident,
216 drop_behavior: Option<DropBehavior>,
217 },
218 DropIndex {
222 name: Ident,
223 },
224 EnableAlwaysRule {
228 name: Ident,
229 },
230 EnableAlwaysTrigger {
234 name: Ident,
235 },
236 EnableReplicaRule {
240 name: Ident,
241 },
242 EnableReplicaTrigger {
246 name: Ident,
247 },
248 EnableRowLevelSecurity,
252 EnableRule {
256 name: Ident,
257 },
258 EnableTrigger {
262 name: Ident,
263 },
264 RenamePartitions {
266 old_partitions: Vec<Expr>,
267 new_partitions: Vec<Expr>,
268 },
269 ReplicaIdentity {
274 identity: ReplicaIdentity,
275 },
276 AddPartitions {
278 if_not_exists: bool,
279 new_partitions: Vec<Partition>,
280 },
281 DropPartitions {
282 partitions: Vec<Expr>,
283 if_exists: bool,
284 },
285 RenameColumn {
287 old_column_name: Ident,
288 new_column_name: Ident,
289 },
290 RenameTable {
292 table_name: RenameTableNameKind,
293 },
294 ChangeColumn {
296 old_name: Ident,
297 new_name: Ident,
298 data_type: DataType,
299 options: Vec<ColumnOption>,
300 column_position: Option<MySQLColumnPosition>,
302 },
303 ModifyColumn {
305 col_name: Ident,
306 data_type: DataType,
307 options: Vec<ColumnOption>,
308 column_position: Option<MySQLColumnPosition>,
310 },
311 RenameConstraint {
315 old_name: Ident,
316 new_name: Ident,
317 },
318 AlterColumn {
320 column_name: Ident,
321 op: AlterColumnOperation,
322 },
323 SwapWith {
327 table_name: ObjectName,
328 },
329 SetTblProperties {
331 table_properties: Vec<SqlOption>,
332 },
333 OwnerTo {
337 new_owner: Owner,
338 },
339 ClusterBy {
342 exprs: Vec<Expr>,
343 },
344 DropClusteringKey,
345 SuspendRecluster,
346 ResumeRecluster,
347 Algorithm {
353 equals: bool,
354 algorithm: AlterTableAlgorithm,
355 },
356
357 Lock {
363 equals: bool,
364 lock: AlterTableLock,
365 },
366 AutoIncrement {
372 equals: bool,
373 value: ValueWithSpan,
374 },
375 ValidateConstraint {
377 name: Ident,
378 },
379 SetOptionsParens {
387 options: Vec<SqlOption>,
388 },
389 SetDefaultCollate {
393 collate: Expr,
394 },
395}
396
397#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
401#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
402#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
403pub enum AlterPolicyOperation {
404 Rename {
405 new_name: Ident,
406 },
407 Apply {
408 to: Option<Vec<Owner>>,
409 using: Option<Expr>,
410 with_check: Option<Expr>,
411 },
412}
413
414impl fmt::Display for AlterPolicyOperation {
415 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
416 match self {
417 AlterPolicyOperation::Rename { new_name } => {
418 write!(f, " RENAME TO {new_name}")
419 }
420 AlterPolicyOperation::Apply {
421 to,
422 using,
423 with_check,
424 } => {
425 if let Some(to) = to {
426 write!(f, " TO {}", display_comma_separated(to))?;
427 }
428 if let Some(using) = using {
429 write!(f, " USING ({using})")?;
430 }
431 if let Some(with_check) = with_check {
432 write!(f, " WITH CHECK ({with_check})")?;
433 }
434 Ok(())
435 }
436 }
437 }
438}
439
440#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
444#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
445#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
446pub enum AlterTableAlgorithm {
447 Default,
448 Instant,
449 Inplace,
450 Copy,
451}
452
453impl fmt::Display for AlterTableAlgorithm {
454 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
455 f.write_str(match self {
456 Self::Default => "DEFAULT",
457 Self::Instant => "INSTANT",
458 Self::Inplace => "INPLACE",
459 Self::Copy => "COPY",
460 })
461 }
462}
463
464#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
468#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
469#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
470pub enum AlterTableLock {
471 Default,
472 None,
473 Shared,
474 Exclusive,
475}
476
477impl fmt::Display for AlterTableLock {
478 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
479 f.write_str(match self {
480 Self::Default => "DEFAULT",
481 Self::None => "NONE",
482 Self::Shared => "SHARED",
483 Self::Exclusive => "EXCLUSIVE",
484 })
485 }
486}
487
488#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
489#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
490#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
491pub enum Owner {
492 Ident(Ident),
493 CurrentRole,
494 CurrentUser,
495 SessionUser,
496}
497
498impl fmt::Display for Owner {
499 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
500 match self {
501 Owner::Ident(ident) => write!(f, "{ident}"),
502 Owner::CurrentRole => write!(f, "CURRENT_ROLE"),
503 Owner::CurrentUser => write!(f, "CURRENT_USER"),
504 Owner::SessionUser => write!(f, "SESSION_USER"),
505 }
506 }
507}
508
509#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
510#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
511#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
512pub enum AlterConnectorOwner {
513 User(Ident),
514 Role(Ident),
515}
516
517impl fmt::Display for AlterConnectorOwner {
518 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
519 match self {
520 AlterConnectorOwner::User(ident) => write!(f, "USER {ident}"),
521 AlterConnectorOwner::Role(ident) => write!(f, "ROLE {ident}"),
522 }
523 }
524}
525
526#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
527#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
528#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
529pub enum AlterIndexOperation {
530 RenameIndex { index_name: ObjectName },
531}
532
533#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
534#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
535#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
536pub enum AlterViewOperation {
537 SetOptions { options: Vec<SqlOption> },
538 AlterColumn { column_name: Ident, operation: AlterColumnOperation },
539}
540
541impl fmt::Display for AlterViewOperation {
542 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
543 match self {
544 AlterViewOperation::SetOptions { options } => {
545 write!(f, "SET OPTIONS ({})", display_comma_separated(options))
546 }
547 AlterViewOperation::AlterColumn { column_name, operation } => {
548 write!(f, "ALTER COLUMN {} {}", column_name, operation)
549 }
550 }
551 }
552}
553
554impl fmt::Display for AlterTableOperation {
555 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
556 match self {
557 AlterTableOperation::AddPartitions {
558 if_not_exists,
559 new_partitions,
560 } => write!(
561 f,
562 "ADD{ine} {}",
563 display_separated(new_partitions, " "),
564 ine = if *if_not_exists { " IF NOT EXISTS" } else { "" }
565 ),
566 AlterTableOperation::AddConstraint {
567 not_valid,
568 constraint,
569 } => {
570 write!(f, "ADD {constraint}")?;
571 if *not_valid {
572 write!(f, " NOT VALID")?;
573 }
574 Ok(())
575 }
576 AlterTableOperation::AddColumn {
577 column_keyword,
578 if_not_exists,
579 column_def,
580 column_position,
581 } => {
582 write!(f, "ADD")?;
583 if *column_keyword {
584 write!(f, " COLUMN")?;
585 }
586 if *if_not_exists {
587 write!(f, " IF NOT EXISTS")?;
588 }
589 write!(f, " {column_def}")?;
590
591 if let Some(position) = column_position {
592 write!(f, " {position}")?;
593 }
594
595 Ok(())
596 }
597 AlterTableOperation::AddProjection {
598 if_not_exists,
599 name,
600 select: query,
601 } => {
602 write!(f, "ADD PROJECTION")?;
603 if *if_not_exists {
604 write!(f, " IF NOT EXISTS")?;
605 }
606 write!(f, " {name} ({query})")
607 }
608 AlterTableOperation::Algorithm { equals, algorithm } => {
609 write!(
610 f,
611 "ALGORITHM {}{}",
612 if *equals { "= " } else { "" },
613 algorithm
614 )
615 }
616 AlterTableOperation::DropProjection { if_exists, name } => {
617 write!(f, "DROP PROJECTION")?;
618 if *if_exists {
619 write!(f, " IF EXISTS")?;
620 }
621 write!(f, " {name}")
622 }
623 AlterTableOperation::MaterializeProjection {
624 if_exists,
625 name,
626 partition,
627 } => {
628 write!(f, "MATERIALIZE PROJECTION")?;
629 if *if_exists {
630 write!(f, " IF EXISTS")?;
631 }
632 write!(f, " {name}")?;
633 if let Some(partition) = partition {
634 write!(f, " IN PARTITION {partition}")?;
635 }
636 Ok(())
637 }
638 AlterTableOperation::ClearProjection {
639 if_exists,
640 name,
641 partition,
642 } => {
643 write!(f, "CLEAR PROJECTION")?;
644 if *if_exists {
645 write!(f, " IF EXISTS")?;
646 }
647 write!(f, " {name}")?;
648 if let Some(partition) = partition {
649 write!(f, " IN PARTITION {partition}")?;
650 }
651 Ok(())
652 }
653 AlterTableOperation::AlterColumn { column_name, op } => {
654 write!(f, "ALTER COLUMN {column_name} {op}")
655 }
656 AlterTableOperation::DisableRowLevelSecurity => {
657 write!(f, "DISABLE ROW LEVEL SECURITY")
658 }
659 AlterTableOperation::DisableRule { name } => {
660 write!(f, "DISABLE RULE {name}")
661 }
662 AlterTableOperation::DisableTrigger { name } => {
663 write!(f, "DISABLE TRIGGER {name}")
664 }
665 AlterTableOperation::DropPartitions {
666 partitions,
667 if_exists,
668 } => write!(
669 f,
670 "DROP{ie} PARTITION ({})",
671 display_comma_separated(partitions),
672 ie = if *if_exists { " IF EXISTS" } else { "" }
673 ),
674 AlterTableOperation::DropConstraint {
675 if_exists,
676 name,
677 drop_behavior,
678 } => {
679 write!(
680 f,
681 "DROP CONSTRAINT {}{}",
682 if *if_exists { "IF EXISTS " } else { "" },
683 name
684 )?;
685 if let Some(drop_behavior) = drop_behavior {
686 write!(f, " {drop_behavior}")?;
687 }
688 Ok(())
689 }
690 AlterTableOperation::DropPrimaryKey { drop_behavior } => {
691 write!(f, "DROP PRIMARY KEY")?;
692 if let Some(drop_behavior) = drop_behavior {
693 write!(f, " {drop_behavior}")?;
694 }
695 Ok(())
696 }
697 AlterTableOperation::DropForeignKey {
698 name,
699 drop_behavior,
700 } => {
701 write!(f, "DROP FOREIGN KEY {name}")?;
702 if let Some(drop_behavior) = drop_behavior {
703 write!(f, " {drop_behavior}")?;
704 }
705 Ok(())
706 }
707 AlterTableOperation::DropIndex { name } => write!(f, "DROP INDEX {name}"),
708 AlterTableOperation::DropColumn {
709 has_column_keyword,
710 column_names: column_name,
711 if_exists,
712 drop_behavior,
713 } => {
714 write!(
715 f,
716 "DROP {}{}{}",
717 if *has_column_keyword { "COLUMN " } else { "" },
718 if *if_exists { "IF EXISTS " } else { "" },
719 display_comma_separated(column_name),
720 )?;
721 if let Some(drop_behavior) = drop_behavior {
722 write!(f, " {drop_behavior}")?;
723 }
724 Ok(())
725 }
726 AlterTableOperation::AttachPartition { partition } => {
727 write!(f, "ATTACH {partition}")
728 }
729 AlterTableOperation::DetachPartition { partition } => {
730 write!(f, "DETACH {partition}")
731 }
732 AlterTableOperation::EnableAlwaysRule { name } => {
733 write!(f, "ENABLE ALWAYS RULE {name}")
734 }
735 AlterTableOperation::EnableAlwaysTrigger { name } => {
736 write!(f, "ENABLE ALWAYS TRIGGER {name}")
737 }
738 AlterTableOperation::EnableReplicaRule { name } => {
739 write!(f, "ENABLE REPLICA RULE {name}")
740 }
741 AlterTableOperation::EnableReplicaTrigger { name } => {
742 write!(f, "ENABLE REPLICA TRIGGER {name}")
743 }
744 AlterTableOperation::EnableRowLevelSecurity => {
745 write!(f, "ENABLE ROW LEVEL SECURITY")
746 }
747 AlterTableOperation::EnableRule { name } => {
748 write!(f, "ENABLE RULE {name}")
749 }
750 AlterTableOperation::EnableTrigger { name } => {
751 write!(f, "ENABLE TRIGGER {name}")
752 }
753 AlterTableOperation::RenamePartitions {
754 old_partitions,
755 new_partitions,
756 } => write!(
757 f,
758 "PARTITION ({}) RENAME TO PARTITION ({})",
759 display_comma_separated(old_partitions),
760 display_comma_separated(new_partitions)
761 ),
762 AlterTableOperation::RenameColumn {
763 old_column_name,
764 new_column_name,
765 } => write!(f, "RENAME COLUMN {old_column_name} TO {new_column_name}"),
766 AlterTableOperation::RenameTable { table_name } => {
767 write!(f, "RENAME {table_name}")
768 }
769 AlterTableOperation::ChangeColumn {
770 old_name,
771 new_name,
772 data_type,
773 options,
774 column_position,
775 } => {
776 write!(f, "CHANGE COLUMN {old_name} {new_name} {data_type}")?;
777 if !options.is_empty() {
778 write!(f, " {}", display_separated(options, " "))?;
779 }
780 if let Some(position) = column_position {
781 write!(f, " {position}")?;
782 }
783
784 Ok(())
785 }
786 AlterTableOperation::ModifyColumn {
787 col_name,
788 data_type,
789 options,
790 column_position,
791 } => {
792 write!(f, "MODIFY COLUMN {col_name} {data_type}")?;
793 if !options.is_empty() {
794 write!(f, " {}", display_separated(options, " "))?;
795 }
796 if let Some(position) = column_position {
797 write!(f, " {position}")?;
798 }
799
800 Ok(())
801 }
802 AlterTableOperation::RenameConstraint { old_name, new_name } => {
803 write!(f, "RENAME CONSTRAINT {old_name} TO {new_name}")
804 }
805 AlterTableOperation::SwapWith { table_name } => {
806 write!(f, "SWAP WITH {table_name}")
807 }
808 AlterTableOperation::OwnerTo { new_owner } => {
809 write!(f, "OWNER TO {new_owner}")
810 }
811 AlterTableOperation::SetTblProperties { table_properties } => {
812 write!(
813 f,
814 "SET TBLPROPERTIES({})",
815 display_comma_separated(table_properties)
816 )
817 }
818 AlterTableOperation::FreezePartition {
819 partition,
820 with_name,
821 } => {
822 write!(f, "FREEZE {partition}")?;
823 if let Some(name) = with_name {
824 write!(f, " WITH NAME {name}")?;
825 }
826 Ok(())
827 }
828 AlterTableOperation::UnfreezePartition {
829 partition,
830 with_name,
831 } => {
832 write!(f, "UNFREEZE {partition}")?;
833 if let Some(name) = with_name {
834 write!(f, " WITH NAME {name}")?;
835 }
836 Ok(())
837 }
838 AlterTableOperation::ClusterBy { exprs } => {
839 write!(f, "CLUSTER BY ({})", display_comma_separated(exprs))?;
840 Ok(())
841 }
842 AlterTableOperation::DropClusteringKey => {
843 write!(f, "DROP CLUSTERING KEY")?;
844 Ok(())
845 }
846 AlterTableOperation::SuspendRecluster => {
847 write!(f, "SUSPEND RECLUSTER")?;
848 Ok(())
849 }
850 AlterTableOperation::ResumeRecluster => {
851 write!(f, "RESUME RECLUSTER")?;
852 Ok(())
853 }
854 AlterTableOperation::AutoIncrement { equals, value } => {
855 write!(
856 f,
857 "AUTO_INCREMENT {}{}",
858 if *equals { "= " } else { "" },
859 value
860 )
861 }
862 AlterTableOperation::Lock { equals, lock } => {
863 write!(f, "LOCK {}{}", if *equals { "= " } else { "" }, lock)
864 }
865 AlterTableOperation::ReplicaIdentity { identity } => {
866 write!(f, "REPLICA IDENTITY {identity}")
867 }
868 AlterTableOperation::ValidateConstraint { name } => {
869 write!(f, "VALIDATE CONSTRAINT {name}")
870 }
871 AlterTableOperation::SetOptionsParens { options } => {
872 write!(f, "SET ({})", display_comma_separated(options))
873 }
874 AlterTableOperation::SetDefaultCollate { collate } => {
875 write!(f, "SET DEFAULT COLLATE {collate}")
876 }
877 }
878 }
879}
880
881impl fmt::Display for AlterIndexOperation {
882 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
883 match self {
884 AlterIndexOperation::RenameIndex { index_name } => {
885 write!(f, "RENAME TO {index_name}")
886 }
887 }
888 }
889}
890
891#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
893#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
894#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
895pub struct AlterType {
896 pub name: ObjectName,
897 pub operation: AlterTypeOperation,
898}
899
900#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
902#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
903#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
904pub enum AlterTypeOperation {
905 Rename(AlterTypeRename),
906 AddValue(AlterTypeAddValue),
907 RenameValue(AlterTypeRenameValue),
908}
909
910#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
912#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
913#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
914pub struct AlterTypeRename {
915 pub new_name: Ident,
916}
917
918#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
920#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
921#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
922pub struct AlterTypeAddValue {
923 pub if_not_exists: bool,
924 pub value: Ident,
925 pub position: Option<AlterTypeAddValuePosition>,
926}
927
928#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
930#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
931#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
932pub enum AlterTypeAddValuePosition {
933 Before(Ident),
934 After(Ident),
935}
936
937#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
939#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
940#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
941pub struct AlterTypeRenameValue {
942 pub from: Ident,
943 pub to: Ident,
944}
945
946impl fmt::Display for AlterTypeOperation {
947 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
948 match self {
949 Self::Rename(AlterTypeRename { new_name }) => {
950 write!(f, "RENAME TO {new_name}")
951 }
952 Self::AddValue(AlterTypeAddValue {
953 if_not_exists,
954 value,
955 position,
956 }) => {
957 write!(f, "ADD VALUE")?;
958 if *if_not_exists {
959 write!(f, " IF NOT EXISTS")?;
960 }
961 write!(f, " {value}")?;
962 match position {
963 Some(AlterTypeAddValuePosition::Before(neighbor_value)) => {
964 write!(f, " BEFORE {neighbor_value}")?;
965 }
966 Some(AlterTypeAddValuePosition::After(neighbor_value)) => {
967 write!(f, " AFTER {neighbor_value}")?;
968 }
969 None => {}
970 };
971 Ok(())
972 }
973 Self::RenameValue(AlterTypeRenameValue { from, to }) => {
974 write!(f, "RENAME VALUE {from} TO {to}")
975 }
976 }
977 }
978}
979
980#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
982#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
983#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
984pub enum AlterColumnOperation {
985 SetNotNull,
987 DropNotNull,
989 SetDefault { value: Expr },
991 DropDefault,
993 SetDataType {
995 data_type: DataType,
996 using: Option<Expr>,
998 had_set: bool,
1000 },
1001
1002 AddGenerated {
1006 generated_as: Option<GeneratedAs>,
1007 sequence_options: Option<Vec<SequenceOptions>>,
1008 },
1009 SetOptions { options: Vec<SqlOption> },
1013}
1014
1015impl fmt::Display for AlterColumnOperation {
1016 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1017 match self {
1018 AlterColumnOperation::SetNotNull => write!(f, "SET NOT NULL",),
1019 AlterColumnOperation::DropNotNull => write!(f, "DROP NOT NULL",),
1020 AlterColumnOperation::SetDefault { value } => {
1021 write!(f, "SET DEFAULT {value}")
1022 }
1023 AlterColumnOperation::DropDefault => {
1024 write!(f, "DROP DEFAULT")
1025 }
1026 AlterColumnOperation::SetDataType {
1027 data_type,
1028 using,
1029 had_set,
1030 } => {
1031 if *had_set {
1032 write!(f, "SET DATA ")?;
1033 }
1034 write!(f, "TYPE {data_type}")?;
1035 if let Some(expr) = using {
1036 write!(f, " USING {expr}")?;
1037 }
1038 Ok(())
1039 }
1040 AlterColumnOperation::AddGenerated {
1041 generated_as,
1042 sequence_options,
1043 } => {
1044 let generated_as = match generated_as {
1045 Some(GeneratedAs::Always) => " ALWAYS",
1046 Some(GeneratedAs::ByDefault) => " BY DEFAULT",
1047 _ => "",
1048 };
1049
1050 write!(f, "ADD GENERATED{generated_as} AS IDENTITY",)?;
1051 if let Some(options) = sequence_options {
1052 write!(f, " (")?;
1053
1054 for sequence_option in options {
1055 write!(f, "{sequence_option}")?;
1056 }
1057
1058 write!(f, " )")?;
1059 }
1060 Ok(())
1061 }
1062 AlterColumnOperation::SetOptions { options } => {
1063 write!(f, "SET OPTIONS ({})", display_comma_separated(options))
1064 }
1065 }
1066 }
1067}
1068
1069#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1072#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1073#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1074pub enum TableConstraint {
1075 Unique {
1088 name: Option<Ident>,
1092 index_name: Option<Ident>,
1094 index_type_display: KeyOrIndexDisplay,
1096 index_type: Option<IndexType>,
1100 columns: Vec<IndexColumn>,
1102 index_options: Vec<IndexOption>,
1103 characteristics: Option<ConstraintCharacteristics>,
1104 nulls_distinct: NullsDistinctOption,
1106 },
1107 PrimaryKey {
1126 name: Option<Ident>,
1130 index_name: Option<Ident>,
1132 index_type: Option<IndexType>,
1136 columns: Vec<IndexColumn>,
1138 index_options: Vec<IndexOption>,
1139 characteristics: Option<ConstraintCharacteristics>,
1140 },
1141 ForeignKey {
1147 name: Option<Ident>,
1148 index_name: Option<Ident>,
1151 columns: Vec<Ident>,
1152 foreign_table: ObjectName,
1153 referred_columns: Vec<Ident>,
1154 on_delete: Option<ReferentialAction>,
1155 on_update: Option<ReferentialAction>,
1156 characteristics: Option<ConstraintCharacteristics>,
1157 },
1158 Check {
1160 name: Option<Ident>,
1161 expr: Box<Expr>,
1162 enforced: Option<bool>,
1165 },
1166 Index {
1173 display_as_key: bool,
1175 name: Option<Ident>,
1177 index_type: Option<IndexType>,
1181 columns: Vec<IndexColumn>,
1183 index_options: Vec<IndexOption>,
1185 },
1186 FulltextOrSpatial {
1200 fulltext: bool,
1202 index_type_display: KeyOrIndexDisplay,
1204 opt_index_name: Option<Ident>,
1206 columns: Vec<IndexColumn>,
1208 },
1209}
1210
1211impl fmt::Display for TableConstraint {
1212 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1213 match self {
1214 TableConstraint::Unique {
1215 name,
1216 index_name,
1217 index_type_display,
1218 index_type,
1219 columns,
1220 index_options,
1221 characteristics,
1222 nulls_distinct,
1223 } => {
1224 write!(
1225 f,
1226 "{}UNIQUE{nulls_distinct}{index_type_display:>}{}{} ({})",
1227 display_constraint_name(name),
1228 display_option_spaced(index_name),
1229 display_option(" USING ", "", index_type),
1230 display_comma_separated(columns),
1231 )?;
1232
1233 if !index_options.is_empty() {
1234 write!(f, " {}", display_separated(index_options, " "))?;
1235 }
1236
1237 write!(f, "{}", display_option_spaced(characteristics))?;
1238 Ok(())
1239 }
1240 TableConstraint::PrimaryKey {
1241 name,
1242 index_name,
1243 index_type,
1244 columns,
1245 index_options,
1246 characteristics,
1247 } => {
1248 write!(
1249 f,
1250 "{}PRIMARY KEY{}{} ({})",
1251 display_constraint_name(name),
1252 display_option_spaced(index_name),
1253 display_option(" USING ", "", index_type),
1254 display_comma_separated(columns),
1255 )?;
1256
1257 if !index_options.is_empty() {
1258 write!(f, " {}", display_separated(index_options, " "))?;
1259 }
1260
1261 write!(f, "{}", display_option_spaced(characteristics))?;
1262 Ok(())
1263 }
1264 TableConstraint::ForeignKey {
1265 name,
1266 index_name,
1267 columns,
1268 foreign_table,
1269 referred_columns,
1270 on_delete,
1271 on_update,
1272 characteristics,
1273 } => {
1274 write!(
1275 f,
1276 "{}FOREIGN KEY{} ({}) REFERENCES {}",
1277 display_constraint_name(name),
1278 display_option_spaced(index_name),
1279 display_comma_separated(columns),
1280 foreign_table,
1281 )?;
1282 if !referred_columns.is_empty() {
1283 write!(f, "({})", display_comma_separated(referred_columns))?;
1284 }
1285 if let Some(action) = on_delete {
1286 write!(f, " ON DELETE {action}")?;
1287 }
1288 if let Some(action) = on_update {
1289 write!(f, " ON UPDATE {action}")?;
1290 }
1291 if let Some(characteristics) = characteristics {
1292 write!(f, " {characteristics}")?;
1293 }
1294 Ok(())
1295 }
1296 TableConstraint::Check {
1297 name,
1298 expr,
1299 enforced,
1300 } => {
1301 write!(f, "{}CHECK ({})", display_constraint_name(name), expr)?;
1302 if let Some(b) = enforced {
1303 write!(f, " {}", if *b { "ENFORCED" } else { "NOT ENFORCED" })
1304 } else {
1305 Ok(())
1306 }
1307 }
1308 TableConstraint::Index {
1309 display_as_key,
1310 name,
1311 index_type,
1312 columns,
1313 index_options,
1314 } => {
1315 write!(f, "{}", if *display_as_key { "KEY" } else { "INDEX" })?;
1316 if let Some(name) = name {
1317 write!(f, " {name}")?;
1318 }
1319 if let Some(index_type) = index_type {
1320 write!(f, " USING {index_type}")?;
1321 }
1322 write!(f, " ({})", display_comma_separated(columns))?;
1323 if !index_options.is_empty() {
1324 write!(f, " {}", display_comma_separated(index_options))?;
1325 }
1326 Ok(())
1327 }
1328 Self::FulltextOrSpatial {
1329 fulltext,
1330 index_type_display,
1331 opt_index_name,
1332 columns,
1333 } => {
1334 if *fulltext {
1335 write!(f, "FULLTEXT")?;
1336 } else {
1337 write!(f, "SPATIAL")?;
1338 }
1339
1340 write!(f, "{index_type_display:>}")?;
1341
1342 if let Some(name) = opt_index_name {
1343 write!(f, " {name}")?;
1344 }
1345
1346 write!(f, " ({})", display_comma_separated(columns))?;
1347
1348 Ok(())
1349 }
1350 }
1351 }
1352}
1353
1354#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1362#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1363#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1364pub enum KeyOrIndexDisplay {
1365 None,
1367 Key,
1369 Index,
1371}
1372
1373impl KeyOrIndexDisplay {
1374 pub fn is_none(self) -> bool {
1375 matches!(self, Self::None)
1376 }
1377}
1378
1379impl fmt::Display for KeyOrIndexDisplay {
1380 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1381 let left_space = matches!(f.align(), Some(fmt::Alignment::Right));
1382
1383 if left_space && !self.is_none() {
1384 f.write_char(' ')?
1385 }
1386
1387 match self {
1388 KeyOrIndexDisplay::None => {
1389 write!(f, "")
1390 }
1391 KeyOrIndexDisplay::Key => {
1392 write!(f, "KEY")
1393 }
1394 KeyOrIndexDisplay::Index => {
1395 write!(f, "INDEX")
1396 }
1397 }
1398 }
1399}
1400
1401#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1410#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1411#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1412pub enum IndexType {
1413 BTree,
1414 Hash,
1415 GIN,
1416 GiST,
1417 SPGiST,
1418 BRIN,
1419 Bloom,
1420 Custom(Ident),
1423}
1424
1425impl fmt::Display for IndexType {
1426 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1427 match self {
1428 Self::BTree => write!(f, "BTREE"),
1429 Self::Hash => write!(f, "HASH"),
1430 Self::GIN => write!(f, "GIN"),
1431 Self::GiST => write!(f, "GIST"),
1432 Self::SPGiST => write!(f, "SPGIST"),
1433 Self::BRIN => write!(f, "BRIN"),
1434 Self::Bloom => write!(f, "BLOOM"),
1435 Self::Custom(name) => write!(f, "{name}"),
1436 }
1437 }
1438}
1439
1440#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1446#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1447#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1448pub enum IndexOption {
1449 Using(IndexType),
1453 Comment(String),
1455}
1456
1457impl fmt::Display for IndexOption {
1458 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1459 match self {
1460 Self::Using(index_type) => write!(f, "USING {index_type}"),
1461 Self::Comment(s) => write!(f, "COMMENT '{s}'"),
1462 }
1463 }
1464}
1465
1466#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1470#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1471#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1472pub enum NullsDistinctOption {
1473 None,
1475 Distinct,
1477 NotDistinct,
1479}
1480
1481impl fmt::Display for NullsDistinctOption {
1482 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1483 match self {
1484 Self::None => Ok(()),
1485 Self::Distinct => write!(f, " NULLS DISTINCT"),
1486 Self::NotDistinct => write!(f, " NULLS NOT DISTINCT"),
1487 }
1488 }
1489}
1490
1491#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1492#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1493#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1494pub struct ProcedureParam {
1495 pub name: Ident,
1496 pub data_type: DataType,
1497 pub mode: Option<ArgMode>,
1498}
1499
1500impl fmt::Display for ProcedureParam {
1501 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1502 if let Some(mode) = &self.mode {
1503 write!(f, "{mode} {} {}", self.name, self.data_type)
1504 } else {
1505 write!(f, "{} {}", self.name, self.data_type)
1506 }
1507 }
1508}
1509
1510#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1512#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1513#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1514pub struct ColumnDef {
1515 pub name: Ident,
1516 pub data_type: DataType,
1517 pub options: Vec<ColumnOptionDef>,
1518}
1519
1520impl fmt::Display for ColumnDef {
1521 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1522 if self.data_type == DataType::Unspecified {
1523 write!(f, "{}", self.name)?;
1524 } else {
1525 write!(f, "{} {}", self.name, self.data_type)?;
1526 }
1527 for option in &self.options {
1528 write!(f, " {option}")?;
1529 }
1530 Ok(())
1531 }
1532}
1533
1534#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1551#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1552#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1553pub struct ViewColumnDef {
1554 pub name: Ident,
1555 pub data_type: Option<DataType>,
1556 pub options: Option<ColumnOptions>,
1557}
1558
1559#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1560#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1561#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1562pub enum ColumnOptions {
1563 CommaSeparated(Vec<ColumnOption>),
1564 SpaceSeparated(Vec<ColumnOption>),
1565}
1566
1567impl ColumnOptions {
1568 pub fn as_slice(&self) -> &[ColumnOption] {
1569 match self {
1570 ColumnOptions::CommaSeparated(options) => options.as_slice(),
1571 ColumnOptions::SpaceSeparated(options) => options.as_slice(),
1572 }
1573 }
1574}
1575
1576impl fmt::Display for ViewColumnDef {
1577 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1578 write!(f, "{}", self.name)?;
1579 if let Some(data_type) = self.data_type.as_ref() {
1580 write!(f, " {data_type}")?;
1581 }
1582 if let Some(options) = self.options.as_ref() {
1583 match options {
1584 ColumnOptions::CommaSeparated(column_options) => {
1585 write!(f, " {}", display_comma_separated(column_options.as_slice()))?;
1586 }
1587 ColumnOptions::SpaceSeparated(column_options) => {
1588 write!(f, " {}", display_separated(column_options.as_slice(), " "))?
1589 }
1590 }
1591 }
1592 Ok(())
1593 }
1594}
1595
1596#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1613#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1614#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1615pub struct ColumnOptionDef {
1616 pub name: Option<Ident>,
1617 pub option: ColumnOption,
1618}
1619
1620impl fmt::Display for ColumnOptionDef {
1621 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1622 write!(f, "{}{}", display_constraint_name(&self.name), self.option)
1623 }
1624}
1625
1626#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1634#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1635#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1636pub enum IdentityPropertyKind {
1637 Autoincrement(IdentityProperty),
1645 Identity(IdentityProperty),
1658}
1659
1660impl fmt::Display for IdentityPropertyKind {
1661 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1662 let (command, property) = match self {
1663 IdentityPropertyKind::Identity(property) => ("IDENTITY", property),
1664 IdentityPropertyKind::Autoincrement(property) => ("AUTOINCREMENT", property),
1665 };
1666 write!(f, "{command}")?;
1667 if let Some(parameters) = &property.parameters {
1668 write!(f, "{parameters}")?;
1669 }
1670 if let Some(order) = &property.order {
1671 write!(f, "{order}")?;
1672 }
1673 Ok(())
1674 }
1675}
1676
1677#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1678#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1679#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1680pub struct IdentityProperty {
1681 pub parameters: Option<IdentityPropertyFormatKind>,
1682 pub order: Option<IdentityPropertyOrder>,
1683}
1684
1685#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1700#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1701#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1702pub enum IdentityPropertyFormatKind {
1703 FunctionCall(IdentityParameters),
1711 StartAndIncrement(IdentityParameters),
1718}
1719
1720impl fmt::Display for IdentityPropertyFormatKind {
1721 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1722 match self {
1723 IdentityPropertyFormatKind::FunctionCall(parameters) => {
1724 write!(f, "({}, {})", parameters.seed, parameters.increment)
1725 }
1726 IdentityPropertyFormatKind::StartAndIncrement(parameters) => {
1727 write!(
1728 f,
1729 " START {} INCREMENT {}",
1730 parameters.seed, parameters.increment
1731 )
1732 }
1733 }
1734 }
1735}
1736#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1737#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1738#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1739pub struct IdentityParameters {
1740 pub seed: Expr,
1741 pub increment: Expr,
1742}
1743
1744#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1751#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1752#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1753pub enum IdentityPropertyOrder {
1754 Order,
1755 NoOrder,
1756}
1757
1758impl fmt::Display for IdentityPropertyOrder {
1759 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1760 match self {
1761 IdentityPropertyOrder::Order => write!(f, " ORDER"),
1762 IdentityPropertyOrder::NoOrder => write!(f, " NOORDER"),
1763 }
1764 }
1765}
1766
1767#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1775#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1776#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1777pub enum ColumnPolicy {
1778 MaskingPolicy(ColumnPolicyProperty),
1779 ProjectionPolicy(ColumnPolicyProperty),
1780}
1781
1782impl fmt::Display for ColumnPolicy {
1783 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1784 let (command, property) = match self {
1785 ColumnPolicy::MaskingPolicy(property) => ("MASKING POLICY", property),
1786 ColumnPolicy::ProjectionPolicy(property) => ("PROJECTION POLICY", property),
1787 };
1788 if property.with {
1789 write!(f, "WITH ")?;
1790 }
1791 write!(f, "{command} {}", property.policy_name)?;
1792 if let Some(using_columns) = &property.using_columns {
1793 write!(f, " USING ({})", display_comma_separated(using_columns))?;
1794 }
1795 Ok(())
1796 }
1797}
1798
1799#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1800#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1801#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1802pub struct ColumnPolicyProperty {
1803 pub with: bool,
1810 pub policy_name: ObjectName,
1811 pub using_columns: Option<Vec<Ident>>,
1812}
1813
1814#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1821#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1822#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1823pub struct TagsColumnOption {
1824 pub with: bool,
1831 pub tags: Vec<Tag>,
1832}
1833
1834impl fmt::Display for TagsColumnOption {
1835 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1836 if self.with {
1837 write!(f, "WITH ")?;
1838 }
1839 write!(f, "TAG ({})", display_comma_separated(&self.tags))?;
1840 Ok(())
1841 }
1842}
1843
1844#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1847#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1848#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1849pub enum ColumnOption {
1850 Null,
1852 NotNull,
1854 Default(Expr),
1856
1857 Materialized(Expr),
1862 Ephemeral(Option<Expr>),
1866 Alias(Expr),
1870
1871 Unique {
1873 is_primary: bool,
1874 characteristics: Option<ConstraintCharacteristics>,
1875 },
1876 ForeignKey {
1884 foreign_table: ObjectName,
1885 referred_columns: Vec<Ident>,
1886 on_delete: Option<ReferentialAction>,
1887 on_update: Option<ReferentialAction>,
1888 characteristics: Option<ConstraintCharacteristics>,
1889 },
1890 Check(Expr),
1892 DialectSpecific(Vec<Token>),
1896 CharacterSet(ObjectName),
1897 Collation(ObjectName),
1898 Comment(String),
1899 OnUpdate(Expr),
1900 Generated {
1903 generated_as: GeneratedAs,
1904 sequence_options: Option<Vec<SequenceOptions>>,
1905 generation_expr: Option<Expr>,
1906 generation_expr_mode: Option<GeneratedExpressionMode>,
1907 generated_keyword: bool,
1909 },
1910 Options(Vec<SqlOption>),
1918 Identity(IdentityPropertyKind),
1926 OnConflict(Keyword),
1929 Policy(ColumnPolicy),
1937 Tags(TagsColumnOption),
1944 Srid(Box<Expr>),
1951}
1952
1953impl fmt::Display for ColumnOption {
1954 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1955 use ColumnOption::*;
1956 match self {
1957 Null => write!(f, "NULL"),
1958 NotNull => write!(f, "NOT NULL"),
1959 Default(expr) => write!(f, "DEFAULT {expr}"),
1960 Materialized(expr) => write!(f, "MATERIALIZED {expr}"),
1961 Ephemeral(expr) => {
1962 if let Some(e) = expr {
1963 write!(f, "EPHEMERAL {e}")
1964 } else {
1965 write!(f, "EPHEMERAL")
1966 }
1967 }
1968 Alias(expr) => write!(f, "ALIAS {expr}"),
1969 Unique {
1970 is_primary,
1971 characteristics,
1972 } => {
1973 write!(f, "{}", if *is_primary { "PRIMARY KEY" } else { "UNIQUE" })?;
1974 if let Some(characteristics) = characteristics {
1975 write!(f, " {characteristics}")?;
1976 }
1977 Ok(())
1978 }
1979 ForeignKey {
1980 foreign_table,
1981 referred_columns,
1982 on_delete,
1983 on_update,
1984 characteristics,
1985 } => {
1986 write!(f, "REFERENCES {foreign_table}")?;
1987 if !referred_columns.is_empty() {
1988 write!(f, " ({})", display_comma_separated(referred_columns))?;
1989 }
1990 if let Some(action) = on_delete {
1991 write!(f, " ON DELETE {action}")?;
1992 }
1993 if let Some(action) = on_update {
1994 write!(f, " ON UPDATE {action}")?;
1995 }
1996 if let Some(characteristics) = characteristics {
1997 write!(f, " {characteristics}")?;
1998 }
1999 Ok(())
2000 }
2001 Check(expr) => write!(f, "CHECK ({expr})"),
2002 DialectSpecific(val) => write!(f, "{}", display_separated(val, " ")),
2003 CharacterSet(n) => write!(f, "CHARACTER SET {n}"),
2004 Collation(n) => write!(f, "COLLATE {n}"),
2005 Comment(v) => write!(f, "COMMENT '{}'", escape_single_quote_string(v)),
2006 OnUpdate(expr) => write!(f, "ON UPDATE {expr}"),
2007 Generated {
2008 generated_as,
2009 sequence_options,
2010 generation_expr,
2011 generation_expr_mode,
2012 generated_keyword,
2013 } => {
2014 if let Some(expr) = generation_expr {
2015 let modifier = match generation_expr_mode {
2016 None => "",
2017 Some(GeneratedExpressionMode::Virtual) => " VIRTUAL",
2018 Some(GeneratedExpressionMode::Stored) => " STORED",
2019 };
2020 if *generated_keyword {
2021 write!(f, "GENERATED ALWAYS AS ({expr}){modifier}")?;
2022 } else {
2023 write!(f, "AS ({expr}){modifier}")?;
2024 }
2025 Ok(())
2026 } else {
2027 let when = match generated_as {
2029 GeneratedAs::Always => "ALWAYS",
2030 GeneratedAs::ByDefault => "BY DEFAULT",
2031 GeneratedAs::ExpStored => unreachable!(),
2033 };
2034 write!(f, "GENERATED {when} AS IDENTITY")?;
2035 if sequence_options.is_some() {
2036 let so = sequence_options.as_ref().unwrap();
2037 if !so.is_empty() {
2038 write!(f, " (")?;
2039 }
2040 for sequence_option in so {
2041 write!(f, "{sequence_option}")?;
2042 }
2043 if !so.is_empty() {
2044 write!(f, " )")?;
2045 }
2046 }
2047 Ok(())
2048 }
2049 }
2050 Options(options) => {
2051 write!(f, "OPTIONS({})", display_comma_separated(options))
2052 }
2053 Identity(parameters) => {
2054 write!(f, "{parameters}")
2055 }
2056 OnConflict(keyword) => {
2057 write!(f, "ON CONFLICT {keyword:?}")?;
2058 Ok(())
2059 }
2060 Policy(parameters) => {
2061 write!(f, "{parameters}")
2062 }
2063 Tags(tags) => {
2064 write!(f, "{tags}")
2065 }
2066 Srid(srid) => {
2067 write!(f, "SRID {srid}")
2068 }
2069 }
2070 }
2071}
2072
2073#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2076#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2077#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2078pub enum GeneratedAs {
2079 Always,
2080 ByDefault,
2081 ExpStored,
2082}
2083
2084#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2087#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2088#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2089pub enum GeneratedExpressionMode {
2090 Virtual,
2091 Stored,
2092}
2093
2094#[must_use]
2095fn display_constraint_name(name: &'_ Option<Ident>) -> impl fmt::Display + '_ {
2096 struct ConstraintName<'a>(&'a Option<Ident>);
2097 impl fmt::Display for ConstraintName<'_> {
2098 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2099 if let Some(name) = self.0 {
2100 write!(f, "CONSTRAINT {name} ")?;
2101 }
2102 Ok(())
2103 }
2104 }
2105 ConstraintName(name)
2106}
2107
2108#[must_use]
2112fn display_option<'a, T: fmt::Display>(
2113 prefix: &'a str,
2114 postfix: &'a str,
2115 option: &'a Option<T>,
2116) -> impl fmt::Display + 'a {
2117 struct OptionDisplay<'a, T>(&'a str, &'a str, &'a Option<T>);
2118 impl<T: fmt::Display> fmt::Display for OptionDisplay<'_, T> {
2119 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2120 if let Some(inner) = self.2 {
2121 let (prefix, postfix) = (self.0, self.1);
2122 write!(f, "{prefix}{inner}{postfix}")?;
2123 }
2124 Ok(())
2125 }
2126 }
2127 OptionDisplay(prefix, postfix, option)
2128}
2129
2130#[must_use]
2134fn display_option_spaced<T: fmt::Display>(option: &Option<T>) -> impl fmt::Display + '_ {
2135 display_option(" ", "", option)
2136}
2137
2138#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Default, Eq, Ord, Hash)]
2142#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2143#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2144pub struct ConstraintCharacteristics {
2145 pub deferrable: Option<bool>,
2147 pub initially: Option<DeferrableInitial>,
2149 pub enforced: Option<bool>,
2151}
2152
2153#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2154#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2155#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2156pub enum DeferrableInitial {
2157 Immediate,
2159 Deferred,
2161}
2162
2163impl ConstraintCharacteristics {
2164 fn deferrable_text(&self) -> Option<&'static str> {
2165 self.deferrable.map(|deferrable| {
2166 if deferrable {
2167 "DEFERRABLE"
2168 } else {
2169 "NOT DEFERRABLE"
2170 }
2171 })
2172 }
2173
2174 fn initially_immediate_text(&self) -> Option<&'static str> {
2175 self.initially
2176 .map(|initially_immediate| match initially_immediate {
2177 DeferrableInitial::Immediate => "INITIALLY IMMEDIATE",
2178 DeferrableInitial::Deferred => "INITIALLY DEFERRED",
2179 })
2180 }
2181
2182 fn enforced_text(&self) -> Option<&'static str> {
2183 self.enforced.map(
2184 |enforced| {
2185 if enforced {
2186 "ENFORCED"
2187 } else {
2188 "NOT ENFORCED"
2189 }
2190 },
2191 )
2192 }
2193}
2194
2195impl fmt::Display for ConstraintCharacteristics {
2196 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2197 let deferrable = self.deferrable_text();
2198 let initially_immediate = self.initially_immediate_text();
2199 let enforced = self.enforced_text();
2200
2201 match (deferrable, initially_immediate, enforced) {
2202 (None, None, None) => Ok(()),
2203 (None, None, Some(enforced)) => write!(f, "{enforced}"),
2204 (None, Some(initial), None) => write!(f, "{initial}"),
2205 (None, Some(initial), Some(enforced)) => write!(f, "{initial} {enforced}"),
2206 (Some(deferrable), None, None) => write!(f, "{deferrable}"),
2207 (Some(deferrable), None, Some(enforced)) => write!(f, "{deferrable} {enforced}"),
2208 (Some(deferrable), Some(initial), None) => write!(f, "{deferrable} {initial}"),
2209 (Some(deferrable), Some(initial), Some(enforced)) => {
2210 write!(f, "{deferrable} {initial} {enforced}")
2211 }
2212 }
2213 }
2214}
2215
2216#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2221#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2222#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2223pub enum ReferentialAction {
2224 Restrict,
2225 Cascade,
2226 SetNull,
2227 NoAction,
2228 SetDefault,
2229}
2230
2231impl fmt::Display for ReferentialAction {
2232 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2233 f.write_str(match self {
2234 ReferentialAction::Restrict => "RESTRICT",
2235 ReferentialAction::Cascade => "CASCADE",
2236 ReferentialAction::SetNull => "SET NULL",
2237 ReferentialAction::NoAction => "NO ACTION",
2238 ReferentialAction::SetDefault => "SET DEFAULT",
2239 })
2240 }
2241}
2242
2243#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2247#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2248#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2249pub enum DropBehavior {
2250 Restrict,
2251 Cascade,
2252}
2253
2254impl fmt::Display for DropBehavior {
2255 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2256 f.write_str(match self {
2257 DropBehavior::Restrict => "RESTRICT",
2258 DropBehavior::Cascade => "CASCADE",
2259 })
2260 }
2261}
2262
2263#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2265#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2266#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2267pub enum UserDefinedTypeRepresentation {
2268 Composite {
2269 attributes: Vec<UserDefinedTypeCompositeAttributeDef>,
2270 },
2271 Enum { labels: Vec<Ident> },
2273}
2274
2275impl fmt::Display for UserDefinedTypeRepresentation {
2276 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2277 match self {
2278 UserDefinedTypeRepresentation::Composite { attributes } => {
2279 write!(f, "({})", display_comma_separated(attributes))
2280 }
2281 UserDefinedTypeRepresentation::Enum { labels } => {
2282 write!(f, "ENUM ({})", display_comma_separated(labels))
2283 }
2284 }
2285 }
2286}
2287
2288#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2290#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2291#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2292pub struct UserDefinedTypeCompositeAttributeDef {
2293 pub name: Ident,
2294 pub data_type: DataType,
2295 pub collation: Option<ObjectName>,
2296}
2297
2298impl fmt::Display for UserDefinedTypeCompositeAttributeDef {
2299 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2300 write!(f, "{} {}", self.name, self.data_type)?;
2301 if let Some(collation) = &self.collation {
2302 write!(f, " COLLATE {collation}")?;
2303 }
2304 Ok(())
2305 }
2306}
2307
2308#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
2312#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2313#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2314pub enum Partition {
2315 Identifier(Ident),
2316 Expr(Expr),
2317 Part(Expr),
2320 Partitions(Vec<Expr>),
2321}
2322
2323impl fmt::Display for Partition {
2324 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2325 match self {
2326 Partition::Identifier(id) => write!(f, "PARTITION ID {id}"),
2327 Partition::Expr(expr) => write!(f, "PARTITION {expr}"),
2328 Partition::Part(expr) => write!(f, "PART {expr}"),
2329 Partition::Partitions(partitions) => {
2330 write!(f, "PARTITION ({})", display_comma_separated(partitions))
2331 }
2332 }
2333 }
2334}
2335
2336#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2339#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2340#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2341pub enum Deduplicate {
2342 All,
2343 ByExpression(Expr),
2344}
2345
2346impl fmt::Display for Deduplicate {
2347 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2348 match self {
2349 Deduplicate::All => write!(f, "DEDUPLICATE"),
2350 Deduplicate::ByExpression(expr) => write!(f, "DEDUPLICATE BY {expr}"),
2351 }
2352 }
2353}
2354
2355#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2360#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2361#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2362pub struct ClusteredBy {
2363 pub columns: Vec<Ident>,
2364 pub sorted_by: Option<Vec<OrderByExpr>>,
2365 pub num_buckets: Value,
2366}
2367
2368impl fmt::Display for ClusteredBy {
2369 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2370 write!(
2371 f,
2372 "CLUSTERED BY ({})",
2373 display_comma_separated(&self.columns)
2374 )?;
2375 if let Some(ref sorted_by) = self.sorted_by {
2376 write!(f, " SORTED BY ({})", display_comma_separated(sorted_by))?;
2377 }
2378 write!(f, " INTO {} BUCKETS", self.num_buckets)
2379 }
2380}
2381
2382#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2384#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2385#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2386pub struct CreateIndex {
2387 pub name: Option<ObjectName>,
2389 #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
2390 pub table_name: ObjectName,
2391 pub using: Option<IndexType>,
2392 pub columns: Vec<IndexColumn>,
2393 pub unique: bool,
2394 pub concurrently: bool,
2395 pub if_not_exists: bool,
2396 pub include: Vec<Ident>,
2397 pub nulls_distinct: Option<bool>,
2398 pub with: Vec<Expr>,
2400 pub predicate: Option<Expr>,
2401 pub index_options: Vec<IndexOption>,
2402 pub alter_options: Vec<AlterTableOperation>,
2409}
2410
2411impl fmt::Display for CreateIndex {
2412 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2413 write!(
2414 f,
2415 "CREATE {unique}INDEX {concurrently}{if_not_exists}",
2416 unique = if self.unique { "UNIQUE " } else { "" },
2417 concurrently = if self.concurrently {
2418 "CONCURRENTLY "
2419 } else {
2420 ""
2421 },
2422 if_not_exists = if self.if_not_exists {
2423 "IF NOT EXISTS "
2424 } else {
2425 ""
2426 },
2427 )?;
2428 if let Some(value) = &self.name {
2429 write!(f, "{value} ")?;
2430 }
2431 write!(f, "ON {}", self.table_name)?;
2432 if let Some(value) = &self.using {
2433 write!(f, " USING {value} ")?;
2434 }
2435 write!(f, "({})", display_comma_separated(&self.columns))?;
2436 if !self.include.is_empty() {
2437 write!(f, " INCLUDE ({})", display_comma_separated(&self.include))?;
2438 }
2439 if let Some(value) = self.nulls_distinct {
2440 if value {
2441 write!(f, " NULLS DISTINCT")?;
2442 } else {
2443 write!(f, " NULLS NOT DISTINCT")?;
2444 }
2445 }
2446 if !self.with.is_empty() {
2447 write!(f, " WITH ({})", display_comma_separated(&self.with))?;
2448 }
2449 if let Some(predicate) = &self.predicate {
2450 write!(f, " WHERE {predicate}")?;
2451 }
2452 if !self.index_options.is_empty() {
2453 write!(f, " {}", display_separated(&self.index_options, " "))?;
2454 }
2455 if !self.alter_options.is_empty() {
2456 write!(f, " {}", display_separated(&self.alter_options, " "))?;
2457 }
2458 Ok(())
2459 }
2460}
2461
2462#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2464#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2465#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2466pub struct CreateTable {
2467 pub or_replace: bool,
2468 pub temporary: bool,
2469 pub external: bool,
2470 pub dynamic: bool,
2471 pub global: Option<bool>,
2472 pub if_not_exists: bool,
2473 pub transient: bool,
2474 pub volatile: bool,
2475 pub iceberg: bool,
2476 #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
2478 pub name: ObjectName,
2479 pub columns: Vec<ColumnDef>,
2481 pub constraints: Vec<TableConstraint>,
2482 pub hive_distribution: HiveDistributionStyle,
2483 pub hive_formats: Option<HiveFormat>,
2484 pub table_options: CreateTableOptions,
2485 pub file_format: Option<FileFormat>,
2486 pub location: Option<String>,
2487 pub query: Option<Box<Query>>,
2488 pub without_rowid: bool,
2489 pub like: Option<CreateTableLikeKind>,
2490 pub clone: Option<ObjectName>,
2491 pub copy: Option<ObjectName>,
2492 pub version: Option<TableVersion>,
2493 pub comment: Option<CommentDef>,
2497 pub on_commit: Option<OnCommit>,
2498 pub on_cluster: Option<Ident>,
2501 pub primary_key: Option<Box<Expr>>,
2504 pub order_by: Option<OneOrManyWithParens<Expr>>,
2508 pub partition_by: Option<Box<Expr>>,
2511 pub cluster_by: Option<WrappedCollection<Vec<Expr>>>,
2516 pub clustered_by: Option<ClusteredBy>,
2519 pub inherits: Option<Vec<ObjectName>>,
2524 pub strict: bool,
2528 pub copy_grants: bool,
2531 pub enable_schema_evolution: Option<bool>,
2534 pub change_tracking: Option<bool>,
2537 pub data_retention_time_in_days: Option<u64>,
2540 pub max_data_extension_time_in_days: Option<u64>,
2543 pub default_ddl_collation: Option<String>,
2546 pub with_aggregation_policy: Option<ObjectName>,
2549 pub with_row_access_policy: Option<RowAccessPolicy>,
2552 pub with_tags: Option<Vec<Tag>>,
2555 pub external_volume: Option<String>,
2558 pub base_location: Option<String>,
2561 pub catalog: Option<String>,
2564 pub catalog_sync: Option<String>,
2567 pub storage_serialization_policy: Option<StorageSerializationPolicy>,
2570 pub target_lag: Option<String>,
2573 pub warehouse: Option<Ident>,
2576 pub refresh_mode: Option<RefreshModeKind>,
2579 pub initialize: Option<InitializeKind>,
2582 pub require_user: bool,
2585}
2586
2587impl fmt::Display for CreateTable {
2588 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2589 write!(
2597 f,
2598 "CREATE {or_replace}{external}{global}{temporary}{transient}{volatile}{dynamic}{iceberg}TABLE {if_not_exists}{name}",
2599 or_replace = if self.or_replace { "OR REPLACE " } else { "" },
2600 external = if self.external { "EXTERNAL " } else { "" },
2601 global = self.global
2602 .map(|global| {
2603 if global {
2604 "GLOBAL "
2605 } else {
2606 "LOCAL "
2607 }
2608 })
2609 .unwrap_or(""),
2610 if_not_exists = if self.if_not_exists { "IF NOT EXISTS " } else { "" },
2611 temporary = if self.temporary { "TEMPORARY " } else { "" },
2612 transient = if self.transient { "TRANSIENT " } else { "" },
2613 volatile = if self.volatile { "VOLATILE " } else { "" },
2614 iceberg = if self.iceberg { "ICEBERG " } else { "" },
2616 dynamic = if self.dynamic { "DYNAMIC " } else { "" },
2617 name = self.name,
2618 )?;
2619 if let Some(on_cluster) = &self.on_cluster {
2620 write!(f, " ON CLUSTER {on_cluster}")?;
2621 }
2622 if !self.columns.is_empty() || !self.constraints.is_empty() {
2623 f.write_str(" (")?;
2624 NewLine.fmt(f)?;
2625 Indent(DisplayCommaSeparated(&self.columns)).fmt(f)?;
2626 if !self.columns.is_empty() && !self.constraints.is_empty() {
2627 f.write_str(",")?;
2628 SpaceOrNewline.fmt(f)?;
2629 }
2630 Indent(DisplayCommaSeparated(&self.constraints)).fmt(f)?;
2631 NewLine.fmt(f)?;
2632 f.write_str(")")?;
2633 } else if self.query.is_none() && self.like.is_none() && self.clone.is_none() && self.copy.is_none() {
2634 f.write_str(" ()")?;
2636 } else if let Some(CreateTableLikeKind::Parenthesized(like_in_columns_list)) = &self.like {
2637 write!(f, " ({like_in_columns_list})")?;
2638 }
2639
2640 if let Some(comment) = &self.comment {
2643 write!(f, " COMMENT '{comment}'")?;
2644 }
2645
2646 if self.without_rowid {
2648 write!(f, " WITHOUT ROWID")?;
2649 }
2650
2651 if let Some(CreateTableLikeKind::Plain(like)) = &self.like {
2652 write!(f, " {like}")?;
2653 }
2654
2655 if let Some(c) = &self.clone {
2656 write!(f, " CLONE {c}")?;
2657 }
2658
2659 if let Some(c) = &self.copy {
2660 write!(f, " COPY {c}")?;
2661 }
2662
2663 if let Some(version) = &self.version {
2664 write!(f, " {version}")?;
2665 }
2666
2667 match &self.hive_distribution {
2668 HiveDistributionStyle::PARTITIONED { columns } => {
2669 write!(f, " PARTITIONED BY ({})", display_comma_separated(columns))?;
2670 }
2671 HiveDistributionStyle::SKEWED {
2672 columns,
2673 on,
2674 stored_as_directories,
2675 } => {
2676 write!(
2677 f,
2678 " SKEWED BY ({})) ON ({})",
2679 display_comma_separated(columns),
2680 display_comma_separated(on)
2681 )?;
2682 if *stored_as_directories {
2683 write!(f, " STORED AS DIRECTORIES")?;
2684 }
2685 }
2686 _ => (),
2687 }
2688
2689 if let Some(clustered_by) = &self.clustered_by {
2690 write!(f, " {clustered_by}")?;
2691 }
2692
2693 if let Some(HiveFormat {
2694 row_format,
2695 serde_properties,
2696 storage,
2697 location,
2698 }) = &self.hive_formats
2699 {
2700 match row_format {
2701 Some(HiveRowFormat::SERDE { class }) => write!(f, " ROW FORMAT SERDE '{class}'")?,
2702 Some(HiveRowFormat::DELIMITED { delimiters }) => {
2703 write!(f, " ROW FORMAT DELIMITED")?;
2704 if !delimiters.is_empty() {
2705 write!(f, " {}", display_separated(delimiters, " "))?;
2706 }
2707 }
2708 None => (),
2709 }
2710 match storage {
2711 Some(HiveIOFormat::IOF {
2712 input_format,
2713 output_format,
2714 }) => write!(
2715 f,
2716 " STORED AS INPUTFORMAT {input_format} OUTPUTFORMAT {output_format}"
2717 )?,
2718 Some(HiveIOFormat::FileFormat { format }) if !self.external => {
2719 write!(f, " STORED AS {format}")?
2720 }
2721 _ => (),
2722 }
2723 if let Some(serde_properties) = serde_properties.as_ref() {
2724 write!(
2725 f,
2726 " WITH SERDEPROPERTIES ({})",
2727 display_comma_separated(serde_properties)
2728 )?;
2729 }
2730 if !self.external {
2731 if let Some(loc) = location {
2732 write!(f, " LOCATION '{loc}'")?;
2733 }
2734 }
2735 }
2736 if self.external {
2737 if let Some(file_format) = self.file_format {
2738 write!(f, " STORED AS {file_format}")?;
2739 }
2740 write!(f, " LOCATION '{}'", self.location.as_ref().unwrap())?;
2741 }
2742
2743 match &self.table_options {
2744 options @ CreateTableOptions::With(_)
2745 | options @ CreateTableOptions::Plain(_)
2746 | options @ CreateTableOptions::TableProperties(_) => write!(f, " {options}")?,
2747 _ => (),
2748 }
2749
2750 if let Some(primary_key) = &self.primary_key {
2751 write!(f, " PRIMARY KEY {primary_key}")?;
2752 }
2753 if let Some(order_by) = &self.order_by {
2754 write!(f, " ORDER BY {order_by}")?;
2755 }
2756 if let Some(inherits) = &self.inherits {
2757 write!(f, " INHERITS ({})", display_comma_separated(inherits))?;
2758 }
2759 if let Some(partition_by) = self.partition_by.as_ref() {
2760 write!(f, " PARTITION BY {partition_by}")?;
2761 }
2762 if let Some(cluster_by) = self.cluster_by.as_ref() {
2763 write!(f, " CLUSTER BY {cluster_by}")?;
2764 }
2765 if let options @ CreateTableOptions::Options(_) = &self.table_options {
2766 write!(f, " {options}")?;
2767 }
2768 if let Some(external_volume) = self.external_volume.as_ref() {
2769 write!(f, " EXTERNAL_VOLUME='{external_volume}'")?;
2770 }
2771
2772 if let Some(catalog) = self.catalog.as_ref() {
2773 write!(f, " CATALOG='{catalog}'")?;
2774 }
2775
2776 if self.iceberg {
2777 if let Some(base_location) = self.base_location.as_ref() {
2778 write!(f, " BASE_LOCATION='{base_location}'")?;
2779 }
2780 }
2781
2782 if let Some(catalog_sync) = self.catalog_sync.as_ref() {
2783 write!(f, " CATALOG_SYNC='{catalog_sync}'")?;
2784 }
2785
2786 if let Some(storage_serialization_policy) = self.storage_serialization_policy.as_ref() {
2787 write!(
2788 f,
2789 " STORAGE_SERIALIZATION_POLICY={storage_serialization_policy}"
2790 )?;
2791 }
2792
2793 if self.copy_grants {
2794 write!(f, " COPY GRANTS")?;
2795 }
2796
2797 if let Some(is_enabled) = self.enable_schema_evolution {
2798 write!(
2799 f,
2800 " ENABLE_SCHEMA_EVOLUTION={}",
2801 if is_enabled { "TRUE" } else { "FALSE" }
2802 )?;
2803 }
2804
2805 if let Some(is_enabled) = self.change_tracking {
2806 write!(
2807 f,
2808 " CHANGE_TRACKING={}",
2809 if is_enabled { "TRUE" } else { "FALSE" }
2810 )?;
2811 }
2812
2813 if let Some(data_retention_time_in_days) = self.data_retention_time_in_days {
2814 write!(
2815 f,
2816 " DATA_RETENTION_TIME_IN_DAYS={data_retention_time_in_days}",
2817 )?;
2818 }
2819
2820 if let Some(max_data_extension_time_in_days) = self.max_data_extension_time_in_days {
2821 write!(
2822 f,
2823 " MAX_DATA_EXTENSION_TIME_IN_DAYS={max_data_extension_time_in_days}",
2824 )?;
2825 }
2826
2827 if let Some(default_ddl_collation) = &self.default_ddl_collation {
2828 write!(f, " DEFAULT_DDL_COLLATION='{default_ddl_collation}'",)?;
2829 }
2830
2831 if let Some(with_aggregation_policy) = &self.with_aggregation_policy {
2832 write!(f, " WITH AGGREGATION POLICY {with_aggregation_policy}",)?;
2833 }
2834
2835 if let Some(row_access_policy) = &self.with_row_access_policy {
2836 write!(f, " {row_access_policy}",)?;
2837 }
2838
2839 if let Some(tag) = &self.with_tags {
2840 write!(f, " WITH TAG ({})", display_comma_separated(tag.as_slice()))?;
2841 }
2842
2843 if let Some(target_lag) = &self.target_lag {
2844 write!(f, " TARGET_LAG='{target_lag}'")?;
2845 }
2846
2847 if let Some(warehouse) = &self.warehouse {
2848 write!(f, " WAREHOUSE={warehouse}")?;
2849 }
2850
2851 if let Some(refresh_mode) = &self.refresh_mode {
2852 write!(f, " REFRESH_MODE={refresh_mode}")?;
2853 }
2854
2855 if let Some(initialize) = &self.initialize {
2856 write!(f, " INITIALIZE={initialize}")?;
2857 }
2858
2859 if self.require_user {
2860 write!(f, " REQUIRE USER")?;
2861 }
2862
2863 if self.on_commit.is_some() {
2864 let on_commit = match self.on_commit {
2865 Some(OnCommit::DeleteRows) => "ON COMMIT DELETE ROWS",
2866 Some(OnCommit::PreserveRows) => "ON COMMIT PRESERVE ROWS",
2867 Some(OnCommit::Drop) => "ON COMMIT DROP",
2868 None => "",
2869 };
2870 write!(f, " {on_commit}")?;
2871 }
2872 if self.strict {
2873 write!(f, " STRICT")?;
2874 }
2875 if let Some(query) = &self.query {
2876 write!(f, " AS {query}")?;
2877 }
2878 Ok(())
2879 }
2880}
2881
2882#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2883#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2884#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2885pub struct CreateDomain {
2898 pub name: ObjectName,
2900 pub data_type: DataType,
2902 pub collation: Option<Ident>,
2904 pub default: Option<Expr>,
2906 pub constraints: Vec<TableConstraint>,
2908}
2909
2910impl fmt::Display for CreateDomain {
2911 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2912 write!(
2913 f,
2914 "CREATE DOMAIN {name} AS {data_type}",
2915 name = self.name,
2916 data_type = self.data_type
2917 )?;
2918 if let Some(collation) = &self.collation {
2919 write!(f, " COLLATE {collation}")?;
2920 }
2921 if let Some(default) = &self.default {
2922 write!(f, " DEFAULT {default}")?;
2923 }
2924 if !self.constraints.is_empty() {
2925 write!(f, " {}", display_separated(&self.constraints, " "))?;
2926 }
2927 Ok(())
2928 }
2929}
2930
2931#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
2935#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2936#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2937pub enum SqlSecurity {
2938 Definer,
2939 Invoker,
2940}
2941
2942impl fmt::Display for SqlSecurity {
2943 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2944 match self {
2945 SqlSecurity::Definer => write!(f, "SQL SECURITY DEFINER"),
2946 SqlSecurity::Invoker => write!(f, "SQL SECURITY INVOKER"),
2947 }
2948 }
2949}
2950
2951#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2952#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2953#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2954pub struct CreateFunction {
2955 pub or_alter: bool,
2959 pub or_replace: bool,
2960 pub temporary: bool,
2961 pub if_not_exists: bool,
2962 pub aggregate: bool,
2964 pub table_function: bool,
2966 pub name: ObjectName,
2967 pub args: Option<Vec<OperateFunctionArg>>,
2968 pub return_type: Option<DataType>,
2969 pub function_body: Option<CreateFunctionBody>,
2977 pub behavior: Option<FunctionBehavior>,
2983 pub called_on_null: Option<FunctionCalledOnNull>,
2987 pub parallel: Option<FunctionParallel>,
2991 pub using: Option<CreateFunctionUsing>,
2993 pub language: Option<Ident>,
3001 pub determinism_specifier: Option<FunctionDeterminismSpecifier>,
3005 pub options: Option<Vec<SqlOption>>,
3009 pub remote_connection: Option<ObjectName>,
3019 pub sql_security: Option<SqlSecurity>,
3023}
3024
3025impl fmt::Display for CreateFunction {
3026 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3027 write!(
3028 f,
3029 "CREATE {or_alter}{or_replace}{temp}{aggregate}{table}FUNCTION {if_not_exists}{name}",
3030 name = self.name,
3031 temp = if self.temporary { "TEMPORARY " } else { "" },
3032 or_alter = if self.or_alter { "OR ALTER " } else { "" },
3033 or_replace = if self.or_replace { "OR REPLACE " } else { "" },
3034 aggregate = if self.aggregate { "AGGREGATE " } else { "" },
3035 table = if self.table_function { "TABLE " } else { "" },
3036 if_not_exists = if self.if_not_exists {
3037 "IF NOT EXISTS "
3038 } else {
3039 ""
3040 },
3041 )?;
3042 if let Some(args) = &self.args {
3043 write!(f, "({})", display_comma_separated(args))?;
3044 }
3045 if let Some(return_type) = &self.return_type {
3046 write!(f, " RETURNS {return_type}")?;
3047 }
3048 if let Some(determinism_specifier) = &self.determinism_specifier {
3049 write!(f, " {determinism_specifier}")?;
3050 }
3051 if let Some(language) = &self.language {
3052 write!(f, " LANGUAGE {language}")?;
3053 }
3054 if let Some(behavior) = &self.behavior {
3055 write!(f, " {behavior}")?;
3056 }
3057 if let Some(called_on_null) = &self.called_on_null {
3058 write!(f, " {called_on_null}")?;
3059 }
3060 if let Some(parallel) = &self.parallel {
3061 write!(f, " {parallel}")?;
3062 }
3063 if let Some(remote_connection) = &self.remote_connection {
3064 write!(f, " REMOTE WITH CONNECTION {remote_connection}")?;
3065 }
3066 if let Some(sql_security) = &self.sql_security {
3067 write!(f, " {sql_security}")?;
3068 }
3069 if let Some(CreateFunctionBody::AsBeforeOptions(function_body)) = &self.function_body {
3070 write!(f, " AS {function_body}")?;
3071 }
3072 if let Some(CreateFunctionBody::Return(function_body)) = &self.function_body {
3073 write!(f, " RETURN {function_body}")?;
3074 }
3075 if let Some(CreateFunctionBody::AsReturnExpr(function_body)) = &self.function_body {
3076 write!(f, " AS RETURN {function_body}")?;
3077 }
3078 if let Some(CreateFunctionBody::AsReturnSelect(function_body)) = &self.function_body {
3079 write!(f, " AS RETURN {function_body}")?;
3080 }
3081 if let Some(using) = &self.using {
3082 write!(f, " {using}")?;
3083 }
3084 if let Some(options) = &self.options {
3085 write!(
3086 f,
3087 " OPTIONS({})",
3088 display_comma_separated(options.as_slice())
3089 )?;
3090 }
3091 if let Some(CreateFunctionBody::AsAfterOptions(function_body)) = &self.function_body {
3092 write!(f, " AS {function_body}")?;
3093 }
3094 if let Some(CreateFunctionBody::AsBeginEnd(bes)) = &self.function_body {
3095 write!(f, " AS {bes}")?;
3096 }
3097 Ok(())
3098 }
3099}
3100
3101#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
3111#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3112#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
3113pub struct CreateConnector {
3114 pub name: Ident,
3115 pub if_not_exists: bool,
3116 pub connector_type: Option<String>,
3117 pub url: Option<String>,
3118 pub comment: Option<CommentDef>,
3119 pub with_dcproperties: Option<Vec<SqlOption>>,
3120}
3121
3122impl fmt::Display for CreateConnector {
3123 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3124 write!(
3125 f,
3126 "CREATE CONNECTOR {if_not_exists}{name}",
3127 if_not_exists = if self.if_not_exists {
3128 "IF NOT EXISTS "
3129 } else {
3130 ""
3131 },
3132 name = self.name,
3133 )?;
3134
3135 if let Some(connector_type) = &self.connector_type {
3136 write!(f, " TYPE '{connector_type}'")?;
3137 }
3138
3139 if let Some(url) = &self.url {
3140 write!(f, " URL '{url}'")?;
3141 }
3142
3143 if let Some(comment) = &self.comment {
3144 write!(f, " COMMENT = '{comment}'")?;
3145 }
3146
3147 if let Some(with_dcproperties) = &self.with_dcproperties {
3148 write!(
3149 f,
3150 " WITH DCPROPERTIES({})",
3151 display_comma_separated(with_dcproperties)
3152 )?;
3153 }
3154
3155 Ok(())
3156 }
3157}
3158
3159#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
3164#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3165#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
3166pub enum AlterSchemaOperation {
3167 SetDefaultCollate {
3168 collate: Expr,
3169 },
3170 AddReplica {
3171 replica: Ident,
3172 options: Option<Vec<SqlOption>>,
3173 },
3174 DropReplica {
3175 replica: Ident,
3176 },
3177 SetOptionsParens {
3178 options: Vec<SqlOption>,
3179 },
3180 Rename {
3181 name: ObjectName,
3182 },
3183 OwnerTo {
3184 owner: Owner,
3185 },
3186}
3187
3188impl fmt::Display for AlterSchemaOperation {
3189 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3190 match self {
3191 AlterSchemaOperation::SetDefaultCollate { collate } => {
3192 write!(f, "SET DEFAULT COLLATE {collate}")
3193 }
3194 AlterSchemaOperation::AddReplica { replica, options } => {
3195 write!(f, "ADD REPLICA {replica}")?;
3196 if let Some(options) = options {
3197 write!(f, " OPTIONS ({})", display_comma_separated(options))?;
3198 }
3199 Ok(())
3200 }
3201 AlterSchemaOperation::DropReplica { replica } => write!(f, "DROP REPLICA {replica}"),
3202 AlterSchemaOperation::SetOptionsParens { options } => {
3203 write!(f, "SET OPTIONS ({})", display_comma_separated(options))
3204 }
3205 AlterSchemaOperation::Rename { name } => write!(f, "RENAME TO {name}"),
3206 AlterSchemaOperation::OwnerTo { owner } => write!(f, "OWNER TO {owner}"),
3207 }
3208 }
3209}
3210#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
3216#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3217#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
3218pub enum RenameTableNameKind {
3219 As(ObjectName),
3220 To(ObjectName),
3221}
3222
3223impl fmt::Display for RenameTableNameKind {
3224 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3225 match self {
3226 RenameTableNameKind::As(name) => write!(f, "AS {name}"),
3227 RenameTableNameKind::To(name) => write!(f, "TO {name}"),
3228 }
3229 }
3230}
3231
3232#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
3233#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3234#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
3235pub struct AlterSchema {
3236 pub name: ObjectName,
3237 pub if_exists: bool,
3238 pub operations: Vec<AlterSchemaOperation>,
3239}
3240
3241impl fmt::Display for AlterSchema {
3242 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3243 write!(f, "ALTER SCHEMA ")?;
3244 if self.if_exists {
3245 write!(f, "IF EXISTS ")?;
3246 }
3247 write!(f, "{}", self.name)?;
3248 for operation in &self.operations {
3249 write!(f, " {operation}")?;
3250 }
3251
3252 Ok(())
3253 }
3254}
3255
3256impl Spanned for RenameTableNameKind {
3257 fn span(&self) -> Span {
3258 match self {
3259 RenameTableNameKind::As(name) => name.span(),
3260 RenameTableNameKind::To(name) => name.span(),
3261 }
3262 }
3263}
3264
3265#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
3266#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3267#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
3268pub struct CreateTrigger {
3282 pub or_alter: bool,
3286 pub or_replace: bool,
3296 pub is_constraint: bool,
3298 pub name: ObjectName,
3300 pub period: TriggerPeriod,
3329 pub period_before_table: bool,
3338 pub events: Vec<TriggerEvent>,
3340 pub table_name: ObjectName,
3342 pub referenced_table_name: Option<ObjectName>,
3345 pub referencing: Vec<TriggerReferencing>,
3347 pub trigger_object: TriggerObject,
3350 pub include_each: bool,
3352 pub condition: Option<Expr>,
3354 pub exec_body: Option<TriggerExecBody>,
3356 pub statements_as: bool,
3358 pub statements: Option<ConditionalStatements>,
3360 pub characteristics: Option<ConstraintCharacteristics>,
3362}
3363
3364impl Display for CreateTrigger {
3365 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3366 let CreateTrigger {
3367 or_alter,
3368 or_replace,
3369 is_constraint,
3370 name,
3371 period_before_table,
3372 period,
3373 events,
3374 table_name,
3375 referenced_table_name,
3376 referencing,
3377 trigger_object,
3378 condition,
3379 include_each,
3380 exec_body,
3381 statements_as,
3382 statements,
3383 characteristics,
3384 } = self;
3385 write!(
3386 f,
3387 "CREATE {or_alter}{or_replace}{is_constraint}TRIGGER {name} ",
3388 or_alter = if *or_alter { "OR ALTER " } else { "" },
3389 or_replace = if *or_replace { "OR REPLACE " } else { "" },
3390 is_constraint = if *is_constraint { "CONSTRAINT " } else { "" },
3391 )?;
3392
3393 if *period_before_table {
3394 write!(f, "{period}")?;
3395 if !events.is_empty() {
3396 write!(f, " {}", display_separated(events, " OR "))?;
3397 }
3398 write!(f, " ON {table_name}")?;
3399 } else {
3400 write!(f, "ON {table_name}")?;
3401 write!(f, " {period}")?;
3402 if !events.is_empty() {
3403 write!(f, " {}", display_separated(events, ", "))?;
3404 }
3405 }
3406
3407 if let Some(referenced_table_name) = referenced_table_name {
3408 write!(f, " FROM {referenced_table_name}")?;
3409 }
3410
3411 if let Some(characteristics) = characteristics {
3412 write!(f, " {characteristics}")?;
3413 }
3414
3415 if !referencing.is_empty() {
3416 write!(f, " REFERENCING {}", display_separated(referencing, " "))?;
3417 }
3418
3419 if *include_each {
3420 write!(f, " FOR EACH {trigger_object}")?;
3421 } else if exec_body.is_some() {
3422 write!(f, " FOR {trigger_object}")?;
3423 }
3424 if let Some(condition) = condition {
3425 write!(f, " WHEN {condition}")?;
3426 }
3427 if let Some(exec_body) = exec_body {
3428 write!(f, " EXECUTE {exec_body}")?;
3429 }
3430 if let Some(statements) = statements {
3431 if *statements_as {
3432 write!(f, " AS")?;
3433 }
3434 write!(f, " {statements}")?;
3435 }
3436 Ok(())
3437 }
3438}
3439
3440#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
3441#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3442#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
3443pub struct DropTrigger {
3450 pub if_exists: bool,
3452 pub trigger_name: ObjectName,
3454 pub table_name: Option<ObjectName>,
3456 pub option: Option<ReferentialAction>,
3458}
3459
3460impl fmt::Display for DropTrigger {
3461 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3462 let DropTrigger {
3463 if_exists,
3464 trigger_name,
3465 table_name,
3466 option,
3467 } = self;
3468 write!(f, "DROP TRIGGER")?;
3469 if *if_exists {
3470 write!(f, " IF EXISTS")?;
3471 }
3472 match &table_name {
3473 Some(table_name) => write!(f, " {trigger_name} ON {table_name}")?,
3474 None => write!(f, " {trigger_name}")?,
3475 };
3476 if let Some(option) = option {
3477 write!(f, " {option}")?;
3478 }
3479 Ok(())
3480 }
3481}