@@ -31,7 +31,7 @@ use sqlparser_derive::{Visit, VisitMut};
3131use crate :: ast:: value:: escape_single_quote_string;
3232use crate :: ast:: {
3333 display_comma_separated, display_separated, DataType , Expr , Ident , MySQLColumnPosition ,
34- ObjectName , OrderByExpr , ProjectionSelect , SequenceOptions , SqlOption , Value ,
34+ ObjectName , OrderByExpr , ProjectionSelect , SequenceOptions , SqlOption , Tag , Value ,
3535} ;
3636use crate :: keywords:: Keyword ;
3737use crate :: tokenizer:: Token ;
@@ -1096,17 +1096,221 @@ impl fmt::Display for ColumnOptionDef {
10961096 }
10971097}
10981098
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+
10991150#[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
11001151#[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
11011152#[ cfg_attr( feature = "visitor" , derive( Visit , VisitMut ) ) ]
11021153pub 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 {
11031213 pub seed : Expr ,
11041214 pub increment : Expr ,
11051215}
11061216
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 {
11081256 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 ( ( ) )
11101314 }
11111315}
11121316
@@ -1180,16 +1384,32 @@ pub enum ColumnOption {
11801384 /// [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#view_column_option_list
11811385 /// [2]: https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#column_option_list
11821386 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.
11841388 /// Syntax
11851389 /// ```sql
1186- /// IDENTITY [ (seed , increment) ]
1390+ /// { IDENTITY | AUTOINCREMENT } [ (seed , increment) | START num INCREMENT num ] [ ORDER | NOORDER ]
11871391 /// ```
11881392 /// [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 ) ,
11901395 /// SQLite specific: ON CONFLICT option on column definition
11911396 /// <https://www.sqlite.org/lang_conflict.html>
11921397 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 ) ,
11931413}
11941414
11951415impl fmt:: Display for ColumnOption {
@@ -1292,16 +1512,18 @@ impl fmt::Display for ColumnOption {
12921512 write ! ( f, "OPTIONS({})" , display_comma_separated( options) )
12931513 }
12941514 Identity ( parameters) => {
1295- write ! ( f, "IDENTITY" ) ?;
1296- if let Some ( parameters) = parameters {
1297- write ! ( f, "({parameters})" ) ?;
1298- }
1299- Ok ( ( ) )
1515+ write ! ( f, "{parameters}" )
13001516 }
13011517 OnConflict ( keyword) => {
13021518 write ! ( f, "ON CONFLICT {:?}" , keyword) ?;
13031519 Ok ( ( ) )
13041520 }
1521+ Policy ( parameters) => {
1522+ write ! ( f, "{parameters}" )
1523+ }
1524+ Tags ( tags) => {
1525+ write ! ( f, "{tags}" )
1526+ }
13051527 }
13061528 }
13071529}
0 commit comments