@@ -37,8 +37,8 @@ use crate::ast::{
3737 HiveDistributionStyle , HiveFormat , HiveIOFormat , HiveRowFormat , HiveSetLocation , Ident ,
3838 InitializeKind , MySQLColumnPosition , ObjectName , OnCommit , OneOrManyWithParens ,
3939 OperateFunctionArg , OrderByExpr , ProjectionSelect , Query , RefreshModeKind , RowAccessPolicy ,
40- SequenceOptions , Spanned , SqlOption , StorageSerializationPolicy , TableVersion , Tag ,
41- TriggerEvent , TriggerExecBody , TriggerObject , TriggerPeriod , TriggerReferencing , Value ,
40+ SequenceOptions , Spanned , SqlOption , StorageSerializationPolicy , TableConstraint , TableVersion ,
41+ Tag , TriggerEvent , TriggerExecBody , TriggerObject , TriggerPeriod , TriggerReferencing , Value ,
4242 ValueWithSpan , WrappedCollection ,
4343} ;
4444use crate :: display_utils:: { DisplayCommaSeparated , Indent , NewLine , SpaceOrNewline } ;
@@ -1030,291 +1030,6 @@ impl fmt::Display for AlterColumnOperation {
10301030 }
10311031}
10321032
1033- /// A table-level constraint, specified in a `CREATE TABLE` or an
1034- /// `ALTER TABLE ADD <constraint>` statement.
1035- #[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
1036- #[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
1037- #[ cfg_attr( feature = "visitor" , derive( Visit , VisitMut ) ) ]
1038- pub enum TableConstraint {
1039- /// MySQL [definition][1] for `UNIQUE` constraints statements:\
1040- /// * `[CONSTRAINT [<name>]] UNIQUE <index_type_display> [<index_name>] [index_type] (<columns>) <index_options>`
1041- ///
1042- /// where:
1043- /// * [index_type][2] is `USING {BTREE | HASH}`
1044- /// * [index_options][3] is `{index_type | COMMENT 'string' | ... %currently unsupported stmts% } ...`
1045- /// * [index_type_display][4] is `[INDEX | KEY]`
1046- ///
1047- /// [1]: https://dev.mysql.com/doc/refman/8.3/en/create-table.html
1048- /// [2]: IndexType
1049- /// [3]: IndexOption
1050- /// [4]: KeyOrIndexDisplay
1051- Unique {
1052- /// Constraint name.
1053- ///
1054- /// Can be not the same as `index_name`
1055- name : Option < Ident > ,
1056- /// Index name
1057- index_name : Option < Ident > ,
1058- /// Whether the type is followed by the keyword `KEY`, `INDEX`, or no keyword at all.
1059- index_type_display : KeyOrIndexDisplay ,
1060- /// Optional `USING` of [index type][1] statement before columns.
1061- ///
1062- /// [1]: IndexType
1063- index_type : Option < IndexType > ,
1064- /// Identifiers of the columns that are unique.
1065- columns : Vec < IndexColumn > ,
1066- index_options : Vec < IndexOption > ,
1067- characteristics : Option < ConstraintCharacteristics > ,
1068- /// Optional Postgres nulls handling: `[ NULLS [ NOT ] DISTINCT ]`
1069- nulls_distinct : NullsDistinctOption ,
1070- } ,
1071- /// MySQL [definition][1] for `PRIMARY KEY` constraints statements:\
1072- /// * `[CONSTRAINT [<name>]] PRIMARY KEY [index_name] [index_type] (<columns>) <index_options>`
1073- ///
1074- /// Actually the specification have no `[index_name]` but the next query will complete successfully:
1075- /// ```sql
1076- /// CREATE TABLE unspec_table (
1077- /// xid INT NOT NULL,
1078- /// CONSTRAINT p_name PRIMARY KEY index_name USING BTREE (xid)
1079- /// );
1080- /// ```
1081- ///
1082- /// where:
1083- /// * [index_type][2] is `USING {BTREE | HASH}`
1084- /// * [index_options][3] is `{index_type | COMMENT 'string' | ... %currently unsupported stmts% } ...`
1085- ///
1086- /// [1]: https://dev.mysql.com/doc/refman/8.3/en/create-table.html
1087- /// [2]: IndexType
1088- /// [3]: IndexOption
1089- PrimaryKey {
1090- /// Constraint name.
1091- ///
1092- /// Can be not the same as `index_name`
1093- name : Option < Ident > ,
1094- /// Index name
1095- index_name : Option < Ident > ,
1096- /// Optional `USING` of [index type][1] statement before columns.
1097- ///
1098- /// [1]: IndexType
1099- index_type : Option < IndexType > ,
1100- /// Identifiers of the columns that form the primary key.
1101- columns : Vec < IndexColumn > ,
1102- index_options : Vec < IndexOption > ,
1103- characteristics : Option < ConstraintCharacteristics > ,
1104- } ,
1105- /// A referential integrity constraint (`[ CONSTRAINT <name> ] FOREIGN KEY (<columns>)
1106- /// REFERENCES <foreign_table> (<referred_columns>)
1107- /// { [ON DELETE <referential_action>] [ON UPDATE <referential_action>] |
1108- /// [ON UPDATE <referential_action>] [ON DELETE <referential_action>]
1109- /// }`).
1110- ForeignKey {
1111- name : Option < Ident > ,
1112- /// MySQL-specific field
1113- /// <https://dev.mysql.com/doc/refman/8.4/en/create-table-foreign-keys.html>
1114- index_name : Option < Ident > ,
1115- columns : Vec < Ident > ,
1116- foreign_table : ObjectName ,
1117- referred_columns : Vec < Ident > ,
1118- on_delete : Option < ReferentialAction > ,
1119- on_update : Option < ReferentialAction > ,
1120- characteristics : Option < ConstraintCharacteristics > ,
1121- } ,
1122- /// `[ CONSTRAINT <name> ] CHECK (<expr>) [[NOT] ENFORCED]`
1123- Check {
1124- name : Option < Ident > ,
1125- expr : Box < Expr > ,
1126- /// MySQL-specific syntax
1127- /// <https://dev.mysql.com/doc/refman/8.4/en/create-table.html>
1128- enforced : Option < bool > ,
1129- } ,
1130- /// MySQLs [index definition][1] for index creation. Not present on ANSI so, for now, the usage
1131- /// is restricted to MySQL, as no other dialects that support this syntax were found.
1132- ///
1133- /// `{INDEX | KEY} [index_name] [index_type] (key_part,...) [index_option]...`
1134- ///
1135- /// [1]: https://dev.mysql.com/doc/refman/8.0/en/create-table.html
1136- Index {
1137- /// Whether this index starts with KEY (true) or INDEX (false), to maintain the same syntax.
1138- display_as_key : bool ,
1139- /// Index name.
1140- name : Option < Ident > ,
1141- /// Optional [index type][1].
1142- ///
1143- /// [1]: IndexType
1144- index_type : Option < IndexType > ,
1145- /// Referred column identifier list.
1146- columns : Vec < IndexColumn > ,
1147- /// Optional index options such as `USING`; see [`IndexOption`].
1148- index_options : Vec < IndexOption > ,
1149- } ,
1150- /// MySQLs [fulltext][1] definition. Since the [`SPATIAL`][2] definition is exactly the same,
1151- /// and MySQL displays both the same way, it is part of this definition as well.
1152- ///
1153- /// Supported syntax:
1154- ///
1155- /// ```markdown
1156- /// {FULLTEXT | SPATIAL} [INDEX | KEY] [index_name] (key_part,...)
1157- ///
1158- /// key_part: col_name
1159- /// ```
1160- ///
1161- /// [1]: https://dev.mysql.com/doc/refman/8.0/en/fulltext-natural-language.html
1162- /// [2]: https://dev.mysql.com/doc/refman/8.0/en/spatial-types.html
1163- FulltextOrSpatial {
1164- /// Whether this is a `FULLTEXT` (true) or `SPATIAL` (false) definition.
1165- fulltext : bool ,
1166- /// Whether the type is followed by the keyword `KEY`, `INDEX`, or no keyword at all.
1167- index_type_display : KeyOrIndexDisplay ,
1168- /// Optional index name.
1169- opt_index_name : Option < Ident > ,
1170- /// Referred column identifier list.
1171- columns : Vec < IndexColumn > ,
1172- } ,
1173- }
1174-
1175- impl fmt:: Display for TableConstraint {
1176- fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
1177- match self {
1178- TableConstraint :: Unique {
1179- name,
1180- index_name,
1181- index_type_display,
1182- index_type,
1183- columns,
1184- index_options,
1185- characteristics,
1186- nulls_distinct,
1187- } => {
1188- write ! (
1189- f,
1190- "{}UNIQUE{nulls_distinct}{index_type_display:>}{}{} ({})" ,
1191- display_constraint_name( name) ,
1192- display_option_spaced( index_name) ,
1193- display_option( " USING " , "" , index_type) ,
1194- display_comma_separated( columns) ,
1195- ) ?;
1196-
1197- if !index_options. is_empty ( ) {
1198- write ! ( f, " {}" , display_separated( index_options, " " ) ) ?;
1199- }
1200-
1201- write ! ( f, "{}" , display_option_spaced( characteristics) ) ?;
1202- Ok ( ( ) )
1203- }
1204- TableConstraint :: PrimaryKey {
1205- name,
1206- index_name,
1207- index_type,
1208- columns,
1209- index_options,
1210- characteristics,
1211- } => {
1212- write ! (
1213- f,
1214- "{}PRIMARY KEY{}{} ({})" ,
1215- display_constraint_name( name) ,
1216- display_option_spaced( index_name) ,
1217- display_option( " USING " , "" , index_type) ,
1218- display_comma_separated( columns) ,
1219- ) ?;
1220-
1221- if !index_options. is_empty ( ) {
1222- write ! ( f, " {}" , display_separated( index_options, " " ) ) ?;
1223- }
1224-
1225- write ! ( f, "{}" , display_option_spaced( characteristics) ) ?;
1226- Ok ( ( ) )
1227- }
1228- TableConstraint :: ForeignKey {
1229- name,
1230- index_name,
1231- columns,
1232- foreign_table,
1233- referred_columns,
1234- on_delete,
1235- on_update,
1236- characteristics,
1237- } => {
1238- write ! (
1239- f,
1240- "{}FOREIGN KEY{} ({}) REFERENCES {}" ,
1241- display_constraint_name( name) ,
1242- display_option_spaced( index_name) ,
1243- display_comma_separated( columns) ,
1244- foreign_table,
1245- ) ?;
1246- if !referred_columns. is_empty ( ) {
1247- write ! ( f, "({})" , display_comma_separated( referred_columns) ) ?;
1248- }
1249- if let Some ( action) = on_delete {
1250- write ! ( f, " ON DELETE {action}" ) ?;
1251- }
1252- if let Some ( action) = on_update {
1253- write ! ( f, " ON UPDATE {action}" ) ?;
1254- }
1255- if let Some ( characteristics) = characteristics {
1256- write ! ( f, " {characteristics}" ) ?;
1257- }
1258- Ok ( ( ) )
1259- }
1260- TableConstraint :: Check {
1261- name,
1262- expr,
1263- enforced,
1264- } => {
1265- write ! ( f, "{}CHECK ({})" , display_constraint_name( name) , expr) ?;
1266- if let Some ( b) = enforced {
1267- write ! ( f, " {}" , if * b { "ENFORCED" } else { "NOT ENFORCED" } )
1268- } else {
1269- Ok ( ( ) )
1270- }
1271- }
1272- TableConstraint :: Index {
1273- display_as_key,
1274- name,
1275- index_type,
1276- columns,
1277- index_options,
1278- } => {
1279- write ! ( f, "{}" , if * display_as_key { "KEY" } else { "INDEX" } ) ?;
1280- if let Some ( name) = name {
1281- write ! ( f, " {name}" ) ?;
1282- }
1283- if let Some ( index_type) = index_type {
1284- write ! ( f, " USING {index_type}" ) ?;
1285- }
1286- write ! ( f, " ({})" , display_comma_separated( columns) ) ?;
1287- if !index_options. is_empty ( ) {
1288- write ! ( f, " {}" , display_comma_separated( index_options) ) ?;
1289- }
1290- Ok ( ( ) )
1291- }
1292- Self :: FulltextOrSpatial {
1293- fulltext,
1294- index_type_display,
1295- opt_index_name,
1296- columns,
1297- } => {
1298- if * fulltext {
1299- write ! ( f, "FULLTEXT" ) ?;
1300- } else {
1301- write ! ( f, "SPATIAL" ) ?;
1302- }
1303-
1304- write ! ( f, "{index_type_display:>}" ) ?;
1305-
1306- if let Some ( name) = opt_index_name {
1307- write ! ( f, " {name}" ) ?;
1308- }
1309-
1310- write ! ( f, " ({})" , display_comma_separated( columns) ) ?;
1311-
1312- Ok ( ( ) )
1313- }
1314- }
1315- }
1316- }
1317-
13181033/// Representation whether a definition can can contains the KEY or INDEX keywords with the same
13191034/// meaning.
13201035///
@@ -1459,12 +1174,19 @@ pub struct ProcedureParam {
14591174 pub name : Ident ,
14601175 pub data_type : DataType ,
14611176 pub mode : Option < ArgMode > ,
1177+ pub default : Option < Expr > ,
14621178}
14631179
14641180impl fmt:: Display for ProcedureParam {
14651181 fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
14661182 if let Some ( mode) = & self . mode {
1467- write ! ( f, "{mode} {} {}" , self . name, self . data_type)
1183+ if let Some ( default) = & self . default {
1184+ write ! ( f, "{mode} {} {} = {}" , self . name, self . data_type, default )
1185+ } else {
1186+ write ! ( f, "{mode} {} {}" , self . name, self . data_type)
1187+ }
1188+ } else if let Some ( default) = & self . default {
1189+ write ! ( f, "{} {} = {}" , self . name, self . data_type, default )
14681190 } else {
14691191 write ! ( f, "{} {}" , self . name, self . data_type)
14701192 }
@@ -2066,7 +1788,7 @@ pub enum GeneratedExpressionMode {
20661788}
20671789
20681790#[ must_use]
2069- fn display_constraint_name ( name : & ' _ Option < Ident > ) -> impl fmt:: Display + ' _ {
1791+ pub ( crate ) fn display_constraint_name ( name : & ' _ Option < Ident > ) -> impl fmt:: Display + ' _ {
20701792 struct ConstraintName < ' a > ( & ' a Option < Ident > ) ;
20711793 impl fmt:: Display for ConstraintName < ' _ > {
20721794 fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
@@ -2083,7 +1805,7 @@ fn display_constraint_name(name: &'_ Option<Ident>) -> impl fmt::Display + '_ {
20831805/// * `Some(inner)` => create display struct for `"{prefix}{inner}{postfix}"`
20841806/// * `_` => do nothing
20851807#[ must_use]
2086- fn display_option < ' a , T : fmt:: Display > (
1808+ pub ( crate ) fn display_option < ' a , T : fmt:: Display > (
20871809 prefix : & ' a str ,
20881810 postfix : & ' a str ,
20891811 option : & ' a Option < T > ,
@@ -2105,7 +1827,7 @@ fn display_option<'a, T: fmt::Display>(
21051827/// * `Some(inner)` => create display struct for `" {inner}"`
21061828/// * `_` => do nothing
21071829#[ must_use]
2108- fn display_option_spaced < T : fmt:: Display > ( option : & Option < T > ) -> impl fmt:: Display + ' _ {
1830+ pub ( crate ) fn display_option_spaced < T : fmt:: Display > ( option : & Option < T > ) -> impl fmt:: Display + ' _ {
21091831 display_option ( " " , "" , option)
21101832}
21111833
0 commit comments