Skip to content

Commit 5687466

Browse files
author
aleksei.p
committed
MS SQL Server: add support for IDENTITY column option
1 parent 246838a commit 5687466

File tree

4 files changed

+146
-0
lines changed

4 files changed

+146
-0
lines changed

src/ast/ddl.rs

+14
Original file line numberDiff line numberDiff line change
@@ -1120,6 +1120,13 @@ pub enum ColumnOption {
11201120
/// [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#view_column_option_list
11211121
/// [2]: https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#column_option_list
11221122
Options(Vec<SqlOption>),
1123+
/// MS SQL Server specific: Creates an identity column in a table.
1124+
/// Syntax
1125+
/// ```sql
1126+
/// IDENTITY [ (seed , increment) ]
1127+
/// ```
1128+
/// [MS SQL Server]: https://learn.microsoft.com/en-us/sql/t-sql/statements/create-table-transact-sql-identity-property
1129+
Identity(Option<SqlOption>),
11231130
}
11241131

11251132
impl fmt::Display for ColumnOption {
@@ -1221,6 +1228,13 @@ impl fmt::Display for ColumnOption {
12211228
Options(options) => {
12221229
write!(f, "OPTIONS({})", display_comma_separated(options))
12231230
}
1231+
Identity(parameters) => {
1232+
write!(f, "IDENTITY")?;
1233+
if let Some(parameters) = parameters {
1234+
write!(f, "({parameters})")?;
1235+
}
1236+
Ok(())
1237+
}
12241238
}
12251239
}
12261240
}

src/ast/mod.rs

+10
Original file line numberDiff line numberDiff line change
@@ -5818,6 +5818,13 @@ pub enum SqlOption {
58185818
range_direction: Option<PartitionRangeDirection>,
58195819
for_values: Vec<Expr>,
58205820
},
5821+
/// MS SQL Server specific: Optional parameters of identity column
5822+
/// E.g.
5823+
///
5824+
/// IDENTITY(1, 2)
5825+
///
5826+
/// [MS SQL Server]: https://learn.microsoft.com/en-us/sql/t-sql/statements/create-table-transact-sql-identity-property
5827+
Identity { seed: Value, increment: Value },
58215828
}
58225829

58235830
impl fmt::Display for SqlOption {
@@ -5849,6 +5856,9 @@ impl fmt::Display for SqlOption {
58495856
display_comma_separated(for_values)
58505857
)
58515858
}
5859+
SqlOption::Identity { seed, increment } => {
5860+
write!(f, "{}, {}", seed, increment)
5861+
}
58525862
}
58535863
}
58545864
}

src/parser/mod.rs

+14
Original file line numberDiff line numberDiff line change
@@ -6043,6 +6043,20 @@ impl<'a> Parser<'a> {
60436043
&& dialect_of!(self is MySqlDialect | SQLiteDialect | DuckDbDialect | GenericDialect)
60446044
{
60456045
self.parse_optional_column_option_as()
6046+
} else if self.parse_keyword(Keyword::IDENTITY)
6047+
&& dialect_of!(self is MsSqlDialect | GenericDialect)
6048+
{
6049+
let parameters = if self.expect_token(&Token::LParen).is_ok() {
6050+
let seed = self.parse_number_value()?;
6051+
self.expect_token(&Token::Comma)?;
6052+
let increment = self.parse_number_value()?;
6053+
self.expect_token(&Token::RParen)?;
6054+
6055+
Some(SqlOption::Identity { seed, increment })
6056+
} else {
6057+
None
6058+
};
6059+
Ok(Some(ColumnOption::Identity(parameters)))
60466060
} else {
60476061
Ok(None)
60486062
}

tests/sqlparser_mssql.rs

+108
Original file line numberDiff line numberDiff line change
@@ -908,6 +908,114 @@ fn parse_create_table_with_invalid_options() {
908908
}
909909
}
910910

911+
#[test]
912+
fn parse_create_table_with_identity_column() {
913+
let with_column_options = [
914+
(
915+
r#"CREATE TABLE [mytable] ([columnA] INT IDENTITY NOT NULL)"#,
916+
vec![
917+
ColumnOptionDef {
918+
name: None,
919+
option: ColumnOption::Identity(None),
920+
},
921+
ColumnOptionDef {
922+
name: None,
923+
option: ColumnOption::NotNull,
924+
},
925+
],
926+
),
927+
(
928+
r#"CREATE TABLE [mytable] ([columnA] INT IDENTITY(1, 1) NOT NULL)"#,
929+
vec![
930+
ColumnOptionDef {
931+
name: None,
932+
#[cfg(not(feature = "bigdecimal"))]
933+
option: ColumnOption::Identity(Some(SqlOption::Identity {
934+
seed: Value::Number("1".to_string(), false),
935+
increment: Value::Number("1".to_string(), false),
936+
})),
937+
#[cfg(feature = "bigdecimal")]
938+
option: ColumnOption::Identity(Some(SqlOption::Identity {
939+
seed: Value::Number(bigdecimal::BigDecimal::from(1), false),
940+
increment: Value::Number(bigdecimal::BigDecimal::from(1), false),
941+
})),
942+
},
943+
ColumnOptionDef {
944+
name: None,
945+
option: ColumnOption::NotNull,
946+
},
947+
],
948+
),
949+
];
950+
951+
for (sql, column_options) in with_column_options {
952+
assert_eq!(
953+
ms().verified_stmt(sql),
954+
Statement::CreateTable(CreateTable {
955+
or_replace: false,
956+
temporary: false,
957+
external: false,
958+
global: None,
959+
if_not_exists: false,
960+
transient: false,
961+
volatile: false,
962+
name: ObjectName(vec![Ident {
963+
value: "mytable".to_string(),
964+
quote_style: Some('['),
965+
},],),
966+
columns: vec![ColumnDef {
967+
name: Ident {
968+
value: "columnA".to_string(),
969+
quote_style: Some('['),
970+
},
971+
data_type: Int(None,),
972+
collation: None,
973+
options: column_options,
974+
},],
975+
constraints: vec![],
976+
hive_distribution: HiveDistributionStyle::NONE,
977+
hive_formats: Some(HiveFormat {
978+
row_format: None,
979+
serde_properties: None,
980+
storage: None,
981+
location: None,
982+
},),
983+
table_properties: vec![],
984+
with_options: vec![],
985+
file_format: None,
986+
location: None,
987+
query: None,
988+
without_rowid: false,
989+
like: None,
990+
clone: None,
991+
engine: None,
992+
comment: None,
993+
auto_increment_offset: None,
994+
default_charset: None,
995+
collation: None,
996+
on_commit: None,
997+
on_cluster: None,
998+
primary_key: None,
999+
order_by: None,
1000+
partition_by: None,
1001+
cluster_by: None,
1002+
clustered_by: None,
1003+
options: None,
1004+
strict: false,
1005+
copy_grants: false,
1006+
enable_schema_evolution: None,
1007+
change_tracking: None,
1008+
data_retention_time_in_days: None,
1009+
max_data_extension_time_in_days: None,
1010+
default_ddl_collation: None,
1011+
with_aggregation_policy: None,
1012+
with_row_access_policy: None,
1013+
with_tags: None,
1014+
}),
1015+
);
1016+
}
1017+
}
1018+
9111019
fn ms() -> TestedDialects {
9121020
TestedDialects {
9131021
dialects: vec![Box::new(MsSqlDialect {})],

0 commit comments

Comments
 (0)