mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-07-07 17:04:59 +00:00
MS SQL Server: add support for IDENTITY column option (#1432)
This commit is contained in:
parent
71318df8b9
commit
fb42425d51
4 changed files with 155 additions and 2 deletions
|
@ -1050,6 +1050,20 @@ impl fmt::Display for ColumnOptionDef {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
|
||||||
|
pub struct IdentityProperty {
|
||||||
|
pub seed: Expr,
|
||||||
|
pub increment: Expr,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for IdentityProperty {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
write!(f, "{}, {}", self.seed, self.increment)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// `ColumnOption`s are modifiers that follow a column definition in a `CREATE
|
/// `ColumnOption`s are modifiers that follow a column definition in a `CREATE
|
||||||
/// TABLE` statement.
|
/// TABLE` statement.
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
|
@ -1120,6 +1134,13 @@ pub enum ColumnOption {
|
||||||
/// [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#view_column_option_list
|
/// [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#view_column_option_list
|
||||||
/// [2]: https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#column_option_list
|
/// [2]: https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#column_option_list
|
||||||
Options(Vec<SqlOption>),
|
Options(Vec<SqlOption>),
|
||||||
|
/// MS SQL Server specific: Creates an identity column in a table.
|
||||||
|
/// Syntax
|
||||||
|
/// ```sql
|
||||||
|
/// IDENTITY [ (seed , increment) ]
|
||||||
|
/// ```
|
||||||
|
/// [MS SQL Server]: https://learn.microsoft.com/en-us/sql/t-sql/statements/create-table-transact-sql-identity-property
|
||||||
|
Identity(Option<IdentityProperty>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for ColumnOption {
|
impl fmt::Display for ColumnOption {
|
||||||
|
@ -1221,6 +1242,13 @@ impl fmt::Display for ColumnOption {
|
||||||
Options(options) => {
|
Options(options) => {
|
||||||
write!(f, "OPTIONS({})", display_comma_separated(options))
|
write!(f, "OPTIONS({})", display_comma_separated(options))
|
||||||
}
|
}
|
||||||
|
Identity(parameters) => {
|
||||||
|
write!(f, "IDENTITY")?;
|
||||||
|
if let Some(parameters) = parameters {
|
||||||
|
write!(f, "({parameters})")?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,8 +36,8 @@ pub use self::dcl::{AlterRoleOperation, ResetConfig, RoleOption, SetConfigValue,
|
||||||
pub use self::ddl::{
|
pub use self::ddl::{
|
||||||
AlterColumnOperation, AlterIndexOperation, AlterTableOperation, ClusteredBy, ColumnDef,
|
AlterColumnOperation, AlterIndexOperation, AlterTableOperation, ClusteredBy, ColumnDef,
|
||||||
ColumnOption, ColumnOptionDef, ConstraintCharacteristics, Deduplicate, DeferrableInitial,
|
ColumnOption, ColumnOptionDef, ConstraintCharacteristics, Deduplicate, DeferrableInitial,
|
||||||
GeneratedAs, GeneratedExpressionMode, IndexOption, IndexType, KeyOrIndexDisplay, Owner,
|
GeneratedAs, GeneratedExpressionMode, IdentityProperty, IndexOption, IndexType,
|
||||||
Partition, ProcedureParam, ReferentialAction, TableConstraint,
|
KeyOrIndexDisplay, Owner, Partition, ProcedureParam, ReferentialAction, TableConstraint,
|
||||||
UserDefinedTypeCompositeAttributeDef, UserDefinedTypeRepresentation, ViewColumnDef,
|
UserDefinedTypeCompositeAttributeDef, UserDefinedTypeRepresentation, ViewColumnDef,
|
||||||
};
|
};
|
||||||
pub use self::dml::{CreateIndex, CreateTable, Delete, Insert};
|
pub use self::dml::{CreateIndex, CreateTable, Delete, Insert};
|
||||||
|
|
|
@ -6069,6 +6069,20 @@ impl<'a> Parser<'a> {
|
||||||
&& dialect_of!(self is MySqlDialect | SQLiteDialect | DuckDbDialect | GenericDialect)
|
&& dialect_of!(self is MySqlDialect | SQLiteDialect | DuckDbDialect | GenericDialect)
|
||||||
{
|
{
|
||||||
self.parse_optional_column_option_as()
|
self.parse_optional_column_option_as()
|
||||||
|
} else if self.parse_keyword(Keyword::IDENTITY)
|
||||||
|
&& dialect_of!(self is MsSqlDialect | GenericDialect)
|
||||||
|
{
|
||||||
|
let property = if self.consume_token(&Token::LParen) {
|
||||||
|
let seed = self.parse_number()?;
|
||||||
|
self.expect_token(&Token::Comma)?;
|
||||||
|
let increment = self.parse_number()?;
|
||||||
|
self.expect_token(&Token::RParen)?;
|
||||||
|
|
||||||
|
Some(IdentityProperty { seed, increment })
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
Ok(Some(ColumnOption::Identity(property)))
|
||||||
} else {
|
} else {
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
|
|
|
@ -908,6 +908,117 @@ fn parse_create_table_with_invalid_options() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parse_create_table_with_identity_column() {
|
||||||
|
let with_column_options = [
|
||||||
|
(
|
||||||
|
r#"CREATE TABLE mytable (columnA INT IDENTITY NOT NULL)"#,
|
||||||
|
vec![
|
||||||
|
ColumnOptionDef {
|
||||||
|
name: None,
|
||||||
|
option: ColumnOption::Identity(None),
|
||||||
|
},
|
||||||
|
ColumnOptionDef {
|
||||||
|
name: None,
|
||||||
|
option: ColumnOption::NotNull,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r#"CREATE TABLE mytable (columnA INT IDENTITY(1, 1) NOT NULL)"#,
|
||||||
|
vec![
|
||||||
|
ColumnOptionDef {
|
||||||
|
name: None,
|
||||||
|
#[cfg(not(feature = "bigdecimal"))]
|
||||||
|
option: ColumnOption::Identity(Some(IdentityProperty {
|
||||||
|
seed: Expr::Value(Value::Number("1".to_string(), false)),
|
||||||
|
increment: Expr::Value(Value::Number("1".to_string(), false)),
|
||||||
|
})),
|
||||||
|
#[cfg(feature = "bigdecimal")]
|
||||||
|
option: ColumnOption::Identity(Some(IdentityProperty {
|
||||||
|
seed: Expr::Value(Value::Number(bigdecimal::BigDecimal::from(1), false)),
|
||||||
|
increment: Expr::Value(Value::Number(
|
||||||
|
bigdecimal::BigDecimal::from(1),
|
||||||
|
false,
|
||||||
|
)),
|
||||||
|
})),
|
||||||
|
},
|
||||||
|
ColumnOptionDef {
|
||||||
|
name: None,
|
||||||
|
option: ColumnOption::NotNull,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
),
|
||||||
|
];
|
||||||
|
|
||||||
|
for (sql, column_options) in with_column_options {
|
||||||
|
assert_eq!(
|
||||||
|
ms_and_generic().verified_stmt(sql),
|
||||||
|
Statement::CreateTable(CreateTable {
|
||||||
|
or_replace: false,
|
||||||
|
temporary: false,
|
||||||
|
external: false,
|
||||||
|
global: None,
|
||||||
|
if_not_exists: false,
|
||||||
|
transient: false,
|
||||||
|
volatile: false,
|
||||||
|
name: ObjectName(vec![Ident {
|
||||||
|
value: "mytable".to_string(),
|
||||||
|
quote_style: None,
|
||||||
|
},],),
|
||||||
|
columns: vec![ColumnDef {
|
||||||
|
name: Ident {
|
||||||
|
value: "columnA".to_string(),
|
||||||
|
quote_style: None,
|
||||||
|
},
|
||||||
|
data_type: Int(None,),
|
||||||
|
collation: None,
|
||||||
|
options: column_options,
|
||||||
|
},],
|
||||||
|
constraints: vec![],
|
||||||
|
hive_distribution: HiveDistributionStyle::NONE,
|
||||||
|
hive_formats: Some(HiveFormat {
|
||||||
|
row_format: None,
|
||||||
|
serde_properties: None,
|
||||||
|
storage: None,
|
||||||
|
location: None,
|
||||||
|
},),
|
||||||
|
table_properties: vec![],
|
||||||
|
with_options: vec![],
|
||||||
|
file_format: None,
|
||||||
|
location: None,
|
||||||
|
query: None,
|
||||||
|
without_rowid: false,
|
||||||
|
like: None,
|
||||||
|
clone: None,
|
||||||
|
engine: None,
|
||||||
|
comment: None,
|
||||||
|
auto_increment_offset: None,
|
||||||
|
default_charset: None,
|
||||||
|
collation: None,
|
||||||
|
on_commit: None,
|
||||||
|
on_cluster: None,
|
||||||
|
primary_key: None,
|
||||||
|
order_by: None,
|
||||||
|
partition_by: None,
|
||||||
|
cluster_by: None,
|
||||||
|
clustered_by: None,
|
||||||
|
options: None,
|
||||||
|
strict: false,
|
||||||
|
copy_grants: false,
|
||||||
|
enable_schema_evolution: None,
|
||||||
|
change_tracking: None,
|
||||||
|
data_retention_time_in_days: None,
|
||||||
|
max_data_extension_time_in_days: None,
|
||||||
|
default_ddl_collation: None,
|
||||||
|
with_aggregation_policy: None,
|
||||||
|
with_row_access_policy: None,
|
||||||
|
with_tags: None,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn ms() -> TestedDialects {
|
fn ms() -> TestedDialects {
|
||||||
TestedDialects {
|
TestedDialects {
|
||||||
dialects: vec![Box::new(MsSqlDialect {})],
|
dialects: vec![Box::new(MsSqlDialect {})],
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue