@@ -31,7 +31,7 @@ use sqlparser_derive::{Visit, VisitMut};
31
31
use crate :: ast:: value:: escape_single_quote_string;
32
32
use crate :: ast:: {
33
33
display_comma_separated, display_separated, DataType , Expr , Ident , MySQLColumnPosition ,
34
- ObjectName , OrderByExpr , ProjectionSelect , SequenceOptions , SqlOption , Value ,
34
+ ObjectName , OrderByExpr , ProjectionSelect , SequenceOptions , SqlOption , Tag , Value ,
35
35
} ;
36
36
use crate :: keywords:: Keyword ;
37
37
use crate :: tokenizer:: Token ;
@@ -1096,17 +1096,221 @@ impl fmt::Display for ColumnOptionDef {
1096
1096
}
1097
1097
}
1098
1098
1099
+ /// Identity is a column option for defining an identity or autoincrement column in a `CREATE TABLE` statement.
1100
+ /// Syntax
1101
+ /// ```sql
1102
+ /// { IDENTITY | AUTOINCREMENT } [ (seed , increment) | START num INCREMENT num ] [ ORDER | NOORDER ]
1103
+ /// ```
1104
+ /// [MS SQL Server]: https://learn.microsoft.com/en-us/sql/t-sql/statements/create-table-transact-sql-identity-property
1105
+ /// [Snowflake]: https://docs.snowflake.com/en/sql-reference/sql/create-table
1106
+ #[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
1107
+ #[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
1108
+ #[ cfg_attr( feature = "visitor" , derive( Visit , VisitMut ) ) ]
1109
+ pub enum IdentityPropertyKind {
1110
+ /// An identity property declared via the `AUTOINCREMENT` key word
1111
+ /// Example:
1112
+ /// ```sql
1113
+ /// AUTOINCREMENT(100, 1) NOORDER
1114
+ /// AUTOINCREMENT START 100 INCREMENT 1 ORDER
1115
+ /// ```
1116
+ /// [Snowflake]: https://docs.snowflake.com/en/sql-reference/sql/create-table
1117
+ Autoincrement ( IdentityProperty ) ,
1118
+ /// An identity property declared via the `IDENTITY` key word
1119
+ /// Example, [MS SQL Server] or [Snowflake]:
1120
+ /// ```sql
1121
+ /// IDENTITY(100, 1)
1122
+ /// ```
1123
+ /// [Snowflake]
1124
+ /// ```sql
1125
+ /// IDENTITY(100, 1) ORDER
1126
+ /// IDENTITY START 100 INCREMENT 1 NOORDER
1127
+ /// ```
1128
+ /// [MS SQL Server]: https://learn.microsoft.com/en-us/sql/t-sql/statements/create-table-transact-sql-identity-property
1129
+ /// [Snowflake]: https://docs.snowflake.com/en/sql-reference/sql/create-table
1130
+ Identity ( IdentityProperty ) ,
1131
+ }
1132
+
1133
+ impl fmt:: Display for IdentityPropertyKind {
1134
+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
1135
+ let ( command, property) = match self {
1136
+ IdentityPropertyKind :: Identity ( property) => ( "IDENTITY" , property) ,
1137
+ IdentityPropertyKind :: Autoincrement ( property) => ( "AUTOINCREMENT" , property) ,
1138
+ } ;
1139
+ write ! ( f, "{command}" ) ?;
1140
+ if let Some ( parameters) = & property. parameters {
1141
+ write ! ( f, "{parameters}" ) ?;
1142
+ }
1143
+ if let Some ( order) = & property. order {
1144
+ write ! ( f, "{order}" ) ?;
1145
+ }
1146
+ Ok ( ( ) )
1147
+ }
1148
+ }
1149
+
1099
1150
#[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
1100
1151
#[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
1101
1152
#[ cfg_attr( feature = "visitor" , derive( Visit , VisitMut ) ) ]
1102
1153
pub struct IdentityProperty {
1154
+ pub parameters : Option < IdentityPropertyFormatKind > ,
1155
+ pub order : Option < IdentityPropertyOrder > ,
1156
+ }
1157
+
1158
+ /// A format of parameters of identity column.
1159
+ ///
1160
+ /// It is [Snowflake] specific.
1161
+ /// Syntax
1162
+ /// ```sql
1163
+ /// (seed , increment) | START num INCREMENT num
1164
+ /// ```
1165
+ /// [MS SQL Server] uses one way of representing these parameters.
1166
+ /// Syntax
1167
+ /// ```sql
1168
+ /// (seed , increment)
1169
+ /// ```
1170
+ /// [MS SQL Server]: https://learn.microsoft.com/en-us/sql/t-sql/statements/create-table-transact-sql-identity-property
1171
+ /// [Snowflake]: https://docs.snowflake.com/en/sql-reference/sql/create-table
1172
+ #[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
1173
+ #[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
1174
+ #[ cfg_attr( feature = "visitor" , derive( Visit , VisitMut ) ) ]
1175
+ pub enum IdentityPropertyFormatKind {
1176
+ /// A parameters of identity column declared like parameters of function call
1177
+ /// Example:
1178
+ /// ```sql
1179
+ /// (100, 1)
1180
+ /// ```
1181
+ /// [MS SQL Server]: https://learn.microsoft.com/en-us/sql/t-sql/statements/create-table-transact-sql-identity-property
1182
+ /// [Snowflake]: https://docs.snowflake.com/en/sql-reference/sql/create-table
1183
+ FunctionCall ( IdentityParameters ) ,
1184
+ /// A parameters of identity column declared with keywords `START` and `INCREMENT`
1185
+ /// Example:
1186
+ /// ```sql
1187
+ /// START 100 INCREMENT 1
1188
+ /// ```
1189
+ /// [Snowflake]: https://docs.snowflake.com/en/sql-reference/sql/create-table
1190
+ StartAndIncrement ( IdentityParameters ) ,
1191
+ }
1192
+
1193
+ impl fmt:: Display for IdentityPropertyFormatKind {
1194
+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
1195
+ match self {
1196
+ IdentityPropertyFormatKind :: FunctionCall ( parameters) => {
1197
+ write ! ( f, "({}, {})" , parameters. seed, parameters. increment)
1198
+ }
1199
+ IdentityPropertyFormatKind :: StartAndIncrement ( parameters) => {
1200
+ write ! (
1201
+ f,
1202
+ " START {} INCREMENT {}" ,
1203
+ parameters. seed, parameters. increment
1204
+ )
1205
+ }
1206
+ }
1207
+ }
1208
+ }
1209
+ #[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
1210
+ #[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
1211
+ #[ cfg_attr( feature = "visitor" , derive( Visit , VisitMut ) ) ]
1212
+ pub struct IdentityParameters {
1103
1213
pub seed : Expr ,
1104
1214
pub increment : Expr ,
1105
1215
}
1106
1216
1107
- impl fmt:: Display for IdentityProperty {
1217
+ /// The identity column option specifies how values are generated for the auto-incremented column, either in increasing or decreasing order.
1218
+ /// Syntax
1219
+ /// ```sql
1220
+ /// ORDER | NOORDER
1221
+ /// ```
1222
+ /// [Snowflake]: https://docs.snowflake.com/en/sql-reference/sql/create-table
1223
+ #[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
1224
+ #[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
1225
+ #[ cfg_attr( feature = "visitor" , derive( Visit , VisitMut ) ) ]
1226
+ pub enum IdentityPropertyOrder {
1227
+ Order ,
1228
+ NoOrder ,
1229
+ }
1230
+
1231
+ impl fmt:: Display for IdentityPropertyOrder {
1232
+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
1233
+ match self {
1234
+ IdentityPropertyOrder :: Order => write ! ( f, " ORDER" ) ,
1235
+ IdentityPropertyOrder :: NoOrder => write ! ( f, " NOORDER" ) ,
1236
+ }
1237
+ }
1238
+ }
1239
+
1240
+ /// Column policy that identify a security policy of access to a column.
1241
+ /// Syntax
1242
+ /// ```sql
1243
+ /// [ WITH ] MASKING POLICY <policy_name> [ USING ( <col_name> , <cond_col1> , ... ) ]
1244
+ /// [ WITH ] PROJECTION POLICY <policy_name>
1245
+ /// ```
1246
+ /// [Snowflake]: https://docs.snowflake.com/en/sql-reference/sql/create-table
1247
+ #[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
1248
+ #[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
1249
+ #[ cfg_attr( feature = "visitor" , derive( Visit , VisitMut ) ) ]
1250
+ pub enum ColumnPolicy {
1251
+ MaskingPolicy ( ColumnPolicyProperty ) ,
1252
+ ProjectionPolicy ( ColumnPolicyProperty ) ,
1253
+ }
1254
+
1255
+ impl fmt:: Display for ColumnPolicy {
1108
1256
fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
1109
- write ! ( f, "{}, {}" , self . seed, self . increment)
1257
+ let ( command, property) = match self {
1258
+ ColumnPolicy :: MaskingPolicy ( property) => ( "MASKING POLICY" , property) ,
1259
+ ColumnPolicy :: ProjectionPolicy ( property) => ( "PROJECTION POLICY" , property) ,
1260
+ } ;
1261
+ if property. with {
1262
+ write ! ( f, "WITH " ) ?;
1263
+ }
1264
+ write ! ( f, "{command} {}" , property. policy_name) ?;
1265
+ if let Some ( using_columns) = & property. using_columns {
1266
+ write ! ( f, " USING ({})" , display_comma_separated( using_columns) ) ?;
1267
+ }
1268
+ Ok ( ( ) )
1269
+ }
1270
+ }
1271
+
1272
+ #[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
1273
+ #[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
1274
+ #[ cfg_attr( feature = "visitor" , derive( Visit , VisitMut ) ) ]
1275
+ pub struct ColumnPolicyProperty {
1276
+ /// This flag indicates that the column policy option is declared using the `WITH` prefix.
1277
+ /// Example
1278
+ /// ```sql
1279
+ /// WITH PROJECTION POLICY sample_policy
1280
+ /// ```
1281
+ /// [Snowflake]: https://docs.snowflake.com/en/sql-reference/sql/create-table
1282
+ pub with : bool ,
1283
+ pub policy_name : Ident ,
1284
+ pub using_columns : Option < Vec < Ident > > ,
1285
+ }
1286
+
1287
+ /// Tags option of column
1288
+ /// Syntax
1289
+ /// ```sql
1290
+ /// [ WITH ] TAG ( <tag_name> = '<tag_value>' [ , <tag_name> = '<tag_value>' , ... ] )
1291
+ /// ```
1292
+ /// [Snowflake]: https://docs.snowflake.com/en/sql-reference/sql/create-table
1293
+ #[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
1294
+ #[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
1295
+ #[ cfg_attr( feature = "visitor" , derive( Visit , VisitMut ) ) ]
1296
+ pub struct TagsColumnOption {
1297
+ /// This flag indicates that the tags option is declared using the `WITH` prefix.
1298
+ /// Example:
1299
+ /// ```sql
1300
+ /// WITH TAG (A = 'Tag A')
1301
+ /// ```
1302
+ /// [Snowflake]: https://docs.snowflake.com/en/sql-reference/sql/create-table
1303
+ pub with : bool ,
1304
+ pub tags : Vec < Tag > ,
1305
+ }
1306
+
1307
+ impl fmt:: Display for TagsColumnOption {
1308
+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
1309
+ if self . with {
1310
+ write ! ( f, "WITH " ) ?;
1311
+ }
1312
+ write ! ( f, "TAG ({})" , display_comma_separated( & self . tags) ) ?;
1313
+ Ok ( ( ) )
1110
1314
}
1111
1315
}
1112
1316
@@ -1180,16 +1384,32 @@ pub enum ColumnOption {
1180
1384
/// [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#view_column_option_list
1181
1385
/// [2]: https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#column_option_list
1182
1386
Options ( Vec < SqlOption > ) ,
1183
- /// MS SQL Server specific: Creates an identity column in a table.
1387
+ /// Creates an identity or an autoincrement column in a table.
1184
1388
/// Syntax
1185
1389
/// ```sql
1186
- /// IDENTITY [ (seed , increment) ]
1390
+ /// { IDENTITY | AUTOINCREMENT } [ (seed , increment) | START num INCREMENT num ] [ ORDER | NOORDER ]
1187
1391
/// ```
1188
1392
/// [MS SQL Server]: https://learn.microsoft.com/en-us/sql/t-sql/statements/create-table-transact-sql-identity-property
1189
- Identity ( Option < IdentityProperty > ) ,
1393
+ /// [Snowflake]: https://docs.snowflake.com/en/sql-reference/sql/create-table
1394
+ Identity ( IdentityPropertyKind ) ,
1190
1395
/// SQLite specific: ON CONFLICT option on column definition
1191
1396
/// <https://www.sqlite.org/lang_conflict.html>
1192
1397
OnConflict ( Keyword ) ,
1398
+ /// Snowflake specific: an option of specifying security masking or projection policy to set on a column.
1399
+ /// Syntax:
1400
+ /// ```sql
1401
+ /// [ WITH ] MASKING POLICY <policy_name> [ USING ( <col_name> , <cond_col1> , ... ) ]
1402
+ /// [ WITH ] PROJECTION POLICY <policy_name>
1403
+ /// ```
1404
+ /// [Snowflake]: https://docs.snowflake.com/en/sql-reference/sql/create-table
1405
+ Policy ( ColumnPolicy ) ,
1406
+ /// Snowflake specific: Specifies the tag name and the tag string value.
1407
+ /// Syntax:
1408
+ /// ```sql
1409
+ /// [ WITH ] TAG ( <tag_name> = '<tag_value>' [ , <tag_name> = '<tag_value>' , ... ] )
1410
+ /// ```
1411
+ /// [Snowflake]: https://docs.snowflake.com/en/sql-reference/sql/create-table
1412
+ Tags ( TagsColumnOption ) ,
1193
1413
}
1194
1414
1195
1415
impl fmt:: Display for ColumnOption {
@@ -1292,16 +1512,18 @@ impl fmt::Display for ColumnOption {
1292
1512
write ! ( f, "OPTIONS({})" , display_comma_separated( options) )
1293
1513
}
1294
1514
Identity ( parameters) => {
1295
- write ! ( f, "IDENTITY" ) ?;
1296
- if let Some ( parameters) = parameters {
1297
- write ! ( f, "({parameters})" ) ?;
1298
- }
1299
- Ok ( ( ) )
1515
+ write ! ( f, "{parameters}" )
1300
1516
}
1301
1517
OnConflict ( keyword) => {
1302
1518
write ! ( f, "ON CONFLICT {:?}" , keyword) ?;
1303
1519
Ok ( ( ) )
1304
1520
}
1521
+ Policy ( parameters) => {
1522
+ write ! ( f, "{parameters}" )
1523
+ }
1524
+ Tags ( tags) => {
1525
+ write ! ( f, "{tags}" )
1526
+ }
1305
1527
}
1306
1528
}
1307
1529
}
0 commit comments