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