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, CommentDef, CreateFunctionBody,
34 CreateFunctionUsing, DataType, Expr, FunctionBehavior, FunctionCalledOnNull,
35 FunctionDeterminismSpecifier, FunctionParallel, Ident, MySQLColumnPosition, ObjectName,
36 OperateFunctionArg, OrderByExpr, ProjectionSelect, SequenceOptions, SqlOption, Tag, Value,
37 ValueWithSpan,
38};
39use crate::keywords::Keyword;
40use crate::tokenizer::Token;
41
42#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
44#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
45#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
46pub enum AlterTableOperation {
47 AddConstraint(TableConstraint),
49 AddColumn {
51 column_keyword: bool,
53 if_not_exists: bool,
55 column_def: ColumnDef,
57 column_position: Option<MySQLColumnPosition>,
59 },
60 AddProjection {
65 if_not_exists: bool,
66 name: Ident,
67 select: ProjectionSelect,
68 },
69 DropProjection {
74 if_exists: bool,
75 name: Ident,
76 },
77 MaterializeProjection {
82 if_exists: bool,
83 name: Ident,
84 partition: Option<Ident>,
85 },
86 ClearProjection {
91 if_exists: bool,
92 name: Ident,
93 partition: Option<Ident>,
94 },
95 DisableRowLevelSecurity,
99 DisableRule {
103 name: Ident,
104 },
105 DisableTrigger {
109 name: Ident,
110 },
111 DropConstraint {
113 if_exists: bool,
114 name: Ident,
115 drop_behavior: Option<DropBehavior>,
116 },
117 DropColumn {
119 column_name: Ident,
120 if_exists: bool,
121 drop_behavior: Option<DropBehavior>,
122 },
123 AttachPartition {
127 partition: Partition,
130 },
131 DetachPartition {
135 partition: Partition,
137 },
138 FreezePartition {
142 partition: Partition,
143 with_name: Option<Ident>,
144 },
145 UnfreezePartition {
149 partition: Partition,
150 with_name: Option<Ident>,
151 },
152 DropPrimaryKey,
158 DropForeignKey {
164 name: Ident,
165 },
166 EnableAlwaysRule {
170 name: Ident,
171 },
172 EnableAlwaysTrigger {
176 name: Ident,
177 },
178 EnableReplicaRule {
182 name: Ident,
183 },
184 EnableReplicaTrigger {
188 name: Ident,
189 },
190 EnableRowLevelSecurity,
194 EnableRule {
198 name: Ident,
199 },
200 EnableTrigger {
204 name: Ident,
205 },
206 RenamePartitions {
208 old_partitions: Vec<Expr>,
209 new_partitions: Vec<Expr>,
210 },
211 AddPartitions {
213 if_not_exists: bool,
214 new_partitions: Vec<Partition>,
215 },
216 DropPartitions {
217 partitions: Vec<Expr>,
218 if_exists: bool,
219 },
220 RenameColumn {
222 old_column_name: Ident,
223 new_column_name: Ident,
224 },
225 RenameTable {
227 table_name: ObjectName,
228 },
229 ChangeColumn {
231 old_name: Ident,
232 new_name: Ident,
233 data_type: DataType,
234 options: Vec<ColumnOption>,
235 column_position: Option<MySQLColumnPosition>,
237 },
238 ModifyColumn {
240 col_name: Ident,
241 data_type: DataType,
242 options: Vec<ColumnOption>,
243 column_position: Option<MySQLColumnPosition>,
245 },
246 RenameConstraint {
250 old_name: Ident,
251 new_name: Ident,
252 },
253 AlterColumn {
255 column_name: Ident,
256 op: AlterColumnOperation,
257 },
258 SwapWith {
262 table_name: ObjectName,
263 },
264 SetTblProperties {
266 table_properties: Vec<SqlOption>,
267 },
268 OwnerTo {
272 new_owner: Owner,
273 },
274 ClusterBy {
277 exprs: Vec<Expr>,
278 },
279 DropClusteringKey,
280 SuspendRecluster,
281 ResumeRecluster,
282 Algorithm {
288 equals: bool,
289 algorithm: AlterTableAlgorithm,
290 },
291
292 Lock {
298 equals: bool,
299 lock: AlterTableLock,
300 },
301 AutoIncrement {
307 equals: bool,
308 value: ValueWithSpan,
309 },
310}
311
312#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
316#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
317#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
318pub enum AlterPolicyOperation {
319 Rename {
320 new_name: Ident,
321 },
322 Apply {
323 to: Option<Vec<Owner>>,
324 using: Option<Expr>,
325 with_check: Option<Expr>,
326 },
327}
328
329impl fmt::Display for AlterPolicyOperation {
330 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
331 match self {
332 AlterPolicyOperation::Rename { new_name } => {
333 write!(f, " RENAME TO {new_name}")
334 }
335 AlterPolicyOperation::Apply {
336 to,
337 using,
338 with_check,
339 } => {
340 if let Some(to) = to {
341 write!(f, " TO {}", display_comma_separated(to))?;
342 }
343 if let Some(using) = using {
344 write!(f, " USING ({using})")?;
345 }
346 if let Some(with_check) = with_check {
347 write!(f, " WITH CHECK ({with_check})")?;
348 }
349 Ok(())
350 }
351 }
352 }
353}
354
355#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
359#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
360#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
361pub enum AlterTableAlgorithm {
362 Default,
363 Instant,
364 Inplace,
365 Copy,
366}
367
368impl fmt::Display for AlterTableAlgorithm {
369 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
370 f.write_str(match self {
371 Self::Default => "DEFAULT",
372 Self::Instant => "INSTANT",
373 Self::Inplace => "INPLACE",
374 Self::Copy => "COPY",
375 })
376 }
377}
378
379#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
383#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
384#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
385pub enum AlterTableLock {
386 Default,
387 None,
388 Shared,
389 Exclusive,
390}
391
392impl fmt::Display for AlterTableLock {
393 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
394 f.write_str(match self {
395 Self::Default => "DEFAULT",
396 Self::None => "NONE",
397 Self::Shared => "SHARED",
398 Self::Exclusive => "EXCLUSIVE",
399 })
400 }
401}
402
403#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
404#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
405#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
406pub enum Owner {
407 Ident(Ident),
408 CurrentRole,
409 CurrentUser,
410 SessionUser,
411}
412
413impl fmt::Display for Owner {
414 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
415 match self {
416 Owner::Ident(ident) => write!(f, "{}", ident),
417 Owner::CurrentRole => write!(f, "CURRENT_ROLE"),
418 Owner::CurrentUser => write!(f, "CURRENT_USER"),
419 Owner::SessionUser => write!(f, "SESSION_USER"),
420 }
421 }
422}
423
424#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
425#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
426#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
427pub enum AlterConnectorOwner {
428 User(Ident),
429 Role(Ident),
430}
431
432impl fmt::Display for AlterConnectorOwner {
433 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
434 match self {
435 AlterConnectorOwner::User(ident) => write!(f, "USER {ident}"),
436 AlterConnectorOwner::Role(ident) => write!(f, "ROLE {ident}"),
437 }
438 }
439}
440
441#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
442#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
443#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
444pub enum AlterIndexOperation {
445 RenameIndex { index_name: ObjectName },
446}
447
448impl fmt::Display for AlterTableOperation {
449 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
450 match self {
451 AlterTableOperation::AddPartitions {
452 if_not_exists,
453 new_partitions,
454 } => write!(
455 f,
456 "ADD{ine} {}",
457 display_separated(new_partitions, " "),
458 ine = if *if_not_exists { " IF NOT EXISTS" } else { "" }
459 ),
460 AlterTableOperation::AddConstraint(c) => write!(f, "ADD {c}"),
461 AlterTableOperation::AddColumn {
462 column_keyword,
463 if_not_exists,
464 column_def,
465 column_position,
466 } => {
467 write!(f, "ADD")?;
468 if *column_keyword {
469 write!(f, " COLUMN")?;
470 }
471 if *if_not_exists {
472 write!(f, " IF NOT EXISTS")?;
473 }
474 write!(f, " {column_def}")?;
475
476 if let Some(position) = column_position {
477 write!(f, " {position}")?;
478 }
479
480 Ok(())
481 }
482 AlterTableOperation::AddProjection {
483 if_not_exists,
484 name,
485 select: query,
486 } => {
487 write!(f, "ADD PROJECTION")?;
488 if *if_not_exists {
489 write!(f, " IF NOT EXISTS")?;
490 }
491 write!(f, " {} ({})", name, query)
492 }
493 AlterTableOperation::Algorithm { equals, algorithm } => {
494 write!(
495 f,
496 "ALGORITHM {}{}",
497 if *equals { "= " } else { "" },
498 algorithm
499 )
500 }
501 AlterTableOperation::DropProjection { if_exists, name } => {
502 write!(f, "DROP PROJECTION")?;
503 if *if_exists {
504 write!(f, " IF EXISTS")?;
505 }
506 write!(f, " {}", name)
507 }
508 AlterTableOperation::MaterializeProjection {
509 if_exists,
510 name,
511 partition,
512 } => {
513 write!(f, "MATERIALIZE PROJECTION")?;
514 if *if_exists {
515 write!(f, " IF EXISTS")?;
516 }
517 write!(f, " {}", name)?;
518 if let Some(partition) = partition {
519 write!(f, " IN PARTITION {}", partition)?;
520 }
521 Ok(())
522 }
523 AlterTableOperation::ClearProjection {
524 if_exists,
525 name,
526 partition,
527 } => {
528 write!(f, "CLEAR PROJECTION")?;
529 if *if_exists {
530 write!(f, " IF EXISTS")?;
531 }
532 write!(f, " {}", name)?;
533 if let Some(partition) = partition {
534 write!(f, " IN PARTITION {}", partition)?;
535 }
536 Ok(())
537 }
538 AlterTableOperation::AlterColumn { column_name, op } => {
539 write!(f, "ALTER COLUMN {column_name} {op}")
540 }
541 AlterTableOperation::DisableRowLevelSecurity => {
542 write!(f, "DISABLE ROW LEVEL SECURITY")
543 }
544 AlterTableOperation::DisableRule { name } => {
545 write!(f, "DISABLE RULE {name}")
546 }
547 AlterTableOperation::DisableTrigger { name } => {
548 write!(f, "DISABLE TRIGGER {name}")
549 }
550 AlterTableOperation::DropPartitions {
551 partitions,
552 if_exists,
553 } => write!(
554 f,
555 "DROP{ie} PARTITION ({})",
556 display_comma_separated(partitions),
557 ie = if *if_exists { " IF EXISTS" } else { "" }
558 ),
559 AlterTableOperation::DropConstraint {
560 if_exists,
561 name,
562 drop_behavior,
563 } => {
564 write!(
565 f,
566 "DROP CONSTRAINT {}{}{}",
567 if *if_exists { "IF EXISTS " } else { "" },
568 name,
569 match drop_behavior {
570 None => "",
571 Some(DropBehavior::Restrict) => " RESTRICT",
572 Some(DropBehavior::Cascade) => " CASCADE",
573 }
574 )
575 }
576 AlterTableOperation::DropPrimaryKey => write!(f, "DROP PRIMARY KEY"),
577 AlterTableOperation::DropForeignKey { name } => write!(f, "DROP FOREIGN KEY {name}"),
578 AlterTableOperation::DropColumn {
579 column_name,
580 if_exists,
581 drop_behavior,
582 } => write!(
583 f,
584 "DROP COLUMN {}{}{}",
585 if *if_exists { "IF EXISTS " } else { "" },
586 column_name,
587 match drop_behavior {
588 None => "",
589 Some(DropBehavior::Restrict) => " RESTRICT",
590 Some(DropBehavior::Cascade) => " CASCADE",
591 }
592 ),
593 AlterTableOperation::AttachPartition { partition } => {
594 write!(f, "ATTACH {partition}")
595 }
596 AlterTableOperation::DetachPartition { partition } => {
597 write!(f, "DETACH {partition}")
598 }
599 AlterTableOperation::EnableAlwaysRule { name } => {
600 write!(f, "ENABLE ALWAYS RULE {name}")
601 }
602 AlterTableOperation::EnableAlwaysTrigger { name } => {
603 write!(f, "ENABLE ALWAYS TRIGGER {name}")
604 }
605 AlterTableOperation::EnableReplicaRule { name } => {
606 write!(f, "ENABLE REPLICA RULE {name}")
607 }
608 AlterTableOperation::EnableReplicaTrigger { name } => {
609 write!(f, "ENABLE REPLICA TRIGGER {name}")
610 }
611 AlterTableOperation::EnableRowLevelSecurity => {
612 write!(f, "ENABLE ROW LEVEL SECURITY")
613 }
614 AlterTableOperation::EnableRule { name } => {
615 write!(f, "ENABLE RULE {name}")
616 }
617 AlterTableOperation::EnableTrigger { name } => {
618 write!(f, "ENABLE TRIGGER {name}")
619 }
620 AlterTableOperation::RenamePartitions {
621 old_partitions,
622 new_partitions,
623 } => write!(
624 f,
625 "PARTITION ({}) RENAME TO PARTITION ({})",
626 display_comma_separated(old_partitions),
627 display_comma_separated(new_partitions)
628 ),
629 AlterTableOperation::RenameColumn {
630 old_column_name,
631 new_column_name,
632 } => write!(f, "RENAME COLUMN {old_column_name} TO {new_column_name}"),
633 AlterTableOperation::RenameTable { table_name } => {
634 write!(f, "RENAME TO {table_name}")
635 }
636 AlterTableOperation::ChangeColumn {
637 old_name,
638 new_name,
639 data_type,
640 options,
641 column_position,
642 } => {
643 write!(f, "CHANGE COLUMN {old_name} {new_name} {data_type}")?;
644 if !options.is_empty() {
645 write!(f, " {}", display_separated(options, " "))?;
646 }
647 if let Some(position) = column_position {
648 write!(f, " {position}")?;
649 }
650
651 Ok(())
652 }
653 AlterTableOperation::ModifyColumn {
654 col_name,
655 data_type,
656 options,
657 column_position,
658 } => {
659 write!(f, "MODIFY COLUMN {col_name} {data_type}")?;
660 if !options.is_empty() {
661 write!(f, " {}", display_separated(options, " "))?;
662 }
663 if let Some(position) = column_position {
664 write!(f, " {position}")?;
665 }
666
667 Ok(())
668 }
669 AlterTableOperation::RenameConstraint { old_name, new_name } => {
670 write!(f, "RENAME CONSTRAINT {old_name} TO {new_name}")
671 }
672 AlterTableOperation::SwapWith { table_name } => {
673 write!(f, "SWAP WITH {table_name}")
674 }
675 AlterTableOperation::OwnerTo { new_owner } => {
676 write!(f, "OWNER TO {new_owner}")
677 }
678 AlterTableOperation::SetTblProperties { table_properties } => {
679 write!(
680 f,
681 "SET TBLPROPERTIES({})",
682 display_comma_separated(table_properties)
683 )
684 }
685 AlterTableOperation::FreezePartition {
686 partition,
687 with_name,
688 } => {
689 write!(f, "FREEZE {partition}")?;
690 if let Some(name) = with_name {
691 write!(f, " WITH NAME {name}")?;
692 }
693 Ok(())
694 }
695 AlterTableOperation::UnfreezePartition {
696 partition,
697 with_name,
698 } => {
699 write!(f, "UNFREEZE {partition}")?;
700 if let Some(name) = with_name {
701 write!(f, " WITH NAME {name}")?;
702 }
703 Ok(())
704 }
705 AlterTableOperation::ClusterBy { exprs } => {
706 write!(f, "CLUSTER BY ({})", display_comma_separated(exprs))?;
707 Ok(())
708 }
709 AlterTableOperation::DropClusteringKey => {
710 write!(f, "DROP CLUSTERING KEY")?;
711 Ok(())
712 }
713 AlterTableOperation::SuspendRecluster => {
714 write!(f, "SUSPEND RECLUSTER")?;
715 Ok(())
716 }
717 AlterTableOperation::ResumeRecluster => {
718 write!(f, "RESUME RECLUSTER")?;
719 Ok(())
720 }
721 AlterTableOperation::AutoIncrement { equals, value } => {
722 write!(
723 f,
724 "AUTO_INCREMENT {}{}",
725 if *equals { "= " } else { "" },
726 value
727 )
728 }
729 AlterTableOperation::Lock { equals, lock } => {
730 write!(f, "LOCK {}{}", if *equals { "= " } else { "" }, lock)
731 }
732 }
733 }
734}
735
736impl fmt::Display for AlterIndexOperation {
737 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
738 match self {
739 AlterIndexOperation::RenameIndex { index_name } => {
740 write!(f, "RENAME TO {index_name}")
741 }
742 }
743 }
744}
745
746#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
748#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
749#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
750pub struct AlterType {
751 pub name: ObjectName,
752 pub operation: AlterTypeOperation,
753}
754
755#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
757#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
758#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
759pub enum AlterTypeOperation {
760 Rename(AlterTypeRename),
761 AddValue(AlterTypeAddValue),
762 RenameValue(AlterTypeRenameValue),
763}
764
765#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
767#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
768#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
769pub struct AlterTypeRename {
770 pub new_name: Ident,
771}
772
773#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
775#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
776#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
777pub struct AlterTypeAddValue {
778 pub if_not_exists: bool,
779 pub value: Ident,
780 pub position: Option<AlterTypeAddValuePosition>,
781}
782
783#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
785#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
786#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
787pub enum AlterTypeAddValuePosition {
788 Before(Ident),
789 After(Ident),
790}
791
792#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
794#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
795#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
796pub struct AlterTypeRenameValue {
797 pub from: Ident,
798 pub to: Ident,
799}
800
801impl fmt::Display for AlterTypeOperation {
802 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
803 match self {
804 Self::Rename(AlterTypeRename { new_name }) => {
805 write!(f, "RENAME TO {new_name}")
806 }
807 Self::AddValue(AlterTypeAddValue {
808 if_not_exists,
809 value,
810 position,
811 }) => {
812 write!(f, "ADD VALUE")?;
813 if *if_not_exists {
814 write!(f, " IF NOT EXISTS")?;
815 }
816 write!(f, " {value}")?;
817 match position {
818 Some(AlterTypeAddValuePosition::Before(neighbor_value)) => {
819 write!(f, " BEFORE {neighbor_value}")?;
820 }
821 Some(AlterTypeAddValuePosition::After(neighbor_value)) => {
822 write!(f, " AFTER {neighbor_value}")?;
823 }
824 None => {}
825 };
826 Ok(())
827 }
828 Self::RenameValue(AlterTypeRenameValue { from, to }) => {
829 write!(f, "RENAME VALUE {from} TO {to}")
830 }
831 }
832 }
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 enum AlterColumnOperation {
840 SetNotNull,
842 DropNotNull,
844 SetDefault { value: Expr },
846 DropDefault,
848 SetDataType {
850 data_type: DataType,
851 using: Option<Expr>,
853 },
854 AddGenerated {
858 generated_as: Option<GeneratedAs>,
859 sequence_options: Option<Vec<SequenceOptions>>,
860 },
861}
862
863impl fmt::Display for AlterColumnOperation {
864 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
865 match self {
866 AlterColumnOperation::SetNotNull => write!(f, "SET NOT NULL",),
867 AlterColumnOperation::DropNotNull => write!(f, "DROP NOT NULL",),
868 AlterColumnOperation::SetDefault { value } => {
869 write!(f, "SET DEFAULT {value}")
870 }
871 AlterColumnOperation::DropDefault => {
872 write!(f, "DROP DEFAULT")
873 }
874 AlterColumnOperation::SetDataType { data_type, using } => {
875 if let Some(expr) = using {
876 write!(f, "SET DATA TYPE {data_type} USING {expr}")
877 } else {
878 write!(f, "SET DATA TYPE {data_type}")
879 }
880 }
881 AlterColumnOperation::AddGenerated {
882 generated_as,
883 sequence_options,
884 } => {
885 let generated_as = match generated_as {
886 Some(GeneratedAs::Always) => " ALWAYS",
887 Some(GeneratedAs::ByDefault) => " BY DEFAULT",
888 _ => "",
889 };
890
891 write!(f, "ADD GENERATED{generated_as} AS IDENTITY",)?;
892 if let Some(options) = sequence_options {
893 write!(f, " (")?;
894
895 for sequence_option in options {
896 write!(f, "{sequence_option}")?;
897 }
898
899 write!(f, " )")?;
900 }
901 Ok(())
902 }
903 }
904 }
905}
906
907#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
910#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
911#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
912pub enum TableConstraint {
913 Unique {
926 name: Option<Ident>,
930 index_name: Option<Ident>,
932 index_type_display: KeyOrIndexDisplay,
934 index_type: Option<IndexType>,
938 columns: Vec<Ident>,
940 index_options: Vec<IndexOption>,
941 characteristics: Option<ConstraintCharacteristics>,
942 nulls_distinct: NullsDistinctOption,
944 },
945 PrimaryKey {
964 name: Option<Ident>,
968 index_name: Option<Ident>,
970 index_type: Option<IndexType>,
974 columns: Vec<Ident>,
976 index_options: Vec<IndexOption>,
977 characteristics: Option<ConstraintCharacteristics>,
978 },
979 ForeignKey {
985 name: Option<Ident>,
986 columns: Vec<Ident>,
987 foreign_table: ObjectName,
988 referred_columns: Vec<Ident>,
989 on_delete: Option<ReferentialAction>,
990 on_update: Option<ReferentialAction>,
991 characteristics: Option<ConstraintCharacteristics>,
992 },
993 Check {
995 name: Option<Ident>,
996 expr: Box<Expr>,
997 },
998 Index {
1005 display_as_key: bool,
1007 name: Option<Ident>,
1009 index_type: Option<IndexType>,
1013 columns: Vec<Ident>,
1015 },
1016 FulltextOrSpatial {
1030 fulltext: bool,
1032 index_type_display: KeyOrIndexDisplay,
1034 opt_index_name: Option<Ident>,
1036 columns: Vec<Ident>,
1038 },
1039}
1040
1041impl fmt::Display for TableConstraint {
1042 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1043 match self {
1044 TableConstraint::Unique {
1045 name,
1046 index_name,
1047 index_type_display,
1048 index_type,
1049 columns,
1050 index_options,
1051 characteristics,
1052 nulls_distinct,
1053 } => {
1054 write!(
1055 f,
1056 "{}UNIQUE{nulls_distinct}{index_type_display:>}{}{} ({})",
1057 display_constraint_name(name),
1058 display_option_spaced(index_name),
1059 display_option(" USING ", "", index_type),
1060 display_comma_separated(columns),
1061 )?;
1062
1063 if !index_options.is_empty() {
1064 write!(f, " {}", display_separated(index_options, " "))?;
1065 }
1066
1067 write!(f, "{}", display_option_spaced(characteristics))?;
1068 Ok(())
1069 }
1070 TableConstraint::PrimaryKey {
1071 name,
1072 index_name,
1073 index_type,
1074 columns,
1075 index_options,
1076 characteristics,
1077 } => {
1078 write!(
1079 f,
1080 "{}PRIMARY KEY{}{} ({})",
1081 display_constraint_name(name),
1082 display_option_spaced(index_name),
1083 display_option(" USING ", "", index_type),
1084 display_comma_separated(columns),
1085 )?;
1086
1087 if !index_options.is_empty() {
1088 write!(f, " {}", display_separated(index_options, " "))?;
1089 }
1090
1091 write!(f, "{}", display_option_spaced(characteristics))?;
1092 Ok(())
1093 }
1094 TableConstraint::ForeignKey {
1095 name,
1096 columns,
1097 foreign_table,
1098 referred_columns,
1099 on_delete,
1100 on_update,
1101 characteristics,
1102 } => {
1103 write!(
1104 f,
1105 "{}FOREIGN KEY ({}) REFERENCES {}",
1106 display_constraint_name(name),
1107 display_comma_separated(columns),
1108 foreign_table,
1109 )?;
1110 if !referred_columns.is_empty() {
1111 write!(f, "({})", display_comma_separated(referred_columns))?;
1112 }
1113 if let Some(action) = on_delete {
1114 write!(f, " ON DELETE {action}")?;
1115 }
1116 if let Some(action) = on_update {
1117 write!(f, " ON UPDATE {action}")?;
1118 }
1119 if let Some(characteristics) = characteristics {
1120 write!(f, " {}", characteristics)?;
1121 }
1122 Ok(())
1123 }
1124 TableConstraint::Check { name, expr } => {
1125 write!(f, "{}CHECK ({})", display_constraint_name(name), expr)
1126 }
1127 TableConstraint::Index {
1128 display_as_key,
1129 name,
1130 index_type,
1131 columns,
1132 } => {
1133 write!(f, "{}", if *display_as_key { "KEY" } else { "INDEX" })?;
1134 if let Some(name) = name {
1135 write!(f, " {name}")?;
1136 }
1137 if let Some(index_type) = index_type {
1138 write!(f, " USING {index_type}")?;
1139 }
1140 write!(f, " ({})", display_comma_separated(columns))?;
1141
1142 Ok(())
1143 }
1144 Self::FulltextOrSpatial {
1145 fulltext,
1146 index_type_display,
1147 opt_index_name,
1148 columns,
1149 } => {
1150 if *fulltext {
1151 write!(f, "FULLTEXT")?;
1152 } else {
1153 write!(f, "SPATIAL")?;
1154 }
1155
1156 write!(f, "{index_type_display:>}")?;
1157
1158 if let Some(name) = opt_index_name {
1159 write!(f, " {name}")?;
1160 }
1161
1162 write!(f, " ({})", display_comma_separated(columns))?;
1163
1164 Ok(())
1165 }
1166 }
1167 }
1168}
1169
1170#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1178#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1179#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1180pub enum KeyOrIndexDisplay {
1181 None,
1183 Key,
1185 Index,
1187}
1188
1189impl KeyOrIndexDisplay {
1190 pub fn is_none(self) -> bool {
1191 matches!(self, Self::None)
1192 }
1193}
1194
1195impl fmt::Display for KeyOrIndexDisplay {
1196 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1197 let left_space = matches!(f.align(), Some(fmt::Alignment::Right));
1198
1199 if left_space && !self.is_none() {
1200 f.write_char(' ')?
1201 }
1202
1203 match self {
1204 KeyOrIndexDisplay::None => {
1205 write!(f, "")
1206 }
1207 KeyOrIndexDisplay::Key => {
1208 write!(f, "KEY")
1209 }
1210 KeyOrIndexDisplay::Index => {
1211 write!(f, "INDEX")
1212 }
1213 }
1214 }
1215}
1216
1217#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1226#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1227#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1228pub enum IndexType {
1229 BTree,
1230 Hash,
1231 GIN,
1232 GiST,
1233 SPGiST,
1234 BRIN,
1235 Bloom,
1236 Custom(Ident),
1239}
1240
1241impl fmt::Display for IndexType {
1242 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1243 match self {
1244 Self::BTree => write!(f, "BTREE"),
1245 Self::Hash => write!(f, "HASH"),
1246 Self::GIN => write!(f, "GIN"),
1247 Self::GiST => write!(f, "GIST"),
1248 Self::SPGiST => write!(f, "SPGIST"),
1249 Self::BRIN => write!(f, "BRIN"),
1250 Self::Bloom => write!(f, "BLOOM"),
1251 Self::Custom(name) => write!(f, "{}", name),
1252 }
1253 }
1254}
1255
1256#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1263#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1264#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1265pub enum IndexOption {
1266 Using(IndexType),
1267 Comment(String),
1268}
1269
1270impl fmt::Display for IndexOption {
1271 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1272 match self {
1273 Self::Using(index_type) => write!(f, "USING {index_type}"),
1274 Self::Comment(s) => write!(f, "COMMENT '{s}'"),
1275 }
1276 }
1277}
1278
1279#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1283#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1284#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1285pub enum NullsDistinctOption {
1286 None,
1288 Distinct,
1290 NotDistinct,
1292}
1293
1294impl fmt::Display for NullsDistinctOption {
1295 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1296 match self {
1297 Self::None => Ok(()),
1298 Self::Distinct => write!(f, " NULLS DISTINCT"),
1299 Self::NotDistinct => write!(f, " NULLS NOT DISTINCT"),
1300 }
1301 }
1302}
1303
1304#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1305#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1306#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1307pub struct ProcedureParam {
1308 pub name: Ident,
1309 pub data_type: DataType,
1310}
1311
1312impl fmt::Display for ProcedureParam {
1313 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1314 write!(f, "{} {}", self.name, self.data_type)
1315 }
1316}
1317
1318#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1320#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1321#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1322pub struct ColumnDef {
1323 pub name: Ident,
1324 pub data_type: DataType,
1325 pub options: Vec<ColumnOptionDef>,
1326}
1327
1328impl fmt::Display for ColumnDef {
1329 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1330 if self.data_type == DataType::Unspecified {
1331 write!(f, "{}", self.name)?;
1332 } else {
1333 write!(f, "{} {}", self.name, self.data_type)?;
1334 }
1335 for option in &self.options {
1336 write!(f, " {option}")?;
1337 }
1338 Ok(())
1339 }
1340}
1341
1342#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1359#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1360#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1361pub struct ViewColumnDef {
1362 pub name: Ident,
1363 pub data_type: Option<DataType>,
1364 pub options: Option<Vec<ColumnOption>>,
1365}
1366
1367impl fmt::Display for ViewColumnDef {
1368 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1369 write!(f, "{}", self.name)?;
1370 if let Some(data_type) = self.data_type.as_ref() {
1371 write!(f, " {}", data_type)?;
1372 }
1373 if let Some(options) = self.options.as_ref() {
1374 write!(f, " {}", display_comma_separated(options.as_slice()))?;
1375 }
1376 Ok(())
1377 }
1378}
1379
1380#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1397#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1398#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1399pub struct ColumnOptionDef {
1400 pub name: Option<Ident>,
1401 pub option: ColumnOption,
1402}
1403
1404impl fmt::Display for ColumnOptionDef {
1405 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1406 write!(f, "{}{}", display_constraint_name(&self.name), self.option)
1407 }
1408}
1409
1410#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1418#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1419#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1420pub enum IdentityPropertyKind {
1421 Autoincrement(IdentityProperty),
1429 Identity(IdentityProperty),
1442}
1443
1444impl fmt::Display for IdentityPropertyKind {
1445 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1446 let (command, property) = match self {
1447 IdentityPropertyKind::Identity(property) => ("IDENTITY", property),
1448 IdentityPropertyKind::Autoincrement(property) => ("AUTOINCREMENT", property),
1449 };
1450 write!(f, "{command}")?;
1451 if let Some(parameters) = &property.parameters {
1452 write!(f, "{parameters}")?;
1453 }
1454 if let Some(order) = &property.order {
1455 write!(f, "{order}")?;
1456 }
1457 Ok(())
1458 }
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 struct IdentityProperty {
1465 pub parameters: Option<IdentityPropertyFormatKind>,
1466 pub order: Option<IdentityPropertyOrder>,
1467}
1468
1469#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1484#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1485#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1486pub enum IdentityPropertyFormatKind {
1487 FunctionCall(IdentityParameters),
1495 StartAndIncrement(IdentityParameters),
1502}
1503
1504impl fmt::Display for IdentityPropertyFormatKind {
1505 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1506 match self {
1507 IdentityPropertyFormatKind::FunctionCall(parameters) => {
1508 write!(f, "({}, {})", parameters.seed, parameters.increment)
1509 }
1510 IdentityPropertyFormatKind::StartAndIncrement(parameters) => {
1511 write!(
1512 f,
1513 " START {} INCREMENT {}",
1514 parameters.seed, parameters.increment
1515 )
1516 }
1517 }
1518 }
1519}
1520#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1521#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1522#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1523pub struct IdentityParameters {
1524 pub seed: Expr,
1525 pub increment: Expr,
1526}
1527
1528#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1535#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1536#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1537pub enum IdentityPropertyOrder {
1538 Order,
1539 NoOrder,
1540}
1541
1542impl fmt::Display for IdentityPropertyOrder {
1543 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1544 match self {
1545 IdentityPropertyOrder::Order => write!(f, " ORDER"),
1546 IdentityPropertyOrder::NoOrder => write!(f, " NOORDER"),
1547 }
1548 }
1549}
1550
1551#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1559#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1560#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1561pub enum ColumnPolicy {
1562 MaskingPolicy(ColumnPolicyProperty),
1563 ProjectionPolicy(ColumnPolicyProperty),
1564}
1565
1566impl fmt::Display for ColumnPolicy {
1567 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1568 let (command, property) = match self {
1569 ColumnPolicy::MaskingPolicy(property) => ("MASKING POLICY", property),
1570 ColumnPolicy::ProjectionPolicy(property) => ("PROJECTION POLICY", property),
1571 };
1572 if property.with {
1573 write!(f, "WITH ")?;
1574 }
1575 write!(f, "{command} {}", property.policy_name)?;
1576 if let Some(using_columns) = &property.using_columns {
1577 write!(f, " USING ({})", display_comma_separated(using_columns))?;
1578 }
1579 Ok(())
1580 }
1581}
1582
1583#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1584#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1585#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1586pub struct ColumnPolicyProperty {
1587 pub with: bool,
1594 pub policy_name: Ident,
1595 pub using_columns: Option<Vec<Ident>>,
1596}
1597
1598#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1605#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1606#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1607pub struct TagsColumnOption {
1608 pub with: bool,
1615 pub tags: Vec<Tag>,
1616}
1617
1618impl fmt::Display for TagsColumnOption {
1619 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1620 if self.with {
1621 write!(f, "WITH ")?;
1622 }
1623 write!(f, "TAG ({})", display_comma_separated(&self.tags))?;
1624 Ok(())
1625 }
1626}
1627
1628#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1631#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1632#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1633pub enum ColumnOption {
1634 Null,
1636 NotNull,
1638 Default(Expr),
1640
1641 Materialized(Expr),
1646 Ephemeral(Option<Expr>),
1650 Alias(Expr),
1654
1655 Unique {
1657 is_primary: bool,
1658 characteristics: Option<ConstraintCharacteristics>,
1659 },
1660 ForeignKey {
1668 foreign_table: ObjectName,
1669 referred_columns: Vec<Ident>,
1670 on_delete: Option<ReferentialAction>,
1671 on_update: Option<ReferentialAction>,
1672 characteristics: Option<ConstraintCharacteristics>,
1673 },
1674 Check(Expr),
1676 DialectSpecific(Vec<Token>),
1680 CharacterSet(ObjectName),
1681 Collation(ObjectName),
1682 Comment(String),
1683 OnUpdate(Expr),
1684 Generated {
1687 generated_as: GeneratedAs,
1688 sequence_options: Option<Vec<SequenceOptions>>,
1689 generation_expr: Option<Expr>,
1690 generation_expr_mode: Option<GeneratedExpressionMode>,
1691 generated_keyword: bool,
1693 },
1694 Options(Vec<SqlOption>),
1702 Identity(IdentityPropertyKind),
1710 OnConflict(Keyword),
1713 Policy(ColumnPolicy),
1721 Tags(TagsColumnOption),
1728}
1729
1730impl fmt::Display for ColumnOption {
1731 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1732 use ColumnOption::*;
1733 match self {
1734 Null => write!(f, "NULL"),
1735 NotNull => write!(f, "NOT NULL"),
1736 Default(expr) => write!(f, "DEFAULT {expr}"),
1737 Materialized(expr) => write!(f, "MATERIALIZED {expr}"),
1738 Ephemeral(expr) => {
1739 if let Some(e) = expr {
1740 write!(f, "EPHEMERAL {e}")
1741 } else {
1742 write!(f, "EPHEMERAL")
1743 }
1744 }
1745 Alias(expr) => write!(f, "ALIAS {expr}"),
1746 Unique {
1747 is_primary,
1748 characteristics,
1749 } => {
1750 write!(f, "{}", if *is_primary { "PRIMARY KEY" } else { "UNIQUE" })?;
1751 if let Some(characteristics) = characteristics {
1752 write!(f, " {}", characteristics)?;
1753 }
1754 Ok(())
1755 }
1756 ForeignKey {
1757 foreign_table,
1758 referred_columns,
1759 on_delete,
1760 on_update,
1761 characteristics,
1762 } => {
1763 write!(f, "REFERENCES {foreign_table}")?;
1764 if !referred_columns.is_empty() {
1765 write!(f, " ({})", display_comma_separated(referred_columns))?;
1766 }
1767 if let Some(action) = on_delete {
1768 write!(f, " ON DELETE {action}")?;
1769 }
1770 if let Some(action) = on_update {
1771 write!(f, " ON UPDATE {action}")?;
1772 }
1773 if let Some(characteristics) = characteristics {
1774 write!(f, " {}", characteristics)?;
1775 }
1776 Ok(())
1777 }
1778 Check(expr) => write!(f, "CHECK ({expr})"),
1779 DialectSpecific(val) => write!(f, "{}", display_separated(val, " ")),
1780 CharacterSet(n) => write!(f, "CHARACTER SET {n}"),
1781 Collation(n) => write!(f, "COLLATE {n}"),
1782 Comment(v) => write!(f, "COMMENT '{}'", escape_single_quote_string(v)),
1783 OnUpdate(expr) => write!(f, "ON UPDATE {expr}"),
1784 Generated {
1785 generated_as,
1786 sequence_options,
1787 generation_expr,
1788 generation_expr_mode,
1789 generated_keyword,
1790 } => {
1791 if let Some(expr) = generation_expr {
1792 let modifier = match generation_expr_mode {
1793 None => "",
1794 Some(GeneratedExpressionMode::Virtual) => " VIRTUAL",
1795 Some(GeneratedExpressionMode::Stored) => " STORED",
1796 };
1797 if *generated_keyword {
1798 write!(f, "GENERATED ALWAYS AS ({expr}){modifier}")?;
1799 } else {
1800 write!(f, "AS ({expr}){modifier}")?;
1801 }
1802 Ok(())
1803 } else {
1804 let when = match generated_as {
1806 GeneratedAs::Always => "ALWAYS",
1807 GeneratedAs::ByDefault => "BY DEFAULT",
1808 GeneratedAs::ExpStored => unreachable!(),
1810 };
1811 write!(f, "GENERATED {when} AS IDENTITY")?;
1812 if sequence_options.is_some() {
1813 let so = sequence_options.as_ref().unwrap();
1814 if !so.is_empty() {
1815 write!(f, " (")?;
1816 }
1817 for sequence_option in so {
1818 write!(f, "{sequence_option}")?;
1819 }
1820 if !so.is_empty() {
1821 write!(f, " )")?;
1822 }
1823 }
1824 Ok(())
1825 }
1826 }
1827 Options(options) => {
1828 write!(f, "OPTIONS({})", display_comma_separated(options))
1829 }
1830 Identity(parameters) => {
1831 write!(f, "{parameters}")
1832 }
1833 OnConflict(keyword) => {
1834 write!(f, "ON CONFLICT {:?}", keyword)?;
1835 Ok(())
1836 }
1837 Policy(parameters) => {
1838 write!(f, "{parameters}")
1839 }
1840 Tags(tags) => {
1841 write!(f, "{tags}")
1842 }
1843 }
1844 }
1845}
1846
1847#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1850#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1851#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1852pub enum GeneratedAs {
1853 Always,
1854 ByDefault,
1855 ExpStored,
1856}
1857
1858#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1861#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1862#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1863pub enum GeneratedExpressionMode {
1864 Virtual,
1865 Stored,
1866}
1867
1868#[must_use]
1869fn display_constraint_name(name: &'_ Option<Ident>) -> impl fmt::Display + '_ {
1870 struct ConstraintName<'a>(&'a Option<Ident>);
1871 impl fmt::Display for ConstraintName<'_> {
1872 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1873 if let Some(name) = self.0 {
1874 write!(f, "CONSTRAINT {name} ")?;
1875 }
1876 Ok(())
1877 }
1878 }
1879 ConstraintName(name)
1880}
1881
1882#[must_use]
1886fn display_option<'a, T: fmt::Display>(
1887 prefix: &'a str,
1888 postfix: &'a str,
1889 option: &'a Option<T>,
1890) -> impl fmt::Display + 'a {
1891 struct OptionDisplay<'a, T>(&'a str, &'a str, &'a Option<T>);
1892 impl<T: fmt::Display> fmt::Display for OptionDisplay<'_, T> {
1893 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1894 if let Some(inner) = self.2 {
1895 let (prefix, postfix) = (self.0, self.1);
1896 write!(f, "{prefix}{inner}{postfix}")?;
1897 }
1898 Ok(())
1899 }
1900 }
1901 OptionDisplay(prefix, postfix, option)
1902}
1903
1904#[must_use]
1908fn display_option_spaced<T: fmt::Display>(option: &Option<T>) -> impl fmt::Display + '_ {
1909 display_option(" ", "", option)
1910}
1911
1912#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Default, Eq, Ord, Hash)]
1916#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1917#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1918pub struct ConstraintCharacteristics {
1919 pub deferrable: Option<bool>,
1921 pub initially: Option<DeferrableInitial>,
1923 pub enforced: Option<bool>,
1925}
1926
1927#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1928#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1929#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1930pub enum DeferrableInitial {
1931 Immediate,
1933 Deferred,
1935}
1936
1937impl ConstraintCharacteristics {
1938 fn deferrable_text(&self) -> Option<&'static str> {
1939 self.deferrable.map(|deferrable| {
1940 if deferrable {
1941 "DEFERRABLE"
1942 } else {
1943 "NOT DEFERRABLE"
1944 }
1945 })
1946 }
1947
1948 fn initially_immediate_text(&self) -> Option<&'static str> {
1949 self.initially
1950 .map(|initially_immediate| match initially_immediate {
1951 DeferrableInitial::Immediate => "INITIALLY IMMEDIATE",
1952 DeferrableInitial::Deferred => "INITIALLY DEFERRED",
1953 })
1954 }
1955
1956 fn enforced_text(&self) -> Option<&'static str> {
1957 self.enforced.map(
1958 |enforced| {
1959 if enforced {
1960 "ENFORCED"
1961 } else {
1962 "NOT ENFORCED"
1963 }
1964 },
1965 )
1966 }
1967}
1968
1969impl fmt::Display for ConstraintCharacteristics {
1970 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1971 let deferrable = self.deferrable_text();
1972 let initially_immediate = self.initially_immediate_text();
1973 let enforced = self.enforced_text();
1974
1975 match (deferrable, initially_immediate, enforced) {
1976 (None, None, None) => Ok(()),
1977 (None, None, Some(enforced)) => write!(f, "{enforced}"),
1978 (None, Some(initial), None) => write!(f, "{initial}"),
1979 (None, Some(initial), Some(enforced)) => write!(f, "{initial} {enforced}"),
1980 (Some(deferrable), None, None) => write!(f, "{deferrable}"),
1981 (Some(deferrable), None, Some(enforced)) => write!(f, "{deferrable} {enforced}"),
1982 (Some(deferrable), Some(initial), None) => write!(f, "{deferrable} {initial}"),
1983 (Some(deferrable), Some(initial), Some(enforced)) => {
1984 write!(f, "{deferrable} {initial} {enforced}")
1985 }
1986 }
1987 }
1988}
1989
1990#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1995#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1996#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1997pub enum ReferentialAction {
1998 Restrict,
1999 Cascade,
2000 SetNull,
2001 NoAction,
2002 SetDefault,
2003}
2004
2005impl fmt::Display for ReferentialAction {
2006 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2007 f.write_str(match self {
2008 ReferentialAction::Restrict => "RESTRICT",
2009 ReferentialAction::Cascade => "CASCADE",
2010 ReferentialAction::SetNull => "SET NULL",
2011 ReferentialAction::NoAction => "NO ACTION",
2012 ReferentialAction::SetDefault => "SET DEFAULT",
2013 })
2014 }
2015}
2016
2017#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2021#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2022#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2023pub enum DropBehavior {
2024 Restrict,
2025 Cascade,
2026}
2027
2028impl fmt::Display for DropBehavior {
2029 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2030 f.write_str(match self {
2031 DropBehavior::Restrict => "RESTRICT",
2032 DropBehavior::Cascade => "CASCADE",
2033 })
2034 }
2035}
2036
2037#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2039#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2040#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2041pub enum UserDefinedTypeRepresentation {
2042 Composite {
2043 attributes: Vec<UserDefinedTypeCompositeAttributeDef>,
2044 },
2045 Enum { labels: Vec<Ident> },
2047}
2048
2049impl fmt::Display for UserDefinedTypeRepresentation {
2050 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2051 match self {
2052 UserDefinedTypeRepresentation::Composite { attributes } => {
2053 write!(f, "({})", display_comma_separated(attributes))
2054 }
2055 UserDefinedTypeRepresentation::Enum { labels } => {
2056 write!(f, "ENUM ({})", display_comma_separated(labels))
2057 }
2058 }
2059 }
2060}
2061
2062#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2064#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2065#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2066pub struct UserDefinedTypeCompositeAttributeDef {
2067 pub name: Ident,
2068 pub data_type: DataType,
2069 pub collation: Option<ObjectName>,
2070}
2071
2072impl fmt::Display for UserDefinedTypeCompositeAttributeDef {
2073 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2074 write!(f, "{} {}", self.name, self.data_type)?;
2075 if let Some(collation) = &self.collation {
2076 write!(f, " COLLATE {collation}")?;
2077 }
2078 Ok(())
2079 }
2080}
2081
2082#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
2086#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2087#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2088pub enum Partition {
2089 Identifier(Ident),
2090 Expr(Expr),
2091 Part(Expr),
2094 Partitions(Vec<Expr>),
2095}
2096
2097impl fmt::Display for Partition {
2098 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2099 match self {
2100 Partition::Identifier(id) => write!(f, "PARTITION ID {id}"),
2101 Partition::Expr(expr) => write!(f, "PARTITION {expr}"),
2102 Partition::Part(expr) => write!(f, "PART {expr}"),
2103 Partition::Partitions(partitions) => {
2104 write!(f, "PARTITION ({})", display_comma_separated(partitions))
2105 }
2106 }
2107 }
2108}
2109
2110#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2113#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2114#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2115pub enum Deduplicate {
2116 All,
2117 ByExpression(Expr),
2118}
2119
2120impl fmt::Display for Deduplicate {
2121 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2122 match self {
2123 Deduplicate::All => write!(f, "DEDUPLICATE"),
2124 Deduplicate::ByExpression(expr) => write!(f, "DEDUPLICATE BY {expr}"),
2125 }
2126 }
2127}
2128
2129#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2134#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2135#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2136pub struct ClusteredBy {
2137 pub columns: Vec<Ident>,
2138 pub sorted_by: Option<Vec<OrderByExpr>>,
2139 pub num_buckets: Value,
2140}
2141
2142impl fmt::Display for ClusteredBy {
2143 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2144 write!(
2145 f,
2146 "CLUSTERED BY ({})",
2147 display_comma_separated(&self.columns)
2148 )?;
2149 if let Some(ref sorted_by) = self.sorted_by {
2150 write!(f, " SORTED BY ({})", display_comma_separated(sorted_by))?;
2151 }
2152 write!(f, " INTO {} BUCKETS", self.num_buckets)
2153 }
2154}
2155
2156#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2157#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2158#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2159pub struct CreateFunction {
2160 pub or_alter: bool,
2164 pub or_replace: bool,
2165 pub temporary: bool,
2166 pub if_not_exists: bool,
2167 pub name: ObjectName,
2168 pub args: Option<Vec<OperateFunctionArg>>,
2169 pub return_type: Option<DataType>,
2170 pub function_body: Option<CreateFunctionBody>,
2178 pub behavior: Option<FunctionBehavior>,
2184 pub called_on_null: Option<FunctionCalledOnNull>,
2188 pub parallel: Option<FunctionParallel>,
2192 pub using: Option<CreateFunctionUsing>,
2194 pub language: Option<Ident>,
2202 pub determinism_specifier: Option<FunctionDeterminismSpecifier>,
2206 pub options: Option<Vec<SqlOption>>,
2210 pub remote_connection: Option<ObjectName>,
2220}
2221
2222impl fmt::Display for CreateFunction {
2223 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2224 write!(
2225 f,
2226 "CREATE {or_alter}{or_replace}{temp}FUNCTION {if_not_exists}{name}",
2227 name = self.name,
2228 temp = if self.temporary { "TEMPORARY " } else { "" },
2229 or_alter = if self.or_alter { "OR ALTER " } else { "" },
2230 or_replace = if self.or_replace { "OR REPLACE " } else { "" },
2231 if_not_exists = if self.if_not_exists {
2232 "IF NOT EXISTS "
2233 } else {
2234 ""
2235 },
2236 )?;
2237 if let Some(args) = &self.args {
2238 write!(f, "({})", display_comma_separated(args))?;
2239 }
2240 if let Some(return_type) = &self.return_type {
2241 write!(f, " RETURNS {return_type}")?;
2242 }
2243 if let Some(determinism_specifier) = &self.determinism_specifier {
2244 write!(f, " {determinism_specifier}")?;
2245 }
2246 if let Some(language) = &self.language {
2247 write!(f, " LANGUAGE {language}")?;
2248 }
2249 if let Some(behavior) = &self.behavior {
2250 write!(f, " {behavior}")?;
2251 }
2252 if let Some(called_on_null) = &self.called_on_null {
2253 write!(f, " {called_on_null}")?;
2254 }
2255 if let Some(parallel) = &self.parallel {
2256 write!(f, " {parallel}")?;
2257 }
2258 if let Some(remote_connection) = &self.remote_connection {
2259 write!(f, " REMOTE WITH CONNECTION {remote_connection}")?;
2260 }
2261 if let Some(CreateFunctionBody::AsBeforeOptions(function_body)) = &self.function_body {
2262 write!(f, " AS {function_body}")?;
2263 }
2264 if let Some(CreateFunctionBody::Return(function_body)) = &self.function_body {
2265 write!(f, " RETURN {function_body}")?;
2266 }
2267 if let Some(using) = &self.using {
2268 write!(f, " {using}")?;
2269 }
2270 if let Some(options) = &self.options {
2271 write!(
2272 f,
2273 " OPTIONS({})",
2274 display_comma_separated(options.as_slice())
2275 )?;
2276 }
2277 if let Some(CreateFunctionBody::AsAfterOptions(function_body)) = &self.function_body {
2278 write!(f, " AS {function_body}")?;
2279 }
2280 if let Some(CreateFunctionBody::AsBeginEnd(bes)) = &self.function_body {
2281 write!(f, " AS {bes}")?;
2282 }
2283 Ok(())
2284 }
2285}
2286
2287#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2297#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2298#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2299pub struct CreateConnector {
2300 pub name: Ident,
2301 pub if_not_exists: bool,
2302 pub connector_type: Option<String>,
2303 pub url: Option<String>,
2304 pub comment: Option<CommentDef>,
2305 pub with_dcproperties: Option<Vec<SqlOption>>,
2306}
2307
2308impl fmt::Display for CreateConnector {
2309 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2310 write!(
2311 f,
2312 "CREATE CONNECTOR {if_not_exists}{name}",
2313 if_not_exists = if self.if_not_exists {
2314 "IF NOT EXISTS "
2315 } else {
2316 ""
2317 },
2318 name = self.name,
2319 )?;
2320
2321 if let Some(connector_type) = &self.connector_type {
2322 write!(f, " TYPE '{connector_type}'")?;
2323 }
2324
2325 if let Some(url) = &self.url {
2326 write!(f, " URL '{url}'")?;
2327 }
2328
2329 if let Some(comment) = &self.comment {
2330 write!(f, " COMMENT = '{comment}'")?;
2331 }
2332
2333 if let Some(with_dcproperties) = &self.with_dcproperties {
2334 write!(
2335 f,
2336 " WITH DCPROPERTIES({})",
2337 display_comma_separated(with_dcproperties)
2338 )?;
2339 }
2340
2341 Ok(())
2342 }
2343}