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,
156 EnableAlwaysRule {
160 name: Ident,
161 },
162 EnableAlwaysTrigger {
166 name: Ident,
167 },
168 EnableReplicaRule {
172 name: Ident,
173 },
174 EnableReplicaTrigger {
178 name: Ident,
179 },
180 EnableRowLevelSecurity,
184 EnableRule {
188 name: Ident,
189 },
190 EnableTrigger {
194 name: Ident,
195 },
196 RenamePartitions {
198 old_partitions: Vec<Expr>,
199 new_partitions: Vec<Expr>,
200 },
201 AddPartitions {
203 if_not_exists: bool,
204 new_partitions: Vec<Partition>,
205 },
206 DropPartitions {
207 partitions: Vec<Expr>,
208 if_exists: bool,
209 },
210 RenameColumn {
212 old_column_name: Ident,
213 new_column_name: Ident,
214 },
215 RenameTable {
217 table_name: ObjectName,
218 },
219 ChangeColumn {
221 old_name: Ident,
222 new_name: Ident,
223 data_type: DataType,
224 options: Vec<ColumnOption>,
225 column_position: Option<MySQLColumnPosition>,
227 },
228 ModifyColumn {
230 col_name: Ident,
231 data_type: DataType,
232 options: Vec<ColumnOption>,
233 column_position: Option<MySQLColumnPosition>,
235 },
236 RenameConstraint {
240 old_name: Ident,
241 new_name: Ident,
242 },
243 AlterColumn {
245 column_name: Ident,
246 op: AlterColumnOperation,
247 },
248 SwapWith {
252 table_name: ObjectName,
253 },
254 SetTblProperties {
256 table_properties: Vec<SqlOption>,
257 },
258 OwnerTo {
262 new_owner: Owner,
263 },
264 ClusterBy {
267 exprs: Vec<Expr>,
268 },
269 DropClusteringKey,
270 SuspendRecluster,
271 ResumeRecluster,
272 Algorithm {
278 equals: bool,
279 algorithm: AlterTableAlgorithm,
280 },
281 AutoIncrement {
287 equals: bool,
288 value: ValueWithSpan,
289 },
290}
291
292#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
296#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
297#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
298pub enum AlterPolicyOperation {
299 Rename {
300 new_name: Ident,
301 },
302 Apply {
303 to: Option<Vec<Owner>>,
304 using: Option<Expr>,
305 with_check: Option<Expr>,
306 },
307}
308
309impl fmt::Display for AlterPolicyOperation {
310 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
311 match self {
312 AlterPolicyOperation::Rename { new_name } => {
313 write!(f, " RENAME TO {new_name}")
314 }
315 AlterPolicyOperation::Apply {
316 to,
317 using,
318 with_check,
319 } => {
320 if let Some(to) = to {
321 write!(f, " TO {}", display_comma_separated(to))?;
322 }
323 if let Some(using) = using {
324 write!(f, " USING ({using})")?;
325 }
326 if let Some(with_check) = with_check {
327 write!(f, " WITH CHECK ({with_check})")?;
328 }
329 Ok(())
330 }
331 }
332 }
333}
334
335#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
339#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
340#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
341pub enum AlterTableAlgorithm {
342 Default,
343 Instant,
344 Inplace,
345 Copy,
346}
347
348impl fmt::Display for AlterTableAlgorithm {
349 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
350 f.write_str(match self {
351 Self::Default => "DEFAULT",
352 Self::Instant => "INSTANT",
353 Self::Inplace => "INPLACE",
354 Self::Copy => "COPY",
355 })
356 }
357}
358
359#[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 Owner {
363 Ident(Ident),
364 CurrentRole,
365 CurrentUser,
366 SessionUser,
367}
368
369impl fmt::Display for Owner {
370 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
371 match self {
372 Owner::Ident(ident) => write!(f, "{}", ident),
373 Owner::CurrentRole => write!(f, "CURRENT_ROLE"),
374 Owner::CurrentUser => write!(f, "CURRENT_USER"),
375 Owner::SessionUser => write!(f, "SESSION_USER"),
376 }
377 }
378}
379
380#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
381#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
382#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
383pub enum AlterConnectorOwner {
384 User(Ident),
385 Role(Ident),
386}
387
388impl fmt::Display for AlterConnectorOwner {
389 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
390 match self {
391 AlterConnectorOwner::User(ident) => write!(f, "USER {ident}"),
392 AlterConnectorOwner::Role(ident) => write!(f, "ROLE {ident}"),
393 }
394 }
395}
396
397#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
398#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
399#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
400pub enum AlterIndexOperation {
401 RenameIndex { index_name: ObjectName },
402}
403
404impl fmt::Display for AlterTableOperation {
405 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
406 match self {
407 AlterTableOperation::AddPartitions {
408 if_not_exists,
409 new_partitions,
410 } => write!(
411 f,
412 "ADD{ine} {}",
413 display_separated(new_partitions, " "),
414 ine = if *if_not_exists { " IF NOT EXISTS" } else { "" }
415 ),
416 AlterTableOperation::AddConstraint(c) => write!(f, "ADD {c}"),
417 AlterTableOperation::AddColumn {
418 column_keyword,
419 if_not_exists,
420 column_def,
421 column_position,
422 } => {
423 write!(f, "ADD")?;
424 if *column_keyword {
425 write!(f, " COLUMN")?;
426 }
427 if *if_not_exists {
428 write!(f, " IF NOT EXISTS")?;
429 }
430 write!(f, " {column_def}")?;
431
432 if let Some(position) = column_position {
433 write!(f, " {position}")?;
434 }
435
436 Ok(())
437 }
438 AlterTableOperation::AddProjection {
439 if_not_exists,
440 name,
441 select: query,
442 } => {
443 write!(f, "ADD PROJECTION")?;
444 if *if_not_exists {
445 write!(f, " IF NOT EXISTS")?;
446 }
447 write!(f, " {} ({})", name, query)
448 }
449 AlterTableOperation::Algorithm { equals, algorithm } => {
450 write!(
451 f,
452 "ALGORITHM {}{}",
453 if *equals { "= " } else { "" },
454 algorithm
455 )
456 }
457 AlterTableOperation::DropProjection { if_exists, name } => {
458 write!(f, "DROP PROJECTION")?;
459 if *if_exists {
460 write!(f, " IF EXISTS")?;
461 }
462 write!(f, " {}", name)
463 }
464 AlterTableOperation::MaterializeProjection {
465 if_exists,
466 name,
467 partition,
468 } => {
469 write!(f, "MATERIALIZE PROJECTION")?;
470 if *if_exists {
471 write!(f, " IF EXISTS")?;
472 }
473 write!(f, " {}", name)?;
474 if let Some(partition) = partition {
475 write!(f, " IN PARTITION {}", partition)?;
476 }
477 Ok(())
478 }
479 AlterTableOperation::ClearProjection {
480 if_exists,
481 name,
482 partition,
483 } => {
484 write!(f, "CLEAR PROJECTION")?;
485 if *if_exists {
486 write!(f, " IF EXISTS")?;
487 }
488 write!(f, " {}", name)?;
489 if let Some(partition) = partition {
490 write!(f, " IN PARTITION {}", partition)?;
491 }
492 Ok(())
493 }
494 AlterTableOperation::AlterColumn { column_name, op } => {
495 write!(f, "ALTER COLUMN {column_name} {op}")
496 }
497 AlterTableOperation::DisableRowLevelSecurity => {
498 write!(f, "DISABLE ROW LEVEL SECURITY")
499 }
500 AlterTableOperation::DisableRule { name } => {
501 write!(f, "DISABLE RULE {name}")
502 }
503 AlterTableOperation::DisableTrigger { name } => {
504 write!(f, "DISABLE TRIGGER {name}")
505 }
506 AlterTableOperation::DropPartitions {
507 partitions,
508 if_exists,
509 } => write!(
510 f,
511 "DROP{ie} PARTITION ({})",
512 display_comma_separated(partitions),
513 ie = if *if_exists { " IF EXISTS" } else { "" }
514 ),
515 AlterTableOperation::DropConstraint {
516 if_exists,
517 name,
518 drop_behavior,
519 } => {
520 write!(
521 f,
522 "DROP CONSTRAINT {}{}{}",
523 if *if_exists { "IF EXISTS " } else { "" },
524 name,
525 match drop_behavior {
526 None => "",
527 Some(DropBehavior::Restrict) => " RESTRICT",
528 Some(DropBehavior::Cascade) => " CASCADE",
529 }
530 )
531 }
532 AlterTableOperation::DropPrimaryKey => write!(f, "DROP PRIMARY KEY"),
533 AlterTableOperation::DropColumn {
534 column_name,
535 if_exists,
536 drop_behavior,
537 } => write!(
538 f,
539 "DROP COLUMN {}{}{}",
540 if *if_exists { "IF EXISTS " } else { "" },
541 column_name,
542 match drop_behavior {
543 None => "",
544 Some(DropBehavior::Restrict) => " RESTRICT",
545 Some(DropBehavior::Cascade) => " CASCADE",
546 }
547 ),
548 AlterTableOperation::AttachPartition { partition } => {
549 write!(f, "ATTACH {partition}")
550 }
551 AlterTableOperation::DetachPartition { partition } => {
552 write!(f, "DETACH {partition}")
553 }
554 AlterTableOperation::EnableAlwaysRule { name } => {
555 write!(f, "ENABLE ALWAYS RULE {name}")
556 }
557 AlterTableOperation::EnableAlwaysTrigger { name } => {
558 write!(f, "ENABLE ALWAYS TRIGGER {name}")
559 }
560 AlterTableOperation::EnableReplicaRule { name } => {
561 write!(f, "ENABLE REPLICA RULE {name}")
562 }
563 AlterTableOperation::EnableReplicaTrigger { name } => {
564 write!(f, "ENABLE REPLICA TRIGGER {name}")
565 }
566 AlterTableOperation::EnableRowLevelSecurity => {
567 write!(f, "ENABLE ROW LEVEL SECURITY")
568 }
569 AlterTableOperation::EnableRule { name } => {
570 write!(f, "ENABLE RULE {name}")
571 }
572 AlterTableOperation::EnableTrigger { name } => {
573 write!(f, "ENABLE TRIGGER {name}")
574 }
575 AlterTableOperation::RenamePartitions {
576 old_partitions,
577 new_partitions,
578 } => write!(
579 f,
580 "PARTITION ({}) RENAME TO PARTITION ({})",
581 display_comma_separated(old_partitions),
582 display_comma_separated(new_partitions)
583 ),
584 AlterTableOperation::RenameColumn {
585 old_column_name,
586 new_column_name,
587 } => write!(f, "RENAME COLUMN {old_column_name} TO {new_column_name}"),
588 AlterTableOperation::RenameTable { table_name } => {
589 write!(f, "RENAME TO {table_name}")
590 }
591 AlterTableOperation::ChangeColumn {
592 old_name,
593 new_name,
594 data_type,
595 options,
596 column_position,
597 } => {
598 write!(f, "CHANGE COLUMN {old_name} {new_name} {data_type}")?;
599 if !options.is_empty() {
600 write!(f, " {}", display_separated(options, " "))?;
601 }
602 if let Some(position) = column_position {
603 write!(f, " {position}")?;
604 }
605
606 Ok(())
607 }
608 AlterTableOperation::ModifyColumn {
609 col_name,
610 data_type,
611 options,
612 column_position,
613 } => {
614 write!(f, "MODIFY COLUMN {col_name} {data_type}")?;
615 if !options.is_empty() {
616 write!(f, " {}", display_separated(options, " "))?;
617 }
618 if let Some(position) = column_position {
619 write!(f, " {position}")?;
620 }
621
622 Ok(())
623 }
624 AlterTableOperation::RenameConstraint { old_name, new_name } => {
625 write!(f, "RENAME CONSTRAINT {old_name} TO {new_name}")
626 }
627 AlterTableOperation::SwapWith { table_name } => {
628 write!(f, "SWAP WITH {table_name}")
629 }
630 AlterTableOperation::OwnerTo { new_owner } => {
631 write!(f, "OWNER TO {new_owner}")
632 }
633 AlterTableOperation::SetTblProperties { table_properties } => {
634 write!(
635 f,
636 "SET TBLPROPERTIES({})",
637 display_comma_separated(table_properties)
638 )
639 }
640 AlterTableOperation::FreezePartition {
641 partition,
642 with_name,
643 } => {
644 write!(f, "FREEZE {partition}")?;
645 if let Some(name) = with_name {
646 write!(f, " WITH NAME {name}")?;
647 }
648 Ok(())
649 }
650 AlterTableOperation::UnfreezePartition {
651 partition,
652 with_name,
653 } => {
654 write!(f, "UNFREEZE {partition}")?;
655 if let Some(name) = with_name {
656 write!(f, " WITH NAME {name}")?;
657 }
658 Ok(())
659 }
660 AlterTableOperation::ClusterBy { exprs } => {
661 write!(f, "CLUSTER BY ({})", display_comma_separated(exprs))?;
662 Ok(())
663 }
664 AlterTableOperation::DropClusteringKey => {
665 write!(f, "DROP CLUSTERING KEY")?;
666 Ok(())
667 }
668 AlterTableOperation::SuspendRecluster => {
669 write!(f, "SUSPEND RECLUSTER")?;
670 Ok(())
671 }
672 AlterTableOperation::ResumeRecluster => {
673 write!(f, "RESUME RECLUSTER")?;
674 Ok(())
675 }
676 AlterTableOperation::AutoIncrement { equals, value } => {
677 write!(
678 f,
679 "AUTO_INCREMENT {}{}",
680 if *equals { "= " } else { "" },
681 value
682 )
683 }
684 }
685 }
686}
687
688impl fmt::Display for AlterIndexOperation {
689 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
690 match self {
691 AlterIndexOperation::RenameIndex { index_name } => {
692 write!(f, "RENAME TO {index_name}")
693 }
694 }
695 }
696}
697
698#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
700#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
701#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
702pub struct AlterType {
703 pub name: ObjectName,
704 pub operation: AlterTypeOperation,
705}
706
707#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
709#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
710#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
711pub enum AlterTypeOperation {
712 Rename(AlterTypeRename),
713 AddValue(AlterTypeAddValue),
714 RenameValue(AlterTypeRenameValue),
715}
716
717#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
719#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
720#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
721pub struct AlterTypeRename {
722 pub new_name: Ident,
723}
724
725#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
727#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
728#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
729pub struct AlterTypeAddValue {
730 pub if_not_exists: bool,
731 pub value: Ident,
732 pub position: Option<AlterTypeAddValuePosition>,
733}
734
735#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
737#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
738#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
739pub enum AlterTypeAddValuePosition {
740 Before(Ident),
741 After(Ident),
742}
743
744#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
746#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
747#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
748pub struct AlterTypeRenameValue {
749 pub from: Ident,
750 pub to: Ident,
751}
752
753impl fmt::Display for AlterTypeOperation {
754 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
755 match self {
756 Self::Rename(AlterTypeRename { new_name }) => {
757 write!(f, "RENAME TO {new_name}")
758 }
759 Self::AddValue(AlterTypeAddValue {
760 if_not_exists,
761 value,
762 position,
763 }) => {
764 write!(f, "ADD VALUE")?;
765 if *if_not_exists {
766 write!(f, " IF NOT EXISTS")?;
767 }
768 write!(f, " {value}")?;
769 match position {
770 Some(AlterTypeAddValuePosition::Before(neighbor_value)) => {
771 write!(f, " BEFORE {neighbor_value}")?;
772 }
773 Some(AlterTypeAddValuePosition::After(neighbor_value)) => {
774 write!(f, " AFTER {neighbor_value}")?;
775 }
776 None => {}
777 };
778 Ok(())
779 }
780 Self::RenameValue(AlterTypeRenameValue { from, to }) => {
781 write!(f, "RENAME VALUE {from} TO {to}")
782 }
783 }
784 }
785}
786
787#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
789#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
790#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
791pub enum AlterColumnOperation {
792 SetNotNull,
794 DropNotNull,
796 SetDefault { value: Expr },
798 DropDefault,
800 SetDataType {
802 data_type: DataType,
803 using: Option<Expr>,
805 },
806 AddGenerated {
810 generated_as: Option<GeneratedAs>,
811 sequence_options: Option<Vec<SequenceOptions>>,
812 },
813}
814
815impl fmt::Display for AlterColumnOperation {
816 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
817 match self {
818 AlterColumnOperation::SetNotNull => write!(f, "SET NOT NULL",),
819 AlterColumnOperation::DropNotNull => write!(f, "DROP NOT NULL",),
820 AlterColumnOperation::SetDefault { value } => {
821 write!(f, "SET DEFAULT {value}")
822 }
823 AlterColumnOperation::DropDefault {} => {
824 write!(f, "DROP DEFAULT")
825 }
826 AlterColumnOperation::SetDataType { data_type, using } => {
827 if let Some(expr) = using {
828 write!(f, "SET DATA TYPE {data_type} USING {expr}")
829 } else {
830 write!(f, "SET DATA TYPE {data_type}")
831 }
832 }
833 AlterColumnOperation::AddGenerated {
834 generated_as,
835 sequence_options,
836 } => {
837 let generated_as = match generated_as {
838 Some(GeneratedAs::Always) => " ALWAYS",
839 Some(GeneratedAs::ByDefault) => " BY DEFAULT",
840 _ => "",
841 };
842
843 write!(f, "ADD GENERATED{generated_as} AS IDENTITY",)?;
844 if let Some(options) = sequence_options {
845 write!(f, " (")?;
846
847 for sequence_option in options {
848 write!(f, "{sequence_option}")?;
849 }
850
851 write!(f, " )")?;
852 }
853 Ok(())
854 }
855 }
856 }
857}
858
859#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
862#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
863#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
864pub enum TableConstraint {
865 Unique {
878 name: Option<Ident>,
882 index_name: Option<Ident>,
884 index_type_display: KeyOrIndexDisplay,
886 index_type: Option<IndexType>,
890 columns: Vec<Ident>,
892 index_options: Vec<IndexOption>,
893 characteristics: Option<ConstraintCharacteristics>,
894 nulls_distinct: NullsDistinctOption,
896 },
897 PrimaryKey {
916 name: Option<Ident>,
920 index_name: Option<Ident>,
922 index_type: Option<IndexType>,
926 columns: Vec<Ident>,
928 index_options: Vec<IndexOption>,
929 characteristics: Option<ConstraintCharacteristics>,
930 },
931 ForeignKey {
937 name: Option<Ident>,
938 columns: Vec<Ident>,
939 foreign_table: ObjectName,
940 referred_columns: Vec<Ident>,
941 on_delete: Option<ReferentialAction>,
942 on_update: Option<ReferentialAction>,
943 characteristics: Option<ConstraintCharacteristics>,
944 },
945 Check {
947 name: Option<Ident>,
948 expr: Box<Expr>,
949 },
950 Index {
957 display_as_key: bool,
959 name: Option<Ident>,
961 index_type: Option<IndexType>,
965 columns: Vec<Ident>,
967 },
968 FulltextOrSpatial {
982 fulltext: bool,
984 index_type_display: KeyOrIndexDisplay,
986 opt_index_name: Option<Ident>,
988 columns: Vec<Ident>,
990 },
991}
992
993impl fmt::Display for TableConstraint {
994 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
995 match self {
996 TableConstraint::Unique {
997 name,
998 index_name,
999 index_type_display,
1000 index_type,
1001 columns,
1002 index_options,
1003 characteristics,
1004 nulls_distinct,
1005 } => {
1006 write!(
1007 f,
1008 "{}UNIQUE{nulls_distinct}{index_type_display:>}{}{} ({})",
1009 display_constraint_name(name),
1010 display_option_spaced(index_name),
1011 display_option(" USING ", "", index_type),
1012 display_comma_separated(columns),
1013 )?;
1014
1015 if !index_options.is_empty() {
1016 write!(f, " {}", display_separated(index_options, " "))?;
1017 }
1018
1019 write!(f, "{}", display_option_spaced(characteristics))?;
1020 Ok(())
1021 }
1022 TableConstraint::PrimaryKey {
1023 name,
1024 index_name,
1025 index_type,
1026 columns,
1027 index_options,
1028 characteristics,
1029 } => {
1030 write!(
1031 f,
1032 "{}PRIMARY KEY{}{} ({})",
1033 display_constraint_name(name),
1034 display_option_spaced(index_name),
1035 display_option(" USING ", "", index_type),
1036 display_comma_separated(columns),
1037 )?;
1038
1039 if !index_options.is_empty() {
1040 write!(f, " {}", display_separated(index_options, " "))?;
1041 }
1042
1043 write!(f, "{}", display_option_spaced(characteristics))?;
1044 Ok(())
1045 }
1046 TableConstraint::ForeignKey {
1047 name,
1048 columns,
1049 foreign_table,
1050 referred_columns,
1051 on_delete,
1052 on_update,
1053 characteristics,
1054 } => {
1055 write!(
1056 f,
1057 "{}FOREIGN KEY ({}) REFERENCES {}",
1058 display_constraint_name(name),
1059 display_comma_separated(columns),
1060 foreign_table,
1061 )?;
1062 if !referred_columns.is_empty() {
1063 write!(f, "({})", display_comma_separated(referred_columns))?;
1064 }
1065 if let Some(action) = on_delete {
1066 write!(f, " ON DELETE {action}")?;
1067 }
1068 if let Some(action) = on_update {
1069 write!(f, " ON UPDATE {action}")?;
1070 }
1071 if let Some(characteristics) = characteristics {
1072 write!(f, " {}", characteristics)?;
1073 }
1074 Ok(())
1075 }
1076 TableConstraint::Check { name, expr } => {
1077 write!(f, "{}CHECK ({})", display_constraint_name(name), expr)
1078 }
1079 TableConstraint::Index {
1080 display_as_key,
1081 name,
1082 index_type,
1083 columns,
1084 } => {
1085 write!(f, "{}", if *display_as_key { "KEY" } else { "INDEX" })?;
1086 if let Some(name) = name {
1087 write!(f, " {name}")?;
1088 }
1089 if let Some(index_type) = index_type {
1090 write!(f, " USING {index_type}")?;
1091 }
1092 write!(f, " ({})", display_comma_separated(columns))?;
1093
1094 Ok(())
1095 }
1096 Self::FulltextOrSpatial {
1097 fulltext,
1098 index_type_display,
1099 opt_index_name,
1100 columns,
1101 } => {
1102 if *fulltext {
1103 write!(f, "FULLTEXT")?;
1104 } else {
1105 write!(f, "SPATIAL")?;
1106 }
1107
1108 write!(f, "{index_type_display:>}")?;
1109
1110 if let Some(name) = opt_index_name {
1111 write!(f, " {name}")?;
1112 }
1113
1114 write!(f, " ({})", display_comma_separated(columns))?;
1115
1116 Ok(())
1117 }
1118 }
1119 }
1120}
1121
1122#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1130#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1131#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1132pub enum KeyOrIndexDisplay {
1133 None,
1135 Key,
1137 Index,
1139}
1140
1141impl KeyOrIndexDisplay {
1142 pub fn is_none(self) -> bool {
1143 matches!(self, Self::None)
1144 }
1145}
1146
1147impl fmt::Display for KeyOrIndexDisplay {
1148 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1149 let left_space = matches!(f.align(), Some(fmt::Alignment::Right));
1150
1151 if left_space && !self.is_none() {
1152 f.write_char(' ')?
1153 }
1154
1155 match self {
1156 KeyOrIndexDisplay::None => {
1157 write!(f, "")
1158 }
1159 KeyOrIndexDisplay::Key => {
1160 write!(f, "KEY")
1161 }
1162 KeyOrIndexDisplay::Index => {
1163 write!(f, "INDEX")
1164 }
1165 }
1166 }
1167}
1168
1169#[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 IndexType {
1181 BTree,
1182 Hash,
1183 }
1185
1186impl fmt::Display for IndexType {
1187 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1188 match self {
1189 Self::BTree => write!(f, "BTREE"),
1190 Self::Hash => write!(f, "HASH"),
1191 }
1192 }
1193}
1194
1195#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1202#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1203#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1204pub enum IndexOption {
1205 Using(IndexType),
1206 Comment(String),
1207}
1208
1209impl fmt::Display for IndexOption {
1210 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1211 match self {
1212 Self::Using(index_type) => write!(f, "USING {index_type}"),
1213 Self::Comment(s) => write!(f, "COMMENT '{s}'"),
1214 }
1215 }
1216}
1217
1218#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1222#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1223#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1224pub enum NullsDistinctOption {
1225 None,
1227 Distinct,
1229 NotDistinct,
1231}
1232
1233impl fmt::Display for NullsDistinctOption {
1234 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1235 match self {
1236 Self::None => Ok(()),
1237 Self::Distinct => write!(f, " NULLS DISTINCT"),
1238 Self::NotDistinct => write!(f, " NULLS NOT DISTINCT"),
1239 }
1240 }
1241}
1242
1243#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1244#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1245#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1246pub struct ProcedureParam {
1247 pub name: Ident,
1248 pub data_type: DataType,
1249}
1250
1251impl fmt::Display for ProcedureParam {
1252 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1253 write!(f, "{} {}", self.name, self.data_type)
1254 }
1255}
1256
1257#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1259#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1260#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1261pub struct ColumnDef {
1262 pub name: Ident,
1263 pub data_type: DataType,
1264 pub options: Vec<ColumnOptionDef>,
1265}
1266
1267impl fmt::Display for ColumnDef {
1268 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1269 if self.data_type == DataType::Unspecified {
1270 write!(f, "{}", self.name)?;
1271 } else {
1272 write!(f, "{} {}", self.name, self.data_type)?;
1273 }
1274 for option in &self.options {
1275 write!(f, " {option}")?;
1276 }
1277 Ok(())
1278 }
1279}
1280
1281#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1298#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1299#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1300pub struct ViewColumnDef {
1301 pub name: Ident,
1302 pub data_type: Option<DataType>,
1303 pub options: Option<Vec<ColumnOption>>,
1304}
1305
1306impl fmt::Display for ViewColumnDef {
1307 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1308 write!(f, "{}", self.name)?;
1309 if let Some(data_type) = self.data_type.as_ref() {
1310 write!(f, " {}", data_type)?;
1311 }
1312 if let Some(options) = self.options.as_ref() {
1313 write!(f, " {}", display_comma_separated(options.as_slice()))?;
1314 }
1315 Ok(())
1316 }
1317}
1318
1319#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1336#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1337#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1338pub struct ColumnOptionDef {
1339 pub name: Option<Ident>,
1340 pub option: ColumnOption,
1341}
1342
1343impl fmt::Display for ColumnOptionDef {
1344 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1345 write!(f, "{}{}", display_constraint_name(&self.name), self.option)
1346 }
1347}
1348
1349#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1357#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1358#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1359pub enum IdentityPropertyKind {
1360 Autoincrement(IdentityProperty),
1368 Identity(IdentityProperty),
1381}
1382
1383impl fmt::Display for IdentityPropertyKind {
1384 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1385 let (command, property) = match self {
1386 IdentityPropertyKind::Identity(property) => ("IDENTITY", property),
1387 IdentityPropertyKind::Autoincrement(property) => ("AUTOINCREMENT", property),
1388 };
1389 write!(f, "{command}")?;
1390 if let Some(parameters) = &property.parameters {
1391 write!(f, "{parameters}")?;
1392 }
1393 if let Some(order) = &property.order {
1394 write!(f, "{order}")?;
1395 }
1396 Ok(())
1397 }
1398}
1399
1400#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1401#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1402#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1403pub struct IdentityProperty {
1404 pub parameters: Option<IdentityPropertyFormatKind>,
1405 pub order: Option<IdentityPropertyOrder>,
1406}
1407
1408#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1423#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1424#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1425pub enum IdentityPropertyFormatKind {
1426 FunctionCall(IdentityParameters),
1434 StartAndIncrement(IdentityParameters),
1441}
1442
1443impl fmt::Display for IdentityPropertyFormatKind {
1444 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1445 match self {
1446 IdentityPropertyFormatKind::FunctionCall(parameters) => {
1447 write!(f, "({}, {})", parameters.seed, parameters.increment)
1448 }
1449 IdentityPropertyFormatKind::StartAndIncrement(parameters) => {
1450 write!(
1451 f,
1452 " START {} INCREMENT {}",
1453 parameters.seed, parameters.increment
1454 )
1455 }
1456 }
1457 }
1458}
1459#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1460#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1461#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1462pub struct IdentityParameters {
1463 pub seed: Expr,
1464 pub increment: Expr,
1465}
1466
1467#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1474#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1475#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1476pub enum IdentityPropertyOrder {
1477 Order,
1478 NoOrder,
1479}
1480
1481impl fmt::Display for IdentityPropertyOrder {
1482 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1483 match self {
1484 IdentityPropertyOrder::Order => write!(f, " ORDER"),
1485 IdentityPropertyOrder::NoOrder => write!(f, " NOORDER"),
1486 }
1487 }
1488}
1489
1490#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1498#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1499#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1500pub enum ColumnPolicy {
1501 MaskingPolicy(ColumnPolicyProperty),
1502 ProjectionPolicy(ColumnPolicyProperty),
1503}
1504
1505impl fmt::Display for ColumnPolicy {
1506 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1507 let (command, property) = match self {
1508 ColumnPolicy::MaskingPolicy(property) => ("MASKING POLICY", property),
1509 ColumnPolicy::ProjectionPolicy(property) => ("PROJECTION POLICY", property),
1510 };
1511 if property.with {
1512 write!(f, "WITH ")?;
1513 }
1514 write!(f, "{command} {}", property.policy_name)?;
1515 if let Some(using_columns) = &property.using_columns {
1516 write!(f, " USING ({})", display_comma_separated(using_columns))?;
1517 }
1518 Ok(())
1519 }
1520}
1521
1522#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1523#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1524#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1525pub struct ColumnPolicyProperty {
1526 pub with: bool,
1533 pub policy_name: Ident,
1534 pub using_columns: Option<Vec<Ident>>,
1535}
1536
1537#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1544#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1545#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1546pub struct TagsColumnOption {
1547 pub with: bool,
1554 pub tags: Vec<Tag>,
1555}
1556
1557impl fmt::Display for TagsColumnOption {
1558 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1559 if self.with {
1560 write!(f, "WITH ")?;
1561 }
1562 write!(f, "TAG ({})", display_comma_separated(&self.tags))?;
1563 Ok(())
1564 }
1565}
1566
1567#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1570#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1571#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1572pub enum ColumnOption {
1573 Null,
1575 NotNull,
1577 Default(Expr),
1579
1580 Materialized(Expr),
1585 Ephemeral(Option<Expr>),
1589 Alias(Expr),
1593
1594 Unique {
1596 is_primary: bool,
1597 characteristics: Option<ConstraintCharacteristics>,
1598 },
1599 ForeignKey {
1607 foreign_table: ObjectName,
1608 referred_columns: Vec<Ident>,
1609 on_delete: Option<ReferentialAction>,
1610 on_update: Option<ReferentialAction>,
1611 characteristics: Option<ConstraintCharacteristics>,
1612 },
1613 Check(Expr),
1615 DialectSpecific(Vec<Token>),
1619 CharacterSet(ObjectName),
1620 Collation(ObjectName),
1621 Comment(String),
1622 OnUpdate(Expr),
1623 Generated {
1626 generated_as: GeneratedAs,
1627 sequence_options: Option<Vec<SequenceOptions>>,
1628 generation_expr: Option<Expr>,
1629 generation_expr_mode: Option<GeneratedExpressionMode>,
1630 generated_keyword: bool,
1632 },
1633 Options(Vec<SqlOption>),
1641 Identity(IdentityPropertyKind),
1649 OnConflict(Keyword),
1652 Policy(ColumnPolicy),
1660 Tags(TagsColumnOption),
1667}
1668
1669impl fmt::Display for ColumnOption {
1670 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1671 use ColumnOption::*;
1672 match self {
1673 Null => write!(f, "NULL"),
1674 NotNull => write!(f, "NOT NULL"),
1675 Default(expr) => write!(f, "DEFAULT {expr}"),
1676 Materialized(expr) => write!(f, "MATERIALIZED {expr}"),
1677 Ephemeral(expr) => {
1678 if let Some(e) = expr {
1679 write!(f, "EPHEMERAL {e}")
1680 } else {
1681 write!(f, "EPHEMERAL")
1682 }
1683 }
1684 Alias(expr) => write!(f, "ALIAS {expr}"),
1685 Unique {
1686 is_primary,
1687 characteristics,
1688 } => {
1689 write!(f, "{}", if *is_primary { "PRIMARY KEY" } else { "UNIQUE" })?;
1690 if let Some(characteristics) = characteristics {
1691 write!(f, " {}", characteristics)?;
1692 }
1693 Ok(())
1694 }
1695 ForeignKey {
1696 foreign_table,
1697 referred_columns,
1698 on_delete,
1699 on_update,
1700 characteristics,
1701 } => {
1702 write!(f, "REFERENCES {foreign_table}")?;
1703 if !referred_columns.is_empty() {
1704 write!(f, " ({})", display_comma_separated(referred_columns))?;
1705 }
1706 if let Some(action) = on_delete {
1707 write!(f, " ON DELETE {action}")?;
1708 }
1709 if let Some(action) = on_update {
1710 write!(f, " ON UPDATE {action}")?;
1711 }
1712 if let Some(characteristics) = characteristics {
1713 write!(f, " {}", characteristics)?;
1714 }
1715 Ok(())
1716 }
1717 Check(expr) => write!(f, "CHECK ({expr})"),
1718 DialectSpecific(val) => write!(f, "{}", display_separated(val, " ")),
1719 CharacterSet(n) => write!(f, "CHARACTER SET {n}"),
1720 Collation(n) => write!(f, "COLLATE {n}"),
1721 Comment(v) => write!(f, "COMMENT '{}'", escape_single_quote_string(v)),
1722 OnUpdate(expr) => write!(f, "ON UPDATE {expr}"),
1723 Generated {
1724 generated_as,
1725 sequence_options,
1726 generation_expr,
1727 generation_expr_mode,
1728 generated_keyword,
1729 } => {
1730 if let Some(expr) = generation_expr {
1731 let modifier = match generation_expr_mode {
1732 None => "",
1733 Some(GeneratedExpressionMode::Virtual) => " VIRTUAL",
1734 Some(GeneratedExpressionMode::Stored) => " STORED",
1735 };
1736 if *generated_keyword {
1737 write!(f, "GENERATED ALWAYS AS ({expr}){modifier}")?;
1738 } else {
1739 write!(f, "AS ({expr}){modifier}")?;
1740 }
1741 Ok(())
1742 } else {
1743 let when = match generated_as {
1745 GeneratedAs::Always => "ALWAYS",
1746 GeneratedAs::ByDefault => "BY DEFAULT",
1747 GeneratedAs::ExpStored => unreachable!(),
1749 };
1750 write!(f, "GENERATED {when} AS IDENTITY")?;
1751 if sequence_options.is_some() {
1752 let so = sequence_options.as_ref().unwrap();
1753 if !so.is_empty() {
1754 write!(f, " (")?;
1755 }
1756 for sequence_option in so {
1757 write!(f, "{sequence_option}")?;
1758 }
1759 if !so.is_empty() {
1760 write!(f, " )")?;
1761 }
1762 }
1763 Ok(())
1764 }
1765 }
1766 Options(options) => {
1767 write!(f, "OPTIONS({})", display_comma_separated(options))
1768 }
1769 Identity(parameters) => {
1770 write!(f, "{parameters}")
1771 }
1772 OnConflict(keyword) => {
1773 write!(f, "ON CONFLICT {:?}", keyword)?;
1774 Ok(())
1775 }
1776 Policy(parameters) => {
1777 write!(f, "{parameters}")
1778 }
1779 Tags(tags) => {
1780 write!(f, "{tags}")
1781 }
1782 }
1783 }
1784}
1785
1786#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1789#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1790#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1791pub enum GeneratedAs {
1792 Always,
1793 ByDefault,
1794 ExpStored,
1795}
1796
1797#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1800#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1801#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1802pub enum GeneratedExpressionMode {
1803 Virtual,
1804 Stored,
1805}
1806
1807#[must_use]
1808fn display_constraint_name(name: &'_ Option<Ident>) -> impl fmt::Display + '_ {
1809 struct ConstraintName<'a>(&'a Option<Ident>);
1810 impl fmt::Display for ConstraintName<'_> {
1811 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1812 if let Some(name) = self.0 {
1813 write!(f, "CONSTRAINT {name} ")?;
1814 }
1815 Ok(())
1816 }
1817 }
1818 ConstraintName(name)
1819}
1820
1821#[must_use]
1825fn display_option<'a, T: fmt::Display>(
1826 prefix: &'a str,
1827 postfix: &'a str,
1828 option: &'a Option<T>,
1829) -> impl fmt::Display + 'a {
1830 struct OptionDisplay<'a, T>(&'a str, &'a str, &'a Option<T>);
1831 impl<T: fmt::Display> fmt::Display for OptionDisplay<'_, T> {
1832 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1833 if let Some(inner) = self.2 {
1834 let (prefix, postfix) = (self.0, self.1);
1835 write!(f, "{prefix}{inner}{postfix}")?;
1836 }
1837 Ok(())
1838 }
1839 }
1840 OptionDisplay(prefix, postfix, option)
1841}
1842
1843#[must_use]
1847fn display_option_spaced<T: fmt::Display>(option: &Option<T>) -> impl fmt::Display + '_ {
1848 display_option(" ", "", option)
1849}
1850
1851#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Default, Eq, Ord, Hash)]
1855#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1856#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1857pub struct ConstraintCharacteristics {
1858 pub deferrable: Option<bool>,
1860 pub initially: Option<DeferrableInitial>,
1862 pub enforced: Option<bool>,
1864}
1865
1866#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1867#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1868#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1869pub enum DeferrableInitial {
1870 Immediate,
1872 Deferred,
1874}
1875
1876impl ConstraintCharacteristics {
1877 fn deferrable_text(&self) -> Option<&'static str> {
1878 self.deferrable.map(|deferrable| {
1879 if deferrable {
1880 "DEFERRABLE"
1881 } else {
1882 "NOT DEFERRABLE"
1883 }
1884 })
1885 }
1886
1887 fn initially_immediate_text(&self) -> Option<&'static str> {
1888 self.initially
1889 .map(|initially_immediate| match initially_immediate {
1890 DeferrableInitial::Immediate => "INITIALLY IMMEDIATE",
1891 DeferrableInitial::Deferred => "INITIALLY DEFERRED",
1892 })
1893 }
1894
1895 fn enforced_text(&self) -> Option<&'static str> {
1896 self.enforced.map(
1897 |enforced| {
1898 if enforced {
1899 "ENFORCED"
1900 } else {
1901 "NOT ENFORCED"
1902 }
1903 },
1904 )
1905 }
1906}
1907
1908impl fmt::Display for ConstraintCharacteristics {
1909 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1910 let deferrable = self.deferrable_text();
1911 let initially_immediate = self.initially_immediate_text();
1912 let enforced = self.enforced_text();
1913
1914 match (deferrable, initially_immediate, enforced) {
1915 (None, None, None) => Ok(()),
1916 (None, None, Some(enforced)) => write!(f, "{enforced}"),
1917 (None, Some(initial), None) => write!(f, "{initial}"),
1918 (None, Some(initial), Some(enforced)) => write!(f, "{initial} {enforced}"),
1919 (Some(deferrable), None, None) => write!(f, "{deferrable}"),
1920 (Some(deferrable), None, Some(enforced)) => write!(f, "{deferrable} {enforced}"),
1921 (Some(deferrable), Some(initial), None) => write!(f, "{deferrable} {initial}"),
1922 (Some(deferrable), Some(initial), Some(enforced)) => {
1923 write!(f, "{deferrable} {initial} {enforced}")
1924 }
1925 }
1926 }
1927}
1928
1929#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1934#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1935#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1936pub enum ReferentialAction {
1937 Restrict,
1938 Cascade,
1939 SetNull,
1940 NoAction,
1941 SetDefault,
1942}
1943
1944impl fmt::Display for ReferentialAction {
1945 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1946 f.write_str(match self {
1947 ReferentialAction::Restrict => "RESTRICT",
1948 ReferentialAction::Cascade => "CASCADE",
1949 ReferentialAction::SetNull => "SET NULL",
1950 ReferentialAction::NoAction => "NO ACTION",
1951 ReferentialAction::SetDefault => "SET DEFAULT",
1952 })
1953 }
1954}
1955
1956#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1960#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1961#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1962pub enum DropBehavior {
1963 Restrict,
1964 Cascade,
1965}
1966
1967impl fmt::Display for DropBehavior {
1968 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1969 f.write_str(match self {
1970 DropBehavior::Restrict => "RESTRICT",
1971 DropBehavior::Cascade => "CASCADE",
1972 })
1973 }
1974}
1975
1976#[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 UserDefinedTypeRepresentation {
1981 Composite {
1982 attributes: Vec<UserDefinedTypeCompositeAttributeDef>,
1983 },
1984 Enum { labels: Vec<Ident> },
1986}
1987
1988impl fmt::Display for UserDefinedTypeRepresentation {
1989 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1990 match self {
1991 UserDefinedTypeRepresentation::Composite { attributes } => {
1992 write!(f, "({})", display_comma_separated(attributes))
1993 }
1994 UserDefinedTypeRepresentation::Enum { labels } => {
1995 write!(f, "ENUM ({})", display_comma_separated(labels))
1996 }
1997 }
1998 }
1999}
2000
2001#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2003#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2004#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2005pub struct UserDefinedTypeCompositeAttributeDef {
2006 pub name: Ident,
2007 pub data_type: DataType,
2008 pub collation: Option<ObjectName>,
2009}
2010
2011impl fmt::Display for UserDefinedTypeCompositeAttributeDef {
2012 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2013 write!(f, "{} {}", self.name, self.data_type)?;
2014 if let Some(collation) = &self.collation {
2015 write!(f, " COLLATE {collation}")?;
2016 }
2017 Ok(())
2018 }
2019}
2020
2021#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
2025#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2026#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2027pub enum Partition {
2028 Identifier(Ident),
2029 Expr(Expr),
2030 Part(Expr),
2033 Partitions(Vec<Expr>),
2034}
2035
2036impl fmt::Display for Partition {
2037 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2038 match self {
2039 Partition::Identifier(id) => write!(f, "PARTITION ID {id}"),
2040 Partition::Expr(expr) => write!(f, "PARTITION {expr}"),
2041 Partition::Part(expr) => write!(f, "PART {expr}"),
2042 Partition::Partitions(partitions) => {
2043 write!(f, "PARTITION ({})", display_comma_separated(partitions))
2044 }
2045 }
2046 }
2047}
2048
2049#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2052#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2053#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2054pub enum Deduplicate {
2055 All,
2056 ByExpression(Expr),
2057}
2058
2059impl fmt::Display for Deduplicate {
2060 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2061 match self {
2062 Deduplicate::All => write!(f, "DEDUPLICATE"),
2063 Deduplicate::ByExpression(expr) => write!(f, "DEDUPLICATE BY {expr}"),
2064 }
2065 }
2066}
2067
2068#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2073#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2074#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2075pub struct ClusteredBy {
2076 pub columns: Vec<Ident>,
2077 pub sorted_by: Option<Vec<OrderByExpr>>,
2078 pub num_buckets: Value,
2079}
2080
2081impl fmt::Display for ClusteredBy {
2082 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2083 write!(
2084 f,
2085 "CLUSTERED BY ({})",
2086 display_comma_separated(&self.columns)
2087 )?;
2088 if let Some(ref sorted_by) = self.sorted_by {
2089 write!(f, " SORTED BY ({})", display_comma_separated(sorted_by))?;
2090 }
2091 write!(f, " INTO {} BUCKETS", self.num_buckets)
2092 }
2093}
2094
2095#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2096#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2097#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2098pub struct CreateFunction {
2099 pub or_replace: bool,
2100 pub temporary: bool,
2101 pub if_not_exists: bool,
2102 pub name: ObjectName,
2103 pub args: Option<Vec<OperateFunctionArg>>,
2104 pub return_type: Option<DataType>,
2105 pub function_body: Option<CreateFunctionBody>,
2113 pub behavior: Option<FunctionBehavior>,
2119 pub called_on_null: Option<FunctionCalledOnNull>,
2123 pub parallel: Option<FunctionParallel>,
2127 pub using: Option<CreateFunctionUsing>,
2129 pub language: Option<Ident>,
2137 pub determinism_specifier: Option<FunctionDeterminismSpecifier>,
2141 pub options: Option<Vec<SqlOption>>,
2145 pub remote_connection: Option<ObjectName>,
2155}
2156
2157impl fmt::Display for CreateFunction {
2158 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2159 write!(
2160 f,
2161 "CREATE {or_replace}{temp}FUNCTION {if_not_exists}{name}",
2162 name = self.name,
2163 temp = if self.temporary { "TEMPORARY " } else { "" },
2164 or_replace = if self.or_replace { "OR REPLACE " } else { "" },
2165 if_not_exists = if self.if_not_exists {
2166 "IF NOT EXISTS "
2167 } else {
2168 ""
2169 },
2170 )?;
2171 if let Some(args) = &self.args {
2172 write!(f, "({})", display_comma_separated(args))?;
2173 }
2174 if let Some(return_type) = &self.return_type {
2175 write!(f, " RETURNS {return_type}")?;
2176 }
2177 if let Some(determinism_specifier) = &self.determinism_specifier {
2178 write!(f, " {determinism_specifier}")?;
2179 }
2180 if let Some(language) = &self.language {
2181 write!(f, " LANGUAGE {language}")?;
2182 }
2183 if let Some(behavior) = &self.behavior {
2184 write!(f, " {behavior}")?;
2185 }
2186 if let Some(called_on_null) = &self.called_on_null {
2187 write!(f, " {called_on_null}")?;
2188 }
2189 if let Some(parallel) = &self.parallel {
2190 write!(f, " {parallel}")?;
2191 }
2192 if let Some(remote_connection) = &self.remote_connection {
2193 write!(f, " REMOTE WITH CONNECTION {remote_connection}")?;
2194 }
2195 if let Some(CreateFunctionBody::AsBeforeOptions(function_body)) = &self.function_body {
2196 write!(f, " AS {function_body}")?;
2197 }
2198 if let Some(CreateFunctionBody::Return(function_body)) = &self.function_body {
2199 write!(f, " RETURN {function_body}")?;
2200 }
2201 if let Some(using) = &self.using {
2202 write!(f, " {using}")?;
2203 }
2204 if let Some(options) = &self.options {
2205 write!(
2206 f,
2207 " OPTIONS({})",
2208 display_comma_separated(options.as_slice())
2209 )?;
2210 }
2211 if let Some(CreateFunctionBody::AsAfterOptions(function_body)) = &self.function_body {
2212 write!(f, " AS {function_body}")?;
2213 }
2214 Ok(())
2215 }
2216}
2217
2218#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2228#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2229#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2230pub struct CreateConnector {
2231 pub name: Ident,
2232 pub if_not_exists: bool,
2233 pub connector_type: Option<String>,
2234 pub url: Option<String>,
2235 pub comment: Option<CommentDef>,
2236 pub with_dcproperties: Option<Vec<SqlOption>>,
2237}
2238
2239impl fmt::Display for CreateConnector {
2240 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2241 write!(
2242 f,
2243 "CREATE CONNECTOR {if_not_exists}{name}",
2244 if_not_exists = if self.if_not_exists {
2245 "IF NOT EXISTS "
2246 } else {
2247 ""
2248 },
2249 name = self.name,
2250 )?;
2251
2252 if let Some(connector_type) = &self.connector_type {
2253 write!(f, " TYPE '{connector_type}'")?;
2254 }
2255
2256 if let Some(url) = &self.url {
2257 write!(f, " URL '{url}'")?;
2258 }
2259
2260 if let Some(comment) = &self.comment {
2261 write!(f, " COMMENT = '{comment}'")?;
2262 }
2263
2264 if let Some(with_dcproperties) = &self.with_dcproperties {
2265 write!(
2266 f,
2267 " WITH DCPROPERTIES({})",
2268 display_comma_separated(with_dcproperties)
2269 )?;
2270 }
2271
2272 Ok(())
2273 }
2274}