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 sqltk_parser_derive::{Visit, VisitMut};
30
31use crate::ast::value::escape_single_quote_string;
32use crate::ast::{
33 display_comma_separated, display_separated, CreateFunctionBody, CreateFunctionUsing, DataType,
34 Expr, FunctionBehavior, FunctionCalledOnNull, FunctionDeterminismSpecifier, FunctionParallel,
35 Ident, MySQLColumnPosition, ObjectName, OperateFunctionArg, OrderByExpr, ProjectionSelect,
36 SequenceOptions, SqlOption, Tag, Value,
37};
38use crate::keywords::Keyword;
39use crate::tokenizer::Token;
40
41#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
43#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
44#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
45pub enum AlterTableOperation {
46 AddConstraint(TableConstraint),
48 AddColumn {
50 column_keyword: bool,
52 if_not_exists: bool,
54 column_def: ColumnDef,
56 column_position: Option<MySQLColumnPosition>,
58 },
59 AddProjection {
64 if_not_exists: bool,
65 name: Ident,
66 select: ProjectionSelect,
67 },
68
69 DropProjection {
74 if_exists: bool,
75 name: Ident,
76 },
77
78 MaterializeProjection {
83 if_exists: bool,
84 name: Ident,
85 partition: Option<Ident>,
86 },
87
88 ClearProjection {
93 if_exists: bool,
94 name: Ident,
95 partition: Option<Ident>,
96 },
97
98 DisableRowLevelSecurity,
102 DisableRule {
106 name: Ident,
107 },
108 DisableTrigger {
112 name: Ident,
113 },
114 DropConstraint {
116 if_exists: bool,
117 name: Ident,
118 cascade: bool,
119 },
120 DropColumn {
122 column_name: Ident,
123 if_exists: bool,
124 cascade: bool,
125 },
126 AttachPartition {
130 partition: Partition,
133 },
134 DetachPartition {
138 partition: Partition,
140 },
141 FreezePartition {
145 partition: Partition,
146 with_name: Option<Ident>,
147 },
148 UnfreezePartition {
152 partition: Partition,
153 with_name: Option<Ident>,
154 },
155 DropPrimaryKey,
159 EnableAlwaysRule {
163 name: Ident,
164 },
165 EnableAlwaysTrigger {
169 name: Ident,
170 },
171 EnableReplicaRule {
175 name: Ident,
176 },
177 EnableReplicaTrigger {
181 name: Ident,
182 },
183 EnableRowLevelSecurity,
187 EnableRule {
191 name: Ident,
192 },
193 EnableTrigger {
197 name: Ident,
198 },
199 RenamePartitions {
201 old_partitions: Vec<Expr>,
202 new_partitions: Vec<Expr>,
203 },
204 AddPartitions {
206 if_not_exists: bool,
207 new_partitions: Vec<Partition>,
208 },
209 DropPartitions {
210 partitions: Vec<Expr>,
211 if_exists: bool,
212 },
213 RenameColumn {
215 old_column_name: Ident,
216 new_column_name: Ident,
217 },
218 RenameTable {
220 table_name: ObjectName,
221 },
222 ChangeColumn {
224 old_name: Ident,
225 new_name: Ident,
226 data_type: DataType,
227 options: Vec<ColumnOption>,
228 column_position: Option<MySQLColumnPosition>,
230 },
231 ModifyColumn {
233 col_name: Ident,
234 data_type: DataType,
235 options: Vec<ColumnOption>,
236 column_position: Option<MySQLColumnPosition>,
238 },
239 RenameConstraint {
243 old_name: Ident,
244 new_name: Ident,
245 },
246 AlterColumn {
248 column_name: Ident,
249 op: AlterColumnOperation,
250 },
251 SwapWith {
255 table_name: ObjectName,
256 },
257 SetTblProperties {
259 table_properties: Vec<SqlOption>,
260 },
261 OwnerTo {
265 new_owner: Owner,
266 },
267 ClusterBy {
270 exprs: Vec<Expr>,
271 },
272 DropClusteringKey,
273 SuspendRecluster,
274 ResumeRecluster,
275}
276
277#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
281#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
282#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
283pub enum AlterPolicyOperation {
284 Rename {
285 new_name: Ident,
286 },
287 Apply {
288 to: Option<Vec<Owner>>,
289 using: Option<Expr>,
290 with_check: Option<Expr>,
291 },
292}
293
294impl fmt::Display for AlterPolicyOperation {
295 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
296 match self {
297 AlterPolicyOperation::Rename { new_name } => {
298 write!(f, " RENAME TO {new_name}")
299 }
300 AlterPolicyOperation::Apply {
301 to,
302 using,
303 with_check,
304 } => {
305 if let Some(to) = to {
306 write!(f, " TO {}", display_comma_separated(to))?;
307 }
308 if let Some(using) = using {
309 write!(f, " USING ({using})")?;
310 }
311 if let Some(with_check) = with_check {
312 write!(f, " WITH CHECK ({with_check})")?;
313 }
314 Ok(())
315 }
316 }
317 }
318}
319
320#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
321#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
322#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
323pub enum Owner {
324 Ident(Ident),
325 CurrentRole,
326 CurrentUser,
327 SessionUser,
328}
329
330impl fmt::Display for Owner {
331 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
332 match self {
333 Owner::Ident(ident) => write!(f, "{}", ident),
334 Owner::CurrentRole => write!(f, "CURRENT_ROLE"),
335 Owner::CurrentUser => write!(f, "CURRENT_USER"),
336 Owner::SessionUser => write!(f, "SESSION_USER"),
337 }
338 }
339}
340
341#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
342#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
343#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
344pub enum AlterIndexOperation {
345 RenameIndex { index_name: ObjectName },
346}
347
348impl fmt::Display for AlterTableOperation {
349 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
350 match self {
351 AlterTableOperation::AddPartitions {
352 if_not_exists,
353 new_partitions,
354 } => write!(
355 f,
356 "ADD{ine} {}",
357 display_separated(new_partitions, " "),
358 ine = if *if_not_exists { " IF NOT EXISTS" } else { "" }
359 ),
360 AlterTableOperation::AddConstraint(c) => write!(f, "ADD {c}"),
361 AlterTableOperation::AddColumn {
362 column_keyword,
363 if_not_exists,
364 column_def,
365 column_position,
366 } => {
367 write!(f, "ADD")?;
368 if *column_keyword {
369 write!(f, " COLUMN")?;
370 }
371 if *if_not_exists {
372 write!(f, " IF NOT EXISTS")?;
373 }
374 write!(f, " {column_def}")?;
375
376 if let Some(position) = column_position {
377 write!(f, " {position}")?;
378 }
379
380 Ok(())
381 }
382 AlterTableOperation::AddProjection {
383 if_not_exists,
384 name,
385 select: query,
386 } => {
387 write!(f, "ADD PROJECTION")?;
388 if *if_not_exists {
389 write!(f, " IF NOT EXISTS")?;
390 }
391 write!(f, " {} ({})", name, query)
392 }
393 AlterTableOperation::DropProjection { if_exists, name } => {
394 write!(f, "DROP PROJECTION")?;
395 if *if_exists {
396 write!(f, " IF EXISTS")?;
397 }
398 write!(f, " {}", name)
399 }
400 AlterTableOperation::MaterializeProjection {
401 if_exists,
402 name,
403 partition,
404 } => {
405 write!(f, "MATERIALIZE PROJECTION")?;
406 if *if_exists {
407 write!(f, " IF EXISTS")?;
408 }
409 write!(f, " {}", name)?;
410 if let Some(partition) = partition {
411 write!(f, " IN PARTITION {}", partition)?;
412 }
413 Ok(())
414 }
415 AlterTableOperation::ClearProjection {
416 if_exists,
417 name,
418 partition,
419 } => {
420 write!(f, "CLEAR PROJECTION")?;
421 if *if_exists {
422 write!(f, " IF EXISTS")?;
423 }
424 write!(f, " {}", name)?;
425 if let Some(partition) = partition {
426 write!(f, " IN PARTITION {}", partition)?;
427 }
428 Ok(())
429 }
430 AlterTableOperation::AlterColumn { column_name, op } => {
431 write!(f, "ALTER COLUMN {column_name} {op}")
432 }
433 AlterTableOperation::DisableRowLevelSecurity => {
434 write!(f, "DISABLE ROW LEVEL SECURITY")
435 }
436 AlterTableOperation::DisableRule { name } => {
437 write!(f, "DISABLE RULE {name}")
438 }
439 AlterTableOperation::DisableTrigger { name } => {
440 write!(f, "DISABLE TRIGGER {name}")
441 }
442 AlterTableOperation::DropPartitions {
443 partitions,
444 if_exists,
445 } => write!(
446 f,
447 "DROP{ie} PARTITION ({})",
448 display_comma_separated(partitions),
449 ie = if *if_exists { " IF EXISTS" } else { "" }
450 ),
451 AlterTableOperation::DropConstraint {
452 if_exists,
453 name,
454 cascade,
455 } => {
456 write!(
457 f,
458 "DROP CONSTRAINT {}{}{}",
459 if *if_exists { "IF EXISTS " } else { "" },
460 name,
461 if *cascade { " CASCADE" } else { "" },
462 )
463 }
464 AlterTableOperation::DropPrimaryKey => write!(f, "DROP PRIMARY KEY"),
465 AlterTableOperation::DropColumn {
466 column_name,
467 if_exists,
468 cascade,
469 } => write!(
470 f,
471 "DROP COLUMN {}{}{}",
472 if *if_exists { "IF EXISTS " } else { "" },
473 column_name,
474 if *cascade { " CASCADE" } else { "" }
475 ),
476 AlterTableOperation::AttachPartition { partition } => {
477 write!(f, "ATTACH {partition}")
478 }
479 AlterTableOperation::DetachPartition { partition } => {
480 write!(f, "DETACH {partition}")
481 }
482 AlterTableOperation::EnableAlwaysRule { name } => {
483 write!(f, "ENABLE ALWAYS RULE {name}")
484 }
485 AlterTableOperation::EnableAlwaysTrigger { name } => {
486 write!(f, "ENABLE ALWAYS TRIGGER {name}")
487 }
488 AlterTableOperation::EnableReplicaRule { name } => {
489 write!(f, "ENABLE REPLICA RULE {name}")
490 }
491 AlterTableOperation::EnableReplicaTrigger { name } => {
492 write!(f, "ENABLE REPLICA TRIGGER {name}")
493 }
494 AlterTableOperation::EnableRowLevelSecurity => {
495 write!(f, "ENABLE ROW LEVEL SECURITY")
496 }
497 AlterTableOperation::EnableRule { name } => {
498 write!(f, "ENABLE RULE {name}")
499 }
500 AlterTableOperation::EnableTrigger { name } => {
501 write!(f, "ENABLE TRIGGER {name}")
502 }
503 AlterTableOperation::RenamePartitions {
504 old_partitions,
505 new_partitions,
506 } => write!(
507 f,
508 "PARTITION ({}) RENAME TO PARTITION ({})",
509 display_comma_separated(old_partitions),
510 display_comma_separated(new_partitions)
511 ),
512 AlterTableOperation::RenameColumn {
513 old_column_name,
514 new_column_name,
515 } => write!(f, "RENAME COLUMN {old_column_name} TO {new_column_name}"),
516 AlterTableOperation::RenameTable { table_name } => {
517 write!(f, "RENAME TO {table_name}")
518 }
519 AlterTableOperation::ChangeColumn {
520 old_name,
521 new_name,
522 data_type,
523 options,
524 column_position,
525 } => {
526 write!(f, "CHANGE COLUMN {old_name} {new_name} {data_type}")?;
527 if !options.is_empty() {
528 write!(f, " {}", display_separated(options, " "))?;
529 }
530 if let Some(position) = column_position {
531 write!(f, " {position}")?;
532 }
533
534 Ok(())
535 }
536 AlterTableOperation::ModifyColumn {
537 col_name,
538 data_type,
539 options,
540 column_position,
541 } => {
542 write!(f, "MODIFY COLUMN {col_name} {data_type}")?;
543 if !options.is_empty() {
544 write!(f, " {}", display_separated(options, " "))?;
545 }
546 if let Some(position) = column_position {
547 write!(f, " {position}")?;
548 }
549
550 Ok(())
551 }
552 AlterTableOperation::RenameConstraint { old_name, new_name } => {
553 write!(f, "RENAME CONSTRAINT {old_name} TO {new_name}")
554 }
555 AlterTableOperation::SwapWith { table_name } => {
556 write!(f, "SWAP WITH {table_name}")
557 }
558 AlterTableOperation::OwnerTo { new_owner } => {
559 write!(f, "OWNER TO {new_owner}")
560 }
561 AlterTableOperation::SetTblProperties { table_properties } => {
562 write!(
563 f,
564 "SET TBLPROPERTIES({})",
565 display_comma_separated(table_properties)
566 )
567 }
568 AlterTableOperation::FreezePartition {
569 partition,
570 with_name,
571 } => {
572 write!(f, "FREEZE {partition}")?;
573 if let Some(name) = with_name {
574 write!(f, " WITH NAME {name}")?;
575 }
576 Ok(())
577 }
578 AlterTableOperation::UnfreezePartition {
579 partition,
580 with_name,
581 } => {
582 write!(f, "UNFREEZE {partition}")?;
583 if let Some(name) = with_name {
584 write!(f, " WITH NAME {name}")?;
585 }
586 Ok(())
587 }
588 AlterTableOperation::ClusterBy { exprs } => {
589 write!(f, "CLUSTER BY ({})", display_comma_separated(exprs))?;
590 Ok(())
591 }
592 AlterTableOperation::DropClusteringKey => {
593 write!(f, "DROP CLUSTERING KEY")?;
594 Ok(())
595 }
596 AlterTableOperation::SuspendRecluster => {
597 write!(f, "SUSPEND RECLUSTER")?;
598 Ok(())
599 }
600 AlterTableOperation::ResumeRecluster => {
601 write!(f, "RESUME RECLUSTER")?;
602 Ok(())
603 }
604 }
605 }
606}
607
608impl fmt::Display for AlterIndexOperation {
609 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
610 match self {
611 AlterIndexOperation::RenameIndex { index_name } => {
612 write!(f, "RENAME TO {index_name}")
613 }
614 }
615 }
616}
617
618#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
620#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
621#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
622pub enum AlterColumnOperation {
623 SetNotNull,
625 DropNotNull,
627 SetDefault { value: Expr },
629 DropDefault,
631 SetDataType {
633 data_type: DataType,
634 using: Option<Expr>,
636 },
637 AddGenerated {
641 generated_as: Option<GeneratedAs>,
642 sequence_options: Option<Vec<SequenceOptions>>,
643 },
644}
645
646impl fmt::Display for AlterColumnOperation {
647 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
648 match self {
649 AlterColumnOperation::SetNotNull => write!(f, "SET NOT NULL",),
650 AlterColumnOperation::DropNotNull => write!(f, "DROP NOT NULL",),
651 AlterColumnOperation::SetDefault { value } => {
652 write!(f, "SET DEFAULT {value}")
653 }
654 AlterColumnOperation::DropDefault {} => {
655 write!(f, "DROP DEFAULT")
656 }
657 AlterColumnOperation::SetDataType { data_type, using } => {
658 if let Some(expr) = using {
659 write!(f, "SET DATA TYPE {data_type} USING {expr}")
660 } else {
661 write!(f, "SET DATA TYPE {data_type}")
662 }
663 }
664 AlterColumnOperation::AddGenerated {
665 generated_as,
666 sequence_options,
667 } => {
668 let generated_as = match generated_as {
669 Some(GeneratedAs::Always) => " ALWAYS",
670 Some(GeneratedAs::ByDefault) => " BY DEFAULT",
671 _ => "",
672 };
673
674 write!(f, "ADD GENERATED{generated_as} AS IDENTITY",)?;
675 if let Some(options) = sequence_options {
676 write!(f, " (")?;
677
678 for sequence_option in options {
679 write!(f, "{sequence_option}")?;
680 }
681
682 write!(f, " )")?;
683 }
684 Ok(())
685 }
686 }
687 }
688}
689
690#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
693#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
694#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
695pub enum TableConstraint {
696 Unique {
709 name: Option<Ident>,
713 index_name: Option<Ident>,
715 index_type_display: KeyOrIndexDisplay,
717 index_type: Option<IndexType>,
721 columns: Vec<Ident>,
723 index_options: Vec<IndexOption>,
724 characteristics: Option<ConstraintCharacteristics>,
725 nulls_distinct: NullsDistinctOption,
727 },
728 PrimaryKey {
747 name: Option<Ident>,
751 index_name: Option<Ident>,
753 index_type: Option<IndexType>,
757 columns: Vec<Ident>,
759 index_options: Vec<IndexOption>,
760 characteristics: Option<ConstraintCharacteristics>,
761 },
762 ForeignKey {
768 name: Option<Ident>,
769 columns: Vec<Ident>,
770 foreign_table: ObjectName,
771 referred_columns: Vec<Ident>,
772 on_delete: Option<ReferentialAction>,
773 on_update: Option<ReferentialAction>,
774 characteristics: Option<ConstraintCharacteristics>,
775 },
776 Check {
778 name: Option<Ident>,
779 expr: Box<Expr>,
780 },
781 Index {
788 display_as_key: bool,
790 name: Option<Ident>,
792 index_type: Option<IndexType>,
796 columns: Vec<Ident>,
798 },
799 FulltextOrSpatial {
813 fulltext: bool,
815 index_type_display: KeyOrIndexDisplay,
817 opt_index_name: Option<Ident>,
819 columns: Vec<Ident>,
821 },
822}
823
824impl fmt::Display for TableConstraint {
825 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
826 match self {
827 TableConstraint::Unique {
828 name,
829 index_name,
830 index_type_display,
831 index_type,
832 columns,
833 index_options,
834 characteristics,
835 nulls_distinct,
836 } => {
837 write!(
838 f,
839 "{}UNIQUE{nulls_distinct}{index_type_display:>}{}{} ({})",
840 display_constraint_name(name),
841 display_option_spaced(index_name),
842 display_option(" USING ", "", index_type),
843 display_comma_separated(columns),
844 )?;
845
846 if !index_options.is_empty() {
847 write!(f, " {}", display_separated(index_options, " "))?;
848 }
849
850 write!(f, "{}", display_option_spaced(characteristics))?;
851 Ok(())
852 }
853 TableConstraint::PrimaryKey {
854 name,
855 index_name,
856 index_type,
857 columns,
858 index_options,
859 characteristics,
860 } => {
861 write!(
862 f,
863 "{}PRIMARY KEY{}{} ({})",
864 display_constraint_name(name),
865 display_option_spaced(index_name),
866 display_option(" USING ", "", index_type),
867 display_comma_separated(columns),
868 )?;
869
870 if !index_options.is_empty() {
871 write!(f, " {}", display_separated(index_options, " "))?;
872 }
873
874 write!(f, "{}", display_option_spaced(characteristics))?;
875 Ok(())
876 }
877 TableConstraint::ForeignKey {
878 name,
879 columns,
880 foreign_table,
881 referred_columns,
882 on_delete,
883 on_update,
884 characteristics,
885 } => {
886 write!(
887 f,
888 "{}FOREIGN KEY ({}) REFERENCES {}({})",
889 display_constraint_name(name),
890 display_comma_separated(columns),
891 foreign_table,
892 display_comma_separated(referred_columns),
893 )?;
894 if let Some(action) = on_delete {
895 write!(f, " ON DELETE {action}")?;
896 }
897 if let Some(action) = on_update {
898 write!(f, " ON UPDATE {action}")?;
899 }
900 if let Some(characteristics) = characteristics {
901 write!(f, " {}", characteristics)?;
902 }
903 Ok(())
904 }
905 TableConstraint::Check { name, expr } => {
906 write!(f, "{}CHECK ({})", display_constraint_name(name), expr)
907 }
908 TableConstraint::Index {
909 display_as_key,
910 name,
911 index_type,
912 columns,
913 } => {
914 write!(f, "{}", if *display_as_key { "KEY" } else { "INDEX" })?;
915 if let Some(name) = name {
916 write!(f, " {name}")?;
917 }
918 if let Some(index_type) = index_type {
919 write!(f, " USING {index_type}")?;
920 }
921 write!(f, " ({})", display_comma_separated(columns))?;
922
923 Ok(())
924 }
925 Self::FulltextOrSpatial {
926 fulltext,
927 index_type_display,
928 opt_index_name,
929 columns,
930 } => {
931 if *fulltext {
932 write!(f, "FULLTEXT")?;
933 } else {
934 write!(f, "SPATIAL")?;
935 }
936
937 write!(f, "{index_type_display:>}")?;
938
939 if let Some(name) = opt_index_name {
940 write!(f, " {name}")?;
941 }
942
943 write!(f, " ({})", display_comma_separated(columns))?;
944
945 Ok(())
946 }
947 }
948 }
949}
950
951#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
959#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
960#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
961pub enum KeyOrIndexDisplay {
962 None,
964 Key,
966 Index,
968}
969
970impl KeyOrIndexDisplay {
971 pub fn is_none(self) -> bool {
972 matches!(self, Self::None)
973 }
974}
975
976impl fmt::Display for KeyOrIndexDisplay {
977 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
978 let left_space = matches!(f.align(), Some(fmt::Alignment::Right));
979
980 if left_space && !self.is_none() {
981 f.write_char(' ')?
982 }
983
984 match self {
985 KeyOrIndexDisplay::None => {
986 write!(f, "")
987 }
988 KeyOrIndexDisplay::Key => {
989 write!(f, "KEY")
990 }
991 KeyOrIndexDisplay::Index => {
992 write!(f, "INDEX")
993 }
994 }
995 }
996}
997
998#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1007#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1008#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1009pub enum IndexType {
1010 BTree,
1011 Hash,
1012 }
1014
1015impl fmt::Display for IndexType {
1016 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1017 match self {
1018 Self::BTree => write!(f, "BTREE"),
1019 Self::Hash => write!(f, "HASH"),
1020 }
1021 }
1022}
1023
1024#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1031#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1032#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1033pub enum IndexOption {
1034 Using(IndexType),
1035 Comment(String),
1036}
1037
1038impl fmt::Display for IndexOption {
1039 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1040 match self {
1041 Self::Using(index_type) => write!(f, "USING {index_type}"),
1042 Self::Comment(s) => write!(f, "COMMENT '{s}'"),
1043 }
1044 }
1045}
1046
1047#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1051#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1052#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1053pub enum NullsDistinctOption {
1054 None,
1056 Distinct,
1058 NotDistinct,
1060}
1061
1062impl fmt::Display for NullsDistinctOption {
1063 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1064 match self {
1065 Self::None => Ok(()),
1066 Self::Distinct => write!(f, " NULLS DISTINCT"),
1067 Self::NotDistinct => write!(f, " NULLS NOT DISTINCT"),
1068 }
1069 }
1070}
1071
1072#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1073#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1074#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1075pub struct ProcedureParam {
1076 pub name: Ident,
1077 pub data_type: DataType,
1078}
1079
1080impl fmt::Display for ProcedureParam {
1081 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1082 write!(f, "{} {}", self.name, self.data_type)
1083 }
1084}
1085
1086#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1088#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1089#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1090pub struct ColumnDef {
1091 pub name: Ident,
1092 pub data_type: DataType,
1093 pub collation: Option<ObjectName>,
1094 pub options: Vec<ColumnOptionDef>,
1095}
1096
1097impl fmt::Display for ColumnDef {
1098 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1099 if self.data_type == DataType::Unspecified {
1100 write!(f, "{}", self.name)?;
1101 } else {
1102 write!(f, "{} {}", self.name, self.data_type)?;
1103 }
1104 if let Some(collation) = &self.collation {
1105 write!(f, " COLLATE {collation}")?;
1106 }
1107 for option in &self.options {
1108 write!(f, " {option}")?;
1109 }
1110 Ok(())
1111 }
1112}
1113
1114#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1131#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1132#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1133pub struct ViewColumnDef {
1134 pub name: Ident,
1135 pub data_type: Option<DataType>,
1136 pub options: Option<Vec<ColumnOption>>,
1137}
1138
1139impl fmt::Display for ViewColumnDef {
1140 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1141 write!(f, "{}", self.name)?;
1142 if let Some(data_type) = self.data_type.as_ref() {
1143 write!(f, " {}", data_type)?;
1144 }
1145 if let Some(options) = self.options.as_ref() {
1146 write!(f, " {}", display_comma_separated(options.as_slice()))?;
1147 }
1148 Ok(())
1149 }
1150}
1151
1152#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1169#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1170#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1171pub struct ColumnOptionDef {
1172 pub name: Option<Ident>,
1173 pub option: ColumnOption,
1174}
1175
1176impl fmt::Display for ColumnOptionDef {
1177 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1178 write!(f, "{}{}", display_constraint_name(&self.name), self.option)
1179 }
1180}
1181
1182#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1190#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1191#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1192pub enum IdentityPropertyKind {
1193 Autoincrement(IdentityProperty),
1201 Identity(IdentityProperty),
1214}
1215
1216impl fmt::Display for IdentityPropertyKind {
1217 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1218 let (command, property) = match self {
1219 IdentityPropertyKind::Identity(property) => ("IDENTITY", property),
1220 IdentityPropertyKind::Autoincrement(property) => ("AUTOINCREMENT", property),
1221 };
1222 write!(f, "{command}")?;
1223 if let Some(parameters) = &property.parameters {
1224 write!(f, "{parameters}")?;
1225 }
1226 if let Some(order) = &property.order {
1227 write!(f, "{order}")?;
1228 }
1229 Ok(())
1230 }
1231}
1232
1233#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1234#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1235#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1236pub struct IdentityProperty {
1237 pub parameters: Option<IdentityPropertyFormatKind>,
1238 pub order: Option<IdentityPropertyOrder>,
1239}
1240
1241#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1256#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1257#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1258pub enum IdentityPropertyFormatKind {
1259 FunctionCall(IdentityParameters),
1267 StartAndIncrement(IdentityParameters),
1274}
1275
1276impl fmt::Display for IdentityPropertyFormatKind {
1277 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1278 match self {
1279 IdentityPropertyFormatKind::FunctionCall(parameters) => {
1280 write!(f, "({}, {})", parameters.seed, parameters.increment)
1281 }
1282 IdentityPropertyFormatKind::StartAndIncrement(parameters) => {
1283 write!(
1284 f,
1285 " START {} INCREMENT {}",
1286 parameters.seed, parameters.increment
1287 )
1288 }
1289 }
1290 }
1291}
1292#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1293#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1294#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1295pub struct IdentityParameters {
1296 pub seed: Expr,
1297 pub increment: Expr,
1298}
1299
1300#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1307#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1308#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1309pub enum IdentityPropertyOrder {
1310 Order,
1311 NoOrder,
1312}
1313
1314impl fmt::Display for IdentityPropertyOrder {
1315 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1316 match self {
1317 IdentityPropertyOrder::Order => write!(f, " ORDER"),
1318 IdentityPropertyOrder::NoOrder => write!(f, " NOORDER"),
1319 }
1320 }
1321}
1322
1323#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1331#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1332#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1333pub enum ColumnPolicy {
1334 MaskingPolicy(ColumnPolicyProperty),
1335 ProjectionPolicy(ColumnPolicyProperty),
1336}
1337
1338impl fmt::Display for ColumnPolicy {
1339 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1340 let (command, property) = match self {
1341 ColumnPolicy::MaskingPolicy(property) => ("MASKING POLICY", property),
1342 ColumnPolicy::ProjectionPolicy(property) => ("PROJECTION POLICY", property),
1343 };
1344 if property.with {
1345 write!(f, "WITH ")?;
1346 }
1347 write!(f, "{command} {}", property.policy_name)?;
1348 if let Some(using_columns) = &property.using_columns {
1349 write!(f, " USING ({})", display_comma_separated(using_columns))?;
1350 }
1351 Ok(())
1352 }
1353}
1354
1355#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1356#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1357#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1358pub struct ColumnPolicyProperty {
1359 pub with: bool,
1366 pub policy_name: Ident,
1367 pub using_columns: Option<Vec<Ident>>,
1368}
1369
1370#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1377#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1378#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1379pub struct TagsColumnOption {
1380 pub with: bool,
1387 pub tags: Vec<Tag>,
1388}
1389
1390impl fmt::Display for TagsColumnOption {
1391 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1392 if self.with {
1393 write!(f, "WITH ")?;
1394 }
1395 write!(f, "TAG ({})", display_comma_separated(&self.tags))?;
1396 Ok(())
1397 }
1398}
1399
1400#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1403#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1404#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1405pub enum ColumnOption {
1406 Null,
1408 NotNull,
1410 Default(Expr),
1412
1413 Materialized(Expr),
1418 Ephemeral(Option<Expr>),
1422 Alias(Expr),
1426
1427 Unique {
1429 is_primary: bool,
1430 characteristics: Option<ConstraintCharacteristics>,
1431 },
1432 ForeignKey {
1440 foreign_table: ObjectName,
1441 referred_columns: Vec<Ident>,
1442 on_delete: Option<ReferentialAction>,
1443 on_update: Option<ReferentialAction>,
1444 characteristics: Option<ConstraintCharacteristics>,
1445 },
1446 Check(Expr),
1448 DialectSpecific(Vec<Token>),
1452 CharacterSet(ObjectName),
1453 Comment(String),
1454 OnUpdate(Expr),
1455 Generated {
1458 generated_as: GeneratedAs,
1459 sequence_options: Option<Vec<SequenceOptions>>,
1460 generation_expr: Option<Expr>,
1461 generation_expr_mode: Option<GeneratedExpressionMode>,
1462 generated_keyword: bool,
1464 },
1465 Options(Vec<SqlOption>),
1473 Identity(IdentityPropertyKind),
1481 OnConflict(Keyword),
1484 Policy(ColumnPolicy),
1492 Tags(TagsColumnOption),
1499}
1500
1501impl fmt::Display for ColumnOption {
1502 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1503 use ColumnOption::*;
1504 match self {
1505 Null => write!(f, "NULL"),
1506 NotNull => write!(f, "NOT NULL"),
1507 Default(expr) => write!(f, "DEFAULT {expr}"),
1508 Materialized(expr) => write!(f, "MATERIALIZED {expr}"),
1509 Ephemeral(expr) => {
1510 if let Some(e) = expr {
1511 write!(f, "EPHEMERAL {e}")
1512 } else {
1513 write!(f, "EPHEMERAL")
1514 }
1515 }
1516 Alias(expr) => write!(f, "ALIAS {expr}"),
1517 Unique {
1518 is_primary,
1519 characteristics,
1520 } => {
1521 write!(f, "{}", if *is_primary { "PRIMARY KEY" } else { "UNIQUE" })?;
1522 if let Some(characteristics) = characteristics {
1523 write!(f, " {}", characteristics)?;
1524 }
1525 Ok(())
1526 }
1527 ForeignKey {
1528 foreign_table,
1529 referred_columns,
1530 on_delete,
1531 on_update,
1532 characteristics,
1533 } => {
1534 write!(f, "REFERENCES {foreign_table}")?;
1535 if !referred_columns.is_empty() {
1536 write!(f, " ({})", display_comma_separated(referred_columns))?;
1537 }
1538 if let Some(action) = on_delete {
1539 write!(f, " ON DELETE {action}")?;
1540 }
1541 if let Some(action) = on_update {
1542 write!(f, " ON UPDATE {action}")?;
1543 }
1544 if let Some(characteristics) = characteristics {
1545 write!(f, " {}", characteristics)?;
1546 }
1547 Ok(())
1548 }
1549 Check(expr) => write!(f, "CHECK ({expr})"),
1550 DialectSpecific(val) => write!(f, "{}", display_separated(val, " ")),
1551 CharacterSet(n) => write!(f, "CHARACTER SET {n}"),
1552 Comment(v) => write!(f, "COMMENT '{}'", escape_single_quote_string(v)),
1553 OnUpdate(expr) => write!(f, "ON UPDATE {expr}"),
1554 Generated {
1555 generated_as,
1556 sequence_options,
1557 generation_expr,
1558 generation_expr_mode,
1559 generated_keyword,
1560 } => {
1561 if let Some(expr) = generation_expr {
1562 let modifier = match generation_expr_mode {
1563 None => "",
1564 Some(GeneratedExpressionMode::Virtual) => " VIRTUAL",
1565 Some(GeneratedExpressionMode::Stored) => " STORED",
1566 };
1567 if *generated_keyword {
1568 write!(f, "GENERATED ALWAYS AS ({expr}){modifier}")?;
1569 } else {
1570 write!(f, "AS ({expr}){modifier}")?;
1571 }
1572 Ok(())
1573 } else {
1574 let when = match generated_as {
1576 GeneratedAs::Always => "ALWAYS",
1577 GeneratedAs::ByDefault => "BY DEFAULT",
1578 GeneratedAs::ExpStored => unreachable!(),
1580 };
1581 write!(f, "GENERATED {when} AS IDENTITY")?;
1582 if sequence_options.is_some() {
1583 let so = sequence_options.as_ref().unwrap();
1584 if !so.is_empty() {
1585 write!(f, " (")?;
1586 }
1587 for sequence_option in so {
1588 write!(f, "{sequence_option}")?;
1589 }
1590 if !so.is_empty() {
1591 write!(f, " )")?;
1592 }
1593 }
1594 Ok(())
1595 }
1596 }
1597 Options(options) => {
1598 write!(f, "OPTIONS({})", display_comma_separated(options))
1599 }
1600 Identity(parameters) => {
1601 write!(f, "{parameters}")
1602 }
1603 OnConflict(keyword) => {
1604 write!(f, "ON CONFLICT {:?}", keyword)?;
1605 Ok(())
1606 }
1607 Policy(parameters) => {
1608 write!(f, "{parameters}")
1609 }
1610 Tags(tags) => {
1611 write!(f, "{tags}")
1612 }
1613 }
1614 }
1615}
1616
1617#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1620#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1621#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1622pub enum GeneratedAs {
1623 Always,
1624 ByDefault,
1625 ExpStored,
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 GeneratedExpressionMode {
1634 Virtual,
1635 Stored,
1636}
1637
1638#[must_use]
1639fn display_constraint_name(name: &'_ Option<Ident>) -> impl fmt::Display + '_ {
1640 struct ConstraintName<'a>(&'a Option<Ident>);
1641 impl fmt::Display for ConstraintName<'_> {
1642 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1643 if let Some(name) = self.0 {
1644 write!(f, "CONSTRAINT {name} ")?;
1645 }
1646 Ok(())
1647 }
1648 }
1649 ConstraintName(name)
1650}
1651
1652#[must_use]
1656fn display_option<'a, T: fmt::Display>(
1657 prefix: &'a str,
1658 postfix: &'a str,
1659 option: &'a Option<T>,
1660) -> impl fmt::Display + 'a {
1661 struct OptionDisplay<'a, T>(&'a str, &'a str, &'a Option<T>);
1662 impl<T: fmt::Display> fmt::Display for OptionDisplay<'_, T> {
1663 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1664 if let Some(inner) = self.2 {
1665 let (prefix, postfix) = (self.0, self.1);
1666 write!(f, "{prefix}{inner}{postfix}")?;
1667 }
1668 Ok(())
1669 }
1670 }
1671 OptionDisplay(prefix, postfix, option)
1672}
1673
1674#[must_use]
1678fn display_option_spaced<T: fmt::Display>(option: &Option<T>) -> impl fmt::Display + '_ {
1679 display_option(" ", "", option)
1680}
1681
1682#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Default, Eq, Ord, Hash)]
1686#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1687#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1688pub struct ConstraintCharacteristics {
1689 pub deferrable: Option<bool>,
1691 pub initially: Option<DeferrableInitial>,
1693 pub enforced: Option<bool>,
1695}
1696
1697#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1698#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1699#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1700pub enum DeferrableInitial {
1701 Immediate,
1703 Deferred,
1705}
1706
1707impl ConstraintCharacteristics {
1708 fn deferrable_text(&self) -> Option<&'static str> {
1709 self.deferrable.map(|deferrable| {
1710 if deferrable {
1711 "DEFERRABLE"
1712 } else {
1713 "NOT DEFERRABLE"
1714 }
1715 })
1716 }
1717
1718 fn initially_immediate_text(&self) -> Option<&'static str> {
1719 self.initially
1720 .map(|initially_immediate| match initially_immediate {
1721 DeferrableInitial::Immediate => "INITIALLY IMMEDIATE",
1722 DeferrableInitial::Deferred => "INITIALLY DEFERRED",
1723 })
1724 }
1725
1726 fn enforced_text(&self) -> Option<&'static str> {
1727 self.enforced.map(
1728 |enforced| {
1729 if enforced {
1730 "ENFORCED"
1731 } else {
1732 "NOT ENFORCED"
1733 }
1734 },
1735 )
1736 }
1737}
1738
1739impl fmt::Display for ConstraintCharacteristics {
1740 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1741 let deferrable = self.deferrable_text();
1742 let initially_immediate = self.initially_immediate_text();
1743 let enforced = self.enforced_text();
1744
1745 match (deferrable, initially_immediate, enforced) {
1746 (None, None, None) => Ok(()),
1747 (None, None, Some(enforced)) => write!(f, "{enforced}"),
1748 (None, Some(initial), None) => write!(f, "{initial}"),
1749 (None, Some(initial), Some(enforced)) => write!(f, "{initial} {enforced}"),
1750 (Some(deferrable), None, None) => write!(f, "{deferrable}"),
1751 (Some(deferrable), None, Some(enforced)) => write!(f, "{deferrable} {enforced}"),
1752 (Some(deferrable), Some(initial), None) => write!(f, "{deferrable} {initial}"),
1753 (Some(deferrable), Some(initial), Some(enforced)) => {
1754 write!(f, "{deferrable} {initial} {enforced}")
1755 }
1756 }
1757 }
1758}
1759
1760#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1765#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1766#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1767pub enum ReferentialAction {
1768 Restrict,
1769 Cascade,
1770 SetNull,
1771 NoAction,
1772 SetDefault,
1773}
1774
1775impl fmt::Display for ReferentialAction {
1776 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1777 f.write_str(match self {
1778 ReferentialAction::Restrict => "RESTRICT",
1779 ReferentialAction::Cascade => "CASCADE",
1780 ReferentialAction::SetNull => "SET NULL",
1781 ReferentialAction::NoAction => "NO ACTION",
1782 ReferentialAction::SetDefault => "SET DEFAULT",
1783 })
1784 }
1785}
1786
1787#[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 UserDefinedTypeRepresentation {
1792 Composite {
1793 attributes: Vec<UserDefinedTypeCompositeAttributeDef>,
1794 },
1795 Enum { labels: Vec<Ident> },
1797}
1798
1799impl fmt::Display for UserDefinedTypeRepresentation {
1800 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1801 match self {
1802 UserDefinedTypeRepresentation::Composite { attributes } => {
1803 write!(f, "({})", display_comma_separated(attributes))
1804 }
1805 UserDefinedTypeRepresentation::Enum { labels } => {
1806 write!(f, "ENUM ({})", display_comma_separated(labels))
1807 }
1808 }
1809 }
1810}
1811
1812#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1814#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1815#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1816pub struct UserDefinedTypeCompositeAttributeDef {
1817 pub name: Ident,
1818 pub data_type: DataType,
1819 pub collation: Option<ObjectName>,
1820}
1821
1822impl fmt::Display for UserDefinedTypeCompositeAttributeDef {
1823 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1824 write!(f, "{} {}", self.name, self.data_type)?;
1825 if let Some(collation) = &self.collation {
1826 write!(f, " COLLATE {collation}")?;
1827 }
1828 Ok(())
1829 }
1830}
1831
1832#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
1836#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1837#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1838pub enum Partition {
1839 Identifier(Ident),
1840 Expr(Expr),
1841 Part(Expr),
1844 Partitions(Vec<Expr>),
1845}
1846
1847impl fmt::Display for Partition {
1848 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1849 match self {
1850 Partition::Identifier(id) => write!(f, "PARTITION ID {id}"),
1851 Partition::Expr(expr) => write!(f, "PARTITION {expr}"),
1852 Partition::Part(expr) => write!(f, "PART {expr}"),
1853 Partition::Partitions(partitions) => {
1854 write!(f, "PARTITION ({})", display_comma_separated(partitions))
1855 }
1856 }
1857 }
1858}
1859
1860#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1863#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1864#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1865pub enum Deduplicate {
1866 All,
1867 ByExpression(Expr),
1868}
1869
1870impl fmt::Display for Deduplicate {
1871 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1872 match self {
1873 Deduplicate::All => write!(f, "DEDUPLICATE"),
1874 Deduplicate::ByExpression(expr) => write!(f, "DEDUPLICATE BY {expr}"),
1875 }
1876 }
1877}
1878
1879#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1884#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1885#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1886pub struct ClusteredBy {
1887 pub columns: Vec<Ident>,
1888 pub sorted_by: Option<Vec<OrderByExpr>>,
1889 pub num_buckets: Value,
1890}
1891
1892impl fmt::Display for ClusteredBy {
1893 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1894 write!(
1895 f,
1896 "CLUSTERED BY ({})",
1897 display_comma_separated(&self.columns)
1898 )?;
1899 if let Some(ref sorted_by) = self.sorted_by {
1900 write!(f, " SORTED BY ({})", display_comma_separated(sorted_by))?;
1901 }
1902 write!(f, " INTO {} BUCKETS", self.num_buckets)
1903 }
1904}
1905
1906#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1907#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1908#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1909pub struct CreateFunction {
1910 pub or_replace: bool,
1911 pub temporary: bool,
1912 pub if_not_exists: bool,
1913 pub name: ObjectName,
1914 pub args: Option<Vec<OperateFunctionArg>>,
1915 pub return_type: Option<DataType>,
1916 pub function_body: Option<CreateFunctionBody>,
1924 pub behavior: Option<FunctionBehavior>,
1930 pub called_on_null: Option<FunctionCalledOnNull>,
1934 pub parallel: Option<FunctionParallel>,
1938 pub using: Option<CreateFunctionUsing>,
1940 pub language: Option<Ident>,
1948 pub determinism_specifier: Option<FunctionDeterminismSpecifier>,
1952 pub options: Option<Vec<SqlOption>>,
1956 pub remote_connection: Option<ObjectName>,
1966}
1967
1968impl fmt::Display for CreateFunction {
1969 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1970 write!(
1971 f,
1972 "CREATE {or_replace}{temp}FUNCTION {if_not_exists}{name}",
1973 name = self.name,
1974 temp = if self.temporary { "TEMPORARY " } else { "" },
1975 or_replace = if self.or_replace { "OR REPLACE " } else { "" },
1976 if_not_exists = if self.if_not_exists {
1977 "IF NOT EXISTS "
1978 } else {
1979 ""
1980 },
1981 )?;
1982 if let Some(args) = &self.args {
1983 write!(f, "({})", display_comma_separated(args))?;
1984 }
1985 if let Some(return_type) = &self.return_type {
1986 write!(f, " RETURNS {return_type}")?;
1987 }
1988 if let Some(determinism_specifier) = &self.determinism_specifier {
1989 write!(f, " {determinism_specifier}")?;
1990 }
1991 if let Some(language) = &self.language {
1992 write!(f, " LANGUAGE {language}")?;
1993 }
1994 if let Some(behavior) = &self.behavior {
1995 write!(f, " {behavior}")?;
1996 }
1997 if let Some(called_on_null) = &self.called_on_null {
1998 write!(f, " {called_on_null}")?;
1999 }
2000 if let Some(parallel) = &self.parallel {
2001 write!(f, " {parallel}")?;
2002 }
2003 if let Some(remote_connection) = &self.remote_connection {
2004 write!(f, " REMOTE WITH CONNECTION {remote_connection}")?;
2005 }
2006 if let Some(CreateFunctionBody::AsBeforeOptions(function_body)) = &self.function_body {
2007 write!(f, " AS {function_body}")?;
2008 }
2009 if let Some(CreateFunctionBody::Return(function_body)) = &self.function_body {
2010 write!(f, " RETURN {function_body}")?;
2011 }
2012 if let Some(using) = &self.using {
2013 write!(f, " {using}")?;
2014 }
2015 if let Some(options) = &self.options {
2016 write!(
2017 f,
2018 " OPTIONS({})",
2019 display_comma_separated(options.as_slice())
2020 )?;
2021 }
2022 if let Some(CreateFunctionBody::AsAfterOptions(function_body)) = &self.function_body {
2023 write!(f, " AS {function_body}")?;
2024 }
2025 Ok(())
2026 }
2027}