@@ -30,15 +30,15 @@ use sqlparser_derive::{Visit, VisitMut};
30
30
31
31
use crate :: ast:: value:: escape_single_quote_string;
32
32
use 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 ,
42
42
} ;
43
43
use crate :: display_utils:: { DisplayCommaSeparated , Indent , NewLine , SpaceOrNewline } ;
44
44
use crate :: keywords:: Keyword ;
@@ -1029,291 +1029,6 @@ impl fmt::Display for AlterColumnOperation {
1029
1029
}
1030
1030
}
1031
1031
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
-
1317
1032
/// Representation whether a definition can can contains the KEY or INDEX keywords with the same
1318
1033
/// meaning.
1319
1034
///
@@ -2065,7 +1780,7 @@ pub enum GeneratedExpressionMode {
2065
1780
}
2066
1781
2067
1782
#[ 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 + ' _ {
2069
1784
struct ConstraintName < ' a > ( & ' a Option < Ident > ) ;
2070
1785
impl fmt:: Display for ConstraintName < ' _ > {
2071
1786
fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
@@ -2082,7 +1797,7 @@ fn display_constraint_name(name: &'_ Option<Ident>) -> impl fmt::Display + '_ {
2082
1797
/// * `Some(inner)` => create display struct for `"{prefix}{inner}{postfix}"`
2083
1798
/// * `_` => do nothing
2084
1799
#[ must_use]
2085
- fn display_option < ' a , T : fmt:: Display > (
1800
+ pub ( crate ) fn display_option < ' a , T : fmt:: Display > (
2086
1801
prefix : & ' a str ,
2087
1802
postfix : & ' a str ,
2088
1803
option : & ' a Option < T > ,
@@ -2104,7 +1819,7 @@ fn display_option<'a, T: fmt::Display>(
2104
1819
/// * `Some(inner)` => create display struct for `" {inner}"`
2105
1820
/// * `_` => do nothing
2106
1821
#[ 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 + ' _ {
2108
1823
display_option ( " " , "" , option)
2109
1824
}
2110
1825
0 commit comments