1#[cfg(not(feature = "std"))]
22use alloc::{boxed::Box, string::String, vec::Vec};
23use core::fmt::{self, Write};
24
25#[cfg(feature = "serde")]
26use serde::{Deserialize, Serialize};
27
28#[cfg(feature = "visitor")]
29use sqlparser_derive::{Visit, VisitMut};
30
31use crate::ast::value::escape_single_quote_string;
32use crate::ast::{
33 display_comma_separated, display_separated, ArgMode, CommentDef, CreateFunctionBody,
34 CreateFunctionUsing, DataType, Expr, FunctionBehavior, FunctionCalledOnNull,
35 FunctionDeterminismSpecifier, FunctionParallel, Ident, IndexColumn, MySQLColumnPosition,
36 ObjectName, OperateFunctionArg, OrderByExpr, ProjectionSelect, SequenceOptions, SqlOption, Tag,
37 Value, ValueWithSpan,
38};
39use crate::keywords::Keyword;
40use crate::tokenizer::Token;
41
42#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
45#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
46#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
47pub enum ReplicaIdentity {
48 None,
49 Full,
50 Default,
51 Index(Ident),
52}
53
54impl fmt::Display for ReplicaIdentity {
55 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
56 match self {
57 ReplicaIdentity::None => f.write_str("NONE"),
58 ReplicaIdentity::Full => f.write_str("FULL"),
59 ReplicaIdentity::Default => f.write_str("DEFAULT"),
60 ReplicaIdentity::Index(idx) => write!(f, "USING INDEX {idx}"),
61 }
62 }
63}
64
65#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
67#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
68#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
69pub enum AlterTableOperation {
70 AddConstraint {
72 constraint: TableConstraint,
73 not_valid: bool,
74 },
75 AddColumn {
77 column_keyword: bool,
79 if_not_exists: bool,
81 column_def: ColumnDef,
83 column_position: Option<MySQLColumnPosition>,
85 },
86 AddProjection {
91 if_not_exists: bool,
92 name: Ident,
93 select: ProjectionSelect,
94 },
95 DropProjection {
100 if_exists: bool,
101 name: Ident,
102 },
103 MaterializeProjection {
108 if_exists: bool,
109 name: Ident,
110 partition: Option<Ident>,
111 },
112 ClearProjection {
117 if_exists: bool,
118 name: Ident,
119 partition: Option<Ident>,
120 },
121 DisableRowLevelSecurity,
125 DisableRule {
129 name: Ident,
130 },
131 DisableTrigger {
135 name: Ident,
136 },
137 DropConstraint {
139 if_exists: bool,
140 name: Ident,
141 drop_behavior: Option<DropBehavior>,
142 },
143 DropColumn {
145 has_column_keyword: bool,
146 column_names: Vec<Ident>,
147 if_exists: bool,
148 drop_behavior: Option<DropBehavior>,
149 },
150 AttachPartition {
154 partition: Partition,
157 },
158 DetachPartition {
162 partition: Partition,
164 },
165 FreezePartition {
169 partition: Partition,
170 with_name: Option<Ident>,
171 },
172 UnfreezePartition {
176 partition: Partition,
177 with_name: Option<Ident>,
178 },
179 DropPrimaryKey,
185 DropForeignKey {
191 name: Ident,
192 },
193 DropIndex {
197 name: Ident,
198 },
199 EnableAlwaysRule {
203 name: Ident,
204 },
205 EnableAlwaysTrigger {
209 name: Ident,
210 },
211 EnableReplicaRule {
215 name: Ident,
216 },
217 EnableReplicaTrigger {
221 name: Ident,
222 },
223 EnableRowLevelSecurity,
227 EnableRule {
231 name: Ident,
232 },
233 EnableTrigger {
237 name: Ident,
238 },
239 RenamePartitions {
241 old_partitions: Vec<Expr>,
242 new_partitions: Vec<Expr>,
243 },
244 ReplicaIdentity {
249 identity: ReplicaIdentity,
250 },
251 AddPartitions {
253 if_not_exists: bool,
254 new_partitions: Vec<Partition>,
255 },
256 DropPartitions {
257 partitions: Vec<Expr>,
258 if_exists: bool,
259 },
260 RenameColumn {
262 old_column_name: Ident,
263 new_column_name: Ident,
264 },
265 RenameTable {
267 table_name: ObjectName,
268 },
269 ChangeColumn {
271 old_name: Ident,
272 new_name: Ident,
273 data_type: DataType,
274 options: Vec<ColumnOption>,
275 column_position: Option<MySQLColumnPosition>,
277 },
278 ModifyColumn {
280 col_name: Ident,
281 data_type: DataType,
282 options: Vec<ColumnOption>,
283 column_position: Option<MySQLColumnPosition>,
285 },
286 RenameConstraint {
290 old_name: Ident,
291 new_name: Ident,
292 },
293 AlterColumn {
295 column_name: Ident,
296 op: AlterColumnOperation,
297 },
298 SwapWith {
302 table_name: ObjectName,
303 },
304 SetTblProperties {
306 table_properties: Vec<SqlOption>,
307 },
308 OwnerTo {
312 new_owner: Owner,
313 },
314 ClusterBy {
317 exprs: Vec<Expr>,
318 },
319 DropClusteringKey,
320 SuspendRecluster,
321 ResumeRecluster,
322 Algorithm {
328 equals: bool,
329 algorithm: AlterTableAlgorithm,
330 },
331
332 Lock {
338 equals: bool,
339 lock: AlterTableLock,
340 },
341 AutoIncrement {
347 equals: bool,
348 value: ValueWithSpan,
349 },
350 ValidateConstraint {
352 name: Ident,
353 },
354}
355
356#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
360#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
361#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
362pub enum AlterPolicyOperation {
363 Rename {
364 new_name: Ident,
365 },
366 Apply {
367 to: Option<Vec<Owner>>,
368 using: Option<Expr>,
369 with_check: Option<Expr>,
370 },
371}
372
373impl fmt::Display for AlterPolicyOperation {
374 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
375 match self {
376 AlterPolicyOperation::Rename { new_name } => {
377 write!(f, " RENAME TO {new_name}")
378 }
379 AlterPolicyOperation::Apply {
380 to,
381 using,
382 with_check,
383 } => {
384 if let Some(to) = to {
385 write!(f, " TO {}", display_comma_separated(to))?;
386 }
387 if let Some(using) = using {
388 write!(f, " USING ({using})")?;
389 }
390 if let Some(with_check) = with_check {
391 write!(f, " WITH CHECK ({with_check})")?;
392 }
393 Ok(())
394 }
395 }
396 }
397}
398
399#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
403#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
404#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
405pub enum AlterTableAlgorithm {
406 Default,
407 Instant,
408 Inplace,
409 Copy,
410}
411
412impl fmt::Display for AlterTableAlgorithm {
413 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
414 f.write_str(match self {
415 Self::Default => "DEFAULT",
416 Self::Instant => "INSTANT",
417 Self::Inplace => "INPLACE",
418 Self::Copy => "COPY",
419 })
420 }
421}
422
423#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
427#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
428#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
429pub enum AlterTableLock {
430 Default,
431 None,
432 Shared,
433 Exclusive,
434}
435
436impl fmt::Display for AlterTableLock {
437 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
438 f.write_str(match self {
439 Self::Default => "DEFAULT",
440 Self::None => "NONE",
441 Self::Shared => "SHARED",
442 Self::Exclusive => "EXCLUSIVE",
443 })
444 }
445}
446
447#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
448#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
449#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
450pub enum Owner {
451 Ident(Ident),
452 CurrentRole,
453 CurrentUser,
454 SessionUser,
455}
456
457impl fmt::Display for Owner {
458 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
459 match self {
460 Owner::Ident(ident) => write!(f, "{ident}"),
461 Owner::CurrentRole => write!(f, "CURRENT_ROLE"),
462 Owner::CurrentUser => write!(f, "CURRENT_USER"),
463 Owner::SessionUser => write!(f, "SESSION_USER"),
464 }
465 }
466}
467
468#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
469#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
470#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
471pub enum AlterConnectorOwner {
472 User(Ident),
473 Role(Ident),
474}
475
476impl fmt::Display for AlterConnectorOwner {
477 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
478 match self {
479 AlterConnectorOwner::User(ident) => write!(f, "USER {ident}"),
480 AlterConnectorOwner::Role(ident) => write!(f, "ROLE {ident}"),
481 }
482 }
483}
484
485#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
486#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
487#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
488pub enum AlterIndexOperation {
489 RenameIndex { index_name: ObjectName },
490}
491
492impl fmt::Display for AlterTableOperation {
493 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
494 match self {
495 AlterTableOperation::AddPartitions {
496 if_not_exists,
497 new_partitions,
498 } => write!(
499 f,
500 "ADD{ine} {}",
501 display_separated(new_partitions, " "),
502 ine = if *if_not_exists { " IF NOT EXISTS" } else { "" }
503 ),
504 AlterTableOperation::AddConstraint {
505 not_valid,
506 constraint,
507 } => {
508 write!(f, "ADD {constraint}")?;
509 if *not_valid {
510 write!(f, " NOT VALID")?;
511 }
512 Ok(())
513 }
514 AlterTableOperation::AddColumn {
515 column_keyword,
516 if_not_exists,
517 column_def,
518 column_position,
519 } => {
520 write!(f, "ADD")?;
521 if *column_keyword {
522 write!(f, " COLUMN")?;
523 }
524 if *if_not_exists {
525 write!(f, " IF NOT EXISTS")?;
526 }
527 write!(f, " {column_def}")?;
528
529 if let Some(position) = column_position {
530 write!(f, " {position}")?;
531 }
532
533 Ok(())
534 }
535 AlterTableOperation::AddProjection {
536 if_not_exists,
537 name,
538 select: query,
539 } => {
540 write!(f, "ADD PROJECTION")?;
541 if *if_not_exists {
542 write!(f, " IF NOT EXISTS")?;
543 }
544 write!(f, " {name} ({query})")
545 }
546 AlterTableOperation::Algorithm { equals, algorithm } => {
547 write!(
548 f,
549 "ALGORITHM {}{}",
550 if *equals { "= " } else { "" },
551 algorithm
552 )
553 }
554 AlterTableOperation::DropProjection { if_exists, name } => {
555 write!(f, "DROP PROJECTION")?;
556 if *if_exists {
557 write!(f, " IF EXISTS")?;
558 }
559 write!(f, " {name}")
560 }
561 AlterTableOperation::MaterializeProjection {
562 if_exists,
563 name,
564 partition,
565 } => {
566 write!(f, "MATERIALIZE PROJECTION")?;
567 if *if_exists {
568 write!(f, " IF EXISTS")?;
569 }
570 write!(f, " {name}")?;
571 if let Some(partition) = partition {
572 write!(f, " IN PARTITION {partition}")?;
573 }
574 Ok(())
575 }
576 AlterTableOperation::ClearProjection {
577 if_exists,
578 name,
579 partition,
580 } => {
581 write!(f, "CLEAR PROJECTION")?;
582 if *if_exists {
583 write!(f, " IF EXISTS")?;
584 }
585 write!(f, " {name}")?;
586 if let Some(partition) = partition {
587 write!(f, " IN PARTITION {partition}")?;
588 }
589 Ok(())
590 }
591 AlterTableOperation::AlterColumn { column_name, op } => {
592 write!(f, "ALTER COLUMN {column_name} {op}")
593 }
594 AlterTableOperation::DisableRowLevelSecurity => {
595 write!(f, "DISABLE ROW LEVEL SECURITY")
596 }
597 AlterTableOperation::DisableRule { name } => {
598 write!(f, "DISABLE RULE {name}")
599 }
600 AlterTableOperation::DisableTrigger { name } => {
601 write!(f, "DISABLE TRIGGER {name}")
602 }
603 AlterTableOperation::DropPartitions {
604 partitions,
605 if_exists,
606 } => write!(
607 f,
608 "DROP{ie} PARTITION ({})",
609 display_comma_separated(partitions),
610 ie = if *if_exists { " IF EXISTS" } else { "" }
611 ),
612 AlterTableOperation::DropConstraint {
613 if_exists,
614 name,
615 drop_behavior,
616 } => {
617 write!(
618 f,
619 "DROP CONSTRAINT {}{}{}",
620 if *if_exists { "IF EXISTS " } else { "" },
621 name,
622 match drop_behavior {
623 None => "",
624 Some(DropBehavior::Restrict) => " RESTRICT",
625 Some(DropBehavior::Cascade) => " CASCADE",
626 }
627 )
628 }
629 AlterTableOperation::DropPrimaryKey => write!(f, "DROP PRIMARY KEY"),
630 AlterTableOperation::DropForeignKey { name } => write!(f, "DROP FOREIGN KEY {name}"),
631 AlterTableOperation::DropIndex { name } => write!(f, "DROP INDEX {name}"),
632 AlterTableOperation::DropColumn {
633 has_column_keyword,
634 column_names: column_name,
635 if_exists,
636 drop_behavior,
637 } => write!(
638 f,
639 "DROP {}{}{}{}",
640 if *has_column_keyword { "COLUMN " } else { "" },
641 if *if_exists { "IF EXISTS " } else { "" },
642 display_comma_separated(column_name),
643 match drop_behavior {
644 None => "",
645 Some(DropBehavior::Restrict) => " RESTRICT",
646 Some(DropBehavior::Cascade) => " CASCADE",
647 }
648 ),
649 AlterTableOperation::AttachPartition { partition } => {
650 write!(f, "ATTACH {partition}")
651 }
652 AlterTableOperation::DetachPartition { partition } => {
653 write!(f, "DETACH {partition}")
654 }
655 AlterTableOperation::EnableAlwaysRule { name } => {
656 write!(f, "ENABLE ALWAYS RULE {name}")
657 }
658 AlterTableOperation::EnableAlwaysTrigger { name } => {
659 write!(f, "ENABLE ALWAYS TRIGGER {name}")
660 }
661 AlterTableOperation::EnableReplicaRule { name } => {
662 write!(f, "ENABLE REPLICA RULE {name}")
663 }
664 AlterTableOperation::EnableReplicaTrigger { name } => {
665 write!(f, "ENABLE REPLICA TRIGGER {name}")
666 }
667 AlterTableOperation::EnableRowLevelSecurity => {
668 write!(f, "ENABLE ROW LEVEL SECURITY")
669 }
670 AlterTableOperation::EnableRule { name } => {
671 write!(f, "ENABLE RULE {name}")
672 }
673 AlterTableOperation::EnableTrigger { name } => {
674 write!(f, "ENABLE TRIGGER {name}")
675 }
676 AlterTableOperation::RenamePartitions {
677 old_partitions,
678 new_partitions,
679 } => write!(
680 f,
681 "PARTITION ({}) RENAME TO PARTITION ({})",
682 display_comma_separated(old_partitions),
683 display_comma_separated(new_partitions)
684 ),
685 AlterTableOperation::RenameColumn {
686 old_column_name,
687 new_column_name,
688 } => write!(f, "RENAME COLUMN {old_column_name} TO {new_column_name}"),
689 AlterTableOperation::RenameTable { table_name } => {
690 write!(f, "RENAME TO {table_name}")
691 }
692 AlterTableOperation::ChangeColumn {
693 old_name,
694 new_name,
695 data_type,
696 options,
697 column_position,
698 } => {
699 write!(f, "CHANGE COLUMN {old_name} {new_name} {data_type}")?;
700 if !options.is_empty() {
701 write!(f, " {}", display_separated(options, " "))?;
702 }
703 if let Some(position) = column_position {
704 write!(f, " {position}")?;
705 }
706
707 Ok(())
708 }
709 AlterTableOperation::ModifyColumn {
710 col_name,
711 data_type,
712 options,
713 column_position,
714 } => {
715 write!(f, "MODIFY COLUMN {col_name} {data_type}")?;
716 if !options.is_empty() {
717 write!(f, " {}", display_separated(options, " "))?;
718 }
719 if let Some(position) = column_position {
720 write!(f, " {position}")?;
721 }
722
723 Ok(())
724 }
725 AlterTableOperation::RenameConstraint { old_name, new_name } => {
726 write!(f, "RENAME CONSTRAINT {old_name} TO {new_name}")
727 }
728 AlterTableOperation::SwapWith { table_name } => {
729 write!(f, "SWAP WITH {table_name}")
730 }
731 AlterTableOperation::OwnerTo { new_owner } => {
732 write!(f, "OWNER TO {new_owner}")
733 }
734 AlterTableOperation::SetTblProperties { table_properties } => {
735 write!(
736 f,
737 "SET TBLPROPERTIES({})",
738 display_comma_separated(table_properties)
739 )
740 }
741 AlterTableOperation::FreezePartition {
742 partition,
743 with_name,
744 } => {
745 write!(f, "FREEZE {partition}")?;
746 if let Some(name) = with_name {
747 write!(f, " WITH NAME {name}")?;
748 }
749 Ok(())
750 }
751 AlterTableOperation::UnfreezePartition {
752 partition,
753 with_name,
754 } => {
755 write!(f, "UNFREEZE {partition}")?;
756 if let Some(name) = with_name {
757 write!(f, " WITH NAME {name}")?;
758 }
759 Ok(())
760 }
761 AlterTableOperation::ClusterBy { exprs } => {
762 write!(f, "CLUSTER BY ({})", display_comma_separated(exprs))?;
763 Ok(())
764 }
765 AlterTableOperation::DropClusteringKey => {
766 write!(f, "DROP CLUSTERING KEY")?;
767 Ok(())
768 }
769 AlterTableOperation::SuspendRecluster => {
770 write!(f, "SUSPEND RECLUSTER")?;
771 Ok(())
772 }
773 AlterTableOperation::ResumeRecluster => {
774 write!(f, "RESUME RECLUSTER")?;
775 Ok(())
776 }
777 AlterTableOperation::AutoIncrement { equals, value } => {
778 write!(
779 f,
780 "AUTO_INCREMENT {}{}",
781 if *equals { "= " } else { "" },
782 value
783 )
784 }
785 AlterTableOperation::Lock { equals, lock } => {
786 write!(f, "LOCK {}{}", if *equals { "= " } else { "" }, lock)
787 }
788 AlterTableOperation::ReplicaIdentity { identity } => {
789 write!(f, "REPLICA IDENTITY {identity}")
790 }
791 AlterTableOperation::ValidateConstraint { name } => {
792 write!(f, "VALIDATE CONSTRAINT {name}")
793 }
794 }
795 }
796}
797
798impl fmt::Display for AlterIndexOperation {
799 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
800 match self {
801 AlterIndexOperation::RenameIndex { index_name } => {
802 write!(f, "RENAME TO {index_name}")
803 }
804 }
805 }
806}
807
808#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
810#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
811#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
812pub struct AlterType {
813 pub name: ObjectName,
814 pub operation: AlterTypeOperation,
815}
816
817#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
819#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
820#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
821pub enum AlterTypeOperation {
822 Rename(AlterTypeRename),
823 AddValue(AlterTypeAddValue),
824 RenameValue(AlterTypeRenameValue),
825}
826
827#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
829#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
830#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
831pub struct AlterTypeRename {
832 pub new_name: Ident,
833}
834
835#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
837#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
838#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
839pub struct AlterTypeAddValue {
840 pub if_not_exists: bool,
841 pub value: Ident,
842 pub position: Option<AlterTypeAddValuePosition>,
843}
844
845#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
847#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
848#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
849pub enum AlterTypeAddValuePosition {
850 Before(Ident),
851 After(Ident),
852}
853
854#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
856#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
857#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
858pub struct AlterTypeRenameValue {
859 pub from: Ident,
860 pub to: Ident,
861}
862
863impl fmt::Display for AlterTypeOperation {
864 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
865 match self {
866 Self::Rename(AlterTypeRename { new_name }) => {
867 write!(f, "RENAME TO {new_name}")
868 }
869 Self::AddValue(AlterTypeAddValue {
870 if_not_exists,
871 value,
872 position,
873 }) => {
874 write!(f, "ADD VALUE")?;
875 if *if_not_exists {
876 write!(f, " IF NOT EXISTS")?;
877 }
878 write!(f, " {value}")?;
879 match position {
880 Some(AlterTypeAddValuePosition::Before(neighbor_value)) => {
881 write!(f, " BEFORE {neighbor_value}")?;
882 }
883 Some(AlterTypeAddValuePosition::After(neighbor_value)) => {
884 write!(f, " AFTER {neighbor_value}")?;
885 }
886 None => {}
887 };
888 Ok(())
889 }
890 Self::RenameValue(AlterTypeRenameValue { from, to }) => {
891 write!(f, "RENAME VALUE {from} TO {to}")
892 }
893 }
894 }
895}
896
897#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
899#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
900#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
901pub enum AlterColumnOperation {
902 SetNotNull,
904 DropNotNull,
906 SetDefault { value: Expr },
908 DropDefault,
910 SetDataType {
912 data_type: DataType,
913 using: Option<Expr>,
915 had_set: bool,
917 },
918
919 AddGenerated {
923 generated_as: Option<GeneratedAs>,
924 sequence_options: Option<Vec<SequenceOptions>>,
925 },
926}
927
928impl fmt::Display for AlterColumnOperation {
929 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
930 match self {
931 AlterColumnOperation::SetNotNull => write!(f, "SET NOT NULL",),
932 AlterColumnOperation::DropNotNull => write!(f, "DROP NOT NULL",),
933 AlterColumnOperation::SetDefault { value } => {
934 write!(f, "SET DEFAULT {value}")
935 }
936 AlterColumnOperation::DropDefault => {
937 write!(f, "DROP DEFAULT")
938 }
939 AlterColumnOperation::SetDataType {
940 data_type,
941 using,
942 had_set,
943 } => {
944 if *had_set {
945 write!(f, "SET DATA ")?;
946 }
947 write!(f, "TYPE {data_type}")?;
948 if let Some(expr) = using {
949 write!(f, " USING {expr}")?;
950 }
951 Ok(())
952 }
953 AlterColumnOperation::AddGenerated {
954 generated_as,
955 sequence_options,
956 } => {
957 let generated_as = match generated_as {
958 Some(GeneratedAs::Always) => " ALWAYS",
959 Some(GeneratedAs::ByDefault) => " BY DEFAULT",
960 _ => "",
961 };
962
963 write!(f, "ADD GENERATED{generated_as} AS IDENTITY",)?;
964 if let Some(options) = sequence_options {
965 write!(f, " (")?;
966
967 for sequence_option in options {
968 write!(f, "{sequence_option}")?;
969 }
970
971 write!(f, " )")?;
972 }
973 Ok(())
974 }
975 }
976 }
977}
978
979#[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 TableConstraint {
985 Unique {
998 name: Option<Ident>,
1002 index_name: Option<Ident>,
1004 index_type_display: KeyOrIndexDisplay,
1006 index_type: Option<IndexType>,
1010 columns: Vec<IndexColumn>,
1012 index_options: Vec<IndexOption>,
1013 characteristics: Option<ConstraintCharacteristics>,
1014 nulls_distinct: NullsDistinctOption,
1016 },
1017 PrimaryKey {
1036 name: Option<Ident>,
1040 index_name: Option<Ident>,
1042 index_type: Option<IndexType>,
1046 columns: Vec<IndexColumn>,
1048 index_options: Vec<IndexOption>,
1049 characteristics: Option<ConstraintCharacteristics>,
1050 },
1051 ForeignKey {
1057 name: Option<Ident>,
1058 index_name: Option<Ident>,
1061 columns: Vec<Ident>,
1062 foreign_table: ObjectName,
1063 referred_columns: Vec<Ident>,
1064 on_delete: Option<ReferentialAction>,
1065 on_update: Option<ReferentialAction>,
1066 characteristics: Option<ConstraintCharacteristics>,
1067 },
1068 Check {
1070 name: Option<Ident>,
1071 expr: Box<Expr>,
1072 enforced: Option<bool>,
1075 },
1076 Index {
1083 display_as_key: bool,
1085 name: Option<Ident>,
1087 index_type: Option<IndexType>,
1091 columns: Vec<IndexColumn>,
1093 },
1094 FulltextOrSpatial {
1108 fulltext: bool,
1110 index_type_display: KeyOrIndexDisplay,
1112 opt_index_name: Option<Ident>,
1114 columns: Vec<IndexColumn>,
1116 },
1117}
1118
1119impl fmt::Display for TableConstraint {
1120 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1121 match self {
1122 TableConstraint::Unique {
1123 name,
1124 index_name,
1125 index_type_display,
1126 index_type,
1127 columns,
1128 index_options,
1129 characteristics,
1130 nulls_distinct,
1131 } => {
1132 write!(
1133 f,
1134 "{}UNIQUE{nulls_distinct}{index_type_display:>}{}{} ({})",
1135 display_constraint_name(name),
1136 display_option_spaced(index_name),
1137 display_option(" USING ", "", index_type),
1138 display_comma_separated(columns),
1139 )?;
1140
1141 if !index_options.is_empty() {
1142 write!(f, " {}", display_separated(index_options, " "))?;
1143 }
1144
1145 write!(f, "{}", display_option_spaced(characteristics))?;
1146 Ok(())
1147 }
1148 TableConstraint::PrimaryKey {
1149 name,
1150 index_name,
1151 index_type,
1152 columns,
1153 index_options,
1154 characteristics,
1155 } => {
1156 write!(
1157 f,
1158 "{}PRIMARY KEY{}{} ({})",
1159 display_constraint_name(name),
1160 display_option_spaced(index_name),
1161 display_option(" USING ", "", index_type),
1162 display_comma_separated(columns),
1163 )?;
1164
1165 if !index_options.is_empty() {
1166 write!(f, " {}", display_separated(index_options, " "))?;
1167 }
1168
1169 write!(f, "{}", display_option_spaced(characteristics))?;
1170 Ok(())
1171 }
1172 TableConstraint::ForeignKey {
1173 name,
1174 index_name,
1175 columns,
1176 foreign_table,
1177 referred_columns,
1178 on_delete,
1179 on_update,
1180 characteristics,
1181 } => {
1182 write!(
1183 f,
1184 "{}FOREIGN KEY{} ({}) REFERENCES {}",
1185 display_constraint_name(name),
1186 display_option_spaced(index_name),
1187 display_comma_separated(columns),
1188 foreign_table,
1189 )?;
1190 if !referred_columns.is_empty() {
1191 write!(f, "({})", display_comma_separated(referred_columns))?;
1192 }
1193 if let Some(action) = on_delete {
1194 write!(f, " ON DELETE {action}")?;
1195 }
1196 if let Some(action) = on_update {
1197 write!(f, " ON UPDATE {action}")?;
1198 }
1199 if let Some(characteristics) = characteristics {
1200 write!(f, " {characteristics}")?;
1201 }
1202 Ok(())
1203 }
1204 TableConstraint::Check {
1205 name,
1206 expr,
1207 enforced,
1208 } => {
1209 write!(f, "{}CHECK ({})", display_constraint_name(name), expr)?;
1210 if let Some(b) = enforced {
1211 write!(f, " {}", if *b { "ENFORCED" } else { "NOT ENFORCED" })
1212 } else {
1213 Ok(())
1214 }
1215 }
1216 TableConstraint::Index {
1217 display_as_key,
1218 name,
1219 index_type,
1220 columns,
1221 } => {
1222 write!(f, "{}", if *display_as_key { "KEY" } else { "INDEX" })?;
1223 if let Some(name) = name {
1224 write!(f, " {name}")?;
1225 }
1226 if let Some(index_type) = index_type {
1227 write!(f, " USING {index_type}")?;
1228 }
1229 write!(f, " ({})", display_comma_separated(columns))?;
1230
1231 Ok(())
1232 }
1233 Self::FulltextOrSpatial {
1234 fulltext,
1235 index_type_display,
1236 opt_index_name,
1237 columns,
1238 } => {
1239 if *fulltext {
1240 write!(f, "FULLTEXT")?;
1241 } else {
1242 write!(f, "SPATIAL")?;
1243 }
1244
1245 write!(f, "{index_type_display:>}")?;
1246
1247 if let Some(name) = opt_index_name {
1248 write!(f, " {name}")?;
1249 }
1250
1251 write!(f, " ({})", display_comma_separated(columns))?;
1252
1253 Ok(())
1254 }
1255 }
1256 }
1257}
1258
1259#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1267#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1268#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1269pub enum KeyOrIndexDisplay {
1270 None,
1272 Key,
1274 Index,
1276}
1277
1278impl KeyOrIndexDisplay {
1279 pub fn is_none(self) -> bool {
1280 matches!(self, Self::None)
1281 }
1282}
1283
1284impl fmt::Display for KeyOrIndexDisplay {
1285 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1286 let left_space = matches!(f.align(), Some(fmt::Alignment::Right));
1287
1288 if left_space && !self.is_none() {
1289 f.write_char(' ')?
1290 }
1291
1292 match self {
1293 KeyOrIndexDisplay::None => {
1294 write!(f, "")
1295 }
1296 KeyOrIndexDisplay::Key => {
1297 write!(f, "KEY")
1298 }
1299 KeyOrIndexDisplay::Index => {
1300 write!(f, "INDEX")
1301 }
1302 }
1303 }
1304}
1305
1306#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1315#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1316#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1317pub enum IndexType {
1318 BTree,
1319 Hash,
1320 GIN,
1321 GiST,
1322 SPGiST,
1323 BRIN,
1324 Bloom,
1325 Custom(Ident),
1328}
1329
1330impl fmt::Display for IndexType {
1331 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1332 match self {
1333 Self::BTree => write!(f, "BTREE"),
1334 Self::Hash => write!(f, "HASH"),
1335 Self::GIN => write!(f, "GIN"),
1336 Self::GiST => write!(f, "GIST"),
1337 Self::SPGiST => write!(f, "SPGIST"),
1338 Self::BRIN => write!(f, "BRIN"),
1339 Self::Bloom => write!(f, "BLOOM"),
1340 Self::Custom(name) => write!(f, "{name}"),
1341 }
1342 }
1343}
1344
1345#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1352#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1353#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1354pub enum IndexOption {
1355 Using(IndexType),
1356 Comment(String),
1357}
1358
1359impl fmt::Display for IndexOption {
1360 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1361 match self {
1362 Self::Using(index_type) => write!(f, "USING {index_type}"),
1363 Self::Comment(s) => write!(f, "COMMENT '{s}'"),
1364 }
1365 }
1366}
1367
1368#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1372#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1373#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1374pub enum NullsDistinctOption {
1375 None,
1377 Distinct,
1379 NotDistinct,
1381}
1382
1383impl fmt::Display for NullsDistinctOption {
1384 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1385 match self {
1386 Self::None => Ok(()),
1387 Self::Distinct => write!(f, " NULLS DISTINCT"),
1388 Self::NotDistinct => write!(f, " NULLS NOT DISTINCT"),
1389 }
1390 }
1391}
1392
1393#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1394#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1395#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1396pub struct ProcedureParam {
1397 pub name: Ident,
1398 pub data_type: DataType,
1399 pub mode: Option<ArgMode>,
1400}
1401
1402impl fmt::Display for ProcedureParam {
1403 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1404 if let Some(mode) = &self.mode {
1405 write!(f, "{mode} {} {}", self.name, self.data_type)
1406 } else {
1407 write!(f, "{} {}", self.name, self.data_type)
1408 }
1409 }
1410}
1411
1412#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1414#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1415#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1416pub struct ColumnDef {
1417 pub name: Ident,
1418 pub data_type: DataType,
1419 pub options: Vec<ColumnOptionDef>,
1420}
1421
1422impl fmt::Display for ColumnDef {
1423 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1424 if self.data_type == DataType::Unspecified {
1425 write!(f, "{}", self.name)?;
1426 } else {
1427 write!(f, "{} {}", self.name, self.data_type)?;
1428 }
1429 for option in &self.options {
1430 write!(f, " {option}")?;
1431 }
1432 Ok(())
1433 }
1434}
1435
1436#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1453#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1454#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1455pub struct ViewColumnDef {
1456 pub name: Ident,
1457 pub data_type: Option<DataType>,
1458 pub options: Option<ColumnOptions>,
1459}
1460
1461#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1462#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1463#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1464pub enum ColumnOptions {
1465 CommaSeparated(Vec<ColumnOption>),
1466 SpaceSeparated(Vec<ColumnOption>),
1467}
1468
1469impl ColumnOptions {
1470 pub fn as_slice(&self) -> &[ColumnOption] {
1471 match self {
1472 ColumnOptions::CommaSeparated(options) => options.as_slice(),
1473 ColumnOptions::SpaceSeparated(options) => options.as_slice(),
1474 }
1475 }
1476}
1477
1478impl fmt::Display for ViewColumnDef {
1479 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1480 write!(f, "{}", self.name)?;
1481 if let Some(data_type) = self.data_type.as_ref() {
1482 write!(f, " {data_type}")?;
1483 }
1484 if let Some(options) = self.options.as_ref() {
1485 match options {
1486 ColumnOptions::CommaSeparated(column_options) => {
1487 write!(f, " {}", display_comma_separated(column_options.as_slice()))?;
1488 }
1489 ColumnOptions::SpaceSeparated(column_options) => {
1490 write!(f, " {}", display_separated(column_options.as_slice(), " "))?
1491 }
1492 }
1493 }
1494 Ok(())
1495 }
1496}
1497
1498#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1515#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1516#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1517pub struct ColumnOptionDef {
1518 pub name: Option<Ident>,
1519 pub option: ColumnOption,
1520}
1521
1522impl fmt::Display for ColumnOptionDef {
1523 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1524 write!(f, "{}{}", display_constraint_name(&self.name), self.option)
1525 }
1526}
1527
1528#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1536#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1537#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1538pub enum IdentityPropertyKind {
1539 Autoincrement(IdentityProperty),
1547 Identity(IdentityProperty),
1560}
1561
1562impl fmt::Display for IdentityPropertyKind {
1563 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1564 let (command, property) = match self {
1565 IdentityPropertyKind::Identity(property) => ("IDENTITY", property),
1566 IdentityPropertyKind::Autoincrement(property) => ("AUTOINCREMENT", property),
1567 };
1568 write!(f, "{command}")?;
1569 if let Some(parameters) = &property.parameters {
1570 write!(f, "{parameters}")?;
1571 }
1572 if let Some(order) = &property.order {
1573 write!(f, "{order}")?;
1574 }
1575 Ok(())
1576 }
1577}
1578
1579#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1580#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1581#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1582pub struct IdentityProperty {
1583 pub parameters: Option<IdentityPropertyFormatKind>,
1584 pub order: Option<IdentityPropertyOrder>,
1585}
1586
1587#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1602#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1603#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1604pub enum IdentityPropertyFormatKind {
1605 FunctionCall(IdentityParameters),
1613 StartAndIncrement(IdentityParameters),
1620}
1621
1622impl fmt::Display for IdentityPropertyFormatKind {
1623 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1624 match self {
1625 IdentityPropertyFormatKind::FunctionCall(parameters) => {
1626 write!(f, "({}, {})", parameters.seed, parameters.increment)
1627 }
1628 IdentityPropertyFormatKind::StartAndIncrement(parameters) => {
1629 write!(
1630 f,
1631 " START {} INCREMENT {}",
1632 parameters.seed, parameters.increment
1633 )
1634 }
1635 }
1636 }
1637}
1638#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1639#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1640#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1641pub struct IdentityParameters {
1642 pub seed: Expr,
1643 pub increment: Expr,
1644}
1645
1646#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1653#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1654#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1655pub enum IdentityPropertyOrder {
1656 Order,
1657 NoOrder,
1658}
1659
1660impl fmt::Display for IdentityPropertyOrder {
1661 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1662 match self {
1663 IdentityPropertyOrder::Order => write!(f, " ORDER"),
1664 IdentityPropertyOrder::NoOrder => write!(f, " NOORDER"),
1665 }
1666 }
1667}
1668
1669#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1677#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1678#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1679pub enum ColumnPolicy {
1680 MaskingPolicy(ColumnPolicyProperty),
1681 ProjectionPolicy(ColumnPolicyProperty),
1682}
1683
1684impl fmt::Display for ColumnPolicy {
1685 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1686 let (command, property) = match self {
1687 ColumnPolicy::MaskingPolicy(property) => ("MASKING POLICY", property),
1688 ColumnPolicy::ProjectionPolicy(property) => ("PROJECTION POLICY", property),
1689 };
1690 if property.with {
1691 write!(f, "WITH ")?;
1692 }
1693 write!(f, "{command} {}", property.policy_name)?;
1694 if let Some(using_columns) = &property.using_columns {
1695 write!(f, " USING ({})", display_comma_separated(using_columns))?;
1696 }
1697 Ok(())
1698 }
1699}
1700
1701#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1702#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1703#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1704pub struct ColumnPolicyProperty {
1705 pub with: bool,
1712 pub policy_name: ObjectName,
1713 pub using_columns: Option<Vec<Ident>>,
1714}
1715
1716#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1723#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1724#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1725pub struct TagsColumnOption {
1726 pub with: bool,
1733 pub tags: Vec<Tag>,
1734}
1735
1736impl fmt::Display for TagsColumnOption {
1737 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1738 if self.with {
1739 write!(f, "WITH ")?;
1740 }
1741 write!(f, "TAG ({})", display_comma_separated(&self.tags))?;
1742 Ok(())
1743 }
1744}
1745
1746#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1749#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1750#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1751pub enum ColumnOption {
1752 Null,
1754 NotNull,
1756 Default(Expr),
1758
1759 Materialized(Expr),
1764 Ephemeral(Option<Expr>),
1768 Alias(Expr),
1772
1773 Unique {
1775 is_primary: bool,
1776 characteristics: Option<ConstraintCharacteristics>,
1777 },
1778 ForeignKey {
1786 foreign_table: ObjectName,
1787 referred_columns: Vec<Ident>,
1788 on_delete: Option<ReferentialAction>,
1789 on_update: Option<ReferentialAction>,
1790 characteristics: Option<ConstraintCharacteristics>,
1791 },
1792 Check(Expr),
1794 DialectSpecific(Vec<Token>),
1798 CharacterSet(ObjectName),
1799 Collation(ObjectName),
1800 Comment(String),
1801 OnUpdate(Expr),
1802 Generated {
1805 generated_as: GeneratedAs,
1806 sequence_options: Option<Vec<SequenceOptions>>,
1807 generation_expr: Option<Expr>,
1808 generation_expr_mode: Option<GeneratedExpressionMode>,
1809 generated_keyword: bool,
1811 },
1812 Options(Vec<SqlOption>),
1820 Identity(IdentityPropertyKind),
1828 OnConflict(Keyword),
1831 Policy(ColumnPolicy),
1839 Tags(TagsColumnOption),
1846 Srid(Box<Expr>),
1853}
1854
1855impl fmt::Display for ColumnOption {
1856 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1857 use ColumnOption::*;
1858 match self {
1859 Null => write!(f, "NULL"),
1860 NotNull => write!(f, "NOT NULL"),
1861 Default(expr) => write!(f, "DEFAULT {expr}"),
1862 Materialized(expr) => write!(f, "MATERIALIZED {expr}"),
1863 Ephemeral(expr) => {
1864 if let Some(e) = expr {
1865 write!(f, "EPHEMERAL {e}")
1866 } else {
1867 write!(f, "EPHEMERAL")
1868 }
1869 }
1870 Alias(expr) => write!(f, "ALIAS {expr}"),
1871 Unique {
1872 is_primary,
1873 characteristics,
1874 } => {
1875 write!(f, "{}", if *is_primary { "PRIMARY KEY" } else { "UNIQUE" })?;
1876 if let Some(characteristics) = characteristics {
1877 write!(f, " {characteristics}")?;
1878 }
1879 Ok(())
1880 }
1881 ForeignKey {
1882 foreign_table,
1883 referred_columns,
1884 on_delete,
1885 on_update,
1886 characteristics,
1887 } => {
1888 write!(f, "REFERENCES {foreign_table}")?;
1889 if !referred_columns.is_empty() {
1890 write!(f, " ({})", display_comma_separated(referred_columns))?;
1891 }
1892 if let Some(action) = on_delete {
1893 write!(f, " ON DELETE {action}")?;
1894 }
1895 if let Some(action) = on_update {
1896 write!(f, " ON UPDATE {action}")?;
1897 }
1898 if let Some(characteristics) = characteristics {
1899 write!(f, " {characteristics}")?;
1900 }
1901 Ok(())
1902 }
1903 Check(expr) => write!(f, "CHECK ({expr})"),
1904 DialectSpecific(val) => write!(f, "{}", display_separated(val, " ")),
1905 CharacterSet(n) => write!(f, "CHARACTER SET {n}"),
1906 Collation(n) => write!(f, "COLLATE {n}"),
1907 Comment(v) => write!(f, "COMMENT '{}'", escape_single_quote_string(v)),
1908 OnUpdate(expr) => write!(f, "ON UPDATE {expr}"),
1909 Generated {
1910 generated_as,
1911 sequence_options,
1912 generation_expr,
1913 generation_expr_mode,
1914 generated_keyword,
1915 } => {
1916 if let Some(expr) = generation_expr {
1917 let modifier = match generation_expr_mode {
1918 None => "",
1919 Some(GeneratedExpressionMode::Virtual) => " VIRTUAL",
1920 Some(GeneratedExpressionMode::Stored) => " STORED",
1921 };
1922 if *generated_keyword {
1923 write!(f, "GENERATED ALWAYS AS ({expr}){modifier}")?;
1924 } else {
1925 write!(f, "AS ({expr}){modifier}")?;
1926 }
1927 Ok(())
1928 } else {
1929 let when = match generated_as {
1931 GeneratedAs::Always => "ALWAYS",
1932 GeneratedAs::ByDefault => "BY DEFAULT",
1933 GeneratedAs::ExpStored => unreachable!(),
1935 };
1936 write!(f, "GENERATED {when} AS IDENTITY")?;
1937 if sequence_options.is_some() {
1938 let so = sequence_options.as_ref().unwrap();
1939 if !so.is_empty() {
1940 write!(f, " (")?;
1941 }
1942 for sequence_option in so {
1943 write!(f, "{sequence_option}")?;
1944 }
1945 if !so.is_empty() {
1946 write!(f, " )")?;
1947 }
1948 }
1949 Ok(())
1950 }
1951 }
1952 Options(options) => {
1953 write!(f, "OPTIONS({})", display_comma_separated(options))
1954 }
1955 Identity(parameters) => {
1956 write!(f, "{parameters}")
1957 }
1958 OnConflict(keyword) => {
1959 write!(f, "ON CONFLICT {keyword:?}")?;
1960 Ok(())
1961 }
1962 Policy(parameters) => {
1963 write!(f, "{parameters}")
1964 }
1965 Tags(tags) => {
1966 write!(f, "{tags}")
1967 }
1968 Srid(srid) => {
1969 write!(f, "SRID {srid}")
1970 }
1971 }
1972 }
1973}
1974
1975#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1978#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1979#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1980pub enum GeneratedAs {
1981 Always,
1982 ByDefault,
1983 ExpStored,
1984}
1985
1986#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1989#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1990#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1991pub enum GeneratedExpressionMode {
1992 Virtual,
1993 Stored,
1994}
1995
1996#[must_use]
1997fn display_constraint_name(name: &'_ Option<Ident>) -> impl fmt::Display + '_ {
1998 struct ConstraintName<'a>(&'a Option<Ident>);
1999 impl fmt::Display for ConstraintName<'_> {
2000 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2001 if let Some(name) = self.0 {
2002 write!(f, "CONSTRAINT {name} ")?;
2003 }
2004 Ok(())
2005 }
2006 }
2007 ConstraintName(name)
2008}
2009
2010#[must_use]
2014fn display_option<'a, T: fmt::Display>(
2015 prefix: &'a str,
2016 postfix: &'a str,
2017 option: &'a Option<T>,
2018) -> impl fmt::Display + 'a {
2019 struct OptionDisplay<'a, T>(&'a str, &'a str, &'a Option<T>);
2020 impl<T: fmt::Display> fmt::Display for OptionDisplay<'_, T> {
2021 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2022 if let Some(inner) = self.2 {
2023 let (prefix, postfix) = (self.0, self.1);
2024 write!(f, "{prefix}{inner}{postfix}")?;
2025 }
2026 Ok(())
2027 }
2028 }
2029 OptionDisplay(prefix, postfix, option)
2030}
2031
2032#[must_use]
2036fn display_option_spaced<T: fmt::Display>(option: &Option<T>) -> impl fmt::Display + '_ {
2037 display_option(" ", "", option)
2038}
2039
2040#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Default, Eq, Ord, Hash)]
2044#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2045#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2046pub struct ConstraintCharacteristics {
2047 pub deferrable: Option<bool>,
2049 pub initially: Option<DeferrableInitial>,
2051 pub enforced: Option<bool>,
2053}
2054
2055#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2056#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2057#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2058pub enum DeferrableInitial {
2059 Immediate,
2061 Deferred,
2063}
2064
2065impl ConstraintCharacteristics {
2066 fn deferrable_text(&self) -> Option<&'static str> {
2067 self.deferrable.map(|deferrable| {
2068 if deferrable {
2069 "DEFERRABLE"
2070 } else {
2071 "NOT DEFERRABLE"
2072 }
2073 })
2074 }
2075
2076 fn initially_immediate_text(&self) -> Option<&'static str> {
2077 self.initially
2078 .map(|initially_immediate| match initially_immediate {
2079 DeferrableInitial::Immediate => "INITIALLY IMMEDIATE",
2080 DeferrableInitial::Deferred => "INITIALLY DEFERRED",
2081 })
2082 }
2083
2084 fn enforced_text(&self) -> Option<&'static str> {
2085 self.enforced.map(
2086 |enforced| {
2087 if enforced {
2088 "ENFORCED"
2089 } else {
2090 "NOT ENFORCED"
2091 }
2092 },
2093 )
2094 }
2095}
2096
2097impl fmt::Display for ConstraintCharacteristics {
2098 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2099 let deferrable = self.deferrable_text();
2100 let initially_immediate = self.initially_immediate_text();
2101 let enforced = self.enforced_text();
2102
2103 match (deferrable, initially_immediate, enforced) {
2104 (None, None, None) => Ok(()),
2105 (None, None, Some(enforced)) => write!(f, "{enforced}"),
2106 (None, Some(initial), None) => write!(f, "{initial}"),
2107 (None, Some(initial), Some(enforced)) => write!(f, "{initial} {enforced}"),
2108 (Some(deferrable), None, None) => write!(f, "{deferrable}"),
2109 (Some(deferrable), None, Some(enforced)) => write!(f, "{deferrable} {enforced}"),
2110 (Some(deferrable), Some(initial), None) => write!(f, "{deferrable} {initial}"),
2111 (Some(deferrable), Some(initial), Some(enforced)) => {
2112 write!(f, "{deferrable} {initial} {enforced}")
2113 }
2114 }
2115 }
2116}
2117
2118#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2123#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2124#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2125pub enum ReferentialAction {
2126 Restrict,
2127 Cascade,
2128 SetNull,
2129 NoAction,
2130 SetDefault,
2131}
2132
2133impl fmt::Display for ReferentialAction {
2134 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2135 f.write_str(match self {
2136 ReferentialAction::Restrict => "RESTRICT",
2137 ReferentialAction::Cascade => "CASCADE",
2138 ReferentialAction::SetNull => "SET NULL",
2139 ReferentialAction::NoAction => "NO ACTION",
2140 ReferentialAction::SetDefault => "SET DEFAULT",
2141 })
2142 }
2143}
2144
2145#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2149#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2150#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2151pub enum DropBehavior {
2152 Restrict,
2153 Cascade,
2154}
2155
2156impl fmt::Display for DropBehavior {
2157 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2158 f.write_str(match self {
2159 DropBehavior::Restrict => "RESTRICT",
2160 DropBehavior::Cascade => "CASCADE",
2161 })
2162 }
2163}
2164
2165#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2167#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2168#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2169pub enum UserDefinedTypeRepresentation {
2170 Composite {
2171 attributes: Vec<UserDefinedTypeCompositeAttributeDef>,
2172 },
2173 Enum { labels: Vec<Ident> },
2175}
2176
2177impl fmt::Display for UserDefinedTypeRepresentation {
2178 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2179 match self {
2180 UserDefinedTypeRepresentation::Composite { attributes } => {
2181 write!(f, "({})", display_comma_separated(attributes))
2182 }
2183 UserDefinedTypeRepresentation::Enum { labels } => {
2184 write!(f, "ENUM ({})", display_comma_separated(labels))
2185 }
2186 }
2187 }
2188}
2189
2190#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2192#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2193#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2194pub struct UserDefinedTypeCompositeAttributeDef {
2195 pub name: Ident,
2196 pub data_type: DataType,
2197 pub collation: Option<ObjectName>,
2198}
2199
2200impl fmt::Display for UserDefinedTypeCompositeAttributeDef {
2201 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2202 write!(f, "{} {}", self.name, self.data_type)?;
2203 if let Some(collation) = &self.collation {
2204 write!(f, " COLLATE {collation}")?;
2205 }
2206 Ok(())
2207 }
2208}
2209
2210#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
2214#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2215#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2216pub enum Partition {
2217 Identifier(Ident),
2218 Expr(Expr),
2219 Part(Expr),
2222 Partitions(Vec<Expr>),
2223}
2224
2225impl fmt::Display for Partition {
2226 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2227 match self {
2228 Partition::Identifier(id) => write!(f, "PARTITION ID {id}"),
2229 Partition::Expr(expr) => write!(f, "PARTITION {expr}"),
2230 Partition::Part(expr) => write!(f, "PART {expr}"),
2231 Partition::Partitions(partitions) => {
2232 write!(f, "PARTITION ({})", display_comma_separated(partitions))
2233 }
2234 }
2235 }
2236}
2237
2238#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2241#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2242#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2243pub enum Deduplicate {
2244 All,
2245 ByExpression(Expr),
2246}
2247
2248impl fmt::Display for Deduplicate {
2249 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2250 match self {
2251 Deduplicate::All => write!(f, "DEDUPLICATE"),
2252 Deduplicate::ByExpression(expr) => write!(f, "DEDUPLICATE BY {expr}"),
2253 }
2254 }
2255}
2256
2257#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2262#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2263#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2264pub struct ClusteredBy {
2265 pub columns: Vec<Ident>,
2266 pub sorted_by: Option<Vec<OrderByExpr>>,
2267 pub num_buckets: Value,
2268}
2269
2270impl fmt::Display for ClusteredBy {
2271 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2272 write!(
2273 f,
2274 "CLUSTERED BY ({})",
2275 display_comma_separated(&self.columns)
2276 )?;
2277 if let Some(ref sorted_by) = self.sorted_by {
2278 write!(f, " SORTED BY ({})", display_comma_separated(sorted_by))?;
2279 }
2280 write!(f, " INTO {} BUCKETS", self.num_buckets)
2281 }
2282}
2283
2284#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2285#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2286#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2287pub struct CreateDomain {
2300 pub name: ObjectName,
2302 pub data_type: DataType,
2304 pub collation: Option<Ident>,
2306 pub default: Option<Expr>,
2308 pub constraints: Vec<TableConstraint>,
2310}
2311
2312impl fmt::Display for CreateDomain {
2313 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2314 write!(
2315 f,
2316 "CREATE DOMAIN {name} AS {data_type}",
2317 name = self.name,
2318 data_type = self.data_type
2319 )?;
2320 if let Some(collation) = &self.collation {
2321 write!(f, " COLLATE {collation}")?;
2322 }
2323 if let Some(default) = &self.default {
2324 write!(f, " DEFAULT {default}")?;
2325 }
2326 if !self.constraints.is_empty() {
2327 write!(f, " {}", display_separated(&self.constraints, " "))?;
2328 }
2329 Ok(())
2330 }
2331}
2332
2333#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2334#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2335#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2336pub struct CreateFunction {
2337 pub or_alter: bool,
2341 pub or_replace: bool,
2342 pub temporary: bool,
2343 pub if_not_exists: bool,
2344 pub name: ObjectName,
2345 pub args: Option<Vec<OperateFunctionArg>>,
2346 pub return_type: Option<DataType>,
2347 pub function_body: Option<CreateFunctionBody>,
2355 pub behavior: Option<FunctionBehavior>,
2361 pub called_on_null: Option<FunctionCalledOnNull>,
2365 pub parallel: Option<FunctionParallel>,
2369 pub using: Option<CreateFunctionUsing>,
2371 pub language: Option<Ident>,
2379 pub determinism_specifier: Option<FunctionDeterminismSpecifier>,
2383 pub options: Option<Vec<SqlOption>>,
2387 pub remote_connection: Option<ObjectName>,
2397}
2398
2399impl fmt::Display for CreateFunction {
2400 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2401 write!(
2402 f,
2403 "CREATE {or_alter}{or_replace}{temp}FUNCTION {if_not_exists}{name}",
2404 name = self.name,
2405 temp = if self.temporary { "TEMPORARY " } else { "" },
2406 or_alter = if self.or_alter { "OR ALTER " } else { "" },
2407 or_replace = if self.or_replace { "OR REPLACE " } else { "" },
2408 if_not_exists = if self.if_not_exists {
2409 "IF NOT EXISTS "
2410 } else {
2411 ""
2412 },
2413 )?;
2414 if let Some(args) = &self.args {
2415 write!(f, "({})", display_comma_separated(args))?;
2416 }
2417 if let Some(return_type) = &self.return_type {
2418 write!(f, " RETURNS {return_type}")?;
2419 }
2420 if let Some(determinism_specifier) = &self.determinism_specifier {
2421 write!(f, " {determinism_specifier}")?;
2422 }
2423 if let Some(language) = &self.language {
2424 write!(f, " LANGUAGE {language}")?;
2425 }
2426 if let Some(behavior) = &self.behavior {
2427 write!(f, " {behavior}")?;
2428 }
2429 if let Some(called_on_null) = &self.called_on_null {
2430 write!(f, " {called_on_null}")?;
2431 }
2432 if let Some(parallel) = &self.parallel {
2433 write!(f, " {parallel}")?;
2434 }
2435 if let Some(remote_connection) = &self.remote_connection {
2436 write!(f, " REMOTE WITH CONNECTION {remote_connection}")?;
2437 }
2438 if let Some(CreateFunctionBody::AsBeforeOptions(function_body)) = &self.function_body {
2439 write!(f, " AS {function_body}")?;
2440 }
2441 if let Some(CreateFunctionBody::Return(function_body)) = &self.function_body {
2442 write!(f, " RETURN {function_body}")?;
2443 }
2444 if let Some(CreateFunctionBody::AsReturnExpr(function_body)) = &self.function_body {
2445 write!(f, " AS RETURN {function_body}")?;
2446 }
2447 if let Some(CreateFunctionBody::AsReturnSelect(function_body)) = &self.function_body {
2448 write!(f, " AS RETURN {function_body}")?;
2449 }
2450 if let Some(using) = &self.using {
2451 write!(f, " {using}")?;
2452 }
2453 if let Some(options) = &self.options {
2454 write!(
2455 f,
2456 " OPTIONS({})",
2457 display_comma_separated(options.as_slice())
2458 )?;
2459 }
2460 if let Some(CreateFunctionBody::AsAfterOptions(function_body)) = &self.function_body {
2461 write!(f, " AS {function_body}")?;
2462 }
2463 if let Some(CreateFunctionBody::AsBeginEnd(bes)) = &self.function_body {
2464 write!(f, " AS {bes}")?;
2465 }
2466 Ok(())
2467 }
2468}
2469
2470#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2480#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2481#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2482pub struct CreateConnector {
2483 pub name: Ident,
2484 pub if_not_exists: bool,
2485 pub connector_type: Option<String>,
2486 pub url: Option<String>,
2487 pub comment: Option<CommentDef>,
2488 pub with_dcproperties: Option<Vec<SqlOption>>,
2489}
2490
2491impl fmt::Display for CreateConnector {
2492 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2493 write!(
2494 f,
2495 "CREATE CONNECTOR {if_not_exists}{name}",
2496 if_not_exists = if self.if_not_exists {
2497 "IF NOT EXISTS "
2498 } else {
2499 ""
2500 },
2501 name = self.name,
2502 )?;
2503
2504 if let Some(connector_type) = &self.connector_type {
2505 write!(f, " TYPE '{connector_type}'")?;
2506 }
2507
2508 if let Some(url) = &self.url {
2509 write!(f, " URL '{url}'")?;
2510 }
2511
2512 if let Some(comment) = &self.comment {
2513 write!(f, " COMMENT = '{comment}'")?;
2514 }
2515
2516 if let Some(with_dcproperties) = &self.with_dcproperties {
2517 write!(
2518 f,
2519 " WITH DCPROPERTIES({})",
2520 display_comma_separated(with_dcproperties)
2521 )?;
2522 }
2523
2524 Ok(())
2525 }
2526}